{"id":644,"date":"2025-01-18T00:59:56","date_gmt":"2025-01-18T00:59:56","guid":{"rendered":"https:\/\/ocr365.com\/?page_id=644"},"modified":"2025-03-15T06:03:19","modified_gmt":"2025-03-15T06:03:19","slug":"%ed%95%84%ea%b8%b0%ec%97%90%ec%84%9c-%ed%85%8d%ec%8a%a4%ed%8a%b8%eb%a1%9c","status":"publish","type":"page","link":"https:\/\/ocr365.com\/ko\/handwriting-to-text\/","title":{"rendered":"\ud544\uae30\ub97c \ud14d\uc2a4\ud2b8\ub85c"},"content":{"rendered":"\t\t<div data-elementor-type=\"wp-page\" data-elementor-id=\"644\" class=\"elementor elementor-644\" data-elementor-post-type=\"page\">\n\t\t\t\t<div class=\"elementor-element elementor-element-658b7d1 e-con-full e-flex e-con e-parent\" data-id=\"658b7d1\" data-element_type=\"container\" data-settings=\"{&quot;background_background&quot;:&quot;gradient&quot;}\">\n\t\t<div class=\"elementor-element elementor-element-134cc99 e-flex e-con-boxed e-con e-child\" data-id=\"134cc99\" data-element_type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-99d3244 elementor-widget elementor-widget-ucaddon_gradient_text_effect\" data-id=\"99d3244\" data-element_type=\"widget\" data-widget_type=\"ucaddon_gradient_text_effect.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\n<!-- start Gradient Text Effect -->\n<style>\/* widget: Gradient Text Effect *\/\n\n#uc_gradient_text_effect_elementor_99d3244 .ue_gradient_text{\n  color: #00d7ff;\n}\n\n@supports ((background-clip: text) or (-webkit-background-clip: text)) and ((text-fill-color: transparent) or (-webkit-text-fill-color: transparent)) {\n  #uc_gradient_text_effect_elementor_99d3244 .ue_gradient_text{\n    background-image: linear-gradient(\n      90deg,\n      #00d7ff 0%,\n      #5f00ff 100%\n    );\n    background-size: cover;\n    -webkit-background-clip: text;\n    background-clip: text;\n    -webkit-text-fill-color: transparent;\n    text-fill-color: transparent;\n    display:inline-block;\n    \n  }\n  #uc_gradient_text_effect_elementor_99d3244 .ue_gradient_text::selection {\n    -webkit-text-fill-color: #474747;\n  }\n}\n\n<\/style>\n\n<h1 id=\"uc_gradient_text_effect_elementor_99d3244\" class=\"ue-text\">\n  <span class=\"ue_beginning_text\"> <\/span> \n  <span class=\"ue_gradient_text\"> Convert Handwriting <\/span>\n  <span class=\"ue_ending_text\">  <\/span>\n<\/h1>\n<!-- end Gradient Text Effect -->\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-bb165ab e-flex e-con-boxed e-con e-child\" data-id=\"bb165ab\" data-element_type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-4f65d76 elementor-widget elementor-widget-shortcode\" data-id=\"4f65d76\" data-element_type=\"widget\" data-widget_type=\"shortcode.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<div class=\"elementor-shortcode\"><!-- Prevent specific elements from being auto-translated -->\n<meta name=\"google\" content=\"notranslate\">\n       \n<div class=\"vision-upload-container\">\n    <form id=\"visionUploadForm\" method=\"post\" enctype=\"multipart\/form-data\">\n        <!-- Initial upload area -->\n        <div class=\"upload-area\" id=\"initialUploadArea\">\n            <div class=\"upload-instructions\">\n                <div class=\"upload-icon\">\n                    <i class=\"fas fa-cloud-arrow-up\"><\/i>\n                <\/div>\n                <h3>Upload Images<\/h3>\n                <p class=\"upload-desc\">Drop Files<\/p>\n            <\/div>\n            \n            <!-- Native file input with custom button -->\n            <div class=\"file-input-wrapper\">\n                <input type=\"file\" \n                       id=\"visionFileInput\" \n                       name=\"files[]\" \n                       accept=\"image\/jpeg,image\/png,image\/gif,image\/bmp,image\/webp,image\/tiff\" \n                       multiple\n                       style=\"opacity: 0; position: absolute; z-index: -1;\">\n                <button type=\"button\" class=\"custom-file-button\">\n                    <i class=\"fas fa-cloud-arrow-up\"><\/i>\n                    <span class=\"button-text\">Select Images<\/span>\n                <\/button>\n            <\/div>\n            <\/div>\n            \n        <!-- Image Gallery View - initially hidden -->\n        <div class=\"vision-gallery-container\" id=\"imageGalleryView\" style=\"display: none;\">\n            <!-- Gallery Header -->\n            <div class=\"gallery-header\">\n                <div class=\"gallery-info\">\n                    <div class=\"image-counter\">\n                        <i class=\"fas fa-images\"><\/i>\n                        <span class=\"images-count\">0<\/span>\n                    <\/div>\n                <\/div>\n                <div class=\"gallery-actions\">\n                    <button type=\"button\" class=\"action-btn add-more-btn\" title=\"Add More Images\">\n                        <i class=\"fas fa-plus\"><\/i><span class=\"btn-text\">Add<\/span>\n                    <\/button>\n                    <div class=\"selection-controls\">\n                        <button type=\"button\" class=\"action-btn delete-selected\" disabled title=\"Delete Selected Images\">\n                            <i class=\"fas fa-trash\"><\/i><span class=\"btn-text\">Delete<\/span>\n                        <\/button>\n                    <\/div>\n                <\/div>\n            <\/div>\n\n            <!-- Gallery Grid -->\n            <div class=\"gallery-grid view-grid\">\n                <!-- Images will be populated here -->\n        <\/div>\n\n            <!-- Convert button - only shown below image gallery -->\n        <button type=\"submit\" id=\"visionConvertButton\" disabled>\n                <span class=\"dashicons dashicons-text-page\"><\/span>\n            Convert        <\/button>\n        \n        <!-- Daily Limit Warning - hidden by default -->\n        <div id=\"visionDailyLimitWarning\" class=\"vision-daily-limit-warning\" style=\"display: none;\">\n            <div class=\"limit-warning-content\">\n                <button type=\"button\" class=\"limit-close-btn\" onclick=\"document.getElementById('visionDailyLimitWarning').style.display='none';\">\u00d7<\/button>\n                <div class=\"limit-icon\">\n                    <span class=\"dashicons dashicons-warning\"><\/span>\n                <\/div>\n                <div class=\"limit-message\">\n                    <p class=\"limit-main-text\">You have reached your daily limit of <span class=\"limit-count\">5<\/span> free conversions<\/p>\n                    <p class=\"limit-reset-text\">\n                        Please try again tomorrow or <a href=\"https:\/\/ocr365.com\/ko\/pricing\/\" class=\"inline-upgrade-link\" data-no-translation>upgrade<\/a> for unlimited conversions                    <\/p>\n                    <div class=\"limit-countdown\" id=\"limitCountdown\">\n                        <span class=\"limit-countdown-label\">Resets in:<\/span>\n                        <span class=\"limit-countdown-time\" id=\"limitCountdownTime\">--:--:--<\/span>\n                    <\/div>\n                <\/div>\n                <div class=\"limit-actions\">\n                    <a href=\"https:\/\/ocr365.com\/ko\/pricing\/\" class=\"limit-upgrade-btn\" data-no-translation>\n                        Upgrade Now                    <\/a>\n                <\/div>\n            <\/div>\n        <\/div>\n        \n        <!-- Cloudflare Turnstile Container - only shown for non-subscribers -->\n                <div id=\"visionTurnstileContainer\" class=\"turnstile-container\" style=\"display: none; margin: 20px auto; text-align: center;\">\n            <!-- Turnstile widget will be rendered here -->\n        <\/div>\n                <\/div>\n\n        <!-- Progress Container -->\n        <div id=\"visionProgressContainer\" class=\"vision-progress-container\" style=\"display: none;\">\n            <div class=\"vision-progress-message\">\n                <div class=\"vision-progress-icon\">\n                    <span class=\"dashicons dashicons-update\"><\/span>\n                <\/div>\n                <div class=\"vision-progress-text\">Processing your images...<\/div>\n            <\/div>\n            <div class=\"vision-progress-status\">\n                <div class=\"vision-progress-bar\"><\/div>\n            <\/div>\n        <\/div>\n\n        <!-- Results Container -->\n        <div id=\"visionResults\"><\/div>\n\n        <!-- Error Messages -->\n        <div id=\"visionErrorMessages\" class=\"error-message\" style=\"display: none;\"><\/div>\n    <\/form>\n<\/div>\n\n<!-- Image Preview Modal -->\n<div class=\"vision-image-preview-modal\">\n    <div class=\"modal-overlay\"><\/div>\n    <div class=\"modal-content\">\n        <button class=\"modal-close\"><i class=\"fas fa-times\"><\/i><\/button>\n        <div class=\"preview-navigation\">\n            <button class=\"nav-btn prev-image\"><i class=\"fas fa-chevron-left\"><\/i><\/button>\n            <div class=\"preview-image-container\">\n                <img decoding=\"async\" src=\"\" alt=\"Preview\" class=\"preview-image\">\n            <\/div>\n            <button class=\"nav-btn next-image\"><i class=\"fas fa-chevron-right\"><\/i><\/button>\n        <\/div>\n        <div class=\"preview-info\">\n            <h3 class=\"preview-filename\"><\/h3>\n            <div class=\"preview-metadata\">\n                <span class=\"preview-size\"><\/span>\n                <span class=\"preview-dimensions\"><\/span>\n                <span class=\"preview-type\"><\/span>\n            <\/div>\n        <\/div>\n    <\/div>\n<\/div>\n\n<!-- Modal window for limit notification -->\n<div id=\"visionLimitModal\" class=\"vision-limit-modal\">\n    <div class=\"vision-limit-content\">\n        <div class=\"vision-limit-close\" id=\"limitModalCloseBtn\">\u00d7<\/div>\n        \n        <div class=\"vision-limit-header\">\n            <div class=\"limit-icon\">\n                <span class=\"dashicons dashicons-lock\"><\/span>\n            <\/div>\n            <h3>Batch Upload Limit<\/h3>\n            <p>You have reached the batch upload limit for free users<\/p>\n        <\/div>\n\n        <div class=\"vision-limit-plan\">\n            <div class=\"plan-badge\">Pro<\/div>\n            <ul class=\"vision-limit-features\">\n                <li>\n                    Larger batch upload limits\n                <\/li>\n                <li>\n                    Unlimited daily conversions\n                <\/li>\n                <li>\n                    Priority processing\n                <\/li>\n            <\/ul>\n        <\/div>\n\n        <div class=\"vision-limit-actions\">\n            <a href=\"https:\/\/ocr365.com\/ko\/pricing\/\" \n               class=\"vision-upgrade-button\" data-no-translation>\n                Upgrade to Pro\n            <\/a>\n        <\/div>\n    <\/div>\n<\/div>\n\n<script>\n\/\/ Wait for DOM to be fully loaded\ndocument.addEventListener('DOMContentLoaded', function() {\n    \/\/ Get the close button element\n    var closeBtn = document.getElementById('limitModalCloseBtn');\n    if (closeBtn) {\n        \/\/ Add click event listener\n        closeBtn.addEventListener('click', function() {\n            \/\/ Check if global closeModal function exists\n            if (typeof closeModal === 'function') {\n                closeModal();\n            } else {\n                \/\/ If function doesn't exist, hide modal directly\n                var modal = document.getElementById('visionLimitModal');\n                if (modal) {\n                    modal.style.display = 'none';\n                    document.body.style.overflow = '';\n                }\n            }\n        });\n    }\n});\n<\/script> \n<!-- Add required libraries -->\n<link rel=\"stylesheet\" href=\"https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/font-awesome\/6.4.0\/css\/all.min.css\">\n<script src=\"https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/jszip\/3.10.1\/jszip.min.js\"><\/script>\n<script src=\"https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/FileSaver.js\/2.0.5\/FileSaver.min.js\"><\/script>\n\n<script>\n\/\/ Define a simple and effective returnToUpload function\nwindow.returnToUpload = function(event) {\n    if (event) event.preventDefault();\n    \n    \/\/ Show upload area\n    document.getElementById('initialUploadArea').style.display = 'block';\n    document.getElementById('visionResults').style.display = 'none';\n    \n    \/\/ Remove body class when results are hidden\n    document.body.classList.remove('vision-results-active');\n    \n    \/\/ Clear results container\n    document.getElementById('visionResults').innerHTML = '';\n    \n    return false;\n};\n\ndocument.addEventListener('DOMContentLoaded', function() {\n    var fileInput = document.getElementById('visionFileInput');\n    var customButton = document.querySelector('.custom-file-button .button-text');\n    var convertButton = document.getElementById('visionConvertButton');\n    var selectedFilesMap = new Map();\n    var initialUploadArea = document.getElementById('initialUploadArea');\n    var imageGalleryView = document.getElementById('imageGalleryView');\n    var galleryGrid = document.querySelector('.gallery-grid');\n    var previewModal = document.querySelector('.vision-image-preview-modal');\n    var turnstileContainer = document.getElementById('visionTurnstileContainer');\n    var turnstileToken = '';\n    var turnstileWidgetId = null;\n    let currentImageIndex = 0;\n    let galleryItems = [];\n    let isSubmitting = false; \/\/ Add submission status flag\n    \n    \/\/ Output debug information to verify wpVision object is correctly loaded\n    console.log('VisionPlugin initialization - Batch upload limits:', {\n        wpVision: typeof wpVision !== 'undefined' ? {\n            maxFiles: wpVision.maxFiles,\n            subscriptionType: wpVision.subscriptionType\n        } : 'undefined',\n        maxBatchLimit: typeof wpVision !== 'undefined' && wpVision.maxFiles ? \n            (wpVision.maxFiles[wpVision.subscriptionType] || wpVision.maxFiles.free) : 'undefined'\n    });\n    \n    \/\/ Ensure progress container is hidden on page load\n    const progressContainer = document.getElementById('visionProgressContainer');\n    if (progressContainer) {\n        progressContainer.style.display = 'none';\n    }\n    \n    \/\/ Initialize drag and drop functionality\n    initializeDragDrop();\n    \n    function initializeDragDrop() {\n        if (!initialUploadArea) return;\n        \n        \/\/ Add event listeners for drag and drop area\n        ['dragenter', 'dragover', 'dragleave', 'drop'].forEach(eventName => {\n            initialUploadArea.addEventListener(eventName, preventDefaults, false);\n        });\n        \n        \/\/ Add drag effects\n        initialUploadArea.addEventListener('dragenter', highlight, false);\n        initialUploadArea.addEventListener('dragover', highlight, false);\n        initialUploadArea.addEventListener('dragleave', unhighlight, false);\n        initialUploadArea.addEventListener('drop', unhighlight, false);\n        \n        \/\/ Handle file drop\n        initialUploadArea.addEventListener('drop', handleDrop, false);\n        \n        function preventDefaults(e) {\n            e.preventDefault();\n            e.stopPropagation();\n        }\n        \n        function highlight() {\n            initialUploadArea.classList.add('highlight');\n        }\n        \n        function unhighlight() {\n            initialUploadArea.classList.remove('highlight');\n        }\n        \n        function handleDrop(e) {\n            const dt = e.dataTransfer;\n            const files = dt.files;\n            \n            \/\/ Directly use the same logic as click upload\n            if (files && files.length > 0) {\n                \/\/ Set dropped files to the file input element to trigger the same handling as click upload\n                try {\n                    \/\/ Create a DataTransfer object\n                    const dataTransfer = new DataTransfer();\n                    \n                    \/\/ Add all dropped files\n                    Array.from(files).forEach(file => {\n                        dataTransfer.items.add(file);\n                    });\n                    \n                    \/\/ Set to file input element\n                    fileInput.files = dataTransfer.files;\n                    \n                    \/\/ Manually trigger change event to execute the same logic as click upload\n                    const event = new Event('change', { bubbles: true });\n                    fileInput.dispatchEvent(event);\n                } catch (error) {\n                    console.error('Error setting files:', error);\n                    \/\/ If file setting fails, show an error\n                    showError('Error processing files, please try selecting files using the upload button.');\n                }\n            }\n        }\n    }\n    \n    if (fileInput && customButton) {\n        fileInput.addEventListener('change', function() {\n            \/\/ Check file limits before adding files\n            const newFiles = Array.from(this.files);\n            \n            \/\/ Check and filter duplicate files\n            const uniqueFiles = filterDuplicateFiles(newFiles);\n            \n            \/\/ If all files are duplicates, notify the user\n            if (uniqueFiles.length === 0 && newFiles.length > 0) {\n                showError('Duplicate files detected', 'warning');\n                return;\n            }\n            \n            \/\/ Use the same checking method as handleFiles function\n            \/\/ Check file limits with auto-trimming enabled\n            if (!checkFileLimits(uniqueFiles, true)) return;\n            \n            \/\/ Get the limited files if needed\n            const limitedFiles = getLimitedFiles(uniqueFiles);\n            if (limitedFiles.length === 0) return;\n            \n            \/\/ Store allowed files\n            limitedFiles.forEach((file, index) => {\n                const fileId = 'file_' + Date.now() + '_' + index;\n                selectedFilesMap.set(fileId, file);\n            });\n            \n            updateButtonText();\n            updateGalleryInfo();\n            showGalleryView();\n            renderGalleryItems();\n        });\n\n        \/\/ Function to check for duplicate files\n        function filterDuplicateFiles(newFiles) {\n            const uniqueFiles = [];\n            \n            newFiles.forEach(newFile => {\n                let isDuplicate = false;\n                \n                \/\/ Check existing files for duplicates\n                selectedFilesMap.forEach(existingFile => {\n                    \/\/ Determine if files are identical by name and size\n                    if (existingFile.name === newFile.name && existingFile.size === newFile.size) {\n                        isDuplicate = true;\n                    }\n                });\n                \n                \/\/ If not a duplicate, add to unique files list\n                if (!isDuplicate) {\n                    uniqueFiles.push(newFile);\n                }\n            });\n            \n            return uniqueFiles;\n        }\n\n        \/\/ Trigger file input when custom button is clicked\n        document.querySelector('.custom-file-button').addEventListener('click', function() {\n            fileInput.click();\n        });\n        \n        \/\/ Add more images button\n        document.querySelector('.add-more-btn').addEventListener('click', function() {\n            \/\/ Create a new file input element\n            const newFileInput = document.createElement('input');\n            newFileInput.type = 'file';\n            newFileInput.multiple = true;\n            newFileInput.accept = 'image\/jpeg,image\/png,image\/gif,image\/bmp,image\/webp,image\/tiff';\n            \n            \/\/ Listen for change event on new file input\n            newFileInput.addEventListener('change', function(e) {\n                \/\/ Get newly selected files\n                const newFiles = Array.from(this.files);\n                \n                \/\/ Use the same duplicate file filter function\n                const uniqueFiles = filterDuplicateFiles(newFiles);\n                \n                \/\/ If all files are duplicates, show a warning\n                if (uniqueFiles.length === 0 && newFiles.length > 0) {\n                    showError('Duplicate files detected', 'warning');\n                    document.body.removeChild(newFileInput); \/\/ Remove temporary element\n                    return;\n                }\n                \n                \/\/ Calculate current files count and max files limit\n                const currentCount = selectedFilesMap.size;\n                const maxFiles = typeof wpVision !== 'undefined' && wpVision.maxFiles ? \n                    (wpVision.maxFiles[wpVision.subscriptionType] || wpVision.maxFiles.free) : 3;\n                \n                \/\/ First check file limits without auto-trimming to show modal\n                if (currentCount + uniqueFiles.length > maxFiles) {\n                    checkFileLimits(uniqueFiles, false);\n                }\n                \n                \/\/ Now check with auto-trimming to process files\n                if (!checkFileLimits(uniqueFiles, true)) {\n                    document.body.removeChild(newFileInput); \/\/ Remove temporary element\n                    return;\n                }\n                \n                \/\/ Get the limited files if needed\n                const limitedFiles = getLimitedFiles(uniqueFiles);\n                if (limitedFiles.length === 0) {\n                    document.body.removeChild(newFileInput); \/\/ Remove temporary element\n                    return;\n                }\n                \n                \/\/ Store allowed files\n                limitedFiles.forEach((file, index) => {\n                    const fileId = 'file_' + Date.now() + '_' + index;\n                    selectedFilesMap.set(fileId, file);\n                });\n                \n                updateButtonText();\n                updateGalleryInfo();\n                showGalleryView();\n                renderGalleryItems();\n                \n                \/\/ Remove the temporary file input element\n                document.body.removeChild(newFileInput);\n            });\n            \n            \/\/ Append new file input to body and trigger click\n            document.body.appendChild(newFileInput);\n            newFileInput.style.display = 'none';\n            newFileInput.click();\n        });\n        \n        \/\/ Delete selected button\n        document.querySelector('.delete-selected').addEventListener('click', function() {\n            const selectedCheckboxes = document.querySelectorAll('.gallery-item-checkbox:checked');\n            selectedCheckboxes.forEach(checkbox => {\n                const galleryItem = checkbox.closest('.gallery-item');\n                if (galleryItem) {\n                    const fileId = galleryItem.getAttribute('data-file-id');\n                    selectedFilesMap.delete(fileId);\n                    galleryItem.remove();\n                }\n            });\n            \n            updateGalleryInfo();\n            updateButtonText();\n            updateDeleteSelectedButton();\n            \n            \/\/ If no images left, return to initial upload view\n            if (selectedFilesMap.size === 0) {\n                showInitialUploadArea();\n            }\n        });\n        \n        \/\/ Handle gallery item events (preview and delete)\n        galleryGrid.addEventListener('click', function(e) {\n            \/\/ Handle preview action\n            if (e.target.closest('.preview-action')) {\n                const galleryItem = e.target.closest('.gallery-item');\n                openPreviewModal(galleryItem);\n            }\n            \n            \/\/ Handle delete action\n            if (e.target.closest('.delete-action')) {\n                const galleryItem = e.target.closest('.gallery-item');\n                const fileId = galleryItem.getAttribute('data-file-id');\n                selectedFilesMap.delete(fileId);\n                galleryItem.remove();\n                \n                updateGalleryInfo();\n                updateButtonText();\n                \n                \/\/ Update gallery items array\n                galleryItems = Array.from(document.querySelectorAll('.gallery-item'));\n                \n                \/\/ If no images left, return to initial upload view\n                if (selectedFilesMap.size === 0) {\n                    showInitialUploadArea();\n                }\n            }\n        });\n        \n        \/\/ Image preview modal handlers\n        document.querySelector('.modal-close').addEventListener('click', closePreviewModal);\n        document.querySelector('.modal-overlay').addEventListener('click', function(e) {\n            if (e.target === this) {\n                closePreviewModal();\n            }\n        });\n        \n        \/\/ Navigation in preview modal\n        document.querySelector('.prev-image').addEventListener('click', function() {\n            if (currentImageIndex > 0) {\n                currentImageIndex--;\n                updatePreviewImage();\n            }\n        });\n        \n        document.querySelector('.next-image').addEventListener('click', function() {\n            if (currentImageIndex < galleryItems.length - 1) {\n                currentImageIndex++;\n                updatePreviewImage();\n            }\n        });\n\n        \/\/ Function to update button text and file input state\n        function updateButtonText() {\n            const filesCount = selectedFilesMap.size;\n            customButton.textContent = filesCount > 0 ? \n                'Images Selected' : \n                'Select Images';\n            \n            \/\/ Show\/hide convert button based on file count\n            if (filesCount > 0) {\n                convertButton.classList.add('show');\n                convertButton.disabled = false;\n            } else {\n                convertButton.classList.remove('show');\n                convertButton.disabled = true;\n            }\n\n            \/\/ Sync the native file input with selected files\n            const dataTransfer = new DataTransfer();\n            selectedFilesMap.forEach(file => {\n                dataTransfer.items.add(file);\n            });\n            fileInput.files = dataTransfer.files;\n        }\n\n        \/\/ Function to show gallery view\n        function showGalleryView() {\n            if (initialUploadArea && imageGalleryView) {\n                initialUploadArea.style.display = 'none';\n                imageGalleryView.style.display = 'flex';\n            }\n        }\n        \n        \/\/ Function to show initial upload area\n        function showInitialUploadArea() {\n            if (initialUploadArea && imageGalleryView) {\n                initialUploadArea.style.display = 'block';\n                imageGalleryView.style.display = 'none';\n            }\n        }\n        \n        \/\/ Update gallery info (count, etc)\n        function updateGalleryInfo() {\n            const count = selectedFilesMap.size;\n            document.querySelector('.images-count').textContent = count;\n            \n            \/\/ Update convert button state\n            if (convertButton) {\n                convertButton.disabled = count === 0;\n                convertButton.classList.toggle('show', count > 0);\n            }\n            \n            \/\/ Update delete selected button state\n            updateDeleteSelectedButton();\n        }\n        \n        \/\/ Render all gallery items\n        function renderGalleryItems() {\n            \/\/ Clear current gallery\n            galleryGrid.innerHTML = '';\n            galleryItems = [];\n            \n            \/\/ Add each file to the gallery\n            selectedFilesMap.forEach((file, fileId) => {\n                createGalleryItem(file, fileId);\n            });\n            \n            \/\/ Update gallery info after rendering\n            updateGalleryInfo();\n        }\n        \n        \/\/ Create a single gallery item\n        function createGalleryItem(file, fileId) {\n            const reader = new FileReader();\n            const galleryItem = document.createElement('div');\n            galleryItem.className = 'gallery-item';\n            galleryItem.setAttribute('data-file-id', fileId);\n            \n            reader.onload = function(e) {\n                \/\/ Create image element to get dimensions\n                const img = new Image();\n                img.onload = function() {\n                    const dimensions = `${this.width} \u00d7 ${this.height}`;\n                    \n                    \/\/ Update item HTML\n                    galleryItem.innerHTML = `\n                        <div class=\"item-checkbox\">\n                            <input type=\"checkbox\" class=\"gallery-item-checkbox\">\n                        <\/div>\n                        <div class=\"item-preview\">\n                            <img decoding=\"async\" src=\"${e.target.result}\" alt=\"${file.name}\">\n                            <div class=\"item-overlay\">\n                                <button type=\"button\" class=\"item-action preview-action\"><i class=\"fas fa-search-plus\"><\/i><\/button>\n                                <button type=\"button\" class=\"item-action delete-action\"><i class=\"fas fa-trash\"><\/i><\/button>\n                            <\/div>\n                        <\/div>\n                        <div class=\"item-info\">\n                            <h4 class=\"item-name\" title=\"${file.name}\">${file.name}<\/h4>\n                            <span class=\"item-meta\">${formatFileSize(file.size)} \u00b7 ${dimensions}<\/span>\n                        <\/div>\n                    `;\n                    \n                    \/\/ Add event listeners for checkbox\n                    const checkbox = galleryItem.querySelector('.gallery-item-checkbox');\n                    checkbox.addEventListener('change', function() {\n                        updateDeleteSelectedButton();\n                    });\n                    \n                    \/\/ Update gallery items array\n                    galleryItems = Array.from(document.querySelectorAll('.gallery-item'));\n                };\n                img.src = e.target.result;\n            };\n            \n            reader.onerror = function() {\n                console.error(\"Error reading file:\", file.name);\n            };\n            \n            reader.readAsDataURL(file);\n            galleryGrid.appendChild(galleryItem);\n        }\n        \n        \/\/ Format file size for display\n        function formatFileSize(bytes) {\n            if (bytes === 0) return '0 Bytes';\n            const k = 1024;\n            const sizes = ['Bytes', 'KB', 'MB', 'GB'];\n            const i = Math.floor(Math.log(bytes) \/ Math.log(k));\n            return parseFloat((bytes \/ Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];\n        }\n        \n        \/\/ Open preview modal\n        function openPreviewModal(galleryItem) {\n            galleryItems = Array.from(document.querySelectorAll('.gallery-item'));\n            currentImageIndex = galleryItems.indexOf(galleryItem);\n            \n            updatePreviewImage();\n            previewModal.classList.add('open');\n            document.body.style.overflow = 'hidden'; \/\/ Prevent background scrolling\n        }\n        \n        \/\/ Close preview modal\n        function closePreviewModal() {\n            previewModal.classList.remove('open');\n            document.body.style.overflow = '';\n        }\n        \n        \/\/ Update preview image and navigation\n        function updatePreviewImage() {\n            const galleryItem = galleryItems[currentImageIndex];\n            const fileId = galleryItem.getAttribute('data-file-id');\n            const file = selectedFilesMap.get(fileId);\n            const img = galleryItem.querySelector('.item-preview img');\n            const name = galleryItem.querySelector('.item-name').textContent;\n            const metaText = galleryItem.querySelector('.item-meta').textContent;\n            \n            \/\/ Update modal content\n            document.querySelector('.preview-image').src = img.src;\n            document.querySelector('.preview-filename').textContent = name;\n            \n            \/\/ Parse metadata\n            const sizeMatch = metaText.match(\/([0-9.]+\\s+[A-Z]+)\/);\n            const dimensionsMatch = metaText.match(\/([0-9]+\\s+\u00d7\\s+[0-9]+)\/);\n            \n            if (sizeMatch) document.querySelector('.preview-size').textContent = sizeMatch[0];\n            if (dimensionsMatch) document.querySelector('.preview-dimensions').textContent = dimensionsMatch[0];\n            document.querySelector('.preview-type').textContent = file.type.split('\/')[1].toUpperCase();\n            \n            \/\/ Update navigation buttons\n            document.querySelector('.prev-image').disabled = currentImageIndex === 0;\n            document.querySelector('.next-image').disabled = currentImageIndex === galleryItems.length - 1;\n        }\n        \n        \/\/ Update delete selected button state\n        function updateDeleteSelectedButton() {\n            const selectedCount = document.querySelectorAll('.gallery-item-checkbox:checked').length;\n            document.querySelector('.delete-selected').disabled = selectedCount === 0;\n        }\n\n        \/\/ Keyboard navigation for preview modal\n        document.addEventListener('keydown', function(e) {\n            if (!previewModal.classList.contains('open')) return;\n            \n            switch(e.key) {\n                case 'Escape':\n                    closePreviewModal();\n                    break;\n                case 'ArrowLeft':\n                    if (currentImageIndex > 0) {\n                        currentImageIndex--;\n                        updatePreviewImage();\n                    }\n                    break;\n                case 'ArrowRight':\n                    if (currentImageIndex < galleryItems.length - 1) {\n                        currentImageIndex++;\n                        updatePreviewImage();\n                    }\n                    break;\n            }\n        });\n\n        \/\/ Update file handling function\n        function handleFiles(files) {\n            if (!files.length) return;\n            \n            \/\/ Filter files for valid types first\n            const validFiles = Array.from(files).filter(file => {\n                \/\/ Define allowed MIME types\n                const allowedTypes = [\n                    'image\/jpeg',\n                    'image\/png',\n                    'image\/gif',\n                    'image\/bmp',\n                    'image\/webp',\n                    'image\/tiff'\n                ];\n                \n                const isValid = allowedTypes.includes(file.type);\n                \n                if (!isValid) {\n                    showError(`${file.name} is not a supported image format. Supported formats: JPEG, PNG, GIF, BMP, WebP, TIFF`);\n                }\n                \n                return isValid;\n            });\n            \n            \/\/ Calculate current files count and max files limit\n            const currentCount = selectedFilesMap.size;\n            const maxFiles = typeof wpVision !== 'undefined' && wpVision.maxFiles ? \n                (wpVision.maxFiles[wpVision.subscriptionType] || wpVision.maxFiles.free) : 3;\n            \n            \/\/ First check file limits without auto-trimming to show modal\n            if (currentCount + validFiles.length > maxFiles) {\n                checkFileLimits(validFiles, false);\n            }\n            \n            \/\/ Now check with auto-trimming to process files\n            if (!checkFileLimits(validFiles, true)) return;\n            \n            \/\/ Get the limited files if needed\n            const limitedFiles = getLimitedFiles(validFiles);\n            if (limitedFiles.length === 0) return;\n            \n            \/\/ Process each file\n            limitedFiles.forEach(file => {\n                const fileId = 'file_' + Date.now() + '_' + Math.random().toString(36).substr(2, 9);\n                selectedFilesMap.set(fileId, file);\n                createFilePreview(file, fileId);\n            });\n            \n            \/\/ Update UI\n            updateButtonText();\n            showGalleryView();\n            renderGalleryItems();\n        }\n\n        \/\/ Add function to check file limits\n        function checkFileLimits(files, shouldTrim = false) {\n            const currentCount = selectedFilesMap.size;\n            const newCount = files.length;\n            const totalCount = currentCount + newCount;\n            \n            \/\/ Get maximum file limit\n            const maxFiles = typeof wpVision !== 'undefined' && wpVision.maxFiles ? \n                (wpVision.maxFiles[wpVision.subscriptionType] || wpVision.maxFiles.free) : 3;\n            \n            \/\/ Add detailed debug logs\n            console.log('Checking batch upload limits:', {\n                currentFilesCount: currentCount,\n                newFilesCount: newCount, \n                totalFilesCount: totalCount,\n                maxLimit: maxFiles,\n                subscriptionType: wpVision.subscriptionType,\n                shouldTrim: shouldTrim,\n                exceedsLimit: totalCount > maxFiles\n            });\n            \n            if (totalCount > maxFiles) {\n                \/\/ If not in trim mode, just show the modal and return false\n                if (!shouldTrim) {\n                    const limitModal = document.getElementById('visionLimitModal');\n                    if (limitModal) {\n                        limitModal.style.display = 'flex';\n                        document.body.style.overflow = 'hidden';\n                    } else {\n                        alert(`You can upload a maximum of ${maxFiles} images at once. Please remove some images and try again.`);\n                    }\n                    return false;\n                }\n                \n                \/\/ Calculate how many more files we can add\n                const remainingSlots = Math.max(0, maxFiles - currentCount);\n                \n                \/\/ If we can't add any more files\n                if (remainingSlots <= 0) {\n                    const limitModal = document.getElementById('visionLimitModal');\n                    if (limitModal) {\n                        limitModal.style.display = 'flex';\n                        document.body.style.overflow = 'hidden';\n                    }\n                    return false;\n                }\n                \n                \/\/ Always show the modal when exceeding limits, even in trim mode\n                const limitModal = document.getElementById('visionLimitModal');\n                if (limitModal) {\n                    limitModal.style.display = 'flex';\n                    document.body.style.overflow = 'hidden';\n                }\n                \n                \/\/ Return true since we'll process some files\n                return true;\n            }\n            \n            return true;\n        }\n        \n        \/\/ Function to get limited files according to subscription limits\n        function getLimitedFiles(files) {\n            const currentCount = selectedFilesMap.size;\n            \n            \/\/ Get maximum file limit\n            const maxFiles = typeof wpVision !== 'undefined' && wpVision.maxFiles ? \n                (wpVision.maxFiles[wpVision.subscriptionType] || wpVision.maxFiles.free) : 3;\n                \n            if (currentCount + files.length > maxFiles) {\n                \/\/ Calculate how many more files we can add\n                const remainingSlots = Math.max(0, maxFiles - currentCount);\n                \n                \/\/ If we can't add any more files\n                if (remainingSlots <= 0) {\n                    return [];\n                }\n                \n                \/\/ Return only the allowed number of files\n                return files.slice(0, remainingSlots);\n            }\n            \n            \/\/ If within limits, return all files\n            return files;\n        }\n\n        \/\/ Add function to show errors\n        function showError(message, type = 'error', duration = 3000) {\n            \/\/ Create or get toast notification element\n            let toastElement = document.querySelector('.vision-notification-toast');\n            if (!toastElement) {\n                toastElement = document.createElement('div');\n                toastElement.className = 'vision-notification-toast';\n                document.body.appendChild(toastElement);\n            }\n            \n            \/\/ Set notification type style\n            toastElement.className = `vision-notification-toast ${type}`;\n            \n            \/\/ Set notification content\n            toastElement.innerHTML = `\n                <div class=\"toast-icon\">\n                    ${type === 'error' ? '<i class=\"fas fa-exclamation-circle\"><\/i>' : \n                      type === 'warning' ? '<i class=\"fas fa-exclamation-triangle\"><\/i>' : \n                      '<i class=\"fas fa-info-circle\"><\/i>'}\n                <\/div>\n                <div class=\"toast-message\">${message}<\/div>\n            `;\n            \n            \/\/ Show notification\n            toastElement.classList.add('show');\n            \n            \/\/ Set auto-hide\n            setTimeout(() => {\n                toastElement.classList.remove('show');\n            }, duration);\n        }\n\n        \/\/ Add form submission event listener\n        document.getElementById('visionUploadForm').addEventListener('submit', function(e) {\n            e.preventDefault();\n            \n            \/\/ Prevent multiple submissions\n            if (isSubmitting) {\n                console.log('Form is already being submitted');\n                return;\n            }\n            \n            \/\/ Make sure results container is empty and hidden initially\n            const resultsContainer = document.getElementById('visionResults');\n            if (resultsContainer) {\n                resultsContainer.innerHTML = '';\n                resultsContainer.style.display = 'none';\n            }\n            \n            \/\/ Check if user is a subscriber\n            const isSubscriber = wpVision.isSubscriber;\n            \n            \/\/ If Turnstile is enabled and user is not a subscriber\n            if (wpVision.turnstile.enabled && !isSubscriber) {\n                \/\/ If Turnstile token is not yet obtained, show the Turnstile widget\n                if (!turnstileToken) {\n                    \/\/ Show Turnstile container\n                    if (turnstileContainer) {\n                        turnstileContainer.style.display = 'block';\n                    }\n                    \n                    \/\/ Scroll to Turnstile container\n                    if (turnstileContainer) {\n                        turnstileContainer.scrollIntoView({ behavior: 'smooth', block: 'center' });\n                    }\n                    \n                    \/\/ Render Turnstile widget if not already rendered\n                    if (!turnstileWidgetId && turnstileContainer) {\n                        turnstileWidgetId = turnstile.render('#visionTurnstileContainer', {\n                            sitekey: wpVision.turnstile.siteKey,\n                            callback: function(token) {\n                                console.log('Turnstile verification successful');\n                                \/\/ Store token\n                                turnstileToken = token;\n                                \n                                \/\/ Hide Turnstile container\n                                if (turnstileContainer) {\n                                    turnstileContainer.style.display = 'none';\n                                }\n                                \n                                \/\/ Now start the actual form submission process\n                                startFormSubmission();\n                            },\n                            'expired-callback': function() {\n                                \/\/ Reset token\n                                turnstileToken = '';\n                                turnstileWidgetId = null;\n                            }\n                        });\n                    }\n                    \n                    return;\n                }\n            }\n            \n            \/\/ If we reach here, either user is a subscriber or Turnstile verification is complete\n            startFormSubmission();\n        });\n        \n        \/\/ Override the global showProgress function to prevent it from being called elsewhere\n        window.showProgress = function() {\n            console.log('Global showProgress called but ignored');\n            \/\/ Do nothing - we'll control progress display ourselves\n        };\n        \n        \/\/ Function to start the form submission process\n        function startFormSubmission() {\n            console.log('Starting form submission process');\n            isSubmitting = true;\n            \n            \/\/ Hide image gallery and initial upload area\n            if (imageGalleryView) {\n                imageGalleryView.style.display = 'none';\n            }\n            \n            if (initialUploadArea) {\n                initialUploadArea.style.display = 'none';\n            }\n            \n            \/\/ Show loading state on button\n            if (convertButton) {\n                convertButton.disabled = true;\n                convertButton.innerHTML = '<span class=\"dashicons dashicons-update rotating\"><\/span> Converting...';\n            }\n            \n            \/\/ Now show results container with progress animation\n            const resultsContainer = document.getElementById('visionResults');\n            if (resultsContainer) {\n                resultsContainer.style.display = 'block';\n                \n                \/\/ Create animated progress indicator\n                const progressHtml = `\n                    <div class=\"vision-animated-loader\">\n                        <div class=\"loader-pulse\">\n                            <div class=\"loader-track\"><\/div>\n                            <div class=\"loader-progress\"><\/div>\n                            <div class=\"loader-circle\"><\/div>\n                            <div class=\"loader-particles\">\n                                <div class=\"particle\"><\/div>\n                                <div class=\"particle\"><\/div>\n                                <div class=\"particle\"><\/div>\n                                <div class=\"particle\"><\/div>\n                                <div class=\"particle\"><\/div>\n                            <\/div>\n                            <div class=\"loader-complete\"><\/div>\n                        <\/div>\n                    <\/div>\n                `;\n                \n                resultsContainer.innerHTML = progressHtml;\n            }\n            \n            \/\/ Now proceed with the actual AJAX submission\n            submitFormData();\n        }\n        \n        \/\/ Function to submit the form data via AJAX\n        async function submitFormData() {\n            try {\n                \/\/ Create FormData object\n                const formData = new FormData();\n                \n                \/\/ Add all selected files\n                selectedFilesMap.forEach((file, fileId) => {\n                    formData.append('files[]', file);\n                });\n                \n                \/\/ Add other necessary data\n                formData.append('action', 'vision_convert_images');\n                formData.append('nonce', wpVision.nonce);\n                \n                \/\/ Add Turnstile token if available\n                if (turnstileToken) {\n                    formData.append('turnstile_token', turnstileToken);\n                }\n                \n                console.log('Sending AJAX request');\n                \/\/ Send a single AJAX request\n                const response = await fetch(wpVision.ajaxurl, {\n                    method: 'POST',\n                    body: formData,\n                    credentials: 'same-origin'\n                });\n\n                const data = await response.json();\n                \n                \/\/ Clear animated progress indicator\n                const resultsContainer = document.getElementById('visionResults');\n                if (resultsContainer) {\n                    resultsContainer.innerHTML = '';\n                }\n                \n                \/\/ Check for daily limit error in error response\n                if (!data.success && data.data && data.data.error === 'daily_limit_reached') {\n                    console.log('Daily limit reached:', data.data);\n                    \n                    \/\/ Update daily uploads count\n                    if (data.data.dailyUploadsCount !== undefined) {\n                        wpVision.dailyUploadsCount = data.data.dailyUploadsCount;\n                    }\n                    \n                    \/\/ Show gallery view again\n                    if (imageGalleryView) {\n                        imageGalleryView.style.display = 'block';\n                    }\n                    \n                    \/\/ Show daily limit warning\n                    const limitWarning = document.getElementById('visionDailyLimitWarning');\n                    if (limitWarning) {\n                        limitWarning.style.display = 'block';\n                        limitWarning.classList.add('show');\n                    }\n                    \n                    \/\/ Disable convert button\n                    if (convertButton) {\n                        convertButton.disabled = true;\n                        convertButton.classList.add('disabled-by-limit');\n                    }\n                    \n                    \/\/ Start countdown timer\n                    startLimitCountdown();\n                    \n                    \/\/ Show user-friendly message\n                    showError(data.data.message || 'Daily limit reached. Please try again tomorrow.');\n                    return;\n                }\n                \n                if (data.success) {\n                    console.log('AJAX request successful');\n                    \n                    \/\/ Update daily uploads count if provided in response\n                    if (data.data.dailyUploadsCount !== undefined) {\n                        wpVision.dailyUploadsCount = data.data.dailyUploadsCount;\n                        \n                        \/\/ If we've reached the limit during this upload, show warning after displaying results\n                        if (data.data.reachedLimit) {\n                            setTimeout(() => {\n                                const limitWarning = document.getElementById('visionDailyLimitWarning');\n                                if (limitWarning) {\n                                    limitWarning.style.display = 'block';\n                                    limitWarning.classList.add('show');\n                                }\n                                \n                                \/\/ Start countdown timer\n                                startLimitCountdown();\n                            }, 1000);\n                        }\n                    }\n                    \n                    \/\/ Display conversion results\n                    const results = data.data.results || data.data;\n                    displayResults(results);\n                } else {\n                    console.log('AJAX request failed:', data.data);\n                    showError(data.data || 'Error processing images');\n                    \n                    \/\/ Show gallery view again\n                    if (imageGalleryView) {\n                        imageGalleryView.style.display = 'block';\n                    }\n                    \n                    \/\/ Reset Turnstile if verification failed\n                    if (data.data && data.data.includes && data.data.includes('verification')) {\n                        turnstileToken = '';\n                        if (turnstileWidgetId) {\n                            turnstile.reset(turnstileWidgetId);\n                        }\n                        if (turnstileContainer) {\n                            turnstileContainer.style.display = 'block';\n                        }\n                    }\n                }\n            } catch (error) {\n                console.error('Error:', error);\n                showError('Network error occurred');\n                \n                \/\/ Show gallery view again\n                if (imageGalleryView) {\n                    imageGalleryView.style.display = 'block';\n                }\n                \n                \/\/ Clear animated progress indicator\n                const resultsContainer = document.getElementById('visionResults');\n                if (resultsContainer) {\n                    resultsContainer.innerHTML = '';\n                }\n            } finally {\n                \/\/ Reset button state\n                if (convertButton) {\n                    convertButton.disabled = false;\n                    convertButton.innerHTML = '<span class=\"dashicons dashicons-text-page\"><\/span> Convert';\n                }\n                \n                isSubmitting = false; \/\/ Reset submission status\n            }\n        }\n        \n        \/\/ Start limit countdown timer\n        function startLimitCountdown() {\n            const countdownElem = document.getElementById('limitCountdownTime');\n            if (!countdownElem) return;\n            \n            \/\/ Clear previous interval if any\n            if (window.limitCountdownInterval) {\n                clearInterval(window.limitCountdownInterval);\n            }\n            \n            \/\/ Update countdown time\n            function updateCountdown() {\n                const now = new Date();\n                const tomorrow = new Date();\n                tomorrow.setHours(24, 0, 0, 0);\n                \n                const diff = tomorrow - now;\n                const hours = Math.floor(diff \/ (1000 * 60 * 60));\n                const minutes = Math.floor((diff % (1000 * 60 * 60)) \/ (1000 * 60));\n                const seconds = Math.floor((diff % (1000 * 60)) \/ 1000);\n                \n                countdownElem.textContent = \n                    String(hours).padStart(2, '0') + ':' + \n                    String(minutes).padStart(2, '0') + ':' + \n                    String(seconds).padStart(2, '0');\n            }\n            \n            \/\/ Update immediately\n            updateCountdown();\n            \n            \/\/ Update every second\n            window.limitCountdownInterval = setInterval(updateCountdown, 1000);\n        }\n\n        \/\/ Display function for showing conversion results\n        function displayResults(resultData) {\n            const resultsContainer = document.getElementById('visionResults');\n            \n            \/\/ Make sure progress container is hidden\n            const progressContainer = document.getElementById('visionProgressContainer');\n            if (progressContainer) {\n                progressContainer.style.display = 'none';\n            }\n\n            \/\/ Make results container visible\n            if (resultsContainer) {\n                resultsContainer.style.display = 'block';\n            }\n\n            \/\/ Add class to body when results are shown\n            document.body.classList.add('vision-results-active');\n            \n            \/\/ Store original data in a global variable\n            window.visionResultData = resultData;\n            \n            \/\/ Create header HTML\n            const headerHtml = `\n                <div class=\"results-header mobile-friendly\">\n                    <div class=\"header-left\">\n                        <button type=\"button\" class=\"result-button return-button\" onclick=\"return returnToUpload(event)\" title=\"Return to upload\">\n                            <span class=\"dashicons dashicons-arrow-left-alt\"><\/span>\n                            <span class=\"button-text\">Back<\/span>\n                        <\/button>\n                    <\/div>\n                    <div class=\"header-center\">\n                        <div class=\"expand-controls\">\n                            <button type=\"button\" class=\"result-button toggle-all-button\" onclick=\"return toggleAllResults(event)\" title=\"Toggle expand\/collapse all\">\n                                <span class=\"dashicons dashicons-arrow-down-alt2\"><\/span>\n                                <span class=\"button-text\">Expand All<\/span>\n                            <\/button>\n                        <\/div>\n                    <\/div>\n                    <div class=\"header-right\">\n                        <button type=\"button\" class=\"result-button download-all-button\" onclick=\"return downloadAllResults(event)\" title=\"Download results as TXT or ZIP\">\n                            <span class=\"dashicons dashicons-download\"><\/span>\n                            <span class=\"button-text\">Download All<\/span>\n                        <\/button>\n                    <\/div>\n                <\/div>\n            `;\n\n            \/\/ Generate results HTML with accordion functionality\n            const resultsHtml = resultData.map((result, index) => {\n                if (result.error) {\n                    return `\n                        <div class=\"result-item\">\n                            <div class=\"result-header\">\n                                <h3>${result.fileName}<\/h3>\n                                <span class=\"toggle-icon dashicons dashicons-arrow-down-alt2\"><\/span>\n                            <\/div>\n                            <div class=\"result-body\">\n                                <div class=\"result-error\">${result.error}<\/div>\n                            <\/div>\n                        <\/div>\n                    `;\n                }\n                \n                \/\/ Get image URL from selected files\n                const originalImage = selectedFilesMap.get(Array.from(selectedFilesMap.keys()).find(key => \n                    selectedFilesMap.get(key).name === result.fileName\n                ));\n                const imageUrl = originalImage ? URL.createObjectURL(originalImage) : '';\n                \n                \/\/ First item expanded by default, others collapsed\n                const isExpanded = index === 0 ? 'expanded' : '';\n                \n                \/\/ Create truncated filename for display - more characters for desktop\n                const isMobile = window.innerWidth <= 768;\n                const isTablet = window.innerWidth > 768 && window.innerWidth <= 1024;\n                \/\/ Adjust character limits for different device types\n                const charLimit = isMobile ? 15 : (isTablet ? 30 : 60); \/\/ Shorter on mobile, medium on tablet, longer on desktop\n                const truncatedFileName = result.fileName.length > charLimit ? \n                    result.fileName.substring(0, charLimit - 3) + '...' : \n                    result.fileName;\n                \n                return `\n                    <div class=\"result-item ${isExpanded}\" data-id=\"${result.id}\">\n                        <div class=\"result-header\" onclick=\"toggleResultItem(this.parentElement)\">\n                            <table style=\"width:auto; border:none; margin:0; padding:0; border-spacing:0; border-collapse:collapse;\">\n                                <tr>\n                                    <td style=\"vertical-align:middle; padding:0; white-space:nowrap;\">\n                                        <span class=\"toggle-icon dashicons dashicons-arrow-down-alt2\"><\/span>\n                                        <h3 title=\"${result.fileName}\" style=\"display:inline-block; max-width:calc(100% - 10px); text-overflow:ellipsis; overflow:hidden;\">${truncatedFileName}<\/h3>\n                                    <\/td>\n                                <\/tr>\n                            <\/table>\n                            <div class=\"result-header-actions\">\n                                <button type=\"button\" class=\"item-action-btn preview-icon-btn vision-custom-btn\" onclick=\"event.stopPropagation(); openPreviewModal('${imageUrl}', '${result.fileName}', '${result.text.replace(\/'\/g, \"\\\\'\").replace(\/\\n\/g, \"\\\\n\")}')\" title=\"View Image and Text\">\n                                    <i class=\"fas fa-eye\" style=\"font-size:20px !important; width:20px !important; height:20px !important; display:inline-flex !important; align-items:center !important; justify-content:center !important; margin:0 !important; color:#0ea5e9 !important;\"><\/i>\n                                    <span class=\"btn-action-text\">Preview<\/span>\n                                <\/button>\n                                <button type=\"button\" class=\"item-action-btn copy-icon-btn vision-custom-btn\" onclick=\"event.stopPropagation(); return copyText(this, event)\" title=\"Copy Text\">\n                                    <i class=\"fas fa-copy\" style=\"font-size:20px !important; width:20px !important; height:20px !important; display:inline-flex !important; align-items:center !important; justify-content:center !important; margin:0 !important; color:#4f46e5 !important;\"><\/i>\n                                    <span class=\"btn-action-text\">Copy<\/span>\n                                <\/button>\n                                <button type=\"button\" class=\"item-action-btn download-icon-btn vision-custom-btn\" onclick=\"event.stopPropagation(); return visionDownloadText(this, event)\" title=\"Download Text\">\n                                    <i class=\"fas fa-file-download\" style=\"font-size:20px !important; width:20px !important; height:20px !important; display:inline-flex !important; align-items:center !important; justify-content:center !important; margin:0 !important; color:#2563eb !important;\"><\/i>\n                                    <span class=\"btn-action-text\">Download<\/span>\n                                <\/button>\n                            <\/div>\n                        <\/div>\n                        <div class=\"result-body\">\n                            <div class=\"result-content\">\n                                <div class=\"result-image-preview\">\n                                    <img decoding=\"async\" src=\"${imageUrl}\" alt=\"${result.fileName}\" onclick=\"openPreviewModal('${imageUrl}', '${result.fileName}', '${result.text.replace(\/'\/g, \"\\\\'\").replace(\/\\n\/g, \"\\\\n\")}')\">\n                                    <div class=\"image-click-indicator\" title=\"Click to view in detail\" onclick=\"openPreviewModal('${imageUrl}', '${result.fileName}', '${result.text.replace(\/'\/g, \"\\\\'\").replace(\/\\n\/g, \"\\\\n\")}')\">\n                                        <span class=\"dashicons dashicons-visibility\"><\/span>\n                                    <\/div>\n                                <\/div>\n                                <div class=\"result-text-container\">\n                                    <div class=\"result-text notranslate\" contenteditable=\"true\" translate=\"no\" data-notranslate>${result.text}<\/div>\n                                <\/div>\n                            <\/div>\n                        <\/div>\n                    <\/div>\n                `;\n            }).join('');\n\n            \/\/ Add modal for enhanced preview\n            const modalHtml = `\n                <div class=\"vision-preview-modal\">\n                    <div class=\"modal-container\">\n                        <div class=\"modal-image-section\">\n                            <div class=\"modal-image-container\">\n                                <img decoding=\"async\" class=\"modal-image\" src=\"\" alt=\"\">\n                            <\/div>\n                            <div class=\"modal-image-controls\">\n                                <div class=\"image-control\" onclick=\"zoomImage(-0.1)\">\n                                    <span class=\"dashicons dashicons-minus\"><\/span>\n                                <\/div>\n                                <div class=\"image-control\" onclick=\"zoomImage(0.1)\">\n                                    <span class=\"dashicons dashicons-plus\"><\/span>\n                                <\/div>\n                                <div class=\"image-control\" onclick=\"rotateImage()\">\n                                    <span class=\"dashicons dashicons-redo\"><\/span>\n                                <\/div>\n                            <\/div>\n                        <\/div>\n                        <div class=\"modal-text-section\">\n                            <div class=\"modal-header\">\n                                <h3 class=\"modal-title\"><\/h3>\n                            <\/div>\n                            <div class=\"modal-text-content notranslate\" translate=\"no\" data-notranslate><\/div>\n                        <\/div>\n                        <div class=\"modal-close\" onclick=\"closePreviewModal()\">\n                            <span class=\"dashicons dashicons-no-alt\"><\/span>\n                        <\/div>\n                    <\/div>\n                <\/div>\n            `;\n            \n            \/\/ Set container content and add event handlers\n            resultsContainer.innerHTML = headerHtml + resultsHtml + modalHtml;\n            \n            \/\/ Hide upload elements and show results\n            document.getElementById('imageGalleryView').style.display = 'none';\n            document.getElementById('initialUploadArea').style.display = 'none';\n            resultsContainer.style.display = 'block';\n        }\n\n        \/\/ Toggle accordion result item\n        window.toggleResultItem = function(item) {\n            \/\/ Close all items first\n            document.querySelectorAll('.result-item.expanded').forEach(expandedItem => {\n                if (expandedItem !== item) {\n                    expandedItem.classList.remove('expanded');\n                }\n            });\n            \n            \/\/ Toggle current item\n            item.classList.toggle('expanded');\n        }\n        \n        \/\/ Toggle all result items (expand\/collapse)\n        window.toggleAllResults = function(event) {\n            if (event) event.preventDefault();\n            \n            const button = event.currentTarget;\n            const isExpanded = button.getAttribute('data-expanded') === 'true';\n            \n            if (isExpanded) {\n                \/\/ Collapse all\n                document.querySelectorAll('.result-item').forEach(item => {\n                    item.classList.remove('expanded');\n                });\n                \n                \/\/ Update button\n                button.innerHTML = '<span class=\"dashicons dashicons-arrow-down-alt2\"><\/span><span class=\"button-text\">Expand All<\/span>';\n                button.setAttribute('data-expanded', 'false');\n            } else {\n                \/\/ Expand all\n                document.querySelectorAll('.result-item').forEach(item => {\n                    item.classList.add('expanded');\n                });\n                \n                \/\/ Update button\n                button.innerHTML = '<span class=\"dashicons dashicons-arrow-up-alt2\"><\/span><span class=\"button-text\">Collapse All<\/span>';\n                button.setAttribute('data-expanded', 'true');\n            }\n            \n            return false;\n        }\n        \n        \/\/ Copy text to clipboard\n        window.copyText = function(button, event) {\n            \/\/ Prevent any default action and stop event propagation\n            if (event) {\n                event.preventDefault();\n                event.stopPropagation();\n            }\n            \n            \/\/ Find the closest result item and get the text content\n            const resultItem = button.closest('.result-item');\n            const textContent = resultItem.querySelector('.result-text').textContent;\n            \n            \/\/ Save original icon for restoration\n            const originalIcon = button.innerHTML;\n            \n            \/\/ Use the clipboard API to copy the text\n            navigator.clipboard.writeText(textContent)\n                .then(() => {\n                    \/\/ Show success feedback - ONLY ICON, NO TEXT\n                    button.innerHTML = '<i class=\"fas fa-check\" style=\"font-size:20px !important; width:20px !important; height:20px !important; display:inline-flex !important; align-items:center !important; justify-content:center !important; margin:0 !important; color:#22c55e !important;\"><\/i>';\n                    \n                    \/\/ Reset button after a delay\n                    setTimeout(() => {\n                        button.innerHTML = originalIcon;\n                    }, 2000);\n                })\n                .catch(err => {\n                    console.error('Failed to copy text: ', err);\n                    \n                    \/\/ Show error feedback - ONLY ICON, NO TEXT\n                    button.innerHTML = '<i class=\"fas fa-exclamation-triangle\" style=\"font-size:20px !important; width:20px !important; height:20px !important; display:inline-flex !important; align-items:center !important; justify-content:center !important; margin:0 !important; color:#ef4444 !important;\"><\/i>';\n                    \n                    \/\/ Reset button after a delay\n                    setTimeout(() => {\n                        button.innerHTML = originalIcon;\n                    }, 2000);\n                });\n            \n            \/\/ Return false to prevent default action\n            return false;\n        }\n        \n        \/\/ Download text as file\n        window.visionDownloadText = function(button, event) {\n            \/\/ Prevent any default action and stop event propagation\n            if (event) {\n                event.preventDefault();\n                event.stopPropagation();\n            }\n            \n            \/\/ Find the closest result item and get necessary data\n            const resultItem = button.closest('.result-item');\n            const textContent = resultItem.querySelector('.result-text').textContent;\n            const fileName = resultItem.querySelector('.result-header h3').textContent;\n            \n            \/\/ Save original icon for restoration\n            const originalIcon = button.innerHTML;\n            \n            \/\/ Create a Blob with the text content\n            const blob = new Blob([textContent], {type: 'text\/plain;charset=utf-8'});\n            \n            \/\/ Use FileSaver.js to save the file\n            try {\n                \/\/ Show downloading feedback\n                button.innerHTML = '<i class=\"fas fa-spinner fa-spin\" style=\"font-size:20px !important; width:20px !important; height:20px !important; display:inline-flex !important; align-items:center !important; justify-content:center !important; margin:0 !important; color:#2563eb !important;\"><\/i>';\n                \n                \/\/ Download the file\n                saveAs(blob, fileName.replace(\/\\.[^\/.]+$\/, \"\") + '.txt');\n                \n                \/\/ Reset button after a delay\n                setTimeout(() => {\n                    button.innerHTML = originalIcon;\n                }, 2000);\n            } catch (err) {\n                console.error('Failed to download text: ', err);\n                \n                \/\/ Show error feedback\n                button.innerHTML = '<i class=\"fas fa-exclamation-triangle\" style=\"font-size:20px !important; width:20px !important; height:20px !important; display:inline-flex !important; align-items:center !important; justify-content:center !important; margin:0 !important; color:#ef4444 !important;\"><\/i>';\n                \n                \/\/ Reset button after a delay\n                setTimeout(() => {\n                    button.innerHTML = originalIcon;\n                }, 2000);\n            }\n            \n            \/\/ Return false to prevent default action\n            return false;\n        }\n        \n        \/\/ Open enhanced preview modal\n        window.openPreviewModal = function(imageUrl, fileName, textContent) {\n            const modal = document.querySelector('.vision-preview-modal');\n            const modalImage = modal.querySelector('.modal-image');\n            const modalTitle = modal.querySelector('.modal-title');\n            const modalTextContent = modal.querySelector('.modal-text-content');\n            \n            \/\/ Set content\n            modalImage.src = imageUrl;\n            modalImage.setAttribute('data-scale', '1');\n            modalImage.setAttribute('data-rotate', '0');\n            modalTitle.textContent = fileName;\n            \n            \/\/ Properly handle text formatting, preserving line breaks\n            const formattedText = textContent.replace(\/\\\\n\/g, \"\\n\");\n            \n            \/\/ Clear content\n            modalTextContent.innerHTML = '';\n            \n            \/\/ Split text into paragraphs and add to container\n            const paragraphs = formattedText.split(\"\\n\");\n            paragraphs.forEach(paragraph => {\n                if (paragraph.trim()) {\n                    const p = document.createElement('p');\n                    p.textContent = paragraph;\n                    p.style.margin = '0 0 12px 0';\n                    modalTextContent.appendChild(p);\n                } else {\n                    \/\/ Add extra spacing for empty lines\n                    const spacer = document.createElement('div');\n                    spacer.style.height = '12px';\n                    modalTextContent.appendChild(spacer);\n                }\n            });\n            \n            \/\/ Show modal\n            modal.classList.add('open');\n            document.body.style.overflow = 'hidden';\n        }\n        \n        \/\/ Close preview modal\n        window.closePreviewModal = function() {\n            const modal = document.querySelector('.vision-preview-modal');\n            modal.classList.remove('open');\n            document.body.style.overflow = '';\n        }\n        \n        \/\/ Image zoom functionality\n        window.zoomImage = function(delta) {\n            const modalImage = document.querySelector('.modal-image');\n            let scale = parseFloat(modalImage.getAttribute('data-scale') || '1');\n            scale = Math.max(0.5, Math.min(3, scale + delta));\n            modalImage.setAttribute('data-scale', scale);\n            modalImage.style.transform = `scale(${scale}) rotate(${modalImage.getAttribute('data-rotate')}deg)`;\n        }\n        \n        \/\/ Image rotate functionality\n        window.rotateImage = function() {\n            const modalImage = document.querySelector('.modal-image');\n            let rotate = parseInt(modalImage.getAttribute('data-rotate') || '0');\n            rotate = (rotate + 90) % 360;\n            modalImage.setAttribute('data-rotate', rotate);\n            modalImage.style.transform = `scale(${modalImage.getAttribute('data-scale')}) rotate(${rotate}deg)`;\n        }\n        \n        \/\/ Reset image transformation\n        window.resetImage = function() {\n            const modalImage = document.querySelector('.modal-image');\n            modalImage.setAttribute('data-scale', '1');\n            modalImage.setAttribute('data-rotate', '0');\n            modalImage.style.transform = 'scale(1) rotate(0deg)';\n        }\n        \n        \/\/ Download all texts (single TXT or ZIP for multiple)\n        window.downloadAllResults = function(event) {\n            \/\/ Prevent any default action\n            if (event) event.preventDefault();\n            \n            \/\/ Get all valid result items (excluding those with errors)\n            const resultItems = Array.from(document.querySelectorAll('.result-item'))\n                .filter(item => !item.querySelector('.result-error'));\n            \n            if (resultItems.length === 0) {\n                console.warn('No valid result items found');\n                return;\n            }\n            \n            \/\/ Show download status\n            const downloadBtn = document.querySelector('.download-all-button');\n            const originalText = downloadBtn.innerHTML;\n            \n            \/\/ If there's only one item, download it directly as TXT\n            if (resultItems.length === 1) {\n                const item = resultItems[0];\n                const fileName = item.querySelector('.result-header h3').textContent;\n                const textContent = item.querySelector('.result-text').textContent;\n                \n                \/\/ Update button text\n                downloadBtn.innerHTML = '<span class=\"dashicons dashicons-download\"><\/span> Downloading...';\n                \n                \/\/ Create and download a single text file\n                const blob = new Blob([textContent], {type: 'text\/plain;charset=utf-8'});\n                saveAs(blob, fileName.replace(\/\\.[^\/.]+$\/, \"\") + '.txt');\n                \n                \/\/ Update button to show success\n                downloadBtn.innerHTML = '<span class=\"dashicons dashicons-yes\"><\/span> Downloaded!';\n                \n                \/\/ Reset button after a delay\n                setTimeout(() => {\n                    downloadBtn.innerHTML = originalText;\n                }, 2000);\n                \n                return false;\n            }\n            \n            \/\/ For multiple items, create a ZIP file (existing logic)\n            \/\/ Check if JSZip is available\n            if (typeof JSZip === 'undefined') {\n                console.error('JSZip is not loaded');\n                return;\n            }\n            \n            \/\/ Update button for ZIP creation\n            downloadBtn.innerHTML = '<span class=\"dashicons dashicons-update rotating\"><\/span> Creating zip...';\n            \n            \/\/ Create a new zip file\n            const zip = new JSZip();\n            \n            \/\/ Add each text file to the zip\n            resultItems.forEach((item) => {\n                const fileName = item.querySelector('.result-header h3').textContent;\n                const textContent = item.querySelector('.result-text').textContent;\n                \n                \/\/ Add file to zip\n                zip.file(fileName.replace(\/\\.[^\/.]+$\/, \"\") + '.txt', textContent);\n            });\n            \n            \/\/ Generate the zip file\n            zip.generateAsync({type: 'blob'})\n                .then(blob => {\n                    \/\/ Use FileSaver.js to save the zip file\n                    saveAs(blob, 'converted_texts_' + new Date().toISOString().slice(0, 10) + '.zip');\n                    \n                    \/\/ Update button to show success\n                    downloadBtn.innerHTML = '<span class=\"dashicons dashicons-yes\"><\/span> Downloaded!';\n                    \n                    \/\/ Reset button after a delay\n                    setTimeout(() => {\n                        downloadBtn.innerHTML = originalText;\n                    }, 2000);\n                })\n                .catch(err => {\n                    console.error('Failed to create zip file: ', err);\n                    \n                    \/\/ Show error on button\n                    downloadBtn.innerHTML = '<span class=\"dashicons dashicons-warning\"><\/span> Error!';\n                    \n                    \/\/ Reset button after a delay\n                    setTimeout(() => {\n                        downloadBtn.innerHTML = originalText;\n                    }, 2000);\n                });\n        }\n\n        \/\/ Check daily limit on page load\n        if (wpVision && wpVision.dailyUploadsCount !== undefined && wpVision.dailyLimit !== undefined) {\n            if (!wpVision.isSubscriber && wpVision.dailyUploadsCount >= wpVision.dailyLimit) {\n                const limitWarning = document.getElementById('visionDailyLimitWarning');\n                if (limitWarning) {\n                    limitWarning.style.display = 'block';\n                    limitWarning.classList.add('show');\n                    \n                    \/\/ Disable convert button\n                    if (convertButton) {\n                        convertButton.disabled = true;\n                        convertButton.classList.add('disabled-by-limit');\n                    }\n                    \n                    \/\/ Start the countdown\n                    startLimitCountdown();\n                }\n            }\n        }\n    }\n});\n<\/script><\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-4b51761 e-flex e-con-boxed e-con e-child\" data-id=\"4b51761\" data-element_type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-8475d63 elementor-widget elementor-widget-html\" data-id=\"8475d63\" data-element_type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<style>\r\n    * {\r\n      margin: 0;\r\n      padding: 0;\r\n      box-sizing: border-box;\r\n      font-family: 'Segoe UI', 'SF Pro Display', Arial, sans-serif;\r\n    }\r\n    \r\n    body {\r\n      background-color: #fafafa;\r\n    }\r\n    \r\n    .premium-features {\r\n      display: flex;\r\n      justify-content: center;\r\n      flex-wrap: wrap;\r\n      gap: 16px;\r\n      padding: 20px 10px;\r\n      max-width: 900px;\r\n      margin: 0 auto;\r\n    }\r\n    \r\n    .premium-badge {\r\n      display: flex;\r\n      align-items: center;\r\n      gap: 12px;\r\n      background-color: white;\r\n      padding: 10px 16px;\r\n      border-radius: 50px;\r\n      box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);\r\n      transition: all 0.3s ease;\r\n      border: 1px solid rgba(0, 0, 0, 0.05);\r\n    }\r\n    \r\n    .premium-badge:hover {\r\n      transform: translateY(-3px);\r\n      box-shadow: 0 6px 16px rgba(0, 0, 0, 0.1);\r\n    }\r\n    \r\n    .badge-icon {\r\n      display: flex;\r\n      align-items: center;\r\n      justify-content: center;\r\n      width: 28px;\r\n      height: 28px;\r\n      border-radius: 50%;\r\n      color: white;\r\n      font-size: 14px;\r\n    }\r\n    .premium-badge:nth-child(1) .badge-icon {\r\n      background: linear-gradient(135deg, #ff6f00 0%, #ff8f00 100%);\r\n    }\r\n\r\n    .premium-badge:nth-child(2) .badge-icon {\r\n      background: linear-gradient(135deg, #ab47bc 0%, #8e24aa 100%);\r\n    }\r\n\r\n    .premium-badge:nth-child(3) .badge-icon {\r\n      background: linear-gradient(135deg, #00c853 0%, #009624 100%);\r\n    }\r\n    \r\n    .badge-icon svg {\r\n      width: 16px;\r\n      height: 16px;\r\n      fill: none;\r\n      stroke: currentColor;\r\n      stroke-width: 2;\r\n      stroke-linecap: round;\r\n      stroke-linejoin: round;\r\n    }\r\n    \r\n    .badge-text {\r\n      font-size: 14px;\r\n      font-weight: 600;\r\n      color: #333;\r\n    }\r\n    \r\n    \/* Media queries for responsiveness *\/\r\n    @media (max-width: 768px) {\r\n      .premium-features {\r\n        padding: 15px 10px;\r\n      }\r\n    }\r\n    \r\n    @media (max-width: 480px) {\r\n      .premium-features {\r\n        flex-direction: column;\r\n        align-items: center;\r\n      }\r\n      \r\n      .premium-badge {\r\n        width: 100%;\r\n        max-width: 260px;\r\n        justify-content: flex-start;\r\n      }\r\n    }\r\n  <\/style>\r\n<\/head>\r\n<body>\r\n  <div class=\"premium-features\">\r\n    <div class=\"premium-badge\">\r\n      <div class=\"badge-icon\">\r\n        <svg viewBox=\"0 0 24 24\">\r\n          <circle cx=\"12\" cy=\"12\" r=\"10\"><\/circle>\r\n          <line x1=\"2\" y1=\"12\" x2=\"22\" y2=\"12\"><\/line>\r\n          <path d=\"M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z\"><\/path>\r\n        <\/svg>\r\n      <\/div>\r\n      <div class=\"badge-text\">100+ Languages<\/div>\r\n    <\/div>\r\n    \r\n    <div class=\"premium-badge\">\r\n      <div class=\"badge-icon\">\r\n        <svg viewBox=\"0 0 24 24\">\r\n          <path d=\"M20 6L9 17l-5-5\"><\/path>\r\n        <\/svg>\r\n      <\/div>\r\n      <div class=\"badge-text\">99.8% Accuracy<\/div>\r\n    <\/div>\r\n    \r\n    <div class=\"premium-badge\">\r\n      <div class=\"badge-icon\">\r\n        <svg viewBox=\"0 0 24 24\">\r\n          <rect x=\"3\" y=\"11\" width=\"18\" height=\"11\" rx=\"2\" ry=\"2\"><\/rect>\r\n          <path d=\"M7 11V7a5 5 0 0 1 10 0v4\"><\/path>\r\n        <\/svg>\r\n      <\/div>\r\n      <div class=\"badge-text\">Secure & Private<\/div>\r\n    <\/div>\r\n  <\/div>\r\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-baccefc e-flex e-con-boxed e-con e-parent\" data-id=\"baccefc\" data-element_type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-e623faa elementor-widget elementor-widget-shortcode\" data-id=\"e623faa\" data-element_type=\"widget\" data-widget_type=\"shortcode.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<div class=\"elementor-shortcode\"><script async src=\"https:\/\/pagead2.googlesyndication.com\/pagead\/js\/adsbygoogle.js?client=ca-pub-8069529413860845\"\n     crossorigin=\"anonymous\"><\/script>\n<!-- 1000-100 -->\n<ins class=\"adsbygoogle\"\n     style=\"display:inline-block;width:1000px;height:100px\"\n     data-ad-client=\"ca-pub-8069529413860845\"\n     data-ad-slot=\"9855343712\"><\/ins>\n<script>\n     (adsbygoogle = window.adsbygoogle || []).push({});\n<\/script><\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-f5b788b e-flex e-con-boxed e-con e-parent\" data-id=\"f5b788b\" data-element_type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-5ba6856 elementor-widget elementor-widget-heading\" data-id=\"5ba6856\" data-element_type=\"widget\" data-widget_type=\"heading.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<h2 class=\"elementor-heading-title elementor-size-default\">Your first choice for handwriting-to-text<\/h2>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-fbe34fc elementor-widget elementor-widget-text-editor\" data-id=\"fbe34fc\" data-element_type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>We have developed OCR365 with a focus on user-friendliness, accuracy, and speed. Our intuitive interface allows you to easily upload your scanned images and receive the converted text within seconds. We utilize advanced OCR algorithms that are specifically trained to recognize a wide variety of handwriting styles, ensuring a high level of accuracy even with less-than-perfect handwriting.<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-7d431b7 elementor-widget elementor-widget-heading\" data-id=\"7d431b7\" data-element_type=\"widget\" data-widget_type=\"heading.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<h2 class=\"elementor-heading-title elementor-size-default\">\"Everything You Write Becomes Text!\"<\/h2>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-6df617e elementor-widget elementor-widget-ucaddon_uc_material_bullets\" data-id=\"6df617e\" data-element_type=\"widget\" data-widget_type=\"ucaddon_uc_material_bullets.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\n<!-- start Icon Bullets -->\n\t\t<link id='font-awesome-css' href='https:\/\/ocr365.com\/wp-content\/plugins\/unlimited-elements-for-elementor-premium\/assets_libraries\/font-awesome6\/fontawesome-all.min.css' type='text\/css' rel='stylesheet' >\n\t\t<link id='font-awesome-4-shim-css' href='https:\/\/ocr365.com\/wp-content\/plugins\/unlimited-elements-for-elementor-premium\/assets_libraries\/font-awesome6\/fontawesome-v4-shims.min.css' type='text\/css' rel='stylesheet' >\n\n<style>\/* widget: Icon Bullets *\/\n\n\n\n#uc_uc_material_bullets_elementor_6df617e *{\n\t-webkit-box-sizing: border-box;\n\t-moz-box-sizing: border-box;\n\tbox-sizing: border-box;\n}\n\n#uc_uc_material_bullets_elementor_6df617e .ue-icon-wrapper{\n\tdisplay: flex;\n}\n\n#uc_uc_material_bullets_elementor_6df617e .ue-icon{\n  display:flex;\n  align-items:center;\n  justify-content:center;\n  flex-grow:0;\n  flex-shrink:0;\n  line-height:1em;\n  transition:0.3s;\n}\n\n#uc_uc_material_bullets_elementor_6df617e .ue-icon svg{\n  height:1em;\n  width:1em;\n}\n\n#uc_uc_material_bullets_elementor_6df617e .uc_material_bullets_row{\n\tfont-weight:400;\n\toverflow:hidden;\n\tdisplay:flex;\n\tposition:relative;\n\ttext-align:left;\n\twidth:100%;   \n    transition:0.3s;\n}\n\n#uc_uc_material_bullets_elementor_6df617e .uc_material_bullets_row a.ue-item-link{\n  position:absolute;\n  display:block;\n  top:0;\n  right:0;\n  left:0;\n  bottom:0;\n}\n\n#uc_uc_material_bullets_elementor_6df617e .uc_material_bullets_row:last-child{\n\tmargin-bottom:0px !important;\n}\n\n\n#uc_uc_material_bullets_elementor_6df617e .uc_material_bullets_row {\n\tposition:relative;\n\tvertical-align:middle;\n}\n\n#uc_uc_material_bullets_elementor_6df617e .uc_material_bullets_row .uc_content_box{\n\tdisplay:flex;\n    flex-direction:column;\n    justify-content:center;\n    align-items: flex-start;\n    flex-grow:1;\n}\n\n#uc_uc_material_bullets_elementor_6df617e .ue-bullets{\n  display:grid;\n}\n\n#uc_uc_material_bullets_elementor_6df617e .ue-text, \n#uc_uc_material_bullets_elementor_6df617e .ue-title, \n#uc_uc_material_bullets_elementor_6df617e .ue-seperator{\n  width:100%;\n}\n\n#uc_uc_material_bullets_elementor_6df617e .ue-seperator-line{\n  display:inline-block;\n  font-size:0px;\n}\n\n#uc_uc_material_bullets_elementor_6df617e .ue-seperator{\n  font-size:0px;\n}\n\n#uc_uc_material_bullets_elementor_6df617e.uc-remote-parent .uc_material_bullets_row{\n  cursor:pointer;\n}\n\n.ue-title{\n  font-size:21px;\n  margin:0;\n}\n\n#uc_uc_material_bullets_elementor_6df617e .uc_content_box > *{\n  transition: all .3s;\n}\n\n<\/style>\n\n<div class=\"uc_material_bullets  \"  id=\"uc_uc_material_bullets_elementor_6df617e\"  >   \t\n    \t<div class=\"ue-bullets uc-items-wrapper\">\n          \t<div class=\"uc_material_bullets_row elementor-repeater-item-4061aae\">\n  <div class=\"ue-icon-wrapper\">\n              <div class=\"ue-icon\">\n                    <i class='fas fa-school'><\/i>                    \t\n\n                \n              <\/div>\n  <\/div>\n  <div class=\"uc_content_box uc_ceal\">\n    <div class=\"ue-title\">School Notes<\/div>\n    \n    \t\n    \n    <div class=\"ue-text\">Jot down key concepts and ideas during classes to make studying and revision easier.<\/div>\t\n  <\/div>\n    \t\n<\/div>\n<div class=\"uc_material_bullets_row elementor-repeater-item-c647ca0\">\n  <div class=\"ue-icon-wrapper\">\n              <div class=\"ue-icon\">\n                    <i class='fas fa-leaf'><\/i>                    \t\n\n                \n              <\/div>\n  <\/div>\n  <div class=\"uc_content_box uc_ceal\">\n    <div class=\"ue-title\">Creative Writing<\/div>\n    \n    \t\n    \n    <div class=\"ue-text\">Develop stories, poems, or scripts that showcase imagination, creativity, and expression.<\/div>\t\n  <\/div>\n    \t\n<\/div>\n<div class=\"uc_material_bullets_row elementor-repeater-item-27f0d74\">\n  <div class=\"ue-icon-wrapper\">\n              <div class=\"ue-icon\">\n                    <i class='fas fa-user-alt'><\/i>                    \t\n\n                \n              <\/div>\n  <\/div>\n  <div class=\"uc_content_box uc_ceal\">\n    <div class=\"ue-title\">Meeting Minutes<\/div>\n    \n    \t\n    \n    <div class=\"ue-text\">Document key points, decisions, and actions discussed in meetings for future reference.\n<\/div>\t\n  <\/div>\n    \t\n<\/div>\n<div class=\"uc_material_bullets_row elementor-repeater-item-8f44fed\">\n  <div class=\"ue-icon-wrapper\">\n              <div class=\"ue-icon\">\n                    <i class='fas fa-book-open'><\/i>                    \t\n\n                \n              <\/div>\n  <\/div>\n  <div class=\"uc_content_box uc_ceal\">\n    <div class=\"ue-title\">Book Summaries<\/div>\n    \n    \t\n    \n    <div class=\"ue-text\">Condense the core ideas, themes, and important details of books for quick understanding.<\/div>\t\n  <\/div>\n    \t\n<\/div>\n<div class=\"uc_material_bullets_row elementor-repeater-item-4d18fc5\">\n  <div class=\"ue-icon-wrapper\">\n              <div class=\"ue-icon\">\n                    <i class='fas fa-journal-whills'><\/i>                    \t\n\n                \n              <\/div>\n  <\/div>\n  <div class=\"uc_content_box uc_ceal\">\n    <div class=\"ue-title\">Daily Journals<\/div>\n    \n    \t\n    \n    <div class=\"ue-text\">Write about daily experiences, thoughts, and reflections to track personal growth and emotions.<\/div>\t\n  <\/div>\n    \t\n<\/div>\n<div class=\"uc_material_bullets_row elementor-repeater-item-b381589\">\n  <div class=\"ue-icon-wrapper\">\n              <div class=\"ue-icon\">\n                    <i class='far fa-window-restore'><\/i>                    \t\n\n                \n              <\/div>\n  <\/div>\n  <div class=\"uc_content_box uc_ceal\">\n    <div class=\"ue-title\">Research Reports<\/div>\n    \n    \t\n    \n    <div class=\"ue-text\">Present research findings, methodology, analysis, and conclusions in a clear, organized format.<\/div>\t\n  <\/div>\n    \t\n<\/div>\n\n      <\/div>\n<\/div>\n<!-- end Icon Bullets -->\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-76628e6 elementor-widget elementor-widget-heading\" data-id=\"76628e6\" data-element_type=\"widget\" data-widget_type=\"heading.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<h2 class=\"elementor-heading-title elementor-size-default\">How do I convert handwriting to text?\n<\/h2>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-7e721ee elementor-widget elementor-widget-ucaddon_step_process\" data-id=\"7e721ee\" data-element_type=\"widget\" data-widget_type=\"ucaddon_step_process.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\n<!-- start Step Process -->\n\n<style>\/* widget: Step Process *\/\n\n#uc_step_process_elementor_7e721ee\n{\n  display:flex;\n}\n\n#uc_step_process_elementor_7e721ee .ue-link\n{\n  display:block;\n  position:absolute;\n  top:0px;\n  bottom:0px;\n  left:0px;\n  right:0px;\n}\n\n#uc_step_process_elementor_7e721ee .ue-step-item\n{\n  flex:1;\n  display:flex;\n  flex-direction:column;\n  position:relative;\n}\n#uc_step_process_elementor_7e721ee .ue-item-highlight\n{\n  display: flex;\n  align-items:center;\n  \n}\n\n#uc_step_process_elementor_7e721ee .ue-step-item-gap\n{\n  flex-grow:0;\n  flex-shrink:0;\n}\n\n#uc_step_process_elementor_7e721ee .ue-step-item-line\n{\n  height:1px;\n  flex-grow:1;\n}\n\n#uc_step_process_elementor_7e721ee .ue-step-icon\n{\n  display:flex;\n  justify-content:center;\n  align-items:center;\n  flex-grow:0;\n  flex-shrink:0;\n  position:relative;\n  line-height:1em;\n  transition:0.3s;\n}\n\n#uc_step_process_elementor_7e721ee .ue-icon svg\n{\n  height:1em;\n  width:1em;\n}\n\n#uc_step_process_elementor_7e721ee .ue-step-label\n{\n  position:absolute;\n  left:0px;\n  top:0px;\n  display:flex;\n  justify-content:center;\n  align-items:center;\n}\n.ue-step-label\n{\n  font-size:9px;\n  line-height:1em;\n}\n\n#uc_step_process_elementor_7e721ee .ue-step-item-content\n{\n}\n\n#uc_step_process_elementor_7e721ee .ue-step-item:last-child .ue-step-item-line:last-child\n{\n  opacity:0;\n}\n\n#uc_step_process_elementor_7e721ee .ue-step-item:first-child .ue-step-item-line:first-child\n{\n  opacity:0;\n}\n\n#uc_step_process_elementor_7e721ee .ue-step-item-spacer\n{\n  flex-grow:0;\n  flex-shrink:0;\n  \n}\n\n#uc_step_process_elementor_7e721ee .ue-graphic-image img\n{\n  \n}\n\n\n#uc_step_process_elementor_7e721ee.uc-remote-parent .ue-step-item\n{\n  cursor:pointer;\n}\n\n\n\n\n\n\n@media only screen and (max-width: 768px) {\n  #uc_step_process_elementor_7e721ee\n    {\n      flex-direction:column;\n    }\n  \n  #uc_step_process_elementor_7e721ee .ue-step-item\n  {\n    flex-direction:row;\n  }\n  \n  #uc_step_process_elementor_7e721ee .ue-item-highlight\n  {\n    flex-direction:column;\n  }\n  \n   #uc_step_process_elementor_7e721ee .ue-step-item .ue-step-item-line:first-child\n    {\n      display:none;\n    }\n  \n\n    #uc_step_process_elementor_7e721ee  .ue-step-item-gap:nth-child(2)\n     {\n      display:none;    \n      }\n   #uc_step_process_elementor_7e721ee  .ue-step-item-line:first-child\n      {\n      display:none;    \n      }\n  \n    #uc_step_process_elementor_7e721ee  .ue-step-item-line\n      {\n        height:100%;\n        width:1px;\n      }\n}\n\n\n\n<\/style>\n\n<div id=\"uc_step_process_elementor_7e721ee\" class=\"uc-items-wrapper  \"  >\n <div class=\"ue-step-item ue-item elementor-repeater-item-b77fdec\">\n    <div class=\"ue-item-highlight\">\n      \n      <div class=\"ue-step-item-line\"><\/div>\n      <div class=\"ue-step-item-gap\"><\/div>\n      <div class=\"ue-step-icon \">\n        <span class=\"ue-icon\"><i class='fas fa-photo-video'><\/i><\/span>                        \n              <\/div>\n      <div class=\"ue-step-item-gap\"><\/div>\n      <div class=\"ue-step-item-line\"><\/div>\n      \n    <\/div>\n    \n    <div class=\"ue-step-item-spacer\"><\/div>\n    \n    <div class=\"ue-step-item-content\">  \n       <div class=\"ue-step-item-content-title\">Scan or Take a Photo<\/div>       <div class=\"ue-step-item-content-text\">Capture a clear image of the handwritten text using a scanner or your phone\u2019s camera.<\/div>    <\/div>\n  \n    <\/div>\n<div class=\"ue-step-item ue-item elementor-repeater-item-fea387d\">\n    <div class=\"ue-item-highlight\">\n      \n      <div class=\"ue-step-item-line\"><\/div>\n      <div class=\"ue-step-item-gap\"><\/div>\n      <div class=\"ue-step-icon \">\n        <span class=\"ue-icon\"><i class='fas fa-cloud-upload-alt'><\/i><\/span>                        \n              <\/div>\n      <div class=\"ue-step-item-gap\"><\/div>\n      <div class=\"ue-step-item-line\"><\/div>\n      \n    <\/div>\n    \n    <div class=\"ue-step-item-spacer\"><\/div>\n    \n    <div class=\"ue-step-item-content\">  \n       <div class=\"ue-step-item-content-title\">Upload to OCR Tool<\/div>       <div class=\"ue-step-item-content-text\">Upload the image to an online OCR tool that recognizes handwriting and converts it to text.<\/div>    <\/div>\n  \n    <\/div>\n<div class=\"ue-step-item ue-item elementor-repeater-item-4860be0\">\n    <div class=\"ue-item-highlight\">\n      \n      <div class=\"ue-step-item-line\"><\/div>\n      <div class=\"ue-step-item-gap\"><\/div>\n      <div class=\"ue-step-icon \">\n        <span class=\"ue-icon\"><i class='fas fa-sync'><\/i><\/span>                        \n              <\/div>\n      <div class=\"ue-step-item-gap\"><\/div>\n      <div class=\"ue-step-item-line\"><\/div>\n      \n    <\/div>\n    \n    <div class=\"ue-step-item-spacer\"><\/div>\n    \n    <div class=\"ue-step-item-content\">  \n       <div class=\"ue-step-item-content-title\">Convert and Edit<\/div>       <div class=\"ue-step-item-content-text\">The OCR tool processes the image and converts it into editable text, which you can review and adjust as needed.<\/div>    <\/div>\n  \n    <\/div>\n\n<\/div>\n<!-- end Step Process -->\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-486392e elementor-widget elementor-widget-heading\" data-id=\"486392e\" data-element_type=\"widget\" data-widget_type=\"heading.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<h2 class=\"elementor-heading-title elementor-size-default\">Key Features and Benefits of Using OCR365<\/h2>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-27150f2 e-flex e-con-boxed e-con e-child\" data-id=\"27150f2\" data-element_type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-6d79636 elementor-widget elementor-widget-text-editor\" data-id=\"6d79636\" data-element_type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p data-sourcepos=\"27:1-27:132\">Using OCR365 offers a multitude of benefits that can significantly enhance your productivity and streamline your workflow:<\/p><p><strong>High Accuracy:<\/strong> Our advanced algorithms are designed to accurately recognize various handwriting styles, minimizing errors and ensuring reliable results.<\/p><p><strong>Speed and Efficiency:<\/strong> Convert your handwritten notes to text in a matter of seconds, saving you valuable time and effort.<\/p><p><strong>User-Friendly Interface:<\/strong> Our intuitive and clean interface makes the conversion process simple and straightforward, even for users with limited technical experience.<\/p><p><strong>Editable Output:<\/strong> Once converted, the text is fully editable, allowing you to make corrections, format the text, and integrate it into other documents.<\/p><p><strong>Searchable Text:<\/strong> The converted text becomes fully searchable, making it easy to find specific information within your digitized notes.<\/p><p><strong>Accessibility:<\/strong> Convert handwritten notes into digital text for improved accessibility for individuals with visual impairments.<\/p><p><strong>Secure and Private:<\/strong> We prioritize your privacy and ensure that your uploaded images and converted text are handled securely.<\/p><h3 style=\"text-align: center;\" data-sourcepos=\"61:1-61:53\"><strong>Real-World Applications of Online Handwritten OCR<\/strong><\/h3><p data-sourcepos=\"63:1-63:85\">The applications of online handwritten OCR are vast and span across numerous domains:<\/p><p><strong>Digitizing Historical Documents:<\/strong> Preserving and making historical handwritten documents searchable and accessible to researchers and the public.<\/p><p><strong>Streamlining Medical Records:<\/strong> Converting handwritten patient notes into digital records for efficient management and analysis (while ensuring compliance with privacy regulations).<\/p><p><strong>Improving Legal Processes:<\/strong> Digitizing handwritten legal documents, contracts, and testimonies for easier access and organization.<\/p><p><strong>Enhancing Educational Practices:<\/strong> Allowing students to easily digitize notes and enabling educators to efficiently process handwritten assignments.<\/p><p><strong>Boosting Personal Productivity:<\/strong> Helping individuals organize personal notes, recipes, journals, and other handwritten information in a digital format.<\/p><h3 style=\"text-align: center;\" data-sourcepos=\"75:1-75:55\"><strong>Optimizing Your Scanned Images for Best OCR Results<\/strong><\/h3><p data-sourcepos=\"77:1-77:123\">To ensure the highest accuracy when using OCR365, consider the following tips for optimizing your scanned images:<\/p><p><strong>Ensure Good Lighting:<\/strong> Scan or photograph your handwritten document in a well-lit environment to avoid shadows and ensure clarity.<\/p><p><strong>Maintain Proper Focus:<\/strong> Make sure the image is in sharp focus. Blurry images can significantly reduce the accuracy of the OCR process.<\/p><p><strong>Crop Unnecessary Areas:<\/strong> Crop the image to include only the handwritten text. Extra background can sometimes interfere with the OCR process.<\/p><p><strong>Scan at an Appropriate Resolution:<\/strong> A resolution of 300 DPI (dots per inch) is generally recommended for good OCR results.<\/p><p><strong>Keep the Document Straight:<\/strong> Ensure the handwritten document is as straight as possible during scanning or photographing. Skewed images can be harder for the OCR engine to process.<\/p><p><strong>Use High-Quality Scanning Equipment:<\/strong> If possible, use a good quality scanner for optimal results.<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-59575ae e-flex e-con-boxed e-con e-child\" data-id=\"59575ae\" data-element_type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-5a48c7a elementor-widget elementor-widget-heading\" data-id=\"5a48c7a\" data-element_type=\"widget\" data-widget_type=\"heading.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<h3 class=\"elementor-heading-title elementor-size-default\">Frequently Asked Questions (FAQ)<\/h3>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-9694206 elementor-widget elementor-widget-text-editor\" data-id=\"9694206\" data-element_type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<h4>Can handwriting be converted to text?<\/h4><div>Yes, using OCR tools specifically designed for handwriting recognition, though accuracy may vary based on legibility.<\/div><div>\u00a0<\/div><h4>Is handwriting recognition accurate?<\/h4><div>It depends on the legibility of the handwriting. Neat, clear handwriting produces more accurate results, while messy or cursive handwriting may cause errors.<\/div><div>\u00a0<\/div><h4>Can all types of handwriting be recognized?<\/h4><div>Most printed and legible handwriting can be recognized, but highly cursive or messy handwriting might be challenging for OCR software.<\/div><div>\u00a0<\/div><h4>Do I need a special scanner for handwriting recognition?<\/h4><div>No, most handwriting recognition tools can process scanned images or photos of handwritten content.<\/div><div>\u00a0<\/div><h4>Can handwriting in any language be converted to text?<\/h4><div>Many OCR tools support multiple languages, but recognition accuracy may vary depending on the language and handwriting style.<\/div>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-ff9a4e9 elementor-widget elementor-widget-shortcode\" data-id=\"ff9a4e9\" data-element_type=\"widget\" data-widget_type=\"shortcode.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<div class=\"elementor-shortcode\">\n\n<div class=\"kk-star-ratings kksr-shortcode\"\n    data-payload='{&quot;id&quot;:&quot;644&quot;,&quot;slug&quot;:&quot;default&quot;,&quot;ignore&quot;:&quot;&quot;,&quot;reference&quot;:&quot;shortcode&quot;,&quot;align&quot;:&quot;&quot;,&quot;class&quot;:&quot;&quot;,&quot;count&quot;:&quot;15&quot;,&quot;legendonly&quot;:&quot;&quot;,&quot;readonly&quot;:&quot;&quot;,&quot;score&quot;:&quot;4.3&quot;,&quot;starsonly&quot;:&quot;&quot;,&quot;valign&quot;:&quot;&quot;,&quot;best&quot;:&quot;5&quot;,&quot;gap&quot;:&quot;5&quot;,&quot;greet&quot;:&quot;Rate this page&quot;,&quot;legend&quot;:&quot;4.3\\\/5 - (15 votes)&quot;,&quot;size&quot;:&quot;15&quot;,&quot;title&quot;:&quot;Handwriting to text&quot;,&quot;width&quot;:&quot;83.5&quot;,&quot;_legend&quot;:&quot;{score}\\\/{best} - ({count} {votes})&quot;,&quot;font_factor&quot;:&quot;1.25&quot;}'>\n            \n<div class=\"kksr-stars\">\n    \n<div class=\"kksr-stars-inactive\">\n            <div class=\"kksr-star\" data-star=\"1\" style=\"padding-right: 5px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 15px; height: 15px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" data-star=\"2\" style=\"padding-right: 5px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 15px; height: 15px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" data-star=\"3\" style=\"padding-right: 5px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 15px; height: 15px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" data-star=\"4\" style=\"padding-right: 5px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 15px; height: 15px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" data-star=\"5\" style=\"padding-right: 5px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 15px; height: 15px;\"><\/div>\n        <\/div>\n    <\/div>\n    \n<div class=\"kksr-stars-active\" style=\"width: 83.5px;\">\n            <div class=\"kksr-star\" style=\"padding-right: 5px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 15px; height: 15px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" style=\"padding-right: 5px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 15px; height: 15px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" style=\"padding-right: 5px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 15px; height: 15px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" style=\"padding-right: 5px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 15px; height: 15px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" style=\"padding-right: 5px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 15px; height: 15px;\"><\/div>\n        <\/div>\n    <\/div>\n<\/div>\n                \n\n<div class=\"kksr-legend\" style=\"font-size: 12px;\">\n            4.3\/5 - (15 votes)    <\/div>\n    <\/div>\n<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t","protected":false},"excerpt":{"rendered":"<p>Convert Handwriting 100+ Languages 99.8% Accuracy Secure &#038; Private Your first choice for handwriting-to-text We have developed OCR365 with a focus on user-friendliness, accuracy, and speed. Our intuitive interface allows you to easily upload your scanned images and receive the converted text within seconds. We utilize advanced OCR algorithms that are specifically trained to recognize [&#8230;]\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"elementor_header_footer","meta":{"footnotes":""},"class_list":["post-644","page","type-page","status-publish","hentry"],"rankMath":{"parentDomain":"ocr365.com","noFollowDomains":[],"noFollowExcludeDomains":[],"noFollowExternalLinks":false,"featuredImageNotice":"\ucd94\ucc9c \uc774\ubbf8\uc9c0\ub294 Facebook \ubc0f \uae30\ud0c0 \uc18c\uc15c \ubbf8\ub514\uc5b4 \uc0ac\uc774\ud2b8\uc5d0\uc11c \uc120\ud0dd\ud560 \uc218 \uc788\ub3c4\ub85d \ucd5c\uc18c 200 x 200\ud53d\uc140\uc774\uc5b4\uc57c \ud569\ub2c8\ub2e4.","pluginReviewed":false,"postSettings":{"linkSuggestions":true,"useFocusKeyword":false},"frontEndScore":false,"postName":"handwriting-to-text","permalinkFormat":"https:\/\/ocr365.com\/ko\/%pagename%\/","showLockModifiedDate":true,"assessor":{"focusKeywordLink":"https:\/\/ocr365.com\/wp-admin\/edit.php?focus_keyword=%focus_keyword%&post_type=%post_type%","hasTOCPlugin":true,"primaryTaxonomy":false,"serpData":{"title":"\ud544\uae30\ub97c \uc628\ub77c\uc778\uc5d0\uc11c \ud14d\uc2a4\ud2b8\ub85c \ubcc0\ud658","description":"\ud544\uae30\uc5d0\uc11c \ud14d\uc2a4\ud2b8\ub85c: \uc628\ub77c\uc778 OCR \ub3c4\uad6c\ub97c \uc0ac\uc6a9\ud558\uc5ec \uc2a4\uce94\ud55c \ud544\uae30 \uc774\ubbf8\uc9c0\ub97c \ud14d\uc2a4\ud2b8\ub85c \uc27d\uac8c \ubcc0\ud658\ud558\uace0, \uc815\ud655\ud55c \ud544\uae30 \ud14d\uc2a4\ud2b8 \uc778\uc2dd \ubc0f \ud544\uae30\uccb4 OCR\uc744 \uc9c0\uc6d0\ud569\ub2c8\ub2e4. \uc18c\ud504\ud2b8\uc6e8\uc5b4\ub97c \ub2e4\uc6b4\ub85c\ub4dc\ud560 \ud544\uc694 \uc5c6\uc774 \uace0\uc815\ubc00 \ubcc0\ud658 \ubc0f \ube60\ub974\uace0 \ubb34\ub8cc \ud14d\uc2a4\ud2b8 \uc778\uc2dd\uc744 \uc990\uaca8\ubcf4\uc138\uc694.","focusKeywords":"Handwriting to text","pillarContent":false,"canonicalUrl":"","breadcrumbTitle":"","advancedRobots":{"max-snippet":"-1","max-video-preview":"-1","max-image-preview":"large"},"facebookTitle":"","facebookDescription":"","facebookImage":"","facebookImageID":"","facebookHasOverlay":false,"facebookImageOverlay":"","facebookAuthor":"","twitterCardType":"","twitterUseFacebook":true,"twitterTitle":"","twitterDescription":"","twitterImage":"","twitterImageID":"","twitterHasOverlay":false,"twitterImageOverlay":"","twitterPlayerUrl":"","twitterPlayerSize":"","twitterPlayerStream":"","twitterPlayerStreamCtype":"","twitterAppDescription":"","twitterAppIphoneName":"","twitterAppIphoneID":"","twitterAppIphoneUrl":"","twitterAppIpadName":"","twitterAppIpadID":"","twitterAppIpadUrl":"","twitterAppGoogleplayName":"","twitterAppGoogleplayID":"","twitterAppGoogleplayUrl":"","twitterAppCountry":"","robots":{"index":true},"twitterAuthor":"\uc0ac\uc6a9\uc790\uba85","primaryTerm":0,"authorName":"admin","titleTemplate":"%title% %sep% %sitename%","descriptionTemplate":"%excerpt%","showScoreFrontend":true,"lockModifiedDate":false},"powerWords":[],"diacritics":{"A":"[\\u0041\\u24B6\\uFF21\\u00C0\\u00C1\\u00C2\\u1EA6\\u1EA4\\u1EAA\\u1EA8\\u00C3\\u0100\\u0102\\u1EB0\\u1EAE\\u1EB4\\u1EB2\\u0226\\u01E0\\u00C4\\u01DE\\u1EA2\\u00C5\\u01FA\\u01CD\\u0200\\u0202\\u1EA0\\u1EAC\\u1EB6\\u1E00\\u0104\\u023A\\u2C6F]","AA":"[\\uA732]","AE":"[\\u00C6\\u01FC\\u01E2]","AO":"[\\uA734]","AU":"[\\uA736]","AV":"[\\uA738\\uA73A]","AY":"[\\uA73C]","B":"[\\u0042\\u24B7\\uFF22\\u1E02\\u1E04\\u1E06\\u0243\\u0182\\u0181]","C":"[\\u0043\\u24B8\\uFF23\\u0106\\u0108\\u010A\\u010C\\u00C7\\u1E08\\u0187\\u023B\\uA73E]","D":"[\\u0044\\u24B9\\uFF24\\u1E0A\\u010E\\u1E0C\\u1E10\\u1E12\\u1E0E\\u0110\\u018B\\u018A\\u0189\\uA779]","DZ":"[\\u01F1\\u01C4]","Dz":"[\\u01F2\\u01C5]","E":"[\\u0045\\u24BA\\uFF25\\u00C8\\u00C9\\u00CA\\u1EC0\\u1EBE\\u1EC4\\u1EC2\\u1EBC\\u0112\\u1E14\\u1E16\\u0114\\u0116\\u00CB\\u1EBA\\u011A\\u0204\\u0206\\u1EB8\\u1EC6\\u0228\\u1E1C\\u0118\\u1E18\\u1E1A\\u0190\\u018E]","F":"[\\u0046\\u24BB\\uFF26\\u1E1E\\u0191\\uA77B]","G":"[\\u0047\\u24BC\\uFF27\\u01F4\\u011C\\u1E20\\u011E\\u0120\\u01E6\\u0122\\u01E4\\u0193\\uA7A0\\uA77D\\uA77E]","H":"[\\u0048\\u24BD\\uFF28\\u0124\\u1E22\\u1E26\\u021E\\u1E24\\u1E28\\u1E2A\\u0126\\u2C67\\u2C75\\uA78D]","I":"[\\u0049\\u24BE\\uFF29\\u00CC\\u00CD\\u00CE\\u0128\\u012A\\u012C\\u0130\\u00CF\\u1E2E\\u1EC8\\u01CF\\u0208\\u020A\\u1ECA\\u012E\\u1E2C\\u0197]","J":"[\\u004A\\u24BF\\uFF2A\\u0134\\u0248]","K":"[\\u004B\\u24C0\\uFF2B\\u1E30\\u01E8\\u1E32\\u0136\\u1E34\\u0198\\u2C69\\uA740\\uA742\\uA744\\uA7A2]","L":"[\\u004C\\u24C1\\uFF2C\\u013F\\u0139\\u013D\\u1E36\\u1E38\\u013B\\u1E3C\\u1E3A\\u0141\\u023D\\u2C62\\u2C60\\uA748\\uA746\\uA780]","LJ":"[\\u01C7]","Lj":"[\\u01C8]","M":"[\\u004D\\u24C2\\uFF2D\\u1E3E\\u1E40\\u1E42\\u2C6E\\u019C]","N":"[\\u004E\\u24C3\\uFF2E\\u01F8\\u0143\\u00D1\\u1E44\\u0147\\u1E46\\u0145\\u1E4A\\u1E48\\u0220\\u019D\\uA790\\uA7A4]","NJ":"[\\u01CA]","Nj":"[\\u01CB]","O":"[\\u004F\\u24C4\\uFF2F\\u00D2\\u00D3\\u00D4\\u1ED2\\u1ED0\\u1ED6\\u1ED4\\u00D5\\u1E4C\\u022C\\u1E4E\\u014C\\u1E50\\u1E52\\u014E\\u022E\\u0230\\u00D6\\u022A\\u1ECE\\u0150\\u01D1\\u020C\\u020E\\u01A0\\u1EDC\\u1EDA\\u1EE0\\u1EDE\\u1EE2\\u1ECC\\u1ED8\\u01EA\\u01EC\\u00D8\\u01FE\\u0186\\u019F\\uA74A\\uA74C]","OI":"[\\u01A2]","OO":"[\\uA74E]","OU":"[\\u0222]","P":"[\\u0050\\u24C5\\uFF30\\u1E54\\u1E56\\u01A4\\u2C63\\uA750\\uA752\\uA754]","Q":"[\\u0051\\u24C6\\uFF31\\uA756\\uA758\\u024A]","R":"[\\u0052\\u24C7\\uFF32\\u0154\\u1E58\\u0158\\u0210\\u0212\\u1E5A\\u1E5C\\u0156\\u1E5E\\u024C\\u2C64\\uA75A\\uA7A6\\uA782]","S":"[\\u0053\\u24C8\\uFF33\\u1E9E\\u015A\\u1E64\\u015C\\u1E60\\u0160\\u1E66\\u1E62\\u1E68\\u0218\\u015E\\u2C7E\\uA7A8\\uA784]","T":"[\\u0054\\u24C9\\uFF34\\u1E6A\\u0164\\u1E6C\\u021A\\u0162\\u1E70\\u1E6E\\u0166\\u01AC\\u01AE\\u023E\\uA786]","TZ":"[\\uA728]","U":"[\\u0055\\u24CA\\uFF35\\u00D9\\u00DA\\u00DB\\u0168\\u1E78\\u016A\\u1E7A\\u016C\\u00DC\\u01DB\\u01D7\\u01D5\\u01D9\\u1EE6\\u016E\\u0170\\u01D3\\u0214\\u0216\\u01AF\\u1EEA\\u1EE8\\u1EEE\\u1EEC\\u1EF0\\u1EE4\\u1E72\\u0172\\u1E76\\u1E74\\u0244]","V":"[\\u0056\\u24CB\\uFF36\\u1E7C\\u1E7E\\u01B2\\uA75E\\u0245]","VY":"[\\uA760]","W":"[\\u0057\\u24CC\\uFF37\\u1E80\\u1E82\\u0174\\u1E86\\u1E84\\u1E88\\u2C72]","X":"[\\u0058\\u24CD\\uFF38\\u1E8A\\u1E8C]","Y":"[\\u0059\\u24CE\\uFF39\\u1EF2\\u00DD\\u0176\\u1EF8\\u0232\\u1E8E\\u0178\\u1EF6\\u1EF4\\u01B3\\u024E\\u1EFE]","Z":"[\\u005A\\u24CF\\uFF3A\\u0179\\u1E90\\u017B\\u017D\\u1E92\\u1E94\\u01B5\\u0224\\u2C7F\\u2C6B\\uA762]","a":"[\\u0061\\u24D0\\uFF41\\u1E9A\\u00E0\\u00E1\\u00E2\\u1EA7\\u1EA5\\u1EAB\\u1EA9\\u00E3\\u0101\\u0103\\u1EB1\\u1EAF\\u1EB5\\u1EB3\\u0227\\u01E1\\u00E4\\u01DF\\u1EA3\\u00E5\\u01FB\\u01CE\\u0201\\u0203\\u1EA1\\u1EAD\\u1EB7\\u1E01\\u0105\\u2C65\\u0250]","aa":"[\\uA733]","ae":"[\\u00E6\\u01FD\\u01E3]","ao":"[\\uA735]","au":"[\\uA737]","av":"[\\uA739\\uA73B]","ay":"[\\uA73D]","b":"[\\u0062\\u24D1\\uFF42\\u1E03\\u1E05\\u1E07\\u0180\\u0183\\u0253]","c":"[\\u0063\\u24D2\\uFF43\\u0107\\u0109\\u010B\\u010D\\u00E7\\u1E09\\u0188\\u023C\\uA73F\\u2184]","d":"[\\u0064\\u24D3\\uFF44\\u1E0B\\u010F\\u1E0D\\u1E11\\u1E13\\u1E0F\\u0111\\u018C\\u0256\\u0257\\uA77A]","dz":"[\\u01F3\\u01C6]","e":"[\\u0065\\u24D4\\uFF45\\u00E8\\u00E9\\u00EA\\u1EC1\\u1EBF\\u1EC5\\u1EC3\\u1EBD\\u0113\\u1E15\\u1E17\\u0115\\u0117\\u00EB\\u1EBB\\u011B\\u0205\\u0207\\u1EB9\\u1EC7\\u0229\\u1E1D\\u0119\\u1E19\\u1E1B\\u0247\\u025B\\u01DD]","f":"[\\u0066\\u24D5\\uFF46\\u1E1F\\u0192\\uA77C]","g":"[\\u0067\\u24D6\\uFF47\\u01F5\\u011D\\u1E21\\u011F\\u0121\\u01E7\\u0123\\u01E5\\u0260\\uA7A1\\u1D79\\uA77F]","h":"[\\u0068\\u24D7\\uFF48\\u0125\\u1E23\\u1E27\\u021F\\u1E25\\u1E29\\u1E2B\\u1E96\\u0127\\u2C68\\u2C76\\u0265]","hv":"[\\u0195]","i":"[\\u0069\\u24D8\\uFF49\\u00EC\\u00ED\\u00EE\\u0129\\u012B\\u012D\\u00EF\\u1E2F\\u1EC9\\u01D0\\u0209\\u020B\\u1ECB\\u012F\\u1E2D\\u0268\\u0131]","j":"[\\u006A\\u24D9\\uFF4A\\u0135\\u01F0\\u0249]","k":"[\\u006B\\u24DA\\uFF4B\\u1E31\\u01E9\\u1E33\\u0137\\u1E35\\u0199\\u2C6A\\uA741\\uA743\\uA745\\uA7A3]","l":"[\\u006C\\u24DB\\uFF4C\\u0140\\u013A\\u013E\\u1E37\\u1E39\\u013C\\u1E3D\\u1E3B\\u017F\\u0142\\u019A\\u026B\\u2C61\\uA749\\uA781\\uA747]","lj":"[\\u01C9]","m":"[\\u006D\\u24DC\\uFF4D\\u1E3F\\u1E41\\u1E43\\u0271\\u026F]","n":"[\\u006E\\u24DD\\uFF4E\\u01F9\\u0144\\u00F1\\u1E45\\u0148\\u1E47\\u0146\\u1E4B\\u1E49\\u019E\\u0272\\u0149\\uA791\\uA7A5]","nj":"[\\u01CC]","o":"[\\u006F\\u24DE\\uFF4F\\u00F2\\u00F3\\u00F4\\u1ED3\\u1ED1\\u1ED7\\u1ED5\\u00F5\\u1E4D\\u022D\\u1E4F\\u014D\\u1E51\\u1E53\\u014F\\u022F\\u0231\\u00F6\\u022B\\u1ECF\\u0151\\u01D2\\u020D\\u020F\\u01A1\\u1EDD\\u1EDB\\u1EE1\\u1EDF\\u1EE3\\u1ECD\\u1ED9\\u01EB\\u01ED\\u00F8\\u01FF\\u0254\\uA74B\\uA74D\\u0275]","oi":"[\\u01A3]","ou":"[\\u0223]","oo":"[\\uA74F]","p":"[\\u0070\\u24DF\\uFF50\\u1E55\\u1E57\\u01A5\\u1D7D\\uA751\\uA753\\uA755]","q":"[\\u0071\\u24E0\\uFF51\\u024B\\uA757\\uA759]","r":"[\\u0072\\u24E1\\uFF52\\u0155\\u1E59\\u0159\\u0211\\u0213\\u1E5B\\u1E5D\\u0157\\u1E5F\\u024D\\u027D\\uA75B\\uA7A7\\uA783]","s":"[\\u0073\\u24E2\\uFF53\\u015B\\u1E65\\u015D\\u1E61\\u0161\\u1E67\\u1E63\\u1E69\\u0219\\u015F\\u023F\\uA7A9\\uA785\\u1E9B]","ss":"[\\u00DF]","t":"[\\u0074\\u24E3\\uFF54\\u1E6B\\u1E97\\u0165\\u1E6D\\u021B\\u0163\\u1E71\\u1E6F\\u0167\\u01AD\\u0288\\u2C66\\uA787]","tz":"[\\uA729]","u":"[\\u0075\\u24E4\\uFF55\\u00F9\\u00FA\\u00FB\\u0169\\u1E79\\u016B\\u1E7B\\u016D\\u00FC\\u01DC\\u01D8\\u01D6\\u01DA\\u1EE7\\u016F\\u0171\\u01D4\\u0215\\u0217\\u01B0\\u1EEB\\u1EE9\\u1EEF\\u1EED\\u1EF1\\u1EE5\\u1E73\\u0173\\u1E77\\u1E75\\u0289]","v":"[\\u0076\\u24E5\\uFF56\\u1E7D\\u1E7F\\u028B\\uA75F\\u028C]","vy":"[\\uA761]","w":"[\\u0077\\u24E6\\uFF57\\u1E81\\u1E83\\u0175\\u1E87\\u1E85\\u1E98\\u1E89\\u2C73]","x":"[\\u0078\\u24E7\\uFF58\\u1E8B\\u1E8D]","y":"[\\u0079\\u24E8\\uFF59\\u1EF3\\u00FD\\u0177\\u1EF9\\u0233\\u1E8F\\u00FF\\u1EF7\\u1E99\\u1EF5\\u01B4\\u024F\\u1EFF]","z":"[\\u007A\\u24E9\\uFF5A\\u017A\\u1E91\\u017C\\u017E\\u1E93\\u1E95\\u01B6\\u0225\\u0240\\u2C6C\\uA763]"},"researchesTests":["contentHasTOC","contentHasShortParagraphs","contentHasAssets","keywordInTitle","keywordInMetaDescription","keywordInPermalink","keywordIn10Percent","keywordInContent","keywordInSubheadings","keywordInImageAlt","keywordDensity","keywordNotUsed","lengthContent","lengthPermalink","linksHasInternal","linksHasExternals","linksNotAllExternals","titleStartWithKeyword","titleSentiment","titleHasPowerWords","titleHasNumber","hasContentAI"],"hasRedirection":false,"hasBreadcrumb":false},"homeUrl":"https:\/\/ocr365.com\/ko","objectID":644,"objectType":"post","locale":"ko","localeFull":"ko_KR","overlayImages":{"play":{"name":"\uc7ac\uc0dd \uc544\uc774\ucf58","url":"https:\/\/ocr365.com\/wp-content\/plugins\/seo-by-rank-math\/assets\/admin\/img\/icon-play.png","path":"\/var\/www\/vhosts\/ocr365.com\/httpdocs\/wp-content\/plugins\/seo-by-rank-math\/assets\/admin\/img\/icon-play.png","position":"middle_center"},"gif":{"name":"GIF \uc544\uc774\ucf58","url":"https:\/\/ocr365.com\/wp-content\/plugins\/seo-by-rank-math\/assets\/admin\/img\/icon-gif.png","path":"\/var\/www\/vhosts\/ocr365.com\/httpdocs\/wp-content\/plugins\/seo-by-rank-math\/assets\/admin\/img\/icon-gif.png","position":"middle_center"}},"defautOgImage":"https:\/\/ocr365.com\/wp-content\/uploads\/2025\/01\/LOGO8.png","customPermalinks":true,"isUserRegistered":false,"autoSuggestKeywords":false,"connectSiteUrl":"https:\/\/rankmath.com\/auth?site=https%3A%2F%2Focr365.com%2Fko&r=https%3A%2F%2Focr365.com%2Fko%2Fwp-json%2Fwp%2Fv2%2Fpages%2F644%3Fnonce%3Db6eb510581","maxTags":5,"trendsIcon":"<svg viewBox=\"0 0 610 610\"><path d=\"M18.85,446,174.32,290.48l58.08,58.08L76.93,504a14.54,14.54,0,0,1-20.55,0L18.83,466.48a14.54,14.54,0,0,1,0-20.55Z\" style=\"fill:#4285f4\"\/><path d=\"M242.65,242.66,377.59,377.6l-47.75,47.75a14.54,14.54,0,0,1-20.55,0L174.37,290.43l47.75-47.75A14.52,14.52,0,0,1,242.65,242.66Z\" style=\"fill:#ea4335\"\/><polygon points=\"319.53 319.53 479.26 159.8 537.34 217.88 377.61 377.62 319.53 319.53\" style=\"fill:#fabb05\"\/><path d=\"M594.26,262.73V118.61h0a16.94,16.94,0,0,0-16.94-16.94H433.2a16.94,16.94,0,0,0-12,28.92L565.34,274.71h0a16.94,16.94,0,0,0,28.92-12Z\" style=\"fill:#34a853\"\/><rect width=\"610\" height=\"610\" style=\"fill:none\"\/><\/svg>","showScore":true,"siteFavIcon":"https:\/\/ocr365.com\/wp-content\/uploads\/2025\/01\/cropped-512-32x32.png","canUser":{"general":false,"advanced":false,"snippet":false,"social":false,"analysis":false,"analytics":false,"content_ai":false},"showKeywordIntent":true,"isPro":false,"is_front_page":false,"trendsUpgradeLink":"https:\/\/rankmath.com\/pricing\/?utm_source=Plugin&utm_medium=CE%20General%20Tab%20Trends&utm_campaign=WP","trendsUpgradeLabel":"\uc5c5\uadf8\ub808\uc774\ub4dc","trendsPreviewImage":"https:\/\/ocr365.com\/wp-content\/plugins\/seo-by-rank-math\/assets\/admin\/img\/trends-preview.jpg","currentEditor":false,"homepageData":{"assessor":{"powerWords":[],"diacritics":true,"researchesTests":["contentHasTOC","contentHasShortParagraphs","contentHasAssets","keywordInTitle","keywordInMetaDescription","keywordInPermalink","keywordIn10Percent","keywordInContent","keywordInSubheadings","keywordInImageAlt","keywordDensity","keywordNotUsed","lengthContent","lengthPermalink","linksHasInternal","linksHasExternals","linksNotAllExternals","titleStartWithKeyword","titleSentiment","titleHasPowerWords","titleHasNumber","hasContentAI"],"hasBreadcrumb":false,"serpData":{"title":"%sitename% %page% %sep% %sitedesc%","description":"","titleTemplate":"%sitename% %page% %sep% %sitedesc%","descriptionTemplate":"","focusKeywords":"","breadcrumbTitle":"Home","robots":{"index":true},"advancedRobots":{"max-snippet":"-1","max-video-preview":"-1","max-image-preview":"large"},"facebookTitle":"","facebookDescription":"","facebookImage":"","facebookImageID":""}}},"tocTitle":"Table of Contents","tocExcludeHeadings":[],"listStyle":"ul"},"_links":{"self":[{"href":"https:\/\/ocr365.com\/ko\/wp-json\/wp\/v2\/pages\/644","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/ocr365.com\/ko\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/ocr365.com\/ko\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/ocr365.com\/ko\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/ocr365.com\/ko\/wp-json\/wp\/v2\/comments?post=644"}],"version-history":[{"count":151,"href":"https:\/\/ocr365.com\/ko\/wp-json\/wp\/v2\/pages\/644\/revisions"}],"predecessor-version":[{"id":1577,"href":"https:\/\/ocr365.com\/ko\/wp-json\/wp\/v2\/pages\/644\/revisions\/1577"}],"wp:attachment":[{"href":"https:\/\/ocr365.com\/ko\/wp-json\/wp\/v2\/media?parent=644"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}