AI Notes Smart Copy
Client-side intelligent note cleaner, formatter, and multi-format exporter.
New
Formatted Preview
Your formatted notes preview will appear here…
Paste Your Notes
Paste text below to insert into your editor:
Recent Notes
Recover Unsaved Draft?
An unsaved draft from your previous session was found.
No saved notes found.
'; return; } notes.forEach(note => { const item = document.createElement('div'); item.style.cssText = 'display: flex; justify-content: space-between; align-items: center; padding: 10px 12px; background: var(--bg-secondary); border: 1px solid var(--border-color); border-radius: 6px; cursor: pointer;'; item.innerHTML = `${escapeHtml(note.title)}
${new Date(note.updatedAt).toLocaleString()}
Error loading recent notes.
'; } }function performSearch() { if (!searchInput) return; const query = searchInput.value; const caseSensitive = caseCheck ? caseCheck.checked : false; state.searchMatches = []; state.searchMatchIndex = -1;if (!query || !editorEl) { if (matchCountLabel) matchCountLabel.textContent = '0 matches'; return; }const text = editorEl.value; const flags = caseSensitive ? 'g' : 'gi'; try { const regex = new RegExp(query.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'), flags); let match; while ((match = regex.exec(text)) !== null) { state.searchMatches.push({ start: match.index, end: match.index + match[0].length }); } } catch (e) {}if (matchCountLabel) matchCountLabel.textContent = `${state.searchMatches.length} matches`; if (state.searchMatches.length > 0) highlightMatch(0); }function highlightMatch(index) { if (state.searchMatches.length === 0 || !editorEl) return; state.searchMatchIndex = (index + state.searchMatches.length) % state.searchMatches.length; const match = state.searchMatches[state.searchMatchIndex]; editorEl.focus(); editorEl.setSelectionRange(match.start, match.end); }function replaceCurrentMatch() { if (state.searchMatchIndex < 0 || state.searchMatches.length === 0 || !editorEl || !replaceInput) return; const match = state.searchMatches[state.searchMatchIndex]; const replacement = replaceInput.value; const text = editorEl.value; editorEl.value = text.substring(0, match.start) + replacement + text.substring(match.end); state.content = editorEl.value; markDirty(); pushHistory(state.content); performSearch(); }function replaceAllMatches() { if (!searchInput || !replaceInput || !editorEl) return; const query = searchInput.value; const replacement = replaceInput.value; if (!query) return; const caseSensitive = caseCheck ? caseCheck.checked : false; const flags = caseSensitive ? 'g' : 'gi'; try { const regex = new RegExp(query.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'), flags); editorEl.value = editorEl.value.replace(regex, replacement); state.content = editorEl.value; markDirty(); pushHistory(state.content); performSearch(); showToast('All matches replaced', 'success'); } catch (e) {} }function initListeners() { if (editorEl) { editorEl.addEventListener('input', () => { state.content = editorEl.value; state.formattedStale = true; updateStats(state.content); renderPreview(); markDirty(); pushHistory(state.content); }); }if (titleInputEl) titleInputEl.addEventListener('input', markDirty); if (newBtn) newBtn.addEventListener('click', () => { state.content = ''; state.currentNoteId = null; if (editorEl) editorEl.value = ''; if (titleInputEl) titleInputEl.value = 'Untitled Notes'; state.formattedContent = ''; state.formattedStale = true; updateStats(''); renderPreview(); updateSaveState('New'); showToast('New document created', 'success'); });if (recentBtn) recentBtn.addEventListener('click', () => { loadRecentNotesList(); openModal(recentModal); }); if (recentCloseBtn) recentCloseBtn.addEventListener('click', () => closeModal(recentModal)); if (printBtn) printBtn.addEventListener('click', () => { formatNotes(formatStyleSelect ? formatStyleSelect.value : 'study'); window.print(); }); if (themeBtn) themeBtn.addEventListener('click', toggleTheme);if (pasteBtn) pasteBtn.addEventListener('click', () => { if (modalPasteInput) modalPasteInput.value = ''; openModal(pasteModal); }); if (modalCancelBtn) modalCancelBtn.addEventListener('click', () => closeModal(pasteModal)); if (modalInsertBtn) { modalInsertBtn.addEventListener('click', () => { if (modalPasteInput && editorEl) { const text = modalPasteInput.value; const start = editorEl.selectionStart; const end = editorEl.selectionEnd; const val = editorEl.value; editorEl.value = val.substring(0, start) + text + val.substring(end); state.content = editorEl.value; state.formattedStale = true; updateStats(state.content); renderPreview(); markDirty(); pushHistory(state.content); } closeModal(pasteModal); showToast('Text inserted', 'success'); }); }if (clearBtn) clearBtn.addEventListener('click', () => { if (confirm('Clear the editor?')) { state.content = ''; if (editorEl) editorEl.value = ''; state.formattedStale = true; updateStats(''); renderPreview(); markDirty(); pushHistory(''); showToast('Editor cleared', 'success'); } });if (formatBtn) formatBtn.addEventListener('click', () => formatNotes(formatStyleSelect ? formatStyleSelect.value : 'study')); if (detectBtn) detectBtn.addEventListener('click', detectStructure); if (copyBtn) copyBtn.addEventListener('click', () => { const textToCopy = state.formattedStale || !state.formattedContent ? state.content : state.formattedContent; navigator.clipboard.writeText(textToCopy).then(() => showToast('Copied to clipboard!', 'success')).catch(() => showToast('Failed to copy', 'error')); }); if (downloadBtn) downloadBtn.addEventListener('click', downloadFile); if (saveBtn) saveBtn.addEventListener('click', saveNote);if (undoBtn) undoBtn.addEventListener('click', undo); if (redoBtn) redoBtn.addEventListener('click', redo);if (searchToggleBtn && searchBar) { searchToggleBtn.addEventListener('click', () => { searchBar.classList.toggle('active'); if (searchBar.classList.contains('active') && searchInput) searchInput.focus(); }); } if (searchCloseBtn && searchBar) searchCloseBtn.addEventListener('click', () => searchBar.classList.remove('active')); if (searchInput) searchInput.addEventListener('input', performSearch); if (caseCheck) caseCheck.addEventListener('change', performSearch); if (searchPrevBtn) searchPrevBtn.addEventListener('click', () => highlightMatch(state.searchMatchIndex - 1)); if (searchNextBtn) searchNextBtn.addEventListener('click', () => highlightMatch(state.searchMatchIndex + 1)); if (replaceBtn) replaceBtn.addEventListener('click', replaceCurrentMatch); if (replaceAllBtn) replaceAllBtn.addEventListener('click', replaceAllMatches);document.addEventListener('keydown', (e) => { if (!rootEl.contains(document.activeElement)) return; if ((e.ctrlKey || e.metaKey) && e.key.toLowerCase() === 'z') { e.preventDefault(); undo(); } else if ((e.ctrlKey || e.metaKey) && (e.key.toLowerCase() === 'y' || (e.shiftKey && e.key.toLowerCase() === 'z'))) { e.preventDefault(); redo(); } else if ((e.ctrlKey || e.metaKey) && e.key.toLowerCase() === 'f') { e.preventDefault(); if (searchBar) { searchBar.classList.add('active'); if (searchInput) searchInput.focus(); } } else if ((e.ctrlKey || e.metaKey) && e.key.toLowerCase() === 's') { e.preventDefault(); saveNote(); } });try { const savedDraft = localStorage.getItem(DRAFT_KEY); if (savedDraft) { const draft = JSON.parse(savedDraft); if (draft && draft.content && draft.content.trim().length > 0) { openModal(draftModal); if (draftRecoverBtn) { draftRecoverBtn.onclick = () => { state.content = draft.content; if (editorEl) editorEl.value = draft.content; if (titleInputEl && draft.title) titleInputEl.value = draft.title; updateStats(draft.content); renderPreview(); closeModal(draftModal); showToast('Draft recovered', 'success'); }; } if (draftDiscardBtn) { draftDiscardBtn.onclick = () => { localStorage.removeItem(DRAFT_KEY); closeModal(draftModal); }; } } } } catch (e) {}try { const savedTheme = localStorage.getItem(THEME_KEY); if (savedTheme) setTheme(savedTheme); } catch (e) {} }initListeners(); updateStats(''); renderPreview();})();