Files
ai-showcase-platform/contexts/competition-context.tsx

901 lines
28 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"use client"
import { createContext, useContext, useState, useEffect, type ReactNode } from "react"
import type { Judge, JudgeScore, Competition, Award, Team, Proposal, ProposalJudgeScore } from "@/types/competition"
interface CompetitionContextType {
// Judges
judges: Judge[]
addJudge: (judge: Omit<Judge, "id">) => void
updateJudge: (id: string, updates: Partial<Judge>) => void
deleteJudge: (id: string) => void
// Competitions
competitions: Competition[]
currentCompetition: Competition | null
setCurrentCompetition: (competition: Competition | null) => void
addCompetition: (competition: Omit<Competition, "id">) => void
updateCompetition: (id: string, updates: Partial<Competition>) => void
deleteCompetition: (id: string) => void
// Teams
teams: Team[]
addTeam: (team: Omit<Team, "id">) => void
updateTeam: (id: string, updates: Partial<Team>) => void
getTeamById: (id: string) => Team | undefined
// Proposals
proposals: Proposal[]
addProposal: (proposal: Omit<Proposal, "id">) => void
updateProposal: (id: string, updates: Partial<Proposal>) => void
getProposalById: (id: string) => Proposal | undefined
// Judge Scores
judgeScores: JudgeScore[]
proposalJudgeScores: ProposalJudgeScore[]
addJudgeScore: (score: Omit<JudgeScore, "submittedAt">) => void
addProposalJudgeScore: (score: Omit<ProposalJudgeScore, "submittedAt">) => void
submitJudgeScore: (score: Omit<JudgeScore, "submittedAt">) => void
submitProposalJudgeScore: (score: Omit<ProposalJudgeScore, "submittedAt">) => void
getAppJudgeScores: (appId: string) => JudgeScore[]
getProposalJudgeScores: (proposalId: string) => ProposalJudgeScore[]
getAppAverageScore: (appId: string) => number
getProposalAverageScore: (proposalId: string) => number
getAppDetailedScores: (appId: string) => {
innovation: number
technical: number
usability: number
presentation: number
impact: number
total: number
judgeCount: number
}
getProposalDetailedScores: (proposalId: string) => {
problemIdentification: number
solutionFeasibility: number
innovation: number
impact: number
presentation: number
total: number
judgeCount: number
}
// Awards
awards: Award[]
loadingAwards: boolean
loadAwards: () => Promise<void>
addAward: (award: Omit<Award, "id">) => void
updateAward: (award: Award) => void
deleteAward: (awardId: string) => void
getAwardsByYear: (year: number) => Award[]
getAwardsByMonth: (year: number, month: number) => Award[]
getAvailableYears: () => number[]
// Rankings
getCompetitionRankings: (competitionId?: string) => Array<{
appId?: string
proposalId?: string
teamId?: string
appName?: string
proposalTitle?: string
teamName?: string
creator: string
totalScore: number
rank: number
scores: any
competitionType: "individual" | "team" | "proposal"
}>
// Add new filtering functions
getAwardsByCompetitionType: (competitionType?: string) => Award[]
getAwardsByCategory: (category?: string) => Award[]
getTopRankingAwards: () => Award[]
getPopularityAwards: () => Award[]
getPopularityRankings: (competitionId?: string) => Array<{
id: string
name: string
creator: string
department: string
type: string
likes: number
rank: number
}>
}
const CompetitionContext = createContext<CompetitionContextType | undefined>(undefined)
// Mock data
const mockJudges: Judge[] = []
// Mock teams data
const mockTeams: Team[] = []
// Mock proposals data
const mockProposals: Proposal[] = []
// 競賽資料
const mockCompetitions: Competition[] = []
// Mock app likes counter
const appLikesCounter: Record<string, number> = {}
export function CompetitionProvider({ children }: { children: ReactNode }) {
const [judges, setJudges] = useState<Judge[]>(mockJudges)
const [competitions, setCompetitions] = useState<Competition[]>(mockCompetitions)
const [currentCompetition, setCurrentCompetition] = useState<Competition | null>(null)
const [teams, setTeams] = useState<Team[]>(mockTeams)
const [proposals, setProposals] = useState<Proposal[]>(mockProposals)
// 載入所有競賽和當前競賽
useEffect(() => {
const loadCompetitions = async () => {
try {
// 載入所有競賽
const competitionsResponse = await fetch('/api/competitions')
const competitionsData = await competitionsResponse.json()
if (competitionsData.success) {
if (competitionsData.data && competitionsData.data.length > 0) {
// 確保每個競賽都有judges屬性
const competitionsWithJudges = competitionsData.data.map((comp: any) => ({
...comp,
judges: comp.judges || []
}))
setCompetitions(competitionsWithJudges)
} else {
// 沒有競賽資料是正常情況,不報錯
setCompetitions([])
}
} else {
// 沒有競賽數據是正常情況,不報錯
setCompetitions([])
}
// 載入當前競賽
const currentResponse = await fetch('/api/competitions/current')
const currentData = await currentResponse.json()
if (currentData.success) {
if (currentData.data) {
// 確保當前競賽也有judges屬性
const currentCompetitionWithJudges = {
...currentData.data,
judges: currentData.data.judges || []
}
setCurrentCompetition(currentCompetitionWithJudges)
} else {
// 沒有當前競賽是正常情況,不報錯
setCurrentCompetition(null)
}
} else {
// 沒有當前競賽是正常情況,不報錯
setCurrentCompetition(null)
}
// 載入評審數據
const judgesResponse = await fetch('/api/admin/judges')
const judgesData = await judgesResponse.json()
if (judgesData.success) {
if (judgesData.data && judgesData.data.length > 0) {
setJudges(judgesData.data)
} else {
setJudges([])
}
} else {
// 沒有評審數據是正常情況,不報錯
setJudges([])
}
} catch (error) {
console.error('❌ 載入競賽數據失敗:', error)
}
}
loadCompetitions()
}, [])
// Load judge scores from localStorage
const [judgeScores, setJudgeScores] = useState<JudgeScore[]>(() => {
if (typeof window !== "undefined") {
const saved = localStorage.getItem("judgeScores")
if (saved) {
return JSON.parse(saved)
}
}
// 評分資料
const mockScores: JudgeScore[] = []
return mockScores
})
// Load proposal judge scores from localStorage
const [proposalJudgeScores, setProposalJudgeScores] = useState<ProposalJudgeScore[]>(() => {
if (typeof window !== "undefined") {
const saved = localStorage.getItem("proposalJudgeScores")
if (saved) {
return JSON.parse(saved)
}
}
// 提案評分資料
const mockProposalScores: ProposalJudgeScore[] = []
return mockProposalScores
})
// Load awards from database
const [awards, setAwards] = useState<Award[]>([])
const [loadingAwards, setLoadingAwards] = useState(false)
// Save to localStorage when data changes
useEffect(() => {
if (typeof window !== "undefined") {
localStorage.setItem("judgeScores", JSON.stringify(judgeScores))
}
}, [judgeScores])
useEffect(() => {
if (typeof window !== "undefined") {
localStorage.setItem("proposalJudgeScores", JSON.stringify(proposalJudgeScores))
}
}, [proposalJudgeScores])
// 載入獎項數據
useEffect(() => {
loadAwards()
}, [])
const addJudge = (judge: Omit<Judge, "id">) => {
const newJudge: Judge = {
...judge,
id: `j${Date.now()}`,
}
setJudges((prev) => [...prev, newJudge])
}
const updateJudge = (id: string, updates: Partial<Judge>) => {
setJudges((prev) => prev.map((judge) => (judge.id === id ? { ...judge, ...updates } : judge)))
}
const deleteJudge = (id: string) => {
setJudges((prev) => {
const filtered = prev.filter((judge) => judge.id !== id)
return filtered
})
setCompetitions((prev) =>
prev.map((comp) => ({
...comp,
judges: comp.judges ? comp.judges.filter((judgeId) => judgeId !== id) : [],
})),
)
setJudgeScores((prev) => prev.filter((score) => score.judgeId !== id))
setProposalJudgeScores((prev) => prev.filter((score) => score.judgeId !== id))
}
const addCompetition = (competition: Omit<Competition, "id">) => {
const newCompetition: Competition = {
...competition,
id: `c${Date.now()}`,
}
setCompetitions((prev) => [...prev, newCompetition])
}
const updateCompetition = (id: string, updates: Partial<Competition>) => {
setCompetitions((prev) => prev.map((comp) => (comp.id === id ? { ...comp, ...updates } : comp)))
if (currentCompetition?.id === id) {
setCurrentCompetition((prev) => (prev ? { ...prev, ...updates } : null))
}
}
const deleteCompetition = (id: string) => {
setCompetitions((prev) => prev.filter((comp) => comp.id !== id))
if (currentCompetition?.id === id) {
setCurrentCompetition(null)
}
}
const addTeam = (team: Omit<Team, "id">) => {
const newTeam: Team = {
...team,
id: `t${Date.now()}`,
}
setTeams((prev) => [...prev, newTeam])
}
const updateTeam = (id: string, updates: Partial<Team>) => {
setTeams((prev) => prev.map((team) => (team.id === id ? { ...team, ...updates } : team)))
}
const getTeamById = (id: string): Team | undefined => {
return teams.find((team) => team.id === id)
}
const addProposal = (proposal: Omit<Proposal, "id">) => {
const newProposal: Proposal = {
...proposal,
id: `p${Date.now()}`,
}
setProposals((prev) => [...prev, newProposal])
}
const updateProposal = (id: string, updates: Partial<Proposal>) => {
setProposals((prev) => prev.map((proposal) => (proposal.id === id ? { ...proposal, ...updates } : proposal)))
}
const getProposalById = (id: string): Proposal | undefined => {
return proposals.find((proposal) => proposal.id === id)
}
const addJudgeScore = (score: Omit<JudgeScore, "submittedAt">) => {
const newScore: JudgeScore = {
...score,
submittedAt: new Date().toISOString(),
}
const filteredScores = judgeScores.filter((s) => !(s.judgeId === score.judgeId && s.appId === score.appId))
setJudgeScores([...filteredScores, newScore])
}
const addProposalJudgeScore = (score: Omit<ProposalJudgeScore, "submittedAt">) => {
const newScore: ProposalJudgeScore = {
...score,
submittedAt: new Date().toISOString(),
}
const filteredScores = proposalJudgeScores.filter(
(s) => !(s.judgeId === score.judgeId && s.proposalId === score.proposalId),
)
setProposalJudgeScores([...filteredScores, newScore])
}
const submitJudgeScore = async (score: Omit<JudgeScore, "submittedAt">) => {
try {
// 轉換評分格式以符合API要求
const apiScores = {
innovation_score: score.scores.innovation || 0,
technical_score: score.scores.technical || 0,
usability_score: score.scores.usability || 0,
presentation_score: score.scores.presentation || 0,
impact_score: score.scores.impact || 0
}
const response = await fetch('/api/admin/scoring', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
judgeId: score.judgeId,
participantId: score.appId,
participantType: 'app',
scores: apiScores,
comments: score.comments
})
})
const data = await response.json()
if (data.success) {
// 更新本地狀態
addJudgeScore(score)
} else {
throw new Error(data.message || '評分提交失敗')
}
} catch (error) {
console.error('評分提交失敗:', error)
throw error
}
}
const submitProposalJudgeScore = (score: Omit<ProposalJudgeScore, "submittedAt">) => {
addProposalJudgeScore(score)
}
const getAppJudgeScores = (appId: string): JudgeScore[] => {
return judgeScores.filter((score) => score.appId === appId)
}
const getProposalJudgeScores = (proposalId: string): ProposalJudgeScore[] => {
return proposalJudgeScores.filter((score) => score.proposalId === proposalId)
}
const getAppAverageScore = (appId: string): number => {
const scores = getAppJudgeScores(appId)
if (scores.length === 0) return 0
const totalScore = scores.reduce((sum, score) => {
const scoreSum = Object.values(score.scores).reduce((a, b) => a + b, 0)
return sum + scoreSum
}, 0)
return Number((totalScore / (scores.length * 5)).toFixed(1))
}
const getProposalAverageScore = (proposalId: string): number => {
const scores = getProposalJudgeScores(proposalId)
if (scores.length === 0) return 0
const totalScore = scores.reduce((sum, score) => {
const scoreSum = Object.values(score.scores).reduce((a, b) => a + b, 0)
return sum + scoreSum
}, 0)
return Number((totalScore / (scores.length * 5)).toFixed(1))
}
const getAppDetailedScores = (appId: string) => {
const scores = getAppJudgeScores(appId)
if (scores.length === 0) {
return {
innovation: 0,
technical: 0,
usability: 0,
presentation: 0,
impact: 0,
total: 0,
judgeCount: 0,
}
}
const totals = scores.reduce(
(acc, score) => ({
innovation: acc.innovation + score.scores.innovation,
technical: acc.technical + score.scores.technical,
usability: acc.usability + score.scores.usability,
presentation: acc.presentation + score.scores.presentation,
impact: acc.impact + score.scores.impact,
}),
{ innovation: 0, technical: 0, usability: 0, presentation: 0, impact: 0 },
)
const judgeCount = scores.length
const averages = {
innovation: Number((totals.innovation / judgeCount).toFixed(1)),
technical: Number((totals.technical / judgeCount).toFixed(1)),
usability: Number((totals.usability / judgeCount).toFixed(1)),
presentation: Number((totals.presentation / judgeCount).toFixed(1)),
impact: Number((totals.impact / judgeCount).toFixed(1)),
}
const total = Number(
(
(totals.innovation + totals.technical + totals.usability + totals.presentation + totals.impact) /
(judgeCount * 5)
).toFixed(1),
)
return {
...averages,
total,
judgeCount,
}
}
const getProposalDetailedScores = (proposalId: string) => {
const scores = getProposalJudgeScores(proposalId)
if (scores.length === 0) {
return {
problemIdentification: 0,
solutionFeasibility: 0,
innovation: 0,
impact: 0,
presentation: 0,
total: 0,
judgeCount: 0,
}
}
const totals = scores.reduce(
(acc, score) => ({
problemIdentification: acc.problemIdentification + score.scores.problemIdentification,
solutionFeasibility: acc.solutionFeasibility + score.scores.solutionFeasibility,
innovation: acc.innovation + score.scores.innovation,
impact: acc.impact + score.scores.impact,
presentation: acc.presentation + score.scores.presentation,
}),
{ problemIdentification: 0, solutionFeasibility: 0, innovation: 0, impact: 0, presentation: 0 },
)
const judgeCount = scores.length
const averages = {
problemIdentification: Number((totals.problemIdentification / judgeCount).toFixed(1)),
solutionFeasibility: Number((totals.solutionFeasibility / judgeCount).toFixed(1)),
innovation: Number((totals.innovation / judgeCount).toFixed(1)),
impact: Number((totals.impact / judgeCount).toFixed(1)),
presentation: Number((totals.presentation / judgeCount).toFixed(1)),
}
const total = Number(
(
(totals.problemIdentification +
totals.solutionFeasibility +
totals.innovation +
totals.impact +
totals.presentation) /
(judgeCount * 5)
).toFixed(1),
)
return {
...averages,
total,
judgeCount,
}
}
// 載入獎項數據
const loadAwards = async () => {
setLoadingAwards(true)
try {
console.log('🔍 開始載入前台獎項數據...')
const response = await fetch('/api/admin/awards')
const data = await response.json()
if (data.success) {
console.log('📊 載入獎項數據:', data.data.length, '個')
console.log('📋 獎項數據樣本:', data.data.slice(0, 2))
setAwards(data.data)
} else {
console.error('載入獎項失敗:', data.message)
setAwards([])
}
} catch (error) {
console.error('載入獎項失敗:', error)
setAwards([])
} finally {
setLoadingAwards(false)
}
}
const addAward = (award: Omit<Award, "id">) => {
const newAward: Award = {
...award,
id: `a${Date.now()}`,
}
setAwards((prev) => {
// 檢查是否已存在相同的獎項基於競賽ID、參賽者ID和獎項名稱
const exists = prev.some((existingAward: any) =>
existingAward.competitionId === newAward.competitionId &&
existingAward.participantId === newAward.participantId &&
existingAward.awardName === newAward.awardName
)
if (exists) {
console.log('⚠️ 獎項已存在,跳過重複添加:', newAward)
return prev
}
console.log('✅ 添加新獎項:', newAward)
return [...prev, newAward]
})
}
const updateAward = (award: Award) => {
setAwards((prev) => {
const index = prev.findIndex((existingAward) => existingAward.id === award.id)
if (index === -1) {
console.log('⚠️ 找不到要更新的獎項:', award.id)
return prev
}
console.log('✅ 更新獎項:', award)
const updated = [...prev]
updated[index] = award
return updated
})
}
const deleteAward = (awardId: string) => {
setAwards((prev) => {
const filtered = prev.filter((award) => award.id !== awardId)
if (filtered.length === prev.length) {
console.log('⚠️ 找不到要刪除的獎項:', awardId)
return prev
}
console.log('✅ 刪除獎項:', awardId)
return filtered
})
}
const getAwardsByYear = (year: number): Award[] => {
return awards.filter((award) => award.year === year)
}
// 獲取所有可用的年份
const getAvailableYears = (): number[] => {
const years = [...new Set(awards.map(award => award.year))].sort((a, b) => b - a)
return years
}
const getAwardsByMonth = (year: number, month: number): Award[] => {
return awards.filter((award) => award.year === year && award.month === month)
}
const getCompetitionRankings = (competitionId?: string) => {
const targetCompetition = competitionId ? competitions.find((c) => c.id === competitionId) : currentCompetition
if (!targetCompetition) return []
const rankings: any[] = []
// Handle individual competitions
if (targetCompetition.type === "individual" || targetCompetition.type === "mixed") {
targetCompetition.participatingApps.forEach((appId) => {
const detailedScores = getAppDetailedScores(appId)
const appNames: Record<string, string> = {
"1": "智能對話助手",
"2": "圖像生成工具",
"3": "語音識別系統",
"4": "智能推薦引擎",
"5": "文本分析器",
"6": "AI創意寫作",
}
const creators: Record<string, string> = {
"1": "張小明",
"2": "李美華",
"3": "王大偉",
"4": "陳小芳",
"5": "劉志強",
"6": "黃小玲",
}
rankings.push({
appId,
appName: appNames[appId] || `應用 ${appId}`,
creator: creators[appId] || "未知",
totalScore: detailedScores.total,
scores: {
innovation: detailedScores.innovation,
technical: detailedScores.technical,
usability: detailedScores.usability,
presentation: detailedScores.presentation,
impact: detailedScores.impact,
},
rank: 0,
competitionType: "individual" as const,
})
})
}
// Handle team competitions
if (targetCompetition.type === "team" || targetCompetition.type === "mixed") {
targetCompetition.participatingTeams.forEach((teamId) => {
const team = getTeamById(teamId)
if (team) {
// Calculate team score based on their apps
let totalScore = 0
let appCount = 0
team.apps.forEach((appId) => {
const appScore = getAppDetailedScores(appId)
totalScore += appScore.total
appCount++
})
const averageScore = appCount > 0 ? totalScore / appCount : 0
rankings.push({
teamId,
teamName: team.name,
creator: `${team.members.find((m) => m.id === team.leader)?.name}團隊`,
totalScore: averageScore,
scores: {
teamwork: averageScore * 0.25,
technical: averageScore * 0.25,
innovation: averageScore * 0.25,
practical: averageScore * 0.25,
},
rank: 0,
competitionType: "team" as const,
appCount: team.apps.length,
totalLikes: team.totalLikes,
members: team.members,
})
}
})
}
// Handle proposal competitions
if (targetCompetition.type === "proposal" || targetCompetition.type === "mixed") {
targetCompetition.participatingProposals.forEach((proposalId) => {
const proposal = getProposalById(proposalId)
const detailedScores = getProposalDetailedScores(proposalId)
if (proposal) {
const team = getTeamById(proposal.teamId)
rankings.push({
proposalId,
proposalTitle: proposal.title,
creator: team?.name || "未知團隊",
totalScore: detailedScores.total,
scores: {
problemIdentification: detailedScores.problemIdentification,
solutionFeasibility: detailedScores.solutionFeasibility,
innovation: detailedScores.innovation,
impact: detailedScores.impact,
presentation: detailedScores.presentation,
},
rank: 0,
competitionType: "proposal" as const,
proposal,
team,
})
}
})
}
// Sort by total score and assign ranks within each competition type
const individualRankings = rankings
.filter((r) => r.competitionType === "individual")
.sort((a, b) => b.totalScore - a.totalScore)
.map((item, index) => ({ ...item, rank: index + 1 }))
const teamRankings = rankings
.filter((r) => r.competitionType === "team")
.sort((a, b) => b.totalScore - a.totalScore)
.map((item, index) => ({ ...item, rank: index + 1 }))
const proposalRankings = rankings
.filter((r) => r.competitionType === "proposal")
.sort((a, b) => b.totalScore - a.totalScore)
.map((item, index) => ({ ...item, rank: index + 1 }))
// Combine all rankings
return [...individualRankings, ...teamRankings, ...proposalRankings]
}
// Add new filtering functions
const getAwardsByCompetitionType = (competitionType?: string) => {
if (!competitionType || competitionType === "all") return awards
return awards.filter((award) => award.competitionType === competitionType)
}
const getAwardsByCategory = (category?: string) => {
if (!category || category === "all") return awards
return awards.filter((award) => award.category === category)
}
const getTopRankingAwards = () => {
return awards.filter((award) => award.rank > 0 && award.rank <= 3)
}
const getPopularityAwards = () => {
return awards.filter((award) => award.awardType === "popular")
}
const getPopularityRankings = (competitionId?: string) => {
const targetCompetition = competitionId ? competitions.find((c) => c.id === competitionId) : currentCompetition
if (!targetCompetition) return []
const rankings: any[] = []
// Get participants based on competition type
const participants =
targetCompetition.type === "individual"
? targetCompetition.participatingApps
: targetCompetition.type === "team"
? targetCompetition.participatingTeams
: targetCompetition.participatingProposals
// For each participant, calculate popularity based on likes
participants.forEach((participantId) => {
const appNames: Record<string, string> = {
"1": "智能對話助手",
"2": "圖像生成工具",
"3": "語音識別系統",
"4": "智能推薦引擎",
"5": "文本分析器",
"6": "AI創意寫作",
}
const creators: Record<string, string> = {
"1": "張小明",
"2": "李美華",
"3": "王大偉",
"4": "陳小芳",
"5": "劉志強",
"6": "黃小玲",
}
const departments: Record<string, string> = {
"1": "HQBU",
"2": "ITBU",
"3": "MBU1",
"4": "SBU",
"5": "HQBU",
"6": "ITBU",
}
const types: Record<string, string> = {
"1": "文字處理",
"2": "圖像生成",
"3": "語音辨識",
"4": "推薦系統",
"5": "文字處理",
"6": "文字處理",
}
// Get likes from appLikesCounter
const likes = appLikesCounter[participantId] || 0
rankings.push({
id: participantId,
name: appNames[participantId] || `應用 ${participantId}`,
creator: creators[participantId] || "未知",
department: departments[participantId] || "未知",
type: types[participantId] || "未知",
likes: likes,
rank: 0, // Will be calculated after sorting
})
})
// Sort by likes and assign ranks
return rankings.sort((a, b) => b.likes - a.likes).map((item, index) => ({ ...item, rank: index + 1 }))
}
// Add these functions to the context value
return (
<CompetitionContext.Provider
value={{
judges,
addJudge,
updateJudge,
deleteJudge,
competitions,
currentCompetition,
setCurrentCompetition,
addCompetition,
updateCompetition,
deleteCompetition,
teams,
addTeam,
updateTeam,
getTeamById,
proposals,
addProposal,
updateProposal,
getProposalById,
judgeScores,
proposalJudgeScores,
addJudgeScore,
addProposalJudgeScore,
submitJudgeScore,
submitProposalJudgeScore,
getAppJudgeScores,
getProposalJudgeScores,
getAppAverageScore,
getProposalAverageScore,
getAppDetailedScores,
getProposalDetailedScores,
awards,
loadingAwards,
loadAwards,
addAward,
updateAward,
deleteAward,
getAwardsByYear,
getAwardsByMonth,
getAvailableYears,
getCompetitionRankings,
getAwardsByCompetitionType,
getAwardsByCategory,
getTopRankingAwards,
getPopularityAwards,
getPopularityRankings,
}}
>
{children}
</CompetitionContext.Provider>
)
}
export function useCompetition() {
const context = useContext(CompetitionContext)
if (context === undefined) {
throw new Error("useCompetition must be used within a CompetitionProvider")
}
return context
}