@rainersoft/utils 1.2.0 → 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/types.ts","../src/text/index.ts","../src/string/index.ts","../src/date/index.ts","../src/number/index.ts","../src/status/index.ts","../src/validation/index.ts","../src/dom/index.ts","../src/stats/index.ts","../src/auth/index.ts","../src/search/index.ts","../src/hooks/use-password-strength.ts","../src/pt-br.ts"],"names":["formatNumber","window","strValue","React","suggestions","password","formatCompact","formatCurrency","formatDate","formatDateTime","formatRelativeDate","translateStatus"],"mappings":"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","file":"index.js","sourcesContent":["/**\r\n * Types & Constants\r\n *\r\n * Tipos e constantes compartilhadas entre módulos.\r\n *\r\n * @module @rainersoft/utils/types\r\n * @author Rainer Teixeira\r\n */\r\n\r\n/**\r\n * Idiomas suportados\r\n */\r\nexport type Locale = 'pt-BR' | 'en-US' | 'es-ES';\r\n\r\n/**\r\n * Configuração de localização\r\n */\r\nexport interface LocaleConfig {\r\n locale: Locale;\r\n currency?: string;\r\n dateFormat?: 'short' | 'long' | 'full';\r\n}\r\n\r\n/**\r\n * Locale padrão\r\n */\r\nexport const DEFAULT_LOCALE: Locale = 'pt-BR';\r\n\r\n/**\r\n * Mapeamento de moedas por locale\r\n */\r\nexport const CURRENCY_MAP: Record<Locale, string> = {\r\n 'pt-BR': 'BRL',\r\n 'en-US': 'USD',\r\n 'es-ES': 'EUR',\r\n} as const;\r\n","/**\r\n * Text Utilities\r\n *\r\n * Utilitários universais para manipulação de texto e strings.\r\n *\r\n * @module @rainersoft/utils/text\r\n * @author Rainer Teixeira\r\n * @version 1.0.0\r\n */\r\n\r\n// ============================================================================\r\n// AVATAR UTILITIES\r\n// ============================================================================\r\n\r\n/**\r\n * Extrai iniciais de um nome\r\n *\r\n * @param name - Nome completo\r\n * @param maxChars - Número máximo de caracteres (padrão: 2)\r\n * @returns Iniciais do nome em maiúsculas\r\n *\r\n * @example\r\n * ```ts\r\n * extractInitials('John Doe') // 'JD'\r\n * extractInitials('Maria Silva Santos') // 'MS'\r\n * extractInitials('Apple') // 'A'\r\n * extractInitials('', 3) // ''\r\n * ```\r\n */\r\nexport function extractInitials(name: string | null | undefined, maxChars = 2): string {\r\n if (!name || !name.trim()) {\r\n return '';\r\n }\r\n\r\n const words = name.trim().split(/\\s+/);\r\n const initials = words\r\n .slice(0, maxChars)\r\n .map(word => word.charAt(0).toUpperCase())\r\n .join('');\r\n\r\n return initials;\r\n}\r\n\r\n/**\r\n * Gera URL do avatar com base no nome\r\n *\r\n * @param name - Nome para gerar avatar\r\n * @param size - Tamanho do avatar (default: 200)\r\n * @param backgroundColor - Cor de fundo (default: cyan)\r\n * @param textColor - Cor do texto (default: white)\r\n * @returns URL do avatar\r\n *\r\n * @example\r\n * ```ts\r\n * generateAvatarUrl('John Doe') // URL do avatar\r\n * generateAvatarUrl('John Doe', 100, 'f97316', 'fff') // URL com cor laranja\r\n * ```\r\n */\r\nexport function generateAvatarUrl(\r\n name: string,\r\n size: number = 200,\r\n backgroundColor: string = '0891b2',\r\n textColor: string = 'fff'\r\n): string {\r\n const encodedName = encodeURIComponent(name);\r\n \r\n return `https://ui-avatars.com/api/?name=${encodedName}&size=${size}&background=${backgroundColor}&color=${textColor}&font-size=0.5`;\r\n}\r\n\r\n/**\r\n * Valida se uma URL de avatar é válida\r\n *\r\n * @param url - URL do avatar\r\n * @returns true se a URL for válida\r\n *\r\n * @example\r\n * ```ts\r\n * isValidAvatarUrl('https://example.com/avatar.jpg') // true\r\n * isValidAvatarUrl('invalid-url') // false\r\n * ```\r\n */\r\nexport function isValidAvatarUrl(url: string): boolean {\r\n if (!url || typeof url !== 'string') {\r\n return false;\r\n }\r\n\r\n try {\r\n new URL(url);\r\n return true;\r\n } catch {\r\n return false;\r\n }\r\n}\r\n\r\n/**\r\n * Obtém a cor do avatar baseada no hash do nome\r\n *\r\n * @param name - Nome para gerar cor\r\n * @returns Cor em formato hexadecimal\r\n *\r\n * @example\r\n * ```ts\r\n * getAvatarColorFromName('John Doe') // '#0891b2' (ou outra cor)\r\n * getAvatarColorFromName('') // '#0891b2' (cor padrão)\r\n * ```\r\n */\r\nexport function getAvatarColorFromName(name: string): string {\r\n if (!name || typeof name !== 'string') {\r\n return '#0891b2'; // cyan-600 como padrão\r\n }\r\n\r\n // Gera hash simples do nome\r\n let hash = 0;\r\n for (let i = 0; i < name.length; i++) {\r\n hash = name.charCodeAt(i) + ((hash << 5) - hash);\r\n }\r\n\r\n // Cores baseadas em design tokens (compatível com @rainersoft/design-tokens)\r\n const colors = [\r\n '#0891b2', // cyan-600\r\n '#9333ea', // purple-600\r\n '#db2777', // pink-600\r\n '#059669', // emerald-600\r\n '#2563eb', // blue-600\r\n '#f97316', // orange-500\r\n '#dc2626', // red-600\r\n '#7c3aed', // violet-600\r\n ];\r\n\r\n const index = Math.abs(hash) % colors.length;\r\n return colors[index];\r\n}\r\n\r\n/**\r\n * Gera avatar com cor baseada no nome\r\n *\r\n * @param name - Nome para gerar avatar\r\n * @param size - Tamanho do avatar\r\n * @returns URL do avatar com cor automática\r\n *\r\n * @example\r\n * ```ts\r\n * generateDynamicAvatarUrl('John Doe') // URL com cor baseada no nome\r\n * generateDynamicAvatarUrl('Jane Smith', 150) // URL com tamanho 150\r\n * ```\r\n */\r\nexport function generateDynamicAvatarUrl(name: string, size: number = 200): string {\r\n const color = getAvatarColorFromName(name);\r\n const colorHex = color.replace('#', '');\r\n return generateAvatarUrl(name, size, colorHex, 'fff');\r\n}\r\n\r\n// ============================================================================\r\n// TEXT UTILITIES\r\n// ============================================================================\r\n\r\n/**\r\n * Gera ID único baseado em texto\r\n *\r\n * @param text - Texto base para o ID\r\n * @param prefix - Prefixo opcional\r\n * @param suffix - Sufixo opcional\r\n * @returns ID único em formato slug\r\n *\r\n * @example\r\n * ```ts\r\n * generateUniqueId('Hello World') // 'hello-world'\r\n * generateUniqueId('Hello World', 'section') // 'section-hello-world'\r\n * generateUniqueId('Olá! Como vai?', '', '123') // 'ola-como-vai-123'\r\n * ```\r\n */\r\nexport function generateUniqueId(\r\n text: string,\r\n prefix = '',\r\n suffix = ''\r\n): string {\r\n const slug = text\r\n .toLowerCase()\r\n .normalize('NFD')\r\n .replace(/[\\u0300-\\u036f]/g, '') // Remove acentos\r\n .replace(/[^\\w\\s-]/g, '') // Remove caracteres especiais\r\n .replace(/\\s+/g, '-') // Substitui espaços por hífens\r\n .replace(/-+/g, '-') // Remove hífens duplicados\r\n .trim()\r\n .substring(0, 50); // Limita tamanho\r\n\r\n const parts = [prefix, slug, suffix].filter(Boolean);\r\n return parts.join('-');\r\n}\r\n\r\n/**\r\n * Trunca texto com elipse\r\n *\r\n * @param text - Texto para truncar\r\n * @param maxLength - Comprimento máximo\r\n * @param suffix - Sufixo para adicionar (padrão: '...')\r\n * @returns Texto truncado\r\n *\r\n * @example\r\n * ```ts\r\n * truncateText('Hello World', 5) // 'Hello...'\r\n * truncateText('Hello World', 8, '...') // 'Hello...'\r\n * truncateText('Short', 10) // 'Short'\r\n * ```\r\n */\r\nexport function truncateText(\r\n text: string,\r\n maxLength: number,\r\n suffix = '...'\r\n): string {\r\n if (!text || text.length <= maxLength) {\r\n return text || '';\r\n }\r\n\r\n return text.substring(0, maxLength - suffix.length) + suffix;\r\n}\r\n\r\n/**\r\n * Capitaliza primeira letra de cada palavra\r\n *\r\n * @param text - Texto para capitalizar\r\n * @param options - Opções de capitalização\r\n * @returns Texto capitalizado\r\n *\r\n * @example\r\n * ```ts\r\n * capitalize('hello world') // 'Hello World'\r\n * capitalize('hello world', { firstWordOnly: true }) // 'Hello world'\r\n * capitalize('HELLO WORLD', { lowerRest: true }) // 'Hello World'\r\n * ```\r\n */\r\nexport function capitalize(\r\n text: string,\r\n options: { firstWordOnly?: boolean; lowerRest?: boolean } = {}\r\n): string {\r\n if (!text) return '';\r\n\r\n const { firstWordOnly = false, lowerRest = false } = options;\r\n\r\n if (firstWordOnly) {\r\n return text.charAt(0).toUpperCase() + \r\n (lowerRest ? text.slice(1).toLowerCase() : text.slice(1));\r\n }\r\n\r\n if (lowerRest) {\r\n return text.replace(/\\b\\w/g, char => char.toUpperCase()).toLowerCase();\r\n }\r\n\r\n return text.replace(/\\b\\w/g, char => char.toUpperCase());\r\n}\r\n\r\n/**\r\n * Remove caracteres especiais mantendo apenas alfanuméricos e espaços\r\n *\r\n * @param text - Texto para limpar\r\n * @param allowSpaces - Se deve permitir espaços\r\n * @returns Texto limpo\r\n *\r\n * @example\r\n * ```ts\r\n * cleanText('Olá! Como vai?') // 'Ola Como vai'\r\n * cleanText('Olá! Como vai?', false) // 'OlaComoVai'\r\n * ```\r\n */\r\nexport function cleanText(text: string, allowSpaces = true): string {\r\n if (!text) return '';\r\n\r\n const pattern = allowSpaces ? /[^\\w\\s]/g : /[^\\w]/g;\r\n return text.replace(pattern, '');\r\n}\r\n\r\n/**\r\n * Conta palavras em um texto\r\n *\r\n * @param text - Texto para contar\r\n * @returns Número de palavras\r\n *\r\n * @example\r\n * ```ts\r\n * countWords('Hello world') // 2\r\n * countWords(' Hello world ') // 2\r\n * countWords('') // 0\r\n * ```\r\n */\r\nexport function countWords(text: string): number {\r\n if (!text || !text.trim()) {\r\n return 0;\r\n }\r\n\r\n return text.trim().split(/\\s+/).length;\r\n}\r\n\r\n/**\r\n * Verifica se texto está vazio ou contém apenas espaços\r\n *\r\n * @param text - Texto para verificar\r\n * @returns True se estiver vazio\r\n *\r\n * @example\r\n * ```ts\r\n * isEmpty('') // true\r\n * isEmpty(' ') // true\r\n * isEmpty('Hello') // false\r\n * ```\r\n */\r\nexport function isEmpty(text: string | null | undefined): boolean {\r\n return !text || !text.trim();\r\n}\r\n\r\n/**\r\n * Remove espaços em branco extras\r\n *\r\n * @param text - Texto para limpar\r\n * @param options - Opções de limpeza\r\n * @returns Texto sem espaços extras\r\n *\r\n * @example\r\n * ```ts\r\n * normalizeSpaces(' Hello World ') // 'Hello World'\r\n * normalizeSpaces('Hello\\nWorld', { newlines: true }) // 'Hello World'\r\n * ```\r\n */\r\nexport function normalizeSpaces(\r\n text: string,\r\n options: { newlines?: boolean } = {}\r\n): string {\r\n if (!text) return '';\r\n\r\n const { newlines = false } = options;\r\n \r\n let cleaned = text;\r\n \r\n if (newlines) {\r\n cleaned = cleaned.replace(/\\s+/g, ' ');\r\n } else {\r\n cleaned = cleaned.replace(/\\s+/g, ' ');\r\n }\r\n \r\n return cleaned.trim();\r\n}\r\n\r\n/**\r\n * Calcula tempo de leitura baseado no conteúdo\r\n *\r\n * Suporta múltiplos formatos:\r\n * - JSON (objeto com conteúdo estruturado)\r\n * - HTML (string com tags)\r\n * - Texto simples (string)\r\n *\r\n * @param content - Conteúdo a analisar (objeto JSON, HTML ou texto)\r\n * @param wordsPerMinute - Palavras por minuto (padrão: 200)\r\n * @returns Tempo de leitura em minutos (mínimo: 1)\r\n *\r\n * @example\r\n * ```ts\r\n * // JSON estruturado\r\n * const jsonContent = { type: 'doc', content: [...] };\r\n * calculateReadingTime(jsonContent) // 5\r\n *\r\n * // HTML\r\n * calculateReadingTime('<p>Texto longo...</p>') // 3\r\n *\r\n * // Texto simples\r\n * calculateReadingTime('Texto simples') // 1\r\n * ```\r\n */\r\nexport function calculateReadingTime(\r\n content: string | Record<string, any>,\r\n wordsPerMinute: number = 200\r\n): number {\r\n let text = '';\r\n\r\n // Se for objeto (JSON estruturado)\r\n if (typeof content === 'object' && content !== null) {\r\n // Extrai texto de estrutura JSON recursivamente\r\n const extractText = (node: any): string => {\r\n if (!node) return '';\r\n \r\n let result = '';\r\n \r\n // Se tem texto direto\r\n if (node.text) {\r\n result += node.text + ' ';\r\n }\r\n \r\n // Se tem conteúdo (array de nós)\r\n if (Array.isArray(node.content)) {\r\n result += node.content.map(extractText).join(' ');\r\n }\r\n \r\n return result;\r\n };\r\n \r\n text = extractText(content);\r\n } else if (typeof content === 'string') {\r\n // Se for HTML ou texto simples, remove tags HTML\r\n text = content.replace(/<[^>]*>/g, '');\r\n }\r\n\r\n const words = text\r\n .trim()\r\n .split(/\\s+/)\r\n .filter(word => word.length > 0).length;\r\n const time = Math.ceil(words / wordsPerMinute);\r\n\r\n // Retorna no mínimo 1 minuto\r\n return time > 0 ? time : 1;\r\n}\r\n","/**\r\n * String Utilities\r\n *\r\n * Utilitários para manipulação e formatação de strings.\r\n * Funções puras, sem dependências externas, prontas para qualquer plataforma.\r\n *\r\n * @module @rainersoft/utils/string\r\n * @author Rainer Teixeira\r\n */\r\n\r\n/**\r\n * Converte texto para slug URL-friendly\r\n *\r\n * @param text - Texto para converter\r\n * @returns Slug normalizado\r\n *\r\n * @example\r\n * textToSlug('Meu Post Incrível!') // 'meu-post-incrivel'\r\n * textToSlug('São Paulo - SP') // 'sao-paulo-sp'\r\n */\r\nexport function textToSlug(text: string): string {\r\n return text\r\n .toLowerCase()\r\n .normalize('NFD')\r\n .replace(/[\\u0300-\\u036f]/g, '')\r\n .replace(/[^\\w\\s-]/g, '')\r\n .trim()\r\n .replace(/\\s+/g, '-')\r\n .replace(/-+/g, '-');\r\n}\r\n\r\n/**\r\n * Capitaliza primeira letra de cada palavra\r\n *\r\n * @param text - Texto para capitalizar\r\n * @returns Texto capitalizado\r\n *\r\n * @example\r\n * capitalize('rainer teixeira') // 'Rainer Teixeira'\r\n */\r\nexport function capitalize(text: string): string {\r\n return text\r\n .toLowerCase()\r\n .split(' ')\r\n .map(word => word.charAt(0).toUpperCase() + word.slice(1))\r\n .join(' ');\r\n}\r\n\r\n/**\r\n * Trunca texto com ellipsis\r\n *\r\n * @param text - Texto para truncar\r\n * @param maxLength - Comprimento máximo\r\n * @param suffix - Sufixo (padrão: '...')\r\n * @returns Texto truncado\r\n *\r\n * @example\r\n * truncate('Texto muito longo', 10) // 'Texto muit...'\r\n */\r\nexport function truncate(text: string, maxLength: number, suffix = '...'): string {\r\n if (text.length <= maxLength) return text;\r\n return text.slice(0, maxLength - suffix.length) + suffix;\r\n}\r\n\r\n/**\r\n * Remove acentos de texto\r\n *\r\n * @param text - Texto com acentos\r\n * @returns Texto sem acentos\r\n *\r\n * @example\r\n * removeAccents('São Paulo') // 'Sao Paulo'\r\n */\r\nexport function removeAccents(text: string): string {\r\n return text.normalize('NFD').replace(/[\\u0300-\\u036f]/g, '');\r\n}\r\n\r\n/**\r\n * Extrai iniciais de um nome\r\n *\r\n * @param name - Nome completo\r\n * @param maxInitials - Máximo de iniciais (padrão: 2)\r\n * @returns Iniciais em maiúsculas\r\n *\r\n * @example\r\n * getInitials('Rainer Teixeira') // 'RT'\r\n * getInitials('João da Silva Santos', 3) // 'JSS'\r\n */\r\nexport function getInitials(name: string, maxInitials = 2): string {\r\n return name\r\n .split(' ')\r\n .filter(word => word.length > 0)\r\n .map(word => word[0])\r\n .join('')\r\n .toUpperCase()\r\n .slice(0, maxInitials);\r\n}\r\n\r\n/**\r\n * Valida se string é vazia ou apenas espaços\r\n *\r\n * @param text - Texto para validar\r\n * @returns true se vazio, false caso contrário\r\n */\r\nexport function isEmpty(text: string | null | undefined): boolean {\r\n return !text || text.trim().length === 0;\r\n}\r\n\r\n/**\r\n * Conta palavras em um texto\r\n *\r\n * @param text - Texto para contar\r\n * @returns Número de palavras\r\n */\r\nexport function wordCount(text: string): number {\r\n return text.trim().split(/\\s+/).filter(word => word.length > 0).length;\r\n}\r\n","/**\r\n * Date Utilities\r\n *\r\n * Utilitários para formatação e manipulação de datas.\r\n * Suporte para múltiplos idiomas: pt-BR, en-US, es-ES.\r\n *\r\n * @module @rainersoft/utils/date\r\n * @author Rainer Teixeira\r\n */\r\n\r\nimport type { Locale } from '../types';\r\nimport { DEFAULT_LOCALE } from '../types';\r\n\r\n/**\r\n * Textos relativos por idioma\r\n */\r\nconst RELATIVE_TEXTS = {\r\n 'pt-BR': {\r\n now: 'agora',\r\n minute: (n: number) => `há ${n} ${n === 1 ? 'minuto' : 'minutos'}`,\r\n hour: (n: number) => `há ${n} ${n === 1 ? 'hora' : 'horas'}`,\r\n day: (n: number) => `há ${n} ${n === 1 ? 'dia' : 'dias'}`,\r\n month: (n: number) => `há ${n} ${n === 1 ? 'mês' : 'meses'}`,\r\n year: (n: number) => `há ${n} ${n === 1 ? 'ano' : 'anos'}`,\r\n },\r\n 'en-US': {\r\n now: 'now',\r\n minute: (n: number) => `${n} ${n === 1 ? 'minute' : 'minutes'} ago`,\r\n hour: (n: number) => `${n} ${n === 1 ? 'hour' : 'hours'} ago`,\r\n day: (n: number) => `${n} ${n === 1 ? 'day' : 'days'} ago`,\r\n month: (n: number) => `${n} ${n === 1 ? 'month' : 'months'} ago`,\r\n year: (n: number) => `${n} ${n === 1 ? 'year' : 'years'} ago`,\r\n },\r\n 'es-ES': {\r\n now: 'ahora',\r\n minute: (n: number) => `hace ${n} ${n === 1 ? 'minuto' : 'minutos'}`,\r\n hour: (n: number) => `hace ${n} ${n === 1 ? 'hora' : 'horas'}`,\r\n day: (n: number) => `hace ${n} ${n === 1 ? 'día' : 'días'}`,\r\n month: (n: number) => `hace ${n} ${n === 1 ? 'mes' : 'meses'}`,\r\n year: (n: number) => `hace ${n} ${n === 1 ? 'año' : 'años'}`,\r\n },\r\n} as const;\r\n\r\n/**\r\n * Formata data com suporte a múltiplos idiomas\r\n *\r\n * @param date - Data (string ISO ou Date)\r\n * @param format - Formato ('short' | 'long' | 'full')\r\n * @param locale - Idioma (padrão: 'pt-BR')\r\n * @returns Data formatada\r\n *\r\n * @example\r\n * formatDate('2025-11-26') // '26 de novembro de 2025' (pt-BR)\r\n * formatDate('2025-11-26', 'short') // '26/11/2025'\r\n * formatDate('2025-11-26', 'long', 'en-US') // 'November 26, 2025'\r\n * formatDate('2025-11-26', 'long', 'es-ES') // '26 de noviembre de 2025'\r\n */\r\nexport function formatDate(\r\n date: string | Date,\r\n format: 'short' | 'long' | 'full' = 'long',\r\n locale: Locale = DEFAULT_LOCALE\r\n): string {\r\n const d = typeof date === 'string' ? new Date(date) : date;\r\n \r\n // Usar Intl.DateTimeFormat para suporte multi-idioma\r\n const options: Intl.DateTimeFormatOptions = {\r\n day: 'numeric',\r\n month: format === 'short' ? '2-digit' : 'long',\r\n year: 'numeric',\r\n ...(format === 'full' && { weekday: 'long' }),\r\n };\r\n\r\n if (format === 'short') {\r\n return d.toLocaleDateString(locale, { day: '2-digit', month: '2-digit', year: 'numeric' });\r\n }\r\n\r\n return d.toLocaleDateString(locale, options);\r\n}\r\n\r\n/**\r\n * Formata data e hora com suporte a múltiplos idiomas\r\n *\r\n * @param date - Data (string ISO ou Date)\r\n * @param locale - Idioma (padrão: 'pt-BR')\r\n * @returns Data e hora formatadas\r\n *\r\n * @example\r\n * formatDateTime('2025-11-26T14:30:00') // '26 de novembro de 2025, 14:30' (pt-BR)\r\n * formatDateTime('2025-11-26T14:30:00', 'en-US') // 'November 26, 2025, 2:30 PM'\r\n */\r\nexport function formatDateTime(date: string | Date, locale: Locale = DEFAULT_LOCALE): string {\r\n const d = typeof date === 'string' ? new Date(date) : date;\r\n \r\n return d.toLocaleString(locale, {\r\n day: 'numeric',\r\n month: 'long',\r\n year: 'numeric',\r\n hour: '2-digit',\r\n minute: '2-digit',\r\n });\r\n}\r\n\r\n/**\r\n * Formata data relativa (há X dias/horas) com suporte a idiomas\r\n *\r\n * @param date - Data (string ISO ou Date)\r\n * @param locale - Idioma (padrão: 'pt-BR')\r\n * @returns Texto relativo\r\n *\r\n * @example\r\n * formatRelativeDate(new Date()) // 'agora' (pt-BR)\r\n * formatRelativeDate(yesterday, 'en-US') // '1 day ago'\r\n * formatRelativeDate(yesterday, 'es-ES') // 'hace 1 día'\r\n */\r\nexport function formatRelativeDate(date: string | Date, locale: Locale = DEFAULT_LOCALE): string {\r\n const d = typeof date === 'string' ? new Date(date) : date;\r\n\r\n // Proteger contra datas inválidas (evita 'há NaN anos')\r\n if (!(d instanceof Date) || Number.isNaN(d.getTime())) {\r\n return '';\r\n }\r\n const now = new Date();\r\n const diffMs = now.getTime() - d.getTime();\r\n const diffSec = Math.floor(diffMs / 1000);\r\n const diffMin = Math.floor(diffSec / 60);\r\n const diffHour = Math.floor(diffMin / 60);\r\n const diffDay = Math.floor(diffHour / 24);\r\n // Usar média de dias por mês mais próxima da realidade para não arredondar cedo demais para 1 ano\r\n const diffMonth = Math.floor(diffDay / 30.4375); // 365 / 12\r\n const diffYear = Math.floor(diffDay / 365);\r\n\r\n const texts = RELATIVE_TEXTS[locale];\r\n\r\n // Regras especiais por idioma (mais naturais)\r\n if (diffSec < 10) {\r\n if (locale === 'pt-BR') return 'agora mesmo';\r\n if (locale === 'en-US') return 'just now';\r\n if (locale === 'es-ES') return 'ahora mismo';\r\n }\r\n\r\n if (diffSec < 60) return texts.now;\r\n if (diffMin < 60) return texts.minute(diffMin);\r\n if (diffHour < 24) return texts.hour(diffHour);\r\n\r\n // Dias específicos\r\n if (diffDay === 1) {\r\n if (locale === 'pt-BR') return 'ontem';\r\n if (locale === 'en-US') return 'yesterday';\r\n if (locale === 'es-ES') return 'ayer';\r\n }\r\n\r\n if (diffDay === 2) {\r\n if (locale === 'pt-BR') return 'anteontem';\r\n if (locale === 'en-US') return 'the day before yesterday';\r\n if (locale === 'es-ES') return 'anteayer';\r\n }\r\n\r\n if (diffDay < 30) return texts.day(diffDay);\r\n if (diffMonth < 12) return texts.month(diffMonth);\r\n return texts.year(diffYear);\r\n}\r\n\r\n/**\r\n * Converte data para ISO string\r\n *\r\n * @param date - Data\r\n * @returns String ISO\r\n */\r\nexport function toISOString(date: Date): string {\r\n return date.toISOString();\r\n}\r\n\r\n/**\r\n * Verifica se data é válida\r\n *\r\n * @param date - Data para validar\r\n * @returns true se válida\r\n */\r\nexport function isValidDate(date: unknown): date is Date {\r\n return date instanceof Date && !isNaN(date.getTime());\r\n}\r\n","/**\r\n * Number Utilities\r\n *\r\n * Utilitários para formatação de números, moedas e percentuais.\r\n * Suporte para múltiplos idiomas: pt-BR, en-US, es-ES.\r\n *\r\n * @module @rainersoft/utils/number\r\n * @author Rainer Teixeira\r\n */\r\n\r\nimport type { Locale } from '../types';\r\nimport { DEFAULT_LOCALE, CURRENCY_MAP } from '../types';\r\n\r\n/**\r\n * Formata número como moeda com suporte a idiomas\r\n *\r\n * @param value - Valor numérico\r\n * @param locale - Idioma (padrão: 'pt-BR')\r\n * @param options - Opções de formatação\r\n * @returns Valor formatado\r\n *\r\n * @example\r\n * formatCurrency(1234.56) // 'R$ 1.234,56' (pt-BR)\r\n * formatCurrency(1234.56, 'en-US') // '$1,234.56'\r\n * formatCurrency(1234.56, 'es-ES') // '1.234,56 €'\r\n */\r\nexport function formatCurrency(\r\n value: number,\r\n locale: Locale = DEFAULT_LOCALE,\r\n options?: Intl.NumberFormatOptions\r\n): string {\r\n const currency = CURRENCY_MAP[locale];\r\n return new Intl.NumberFormat(locale, {\r\n style: 'currency',\r\n currency,\r\n ...options,\r\n }).format(value);\r\n}\r\n\r\n/**\r\n * Formata número como percentual\r\n *\r\n * @param value - Valor entre 0 e 1 (ou 0 e 100 se usePercentage=true)\r\n * @param decimals - Casas decimais (padrão: 0)\r\n * @param usePercentage - Se true, espera valor 0-100 (padrão: false)\r\n * @returns Percentual formatado\r\n *\r\n * @example\r\n * formatPercent(0.1234) // '12%'\r\n * formatPercent(0.1234, 2) // '12,34%'\r\n * formatPercent(12.34, 2, true) // '12,34%'\r\n */\r\nexport function formatPercent(\r\n value: number,\r\n decimals = 0,\r\n usePercentage = false\r\n): string {\r\n return new Intl.NumberFormat('pt-BR', {\r\n style: 'percent',\r\n minimumFractionDigits: decimals,\r\n maximumFractionDigits: decimals,\r\n }).format(usePercentage ? value / 100 : value);\r\n}\r\n\r\n/**\r\n * Formata número com separadores de milhar\r\n *\r\n * @param value - Valor numérico\r\n * @param decimals - Casas decimais (padrão: 0)\r\n * @param locale - Idioma (padrão: 'pt-BR')\r\n * @returns Número formatado\r\n *\r\n * @example\r\n * formatNumber(1234567) // '1.234.567' (pt-BR)\r\n * formatNumber(1234567, 0, 'en-US') // '1,234,567'\r\n */\r\nexport function formatNumber(value: number, decimals = 0, locale: Locale = DEFAULT_LOCALE): string {\r\n return new Intl.NumberFormat(locale, {\r\n minimumFractionDigits: decimals,\r\n maximumFractionDigits: decimals,\r\n }).format(value);\r\n}\r\n\r\n/**\r\n * Formata número de forma compacta (1K, 1M, 1B)\r\n *\r\n * @param value - Valor numérico\r\n * @param decimals - Casas decimais (padrão: 1)\r\n * @param locale - Idioma (padrão: 'pt-BR')\r\n * @returns Número compacto\r\n *\r\n * @example\r\n * formatCompact(1234) // '1,2 mil' (pt-BR)\r\n * formatCompact(1234567, 1, 'en-US') // '1.2M'\r\n */\r\nexport function formatCompact(value: number, decimals = 1, locale: Locale = DEFAULT_LOCALE): string {\r\n return new Intl.NumberFormat(locale, {\r\n notation: 'compact',\r\n compactDisplay: 'short',\r\n minimumFractionDigits: decimals,\r\n maximumFractionDigits: decimals,\r\n }).format(value);\r\n}\r\n\r\n/**\r\n * Converte string de moeda para número\r\n *\r\n * @param currency - String de moeda (ex: 'R$ 1.234,56')\r\n * @returns Valor numérico\r\n *\r\n * @example\r\n * parseCurrency('R$ 1.234,56') // 1234.56\r\n * parseCurrency('1.234,56') // 1234.56\r\n */\r\nexport function parseCurrency(currency: string): number {\r\n const cleaned = currency\r\n .replace(/[R$\\s]/g, '')\r\n .replace(/\\./g, '')\r\n .replace(',', '.');\r\n return parseFloat(cleaned);\r\n}\r\n\r\n/**\r\n * Arredonda número para casas decimais\r\n *\r\n * @param value - Valor numérico\r\n * @param decimals - Casas decimais\r\n * @returns Valor arredondado\r\n *\r\n * @example\r\n * round(1.2345, 2) // 1.23\r\n */\r\nexport function round(value: number, decimals = 2): number {\r\n const factor = Math.pow(10, decimals);\r\n return Math.round(value * factor) / factor;\r\n}\r\n\r\n/**\r\n * Clamp - limita número entre min e max\r\n *\r\n * @param value - Valor\r\n * @param min - Mínimo\r\n * @param max - Máximo\r\n * @returns Valor limitado\r\n *\r\n * @example\r\n * clamp(150, 0, 100) // 100\r\n * clamp(-10, 0, 100) // 0\r\n */\r\nexport function clamp(value: number, min: number, max: number): number {\r\n return Math.min(Math.max(value, min), max);\r\n}\r\n","/**\r\n * Status Utilities\r\n *\r\n * Utilitários para tradução e manipulação de status.\r\n * Agnóstico de domínio - pode ser usado para posts, pedidos, tarefas, etc.\r\n * Suporte para múltiplos idiomas: pt-BR, en-US, es-ES.\r\n *\r\n * @module @rainersoft/utils/status\r\n * @author Rainer Teixeira\r\n */\r\n\r\nimport type { Locale } from '../types';\r\nimport { DEFAULT_LOCALE } from '../types';\r\n\r\n/**\r\n * Status genéricos de entidades\r\n */\r\nexport type GenericStatus =\r\n | 'DRAFT'\r\n | 'PENDING'\r\n | 'PUBLISHED'\r\n | 'ACTIVE'\r\n | 'INACTIVE'\r\n | 'ARCHIVED'\r\n | 'DELETED'\r\n | 'SCHEDULED'\r\n | 'COMPLETED'\r\n | 'CANCELLED'\r\n | 'APPROVED'\r\n | 'REJECTED';\r\n\r\n/**\r\n * Traduções de status por idioma\r\n */\r\nconst STATUS_TRANSLATIONS: Record<Locale, Record<string, string>> = {\r\n 'pt-BR': {\r\n // Estados de conteúdo\r\n DRAFT: 'Rascunho',\r\n PUBLISHED: 'Publicado',\r\n ARCHIVED: 'Arquivado',\r\n SCHEDULED: 'Agendado',\r\n DELETED: 'Excluído',\r\n \r\n // Estados de processo\r\n PENDING: 'Pendente',\r\n ACTIVE: 'Ativo',\r\n INACTIVE: 'Inativo',\r\n COMPLETED: 'Concluído',\r\n CANCELLED: 'Cancelado',\r\n \r\n // Estados de aprovação\r\n APPROVED: 'Aprovado',\r\n REJECTED: 'Rejeitado',\r\n \r\n // Estados de pedido/pagamento\r\n PROCESSING: 'Processando',\r\n PAID: 'Pago',\r\n UNPAID: 'Não Pago',\r\n REFUNDED: 'Reembolsado',\r\n FAILED: 'Falhou',\r\n \r\n // Estados de usuário\r\n VERIFIED: 'Verificado',\r\n UNVERIFIED: 'Não Verificado',\r\n BANNED: 'Banido',\r\n SUSPENDED: 'Suspenso',\r\n },\r\n 'en-US': {\r\n DRAFT: 'Draft',\r\n PUBLISHED: 'Published',\r\n ARCHIVED: 'Archived',\r\n SCHEDULED: 'Scheduled',\r\n DELETED: 'Deleted',\r\n PENDING: 'Pending',\r\n ACTIVE: 'Active',\r\n INACTIVE: 'Inactive',\r\n COMPLETED: 'Completed',\r\n CANCELLED: 'Cancelled',\r\n APPROVED: 'Approved',\r\n REJECTED: 'Rejected',\r\n PROCESSING: 'Processing',\r\n PAID: 'Paid',\r\n UNPAID: 'Unpaid',\r\n REFUNDED: 'Refunded',\r\n FAILED: 'Failed',\r\n VERIFIED: 'Verified',\r\n UNVERIFIED: 'Unverified',\r\n BANNED: 'Banned',\r\n SUSPENDED: 'Suspended',\r\n },\r\n 'es-ES': {\r\n DRAFT: 'Borrador',\r\n PUBLISHED: 'Publicado',\r\n ARCHIVED: 'Archivado',\r\n SCHEDULED: 'Programado',\r\n DELETED: 'Eliminado',\r\n PENDING: 'Pendiente',\r\n ACTIVE: 'Activo',\r\n INACTIVE: 'Inactivo',\r\n COMPLETED: 'Completado',\r\n CANCELLED: 'Cancelado',\r\n APPROVED: 'Aprobado',\r\n REJECTED: 'Rechazado',\r\n PROCESSING: 'Procesando',\r\n PAID: 'Pagado',\r\n UNPAID: 'No Pagado',\r\n REFUNDED: 'Reembolsado',\r\n FAILED: 'Fallido',\r\n VERIFIED: 'Verificado',\r\n UNVERIFIED: 'No Verificado',\r\n BANNED: 'Bloqueado',\r\n SUSPENDED: 'Suspendido',\r\n },\r\n} as const;\r\n\r\n/**\r\n * Traduz status com suporte a idiomas\r\n *\r\n * @param status - Status em inglês (uppercase)\r\n * @param locale - Idioma (padrão: 'pt-BR')\r\n * @returns Status traduzido\r\n *\r\n * @example\r\n * translateStatus('DRAFT') // 'Rascunho' (pt-BR)\r\n * translateStatus('DRAFT', 'en-US') // 'Draft'\r\n * translateStatus('DRAFT', 'es-ES') // 'Borrador'\r\n */\r\nexport function translateStatus(status: string, locale: Locale = DEFAULT_LOCALE): string {\r\n const normalized = status.toUpperCase();\r\n return STATUS_TRANSLATIONS[locale][normalized] || status;\r\n}\r\n\r\n/**\r\n * Obtém cor baseada no status\r\n *\r\n * @param status - Status\r\n * @returns Classe Tailwind de cor\r\n *\r\n * @example\r\n * getStatusColor('PUBLISHED') // 'text-green-600'\r\n * getStatusColor('DRAFT') // 'text-gray-600'\r\n */\r\nexport function getStatusColor(status: string): string {\r\n const normalized = status.toUpperCase();\r\n \r\n const colorMap: Record<string, string> = {\r\n DRAFT: 'text-gray-600',\r\n PENDING: 'text-yellow-600',\r\n PUBLISHED: 'text-green-600',\r\n ACTIVE: 'text-green-600',\r\n INACTIVE: 'text-gray-600',\r\n ARCHIVED: 'text-orange-600',\r\n DELETED: 'text-red-600',\r\n SCHEDULED: 'text-blue-600',\r\n COMPLETED: 'text-green-600',\r\n CANCELLED: 'text-red-600',\r\n APPROVED: 'text-green-600',\r\n REJECTED: 'text-red-600',\r\n FAILED: 'text-red-600',\r\n VERIFIED: 'text-green-600',\r\n BANNED: 'text-red-600',\r\n };\r\n \r\n return colorMap[normalized] || 'text-gray-600';\r\n}\r\n\r\n/**\r\n * Obtém badge variant baseado no status\r\n *\r\n * @param status - Status\r\n * @returns Variant do badge\r\n *\r\n * @example\r\n * getStatusVariant('PUBLISHED') // 'success'\r\n * getStatusVariant('DRAFT') // 'secondary'\r\n */\r\nexport function getStatusVariant(status: string): 'default' | 'secondary' | 'destructive' | 'outline' {\r\n const normalized = status.toUpperCase();\r\n \r\n if (['PUBLISHED', 'ACTIVE', 'COMPLETED', 'APPROVED', 'VERIFIED'].includes(normalized)) {\r\n return 'default'; // Verde/sucesso\r\n }\r\n \r\n if (['DELETED', 'CANCELLED', 'REJECTED', 'FAILED', 'BANNED'].includes(normalized)) {\r\n return 'destructive'; // Vermelho/erro\r\n }\r\n \r\n if (['DRAFT', 'INACTIVE', 'ARCHIVED'].includes(normalized)) {\r\n return 'secondary'; // Cinza/neutro\r\n }\r\n \r\n return 'outline'; // Padrão\r\n}\r\n\r\n/**\r\n * Traduz status de posts do blog (alias para translateStatus)\r\n * Mantém compatibilidade com código legado\r\n *\r\n * @param status - Status do post (draft, published, archived, etc)\r\n * @param locale - Idioma (padrão: 'pt-BR')\r\n * @returns Status traduzido\r\n *\r\n * @example\r\n * translatePostStatus('draft') // 'Rascunho'\r\n * translatePostStatus('published') // 'Publicado'\r\n * translatePostStatus('pending_review') // 'Aguardando Revisão'\r\n */\r\nexport function translatePostStatus(status: string, locale: Locale = DEFAULT_LOCALE): string {\r\n // Mapeamento de status específicos de posts\r\n const postStatusMap: Record<string, string> = {\r\n 'draft': 'DRAFT',\r\n 'published': 'PUBLISHED',\r\n 'archived': 'ARCHIVED',\r\n 'scheduled': 'SCHEDULED',\r\n 'pending_review': 'PENDING',\r\n };\r\n \r\n // Normaliza o status (lowercase com underscores para uppercase)\r\n const normalized = postStatusMap[status.toLowerCase()] || status.toUpperCase();\r\n \r\n // Traduções específicas para pending_review\r\n if (status.toLowerCase() === 'pending_review') {\r\n const translations = {\r\n 'pt-BR': 'Aguardando Revisão',\r\n 'en-US': 'Pending Review',\r\n 'es-ES': 'Pendiente de Revisión'\r\n };\r\n return translations[locale] || translations['pt-BR'];\r\n }\r\n \r\n return translateStatus(normalized, locale);\r\n}\r\n","/**\r\n * Validation Utilities\r\n *\r\n * Utilitários para validação de dados com suporte a múltiplos idiomas.\r\n * Funções puras, sem dependências externas, prontas para qualquer plataforma.\r\n *\r\n * @module @rainersoft/utils/validation\r\n * @author Rainer Teixeira\r\n */\r\n\r\nimport type { Locale } from '../types';\r\nimport { DEFAULT_LOCALE } from '../types';\r\n\r\n/**\r\n * Interface para resultado de validação\r\n */\r\nexport interface ValidationResult {\r\n isValid: boolean;\r\n errors?: string[];\r\n}\r\n\r\n/**\r\n * Valida email usando regex RFC 5322\r\n *\r\n * @param email - Email para validar\r\n * @param locale - Idioma das mensagens de erro (padrão: 'pt-BR')\r\n * @returns Resultado da validação\r\n *\r\n * @example\r\n * validateEmail('user@example.com') // { isValid: true }\r\n * validateEmail('invalid-email') // { isValid: false, errors: ['Email inválido'] }\r\n */\r\nexport function validateEmail(email: string, locale: Locale = DEFAULT_LOCALE): ValidationResult {\r\n const emailRegex = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\r\n const isValid = emailRegex.test(email);\r\n \r\n if (!isValid) {\r\n const errors = {\r\n 'pt-BR': ['Email inválido'],\r\n 'en-US': ['Invalid email'],\r\n 'es-ES': ['Email inválido']\r\n };\r\n \r\n return {\r\n isValid: false,\r\n errors: errors[locale] || errors['pt-BR']\r\n };\r\n }\r\n \r\n return { isValid: true };\r\n}\r\n\r\n/**\r\n * Valida senha com critérios de segurança\r\n *\r\n * @param password - Senha para validar\r\n * @param options - Opções de validação\r\n * @param locale - Idioma das mensagens de erro\r\n * @returns Resultado da validação\r\n *\r\n * @example\r\n * validatePassword('MySecure123!') // { isValid: true }\r\n * validatePassword('123') // { isValid: false, errors: ['Senha deve ter pelo menos 8 caracteres'] }\r\n */\r\nexport function validatePassword(\r\n password: string, \r\n options: {\r\n minLength?: number;\r\n requireUppercase?: boolean;\r\n requireLowercase?: boolean;\r\n requireNumbers?: boolean;\r\n requireSpecialChars?: boolean;\r\n } = {},\r\n locale: Locale = DEFAULT_LOCALE\r\n): ValidationResult {\r\n const {\r\n minLength = 8,\r\n requireUppercase = true,\r\n requireLowercase = true,\r\n requireNumbers = true,\r\n requireSpecialChars = false\r\n } = options;\r\n \r\n const errors: string[] = [];\r\n \r\n const errorMessages = {\r\n 'pt-BR': {\r\n minLength: `Senha deve ter pelo menos ${minLength} caracteres`,\r\n uppercase: 'Senha deve conter pelo menos uma letra maiúscula',\r\n lowercase: 'Senha deve conter pelo menos uma letra minúscula',\r\n numbers: 'Senha deve conter pelo menos um número',\r\n specialChars: 'Senha deve conter pelo menos um caractere especial'\r\n },\r\n 'en-US': {\r\n minLength: `Password must be at least ${minLength} characters`,\r\n uppercase: 'Password must contain at least one uppercase letter',\r\n lowercase: 'Password must contain at least one lowercase letter',\r\n numbers: 'Password must contain at least one number',\r\n specialChars: 'Password must contain at least one special character'\r\n },\r\n 'es-ES': {\r\n minLength: `La contraseña debe tener al menos ${minLength} caracteres`,\r\n uppercase: 'La contraseña debe contener al menos una letra mayúscula',\r\n lowercase: 'La contraseña debe contener al menos una letra minúscula',\r\n numbers: 'La contraseña debe contener al menos un número',\r\n specialChars: 'La contraseña debe contener al menos un carácter especial'\r\n }\r\n };\r\n \r\n const messages = errorMessages[locale] || errorMessages['pt-BR'];\r\n \r\n if (password.length < minLength) {\r\n errors.push(messages.minLength);\r\n }\r\n \r\n if (requireUppercase && !/[A-Z]/.test(password)) {\r\n errors.push(messages.uppercase);\r\n }\r\n \r\n if (requireLowercase && !/[a-z]/.test(password)) {\r\n errors.push(messages.lowercase);\r\n }\r\n \r\n if (requireNumbers && !/\\d/.test(password)) {\r\n errors.push(messages.numbers);\r\n }\r\n \r\n if (requireSpecialChars && !/[!@#$%^&*(),.?\":{}|<>]/.test(password)) {\r\n errors.push(messages.specialChars);\r\n }\r\n \r\n return {\r\n isValid: errors.length === 0,\r\n errors\r\n };\r\n}\r\n\r\n/**\r\n * Valida URL\r\n *\r\n * @param url - URL para validar\r\n * @param locale - Idioma das mensagens de erro\r\n * @returns Resultado da validação\r\n *\r\n * @example\r\n * validateUrl('https://example.com') // { isValid: true }\r\n * validateUrl('not-a-url') // { isValid: false, errors: ['URL inválida'] }\r\n */\r\nexport function validateUrl(url: string, locale: Locale = DEFAULT_LOCALE): ValidationResult {\r\n try {\r\n new URL(url);\r\n return { isValid: true };\r\n } catch {\r\n const errors = {\r\n 'pt-BR': ['URL inválida'],\r\n 'en-US': ['Invalid URL'],\r\n 'es-ES': ['URL inválida']\r\n };\r\n \r\n return {\r\n isValid: false,\r\n errors: errors[locale] || errors['pt-BR']\r\n };\r\n }\r\n}\r\n\r\n/**\r\n * Valida telefone (formato brasileiro por padrão)\r\n *\r\n * @param phone - Telefone para validar\r\n * @param locale - Idioma das mensagens de erro\r\n * @returns Resultado da validação\r\n *\r\n * @example\r\n * validatePhone('(11) 98765-4321') // { isValid: true }\r\n * validatePhone('123') // { isValid: false, errors: ['Telefone inválido'] }\r\n */\r\nexport function validatePhone(phone: string, locale: Locale = DEFAULT_LOCALE): ValidationResult {\r\n // Regex para telefone brasileiro: (XX) XXXXX-XXXX ou (XX) XXXX-XXXX\r\n const phoneRegex = /^\\(?\\d{2}\\)?[\\s-]?\\d{4,5}[-]?\\d{4}$/;\r\n const isValid = phoneRegex.test(phone);\r\n \r\n if (!isValid) {\r\n const errors = {\r\n 'pt-BR': ['Telefone inválido'],\r\n 'en-US': ['Invalid phone number'],\r\n 'es-ES': ['Teléfono inválido']\r\n };\r\n \r\n return {\r\n isValid: false,\r\n errors: errors[locale] || errors['pt-BR']\r\n };\r\n }\r\n \r\n return { isValid: true };\r\n}\r\n\r\n/**\r\n * Valida username para registro\r\n *\r\n * @param username - Username para validar\r\n * @param options - Opções de validação\r\n * @param locale - Idioma das mensagens de erro\r\n * @returns Resultado da validação\r\n *\r\n * @example\r\n * validateUsername('user123') // { isValid: true }\r\n * validateUsername('us') // { isValid: false, errors: ['Username muito curto'] }\r\n */\r\nexport function validateUsername(\r\n username: string,\r\n options: {\r\n minLength?: number;\r\n maxLength?: number;\r\n allowSpecialChars?: boolean;\r\n } = {},\r\n locale: Locale = DEFAULT_LOCALE\r\n): ValidationResult {\r\n const {\r\n minLength = 3,\r\n maxLength = 20,\r\n allowSpecialChars = false\r\n } = options;\r\n \r\n const errors: string[] = [];\r\n \r\n const errorMessages = {\r\n 'pt-BR': {\r\n minLength: `Username muito curto (mínimo ${minLength} caracteres)`,\r\n maxLength: `Username muito longo (máximo ${maxLength} caracteres)`,\r\n invalidChars: 'Username contém caracteres inválidos'\r\n },\r\n 'en-US': {\r\n minLength: `Username too short (minimum ${minLength} characters)`,\r\n maxLength: `Username too long (maximum ${maxLength} characters)`,\r\n invalidChars: 'Username contains invalid characters'\r\n },\r\n 'es-ES': {\r\n minLength: `Username muy corto (mínimo ${minLength} caracteres)`,\r\n maxLength: `Username muy largo (máximo ${maxLength} caracteres)`,\r\n invalidChars: 'Username contiene caracteres inválidos'\r\n }\r\n };\r\n \r\n const messages = errorMessages[locale] || errorMessages['pt-BR'];\r\n \r\n if (username.length < minLength) {\r\n errors.push(messages.minLength);\r\n }\r\n \r\n if (username.length > maxLength) {\r\n errors.push(messages.maxLength);\r\n }\r\n \r\n const usernameRegex = allowSpecialChars \r\n ? /^[a-zA-Z0-9_]{3,20}$/\r\n : /^[a-zA-Z0-9_]{3,20}$/;\r\n \r\n if (!usernameRegex.test(username)) {\r\n errors.push(messages.invalidChars);\r\n }\r\n \r\n return {\r\n isValid: errors.length === 0,\r\n errors\r\n };\r\n}\r\n\r\n/**\r\n * Valida slug para URLs amigáveis\r\n *\r\n * @param slug - Slug para validar\r\n * @param options - Opções de validação\r\n * @param locale - Idioma das mensagens de erro\r\n * @returns Resultado da validação\r\n *\r\n * @example\r\n * validateSlug('my-post-title') // { isValid: true }\r\n * validateSlug('My Post Title') // { isValid: false, errors: ['Slug inválido'] }\r\n */\r\nexport function validateSlug(\r\n slug: string,\r\n options: {\r\n minLength?: number;\r\n maxLength?: number;\r\n } = {},\r\n locale: Locale = DEFAULT_LOCALE\r\n): ValidationResult {\r\n const {\r\n minLength = 3,\r\n maxLength = 100\r\n } = options;\r\n \r\n const errors: string[] = [];\r\n \r\n const errorMessages = {\r\n 'pt-BR': {\r\n minLength: `Slug muito curto (mínimo ${minLength} caracteres)`,\r\n maxLength: `Slug muito longo (máximo ${maxLength} caracteres)`,\r\n invalidFormat: 'Slug inválido - use apenas letras minúsculas, números e hífens'\r\n },\r\n 'en-US': {\r\n minLength: `Slug too short (minimum ${minLength} characters)`,\r\n maxLength: `Slug too long (maximum ${maxLength} characters)`,\r\n invalidFormat: 'Invalid slug - use only lowercase letters, numbers and hyphens'\r\n },\r\n 'es-ES': {\r\n minLength: `Slug muy corto (mínimo ${minLength} caracteres)`,\r\n maxLength: `Slug muy largo (máximo ${maxLength} caracteres)`,\r\n invalidFormat: 'Slug inválido - use solo letras minúsculas, números y guiones'\r\n }\r\n };\r\n \r\n const messages = errorMessages[locale] || errorMessages['pt-BR'];\r\n \r\n if (slug.length < minLength) {\r\n errors.push(messages.minLength);\r\n }\r\n \r\n if (slug.length > maxLength) {\r\n errors.push(messages.maxLength);\r\n }\r\n \r\n const slugRegex = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;\r\n if (!slugRegex.test(slug)) {\r\n errors.push(messages.invalidFormat);\r\n }\r\n \r\n return {\r\n isValid: errors.length === 0,\r\n errors\r\n };\r\n}\r\n\r\n/**\r\n * Valida texto com comprimento mínimo e máximo\r\n *\r\n * @param text - Texto para validar\r\n * @param options - Opções de validação\r\n * @param locale - Idioma das mensagens de erro\r\n * @returns Resultado da validação\r\n *\r\n * @example\r\n * validateText('Hello', { minLength: 3 }) // { isValid: true }\r\n * validateText('Hi', { minLength: 3 }) // { isValid: false, errors: ['Texto muito curto'] }\r\n */\r\nexport function validateText(\r\n text: string,\r\n options: {\r\n minLength?: number;\r\n maxLength?: number;\r\n fieldName?: string;\r\n } = {},\r\n locale: Locale = DEFAULT_LOCALE\r\n): ValidationResult {\r\n const {\r\n minLength = 0,\r\n maxLength = Infinity,\r\n fieldName = 'Texto'\r\n } = options;\r\n \r\n const errors: string[] = [];\r\n \r\n const errorMessages = {\r\n 'pt-BR': {\r\n minLength: `${fieldName} muito curto (mínimo ${minLength} caracteres)`,\r\n maxLength: `${fieldName} muito longo (máximo ${maxLength} caracteres)`\r\n },\r\n 'en-US': {\r\n minLength: `${fieldName} too short (minimum ${minLength} characters)`,\r\n maxLength: `${fieldName} too long (maximum ${maxLength} characters)`\r\n },\r\n 'es-ES': {\r\n minLength: `${fieldName} muy corto (mínimo ${minLength} caracteres)`,\r\n maxLength: `${fieldName} muy largo (máximo ${maxLength} caracteres)`\r\n }\r\n };\r\n \r\n const messages = errorMessages[locale] || errorMessages['pt-BR'];\r\n \r\n if (text.length < minLength) {\r\n errors.push(messages.minLength);\r\n }\r\n \r\n if (text.length > maxLength) {\r\n errors.push(messages.maxLength);\r\n }\r\n \r\n return {\r\n isValid: errors.length === 0,\r\n errors\r\n };\r\n}\r\n\r\n/**\r\n * Valida mensagem de contato\r\n *\r\n * @param message - Mensagem para validar\r\n * @param options - Opções de validação\r\n * @param locale - Idioma das mensagens de erro\r\n * @returns Resultado da validação\r\n *\r\n * @example\r\n * validateMessage('Olá, gostaria de mais informações') // { isValid: true }\r\n * validateMessage('Oi') // { isValid: false, errors: ['Mensagem muito curta'] }\r\n */\r\nexport function validateMessage(\r\n message: string,\r\n options: {\r\n minLength?: number;\r\n maxLength?: number;\r\n } = {},\r\n locale: Locale = DEFAULT_LOCALE\r\n): ValidationResult {\r\n const {\r\n minLength = 10,\r\n maxLength = 1000\r\n } = options;\r\n \r\n return validateText(message, {\r\n minLength,\r\n maxLength,\r\n fieldName: locale === 'pt-BR' ? 'Mensagem' : locale === 'en-US' ? 'Message' : 'Mensaje'\r\n }, locale);\r\n}\r\n","/**\r\n * DOM Utilities\r\n *\r\n * Utilitários para manipulação do DOM e interações com o browser.\r\n * Funciona em qualquer ambiente browser moderno.\r\n *\r\n * @module @rainersoft/utils/dom\r\n * @author Rainer Teixeira\r\n */\r\n\r\n/**\r\n * Verifica se usuário prefere movimento reduzido (accessibility)\r\n *\r\n * @returns true se preferir movimento reduzido\r\n *\r\n * @example\r\n * if (prefersReducedMotion()) {\r\n * // Desabilitar animações\r\n * }\r\n */\r\nexport function prefersReducedMotion(): boolean {\r\n if (typeof window === 'undefined') return false;\r\n \r\n return window.matchMedia('(prefers-reduced-motion: reduce)').matches;\r\n}\r\n\r\n/**\r\n * Adiciona listener para mudanças na preferência de movimento\r\n *\r\n * @param callback - Função chamada quando a preferência muda\r\n * @returns Função para remover o listener\r\n *\r\n * @example\r\n * const unsubscribe = onReducedMotionChange((prefersReduced) => {\r\n * console.log('Motion preference changed:', prefersReduced);\r\n * });\r\n * \r\n * // Remover listener quando necessário\r\n * unsubscribe();\r\n */\r\nexport function onReducedMotionChange(\r\n callback: (prefersReduced: boolean) => void\r\n): () => void {\r\n if (typeof window === 'undefined') {\r\n return () => {};\r\n }\r\n \r\n const mediaQuery = window.matchMedia('(prefers-reduced-motion: reduce)');\r\n \r\n const handleChange = (e: MediaQueryListEvent) => {\r\n callback(e.matches);\r\n };\r\n \r\n // Adicionar listener (compatibilidade com browsers antigos)\r\n if (mediaQuery.addEventListener) {\r\n mediaQuery.addEventListener('change', handleChange);\r\n } else {\r\n // Fallback para browsers mais antigos\r\n (mediaQuery as any).addListener(handleChange);\r\n }\r\n \r\n // Retornar função de cleanup\r\n return () => {\r\n if (mediaQuery.removeEventListener) {\r\n mediaQuery.removeEventListener('change', handleChange);\r\n } else {\r\n // Fallback para browsers mais antigos\r\n (mediaQuery as any).removeListener(handleChange);\r\n }\r\n };\r\n}\r\n\r\n/**\r\n * Rola a página para uma posição específica\r\n *\r\n * @param x - Posição horizontal (padrão: 0)\r\n * @param y - Posição vertical (padrão: 0)\r\n * @param options - Opções de scroll\r\n *\r\n * @example\r\n * scrollToPosition(0, 500); // Rola para o topo com 500px de margem\r\n * scrollToPosition(0, 0, { smooth: true }); // Scroll suave para o topo\r\n */\r\nexport function scrollToPosition(\r\n x: number = 0,\r\n y: number = 0,\r\n options: {\r\n smooth?: boolean;\r\n behavior?: ScrollBehavior;\r\n } = {}\r\n): void {\r\n if (typeof window === 'undefined') return;\r\n \r\n const { smooth = false, behavior } = options;\r\n \r\n window.scrollTo({\r\n left: x,\r\n top: y,\r\n behavior: behavior || (smooth ? 'smooth' : 'auto')\r\n });\r\n}\r\n\r\n/**\r\n * Rola a página para o topo\r\n *\r\n * @param smooth - Se deve usar scroll suave (padrão: false)\r\n *\r\n * @example\r\n * scrollToTop(); // Scroll instantâneo para o topo\r\n * scrollToTop(true); // Scroll suave para o topo\r\n */\r\nexport function scrollToTop(smooth: boolean = false): void {\r\n scrollToPosition(0, 0, { smooth });\r\n}\r\n\r\n/**\r\n * Rola suavemente para uma posição\r\n *\r\n * @param x - Posição horizontal\r\n * @param y - Posição vertical\r\n * @param duration - Duração da animação em ms (padrão: 300)\r\n *\r\n * @example\r\n * smoothScrollTo(0, 500, 500); // Animação de 500ms para rolar 500px\r\n */\r\nexport function smoothScrollTo(\r\n x: number,\r\n y: number,\r\n duration: number = 300\r\n): void {\r\n if (typeof window === 'undefined') return;\r\n \r\n const startX = window.scrollX;\r\n const startY = window.scrollY;\r\n const distanceX = x - startX;\r\n const distanceY = y - startY;\r\n const startTime = performance.now();\r\n \r\n function animate(currentTime: number): void {\r\n const elapsed = currentTime - startTime;\r\n const progress = Math.min(elapsed / duration, 1);\r\n \r\n // Easing function (ease-out)\r\n const easeProgress = 1 - Math.pow(1 - progress, 3);\r\n \r\n const currentX = startX + (distanceX * easeProgress);\r\n const currentY = startY + (distanceY * easeProgress);\r\n \r\n window.scrollTo(currentX, currentY);\r\n \r\n if (progress < 1) {\r\n requestAnimationFrame(animate);\r\n }\r\n }\r\n \r\n requestAnimationFrame(animate);\r\n}\r\n\r\n/**\r\n * Rola para um elemento específico\r\n *\r\n * @param element - Elemento ou seletor CSS\r\n * @param options - Opções de scroll\r\n *\r\n * @example\r\n * scrollToElement('#my-element'); // Scroll instantâneo\r\n * scrollToElement('.section', { smooth: true, offset: 100 }); // Scroll suave com offset\r\n */\r\nexport function scrollToElement(\r\n element: string | Element,\r\n options: {\r\n smooth?: boolean;\r\n offset?: number;\r\n behavior?: ScrollBehavior;\r\n } = {}\r\n): void {\r\n if (typeof window === 'undefined') return;\r\n \r\n const { smooth = false, offset = 0, behavior } = options;\r\n \r\n let targetElement: Element | null;\r\n \r\n if (typeof element === 'string') {\r\n targetElement = document.querySelector(element);\r\n } else {\r\n targetElement = element;\r\n }\r\n \r\n if (!targetElement) return;\r\n \r\n const rect = targetElement.getBoundingClientRect();\r\n const absoluteY = rect.top + window.scrollY - offset;\r\n \r\n window.scrollTo({\r\n left: 0,\r\n top: absoluteY,\r\n behavior: behavior || (smooth ? 'smooth' : 'auto')\r\n });\r\n}\r\n\r\n/**\r\n * Verifica se elemento está visível na viewport\r\n *\r\n * @param element - Elemento ou seletor CSS\r\n * @param threshold - Limiar de visibilidade (0 a 1, padrão: 0)\r\n * @returns true se elemento estiver visível\r\n *\r\n * @example\r\n * isElementVisible('#my-element'); // true se elemento estiver na viewport\r\n * isElementVisible('.section', 0.5); // true se 50% do elemento estiver visível\r\n */\r\nexport function isElementVisible(\r\n element: string | Element,\r\n threshold: number = 0\r\n): boolean {\r\n if (typeof window === 'undefined') return false;\r\n \r\n let targetElement: Element | null;\r\n \r\n if (typeof element === 'string') {\r\n targetElement = document.querySelector(element);\r\n } else {\r\n targetElement = element;\r\n }\r\n \r\n if (!targetElement) return false;\r\n \r\n const rect = targetElement.getBoundingClientRect();\r\n const windowHeight = window.innerHeight;\r\n const windowWidth = window.innerWidth;\r\n \r\n const verticalThreshold = windowHeight * threshold;\r\n const horizontalThreshold = windowWidth * threshold;\r\n \r\n const isVisibleVertically = \r\n rect.bottom >= verticalThreshold && \r\n rect.top <= windowHeight - verticalThreshold;\r\n \r\n const isVisibleHorizontally = \r\n rect.right >= horizontalThreshold && \r\n rect.left <= windowWidth - horizontalThreshold;\r\n \r\n return isVisibleVertically && isVisibleHorizontally;\r\n}\r\n\r\n/**\r\n * Obtém a posição de um elemento em relação ao documento\r\n *\r\n * @param element - Elemento ou seletor CSS\r\n * @returns Posição { x, y } ou null se elemento não for encontrado\r\n *\r\n * @example\r\n * const position = getElementPosition('#my-element');\r\n * console.log('X:', position.x, 'Y:', position.y);\r\n */\r\nexport function getElementPosition(\r\n element: string | Element\r\n): { x: number; y: number } | null {\r\n if (typeof window === 'undefined') return null;\r\n \r\n let targetElement: Element | null;\r\n \r\n if (typeof element === 'string') {\r\n targetElement = document.querySelector(element);\r\n } else {\r\n targetElement = element;\r\n }\r\n \r\n if (!targetElement) return null;\r\n \r\n const rect = targetElement.getBoundingClientRect();\r\n \r\n return {\r\n x: rect.left + window.scrollX,\r\n y: rect.top + window.scrollY\r\n };\r\n}\r\n\r\n/**\r\n * Verifica se está em dispositivo móvel\r\n *\r\n * @returns true se for dispositivo móvel\r\n *\r\n * @example\r\n * if (isMobile()) {\r\n * // Aplicar layout mobile\r\n * }\r\n */\r\nexport function isMobile(): boolean {\r\n if (typeof window === 'undefined') return false;\r\n \r\n // Verificar User Agent\r\n const isMobileUA = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(\r\n navigator.userAgent\r\n );\r\n \r\n // Verificar tamanho de tela (fallback)\r\n const isMobileScreen = window.innerWidth <= 768;\r\n \r\n return isMobileUA || isMobileScreen;\r\n}\r\n\r\n/**\r\n * Verifica se está em modo escuro\r\n *\r\n * @returns true se o sistema preferir modo escuro\r\n *\r\n * @example\r\n * if (isDarkMode()) {\r\n * // Aplicar tema escuro\r\n * }\r\n */\r\nexport function isDarkMode(): boolean {\r\n if (typeof window === 'undefined') return false;\r\n \r\n return window.matchMedia('(prefers-color-scheme: dark)').matches;\r\n}\r\n\r\n/**\r\n * Adiciona listener para mudanças no tema do sistema\r\n *\r\n * @param callback - Função chamada quando o tema muda\r\n * @returns Função para remover o listener\r\n *\r\n * @example\r\n * const unsubscribe = onDarkModeChange((isDark) => {\r\n * console.log('Theme changed:', isDark ? 'dark' : 'light');\r\n * });\r\n */\r\nexport function onDarkModeChange(\r\n callback: (isDark: boolean) => void\r\n): () => void {\r\n if (typeof window === 'undefined') {\r\n return () => {};\r\n }\r\n \r\n const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');\r\n \r\n const handleChange = (e: MediaQueryListEvent) => {\r\n callback(e.matches);\r\n };\r\n \r\n // Adicionar listener\r\n if (mediaQuery.addEventListener) {\r\n mediaQuery.addEventListener('change', handleChange);\r\n } else {\r\n (mediaQuery as any).addListener(handleChange);\r\n }\r\n \r\n // Retornar função de cleanup\r\n return () => {\r\n if (mediaQuery.removeEventListener) {\r\n mediaQuery.removeEventListener('change', handleChange);\r\n } else {\r\n (mediaQuery as any).removeListener(handleChange);\r\n }\r\n };\r\n}\r\n\r\n/**\r\n * Copia texto para a área de transferência\r\n *\r\n * @param text - Texto para copiar\r\n * @returns Promise que resolve para true se sucesso\r\n *\r\n * @example\r\n * copyToClipboard('Hello World').then(success => {\r\n * if (success) {\r\n * console.log('Texto copiado!');\r\n * }\r\n * });\r\n */\r\nexport async function copyToClipboard(text: string): Promise<boolean> {\r\n if (typeof window === 'undefined') return false;\r\n \r\n try {\r\n // Tentar usar a API moderna\r\n if (navigator.clipboard && window.isSecureContext) {\r\n await navigator.clipboard.writeText(text);\r\n return true;\r\n }\r\n \r\n // Fallback para browsers mais antigos\r\n const textArea = document.createElement('textarea');\r\n textArea.value = text;\r\n textArea.style.position = 'fixed';\r\n textArea.style.left = '-999999px';\r\n textArea.style.top = '-999999px';\r\n document.body.appendChild(textArea);\r\n textArea.focus();\r\n textArea.select();\r\n \r\n const result = document.execCommand('copy');\r\n document.body.removeChild(textArea);\r\n \r\n return result;\r\n } catch {\r\n return false;\r\n }\r\n}\r\n\r\n/**\r\n * Baixa um arquivo como blob\r\n *\r\n * @param blob - Blob para baixar\r\n * @param filename - Nome do arquivo\r\n *\r\n * @example\r\n * downloadFile(new Blob(['Hello World'], { type: 'text/plain' }), 'hello.txt');\r\n */\r\nexport function downloadFile(blob: Blob, filename: string): void {\r\n if (typeof window === 'undefined') return;\r\n \r\n const url = URL.createObjectURL(blob);\r\n const link = document.createElement('a');\r\n link.href = url;\r\n link.download = filename;\r\n document.body.appendChild(link);\r\n link.click();\r\n document.body.removeChild(link);\r\n URL.revokeObjectURL(url);\r\n}\r\n","/**\r\n * Stats Formatting Utilities\r\n *\r\n * Utilitários universais para formatação de estatísticas e números.\r\n *\r\n * @module @rainersoft/utils/stats\r\n * @author Rainer Teixeira\r\n * @version 1.0.0\r\n */\r\n\r\n/**\r\n * Formata número grande com abreviação (1.5k, 2.3M, etc)\r\n *\r\n * @param num - Número para formatar\r\n * @returns String formatada com abreviação\r\n *\r\n * @example\r\n * ```ts\r\n * formatNumber(1500) // '1.5k'\r\n * formatNumber(2500000) // '2.5M'\r\n * formatNumber(999) // '999'\r\n * ```\r\n */\r\nexport function formatNumber(num: number): string {\r\n if (num >= 1000000) {\r\n return (num / 1000000).toFixed(1) + 'M';\r\n }\r\n if (num >= 1000) {\r\n return (num / 1000).toFixed(1) + 'k';\r\n }\r\n return num.toString();\r\n}\r\n\r\n/**\r\n * Calcula percentual de mudança entre dois valores\r\n *\r\n * @param current - Valor atual\r\n * @param previous - Valor anterior\r\n * @returns Percentual de mudança (arredondado)\r\n *\r\n * @example\r\n * ```ts\r\n * calculateChange(150, 100) // 50\r\n * calculateChange(80, 100) // -20\r\n * calculateChange(100, 0) // 100\r\n * ```\r\n */\r\nexport function calculateChange(current: number, previous: number): number {\r\n if (previous === 0) return 100;\r\n return Math.round(((current - previous) / previous) * 100);\r\n}\r\n\r\n/**\r\n * Formata percentual com sinal\r\n *\r\n * @param value - Valor do percentual\r\n * @param options - Opções de formatação\r\n * @returns String formatada com sinal e símbolo\r\n *\r\n * @example\r\n * ```ts\r\n * formatPercentage(25) // '+25%'\r\n * formatPercentage(-10) // '-10%'\r\n * formatPercentage(0) // '0%'\r\n * ```\r\n */\r\nexport function formatPercentage(\r\n value: number,\r\n options: { showSign?: boolean; decimals?: number } = {}\r\n): string {\r\n const { showSign = true, decimals = 0 } = options;\r\n \r\n const sign = showSign && value > 0 ? '+' : '';\r\n const formattedValue = value.toFixed(decimals);\r\n \r\n return `${sign}${formattedValue}%`;\r\n}\r\n\r\n/**\r\n * Gera dados de exemplo para gráficos\r\n *\r\n * @param days - Número de dias para gerar dados\r\n * @param locale - Idioma para formatação de datas\r\n * @returns Array de dados mock\r\n *\r\n * @example\r\n * ```ts\r\n * const data = generateMockChartData(7);\r\n * // [\r\n * // { date: '01/12', views: 1234, uniqueViews: 890, likes: 67, comments: 23 },\r\n * // ...\r\n * // ]\r\n * ```\r\n */\r\nexport function generateMockChartData(\r\n days: number,\r\n locale: string = 'pt-BR'\r\n): Array<Record<string, any>> {\r\n const data = [];\r\n const now = new Date();\r\n\r\n for (let i = days - 1; i >= 0; i--) {\r\n const date = new Date(now);\r\n date.setDate(date.getDate() - i);\r\n\r\n data.push({\r\n date: date.toLocaleDateString(locale, {\r\n day: '2-digit',\r\n month: '2-digit',\r\n }),\r\n views: Math.floor(Math.random() * 1000) + 500,\r\n uniqueViews: Math.floor(Math.random() * 700) + 300,\r\n likes: Math.floor(Math.random() * 100) + 50,\r\n comments: Math.floor(Math.random() * 50) + 10,\r\n shares: Math.floor(Math.random() * 30) + 5,\r\n });\r\n }\r\n\r\n return data;\r\n}\r\n\r\n/**\r\n * Agrupa dados por período (dia, semana, mês)\r\n *\r\n * @param data - Array de dados para agrupar\r\n * @param period - Período de agrupamento\r\n * @param dateField - Campo de data nos objetos\r\n * @returns Array de dados agrupados\r\n *\r\n * @example\r\n * ```ts\r\n * const grouped = groupDataByPeriod(data, 'week', 'date');\r\n * ```\r\n */\r\nexport function groupDataByPeriod<T extends Record<string, any>>(\r\n data: T[],\r\n // period: 'day' | 'week' | 'month' = 'day', // Pode ser usado futuramente para agrupamento\r\n // dateField: keyof T = 'date' as keyof T\r\n): T[] {\r\n // Implementação simplificada - pode ser expandida\r\n // Por enquanto, retorna os dados originais\r\n return data;\r\n}\r\n\r\n/**\r\n * Calcula médias móveis para suavizar dados\r\n *\r\n * @param data - Array de valores numéricos\r\n * @param window - Tamanho da janela de média móvel\r\n * @returns Array com médias móveis\r\n *\r\n * @example\r\n * ```ts\r\n * const smoothed = calculateMovingAverage([1, 2, 3, 4, 5], 3);\r\n * // [2, 3, 4] (médias de [1,2,3], [2,3,4], [3,4,5])\r\n * ```\r\n */\r\nexport function calculateMovingAverage(data: number[], window: number): number[] {\r\n const result: number[] = [];\r\n \r\n for (let i = window - 1; i < data.length; i++) {\r\n const sum = data.slice(i - window + 1, i + 1).reduce((a, b) => a + b, 0);\r\n result.push(sum / window);\r\n }\r\n \r\n return result;\r\n}\r\n\r\n/**\r\n * Encontra valor máximo e mínimo em array de objetos\r\n *\r\n * @param data - Array de objetos\r\n * @param field - Campo para analisar\r\n * @returns Objeto com min e max\r\n *\r\n * @example\r\n * ```ts\r\n * const { min, max } = findMinMax(data, 'views');\r\n * ```\r\n */\r\nexport function findMinMax<T extends Record<string, any>>(\r\n data: T[],\r\n field: keyof T\r\n): { min: number; max: number } {\r\n const values = data.map(item => Number(item[field]) || 0);\r\n \r\n return {\r\n min: Math.min(...values),\r\n max: Math.max(...values)\r\n };\r\n}\r\n","/**\r\n * Auth Utilities\r\n *\r\n * Utilitários para gerenciamento de tokens de autenticação.\r\n * Funções para armazenar, recuperar e remover tokens JWT do localStorage.\r\n *\r\n * @module @rainersoft/utils/auth\r\n * @author Rainer Teixeira\r\n * @version 1.0.0\r\n */\r\n\r\nconst TOKEN_KEY = 'auth_token';\r\nconst REFRESH_TOKEN_KEY = 'refresh_token';\r\n\r\n/**\r\n * Obtém o token de acesso armazenado\r\n * \r\n * @returns string | null - Token JWT ou null se não encontrado\r\n * \r\n * @example\r\n * ```ts\r\n * const token = getToken();\r\n * if (token) {\r\n * // Usar token na requisição\r\n * }\r\n * ```\r\n */\r\nexport const getToken = (): string | null => {\r\n if (typeof window === 'undefined') {\r\n return null;\r\n }\r\n \r\n return localStorage.getItem(TOKEN_KEY);\r\n};\r\n\r\n/**\r\n * Define o token de acesso\r\n * \r\n * @param token - Token JWT a ser armazenado\r\n * \r\n * @example\r\n * ```ts\r\n * setToken('eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...');\r\n * ```\r\n */\r\nexport const setToken = (token: string): void => {\r\n if (typeof window === 'undefined') {\r\n return;\r\n }\r\n \r\n localStorage.setItem(TOKEN_KEY, token);\r\n};\r\n\r\n/**\r\n * Obtém o refresh token armazenado\r\n * \r\n * @returns string | null - Refresh token ou null se não encontrado\r\n * \r\n * @example\r\n * ```ts\r\n * const refreshToken = getRefreshToken();\r\n * ```\r\n */\r\nexport const getRefreshToken = (): string | null => {\r\n if (typeof window === 'undefined') {\r\n return null;\r\n }\r\n \r\n return localStorage.getItem(REFRESH_TOKEN_KEY);\r\n};\r\n\r\n/**\r\n * Define o refresh token\r\n * \r\n * @param refreshToken - Refresh token a ser armazenado\r\n * \r\n * @example\r\n * ```ts\r\n * setRefreshToken('refresh_token_here');\r\n * ```\r\n */\r\nexport const setRefreshToken = (refreshToken: string): void => {\r\n if (typeof window === 'undefined') {\r\n return;\r\n }\r\n \r\n localStorage.setItem(REFRESH_TOKEN_KEY, refreshToken);\r\n};\r\n\r\n/**\r\n * Remove todos os tokens armazenados\r\n * \r\n * @example\r\n * ```ts\r\n * // Logout do usuário\r\n * removeToken();\r\n * ```\r\n */\r\nexport const removeToken = (): void => {\r\n if (typeof window === 'undefined') {\r\n return;\r\n }\r\n \r\n localStorage.removeItem(TOKEN_KEY);\r\n localStorage.removeItem(REFRESH_TOKEN_KEY);\r\n};\r\n\r\n/**\r\n * Verifica se há um token válido armazenado\r\n * \r\n * @returns boolean - True se token existe\r\n * \r\n * @example\r\n * ```ts\r\n * if (hasToken()) {\r\n * // Usuário autenticado\r\n * }\r\n * ```\r\n */\r\nexport const hasToken = (): boolean => {\r\n return !!getToken();\r\n};\r\n\r\n/**\r\n * Obtém os tokens como objeto\r\n * \r\n * @returns object - Com accessToken e refreshToken\r\n * \r\n * @example\r\n * ```ts\r\n * const { accessToken, refreshToken } = getTokens();\r\n * ```\r\n */\r\nexport const getTokens = (): {\r\n accessToken: string | null;\r\n refreshToken: string | null;\r\n} => {\r\n return {\r\n accessToken: getToken(),\r\n refreshToken: getRefreshToken(),\r\n };\r\n};\r\n\r\n/**\r\n * Define ambos os tokens de uma vez\r\n * \r\n * @param accessToken - Token de acesso\r\n * @param refreshToken - Token de refresh\r\n * \r\n * @example\r\n * ```ts\r\n * setTokens({\r\n * accessToken: 'access_token_here',\r\n * refreshToken: 'refresh_token_here'\r\n * });\r\n * ```\r\n */\r\nexport const setTokens = ({\r\n accessToken,\r\n refreshToken,\r\n}: {\r\n accessToken: string;\r\n refreshToken: string;\r\n}): void => {\r\n setToken(accessToken);\r\n setRefreshToken(refreshToken);\r\n};\r\n","/**\r\n * Search Utilities\r\n *\r\n * Utilitários genéricos para busca e filtro de conteúdo.\r\n * Funções puras, agnósticas de domínio e framework.\r\n *\r\n * @module @rainersoft/utils/search\r\n * @author Rainer Teixeira\r\n * @version 1.0.0\r\n */\r\n\r\n/**\r\n * Opções de busca\r\n */\r\nexport interface SearchOptions {\r\n /** Campos a buscar (padrão: ['title', 'description', 'content', 'tags']) */\r\n fields?: string[];\r\n /** Case sensitive (padrão: false) */\r\n caseSensitive?: boolean;\r\n /** Busca exata (padrão: false) */\r\n exactMatch?: boolean;\r\n}\r\n\r\n/**\r\n * Busca genérica em array de objetos\r\n *\r\n * Função de busca client-side para arrays de objetos genéricos.\r\n * Busca em múltiplos campos configuráveis.\r\n *\r\n * @param query - Termo de busca\r\n * @param content - Array de objetos a buscar\r\n * @param options - Opções de busca\r\n * @returns Array filtrado com resultados\r\n *\r\n * @example\r\n * ```ts\r\n * const posts = [\r\n * { title: 'Next.js Guide', description: 'Learn Next.js' },\r\n * { title: 'React Basics', description: 'React fundamentals' }\r\n * ];\r\n * \r\n * searchContent('next', posts) // [{ title: 'Next.js Guide', ... }]\r\n * searchContent('react', posts, { fields: ['title'] }) // [{ title: 'React Basics', ... }]\r\n * ```\r\n */\r\nexport function searchContent<T extends Record<string, any>>(\r\n query: string,\r\n content: T[],\r\n options: SearchOptions = {}\r\n): T[] {\r\n if (!query.trim()) return content;\r\n \r\n const {\r\n fields = ['title', 'description', 'content', 'tags'],\r\n caseSensitive = false,\r\n exactMatch = false\r\n } = options;\r\n \r\n const searchQuery = caseSensitive ? query : query.toLowerCase();\r\n \r\n return content.filter(item => {\r\n return fields.some(field => {\r\n const value = item[field];\r\n \r\n if (!value) return false;\r\n \r\n // Se for array (ex: tags)\r\n if (Array.isArray(value)) {\r\n return value.some(v => {\r\n const strValue = caseSensitive ? String(v) : String(v).toLowerCase();\r\n return exactMatch \r\n ? strValue === searchQuery \r\n : strValue.includes(searchQuery);\r\n });\r\n }\r\n \r\n // Se for string\r\n const strValue = caseSensitive ? String(value) : String(value).toLowerCase();\r\n return exactMatch \r\n ? strValue === searchQuery \r\n : strValue.includes(searchQuery);\r\n });\r\n });\r\n}\r\n\r\n/**\r\n * Busca com score de relevância\r\n *\r\n * Retorna resultados ordenados por relevância baseado em:\r\n * - Correspondência no título (peso maior)\r\n * - Correspondência na descrição\r\n * - Correspondência em outros campos\r\n *\r\n * @param query - Termo de busca\r\n * @param content - Array de objetos a buscar\r\n * @param options - Opções de busca\r\n * @returns Array ordenado por relevância\r\n *\r\n * @example\r\n * ```ts\r\n * const results = searchWithScore('next', posts);\r\n * // Resultados com título contendo 'next' aparecem primeiro\r\n * ```\r\n */\r\nexport function searchWithScore<T extends Record<string, any>>(\r\n query: string,\r\n content: T[],\r\n options: SearchOptions = {}\r\n): T[] {\r\n if (!query.trim()) return content;\r\n \r\n const {\r\n fields = ['title', 'description', 'content', 'tags'],\r\n caseSensitive = false\r\n } = options;\r\n \r\n const searchQuery = caseSensitive ? query : query.toLowerCase();\r\n \r\n // Calcula score para cada item\r\n const scored = content.map(item => {\r\n let score = 0;\r\n \r\n fields.forEach((field, index) => {\r\n const value = item[field];\r\n if (!value) return;\r\n \r\n const weight = fields.length - index; // Primeiro campo tem maior peso\r\n \r\n if (Array.isArray(value)) {\r\n const matches = value.filter(v => {\r\n const strValue = caseSensitive ? String(v) : String(v).toLowerCase();\r\n return strValue.includes(searchQuery);\r\n }).length;\r\n score += matches * weight;\r\n } else {\r\n const strValue = caseSensitive ? String(value) : String(value).toLowerCase();\r\n if (strValue.includes(searchQuery)) {\r\n score += weight;\r\n // Bonus se for match exato\r\n if (strValue === searchQuery) {\r\n score += weight * 2;\r\n }\r\n }\r\n }\r\n });\r\n \r\n return { item, score };\r\n });\r\n \r\n // Filtra apenas com score > 0 e ordena\r\n return scored\r\n .filter(({ score }) => score > 0)\r\n .sort((a, b) => b.score - a.score)\r\n .map(({ item }) => item);\r\n}\r\n\r\n/**\r\n * Busca fuzzy (tolerante a erros de digitação)\r\n *\r\n * Usa distância de Levenshtein simplificada para encontrar\r\n * correspondências aproximadas.\r\n *\r\n * @param query - Termo de busca\r\n * @param content - Array de objetos a buscar\r\n * @param options - Opções de busca + threshold\r\n * @returns Array com correspondências aproximadas\r\n *\r\n * @example\r\n * ```ts\r\n * fuzzySearch('nxt', posts) // Encontra 'next'\r\n * fuzzySearch('raect', posts) // Encontra 'react'\r\n * ```\r\n */\r\nexport function fuzzySearch<T extends Record<string, any>>(\r\n query: string,\r\n content: T[],\r\n options: SearchOptions & { threshold?: number } = {}\r\n): T[] {\r\n if (!query.trim()) return content;\r\n \r\n const {\r\n fields = ['title', 'description'],\r\n caseSensitive = false,\r\n threshold = 0.6 // Similaridade mínima (0-1)\r\n } = options;\r\n \r\n const searchQuery = caseSensitive ? query : query.toLowerCase();\r\n \r\n return content.filter(item => {\r\n return fields.some(field => {\r\n const value = item[field];\r\n if (!value) return false;\r\n \r\n const strValue = caseSensitive ? String(value) : String(value).toLowerCase();\r\n const similarity = calculateSimilarity(searchQuery, strValue);\r\n \r\n return similarity >= threshold;\r\n });\r\n });\r\n}\r\n\r\n/**\r\n * Calcula similaridade entre duas strings (0-1)\r\n * Usa algoritmo de Jaro-Winkler simplificado\r\n */\r\nfunction calculateSimilarity(str1: string, str2: string): number {\r\n if (str1 === str2) return 1;\r\n if (str1.length === 0 || str2.length === 0) return 0;\r\n \r\n // Busca substring\r\n if (str2.includes(str1)) return 0.8;\r\n \r\n // Calcula caracteres em comum\r\n const common = str1.split('').filter(char => str2.includes(char)).length;\r\n const similarity = common / Math.max(str1.length, str2.length);\r\n \r\n return similarity;\r\n}\r\n","/**\r\n * Hook para avaliar e monitorar força de senha\r\n * \r\n * @param {string} password - Senha a ser avaliada\r\n * @param {Object} options - Opções de configuração\r\n * @param {number} options.minLength - Comprimento mínimo (default: 8)\r\n * @param {boolean} options.requireUppercase - Exige letra maiúscula (default: true)\r\n * @param {boolean} options.requireLowercase - Exige letra minúscula (default: true)\r\n * @param {boolean} options.requireNumbers - Exige números (default: true)\r\n * @param {boolean} options.requireSpecialChars - Exige caracteres especiais (default: true)\r\n * @param {string[]} options.customPatterns - Padrões personalizados para validação\r\n * @param {Object} options.labels - Rótulos customizados (para i18n)\r\n * \r\n * @returns {Object} Objeto com força da senha e validações\r\n */\r\n\r\nimport React from 'react';\r\n\r\nexport function usePasswordStrength(\r\n password: string, \r\n options: {\r\n minLength?: number;\r\n requireUppercase?: boolean;\r\n requireLowercase?: boolean;\r\n requireNumbers?: boolean;\r\n requireSpecialChars?: boolean;\r\n customPatterns?: string[];\r\n labels?: {\r\n veryWeak?: string;\r\n weak?: string;\r\n fair?: string;\r\n good?: string;\r\n strong?: string;\r\n enterPassword?: string;\r\n useMinLength?: string;\r\n addUppercase?: string;\r\n addLowercase?: string;\r\n addNumbers?: string;\r\n addSpecialChars?: string;\r\n avoidRepeating?: string;\r\n avoidCommon?: string;\r\n };\r\n } = {}\r\n) {\r\n const {\r\n minLength = 8,\r\n requireUppercase = true,\r\n requireLowercase = true,\r\n requireNumbers = true,\r\n requireSpecialChars = true,\r\n customPatterns = [],\r\n labels = {}\r\n } = options;\r\n\r\n // Rótulos padrão em inglês\r\n const defaultLabels = {\r\n veryWeak: 'Very Weak',\r\n weak: 'Weak',\r\n fair: 'Fair',\r\n good: 'Good',\r\n strong: 'Strong',\r\n enterPassword: 'Enter a password',\r\n useMinLength: `Use at least ${minLength} characters`,\r\n addUppercase: 'Add uppercase letters',\r\n addLowercase: 'Add lowercase letters',\r\n addNumbers: 'Add numbers',\r\n addSpecialChars: 'Add special characters (!@#$%)',\r\n avoidRepeating: 'Avoid repeating characters',\r\n avoidCommon: 'Avoid common passwords or obvious patterns'\r\n };\r\n\r\n // Mesclar rótulos padrão com customizados\r\n const finalLabels = { ...defaultLabels, ...labels };\r\n\r\n // Calcular força da senha\r\n const strength = React.useMemo(() => {\r\n if (!password) return 0;\r\n\r\n let score = 0;\r\n const length = password.length;\r\n\r\n // Pontuação por comprimento\r\n if (length >= minLength) score += 25;\r\n if (length >= 12) score += 15;\r\n if (length >= 16) score += 10;\r\n\r\n // Pontuação por variedade de caracteres\r\n if (/[a-z]/.test(password) && requireLowercase) score += 15;\r\n if (/[A-Z]/.test(password) && requireUppercase) score += 15;\r\n if (/[0-9]/.test(password) && requireNumbers) score += 15;\r\n if (/[^a-zA-Z0-9]/.test(password) && requireSpecialChars) score += 20;\r\n\r\n // Verificar padrões personalizados\r\n customPatterns.forEach(pattern => {\r\n if (new RegExp(pattern).test(password)) {\r\n score += 5;\r\n }\r\n });\r\n\r\n // Bônus por complexidade adicional\r\n if (/(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[^a-zA-Z0-9])/.test(password)) {\r\n score += 10;\r\n }\r\n\r\n // Penalizar senhas comuns ou padrões fracos\r\n const commonPatterns = [\r\n /^123456/,\r\n /password/i,\r\n /qwerty/i,\r\n /admin/i,\r\n /abc123/i,\r\n /^(.)\\1+$/, // Caracteres repetidos\r\n /^(?:[a-z]+|[A-Z]+|[0-9]+)$/ // Apenas um tipo de caractere\r\n ];\r\n\r\n commonPatterns.forEach(pattern => {\r\n if (pattern.test(password)) {\r\n score = Math.max(0, score - 20);\r\n }\r\n });\r\n\r\n return Math.min(100, Math.max(0, score));\r\n }, [password, minLength, requireUppercase, requireLowercase, requireNumbers, requireSpecialChars, customPatterns]);\r\n\r\n // Obter nível da senha\r\n const level = React.useMemo(() => {\r\n if (strength < 20) return 'very-weak';\r\n if (strength < 40) return 'weak';\r\n if (strength < 60) return 'fair';\r\n if (strength < 80) return 'good';\r\n return 'strong';\r\n }, [strength]);\r\n\r\n // Obter cor para indicador visual\r\n const color = React.useMemo(() => {\r\n switch (level) {\r\n case 'very-weak': return '#ef4444'; // red-500\r\n case 'weak': return '#f97316'; // orange-500\r\n case 'fair': return '#eab308'; // yellow-500\r\n case 'good': return '#22c55e'; // green-500\r\n case 'strong': return '#059669'; // emerald-600\r\n default: return '#6b7280'; // gray-500\r\n }\r\n }, [level]);\r\n\r\n // Obter texto descritivo\r\n const label = React.useMemo(() => {\r\n switch (level) {\r\n case 'very-weak': return finalLabels.veryWeak;\r\n case 'weak': return finalLabels.weak;\r\n case 'fair': return finalLabels.fair;\r\n case 'good': return finalLabels.good;\r\n case 'strong': return finalLabels.strong;\r\n default: return finalLabels.enterPassword;\r\n }\r\n }, [level, finalLabels]);\r\n\r\n // Validações específicas\r\n const validations = React.useMemo(() => {\r\n return {\r\n hasMinLength: password.length >= minLength,\r\n hasUppercase: !requireUppercase || /[A-Z]/.test(password),\r\n hasLowercase: !requireLowercase || /[a-z]/.test(password),\r\n hasNumbers: !requireNumbers || /[0-9]/.test(password),\r\n hasSpecialChars: !requireSpecialChars || /[^a-zA-Z0-9]/.test(password),\r\n noRepeatingChars: !/^(.)\\1+$/.test(password),\r\n noCommonPatterns: !(/123456|password|qwerty|admin|abc123/i).test(password)\r\n };\r\n }, [password, minLength, requireUppercase, requireLowercase, requireNumbers, requireSpecialChars]);\r\n\r\n // Verificar se senha atende todos os requisitos\r\n const isValid = React.useMemo(() => {\r\n return Object.values(validations).every(Boolean);\r\n }, [validations]);\r\n\r\n // Obter sugestões de melhoria\r\n const suggestions = React.useMemo(() => {\r\n const suggestions: string[] = [];\r\n\r\n if (!validations.hasMinLength) {\r\n suggestions.push(finalLabels.useMinLength);\r\n }\r\n if (!validations.hasUppercase && requireUppercase) {\r\n suggestions.push(finalLabels.addUppercase);\r\n }\r\n if (!validations.hasLowercase && requireLowercase) {\r\n suggestions.push(finalLabels.addLowercase);\r\n }\r\n if (!validations.hasNumbers && requireNumbers) {\r\n suggestions.push(finalLabels.addNumbers);\r\n }\r\n if (!validations.hasSpecialChars && requireSpecialChars) {\r\n suggestions.push(finalLabels.addSpecialChars);\r\n }\r\n if (!validations.noRepeatingChars) {\r\n suggestions.push(finalLabels.avoidRepeating);\r\n }\r\n if (!validations.noCommonPatterns) {\r\n suggestions.push(finalLabels.avoidCommon);\r\n }\r\n\r\n return suggestions;\r\n }, [validations, finalLabels, minLength, requireUppercase, requireLowercase, requireNumbers, requireSpecialChars]);\r\n\r\n // Gerar senha forte aleatória (opcional)\r\n const generateStrongPassword = React.useCallback((length = 16) => {\r\n const uppercase = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';\r\n const lowercase = 'abcdefghijklmnopqrstuvwxyz';\r\n const numbers = '0123456789';\r\n const special = '!@#$%^&*()_+-=[]{}|;:,.<>?';\r\n \r\n let chars = lowercase;\r\n if (requireUppercase) chars += uppercase;\r\n if (requireNumbers) chars += numbers;\r\n if (requireSpecialChars) chars += special;\r\n \r\n let password = '';\r\n \r\n // Garantir pelo menos um de cada tipo requerido\r\n if (requireLowercase) password += lowercase[Math.floor(Math.random() * lowercase.length)];\r\n if (requireUppercase) password += uppercase[Math.floor(Math.random() * uppercase.length)];\r\n if (requireNumbers) password += numbers[Math.floor(Math.random() * numbers.length)];\r\n if (requireSpecialChars) password += special[Math.floor(Math.random() * special.length)];\r\n \r\n // Preencher o resto\r\n for (let i = password.length; i < length; i++) {\r\n password += chars[Math.floor(Math.random() * chars.length)];\r\n }\r\n \r\n // Embaralhar\r\n return password.split('').sort(() => Math.random() - 0.5).join('');\r\n }, [requireUppercase, requireLowercase, requireNumbers, requireSpecialChars]);\r\n\r\n return {\r\n // Métricas principais\r\n strength,\r\n level,\r\n color,\r\n label,\r\n isValid,\r\n \r\n // Validações detalhadas\r\n validations,\r\n \r\n // Feedback ao usuário\r\n suggestions,\r\n \r\n // Utilitários\r\n generateStrongPassword,\r\n \r\n // Estados convenientes\r\n isVeryWeak: level === 'very-weak',\r\n isWeak: level === 'weak',\r\n isFair: level === 'fair',\r\n isGood: level === 'good',\r\n isStrong: level === 'strong'\r\n };\r\n}\r\n","/**\r\n * Helpers pt-BR\r\n *\r\n * Funções pré-configuradas para português brasileiro.\r\n * Facilitam o uso sem precisar passar locale em cada chamada.\r\n *\r\n * @module @rainersoft/utils/pt-br\r\n * @author Rainer Teixeira\r\n */\r\n\r\nimport {\r\n formatDate as formatDateBase,\r\n formatDateTime as formatDateTimeBase,\r\n formatRelativeDate as formatRelativeDateBase,\r\n} from './date';\r\n\r\nimport {\r\n formatCurrency as formatCurrencyBase,\r\n formatNumber as formatNumberBase,\r\n formatCompact as formatCompactBase,\r\n} from './number';\r\n\r\nimport {\r\n translateStatus as translateStatusBase,\r\n} from './status';\r\n\r\n// ============================================================================\r\n// DATE - PT-BR\r\n// ============================================================================\r\n\r\n/**\r\n * Formata data em português (Brasil)\r\n */\r\nexport function formatDate(\r\n date: string | Date,\r\n format: 'short' | 'long' | 'full' = 'long'\r\n): string {\r\n return formatDateBase(date, format, 'pt-BR');\r\n}\r\n\r\n/**\r\n * Formata data e hora em português (Brasil)\r\n */\r\nexport function formatDateTime(date: string | Date): string {\r\n return formatDateTimeBase(date, 'pt-BR');\r\n}\r\n\r\n/**\r\n * Formata data relativa em português (Brasil)\r\n */\r\nexport function formatRelativeDate(date: string | Date): string {\r\n return formatRelativeDateBase(date, 'pt-BR');\r\n}\r\n\r\n// ============================================================================\r\n// NUMBER - PT-BR\r\n// ============================================================================\r\n\r\n/**\r\n * Formata moeda em Real (BRL)\r\n */\r\nexport function formatCurrency(\r\n value: number,\r\n options?: Intl.NumberFormatOptions\r\n): string {\r\n return formatCurrencyBase(value, 'pt-BR', options);\r\n}\r\n\r\n/**\r\n * Formata número em português (Brasil)\r\n */\r\nexport function formatNumber(value: number, decimals = 0): string {\r\n return formatNumberBase(value, decimals, 'pt-BR');\r\n}\r\n\r\n/**\r\n * Formata número compacto em português (Brasil)\r\n */\r\nexport function formatCompact(value: number, decimals = 1): string {\r\n return formatCompactBase(value, decimals, 'pt-BR');\r\n}\r\n\r\n// ============================================================================\r\n// STATUS - PT-BR\r\n// ============================================================================\r\n\r\n/**\r\n * Traduz status para português (Brasil)\r\n */\r\nexport function translateStatus(status: string): string {\r\n return translateStatusBase(status, 'pt-BR');\r\n}\r\n"]}
1
+ {"version":3,"sources":["../src/types.ts","../src/accessibility/index.ts","../src/date/index.ts","../src/status/index.ts","../src/validation/index.ts","../src/content/tiptap-utils.ts","../src/color/index.ts","../src/dom/index.ts","../src/hooks/useAuth.ts","../src/stats/index.ts","../src/authentication/index.ts","../src/search/index.ts","../src/string/index.ts","../src/number/index.ts","../src/hooks/use-password-strength.ts","../src/pt-br.ts","../src/text/index.ts","../src/index.ts"],"names":["replaceText","hexToRgb","p","q","useRef","useState","useCallback","refreshToken","error","useEffect","window","strValue","formatNumber","React","suggestions","password","formatCompact","formatCurrency","formatDate","formatDateTime","formatRelativeDate","translateStatus","cleanText","countWords"],"mappings":"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","file":"index.js","sourcesContent":["/**\r\n * Types & Constants\r\n *\r\n * Tipos e constantes compartilhadas entre módulos.\r\n *\r\n * @module @rainersoft/utils/types\r\n * @author Rainer Teixeira\r\n */\r\n\r\n/**\r\n * Idiomas suportados\r\n */\r\nexport type Locale = 'pt-BR' | 'en-US' | 'es-ES';\r\n\r\n/**\r\n * Configuração de localização\r\n */\r\nexport interface LocaleConfig {\r\n locale: Locale;\r\n currency?: string;\r\n dateFormat?: 'short' | 'long' | 'full';\r\n}\r\n\r\n/**\r\n * Locale padrão\r\n */\r\nexport const DEFAULT_LOCALE: Locale = 'pt-BR';\r\n\r\n/**\r\n * Mapeamento de moedas por locale\r\n */\r\nexport const CURRENCY_MAP: Record<Locale, string> = {\r\n 'pt-BR': 'BRL',\r\n 'en-US': 'USD',\r\n 'es-ES': 'EUR',\r\n} as const;\r\n","/**\r\n * Accessibility Utilities\r\n * \r\n * Utilitários para verificação e garantia de conformidade com padrões WCAG.\r\n * Funções para cálculo de contraste, luminância e validação de acessibilidade.\r\n * \r\n * @module @rainersoft/utils/accessibility\r\n * @author Rainer Teixeira\r\n * @version 1.0.0\r\n */\r\n\r\n// ============================================================================\r\n// COLOR CONVERSION\r\n// ============================================================================\r\n\r\n/**\r\n * Converte cor hexadecimal para RGB\r\n * \r\n * @param hex - Cor em formato hexadecimal (#RRGGBB ou RRGGBB)\r\n * @returns Objeto com valores RGB { r, g, b }\r\n * \r\n * @example\r\n * ```typescript\r\n * const rgb = hexToRgb('#0891b2');\r\n * // { r: 8, g: 145, b: 178 }\r\n * ```\r\n */\r\nexport function hexToRgb(hex: string): { r: number; g: number; b: number } {\r\n const result = /^#?([a-f\\d]{2})([a-f\\d]{2})([a-f\\d]{2})$/i.exec(hex);\r\n if (!result) {\r\n throw new Error(`Invalid hex color: ${hex}`);\r\n }\r\n return {\r\n r: parseInt(result[1], 16),\r\n g: parseInt(result[2], 16),\r\n b: parseInt(result[3], 16),\r\n };\r\n}\r\n\r\n// ============================================================================\r\n// LUMINANCE CALCULATION\r\n// ============================================================================\r\n\r\n/**\r\n * Calcula a luminância relativa de uma cor RGB\r\n * \r\n * @param r - Componente vermelho (0-255)\r\n * @param g - Componente verde (0-255)\r\n * @param b - Componente azul (0-255)\r\n * @returns Luminância relativa (0-1)\r\n * \r\n * @description\r\n * Fórmula baseada na recomendação WCAG 2.1 para cálculo de luminância.\r\n * \r\n * @example\r\n * ```typescript\r\n * const luminance = getLuminance(8, 145, 178);\r\n * // 0.234\r\n * ```\r\n */\r\nexport function getLuminance(r: number, g: number, b: number): number {\r\n const [rs, gs, bs] = [r, g, b].map((val) => {\r\n const v = val / 255;\r\n return v <= 0.03928 ? v / 12.92 : Math.pow((v + 0.055) / 1.055, 2.4);\r\n });\r\n return 0.2126 * rs + 0.7152 * gs + 0.0722 * bs;\r\n}\r\n\r\n// ============================================================================\r\n// CONTRAST CALCULATION\r\n// ============================================================================\r\n\r\n/**\r\n * Calcula o contraste entre duas cores\r\n * \r\n * @param color1 - Primeira cor em hexadecimal\r\n * @param color2 - Segunda cor em hexadecimal\r\n * @returns Razão de contraste (1-21)\r\n * \r\n * @description\r\n * Retorna a razão de contraste entre duas cores conforme WCAG 2.1.\r\n * Valores mínimos recomendados:\r\n * - WCAG AA (normal): 4.5:1 para texto normal, 3:1 para texto grande\r\n * - WCAG AAA (melhor): 7:1 para texto normal, 4.5:1 para texto grande\r\n * \r\n * @example\r\n * ```typescript\r\n * const contrast = getContrast('#ffffff', '#000000');\r\n * // 21 (máximo contraste)\r\n * \r\n * const contrast2 = getContrast('#0891b2', '#ffffff');\r\n * // 3.2 (atende WCAG AA para texto grande)\r\n * ```\r\n */\r\nexport function getContrast(color1: string, color2: string): number {\r\n const rgb1 = hexToRgb(color1);\r\n const rgb2 = hexToRgb(color2);\r\n\r\n const lum1 = getLuminance(rgb1.r, rgb1.g, rgb1.b);\r\n const lum2 = getLuminance(rgb2.r, rgb2.g, rgb2.b);\r\n\r\n const lighter = Math.max(lum1, lum2);\r\n const darker = Math.min(lum1, lum2);\r\n\r\n return (lighter + 0.05) / (darker + 0.05);\r\n}\r\n\r\n// ============================================================================\r\n// WCAG VALIDATION\r\n// ============================================================================\r\n\r\n/**\r\n * Verifica se o contraste atende ao padrão WCAG AA\r\n * \r\n * @param foreground - Cor do texto (hexadecimal)\r\n * @param background - Cor de fundo (hexadecimal)\r\n * @param largeText - Se o texto é grande (>=18pt ou >=14pt bold)\r\n * @returns true se atende WCAG AA, false caso contrário\r\n * \r\n * @description\r\n * WCAG AA requer:\r\n * - Texto normal: contraste mínimo de 4.5:1\r\n * - Texto grande: contraste mínimo de 3:1\r\n * \r\n * @example\r\n * ```typescript\r\n * const meetsAA = meetsWCAGAA('#0891b2', '#ffffff', false);\r\n * // true (contraste 3.2:1, mas texto normal precisa 4.5:1)\r\n * \r\n * const meetsAALarge = meetsWCAGAA('#0891b2', '#ffffff', true);\r\n * // true (contraste 3.2:1, texto grande precisa 3:1)\r\n * ```\r\n */\r\nexport function meetsWCAGAA(\r\n foreground: string,\r\n background: string,\r\n largeText: boolean = false\r\n): boolean {\r\n const contrast = getContrast(foreground, background);\r\n return largeText ? contrast >= 3 : contrast >= 4.5;\r\n}\r\n\r\n/**\r\n * Verifica se o contraste atende ao padrão WCAG AAA\r\n * \r\n * @param foreground - Cor do texto (hexadecimal)\r\n * @param background - Cor de fundo (hexadecimal)\r\n * @param largeText - Se o texto é grande (>=18pt ou >=14pt bold)\r\n * @returns true se atende WCAG AAA, false caso contrário\r\n * \r\n * @description\r\n * WCAG AAA requer:\r\n * - Texto normal: contraste mínimo de 7:1\r\n * - Texto grande: contraste mínimo de 4.5:1\r\n * \r\n * @example\r\n * ```typescript\r\n * const meetsAAA = meetsWCAGAAA('#000000', '#ffffff', false);\r\n * // true (contraste 21:1)\r\n * ```\r\n */\r\nexport function meetsWCAGAAA(\r\n foreground: string,\r\n background: string,\r\n largeText: boolean = false\r\n): boolean {\r\n const contrast = getContrast(foreground, background);\r\n return largeText ? contrast >= 4.5 : contrast >= 7;\r\n}\r\n\r\n/**\r\n * Retorna informações completas de contraste entre duas cores\r\n * \r\n * @param foreground - Cor do texto (hexadecimal)\r\n * @param background - Cor de fundo (hexadecimal)\r\n * @returns Objeto com informações de contraste\r\n * \r\n * @example\r\n * ```typescript\r\n * const info = getContrastInfo('#0891b2', '#ffffff');\r\n * // {\r\n * // contrast: 3.2,\r\n * // meetsAA: false,\r\n * // meetsAALarge: true,\r\n * // meetsAAA: false,\r\n * // meetsAAALarge: false,\r\n * // level: 'AA Large'\r\n * // }\r\n * ```\r\n */\r\nexport function getContrastInfo(\r\n foreground: string,\r\n background: string\r\n): {\r\n contrast: number;\r\n meetsAA: boolean;\r\n meetsAALarge: boolean;\r\n meetsAAA: boolean;\r\n meetsAAALarge: boolean;\r\n level: 'Fail' | 'AA Large' | 'AA' | 'AAA Large' | 'AAA';\r\n} {\r\n const contrast = getContrast(foreground, background);\r\n const meetsAA = contrast >= 4.5;\r\n const meetsAALarge = contrast >= 3;\r\n const meetsAAA = contrast >= 7;\r\n const meetsAAALarge = contrast >= 4.5;\r\n\r\n let level: 'Fail' | 'AA Large' | 'AA' | 'AAA Large' | 'AAA' = 'Fail';\r\n if (meetsAAA) {\r\n level = 'AAA';\r\n } else if (meetsAAALarge) {\r\n level = 'AAA Large';\r\n } else if (meetsAA) {\r\n level = 'AA';\r\n } else if (meetsAALarge) {\r\n level = 'AA Large';\r\n }\r\n\r\n return {\r\n contrast,\r\n meetsAA,\r\n meetsAALarge,\r\n meetsAAA,\r\n meetsAAALarge,\r\n level,\r\n };\r\n}\r\n\r\n/**\r\n * Valida se uma combinação de cores atende aos padrões de acessibilidade\r\n * \r\n * @param foreground - Cor do texto (hexadecimal)\r\n * @param background - Cor de fundo (hexadecimal)\r\n * @param options - Opções de validação\r\n * @returns Resultado da validação\r\n * \r\n * @example\r\n * ```typescript\r\n * const validation = validateContrast('#0891b2', '#ffffff', {\r\n * largeText: true\r\n * });\r\n * // {\r\n * // valid: true,\r\n * // level: 'AA Large',\r\n * // contrast: 3.2,\r\n * // message: 'Contraste válido para texto grande (WCAG AA)'\r\n * // }\r\n * ```\r\n */\r\nexport function validateContrast(\r\n foreground: string,\r\n background: string,\r\n options: {\r\n requireAAA?: boolean;\r\n largeText?: boolean;\r\n } = {}\r\n): {\r\n valid: boolean;\r\n level: string;\r\n contrast: number;\r\n message: string;\r\n} {\r\n const { requireAAA = false, largeText = false } = options;\r\n const info = getContrastInfo(foreground, background);\r\n\r\n let valid = false;\r\n let message = '';\r\n\r\n if (requireAAA) {\r\n valid = largeText ? info.meetsAAALarge : info.meetsAAA;\r\n message = valid\r\n ? `Contraste válido (WCAG AAA${largeText ? ' - Texto Grande' : ''})`\r\n : `Contraste insuficiente para WCAG AAA${largeText ? ' - Texto Grande' : ''}. Requerido: ${largeText ? '4.5:1' : '7:1'}, atual: ${info.contrast.toFixed(2)}:1`;\r\n } else {\r\n valid = largeText ? info.meetsAALarge : info.meetsAA;\r\n message = valid\r\n ? `Contraste válido (WCAG AA${largeText ? ' - Texto Grande' : ''})`\r\n : `Contraste insuficiente para WCAG AA${largeText ? ' - Texto Grande' : ''}. Requerido: ${largeText ? '3:1' : '4.5:1'}, atual: ${info.contrast.toFixed(2)}:1`;\r\n }\r\n\r\n return {\r\n valid,\r\n level: info.level,\r\n contrast: info.contrast,\r\n message,\r\n };\r\n}\r\n","/**\r\n * Date Utilities\r\n *\r\n * Utilitários para formatação e manipulação de datas.\r\n * Suporte para múltiplos idiomas: pt-BR, en-US, es-ES.\r\n *\r\n * @module @rainersoft/utils/date\r\n * @author Rainer Teixeira\r\n */\r\n\r\nimport type { Locale } from '../types';\r\nimport { DEFAULT_LOCALE } from '../types';\r\n\r\n/**\r\n * Textos relativos por idioma\r\n */\r\nconst RELATIVE_TEXTS = {\r\n 'pt-BR': {\r\n now: 'agora',\r\n minute: (n: number) => `há ${n} ${n === 1 ? 'minuto' : 'minutos'}`,\r\n hour: (n: number) => `há ${n} ${n === 1 ? 'hora' : 'horas'}`,\r\n day: (n: number) => `há ${n} ${n === 1 ? 'dia' : 'dias'}`,\r\n month: (n: number) => `há ${n} ${n === 1 ? 'mês' : 'meses'}`,\r\n year: (n: number) => `há ${n} ${n === 1 ? 'ano' : 'anos'}`,\r\n },\r\n 'en-US': {\r\n now: 'now',\r\n minute: (n: number) => `${n} ${n === 1 ? 'minute' : 'minutes'} ago`,\r\n hour: (n: number) => `${n} ${n === 1 ? 'hour' : 'hours'} ago`,\r\n day: (n: number) => `${n} ${n === 1 ? 'day' : 'days'} ago`,\r\n month: (n: number) => `${n} ${n === 1 ? 'month' : 'months'} ago`,\r\n year: (n: number) => `${n} ${n === 1 ? 'year' : 'years'} ago`,\r\n },\r\n 'es-ES': {\r\n now: 'ahora',\r\n minute: (n: number) => `hace ${n} ${n === 1 ? 'minuto' : 'minutos'}`,\r\n hour: (n: number) => `hace ${n} ${n === 1 ? 'hora' : 'horas'}`,\r\n day: (n: number) => `hace ${n} ${n === 1 ? 'día' : 'días'}`,\r\n month: (n: number) => `hace ${n} ${n === 1 ? 'mes' : 'meses'}`,\r\n year: (n: number) => `hace ${n} ${n === 1 ? 'año' : 'años'}`,\r\n },\r\n} as const;\r\n\r\n/**\r\n * Formata data com suporte a múltiplos idiomas\r\n *\r\n * @param date - Data (string ISO ou Date)\r\n * @param format - Formato ('short' | 'long' | 'full')\r\n * @param locale - Idioma (padrão: 'pt-BR')\r\n * @returns Data formatada\r\n *\r\n * @example\r\n * formatDate('2025-11-26') // '26 de novembro de 2025' (pt-BR)\r\n * formatDate('2025-11-26', 'short') // '26/11/2025'\r\n * formatDate('2025-11-26', 'long', 'en-US') // 'November 26, 2025'\r\n * formatDate('2025-11-26', 'long', 'es-ES') // '26 de noviembre de 2025'\r\n */\r\nexport function formatDate(\r\n date: string | Date,\r\n format: 'short' | 'long' | 'full' = 'long',\r\n locale: Locale = DEFAULT_LOCALE\r\n): string {\r\n const d = typeof date === 'string' ? new Date(date) : date;\r\n \r\n // Usar Intl.DateTimeFormat para suporte multi-idioma\r\n const options: Intl.DateTimeFormatOptions = {\r\n day: 'numeric',\r\n month: format === 'short' ? '2-digit' : 'long',\r\n year: 'numeric',\r\n ...(format === 'full' && { weekday: 'long' }),\r\n };\r\n\r\n if (format === 'short') {\r\n return d.toLocaleDateString(locale, { day: '2-digit', month: '2-digit', year: 'numeric' });\r\n }\r\n\r\n return d.toLocaleDateString(locale, options);\r\n}\r\n\r\n/**\r\n * Formata data e hora com suporte a múltiplos idiomas\r\n *\r\n * @param date - Data (string ISO ou Date)\r\n * @param locale - Idioma (padrão: 'pt-BR')\r\n * @returns Data e hora formatadas\r\n *\r\n * @example\r\n * formatDateTime('2025-11-26T14:30:00') // '26 de novembro de 2025, 14:30' (pt-BR)\r\n * formatDateTime('2025-11-26T14:30:00', 'en-US') // 'November 26, 2025, 2:30 PM'\r\n */\r\nexport function formatDateTime(date: string | Date, locale: Locale = DEFAULT_LOCALE): string {\r\n const d = typeof date === 'string' ? new Date(date) : date;\r\n \r\n return d.toLocaleString(locale, {\r\n day: 'numeric',\r\n month: 'long',\r\n year: 'numeric',\r\n hour: '2-digit',\r\n minute: '2-digit',\r\n });\r\n}\r\n\r\n/**\r\n * Formata data relativa (há X dias/horas) com suporte a idiomas\r\n *\r\n * @param date - Data (string ISO ou Date)\r\n * @param locale - Idioma (padrão: 'pt-BR')\r\n * @returns Texto relativo\r\n *\r\n * @example\r\n * formatRelativeDate(new Date()) // 'agora' (pt-BR)\r\n * formatRelativeDate(yesterday, 'en-US') // '1 day ago'\r\n * formatRelativeDate(yesterday, 'es-ES') // 'hace 1 día'\r\n */\r\nexport function formatRelativeDate(date: string | Date, locale: Locale = DEFAULT_LOCALE): string {\r\n const d = typeof date === 'string' ? new Date(date) : date;\r\n\r\n // Proteger contra datas inválidas (evita 'há NaN anos')\r\n if (!(d instanceof Date) || Number.isNaN(d.getTime())) {\r\n return '';\r\n }\r\n const now = new Date();\r\n const diffMs = now.getTime() - d.getTime();\r\n const diffSec = Math.floor(diffMs / 1000);\r\n const diffMin = Math.floor(diffSec / 60);\r\n const diffHour = Math.floor(diffMin / 60);\r\n const diffDay = Math.floor(diffHour / 24);\r\n // Usar média de dias por mês mais próxima da realidade para não arredondar cedo demais para 1 ano\r\n const diffMonth = Math.floor(diffDay / 30.4375); // 365 / 12\r\n const diffYear = Math.floor(diffDay / 365);\r\n\r\n const texts = RELATIVE_TEXTS[locale];\r\n\r\n // Regras especiais por idioma (mais naturais)\r\n if (diffSec < 10) {\r\n if (locale === 'pt-BR') return 'agora mesmo';\r\n if (locale === 'en-US') return 'just now';\r\n if (locale === 'es-ES') return 'ahora mismo';\r\n }\r\n\r\n if (diffSec < 60) return texts.now;\r\n if (diffMin < 60) return texts.minute(diffMin);\r\n if (diffHour < 24) return texts.hour(diffHour);\r\n\r\n // Dias específicos\r\n if (diffDay === 1) {\r\n if (locale === 'pt-BR') return 'ontem';\r\n if (locale === 'en-US') return 'yesterday';\r\n if (locale === 'es-ES') return 'ayer';\r\n }\r\n\r\n if (diffDay === 2) {\r\n if (locale === 'pt-BR') return 'anteontem';\r\n if (locale === 'en-US') return 'the day before yesterday';\r\n if (locale === 'es-ES') return 'anteayer';\r\n }\r\n\r\n if (diffDay < 30) return texts.day(diffDay);\r\n if (diffMonth < 12) return texts.month(diffMonth);\r\n return texts.year(diffYear);\r\n}\r\n\r\n/**\r\n * Converte data para ISO string\r\n *\r\n * @param date - Data\r\n * @returns String ISO\r\n */\r\nexport function toISOString(date: Date): string {\r\n return date.toISOString();\r\n}\r\n\r\n/**\r\n * Verifica se data é válida\r\n *\r\n * @param date - Data para validar\r\n * @returns true se válida\r\n */\r\nexport function isValidDate(date: unknown): date is Date {\r\n return date instanceof Date && !isNaN(date.getTime());\r\n}\r\n","/**\r\n * Status Utilities\r\n *\r\n * Utilitários para tradução e manipulação de status.\r\n * Agnóstico de domínio - pode ser usado para posts, pedidos, tarefas, etc.\r\n * Suporte para múltiplos idiomas: pt-BR, en-US, es-ES.\r\n *\r\n * @module @rainersoft/utils/status\r\n * @author Rainer Teixeira\r\n */\r\n\r\nimport type { Locale } from '../types';\r\nimport { DEFAULT_LOCALE } from '../types';\r\n\r\n/**\r\n * Status genéricos de entidades\r\n */\r\nexport type GenericStatus =\r\n | 'DRAFT'\r\n | 'PENDING'\r\n | 'PUBLISHED'\r\n | 'ACTIVE'\r\n | 'INACTIVE'\r\n | 'ARCHIVED'\r\n | 'DELETED'\r\n | 'SCHEDULED'\r\n | 'COMPLETED'\r\n | 'CANCELLED'\r\n | 'APPROVED'\r\n | 'REJECTED';\r\n\r\n/**\r\n * Traduções de status por idioma\r\n */\r\nconst STATUS_TRANSLATIONS: Record<Locale, Record<string, string>> = {\r\n 'pt-BR': {\r\n // Estados de conteúdo\r\n DRAFT: 'Rascunho',\r\n PUBLISHED: 'Publicado',\r\n ARCHIVED: 'Arquivado',\r\n SCHEDULED: 'Agendado',\r\n DELETED: 'Excluído',\r\n \r\n // Estados de processo\r\n PENDING: 'Pendente',\r\n ACTIVE: 'Ativo',\r\n INACTIVE: 'Inativo',\r\n COMPLETED: 'Concluído',\r\n CANCELLED: 'Cancelado',\r\n \r\n // Estados de aprovação\r\n APPROVED: 'Aprovado',\r\n REJECTED: 'Rejeitado',\r\n \r\n // Estados de pedido/pagamento\r\n PROCESSING: 'Processando',\r\n PAID: 'Pago',\r\n UNPAID: 'Não Pago',\r\n REFUNDED: 'Reembolsado',\r\n FAILED: 'Falhou',\r\n \r\n // Estados de usuário\r\n VERIFIED: 'Verificado',\r\n UNVERIFIED: 'Não Verificado',\r\n BANNED: 'Banido',\r\n SUSPENDED: 'Suspenso',\r\n },\r\n 'en-US': {\r\n DRAFT: 'Draft',\r\n PUBLISHED: 'Published',\r\n ARCHIVED: 'Archived',\r\n SCHEDULED: 'Scheduled',\r\n DELETED: 'Deleted',\r\n PENDING: 'Pending',\r\n ACTIVE: 'Active',\r\n INACTIVE: 'Inactive',\r\n COMPLETED: 'Completed',\r\n CANCELLED: 'Cancelled',\r\n APPROVED: 'Approved',\r\n REJECTED: 'Rejected',\r\n PROCESSING: 'Processing',\r\n PAID: 'Paid',\r\n UNPAID: 'Unpaid',\r\n REFUNDED: 'Refunded',\r\n FAILED: 'Failed',\r\n VERIFIED: 'Verified',\r\n UNVERIFIED: 'Unverified',\r\n BANNED: 'Banned',\r\n SUSPENDED: 'Suspended',\r\n },\r\n 'es-ES': {\r\n DRAFT: 'Borrador',\r\n PUBLISHED: 'Publicado',\r\n ARCHIVED: 'Archivado',\r\n SCHEDULED: 'Programado',\r\n DELETED: 'Eliminado',\r\n PENDING: 'Pendiente',\r\n ACTIVE: 'Activo',\r\n INACTIVE: 'Inactivo',\r\n COMPLETED: 'Completado',\r\n CANCELLED: 'Cancelado',\r\n APPROVED: 'Aprobado',\r\n REJECTED: 'Rechazado',\r\n PROCESSING: 'Procesando',\r\n PAID: 'Pagado',\r\n UNPAID: 'No Pagado',\r\n REFUNDED: 'Reembolsado',\r\n FAILED: 'Fallido',\r\n VERIFIED: 'Verificado',\r\n UNVERIFIED: 'No Verificado',\r\n BANNED: 'Bloqueado',\r\n SUSPENDED: 'Suspendido',\r\n },\r\n} as const;\r\n\r\n/**\r\n * Traduz status com suporte a idiomas\r\n *\r\n * @param status - Status em inglês (uppercase)\r\n * @param locale - Idioma (padrão: 'pt-BR')\r\n * @returns Status traduzido\r\n *\r\n * @example\r\n * translateStatus('DRAFT') // 'Rascunho' (pt-BR)\r\n * translateStatus('DRAFT', 'en-US') // 'Draft'\r\n * translateStatus('DRAFT', 'es-ES') // 'Borrador'\r\n */\r\nexport function translateStatus(status: string, locale: Locale = DEFAULT_LOCALE): string {\r\n const normalized = status.toUpperCase();\r\n return STATUS_TRANSLATIONS[locale][normalized] || status;\r\n}\r\n\r\n/**\r\n * Obtém cor baseada no status\r\n *\r\n * @param status - Status\r\n * @returns Classe Tailwind de cor\r\n *\r\n * @example\r\n * getStatusColor('PUBLISHED') // 'text-green-600'\r\n * getStatusColor('DRAFT') // 'text-gray-600'\r\n */\r\nexport function getStatusColor(status: string): string {\r\n const normalized = status.toUpperCase();\r\n \r\n const colorMap: Record<string, string> = {\r\n DRAFT: 'text-gray-600',\r\n PENDING: 'text-yellow-600',\r\n PUBLISHED: 'text-green-600',\r\n ACTIVE: 'text-green-600',\r\n INACTIVE: 'text-gray-600',\r\n ARCHIVED: 'text-orange-600',\r\n DELETED: 'text-red-600',\r\n SCHEDULED: 'text-blue-600',\r\n COMPLETED: 'text-green-600',\r\n CANCELLED: 'text-red-600',\r\n APPROVED: 'text-green-600',\r\n REJECTED: 'text-red-600',\r\n FAILED: 'text-red-600',\r\n VERIFIED: 'text-green-600',\r\n BANNED: 'text-red-600',\r\n };\r\n \r\n return colorMap[normalized] || 'text-gray-600';\r\n}\r\n\r\n/**\r\n * Obtém badge variant baseado no status\r\n *\r\n * @param status - Status\r\n * @returns Variant do badge\r\n *\r\n * @example\r\n * getStatusVariant('PUBLISHED') // 'success'\r\n * getStatusVariant('DRAFT') // 'secondary'\r\n */\r\nexport function getStatusVariant(status: string): 'default' | 'secondary' | 'destructive' | 'outline' {\r\n const normalized = status.toUpperCase();\r\n \r\n if (['PUBLISHED', 'ACTIVE', 'COMPLETED', 'APPROVED', 'VERIFIED'].includes(normalized)) {\r\n return 'default'; // Verde/sucesso\r\n }\r\n \r\n if (['DELETED', 'CANCELLED', 'REJECTED', 'FAILED', 'BANNED'].includes(normalized)) {\r\n return 'destructive'; // Vermelho/erro\r\n }\r\n \r\n if (['DRAFT', 'INACTIVE', 'ARCHIVED'].includes(normalized)) {\r\n return 'secondary'; // Cinza/neutro\r\n }\r\n \r\n return 'outline'; // Padrão\r\n}\r\n\r\n/**\r\n * Traduz status de posts do blog (alias para translateStatus)\r\n * Mantém compatibilidade com código legado\r\n *\r\n * @param status - Status do post (draft, published, archived, etc)\r\n * @param locale - Idioma (padrão: 'pt-BR')\r\n * @returns Status traduzido\r\n *\r\n * @example\r\n * translatePostStatus('draft') // 'Rascunho'\r\n * translatePostStatus('published') // 'Publicado'\r\n * translatePostStatus('pending_review') // 'Aguardando Revisão'\r\n */\r\nexport function translatePostStatus(status: string, locale: Locale = DEFAULT_LOCALE): string {\r\n // Mapeamento de status específicos de posts\r\n const postStatusMap: Record<string, string> = {\r\n 'draft': 'DRAFT',\r\n 'published': 'PUBLISHED',\r\n 'archived': 'ARCHIVED',\r\n 'scheduled': 'SCHEDULED',\r\n 'pending_review': 'PENDING',\r\n };\r\n \r\n // Normaliza o status (lowercase com underscores para uppercase)\r\n const normalized = postStatusMap[status.toLowerCase()] || status.toUpperCase();\r\n \r\n // Traduções específicas para pending_review\r\n if (status.toLowerCase() === 'pending_review') {\r\n const translations = {\r\n 'pt-BR': 'Aguardando Revisão',\r\n 'en-US': 'Pending Review',\r\n 'es-ES': 'Pendiente de Revisión'\r\n };\r\n return translations[locale] || translations['pt-BR'];\r\n }\r\n \r\n return translateStatus(normalized, locale);\r\n}\r\n","/**\r\n * Validation Utilities\r\n *\r\n * Utilitários para validação de dados com suporte a múltiplos idiomas.\r\n * Funções puras, sem dependências externas, prontas para qualquer plataforma.\r\n *\r\n * @module @rainersoft/utils/validation\r\n * @author Rainer Teixeira\r\n */\r\n\r\nimport type { Locale } from '../types';\r\nimport { DEFAULT_LOCALE } from '../types';\r\n\r\n/**\r\n * Interface para resultado de validação\r\n */\r\nexport interface ValidationResult {\r\n isValid: boolean;\r\n errors?: string[];\r\n}\r\n\r\n/**\r\n * Valida email usando regex RFC 5322\r\n *\r\n * @param email - Email para validar\r\n * @param locale - Idioma das mensagens de erro (padrão: 'pt-BR')\r\n * @returns Resultado da validação\r\n *\r\n * @example\r\n * validateEmail('user@example.com') // { isValid: true }\r\n * validateEmail('invalid-email') // { isValid: false, errors: ['Email inválido'] }\r\n */\r\nexport function validateEmail(email: string, locale: Locale = DEFAULT_LOCALE): ValidationResult {\r\n const emailRegex = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\r\n const isValid = emailRegex.test(email);\r\n \r\n if (!isValid) {\r\n const errors = {\r\n 'pt-BR': ['Email inválido'],\r\n 'en-US': ['Invalid email'],\r\n 'es-ES': ['Email inválido']\r\n };\r\n \r\n return {\r\n isValid: false,\r\n errors: errors[locale] || errors['pt-BR']\r\n };\r\n }\r\n \r\n return { isValid: true };\r\n}\r\n\r\n/**\r\n * Valida senha com critérios de segurança\r\n *\r\n * @param password - Senha para validar\r\n * @param options - Opções de validação\r\n * @param locale - Idioma das mensagens de erro\r\n * @returns Resultado da validação\r\n *\r\n * @example\r\n * validatePassword('MySecure123!') // { isValid: true }\r\n * validatePassword('123') // { isValid: false, errors: ['Senha deve ter pelo menos 8 caracteres'] }\r\n */\r\nexport function validatePassword(\r\n password: string, \r\n options: {\r\n minLength?: number;\r\n requireUppercase?: boolean;\r\n requireLowercase?: boolean;\r\n requireNumbers?: boolean;\r\n requireSpecialChars?: boolean;\r\n } = {},\r\n locale: Locale = DEFAULT_LOCALE\r\n): ValidationResult {\r\n const {\r\n minLength = 8,\r\n requireUppercase = true,\r\n requireLowercase = true,\r\n requireNumbers = true,\r\n requireSpecialChars = false\r\n } = options;\r\n \r\n const errors: string[] = [];\r\n \r\n const errorMessages = {\r\n 'pt-BR': {\r\n minLength: `Senha deve ter pelo menos ${minLength} caracteres`,\r\n uppercase: 'Senha deve conter pelo menos uma letra maiúscula',\r\n lowercase: 'Senha deve conter pelo menos uma letra minúscula',\r\n numbers: 'Senha deve conter pelo menos um número',\r\n specialChars: 'Senha deve conter pelo menos um caractere especial'\r\n },\r\n 'en-US': {\r\n minLength: `Password must be at least ${minLength} characters`,\r\n uppercase: 'Password must contain at least one uppercase letter',\r\n lowercase: 'Password must contain at least one lowercase letter',\r\n numbers: 'Password must contain at least one number',\r\n specialChars: 'Password must contain at least one special character'\r\n },\r\n 'es-ES': {\r\n minLength: `La contraseña debe tener al menos ${minLength} caracteres`,\r\n uppercase: 'La contraseña debe contener al menos una letra mayúscula',\r\n lowercase: 'La contraseña debe contener al menos una letra minúscula',\r\n numbers: 'La contraseña debe contener al menos un número',\r\n specialChars: 'La contraseña debe contener al menos un carácter especial'\r\n }\r\n };\r\n \r\n const messages = errorMessages[locale] || errorMessages['pt-BR'];\r\n \r\n if (password.length < minLength) {\r\n errors.push(messages.minLength);\r\n }\r\n \r\n if (requireUppercase && !/[A-Z]/.test(password)) {\r\n errors.push(messages.uppercase);\r\n }\r\n \r\n if (requireLowercase && !/[a-z]/.test(password)) {\r\n errors.push(messages.lowercase);\r\n }\r\n \r\n if (requireNumbers && !/\\d/.test(password)) {\r\n errors.push(messages.numbers);\r\n }\r\n \r\n if (requireSpecialChars && !/[!@#$%^&*(),.?\":{}|<>]/.test(password)) {\r\n errors.push(messages.specialChars);\r\n }\r\n \r\n return {\r\n isValid: errors.length === 0,\r\n errors\r\n };\r\n}\r\n\r\n/**\r\n * Valida URL\r\n *\r\n * @param url - URL para validar\r\n * @param locale - Idioma das mensagens de erro\r\n * @returns Resultado da validação\r\n *\r\n * @example\r\n * validateUrl('https://example.com') // { isValid: true }\r\n * validateUrl('not-a-url') // { isValid: false, errors: ['URL inválida'] }\r\n */\r\nexport function validateUrl(url: string, locale: Locale = DEFAULT_LOCALE): ValidationResult {\r\n try {\r\n new URL(url);\r\n return { isValid: true };\r\n } catch {\r\n const errors = {\r\n 'pt-BR': ['URL inválida'],\r\n 'en-US': ['Invalid URL'],\r\n 'es-ES': ['URL inválida']\r\n };\r\n \r\n return {\r\n isValid: false,\r\n errors: errors[locale] || errors['pt-BR']\r\n };\r\n }\r\n}\r\n\r\n/**\r\n * Valida telefone (formato brasileiro por padrão)\r\n *\r\n * @param phone - Telefone para validar\r\n * @param locale - Idioma das mensagens de erro\r\n * @returns Resultado da validação\r\n *\r\n * @example\r\n * validatePhone('(11) 98765-4321') // { isValid: true }\r\n * validatePhone('123') // { isValid: false, errors: ['Telefone inválido'] }\r\n */\r\nexport function validatePhone(phone: string, locale: Locale = DEFAULT_LOCALE): ValidationResult {\r\n // Regex para telefone brasileiro: (XX) XXXXX-XXXX ou (XX) XXXX-XXXX\r\n const phoneRegex = /^\\(?\\d{2}\\)?[\\s-]?\\d{4,5}[-]?\\d{4}$/;\r\n const isValid = phoneRegex.test(phone);\r\n \r\n if (!isValid) {\r\n const errors = {\r\n 'pt-BR': ['Telefone inválido'],\r\n 'en-US': ['Invalid phone number'],\r\n 'es-ES': ['Teléfono inválido']\r\n };\r\n \r\n return {\r\n isValid: false,\r\n errors: errors[locale] || errors['pt-BR']\r\n };\r\n }\r\n \r\n return { isValid: true };\r\n}\r\n\r\n/**\r\n * Valida username para registro\r\n *\r\n * @param username - Username para validar\r\n * @param options - Opções de validação\r\n * @param locale - Idioma das mensagens de erro\r\n * @returns Resultado da validação\r\n *\r\n * @example\r\n * validateUsername('user123') // { isValid: true }\r\n * validateUsername('us') // { isValid: false, errors: ['Username muito curto'] }\r\n */\r\nexport function validateUsername(\r\n username: string,\r\n options: {\r\n minLength?: number;\r\n maxLength?: number;\r\n allowSpecialChars?: boolean;\r\n } = {},\r\n locale: Locale = DEFAULT_LOCALE\r\n): ValidationResult {\r\n const {\r\n minLength = 3,\r\n maxLength = 20,\r\n allowSpecialChars = false\r\n } = options;\r\n \r\n const errors: string[] = [];\r\n \r\n const errorMessages = {\r\n 'pt-BR': {\r\n minLength: `Username muito curto (mínimo ${minLength} caracteres)`,\r\n maxLength: `Username muito longo (máximo ${maxLength} caracteres)`,\r\n invalidChars: 'Username contém caracteres inválidos'\r\n },\r\n 'en-US': {\r\n minLength: `Username too short (minimum ${minLength} characters)`,\r\n maxLength: `Username too long (maximum ${maxLength} characters)`,\r\n invalidChars: 'Username contains invalid characters'\r\n },\r\n 'es-ES': {\r\n minLength: `Username muy corto (mínimo ${minLength} caracteres)`,\r\n maxLength: `Username muy largo (máximo ${maxLength} caracteres)`,\r\n invalidChars: 'Username contiene caracteres inválidos'\r\n }\r\n };\r\n \r\n const messages = errorMessages[locale] || errorMessages['pt-BR'];\r\n \r\n if (username.length < minLength) {\r\n errors.push(messages.minLength);\r\n }\r\n \r\n if (username.length > maxLength) {\r\n errors.push(messages.maxLength);\r\n }\r\n \r\n const usernameRegex = allowSpecialChars \r\n ? /^[a-zA-Z0-9_]{3,20}$/\r\n : /^[a-zA-Z0-9_]{3,20}$/;\r\n \r\n if (!usernameRegex.test(username)) {\r\n errors.push(messages.invalidChars);\r\n }\r\n \r\n return {\r\n isValid: errors.length === 0,\r\n errors\r\n };\r\n}\r\n\r\n/**\r\n * Valida slug para URLs amigáveis\r\n *\r\n * @param slug - Slug para validar\r\n * @param options - Opções de validação\r\n * @param locale - Idioma das mensagens de erro\r\n * @returns Resultado da validação\r\n *\r\n * @example\r\n * validateSlug('my-post-title') // { isValid: true }\r\n * validateSlug('My Post Title') // { isValid: false, errors: ['Slug inválido'] }\r\n */\r\nexport function validateSlug(\r\n slug: string,\r\n options: {\r\n minLength?: number;\r\n maxLength?: number;\r\n } = {},\r\n locale: Locale = DEFAULT_LOCALE\r\n): ValidationResult {\r\n const {\r\n minLength = 3,\r\n maxLength = 100\r\n } = options;\r\n \r\n const errors: string[] = [];\r\n \r\n const errorMessages = {\r\n 'pt-BR': {\r\n minLength: `Slug muito curto (mínimo ${minLength} caracteres)`,\r\n maxLength: `Slug muito longo (máximo ${maxLength} caracteres)`,\r\n invalidFormat: 'Slug inválido - use apenas letras minúsculas, números e hífens'\r\n },\r\n 'en-US': {\r\n minLength: `Slug too short (minimum ${minLength} characters)`,\r\n maxLength: `Slug too long (maximum ${maxLength} characters)`,\r\n invalidFormat: 'Invalid slug - use only lowercase letters, numbers and hyphens'\r\n },\r\n 'es-ES': {\r\n minLength: `Slug muy corto (mínimo ${minLength} caracteres)`,\r\n maxLength: `Slug muy largo (máximo ${maxLength} caracteres)`,\r\n invalidFormat: 'Slug inválido - use solo letras minúsculas, números y guiones'\r\n }\r\n };\r\n \r\n const messages = errorMessages[locale] || errorMessages['pt-BR'];\r\n \r\n if (slug.length < minLength) {\r\n errors.push(messages.minLength);\r\n }\r\n \r\n if (slug.length > maxLength) {\r\n errors.push(messages.maxLength);\r\n }\r\n \r\n const slugRegex = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;\r\n if (!slugRegex.test(slug)) {\r\n errors.push(messages.invalidFormat);\r\n }\r\n \r\n return {\r\n isValid: errors.length === 0,\r\n errors\r\n };\r\n}\r\n\r\n/**\r\n * Valida texto com comprimento mínimo e máximo\r\n *\r\n * @param text - Texto para validar\r\n * @param options - Opções de validação\r\n * @param locale - Idioma das mensagens de erro\r\n * @returns Resultado da validação\r\n *\r\n * @example\r\n * validateText('Hello', { minLength: 3 }) // { isValid: true }\r\n * validateText('Hi', { minLength: 3 }) // { isValid: false, errors: ['Texto muito curto'] }\r\n */\r\nexport function validateText(\r\n text: string,\r\n options: {\r\n minLength?: number;\r\n maxLength?: number;\r\n fieldName?: string;\r\n } = {},\r\n locale: Locale = DEFAULT_LOCALE\r\n): ValidationResult {\r\n const {\r\n minLength = 0,\r\n maxLength = Infinity,\r\n fieldName = 'Texto'\r\n } = options;\r\n \r\n const errors: string[] = [];\r\n \r\n const errorMessages = {\r\n 'pt-BR': {\r\n minLength: `${fieldName} muito curto (mínimo ${minLength} caracteres)`,\r\n maxLength: `${fieldName} muito longo (máximo ${maxLength} caracteres)`\r\n },\r\n 'en-US': {\r\n minLength: `${fieldName} too short (minimum ${minLength} characters)`,\r\n maxLength: `${fieldName} too long (maximum ${maxLength} characters)`\r\n },\r\n 'es-ES': {\r\n minLength: `${fieldName} muy corto (mínimo ${minLength} caracteres)`,\r\n maxLength: `${fieldName} muy largo (máximo ${maxLength} caracteres)`\r\n }\r\n };\r\n \r\n const messages = errorMessages[locale] || errorMessages['pt-BR'];\r\n \r\n if (text.length < minLength) {\r\n errors.push(messages.minLength);\r\n }\r\n \r\n if (text.length > maxLength) {\r\n errors.push(messages.maxLength);\r\n }\r\n \r\n return {\r\n isValid: errors.length === 0,\r\n errors\r\n };\r\n}\r\n\r\n/**\r\n * Valida mensagem de contato\r\n *\r\n * @param message - Mensagem para validar\r\n * @param options - Opções de validação\r\n * @param locale - Idioma das mensagens de erro\r\n * @returns Resultado da validação\r\n *\r\n * @example\r\n * validateMessage('Olá, gostaria de mais informações') // { isValid: true }\r\n * validateMessage('Oi') // { isValid: false, errors: ['Mensagem muito curta'] }\r\n */\r\nexport function validateMessage(\r\n message: string,\r\n options: {\r\n minLength?: number;\r\n maxLength?: number;\r\n } = {},\r\n locale: Locale = DEFAULT_LOCALE\r\n): ValidationResult {\r\n const {\r\n minLength = 10,\r\n maxLength = 1000\r\n } = options;\r\n \r\n return validateText(message, {\r\n minLength,\r\n maxLength,\r\n fieldName: locale === 'pt-BR' ? 'Mensagem' : locale === 'en-US' ? 'Message' : 'Mensaje'\r\n }, locale);\r\n}\r\n","/**\r\n * Tiptap Content Utilities\r\n * \r\n * Utilitários para processamento de conteúdo Tiptap Editor.\r\n * Extração de texto, geração de excerpts, validação e estatísticas.\r\n * \r\n * @module @rainersoft/utils/content\r\n * @author Rainer Teixeira\r\n * @version 1.0.0\r\n * @since 1.0.0\r\n */\r\n\r\n// ============================================================================\r\n// TYPES\r\n// ============================================================================\r\n\r\nexport interface TiptapNode {\r\n type: string;\r\n text?: string;\r\n content?: TiptapNode[];\r\n attrs?: Record<string, any>;\r\n}\r\n\r\nexport interface TiptapJSON {\r\n type: 'doc';\r\n content: TiptapNode[];\r\n}\r\n\r\nexport interface ContentStats {\r\n wordCount: number;\r\n characterCount: number;\r\n readingTime: number;\r\n}\r\n\r\n// ============================================================================\r\n// TEXT EXTRACTION\r\n// ============================================================================\r\n\r\n/**\r\n * Extrai texto de conteúdo Tiptap (JSON)\r\n * \r\n * Processa recursivamente a estrutura JSON do Tiptap para extrair\r\n * todo o texto em formato string, ignorando marcações e metadados.\r\n * \r\n * @param content - Conteúdo JSON do Tiptap\r\n * @returns Texto extraído do conteúdo\r\n * \r\n * @example\r\n * ```ts\r\n * const content = {\r\n * type: 'doc',\r\n * content: [\r\n * { type: 'paragraph', content: [{ type: 'text', text: 'Olá mundo' }] }\r\n * ]\r\n * };\r\n * extractTextFromTiptap(content) // \"Olá mundo\"\r\n * ```\r\n */\r\nexport function extractTextFromTiptap(content: TiptapJSON): string {\r\n /**\r\n * Extrai texto de um nó Tiptap (recursivo)\r\n */\r\n function extractFromNode(node: TiptapJSON | TiptapNode): string {\r\n if ('text' in node && typeof node.text === 'string') {\r\n return node.text;\r\n }\r\n\r\n if ('content' in node && Array.isArray(node.content)) {\r\n return node.content\r\n .map((child: TiptapNode) => extractFromNode(child))\r\n .join(' ');\r\n }\r\n\r\n return '';\r\n }\r\n\r\n return extractFromNode(content).trim();\r\n}\r\n\r\n/**\r\n * Gera excerpt (resumo) do conteúdo Tiptap\r\n * \r\n * Extrai texto do conteúdo e limita a um tamanho máximo.\r\n * Perfeito para previews, meta descriptions, etc.\r\n * \r\n * @param content - Conteúdo JSON do Tiptap\r\n * @param maxLength - Tamanho máximo do excerpt (padrão: 160 caracteres)\r\n * @returns Excerpt formatado com \"...\" se truncado\r\n * \r\n * @example\r\n * ```ts\r\n * const content = { type: 'doc', content: [...] };\r\n * generateExcerpt(content, 50) // \"Primeiros 50 caracteres...\"\r\n * ```\r\n */\r\nexport function generateExcerpt(\r\n content: TiptapJSON,\r\n maxLength: number = 160\r\n): string {\r\n const text = extractTextFromTiptap(content);\r\n\r\n if (text.length <= maxLength) {\r\n return text;\r\n }\r\n\r\n return text.substring(0, maxLength).trim() + '...';\r\n}\r\n\r\n// ============================================================================\r\n// CONTENT CREATION\r\n// ============================================================================\r\n\r\n/**\r\n * Cria conteúdo JSON vazio do Tiptap\r\n * \r\n * Retorna uma estrutura Tiptap válida mas vazia.\r\n * Útil para inicializar editores ou criar novos posts.\r\n * \r\n * @returns Documento vazio do Tiptap\r\n * \r\n * @example\r\n * ```ts\r\n * const emptyContent = createEmptyTiptapContent();\r\n * // { type: 'doc', content: [] }\r\n * ```\r\n */\r\nexport function createEmptyTiptapContent(): TiptapJSON {\r\n return {\r\n type: 'doc',\r\n content: [],\r\n };\r\n}\r\n\r\n// ============================================================================\r\n// CONTENT VALIDATION\r\n// ============================================================================\r\n\r\n/**\r\n * Verifica se o conteúdo Tiptap está vazio\r\n * \r\n * Analisa o conteúdo para determinar se não há texto útil.\r\n * Considera espaços em branco e elementos vazios.\r\n * \r\n * @param content - Conteúdo JSON do Tiptap\r\n * @returns true se o conteúdo estiver vazio\r\n * \r\n * @example\r\n * ```ts\r\n * const empty = { type: 'doc', content: [] };\r\n * isContentEmpty(empty) // true\r\n * \r\n * const withText = { type: 'doc', content: [\r\n * { type: 'paragraph', content: [{ type: 'text', text: 'Olá' }] }\r\n * ]};\r\n * isContentEmpty(withText) // false\r\n * ```\r\n */\r\nexport function isContentEmpty(content: TiptapJSON): boolean {\r\n if (!content || !content.content || content.content.length === 0) {\r\n return true;\r\n }\r\n\r\n const text = extractTextFromTiptap(content);\r\n return text.trim().length === 0;\r\n}\r\n\r\n// ============================================================================\r\n// CONTENT STATISTICS\r\n// ============================================================================\r\n\r\n/**\r\n * Conta palavras no conteúdo Tiptap\r\n * \r\n * Conta o número de palavras usando um algoritmo simples\r\n * que separa por espaços em branco.\r\n * \r\n * @param content - Conteúdo JSON do Tiptap\r\n * @returns Número de palavras no conteúdo\r\n * \r\n * @example\r\n * ```ts\r\n * const content = { type: 'doc', content: [\r\n * { type: 'paragraph', content: [{ type: 'text', text: 'Olá mundo' }] }\r\n * ]};\r\n * countWords(content) // 2\r\n * ```\r\n */\r\nexport function countWords(content: TiptapJSON): number {\r\n const text = extractTextFromTiptap(content);\r\n return text.trim().split(/\\s+/).filter(word => word.length > 0).length;\r\n}\r\n\r\n/**\r\n * Conta caracteres no conteúdo Tiptap\r\n * \r\n * @param content - Conteúdo JSON do Tiptap\r\n * @returns Número de caracteres no conteúdo\r\n */\r\nexport function countCharacters(content: TiptapJSON): number {\r\n return extractTextFromTiptap(content).length;\r\n}\r\n\r\n/**\r\n * Calcula tempo de leitura estimado\r\n * \r\n * Baseado na velocidade média de leitura de 200 palavras por minuto.\r\n * \r\n * @param content - Conteúdo JSON do Tiptap\r\n * @param wordsPerMinute - Velocidade de leitura (padrão: 200)\r\n * @returns Tempo de leitura em minutos\r\n * \r\n * @example\r\n * ```ts\r\n * const content = { type: 'doc', content: [...] };\r\n * getReadingTime(content) // 2.5 (para 500 palavras)\r\n * ```\r\n */\r\nexport function getReadingTime(\r\n content: TiptapJSON,\r\n wordsPerMinute: number = 200\r\n): number {\r\n const wordCount = countWords(content);\r\n return Math.ceil(wordCount / wordsPerMinute);\r\n}\r\n\r\n/**\r\n * Obtém estatísticas completas do conteúdo\r\n * \r\n * Retorna um objeto com todas as métricas relevantes:\r\n * - Contagem de palavras\r\n * - Contagem de caracteres\r\n * - Tempo de leitura estimado\r\n * \r\n * @param content - Conteúdo JSON do Tiptap\r\n * @returns Estatísticas completas do conteúdo\r\n * \r\n * @example\r\n * ```ts\r\n * const stats = getContentStats(content);\r\n * console.log(stats);\r\n * // { wordCount: 150, characterCount: 800, readingTime: 1 }\r\n * ```\r\n */\r\nexport function getContentStats(content: TiptapJSON): ContentStats {\r\n const wordCount = countWords(content);\r\n const characterCount = extractTextFromTiptap(content).length;\r\n const readingTime = getReadingTime(content);\r\n\r\n return {\r\n wordCount,\r\n characterCount,\r\n readingTime,\r\n };\r\n}\r\n\r\n// ============================================================================\r\n// CONTENT TRANSFORMATION\r\n// ============================================================================\r\n\r\n/**\r\n * Limpa e normaliza texto do conteúdo\r\n * \r\n * Remove espaços extras, normaliza quebras de linha\r\n * e limpa caracteres especiais indesejados.\r\n * \r\n * @param content - Conteúdo JSON do Tiptap\r\n * @returns Texto limpo e normalizado\r\n */\r\nexport function cleanText(content: TiptapJSON): string {\r\n const text = extractTextFromTiptap(content);\r\n \r\n return text\r\n .replace(/\\s+/g, ' ') // Normaliza espaços\r\n .replace(/\\n\\s*\\n/g, '\\n') // Remove quebras de linha vazias\r\n .replace(/^\\s+|\\s+$/g, '') // Remove espaços no início/fim\r\n .trim();\r\n}\r\n\r\n/**\r\n * Verifica se o conteúdo contém texto específico\r\n * \r\n * Busca case-insensitive por uma palavra ou frase no conteúdo.\r\n * \r\n * @param content - Conteúdo JSON do Tiptap\r\n * @param searchText - Texto para buscar\r\n * @returns true se encontrar o texto\r\n * \r\n * @example\r\n * ```ts\r\n * const content = { type: 'doc', content: [\r\n * { type: 'paragraph', content: [{ type: 'text', text: 'Olá mundo' }] }\r\n * ]};\r\n * containsText(content, 'mundo') // true\r\n * containsText(content, 'planeta') // false\r\n * ```\r\n */\r\nexport function containsText(content: TiptapJSON, searchText: string): boolean {\r\n const text = extractTextFromTiptap(content).toLowerCase();\r\n return text.includes(searchText.toLowerCase());\r\n}\r\n\r\n/**\r\n * Substitui texto no conteúdo Tiptap\r\n * \r\n * Busca e substitui texto em todo o conteúdo.\r\n * Operação case-insensitive.\r\n * \r\n * @param content - Conteúdo JSON do Tiptap\r\n * @param searchText - Texto para buscar\r\n * @param replaceText - Texto para substituir\r\n * @returns Conteúdo atualizado com o texto substituído\r\n * \r\n * @example\r\n * ```ts\r\n * const content = { type: 'doc', content: [\r\n * { type: 'paragraph', content: [{ type: 'text', text: 'Olá mundo' }] }\r\n * ]};\r\n * const updated = replaceText(content, 'mundo', 'planeta');\r\n * // Resultado: \"Olá planeta\"\r\n * ```\r\n */\r\nexport function replaceText(\r\n content: TiptapJSON,\r\n searchText: string,\r\n replaceText: string\r\n): TiptapJSON {\r\n /**\r\n * Processa nó recursivamente para substituir texto\r\n */\r\n function processNode(node: TiptapNode): TiptapNode {\r\n const newNode = { ...node };\r\n\r\n // Substituir texto no nó atual\r\n if ('text' in node && typeof node.text === 'string') {\r\n newNode.text = node.text.replace(\r\n new RegExp(searchText, 'gi'),\r\n replaceText\r\n );\r\n }\r\n\r\n // Processar nós filhos recursivamente\r\n if ('content' in node && Array.isArray(node.content)) {\r\n newNode.content = node.content.map(child => processNode(child));\r\n }\r\n\r\n return newNode;\r\n }\r\n\r\n // Processar conteúdo principal\r\n const newContent = {\r\n ...content,\r\n content: content.content.map(node => processNode(node))\r\n };\r\n\r\n return newContent;\r\n}\r\n","/**\r\n * Color Utilities\r\n * \r\n * Utilitários para manipulação e conversão de cores.\r\n * Inclui funções para conversão entre formatos, ajuste de cores e cálculos.\r\n * \r\n * @module @rainersoft/utils/color\r\n * @author Rainer Teixeira\r\n * @version 1.0.0\r\n */\r\n\r\n// ============================================================================\r\n// COLOR CONVERSION\r\n// ============================================================================\r\n\r\n/**\r\n * Converte cor hexadecimal para RGB\r\n * \r\n * @param hex - Cor em formato hexadecimal (#RRGGBB ou RRGGBB)\r\n * @returns Objeto com valores RGB { r, g, b }\r\n * \r\n * @example\r\n * ```typescript\r\n * const rgb = hexToRgb('#0891b2');\r\n * // { r: 8, g: 145, b: 178 }\r\n * ```\r\n */\r\nexport function hexToRgb(hex: string): { r: number; g: number; b: number } {\r\n const result = /^#?([a-f\\d]{2})([a-f\\d]{2})([a-f\\d]{2})$/i.exec(hex);\r\n if (!result) {\r\n throw new Error(`Invalid hex color: ${hex}`);\r\n }\r\n return {\r\n r: parseInt(result[1], 16),\r\n g: parseInt(result[2], 16),\r\n b: parseInt(result[3], 16),\r\n };\r\n}\r\n\r\n/**\r\n * Converte RGB para hexadecimal\r\n * \r\n * @param r - Componente vermelho (0-255)\r\n * @param g - Componente verde (0-255)\r\n * @param b - Componente azul (0-255)\r\n * @returns Cor em formato hexadecimal\r\n * \r\n * @example\r\n * ```typescript\r\n * const hex = rgbToHex(8, 145, 178);\r\n * // '#0891b2'\r\n * ```\r\n */\r\nexport function rgbToHex(r: number, g: number, b: number): string {\r\n const toHex = (n: number) => {\r\n const hex = Math.round(Math.max(0, Math.min(255, n))).toString(16);\r\n return hex.length === 1 ? '0' + hex : hex;\r\n };\r\n return `#${toHex(r)}${toHex(g)}${toHex(b)}`;\r\n}\r\n\r\n/**\r\n * Converte cor hexadecimal para HSL\r\n * \r\n * @param hex - Cor em formato hexadecimal\r\n * @returns Objeto com valores HSL { h, s, l }\r\n * \r\n * @example\r\n * ```typescript\r\n * const hsl = hexToHsl('#0891b2');\r\n * // { h: 187, s: 91, l: 36 }\r\n * ```\r\n */\r\nexport function hexToHsl(hex: string): { h: number; s: number; l: number } {\r\n const rgb = hexToRgb(hex);\r\n const r = rgb.r / 255;\r\n const g = rgb.g / 255;\r\n const b = rgb.b / 255;\r\n\r\n const max = Math.max(r, g, b);\r\n const min = Math.min(r, g, b);\r\n let h = 0;\r\n let s = 0;\r\n const l = (max + min) / 2;\r\n\r\n if (max !== min) {\r\n const d = max - min;\r\n s = l > 0.5 ? d / (2 - max - min) : d / (max + min);\r\n \r\n switch (max) {\r\n case r:\r\n h = ((g - b) / d + (g < b ? 6 : 0)) / 6;\r\n break;\r\n case g:\r\n h = ((b - r) / d + 2) / 6;\r\n break;\r\n case b:\r\n h = ((r - g) / d + 4) / 6;\r\n break;\r\n }\r\n }\r\n\r\n return {\r\n h: Math.round(h * 360),\r\n s: Math.round(s * 100),\r\n l: Math.round(l * 100),\r\n };\r\n}\r\n\r\n/**\r\n * Converte HSL para hexadecimal\r\n * \r\n * @param h - Matiz (0-360)\r\n * @param s - Saturação (0-100)\r\n * @param l - Luminosidade (0-100)\r\n * @returns Cor em formato hexadecimal\r\n * \r\n * @example\r\n * ```typescript\r\n * const hex = hslToHex(187, 91, 36);\r\n * // '#0891b2'\r\n * ```\r\n */\r\nexport function hslToHex(h: number, s: number, l: number): string {\r\n h = h / 360;\r\n s = s / 100;\r\n l = l / 100;\r\n\r\n let r, g, b;\r\n\r\n if (s === 0) {\r\n r = g = b = l; // achromatic\r\n } else {\r\n const hue2rgb = (p: number, q: number, t: number) => {\r\n if (t < 0) t += 1;\r\n if (t > 1) t -= 1;\r\n if (t < 1/6) return p + (q - p) * 6 * t;\r\n if (t < 1/2) return q;\r\n if (t < 2/3) return p + (q - p) * (2/3 - t) * 6;\r\n return p;\r\n };\r\n\r\n const q = l < 0.5 ? l * (1 + s) : l + s - l * s;\r\n const p = 2 * l - q;\r\n r = hue2rgb(p, q, h + 1/3);\r\n g = hue2rgb(p, q, h);\r\n b = hue2rgb(p, q, h - 1/3);\r\n }\r\n\r\n return rgbToHex(Math.round(r * 255), Math.round(g * 255), Math.round(b * 255));\r\n}\r\n\r\n// ============================================================================\r\n// COLOR MANIPULATION\r\n// ============================================================================\r\n\r\n/**\r\n * Ajusta o brilho de uma cor\r\n * \r\n * @param hex - Cor em formato hexadecimal\r\n * @param amount - Quantidade de ajuste (-100 a 100)\r\n * @returns Cor ajustada em formato hexadecimal\r\n * \r\n * @example\r\n * ```typescript\r\n * const lighter = adjustBrightness('#0891b2', 20);\r\n * // Cor mais clara\r\n * \r\n * const darker = adjustBrightness('#0891b2', -20);\r\n * // Cor mais escura\r\n * ```\r\n */\r\nexport function adjustBrightness(hex: string, amount: number): string {\r\n const hsl = hexToHsl(hex);\r\n const newL = Math.max(0, Math.min(100, hsl.l + amount));\r\n return hslToHex(hsl.h, hsl.s, newL);\r\n}\r\n\r\n/**\r\n * Ajusta a saturação de uma cor\r\n * \r\n * @param hex - Cor em formato hexadecimal\r\n * @param amount - Quantidade de ajuste (-100 a 100)\r\n * @returns Cor ajustada em formato hexadecimal\r\n * \r\n * @example\r\n * ```typescript\r\n * const moreSaturated = adjustSaturation('#0891b2', 20);\r\n * // Cor mais saturada\r\n * \r\n * const lessSaturated = adjustSaturation('#0891b2', -20);\r\n * // Cor menos saturada\r\n * ```\r\n */\r\nexport function adjustSaturation(hex: string, amount: number): string {\r\n const hsl = hexToHsl(hex);\r\n const newS = Math.max(0, Math.min(100, hsl.s + amount));\r\n return hslToHex(hsl.h, newS, hsl.l);\r\n}\r\n\r\n/**\r\n * Ajusta a matiz (hue) de uma cor\r\n * \r\n * @param hex - Cor em formato hexadecimal\r\n * @param degrees - Graus para ajustar (-360 a 360)\r\n * @returns Cor ajustada em formato hexadecimal\r\n * \r\n * @example\r\n * ```typescript\r\n * const rotated = adjustHue('#0891b2', 30);\r\n * // Cor com matiz ajustada em 30 graus\r\n * ```\r\n */\r\nexport function adjustHue(hex: string, degrees: number): string {\r\n const hsl = hexToHsl(hex);\r\n const newH = (hsl.h + degrees) % 360;\r\n return hslToHex(newH < 0 ? newH + 360 : newH, hsl.s, hsl.l);\r\n}\r\n\r\n/**\r\n * Cria uma variação mais clara de uma cor\r\n * \r\n * @param hex - Cor em formato hexadecimal\r\n * @param amount - Quantidade para clarear (0-100)\r\n * @returns Cor mais clara em formato hexadecimal\r\n * \r\n * @example\r\n * ```typescript\r\n * const lighter = lighten('#0891b2', 20);\r\n * // Versão mais clara da cor\r\n * ```\r\n */\r\nexport function lighten(hex: string, amount: number): string {\r\n return adjustBrightness(hex, amount);\r\n}\r\n\r\n/**\r\n * Cria uma variação mais escura de uma cor\r\n * \r\n * @param hex - Cor em formato hexadecimal\r\n * @param amount - Quantidade para escurecer (0-100)\r\n * @returns Cor mais escura em formato hexadecimal\r\n * \r\n * @example\r\n * ```typescript\r\n * const darker = darken('#0891b2', 20);\r\n * // Versão mais escura da cor\r\n * ```\r\n */\r\nexport function darken(hex: string, amount: number): string {\r\n return adjustBrightness(hex, -amount);\r\n}\r\n\r\n/**\r\n * Gera uma cor opaca a partir de uma hexadecimal\r\n * \r\n * @param hex - Cor em formato hexadecimal\r\n * @param alpha - Opacidade (0-1)\r\n * @returns Cor RGBA\r\n * \r\n * @example\r\n * ```typescript\r\n * const rgba = hexToRgba('#0891b2', 0.5);\r\n * // 'rgba(8, 145, 178, 0.5)'\r\n * ```\r\n */\r\nexport function hexToRgba(hex: string, alpha: number): string {\r\n const rgb = hexToRgb(hex);\r\n return `rgba(${rgb.r}, ${rgb.g}, ${rgb.b}, ${alpha})`;\r\n}\r\n\r\n/**\r\n * Obtém a cor complementar (oposta no círculo cromático)\r\n * \r\n * @param hex - Cor em formato hexadecimal\r\n * @returns Cor complementar em formato hexadecimal\r\n * \r\n * @example\r\n * ```typescript\r\n * const complementary = getComplementary('#0891b2');\r\n * // Cor complementar (oposta)\r\n * ```\r\n */\r\nexport function getComplementary(hex: string): string {\r\n return adjustHue(hex, 180);\r\n}\r\n\r\n/**\r\n * Gera uma paleta de cores análogas\r\n * \r\n * @param hex - Cor base em formato hexadecimal\r\n * @param count - Número de cores na paleta\r\n * @returns Array de cores análogas\r\n * \r\n * @example\r\n * ```typescript\r\n * const palette = getAnalogousPalette('#0891b2', 5);\r\n * // ['#0891b2', '#08b291', '#08b2b2', '#0891b2', '#0870b2']\r\n * ```\r\n */\r\nexport function getAnalogousPalette(hex: string, count: number = 5): string[] {\r\n const hsl = hexToHsl(hex);\r\n const step = 30; // 30 graus de separação\r\n const palette: string[] = [];\r\n \r\n for (let i = 0; i < count; i++) {\r\n const hue = (hsl.h + (i - Math.floor(count / 2)) * step) % 360;\r\n palette.push(hslToHex(hue < 0 ? hue + 360 : hue, hsl.s, hsl.l));\r\n }\r\n \r\n return palette;\r\n}\r\n","/**\r\n * DOM Utilities\r\n *\r\n * Utilitários para manipulação do DOM e interações com o browser.\r\n * Funciona em qualquer ambiente browser moderno.\r\n *\r\n * @module @rainersoft/utils/dom\r\n * @author Rainer Teixeira\r\n */\r\n\r\n/**\r\n * Verifica se usuário prefere movimento reduzido (accessibility)\r\n *\r\n * @returns true se preferir movimento reduzido\r\n *\r\n * @example\r\n * if (prefersReducedMotion()) {\r\n * // Desabilitar animações\r\n * }\r\n */\r\nexport function prefersReducedMotion(): boolean {\r\n if (typeof window === 'undefined') return false;\r\n \r\n return window.matchMedia('(prefers-reduced-motion: reduce)').matches;\r\n}\r\n\r\n/**\r\n * Adiciona listener para mudanças na preferência de movimento\r\n *\r\n * @param callback - Função chamada quando a preferência muda\r\n * @returns Função para remover o listener\r\n *\r\n * @example\r\n * const unsubscribe = onReducedMotionChange((prefersReduced) => {\r\n * console.log('Motion preference changed:', prefersReduced);\r\n * });\r\n * \r\n * // Remover listener quando necessário\r\n * unsubscribe();\r\n */\r\nexport function onReducedMotionChange(\r\n callback: (prefersReduced: boolean) => void\r\n): () => void {\r\n if (typeof window === 'undefined') {\r\n return () => {};\r\n }\r\n \r\n const mediaQuery = window.matchMedia('(prefers-reduced-motion: reduce)');\r\n \r\n const handleChange = (e: MediaQueryListEvent) => {\r\n callback(e.matches);\r\n };\r\n \r\n // Adicionar listener (compatibilidade com browsers antigos)\r\n if (mediaQuery.addEventListener) {\r\n mediaQuery.addEventListener('change', handleChange);\r\n } else {\r\n // Fallback para browsers mais antigos\r\n (mediaQuery as any).addListener(handleChange);\r\n }\r\n \r\n // Retornar função de cleanup\r\n return () => {\r\n if (mediaQuery.removeEventListener) {\r\n mediaQuery.removeEventListener('change', handleChange);\r\n } else {\r\n // Fallback para browsers mais antigos\r\n (mediaQuery as any).removeListener(handleChange);\r\n }\r\n };\r\n}\r\n\r\n/**\r\n * Rola a página para uma posição específica\r\n *\r\n * @param x - Posição horizontal (padrão: 0)\r\n * @param y - Posição vertical (padrão: 0)\r\n * @param options - Opções de scroll\r\n *\r\n * @example\r\n * scrollToPosition(0, 500); // Rola para o topo com 500px de margem\r\n * scrollToPosition(0, 0, { smooth: true }); // Scroll suave para o topo\r\n */\r\nexport function scrollToPosition(\r\n x: number = 0,\r\n y: number = 0,\r\n options: {\r\n smooth?: boolean;\r\n behavior?: ScrollBehavior;\r\n } = {}\r\n): void {\r\n if (typeof window === 'undefined') return;\r\n \r\n const { smooth = false, behavior } = options;\r\n \r\n window.scrollTo({\r\n left: x,\r\n top: y,\r\n behavior: behavior || (smooth ? 'smooth' : 'auto')\r\n });\r\n}\r\n\r\n/**\r\n * Rola a página para o topo\r\n *\r\n * @param smooth - Se deve usar scroll suave (padrão: false)\r\n *\r\n * @example\r\n * scrollToTop(); // Scroll instantâneo para o topo\r\n * scrollToTop(true); // Scroll suave para o topo\r\n */\r\nexport function scrollToTop(smooth: boolean = false): void {\r\n scrollToPosition(0, 0, { smooth });\r\n}\r\n\r\n/**\r\n * Rola suavemente para uma posição\r\n *\r\n * @param x - Posição horizontal\r\n * @param y - Posição vertical\r\n * @param duration - Duração da animação em ms (padrão: 300)\r\n *\r\n * @example\r\n * smoothScrollTo(0, 500, 500); // Animação de 500ms para rolar 500px\r\n */\r\nexport function smoothScrollTo(\r\n x: number,\r\n y: number,\r\n duration: number = 300\r\n): void {\r\n if (typeof window === 'undefined') return;\r\n \r\n const startX = window.scrollX;\r\n const startY = window.scrollY;\r\n const distanceX = x - startX;\r\n const distanceY = y - startY;\r\n const startTime = performance.now();\r\n \r\n function animate(currentTime: number): void {\r\n const elapsed = currentTime - startTime;\r\n const progress = Math.min(elapsed / duration, 1);\r\n \r\n // Easing function (ease-out)\r\n const easeProgress = 1 - Math.pow(1 - progress, 3);\r\n \r\n const currentX = startX + (distanceX * easeProgress);\r\n const currentY = startY + (distanceY * easeProgress);\r\n \r\n window.scrollTo(currentX, currentY);\r\n \r\n if (progress < 1) {\r\n requestAnimationFrame(animate);\r\n }\r\n }\r\n \r\n requestAnimationFrame(animate);\r\n}\r\n\r\n/**\r\n * Rola para um elemento específico\r\n *\r\n * @param element - Elemento ou seletor CSS\r\n * @param options - Opções de scroll\r\n *\r\n * @example\r\n * scrollToElement('#my-element'); // Scroll instantâneo\r\n * scrollToElement('.section', { smooth: true, offset: 100 }); // Scroll suave com offset\r\n */\r\nexport function scrollToElement(\r\n element: string | Element,\r\n options: {\r\n smooth?: boolean;\r\n offset?: number;\r\n behavior?: ScrollBehavior;\r\n } = {}\r\n): void {\r\n if (typeof window === 'undefined') return;\r\n \r\n const { smooth = false, offset = 0, behavior } = options;\r\n \r\n let targetElement: Element | null;\r\n \r\n if (typeof element === 'string') {\r\n targetElement = document.querySelector(element);\r\n } else {\r\n targetElement = element;\r\n }\r\n \r\n if (!targetElement) return;\r\n \r\n const rect = targetElement.getBoundingClientRect();\r\n const absoluteY = rect.top + window.scrollY - offset;\r\n \r\n window.scrollTo({\r\n left: 0,\r\n top: absoluteY,\r\n behavior: behavior || (smooth ? 'smooth' : 'auto')\r\n });\r\n}\r\n\r\n/**\r\n * Verifica se elemento está visível na viewport\r\n *\r\n * @param element - Elemento ou seletor CSS\r\n * @param threshold - Limiar de visibilidade (0 a 1, padrão: 0)\r\n * @returns true se elemento estiver visível\r\n *\r\n * @example\r\n * isElementVisible('#my-element'); // true se elemento estiver na viewport\r\n * isElementVisible('.section', 0.5); // true se 50% do elemento estiver visível\r\n */\r\nexport function isElementVisible(\r\n element: string | Element,\r\n threshold: number = 0\r\n): boolean {\r\n if (typeof window === 'undefined') return false;\r\n \r\n let targetElement: Element | null;\r\n \r\n if (typeof element === 'string') {\r\n targetElement = document.querySelector(element);\r\n } else {\r\n targetElement = element;\r\n }\r\n \r\n if (!targetElement) return false;\r\n \r\n const rect = targetElement.getBoundingClientRect();\r\n const windowHeight = window.innerHeight;\r\n const windowWidth = window.innerWidth;\r\n \r\n const verticalThreshold = windowHeight * threshold;\r\n const horizontalThreshold = windowWidth * threshold;\r\n \r\n const isVisibleVertically = \r\n rect.bottom >= verticalThreshold && \r\n rect.top <= windowHeight - verticalThreshold;\r\n \r\n const isVisibleHorizontally = \r\n rect.right >= horizontalThreshold && \r\n rect.left <= windowWidth - horizontalThreshold;\r\n \r\n return isVisibleVertically && isVisibleHorizontally;\r\n}\r\n\r\n/**\r\n * Obtém a posição de um elemento em relação ao documento\r\n *\r\n * @param element - Elemento ou seletor CSS\r\n * @returns Posição { x, y } ou null se elemento não for encontrado\r\n *\r\n * @example\r\n * const position = getElementPosition('#my-element');\r\n * console.log('X:', position.x, 'Y:', position.y);\r\n */\r\nexport function getElementPosition(\r\n element: string | Element\r\n): { x: number; y: number } | null {\r\n if (typeof window === 'undefined') return null;\r\n \r\n let targetElement: Element | null;\r\n \r\n if (typeof element === 'string') {\r\n targetElement = document.querySelector(element);\r\n } else {\r\n targetElement = element;\r\n }\r\n \r\n if (!targetElement) return null;\r\n \r\n const rect = targetElement.getBoundingClientRect();\r\n \r\n return {\r\n x: rect.left + window.scrollX,\r\n y: rect.top + window.scrollY\r\n };\r\n}\r\n\r\n/**\r\n * Verifica se está em dispositivo móvel\r\n *\r\n * @returns true se for dispositivo móvel\r\n *\r\n * @example\r\n * if (isMobile()) {\r\n * // Aplicar layout mobile\r\n * }\r\n */\r\nexport function isMobile(): boolean {\r\n if (typeof window === 'undefined') return false;\r\n \r\n // Verificar User Agent\r\n const isMobileUA = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(\r\n navigator.userAgent\r\n );\r\n \r\n // Verificar tamanho de tela (fallback)\r\n const isMobileScreen = window.innerWidth <= 768;\r\n \r\n return isMobileUA || isMobileScreen;\r\n}\r\n\r\n/**\r\n * Verifica se está em modo escuro\r\n *\r\n * @returns true se o sistema preferir modo escuro\r\n *\r\n * @example\r\n * if (isDarkMode()) {\r\n * // Aplicar tema escuro\r\n * }\r\n */\r\nexport function isDarkMode(): boolean {\r\n if (typeof window === 'undefined') return false;\r\n \r\n return window.matchMedia('(prefers-color-scheme: dark)').matches;\r\n}\r\n\r\n/**\r\n * Adiciona listener para mudanças no tema do sistema\r\n *\r\n * @param callback - Função chamada quando o tema muda\r\n * @returns Função para remover o listener\r\n *\r\n * @example\r\n * const unsubscribe = onDarkModeChange((isDark) => {\r\n * console.log('Theme changed:', isDark ? 'dark' : 'light');\r\n * });\r\n */\r\nexport function onDarkModeChange(\r\n callback: (isDark: boolean) => void\r\n): () => void {\r\n if (typeof window === 'undefined') {\r\n return () => {};\r\n }\r\n \r\n const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');\r\n \r\n const handleChange = (e: MediaQueryListEvent) => {\r\n callback(e.matches);\r\n };\r\n \r\n // Adicionar listener\r\n if (mediaQuery.addEventListener) {\r\n mediaQuery.addEventListener('change', handleChange);\r\n } else {\r\n (mediaQuery as any).addListener(handleChange);\r\n }\r\n \r\n // Retornar função de cleanup\r\n return () => {\r\n if (mediaQuery.removeEventListener) {\r\n mediaQuery.removeEventListener('change', handleChange);\r\n } else {\r\n (mediaQuery as any).removeListener(handleChange);\r\n }\r\n };\r\n}\r\n\r\n/**\r\n * Copia texto para a área de transferência\r\n *\r\n * @param text - Texto para copiar\r\n * @returns Promise que resolve para true se sucesso\r\n *\r\n * @example\r\n * copyToClipboard('Hello World').then(success => {\r\n * if (success) {\r\n * console.log('Texto copiado!');\r\n * }\r\n * });\r\n */\r\nexport async function copyToClipboard(text: string): Promise<boolean> {\r\n if (typeof window === 'undefined') return false;\r\n \r\n try {\r\n // Tentar usar a API moderna\r\n if (navigator.clipboard && window.isSecureContext) {\r\n await navigator.clipboard.writeText(text);\r\n return true;\r\n }\r\n \r\n // Fallback para browsers mais antigos\r\n const textArea = document.createElement('textarea');\r\n textArea.value = text;\r\n textArea.style.position = 'fixed';\r\n textArea.style.left = '-999999px';\r\n textArea.style.top = '-999999px';\r\n document.body.appendChild(textArea);\r\n textArea.focus();\r\n textArea.select();\r\n \r\n const result = document.execCommand('copy');\r\n document.body.removeChild(textArea);\r\n \r\n return result;\r\n } catch {\r\n return false;\r\n }\r\n}\r\n\r\n/**\r\n * Baixa um arquivo como blob\r\n *\r\n * @param blob - Blob para baixar\r\n * @param filename - Nome do arquivo\r\n *\r\n * @example\r\n * downloadFile(new Blob(['Hello World'], { type: 'text/plain' }), 'hello.txt');\r\n */\r\nexport function downloadFile(blob: Blob, filename: string): void {\r\n if (typeof window === 'undefined') return;\r\n \r\n const url = URL.createObjectURL(blob);\r\n const link = document.createElement('a');\r\n link.href = url;\r\n link.download = filename;\r\n document.body.appendChild(link);\r\n link.click();\r\n document.body.removeChild(link);\r\n URL.revokeObjectURL(url);\r\n}\r\n","/**\r\n * useAuth Hook - Authentication Management\r\n * \r\n * Hook React profissional para gerenciar estado de autenticação.\r\n * Implementa padrões de segurança, persistência e tratamento de erros.\r\n * \r\n * @module @rainersoft/utils/hooks\r\n * @author Rainer Teixeira\r\n * @version 2.0.0\r\n * @since 1.0.0\r\n */\r\n\r\nimport { useCallback, useEffect, useState, useRef } from 'react';\r\n\r\n// ============================================================================\r\n// TYPES & INTERFACES\r\n// ============================================================================\r\n\r\nexport interface UserProfile {\r\n id: string;\r\n nickname: string;\r\n email?: string;\r\n emailVerified?: boolean;\r\n role?: UserRole;\r\n avatar?: string;\r\n createdAt?: string;\r\n updatedAt?: string;\r\n lastLoginAt?: string;\r\n}\r\n\r\nexport enum UserRole {\r\n ADMIN = 'admin',\r\n MODERATOR = 'moderator',\r\n USER = 'user',\r\n GUEST = 'guest'\r\n}\r\n\r\nexport interface LoginCredentials {\r\n email: string;\r\n password: string;\r\n rememberMe?: boolean;\r\n}\r\n\r\nexport interface RegisterData {\r\n nickname: string;\r\n email: string;\r\n password: string;\r\n confirmPassword: string;\r\n role?: UserRole;\r\n}\r\n\r\nexport interface LogoutOptions {\r\n invalidateAllSessions?: boolean;\r\n redirectPath?: string;\r\n}\r\n\r\nexport interface AuthResult {\r\n success: boolean;\r\n user?: UserProfile;\r\n token?: string;\r\n refreshToken?: string;\r\n error?: string;\r\n}\r\n\r\nexport interface UseAuthConfig {\r\n autoRefresh?: boolean;\r\n refreshInterval?: number;\r\n tokenStorageKey?: string;\r\n userStorageKey?: string;\r\n apiEndpoint?: string;\r\n onAuthChange?: (user: UserProfile | null) => void;\r\n onError?: (error: string) => void;\r\n}\r\n\r\n// ============================================================================\r\n// DEFAULT CONFIGURATION\r\n// ============================================================================\r\n\r\nconst DEFAULT_CONFIG: Required<UseAuthConfig> = {\r\n autoRefresh: true,\r\n refreshInterval: 15 * 60 * 1000, // 15 minutes\r\n tokenStorageKey: 'auth_token',\r\n userStorageKey: 'auth_user',\r\n apiEndpoint: '/api/auth',\r\n onAuthChange: () => {},\r\n onError: () => {},\r\n};\r\n\r\n// ============================================================================\r\n// STORAGE UTILITIES\r\n// ============================================================================\r\n\r\nclass AuthStorage {\r\n private static isClient = typeof window !== 'undefined';\r\n\r\n static setItem(key: string, value: string): void {\r\n if (!this.isClient) return;\r\n try {\r\n localStorage.setItem(key, value);\r\n } catch (error) {\r\n console.warn('Failed to save to localStorage:', error);\r\n }\r\n }\r\n\r\n static getItem(key: string): string | null {\r\n if (!this.isClient) return null;\r\n try {\r\n return localStorage.getItem(key);\r\n } catch (error) {\r\n console.warn('Failed to read from localStorage:', error);\r\n return null;\r\n }\r\n }\r\n\r\n static removeItem(key: string): void {\r\n if (!this.isClient) return;\r\n try {\r\n localStorage.removeItem(key);\r\n } catch (error) {\r\n console.warn('Failed to remove from localStorage:', error);\r\n }\r\n }\r\n\r\n static setUser(user: UserProfile, key: string): void {\r\n this.setItem(key, JSON.stringify(user));\r\n }\r\n\r\n static getUser(key: string): UserProfile | null {\r\n const data = this.getItem(key);\r\n if (!data) return null;\r\n try {\r\n return JSON.parse(data);\r\n } catch {\r\n this.removeItem(key);\r\n return null;\r\n }\r\n }\r\n\r\n static removeUser(key: string): void {\r\n this.removeItem(key);\r\n }\r\n}\r\n\r\n// ============================================================================\r\n// TOKEN UTILITIES\r\n// ============================================================================\r\n\r\nclass TokenManager {\r\n static decodeToken(token: string): any {\r\n try {\r\n const payload = token.split('.')[1];\r\n const decoded = atob(payload);\r\n return JSON.parse(decoded);\r\n } catch {\r\n return null;\r\n }\r\n }\r\n\r\n static isTokenExpired(token: string): boolean {\r\n const decoded = this.decodeToken(token);\r\n if (!decoded) return true;\r\n \r\n const now = Date.now() / 1000;\r\n return decoded.exp < now;\r\n }\r\n}\r\n\r\n// ============================================================================\r\n// MAIN HOOK\r\n// ============================================================================\r\n\r\nexport function useAuth(config: Partial<UseAuthConfig> = {}) {\r\n const configRef = useRef({ ...DEFAULT_CONFIG, ...config });\r\n const cfg = configRef.current;\r\n \r\n const [user, setUser] = useState<UserProfile | null>(null);\r\n const [loading, setLoading] = useState(false);\r\n const [error, setError] = useState<string | null>(null);\r\n const [isAuthenticated, setIsAuthenticated] = useState(false);\r\n\r\n const refreshTimerRef = useRef<NodeJS.Timeout | null>(null);\r\n\r\n // ============================================================================\r\n // TOKEN MANAGEMENT\r\n // ============================================================================\r\n\r\n const storeToken = useCallback((token: string, refreshToken?: string) => {\r\n AuthStorage.setItem(cfg.tokenStorageKey, token);\r\n if (refreshToken) {\r\n AuthStorage.setItem(`${cfg.tokenStorageKey}_refresh`, refreshToken);\r\n }\r\n }, [cfg.tokenStorageKey]);\r\n\r\n const getStoredToken = useCallback((): string | null => {\r\n return AuthStorage.getItem(cfg.tokenStorageKey);\r\n }, [cfg.tokenStorageKey]);\r\n\r\n const clearTokens = useCallback((): void => {\r\n AuthStorage.removeItem(cfg.tokenStorageKey);\r\n AuthStorage.removeItem(`${cfg.tokenStorageKey}_refresh`);\r\n }, [cfg.tokenStorageKey]);\r\n\r\n // ============================================================================\r\n // API CALLS\r\n // ============================================================================\r\n\r\n const apiCall = useCallback(async (\r\n endpoint: string,\r\n options: RequestInit = {}\r\n ): Promise<any> => {\r\n const token = getStoredToken();\r\n const url = `${cfg.apiEndpoint}${endpoint}`;\r\n \r\n const response = await fetch(url, {\r\n ...options,\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n ...(token && { Authorization: `Bearer ${token}` }),\r\n ...options.headers,\r\n },\r\n });\r\n\r\n if (!response.ok) {\r\n const error = await response.text();\r\n throw new Error(error || `HTTP ${response.status}`);\r\n }\r\n\r\n return response.json();\r\n }, [cfg.apiEndpoint, getStoredToken]);\r\n\r\n // ============================================================================\r\n // AUTH ACTIONS\r\n // ============================================================================\r\n\r\n const login = useCallback(async (credentials: LoginCredentials): Promise<AuthResult> => {\r\n setLoading(true);\r\n setError(null);\r\n\r\n try {\r\n const response = await apiCall('/login', {\r\n method: 'POST',\r\n body: JSON.stringify(credentials),\r\n });\r\n\r\n if (response.success && response.user && response.token) {\r\n setUser(response.user);\r\n setIsAuthenticated(true);\r\n storeToken(response.token, response.refreshToken);\r\n \r\n if (cfg.onAuthChange) {\r\n cfg.onAuthChange(response.user);\r\n }\r\n \r\n return { success: true, user: response.user, token: response.token };\r\n } else {\r\n const errorMsg = response.error || 'Login failed';\r\n setError(errorMsg);\r\n if (cfg.onError) cfg.onError(errorMsg);\r\n return { success: false, error: errorMsg };\r\n }\r\n } catch (error) {\r\n const errorMsg = error instanceof Error ? error.message : 'Login failed';\r\n setError(errorMsg);\r\n if (cfg.onError) cfg.onError(errorMsg);\r\n return { success: false, error: errorMsg };\r\n } finally {\r\n setLoading(false);\r\n }\r\n }, [apiCall, setUser, storeToken, cfg]);\r\n\r\n const logout = useCallback(async (options: LogoutOptions = {}): Promise<void> => {\r\n try {\r\n if (options.invalidateAllSessions) {\r\n await apiCall('/logout', { method: 'POST' });\r\n }\r\n } catch (error) {\r\n console.warn('Logout API call failed:', error);\r\n } finally {\r\n setUser(null);\r\n setIsAuthenticated(false);\r\n clearTokens();\r\n \r\n if (refreshTimerRef.current) {\r\n clearInterval(refreshTimerRef.current);\r\n refreshTimerRef.current = null;\r\n }\r\n \r\n if (cfg.onAuthChange) {\r\n cfg.onAuthChange(null);\r\n }\r\n }\r\n }, [apiCall, clearTokens, cfg]);\r\n\r\n const register = useCallback(async (userData: RegisterData): Promise<AuthResult> => {\r\n setLoading(true);\r\n setError(null);\r\n\r\n try {\r\n const response = await apiCall('/register', {\r\n method: 'POST',\r\n body: JSON.stringify(userData),\r\n });\r\n\r\n if (response.success && response.user && response.token) {\r\n setUser(response.user);\r\n setIsAuthenticated(true);\r\n storeToken(response.token, response.refreshToken);\r\n \r\n if (cfg.onAuthChange) {\r\n cfg.onAuthChange(response.user);\r\n }\r\n \r\n return { success: true, user: response.user, token: response.token };\r\n } else {\r\n const errorMsg = response.error || 'Registration failed';\r\n setError(errorMsg);\r\n if (cfg.onError) cfg.onError(errorMsg);\r\n return { success: false, error: errorMsg };\r\n }\r\n } catch (error) {\r\n const errorMsg = error instanceof Error ? error.message : 'Registration failed';\r\n setError(errorMsg);\r\n if (cfg.onError) cfg.onError(errorMsg);\r\n return { success: false, error: errorMsg };\r\n } finally {\r\n setLoading(false);\r\n }\r\n }, [apiCall, setUser, storeToken, cfg]);\r\n\r\n const updateProfile = useCallback(async (data: Partial<UserProfile>): Promise<AuthResult> => {\r\n if (!user) {\r\n const error = 'No user logged in';\r\n setError(error);\r\n if (cfg.onError) cfg.onError(error);\r\n return { success: false, error };\r\n }\r\n\r\n setLoading(true);\r\n setError(null);\r\n\r\n try {\r\n const response = await apiCall('/profile', {\r\n method: 'PUT',\r\n body: JSON.stringify(data),\r\n });\r\n\r\n if (response.success && response.user) {\r\n setUser(response.user);\r\n \r\n if (cfg.onAuthChange) {\r\n cfg.onAuthChange(response.user);\r\n }\r\n \r\n return { success: true, user: response.user };\r\n } else {\r\n const errorMsg = response.error || 'Profile update failed';\r\n setError(errorMsg);\r\n if (cfg.onError) cfg.onError(errorMsg);\r\n return { success: false, error: errorMsg };\r\n }\r\n } catch (error) {\r\n const errorMsg = error instanceof Error ? error.message : 'Profile update failed';\r\n setError(errorMsg);\r\n if (cfg.onError) cfg.onError(errorMsg);\r\n return { success: false, error: errorMsg };\r\n } finally {\r\n setLoading(false);\r\n }\r\n }, [apiCall, user, setUser, cfg]);\r\n\r\n const refreshToken = useCallback(async (): Promise<AuthResult> => {\r\n const refreshToken = AuthStorage.getItem(`${cfg.tokenStorageKey}_refresh`);\r\n if (!refreshToken) {\r\n return { success: false, error: 'No refresh token available' };\r\n }\r\n\r\n try {\r\n const response = await apiCall('/refresh', {\r\n method: 'POST',\r\n body: JSON.stringify({ refreshToken }),\r\n });\r\n\r\n if (response.success && response.token && response.user) {\r\n setUser(response.user);\r\n storeToken(response.token, response.refreshToken);\r\n \r\n if (cfg.onAuthChange) {\r\n cfg.onAuthChange(response.user);\r\n }\r\n \r\n return { success: true, user: response.user, token: response.token };\r\n } else {\r\n // Refresh failed, logout user\r\n await logout();\r\n return { success: false, error: 'Session expired' };\r\n }\r\n } catch (error) {\r\n await logout();\r\n return { success: false, error: 'Session expired' };\r\n }\r\n }, [apiCall, setUser, storeToken, logout, cfg]);\r\n\r\n const resetError = useCallback(() => {\r\n setError(null);\r\n }, []);\r\n\r\n // ============================================================================\r\n // INITIALIZATION\r\n // ============================================================================\r\n\r\n useEffect(() => {\r\n // Verificar autenticação existente ao montar\r\n const token = getStoredToken();\r\n const storedUser = AuthStorage.getUser(cfg.userStorageKey);\r\n\r\n if (token && storedUser && !TokenManager.isTokenExpired(token)) {\r\n setUser(storedUser);\r\n setIsAuthenticated(true);\r\n \r\n if (cfg.onAuthChange) {\r\n cfg.onAuthChange(storedUser);\r\n }\r\n } else if (token && TokenManager.isTokenExpired(token)) {\r\n // Token expirado, tentar refresh\r\n refreshToken();\r\n } else {\r\n setLoading(false);\r\n }\r\n\r\n return () => {\r\n if (refreshTimerRef.current) {\r\n clearInterval(refreshTimerRef.current);\r\n }\r\n };\r\n }, []);\r\n\r\n return {\r\n user,\r\n loading,\r\n error,\r\n isAuthenticated,\r\n login,\r\n logout,\r\n register,\r\n updateProfile,\r\n refreshToken,\r\n resetError,\r\n };\r\n}\r\n\r\n// ============================================================================\r\n// UTILITY HOOKS\r\n// ============================================================================\r\n\r\nexport function useIsAuthenticated(): boolean {\r\n const { isAuthenticated } = useAuth();\r\n return isAuthenticated;\r\n}\r\n\r\nexport function useCurrentUser(): UserProfile | null {\r\n const { user } = useAuth();\r\n return user;\r\n}\r\n\r\nexport function useHasRole(role: UserRole): boolean {\r\n const { user } = useAuth();\r\n return user?.role === role;\r\n}\r\n\r\nexport function useIsAdmin(): boolean {\r\n return useHasRole(UserRole.ADMIN);\r\n}\r\n","/**\r\n * Stats Formatting Utilities\r\n *\r\n * Utilitários universais para formatação de estatísticas e números.\r\n *\r\n * @module @rainersoft/utils/stats\r\n * @author Rainer Teixeira\r\n * @version 1.0.0\r\n */\r\n\r\n/**\r\n * Formata número grande com abreviação (1.5k, 2.3M, etc)\r\n *\r\n * @param num - Número para formatar\r\n * @returns String formatada com abreviação\r\n *\r\n * @example\r\n * ```ts\r\n * formatNumber(1500) // '1.5k'\r\n * formatNumber(2500000) // '2.5M'\r\n * formatNumber(999) // '999'\r\n * ```\r\n */\r\nexport function formatNumber(num: number): string {\r\n if (num >= 1000000) {\r\n return (num / 1000000).toFixed(1) + 'M';\r\n }\r\n if (num >= 1000) {\r\n return (num / 1000).toFixed(1) + 'k';\r\n }\r\n return num.toString();\r\n}\r\n\r\n/**\r\n * Calcula percentual de mudança entre dois valores\r\n *\r\n * @param current - Valor atual\r\n * @param previous - Valor anterior\r\n * @returns Percentual de mudança (arredondado)\r\n *\r\n * @example\r\n * ```ts\r\n * calculateChange(150, 100) // 50\r\n * calculateChange(80, 100) // -20\r\n * calculateChange(100, 0) // 100\r\n * ```\r\n */\r\nexport function calculateChange(current: number, previous: number): number {\r\n if (previous === 0) return 100;\r\n return Math.round(((current - previous) / previous) * 100);\r\n}\r\n\r\n/**\r\n * Formata percentual com sinal\r\n *\r\n * @param value - Valor do percentual\r\n * @param options - Opções de formatação\r\n * @returns String formatada com sinal e símbolo\r\n *\r\n * @example\r\n * ```ts\r\n * formatPercentage(25) // '+25%'\r\n * formatPercentage(-10) // '-10%'\r\n * formatPercentage(0) // '0%'\r\n * ```\r\n */\r\nexport function formatPercentage(\r\n value: number,\r\n options: { showSign?: boolean; decimals?: number } = {}\r\n): string {\r\n const { showSign = true, decimals = 0 } = options;\r\n \r\n const sign = showSign && value > 0 ? '+' : '';\r\n const formattedValue = value.toFixed(decimals);\r\n \r\n return `${sign}${formattedValue}%`;\r\n}\r\n\r\n/**\r\n * Gera dados de exemplo para gráficos\r\n *\r\n * @param days - Número de dias para gerar dados\r\n * @param locale - Idioma para formatação de datas\r\n * @returns Array de dados mock\r\n *\r\n * @example\r\n * ```ts\r\n * const data = generateMockChartData(7);\r\n * // [\r\n * // { date: '01/12', views: 1234, uniqueViews: 890, likes: 67, comments: 23 },\r\n * // ...\r\n * // ]\r\n * ```\r\n */\r\nexport function generateMockChartData(\r\n days: number,\r\n locale: string = 'pt-BR'\r\n): Array<Record<string, any>> {\r\n const data = [];\r\n const now = new Date();\r\n\r\n for (let i = days - 1; i >= 0; i--) {\r\n const date = new Date(now);\r\n date.setDate(date.getDate() - i);\r\n\r\n data.push({\r\n date: date.toLocaleDateString(locale, {\r\n day: '2-digit',\r\n month: '2-digit',\r\n }),\r\n views: Math.floor(Math.random() * 1000) + 500,\r\n uniqueViews: Math.floor(Math.random() * 700) + 300,\r\n likes: Math.floor(Math.random() * 100) + 50,\r\n comments: Math.floor(Math.random() * 50) + 10,\r\n shares: Math.floor(Math.random() * 30) + 5,\r\n });\r\n }\r\n\r\n return data;\r\n}\r\n\r\n/**\r\n * Agrupa dados por período (dia, semana, mês)\r\n *\r\n * @param data - Array de dados para agrupar\r\n * @param period - Período de agrupamento\r\n * @param dateField - Campo de data nos objetos\r\n * @returns Array de dados agrupados\r\n *\r\n * @example\r\n * ```ts\r\n * const grouped = groupDataByPeriod(data, 'week', 'date');\r\n * ```\r\n */\r\nexport function groupDataByPeriod<T extends Record<string, any>>(\r\n data: T[],\r\n // period: 'day' | 'week' | 'month' = 'day', // Pode ser usado futuramente para agrupamento\r\n // dateField: keyof T = 'date' as keyof T\r\n): T[] {\r\n // Implementação simplificada - pode ser expandida\r\n // Por enquanto, retorna os dados originais\r\n return data;\r\n}\r\n\r\n/**\r\n * Calcula médias móveis para suavizar dados\r\n *\r\n * @param data - Array de valores numéricos\r\n * @param window - Tamanho da janela de média móvel\r\n * @returns Array com médias móveis\r\n *\r\n * @example\r\n * ```ts\r\n * const smoothed = calculateMovingAverage([1, 2, 3, 4, 5], 3);\r\n * // [2, 3, 4] (médias de [1,2,3], [2,3,4], [3,4,5])\r\n * ```\r\n */\r\nexport function calculateMovingAverage(data: number[], window: number): number[] {\r\n const result: number[] = [];\r\n \r\n for (let i = window - 1; i < data.length; i++) {\r\n const sum = data.slice(i - window + 1, i + 1).reduce((a, b) => a + b, 0);\r\n result.push(sum / window);\r\n }\r\n \r\n return result;\r\n}\r\n\r\n/**\r\n * Encontra valor máximo e mínimo em array de objetos\r\n *\r\n * @param data - Array de objetos\r\n * @param field - Campo para analisar\r\n * @returns Objeto com min e max\r\n *\r\n * @example\r\n * ```ts\r\n * const { min, max } = findMinMax(data, 'views');\r\n * ```\r\n */\r\nexport function findMinMax<T extends Record<string, any>>(\r\n data: T[],\r\n field: keyof T\r\n): { min: number; max: number } {\r\n const values = data.map(item => Number(item[field]) || 0);\r\n \r\n return {\r\n min: Math.min(...values),\r\n max: Math.max(...values)\r\n };\r\n}\r\n","/**\r\n * Auth Utilities\r\n *\r\n * Utilitários para gerenciamento de tokens de autenticação.\r\n * Funções para armazenar, recuperar e remover tokens JWT do localStorage.\r\n *\r\n * @module @rainersoft/utils/auth\r\n * @author Rainer Teixeira\r\n * @version 1.0.0\r\n */\r\n\r\nconst TOKEN_KEY = 'auth_token';\r\nconst REFRESH_TOKEN_KEY = 'refresh_token';\r\n\r\n/**\r\n * Obtém o token de acesso armazenado\r\n * \r\n * @returns string | null - Token JWT ou null se não encontrado\r\n * \r\n * @example\r\n * ```ts\r\n * const token = getToken();\r\n * if (token) {\r\n * // Usar token na requisição\r\n * }\r\n * ```\r\n */\r\nexport const getToken = (): string | null => {\r\n if (typeof window === 'undefined') {\r\n return null;\r\n }\r\n \r\n return localStorage.getItem(TOKEN_KEY);\r\n};\r\n\r\n/**\r\n * Define o token de acesso\r\n * \r\n * @param token - Token JWT a ser armazenado\r\n * \r\n * @example\r\n * ```ts\r\n * setToken('eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...');\r\n * ```\r\n */\r\nexport const setToken = (token: string): void => {\r\n if (typeof window === 'undefined') {\r\n return;\r\n }\r\n \r\n localStorage.setItem(TOKEN_KEY, token);\r\n};\r\n\r\n/**\r\n * Obtém o refresh token armazenado\r\n * \r\n * @returns string | null - Refresh token ou null se não encontrado\r\n * \r\n * @example\r\n * ```ts\r\n * const refreshToken = getRefreshToken();\r\n * ```\r\n */\r\nexport const getRefreshToken = (): string | null => {\r\n if (typeof window === 'undefined') {\r\n return null;\r\n }\r\n \r\n return localStorage.getItem(REFRESH_TOKEN_KEY);\r\n};\r\n\r\n/**\r\n * Define o refresh token\r\n * \r\n * @param refreshToken - Refresh token a ser armazenado\r\n * \r\n * @example\r\n * ```ts\r\n * setRefreshToken('refresh_token_here');\r\n * ```\r\n */\r\nexport const setRefreshToken = (refreshToken: string): void => {\r\n if (typeof window === 'undefined') {\r\n return;\r\n }\r\n \r\n localStorage.setItem(REFRESH_TOKEN_KEY, refreshToken);\r\n};\r\n\r\n/**\r\n * Remove todos os tokens armazenados\r\n * \r\n * @example\r\n * ```ts\r\n * // Logout do usuário\r\n * removeToken();\r\n * ```\r\n */\r\nexport const removeToken = (): void => {\r\n if (typeof window === 'undefined') {\r\n return;\r\n }\r\n \r\n localStorage.removeItem(TOKEN_KEY);\r\n localStorage.removeItem(REFRESH_TOKEN_KEY);\r\n};\r\n\r\n/**\r\n * Verifica se há um token válido armazenado\r\n * \r\n * @returns boolean - True se token existe\r\n * \r\n * @example\r\n * ```ts\r\n * if (hasToken()) {\r\n * // Usuário autenticado\r\n * }\r\n * ```\r\n */\r\nexport const hasToken = (): boolean => {\r\n return !!getToken();\r\n};\r\n\r\n/**\r\n * Obtém os tokens como objeto\r\n * \r\n * @returns object - Com accessToken e refreshToken\r\n * \r\n * @example\r\n * ```ts\r\n * const { accessToken, refreshToken } = getTokens();\r\n * ```\r\n */\r\nexport const getTokens = (): {\r\n accessToken: string | null;\r\n refreshToken: string | null;\r\n} => {\r\n return {\r\n accessToken: getToken(),\r\n refreshToken: getRefreshToken(),\r\n };\r\n};\r\n\r\n/**\r\n * Define ambos os tokens de uma vez\r\n * \r\n * @param accessToken - Token de acesso\r\n * @param refreshToken - Token de refresh\r\n * \r\n * @example\r\n * ```ts\r\n * setTokens({\r\n * accessToken: 'access_token_here',\r\n * refreshToken: 'refresh_token_here'\r\n * });\r\n * ```\r\n */\r\nexport const setTokens = ({\r\n accessToken,\r\n refreshToken,\r\n}: {\r\n accessToken: string;\r\n refreshToken: string;\r\n}): void => {\r\n setToken(accessToken);\r\n setRefreshToken(refreshToken);\r\n};\r\n","/**\r\n * Search Utilities\r\n *\r\n * Utilitários genéricos para busca e filtro de conteúdo.\r\n * Funções puras, agnósticas de domínio e framework.\r\n *\r\n * @module @rainersoft/utils/search\r\n * @author Rainer Teixeira\r\n * @version 1.0.0\r\n */\r\n\r\n/**\r\n * Opções de busca\r\n */\r\nexport interface SearchOptions {\r\n /** Campos a buscar (padrão: ['title', 'description', 'content', 'tags']) */\r\n fields?: string[];\r\n /** Case sensitive (padrão: false) */\r\n caseSensitive?: boolean;\r\n /** Busca exata (padrão: false) */\r\n exactMatch?: boolean;\r\n}\r\n\r\n/**\r\n * Busca genérica em array de objetos\r\n *\r\n * Função de busca client-side para arrays de objetos genéricos.\r\n * Busca em múltiplos campos configuráveis.\r\n *\r\n * @param query - Termo de busca\r\n * @param content - Array de objetos a buscar\r\n * @param options - Opções de busca\r\n * @returns Array filtrado com resultados\r\n *\r\n * @example\r\n * ```ts\r\n * const posts = [\r\n * { title: 'Next.js Guide', description: 'Learn Next.js' },\r\n * { title: 'React Basics', description: 'React fundamentals' }\r\n * ];\r\n * \r\n * searchContent('next', posts) // [{ title: 'Next.js Guide', ... }]\r\n * searchContent('react', posts, { fields: ['title'] }) // [{ title: 'React Basics', ... }]\r\n * ```\r\n */\r\nexport function searchContent<T extends Record<string, any>>(\r\n query: string,\r\n content: T[],\r\n options: SearchOptions = {}\r\n): T[] {\r\n if (!query.trim()) return content;\r\n \r\n const {\r\n fields = ['title', 'description', 'content', 'tags'],\r\n caseSensitive = false,\r\n exactMatch = false\r\n } = options;\r\n \r\n const searchQuery = caseSensitive ? query : query.toLowerCase();\r\n \r\n return content.filter(item => {\r\n return fields.some(field => {\r\n const value = item[field];\r\n \r\n if (!value) return false;\r\n \r\n // Se for array (ex: tags)\r\n if (Array.isArray(value)) {\r\n return value.some(v => {\r\n const strValue = caseSensitive ? String(v) : String(v).toLowerCase();\r\n return exactMatch \r\n ? strValue === searchQuery \r\n : strValue.includes(searchQuery);\r\n });\r\n }\r\n \r\n // Se for string\r\n const strValue = caseSensitive ? String(value) : String(value).toLowerCase();\r\n return exactMatch \r\n ? strValue === searchQuery \r\n : strValue.includes(searchQuery);\r\n });\r\n });\r\n}\r\n\r\n/**\r\n * Busca com score de relevância\r\n *\r\n * Retorna resultados ordenados por relevância baseado em:\r\n * - Correspondência no título (peso maior)\r\n * - Correspondência na descrição\r\n * - Correspondência em outros campos\r\n *\r\n * @param query - Termo de busca\r\n * @param content - Array de objetos a buscar\r\n * @param options - Opções de busca\r\n * @returns Array ordenado por relevância\r\n *\r\n * @example\r\n * ```ts\r\n * const results = searchWithScore('next', posts);\r\n * // Resultados com título contendo 'next' aparecem primeiro\r\n * ```\r\n */\r\nexport function searchWithScore<T extends Record<string, any>>(\r\n query: string,\r\n content: T[],\r\n options: SearchOptions = {}\r\n): T[] {\r\n if (!query.trim()) return content;\r\n \r\n const {\r\n fields = ['title', 'description', 'content', 'tags'],\r\n caseSensitive = false\r\n } = options;\r\n \r\n const searchQuery = caseSensitive ? query : query.toLowerCase();\r\n \r\n // Calcula score para cada item\r\n const scored = content.map(item => {\r\n let score = 0;\r\n \r\n fields.forEach((field, index) => {\r\n const value = item[field];\r\n if (!value) return;\r\n \r\n const weight = fields.length - index; // Primeiro campo tem maior peso\r\n \r\n if (Array.isArray(value)) {\r\n const matches = value.filter(v => {\r\n const strValue = caseSensitive ? String(v) : String(v).toLowerCase();\r\n return strValue.includes(searchQuery);\r\n }).length;\r\n score += matches * weight;\r\n } else {\r\n const strValue = caseSensitive ? String(value) : String(value).toLowerCase();\r\n if (strValue.includes(searchQuery)) {\r\n score += weight;\r\n // Bonus se for match exato\r\n if (strValue === searchQuery) {\r\n score += weight * 2;\r\n }\r\n }\r\n }\r\n });\r\n \r\n return { item, score };\r\n });\r\n \r\n // Filtra apenas com score > 0 e ordena\r\n return scored\r\n .filter(({ score }) => score > 0)\r\n .sort((a, b) => b.score - a.score)\r\n .map(({ item }) => item);\r\n}\r\n\r\n/**\r\n * Busca fuzzy (tolerante a erros de digitação)\r\n *\r\n * Usa distância de Levenshtein simplificada para encontrar\r\n * correspondências aproximadas.\r\n *\r\n * @param query - Termo de busca\r\n * @param content - Array de objetos a buscar\r\n * @param options - Opções de busca + threshold\r\n * @returns Array com correspondências aproximadas\r\n *\r\n * @example\r\n * ```ts\r\n * fuzzySearch('nxt', posts) // Encontra 'next'\r\n * fuzzySearch('raect', posts) // Encontra 'react'\r\n * ```\r\n */\r\nexport function fuzzySearch<T extends Record<string, any>>(\r\n query: string,\r\n content: T[],\r\n options: SearchOptions & { threshold?: number } = {}\r\n): T[] {\r\n if (!query.trim()) return content;\r\n \r\n const {\r\n fields = ['title', 'description'],\r\n caseSensitive = false,\r\n threshold = 0.6 // Similaridade mínima (0-1)\r\n } = options;\r\n \r\n const searchQuery = caseSensitive ? query : query.toLowerCase();\r\n \r\n return content.filter(item => {\r\n return fields.some(field => {\r\n const value = item[field];\r\n if (!value) return false;\r\n \r\n const strValue = caseSensitive ? String(value) : String(value).toLowerCase();\r\n const similarity = calculateSimilarity(searchQuery, strValue);\r\n \r\n return similarity >= threshold;\r\n });\r\n });\r\n}\r\n\r\n/**\r\n * Calcula similaridade entre duas strings (0-1)\r\n * Usa algoritmo de Jaro-Winkler simplificado\r\n */\r\nfunction calculateSimilarity(str1: string, str2: string): number {\r\n if (str1 === str2) return 1;\r\n if (str1.length === 0 || str2.length === 0) return 0;\r\n \r\n // Busca substring\r\n if (str2.includes(str1)) return 0.8;\r\n \r\n // Calcula caracteres em comum\r\n const common = str1.split('').filter(char => str2.includes(char)).length;\r\n const similarity = common / Math.max(str1.length, str2.length);\r\n \r\n return similarity;\r\n}\r\n","/**\r\n * String Utilities\r\n *\r\n * Utilitários para manipulação e formatação de strings.\r\n * Funções puras, sem dependências externas, prontas para qualquer plataforma.\r\n *\r\n * @module @rainersoft/utils/string\r\n * @author Rainer Teixeira\r\n */\r\n\r\n/**\r\n * Converte texto para slug URL-friendly\r\n *\r\n * @param text - Texto para converter\r\n * @returns Slug normalizado\r\n *\r\n * @example\r\n * textToSlug('Meu Post Incrível!') // 'meu-post-incrivel'\r\n * textToSlug('São Paulo - SP') // 'sao-paulo-sp'\r\n */\r\nexport function textToSlug(text: string): string {\r\n return text\r\n .toLowerCase()\r\n .normalize('NFD')\r\n .replace(/[\\u0300-\\u036f]/g, '')\r\n .replace(/[^\\w\\s-]/g, '')\r\n .trim()\r\n .replace(/^-+|-+$/g, '') // Remove hífens do início e fim\r\n .replace(/\\s+/g, '-')\r\n .replace(/-+/g, '-');\r\n}\r\n\r\n/**\r\n * Capitaliza primeira letra de cada palavra\r\n *\r\n * @param text - Texto para capitalizar\r\n * @returns Texto capitalizado\r\n *\r\n * @example\r\n * capitalize('rainer teixeira') // 'Rainer Teixeira'\r\n */\r\nexport function capitalize(text: string): string {\r\n return text\r\n .toLowerCase()\r\n .split(' ')\r\n .map(word => word.charAt(0).toUpperCase() + word.slice(1))\r\n .join(' ');\r\n}\r\n\r\n/**\r\n * Trunca texto com ellipsis\r\n *\r\n * @param text - Texto para truncar\r\n * @param maxLength - Comprimento máximo\r\n * @param suffix - Sufixo (padrão: '...')\r\n * @returns Texto truncado\r\n *\r\n * @example\r\n * truncate('Texto muito longo', 10) // 'Texto muit...'\r\n */\r\nexport function truncate(text: string, maxLength: number, suffix = '...'): string {\r\n if (text.length <= maxLength) return text;\r\n return text.slice(0, maxLength - suffix.length) + suffix;\r\n}\r\n\r\n/**\r\n * Remove acentos de texto\r\n *\r\n * @param text - Texto com acentos\r\n * @returns Texto sem acentos\r\n *\r\n * @example\r\n * removeAccents('São Paulo') // 'Sao Paulo'\r\n */\r\nexport function removeAccents(text: string): string {\r\n return text.normalize('NFD').replace(/[\\u0300-\\u036f]/g, '');\r\n}\r\n\r\n/**\r\n * Extrai iniciais de um nome\r\n *\r\n * @param name - Nome completo\r\n * @param maxInitials - Máximo de iniciais (padrão: 2)\r\n * @returns Iniciais em maiúsculas\r\n *\r\n * @example\r\n * getInitials('Rainer Teixeira') // 'RT'\r\n * getInitials('João da Silva Santos', 3) // 'JSS'\r\n */\r\nexport function getInitials(name: string, maxInitials = 2): string {\r\n return name\r\n .split(' ')\r\n .filter(word => word.length > 0)\r\n .map(word => word[0])\r\n .join('')\r\n .toUpperCase()\r\n .slice(0, maxInitials);\r\n}\r\n\r\n/**\r\n * Valida se string é vazia ou apenas espaços\r\n *\r\n * @param text - Texto para validar\r\n * @returns true se vazio, false caso contrário\r\n */\r\nexport function isEmpty(text: string | null | undefined): boolean {\r\n return !text || text.trim().length === 0;\r\n}\r\n\r\n/**\r\n * Conta palavras em um texto\r\n *\r\n * @param text - Texto para contar\r\n * @returns Número de palavras\r\n */\r\nexport function wordCount(text: string): number {\r\n return text.trim().split(/\\s+/).filter(word => word.length > 0).length;\r\n}\r\n\r\n/**\r\n * Formata um número de telefone brasileiro\r\n * \r\n * @param phone - Número de telefone (com ou sem formatação)\r\n * @returns Telefone formatado\r\n * \r\n * @example\r\n * formatPhone('11999998888') // '(11) 99999-8888'\r\n * formatPhone('1133334444') // '(11) 3333-4444'\r\n */\r\nexport function formatPhone(phone: string): string {\r\n const digits = phone.replace(/\\D/g, '');\r\n \r\n if (digits.length === 11) {\r\n return digits.replace(/(\\d{2})(\\d{5})(\\d{4})/, '($1) $2-$3');\r\n }\r\n \r\n return digits.replace(/(\\d{2})(\\d{4})(\\d{4})/, '($1) $2-$3');\r\n}\r\n\r\n/**\r\n * Formata um CPF\r\n * \r\n * @param cpf - Número do CPF (com ou sem formatação)\r\n * @returns CPF formatado\r\n * \r\n * @example\r\n * formatCPF('12345678901') // '123.456.789-01'\r\n */\r\nexport function formatCPF(cpf: string): string {\r\n const digits = cpf.replace(/\\D/g, '');\r\n return digits.replace(/(\\d{3})(\\d{3})(\\d{3})(\\d{2})/, '$1.$2.$3-$4');\r\n}\r\n\r\n/**\r\n * Formata um CNPJ\r\n * \r\n * @param cnpj - Número do CNPJ (com ou sem formatação)\r\n * @returns CNPJ formatado\r\n * \r\n * @example\r\n * formatCNPJ('12345678000199') // '12.345.678/0001-99'\r\n */\r\nexport function formatCNPJ(cnpj: string): string {\r\n const digits = cnpj.replace(/\\D/g, '');\r\n return digits.replace(/(\\d{2})(\\d{3})(\\d{3})(\\d{4})(\\d{2})/, '$1.$2.$3/$4-$5');\r\n}\r\n\r\n/**\r\n * Valida um CPF\r\n * \r\n * @param cpf - Número do CPF (com ou sem formatação)\r\n * @returns true se válido, false caso contrário\r\n * \r\n * @example\r\n * isCPF('123.456.789-09') // false (CPF inválido)\r\n */\r\nexport function isCPF(cpf: string): boolean {\r\n const digits = cpf.replace(/\\D/g, '');\r\n \r\n if (digits.length !== 11 || /^(\\d)\\1{10}$/.test(digits)) {\r\n return false;\r\n }\r\n \r\n // Cálculo do primeiro dígito verificador\r\n let sum = 0;\r\n for (let i = 0; i < 9; i++) {\r\n sum += parseInt(digits.charAt(i)) * (10 - i);\r\n }\r\n let remainder = (sum * 10) % 11;\r\n if (remainder === 10 || remainder === 11) remainder = 0;\r\n if (remainder !== parseInt(digits.charAt(9))) {\r\n return false;\r\n }\r\n \r\n // Cálculo do segundo dígito verificador\r\n sum = 0;\r\n for (let i = 0; i < 10; i++) {\r\n sum += parseInt(digits.charAt(i)) * (11 - i);\r\n }\r\n remainder = (sum * 10) % 11;\r\n if (remainder === 10 || remainder === 11) remainder = 0;\r\n if (remainder !== parseInt(digits.charAt(10))) {\r\n return false;\r\n }\r\n \r\n return true;\r\n}\r\n\r\n/**\r\n * Valida um CNPJ\r\n * \r\n * @param cnpj - Número do CNPJ (com ou sem formatação)\r\n * @returns true se válido, false caso contrário\r\n * \r\n * @example\r\n * isCNPJ('12.345.678/0001-99') // false (CNPJ inválido)\r\n */\r\nexport function isCNPJ(cnpj: string): boolean {\r\n const digits = cnpj.replace(/\\D/g, '');\r\n \r\n if (digits.length !== 14 || /^(\\d)\\1{13}$/.test(digits)) {\r\n return false;\r\n }\r\n \r\n // Cálculo do primeiro dígito verificador\r\n const weights1 = [5,4,3,2,9,8,7,6,5,4,3,2];\r\n let sum = 0;\r\n for (let i = 0; i < 12; i++) {\r\n sum += parseInt(digits.charAt(i)) * weights1[i];\r\n }\r\n let remainder = sum % 11;\r\n const digit1 = remainder < 2 ? 0 : 11 - remainder;\r\n if (digit1 !== parseInt(digits.charAt(12))) {\r\n return false;\r\n }\r\n \r\n // Cálculo do segundo dígito verificador\r\n const weights2 = [6,5,4,3,2,9,8,7,6,5,4,3,2];\r\n sum = 0;\r\n for (let i = 0; i < 13; i++) {\r\n sum += parseInt(digits.charAt(i)) * weights2[i];\r\n }\r\n remainder = sum % 11;\r\n const digit2 = remainder < 2 ? 0 : 11 - remainder;\r\n if (digit2 !== parseInt(digits.charAt(13))) {\r\n return false;\r\n }\r\n \r\n return true;\r\n}\r\n","/**\r\n * Number Utilities\r\n *\r\n * Utilitários para formatação de números, moedas e percentuais.\r\n * Suporte para múltiplos idiomas: pt-BR, en-US, es-ES.\r\n *\r\n * @module @rainersoft/utils/number\r\n * @author Rainer Teixeira\r\n */\r\n\r\nimport type { Locale } from '../types';\r\nimport { DEFAULT_LOCALE, CURRENCY_MAP } from '../types';\r\n\r\n/**\r\n * Formata número como moeda com suporte a idiomas\r\n *\r\n * @param value - Valor numérico\r\n * @param locale - Idioma (padrão: 'pt-BR')\r\n * @param options - Opções de formatação\r\n * @returns Valor formatado\r\n *\r\n * @example\r\n * formatCurrency(1234.56) // 'R$ 1.234,56' (pt-BR)\r\n * formatCurrency(1234.56, 'en-US') // '$1,234.56'\r\n * formatCurrency(1234.56, 'es-ES') // '1.234,56 €'\r\n */\r\nexport function formatCurrency(\r\n value: number,\r\n locale: Locale = DEFAULT_LOCALE,\r\n options?: Intl.NumberFormatOptions\r\n): string {\r\n const currency = CURRENCY_MAP[locale];\r\n return new Intl.NumberFormat(locale, {\r\n style: 'currency',\r\n currency,\r\n ...options,\r\n }).format(value);\r\n}\r\n\r\n/**\r\n * Formata número como percentual\r\n *\r\n * @param value - Valor entre 0 e 1 (ou 0 e 100 se usePercentage=true)\r\n * @param decimals - Casas decimais (padrão: 0)\r\n * @param usePercentage - Se true, espera valor 0-100 (padrão: false)\r\n * @returns Percentual formatado\r\n *\r\n * @example\r\n * formatPercent(0.1234) // '12%'\r\n * formatPercent(0.1234, 2) // '12,34%'\r\n * formatPercent(12.34, 2, true) // '12,34%'\r\n */\r\nexport function formatPercent(\r\n value: number,\r\n decimals = 0,\r\n usePercentage = false\r\n): string {\r\n return new Intl.NumberFormat('pt-BR', {\r\n style: 'percent',\r\n minimumFractionDigits: decimals,\r\n maximumFractionDigits: decimals,\r\n }).format(usePercentage ? value / 100 : value);\r\n}\r\n\r\n/**\r\n * Formata número com separadores de milhar\r\n *\r\n * @param value - Valor numérico\r\n * @param decimals - Casas decimais (padrão: 0)\r\n * @param locale - Idioma (padrão: 'pt-BR')\r\n * @returns Número formatado\r\n *\r\n * @example\r\n * formatNumber(1234567) // '1.234.567' (pt-BR)\r\n * formatNumber(1234567, 0, 'en-US') // '1,234,567'\r\n */\r\nexport function formatNumber(value: number, decimals = 0, locale: Locale = DEFAULT_LOCALE): string {\r\n return new Intl.NumberFormat(locale, {\r\n minimumFractionDigits: decimals,\r\n maximumFractionDigits: decimals,\r\n }).format(value);\r\n}\r\n\r\n/**\r\n * Formata número de forma compacta (1K, 1M, 1B)\r\n *\r\n * @param value - Valor numérico\r\n * @param decimals - Casas decimais (padrão: 1)\r\n * @param locale - Idioma (padrão: 'pt-BR')\r\n * @returns Número compacto\r\n *\r\n * @example\r\n * formatCompact(1234) // '1,2 mil' (pt-BR)\r\n * formatCompact(1234567, 1, 'en-US') // '1.2M'\r\n */\r\nexport function formatCompact(value: number, decimals = 1, locale: Locale = DEFAULT_LOCALE): string {\r\n return new Intl.NumberFormat(locale, {\r\n notation: 'compact',\r\n compactDisplay: 'short',\r\n minimumFractionDigits: decimals,\r\n maximumFractionDigits: decimals,\r\n }).format(value);\r\n}\r\n\r\n/**\r\n * Converte string de moeda para número\r\n *\r\n * @param currency - String de moeda (ex: 'R$ 1.234,56')\r\n * @returns Valor numérico\r\n *\r\n * @example\r\n * parseCurrency('R$ 1.234,56') // 1234.56\r\n * parseCurrency('1.234,56') // 1234.56\r\n */\r\nexport function parseCurrency(currency: string): number {\r\n const cleaned = currency\r\n .replace(/[R$\\s]/g, '')\r\n .replace(/\\./g, '')\r\n .replace(',', '.');\r\n return parseFloat(cleaned);\r\n}\r\n\r\n/**\r\n * Arredonda número para casas decimais\r\n *\r\n * @param value - Valor numérico\r\n * @param decimals - Casas decimais\r\n * @returns Valor arredondado\r\n *\r\n * @example\r\n * round(1.2345, 2) // 1.23\r\n */\r\nexport function round(value: number, decimals = 2): number {\r\n const factor = Math.pow(10, decimals);\r\n return Math.round(value * factor) / factor;\r\n}\r\n\r\n/**\r\n * Clamp - limita número entre min e max\r\n *\r\n * @param value - Valor\r\n * @param min - Mínimo\r\n * @param max - Máximo\r\n * @returns Valor limitado\r\n *\r\n * @example\r\n * clamp(150, 0, 100) // 100\r\n * clamp(-10, 0, 100) // 0\r\n */\r\nexport function clamp(value: number, min: number, max: number): number {\r\n return Math.min(Math.max(value, min), max);\r\n}\r\n","/**\r\n * Hook para avaliar e monitorar força de senha\r\n * \r\n * @param {string} password - Senha a ser avaliada\r\n * @param {Object} options - Opções de configuração\r\n * @param {number} options.minLength - Comprimento mínimo (default: 8)\r\n * @param {boolean} options.requireUppercase - Exige letra maiúscula (default: true)\r\n * @param {boolean} options.requireLowercase - Exige letra minúscula (default: true)\r\n * @param {boolean} options.requireNumbers - Exige números (default: true)\r\n * @param {boolean} options.requireSpecialChars - Exige caracteres especiais (default: true)\r\n * @param {string[]} options.customPatterns - Padrões personalizados para validação\r\n * @param {Object} options.labels - Rótulos customizados (para i18n)\r\n * \r\n * @returns {Object} Objeto com força da senha e validações\r\n */\r\n\r\nimport React from 'react';\r\n\r\nexport function usePasswordStrength(\r\n password: string, \r\n options: {\r\n minLength?: number;\r\n requireUppercase?: boolean;\r\n requireLowercase?: boolean;\r\n requireNumbers?: boolean;\r\n requireSpecialChars?: boolean;\r\n customPatterns?: string[];\r\n labels?: {\r\n veryWeak?: string;\r\n weak?: string;\r\n fair?: string;\r\n good?: string;\r\n strong?: string;\r\n enterPassword?: string;\r\n useMinLength?: string;\r\n addUppercase?: string;\r\n addLowercase?: string;\r\n addNumbers?: string;\r\n addSpecialChars?: string;\r\n avoidRepeating?: string;\r\n avoidCommon?: string;\r\n };\r\n } = {}\r\n) {\r\n const {\r\n minLength = 8,\r\n requireUppercase = true,\r\n requireLowercase = true,\r\n requireNumbers = true,\r\n requireSpecialChars = true,\r\n customPatterns = [],\r\n labels = {}\r\n } = options;\r\n\r\n // Rótulos padrão em inglês\r\n const defaultLabels = {\r\n veryWeak: 'Very Weak',\r\n weak: 'Weak',\r\n fair: 'Fair',\r\n good: 'Good',\r\n strong: 'Strong',\r\n enterPassword: 'Enter a password',\r\n useMinLength: `Use at least ${minLength} characters`,\r\n addUppercase: 'Add uppercase letters',\r\n addLowercase: 'Add lowercase letters',\r\n addNumbers: 'Add numbers',\r\n addSpecialChars: 'Add special characters (!@#$%)',\r\n avoidRepeating: 'Avoid repeating characters',\r\n avoidCommon: 'Avoid common passwords or obvious patterns'\r\n };\r\n\r\n // Mesclar rótulos padrão com customizados\r\n const finalLabels = { ...defaultLabels, ...labels };\r\n\r\n // Calcular força da senha\r\n const strength = React.useMemo(() => {\r\n if (!password) return 0;\r\n\r\n let score = 0;\r\n const length = password.length;\r\n\r\n // Pontuação por comprimento\r\n if (length >= minLength) score += 25;\r\n if (length >= 12) score += 15;\r\n if (length >= 16) score += 10;\r\n\r\n // Pontuação por variedade de caracteres\r\n if (/[a-z]/.test(password) && requireLowercase) score += 15;\r\n if (/[A-Z]/.test(password) && requireUppercase) score += 15;\r\n if (/[0-9]/.test(password) && requireNumbers) score += 15;\r\n if (/[^a-zA-Z0-9]/.test(password) && requireSpecialChars) score += 20;\r\n\r\n // Verificar padrões personalizados\r\n customPatterns.forEach(pattern => {\r\n if (new RegExp(pattern).test(password)) {\r\n score += 5;\r\n }\r\n });\r\n\r\n // Bônus por complexidade adicional\r\n if (/(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[^a-zA-Z0-9])/.test(password)) {\r\n score += 10;\r\n }\r\n\r\n // Penalizar senhas comuns ou padrões fracos\r\n const commonPatterns = [\r\n /^123456/,\r\n /password/i,\r\n /qwerty/i,\r\n /admin/i,\r\n /abc123/i,\r\n /^(.)\\1+$/, // Caracteres repetidos\r\n /^(?:[a-z]+|[A-Z]+|[0-9]+)$/ // Apenas um tipo de caractere\r\n ];\r\n\r\n commonPatterns.forEach(pattern => {\r\n if (pattern.test(password)) {\r\n score = Math.max(0, score - 20);\r\n }\r\n });\r\n\r\n return Math.min(100, Math.max(0, score));\r\n }, [password, minLength, requireUppercase, requireLowercase, requireNumbers, requireSpecialChars, customPatterns]);\r\n\r\n // Obter nível da senha\r\n const level = React.useMemo(() => {\r\n if (strength < 20) return 'very-weak';\r\n if (strength < 40) return 'weak';\r\n if (strength < 60) return 'fair';\r\n if (strength < 80) return 'good';\r\n return 'strong';\r\n }, [strength]);\r\n\r\n // Obter cor para indicador visual\r\n const color = React.useMemo(() => {\r\n switch (level) {\r\n case 'very-weak': return '#ef4444'; // red-500\r\n case 'weak': return '#f97316'; // orange-500\r\n case 'fair': return '#eab308'; // yellow-500\r\n case 'good': return '#22c55e'; // green-500\r\n case 'strong': return '#059669'; // emerald-600\r\n default: return '#6b7280'; // gray-500\r\n }\r\n }, [level]);\r\n\r\n // Obter texto descritivo\r\n const label = React.useMemo(() => {\r\n switch (level) {\r\n case 'very-weak': return finalLabels.veryWeak;\r\n case 'weak': return finalLabels.weak;\r\n case 'fair': return finalLabels.fair;\r\n case 'good': return finalLabels.good;\r\n case 'strong': return finalLabels.strong;\r\n default: return finalLabels.enterPassword;\r\n }\r\n }, [level, finalLabels]);\r\n\r\n // Validações específicas\r\n const validations = React.useMemo(() => {\r\n return {\r\n hasMinLength: password.length >= minLength,\r\n hasUppercase: !requireUppercase || /[A-Z]/.test(password),\r\n hasLowercase: !requireLowercase || /[a-z]/.test(password),\r\n hasNumbers: !requireNumbers || /[0-9]/.test(password),\r\n hasSpecialChars: !requireSpecialChars || /[^a-zA-Z0-9]/.test(password),\r\n noRepeatingChars: !/^(.)\\1+$/.test(password),\r\n noCommonPatterns: !(/123456|password|qwerty|admin|abc123/i).test(password)\r\n };\r\n }, [password, minLength, requireUppercase, requireLowercase, requireNumbers, requireSpecialChars]);\r\n\r\n // Verificar se senha atende todos os requisitos\r\n const isValid = React.useMemo(() => {\r\n return Object.values(validations).every(Boolean);\r\n }, [validations]);\r\n\r\n // Obter sugestões de melhoria\r\n const suggestions = React.useMemo(() => {\r\n const suggestions: string[] = [];\r\n\r\n if (!validations.hasMinLength) {\r\n suggestions.push(finalLabels.useMinLength);\r\n }\r\n if (!validations.hasUppercase && requireUppercase) {\r\n suggestions.push(finalLabels.addUppercase);\r\n }\r\n if (!validations.hasLowercase && requireLowercase) {\r\n suggestions.push(finalLabels.addLowercase);\r\n }\r\n if (!validations.hasNumbers && requireNumbers) {\r\n suggestions.push(finalLabels.addNumbers);\r\n }\r\n if (!validations.hasSpecialChars && requireSpecialChars) {\r\n suggestions.push(finalLabels.addSpecialChars);\r\n }\r\n if (!validations.noRepeatingChars) {\r\n suggestions.push(finalLabels.avoidRepeating);\r\n }\r\n if (!validations.noCommonPatterns) {\r\n suggestions.push(finalLabels.avoidCommon);\r\n }\r\n\r\n return suggestions;\r\n }, [validations, finalLabels, minLength, requireUppercase, requireLowercase, requireNumbers, requireSpecialChars]);\r\n\r\n // Gerar senha forte aleatória (opcional)\r\n const generateStrongPassword = React.useCallback((length = 16) => {\r\n const uppercase = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';\r\n const lowercase = 'abcdefghijklmnopqrstuvwxyz';\r\n const numbers = '0123456789';\r\n const special = '!@#$%^&*()_+-=[]{}|;:,.<>?';\r\n \r\n let chars = lowercase;\r\n if (requireUppercase) chars += uppercase;\r\n if (requireNumbers) chars += numbers;\r\n if (requireSpecialChars) chars += special;\r\n \r\n let password = '';\r\n \r\n // Garantir pelo menos um de cada tipo requerido\r\n if (requireLowercase) password += lowercase[Math.floor(Math.random() * lowercase.length)];\r\n if (requireUppercase) password += uppercase[Math.floor(Math.random() * uppercase.length)];\r\n if (requireNumbers) password += numbers[Math.floor(Math.random() * numbers.length)];\r\n if (requireSpecialChars) password += special[Math.floor(Math.random() * special.length)];\r\n \r\n // Preencher o resto\r\n for (let i = password.length; i < length; i++) {\r\n password += chars[Math.floor(Math.random() * chars.length)];\r\n }\r\n \r\n // Embaralhar\r\n return password.split('').sort(() => Math.random() - 0.5).join('');\r\n }, [requireUppercase, requireLowercase, requireNumbers, requireSpecialChars]);\r\n\r\n return {\r\n // Métricas principais\r\n strength,\r\n level,\r\n color,\r\n label,\r\n isValid,\r\n \r\n // Validações detalhadas\r\n validations,\r\n \r\n // Feedback ao usuário\r\n suggestions,\r\n \r\n // Utilitários\r\n generateStrongPassword,\r\n \r\n // Estados convenientes\r\n isVeryWeak: level === 'very-weak',\r\n isWeak: level === 'weak',\r\n isFair: level === 'fair',\r\n isGood: level === 'good',\r\n isStrong: level === 'strong'\r\n };\r\n}\r\n","/**\r\n * Helpers pt-BR - Funções pré-configuradas para português brasileiro\r\n * \r\n * Este módulo fornece wrappers convenientes para funções de formatação\r\n * com o locale 'pt-BR' pré-configurado, eliminando a necessidade de\r\n * passar o parâmetro locale repetidamente.\r\n * \r\n * Ideal para projetos exclusivamente em português brasileiro.\r\n * \r\n * @module @rainersoft/utils/pt-br\r\n * @author Rainer Teixeira\r\n * @version 1.0.0\r\n * @since 1.0.0\r\n */\r\n\r\nimport {\r\n formatDate as formatDateBase,\r\n formatDateTime as formatDateTimeBase,\r\n formatRelativeDate as formatRelativeDateBase,\r\n} from './date';\r\n\r\nimport {\r\n formatCurrency as formatCurrencyBase,\r\n formatNumber as formatNumberBase,\r\n formatCompact as formatCompactBase,\r\n} from './number';\r\n\r\nimport {\r\n translateStatus as translateStatusBase,\r\n} from './status';\r\n\r\n/**\r\n * Formata uma data em português brasileiro (pt-BR)\r\n * \r\n * @param date - Data a ser formatada (string ou objeto Date)\r\n * @param format - Formato desejado: 'short', 'long' ou 'full' (padrão: 'long')\r\n * @returns Data formatada em português brasileiro\r\n * \r\n * @example\r\n * formatDate(new Date()); // '26 de novembro de 2025'\r\n * formatDate('2024-01-15', 'short'); // '15/01/2024'\r\n */\r\nexport function formatDate(\r\n date: string | Date,\r\n format: 'short' | 'long' | 'full' = 'long'\r\n): string {\r\n return formatDateBase(date, format, 'pt-BR');\r\n}\r\n\r\n/**\r\n * Formata data e hora em português brasileiro (pt-BR)\r\n * \r\n * @param date - Data com hora a ser formatada\r\n * @returns Data e hora formatadas em português brasileiro\r\n * \r\n * @example\r\n * formatDateTime(new Date()); // '26 de novembro de 2025 às 14:30'\r\n */\r\nexport function formatDateTime(date: string | Date): string {\r\n return formatDateTimeBase(date, 'pt-BR');\r\n}\r\n\r\n/**\r\n * Formata uma data relativa em português brasileiro\r\n * \r\n * Exibe o tempo relativo (ex: \"há 2 dias\", \"há 1 mês\")\r\n * \r\n * @param date - Data de referência\r\n * @returns Data relativa formatada em português\r\n * \r\n * @example\r\n * formatRelativeDate(new Date(Date.now() - 86400000)); // 'há 1 dia'\r\n */\r\nexport function formatRelativeDate(date: string | Date): string {\r\n return formatRelativeDateBase(date, 'pt-BR');\r\n}\r\n\r\n/**\r\n * Formata um valor monetário em Real brasileiro (BRL)\r\n * \r\n * @param value - Valor numérico a ser formatado\r\n * @param options - Opções adicionais de formatação (Intl.NumberFormatOptions)\r\n * @returns Valor formatado como moeda brasileira\r\n * \r\n * @example\r\n * formatCurrency(1234.56); // 'R$ 1.234,56'\r\n * formatCurrency(99.99, { minimumFractionDigits: 2 }); // 'R$ 99,99'\r\n */\r\nexport function formatCurrency(\r\n value: number,\r\n options?: Intl.NumberFormatOptions\r\n): string {\r\n return formatCurrencyBase(value, 'pt-BR', options);\r\n}\r\n\r\n/**\r\n * Formata um número em português brasileiro\r\n * \r\n * @param value - Número a ser formatado\r\n * @param decimals - Número de casas decimais (padrão: 0)\r\n * @returns Número formatado com separadores brasileiros\r\n * \r\n * @example\r\n * formatNumber(1234567); // '1.234.567'\r\n * formatNumber(1234.567, 2); // '1.234,57'\r\n */\r\nexport function formatNumber(value: number, decimals = 0): string {\r\n return formatNumberBase(value, decimals, 'pt-BR');\r\n}\r\n\r\n/**\r\n * Formata um número de forma compacta em português brasileiro\r\n * \r\n * Usa sufixos como \"mil\", \"mi\", \"bi\" para números grandes\r\n * \r\n * @param value - Número a ser formatado\r\n * @param decimals - Casas decimais para números compactos (padrão: 1)\r\n * @returns Número formatado de forma compacta\r\n * \r\n * @example\r\n * formatCompact(1500); // '1,5 mil'\r\n * formatCompact(2500000); // '2,5 mi'\r\n */\r\nexport function formatCompact(value: number, decimals = 1): string {\r\n return formatCompactBase(value, decimals, 'pt-BR');\r\n}\r\n\r\n/**\r\n * Traduz um código de status para português brasileiro\r\n * \r\n * @param status - Código do status (ex: 'DRAFT', 'PUBLISHED', 'ACTIVE')\r\n * @returns Status traduzido para português brasileiro\r\n * \r\n * @example\r\n * translateStatus('DRAFT'); // 'Rascunho'\r\n * translateStatus('PUBLISHED'); // 'Publicado'\r\n */\r\nexport function translateStatus(status: string): string {\r\n return translateStatusBase(status, 'pt-BR');\r\n}\r\n\r\n// Exportação padrão como objeto para facilitar a importação\r\nexport default {\r\n formatDate,\r\n formatDateTime,\r\n formatRelativeDate,\r\n formatCurrency,\r\n formatNumber,\r\n formatCompact,\r\n translateStatus,\r\n};","/**\r\n * Text Utilities\r\n *\r\n * Utilitários universais para manipulação de texto e strings.\r\n *\r\n * @module @rainersoft/utils/text\r\n * @author Rainer Teixeira\r\n * @version 1.0.0\r\n */\r\n\r\n// ============================================================================\r\n// AVATAR UTILITIES\r\n// ============================================================================\r\n\r\n/**\r\n * Extrai iniciais de um nome\r\n *\r\n * @param name - Nome completo\r\n * @param maxChars - Número máximo de caracteres (padrão: 2)\r\n * @returns Iniciais do nome em maiúsculas\r\n *\r\n * @example\r\n * ```ts\r\n * extractInitials('John Doe') // 'JD'\r\n * extractInitials('Maria Silva Santos') // 'MS'\r\n * extractInitials('Apple') // 'A'\r\n * extractInitials('', 3) // ''\r\n * ```\r\n */\r\nexport function extractInitials(name: string | null | undefined, maxChars = 2): string {\r\n if (!name || !name.trim()) {\r\n return '';\r\n }\r\n\r\n const words = name.trim().split(/\\s+/);\r\n const initials = words\r\n .slice(0, maxChars)\r\n .map(word => word.charAt(0).toUpperCase())\r\n .join('');\r\n\r\n return initials;\r\n}\r\n\r\n/**\r\n * Gera URL do avatar com base no nome\r\n *\r\n * @param name - Nome para gerar avatar\r\n * @param size - Tamanho do avatar (default: 200)\r\n * @param backgroundColor - Cor de fundo (default: cyan)\r\n * @param textColor - Cor do texto (default: white)\r\n * @returns URL do avatar\r\n *\r\n * @example\r\n * ```ts\r\n * generateAvatarUrl('John Doe') // URL do avatar\r\n * generateAvatarUrl('John Doe', 100, 'f97316', 'fff') // URL com cor laranja\r\n * ```\r\n */\r\nexport function generateAvatarUrl(\r\n name: string,\r\n size: number = 200,\r\n backgroundColor: string = '0891b2',\r\n textColor: string = 'fff'\r\n): string {\r\n const encodedName = encodeURIComponent(name);\r\n \r\n return `https://ui-avatars.com/api/?name=${encodedName}&size=${size}&background=${backgroundColor}&color=${textColor}&font-size=0.5`;\r\n}\r\n\r\n/**\r\n * Valida se uma URL de avatar é válida\r\n *\r\n * @param url - URL do avatar\r\n * @returns true se a URL for válida\r\n *\r\n * @example\r\n * ```ts\r\n * isValidAvatarUrl('https://example.com/avatar.jpg') // true\r\n * isValidAvatarUrl('invalid-url') // false\r\n * ```\r\n */\r\nexport function isValidAvatarUrl(url: string): boolean {\r\n if (!url || typeof url !== 'string') {\r\n return false;\r\n }\r\n\r\n try {\r\n new URL(url);\r\n return true;\r\n } catch {\r\n return false;\r\n }\r\n}\r\n\r\n/**\r\n * Obtém a cor do avatar baseada no hash do nome\r\n *\r\n * @param name - Nome para gerar cor\r\n * @returns Cor em formato hexadecimal\r\n *\r\n * @example\r\n * ```ts\r\n * getAvatarColorFromName('John Doe') // '#0891b2' (ou outra cor)\r\n * getAvatarColorFromName('') // '#0891b2' (cor padrão)\r\n * ```\r\n */\r\nexport function getAvatarColorFromName(name: string): string {\r\n if (!name || typeof name !== 'string') {\r\n return '#0891b2'; // cyan-600 como padrão\r\n }\r\n\r\n // Gera hash simples do nome\r\n let hash = 0;\r\n for (let i = 0; i < name.length; i++) {\r\n hash = name.charCodeAt(i) + ((hash << 5) - hash);\r\n }\r\n\r\n // Cores baseadas em design tokens (compatível com @rainersoft/design-tokens)\r\n const colors = [\r\n '#0891b2', // cyan-600\r\n '#9333ea', // purple-600\r\n '#db2777', // pink-600\r\n '#059669', // emerald-600\r\n '#2563eb', // blue-600\r\n '#f97316', // orange-500\r\n '#dc2626', // red-600\r\n '#7c3aed', // violet-600\r\n ];\r\n\r\n const index = Math.abs(hash) % colors.length;\r\n return colors[index];\r\n}\r\n\r\n/**\r\n * Gera avatar com cor baseada no nome\r\n *\r\n * @param name - Nome para gerar avatar\r\n * @param size - Tamanho do avatar\r\n * @returns URL do avatar com cor automática\r\n *\r\n * @example\r\n * ```ts\r\n * generateDynamicAvatarUrl('John Doe') // URL com cor baseada no nome\r\n * generateDynamicAvatarUrl('Jane Smith', 150) // URL com tamanho 150\r\n * ```\r\n */\r\nexport function generateDynamicAvatarUrl(name: string, size: number = 200): string {\r\n const color = getAvatarColorFromName(name);\r\n const colorHex = color.replace('#', '');\r\n return generateAvatarUrl(name, size, colorHex, 'fff');\r\n}\r\n\r\n// ============================================================================\r\n// TEXT UTILITIES\r\n// ============================================================================\r\n\r\n/**\r\n * Gera ID único baseado em texto\r\n *\r\n * @param text - Texto base para o ID\r\n * @param prefix - Prefixo opcional\r\n * @param suffix - Sufixo opcional\r\n * @returns ID único em formato slug\r\n *\r\n * @example\r\n * ```ts\r\n * generateUniqueId('Hello World') // 'hello-world'\r\n * generateUniqueId('Hello World', 'section') // 'section-hello-world'\r\n * generateUniqueId('Olá! Como vai?', '', '123') // 'ola-como-vai-123'\r\n * ```\r\n */\r\nexport function generateUniqueId(\r\n text: string,\r\n prefix = '',\r\n suffix = ''\r\n): string {\r\n const slug = text\r\n .toLowerCase()\r\n .normalize('NFD')\r\n .replace(/[\\u0300-\\u036f]/g, '') // Remove acentos\r\n .replace(/[^\\w\\s-]/g, '') // Remove caracteres especiais\r\n .replace(/\\s+/g, '-') // Substitui espaços por hífens\r\n .replace(/-+/g, '-') // Remove hífens duplicados\r\n .trim()\r\n .substring(0, 50); // Limita tamanho\r\n\r\n const parts = [prefix, slug, suffix].filter(Boolean);\r\n return parts.join('-');\r\n}\r\n\r\n/**\r\n * Trunca texto com elipse\r\n *\r\n * @param text - Texto para truncar\r\n * @param maxLength - Comprimento máximo\r\n * @param suffix - Sufixo para adicionar (padrão: '...')\r\n * @returns Texto truncado\r\n *\r\n * @example\r\n * ```ts\r\n * truncateText('Hello World', 5) // 'Hello...'\r\n * truncateText('Hello World', 8, '...') // 'Hello...'\r\n * truncateText('Short', 10) // 'Short'\r\n * ```\r\n */\r\nexport function truncateText(\r\n text: string,\r\n maxLength: number,\r\n suffix = '...'\r\n): string {\r\n if (!text || text.length <= maxLength) {\r\n return text || '';\r\n }\r\n\r\n return text.substring(0, maxLength - suffix.length) + suffix;\r\n}\r\n\r\n/**\r\n * Capitaliza primeira letra de cada palavra\r\n *\r\n * @param text - Texto para capitalizar\r\n * @param options - Opções de capitalização\r\n * @returns Texto capitalizado\r\n *\r\n * @example\r\n * ```ts\r\n * capitalize('hello world') // 'Hello World'\r\n * capitalize('hello world', { firstWordOnly: true }) // 'Hello world'\r\n * capitalize('HELLO WORLD', { lowerRest: true }) // 'Hello World'\r\n * ```\r\n */\r\nexport function capitalize(\r\n text: string,\r\n options: { firstWordOnly?: boolean; lowerRest?: boolean } = {}\r\n): string {\r\n if (!text) return '';\r\n\r\n const { firstWordOnly = false, lowerRest = false } = options;\r\n\r\n if (firstWordOnly) {\r\n return text.charAt(0).toUpperCase() + \r\n (lowerRest ? text.slice(1).toLowerCase() : text.slice(1));\r\n }\r\n\r\n if (lowerRest) {\r\n return text.replace(/\\b\\w/g, char => char.toUpperCase()).toLowerCase();\r\n }\r\n\r\n return text.replace(/\\b\\w/g, char => char.toUpperCase());\r\n}\r\n\r\n/**\r\n * Remove caracteres especiais mantendo apenas alfanuméricos e espaços\r\n *\r\n * @param text - Texto para limpar\r\n * @param allowSpaces - Se deve permitir espaços\r\n * @returns Texto limpo\r\n *\r\n * @example\r\n * ```ts\r\n * cleanText('Olá! Como vai?') // 'Ola Como vai'\r\n * cleanText('Olá! Como vai?', false) // 'OlaComoVai'\r\n * ```\r\n */\r\nexport function cleanText(text: string, allowSpaces = true): string {\r\n if (!text) return '';\r\n\r\n const pattern = allowSpaces ? /[^\\w\\s]/g : /[^\\w]/g;\r\n return text.replace(pattern, '');\r\n}\r\n\r\n/**\r\n * Conta palavras em um texto\r\n *\r\n * @param text - Texto para contar\r\n * @returns Número de palavras\r\n *\r\n * @example\r\n * ```ts\r\n * countWords('Hello world') // 2\r\n * countWords(' Hello world ') // 2\r\n * countWords('') // 0\r\n * ```\r\n */\r\nexport function countWords(text: string): number {\r\n if (!text || !text.trim()) {\r\n return 0;\r\n }\r\n\r\n return text.trim().split(/\\s+/).length;\r\n}\r\n\r\n/**\r\n * Verifica se texto está vazio ou contém apenas espaços\r\n *\r\n * @param text - Texto para verificar\r\n * @returns True se estiver vazio\r\n *\r\n * @example\r\n * ```ts\r\n * isEmpty('') // true\r\n * isEmpty(' ') // true\r\n * isEmpty('Hello') // false\r\n * ```\r\n */\r\nexport function isEmpty(text: string | null | undefined): boolean {\r\n return !text || !text.trim();\r\n}\r\n\r\n/**\r\n * Remove espaços em branco extras\r\n *\r\n * @param text - Texto para limpar\r\n * @param options - Opções de limpeza\r\n * @returns Texto sem espaços extras\r\n *\r\n * @example\r\n * ```ts\r\n * normalizeSpaces(' Hello World ') // 'Hello World'\r\n * normalizeSpaces('Hello\\nWorld', { newlines: true }) // 'Hello World'\r\n * ```\r\n */\r\nexport function normalizeSpaces(\r\n text: string,\r\n options: { newlines?: boolean } = {}\r\n): string {\r\n if (!text) return '';\r\n\r\n const { newlines = false } = options;\r\n \r\n let cleaned = text;\r\n \r\n if (newlines) {\r\n cleaned = cleaned.replace(/\\s+/g, ' ');\r\n } else {\r\n cleaned = cleaned.replace(/\\s+/g, ' ');\r\n }\r\n \r\n return cleaned.trim();\r\n}\r\n\r\n/**\r\n * Calcula tempo de leitura baseado no conteúdo\r\n *\r\n * Suporta múltiplos formatos:\r\n * - JSON (objeto com conteúdo estruturado)\r\n * - HTML (string com tags)\r\n * - Texto simples (string)\r\n *\r\n * @param content - Conteúdo a analisar (objeto JSON, HTML ou texto)\r\n * @param wordsPerMinute - Palavras por minuto (padrão: 200)\r\n * @returns Tempo de leitura em minutos (mínimo: 1)\r\n *\r\n * @example\r\n * ```ts\r\n * // JSON estruturado\r\n * const jsonContent = { type: 'doc', content: [...] };\r\n * calculateReadingTime(jsonContent) // 5\r\n *\r\n * // HTML\r\n * calculateReadingTime('<p>Texto longo...</p>') // 3\r\n *\r\n * // Texto simples\r\n * calculateReadingTime('Texto simples') // 1\r\n * ```\r\n */\r\nexport function calculateReadingTime(\r\n content: string | Record<string, any>,\r\n wordsPerMinute: number = 200\r\n): number {\r\n let text = '';\r\n\r\n // Se for objeto (JSON estruturado)\r\n if (typeof content === 'object' && content !== null) {\r\n // Extrai texto de estrutura JSON recursivamente\r\n const extractText = (node: any): string => {\r\n if (!node) return '';\r\n \r\n let result = '';\r\n \r\n // Se tem texto direto\r\n if (node.text) {\r\n result += node.text + ' ';\r\n }\r\n \r\n // Se tem conteúdo (array de nós)\r\n if (Array.isArray(node.content)) {\r\n result += node.content.map(extractText).join(' ');\r\n }\r\n \r\n return result;\r\n };\r\n \r\n text = extractText(content);\r\n } else if (typeof content === 'string') {\r\n // Se for HTML ou texto simples, remove tags HTML\r\n text = content.replace(/<[^>]*>/g, '');\r\n }\r\n\r\n const words = text\r\n .trim()\r\n .split(/\\s+/)\r\n .filter(word => word.length > 0).length;\r\n const time = Math.ceil(words / wordsPerMinute);\r\n\r\n // Retorna no mínimo 1 minuto\r\n return time > 0 ? time : 1;\r\n}\r\n","/**\r\n * @rainersoft/utils - Biblioteca Universal de Utilitários\r\n *\r\n * Utilitários universais para formatação, conversão e manipulação de dados.\r\n * Agnóstico de framework - funciona em Web, Desktop e Mobile.\r\n * Suporte a múltiplos idiomas: pt-BR, en-US, es-ES.\r\n *\r\n * @module @rainersoft/utils\r\n * @author Rainer Teixeira\r\n * @version 1.3.0\r\n */\r\n\r\n// Exportações principais\r\nexport * from './types';\r\n\r\n// Exportações específicas para evitar conflitos de nomes\r\nexport { hexToRgb, validateContrast } from './accessibility';\r\n\r\n// Exportações restantes\r\nexport * from './date';\r\nexport * from './status';\r\nexport * from './validation';\r\nexport * from './content';\r\nexport * from './color';\r\nexport * from './dom';\r\nexport * from './hooks';\r\nexport * from './stats';\r\nexport * from './authentication';\r\nexport * from './search';\r\n\r\n// ============================================================================\r\n// STRING UTILITIES (sem conflitos)\r\n// ============================================================================\r\nexport { \r\n textToSlug, \r\n formatPhone, \r\n formatCPF, \r\n formatCNPJ, \r\n isCPF, \r\n isCNPJ,\r\n getInitials,\r\n truncate,\r\n} from './string';\r\nexport { formatCurrency } from './number';\r\nexport { usePasswordStrength } from './hooks/use-password-strength';\r\n\r\n// Exportações type\r\nexport type { TiptapNode, TiptapJSON, ContentStats } from './content';\r\n\r\n// Helpers pt-BR\r\nexport * as ptBR from './pt-br';\r\n\r\n// Exportações de texto (text utilities)\r\nexport {\r\n extractInitials,\r\n generateAvatarUrl,\r\n isValidAvatarUrl,\r\n getAvatarColorFromName,\r\n generateDynamicAvatarUrl,\r\n generateUniqueId,\r\n truncateText,\r\n capitalize,\r\n cleanText,\r\n countWords,\r\n isEmpty,\r\n normalizeSpaces,\r\n calculateReadingTime\r\n} from './text';\r\n\r\n// Aliases descritivos\r\nimport * as textModule from './text';\r\nimport * as dateModule from './date';\r\nimport * as authModule from './authentication';\r\nimport * as statusModule from './status';\r\n\r\nexport const textProcessing = textModule;\r\nexport const datetime = dateModule;\r\nexport const authentication = authModule;\r\nexport const stateManagement = statusModule;"]}