{"id":345,"date":"2025-07-26T14:28:20","date_gmt":"2025-07-26T14:28:20","guid":{"rendered":"https:\/\/vijaypandit.in\/?page_id=345"},"modified":"2025-07-26T19:41:45","modified_gmt":"2025-07-26T19:41:45","slug":"base64-encoder","status":"publish","type":"page","link":"https:\/\/vijaypandit.in\/?page_id=345","title":{"rendered":"Base64 Encoder"},"content":{"rendered":"\n<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"UTF-8\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n    <title>Perfect Base64 Encoder<\/title>\n    <style>\n        \/* GeneratePress Compatible Base64 Encoder Styles *\/\n        .gp-base64-encoder-container {\n            max-width: 1200px;\n            margin: 0 auto;\n            padding: 20px;\n            background: #f5f5f5;\n            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;\n            color: #000;\n            min-height: 100vh;\n        }\n\n        .gp-base64-encoder-header {\n            text-align: center;\n            margin-bottom: 30px;\n            background: white;\n            padding: 30px;\n            border-radius: 12px;\n            box-shadow: 0 4px 12px rgba(0,0,0,0.1);\n        }\n\n        .gp-base64-encoder-icon {\n            display: inline-block;\n            background: linear-gradient(135deg, #3498db, #2980b9);\n            color: white;\n            padding: 15px 25px;\n            border-radius: 12px;\n            font-size: 24px;\n            font-weight: 900;\n            margin-bottom: 20px;\n            box-shadow: 0 4px 8px rgba(52, 152, 219, 0.3);\n        }\n\n        .gp-base64-encoder-title {\n            font-size: 36px;\n            font-weight: 900;\n            color: #000;\n            margin: 0 0 10px 0;\n        }\n\n        .gp-base64-encoder-subtitle {\n            font-size: 18px;\n            font-weight: 700;\n            color: #000;\n            margin: 0;\n        }\n\n        .gp-base64-encoder-description {\n            background: #CBCADC;\n            border-left: 4px solid #D97757;\n            padding: 15px 20px;\n            margin: 20px 0;\n            border-radius: 8px;\n            font-weight: 700;\n            color: #000;\n            line-height: 1.6;\n            transition: opacity 0.3s ease;\n        }\n\n        .gp-base64-encoder-tabs {\n            display: flex;\n            background: white;\n            border-radius: 12px 12px 0 0;\n            overflow: hidden;\n            box-shadow: 0 2px 8px rgba(0,0,0,0.1);\n            margin-bottom: 0;\n        }\n\n        .gp-base64-encoder-tab {\n            flex: 1;\n            padding: 15px 20px;\n            background: #f8f9fa;\n            border: none;\n            cursor: pointer;\n            font-family: 'Segoe UI';\n            font-weight: 700;\n            color: #000;\n            font-size: 16px;\n            transition: all 0.3s ease;\n            border-right: 1px solid #e9ecef;\n        }\n\n        .gp-base64-encoder-tab:last-child {\n            border-right: none;\n        }\n\n        .gp-base64-encoder-tab.active {\n            background: white;\n            color: #000;\n            font-weight: 900;\n            transform: translateY(-2px);\n        }\n\n        .gp-base64-encoder-tab:hover:not(.active) {\n            background: #e9ecef;\n        }\n\n        .gp-base64-encoder-content {\n            background: white;\n            border-radius: 0 0 12px 12px;\n            box-shadow: 0 4px 12px rgba(0,0,0,0.1);\n            overflow: hidden;\n        }\n\n        .gp-base64-encoder-tab-content {\n            display: none;\n            padding: 30px;\n        }\n\n        .gp-base64-encoder-tab-content.active {\n            display: block;\n        }\n\n        .gp-base64-encoder-main {\n            display: grid;\n            grid-template-columns: 1fr 1fr;\n            gap: 30px;\n            margin-bottom: 30px;\n        }\n\n        .gp-base64-encoder-section {\n            background: white;\n            padding: 25px;\n            border-radius: 12px;\n            box-shadow: 0 4px 12px rgba(0,0,0,0.1);\n        }\n\n        .gp-base64-encoder-section-title {\n            font-size: 20px;\n            font-weight: 900;\n            color: #000;\n            margin: 0 0 20px 0;\n            padding-bottom: 10px;\n            border-bottom: 2px solid #f0f0f0;\n        }\n\n        .gp-base64-encoder-label {\n            display: block;\n            font-weight: 700;\n            color: #000;\n            margin-bottom: 8px;\n            font-size: 14px;\n        }\n\n        .gp-base64-encoder-textarea,\n        .gp-base64-encoder-select,\n        .gp-base64-encoder-input {\n            width: 100%;\n            padding: 12px;\n            border: 2px solid #e9ecef;\n            border-radius: 8px;\n            font-family: 'Segoe UI';\n            font-weight: 700;\n            color: #000;\n            font-size: 14px;\n            transition: border-color 0.3s ease;\n            box-sizing: border-box;\n        }\n\n        .gp-base64-encoder-textarea {\n            min-height: 120px;\n            resize: vertical;\n        }\n\n        .gp-base64-encoder-textarea:focus,\n        .gp-base64-encoder-select:focus,\n        .gp-base64-encoder-input:focus {\n            outline: none;\n            border-color: #3498db;\n            box-shadow: 0 0 0 3px rgba(52, 152, 219, 0.1);\n        }\n\n        .gp-base64-encoder-button {\n            background: #000 !important;\n            color: white !important;\n            border: none;\n            padding: 12px 24px;\n            border-radius: 8px;\n            font-family: 'Segoe UI';\n            font-weight: 700;\n            font-size: 14px;\n            cursor: pointer;\n            transition: all 0.3s ease;\n            margin-right: 10px;\n            margin-bottom: 10px;\n        }\n\n        .gp-base64-encoder-button:hover {\n            background: #333 !important;\n            transform: translateY(-1px);\n            box-shadow: 0 4px 8px rgba(0,0,0,0.2);\n        }\n\n        .gp-base64-encoder-button:active {\n            transform: translateY(0);\n        }\n\n        .gp-base64-encoder-stats {\n            display: grid;\n            grid-template-columns: repeat(4, 1fr);\n            gap: 20px;\n            margin: 30px 0;\n        }\n\n        .gp-base64-encoder-stat {\n            background: white;\n            padding: 20px;\n            border-radius: 12px;\n            box-shadow: 0 4px 12px rgba(0,0,0,0.1);\n            text-align: center;\n        }\n\n        .gp-base64-encoder-stat-value {\n            font-size: 24px;\n            font-weight: 900;\n            color: #D97757;\n            margin-bottom: 5px;\n            display: block;\n        }\n\n        .gp-base64-encoder-stat-label {\n            font-size: 12px;\n            font-weight: 700;\n            color: #000;\n            text-transform: uppercase;\n            letter-spacing: 0.5px;\n        }\n\n        .gp-base64-encoder-file-drop {\n            border: 3px dashed #e9ecef;\n            border-radius: 12px;\n            padding: 40px;\n            text-align: center;\n            transition: all 0.3s ease;\n            margin-bottom: 20px;\n            background: #f8f9fa;\n            cursor: pointer;\n        }\n\n        .gp-base64-encoder-file-drop.dragover {\n            border-color: #3498db;\n            background: rgba(52, 152, 219, 0.05);\n        }\n\n        .gp-base64-encoder-file-drop-text {\n            font-weight: 700;\n            color: #000;\n            font-size: 16px;\n            margin-bottom: 10px;\n        }\n\n        .gp-base64-encoder-file-drop-hint {\n            font-weight: 700;\n            color: #000;\n            font-size: 12px;\n        }\n\n        .gp-base64-encoder-progress {\n            width: 100%;\n            height: 8px;\n            background: #e9ecef;\n            border-radius: 4px;\n            margin: 15px 0;\n            overflow: hidden;\n        }\n\n        .gp-base64-encoder-progress-bar {\n            height: 100%;\n            background: linear-gradient(90deg, #3498db, #2ecc71);\n            width: 0%;\n            transition: width 0.3s ease;\n        }\n\n        .gp-base64-encoder-batch-item {\n            background: #f8f9fa;\n            padding: 15px;\n            border-radius: 8px;\n            margin-bottom: 10px;\n            border-left: 4px solid #e9ecef;\n        }\n\n        .gp-base64-encoder-batch-item.success {\n            border-left-color: #2ecc71;\n        }\n\n        .gp-base64-encoder-batch-item.error {\n            border-left-color: #e74c3c;\n        }\n\n        .gp-base64-encoder-batch-item.processing {\n            border-left-color: #f39c12;\n        }\n\n        .gp-base64-encoder-examples {\n            background: white;\n            padding: 25px;\n            border-radius: 12px;\n            box-shadow: 0 4px 12px rgba(0,0,0,0.1);\n            margin-top: 30px;\n        }\n\n        .gp-base64-encoder-example {\n            margin-bottom: 20px;\n            padding: 15px;\n            background: #f8f9fa;\n            border-radius: 8px;\n            border-left: 4px solid #3498db;\n        }\n\n        .gp-base64-encoder-example-title {\n            font-weight: 900;\n            color: #000;\n            margin-bottom: 8px;\n            font-size: 14px;\n        }\n\n        .gp-base64-encoder-example-code {\n            font-family: 'Courier New', monospace;\n            font-size: 12px;\n            color: #000;\n            font-weight: 700;\n            word-break: break-all;\n            background: white;\n            padding: 8px;\n            border-radius: 4px;\n        }\n\n        .gp-base64-encoder-history {\n            background: white;\n            padding: 25px;\n            border-radius: 12px;\n            box-shadow: 0 4px 12px rgba(0,0,0,0.1);\n            margin-top: 30px;\n        }\n\n        .gp-base64-encoder-history-item {\n            padding: 12px;\n            border-bottom: 1px solid #e9ecef;\n            display: flex;\n            justify-content: space-between;\n            align-items: center;\n        }\n\n        .gp-base64-encoder-history-text {\n            font-weight: 700;\n            color: #000;\n            font-size: 14px;\n            flex: 1;\n            margin-right: 15px;\n            overflow: hidden;\n            text-overflow: ellipsis;\n            white-space: nowrap;\n        }\n\n        .gp-base64-encoder-history-time {\n            font-weight: 700;\n            color: #D97757;\n            font-size: 12px;\n        }\n\n        .gp-base64-encoder-controls {\n            display: flex;\n            flex-wrap: wrap;\n            gap: 10px;\n            margin-top: 20px;\n        }\n\n        .gp-base64-encoder-inline-controls {\n            display: grid;\n            grid-template-columns: repeat(2, 1fr);\n            gap: 15px;\n            margin-bottom: 20px;\n        }\n\n        .gp-base64-encoder-control-group {\n            display: flex;\n            flex-direction: column;\n        }\n\n        .gp-base64-encoder-notification {\n            position: fixed;\n            top: 20px;\n            right: 20px;\n            background: #2ecc71;\n            color: white;\n            padding: 15px 20px;\n            border-radius: 8px;\n            font-weight: 700;\n            z-index: 1000;\n            transform: translateX(400px);\n            transition: transform 0.3s ease;\n        }\n\n        .gp-base64-encoder-notification.show {\n            transform: translateX(0);\n        }\n\n        .gp-base64-encoder-notification.error {\n            background: #e74c3c;\n        }\n\n        @media (max-width: 768px) {\n            .gp-base64-encoder-container {\n                padding: 15px;\n            }\n\n            .gp-base64-encoder-main {\n                grid-template-columns: 1fr;\n                gap: 20px;\n            }\n\n            .gp-base64-encoder-stats {\n                grid-template-columns: repeat(2, 1fr);\n                gap: 15px;\n            }\n\n            .gp-base64-encoder-tabs {\n                flex-direction: column;\n            }\n\n            .gp-base64-encoder-tab {\n                border-right: none;\n                border-bottom: 1px solid #e9ecef;\n            }\n\n            .gp-base64-encoder-tab:last-child {\n                border-bottom: none;\n            }\n\n            .gp-base64-encoder-title {\n                font-size: 28px;\n            }\n\n            .gp-base64-encoder-inline-controls {\n                grid-template-columns: 1fr;\n            }\n        }\n\n        @media (max-width: 480px) {\n            .gp-base64-encoder-stats {\n                grid-template-columns: repeat(2, 1fr);\n            }\n\n            .gp-base64-encoder-controls {\n                flex-direction: column;\n            }\n\n            .gp-base64-encoder-button {\n                margin-right: 0;\n                width: 100%;\n            }\n        }\n    <\/style>\n<\/head>\n<body>\n    <div class=\"gp-base64-encoder-container\">\n        <header class=\"gp-base64-encoder-header\">\n            <div class=\"gp-base64-encoder-icon\">\u2192B64<\/div>\n            <h1 class=\"gp-base64-encoder-title\">Perfect Base64 Encoder<\/h1>\n            <p class=\"gp-base64-encoder-subtitle\">Advanced encoding tool with multiple formats and batch processing<\/p>\n            <div class=\"gp-base64-encoder-description\" id=\"description\">\n                Base64 encoding converts binary data into ASCII text using 64 printable characters. Essential for web development, data transmission, and embedding files in HTML\/CSS.\n            <\/div>\n        <\/header>\n\n        <div class=\"gp-base64-encoder-stats\" id=\"stats\">\n            <div class=\"gp-base64-encoder-stat\">\n                <span class=\"gp-base64-encoder-stat-value\" id=\"totalProcessed\">0<\/span>\n                <span class=\"gp-base64-encoder-stat-label\">Processed<\/span>\n            <\/div>\n            <div class=\"gp-base64-encoder-stat\">\n                <span class=\"gp-base64-encoder-stat-value\" id=\"inputSize\">0<\/span>\n                <span class=\"gp-base64-encoder-stat-label\">Input Bytes<\/span>\n            <\/div>\n            <div class=\"gp-base64-encoder-stat\">\n                <span class=\"gp-base64-encoder-stat-value\" id=\"outputSize\">0<\/span>\n                <span class=\"gp-base64-encoder-stat-label\">Output Bytes<\/span>\n            <\/div>\n            <div class=\"gp-base64-encoder-stat\">\n                <span class=\"gp-base64-encoder-stat-value\" id=\"compressionRatio\">0%<\/span>\n                <span class=\"gp-base64-encoder-stat-label\">Size Change<\/span>\n            <\/div>\n            <div class=\"gp-base64-encoder-stat\">\n                <span class=\"gp-base64-encoder-stat-value\" id=\"processTime\">0ms<\/span>\n                <span class=\"gp-base64-encoder-stat-label\">Process Time<\/span>\n            <\/div>\n            <div class=\"gp-base64-encoder-stat\">\n                <span class=\"gp-base64-encoder-stat-value\" id=\"filesProcessed\">0<\/span>\n                <span class=\"gp-base64-encoder-stat-label\">Files Done<\/span>\n            <\/div>\n            <div class=\"gp-base64-encoder-stat\">\n                <span class=\"gp-base64-encoder-stat-value\" id=\"avgSpeed\">0<\/span>\n                <span class=\"gp-base64-encoder-stat-label\">KB\/s<\/span>\n            <\/div>\n            <div class=\"gp-base64-encoder-stat\">\n                <span class=\"gp-base64-encoder-stat-value\" id=\"successRate\">100%<\/span>\n                <span class=\"gp-base64-encoder-stat-label\">Success Rate<\/span>\n            <\/div>\n        <\/div>\n\n        <div class=\"gp-base64-encoder-tabs\">\n            <button class=\"gp-base64-encoder-tab active\" data-tab=\"text\">Text Encoding<\/button>\n            <button class=\"gp-base64-encoder-tab\" data-tab=\"file\">File Encoding<\/button>\n            <button class=\"gp-base64-encoder-tab\" data-tab=\"batch\">Batch Processing<\/button>\n            <button class=\"gp-base64-encoder-tab\" data-tab=\"url\">URL Encoding<\/button>\n        <\/div>\n\n        <div class=\"gp-base64-encoder-content\">\n            <!-- Text Encoding Tab -->\n            <div class=\"gp-base64-encoder-tab-content active\" id=\"textTab\">\n                <div class=\"gp-base64-encoder-main\">\n                    <div class=\"gp-base64-encoder-section\">\n                        <h3 class=\"gp-base64-encoder-section-title\">Input Text<\/h3>\n                        \n                        <div class=\"gp-base64-encoder-inline-controls\">\n                            <div class=\"gp-base64-encoder-control-group\">\n                                <label class=\"gp-base64-encoder-label\" for=\"inputEncoding\">Input Encoding<\/label>\n                                <select class=\"gp-base64-encoder-select\" id=\"inputEncoding\">\n                                    <option value=\"utf8\">UTF-8<\/option>\n                                    <option value=\"ascii\">ASCII<\/option>\n                                    <option value=\"latin1\">Latin-1<\/option>\n                                    <option value=\"utf16\">UTF-16<\/option>\n                                    <option value=\"binary\">Binary<\/option>\n                                <\/select>\n                            <\/div>\n                            <div class=\"gp-base64-encoder-control-group\">\n                                <label class=\"gp-base64-encoder-label\">\n                                    <input type=\"checkbox\" id=\"compressText\" style=\"margin-right: 8px;\">\n                                    Compress before encoding\n                                <\/label>\n                            <\/div>\n                        <\/div>\n\n                        <label class=\"gp-base64-encoder-label\" for=\"inputText\">Enter your text:<\/label>\n                        <textarea class=\"gp-base64-encoder-textarea\" id=\"inputText\" placeholder=\"Enter text to encode...\"><\/textarea>\n                    <\/div>\n\n                    <div class=\"gp-base64-encoder-section\">\n                        <h3 class=\"gp-base64-encoder-section-title\">Output &#038; Controls<\/h3>\n                        \n                        <div class=\"gp-base64-encoder-inline-controls\">\n                            <div class=\"gp-base64-encoder-control-group\">\n                                <label class=\"gp-base64-encoder-label\" for=\"outputFormat\">Output Format<\/label>\n                                <select class=\"gp-base64-encoder-select\" id=\"outputFormat\">\n                                    <option value=\"standard\">Standard Base64<\/option>\n                                    <option value=\"urlsafe\">URL-Safe Base64<\/option>\n                                    <option value=\"mime\">MIME Base64<\/option>\n                                    <option value=\"pem\">PEM Format<\/option>\n                                    <option value=\"custom\">Custom Line Length<\/option>\n                                <\/select>\n                            <\/div>\n                            <div class=\"gp-base64-encoder-control-group\">\n                                <label class=\"gp-base64-encoder-label\" for=\"lineLength\">Line Length<\/label>\n                                <input type=\"number\" class=\"gp-base64-encoder-input\" id=\"lineLength\" value=\"76\" min=\"0\" max=\"1000\">\n                            <\/div>\n                        <\/div>\n\n                        <label class=\"gp-base64-encoder-label\" for=\"outputText\">Encoded result:<\/label>\n                        <textarea class=\"gp-base64-encoder-textarea\" id=\"outputText\" readonly placeholder=\"Encoded text will appear here...\"><\/textarea>\n                        \n                        <div class=\"gp-base64-encoder-controls\">\n                            <button class=\"gp-base64-encoder-button\" onclick=\"encodeText()\">Encode<\/button>\n                            <button class=\"gp-base64-encoder-button\" onclick=\"decodeText()\">Decode<\/button>\n                            <button class=\"gp-base64-encoder-button\" onclick=\"copyToClipboard('outputText')\">Copy<\/button>\n                            <button class=\"gp-base64-encoder-button\" onclick=\"clearText()\">Clear<\/button>\n                            <button class=\"gp-base64-encoder-button\" onclick=\"downloadResult('text')\">Download<\/button>\n                            <button class=\"gp-base64-encoder-button\" onclick=\"undoOperation()\">Undo<\/button>\n                            <button class=\"gp-base64-encoder-button\" onclick=\"redoOperation()\">Redo<\/button>\n                        <\/div>\n                    <\/div>\n                <\/div>\n            <\/div>\n\n            <!-- File Encoding Tab -->\n            <div class=\"gp-base64-encoder-tab-content\" id=\"fileTab\">\n                <div class=\"gp-base64-encoder-main\">\n                    <div class=\"gp-base64-encoder-section\">\n                        <h3 class=\"gp-base64-encoder-section-title\">File Input<\/h3>\n                        \n                        <div class=\"gp-base64-encoder-file-drop\" id=\"fileDrop\">\n                            <div class=\"gp-base64-encoder-file-drop-text\">Drop files here or click to select<\/div>\n                            <div class=\"gp-base64-encoder-file-drop-hint\">Max file size: 50MB | Supports all file types<\/div>\n                            <input type=\"file\" id=\"fileInput\" style=\"display: none;\" multiple>\n                        <\/div>\n\n                        <div class=\"gp-base64-encoder-inline-controls\">\n                            <div class=\"gp-base64-encoder-control-group\">\n                                <label class=\"gp-base64-encoder-label\">\n                                    <input type=\"checkbox\" id=\"createDataURI\" style=\"margin-right: 8px;\" checked>\n                                    Create Data URI\n                                <\/label>\n                            <\/div>\n                            <div class=\"gp-base64-encoder-control-group\">\n                                <label class=\"gp-base64-encoder-label\">\n                                    <input type=\"checkbox\" id=\"detectMimeType\" style=\"margin-right: 8px;\" checked>\n                                    Auto-detect MIME type\n                                <\/label>\n                            <\/div>\n                        <\/div>\n\n                        <div id=\"fileList\"><\/div>\n                    <\/div>\n\n                    <div class=\"gp-base64-encoder-section\">\n                        <h3 class=\"gp-base64-encoder-section-title\">File Output<\/h3>\n                        \n                        <label class=\"gp-base64-encoder-label\" for=\"fileOutput\">Encoded file:<\/label>\n                        <textarea class=\"gp-base64-encoder-textarea\" id=\"fileOutput\" readonly placeholder=\"Encoded file will appear here...\"><\/textarea>\n                        \n                        <div class=\"gp-base64-encoder-controls\">\n                            <button class=\"gp-base64-encoder-button\" onclick=\"copyToClipboard('fileOutput')\">Copy<\/button>\n                            <button class=\"gp-base64-encoder-button\" onclick=\"downloadResult('file')\">Download<\/button>\n                            <button class=\"gp-base64-encoder-button\" onclick=\"clearFiles()\">Clear<\/button>\n                        <\/div>\n                    <\/div>\n                <\/div>\n            <\/div>\n\n            <!-- Batch Processing Tab -->\n            <div class=\"gp-base64-encoder-tab-content\" id=\"batchTab\">\n                <div class=\"gp-base64-encoder-section\">\n                    <h3 class=\"gp-base64-encoder-section-title\">Batch Processing<\/h3>\n                    \n                    <div class=\"gp-base64-encoder-file-drop\" id=\"batchFileDrop\">\n                        <div class=\"gp-base64-encoder-file-drop-text\">Drop multiple files for batch processing<\/div>\n                        <div class=\"gp-base64-encoder-file-drop-hint\">Process up to 100 files simultaneously<\/div>\n                        <input type=\"file\" id=\"batchFileInput\" style=\"display: none;\" multiple>\n                    <\/div>\n\n                    <div class=\"gp-base64-encoder-progress\">\n                        <div class=\"gp-base64-encoder-progress-bar\" id=\"batchProgress\"><\/div>\n                    <\/div>\n\n                    <div class=\"gp-base64-encoder-controls\">\n                        <button class=\"gp-base64-encoder-button\" onclick=\"processBatch()\">Process Batch<\/button>\n                        <button class=\"gp-base64-encoder-button\" onclick=\"downloadBatchResults()\">Download All<\/button>\n                        <button class=\"gp-base64-encoder-button\" onclick=\"clearBatch()\">Clear Batch<\/button>\n                    <\/div>\n\n                    <div id=\"batchResults\"><\/div>\n                <\/div>\n            <\/div>\n\n            <!-- URL Encoding Tab -->\n            <div class=\"gp-base64-encoder-tab-content\" id=\"urlTab\">\n                <div class=\"gp-base64-encoder-main\">\n                    <div class=\"gp-base64-encoder-section\">\n                        <h3 class=\"gp-base64-encoder-section-title\">URL Input<\/h3>\n                        \n                        <div class=\"gp-base64-encoder-inline-controls\">\n                            <div class=\"gp-base64-encoder-control-group\">\n                                <label class=\"gp-base64-encoder-label\">\n                                    <input type=\"radio\" name=\"urlMode\" value=\"full\" checked style=\"margin-right: 8px;\">\n                                    Encode full URL\n                                <\/label>\n                            <\/div>\n                            <div class=\"gp-base64-encoder-control-group\">\n                                <label class=\"gp-base64-encoder-label\">\n                                    <input type=\"radio\" name=\"urlMode\" value=\"params\" style=\"margin-right: 8px;\">\n                                    Encode parameters only\n                                <\/label>\n                            <\/div>\n                        <\/div>\n\n                        <label class=\"gp-base64-encoder-label\" for=\"urlInput\">Enter URL:<\/label>\n                        <textarea class=\"gp-base64-encoder-textarea\" id=\"urlInput\" placeholder=\"https:\/\/example.com?param=value\"><\/textarea>\n                    <\/div>\n\n                    <div class=\"gp-base64-encoder-section\">\n                        <h3 class=\"gp-base64-encoder-section-title\">URL Output<\/h3>\n                        \n                        <label class=\"gp-base64-encoder-label\" for=\"urlOutput\">Encoded URL:<\/label>\n                        <textarea class=\"gp-base64-encoder-textarea\" id=\"urlOutput\" readonly placeholder=\"Encoded URL will appear here...\"><\/textarea>\n                        \n                        <div class=\"gp-base64-encoder-controls\">\n                            <button class=\"gp-base64-encoder-button\" onclick=\"encodeURL()\">Encode URL<\/button>\n                            <button class=\"gp-base64-encoder-button\" onclick=\"decodeURL()\">Decode URL<\/button>\n                            <button class=\"gp-base64-encoder-button\" onclick=\"copyToClipboard('urlOutput')\">Copy<\/button>\n                            <button class=\"gp-base64-encoder-button\" onclick=\"clearURL()\">Clear<\/button>\n                        <\/div>\n                    <\/div>\n                <\/div>\n            <\/div>\n        <\/div>\n\n        <!-- Format Examples -->\n        <div class=\"gp-base64-encoder-examples\">\n            <h3 class=\"gp-base64-encoder-section-title\">Format Examples<\/h3>\n            <div id=\"formatExamples\">\n                <div class=\"gp-base64-encoder-example\">\n                    <div class=\"gp-base64-encoder-example-title\">Standard Base64<\/div>\n                    <div class=\"gp-base64-encoder-example-code\">SGVsbG8gV29ybGQ=<\/div>\n                <\/div>\n                <div class=\"gp-base64-encoder-example\">\n                    <div class=\"gp-base64-encoder-example-title\">URL-Safe Base64<\/div>\n                    <div class=\"gp-base64-encoder-example-code\">SGVsbG8gV29ybGQ<\/div>\n                <\/div>\n                <div class=\"gp-base64-encoder-example\">\n                    <div class=\"gp-base64-encoder-example-title\">MIME Base64 (76 chars\/line)<\/div>\n                    <div class=\"gp-base64-encoder-example-code\">VGhpcyBpcyBhIGxvbmcgZXhhbXBsZSB0ZXh0IHRoYXQgd2lsbCBiZSBicm9rZW4gaW50byBtdWx0<br>aXBsZSBsaW5lcyBmb3IgTUlNRSBmb3JtYXR0aW5n<\/div>\n                <\/div>\n                <div class=\"gp-base64-encoder-example\">\n                    <div class=\"gp-base64-encoder-example-title\">Data URI<\/div>\n                    <div class=\"gp-base64-encoder-example-code\">data:text\/plain;base64,SGVsbG8gV29ybGQ=<\/div>\n                <\/div>\n            <\/div>\n        <\/div>\n\n        <!-- Operation History -->\n        <div class=\"gp-base64-encoder-history\">\n            <h3 class=\"gp-base64-encoder-section-title\">Operation History<\/h3>\n            <div id=\"operationHistory\">\n                <div style=\"text-align: center; color: #000; font-weight: 700; padding: 20px;\">\n                    No operations performed yet\n                <\/div>\n            <\/div>\n        <\/div>\n    <\/div>\n\n    <div class=\"gp-base64-encoder-notification\" id=\"notification\"><\/div>\n\n    <script>\n        \/\/ Global state management\n        const state = {\n            currentTab: 'text',\n            history: [],\n            historyIndex: -1,\n            stats: {\n                totalProcessed: 0,\n                inputSize: 0,\n                outputSize: 0,\n                processTime: 0,\n                filesProcessed: 0,\n                successCount: 0,\n                errorCount: 0\n            },\n            batchFiles: [],\n            batchResults: [],\n            operationHistory: []\n        };\n\n        \/\/ Educational descriptions that rotate\n        const descriptions = [\n            \"Base64 encoding converts binary data into ASCII text using 64 printable characters. Essential for web development, data transmission, and embedding files in HTML\/CSS.\",\n            \"URL-Safe Base64 replaces '+' with '-' and '\/' with '_', making it safe for URLs and filenames without percent-encoding.\",\n            \"MIME Base64 breaks encoded data into 76-character lines with CRLF line endings, perfect for email attachments and HTTP headers.\",\n            \"Data URIs embed files directly in HTML\/CSS using base64, reducing HTTP requests but increasing document size by ~33%.\",\n            \"PEM format wraps base64 data with headers and 64-character lines, commonly used for certificates and cryptographic keys.\",\n            \"Base64 increases data size by approximately 33% due to encoding 3 bytes as 4 ASCII characters with padding.\",\n            \"Custom line lengths help format base64 for specific applications - shorter lines for readability, longer for efficiency.\",\n            \"Compression before encoding can significantly reduce final size for text data, but may not help with already-compressed files.\"\n        ];\n\n        let descriptionIndex = 0;\n\n        \/\/ Initialize the application\n        document.addEventListener('DOMContentLoaded', function() {\n            initializeTabs();\n            initializeFileHandlers();\n            updateStats();\n            rotateDescription();\n            \n            \/\/ Set up real-time encoding for text\n            document.getElementById('inputText').addEventListener('input', debounce(encodeText, 500));\n            \n            \/\/ Update examples when format changes\n            document.getElementById('outputFormat').addEventListener('change', updateFormatExamples);\n            document.getElementById('lineLength').addEventListener('input', updateFormatExamples);\n            \n            \/\/ Initialize format examples\n            updateFormatExamples();\n        });\n\n        \/\/ Tab management\n        function initializeTabs() {\n            const tabs = document.querySelectorAll('.gp-base64-encoder-tab');\n            const contents = document.querySelectorAll('.gp-base64-encoder-tab-content');\n\n            tabs.forEach(tab => {\n                tab.addEventListener('click', () => {\n                    const tabName = tab.dataset.tab;\n                    \n                    \/\/ Update active states\n                    tabs.forEach(t => t.classList.remove('active'));\n                    contents.forEach(c => c.classList.remove('active'));\n                    \n                    tab.classList.add('active');\n                    document.getElementById(tabName + 'Tab').classList.add('active');\n                    \n                    state.currentTab = tabName;\n                });\n            });\n        }\n\n        \/\/ File handling initialization\n        function initializeFileHandlers() {\n            setupFileDrop('fileDrop', 'fileInput', handleFiles);\n            setupFileDrop('batchFileDrop', 'batchFileInput', handleBatchFiles);\n        }\n\n        function setupFileDrop(dropId, inputId, handler) {\n            const dropZone = document.getElementById(dropId);\n            const fileInput = document.getElementById(inputId);\n\n            dropZone.addEventListener('click', () => fileInput.click());\n            \n            dropZone.addEventListener('dragover', (e) => {\n                e.preventDefault();\n                dropZone.classList.add('dragover');\n            });\n\n            dropZone.addEventListener('dragleave', () => {\n                dropZone.classList.remove('dragover');\n            });\n\n            dropZone.addEventListener('drop', (e) => {\n                e.preventDefault();\n                dropZone.classList.remove('dragover');\n                handler(e.dataTransfer.files);\n            });\n\n            fileInput.addEventListener('change', (e) => {\n                handler(e.target.files);\n            });\n        }\n\n        \/\/ Core encoding functions\n        function encodeText() {\n            const startTime = performance.now();\n            const input = document.getElementById('inputText').value;\n            const format = document.getElementById('outputFormat').value;\n            const compress = document.getElementById('compressText').checked;\n            const encoding = document.getElementById('inputEncoding').value;\n            \n            if (!input.trim()) {\n                document.getElementById('outputText').value = '';\n                return;\n            }\n\n            try {\n                let processedInput = input;\n                \n                \/\/ Apply compression if requested\n                if (compress) {\n                    processedInput = compressString(input);\n                }\n\n                \/\/ Convert to appropriate encoding\n                const bytes = encodeString(processedInput, encoding);\n                \n                \/\/ Apply base64 encoding with format\n                let result = formatBase64(btoa(bytes), format);\n                \n                document.getElementById('outputText').value = result;\n                \n                const endTime = performance.now();\n                updateStatsAfterOperation(input.length, result.length, endTime - startTime, true);\n                addToHistory('encode', input.substring(0, 50) + '...', result.substring(0, 50) + '...', endTime - startTime);\n                \n                showNotification('Text encoded successfully!');\n                \n            } catch (error) {\n                showNotification('Encoding failed: ' + error.message, 'error');\n                updateStatsAfterOperation(0, 0, 0, false);\n            }\n        }\n\n        function decodeText() {\n            const startTime = performance.now();\n            const input = document.getElementById('outputText').value;\n            \n            if (!input.trim()) {\n                document.getElementById('inputText').value = '';\n                return;\n            }\n\n            try {\n                \/\/ Clean the input (remove whitespace and data URI prefix if present)\n                let cleanInput = input.replace(\/\\s\/g, '');\n                if (cleanInput.startsWith('data:')) {\n                    const commaIndex = cleanInput.indexOf(',');\n                    if (commaIndex !== -1) {\n                        cleanInput = cleanInput.substring(commaIndex + 1);\n                    }\n                }\n\n                const result = atob(cleanInput);\n                document.getElementById('inputText').value = result;\n                \n                const endTime = performance.now();\n                updateStatsAfterOperation(input.length, result.length, endTime - startTime, true);\n                addToHistory('decode', input.substring(0, 50) + '...', result.substring(0, 50) + '...', endTime - startTime);\n                \n                showNotification('Text decoded successfully!');\n                \n            } catch (error) {\n                showNotification('Decoding failed: Invalid Base64 input', 'error');\n                updateStatsAfterOperation(0, 0, 0, false);\n            }\n        }\n\n        function handleFiles(files) {\n            const fileList = document.getElementById('fileList');\n            fileList.innerHTML = '';\n            \n            Array.from(files).forEach(file => {\n                if (file.size > 50 * 1024 * 1024) { \/\/ 50MB limit\n                    showNotification(`File ${file.name} is too large (max 50MB)`, 'error');\n                    return;\n                }\n                \n                const fileItem = document.createElement('div');\n                fileItem.className = 'gp-base64-encoder-batch-item';\n                fileItem.innerHTML = `\n                    <strong>${file.name}<\/strong> (${formatFileSize(file.size)}) - ${file.type || 'Unknown type'}\n                `;\n                fileList.appendChild(fileItem);\n                \n                processFile(file);\n            });\n        }\n\n        function processFile(file) {\n            const startTime = performance.now();\n            const reader = new FileReader();\n            \n            reader.onload = function(e) {\n                try {\n                    const arrayBuffer = e.target.result;\n                    const bytes = new Uint8Array(arrayBuffer);\n                    let binary = '';\n                    for (let i = 0; i < bytes.length; i++) {\n                        binary += String.fromCharCode(bytes[i]);\n                    }\n                    \n                    let result = btoa(binary);\n                    const createDataURI = document.getElementById('createDataURI').checked;\n                    const detectMime = document.getElementById('detectMimeType').checked;\n                    \n                    if (createDataURI) {\n                        const mimeType = detectMime ? (file.type || detectFileType(file.name)) : 'application\/octet-stream';\n                        result = `data:${mimeType};base64,${result}`;\n                    }\n                    \n                    document.getElementById('fileOutput').value = result;\n                    \n                    const endTime = performance.now();\n                    updateStatsAfterOperation(file.size, result.length, endTime - startTime, true);\n                    addToHistory('file-encode', file.name, `${result.length} chars`, endTime - startTime);\n                    \n                    showNotification(`File ${file.name} encoded successfully!`);\n                    \n                } catch (error) {\n                    showNotification(`Failed to encode ${file.name}: ${error.message}`, 'error');\n                    updateStatsAfterOperation(0, 0, 0, false);\n                }\n            };\n            \n            reader.readAsArrayBuffer(file);\n        }\n\n        function handleBatchFiles(files) {\n            state.batchFiles = Array.from(files).filter(file => {\n                if (file.size > 50 * 1024 * 1024) {\n                    showNotification(`File ${file.name} is too large (max 50MB)`, 'error');\n                    return false;\n                }\n                return true;\n            });\n            \n            updateBatchDisplay();\n        }\n\n        function updateBatchDisplay() {\n            const results = document.getElementById('batchResults');\n            results.innerHTML = '';\n            \n            state.batchFiles.forEach((file, index) => {\n                const item = document.createElement('div');\n                item.className = 'gp-base64-encoder-batch-item';\n                item.id = `batch-item-${index}`;\n                item.innerHTML = `\n                    <strong>${file.name}<\/strong> (${formatFileSize(file.size)}) - <span id=\"batch-status-${index}\">Pending<\/span>\n                `;\n                results.appendChild(item);\n            });\n        }\n\n        function processBatch() {\n            if (state.batchFiles.length === 0) {\n                showNotification('No files selected for batch processing', 'error');\n                return;\n            }\n\n            const progressBar = document.getElementById('batchProgress');\n            let processed = 0;\n            state.batchResults = [];\n\n            state.batchFiles.forEach((file, index) => {\n                const item = document.getElementById(`batch-item-${index}`);\n                const status = document.getElementById(`batch-status-${index}`);\n                \n                item.classList.add('processing');\n                status.textContent = 'Processing...';\n                \n                const reader = new FileReader();\n                reader.onload = function(e) {\n                    try {\n                        const arrayBuffer = e.target.result;\n                        const bytes = new Uint8Array(arrayBuffer);\n                        let binary = '';\n                        for (let i = 0; i < bytes.length; i++) {\n                            binary += String.fromCharCode(bytes[i]);\n                        }\n                        \n                        const result = btoa(binary);\n                        state.batchResults[index] = {\n                            filename: file.name,\n                            original: file,\n                            encoded: result,\n                            success: true\n                        };\n                        \n                        item.classList.remove('processing');\n                        item.classList.add('success');\n                        status.textContent = 'Success';\n                        \n                        updateStatsAfterOperation(file.size, result.length, 0, true);\n                        \n                    } catch (error) {\n                        state.batchResults[index] = {\n                            filename: file.name,\n                            original: file,\n                            error: error.message,\n                            success: false\n                        };\n                        \n                        item.classList.remove('processing');\n                        item.classList.add('error');\n                        status.textContent = `Error: ${error.message}`;\n                        \n                        updateStatsAfterOperation(0, 0, 0, false);\n                    }\n                    \n                    processed++;\n                    const progress = (processed \/ state.batchFiles.length) * 100;\n                    progressBar.style.width = progress + '%';\n                    \n                    if (processed === state.batchFiles.length) {\n                        const successCount = state.batchResults.filter(r => r.success).length;\n                        showNotification(`Batch processing complete: ${successCount}\/${state.batchFiles.length} files processed`);\n                    }\n                };\n                \n                reader.readAsArrayBuffer(file);\n            });\n        }\n\n        function downloadBatchResults() {\n            if (!state.batchResults || state.batchResults.length === 0) {\n                showNotification('No batch results to download', 'error');\n                return;\n            }\n\n            const successfulResults = state.batchResults.filter(r => r.success);\n            if (successfulResults.length === 0) {\n                showNotification('No successful encodings to download', 'error');\n                return;\n            }\n\n            \/\/ Create a JSON file with all results\n            const results = {\n                timestamp: new Date().toISOString(),\n                totalFiles: state.batchResults.length,\n                successfulFiles: successfulResults.length,\n                files: successfulResults.map(result => ({\n                    filename: result.filename,\n                    originalSize: result.original.size,\n                    encodedSize: result.encoded.length,\n                    mimeType: result.original.type || detectFileType(result.filename),\n                    encoded: result.encoded\n                }))\n            };\n\n            const blob = new Blob([JSON.stringify(results, null, 2)], { type: 'application\/json' });\n            const url = URL.createObjectURL(blob);\n            const a = document.createElement('a');\n            a.href = url;\n            a.download = `batch-base64-results-${new Date().toISOString().split('T')[0]}.json`;\n            a.click();\n            URL.revokeObjectURL(url);\n\n            showNotification('Batch results downloaded successfully!');\n        }\n\n        function encodeURL() {\n            const input = document.getElementById('urlInput').value;\n            const mode = document.querySelector('input[name=\"urlMode\"]:checked').value;\n            \n            if (!input.trim()) {\n                showNotification('Please enter a URL to encode', 'error');\n                return;\n            }\n\n            const startTime = performance.now();\n            \n            try {\n                let result;\n                if (mode === 'full') {\n                    result = btoa(input);\n                } else {\n                    \/\/ Extract and encode only parameters\n                    try {\n                        const url = new URL(input);\n                        const params = url.searchParams.toString();\n                        if (params) {\n                            result = url.origin + url.pathname + '?' + btoa(params);\n                        } else {\n                            result = btoa(input);\n                        }\n                    } catch {\n                        result = btoa(input);\n                    }\n                }\n                \n                document.getElementById('urlOutput').value = result;\n                \n                const endTime = performance.now();\n                updateStatsAfterOperation(input.length, result.length, endTime - startTime, true);\n                addToHistory('url-encode', input.substring(0, 50) + '...', result.substring(0, 50) + '...', endTime - startTime);\n                \n                showNotification('URL encoded successfully!');\n                \n            } catch (error) {\n                showNotification('URL encoding failed: ' + error.message, 'error');\n                updateStatsAfterOperation(0, 0, 0, false);\n            }\n        }\n\n        function decodeURL() {\n            const input = document.getElementById('urlOutput').value;\n            \n            if (!input.trim()) {\n                showNotification('Please enter encoded URL to decode', 'error');\n                return;\n            }\n\n            const startTime = performance.now();\n            \n            try {\n                const result = atob(input);\n                document.getElementById('urlInput').value = result;\n                \n                const endTime = performance.now();\n                updateStatsAfterOperation(input.length, result.length, endTime - startTime, true);\n                addToHistory('url-decode', input.substring(0, 50) + '...', result.substring(0, 50) + '...', endTime - startTime);\n                \n                showNotification('URL decoded successfully!');\n                \n            } catch (error) {\n                showNotification('URL decoding failed: Invalid Base64 input', 'error');\n                updateStatsAfterOperation(0, 0, 0, false);\n            }\n        }\n\n        \/\/ Utility functions\n        function formatBase64(base64, format) {\n            const lineLength = parseInt(document.getElementById('lineLength').value) || 76;\n            \n            switch (format) {\n                case 'urlsafe':\n                    return base64.replace(\/\\+\/g, '-').replace(\/\\\/\/g, '_').replace(\/=\/g, '');\n                case 'mime':\n                    return base64.match(new RegExp(`.{1,${lineLength}}`, 'g')).join('\\r\\n');\n                case 'pem':\n                    return '-----BEGIN ENCODED DATA-----\\r\\n' + \n                           base64.match(new RegExp(`.{1,64}`, 'g')).join('\\r\\n') + \n                           '\\r\\n-----END ENCODED DATA-----';\n                case 'custom':\n                    if (lineLength > 0) {\n                        return base64.match(new RegExp(`.{1,${lineLength}}`, 'g')).join('\\r\\n');\n                    }\n                    return base64;\n                default:\n                    return base64;\n            }\n        }\n\n        function encodeString(str, encoding) {\n            switch (encoding) {\n                case 'utf8':\n                    return unescape(encodeURIComponent(str));\n                case 'ascii':\n                    return str.replace(\/[\\u0080-\\uFFFF]\/g, '?');\n                case 'latin1':\n                    return str;\n                case 'utf16':\n                    return String.fromCharCode(...new Uint16Array(new TextEncoder().encode(str).buffer));\n                case 'binary':\n                    return str;\n                default:\n                    return str;\n            }\n        }\n\n        function compressString(str) {\n            \/\/ Simple compression simulation - just return original for now\n            return str;\n        }\n\n        function detectFileType(fileName) {\n            const ext = fileName.split('.').pop().toLowerCase();\n            const mimeTypes = {\n                'jpg': 'image\/jpeg',\n                'jpeg': 'image\/jpeg',\n                'png': 'image\/png',\n                'gif': 'image\/gif',\n                'pdf': 'application\/pdf',\n                'txt': 'text\/plain',\n                'html': 'text\/html',\n                'css': 'text\/css',\n                'js': 'application\/javascript',\n                'json': 'application\/json',\n                'xml': 'application\/xml',\n                'zip': 'application\/zip',\n                'mp3': 'audio\/mpeg',\n                'mp4': 'video\/mp4',\n                'doc': 'application\/msword',\n                'docx': 'application\/vnd.openxmlformats-officedocument.wordprocessingml.document',\n                'xls': 'application\/vnd.ms-excel',\n                'xlsx': 'application\/vnd.openxmlformats-officedocument.spreadsheetml.sheet'\n            };\n            \n            return mimeTypes[ext] || 'application\/octet-stream';\n        }\n\n        function updateStatsAfterOperation(inputSize, outputSize, processTime, success) {\n            if (success) {\n                state.stats.totalProcessed++;\n                state.stats.successCount++;\n                if (state.currentTab === 'file' || state.currentTab === 'batch') {\n                    state.stats.filesProcessed++;\n                }\n            } else {\n                state.stats.errorCount++;\n            }\n            \n            state.stats.inputSize += inputSize;\n            state.stats.outputSize += outputSize;\n            state.stats.processTime += processTime;\n            \n            updateStats();\n        }\n\n        function updateStats() {\n            const stats = state.stats;\n            \n            \/\/ Update numbers with animation\n            animateNumber('totalProcessed', stats.totalProcessed);\n            animateNumber('inputSize', formatBytes(stats.inputSize), true);\n            animateNumber('outputSize', formatBytes(stats.outputSize), true);\n            animateNumber('filesProcessed', stats.filesProcessed);\n            animateNumber('processTime', Math.round(stats.processTime) + 'ms', true);\n            \n            \/\/ Calculate derived stats\n            const compressionRatio = stats.inputSize > 0 ? \n                Math.round(((stats.outputSize - stats.inputSize) \/ stats.inputSize) * 100) : 0;\n            animateNumber('compressionRatio', compressionRatio + '%', true);\n            \n            const avgSpeed = stats.processTime > 0 ? \n                Math.round((stats.inputSize \/ 1024) \/ (stats.processTime \/ 1000)) : 0;\n            animateNumber('avgSpeed', avgSpeed, true);\n            \n            const successRate = (stats.successCount + stats.errorCount) > 0 ? \n                Math.round((stats.successCount \/ (stats.successCount + stats.errorCount)) * 100) : 100;\n            animateNumber('successRate', successRate + '%', true);\n        }\n\n        function animateNumber(elementId, value, isText = false) {\n            const element = document.getElementById(elementId);\n            if (!element) return;\n            \n            if (isText) {\n                element.textContent = value;\n            } else {\n                const current = parseInt(element.textContent) || 0;\n                const target = parseInt(value) || 0;\n                const steps = 20;\n                const increment = (target - current) \/ steps;\n                \n                let step = 0;\n                const timer = setInterval(() => {\n                    step++;\n                    const newValue = Math.round(current + (increment * step));\n                    element.textContent = step === steps ? target : newValue;\n                    \n                    if (step === steps) {\n                        clearInterval(timer);\n                    }\n                }, 50);\n            }\n        }\n\n        function formatBytes(bytes) {\n            if (bytes === 0) return '0B';\n            const k = 1024;\n            const sizes = ['B', 'KB', 'MB', 'GB'];\n            const i = Math.floor(Math.log(bytes) \/ Math.log(k));\n            return parseFloat((bytes \/ Math.pow(k, i)).toFixed(1)) + sizes[i];\n        }\n\n        function formatFileSize(bytes) {\n            return formatBytes(bytes);\n        }\n\n        function addToHistory(operation, input, output, processTime) {\n            const historyItem = {\n                operation,\n                input,\n                output,\n                processTime: Math.round(processTime),\n                timestamp: new Date(),\n                tab: state.currentTab\n            };\n            \n            state.operationHistory.unshift(historyItem);\n            \n            \/\/ Keep only last 50 operations\n            if (state.operationHistory.length > 50) {\n                state.operationHistory = state.operationHistory.slice(0, 50);\n            }\n            \n            updateHistoryDisplay();\n            \n            \/\/ Add to undo\/redo history for current tab\n            const currentState = getCurrentTabState();\n            state.history.push(currentState);\n            state.historyIndex = state.history.length - 1;\n            \n            \/\/ Limit history size\n            if (state.history.length > 20) {\n                state.history.shift();\n                state.historyIndex--;\n            }\n        }\n\n        function updateHistoryDisplay() {\n            const historyContainer = document.getElementById('operationHistory');\n            \n            if (state.operationHistory.length === 0) {\n                historyContainer.innerHTML = `\n                    <div style=\"text-align: center; color: #000; font-weight: 700; padding: 20px;\">\n                        No operations performed yet\n                    <\/div>\n                `;\n                return;\n            }\n            \n            historyContainer.innerHTML = state.operationHistory.map(item => `\n                <div class=\"gp-base64-encoder-history-item\">\n                    <span class=\"gp-base64-encoder-history-text\">\n                        [${item.tab.toUpperCase()}] ${item.operation}: ${item.input}\n                    <\/span>\n                    <span class=\"gp-base64-encoder-history-time\">\n                        ${item.processTime}ms - ${item.timestamp.toLocaleTimeString()}\n                    <\/span>\n                <\/div>\n            `).join('');\n        }\n\n        function getCurrentTabState() {\n            const tab = state.currentTab;\n            switch (tab) {\n                case 'text':\n                    return {\n                        tab,\n                        input: document.getElementById('inputText').value,\n                        output: document.getElementById('outputText').value,\n                        format: document.getElementById('outputFormat').value,\n                        encoding: document.getElementById('inputEncoding').value,\n                        compress: document.getElementById('compressText').checked,\n                        lineLength: document.getElementById('lineLength').value\n                    };\n                case 'url':\n                    return {\n                        tab,\n                        input: document.getElementById('urlInput').value,\n                        output: document.getElementById('urlOutput').value,\n                        mode: document.querySelector('input[name=\"urlMode\"]:checked').value\n                    };\n                default:\n                    return { tab };\n            }\n        }\n\n        function restoreTabState(state) {\n            if (state.tab === 'text') {\n                document.getElementById('inputText').value = state.input || '';\n                document.getElementById('outputText').value = state.output || '';\n                document.getElementById('outputFormat').value = state.format || 'standard';\n                document.getElementById('inputEncoding').value = state.encoding || 'utf8';\n                document.getElementById('compressText').checked = state.compress || false;\n                document.getElementById('lineLength').value = state.lineLength || '76';\n            } else if (state.tab === 'url') {\n                document.getElementById('urlInput').value = state.input || '';\n                document.getElementById('urlOutput').value = state.output || '';\n                const modeRadio = document.querySelector(`input[name=\"urlMode\"][value=\"${state.mode || 'full'}\"]`);\n                if (modeRadio) modeRadio.checked = true;\n            }\n        }\n\n        function undoOperation() {\n            if (state.historyIndex > 0) {\n                state.historyIndex--;\n                const previousState = state.history[state.historyIndex];\n                restoreTabState(previousState);\n                showNotification('Operation undone');\n            } else {\n                showNotification('Nothing to undo', 'error');\n            }\n        }\n\n        function redoOperation() {\n            if (state.historyIndex < state.history.length - 1) {\n                state.historyIndex++;\n                const nextState = state.history[state.historyIndex];\n                restoreTabState(nextState);\n                showNotification('Operation redone');\n            } else {\n                showNotification('Nothing to redo', 'error');\n            }\n        }\n\n        function updateFormatExamples() {\n            const format = document.getElementById('outputFormat').value;\n            const lineLength = parseInt(document.getElementById('lineLength').value) || 76;\n            const sampleText = \"Hello World\";\n            const sampleBase64 = btoa(sampleText);\n            \n            const examples = {\n                standard: sampleBase64,\n                urlsafe: sampleBase64.replace(\/\\+\/g, '-').replace(\/\\\/\/g, '_').replace(\/=\/g, ''),\n                mime: sampleBase64.match(new RegExp(`.{1,${Math.min(lineLength, sampleBase64.length)}}`, 'g')).join('<br>'),\n                pem: '-----BEGIN ENCODED DATA-----<br>' + \n                     sampleBase64.match(new RegExp(`.{1,64}`, 'g')).join('<br>') + \n                     '<br>-----END ENCODED DATA-----',\n                custom: lineLength > 0 ? \n                       sampleBase64.match(new RegExp(`.{1,${Math.min(lineLength, sampleBase64.length)}}`, 'g')).join('<br>') : \n                       sampleBase64\n            };\n            \n            const exampleElements = document.querySelectorAll('.gp-base64-encoder-example-code');\n            if (exampleElements.length >= 4) {\n                exampleElements[0].innerHTML = examples.standard;\n                exampleElements[1].innerHTML = examples.urlsafe;\n                exampleElements[2].innerHTML = examples.mime;\n                exampleElements[3].innerHTML = `data:text\/plain;base64,${examples.standard}`;\n            }\n        }\n\n        function rotateDescription() {\n            const descriptionElement = document.getElementById('description');\n            descriptionElement.style.opacity = '0';\n            \n            setTimeout(() => {\n                descriptionElement.textContent = descriptions[descriptionIndex];\n                descriptionElement.style.opacity = '1';\n                descriptionIndex = (descriptionIndex + 1) % descriptions.length;\n            }, 300);\n            \n            setTimeout(rotateDescription, 8000); \/\/ Rotate every 8 seconds\n        }\n\n        function showNotification(message, type = 'success') {\n            const notification = document.getElementById('notification');\n            notification.textContent = message;\n            notification.className = `gp-base64-encoder-notification ${type}`;\n            notification.classList.add('show');\n            \n            setTimeout(() => {\n                notification.classList.remove('show');\n            }, 3000);\n        }\n\n        function debounce(func, wait) {\n            let timeout;\n            return function executedFunction(...args) {\n                const later = () => {\n                    clearTimeout(timeout);\n                    func(...args);\n                };\n                clearTimeout(timeout);\n                timeout = setTimeout(later, wait);\n            };\n        }\n\n        \/\/ Button event handlers\n        function copyToClipboard(elementId) {\n            const element = document.getElementById(elementId);\n            element.select();\n            element.setSelectionRange(0, 99999);\n            \n            try {\n                document.execCommand('copy');\n                showNotification('Copied to clipboard!');\n            } catch (err) {\n                \/\/ Fallback for modern browsers\n                navigator.clipboard.writeText(element.value).then(() => {\n                    showNotification('Copied to clipboard!');\n                }).catch(() => {\n                    showNotification('Failed to copy to clipboard', 'error');\n                });\n            }\n        }\n\n        function downloadResult(type) {\n            let content, filename, mimeType;\n            \n            switch (type) {\n                case 'text':\n                    content = document.getElementById('outputText').value;\n                    filename = 'encoded-text.txt';\n                    mimeType = 'text\/plain';\n                    break;\n                case 'file':\n                    content = document.getElementById('fileOutput').value;\n                    filename = 'encoded-file.txt';\n                    mimeType = 'text\/plain';\n                    break;\n                default:\n                    showNotification('No content to download', 'error');\n                    return;\n            }\n            \n            if (!content.trim()) {\n                showNotification('No content to download', 'error');\n                return;\n            }\n            \n            const blob = new Blob([content], { type: mimeType });\n            const url = URL.createObjectURL(blob);\n            const a = document.createElement('a');\n            a.href = url;\n            a.download = filename;\n            a.click();\n            URL.revokeObjectURL(url);\n            \n            showNotification('File downloaded successfully!');\n        }\n\n        function clearText() {\n            document.getElementById('inputText').value = '';\n            document.getElementById('outputText').value = '';\n            showNotification('Text fields cleared');\n        }\n\n        function clearFiles() {\n            document.getElementById('fileInput').value = '';\n            document.getElementById('fileOutput').value = '';\n            document.getElementById('fileList').innerHTML = '';\n            showNotification('File fields cleared');\n        }\n\n        function clearBatch() {\n            document.getElementById('batchFileInput').value = '';\n            document.getElementById('batchResults').innerHTML = '';\n            document.getElementById('batchProgress').style.width = '0%';\n            state.batchFiles = [];\n            state.batchResults = [];\n            showNotification('Batch cleared');\n        }\n\n        function clearURL() {\n            document.getElementById('urlInput').value = '';\n            document.getElementById('urlOutput').value = '';\n            showNotification('URL fields cleared');\n        }\n\n        \/\/ Keyboard shortcuts\n        document.addEventListener('keydown', function(e) {\n            if (e.ctrlKey || e.metaKey) {\n                switch (e.key) {\n                    case 'Enter':\n                        e.preventDefault();\n                        if (state.currentTab === 'text') {\n                            encodeText();\n                        } else if (state.currentTab === 'url') {\n                            encodeURL();\n                        }\n                        break;\n                    case 'z':\n                        if (e.shiftKey) {\n                            e.preventDefault();\n                            redoOperation();\n                        } else {\n                            e.preventDefault();\n                            undoOperation();\n                        }\n                        break;\n                }\n            }\n        });\n\n        \/\/ Tab switching with keyboard\n        document.addEventListener('keydown', function(e) {\n            if (e.altKey && e.key >= '1' && e.key <= '4') {\n                e.preventDefault();\n                const tabIndex = parseInt(e.key) - 1;\n                const tabs = document.querySelectorAll('.gp-base64-encoder-tab');\n                if (tabs[tabIndex]) {\n                    tabs[tabIndex].click();\n                }\n            }\n        });\n\n        \/\/ Advanced validation functions\n        function validateBase64(input) {\n            const base64Regex = \/^[A-Za-z0-9+\/]*={0,2}$\/;\n            const urlSafeBase64Regex = \/^[A-Za-z0-9_-]*$\/;\n            \n            \/\/ Remove whitespace and line breaks\n            const cleaned = input.replace(\/\\s\/g, '');\n            \n            \/\/ Check for data URI format\n            if (cleaned.startsWith('data:')) {\n                const commaIndex = cleaned.indexOf(',');\n                if (commaIndex === -1) return false;\n                const base64Part = cleaned.substring(commaIndex + 1);\n                return base64Regex.test(base64Part);\n            }\n            \n            \/\/ Check standard base64\n            if (base64Regex.test(cleaned)) return true;\n            \n            \/\/ Check URL-safe base64\n            if (urlSafeBase64Regex.test(cleaned)) return true;\n            \n            return false;\n        }\n\n        function detectFormat(input) {\n            const cleaned = input.replace(\/\\s\/g, '');\n            \n            if (cleaned.startsWith('data:')) return 'datauri';\n            if (cleaned.includes('-----BEGIN') &#038;&#038; cleaned.includes('-----END')) return 'pem';\n            if (cleaned.includes('\\r\\n') || cleaned.includes('\\n')) return 'mime';\n            if (cleaned.includes('-') || cleaned.includes('_')) return 'urlsafe';\n            \n            return 'standard';\n        }\n\n        \/\/ Enhanced error handling\n        function handleError(error, context) {\n            console.error(`Error in ${context}:`, error);\n            \n            let userMessage = 'An error occurred';\n            if (error.name === 'InvalidCharacterError') {\n                userMessage = 'Invalid Base64 characters detected';\n            } else if (error.name === 'QuotaExceededError') {\n                userMessage = 'File too large for processing';\n            } else if (error.message.includes('network')) {\n                userMessage = 'Network error occurred';\n            }\n            \n            showNotification(userMessage, 'error');\n            updateStatsAfterOperation(0, 0, 0, false);\n        }\n\n        \/\/ Initialize advanced features\n        function initializeAdvancedFeatures() {\n            \/\/ Add integrity checking\n            window.addEventListener('beforeunload', function(e) {\n                if (state.operationHistory.length > 0) {\n                    e.preventDefault();\n                    e.returnValue = '';\n                }\n            });\n            \n            \/\/ Add auto-save to localStorage (optional)\n            if (typeof Storage !== 'undefined') {\n                setInterval(() => {\n                    try {\n                        localStorage.setItem('gp-base64-encoder-state', JSON.stringify({\n                            history: state.operationHistory.slice(0, 10), \/\/ Save last 10 operations\n                            stats: state.stats\n                        }));\n                    } catch (e) {\n                        \/\/ localStorage might be full or disabled\n                    }\n                }, 30000); \/\/ Save every 30 seconds\n                \n                \/\/ Restore state on load\n                try {\n                    const saved = localStorage.getItem('gp-base64-encoder-state');\n                    if (saved) {\n                        const parsed = JSON.parse(saved);\n                        if (parsed.history) {\n                            state.operationHistory = parsed.history;\n                            updateHistoryDisplay();\n                        }\n                        if (parsed.stats) {\n                            Object.assign(state.stats, parsed.stats);\n                            updateStats();\n                        }\n                    }\n                } catch (e) {\n                    \/\/ Invalid saved state\n                }\n            }\n        }\n\n        \/\/ Initialize advanced features when DOM is loaded\n        document.addEventListener('DOMContentLoaded', function() {\n            initializeAdvancedFeatures();\n        });\n\n        \/\/ Export functions for WordPress integration\n        if (typeof window !== 'undefined') {\n            window.GPBase64Encoder = {\n                encode: encodeText,\n                decode: decodeText,\n                encodeFile: processFile,\n                processBatch: processBatch,\n                getStats: () => state.stats,\n                getHistory: () => state.operationHistory,\n                clear: () => {\n                    clearText();\n                    clearFiles();\n                    clearBatch();\n                    clearURL();\n                },\n                reset: () => {\n                    state.stats = {\n                        totalProcessed: 0,\n                        inputSize: 0,\n                        outputSize: 0,\n                        processTime: 0,\n                        filesProcessed: 0,\n                        successCount: 0,\n                        errorCount: 0\n                    };\n                    state.operationHistory = [];\n                    state.history = [];\n                    state.historyIndex = -1;\n                    updateStats();\n                    updateHistoryDisplay();\n                }\n            };\n        }\n    <\/script>\n<\/body>\n<\/html>\n","protected":false},"excerpt":{"rendered":"<p>Perfect Base64 Encoder \u2192B64 Perfect Base64 Encoder Advanced encoding tool with multiple formats and batch processing Base64 encoding converts binary &#8230; <\/p>\n<p class=\"read-more-container\"><a title=\"Base64 Encoder\" class=\"read-more button\" href=\"https:\/\/vijaypandit.in\/?page_id=345#more-345\" aria-label=\"More on Base64 Encoder\">Read more<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-345","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/vijaypandit.in\/index.php?rest_route=\/wp\/v2\/pages\/345","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/vijaypandit.in\/index.php?rest_route=\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/vijaypandit.in\/index.php?rest_route=\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/vijaypandit.in\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/vijaypandit.in\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=345"}],"version-history":[{"count":2,"href":"https:\/\/vijaypandit.in\/index.php?rest_route=\/wp\/v2\/pages\/345\/revisions"}],"predecessor-version":[{"id":351,"href":"https:\/\/vijaypandit.in\/index.php?rest_route=\/wp\/v2\/pages\/345\/revisions\/351"}],"wp:attachment":[{"href":"https:\/\/vijaypandit.in\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=345"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}