// 경량 i18n — ?lang=en 쿼리로 한/영 전환. SSG 유지(서버에서 lang 주입). import type { Team } from "./types"; export type Lang = "ko" | "en"; export function parseLang(v: unknown): Lang { return v === "en" ? "en" : "ko"; } // 팀 짧은 표기 (KO=한글, EN=영문 약식) const TEAM_EN: Record = { KOR: "Korea", CZE: "Czechia", MEX: "Mexico", RSA: "S. Africa", }; export function teamShort(team: Team, lang: Lang): string { return lang === "en" ? TEAM_EN[team.code] ?? team.name : team.shortName; } const DAYS: Record = { ko: ["일", "월", "화", "수", "목", "금", "토"], en: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], }; const MONTHS_EN = ["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"]; export function dayName(lang: Lang, dow: number): string { return DAYS[lang][dow]; } export function monthEn(m: number): string { return MONTHS_EN[m - 1]; } // roundLabel 안의 한국어 토막 번역 export function roundLabel(label: string, lang: Lang): string { if (lang === "ko") return label; return label.replace("개막전", "Opener"); } type Dict = { heroPill: string; back: string; share: string; shareCopied: string; introLead: string; prizeLine1: string; prizeLine2: string; schedTitle: string; schedGuide: string; phase: { open: string; scheduled: string; locked: string; finished: string }; aiPicks: string; draw: string; joined: (n: string) => string; aiBattle: string; yourPickLabel: string; yourChoice: string; win: string; drawLabel: string; winProb: (team: string) => string; drawOdds: string; ctaBeat: string; ctaResult: string; ctaLocked: string; ctaOpens: (d: string) => string; emailGate: string; emailPh: string; notify: string; submit: string; myPick: string; sameAI: (models: string, exact: boolean) => string; soloPick: string; shareThis: string; copyLink: string; copied: string; goldDesc: string; goldBtn: string; crowdSub: string; finalResult: string; hit: string; miss: string; matchEnded: string; cdUntil: string; cdClosed: string; final: string; group: (g: string) => string; footerNotOfficial: string; footerDisc1: string; footerDisc2: string; footerDisc3: string; hook: (a: string, b: string) => string; adLabel: string; ado2Tagline: string; ado2Sub: string; ado2Cta: string; genLabel: string; moreMatches: string; }; export const DICT: Record = { ko: { heroPill: "AI와 함께하는 2026 글로벌 축구 축전 승부예측 챌린지", back: "← 전체 일정", share: "투표 공유하기", shareCopied: "링크 복사됨 ✓", introLead: "GPT · Claude · Gemini가 매 경기를\n서로 다르게 예측합니다.", prizeLine1: "가장 많이 참여하고, 가장 정확하게 예측한", prizeLine2: "최종 우승자에게 100만원 상금", schedTitle: "전체 일정", schedGuide: "투표하고 싶은 경기를 선택해주세요", phase: { open: "투표 중", scheduled: "오픈 예정", locked: "투표 마감", finished: "투표종료" }, aiPicks: "AI 픽", draw: "무", joined: (n) => `${n}명 참여`, aiBattle: "AI의 예측 대결", yourPickLabel: "Your Pick · 내 예측", yourChoice: "당신의 선택", win: "승", drawLabel: "무승부", winProb: (t) => `${t} 승리 확률`, drawOdds: "무승부 가능성", ctaBeat: "AI보다 잘 맞히기", ctaResult: "결과 보기", ctaLocked: "예측 마감 (경기 시작)", ctaOpens: (d) => `투표 오픈 ${d}`, emailGate: "투표를 제출하려면 이메일을 입력하세요", emailPh: "이메일 입력 → 투표 결과·다음 경기 알림", notify: "결과 알림 + 다음 경기 소식 + ₩100만 챌린지 기회까지 무료로 받기", submit: "투표 제출하고 AI와 겨루기", myPick: "내 예측", sameAI: (m, exact) => `당신은 ${m}와 같은 선택입니다.${exact ? " 스코어까지 일치!" : ""} 나머지 AI는 생각이 다릅니다.`, soloPick: "당신은 AI 셋 모두와 다른 선택! 소신 픽 🔥", shareThis: "이 경기 공유하기", copyLink: "링크 복사", copied: "복사됨 ✓", goldDesc: "경기마다 승패·스코어를 맞혀 포인트를 쌓고, 누적 1위에게 최종 100만원", goldBtn: "100만 원에\n도전하기", crowdSub: "| 참여자들의 선택", finalResult: "최종 결과", hit: "적중 ✓", miss: "빗나감", matchEnded: "경기 종료 · 최종 결과", cdUntil: "투표 종료까지", cdClosed: "투표가 마감되었습니다", final: "Final", group: (g) => `Group ${g}`, footerNotOfficial: "Independent AI prediction game — not affiliated with, endorsed by, or sponsored by FIFA or any official football tournament.", footerDisc1: "FIFA 및 공식 축구 대회와 무관한 독립 AI 예측 게임입니다 (제휴·후원·운영 아님).", footerDisc2: "스포츠 분석·엔터테인먼트 목적의 예측 게임이며 베팅·도박을 권유하지 않습니다. AI 예측은 실제 결과를 보장하지 않습니다.", footerDisc3: "100만 원 이벤트는 무료 참여형 챌린지입니다. 지급·동점 처리 조건은 별도 약관에 따릅니다. 이메일은 결과·이벤트 알림 목적으로만 사용됩니다.", hook: (a, b) => `${a} vs ${b}, AI의 선택은 갈렸다`, genLabel: "예측 기준", moreMatches: "다른 경기 투표하기", adLabel: "광고", ado2Tagline: "AI 마케팅 자동화 플랫폼", ado2Sub: "AI Marketing Automation Platform →", ado2Cta: "사용해보기", }, en: { heroPill: "AI-powered Global Football Festival 2026 match predictions", back: "← All matches", share: "Share vote", shareCopied: "Link copied ✓", introLead: "GPT · Claude · Gemini predict\nevery match differently.", prizeLine1: "The most active, most accurate", prizeLine2: "overall winner takes ₩1,000,000", schedTitle: "All Matches", schedGuide: "Pick a match to predict", phase: { open: "Voting", scheduled: "Opens soon", locked: "Closed", finished: "Voting closed" }, aiPicks: "AI picks", draw: "Draw", joined: (n) => `${n} joined`, aiBattle: "AI Prediction Battle", yourPickLabel: "Your Pick", yourChoice: "Your Choice", win: "Win", drawLabel: "Draw", winProb: (t) => `${t} win prob.`, drawOdds: "Draw odds", ctaBeat: "Beat the AI", ctaResult: "View result", ctaLocked: "Closed (kickoff)", ctaOpens: (d) => `Opens ${d}`, emailGate: "Enter your email to submit your vote", emailPh: "Your email → result & next-match alerts", notify: "Result alerts + next-match news + a shot at the ₩1,000,000 challenge — free", submit: "Submit your vote & face the AI", myPick: "My Pick", sameAI: (m, exact) => `You matched ${m}.${exact ? " Exact score too!" : ""} The other AIs disagree.`, soloPick: "You disagree with all three AIs — bold pick 🔥", shareThis: "Share this match", copyLink: "Copy link", copied: "Copied ✓", goldDesc: "Earn points each match by nailing the result & score — the overall #1 wins ₩1,000,000.", goldBtn: "Go for\n₩1,000,000", crowdSub: "| What the crowd picked", finalResult: "Final result", hit: "Hit ✓", miss: "Miss", matchEnded: "Match ended · Final", cdUntil: "Voting closes in", cdClosed: "Voting closed", final: "Final", group: (g) => `Group ${g}`, footerNotOfficial: "Independent AI prediction game — not affiliated with, endorsed by, or sponsored by FIFA or any official football tournament.", footerDisc1: "A fan-run prediction game using public match schedules; all picks are independent.", footerDisc2: "A sports-analysis & entertainment prediction game. No betting or gambling. AI predictions do not guarantee real outcomes.", footerDisc3: "The ₩1,000,000 event is a free-to-enter challenge. Payout & tie-break terms follow separate rules. Email is used only for result & event alerts.", hook: (a, b) => `AI is split on ${a} vs ${b}`, genLabel: "As of", moreMatches: "Vote on another match", adLabel: "AD", ado2Tagline: "AI Marketing Automation Platform", ado2Sub: "Visit ado2.o2osolution.ai →", ado2Cta: "Try it", }, }; export function dict(lang: Lang): Dict { return DICT[lang]; }