import type { SimulationState } from './types'; /** * Encode simulation state into a shareable URL hash. * Uses lz-string for compression. */ export async function encodeState(state: SimulationState): Promise { const { compressToEncodedURIComponent } = await import('lz-string'); const json = JSON.stringify(state); return compressToEncodedURIComponent(json); } /** * Decode simulation state from a URL hash. */ export async function decodeState(hash: string): Promise { try { const { decompressFromEncodedURIComponent } = await import('lz-string'); const json = decompressFromEncodedURIComponent(hash); if (!json) return null; return JSON.parse(json) as SimulationState; } catch { return null; } } /** * Export yearly data as CSV. */ export function exportCSV(headers: string[], rows: (string | number)[][]): void { const bom = '\uFEFF'; // UTF-8 BOM for Excel const sep = ';'; const lines = [ headers.join(sep), ...rows.map((row) => row.map((v) => (typeof v === 'number' ? v.toFixed(2) : v)).join(sep)), ]; const csv = bom + lines.join('\n'); const blob = new Blob([csv], { type: 'text/csv;charset=utf-8;' }); const url = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = `simulation-pret-immo-${new Date().toISOString().slice(0, 10)}.csv`; a.click(); URL.revokeObjectURL(url); } /** * Copy text to clipboard. */ export async function copyToClipboard(text: string): Promise { try { await navigator.clipboard.writeText(text); return true; } catch { return false; } }