// 공용 DOM 헬퍼 · 토스트 · 이스터에그(이모지 날리기). 다른 모듈이 import 해서 쓴다. export const $ = (s, r) => (r || document).querySelector(s); export const $$ = (s, r) => Array.prototype.slice.call((r || document).querySelectorAll(s)); export const EGGS_ON = true; const CHECK_SVG = ''; let toastTimer = null; export function toast(msg) { if (!msg) return; const old = $(".toast"); if (old) old.remove(); const t = document.createElement("div"); t.className = "toast"; t.innerHTML = '' + CHECK_SVG + ""; t.appendChild(document.createTextNode(msg)); document.body.appendChild(t); if (toastTimer) clearTimeout(toastTimer); toastTimer = setTimeout(() => { if (t.parentNode) t.remove(); }, 2700); } let flyId = 0; function flyLayer() { let l = $(".flyers"); if (!l) { l = document.createElement("div"); l.className = "flyers"; document.body.appendChild(l); } return l; } function addFlyer(content, style, ttl) { const span = document.createElement("span"); span.className = "flyer"; span.textContent = content; Object.keys(style).forEach((k) => { span.style[k] = style[k]; }); flyLayer().appendChild(span); span._id = ++flyId; setTimeout(() => { if (span.parentNode) span.remove(); }, ttl); } export function burstThumbs() { if (!EGGS_ON) return; const cx = window.innerWidth / 2; for (let i = 0; i < 6; i++) { const dx = (Math.random() - 0.5) * 180; addFlyer("👍", { left: (cx + dx) + "px", top: (window.innerHeight * 0.62) + "px", fontSize: (22 + Math.random() * 14) + "px", animation: "aidev-flyup " + (0.9 + Math.random() * 0.3) + "s ease-out " + (i * 60) + "ms forwards", opacity: 0, }, 1500); } } export function burstRocket() { if (!EGGS_ON) return; addFlyer("🚀", { left: "-40px", top: (window.innerHeight * (0.18 + Math.random() * 0.2)) + "px", fontSize: "34px", animation: "aidev-rocket 1.1s ease-in forwards", }, 1300); } export function burstSparkle(x, y) { if (!EGGS_ON) return; const chars = ["✨", "⭐", "💫"]; for (let i = 0; i < 7; i++) { const dx = (Math.random() - 0.5) * 90, dy = (Math.random() - 0.5) * 90; addFlyer(chars[i % 3], { left: (x + dx) + "px", top: (y + dy) + "px", fontSize: (12 + Math.random() * 12) + "px", animation: "aidev-sparkle " + (0.5 + Math.random() * 0.3) + "s ease-out forwards", }, 900); } }