diff --git a/api/allMovieType.ts b/api/allMovieType.ts index f22cad1..c9b742f 100644 --- a/api/allMovieType.ts +++ b/api/allMovieType.ts @@ -363,4 +363,167 @@ export enum Gender { export interface Multilingual_video extends MultilingualVideo {} export interface RootObject extends VideoFlowProjectResponse {} + /** + * 新角色列表项接口 + */ + export interface NewCharacterItem { + /** 角色名称 */ + character_name: string; + /** 角色描述 */ + character_description: string; + /** 角色类型 */ + role: string; + /** 图片路径 */ + image_path: string; + /** 语音ID */ + voice_id: string; + /** 语音URL */ + voice_url: string; + /** 语音描述 */ + voice_desc: string; + /** 简介 */ + brief: string; + /** 性别 */ + gender: string; + /** 体型年龄 */ + physique_age: string; + /** 关键视觉锚点 */ + key_visual_anchors: string; + /** 发型 */ + hairstyle: string; + /** 默认表情 */ + default_demeanor: string; + /** 种族 */ + race: string; + } + /** + * 新角色列表响应接口 + */ + export interface NewCharacterListResponse { + /** 角色列表 */ + data: NewCharacterItem[]; + } + +/** + * 项目角色列表请求参数 + */ +export interface CharacterListByProjectRequest { + /** 项目ID */ + project_id: string; + /** 每个角色最多提取的高亮关键词数量 */ + max_keywords?: number; +} + +/** + * 项目角色列表项(含高亮关键词) + */ +export interface CharacterListByProjectItem { + /** 角色名称 */ + character_name: string; + /** 角色自然语言描述 */ + character_description: string; + /** 角色类型/作用 */ + role?: string; + /** 角色图片URL */ + image_path?: string; + /** 角色语音ID */ + voice_id?: string; + /** 角色语音音频URL */ + voice_url?: string; + /** 角色语音描述 */ + voice_desc?: string; + /** 角色简要说明/摘要 */ + brief?: string; + /** 性别 */ + gender?: string; + /** 体格与年龄描述 */ + physique_age?: string; + /** 关键视觉锚点 */ + key_visual_anchors?: string; + /** 发型描述 */ + hairstyle?: string; + /** 默认行为/性格 */ + default_demeanor?: string; + /** 种族/人种 */ + race?: string; + /** 从角色描述提取的高亮关键词/短语 */ + highlights: string[]; +} + +/** + * 项目角色列表响应 + */ +export interface CharacterListByProjectWithHighlightResponse { + /** 项目ID */ + project_id: string; + /** 角色列表 */ + characters: CharacterListByProjectItem[]; +} + +/** + * 角色更新和重新生成请求参数 + */ +export interface CharacterUpdateAndRegenerateRequest { + /** 项目ID */ + project_id: string; + /** 角色名称 */ + character_name: string; + /** 新的角色描述 */ + character_description: string; + /** 返回的高亮关键词数量上限 */ + max_keywords?: number; +} + +/** + * 角色更新和重新生成响应 + */ +export interface CharacterUpdateAndRegenerateResponse { + /** 项目ID */ + project_id: string; + /** 更新后的角色对象 */ + character: { + /** 角色名称 */ + character_name: string; + /** 角色描述(已更新) */ + character_description: string; + /** 重新生成产物的图片地址 */ + image_path?: string; + /** 角色类型/作用 */ + role?: string; + /** 性别 */ + gender?: string; + /** 角色简要说明/摘要 */ + brief?: string; + /** 从角色描述提取的高亮关键词/短语 */ + highlights: string[]; + }; +} + +/** + * 角色描述生成请求接口 + */ +export interface CharacterGenerateDescriptionRequest { + /** 前端提供的原始文字描述 */ + original_text: string; + /** 优化类型 */ + optimization_type?: string; + /** 风格偏好 */ + style_preference?: string; +} + +/** + * 角色描述生成响应接口 + */ +export interface CharacterGenerateDescriptionResponse { + /** 原始文本 */ + original_text: string; + /** 优化后的角色描述 */ + optimized_description: string; + /** 提取的关键词 */ + keywords: string[]; + /** 优化类型 */ + optimization_type: string; + /** 风格偏好 */ + style_preference: string; +} diff --git a/api/video_flow.ts b/api/video_flow.ts index 9b800db..85092ba 100644 --- a/api/video_flow.ts +++ b/api/video_flow.ts @@ -15,7 +15,8 @@ import { ScriptSlice, } from "@/app/service/domain/valueObject"; import { task_item, VideoSegmentEntityAdapter } from "@/app/service/adapter/oldErrAdapter"; -import { VideoFlowProjectResponse } from "./allMovieType"; +import { VideoFlowProjectResponse, NewCharacterItem, NewCharacterListResponse, CharacterListByProjectWithHighlightResponse, CharacterUpdateAndRegenerateRequest, CharacterUpdateAndRegenerateResponse } from "./allMovieType"; +import { RoleResponse } from "@/app/service/usecase/RoleEditUseCase"; // API 响应类型 interface BaseApiResponse { @@ -815,3 +816,67 @@ export const updateShotPrompt = async (request: { }): Promise> => { return post("/movie/update_shot_prompt", request); }; + +/** + * 人脸识别接口 + * @param request - 人脸识别请求参数 + * @returns Promise> 人脸识别结果 + */ +export const faceRecognition = async (request: { + /** 项目ID */ + project_id: string; + /** 视频ID */ + video_id: string; + /** 目标图片URL */ + target_image_url: string; +}): Promise> => { + return post>("/character/face_recognition", request); +}; + +/** + * 获取所有角色列表接口 + * @returns Promise> 所有角色列表 + */ +export const getAllCharacterList = async (): Promise> => { + return post>("/character/list_all"); +}; + +/** + * 获取项目角色列表(含高亮关键词)接口 + * @param request - 项目角色列表请求参数 + * @returns Promise> 项目角色列表 + */ +export const getCharacterListByProjectWithHighlight = async (request: { + /** 项目ID */ + project_id: string; + /** 每个角色最多提取的高亮关键词数量 */ + max_keywords?: number; +}): Promise> => { + return post("/character/list_by_project_with_highlight", request); +}; + +/** + * 角色更新和重新生成接口 + * @param request - 角色更新和重新生成请求参数 + * @returns Promise> 更新后的角色信息 + */ +export const updateAndRegenerateCharacter = async (request: CharacterUpdateAndRegenerateRequest): Promise> => { + return post>("/character/update_and_regenerate", request); +}; + +/** + * 角色描述智能优化接口 + * @param request - 角色描述优化请求参数 + * @returns Promise> + */ +export const generateCharacterDescription = async (request: { + /** 前端提供的原始文字描述 */ + original_text: string; +}): Promise> => { + return post("/character/generate_description", request); +}; diff --git a/app/service/Interaction/RoleService.ts b/app/service/Interaction/RoleService.ts index 00347ce..a755c82 100644 --- a/app/service/Interaction/RoleService.ts +++ b/app/service/Interaction/RoleService.ts @@ -47,6 +47,7 @@ export const useRoleServiceHook = (): UseRoleService => { const [selectedRole, setSelectedRole] = useState(null); const [currentRoleText, setCurrentRoleText] = useState(null); const [userRoleLibrary, setUserRoleLibrary] = useState([]); + const [projectId, setProjectId] = useState(''); // 添加项目ID状态 // UseCase实例 - 在角色选择时初始化 const [roleEditUseCase, setRoleEditUseCase] = useState(null); @@ -69,6 +70,9 @@ export const useRoleServiceHook = (): UseRoleService => { */ const fetchRoleList = useCallback(async (projectId: string) => { try { + // 保存项目ID到状态 + setProjectId(projectId); + // 初始化角色编辑UseCase实例 const newRoleEditUseCase = new RoleEditUseCase(); const roleList = await newRoleEditUseCase.getRoleList(projectId); @@ -122,11 +126,10 @@ export const useRoleServiceHook = (): UseRoleService => { /** * 优化AI文本 * @description 对当前角色的AI文本进行优化 - * @param userSuggestion 用户优化建议 * @throws {Error} 当没有可优化的文本内容或UseCase未初始化时抛出错误 * @returns {Promise} 优化完成后的Promise */ - const optimizeRoleText = useCallback(async (userSuggestion: string) => { + const optimizeRoleText = useCallback(async () => { if (!roleEditUseCase) { throw new Error('角色编辑UseCase未初始化'); } @@ -135,22 +138,45 @@ export const useRoleServiceHook = (): UseRoleService => { throw new Error('没有可优化的文本内容'); } - try { - const optimizedDescription = await roleEditUseCase.optimizeRoleDescription(userSuggestion, currentRoleText); - setCurrentRoleText(optimizedDescription); + if (!selectedRole) { + throw new Error('没有选中的角色'); + } - // 更新角色列表中的对应角色描述 + try { + const { optimizedDescription, keywords } = await roleEditUseCase.optimizeRoleDescription(selectedRole); + setCurrentRoleText(optimizedDescription); + // 更新角色列表中的对应角色描述和标签 setRoleList(prev => prev.map(role => role.id === selectedRole?.id - ? { ...role, generateText: optimizedDescription } + ? { + ...role, + generateText: optimizedDescription, + tags: keywords.map(keyword => ({ + id: `tag_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`, + /** 名称 */ + name: keyword, + /** 内容 */ + content: keyword, + loadingProgress: 100, + disableEdit: false + })) + } : role ) ); // 更新当前选中角色 if (selectedRole) { - setSelectedRole({ ...selectedRole, generateText: optimizedDescription }); + setSelectedRole({ ...selectedRole, generateText: optimizedDescription, tags: keywords.map(keyword => ({ + id: `tag_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`, + /** 名称 */ + name: keyword, + /** 内容 */ + content: keyword, + loadingProgress: 100, + disableEdit: false + })) }); } } catch (error) { console.error('优化角色文本失败:', error); @@ -202,8 +228,16 @@ export const useRoleServiceHook = (): UseRoleService => { throw new Error('缺少重新生成角色所需的数据'); } + if (!projectId) { + throw new Error('缺少项目ID,无法重新生成角色'); + } + try { - const newRoleEntity = await roleEditUseCase.AIgenerateRole(currentRoleText); + const newRoleEntity = await roleEditUseCase.AIgenerateRole( + projectId, + selectedRole.name, + currentRoleText + ); setSelectedRole(newRoleEntity); // 更新角色列表 @@ -218,7 +252,7 @@ export const useRoleServiceHook = (): UseRoleService => { console.error('重新生成角色失败:', error); throw error; } - }, [roleEditUseCase, selectedRole, currentRoleText]); + }, [roleEditUseCase, selectedRole, currentRoleText, projectId]); /** * 获取用户角色库 diff --git a/app/service/Interaction/SceneService.ts b/app/service/Interaction/SceneService.ts index 1d02113..6e3719d 100644 --- a/app/service/Interaction/SceneService.ts +++ b/app/service/Interaction/SceneService.ts @@ -30,8 +30,8 @@ interface UseSceneService { sceneList: SceneItem[]; /** 当前选中的场景 */ selectedScene: SceneItem | null; - /** 当前场景的AI文本 */ - currentSceneText: TextItem | null; + // /** 当前场景的AI文本 */ + // currentSceneText: TextItem | null; // TODO: TextEditUseCase not implemented yet /** 当前场景的标签列表 */ currentSceneTags: TagItem[]; /** 场景图片URL */ @@ -50,10 +50,10 @@ interface UseSceneService { selectScene: (sceneId: string) => void; /** 初始化当前选中场景的AI文本和标签数据 */ initializeSceneData: () => Promise; - /** 优化AI文本 */ - optimizeSceneText: () => Promise; - /** 修改AI文本 */ - updateSceneText: (newContent: string) => Promise; + // /** 优化AI文本 */ + // optimizeSceneText: () => Promise; // TODO: TextEditUseCase not implemented yet + // /** 修改AI文本 */ + // updateSceneText: (newContent: string) => Promise; // TODO: TextEditUseCase not implemented yet /** 修改标签内容 */ updateTagContent: (tagId: string, newContent: string | number) => Promise; /** 重新生成场景 */ @@ -76,13 +76,13 @@ export const useSceneServiceHook = (): UseSceneService => { // 响应式状态 const [sceneList, setSceneList] = useState([]); const [selectedScene, setSelectedScene] = useState(null); - const [currentSceneText, setCurrentSceneText] = useState(null); + // const [currentSceneText, setCurrentSceneText] = useState(null); // TODO: TextEditUseCase not implemented yet const [currentSceneTags, setCurrentSceneTags] = useState([]); const [shotSelectionList, setShotSelectionList] = useState([]); // UseCase实例 - 在场景选择时初始化 const [sceneEditUseCase, setSceneEditUseCase] = useState(null); - const [textEditUseCase, setTextEditUseCase] = useState(null); + // const [textEditUseCase, setTextEditUseCase] = useState(null); // TODO: TextEditUseCase not implemented yet const [tagEditUseCases, setTagEditUseCases] = useState>(new Map()); // 计算属性 diff --git a/app/service/Interaction/ShotService.ts b/app/service/Interaction/ShotService.ts index 27f4cbe..05aad39 100644 --- a/app/service/Interaction/ShotService.ts +++ b/app/service/Interaction/ShotService.ts @@ -40,7 +40,7 @@ export interface UseShotService { /** 删除指定镜头 */ deleteLens: (lensName: string) => void; /** 获取视频当前帧并上传到七牛云 */ - filterRole: (video: HTMLVideoElement) => Promise; + filterRole: (video: HTMLVideoElement, projectId: string, videoId: string) => Promise; /** 设置角色简单数据 */ setSimpleCharacter: (characters: SimpleCharacter[]) => void; } @@ -95,8 +95,6 @@ export const useShotService = (): UseShotService => { */ const regenerateVideoSegment = useCallback( async ( - // roleReplaceParams?: { oldId: string; newId: string }[], - // sceneReplaceParams?: { oldId: string; newId: string }[] ): Promise => { try { setLoading(true); @@ -105,8 +103,6 @@ export const useShotService = (): UseShotService => { projectId, selectedSegment!.lens, selectedSegment!.id, - // roleReplaceParams, - // sceneReplaceParams ); // 如果重新生成的是现有片段,更新列表中的对应项 @@ -116,9 +112,6 @@ export const useShotService = (): UseShotService => { segment.id === selectedSegment.id ? regeneratedSegment : segment ) ); - } else { - // 如果是新生成的片段,添加到列表中 - setVideoSegments(prev => [...prev, regeneratedSegment]); } return regeneratedSegment; @@ -253,14 +246,19 @@ export const useShotService = (): UseShotService => { /** * 获取视频当前帧的画面,上传到七牛云,并返回七牛云的图片地址,然后调用接口识别出里面的人物信息,返回人物信息 * @param video HTML视频元素 + * @param projectId 项目ID + * @param videoId 视频ID * @returns Promise 七牛云的图片地址 */ - const filterRole = useCallback(async (video: HTMLVideoElement): Promise => { + const filterRole = useCallback(async ( + video: HTMLVideoElement, + ): Promise => { try { // 创建canvas元素来截取视频帧 const canvas = document.createElement('canvas'); const ctx = canvas.getContext('2d'); - + console.log(video); + video.crossOrigin = 'anonymous'; if (!ctx) { throw new Error('无法获取canvas上下文'); } @@ -292,12 +290,26 @@ export const useShotService = (): UseShotService => { // 上传到七牛云 const imageUrl = await uploadToQiniu(file, token); + // 调用用例中的识别角色方法 + if (vidoEditUseCase) { + try { + const recognitionResult = await vidoEditUseCase.recognizeRoleFromImage( + projectId, + selectedSegment!.id, + imageUrl + ); + console.log('角色识别结果:', recognitionResult); + } catch (recognitionError) { + console.warn('角色识别失败,但图片上传成功:', recognitionError); + } + } + return imageUrl; } catch (error) { console.error('获取视频帧失败:', error); throw error; } - }, []); + }, [projectId, selectedSegment, vidoEditUseCase]); return { // 响应式状态 loading, diff --git a/app/service/domain/Item.ts b/app/service/domain/Item.ts index 758347a..84abd70 100644 --- a/app/service/domain/Item.ts +++ b/app/service/domain/Item.ts @@ -2,10 +2,10 @@ import { BaseEntity, AITextEntity, RoleEntity, - TagValueObject, SceneEntity, VideoSegmentEntity } from './Entities'; +import { TagValueObject } from './valueObject'; /** * 可编辑项类型枚举 diff --git a/app/service/domain/valueObject.ts b/app/service/domain/valueObject.ts index 331baa6..0d6e30a 100644 --- a/app/service/domain/valueObject.ts +++ b/app/service/domain/valueObject.ts @@ -83,10 +83,16 @@ export class LensType { * 标签实体接口 */ export interface TagValueObject { + /** 唯一标识 */ + readonly id: string; /** 标签名称 */ name: string; /** 内容标签类型 */ content: number | string; + /**loading进度 0-100 */ + loadingProgress: number; + /** 禁止编辑 */ + disableEdit: boolean; } diff --git a/app/service/usecase/RoleEditUseCase.ts b/app/service/usecase/RoleEditUseCase.ts index e4db496..16432ce 100644 --- a/app/service/usecase/RoleEditUseCase.ts +++ b/app/service/usecase/RoleEditUseCase.ts @@ -1,17 +1,30 @@ -import { VideoFlowProjectResponse } from '@/api/allMovieType'; +import { NewCharacterItem, CharacterListByProjectItem, CharacterListByProjectWithHighlightResponse, CharacterUpdateAndRegenerateRequest, CharacterUpdateAndRegenerateResponse } from '@/api/allMovieType'; import { RoleEntity } from '../domain/Entities'; import { applyRoleToShots, getRoleList, - getUserRoleLibrary, getRoleData, regenerateRole, getRoleShots, replaceRole, - optimizeRoleDescription, - detailScriptEpisodeNew + getAllCharacterList, + getCharacterListByProjectWithHighlight, + updateAndRegenerateCharacter, + getUserRoleLibrary, + generateCharacterDescription, } from '@/api/video_flow'; +export interface RoleResponse { + /** 角色描述 */ + character_description: string; + /** 角色名称 */ + character_name: string; + /** 高亮关键词 */ + highlights: string[]; + /** 角色图片地址 */ + image_path: string; +} + /** * 角色图编辑用例 * 负责角色图内容的初始化、修改和优化 @@ -32,22 +45,31 @@ export class RoleEditUseCase { */ async getRoleList(projectId: string): Promise { try { - // const response = await getRoleList({ projectId }); - const detail = await detailScriptEpisodeNew({ project_id: projectId }); - const roleList = this.parseRoleList(detail.data); - if (detail.successful) { + // 使用新的项目角色列表接口 + const response = await getCharacterListByProjectWithHighlight({ + project_id: projectId, + max_keywords: 6 // 默认提取6个关键词 + }); + + if (response.successful) { + const roleList = this.parseProjectRoleList(response.data); return roleList; } else { - throw new Error(detail.message || '获取角色列表失败'); + throw new Error(response.message || '获取项目角色列表失败'); } } catch (error) { - console.error('获取角色列表失败:', error); + console.error('获取项目角色列表失败:', error); throw error; } } - parseRoleList(detail: VideoFlowProjectResponse): RoleEntity[] { - const characters = detail.data?.character.data || []; + /** + * 解析新角色列表接口返回的数据 + * @param newCharacterData 新角色列表数据 + * @returns RoleEntity[] 角色实体数组 + */ + parseNewRoleList(newCharacterData: { data: NewCharacterItem[] }): RoleEntity[] { + const characters = newCharacterData.data || []; return characters.map((char, index) => { const roleEntity: RoleEntity = { @@ -65,15 +87,64 @@ export class RoleEditUseCase { }); } + /** + * 解析项目角色列表接口返回的数据 + * @description 将接口返回的项目角色列表数据转换为RoleEntity数组 + * @param {RoleResponse[]} projectRoleData - 项目角色列表数据 + * @returns {RoleEntity[]} 角色实体数组 + * @throws {Error} 如果数据格式不正确则抛出异常 + */ + /** + * 解析项目角色列表接口返回的数据 + * @description 将接口返回的项目角色列表数据转换为RoleEntity数组 + * @param {RoleResponse[]} projectRoleData - 项目角色列表数据 + * @returns {RoleEntity[]} 角色实体数组 + * @throws {Error} 如果数据格式不正确则抛出异常 + */ + parseProjectRoleList(projectRoleData: RoleResponse[]): RoleEntity[] { + if (!Array.isArray(projectRoleData)) { + throw new Error('项目角色数据格式错误'); + } + + return projectRoleData.map((char, index) => { + /** 角色实体对象 */ + const roleEntity: RoleEntity = { + id: `role_${index + 1}`, + name: char.character_name || '', + generateText: char.character_description || '', + tags: Array.isArray(char.highlights) + ? char.highlights.map((highlight: string) => ({ + id: `tag_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`, + updatedAt: Date.now(), + /** 名称 */ + name: highlight, + /** 内容 */ + content: highlight, + loadingProgress: 100, + disableEdit: false + })) + : [], + imageUrl: char.image_path || '', + loadingProgress: 100, + disableEdit: false, + updatedAt: Date.now() + }; + + return roleEntity; + }); + } + /** * 获取角色库的角色列表 * @returns Promise 角色库列表 */ async getRoleLibraryList(): Promise { try { - const response = await getUserRoleLibrary(); + // 使用新的角色列表接口获取角色库 + const response = await getAllCharacterList(); if (response.successful) { - return response.data; + const roleList = this.parseNewRoleList(response.data); + return roleList; } else { throw new Error(response.message || '获取角色库失败'); } @@ -108,26 +179,54 @@ export class RoleEditUseCase { } /** - * 重新生成角色 - * @param prompt 角色提示词 - * @returns Promise 重新生成的角色 + * AI生成角色 + * @param projectId 项目ID + * @param characterName 角色名称 + * @param characterDescription 角色描述 + * @returns Promise 生成的角色实体 */ - async AIgenerateRole(prompt: string): Promise { + async AIgenerateRole( + projectId: string, + characterName: string, + characterDescription: string + ): Promise { try { - // 直接使用当前角色的ID,不做任何处理 - const response = await regenerateRole({ - prompt, - tagTypes: [], // 标签现在只是文本的一部分,传递空数组 - roleId: this.selectedRole?.id + // 使用新的角色更新和重新生成接口 + const response = await updateAndRegenerateCharacter({ + project_id: projectId, + character_name: characterName, + character_description: characterDescription, + max_keywords: 6 // 默认提取6个关键词 }); - if (response.successful) { - return response.data; - } else { - throw new Error(response.message || '重新生成角色失败'); + if (!response.successful) { + throw new Error(response.message || 'AI生成角色失败'); } + + const characterData = response.data.character; + + // 将API响应转换为RoleEntity + const roleEntity: RoleEntity = { + id: `role_${Date.now()}`, // 生成唯一ID + name: characterData.character_name, + generateText: characterData.character_description, + tags: (characterData.highlights || []).map(highlight => ({ + id: `tag_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`, + updatedAt: Date.now(), + name: highlight, + content: highlight, + loadingProgress: 100, + disableEdit: false + })), // 将高亮关键词转换为TagValueObject格式 + imageUrl: characterData.image_path || '', + loadingProgress: 100, + disableEdit: false, + updatedAt: Date.now() + }; + + return roleEntity; } catch (error) { - console.error('重新生成角色失败:', error); + console.error('AI生成角色失败:', error); throw error; } } @@ -201,36 +300,36 @@ export class RoleEditUseCase { /** * @description: AI优化当前角色描述 - * @param userSuggestion 用户优化建议 - * @param roleDescription 角色描述文本 - * @returns Promise 优化后的角色描述 + * @param selectedRole 角色描述文本 + * @returns Promise<{optimizedDescription: string, keywords: string[]}> 优化后的角色描述和关键词 */ - async optimizeRoleDescription(userSuggestion: string, roleDescription: string): Promise { + async optimizeRoleDescription( selectedRole: RoleEntity): Promise<{optimizedDescription: string, keywords: string[]}> { try { if (!this.selectedRole) { throw new Error('请先选择角色'); } - // 调用AI优化角色描述API - const response = await optimizeRoleDescription({ - roleId: this.selectedRole.id, - userSuggestion, - roleDescription, + // 调用新的AI优化角色描述API + const response = await generateCharacterDescription({ + original_text: selectedRole.generateText, }); if (!response.successful) { throw new Error(response.message || 'AI优化角色描述失败'); } - const optimizedDescription = response.data.optimizedDescription; + const { optimized_description, keywords } = response.data; // 更新角色列表中的对应角色描述 const roleIndex = this.roleList.findIndex(role => role.id === this.selectedRole?.id); if (roleIndex !== -1) { - this.roleList[roleIndex].generateText = optimizedDescription; + this.roleList[roleIndex].generateText = optimized_description; } - return optimizedDescription; + return { + optimizedDescription: optimized_description, + keywords: keywords + }; } catch (error) { console.error('AI优化角色描述失败:', error); throw error; diff --git a/app/service/usecase/ShotEditUsecase.ts b/app/service/usecase/ShotEditUsecase.ts index 0e2d03f..2296055 100644 --- a/app/service/usecase/ShotEditUsecase.ts +++ b/app/service/usecase/ShotEditUsecase.ts @@ -8,6 +8,7 @@ import { optimizeShotContent, updateShotPrompt, detailScriptEpisodeNew, + faceRecognition, } from "@/api/video_flow"; /** @@ -234,4 +235,41 @@ export class VideoSegmentEditUseCase { isLoading(): boolean { return this.loading; } + + /** + * @description 识别视频帧中的角色 + * @param projectId 项目ID + * @param videoId 视频ID + * @param targetImageUrl 目标图片URL + * @returns Promise 识别结果 + */ + async recognizeRoleFromImage( + projectId: string, + videoId: string, + targetImageUrl: string + ): Promise { + try { + this.loading = true; + + const response = await faceRecognition({ + project_id: projectId, + video_id: videoId, + target_image_url: targetImageUrl, + }); + + if (!response.successful) { + throw new Error(response.message || "人脸识别失败"); + } + + // 打印返回结果 + console.log('人脸识别接口返回结果:', response); + + return response.data; + } catch (error) { + console.error("人脸识别失败:", error); + throw error; + } finally { + this.loading = false; + } + } } diff --git a/app/service/usecase/TagEditUseCase.ts b/app/service/usecase/TagEditUseCase.ts index 8e3e5d6..adeb502 100644 --- a/app/service/usecase/TagEditUseCase.ts +++ b/app/service/usecase/TagEditUseCase.ts @@ -35,8 +35,12 @@ export class TagEditUseCase { // 创建新标签 const newTag: TagValueObject = { + id: `tag_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`, + updatedAt: Date.now(), name: tagName, - content: content + content: content, + loadingProgress: 100, + disableEdit: false }; this.tagList.push(newTag); diff --git a/package-lock.json b/package-lock.json index 28771c9..a89eeae 100644 --- a/package-lock.json +++ b/package-lock.json @@ -133,7 +133,6 @@ }, "node_modules/@ampproject/remapping": { "version": "2.3.0", - "dev": true, "license": "Apache-2.0", "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", @@ -242,7 +241,6 @@ }, "node_modules/@babel/code-frame": { "version": "7.27.1", - "dev": true, "license": "MIT", "dependencies": { "@babel/helper-validator-identifier": "^7.27.1", @@ -255,7 +253,6 @@ }, "node_modules/@babel/compat-data": { "version": "7.28.0", - "dev": true, "license": "MIT", "engines": { "node": ">=6.9.0" @@ -263,7 +260,6 @@ }, "node_modules/@babel/core": { "version": "7.28.0", - "dev": true, "license": "MIT", "dependencies": { "@ampproject/remapping": "^2.2.0", @@ -294,7 +290,6 @@ "version": "2.2.3", "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", - "dev": true, "license": "MIT", "bin": { "json5": "lib/cli.js" @@ -307,7 +302,6 @@ "version": "6.3.1", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, "license": "ISC", "bin": { "semver": "bin/semver.js" @@ -315,7 +309,6 @@ }, "node_modules/@babel/generator": { "version": "7.28.0", - "dev": true, "license": "MIT", "dependencies": { "@babel/parser": "^7.28.0", @@ -330,7 +323,6 @@ }, "node_modules/@babel/helper-compilation-targets": { "version": "7.27.2", - "dev": true, "license": "MIT", "dependencies": { "@babel/compat-data": "^7.27.2", @@ -345,7 +337,6 @@ }, "node_modules/@babel/helper-compilation-targets/node_modules/lru-cache": { "version": "5.1.1", - "dev": true, "license": "ISC", "dependencies": { "yallist": "^3.0.2" @@ -355,7 +346,6 @@ "version": "6.3.1", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, "license": "ISC", "bin": { "semver": "bin/semver.js" @@ -363,7 +353,6 @@ }, "node_modules/@babel/helper-globals": { "version": "7.28.0", - "dev": true, "license": "MIT", "engines": { "node": ">=6.9.0" @@ -371,7 +360,6 @@ }, "node_modules/@babel/helper-module-imports": { "version": "7.27.1", - "dev": true, "license": "MIT", "dependencies": { "@babel/traverse": "^7.27.1", @@ -383,7 +371,6 @@ }, "node_modules/@babel/helper-module-transforms": { "version": "7.27.3", - "dev": true, "license": "MIT", "dependencies": { "@babel/helper-module-imports": "^7.27.1", @@ -409,7 +396,6 @@ }, "node_modules/@babel/helper-string-parser": { "version": "7.27.1", - "dev": true, "license": "MIT", "engines": { "node": ">=6.9.0" @@ -417,7 +403,6 @@ }, "node_modules/@babel/helper-validator-identifier": { "version": "7.27.1", - "dev": true, "license": "MIT", "engines": { "node": ">=6.9.0" @@ -425,7 +410,6 @@ }, "node_modules/@babel/helper-validator-option": { "version": "7.27.1", - "dev": true, "license": "MIT", "engines": { "node": ">=6.9.0" @@ -433,7 +417,6 @@ }, "node_modules/@babel/helpers": { "version": "7.28.2", - "dev": true, "license": "MIT", "dependencies": { "@babel/template": "^7.27.2", @@ -445,7 +428,6 @@ }, "node_modules/@babel/parser": { "version": "7.28.0", - "dev": true, "license": "MIT", "dependencies": { "@babel/types": "^7.28.0" @@ -707,7 +689,6 @@ }, "node_modules/@babel/template": { "version": "7.27.2", - "dev": true, "license": "MIT", "dependencies": { "@babel/code-frame": "^7.27.1", @@ -720,7 +701,6 @@ }, "node_modules/@babel/traverse": { "version": "7.28.0", - "dev": true, "license": "MIT", "dependencies": { "@babel/code-frame": "^7.27.1", @@ -737,7 +717,6 @@ }, "node_modules/@babel/types": { "version": "7.28.2", - "dev": true, "license": "MIT", "dependencies": { "@babel/helper-string-parser": "^7.27.1", @@ -1741,6 +1720,17 @@ "node": ">=6.0.0" } }, + "node_modules/@jridgewell/source-map": { + "version": "0.3.10", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.10.tgz", + "integrity": "sha512-0pPkgz9dY+bijgistcTTJ5mR+ocqRXLuhXHYdzoMmmoJ2C9S46RCm2GMUbatPEUK9Yjy26IrAy8D/M00lLkv+Q==", + "license": "MIT", + "peer": true, + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25" + } + }, "node_modules/@jridgewell/sourcemap-codec": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", @@ -7657,16 +7647,16 @@ } }, "node_modules/@tiptap/core": { - "version": "3.0.7", - "resolved": "https://registry.npmmirror.com/@tiptap/core/-/core-3.0.7.tgz", - "integrity": "sha512-/NC0BbekWzi5sC+s7gRrGIv33cUfuiZUG5DWx8TNedA6b6aTFPHUe+2wKRPaPQ0pfGdOWU0nsOkboUJ9dAjl4g==", + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/@tiptap/core/-/core-3.0.9.tgz", + "integrity": "sha512-1zdDyILerBcD3P0fu8kCtPLOFj0R5utjexCQ2CZ46pckn/Wk4V+WUBARzhG5Yz2JDkmJIUIcmLBVrL6G1rjJWg==", "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/pm": "^3.0.7" + "@tiptap/pm": "^3.0.9" } }, "node_modules/@tiptap/extension-blockquote": { @@ -7997,23 +7987,23 @@ } }, "node_modules/@tiptap/extensions": { - "version": "3.0.7", - "resolved": "https://registry.npmmirror.com/@tiptap/extensions/-/extensions-3.0.7.tgz", - "integrity": "sha512-GkXX5l7Q/543BKsC14j8M3qT+75ILb7138zy7cZoHm/s1ztV1XTknpEswBZIRZA9n6qq+Wd9g5qkbR879s6xhA==", + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/@tiptap/extensions/-/extensions-3.0.9.tgz", + "integrity": "sha512-IyTcPnZXUf0nxDkC+CCWh10vzn81Kq50euV/ivk8IyPr15hxPiT3Zk1LmCI10Pqf4Bwgz38XUIWtToDfIeEgpg==", "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/core": "^3.0.7", - "@tiptap/pm": "^3.0.7" + "@tiptap/core": "^3.0.9", + "@tiptap/pm": "^3.0.9" } }, "node_modules/@tiptap/pm": { - "version": "3.0.7", - "resolved": "https://registry.npmmirror.com/@tiptap/pm/-/pm-3.0.7.tgz", - "integrity": "sha512-f8PnWjYqbMCxny8cyjbFNeIyeOYLECTa/7gj8DJr53Ns+P94b4kYIt/GkveR5KoOxsbmXi8Uc4mjcR1giQPaIQ==", + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/@tiptap/pm/-/pm-3.0.9.tgz", + "integrity": "sha512-cJdnpGyirRxwi6M4IkyapEK/jhcjFXdfX3uhJp/4uVH1dynNXalV0gE/YnH/yt55kzwvG9OUrwOQt+t1iXgNog==", "license": "MIT", "dependencies": { "prosemirror-changeset": "^2.3.0", @@ -8241,6 +8231,28 @@ "@types/ms": "*" } }, + "node_modules/@types/eslint": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-9.6.1.tgz", + "integrity": "sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag==", + "license": "MIT", + "peer": true, + "dependencies": { + "@types/estree": "*", + "@types/json-schema": "*" + } + }, + "node_modules/@types/eslint-scope": { + "version": "3.7.7", + "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz", + "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==", + "license": "MIT", + "peer": true, + "dependencies": { + "@types/eslint": "*", + "@types/estree": "*" + } + }, "node_modules/@types/estree": { "version": "1.0.8", "resolved": "https://registry.npmmirror.com/@types/estree/-/estree-1.0.8.tgz", @@ -8319,6 +8331,13 @@ "pretty-format": "^30.0.0" } }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "license": "MIT", + "peer": true + }, "node_modules/@types/json5": { "version": "0.0.29", "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", @@ -8972,12 +8991,187 @@ "win32" ] }, + "node_modules/@webassemblyjs/ast": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.14.1.tgz", + "integrity": "sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "@webassemblyjs/helper-numbers": "1.13.2", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2" + } + }, + "node_modules/@webassemblyjs/floating-point-hex-parser": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.13.2.tgz", + "integrity": "sha512-6oXyTOzbKxGH4steLbLNOu71Oj+C8Lg34n6CqRvqfS2O71BxY6ByfMDRhBytzknj9yGUPVJ1qIKhRlAwO1AovA==", + "license": "MIT", + "peer": true + }, + "node_modules/@webassemblyjs/helper-api-error": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.13.2.tgz", + "integrity": "sha512-U56GMYxy4ZQCbDZd6JuvvNV/WFildOjsaWD3Tzzvmw/mas3cXzRJPMjP83JqEsgSbyrmaGjBfDtV7KDXV9UzFQ==", + "license": "MIT", + "peer": true + }, + "node_modules/@webassemblyjs/helper-buffer": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.14.1.tgz", + "integrity": "sha512-jyH7wtcHiKssDtFPRB+iQdxlDf96m0E39yb0k5uJVhFGleZFoNw1c4aeIcVUPPbXUVJ94wwnMOAqUHyzoEPVMA==", + "license": "MIT", + "peer": true + }, + "node_modules/@webassemblyjs/helper-numbers": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.13.2.tgz", + "integrity": "sha512-FE8aCmS5Q6eQYcV3gI35O4J789wlQA+7JrqTTpJqn5emA4U2hvwJmvFRC0HODS+3Ye6WioDklgd6scJ3+PLnEA==", + "license": "MIT", + "peer": true, + "dependencies": { + "@webassemblyjs/floating-point-hex-parser": "1.13.2", + "@webassemblyjs/helper-api-error": "1.13.2", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/helper-wasm-bytecode": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.13.2.tgz", + "integrity": "sha512-3QbLKy93F0EAIXLh0ogEVR6rOubA9AoZ+WRYhNbFyuB70j3dRdwH9g+qXhLAO0kiYGlg3TxDV+I4rQTr/YNXkA==", + "license": "MIT", + "peer": true + }, + "node_modules/@webassemblyjs/helper-wasm-section": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.14.1.tgz", + "integrity": "sha512-ds5mXEqTJ6oxRoqjhWDU83OgzAYjwsCV8Lo/N+oRsNDmx/ZDpqalmrtgOMkHwxsG0iI//3BwWAErYRHtgn0dZw==", + "license": "MIT", + "peer": true, + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/wasm-gen": "1.14.1" + } + }, + "node_modules/@webassemblyjs/ieee754": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.13.2.tgz", + "integrity": "sha512-4LtOzh58S/5lX4ITKxnAK2USuNEvpdVV9AlgGQb8rJDHaLeHciwG4zlGr0j/SNWlr7x3vO1lDEsuePvtcDNCkw==", + "license": "MIT", + "peer": true, + "dependencies": { + "@xtuc/ieee754": "^1.2.0" + } + }, + "node_modules/@webassemblyjs/leb128": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.13.2.tgz", + "integrity": "sha512-Lde1oNoIdzVzdkNEAWZ1dZ5orIbff80YPdHx20mrHwHrVNNTjNr8E3xz9BdpcGqRQbAEa+fkrCb+fRFTl/6sQw==", + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/utf8": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.13.2.tgz", + "integrity": "sha512-3NQWGjKTASY1xV5m7Hr0iPeXD9+RDobLll3T9d2AO+g3my8xy5peVyjSag4I50mR1bBSN/Ct12lo+R9tJk0NZQ==", + "license": "MIT", + "peer": true + }, + "node_modules/@webassemblyjs/wasm-edit": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.14.1.tgz", + "integrity": "sha512-RNJUIQH/J8iA/1NzlE4N7KtyZNHi3w7at7hDjvRNm5rcUXa00z1vRz3glZoULfJ5mpvYhLybmVcwcjGrC1pRrQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/helper-wasm-section": "1.14.1", + "@webassemblyjs/wasm-gen": "1.14.1", + "@webassemblyjs/wasm-opt": "1.14.1", + "@webassemblyjs/wasm-parser": "1.14.1", + "@webassemblyjs/wast-printer": "1.14.1" + } + }, + "node_modules/@webassemblyjs/wasm-gen": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.14.1.tgz", + "integrity": "sha512-AmomSIjP8ZbfGQhumkNvgC33AY7qtMCXnN6bL2u2Js4gVCg8fp735aEiMSBbDR7UQIj90n4wKAFUSEd0QN2Ukg==", + "license": "MIT", + "peer": true, + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/ieee754": "1.13.2", + "@webassemblyjs/leb128": "1.13.2", + "@webassemblyjs/utf8": "1.13.2" + } + }, + "node_modules/@webassemblyjs/wasm-opt": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.14.1.tgz", + "integrity": "sha512-PTcKLUNvBqnY2U6E5bdOQcSM+oVP/PmrDY9NzowJjislEjwP/C4an2303MCVS2Mg9d3AJpIGdUFIQQWbPds0Sw==", + "license": "MIT", + "peer": true, + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/wasm-gen": "1.14.1", + "@webassemblyjs/wasm-parser": "1.14.1" + } + }, + "node_modules/@webassemblyjs/wasm-parser": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.14.1.tgz", + "integrity": "sha512-JLBl+KZ0R5qB7mCnud/yyX08jWFw5MsoalJ1pQ4EdFlgj9VdXKGuENGsiCIjegI1W7p91rUlcB/LB5yRJKNTcQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-api-error": "1.13.2", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/ieee754": "1.13.2", + "@webassemblyjs/leb128": "1.13.2", + "@webassemblyjs/utf8": "1.13.2" + } + }, + "node_modules/@webassemblyjs/wast-printer": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.14.1.tgz", + "integrity": "sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw==", + "license": "MIT", + "peer": true, + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@xtuc/long": "4.2.2" + } + }, "node_modules/@webgpu/types": { "version": "0.1.63", "resolved": "https://registry.npmmirror.com/@webgpu/types/-/types-0.1.63.tgz", "integrity": "sha512-s9Kuh0nE/2+nKrvmKNMB2fE5Zlr3DL2t3OFKM55v5jRcfCOxbkOHhQoshoFum5mmXIfEtRXtLCWmkeTJsVjE9w==", "license": "BSD-3-Clause" }, + "node_modules/@xtuc/ieee754": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", + "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", + "license": "BSD-3-Clause", + "peer": true + }, + "node_modules/@xtuc/long": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", + "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", + "license": "Apache-2.0", + "peer": true + }, "node_modules/acorn": { "version": "8.15.0", "resolved": "https://registry.npmmirror.com/acorn/-/acorn-8.15.0.tgz", @@ -8990,6 +9184,19 @@ "node": ">=0.4.0" } }, + "node_modules/acorn-import-phases": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/acorn-import-phases/-/acorn-import-phases-1.0.4.tgz", + "integrity": "sha512-wKmbr/DDiIXzEOiWrTTUcDm24kQ2vGfZQvM2fwg2vXqR5uW6aapr7ObPtj1th32b9u90/Pf4AItvdTh42fBmVQ==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=10.13.0" + }, + "peerDependencies": { + "acorn": "^8.14.0" + } + }, "node_modules/acorn-jsx": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", @@ -9015,6 +9222,48 @@ "url": "https://github.com/sponsors/epoberezkin" } }, + "node_modules/ajv-formats": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", + "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", + "license": "MIT", + "peer": true, + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/ajv-formats/node_modules/ajv": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "license": "MIT", + "peer": true, + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-formats/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "license": "MIT", + "peer": true + }, "node_modules/ansi-escapes": { "version": "4.3.2", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", @@ -9682,7 +9931,6 @@ }, "node_modules/buffer-from": { "version": "1.1.2", - "dev": true, "license": "MIT" }, "node_modules/busboy": { @@ -9912,6 +10160,16 @@ "node": ">= 6" } }, + "node_modules/chrome-trace-event": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.4.tgz", + "integrity": "sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=6.0" + } + }, "node_modules/ci-info": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.3.0.tgz", @@ -10161,7 +10419,6 @@ }, "node_modules/convert-source-map": { "version": "2.0.0", - "dev": true, "license": "MIT" }, "node_modules/copy-to-clipboard": { @@ -10920,6 +11177,13 @@ "node": ">= 0.4" } }, + "node_modules/es-module-lexer": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.7.0.tgz", + "integrity": "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==", + "license": "MIT", + "peer": true + }, "node_modules/es-object-atoms": { "version": "1.1.1", "resolved": "https://registry.npmmirror.com/es-object-atoms/-/es-object-atoms-1.1.1.tgz", @@ -11569,6 +11833,16 @@ "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", "license": "MIT" }, + "node_modules/events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=0.8.x" + } + }, "node_modules/execa": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", @@ -11686,6 +11960,23 @@ "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", "license": "MIT" }, + "node_modules/fast-uri": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.6.tgz", + "integrity": "sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "BSD-3-Clause", + "peer": true + }, "node_modules/fastq": { "version": "1.17.1", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", @@ -11971,7 +12262,6 @@ }, "node_modules/gensync": { "version": "1.0.0-beta.2", - "dev": true, "license": "MIT", "engines": { "node": ">=6.9.0" @@ -13981,6 +14271,37 @@ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, + "node_modules/jest-worker": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", + "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", + "license": "MIT", + "peer": true, + "dependencies": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/jest-worker/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "license": "MIT", + "peer": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, "node_modules/jiti": { "version": "1.21.6", "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.6.tgz", @@ -14010,7 +14331,6 @@ }, "node_modules/jsesc": { "version": "3.1.0", - "dev": true, "license": "MIT", "bin": { "jsesc": "bin/jsesc" @@ -14027,7 +14347,6 @@ }, "node_modules/json-parse-even-better-errors": { "version": "2.3.1", - "dev": true, "license": "MIT" }, "node_modules/json-schema-traverse": { @@ -14158,6 +14477,16 @@ "integrity": "sha512-NT1CJtq3hHIreOianA8aSXn6Cw0JzYOuDQbOrSPe7gqFnCpKP++MQe3ODgO3oh2GJFORkAAdqredOa60z63GbA==", "license": "MIT" }, + "node_modules/loader-runner": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", + "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=6.11.5" + } + }, "node_modules/locate-path": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", @@ -14629,7 +14958,6 @@ }, "node_modules/merge-stream": { "version": "2.0.0", - "dev": true, "license": "MIT" }, "node_modules/merge2": { @@ -15545,6 +15873,13 @@ "node": ">= 0.6" } }, + "node_modules/neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "license": "MIT", + "peer": true + }, "node_modules/next": { "version": "13.5.1", "resolved": "https://registry.npmjs.org/next/-/next-13.5.1.tgz", @@ -16668,6 +17003,16 @@ "integrity": "sha512-tQkJl2GRWh83ui2DiPTJz9wEiMN20syf+5oKfB03yYP7ioZcJwsIK8FjrtLwH1m7C7e+Tt2yYBlrOpdT+dyeIQ==", "license": "MIT" }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, "node_modules/rc-cascader": { "version": "3.34.0", "resolved": "https://registry.npmmirror.com/rc-cascader/-/rc-cascader-3.34.0.tgz", @@ -18046,6 +18391,16 @@ "node": ">=0.10.0" } }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/reselect": { "version": "5.1.1", "resolved": "https://registry.npmmirror.com/reselect/-/reselect-5.1.1.tgz", @@ -18257,6 +18612,63 @@ "loose-envify": "^1.1.0" } }, + "node_modules/schema-utils": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.2.tgz", + "integrity": "sha512-Gn/JaSk/Mt9gYubxTtSn/QCV4em9mpAPiR1rqy/Ocu19u/G9J5WWdNoUT4SiV6mFC3y6cxyFcFwdzPM3FgxGAQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "@types/json-schema": "^7.0.9", + "ajv": "^8.9.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.1.0" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/schema-utils/node_modules/ajv": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "license": "MIT", + "peer": true, + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/schema-utils/node_modules/ajv-keywords": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", + "license": "MIT", + "peer": true, + "dependencies": { + "fast-deep-equal": "^3.1.3" + }, + "peerDependencies": { + "ajv": "^8.8.2" + } + }, + "node_modules/schema-utils/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "license": "MIT", + "peer": true + }, "node_modules/scroll": { "version": "3.0.1", "resolved": "https://registry.npmmirror.com/scroll/-/scroll-3.0.1.tgz", @@ -18296,6 +18708,16 @@ "node": ">=10" } }, + "node_modules/serialize-javascript": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", + "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", + "license": "BSD-3-Clause", + "peer": true, + "dependencies": { + "randombytes": "^2.1.0" + } + }, "node_modules/set-function-length": { "version": "1.2.2", "license": "MIT", @@ -18472,7 +18894,6 @@ }, "node_modules/source-map": { "version": "0.6.1", - "dev": true, "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" @@ -18487,6 +18908,17 @@ "node": ">=0.10.0" } }, + "node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "license": "MIT", + "peer": true, + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, "node_modules/space-separated-tokens": { "version": "2.0.2", "resolved": "https://registry.npmmirror.com/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz", @@ -19130,6 +19562,67 @@ "node": ">=6" } }, + "node_modules/terser": { + "version": "5.43.1", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.43.1.tgz", + "integrity": "sha512-+6erLbBm0+LROX2sPXlUYx/ux5PyE9K/a92Wrt6oA+WDAoFTdpHE5tCYCI5PNzq2y8df4rA+QgHLJuR4jNymsg==", + "license": "BSD-2-Clause", + "peer": true, + "dependencies": { + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.14.0", + "commander": "^2.20.0", + "source-map-support": "~0.5.20" + }, + "bin": { + "terser": "bin/terser" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/terser-webpack-plugin": { + "version": "5.3.14", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.14.tgz", + "integrity": "sha512-vkZjpUjb6OMS7dhV+tILUW6BhpDR7P2L/aQSAv+Uwk+m8KATX9EccViHTJR2qDtACKPIYndLGCyl3FMo+r2LMw==", + "license": "MIT", + "peer": true, + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.25", + "jest-worker": "^27.4.5", + "schema-utils": "^4.3.0", + "serialize-javascript": "^6.0.2", + "terser": "^5.31.1" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.1.0" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "uglify-js": { + "optional": true + } + } + }, + "node_modules/terser/node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "license": "MIT", + "peer": true + }, "node_modules/test-exclude": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", @@ -19929,6 +20422,103 @@ "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", "license": "BSD-2-Clause" }, + "node_modules/webpack": { + "version": "5.101.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.101.0.tgz", + "integrity": "sha512-B4t+nJqytPeuZlHuIKTbalhljIFXeNRqrUGAQgTGlfOl2lXXKXw+yZu6bicycP+PUlM44CxBjCFD6aciKFT3LQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "@types/eslint-scope": "^3.7.7", + "@types/estree": "^1.0.8", + "@types/json-schema": "^7.0.15", + "@webassemblyjs/ast": "^1.14.1", + "@webassemblyjs/wasm-edit": "^1.14.1", + "@webassemblyjs/wasm-parser": "^1.14.1", + "acorn": "^8.15.0", + "acorn-import-phases": "^1.0.3", + "browserslist": "^4.24.0", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^5.17.2", + "es-module-lexer": "^1.2.1", + "eslint-scope": "5.1.1", + "events": "^3.2.0", + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.2.11", + "json-parse-even-better-errors": "^2.3.1", + "loader-runner": "^4.2.0", + "mime-types": "^2.1.27", + "neo-async": "^2.6.2", + "schema-utils": "^4.3.2", + "tapable": "^2.1.1", + "terser-webpack-plugin": "^5.3.11", + "watchpack": "^2.4.1", + "webpack-sources": "^3.3.3" + }, + "bin": { + "webpack": "bin/webpack.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependenciesMeta": { + "webpack-cli": { + "optional": true + } + } + }, + "node_modules/webpack-sources": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.3.3.tgz", + "integrity": "sha512-yd1RBzSGanHkitROoPFd6qsrxt+oFhg/129YzheDGqeustzX0vTZJZsSsQjVQC4yzBQ56K55XU8gaNCtIzOnTg==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/webpack/node_modules/eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "license": "BSD-2-Clause", + "peer": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/webpack/node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "license": "BSD-2-Clause", + "peer": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/webpack/node_modules/watchpack": { + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.4.tgz", + "integrity": "sha512-c5EGNOiyxxV5qmTtAB7rbiXxi1ooX1pQKMLX/MIabJjRA0SJBQOjKF+KSVfHkr9U1cADPon0mRiVe/riyaiDUA==", + "license": "MIT", + "peer": true, + "dependencies": { + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.1.2" + }, + "engines": { + "node": ">=10.13.0" + } + }, "node_modules/whatwg-url": { "version": "5.0.0", "resolved": "https://registry.npmmirror.com/whatwg-url/-/whatwg-url-5.0.0.tgz", @@ -20173,7 +20763,6 @@ }, "node_modules/yallist": { "version": "3.1.1", - "dev": true, "license": "ISC" }, "node_modules/yaml": {