Showing source for: https://www.banglapdfeditor.com/
Duration: 0.547843s
Server: cloudflare
<!DOCTYPE html>
<html lang="bn">
<head>
<!-- Google Tag Manager -->
<script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
})(window,document,'script','dataLayer','GTM-5GX8TKCX');</script>
<!-- End Google Tag Manager -->
<meta charset="UTF-8">
<script src="https://browser.sentry-cdn.com/8.0.0/bundle.min.js" crossorigin="anonymous"></script>
<script>
// Helper to identify third-party / AdSense / extension script noise
function isThirdPartyNoise(msg, stack, filename) {
var text = ((msg || '') + ' ' + (stack || '') + ' ' + (filename || '')).toLowerCase();
return (
text.includes('chrome-extension://') ||
text.includes('moz-extension://') ||
text.includes('safari-extension://') ||
text.includes('pagead') ||
text.includes('googlesyndication') ||
text.includes('doubleclick') ||
text.includes('googleads') ||
text.includes('google-analytics') ||
text.includes('googletagmanager') ||
text.includes('clarity.ms') ||
text.includes('adtrafficquality') ||
text.includes('rum_fy') ||
text.includes('show_ads') ||
text.includes('int64') ||
text.includes('failed to fetch') ||
text.includes('networkerror') ||
text.includes('resizeobserver') ||
text.includes('script error')
);
}
Sentry.init({
dsn: "https://64172d16d259af3cab327e77281d8941@o4511712681197568.ingest.de.sentry.io/4511712705314896",
ignoreErrors: [
'top.GLOBALS',
'Cannot read properties of undefined (reading \'M_ID\')',
'Failed to fetch',
'NetworkError when attempting to fetch resource',
'Failed to read the \'localStorage\' property from \'Window\'',
'SecurityError',
'int64',
'Error: int64',
/^int64$/i,
/int64/i,
/adsbygoogle/i,
'ResizeObserver loop limit exceeded',
'ResizeObserver loop completed with undelivered notifications',
'Script error.',
],
denyUrls: [
/extensions\//i,
/^chrome:\/\//i,
/^chrome-extension:\/\//i,
/^moz-extension:\/\//i,
/^safari-web-extension:\/\//i,
/pagead/i,
/googlesyndication/i,
/doubleclick/i,
/googleads/i,
/google-analytics/i,
/googletagmanager/i,
/clarity\.ms/i,
/adtrafficquality/i,
/rum_fy/i,
/show_ads/i,
],
beforeSend: function(event, hint) {
try {
var err = hint && (hint.originalException || hint.syntheticException);
var errMsg = (event.message || (err && err.message) || (err && err.toString()) || '').toLowerCase();
if (
errMsg.includes('int64') ||
errMsg.includes('adsbygoogle') ||
errMsg.includes('resizeobserver') ||
errMsg.includes('failed to fetch')
) {
return null;
}
var values = (event.exception && event.exception.values) || [];
for (var v = 0; v < values.length; v++) {
var frames = (values[v].stacktrace && values[v].stacktrace.frames) || [];
for (var i = 0; i < frames.length; i++) {
var fn = (frames[i].filename || '').toLowerCase();
var mod = (frames[i].module || '').toLowerCase();
if (
fn.includes('pagead') ||
fn.includes('googlesyndication') ||
fn.includes('doubleclick') ||
fn.includes('googleads') ||
fn.includes('google-analytics') ||
fn.includes('googletagmanager') ||
fn.includes('clarity.ms') ||
fn.includes('adtrafficquality') ||
fn.includes('chrome-extension') ||
fn.includes('moz-extension') ||
fn.includes('safari-extension') ||
fn.includes('rum_fy') ||
fn.includes('show_ads') ||
mod.includes('pagead')
) {
return null;
}
}
}
var culprit = (event.culprit || event.transaction || '').toLowerCase();
if (
culprit.includes('pagead') ||
culprit.includes('rum_fy') ||
culprit.includes('googlesyndication') ||
culprit.includes('doubleclick')
) {
return null;
}
} catch (e) {
// Prevent filter exceptions
}
return event;
}
});
// Global error hook for Telegram
window.addEventListener("error", function(e) {
var stack = (e.error && e.error.stack) || '';
if (isThirdPartyNoise(e.message, stack, e.filename)) return;
fetch('/api/frontend-error', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ message: e.message, url: window.location.href, stack: stack })
}).catch(function(err) { console.error('Error logging to backend:', err); });
});
window.addEventListener("unhandledrejection", function(e) {
var reason = e.reason ? (e.reason.message || e.reason.toString()) : 'Promise Rejection';
var stack = (e.reason && e.reason.stack) || '';
if (isThirdPartyNoise(reason, stack, '')) return;
fetch('/api/frontend-error', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ message: reason, url: window.location.href, stack: stack })
}).catch(function(err) { console.error('Error logging to backend:', err); });
});
</script>
<meta name="viewport" content="width=1000, initial-scale=1.0, maximum-scale=5.0, user-scalable=yes"
id="viewport-meta">
<!-- REMOVED: Desktop viewport was causing gesture issues -->
<!-- <script src="/static/js/mobile-desktop-viewport.js"></script> -->
<!-- Removed mobile-specific detection - serving desktop version to all devices -->
<script>
// All users (mobile and desktop) now use the same desktop code
window.DEVICE_TYPE = 'desktop';
console.log('💻 Serving desktop version to all devices');
// Prevent ReferenceErrors if UI buttons clicked before main script loads
window.openPaymentModal = window.openAuthModal = window.logoutUser = window.openDocsPanel = function() {};
</script>
<title>বাংলা পিডিএফ এডিটর | Bangla PDF Editor</title>
<!-- Favicons -->
<link rel="icon" type="image/x-icon" href="/static/favicon.ico">
<link rel="icon" type="image/png" sizes="16x16" href="/static/icons/favicon-16.png">
<link rel="icon" type="image/png" sizes="32x32" href="/static/icons/favicon-32.png">
<link rel="icon" type="image/png" sizes="96x96" href="/static/icons/favicon-96.png">
<link rel="icon" type="image/png" sizes="192x192" href="/static/icons/favicon-192.png">
<link rel="apple-touch-icon" sizes="180x180" href="/static/icons/apple-touch-icon-180.png">
<link rel="icon" type="image/svg+xml" href="/static/favicon.svg">
<!-- Theme Color -->
<meta name="theme-color" content="#10B981">
<!-- Open Graph / Social Media Meta Tags -->
<meta property="og:title" content="বাংলা পিডিএফ এডিটর | Free Bangla PDF Editor Online">
<meta property="og:description"
content="Free online Bangla PDF Editor. Edit, merge, split, compress PDFs with Bengali Unicode support. 396+ fonts, OCR, watermark, e-signature. No registration required.">
<meta property="og:image" content="/static/logo.png">
<meta property="og:url" content="https://banglapdfeditor.com/">
<meta property="og:type" content="website">
<meta property="og:site_name" content="Bangla PDF Editor">
<meta property="og:locale" content="bn_BD">
<meta property="og:locale:alternate" content="en_US">
<!-- Twitter Card Meta Tags -->
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:title" content="বাংলা পিডিএফ এডিটর | Free Bangla PDF Editor Online">
<meta name="twitter:description"
content="Free online Bangla PDF Editor. Edit, merge, split, compress PDFs with Bengali Unicode support. 396+ fonts, OCR, watermark, e-signature.">
<meta name="twitter:image" content="/static/logo.png">
<meta name="twitter:site" content="@banglapdfeditor">
<meta name="twitter:creator" content="@banglapdfeditor">
<!-- SEO Meta Tags - Enhanced -->
<meta name="description"
content="Free online Bangla PDF Editor. Edit, merge, split, compress PDFs with Bengali Unicode support. 396+ fonts, OCR, watermark, e-signature.">
<meta name="keywords"
content="bangla pdf editor, bengali pdf editor, বাংলা পিডিএফ এডিটর, pdf edit bangla, unicode pdf, bijoy to unicode, ocr bengali, merge pdf, split pdf, compress pdf, pdf to word bangla, free pdf editor">
<meta name="author" content="Bangla PDF Editor">
<meta name="robots" content="index, follow, max-image-preview:large, max-snippet:-1, max-video-preview:-1">
<!-- Canonical URL - Dynamic based on language/region -->
<link rel="canonical" href="https://www.banglapdfeditor.com/">
<!-- Sitemap for SEO -->
<link rel="sitemap" type="application/xml" href="/sitemap.xml">
<!-- Language & Regional Alternatives - Phase 5 International SEO -->
<!-- Multi-language support - All point to canonical URL to avoid duplicate content -->
<link rel="alternate" hreflang="bn" href="https://banglapdfeditor.com/">
<link rel="alternate" hreflang="bn-BD" href="https://banglapdfeditor.com/">
<link rel="alternate" hreflang="en" href="https://banglapdfeditor.com/">
<link rel="alternate" hreflang="en-US" href="https://banglapdfeditor.com/">
<link rel="alternate" hreflang="en-GB" href="https://banglapdfeditor.com/">
<link rel="alternate" hreflang="en-IN" href="https://banglapdfeditor.com/">
<link rel="alternate" hreflang="x-default" href="https://banglapdfeditor.com/">
<!-- Preconnect for Performance -->
<link rel="dns-prefetch" href="https://www.google-analytics.com">
<!-- Preload Critical Resources -->
<link rel="preload" href="/static/css/style.css?v=20260224" as="style">
<!-- Simple approach: Use same code, scale with CSS -->
<!-- app.js loaded as regular script below — no preload needed -->
<!-- Optimized Font Loading - WOFF2 Only -->
<!-- Optimized Font Loading with Preloading -->
<link rel="preload" href="/fonts/Kalpurush.woff2" as="font" type="font/woff2" crossorigin>
<link rel="preload" href="/fonts/SolaimanLipi.woff2" as="font" type="font/woff2" crossorigin>
<link rel="preload" href="/fonts/Nikosh.woff2" as="font" type="font/woff2" crossorigin>
<link rel="stylesheet" href="/static/css/fonts-optimized.css?v=202601267">
<link rel="stylesheet" href="/static/css/optimized-fonts.css?v=202601267">
<!-- Minified CSS for Performance - 30% size reduction -->
<link rel="stylesheet" href="/static/css/style.css?v=20260224">
<!-- Mobile Editor Optimization -->
<!-- <link rel="stylesheet" href="/static/css/mobile-editor-optimized.css?v=202601270"> -->
<link rel="stylesheet" href="/static/css/ribbon.css?v=202601265">
<!-- <link rel="stylesheet" href="/static/css/mobile-responsive.css?v=202601270"> -->
<!-- Enhanced mobile experience -->
<!-- <link rel="stylesheet" href="/static/css/mobile-basic.css?v=202601270"> -->
<link rel="stylesheet" href="/static/css/merge_split.css?v=202601265">
<link rel="stylesheet" href="/static/css/signature.css?v=202601265">
<link rel="stylesheet" href="/static/css/share.css?v=202601265">
<link rel="stylesheet" href="/static/css/export.css?v=202601265">
<link rel="stylesheet" href="/static/css/compress.css?v=202601265">
<link rel="stylesheet" href="/static/css/watermark.css?v=202601265">
<link rel="stylesheet" href="/static/css/ribbon-style.css?v=202602021">
<link rel="stylesheet" href="/static/css/edit-bar.css?v=202602022">
<link rel="stylesheet" href="/static/css/modern-ribbon.css?v=202602023">
<!-- PWA styles disabled -->
<!-- <link rel="stylesheet" href="/static/css/pwa-styles.css?v=202601265"> -->
<!-- PWA Manifest - DISABLED -->
<!-- <link rel="manifest" href="/manifest.json"> -->
<!-- Theme Color -->
<meta name="theme-color" content="#3b82f6">
<!-- PWA meta tags disabled -->
<!-- <meta name="mobile-web-app-capable" content="yes"> -->
<!-- <meta name="apple-mobile-web-app-capable" content="yes"> -->
<!-- <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent"> -->
<!-- <meta name="apple-mobile-web-app-title" content="Bangla PDF"> -->
<!-- iOS Icons - Disabled for non-PWA -->
<!-- <link rel="apple-touch-icon" href="/static/icons/icon-152x152.png"> -->
<!-- <link rel="apple-touch-icon" sizes="180x180" href="/static/icons/icon-192x192.png"> -->
<!-- Structured Data - JSON-LD Schemas -->
<!-- Organization Schema -->
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "Organization",
"name": "Bangla PDF Editor",
"alternateName": "বাংলা পিডিএফ এডিটর",
"url": "https://banglapdfeditor.com",
"logo": "https://banglapdfeditor.com/static/logo.png",
"description": "Free online Bangla PDF Editor with Bengali Unicode support. Edit, merge, split, compress PDFs with 190+ fonts, OCR, watermark, and e-signature features.",
"sameAs": [
"https://twitter.com/banglapdfeditor",
"https://facebook.com/banglapdfeditor"
],
"contactPoint": {
"@type": "ContactPoint",
"contactType": "Customer Support",
"availableLanguage": ["Bengali", "English"]
}
}
</script>
<!-- WebSite Schema with Search Action -->
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "WebSite",
"name": "Bangla PDF Editor",
"alternateName": "বাংলা পিডিএফ এডিটর",
"url": "https://banglapdfeditor.com",
"description": "Free online Bangla PDF Editor. Edit, merge, split, compress PDFs with Bengali Unicode support.",
"inLanguage": ["bn", "en"],
"potentialAction": {
"@type": "SearchAction",
"target": {
"@type": "EntryPoint",
"urlTemplate": "https://banglapdfeditor.com/?q={search_term_string}"
},
"query-input": "required name=search_term_string"
}
}
</script>
<!-- WebApplication Schema -->
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "WebApplication",
"name": "Bangla PDF Editor",
"alternateName": "বাংলা পিডিএফ এডিটর",
"url": "https://banglapdfeditor.com",
"applicationCategory": "UtilitiesApplication",
"operatingSystem": "Any",
"browserRequirements": "Requires JavaScript. Requires HTML5.",
"description": "Free online Bangla PDF Editor with full Bengali Unicode support. Features include PDF editing, text overlay, Bengali fonts (190+), OCR, merge, split, compress, watermark, and electronic signatures.",
"offers": {
"@type": "Offer",
"price": "0",
"priceCurrency": "USD"
},
"featureList": [
"Edit Bengali text in PDF",
"190+ Bengali and English fonts",
"OCR text extraction (Bengali & English)",
"Merge PDF files",
"Split PDF documents",
"Compress PDF size",
"PDF to Word converter",
"PDF to Excel converter",
"Add watermarks",
"Electronic signatures",
"Bijoy to Unicode converter",
"QR code generation",
"Real-time editing",
"Autosave feature",
"Dark mode",
"Mobile responsive"
],
"screenshot": "https://banglapdfeditor.com/static/screenshots/desktop.png",
"softwareVersion": "1.0.0",
"aggregateRating": {
"@type": "AggregateRating",
"ratingValue": "4.8",
"ratingCount": "250",
"bestRating": "5",
"worstRating": "1"
},
"author": {
"@type": "Organization",
"name": "Bangla PDF Editor"
}
}
</script>
<!-- SoftwareApplication Schema -->
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "SoftwareApplication",
"name": "Bangla PDF Editor",
"alternateName": "বাংলা পিডিএফ এডিটর",
"description": "Professional online PDF editor with full Bengali language support. Edit, format, and manage PDF documents with 190+ fonts, OCR, and advanced features.",
"applicationCategory": "BusinessApplication",
"applicationSubCategory": "PDF Editor",
"operatingSystem": "Web Browser",
"url": "https://banglapdfeditor.com",
"screenshot": "https://banglapdfeditor.com/static/screenshots/desktop.png",
"softwareVersion": "1.0.0",
"offers": {
"@type": "Offer",
"price": "0",
"priceCurrency": "USD",
"availability": "https://schema.org/InStock"
},
"aggregateRating": {
"@type": "AggregateRating",
"ratingValue": "4.8",
"reviewCount": "250"
}
}
</script>
<!-- BreadcrumbList Schema -->
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "BreadcrumbList",
"itemListElement": [
{
"@type": "ListItem",
"position": 1,
"name": "Home",
"item": "https://banglapdfeditor.com/"
},
{
"@type": "ListItem",
"position": 2,
"name": "Features",
"item": "https://banglapdfeditor.com/#features"
},
{
"@type": "ListItem",
"position": 3,
"name": "Blog",
"item": "https://banglapdfeditor.com/blog"
},
{
"@type": "ListItem",
"position": 4,
"name": "Tutorials",
"item": "https://banglapdfeditor.com/tutorials"
}
]
}
</script>
<!-- FAQPage Schema for Homepage -->
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "FAQPage",
"mainEntity": [
{
"@type": "Question",
"name": "Is Bangla PDF Editor free to use?",
"acceptedAnswer": {
"@type": "Answer",
"text": "Yes, Bangla PDF Editor is completely free to use with no registration required. All features including Bengali text editing, OCR, merge, split, compress, and conversions are available at no cost."
}
},
{
"@type": "Question",
"name": "Does it support Bengali Unicode?",
"acceptedAnswer": {
"@type": "Answer",
"text": "Yes, we have full Bengali Unicode support with 190+ fonts including popular Bengali fonts like Kalpurush, Solaiman Lipi, Hoogli, and Kohinoor. All Bengali characters render perfectly."
}
},
{
"@type": "Question",
"name": "Can I convert Bijoy to Unicode?",
"acceptedAnswer": {
"@type": "Answer",
"text": "Yes, we have a built-in Bijoy to Unicode converter. You can convert legacy Bijoy encoded text to modern Unicode format and vice versa."
}
},
{
"@type": "Question",
"name": "Is my data secure?",
"acceptedAnswer": {
"@type": "Answer",
"text": "Yes, we implement 35+ security features including 5-layer file validation, ClamAV antivirus scanning, rate limiting, and secure session management. Your files are processed securely and deleted after your session."
}
},
{
"@type": "Question",
"name": "What file formats are supported?",
"acceptedAnswer": {
"@type": "Answer",
"text": "We support PDF files (up to 50MB) for editing. You can also convert PDFs to Word (DOCX), Excel (XLSX), and create PDFs from images (JPG, PNG). OCR works on images and scanned PDFs."
}
}
]
}
</script>
<!-- Google Fonts - Roboto -->
<style type="text/css">@font-face {font-family:'Roboto';font-style:normal;font-weight:300;src:url(/cf-fonts/v/roboto/5.2.10/greek/wght/normal.woff2);unicode-range:U+0370-0377,U+037A-037F,U+0384-038A,U+038C,U+038E-03A1,U+03A3-03FF;font-display:swap;}@font-face {font-family:'Roboto';font-style:normal;font-weight:300;src:url(/cf-fonts/v/roboto/5.2.10/vietnamese/wght/normal.woff2);unicode-range:U+0102-0103,U+0110-0111,U+0128-0129,U+0168-0169,U+01A0-01A1,U+01AF-01B0,U+0300-0301,U+0303-0304,U+0308-0309,U+0323,U+0329,U+1EA0-1EF9,U+20AB;font-display:swap;}@font-face {font-family:'Roboto';font-style:normal;font-weight:300;src:url(/cf-fonts/v/roboto/5.2.10/latin-ext/wght/normal.woff2);unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;font-display:swap;}@font-face {font-family:'Roboto';font-style:normal;font-weight:300;src:url(/cf-fonts/v/roboto/5.2.10/greek-ext/wght/normal.woff2);unicode-range:U+1F00-1FFF;font-display:swap;}@font-face {font-family:'Roboto';font-style:normal;font-weight:300;src:url(/cf-fonts/v/roboto/5.2.10/latin/wght/normal.woff2);unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;font-display:swap;}@font-face {font-family:'Roboto';font-style:normal;font-weight:300;src:url(/cf-fonts/v/roboto/5.2.10/symbols/wght/normal.woff2);unicode-range:U+0001-000C,U+000E-001F,U+007F-009F,U+20DD-20E0,U+20E2-20E4,U+2150-218F,U+2190,U+2192,U+2194-2199,U+21AF,U+21E6-21F0,U+21F3,U+2218-2219,U+2299,U+22C4-22C6,U+2300-243F,U+2440-244A,U+2460-24FF,U+25A0-27BF,U+2800-28FF,U+2921-2922,U+2981,U+29BF,U+29EB,U+2B00-2BFF,U+4DC0-4DFF,U+FFF9-FFFB,U+10140-1018E,U+10190-1019C,U+101A0,U+101D0-101FD,U+102E0-102FB,U+10E60-10E7E,U+1D2C0-1D2D3,U+1D2E0-1D37F,U+1F000-1F0FF,U+1F100-1F1AD,U+1F1E6-1F1FF,U+1F30D-1F30F,U+1F315,U+1F31C,U+1F31E,U+1F320-1F32C,U+1F336,U+1F378,U+1F37D,U+1F382,U+1F393-1F39F,U+1F3A7-1F3A8,U+1F3AC-1F3AF,U+1F3C2,U+1F3C4-1F3C6,U+1F3CA-1F3CE,U+1F3D4-1F3E0,U+1F3ED,U+1F3F1-1F3F3,U+1F3F5-1F3F7,U+1F408,U+1F415,U+1F41F,U+1F426,U+1F43F,U+1F441-1F442,U+1F444,U+1F446-1F449,U+1F44C-1F44E,U+1F453,U+1F46A,U+1F47D,U+1F4A3,U+1F4B0,U+1F4B3,U+1F4B9,U+1F4BB,U+1F4BF,U+1F4C8-1F4CB,U+1F4D6,U+1F4DA,U+1F4DF,U+1F4E3-1F4E6,U+1F4EA-1F4ED,U+1F4F7,U+1F4F9-1F4FB,U+1F4FD-1F4FE,U+1F503,U+1F507-1F50B,U+1F50D,U+1F512-1F513,U+1F53E-1F54A,U+1F54F-1F5FA,U+1F610,U+1F650-1F67F,U+1F687,U+1F68D,U+1F691,U+1F694,U+1F698,U+1F6AD,U+1F6B2,U+1F6B9-1F6BA,U+1F6BC,U+1F6C6-1F6CF,U+1F6D3-1F6D7,U+1F6E0-1F6EA,U+1F6F0-1F6F3,U+1F6F7-1F6FC,U+1F700-1F7FF,U+1F800-1F80B,U+1F810-1F847,U+1F850-1F859,U+1F860-1F887,U+1F890-1F8AD,U+1F8B0-1F8BB,U+1F8C0-1F8C1,U+1F900-1F90B,U+1F93B,U+1F946,U+1F984,U+1F996,U+1F9E9,U+1FA00-1FA6F,U+1FA70-1FA7C,U+1FA80-1FA89,U+1FA8F-1FAC6,U+1FACE-1FADC,U+1FADF-1FAE9,U+1FAF0-1FAF8,U+1FB00-1FBFF;font-display:swap;}@font-face {font-family:'Roboto';font-style:normal;font-weight:300;src:url(/cf-fonts/v/roboto/5.2.10/cyrillic/wght/normal.woff2);unicode-range:U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116;font-display:swap;}@font-face {font-family:'Roboto';font-style:normal;font-weight:300;src:url(/cf-fonts/v/roboto/5.2.10/cyrillic-ext/wght/normal.woff2);unicode-range:U+0460-052F,U+1C80-1C8A,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F;font-display:swap;}@font-face {font-family:'Roboto';font-style:normal;font-weight:300;src:url(/cf-fonts/v/roboto/5.2.10/math/wght/normal.woff2);unicode-range:U+0302-0303,U+0305,U+0307-0308,U+0310,U+0312,U+0315,U+031A,U+0326-0327,U+032C,U+032F-0330,U+0332-0333,U+0338,U+033A,U+0346,U+034D,U+0391-03A1,U+03A3-03A9,U+03B1-03C9,U+03D1,U+03D5-03D6,U+03F0-03F1,U+03F4-03F5,U+2016-2017,U+2034-2038,U+203C,U+2040,U+2043,U+2047,U+2050,U+2057,U+205F,U+2070-2071,U+2074-208E,U+2090-209C,U+20D0-20DC,U+20E1,U+20E5-20EF,U+2100-2112,U+2114-2115,U+2117-2121,U+2123-214F,U+2190,U+2192,U+2194-21AE,U+21B0-21E5,U+21F1-21F2,U+21F4-2211,U+2213-2214,U+2216-22FF,U+2308-230B,U+2310,U+2319,U+231C-2321,U+2336-237A,U+237C,U+2395,U+239B-23B7,U+23D0,U+23DC-23E1,U+2474-2475,U+25AF,U+25B3,U+25B7,U+25BD,U+25C1,U+25CA,U+25CC,U+25FB,U+266D-266F,U+27C0-27FF,U+2900-2AFF,U+2B0E-2B11,U+2B30-2B4C,U+2BFE,U+3030,U+FF5B,U+FF5D,U+1D400-1D7FF,U+1EE00-1EEFF;font-display:swap;}@font-face {font-family:'Roboto';font-style:normal;font-weight:400;src:url(/cf-fonts/v/roboto/5.2.10/latin-ext/wght/normal.woff2);unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;font-display:swap;}@font-face {font-family:'Roboto';font-style:normal;font-weight:400;src:url(/cf-fonts/v/roboto/5.2.10/latin/wght/normal.woff2);unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;font-display:swap;}@font-face {font-family:'Roboto';font-style:normal;font-weight:400;src:url(/cf-fonts/v/roboto/5.2.10/symbols/wght/normal.woff2);unicode-range:U+0001-000C,U+000E-001F,U+007F-009F,U+20DD-20E0,U+20E2-20E4,U+2150-218F,U+2190,U+2192,U+2194-2199,U+21AF,U+21E6-21F0,U+21F3,U+2218-2219,U+2299,U+22C4-22C6,U+2300-243F,U+2440-244A,U+2460-24FF,U+25A0-27BF,U+2800-28FF,U+2921-2922,U+2981,U+29BF,U+29EB,U+2B00-2BFF,U+4DC0-4DFF,U+FFF9-FFFB,U+10140-1018E,U+10190-1019C,U+101A0,U+101D0-101FD,U+102E0-102FB,U+10E60-10E7E,U+1D2C0-1D2D3,U+1D2E0-1D37F,U+1F000-1F0FF,U+1F100-1F1AD,U+1F1E6-1F1FF,U+1F30D-1F30F,U+1F315,U+1F31C,U+1F31E,U+1F320-1F32C,U+1F336,U+1F378,U+1F37D,U+1F382,U+1F393-1F39F,U+1F3A7-1F3A8,U+1F3AC-1F3AF,U+1F3C2,U+1F3C4-1F3C6,U+1F3CA-1F3CE,U+1F3D4-1F3E0,U+1F3ED,U+1F3F1-1F3F3,U+1F3F5-1F3F7,U+1F408,U+1F415,U+1F41F,U+1F426,U+1F43F,U+1F441-1F442,U+1F444,U+1F446-1F449,U+1F44C-1F44E,U+1F453,U+1F46A,U+1F47D,U+1F4A3,U+1F4B0,U+1F4B3,U+1F4B9,U+1F4BB,U+1F4BF,U+1F4C8-1F4CB,U+1F4D6,U+1F4DA,U+1F4DF,U+1F4E3-1F4E6,U+1F4EA-1F4ED,U+1F4F7,U+1F4F9-1F4FB,U+1F4FD-1F4FE,U+1F503,U+1F507-1F50B,U+1F50D,U+1F512-1F513,U+1F53E-1F54A,U+1F54F-1F5FA,U+1F610,U+1F650-1F67F,U+1F687,U+1F68D,U+1F691,U+1F694,U+1F698,U+1F6AD,U+1F6B2,U+1F6B9-1F6BA,U+1F6BC,U+1F6C6-1F6CF,U+1F6D3-1F6D7,U+1F6E0-1F6EA,U+1F6F0-1F6F3,U+1F6F7-1F6FC,U+1F700-1F7FF,U+1F800-1F80B,U+1F810-1F847,U+1F850-1F859,U+1F860-1F887,U+1F890-1F8AD,U+1F8B0-1F8BB,U+1F8C0-1F8C1,U+1F900-1F90B,U+1F93B,U+1F946,U+1F984,U+1F996,U+1F9E9,U+1FA00-1FA6F,U+1FA70-1FA7C,U+1FA80-1FA89,U+1FA8F-1FAC6,U+1FACE-1FADC,U+1FADF-1FAE9,U+1FAF0-1FAF8,U+1FB00-1FBFF;font-display:swap;}@font-face {font-family:'Roboto';font-style:normal;font-weight:400;src:url(/cf-fonts/v/roboto/5.2.10/vietnamese/wght/normal.woff2);unicode-range:U+0102-0103,U+0110-0111,U+0128-0129,U+0168-0169,U+01A0-01A1,U+01AF-01B0,U+0300-0301,U+0303-0304,U+0308-0309,U+0323,U+0329,U+1EA0-1EF9,U+20AB;font-display:swap;}@font-face {font-family:'Roboto';font-style:normal;font-weight:400;src:url(/cf-fonts/v/roboto/5.2.10/greek/wght/normal.woff2);unicode-range:U+0370-0377,U+037A-037F,U+0384-038A,U+038C,U+038E-03A1,U+03A3-03FF;font-display:swap;}@font-face {font-family:'Roboto';font-style:normal;font-weight:400;src:url(/cf-fonts/v/roboto/5.2.10/greek-ext/wght/normal.woff2);unicode-range:U+1F00-1FFF;font-display:swap;}@font-face {font-family:'Roboto';font-style:normal;font-weight:400;src:url(/cf-fonts/v/roboto/5.2.10/math/wght/normal.woff2);unicode-range:U+0302-0303,U+0305,U+0307-0308,U+0310,U+0312,U+0315,U+031A,U+0326-0327,U+032C,U+032F-0330,U+0332-0333,U+0338,U+033A,U+0346,U+034D,U+0391-03A1,U+03A3-03A9,U+03B1-03C9,U+03D1,U+03D5-03D6,U+03F0-03F1,U+03F4-03F5,U+2016-2017,U+2034-2038,U+203C,U+2040,U+2043,U+2047,U+2050,U+2057,U+205F,U+2070-2071,U+2074-208E,U+2090-209C,U+20D0-20DC,U+20E1,U+20E5-20EF,U+2100-2112,U+2114-2115,U+2117-2121,U+2123-214F,U+2190,U+2192,U+2194-21AE,U+21B0-21E5,U+21F1-21F2,U+21F4-2211,U+2213-2214,U+2216-22FF,U+2308-230B,U+2310,U+2319,U+231C-2321,U+2336-237A,U+237C,U+2395,U+239B-23B7,U+23D0,U+23DC-23E1,U+2474-2475,U+25AF,U+25B3,U+25B7,U+25BD,U+25C1,U+25CA,U+25CC,U+25FB,U+266D-266F,U+27C0-27FF,U+2900-2AFF,U+2B0E-2B11,U+2B30-2B4C,U+2BFE,U+3030,U+FF5B,U+FF5D,U+1D400-1D7FF,U+1EE00-1EEFF;font-display:swap;}@font-face {font-family:'Roboto';font-style:normal;font-weight:400;src:url(/cf-fonts/v/roboto/5.2.10/cyrillic-ext/wght/normal.woff2);unicode-range:U+0460-052F,U+1C80-1C8A,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F;font-display:swap;}@font-face {font-family:'Roboto';font-style:normal;font-weight:400;src:url(/cf-fonts/v/roboto/5.2.10/cyrillic/wght/normal.woff2);unicode-range:U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116;font-display:swap;}@font-face {font-family:'Roboto';font-style:normal;font-weight:500;src:url(/cf-fonts/v/roboto/5.2.10/cyrillic/wght/normal.woff2);unicode-range:U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116;font-display:swap;}@font-face {font-family:'Roboto';font-style:normal;font-weight:500;src:url(/cf-fonts/v/roboto/5.2.10/latin-ext/wght/normal.woff2);unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;font-display:swap;}@font-face {font-family:'Roboto';font-style:normal;font-weight:500;src:url(/cf-fonts/v/roboto/5.2.10/symbols/wght/normal.woff2);unicode-range:U+0001-000C,U+000E-001F,U+007F-009F,U+20DD-20E0,U+20E2-20E4,U+2150-218F,U+2190,U+2192,U+2194-2199,U+21AF,U+21E6-21F0,U+21F3,U+2218-2219,U+2299,U+22C4-22C6,U+2300-243F,U+2440-244A,U+2460-24FF,U+25A0-27BF,U+2800-28FF,U+2921-2922,U+2981,U+29BF,U+29EB,U+2B00-2BFF,U+4DC0-4DFF,U+FFF9-FFFB,U+10140-1018E,U+10190-1019C,U+101A0,U+101D0-101FD,U+102E0-102FB,U+10E60-10E7E,U+1D2C0-1D2D3,U+1D2E0-1D37F,U+1F000-1F0FF,U+1F100-1F1AD,U+1F1E6-1F1FF,U+1F30D-1F30F,U+1F315,U+1F31C,U+1F31E,U+1F320-1F32C,U+1F336,U+1F378,U+1F37D,U+1F382,U+1F393-1F39F,U+1F3A7-1F3A8,U+1F3AC-1F3AF,U+1F3C2,U+1F3C4-1F3C6,U+1F3CA-1F3CE,U+1F3D4-1F3E0,U+1F3ED,U+1F3F1-1F3F3,U+1F3F5-1F3F7,U+1F408,U+1F415,U+1F41F,U+1F426,U+1F43F,U+1F441-1F442,U+1F444,U+1F446-1F449,U+1F44C-1F44E,U+1F453,U+1F46A,U+1F47D,U+1F4A3,U+1F4B0,U+1F4B3,U+1F4B9,U+1F4BB,U+1F4BF,U+1F4C8-1F4CB,U+1F4D6,U+1F4DA,U+1F4DF,U+1F4E3-1F4E6,U+1F4EA-1F4ED,U+1F4F7,U+1F4F9-1F4FB,U+1F4FD-1F4FE,U+1F503,U+1F507-1F50B,U+1F50D,U+1F512-1F513,U+1F53E-1F54A,U+1F54F-1F5FA,U+1F610,U+1F650-1F67F,U+1F687,U+1F68D,U+1F691,U+1F694,U+1F698,U+1F6AD,U+1F6B2,U+1F6B9-1F6BA,U+1F6BC,U+1F6C6-1F6CF,U+1F6D3-1F6D7,U+1F6E0-1F6EA,U+1F6F0-1F6F3,U+1F6F7-1F6FC,U+1F700-1F7FF,U+1F800-1F80B,U+1F810-1F847,U+1F850-1F859,U+1F860-1F887,U+1F890-1F8AD,U+1F8B0-1F8BB,U+1F8C0-1F8C1,U+1F900-1F90B,U+1F93B,U+1F946,U+1F984,U+1F996,U+1F9E9,U+1FA00-1FA6F,U+1FA70-1FA7C,U+1FA80-1FA89,U+1FA8F-1FAC6,U+1FACE-1FADC,U+1FADF-1FAE9,U+1FAF0-1FAF8,U+1FB00-1FBFF;font-display:swap;}@font-face {font-family:'Roboto';font-style:normal;font-weight:500;src:url(/cf-fonts/v/roboto/5.2.10/greek/wght/normal.woff2);unicode-range:U+0370-0377,U+037A-037F,U+0384-038A,U+038C,U+038E-03A1,U+03A3-03FF;font-display:swap;}@font-face {font-family:'Roboto';font-style:normal;font-weight:500;src:url(/cf-fonts/v/roboto/5.2.10/vietnamese/wght/normal.woff2);unicode-range:U+0102-0103,U+0110-0111,U+0128-0129,U+0168-0169,U+01A0-01A1,U+01AF-01B0,U+0300-0301,U+0303-0304,U+0308-0309,U+0323,U+0329,U+1EA0-1EF9,U+20AB;font-display:swap;}@font-face {font-family:'Roboto';font-style:normal;font-weight:500;src:url(/cf-fonts/v/roboto/5.2.10/cyrillic-ext/wght/normal.woff2);unicode-range:U+0460-052F,U+1C80-1C8A,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F;font-display:swap;}@font-face {font-family:'Roboto';font-style:normal;font-weight:500;src:url(/cf-fonts/v/roboto/5.2.10/greek-ext/wght/normal.woff2);unicode-range:U+1F00-1FFF;font-display:swap;}@font-face {font-family:'Roboto';font-style:normal;font-weight:500;src:url(/cf-fonts/v/roboto/5.2.10/latin/wght/normal.woff2);unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;font-display:swap;}@font-face {font-family:'Roboto';font-style:normal;font-weight:500;src:url(/cf-fonts/v/roboto/5.2.10/math/wght/normal.woff2);unicode-range:U+0302-0303,U+0305,U+0307-0308,U+0310,U+0312,U+0315,U+031A,U+0326-0327,U+032C,U+032F-0330,U+0332-0333,U+0338,U+033A,U+0346,U+034D,U+0391-03A1,U+03A3-03A9,U+03B1-03C9,U+03D1,U+03D5-03D6,U+03F0-03F1,U+03F4-03F5,U+2016-2017,U+2034-2038,U+203C,U+2040,U+2043,U+2047,U+2050,U+2057,U+205F,U+2070-2071,U+2074-208E,U+2090-209C,U+20D0-20DC,U+20E1,U+20E5-20EF,U+2100-2112,U+2114-2115,U+2117-2121,U+2123-214F,U+2190,U+2192,U+2194-21AE,U+21B0-21E5,U+21F1-21F2,U+21F4-2211,U+2213-2214,U+2216-22FF,U+2308-230B,U+2310,U+2319,U+231C-2321,U+2336-237A,U+237C,U+2395,U+239B-23B7,U+23D0,U+23DC-23E1,U+2474-2475,U+25AF,U+25B3,U+25B7,U+25BD,U+25C1,U+25CA,U+25CC,U+25FB,U+266D-266F,U+27C0-27FF,U+2900-2AFF,U+2B0E-2B11,U+2B30-2B4C,U+2BFE,U+3030,U+FF5B,U+FF5D,U+1D400-1D7FF,U+1EE00-1EEFF;font-display:swap;}@font-face {font-family:'Roboto';font-style:normal;font-weight:700;src:url(/cf-fonts/v/roboto/5.2.10/latin-ext/wght/normal.woff2);unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;font-display:swap;}@font-face {font-family:'Roboto';font-style:normal;font-weight:700;src:url(/cf-fonts/v/roboto/5.2.10/symbols/wght/normal.woff2);unicode-range:U+0001-000C,U+000E-001F,U+007F-009F,U+20DD-20E0,U+20E2-20E4,U+2150-218F,U+2190,U+2192,U+2194-2199,U+21AF,U+21E6-21F0,U+21F3,U+2218-2219,U+2299,U+22C4-22C6,U+2300-243F,U+2440-244A,U+2460-24FF,U+25A0-27BF,U+2800-28FF,U+2921-2922,U+2981,U+29BF,U+29EB,U+2B00-2BFF,U+4DC0-4DFF,U+FFF9-FFFB,U+10140-1018E,U+10190-1019C,U+101A0,U+101D0-101FD,U+102E0-102FB,U+10E60-10E7E,U+1D2C0-1D2D3,U+1D2E0-1D37F,U+1F000-1F0FF,U+1F100-1F1AD,U+1F1E6-1F1FF,U+1F30D-1F30F,U+1F315,U+1F31C,U+1F31E,U+1F320-1F32C,U+1F336,U+1F378,U+1F37D,U+1F382,U+1F393-1F39F,U+1F3A7-1F3A8,U+1F3AC-1F3AF,U+1F3C2,U+1F3C4-1F3C6,U+1F3CA-1F3CE,U+1F3D4-1F3E0,U+1F3ED,U+1F3F1-1F3F3,U+1F3F5-1F3F7,U+1F408,U+1F415,U+1F41F,U+1F426,U+1F43F,U+1F441-1F442,U+1F444,U+1F446-1F449,U+1F44C-1F44E,U+1F453,U+1F46A,U+1F47D,U+1F4A3,U+1F4B0,U+1F4B3,U+1F4B9,U+1F4BB,U+1F4BF,U+1F4C8-1F4CB,U+1F4D6,U+1F4DA,U+1F4DF,U+1F4E3-1F4E6,U+1F4EA-1F4ED,U+1F4F7,U+1F4F9-1F4FB,U+1F4FD-1F4FE,U+1F503,U+1F507-1F50B,U+1F50D,U+1F512-1F513,U+1F53E-1F54A,U+1F54F-1F5FA,U+1F610,U+1F650-1F67F,U+1F687,U+1F68D,U+1F691,U+1F694,U+1F698,U+1F6AD,U+1F6B2,U+1F6B9-1F6BA,U+1F6BC,U+1F6C6-1F6CF,U+1F6D3-1F6D7,U+1F6E0-1F6EA,U+1F6F0-1F6F3,U+1F6F7-1F6FC,U+1F700-1F7FF,U+1F800-1F80B,U+1F810-1F847,U+1F850-1F859,U+1F860-1F887,U+1F890-1F8AD,U+1F8B0-1F8BB,U+1F8C0-1F8C1,U+1F900-1F90B,U+1F93B,U+1F946,U+1F984,U+1F996,U+1F9E9,U+1FA00-1FA6F,U+1FA70-1FA7C,U+1FA80-1FA89,U+1FA8F-1FAC6,U+1FACE-1FADC,U+1FADF-1FAE9,U+1FAF0-1FAF8,U+1FB00-1FBFF;font-display:swap;}@font-face {font-family:'Roboto';font-style:normal;font-weight:700;src:url(/cf-fonts/v/roboto/5.2.10/greek/wght/normal.woff2);unicode-range:U+0370-0377,U+037A-037F,U+0384-038A,U+038C,U+038E-03A1,U+03A3-03FF;font-display:swap;}@font-face {font-family:'Roboto';font-style:normal;font-weight:700;src:url(/cf-fonts/v/roboto/5.2.10/greek-ext/wght/normal.woff2);unicode-range:U+1F00-1FFF;font-display:swap;}@font-face {font-family:'Roboto';font-style:normal;font-weight:700;src:url(/cf-fonts/v/roboto/5.2.10/latin/wght/normal.woff2);unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;font-display:swap;}@font-face {font-family:'Roboto';font-style:normal;font-weight:700;src:url(/cf-fonts/v/roboto/5.2.10/vietnamese/wght/normal.woff2);unicode-range:U+0102-0103,U+0110-0111,U+0128-0129,U+0168-0169,U+01A0-01A1,U+01AF-01B0,U+0300-0301,U+0303-0304,U+0308-0309,U+0323,U+0329,U+1EA0-1EF9,U+20AB;font-display:swap;}@font-face {font-family:'Roboto';font-style:normal;font-weight:700;src:url(/cf-fonts/v/roboto/5.2.10/cyrillic-ext/wght/normal.woff2);unicode-range:U+0460-052F,U+1C80-1C8A,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F;font-display:swap;}@font-face {font-family:'Roboto';font-style:normal;font-weight:700;src:url(/cf-fonts/v/roboto/5.2.10/math/wght/normal.woff2);unicode-range:U+0302-0303,U+0305,U+0307-0308,U+0310,U+0312,U+0315,U+031A,U+0326-0327,U+032C,U+032F-0330,U+0332-0333,U+0338,U+033A,U+0346,U+034D,U+0391-03A1,U+03A3-03A9,U+03B1-03C9,U+03D1,U+03D5-03D6,U+03F0-03F1,U+03F4-03F5,U+2016-2017,U+2034-2038,U+203C,U+2040,U+2043,U+2047,U+2050,U+2057,U+205F,U+2070-2071,U+2074-208E,U+2090-209C,U+20D0-20DC,U+20E1,U+20E5-20EF,U+2100-2112,U+2114-2115,U+2117-2121,U+2123-214F,U+2190,U+2192,U+2194-21AE,U+21B0-21E5,U+21F1-21F2,U+21F4-2211,U+2213-2214,U+2216-22FF,U+2308-230B,U+2310,U+2319,U+231C-2321,U+2336-237A,U+237C,U+2395,U+239B-23B7,U+23D0,U+23DC-23E1,U+2474-2475,U+25AF,U+25B3,U+25B7,U+25BD,U+25C1,U+25CA,U+25CC,U+25FB,U+266D-266F,U+27C0-27FF,U+2900-2AFF,U+2B0E-2B11,U+2B30-2B4C,U+2BFE,U+3030,U+FF5B,U+FF5D,U+1D400-1D7FF,U+1EE00-1EEFF;font-display:swap;}@font-face {font-family:'Roboto';font-style:normal;font-weight:700;src:url(/cf-fonts/v/roboto/5.2.10/cyrillic/wght/normal.woff2);unicode-range:U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116;font-display:swap;}</style>
<!-- Fabric.js Bengali Font Support -->
<link rel="stylesheet" href="/static/css/fabric-bengali-fonts.css?v=20260131z">
<link rel="stylesheet" href="/static/css/history-panel.css?v=20260215">
<!-- Premium Landing Hero Styles -->
<link rel="stylesheet" href="/static/css/landing-hero.css?v=20260626">
<style>
/* Tutorial Modal Styles */
.tutorial-modal { display: none; position: fixed; z-index: 99999; left: 0; top: 0; width: 100%; height: 100%; background-color: rgba(0,0,0,0.8); align-items: center; justify-content: center; opacity: 0; transition: opacity 0.3s ease; }
.tutorial-modal.show { display: flex; opacity: 1; }
.tutorial-content { background: #fff; padding: 20px; border-radius: 12px; width: 90%; max-width: 680px; position: relative; box-shadow: 0 4px 20px rgba(0,0,0,0.2); }
.tutorial-close { position: absolute; top: -15px; right: -15px; background: #ef4444; color: white; border: none; border-radius: 50%; width: 32px; height: 32px; font-size: 20px; cursor: pointer; display: flex; align-items: center; justify-content: center; box-shadow: 0 2px 5px rgba(0,0,0,0.2); z-index: 10; }
.tutorial-close:hover { background: #dc2626; }
.tutorial-video-container { position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden; border-radius: 8px; }
.tutorial-video-container iframe { position: absolute; top: 0; left: 0; width: 100%; height: 100%; }
.tutorial-btn-pulse {
background: linear-gradient(135deg, #fbbf24, #f59e0b) !important;
color: #1e3a8a !important;
margin-left: 10px;
border: none;
box-shadow: 0 0 0 0 rgba(251, 191, 36, 0.7);
animation: pulse-yellow 2s infinite;
}
@keyframes pulse-yellow {
0% { transform: scale(0.95); box-shadow: 0 0 0 0 rgba(251, 191, 36, 0.7); }
70% { transform: scale(1); box-shadow: 0 0 0 10px rgba(251, 191, 36, 0); }
100% { transform: scale(0.95); box-shadow: 0 0 0 0 rgba(251, 191, 36, 0); }
}
</style>
<!-- Microsoft Clarity Tracking Script -->
<script type="text/javascript">
(function(c,l,a,r,i,t,y){
c[a]=c[a]||function(){(c[a].q=c[a].q||[]).push(arguments)};
t=l.createElement(r);t.async=1;t.src="https://www.clarity.ms/tag/"+i;
y=l.getElementsByTagName(r)[0];y.parentNode.insertBefore(t,y);
})(window, document, "clarity", "script", "xm7ve8av4k");
</script>
<!-- Google AdSense -->
<meta name="google-adsense-account" content="ca-pub-9028963340093233">
<script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-9028963340093233" crossorigin="anonymous"></script>
<!-- Schema.org Structured Data for Bangla PDF Editor -->
<!-- Organization Schema -->
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "SoftwareApplication",
"name": "Bangla PDF Editor",
"alternateName": "বাংলা পিডিএফ এডিটর",
"applicationCategory": "BusinessApplication",
"operatingSystem": "Web Browser",
"offers": {
"@type": "Offer",
"price": "0",
"priceCurrency": "USD"
},
"aggregateRating": {
"@type": "AggregateRating",
"ratingValue": "4.8",
"ratingCount": "1250",
"bestRating": "5",
"worstRating": "1"
},
"url": "https://www.banglapdfeditor.com",
"description": "Free online Bangla PDF Editor with full Bengali Unicode support. Edit, merge, split, compress PDFs with 396+ Bengali fonts, OCR, watermark, and electronic signatures.",
"screenshot": "https://www.banglapdfeditor.com/static/images/screenshot.png",
"featureList": [
"Edit Bengali text in PDF",
"Merge PDF files",
"Split PDF files",
"Compress PDF",
"PDF to Word conversion",
"PDF to Excel conversion",
"Bengali OCR",
"Add watermark",
"Electronic signature",
"Password protect PDF",
"Organize PDF pages",
"PDF to Image conversion",
"Edit PDF metadata",
"396+ Bengali fonts",
"Bijoy to Unicode converter"
],
"inLanguage": ["bn", "en"],
"availableOnDevice": ["Desktop", "Mobile", "Tablet"],
"softwareRequirements": "Modern web browser with JavaScript enabled",
"provider": {
"@type": "Organization",
"name": "Bangla PDF Editor",
"url": "https://www.banglapdfeditor.com",
"logo": "https://www.banglapdfeditor.com/static/logo.png",
"sameAs": [
"https://www.facebook.com/banglapdfeditor",
"https://twitter.com/banglapdfeditor"
],
"contactPoint": {
"@type": "ContactPoint",
"contactType": "Customer Support",
"availableLanguage": ["Bengali", "English"],
"areaServed": "Worldwide"
}
}
}
</script>
<!-- WebSite Schema with Sitelinks Search Box -->
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "WebSite",
"name": "Bangla PDF Editor",
"url": "https://www.banglapdfeditor.com",
"potentialAction": {
"@type": "SearchAction",
"target": {
"@type": "EntryPoint",
"urlTemplate": "https://www.banglapdfeditor.com/search?q={search_term_string}"
},
"query-input": "required name=search_term_string"
},
"inLanguage": ["bn-BD", "en-US"],
"description": "Free online PDF editor with Bengali Unicode support for editing, merging, splitting, and converting PDFs."
}
</script>
<!-- BreadcrumbList Schema (for all pages) -->
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "BreadcrumbList",
"itemListElement": [
{
"@type": "ListItem",
"position": 1,
"name": "Home",
"item": "https://www.banglapdfeditor.com"
}
]
}
</script>
<!-- FAQ Schema (for FAQ page) -->
<script type="application/ld+json" id="faq-schema" style="display: none;">
{
"@context": "https://schema.org",
"@type": "FAQPage",
"mainEntity": [
{
"@type": "Question",
"name": "Is Bangla PDF Editor free to use?",
"acceptedAnswer": {
"@type": "Answer",
"text": "Yes, Bangla PDF Editor is completely free to use. All features including PDF editing, merging, splitting, compression, and Bengali text editing are available at no cost."
}
},
{
"@type": "Question",
"name": "Do I need to register to use Bangla PDF Editor?",
"acceptedAnswer": {
"@type": "Answer",
"text": "No registration is required. You can use all features immediately without creating an account."
}
},
{
"@type": "Question",
"name": "How many Bengali fonts are available?",
"acceptedAnswer": {
"@type": "Answer",
"text": "Bangla PDF Editor offers 396+ Bengali fonts including popular fonts like SolaimanLipi, Kalpurush, Nikosh, and many others."
}
},
{
"@type": "Question",
"name": "Is my PDF file secure?",
"acceptedAnswer": {
"@type": "Answer",
"text": "Yes, your files are completely secure. All files are automatically deleted from our servers after 1 hour. We use HTTPS encryption for all transfers."
}
},
{
"@type": "Question",
"name": "Can I use Bangla PDF Editor on mobile?",
"acceptedAnswer": {
"@type": "Answer",
"text": "Yes, Bangla PDF Editor is fully responsive and works on all devices including smartphones, tablets, and desktop computers."
}
},
{
"@type": "Question",
"name": "What is the maximum file size I can upload?",
"acceptedAnswer": {
"@type": "Answer",
"text": "There is no strict file size limit, but we recommend keeping files under 100MB for optimal performance."
}
},
{
"@type": "Question",
"name": "Can I convert Bijoy to Unicode?",
"acceptedAnswer": {
"@type": "Answer",
"text": "Yes, Bangla PDF Editor has a built-in Bijoy to Unicode converter that works seamlessly with all PDF editing features."
}
},
{
"@type": "Question",
"name": "Does it support Bengali OCR?",
"acceptedAnswer": {
"@type": "Answer",
"text": "Yes, we offer Bengali OCR (Optical Character Recognition) to extract text from scanned PDFs and images."
}
}
]
}
</script>
<!-- HowTo Schema (for tutorials) -->
<script type="application/ld+json" id="howto-schema" style="display: none;">
{
"@context": "https://schema.org",
"@type": "HowTo",
"name": "How to Edit Bengali Text in PDF",
"description": "Step-by-step guide to editing Bengali text in PDF files using Bangla PDF Editor",
"image": "https://www.banglapdfeditor.com/static/images/tutorial-edit-bengali.png",
"totalTime": "PT5M",
"estimatedCost": {
"@type": "MonetaryAmount",
"currency": "USD",
"value": "0"
},
"tool": [
{
"@type": "HowToTool",
"name": "Bangla PDF Editor"
},
{
"@type": "HowToTool",
"name": "PDF file"
}
],
"step": [
{
"@type": "HowToStep",
"position": 1,
"name": "Upload PDF",
"text": "Upload your PDF file by clicking 'Choose PDF' or dragging and dropping the file.",
"image": "https://www.banglapdfeditor.com/static/images/step1-upload.png"
},
{
"@type": "HowToStep",
"position": 2,
"name": "Select Bengali Font",
"text": "Choose from 396+ Bengali fonts available in the font selector.",
"image": "https://www.banglapdfeditor.com/static/images/step2-font.png"
},
{
"@type": "HowToStep",
"position": 3,
"name": "Edit Text",
"text": "Click on the PDF to add or edit Bengali text. Use the text tools to adjust size and position.",
"image": "https://www.banglapdfeditor.com/static/images/step3-edit.png"
},
{
"@type": "HowToStep",
"position": 4,
"name": "Download",
"text": "Click 'Download' to save your edited PDF file.",
"image": "https://www.banglapdfeditor.com/static/images/step4-download.png"
}
]
}
</script>
<!-- Service Schema for each tool -->
<script type="application/ld+json" id="service-schema" style="display: none;">
{
"@context": "https://schema.org",
"@type": "Service",
"serviceType": "PDF Editing Service",
"provider": {
"@type": "Organization",
"name": "Bangla PDF Editor"
},
"areaServed": {
"@type": "Country",
"name": "Worldwide"
},
"availableChannel": {
"@type": "ServiceChannel",
"serviceUrl": "https://www.banglapdfeditor.com",
"serviceType": "Online Service"
},
"offers": {
"@type": "Offer",
"price": "0",
"priceCurrency": "USD"
}
}
</script>
</head>
<body>
<!-- Google Tag Manager (noscript) -->
<noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-5GX8TKCX"
height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
<!-- End Google Tag Manager (noscript) -->
<!-- Skip to content for accessibility -->
<a href="#main-content" class="skip-to-content">Skip to main content</a>
<!-- Hidden H1 for SEO - Visually hidden but accessible to search engines -->
<h1 style="position: absolute; left: -10000px; width: 1px; height: 1px; overflow: hidden;">বাংলা পিডিএফ এডিটর | Free
Online Bangla PDF Editor with Bengali Unicode Support</h1>
<!-- Mobile Hamburger Menu - DISABLED FOR PC ONLY -->
<!-- <button class="hamburger-menu" id="hamburger-menu" aria-label="Toggle menu">
<span></span>
<span></span>
<span></span>
</button> -->
<!-- Mobile Menu Overlay - DISABLED FOR PC ONLY -->
<!-- <div class="mobile-menu-overlay" id="mobile-menu-overlay"></div> -->
<!-- Mobile Menu Drawer - DISABLED FOR PC ONLY -->
<!-- <nav class="mobile-menu" id="mobile-menu" aria-label="Mobile navigation">
<div class="mobile-menu-header">
<img src="/static/logo.png" alt="Bangla PDF Editor - Free Online PDF Editor" class="mobile-menu-logo">
<h2>Bangla PDF Editor</h2>
<p>Bangla PDF Editor</p>
</div>
<div class="mobile-menu-content">
<div class="mobile-menu-section">
<h3>Learn & Explore</h3>
<div class="mobile-menu-item" onclick="window.location.href='/tutorials'">
<span class="icon">📚</span>
<span>Tutorials</span>
</div>
<div class="mobile-menu-item" onclick="window.location.href='/blog'">
<span class="icon">📝</span>
<span>Blog</span>
</div>
<div class="mobile-menu-item" onclick="window.location.href='/faq'">
<span class="icon">❓</span>
<span>FAQ</span>
</div>
</div>
<div class="mobile-menu-section">
<h3>File Operations</h3>
<div class="mobile-menu-item" onclick="document.getElementById('pdfUpload').click()">
<span class="icon">📂</span>
<span>Open PDF</span>
</div>
<div class="mobile-menu-item" onclick="closePDF()">
<span class="icon">❌</span>
<span>Close PDF</span>
</div>
<div class="mobile-menu-item" onclick="saveBtn.click()">
<span class="icon">💾</span>
<span>Save PDF</span>
</div>
<div class="mobile-menu-item" onclick="downloadBtn.click()">
<span class="icon">⬇️</span>
<span>Download PDF</span>
</div>
</div>
<div class="mobile-menu-section">
<h3>Edit Tools</h3>
<div class="mobile-menu-item" onclick="selectTool('text')">
<span class="icon">✏️</span>
<span>Edit Text</span>
</div>
<div class="mobile-menu-item" onclick="selectTool('add-text')">
<span class="icon">➕</span>
<span>Add Text</span>
</div>
<div class="mobile-menu-item" onclick="selectTool('erase')">
<span class="icon">🧹</span>
<span>Erase</span>
</div>
<div class="mobile-menu-item" onclick="selectTool('ocr')">
<span class="icon">🔍</span>
<span>OCR Detection</span>
</div>
</div>
<div class="mobile-menu-section">
<h3>View</h3>
<div class="mobile-menu-item" onclick="zoomIn()">
<span class="icon">🔍+</span>
<span>Zoom In</span>
</div>
<div class="mobile-menu-item" onclick="zoomOut()">
<span class="icon">🔍-</span>
<span>Zoom Out</span>
</div>
<div class="mobile-menu-item" onclick="resetZoom()">
<span class="icon">↺</span>
<span>Reset Zoom</span>
</div>
</div>
<div class="mobile-menu-section">
<h3>Navigation</h3>
<div class="mobile-menu-item" onclick="prevPage()">
<span class="icon">⬅️</span>
<span>Previous Page</span>
</div>
<div class="mobile-menu-item" onclick="nextPage()">
<span class="icon">➡️</span>
<span>Next Page</span>
</div>
</div>
<div class="mobile-menu-section">
<h3>Settings</h3>
<div class="mobile-menu-item" onclick="DarkMode.toggle(); closeMobileMenu();">
<span class="icon" id="mobile-theme-icon">🌙</span>
<span id="mobile-theme-text">Dark Mode</span>
</div>
</div>
<div class="mobile-menu-section">
<h3>Help & Support</h3>
<div class="mobile-menu-item" onclick="openFeedbackModal()">
<span class="icon">💬</span>
<span>Feedback</span>
</div>
</div>
<div class="mobile-menu-section">
<h3>Legal</h3>
<div class="mobile-menu-item" onclick="window.open('/privacy-policy', '_blank')">
<span class="icon">🔒</span>
<span>Privacy Policy</span>
</div>
<div class="mobile-menu-item" onclick="window.open('/terms-of-service', '_blank')">
<span class="icon">📜</span>
<span>Terms of Service</span>
</div>
</div>
</div>
</nav> -->
<!-- Ribbon-Style Menu -->
<div class="ribbon-container">
<!-- Ribbon Tabs Row -->
<div class="ribbon-tabs">
<!-- Brand Logo -->
<div class="ribbon-brand">
<img src="/static/logo.png" alt="Bangla PDF Editor" class="ribbon-brand-logo" onerror="this.style.display='none'">
<span class="ribbon-brand-name">BanglaPDF</span>
</div>
<!-- Ribbon Tabs -->
<button class="ribbon-tab active" data-tab="files">Files</button>
<button class="ribbon-tab" data-tab="edit">Edit</button>
<button class="ribbon-tab" data-tab="help">Help</button>
<button id="open-tutorial-btn" class="modern-badge tutorial-btn-pulse" style="border:none;">🎬 টিউটোরিয়াল</button>
<!-- Credit / Auth Widget -->
<!-- Credit / Auth Widget CSS -->
<style>
.user-info-toolbar {
margin-left: auto;
display: flex;
align-items: center;
gap: 12px;
padding: 6px 16px;
background: rgba(30, 41, 59, 0.4);
backdrop-filter: blur(10px);
-webkit-backdrop-filter: blur(10px);
border: 1px solid rgba(255, 255, 255, 0.08);
border-radius: 12px;
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
transition: all 0.3s ease;
}
.user-info-toolbar:hover {
background: rgba(30, 41, 59, 0.6);
border-color: rgba(255, 255, 255, 0.12);
}
.modern-badge {
display: flex;
align-items: center;
gap: 6px;
background: linear-gradient(135deg, rgba(108, 59, 236, 0.15), rgba(155, 93, 229, 0.15));
border: 1px solid rgba(155, 93, 229, 0.3);
color: #d8b4fe;
padding: 6px 14px;
border-radius: 20px;
font-size: 13px;
font-weight: 600;
cursor: pointer;
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
box-shadow: 0 2px 10px rgba(108, 59, 236, 0.1);
}
.modern-badge:hover {
background: linear-gradient(135deg, rgba(108, 59, 236, 0.25), rgba(155, 93, 229, 0.25));
border-color: rgba(155, 93, 229, 0.6);
transform: translateY(-1px);
box-shadow: 0 4px 12px rgba(108, 59, 236, 0.2);
}
.modern-btn {
padding: 6px 16px;
border-radius: 8px;
font-size: 13px;
font-weight: 600;
cursor: pointer;
transition: all 0.2s ease;
border: none;
outline: none;
display: inline-flex;
align-items: center;
justify-content: center;
gap: 6px;
}
.modern-btn-outline {
background: rgba(255, 255, 255, 0.05);
color: #f8fafc;
border: 1px solid rgba(255, 255, 255, 0.1);
}
.modern-btn-outline:hover {
background: rgba(255, 255, 255, 0.1);
border-color: rgba(255, 255, 255, 0.2);
transform: translateY(-1px);
}
.modern-btn-primary {
background: linear-gradient(135deg, #6c3bec, #9b5de5);
color: white;
box-shadow: 0 2px 8px rgba(108, 59, 236, 0.4);
}
.modern-btn-primary:hover {
background: linear-gradient(135deg, #7c4bfa, #a66cf0);
transform: translateY(-1px);
box-shadow: 0 4px 12px rgba(108, 59, 236, 0.5);
}
.modern-btn-danger {
background: rgba(239, 68, 68, 0.1);
color: #fca5a5;
border: 1px solid rgba(239, 68, 68, 0.2);
padding: 6px 10px;
}
.modern-btn-danger:hover {
background: rgba(239, 68, 68, 0.2);
border-color: rgba(239, 68, 68, 0.4);
transform: translateY(-1px);
}
.modern-user-profile {
display: flex;
align-items: center;
gap: 8px;
padding: 4px 12px 4px 6px;
background: rgba(255, 255, 255, 0.05);
border: 1px solid rgba(255, 255, 255, 0.1);
border-radius: 20px;
color: #e2e8f0;
font-weight: 600;
font-size: 13px;
cursor: pointer;
transition: all 0.2s ease;
}
.modern-user-profile:hover {
background: rgba(255, 255, 255, 0.1);
border-color: rgba(255, 255, 255, 0.2);
transform: translateY(-1px);
}
.modern-user-avatar {
width: 24px;
height: 24px;
border-radius: 50%;
background: linear-gradient(135deg, #475569, #334155);
display: flex;
align-items: center;
justify-content: center;
font-size: 12px;
color: #fff;
}
</style>
<!-- Credit / Auth Widget -->
<!-- Credit / Auth Widget CSS -->
<style>
.user-info-toolbar {
margin-left: auto;
display: flex;
align-items: center;
gap: 12px;
padding: 6px 16px;
background: rgba(30, 41, 59, 0.4);
backdrop-filter: blur(10px);
-webkit-backdrop-filter: blur(10px);
border: 1px solid rgba(255, 255, 255, 0.08);
border-radius: 12px;
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
transition: all 0.3s ease;
}
.user-info-toolbar:hover {
background: rgba(30, 41, 59, 0.6);
border-color: rgba(255, 255, 255, 0.12);
}
.modern-badge {
display: flex;
align-items: center;
gap: 6px;
background: linear-gradient(135deg, rgba(108, 59, 236, 0.15), rgba(155, 93, 229, 0.15));
border: 1px solid rgba(155, 93, 229, 0.3);
color: #d8b4fe;
padding: 6px 14px;
border-radius: 20px;
font-size: 13px;
font-weight: 600;
cursor: pointer;
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
box-shadow: 0 2px 10px rgba(108, 59, 236, 0.1);
}
.modern-badge:hover {
background: linear-gradient(135deg, rgba(108, 59, 236, 0.25), rgba(155, 93, 229, 0.25));
border-color: rgba(155, 93, 229, 0.6);
transform: translateY(-1px);
box-shadow: 0 4px 12px rgba(108, 59, 236, 0.2);
}
.modern-btn {
padding: 6px 16px;
border-radius: 8px;
font-size: 13px;
font-weight: 600;
cursor: pointer;
transition: all 0.2s ease;
border: none;
outline: none;
display: inline-flex;
align-items: center;
justify-content: center;
gap: 6px;
}
.modern-btn-outline {
background: rgba(255, 255, 255, 0.05);
color: #f8fafc;
border: 1px solid rgba(255, 255, 255, 0.1);
}
.modern-btn-outline:hover {
background: rgba(255, 255, 255, 0.1);
border-color: rgba(255, 255, 255, 0.2);
transform: translateY(-1px);
}
.modern-btn-primary {
background: linear-gradient(135deg, #6c3bec, #9b5de5);
color: white;
box-shadow: 0 2px 8px rgba(108, 59, 236, 0.4);
}
.modern-btn-primary:hover {
background: linear-gradient(135deg, #7c4bfa, #a66cf0);
transform: translateY(-1px);
box-shadow: 0 4px 12px rgba(108, 59, 236, 0.5);
}
.modern-btn-danger {
background: rgba(239, 68, 68, 0.1);
color: #fca5a5;
border: 1px solid rgba(239, 68, 68, 0.2);
padding: 6px 10px;
}
.modern-btn-danger:hover {
background: rgba(239, 68, 68, 0.2);
border-color: rgba(239, 68, 68, 0.4);
transform: translateY(-1px);
}
.modern-user-profile {
display: flex;
align-items: center;
gap: 8px;
padding: 4px 12px 4px 6px;
background: rgba(255, 255, 255, 0.05);
border: 1px solid rgba(255, 255, 255, 0.1);
border-radius: 20px;
color: #e2e8f0;
font-weight: 600;
font-size: 13px;
cursor: pointer;
transition: all 0.2s ease;
}
.modern-user-profile:hover {
background: rgba(255, 255, 255, 0.1);
border-color: rgba(255, 255, 255, 0.2);
transform: translateY(-1px);
}
.modern-user-avatar {
width: 24px;
height: 24px;
border-radius: 50%;
background: linear-gradient(135deg, #475569, #334155);
display: flex;
align-items: center;
justify-content: center;
font-size: 12px;
color: #fff;
}
</style>
<!-- Credit / Auth Widget -->
<div id="credit-widget" class="user-info-toolbar">
<div id="credit-display" class="modern-badge" style="display:none;" onclick="openPaymentModal()" title="Get more credits">
<span style="font-size: 14px;">⚡</span>
<span><span id="credit-count">0</span> Credits</span>
</div>
<button id="auth-login-btn" class="modern-btn modern-btn-outline" onclick="openAuthModal('login')">
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M15 3h4a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2h-4"></path><polyline points="10 17 15 12 10 7"></polyline><line x1="15" y1="12" x2="3" y2="12"></line></svg>
Log In
</button>
<button id="auth-register-btn" class="modern-btn modern-btn-primary" onclick="openPaymentModal()">
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M16 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"></path><circle cx="8.5" cy="7" r="4"></circle><line x1="20" y1="8" x2="20" y2="14"></line><line x1="23" y1="11" x2="17" y2="11"></line></svg>
Sign Up
</button>
<div id="auth-user-name" class="modern-user-profile" style="display:none;" onclick="openDocsPanel()">
</div>
<button id="auth-logout-btn" class="modern-btn modern-btn-danger" style="display:none;" onclick="logoutUser()" title="Log out">
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4"></path><polyline points="16 17 21 12 16 7"></polyline><line x1="21" y1="12" x2="9" y2="12"></line></svg>
</button>
</div>
<!-- Always Visible Compact Groups -->
<div class="ribbon-compact-groups">
<div class="ribbon-compact-group">
<button class="ribbon-btn-enhanced" onclick="addTextBtn.click()" title="Add Text">
<span class="btn-label">Add Text</span>
<span class="btn-icon">➕</span>
</button>
<button class="ribbon-btn-enhanced" id="eraserToolBtn" onclick="toggleEraserTool()"
title="Eraser Tool">
<span class="btn-label">Eraser</span>
<span class="btn-icon">🧹</span>
</button>
<button class="ribbon-btn-enhanced" id="detectionModeBtn" onclick="toggleDetectionMode()"
title="Toggle between Line and Word detection">
<span class="btn-label" id="detectionModeLabel">Line Mode</span>
<span class="btn-icon">📄</span>
</button>
</div>
<div class="ribbon-compact-group">
<button class="ribbon-btn-enhanced" onclick="prevPageBtn.click()" title="Previous Page">
<span class="btn-label">Previous</span>
<span class="btn-icon">⬅️</span>
</button>
<div class="page-counter-display" id="pageCounterDisplay">
<span class="counter-label">Page</span>
<span class="counter-value" id="currentPageNum">1</span>
<span class="counter-total">of <span id="totalPagesNum">1</span></span>
</div>
<button class="ribbon-btn-enhanced" onclick="nextPageBtn.click()" title="Next Page">
<span class="btn-label">Next</span>
<span class="btn-icon">➡️</span>
</button>
<span style="color:#ccc;padding:0 2px;align-self:center;">|</span>
<button class="ribbon-btn-enhanced" onclick="zoomOutBtn.click()" title="Zoom Out">
<span class="btn-label">Zoom−</span>
<span class="btn-icon">🔍−</span>
</button>
<span id="zoomLevel"
style="font-size:11px;padding:0 2px;align-self:center;min-width:36px;text-align:center;">100%</span>
<button class="ribbon-btn-enhanced" onclick="zoomInBtn.click()" title="Zoom In">
<span class="btn-label">Zoom+</span>
<span class="btn-icon">🔍+</span>
</button>
<span style="color:#ccc;padding:0 2px;align-self:center;">|</span>
<button class="ribbon-btn-enhanced" onclick="printPreviewBtn.click()" title="Print">
<span class="btn-label">Print</span>
<span class="btn-icon">🖨️</span>
</button>
</div>
</div>
</div>
<!-- Files Tab Content -->
<div id="ribbon-files" class="ribbon-content active">
<div class="ribbon-group">
<div class="ribbon-buttons">
<button class="ribbon-btn" onclick="document.getElementById('pdfUpload').click()">
<span class="icon">📂</span>
<span class="label">Open</span>
</button>
<button id="ribbonCloseBtn" class="ribbon-btn" onclick="closePDF()" disabled>
<span class="icon">❌</span>
<span class="label">Close</span>
</button>
<button id="ribbonSaveBtn" class="ribbon-btn" onclick="saveBtn.click()" disabled>
<span class="icon">💾</span>
<span class="label">Save</span>
</button>
<button id="ribbonDownloadBtn" class="ribbon-btn" onclick="downloadBtn.click()" disabled>
<span class="icon">💾⬇️</span>
<span class="label">Download</span>
</button>
</div>
<div class="ribbon-group-label">File Operations</div>
</div>
<div class="ribbon-group">
<div class="ribbon-buttons">
<button class="ribbon-btn" onclick="mergeBtn.click()">
<span class="icon">🔗</span>
<span class="label">Merge</span>
</button>
<button class="ribbon-btn" onclick="splitBtn.click()">
<span class="icon">✂️</span>
<span class="label">Split</span>
</button>
<button class="ribbon-btn" onclick="compressBtn.click()">
<span class="icon">🗜️</span>
<span class="label">Compress</span>
</button>
<button class="ribbon-btn" onclick="shareBtn.click()">
<span class="icon">🔗</span>
<span class="label">Share</span>
</button>
<!-- AI Summary button removed -->
</div>
<div class="ribbon-group-label">Document Tools</div>
</div>
</div>
<!-- Edit Tab Content -->
<div id="ribbon-edit" class="ribbon-content">
<div class="ribbon-group">
<div class="ribbon-buttons">
<!-- Undo/Redo buttons removed -->
</div>
<div class="ribbon-group-label">History</div>
</div>
<div class="ribbon-group">
<div class="ribbon-buttons">
<button id="ribbonAddPageBtn" class="ribbon-btn"
onclick="event.stopPropagation();document.getElementById('addPageModal').style.display='flex';">
<span class="icon">➕📄</span>
<span class="label">Add Page</span>
</button>
<button id="ribbonDeletePageBtn" class="ribbon-btn"
onclick="if(window.handleDeletePage)handleDeletePage();">
<span class="icon">🗑️📄</span>
<span class="label">Delete Page</span>
</button>
<button id="ribbonRotatePageBtn" class="ribbon-btn" onclick="handleRotatePage()" disabled>
<span class="icon">🔄</span>
<span class="label">Rotate</span>
</button>
</div>
<div class="ribbon-group-label">Pages</div>
</div>
<div class="ribbon-group">
<div class="ribbon-buttons">
<button id="ocrBtn" class="ribbon-btn" onclick="runOCR()" disabled>
<span class="icon">🔍</span>
<span class="label">Run OCR</span>
</button>
</div>
<div class="ribbon-group-label">OCR</div>
</div>
</div>
<!-- Help Tab Content -->
<div id="ribbon-help" class="ribbon-content">
<div class="ribbon-group">
<div class="ribbon-buttons">
<button class="ribbon-btn" onclick="window.open('/tutorials', '_blank')">
<span class="icon">📚</span>
<span class="label">Tutorials</span>
</button>
<button class="ribbon-btn" onclick="window.open('/blog', '_blank')">
<span class="icon">📝</span>
<span class="label">Blog</span>
</button>
<button class="ribbon-btn" onclick="window.open('/documentation', '_blank')">
<span class="icon">❓</span>
<span class="label">Help</span>
</button>
<button class="ribbon-btn" onclick="DarkMode.toggle()">
<span class="icon" id="darkModeIcon">🌙</span>
<span class="label">Dark Mode</span>
</button>
</div>
<div class="ribbon-group-label">Help & Settings</div>
</div>
</div>
</div>
<div id="app">
<!-- Main Content -->
<div class="main-container">
<!-- Left Panel - Page Thumbnails -->
<aside class="left-panel">
<h3>Page Thumbnails</h3>
<div id="thumbnailContainer" class="thumbnail-container">
<!-- Thumbnails will be added here dynamically -->
</div>
</aside>
<!-- Sidebar -->
<aside class="sidebar">
<div class="sidebar-section">
<h3>📁 File</h3>
<label for="pdfUpload" class="btn btn-primary full-width">
📤 Upload PDF
<input type="file" id="pdfUpload" accept=".pdf" hidden>
</label>
<button id="saveBtn" class="btn btn-success full-width" disabled>
💾 Save
</button>
<button id="downloadBtn" class="btn btn-info full-width" disabled>
⬇️ Download
</button>
</div>
<div class="sidebar-section">
<h3>✏️ Text Edit</h3>
<!-- Detection Mode Toggle -->
<div class="detection-mode-group"
style="margin-bottom: 15px; padding: 10px; background: #f8f9fa; border-radius: 4px; border: 1px solid #dee2e6;">
<label
style="display: block; font-size: 13px; margin-bottom: 8px; font-weight: 600; color: #495057;">
🔍 Text Detection Mode:
</label>
<select id="detectionModeSelect" onchange="switchDetectionMode()"
style="width: 100%; padding: 8px 12px; border: 1px solid #ced4da; border-radius: 4px; font-size: 14px; background: white; cursor: pointer;">
<option value="line" selected>📄 Line-by-Line (Clean PDFs)</option>
<option value="word">📝 Word-by-Word (Scanned PDFs)</option>
</select>
<small style="display: block; margin-top: 5px; color: #6c757d; font-size: 11px;">
Switch mode if text boxes are incorrect
</small>
</div>
<button id="addTextBtn" class="btn full-width" disabled>
➕ Add Text
</button>
<button id="deleteTextBtn" class="btn full-width" disabled>
🗑️ Delete Text
</button>
</div>
<div class="sidebar-section">
<h3>🎨 Annotation</h3>
<button id="signatureBtn" class="btn full-width" disabled>
✒️ স্বাক্ষর | Signature
</button>
<!-- Draw tools moved to top ribbon Draw tab -->
</div>
<div class="sidebar-section">
<h3>📄 Pages</h3>
<button id="addPageBtn" class="btn full-width"
onclick="event.stopPropagation();document.getElementById('addPageModal').style.display='flex';">
➕ পেজ যোগ করুন | Add Page
</button>
<button id="deletePageBtn" class="btn full-width"
onclick="if(window.handleDeletePage)handleDeletePage();">
🗑️ পেজ মুছুন | Delete Page
</button>
<button id="rotatePageBtn" class="btn full-width" disabled>
🔄 পেজ ঘুরান | Rotate Page
</button>
</div>
<div class="sidebar-section">
<h3>🎨 Fonts</h3>
<!-- System Fonts -->
<label style="font-size: 0.9rem; margin-bottom: 0.3rem; display: block;">System Font
Fonts:</label>
<select id="systemFontSelect" class="full-width" style="margin-bottom: 0.8rem;">
<option value="">-- Select System Font --</option>
</select>
<!-- Uploaded Fonts -->
<label style="font-size: 0.9rem; margin-bottom: 0.3rem; display: block;">My Font
Fonts:</label>
<select id="uploadedFontSelect" class="full-width" style="margin-bottom: 0.5rem;">
<option value="">-- No Uploaded Fonts --</option>
</select>
<!-- Upload Font Button -->
<button id="uploadFontBtn" class="btn full-width" style="margin-bottom: 0.5rem;">
📤 ফন্ট আপলোড করুন | Upload Font
</button>
<input type="file" id="fontFileInput" accept=".ttf,.otf" style="display: none;">
<!-- Delete Font Button -->
<button id="deleteFontBtn" class="btn full-width" disabled style="background-color: #dc3545;">
🗑️ ফন্ট মুছুন | Delete Font
</button>
<small style="display: block; margin-top: 0.5rem; color: #6c757d; font-size: 0.75rem;">
⚠️ Only Unicode Bengali fonts supported
</small>
</div>
<div class="sidebar-section">
<h3>🔧 Document</h3>
<button id="mergeBtn" class="btn full-width" disabled>
🔗 মার্জ করুন | Merge
</button>
<button id="splitBtn" class="btn full-width" disabled>
✂️ স্প্লিট করুন | Split
</button>
<button id="compressBtn" class="btn full-width" disabled>
🗜️ কম্প্রেস করুন | Compress
</button>
<button id="shareBtn" class="btn full-width" disabled>
🔗 শেয়ার করুন | Share
</button>
<!-- Images to PDF button removed as requested -->
<!-- AI Summary button removed -->
</div>
</aside>
<!-- Main Workspace -->
<main class="workspace">
<!-- Hidden actual buttons (needed for JS event listeners) -->
<div style="display:none;">
<button id="prevPageBtn" title="Previous Page">◀</button>
<span id="pageInfo">Page 0 / 0</span>
<button id="nextPageBtn" title="Next Page">▶</button>
<button id="zoomOutBtn" title="Zoom Out">−</button>
<button id="zoomInBtn" title="Zoom In">+</button>
<button id="printPreviewBtn" title="Print Preview">🖨️</button>
</div>
<div class="canvas-container">
<div id="loadingMessage" class="message">
<!-- ═══════════ PREMIUM HERO SECTION ═══════════ -->
<canvas id="heroParticles"></canvas>
<!-- Floating background orbs -->
<div class="hero-orb hero-orb-1"></div>
<div class="hero-orb hero-orb-2"></div>
<div class="hero-orb hero-orb-3"></div>
<div id="welcome-upload-zone">
<div class="hero-inner">
<!-- Badge -->
<div class="hero-badge">
<span class="badge-dot"></span>
বাংলাদেশের #১ পিডিএফ এডিটর · Free to Use
</div>
<!-- Headline -->
<h2 class="hero-headline">
<span class="white-text">Edit PDFs in </span><span class="grad-text">Pure Bangla</span>
</h2>
<p class="hero-bn-sub">বাংলা পিডিএফ এডিটর</p>
<!-- Description -->
<p class="hero-desc">
Professional PDF editing with full Bengali Unicode support — 396+ fonts, OCR, merge, split, compress, watermark & e-signature. All in your browser, no install needed.
</p>
<!-- Upload CTA -->
<div class="hero-upload-cta">
<div class="pulse-ring"></div>
<div class="pulse-ring"></div>
<button class="upload-btn-premium" onclick="document.getElementById('pdfUpload').click()" id="hero-upload-btn">
<span class="btn-icon">📤</span>
<span>PDF আপলোড করুন</span>
</button>
</div>
<p class="hero-drag-hint">or drag & drop your PDF here · Max 50 MB</p>
<!-- Stats Row -->
<div class="hero-stats">
<div class="hero-stat">
<span class="stat-num">396+</span>
<span class="stat-label">Bangla Fonts</span>
</div>
<div class="hero-stat-divider"></div>
<div class="hero-stat">
<span class="stat-num">50MB</span>
<span class="stat-label">Max File Size</span>
</div>
<div class="hero-stat-divider"></div>
<div class="hero-stat">
<span class="stat-num">4.8★</span>
<span class="stat-label">User Rating</span>
</div>
<div class="hero-stat-divider"></div>
<div class="hero-stat">
<span class="stat-num">100%</span>
<span class="stat-label">Free</span>
</div>
</div>
<!-- Features Grid -->
<div class="hero-features-grid">
<div class="feat-card"><span class="feat-icon">✏️</span><span class="feat-label">Bengali Text Editing</span></div>
<div class="feat-card"><span class="feat-icon">🔍</span><span class="feat-label">OCR বাংলা স্ক্যান</span></div>
<div class="feat-card"><span class="feat-icon">🔗</span><span class="feat-label">Merge PDFs</span></div>
<div class="feat-card"><span class="feat-icon">✂️</span><span class="feat-label">Split PDF Pages</span></div>
<div class="feat-card"><span class="feat-icon">🗜️</span><span class="feat-label">Compress PDF</span></div>
<div class="feat-card"><span class="feat-icon">💧</span><span class="feat-label">Add Watermark</span></div>
<div class="feat-card"><span class="feat-icon">✒️</span><span class="feat-label">E-Signature</span></div>
<div class="feat-card"><span class="feat-icon">📝</span><span class="feat-label">PDF to Word</span></div>
</div>
<!-- Trust Badges -->
<div class="hero-trust">
<span class="trust-badge"><span class="tb-icon">🔒</span> Secure & Private</span>
<span class="trust-badge"><span class="tb-icon">⚡</span> No Registration Needed</span>
<span class="trust-badge"><span class="tb-icon">🌐</span> Works in Browser</span>
<span class="trust-badge"><span class="tb-icon">🇧🇩</span> Made for Bangladesh</span>
</div>
</div>
</div>
</div>
<div class="canvas-wrapper" id="canvasWrapper">
<canvas id="pdfCanvas"></canvas>
<div id="textOverlay"></div>
<!-- Canvas overlay for drawing and text -->
<div id="canvas-wrapper" style="position: absolute; top: 0; left: 0; pointer-events: none; z-index: 10;">
<canvas id="fabricCanvas"></canvas>
</div>
</div>
</div>
<!-- Text Edit Panel - REMOVED -->
<!-- Modal removed as per user request -->
<!-- Sejda-Style Floating Toolbar (2 Rows) -->
<div id="floatingToolbar" class="sejda-toolbar sejda-toolbar-2rows" style="display: none;">
<!-- Row 1: Text, Font, Size, Color, Styles -->
<div class="sejda-toolbar-row">
<!-- Text Edit Input (inline) -->
<input type="text" id="floatingTextArea" class="sejda-text-input" placeholder="Edit text..."
title="Edit text content">
<!-- Divider -->
<div class="sejda-divider"></div>
<!-- Font Selection -->
<select id="floatingSystemFontSelect" class="sejda-select" title="System Fonts"
style="min-width: 130px;">
<option value="">System Fonts</option>
</select>
<!-- Uploaded Fonts -->
<select id="floatingUploadedFontSelect" class="sejda-select" title="My Fonts"
style="min-width: 110px;">
<option value="">My Fonts</option>
</select>
<!-- Upload Font -->
<button class="sejda-btn-icon" onclick="document.getElementById('fontFileInput').click()"
title="Upload Font">📤</button>
<!-- Delete Font -->
<button class="sejda-btn-icon" id="floatingDeleteFontBtn" onclick="handleToolbarFontDelete()"
title="Delete Font" disabled>🗑️</button>
<!-- Font Size -->
<div class="sejda-size-group">
<button class="sejda-btn-icon" onclick="adjustFloatingFontSize(-1)"
title="Decrease size">−</button>
<input type="number" id="floatingFontSize" value="12" min="6" max="72"
class="sejda-input-size">
<button class="sejda-btn-icon" onclick="adjustFloatingFontSize(1)"
title="Increase size">+</button>
</div>
<!-- Divider -->
<div class="sejda-divider"></div>
<!-- Text Color -->
<input type="color" id="floatingTextColor" value="#000000" class="sejda-color-picker"
title="Text color">
<!-- Divider -->
<div class="sejda-divider"></div>
<!-- Style Buttons -->
<button class="sejda-style-btn" id="floatingBoldBtn" title="Bold"><b>B</b></button>
<button class="sejda-style-btn" id="floatingItalicBtn" title="Italic"><i>I</i></button>
<button class="sejda-style-btn" id="floatingUnderlineBtn" title="Underline"><u>U</u></button>
</div>
<!-- Row 2: Position, Size, Action Buttons -->
<div class="sejda-toolbar-row">
<!-- Positioning Controls (Y & X) -->
<div class="sejda-positioning-inline">
<div class="sejda-pos-control">
<span class="sejda-pos-label">Y:</span>
<button class="sejda-pos-btn-inline" onclick="adjustFloatingPosition('y', -1)"
title="Move up">↑</button>
<span class="sejda-pos-display" id="floatingYDisplay">0</span>
<button class="sejda-pos-btn-inline" onclick="adjustFloatingPosition('y', 1)"
title="Move down">↓</button>
</div>
<div class="sejda-pos-control">
<span class="sejda-pos-label">X:</span>
<button class="sejda-pos-btn-inline" onclick="adjustFloatingPosition('x', -1)"
title="Move left">←</button>
<span class="sejda-pos-display" id="floatingXDisplay">0</span>
<button class="sejda-pos-btn-inline" onclick="adjustFloatingPosition('x', 1)"
title="Move right">→</button>
</div>
</div>
<!-- Divider -->
<div class="sejda-divider"></div>
<!-- Size Controls (Width & Height) -->
<div class="sejda-positioning-inline">
<div class="sejda-pos-control">
<span class="sejda-pos-label">W:</span>
<button class="sejda-pos-btn-inline" onclick="adjustFloatingPosition('width', -5)"
title="Decrease width">←</button>
<span class="sejda-pos-display" id="floatingWidthDisplay">0</span>
<button class="sejda-pos-btn-inline" onclick="adjustFloatingPosition('width', 5)"
title="Increase width">→</button>
</div>
<div class="sejda-pos-control">
<span class="sejda-pos-label">H:</span>
<button class="sejda-pos-btn-inline" onclick="adjustFloatingPosition('height', -2)"
title="Decrease height">↓</button>
<span class="sejda-pos-display" id="floatingHeightDisplay">0</span>
<button class="sejda-pos-btn-inline" onclick="adjustFloatingPosition('height', 2)"
title="Increase height">↑</button>
</div>
</div>
<!-- Divider -->
<div class="sejda-divider"></div>
<!-- Action Buttons -->
<button id="floatingApplyBtn" class="sejda-btn-success" title="Apply changes">✓</button>
<button id="floatingCancelBtn" class="sejda-btn-cancel" title="Cancel"
onclick="closeFloatingToolbar()">✕</button>
</div>
<!-- Hidden inputs for all adjustment values -->
<input type="hidden" id="floatingYInput" value="0">
<input type="hidden" id="floatingXInput" value="0">
<input type="hidden" id="floatingWidthInput" value="0">
<input type="hidden" id="floatingHeightInput" value="0">
<input type="hidden" id="floatingLineHeightInput" value="1.8">
<input type="hidden" id="floatingLetterSpacingInput" value="0">
</div>
<!-- New Text Bar (Clone of Sejda Toolbar for New Text Boxes) -->
<div id="newTextBar" class="sejda-toolbar sejda-toolbar-2rows" style="display: none;">
<!-- Row 1: Text, Font, Size, Color, Styles -->
<div class="sejda-toolbar-row">
<!-- Text Edit Input (inline) -->
<input type="text" id="newTextInput" class="sejda-text-input" placeholder="Type your text..."
title="Enter text content">
<!-- Divider -->
<div class="sejda-divider"></div>
<!-- Font Selection -->
<select id="newTextSystemFontSelect" class="sejda-select" title="System Fonts"
style="min-width: 130px;">
<option value="">System Fonts</option>
</select>
<!-- Uploaded Fonts -->
<select id="newTextUploadedFontSelect" class="sejda-select" title="My Fonts"
style="min-width: 110px;">
<option value="">My Fonts</option>
</select>
<!-- Upload Font -->
<button class="sejda-btn-icon" onclick="document.getElementById('fontFileInput').click()"
title="Upload Font">📤</button>
<!-- Delete Font -->
<button class="sejda-btn-icon" id="newTextDeleteFontBtn" onclick="handleNewTextFontDelete()"
title="Delete Font" disabled>🗑️</button>
<!-- Font Size -->
<div class="sejda-size-group">
<button class="sejda-btn-icon" onclick="adjustNewTextFontSize(-1)"
title="Decrease size">−</button>
<input type="number" id="newTextFontSize" value="16" min="6" max="72"
class="sejda-input-size">
<button class="sejda-btn-icon" onclick="adjustNewTextFontSize(1)"
title="Increase size">+</button>
</div>
<!-- Divider -->
<div class="sejda-divider"></div>
<!-- Text Color -->
<input type="color" id="newTextColor" value="#000000" class="sejda-color-picker"
title="Text color">
<!-- Divider -->
<div class="sejda-divider"></div>
<!-- Style Buttons -->
<button class="sejda-style-btn" id="newTextBoldBtn" title="Bold"><b>B</b></button>
<button class="sejda-style-btn" id="newTextItalicBtn" title="Italic"><i>I</i></button>
<button class="sejda-style-btn" id="newTextUnderlineBtn" title="Underline"><u>U</u></button>
</div>
<!-- Row 2: Position, Size, Action Buttons -->
<div class="sejda-toolbar-row">
<!-- Positioning Controls (Y & X) -->
<div class="sejda-positioning-inline">
<div class="sejda-pos-control">
<span class="sejda-pos-label">Y:</span>
<button class="sejda-pos-btn-inline" onclick="adjustNewTextPosition('y', -1)"
title="Move up">↑</button>
<span class="sejda-pos-display" id="newTextYDisplay">0</span>
<button class="sejda-pos-btn-inline" onclick="adjustNewTextPosition('y', 1)"
title="Move down">↓</button>
</div>
<div class="sejda-pos-control">
<span class="sejda-pos-label">X:</span>
<button class="sejda-pos-btn-inline" onclick="adjustNewTextPosition('x', -1)"
title="Move left">←</button>
<span class="sejda-pos-display" id="newTextXDisplay">0</span>
<button class="sejda-pos-btn-inline" onclick="adjustNewTextPosition('x', 1)"
title="Move right">→</button>
</div>
</div>
<!-- Divider -->
<div class="sejda-divider"></div>
<!-- Size Controls (Width & Height) -->
<div class="sejda-positioning-inline">
<div class="sejda-pos-control">
<span class="sejda-pos-label">W:</span>
<button class="sejda-pos-btn-inline" onclick="adjustNewTextPosition('width', -5)"
title="Decrease width">←</button>
<span class="sejda-pos-display" id="newTextWidthDisplay">0</span>
<button class="sejda-pos-btn-inline" onclick="adjustNewTextPosition('width', 5)"
title="Increase width">→</button>
</div>
<div class="sejda-pos-control">
<span class="sejda-pos-label">H:</span>
<button class="sejda-pos-btn-inline" onclick="adjustNewTextPosition('height', -2)"
title="Decrease height">↓</button>
<span class="sejda-pos-display" id="newTextHeightDisplay">0</span>
<button class="sejda-pos-btn-inline" onclick="adjustNewTextPosition('height', 2)"
title="Increase height">↑</button>
</div>
</div>
<!-- Divider -->
<div class="sejda-divider"></div>
<!-- Action Buttons -->
<button id="newTextApplyBtn" class="sejda-btn-success" title="Apply changes">✓</button>
<button id="newTextCancelBtn" class="sejda-btn-cancel" title="Cancel"
onclick="closeNewTextBar()">✕</button>
</div>
<!-- Hidden inputs for all adjustment values -->
<input type="hidden" id="newTextYInput" value="0">
<input type="hidden" id="newTextXInput" value="0">
<input type="hidden" id="newTextWidthInput" value="0">
<input type="hidden" id="newTextHeightInput" value="0">
<input type="hidden" id="newTextLineHeightInput" value="1.8">
<input type="hidden" id="newTextLetterSpacingInput" value="0">
</div>
<!-- Status Bar / HUD -->
<div class="status-bar"
style="position: fixed; bottom: 0; left: 0; right: 0; background: #f8f9fa; border-top: 1px solid #ddd; padding: 0.5rem 1rem; display: flex; justify-content: space-between; align-items: center; font-size: 0.85rem; z-index: 100;">
<!-- Mobile Hamburger Menu in HUD -->
<button class="hud-hamburger-menu" id="hud-hamburger-menu" aria-label="Menu" style="display: none;">
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor"
stroke-width="2" stroke-linecap="round">
<line x1="3" y1="6" x2="21" y2="6"></line>
<line x1="3" y1="12" x2="21" y2="12"></line>
<line x1="3" y1="18" x2="21" y2="18"></line>
</svg>
</button>
<span id="statusMessage" style="color: #495057;">Ready</span>
<span id="autosaveIndicator" class="autosave-indicator"></span>
<span id="sessionInfo" style="color: #6c757d; font-size: 0.8rem;"></span>
<span style="margin-left: auto; font-size: 0.85rem;">
<a href="/terms-of-service" target="_blank" style="color: #6c757d; text-decoration: none; margin-right: 15px;">Terms of Service</a>
<a href="/privacy-policy" target="_blank" style="color: #6c757d; text-decoration: none;">Privacy Policy</a>
</span>
</div>
<!-- Modals -->
<div id="modalOverlay" class="modal-overlay" style="display: none;">
<div id="modalContent" class="modal-content">
<!-- Dynamic modal content -->
</div>
</div>
<!-- Unicode Keyboard Warning Modal -->
<div id="keyboardWarningModal" class="modal-overlay" style="display: none;">
<div class="modal-content"
style="max-width: 420px; width: 90%; padding: 1.5rem; text-align: center;">
<div style="font-size: 2.5rem; margin-bottom: 0.5rem;">⚠️</div>
<h3 style="color: #dc3545; margin-bottom: 1rem; font-size: clamp(1.1rem, 3vw, 1.3rem);">Use
Unicode Keyboard Only</h3>
<div
style="text-align: left; background: #f8f9fa; padding: 0.875rem; border-radius: 6px; margin-bottom: 1rem; font-size: clamp(0.85rem, 2vw, 0.9rem);">
<p style="margin-bottom: 0.75rem; font-weight: 600;">✅ Supported:</p>
<div style="margin-left: 0.75rem; margin-bottom: 0.75rem; line-height: 1.6;">
<div>• Avro Keyboard</div>
<div>• Ridmik Keyboard</div>
<div>• Bijoy Bayanno (Unicode)</div>
</div>
<p style="margin-bottom: 0.5rem; font-weight: 600; color: #dc3545;">❌ Not Supported:</p>
<div style="margin-left: 0.75rem; color: #dc3545; line-height: 1.6;">
<div>• Bijoy Classic (ANSI)</div>
<div>• Any ANSI keyboard</div>
</div>
</div>
<!-- TOS & Privacy Policy Agreement -->
<div style="text-align: left; margin-bottom: 1rem; padding: 10px; border: 1px solid #dc3545; border-radius: 6px; background: #fff3f3; font-size: 0.85rem;">
<label style="display: flex; align-items: flex-start; cursor: pointer; gap: 8px;">
<input type="checkbox" id="tosAgreementCheckbox" style="margin-top: 3px; cursor: pointer;">
<span>I agree to the <a href="/terms-of-service" target="_blank" style="color: #0056b3; text-decoration: underline;">Terms of Service</a> & <a href="/privacy-policy" target="_blank" style="color: #0056b3; text-decoration: underline;">Privacy Policy</a>, and I confirm that I am NOT editing this document for any illegal purpose or forgery.</span>
</label>
</div>
<button id="dismissKeyboardWarning" class="btn"
style="background-color: #6c757d; color: white; padding: 0.65rem 1.5rem; font-size: clamp(0.9rem, 2.5vw, 1rem); border-radius: 6px; border: none; cursor: not-allowed; font-weight: 600; width: 100%; max-width: 200px;" disabled>
Start Editing
</button>
<script>
document.getElementById('tosAgreementCheckbox').addEventListener('change', function() {
const btn = document.getElementById('dismissKeyboardWarning');
if (this.checked) {
btn.disabled = false;
btn.style.backgroundColor = '#28a745';
btn.style.cursor = 'pointer';
} else {
btn.disabled = true;
btn.style.backgroundColor = '#6c757d';
btn.style.cursor = 'not-allowed';
}
});
</script>
</div>
</div>
<!-- Progress Bar Overlay -->
<div id="progressOverlay" class="progress-overlay" style="display: none;">
<div class="progress-container">
<div class="progress-icon">⏳</div>
<h3 id="progressTitle">Processing...</h3>
<p id="progressMessage">Please wait...</p>
<div class="progress-bar">
<div id="progressFill" class="progress-fill"></div>
</div>
<div id="progressPercent" class="progress-percent">0%</div>
</div>
</div>
<!-- Priority Page Selection Modal (must be outside progressOverlay) -->
<div id="priorityPageModal" class="modal"
style="display:none; position:fixed; top:0; left:0; width:100%; height:100%; background:rgba(0,0,0,0.5); z-index:9999; justify-content:center; align-items:center;">
<div
style="background:white; border-radius:12px; padding:2rem; max-width:480px; width:90%; box-shadow:0 20px 60px rgba(0,0,0,0.3);">
<h2 style="margin:0 0 0.5rem; font-size:1.4rem; color:#333;">📄 Which page to edit first?</h2>
<div style="display:flex; align-items:center; gap:1rem; margin-bottom:1.5rem;">
<label style="font-weight:600; color:#333; white-space:nowrap;">Page Number:</label>
<input type="number" id="priorityPageInput" min="1" value="1"
style="flex:1; padding:0.6rem 1rem; border:2px solid #ddd; border-radius:8px; font-size:1.1rem; text-align:center;">
<span id="priorityPageTotal" style="color:#666; white-space:nowrap;">of 1</span>
</div>
<div id="priorityPageGrid"
style="display:grid; grid-template-columns:repeat(auto-fill, minmax(50px,1fr)); gap:8px; max-height:200px; overflow-y:auto; margin-bottom:1.5rem; padding:8px; border:1px solid #eee; border-radius:8px;">
<!-- Page buttons filled by JS -->
</div>
<div style="display:flex; gap:1rem; justify-content:flex-end;">
<button id="priorityPageCancel"
onclick="document.getElementById('priorityPageModal').style.display='none'; window._priorityPageResolve && window._priorityPageResolve(1);"
style="padding:0.6rem 1.5rem; background:#6c757d; color:white; border:none; border-radius:8px; cursor:pointer; font-weight:600;">Page
1 (Default)</button>
<button id="priorityPageConfirm"
onclick="window._confirmPriorityPage && window._confirmPriorityPage();"
style="padding:0.6rem 1.5rem; background:#28a745; color:white; border:none; border-radius:8px; cursor:pointer; font-weight:600;">✅
Start Editing</button>
</div>
</div>
</div>
<!-- OCR Page Selection Modal -->
<div id="ocrPageModal" class="modal"
style="display:none; position:fixed; top:0; left:0; width:100%; height:100%; background:rgba(0,0,0,0.5); z-index:9999; justify-content:center; align-items:center;">
<div
style="background:white; border-radius:12px; padding:2rem; max-width:480px; width:90%; box-shadow:0 20px 60px rgba(0,0,0,0.3);">
<h2 style="margin:0 0 0.5rem; font-size:1.4rem; color:#333;">🔍 Which page to run OCR on?</h2>
<p style="margin:0 0 1rem; color:#666; font-size:0.95rem;">OCR will process this page first.
Remaining pages will be processed in the background.</p>
<div style="display:flex; align-items:center; gap:1rem; margin-bottom:1.5rem;">
<label style="font-weight:600; color:#333; white-space:nowrap;">Page Number:</label>
<input type="number" id="ocrPageInput" min="1" value="1"
style="flex:1; padding:0.6rem 1rem; border:2px solid #ddd; border-radius:8px; font-size:1.1rem; text-align:center;">
<span id="ocrPageTotal" style="color:#666; white-space:nowrap;">of 1</span>
</div>
<div id="ocrPageGrid"
style="display:grid; grid-template-columns:repeat(auto-fill, minmax(50px,1fr)); gap:8px; max-height:200px; overflow-y:auto; margin-bottom:1.5rem; padding:8px; border:1px solid #eee; border-radius:8px;">
<!-- Page buttons filled by JS -->
</div>
<div style="display:flex; gap:1rem; justify-content:flex-end;">
<button id="ocrPageCancel"
onclick="document.getElementById('ocrPageModal').style.display='none'; window._ocrPageResolve && window._ocrPageResolve(null);"
style="padding:0.6rem 1.5rem; background:#6c757d; color:white; border:none; border-radius:8px; cursor:pointer; font-weight:600;">Cancel</button>
<button id="ocrPageConfirm" onclick="window._confirmOCRPage && window._confirmOCRPage();"
style="padding:0.6rem 1.5rem; background:#28a745; color:white; border:none; border-radius:8px; cursor:pointer; font-weight:600;">🔍
Run OCR</button>
</div>
</div>
</div>
<!-- Add Page Position Modal (must be outside progressOverlay) -->
<div id="addPageModal" class="modal" style="display: none;">
<div class="modal-content" style="max-width: 500px; border-radius: 12px; padding: 2rem;">
<h2 style="margin-bottom: 1.5rem; color: #2c3e50; font-size: 1.5rem; text-align: center;">
📄 Add New Page
</h2>
<p style="margin-bottom: 1.5rem; color: #666; text-align: center; font-size: 0.95rem;">
Choose where to insert the blank page:
</p>
<div style="display: flex; flex-direction: column; gap: 1rem; margin-bottom: 2rem;">
<!-- Option 1: At Start -->
<label class="add-page-option"
style="display: flex; align-items: center; padding: 1rem; border: 2px solid #e0e0e0; border-radius: 8px; cursor: pointer; transition: all 0.3s;">
<input type="radio" name="pagePosition" value="start"
style="width: 20px; height: 20px; margin-right: 1rem; cursor: pointer;">
<div>
<div style="font-weight: 600; color: #2c3e50; margin-bottom: 0.25rem;">At the Start
</div>
<div style="font-size: 0.85rem; color: #888;">Insert as first page (Page 1)</div>
</div>
</label>
<!-- Option 2: After Current -->
<label class="add-page-option"
style="display: flex; align-items: center; padding: 1rem; border: 2px solid #e0e0e0; border-radius: 8px; cursor: pointer; transition: all 0.3s;">
<input type="radio" name="pagePosition" value="current" checked
style="width: 20px; height: 20px; margin-right: 1rem; cursor: pointer;">
<div>
<div style="font-weight: 600; color: #2c3e50; margin-bottom: 0.25rem;">After Current
Page</div>
<div style="font-size: 0.85rem; color: #888;">Insert after page <span
id="currentPageDisplay">1</span></div>
</div>
</label>
<!-- Option 3: At End -->
<label class="add-page-option"
style="display: flex; align-items: center; padding: 1rem; border: 2px solid #e0e0e0; border-radius: 8px; cursor: pointer; transition: all 0.3s;">
<input type="radio" name="pagePosition" value="end"
style="width: 20px; height: 20px; margin-right: 1rem; cursor: pointer;">
<div>
<div style="font-weight: 600; color: #2c3e50; margin-bottom: 0.25rem;">At the End
</div>
<div style="font-size: 0.85rem; color: #888;">Append as last page (Page <span
id="totalPagesDisplay">1</span>)</div>
</div>
</label>
<!-- Option 4: Custom Position -->
<label class="add-page-option"
style="display: flex; align-items: center; padding: 1rem; border: 2px solid #e0e0e0; border-radius: 8px; cursor: pointer; transition: all 0.3s;">
<input type="radio" name="pagePosition" value="custom"
style="width: 20px; height: 20px; margin-right: 1rem; cursor: pointer;">
<div style="flex: 1;">
<div style="font-weight: 600; color: #2c3e50; margin-bottom: 0.5rem;">At Specific
Position</div>
<div style="display: flex; align-items: center; gap: 0.5rem;">
<span style="font-size: 0.85rem; color: #888;">Insert before page:</span>
<input type="number" id="customPageNumber" min="1" max="1" value="1"
style="width: 80px; padding: 0.5rem; border: 1px solid #ddd; border-radius: 4px; font-size: 0.9rem;"
disabled>
</div>
</div>
</label>
</div>
<div style="display: flex; gap: 1rem; justify-content: center;">
<button id="cancelAddPage" class="btn"
onclick="document.getElementById('addPageModal').style.display='none';"
style="background-color: #6c757d; color: white; padding: 0.75rem 2rem; border-radius: 8px; border: none; cursor: pointer; font-weight: 600; font-size: 1rem;">
Cancel
</button>
<button id="confirmAddPage" class="btn"
onclick="if(window.executeAddPage){executeAddPage();document.getElementById('addPageModal').style.display='none';}"
style="background-color: #28a745; color: white; padding: 0.75rem 2rem; border-radius: 8px; border: none; cursor: pointer; font-weight: 600; font-size: 1rem;">
Add Page
</button>
</div>
</div>
</div>
<script src="/static/js/font_manager.js?v=20260225d"></script>
<script src="/static/js/toast.js?v=202601265"></script>
<script src="/static/js/dark-mode.js?v=202601271"></script>
<!-- ── Hero Particle Animation ── -->
<script>
(function(){
var canvas, ctx, W, H, particles = [], raf;
function init(){
canvas = document.getElementById('heroParticles');
if(!canvas) return;
ctx = canvas.getContext('2d');
resize();
particles = [];
for(var i=0;i<80;i++) spawnParticle();
if(raf) cancelAnimationFrame(raf);
loop();
window.addEventListener('resize', resize);
}
function resize(){
if(!canvas) return;
W = canvas.width = window.innerWidth;
H = canvas.height = window.innerHeight;
}
function rand(a,b){ return a + Math.random()*(b-a); }
function spawnParticle(){
return {
x: rand(0, W||1200),
y: rand(0, H||800),
r: rand(0.6, 2.2),
vx: rand(-0.18, 0.18),
vy: rand(-0.35, -0.08),
alpha: rand(0.2, 0.7),
hue: rand(240, 300)
};
}
function loop(){
if(!ctx) return;
ctx.clearRect(0,0,W,H);
for(var i=0;i<particles.length;i++){
var p = particles[i];
p.x += p.vx;
p.y += p.vy;
p.alpha -= 0.0008;
if(p.y < -10 || p.alpha <= 0){
particles[i] = spawnParticle();
particles[i].y = H + 5;
}
ctx.beginPath();
ctx.arc(p.x, p.y, p.r, 0, Math.PI*2);
ctx.fillStyle = 'hsla('+p.hue+',80%,70%,'+p.alpha+')';
ctx.fill();
}
raf = requestAnimationFrame(loop);
}
/* Start when DOM ready, stop when PDF loads */
document.addEventListener('DOMContentLoaded', function(){
init();
/* observe loadingMessage visibility */
var lm = document.getElementById('loadingMessage');
if(lm){
var obs = new MutationObserver(function(){
if(lm.style.display==='none'){ cancelAnimationFrame(raf); }
});
obs.observe(lm, {attributes:true, attributeFilter:['style']});
}
});
})();
</script>
<!-- Minified & Deferred JS for Performance - 37.6% size reduction -->
<!-- Minified & Deferred JS for Performance - 37.6% size reduction -->
<!-- Load desktop app.js for all users -->
<script src="/static/js/ribbon-menu.js?v=202602021"></script>
<script src="/static/js/page-counter-update.js?v=202602022"></script>
<script src="/static/js/page-counter-integration.js?v=202602022"></script>
<script src="/static/js/app.js?v=20260226i" defer></script>
<!-- Drag & Drop System -->
<link rel="stylesheet" href="/static/css/drag-drop.css?v=20260131z">
<link rel="stylesheet" href="/static/css/draggable-elements.css?v=20260131z">
<script src="/static/js/drag-drop.js?v=20260131z" defer></script>
<script src="/static/js/draggable-elements.js?v=20260131z" defer></script>
<!-- Mobile Precision Editor -->
<link rel="stylesheet" href="/static/css/mobile-precision-editor.css?v=20260131z">
<!-- <script src="/static/js/mobile-precision-editor.js?v=20260131z" defer></script> -->
<!-- DISABLED - Blocking pinch and zoom -->
<script src="/static/js/merge_split.js?v=20260224"></script>
<script src="/static/js/signature.js?v=202601265"></script>
<script src="/static/js/share.js?v=202601265"></script>
<script src="/static/js/compress.js?v=202601265"></script>
<script src="/static/js/watermark.js?v=202601265"></script>
<script src="/static/js/vector-shapes.js?v=20260226a"></script>
<script src="/static/js/images_to_pdf.js?v=202601265"></script>
<script src="/static/js/highlight.js?v=202601265"></script>
<!-- AI Summary module removed -->
<!-- <script src="/static/js/mobile-navigation.js?v=202601281"></script> -->
<!-- PWA manager disabled -->
<!-- <script src="/static/js/pwa-manager.js?v=202601265"></script> -->
<!-- Force unregister service worker on page load -->
<script src="/static/js/unregister-sw.js?v=202601265"></script>
<!-- Offline Indicator - DISABLED -->
<div class="offline-indicator" id="offline-indicator" style="display: none !important;">
🔴 You are offline - Some features may be limited
</div>
<!-- Connection Status -->
<div class="connection-status" id="connection-status" title="Connection status"></div>
<!-- PWA Install Button - DISABLED -->
<!-- <button class="install-pwa-btn" id="install-pwa-btn" style="display: none;">
Install App
</button> -->
<!-- Scan Document Button (mobile) - DISABLED FOR PC ONLY -->
<!-- <button class="scan-document-btn mobile-only" id="scan-document-btn" style="display: none;">
Scan Document
</button> -->
<!-- Share Button -->
<button class="share-pdf-btn" id="share-pdf-btn" style="display: none;">
Share PDF
</button>
<!-- PWA Badge - DISABLED -->
<!-- <div class="pwa-badge">Installed</div> -->
<!-- Admin Dashboard Analytics Tracking -->
<script>
(function() {
// Generate or get session ID
let sid = null;
try {
sid = sessionStorage.getItem('bpe_session_id');
if (!sid) {
sid = 'sess_' + Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15);
sessionStorage.setItem('bpe_session_id', sid);
}
} catch (e) {
sid = 'sess_' + Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15);
}
// Ping session to admin dashboard
function pingSession() {
fetch('/secret-admin-9f4k/sessions/track', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
session_id: sid,
ip_address: '', // Handled by backend if needed
user_agent: navigator.userAgent,
page_url: window.location.href,
referrer: document.referrer
})
}).catch(e => {});
}
// Ping on load
pingSession();
// Ping every 5 minutes
setInterval(pingSession, 5 * 60 * 1000);
// Hook into trackPDFUpload to send conversions to admin dashboard
const originalTrackPDFUpload = window.trackPDFUpload;
window.trackPDFUpload = async function(fileName, fileSizeMB, numPages) {
// Call original GA4 tracking
if (originalTrackPDFUpload) {
await originalTrackPDFUpload(fileName, fileSizeMB, numPages);
}
// Send to admin dashboard
fetch('/secret-admin-9f4k/sessions/track-conversion', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
session_id: sid,
conversion_type: 'pdf_edit',
file_size: Math.round((fileSizeMB || 0) * 1024 * 1024),
pages_count: numPages || 0,
processing_time: 0,
success: 1
})
}).catch(e => {});
};
})();
</script>
<!-- Google Analytics 4 -->
<script async src="https://www.googletagmanager.com/gtag/js?id=G-TBTKS2GMTH"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'G-TBTKS2GMTH', {
'send_page_view': true,
'cookie_flags': 'SameSite=None;Secure'
});
// Track custom events
function trackEvent(eventName, eventParams) {
gtag('event', eventName, eventParams);
}
// ── Enhanced Upload Tracking with Location ──────────────
// Cache geolocation data so we only look it up once per session
window._geoCache = null;
async function _fetchGeoData() {
if (window._geoCache) return window._geoCache;
try {
// ipapi.co — free, no API key, 1000 req/day
const r = await fetch('https://ipapi.co/json/', { cache: 'force-cache' });
if (r.ok) {
const d = await r.json();
window._geoCache = {
country: d.country_name || 'Unknown',
city: d.city || 'Unknown',
region: d.region || 'Unknown',
country_code: d.country_code || ''
};
}
} catch (e) {
window._geoCache = { country: 'Unknown', city: 'Unknown', region: 'Unknown', country_code: '' };
}
return window._geoCache;
}
// Pre-fetch geo on page load (background, non-blocking)
setTimeout(_fetchGeoData, 2000);
// Track PDF uploads — sends rich event to GA4
window.trackPDFUpload = async function(fileName, fileSizeMB, numPages) {
try {
const geo = await _fetchGeoData();
trackEvent('pdf_upload', {
'event_category': 'engagement',
'event_label': 'PDF Upload',
'file_name': fileName || 'unknown',
'file_size_mb': fileSizeMB || 0,
'num_pages': numPages || 0,
'user_country': geo.country,
'user_city': geo.city,
'user_region': geo.region,
'user_country_code': geo.country_code
});
console.log(`📊 GA4: pdf_upload tracked — ${fileName} from ${geo.city}, ${geo.country}`);
} catch(e) {
// Fallback: track without geo
trackEvent('pdf_upload', {
'event_category': 'engagement',
'event_label': 'PDF Upload',
'file_name': fileName || 'unknown',
'file_size_mb': fileSizeMB || 0,
'num_pages': numPages || 0
});
}
};
// Track PDF downloads
window.trackPDFDownload = function () {
trackEvent('pdf_download', {
'event_category': 'conversion',
'event_label': 'PDF Download'
});
};
// Track feature usage
window.trackFeatureUse = function (featureName) {
trackEvent('feature_use', {
'event_category': 'engagement',
'event_label': featureName
});
};
// Track page interactions
window.trackButtonClick = function (buttonName) {
trackEvent('button_click', {
'event_category': 'engagement',
'event_label': buttonName
});
};
</script>
<!-- Structured Data - Organization Schema -->
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "Organization",
"name": "Bangla PDF Editor",
"url": "https://banglapdfeditor.com",
"logo": "https://banglapdfeditor.com/static/logo.png",
"description": "Free online Bangla PDF Editor with Bengali Unicode support, OCR, and 396+ Bengali fonts",
"sameAs": [
"https://twitter.com/banglapdfeditor",
"https://facebook.com/banglapdfeditor"
]
}
</script>
<!-- Structured Data - SoftwareApplication Schema -->
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "SoftwareApplication",
"name": "Bangla PDF Editor",
"applicationCategory": "BusinessApplication",
"operatingSystem": "Web Browser",
"offers": {
"@type": "Offer",
"price": "0",
"priceCurrency": "USD"
},
"aggregateRating": {
"@type": "AggregateRating",
"ratingValue": "4.8",
"ratingCount": "1250"
},
"description": "Free online Bangla PDF Editor. Edit, merge, split, compress PDFs with Bengali Unicode support. 396+ Bengali fonts, OCR, watermark, e-signature. No registration required.",
"featureList": [
"Edit PDF text with Bengali Unicode",
"Merge multiple PDFs",
"Split PDF pages",
"Compress PDF files",
"Convert PDF to Word/Excel",
"OCR for Bengali documents",
"Add watermark and e-signature",
"396+ Bengali fonts support"
],
"screenshot": "https://banglapdfeditor.com/static/screenshots/desktop.png",
"url": "https://banglapdfeditor.com"
}
</script>
<!-- Structured Data - WebSite Schema with SearchAction -->
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "WebSite",
"name": "Bangla PDF Editor",
"url": "https://banglapdfeditor.com",
"description": "Free online Bangla PDF Editor with Bengali Unicode support",
"inLanguage": ["bn", "en"],
"potentialAction": {
"@type": "SearchAction",
"target": "https://banglapdfeditor.com/search?q={search_term_string}",
"query-input": "required name=search_term_string"
}
}
</script>
<script src="/static/js/feedback.js?v=202601270"></script>
<!-- Font Lazy Loader - Load fonts only when user selects them -->
<script src="/static/js/font-lazy-loader.js?v=202601267"></script>
<!-- Advanced Font Optimizations -->
<script src="/static/js/intelligent-font-preloader.js?v=20260217"></script>
<script src="/static/js/font-loading-scheduler.js?v=20260217"></script>
<script src="/static/js/font-performance-monitor.js?v=20260217"></script>
<!-- UX Enhancements - Keyboard shortcuts, touch gestures, accessibility -->
<script src="/static/js/ux-enhancements.js?v=20260226a"></script>
<script src="/static/js/telemetry.js?v=1"></script>
<!-- Mobile Editor - Touch-optimized editing experience -->
<!-- <script src="/static/js/mobile-editor.js?v=202601267"></script> -->
<!-- Basic Mobile Menu Script - DISABLED FOR PC ONLY -->
<!-- <script>
(function() {
const hamburger = document.getElementById('hamburger-menu');
const mobileMenu = document.getElementById('mobile-menu');
const menuOverlay = document.getElementById('mobile-menu-overlay');
if (hamburger && mobileMenu && menuOverlay) {
hamburger.addEventListener('click', function() {
hamburger.classList.toggle('active');
mobileMenu.classList.toggle('active');
menuOverlay.classList.toggle('active');
});
menuOverlay.addEventListener('click', function() {
hamburger.classList.remove('active');
mobileMenu.classList.remove('active');
menuOverlay.classList.remove('active');
});
// Close on menu item click
const menuItems = mobileMenu.querySelectorAll('.mobile-menu-item');
menuItems.forEach(item => {
item.addEventListener('click', function() {
hamburger.classList.remove('active');
mobileMenu.classList.remove('active');
menuOverlay.classList.remove('active');
});
});
}
})();
</script> -->
<!-- Tutorial Modal HTML -->
<div id="tutorialModal" class="tutorial-modal">
<div class="tutorial-content">
<button id="closeTutorialBtn" class="tutorial-close">×</button>
<h3 style="margin-top: 0; margin-bottom: 15px; color: #1e3a8a; text-align: center; font-family: inherit; font-size: 20px;">Bangla PDF Editor কিভাবে ব্যবহার করবেন?</h3>
<div class="tutorial-video-container" id="tutorialVideoContainer">
<video id="localVideoPlayer" width="100%" height="100%" controls style="position: absolute; top: 0; left: 0;">
<source src="/static/videos/tutorial.mp4" type="video/mp4">
Your browser does not support the video tag.
</video>
</div>
</div>
</div>
<!-- Tutorial Modal JS -->
<script>
document.addEventListener('DOMContentLoaded', function() {
const modal = document.getElementById('tutorialModal');
const closeBtn = document.getElementById('closeTutorialBtn');
const openBtn = document.getElementById('open-tutorial-btn');
const videoPlayer = document.getElementById('localVideoPlayer');
// Function to open modal
function openTutorial(e) {
if(e) e.preventDefault();
modal.classList.add('show');
}
// Function to close modal
function closeTutorial() {
modal.classList.remove('show');
try { localStorage.setItem('banglapdf_tutorial_watched', 'true'); } catch (e) {}
if (videoPlayer) {
videoPlayer.pause();
}
}
// Event listeners
if(openBtn) openBtn.addEventListener('click', openTutorial);
if(closeBtn) closeBtn.addEventListener('click', closeTutorial);
// Close on outside click
window.addEventListener('click', function(e) {
if (e.target === modal) {
closeTutorial();
}
});
// Check localStorage for first-time auto-popup (with slight delay)
try {
if (!localStorage.getItem('banglapdf_tutorial_watched')) {
// setTimeout(openTutorial, 2000); // Disabled upon request
}
} catch (e) {}
});
</script>
<!-- Exit Intent Feedback Modal -->
<div id="exitIntentModal" style="display:none; position:fixed; top:0; left:0; right:0; bottom:0; z-index:99999; background:rgba(17,24,39,0.7); backdrop-filter:blur(4px);">
<div id="exitIntentContent" style="position:absolute; top:50%; left:50%; transform:translate(-50%,-50%); background:#fff; border-radius:1.25rem; box-shadow:0 25px 50px rgba(0,0,0,0.35); padding:2.5rem; max-width:500px; width:calc(100% - 2rem); transition:opacity 0.3s, transform 0.3s; opacity:0; transform:translate(-50%,-50%) scale(0.95);">
<!-- Close Button -->
<button onclick="closeExitIntent()" class="absolute top-4 right-4 text-gray-400 hover:text-gray-600 focus:outline-none">
<i class="fas fa-times text-xl"></i>
</button>
<div id="exitStep1" class="text-center">
<div class="w-16 h-16 bg-blue-100 rounded-full flex items-center justify-center mx-auto mb-4">
<i class="fas fa-question text-3xl text-blue-600"></i>
</div>
<h2 class="text-2xl font-bold text-gray-800 mb-2">একটু শুনবেন!</h2>
<p class="text-gray-600 mb-6 text-lg">আপনি কি আপনার প্রয়োজনীয় পিডিএফ এডিট করতে পেরেছেন?</p>
<div class="flex flex-col sm:flex-row gap-4 justify-center">
<button onclick="submitExitFeedback('yes')" class="flex-1 bg-green-500 hover:bg-green-600 text-white font-semibold py-3 px-6 rounded-xl transition duration-200 flex items-center justify-center">
<i class="fas fa-check-circle mr-2"></i> হ্যাঁ পেরেছি
</button>
<button onclick="showExitFeedbackForm()" class="flex-1 bg-red-500 hover:bg-red-600 text-white font-semibold py-3 px-6 rounded-xl transition duration-200 flex items-center justify-center">
<i class="fas fa-times-circle mr-2"></i> না পারিনি
</button>
</div>
</div>
<div id="exitStep2" class="hidden">
<h2 class="text-xl font-bold text-gray-800 mb-4 flex items-center">
<i class="fas fa-comment-dots text-blue-500 mr-2"></i> আপনার সমস্যাটি আমাদের জানান
</h2>
<div class="bg-yellow-50 border-l-4 border-yellow-400 p-3 mb-3 rounded-md text-left">
<p class="text-sm text-yellow-800 font-semibold mb-1">
<i class="fas fa-video mr-1"></i> পিডিএফ এডিট করতে সমস্যা হচ্ছে?
</p>
<p class="text-sm text-yellow-700">
আমাদের টিউটোরিয়াল ভিডিওটি দেখলে খুব সহজেই এডিট করতে পারবেন।
<a href="#" onclick="closeExitIntent(); document.getElementById('tutorialModal').classList.add('show'); return false;" class="text-blue-600 underline font-bold">ভিডিওটি দেখুন</a>
</p>
</div>
<div class="bg-blue-50 border-l-4 border-blue-500 p-3 mb-4 rounded-md text-left">
<p class="text-sm text-blue-800 font-semibold mb-1">
<i class="fas fa-crown mr-1"></i> সময় বাঁচাতে চান?
</p>
<p class="text-sm text-blue-700 mb-2">
আমাদের প্রিমিয়াম সার্ভিসে হাই-স্পিড এআই এবং এক্সট্রা ফিচার ব্যবহার করে সেকেন্ডের মধ্যে কাজ শেষ করুন!
</p>
<div class="mt-4">
<button onclick="closeExitIntent(); if(typeof openPaymentModal === 'function') openPaymentModal();" class="w-full bg-blue-600 hover:bg-blue-700 text-white text-sm font-bold py-2 px-4 rounded transition duration-200">
একাউন্ট তৈরি করুন
</button>
</div>
</div>
<p class="text-sm text-gray-600 mb-3">(দয়া করে বাংলায় লিখুন, আমরা সমস্যাটি সমাধান করব)</p>
<textarea id="exitFeedbackText" rows="4" class="w-full border-2 border-gray-200 rounded-xl p-3 focus:border-blue-500 focus:ring-0 transition" placeholder="এখানে লিখুন..."></textarea>
<button onclick="submitExitFeedback('no')" class="w-full mt-4 bg-blue-600 hover:bg-blue-700 text-white font-semibold py-3 px-6 rounded-xl transition duration-200">
সাবমিট করুন
</button>
</div>
<div id="exitStep3" class="hidden text-center py-6">
<div class="w-16 h-16 bg-green-100 rounded-full flex items-center justify-center mx-auto mb-4">
<i class="fas fa-heart text-3xl text-green-500"></i>
</div>
<h2 class="text-2xl font-bold text-gray-800 mb-2">ধন্যবাদ!</h2>
<p class="text-gray-600">আপনার মতামতের জন্য অসংখ্য ধন্যবাদ.</p>
<button onclick="closeExitIntent()" class="mt-6 bg-gray-100 hover:bg-gray-200 text-gray-800 font-semibold py-2 px-6 rounded-lg transition duration-200">
বন্ধ করুন
</button>
</div>
</div>
</div>
<script>
// Exit Intent Logic
document.addEventListener('DOMContentLoaded', function() {
let exitIntentTriggered = false;
let pageTimeReady = false;
const STORAGE_KEY = 'exitFeedback_v2';
// Arm the exit intent after 15 seconds
setTimeout(function() {
pageTimeReady = true;
}, 15000);
// Track mouse Y position — fires reliably even over PDF canvas/overlays
document.addEventListener('mousemove', function(e) {
const hasUploadedPdf = (typeof AppState !== 'undefined' && AppState.pdfData !== null);
let hasSeenPopup = false;
try { hasSeenPopup = localStorage.getItem(STORAGE_KEY); } catch(e){}
if (hasUploadedPdf && pageTimeReady && !exitIntentTriggered && !hasSeenPopup) {
// Trigger when mouse reaches within 10px of the very top of the screen
if (e.clientY <= 10) {
// showExitIntentModal(); // Disabled upon request
}
}
}, { passive: true });
function showExitIntentModal() {
exitIntentTriggered = true;
try { localStorage.setItem(STORAGE_KEY, 'true'); } catch(e){}
const modal = document.getElementById('exitIntentModal');
const content = document.getElementById('exitIntentContent');
modal.style.display = 'block';
setTimeout(() => {
content.style.opacity = '1';
content.style.transform = 'translate(-50%, -50%) scale(1)';
}, 10);
}
});
function closeExitIntent() {
const modal = document.getElementById('exitIntentModal');
const content = document.getElementById('exitIntentContent');
content.style.opacity = '0';
content.style.transform = 'translate(-50%, -50%) scale(0.95)';
setTimeout(() => {
modal.style.display = 'none';
}, 300);
}
function showExitFeedbackForm() {
document.getElementById('exitStep1').classList.add('hidden');
document.getElementById('exitStep2').classList.remove('hidden');
}
function submitExitFeedback(answer) {
let rating = 5;
let message = 'User successfully edited PDF (Exit Intent)';
if (answer === 'no') {
rating = 1;
const text = document.getElementById('exitFeedbackText').value.trim();
if (!text) {
alert('অনুগ্রহ করে আপনার সমস্যাটি লিখুন।');
return;
}
message = text;
}
// Show thank you screen
document.getElementById('exitStep1').classList.add('hidden');
document.getElementById('exitStep2').classList.add('hidden');
document.getElementById('exitStep3').classList.remove('hidden');
// Submit to existing feedback endpoint
fetch('/api/feedback', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
type: 'exit_intent',
rating: rating,
message: message,
timestamp: new Date().toISOString()
})
}).catch(e => console.error('Feedback submission failed:', e));
// Auto close after 3 seconds
setTimeout(closeExitIntent, 3000);
}
</script>
</div>
<div style="display: flex; gap: 10px;">
<button onclick="var el = document.getElementById('cookie-consent-banner'); if (el) el.style.display='none'; try { localStorage.setItem('cookie_consent', 'true'); } catch(e){}" style="background: #6c3bec; color: #fff; border: none; padding: 10px 24px; border-radius: 8px; cursor: pointer; font-weight: 600; font-size: 14px; transition: background 0.2s; white-space: nowrap;">Accept All</button>
</div>
</div>
<script>
try {
if(localStorage.getItem('cookie_consent') === 'true') {
var ccBanner = document.getElementById('cookie-consent-banner');
if (ccBanner) ccBanner.style.display = 'none';
}
} catch (e) {}
</script>
<!-- ==============================================================
EDUCATIONAL CONTENT & COMPREHENSIVE BENGALI PDF GUIDE
High-Value Indexable Content & User Guide for AdSense Compliance
============================================================== -->
<section id="pdf-guide-section" class="bpe-guide-section" style="background: #ffffff; color: #1e293b; padding: 60px 20px; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif; border-top: 2px solid #e2e8f0; clear: both; width: 100%; box-sizing: border-box;">
<div style="max-width: 1200px; margin: 0 auto;">
<!-- Section Header -->
<div style="text-align: center; margin-bottom: 50px;">
<span style="background: #e0e7ff; color: #4338ca; font-size: 0.85rem; font-weight: 700; padding: 6px 16px; border-radius: 9999px; text-transform: uppercase; letter-spacing: 0.05em; display: inline-block; margin-bottom: 12px;">সম্পূর্ণ বিনামূল্যে বাংলা পিডিএফ প্ল্যাটফর্ম</span>
<h2 style="font-size: 2.2rem; font-weight: 800; color: #0f172a; margin: 0 0 16px 0; line-height: 1.3;">বাংলা পিডিএফ এডিটর: সহজে ও নির্ভুলভাবে পিডিএফ সম্পাদনা করুন</h2>
<p style="font-size: 1.15rem; color: #64748b; max-width: 820px; margin: 0 auto; line-height: 1.7;">Bangla PDF Editor is the premier online platform designed specifically for the global Bengali community. Edit, convert, OCR, merge, and protect your PDF documents directly in your web browser with 100% native Bengali Unicode support.</p>
</div>
<!-- 4 Key Feature Pillars Grid -->
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(270px, 1fr)); gap: 24px; margin-bottom: 60px;">
<div style="background: #f8fafc; border: 1px solid #e2e8f0; border-radius: 14px; padding: 28px; box-shadow: 0 2px 8px rgba(0,0,0,0.03);">
<div style="width: 48px; height: 48px; background: #dbeafe; border-radius: 10px; display: flex; align-items: center; justify-content: center; font-size: 1.5rem; margin-bottom: 18px;">✍️</div>
<h3 style="font-size: 1.25rem; font-weight: 700; color: #1e293b; margin: 0 0 10px 0;">নিখুঁত বাংলা টেক্সট এডিটিং</h3>
<p style="font-size: 0.95rem; color: #475569; line-height: 1.7; margin: 0;">আন্তর্জাতিক সাধারণ এডিটরগুলোতে বাংলা যুক্তবর্ণ বা হ্রস্ব-ই কার ভেঙে যায়। আমাদের প্ল্যাটফর্মে কালপুরুষ, সোলাইমানলিপি ও নিকোশ সহ ২০০+ বাংলা ফন্টে সরাসরি যেকোনো অক্ষত লাইনে টেক্সট এডিট করুন।</p>
</div>
<div style="background: #f8fafc; border: 1px solid #e2e8f0; border-radius: 14px; padding: 28px; box-shadow: 0 2px 8px rgba(0,0,0,0.03);">
<div style="width: 48px; height: 48px; background: #e0e7ff; border-radius: 10px; display: flex; align-items: center; justify-content: center; font-size: 1.5rem; margin-bottom: 18px;">🔍</div>
<h3 style="font-size: 1.25rem; font-weight: 700; color: #1e293b; margin: 0 0 10px 0;">বাংলা ওসিআর (OCR) প্রযুক্তি</h3>
<p style="font-size: 0.95rem; color: #475569; line-height: 1.7; margin: 0;">স্ক্যান করা পুরোনো দলিল, সরকারি ফর্ম বা বইয়ের ছবি থেকে সরাসরি বাংলা লেখা এক্সট্র্যাক্ট করুন। অপটিক্যাল ক্যারেক্টার রিকগনিশনের মাধ্যমে ইমেজ পিডিএফ নিমেষেই এডিটেবল টেক্সটে রূপান্তর হয়।</p>
</div>
<div style="background: #f8fafc; border: 1px solid #e2e8f0; border-radius: 14px; padding: 28px; box-shadow: 0 2px 8px rgba(0,0,0,0.03);">
<div style="width: 48px; height: 48px; background: #fef3c7; border-radius: 10px; display: flex; align-items: center; justify-content: center; font-size: 1.5rem; margin-bottom: 18px;">🔄</div>
<h3 style="font-size: 1.25rem; font-weight: 700; color: #1e293b; margin: 0 0 10px 0;">বিজয় ↔ ইউনিকোড রূপান্তর</h3>
<p style="font-size: 0.95rem; color: #475569; line-height: 1.7; margin: 0;">বিজয় (SutonnyMJ) কিবোর্ডে টাইপ করা পুরোনো পিডিএফ আধুনিক ইউনিকোডে রূপান্তর করা এখন সহজ। আমাদের ইন-বিল্ট বাই-ডাইরেকশনাল কনভার্টার ফন্ট জটিলতা স্বয়ংক্রিয়ভাবে সমাধান করে।</p>
</div>
<div style="background: #f8fafc; border: 1px solid #e2e8f0; border-radius: 14px; padding: 28px; box-shadow: 0 2px 8px rgba(0,0,0,0.03);">
<div style="width: 48px; height: 48px; background: #dcfce7; border-radius: 10px; display: flex; align-items: center; justify-content: center; font-size: 1.5rem; margin-bottom: 18px;">🛡️</div>
<h3 style="font-size: 1.25rem; font-weight: 700; color: #1e293b; margin: 0 0 10px 0;">সম্পূর্ণ সুরক্ষিত ও ব্যক্তিগত</h3>
<p style="font-size: 0.95rem; color: #475569; line-height: 1.7; margin: 0;">আপনার নথির সর্বোচ্চ গোপনীয়তা নিশ্চিত করা আমাদের দায়িত্ব। প্রসেসিং শেষে বা ১ ঘণ্টার মধ্যে সমস্ত আপলোড করা ফাইল সার্ভার থেকে স্বয়ংক্রিয়ভাবে ডিলিট হয়ে যায়। কোনো তথ্য স্থায়ীভাবে সংরক্ষিত হয় না।</p>
</div>
</div>
<!-- Step-by-Step Tutorial Guide -->
<div style="background: linear-gradient(135deg, #f8fafc 0%, #edf2f7 100%); border: 1px solid #cbd5e1; border-radius: 16px; padding: 40px; margin-bottom: 60px;">
<h3 style="font-size: 1.6rem; font-weight: 800; color: #0f172a; margin: 0 0 24px 0; text-align: center;">কীভাবে সহজে বাংলা পিডিএফ সম্পাদনা করবেন? | Step-by-Step Guide</h3>
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 20px;">
<div style="background: #ffffff; border-radius: 12px; padding: 22px; border-left: 4px solid #3b82f6;">
<div style="font-size: 0.85rem; font-weight: 800; color: #3b82f6; text-transform: uppercase; margin-bottom: 6px;">ধাপ ১</div>
<h4 style="font-size: 1.1rem; font-weight: 700; margin: 0 0 8px 0; color: #1e293b;">পিডিএফ ফাইল নির্বাচন</h4>
<p style="font-size: 0.9rem; color: #64748b; line-height: 1.6; margin: 0;">ড্র্যাগ-অ্যান্ড-ড্রপ করুন অথবা 'পিডিএফ ফাইল আপলোড করুন' বাটনে ক্লিক করে ডিভাইস থেকে ফাইল সিলেক্ট করুন।</p>
</div>
<div style="background: #ffffff; border-radius: 12px; padding: 22px; border-left: 4px solid #6366f1;">
<div style="font-size: 0.85rem; font-weight: 800; color: #6366f1; text-transform: uppercase; margin-bottom: 6px;">ধাপ ২</div>
<h4 style="font-size: 1.1rem; font-weight: 700; margin: 0 0 8px 0; color: #1e293b;">টেক্সট বা উপাদান নির্বাচন</h4>
<p style="font-size: 0.9rem; color: #64748b; line-height: 1.6; margin: 0;">যে লাইনটি পরিবর্তন করতে চান সেটির ওপর ক্লিক করুন। এডিটর স্বয়ংক্রিয়ভাবে ব্যাকগ্রাউন্ড মুছে নতুন টেক্সট লেখার সুযোগ দেবে।</p>
</div>
<div style="background: #ffffff; border-radius: 12px; padding: 22px; border-left: 4px solid #8b5cf6;">
<div style="font-size: 0.85rem; font-weight: 800; color: #8b5cf6; text-transform: uppercase; margin-bottom: 6px;">ধাপ ৩</div>
<h4 style="font-size: 1.1rem; font-weight: 700; margin: 0 0 8px 0; color: #1e293b;">ফন্ট ও ফরম্যাটিং</h4>
<p style="font-size: 0.9rem; color: #64748b; line-height: 1.6; margin: 0;">আপনার পছন্দমতো ফন্ট (যেমন Kalpurush), সাইজ এবং কালার নির্বাচন করুন। প্রয়োজন হলে সিগনেচার বা ছবি যোগ করুন।</p>
</div>
<div style="background: #ffffff; border-radius: 12px; padding: 22px; border-left: 4px solid #10b981;">
<div style="font-size: 0.85rem; font-weight: 800; color: #10b981; text-transform: uppercase; margin-bottom: 6px;">ধাপ ৪</div>
<h4 style="font-size: 1.1rem; font-weight: 700; margin: 0 0 8px 0; color: #1e293b;">তাত্ক্ষণিক ডাউনলোড</h4>
<p style="font-size: 0.9rem; color: #64748b; line-height: 1.6; margin: 0;">'ডাউনলোড' বাটনে চাপুন। কোনো ওয়াটারমার্ক ছাড়া সরাসরি হাই-রেজোলিউশন নতুন পিডিএফ ফাইলটি সংরক্ষণ করুন।</p>
</div>
</div>
</div>
<!-- Educational Deep Dive: Bengali Typography in PDFs -->
<div style="margin-bottom: 60px;">
<h3 style="font-size: 1.6rem; font-weight: 800; color: #0f172a; margin: 0 0 16px 0;">বাংলা পিডিএফ টাইপোগ্রাফি ও কারিগরি বৈশিষ্ট্য</h3>
<p style="font-size: 1rem; color: #475569; line-height: 1.8; margin-bottom: 16px;">
বাংলা একটি জটিল লিপি (Complex Text Script), যেখানে স্বরবর্ণের কার-চিহ্নগুলো ব্যঞ্জনবর্ণের পূর্বে, পরে বা নিচে বসে যুক্তাক্ষর গঠন করে। সাধারণ পিডিএফ এডিটরগুলো প্রতিটি গ্লিফকে আলাদা ক্যারেক্টার হিসেবে চিহ্নিত করতে গিয়ে যুক্তাক্ষর ভেঙে ফেলে। Bangla PDF Editor-এ আমরা HarfBuzz এবং উন্নত ওপেন-টাইপ শেপিং ইঞ্জিন ব্যবহার করি, যা বাংলা ভাষার স্বাভাবিক রূপ হুবহু ধরে রাখে।
</p>
<p style="font-size: 1rem; color: #475569; line-height: 1.8; margin-bottom: 0;">
এছাড়াও অফিস বা একাডেমিক প্রয়োজনে যদি একাধিক ফাইল একত্রিত করতে হয়, তবে আমাদের <a href="/merge-pdf" style="color: #4f46e5; font-weight: 600;">Merge PDF</a> টুল ব্যবহার করতে পারেন। বড় ফাইলের আকার ছোট করতে <a href="/compress-pdf" style="color: #4f46e5; font-weight: 600;">Compress PDF</a> এবং নির্দিষ্ট পেজ আলাদা করতে <a href="/split-pdf" style="color: #4f46e5; font-weight: 600;">Split PDF</a> টুল সার্বক্ষণিক প্রস্তুত।
</p>
</div>
<!-- Comprehensive FAQ Accordion/Cards -->
<div>
<h3 style="font-size: 1.6rem; font-weight: 800; color: #0f172a; margin: 0 0 24px 0; text-align: center;">সচরাচর জিজ্ঞাসিত প্রশ্নাবলী (FAQ)</h3>
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); gap: 20px;">
<div style="background: #f8fafc; border: 1px solid #e2e8f0; border-radius: 12px; padding: 22px;">
<h4 style="font-size: 1.05rem; font-weight: 700; color: #1e293b; margin: 0 0 8px 0;">❓ বাংলা পিডিএফ এডিটর কি সম্পূর্ণ বিনামূল্যে?</h4>
<p style="font-size: 0.95rem; color: #64748b; line-height: 1.7; margin: 0;">হ্যাঁ, আমাদের সব মূল টুলস (টেক্সট এডিট, ওসিআর, মার্জ, স্প্লিট, কম্প্রেস ইত্যাদি) ১০০% ফ্রি। কোনো ক্রেডিট কার্ড বা গোপন সাবস্ক্রিপশন ফি নেই।</p>
</div>
<div style="background: #f8fafc; border: 1px solid #e2e8f0; border-radius: 12px; padding: 22px;">
<h4 style="font-size: 1.05rem; font-weight: 700; color: #1e293b; margin: 0 0 8px 0;">❓ এডিট করার পর কি কোনো ওয়াটারমার্ক যোগ হবে?</h4>
<p style="font-size: 0.95rem; color: #64748b; line-height: 1.7; margin: 0;">না, Bangla PDF Editor ব্যবহার করে তৈরি বা সম্পাদিত কোনো পিডিএফে কোনো অযাচিত ওয়াটারমার্ক বা সাইটের লোগো যুক্ত করা হয় না। আপনার ফাইল সম্পূর্ণ পেশাদার দেখাবে।</p>
</div>
<div style="background: #f8fafc; border: 1px solid #e2e8f0; border-radius: 12px; padding: 22px;">
<h4 style="font-size: 1.05rem; font-weight: 700; color: #1e293b; margin: 0 0 8px 0;">❓ আমার আপলোড করা ডকুমেন্টের নিরাপত্তা কেমন?</h4>
<p style="font-size: 0.95rem; color: #64748b; line-height: 1.7; margin: 0;">আপনার ফাইল কঠোর এনক্রিপশনের মাধ্যমে প্রসেস করা হয়। আপনার এডিটিং সেশন শেষ হওয়া মাত্র অথবা সর্বোচ্চ ১ ঘণ্টার মধ্যে সার্ভার থেকে ফাইল চিরতরে মুছে ফেলা হয়।</p>
</div>
<div style="background: #f8fafc; border: 1px solid #e2e8f0; border-radius: 12px; padding: 22px;">
<h4 style="font-size: 1.05rem; font-weight: 700; color: #1e293b; margin: 0 0 8px 0;">❓ মোবাইল ফোন থেকেও কি এটি ব্যবহার করা যাবে?</h4>
<p style="font-size: 0.95rem; color: #64748b; line-height: 1.7; margin: 0;">হ্যাঁ, যেকোনো আধুনিক স্মার্টফোন ব্রাউজারে সাইটটি কাজ করে। তবে নিখুঁতভাবে টাইপিং ও ড্র্যাগ করার সুবিধার্থে বড় স্ক্রিন বা ডেক্সটপ মোড ব্যবহারের পরামর্শ দেওয়া হয়।</p>
</div>
</div>
</div>
</div>
</section>
<!-- ==============================================================
COMPREHENSIVE SITEWIDE FOOTER
Mandatory Publisher & AdSense Compliance Architecture
============================================================== -->
<footer style="background: #0f172a; color: #94a3b8; padding: 60px 20px 30px; border-top: 4px solid #4f46e5; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif; clear: both; width: 100%; box-sizing: border-box;">
<div style="max-width: 1200px; margin: 0 auto; display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 40px; text-align: left;">
<!-- Column 1: Core Tools -->
<div>
<h4 style="color: #ffffff; font-size: 1.1rem; font-weight: 700; margin: 0 0 20px 0; letter-spacing: 0.02em;">পিডিএফ টুলস | PDF Tools</h4>
<ul style="list-style: none; padding: 0; margin: 0; line-height: 2.2; font-size: 0.95rem;">
<li><a href="/edit-bengali-text" style="color: #94a3b8; text-decoration: none; transition: color 0.2s;" onmouseover="this.style.color='#ffffff'" onmouseout="this.style.color='#94a3b8'">Edit Bengali Text</a></li>
<li><a href="/ocr-bengali" style="color: #94a3b8; text-decoration: none; transition: color 0.2s;" onmouseover="this.style.color='#ffffff'" onmouseout="this.style.color='#94a3b8'">OCR Bengali PDF</a></li>
<li><a href="/merge-pdf" style="color: #94a3b8; text-decoration: none; transition: color 0.2s;" onmouseover="this.style.color='#ffffff'" onmouseout="this.style.color='#94a3b8'">Merge PDF</a></li>
<li><a href="/split-pdf" style="color: #94a3b8; text-decoration: none; transition: color 0.2s;" onmouseover="this.style.color='#ffffff'" onmouseout="this.style.color='#94a3b8'">Split PDF</a></li>
<li><a href="/compress-pdf" style="color: #94a3b8; text-decoration: none; transition: color 0.2s;" onmouseover="this.style.color='#ffffff'" onmouseout="this.style.color='#94a3b8'">Compress PDF</a></li>
</ul>
</div>
<!-- Column 2: Converters -->
<div>
<h4 style="color: #ffffff; font-size: 1.1rem; font-weight: 700; margin: 0 0 20px 0; letter-spacing: 0.02em;">কনভার্টারস | Converters</h4>
<ul style="list-style: none; padding: 0; margin: 0; line-height: 2.2; font-size: 0.95rem;">
<li><a href="/pdf-to-word" style="color: #94a3b8; text-decoration: none; transition: color 0.2s;" onmouseover="this.style.color='#ffffff'" onmouseout="this.style.color='#94a3b8'">PDF to Word (DOCX)</a></li>
<li><a href="/pdf-to-excel" style="color: #94a3b8; text-decoration: none; transition: color 0.2s;" onmouseover="this.style.color='#ffffff'" onmouseout="this.style.color='#94a3b8'">PDF to Excel (XLSX)</a></li>
<li><a href="/bijoy-unicode-converter" style="color: #94a3b8; text-decoration: none; transition: color 0.2s;" onmouseover="this.style.color='#ffffff'" onmouseout="this.style.color='#94a3b8'">Bijoy to Unicode</a></li>
<li><a href="/features/add-images-to-pdf" style="color: #94a3b8; text-decoration: none; transition: color 0.2s;" onmouseover="this.style.color='#ffffff'" onmouseout="this.style.color='#94a3b8'">Images to PDF</a></li>
</ul>
</div>
<!-- Column 3: Resources -->
<div>
<h4 style="color: #ffffff; font-size: 1.1rem; font-weight: 700; margin: 0 0 20px 0; letter-spacing: 0.02em;">রিসোর্স | Resources</h4>
<ul style="list-style: none; padding: 0; margin: 0; line-height: 2.2; font-size: 0.95rem;">
<li><a href="/download-free-bangla-fonts" style="color: #94a3b8; text-decoration: none; transition: color 0.2s;" onmouseover="this.style.color='#ffffff'" onmouseout="this.style.color='#94a3b8'">Bangla Fonts Hub</a></li>
<li><a href="/blog" style="color: #94a3b8; text-decoration: none; transition: color 0.2s;" onmouseover="this.style.color='#ffffff'" onmouseout="this.style.color='#94a3b8'">Technical Blog</a></li>
<li><a href="/tutorials" style="color: #94a3b8; text-decoration: none; transition: color 0.2s;" onmouseover="this.style.color='#ffffff'" onmouseout="this.style.color='#94a3b8'">Video & Guides</a></li>
<li><a href="/faq" style="color: #94a3b8; text-decoration: none; transition: color 0.2s;" onmouseover="this.style.color='#ffffff'" onmouseout="this.style.color='#94a3b8'">FAQs</a></li>
</ul>
</div>
<!-- Column 4: Company & Legal -->
<div>
<h4 style="color: #ffffff; font-size: 1.1rem; font-weight: 700; margin: 0 0 20px 0; letter-spacing: 0.02em;">কোম্পানি ও নীতিমালা | Legal</h4>
<ul style="list-style: none; padding: 0; margin: 0; line-height: 2.2; font-size: 0.95rem;">
<li><a href="/" style="color: #94a3b8; text-decoration: none; transition: color 0.2s;" onmouseover="this.style.color='#ffffff'" onmouseout="this.style.color='#94a3b8'">হোম | Home</a></li>
<li><a href="/about-us" style="color: #94a3b8; text-decoration: none; transition: color 0.2s;" onmouseover="this.style.color='#ffffff'" onmouseout="this.style.color='#94a3b8'">আমাদের সম্পর্কে | About Us</a></li>
<li><a href="/contact-us" style="color: #94a3b8; text-decoration: none; transition: color 0.2s;" onmouseover="this.style.color='#ffffff'" onmouseout="this.style.color='#94a3b8'">যোগাযোগ | Contact Us</a></li>
<li><a href="/privacy-policy" style="color: #94a3b8; text-decoration: none; transition: color 0.2s;" onmouseover="this.style.color='#ffffff'" onmouseout="this.style.color='#94a3b8'">গোপনীয়তা নীতি | Privacy Policy</a></li>
<li><a href="/terms-of-service" style="color: #94a3b8; text-decoration: none; transition: color 0.2s;" onmouseover="this.style.color='#ffffff'" onmouseout="this.style.color='#94a3b8'">ব্যবহারের শর্তাবলী | Terms</a></li>
<li><a href="/documentation" style="color: #94a3b8; text-decoration: none; transition: color 0.2s;" onmouseover="this.style.color='#ffffff'" onmouseout="this.style.color='#94a3b8'">ডকুমেন্টেশন | Docs</a></li>
</ul>
</div>
</div>
<!-- Bottom Copyright Bar -->
<div style="max-width: 1200px; margin: 40px auto 0; padding-top: 24px; border-top: 1px solid #1e293b; text-align: center; font-size: 0.9rem; color: #64748b; display: flex; flex-wrap: wrap; justify-content: space-between; align-items: center; gap: 15px;">
<p style="margin: 0;">© 2026 Bangla PDF Editor (banglapdfeditor.com). সর্বস্বত্ব সংরক্ষিত | All rights reserved.</p>
<p style="margin: 0; font-size: 0.85rem;">Designed for 100% Native Bengali Unicode & Document Security</p>
</div>
</footer>
<!-- ═══════════════════════════════════════════════════════════
MONETIZATION UI — Auth + Payment + Documents Modals
═══════════════════════════════════════════════════════════ -->
<style>
.mon-overlay{position:fixed;inset:0;background:rgba(0,0,0,.6);backdrop-filter:blur(4px);z-index:9000;display:none;align-items:center;justify-content:center}
.mon-overlay.open{display:flex}
.mon-modal{background:#1a1a2e;border:1px solid rgba(255,255,255,.12);border-radius:20px;padding:36px;width:460px;max-width:94vw;max-height:90vh;overflow-y:auto;position:relative;box-shadow:0 24px 60px rgba(0,0,0,.5)}
.mon-modal h2{font-size:22px;font-weight:800;color:#fff;margin:0 0 24px;text-align:center}
.mon-modal .tabs{display:flex;gap:0;margin-bottom:24px;background:rgba(255,255,255,.06);border-radius:10px;padding:4px}
.mon-modal .tab{flex:1;padding:8px;text-align:center;cursor:pointer;border-radius:8px;font-size:14px;font-weight:600;color:rgba(255,255,255,.5);transition:.2s}
.mon-modal .tab.active{background:linear-gradient(135deg,#6c3bec,#9b5de5);color:#fff}
.mon-field{margin-bottom:16px}
.mon-field label{display:block;font-size:13px;font-weight:600;color:rgba(255,255,255,.7);margin-bottom:6px}
.mon-field input{width:100%;background:rgba(255,255,255,.07);border:1px solid rgba(255,255,255,.15);border-radius:10px;padding:11px 14px;color:#fff;font-size:15px}
.mon-field input:focus{outline:none;border-color:#9b5de5}
.mon-btn{width:100%;padding:14px;background:linear-gradient(135deg,#6c3bec,#9b5de5);color:#fff;border:none;border-radius:12px;font-size:16px;font-weight:700;cursor:pointer;margin-top:8px;transition:.2s}
.mon-btn:hover{opacity:.9}
.mon-btn.secondary{background:rgba(255,255,255,.08);color:#e2e8f0}
.mon-err{background:rgba(229,62,62,.15);border:1px solid rgba(229,62,62,.3);color:#fc8181;padding:10px 14px;border-radius:8px;font-size:13px;margin-bottom:12px;display:none}
.mon-success{background:rgba(11,163,96,.15);border:1px solid rgba(11,163,96,.3);color:#68d391;padding:10px 14px;border-radius:8px;font-size:13px;margin-bottom:12px;display:none}
.pkg-grid{display:grid;grid-template-columns:1fr 1fr;gap:12px;margin-bottom:20px}
.pkg-opt{border:2px solid rgba(255,255,255,.1);border-radius:12px;padding:16px;cursor:pointer;text-align:center;transition:.2s}
.pkg-opt:hover,.pkg-opt.selected{border-color:#9b5de5;background:rgba(108,59,236,.15)}
.pkg-opt .name{font-weight:700;color:#fff;font-size:15px}
.pkg-opt .price{font-size:22px;font-weight:800;color:#9b5de5;margin:4px 0}
.pkg-opt .pages{font-size:12px;color:rgba(255,255,255,.5)}
.doc-item{display:flex;justify-content:space-between;align-items:center;padding:12px;border:1px solid rgba(255,255,255,.1);border-radius:10px;margin-bottom:8px}
.doc-item .name{font-size:14px;color:#e2e8f0;font-weight:500}
.doc-item .meta{font-size:12px;color:rgba(255,255,255,.4);margin-top:2px}
</style>
<!-- Auth Modal -->
<div class="mon-overlay" id="auth-modal">
<div class="mon-modal">
<button onclick="closeAuthModal()" style="position:absolute;top:14px;right:16px;background:none;border:none;color:rgba(255,255,255,.4);font-size:22px;cursor:pointer">✕</button>
<div class="tabs">
<div class="tab active" id="tab-login" onclick="switchAuthTab('login')">লগইন</div>
<div class="tab" id="tab-register" onclick="switchAuthTab('register')">রেজিস্ট্রেশন</div>
</div>
<div id="auth-err" class="mon-err"></div>
<div id="auth-success" class="mon-success"></div>
<!-- Login Form -->
<div id="form-login">
<button class="mon-btn" onclick="window.location.href='/api/auth/google/login'" style="background:white;color:#333;display:flex;align-items:center;justify-content:center;gap:12px;margin-bottom:16px;margin-top:10px;">
<img src="https://upload.wikimedia.org/wikipedia/commons/c/c1/Google_%22G%22_logo.svg" alt="G" width="18" loading="lazy"> Google দিয়ে চালিয়ে যান
</button>
<div style="display:flex;align-items:center;margin:16px 0 20px 0;">
<div style="flex:1;height:1px;background:rgba(255,255,255,.15);"></div>
<span style="padding:0 12px;color:rgba(255,255,255,.5);font-size:12px;">অথবা ইমেইল দিয়ে করুন</span>
<div style="flex:1;height:1px;background:rgba(255,255,255,.15);"></div>
</div>
<div class="mon-field"><label>ইমেইল</label><input type="email" id="login-email" placeholder="[email protected]"></div>
<div class="mon-field"><label>পাসওয়ার্ড</label><input type="password" id="login-password" placeholder="••••••••"></div>
<button class="mon-btn" onclick="submitLogin()">লগইন করুন →</button>
<p style="text-align:center;margin-top:20px;font-size:13px;color:rgba(255,255,255,.4)">অ্যাকাউন্ট নেই? <a href="#" onclick="switchAuthTab('register')" style="color:#9b5de5">রেজিস্ট্রেশন করুন</a></p>
</div>
<!-- Register Form -->
<div id="form-register" style="display:none">
<button class="mon-btn" onclick="window.location.href='/api/auth/google/login'" style="background:white;color:#333;display:flex;align-items:center;justify-content:center;gap:12px;margin-bottom:16px;margin-top:10px;">
<img src="https://upload.wikimedia.org/wikipedia/commons/c/c1/Google_%22G%22_logo.svg" alt="G" width="18" loading="lazy"> Google দিয়ে চালিয়ে যান
</button>
<div style="display:flex;align-items:center;margin:16px 0 20px 0;">
<div style="flex:1;height:1px;background:rgba(255,255,255,.15);"></div>
<span style="padding:0 12px;color:rgba(255,255,255,.5);font-size:12px;">অথবা ইমেইল দিয়ে করুন</span>
<div style="flex:1;height:1px;background:rgba(255,255,255,.15);"></div>
</div>
<div class="mon-field"><label>পুরো নাম</label><input type="text" id="reg-name" placeholder="আপনার নাম"></div>
<div class="mon-field"><label>ইমেইল</label><input type="email" id="reg-email" placeholder="[email protected]"></div>
<div class="mon-field"><label>ফোন (ঐচ্ছিক)</label><input type="tel" id="reg-phone" placeholder="01XXXXXXXXX"></div>
<div class="mon-field"><label>পাসওয়ার্ড</label><input type="password" id="reg-password" placeholder="কমপক্ষে ৮ অক্ষর"></div>
<button class="mon-btn" onclick="submitRegister()">অ্যাকাউন্ট তৈরি করুন →</button>
</div>
<!-- Verify Form -->
<div id="form-verify" style="display:none">
<p style="color:rgba(255,255,255,.7);text-align:center;margin-bottom:20px;font-size:14px">আপনার ইমেইলে ৬ সংখ্যার কোড পাঠানো হয়েছে</p>
<div class="mon-field"><label>যাচাই কোড</label><input type="text" id="verify-code" placeholder="123456" maxlength="6" style="text-align:center;font-size:24px;letter-spacing:8px"></div>
<button class="mon-btn" onclick="submitVerify()">যাচাই করুন ✓</button>
</div>
</div>
</div>
<!-- Payment Modal -->
<div class="mon-overlay" id="payment-modal">
<div class="mon-modal">
<button onclick="closePaymentModal()" style="position:absolute;top:14px;right:16px;background:none;border:none;color:rgba(255,255,255,.4);font-size:22px;cursor:pointer">✕</button>
<h2>💳 ক্রেডিট কিনুন</h2>
<div id="pay-err" class="mon-err"></div>
<div id="pay-success" class="mon-success"></div>
<div id="pay-step-1">
<p style="color:rgba(255,255,255,.6);font-size:13px;text-align:center;margin-bottom:16px">প্যাকেজ বেছে নিন:</p>
<div class="pkg-grid" id="pkg-grid"></div>
<div style="background:rgba(255,255,255,.05);border-radius:12px;padding:16px;margin-bottom:20px">
<p style="color:rgba(255,255,255,.5);font-size:12px;margin-bottom:8px">Send Money করুন:</p>
<div style="display:flex;gap:8px;margin-bottom:8px">
<span style="background:rgba(232,0,77,.15);color:#ff6b9d;padding:4px 12px;border-radius:20px;font-size:13px;font-weight:700">bKash</span>
<span style="background:rgba(242,105,0,.15);color:#ffab40;padding:4px 12px;border-radius:20px;font-size:13px;font-weight:700">Nagad</span>
<span style="background:rgba(0,121,255,.15);color:#63b3ed;padding:4px 12px;border-radius:20px;font-size:13px;font-weight:700">CellFin</span>
</div>
<div style="font-family:monospace;font-size:22px;font-weight:800;color:#9b5de5;letter-spacing:2px">01819617974</div>
<p style="font-size:11px;color:rgba(255,255,255,.3);margin-top:4px">⚠️ অবশ্যই Send Money করুন, পেমেন্ট নয়</p>
</div>
<button class="mon-btn" onclick="goToPayStep2()">পেমেন্ট করেছি →</button>
</div>
<div id="pay-step-2" style="display:none">
<p style="color:rgba(255,255,255,.6);font-size:13px;margin-bottom:16px">পেমেন্টের তথ্য দিন:</p>
<div class="mon-field">
<label>পেমেন্ট পদ্ধতি</label>
<select id="pay-method" style="width:100%;background:rgba(255,255,255,.07);border:1px solid rgba(255,255,255,.15);border-radius:10px;padding:11px 14px;color:#fff;font-size:15px">
<option value="bkash">bKash</option>
<option value="nagad">Nagad</option>
<option value="cellfin">CellFin</option>
</select>
</div>
<div class="mon-field"><label>ট্রানজেকশন আইডি (TrxID)</label><input type="text" id="pay-trxid" placeholder="যেমন: 8N6A02RTYP"></div>
<div class="mon-field"><label>প্রেরকের নম্বর</label><input type="tel" id="pay-sender" placeholder="01XXXXXXXXX"></div>
<div style="background:rgba(108,59,236,.1);border:1px solid rgba(108,59,236,.3);border-radius:10px;padding:12px;margin-bottom:16px;font-size:13px;color:rgba(255,255,255,.6)">
প্যাকেজ: <strong style="color:#9b5de5" id="pay-summary">—</strong>
</div>
<button class="mon-btn" onclick="submitPayment()">জমা দিন ✓</button>
<button class="mon-btn secondary" onclick="goToPayStep1()" style="margin-top:8px">← পেছনে যান</button>
</div>
</div>
</div>
<!-- Documents Panel -->
<div class="mon-overlay" id="docs-modal">
<div class="mon-modal" style="width:520px">
<button onclick="closeDocsPanel()" style="position:absolute;top:14px;right:16px;background:none;border:none;color:rgba(255,255,255,.4);font-size:22px;cursor:pointer">✕</button>
<h2>📄 আমার ডকুমেন্ট</h2>
<div id="docs-list"><p style="color:rgba(255,255,255,.4);text-align:center;padding:20px">লোড হচ্ছে...</p></div>
</div>
</div>
<script>
// ─── Token Storage ───────────────────────────────────────────
const AUTH_KEY = 'bpe_auth_token';
const USER_KEY = 'bpe_user';
function getToken(){ try{ return localStorage.getItem(AUTH_KEY); } catch(e){ return null; } }
function getUser(){ try{ return JSON.parse(localStorage.getItem(USER_KEY)||'null'); } catch(e){ return null; } }
function setAuth(token, user){ try{ localStorage.setItem(AUTH_KEY, token); localStorage.setItem(USER_KEY, JSON.stringify(user)); } catch(e){} }
function clearAuth(){ try{ localStorage.removeItem(AUTH_KEY); localStorage.removeItem(USER_KEY); } catch(e){} }
function apiHeaders(){
const h = {'Content-Type':'application/json'};
const t = getToken();
if(t) h['Authorization'] = 'Bearer ' + t;
return h;
}
// ─── Widget Update ───────────────────────────────────────────
let _balancePoll = null;
function updateWidget(){
const user = getUser();
const loginBtn = document.getElementById('auth-login-btn');
const regBtn = document.getElementById('auth-register-btn');
const nameEl = document.getElementById('auth-user-name');
const logoutBtn = document.getElementById('auth-logout-btn');
const creditDisplay = document.getElementById('credit-display');
if(user && getToken()){
loginBtn.style.display = 'none';
regBtn.style.display = 'none';
nameEl.style.display = 'flex';
const displayName = user.name || user.email.split('@')[0];
const initial = displayName.charAt(0).toUpperCase();
nameEl.innerHTML = `<div class="modern-user-avatar">${initial}</div><span>${displayName}</span>`;
logoutBtn.style.display = 'inline-flex';
creditDisplay.style.display = 'flex';
fetchBalance();
// Start auto-polling if not already running
if(!_balancePoll) {
_balancePoll = setInterval(() => fetchBalance(), 15000); // Check every 15s
}
} else {
loginBtn.style.display = 'inline-flex';
regBtn.style.display = 'inline-flex';
nameEl.style.display = 'none';
logoutBtn.style.display = 'none';
creditDisplay.style.display = 'none';
if(_balancePoll) {
clearInterval(_balancePoll);
_balancePoll = null;
}
}
}
function fetchBalance(){
if(!getToken()) return;
fetch('/api/credits/balance?t=' + Date.now(), {headers: apiHeaders()})
.then(r=>r.json()).then(d=>{
if(d.balance !== undefined)
document.getElementById('credit-count').textContent = d.balance;
}).catch(()=>{});
}
// ─── Auth Modal ──────────────────────────────────────────────
function openAuthModal(tab='login'){
document.getElementById('auth-modal').classList.add('open');
switchAuthTab(tab);
clearAuthMessages();
}
function closeAuthModal(){ document.getElementById('auth-modal').classList.remove('open'); }
function switchAuthTab(tab){
document.getElementById('form-login').style.display = tab==='login'?'block':'none';
document.getElementById('form-register').style.display = tab==='register'?'block':'none';
document.getElementById('form-verify').style.display = 'none';
document.getElementById('tab-login').classList.toggle('active', tab==='login');
document.getElementById('tab-register').classList.toggle('active', tab==='register');
clearAuthMessages();
}
function clearAuthMessages(){
document.getElementById('auth-err').style.display='none';
document.getElementById('auth-success').style.display='none';
}
function showAuthErr(msg){ const el=document.getElementById('auth-err'); el.textContent=msg; el.style.display='block'; }
function showAuthOk(msg){ const el=document.getElementById('auth-success'); el.textContent=msg; el.style.display='block'; }
let _verifyEmail = '';
function submitLogin(){
const email = document.getElementById('login-email').value.trim();
const password = document.getElementById('login-password').value;
if(!email || !password){ showAuthErr('ইমেইল ও পাসওয়ার্ড দিন'); return; }
fetch('/api/auth/login', {method:'POST', headers:apiHeaders(), body:JSON.stringify({email,password})})
.then(r=>r.json()).then(d=>{
if(d.token){
setAuth(d.token, d.user);
updateWidget();
closeAuthModal();
// Check for pending payments
let pending = null;
try { pending = sessionStorage.getItem('pendingPayment'); } catch(e){}
if(pending) {
try { sessionStorage.removeItem('pendingPayment'); } catch(e){}
// Logic to retry payment if needed
}
}
else showAuthErr(d.error || 'লগইন ব্যর্থ হয়েছে');
}).catch(()=>showAuthErr('নেটওয়ার্ক সমস্যা'));
}
function submitRegister(){
const name = document.getElementById('reg-name').value.trim();
const email = document.getElementById('reg-email').value.trim();
const phone = document.getElementById('reg-phone').value.trim();
const password = document.getElementById('reg-password').value;
if(!email || !password){ showAuthErr('ইমেইল ও পাসওয়ার্ড দিন'); return; }
fetch('/api/auth/register', {method:'POST', headers:apiHeaders(), body:JSON.stringify({name,email,phone,password})})
.then(r=>r.json()).then(d=>{
if(d.success){
if(d.token) setAuth(d.token, d.user);
updateWidget();
closeAuthModal();
// Process pending payment if any
let pendingStr = null;
try { pendingStr = sessionStorage.getItem('pendingPayment'); } catch(e){}
if(pendingStr) {
try { sessionStorage.removeItem('pendingPayment'); } catch(e){}
const paymentData = JSON.parse(pendingStr);
fetch('/api/credits/purchase', {method:'POST', headers:apiHeaders(), body:JSON.stringify(paymentData)})
.then(r=>r.json()).then(pd=>{
if(pd.success) {
openPaymentModal(); // show success screen
document.getElementById('pay-step-1').style.display='none';
document.getElementById('pay-step-2').style.display='none';
document.getElementById('pay-success').textContent = '✅ রেজিস্ট্রেশন এবং পেমেন্ট জমা হয়েছে! রেফ: ' + pd.reference_code;
document.getElementById('pay-success').style.display='block';
} else {
showAuthErr('রেজিস্ট্রেশন সফল, কিন্তু পেমেন্ট ব্যর্থ: ' + pd.error);
}
}).catch(()=>showAuthErr('রেজিস্ট্রেশন সফল, পেমেন্ট সাবমিট করতে সমস্যা।'));
} else {
showAuthOk('রেজিস্ট্রেশন সফল! আপনি লগইন হয়েছেন।');
}
} else showAuthErr(d.error || 'রেজিস্ট্রেশন ব্যর্থ হয়েছে');
}).catch(()=>showAuthErr('নেটওয়ার্ক সমস্যা'));
}
function submitVerify(){
const code = document.getElementById('verify-code').value.trim();
if(!code){ showAuthErr('কোড দিন'); return; }
fetch('/api/auth/verify-email', {method:'POST', headers:apiHeaders(), body:JSON.stringify({email:_verifyEmail, code})})
.then(r=>r.json()).then(d=>{
if(d.token){ setAuth(d.token, d.user); updateWidget(); closeAuthModal(); }
else showAuthErr(d.error || 'কোড ভুল হয়েছে');
}).catch(()=>showAuthErr('নেটওয়ার্ক সমস্যা'));
}
function logoutUser(){
fetch('/api/auth/logout', {method:'POST', headers:apiHeaders()}).catch(()=>{});
clearAuth(); updateWidget();
}
// ─── Payment Modal ───────────────────────────────────────────
const PACKAGES = [
{name:'Starter', pages:50, price:20, per:'০.৪০'},
{name:'Standard', pages:150, price:55, per:'০.৩৭'},
{name:'Pro', pages:300, price:100, per:'০.৩৩'},
{name:'Bulk', pages:1000, price:250, per:'০.২৫'},
];
let _selectedPkg = null;
function openPaymentModal(){
document.getElementById('payment-modal').classList.add('open');
renderPackages();
document.getElementById('pay-step-1').style.display='block';
document.getElementById('pay-step-2').style.display='none';
document.getElementById('pay-err').style.display='none';
document.getElementById('pay-success').style.display='none';
}
function closePaymentModal(){ document.getElementById('payment-modal').classList.remove('open'); }
function renderPackages(){
const grid = document.getElementById('pkg-grid');
grid.innerHTML = PACKAGES.map((p,i)=>`
<div class="pkg-opt ${_selectedPkg===i?'selected':''}" onclick="selectPkg(${i})">
<div class="name">${p.name}</div>
<div class="price">৳${p.price}</div>
<div class="pages">${p.pages} পেজ · ৳${p.per}/পেজ</div>
</div>`).join('');
}
function selectPkg(i){ _selectedPkg=i; renderPackages(); }
function goToPayStep2(){
if(_selectedPkg===null){ document.getElementById('pay-err').textContent='প্যাকেজ বেছে নিন'; document.getElementById('pay-err').style.display='block'; return; }
const p = PACKAGES[_selectedPkg];
document.getElementById('pay-summary').textContent = p.name + ' — ৳' + p.price + ' (' + p.pages + ' পেজ)';
document.getElementById('pay-step-1').style.display='none';
document.getElementById('pay-step-2').style.display='block';
}
function goToPayStep1(){
document.getElementById('pay-step-1').style.display='block';
document.getElementById('pay-step-2').style.display='none';
}
function submitPayment(){
const pkg = PACKAGES[_selectedPkg];
const method = document.getElementById('pay-method').value;
const trxid = document.getElementById('pay-trxid').value.trim();
const sender = document.getElementById('pay-sender').value.trim();
if(!trxid){ document.getElementById('pay-err').textContent='TrxID দিন'; document.getElementById('pay-err').style.display='block'; return; }
const paymentData = {
package_name:pkg.name, payment_method:method, transaction_id:trxid, sender_number:sender
};
if(!getToken()) {
try { sessionStorage.setItem('pendingPayment', JSON.stringify(paymentData)); } catch(e){}
closePaymentModal();
const title = document.querySelector('#auth-modal h2');
if(title) title.innerHTML = 'পেমেন্ট সম্পন্ন করতে <br> একাউন্ট তৈরি করুন';
openAuthModal('register');
return;
}
fetch('/api/credits/purchase', {method:'POST', headers:apiHeaders(), body:JSON.stringify(paymentData)}).then(r=>r.json()).then(d=>{
if(d.success){
document.getElementById('pay-success').textContent = '✅ জমা হয়েছে! রেফ: ' + d.reference_code + ' · ১-৬ ঘণ্টার মধ্যে ক্রেডিট পাবেন।';
document.getElementById('pay-success').style.display='block';
document.getElementById('pay-step-2').style.display='none';
} else {
document.getElementById('pay-err').textContent = d.error || 'জমা ব্যর্থ হয়েছে';
document.getElementById('pay-err').style.display='block';
}
}).catch(()=>{ document.getElementById('pay-err').textContent='নেটওয়ার্ক সমস্যা'; document.getElementById('pay-err').style.display='block'; });
}
// ─── Documents Panel ─────────────────────────────────────────
function openDocsPanel(){
document.getElementById('docs-modal').classList.add('open');
fetch('/api/documents', {headers:apiHeaders()})
.then(r=>r.json()).then(d=>{
const list = document.getElementById('docs-list');
if(!d.documents || d.documents.length===0){
list.innerHTML='<p style="color:rgba(255,255,255,.4);text-align:center;padding:20px">কোনো ডকুমেন্ট নেই</p>';
return;
}
list.innerHTML = d.documents.map(doc=>`
<div class="doc-item">
<div>
<a href="/?session_id=${doc.session_id}" class="name" style="text-decoration:none; display:block; cursor:pointer;" onclick="closeDocsPanel()">📄 ${doc.original_filename}</a>
<div class="meta">${doc.num_pages||0} পেজ · ${doc.pages_processed||0} প্রসেস · ${doc.created_at?doc.created_at.slice(0,10):'-'}</div>
</div>
<button onclick="deleteDoc(${doc.id}, this)" style="background:rgba(229,62,62,.15);color:#fc8181;border:1px solid rgba(229,62,62,.3);padding:5px 10px;border-radius:6px;cursor:pointer;font-size:12px">🗑</button>
</div>`).join('');
}).catch(()=>{ document.getElementById('docs-list').innerHTML='<p style="color:#fc8181;text-align:center">লোড ব্যর্থ</p>'; });
}
function closeDocsPanel(){ document.getElementById('docs-modal').classList.remove('open'); }
function deleteDoc(id, btn){
if(!confirm('এই ডকুমেন্ট মুছবেন?')) return;
fetch('/api/documents/'+id, {method:'DELETE', headers:apiHeaders()})
.then(r=>r.json()).then(d=>{ if(d.success) btn.closest('.doc-item').remove(); });
}
// ─── Fingerprint (simple canvas) ─────────────────────────────
(function(){
try{
const c = document.createElement('canvas');
const ctx = c.getContext('2d');
ctx.textBaseline='top'; ctx.font='14px Arial';
ctx.fillText('fingerprint',0,0);
window._bpe_fp = btoa(c.toDataURL()).slice(20,50);
} catch(e){ window._bpe_fp = 'unknown'; }
})();
// ─── Init ─────────────────────────────────────────────────────
document.addEventListener('DOMContentLoaded', function(){
updateWidget();
// Close modals on overlay click
['auth-modal','payment-modal','docs-modal'].forEach(id=>{
document.getElementById(id).addEventListener('click',function(e){ if(e.target===this) this.classList.remove('open'); });
});
// Handle Google OAuth callback
const urlParams = new URLSearchParams(window.location.search);
if (urlParams.get('auth_success') === 'google') {
fetch('/api/auth/me')
.then(r => r.json())
.then(d => {
if (d.success && d.token) {
setAuth(d.token, d.user);
updateWidget();
// Clean URL
window.history.replaceState({}, document.title, "/");
// Process pending payment if any
let pendingStr = null;
try { pendingStr = sessionStorage.getItem('pendingPayment'); } catch(e){}
if(pendingStr) {
try { sessionStorage.removeItem('pendingPayment'); } catch(e){}
const paymentData = JSON.parse(pendingStr);
fetch('/api/credits/purchase', {method:'POST', headers:apiHeaders(), body:JSON.stringify(paymentData)})
.then(r=>r.json()).then(pd=>{
if(pd.success) {
openPaymentModal(); // show success screen
document.getElementById('pay-step-1').style.display='none';
document.getElementById('pay-step-2').style.display='none';
document.getElementById('pay-success').textContent = '✅ লগইন এবং পেমেন্ট জমা হয়েছে! রেফ: ' + pd.reference_code;
document.getElementById('pay-success').style.display='block';
} else {
alert('Google লগইন সফল, কিন্তু পেমেন্ট ব্যর্থ: ' + pd.error);
}
}).catch(()=>alert('Google লগইন সফল, পেমেন্ট সাবমিট করতে সমস্যা।'));
}
}
});
} else if (urlParams.get('auth_error') === 'google_failed') {
showAuthErr('Google লগইন ব্যর্থ হয়েছে।');
openAuthModal('login');
window.history.replaceState({}, document.title, "/");
}
});
</script>
<!-- Mobile Warning Modal -->
<div id="mobileWarningModal" style="display:none; position:fixed; top:0; left:0; width:100%; height:100%; background:rgba(0,0,0,0.7); z-index:10000; align-items:center; justify-content:center;">
<div style="background:white; border-radius:12px; padding:24px; max-width:90%; width:400px; box-shadow:0 8px 32px rgba(0,0,0,0.3); text-align:center; box-sizing:border-box;">
<h3 style="margin:0 0 16px; font-size:1.3rem; color:#111827; font-weight:bold;">📱 Desktop Experience Recommended</h3>
<div style="background:#f0f9ff; border:1px solid #60a5fa; color:#1e40af; padding:15px; border-radius:8px; margin-bottom:20px; font-size:0.95rem; line-height:1.5; text-align:left;">
Welcome! This tool is optimized for desktop screens. While you can use it on mobile, the smaller screen size may make editing difficult.
<br><br>
If you choose to continue on your phone, we highly recommend <strong>pinching to zoom out</strong> before tapping a line to edit. This will ensure the text edit box stays fully visible on your screen.
</div>
<button onclick="dismissMobileWarning()" style="background:#2563eb; color:white; padding:12px 24px; border:none; border-radius:6px; font-weight:bold; font-size:1rem; cursor:pointer; width:100%; transition:background 0.2s;">
Got it, continue
</button>
</div>
</div>
<!-- UI Improvements -->
<link rel="stylesheet" href="/static/css/loading-spinners.css">
<script src="/static/js/ui-improvements.js"></script>
<script src="/static/js/keyboard-shortcuts.js"></script>
<!-- Mobile Toolbar Position Fix -->
<!-- MOBILE DEBUG: Diagnostic script (2026-01-31) -->
<script src="/static/js/mobile-debug.js" defer></script>
<!-- MOBILE TOOLBAR FIX: Added defer to load after app.js (2026-01-31) -->
<script src="/static/js/mobile-toolbar-fix.js" defer></script>
<!-- Mobile Coordinate Fix - 1000px viewport -->
<!-- History panel disabled - using simple linear undo/redo instead -->
<!-- <script src="/static/js/history-panel.js?v=20260215"></script> -->
<script src="/static/js/mobile-coordinate-fix.js?v=20260224"></script>
<!-- Mobile Force Gestures - ABSOLUTE LAST CSS - Nuclear option -->
<link rel="stylesheet" href="/static/css/mobile-force-gestures.css"></main><script>(function(){function c(){var b=a.contentDocument||(a.contentWindow&&a.contentWindow.document);if(b){var d=b.createElement('script');d.innerHTML="window.__CF$cv$params={r:'a4b10ff07a089489',t:'MTc5MjA5MDc4MA=='};var a=document.createElement('script');a.src='/cdn-cgi/challenge-platform/scripts/jsd/main.js';document.getElementsByTagName('head')[0].appendChild(a);";b.getElementsByTagName('head')[0].appendChild(d)}}if(document.body){var a=document.createElement('iframe');a.height=1;a.width=1;a.style.position='absolute';a.style.top=0;a.style.left=0;a.style.border='none';a.style.visibility='hidden';document.body.appendChild(a);if('loading'!==document.readyState)c();else if(window.addEventListener)document.addEventListener('DOMContentLoaded',c);else{var e=document.onreadystatechange||function(){};document.onreadystatechange=function(b){e(b);'loading'!==document.readyState&&(document.onreadystatechange=e,c())}}}})();</script></body></html>
| # |
Url |
Url |
Source |
Date |
| 1 |
https://www.banglapdfeditor.com/ |
|
2026-10-15 18:59:40 |
| 2 |
https://www.texarkanatwins.com/%25… |
|
2026-10-15 18:59:40 |
| 3 |
https://www.texarkanatwins.com/%25… |
|
2026-10-15 18:59:39 |
| 4 |
https://www.texarkanatwins.com/%25… |
|
2026-10-15 18:59:39 |
| 5 |
https://www.texarkanatwins.com/%25… |
|
2026-10-15 18:59:38 |
| 6 |
https://www.texarkanatwins.com/%25… |
|
2026-10-15 18:59:37 |
| 7 |
https://www.texarkanatwins.com/%25… |
|
2026-10-15 18:59:37 |
| 8 |
https://www.texarkanatwins.com/%25… |
|
2026-10-15 18:59:26 |
| 9 |
https://www.texarkanatwins.com/%25… |
|
2026-10-15 18:59:26 |
| 10 |
https://arinastar.ru/ |
|
2026-10-15 18:59:25 |
| 11 |
https://laskartimun.com/ |
|
2026-10-15 18:59:25 |
| 12 |
https://www.texarkanatwins.com/%25… |
|
2026-10-15 18:59:23 |
| 13 |
http://62138.casino/lips/59190/ |
|
2026-10-15 18:59:21 |
| 14 |
https://consent.youtube.com/m?cont… |
|
2026-10-15 18:59:19 |
| 15 |
https://consent.youtube.com/m?cont… |
|
2026-10-15 18:59:19 |
| 16 |
https://www.eporner.com/video-rkrH… |
|
2026-10-15 18:59:17 |
| 17 |
https://www.texarkanatwins.com/%25… |
|
2026-10-15 18:59:16 |
| 18 |
https://www.thebolditalic.com/?gi=… |
|
2026-10-15 18:59:15 |
| 19 |
https://www.youtube.com/watch?app=… |
|
2026-10-15 18:59:15 |
| 20 |
https://www.thebolditalic.com/?gi=… |
|
2026-10-15 18:59:15 |