aitu-app 0.9.2 → 0.9.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -3
- package/assets/{CanvasAudioPlayer-C_USx5uz.js → CanvasAudioPlayer-BKMfe-GO.js} +2 -2
- package/assets/{ComicCreator-qGQaXp7h.js → ComicCreator-D5HnnPYu.js} +3 -3
- package/assets/DeferredAIInputBar-CVXfAbVO.css +1 -0
- package/assets/DeferredAIInputBar-Ce250DxA.js +107 -0
- package/assets/{DrawnixDeferredFeatures-Hy_-quZ1.js → DrawnixDeferredFeatures-ue9KjDJ6.js} +2 -2
- package/assets/{KnowledgeBaseContent-DSKNA70H.js → KnowledgeBaseContent-YCNU2vP8.js} +5 -5
- package/assets/{MVCreator-C3iClDLU.js → MVCreator-uWWF5q7x.js} +4 -4
- package/assets/{ModelBenchmarkWorkbench-BxwdcZ0q.js → ModelBenchmarkWorkbench-Bm75hOT0.js} +2 -2
- package/assets/{MusicAnalyzer-f_T6_YPJ.js → MusicAnalyzer-BXe6y3_p.js} +1 -1
- package/assets/ParametersDropdown-BE58BbHs.css +1 -0
- package/assets/{ParametersDropdown-CTSN3ClD.js → ParametersDropdown-wKdOCk_p.js} +1 -1
- package/assets/{PromptHistoryTool-DV-8RSdz.js → PromptHistoryTool-BRMlnlE1.js} +2 -2
- package/assets/{ResizableDivider-CUQBmPpx.js → ResizableDivider-tAq9KErj.js} +1 -1
- package/assets/{TaskQueuePanel-CtjY1W4t.js → TaskQueuePanel-D4PA4azU.js} +1 -1
- package/assets/{VideoAnalyzer-BBVBSONO.js → VideoAnalyzer-CVqV3zd3.js} +3 -3
- package/assets/{VideoAnalyzer-BmAjGvN8.js → VideoAnalyzer-gVfFvd5A.js} +1 -1
- package/assets/{ai-chat-BO5vbKZW.js → ai-chat-D_s8vs6j.js} +45 -45
- package/assets/{ai-chat-DyV67c_f.css → ai-chat-_KImIteT.css} +1 -1
- package/assets/{ai-generation-preferences-service-ZmPTR-wz.js → ai-generation-preferences-service-rBqGBu1Z.js} +1 -1
- package/assets/{batch-image-generation-BLBSv-t6.js → batch-image-generation-BHunNwyR.js} +6 -6
- package/assets/{diagram-engines-CSzW_-6N.js → diagram-engines-y0JSIEUO.js} +3 -3
- package/assets/{editor-engines-C573k8UM.js → editor-engines-Cc9_gvTn.js} +1 -1
- package/assets/{index-BT-rxxI3.js → index-BECJnoIM.js} +1 -1
- package/assets/{index-jxwTv7c1.js → index-BOOKwIS8.js} +1 -1
- package/assets/{index-N8asYyaz.js → index-Co0sFz6V.js} +2 -2
- package/assets/{index-IHNaVKGH.js → index-CrsvRs42.js} +1 -1
- package/assets/{index-Dw_8lcIi.js → index-Dthb4yKS.js} +1 -1
- package/assets/{index.es-BLXvmueB.js → index.es-l6CUS7uC.js} +1 -1
- package/assets/{jspdf.es.min-DxWvbkh4.js → jspdf.es.min-vSonSXg8.js} +3 -3
- package/assets/{markdown-to-drawnix-BVFYnimo.js → markdown-to-drawnix-CkXxETO6.js} +3 -3
- package/assets/{mermaid-to-drawnix-nGs2aeZ7.js → mermaid-to-drawnix-CiiYHL53.js} +3 -3
- package/assets/{model-benchmark-launcher-DAWoSySc.js → model-benchmark-launcher-EfxZ9z3O.js} +1 -1
- package/assets/{photo-wall-splitter-CCUURzGk.js → photo-wall-splitter-BJ5RLX6n.js} +1 -1
- package/assets/{prompt-utils-MF_LILNU.js → prompt-utils-7NlWAivq.js} +1 -1
- package/assets/{settings-dialog-Ac7R-_CG.js → settings-dialog-CBNPo-wJ.js} +1 -1
- package/assets/{skill-dsl-parser-Do9iAYbB.js → skill-dsl-parser-9CW3IgX7.js} +1 -1
- package/assets/{startup-app-CKHrOmQ0.css → startup-app-BJH8E5sr.css} +1 -1
- package/assets/{startup-app-eD_rQhSh.js → startup-app-M6vjXkRC.js} +509 -504
- package/assets/{task-sync-BJVOunRa.js → task-sync-B01Tbv7m.js} +1 -1
- package/assets/{tool-windows-CmgL3thd.js → tool-windows-Cf62DjP-.js} +21 -21
- package/assets/ttd-dialog-O1oaoYry.js +6 -0
- package/assets/{ttd-dialog-submit-shortcut-C2lJygXA.js → ttd-dialog-submit-shortcut-rkvbdHF7.js} +1 -1
- package/assets/{useCharacters-BAKE4TeJ.js → useCharacters-BVPiqeuF.js} +1 -1
- package/assets/{useMediaViewer-BGw5RkSR.js → useMediaViewer-Be0fy5RZ.js} +1 -1
- package/assets/{useWorkflowSubmission-iAPmKke9.js → useWorkflowSubmission-BwYRubj-.js} +9 -9
- package/assets/{video-recovery-service-CW7bErP2.js → video-recovery-service-CUmfssNZ.js} +1 -1
- package/assets/{workflow-generation-utils-DhIVnOHO.js → workflow-generation-utils-362XEGgT.js} +3 -3
- package/assets/{workflow-submission-service-Ce0cpj8E.js → workflow-submission-service-Dk47OkGu.js} +2 -2
- package/changelog.json +18 -13
- package/idle-prefetch-manifest.json +286 -286
- package/manifest.json +3 -3
- package/package.json +1 -1
- package/precache-manifest.json +6 -6
- package/sw.js +1 -1
- package/version.json +3 -4
- package/assets/DeferredAIInputBar-CPykEFYX.css +0 -1
- package/assets/DeferredAIInputBar-LmZGQCLT.js +0 -107
- package/assets/ParametersDropdown-b2oWAycj.css +0 -1
- package/assets/ttd-dialog-B12v0SVY.js +0 -6
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import{j as t,E as ct,m$ as Ca,e0 as vt,n0 as fa,a1 as Wa,n1 as is,mQ as Vt,mV as ls,n2 as cs,n3 as Ut,n4 as us,n5 as ds,mT as ms,mY as ps,mZ as fs,n6 as xe,ck as ha,r as s,aw as we,aB as ut,n7 as Xe,gm as hs,jN as Qt,M as Se,n8 as wa,n9 as vs,am as $e,bz as ze,na as $t,nb as Ya,nc as qa,aA as Ft,nd as va,ah as ja,ne as gs,nf as Ze,ng as ys,bg as ge,nh as Za,ni as ea,nj as bs,mp as ta,nk as _s,nl as Ma,iV as Is,iX as xs,jo as Ss,nm as ka,ha as Tt,db as aa,nn as Cs,gT as Xa,dB as Ve,no as sa,np as Na,nq as ws,b7 as js,R as lt,ef as ra,eK as Pa,nr as Ms,$ as ks,l as Ns,mH as Ta,mI as Ps,mJ as Ts,ns as As,c1 as zs,mL as Es,mM as Ds,d as Rs,c as Vs,mN as Fs}from"./startup-app-eD_rQhSh.js";import{i as dt,j as Aa,k as za,T as Os,R as Ot,K as Ls,m as Ee,v as Ea,q as na,V as Ja,U as Us}from"./ai-chat-BO5vbKZW.js";import{e as $s,c as Bs,r as Gs,a as Hs,b as Ks,w as oa,d as Ws,g as Ys,f as qs}from"./workflow-generation-utils-DhIVnOHO.js";import{c as Da,f as Ra,g as Zs,d as Xs}from"./ai-generation-preferences-service-ZmPTR-wz.js";import{M as Va}from"./tool-windows-CmgL3thd.js";/* empty css *//* empty css */import{R as Js}from"./ResizableDivider-CUQBmPpx.js";import{P as Fa}from"./ParametersDropdown-CTSN3ClD.js";import{u as Qs}from"./VideoAnalyzer-BmAjGvN8.js";import"./startup-runtime-DTmhLESk.js";const er=({shots:e,totalDuration:r})=>t.jsx("div",{className:"va-timeline",children:e.filter(Boolean).map(l=>t.jsx(ct,{content:`${l.label||"未命名镜头"} ${l.startTime??0}s-${l.endTime??0}s`,showArrow:!1,children:t.jsx("div",{className:"va-timeline-segment",style:{flex:Math.max(((l.endTime??0)-(l.startTime??0))/Math.max(r,1),0),backgroundColor:l.type&&Ca[l.type]||Ca.other}})},l.id))});function Oa(e){return(e||"").trim().toLowerCase().replace(/[^a-z0-9]/g,"")||"mp4"}function tr(e){const r=e.name.split(".").pop();if(r&&r.length<=8)return Oa(r);const l=e.type.split("/")[1];return Oa(l)}async function ar(e,r){const l=tr(e),c=`/__aitu_cache__/video/${`video-analyzer-source-${Date.now()}-${Math.random().toString(36).slice(2,8)}`}.${l}`;return await vt.cacheMediaFromBlob(c,e,"video",{metadata:{source:"video-analyzer-input",fileName:e.name,mimeType:e.type||"video/mp4",size:e.size}}),{type:"upload",cacheUrl:c,fileName:e.name||`video-source.${l}`,mimeType:e.type||"video/mp4",size:e.size}}async function sr(e){if(!e||e.type!=="upload")return null;const r=await vt.getCachedBlob(e.cacheUrl);return r?new File([r],e.fileName||"video-source.mp4",{type:e.mimeType||r.type||"video/mp4",lastModified:Date.now()}):null}function Qa(e){return ps(e,"videoAnalyzerAction",["analyze","rewrite","prompt-generate"])}function rr(e){return fs(e,{missingMessage:"分析任务缺少结果内容",fromStructured:r=>r})}function nr(e){const r=e.params.videoAnalyzerSourceSnapshot;if((r==null?void 0:r.type)==="youtube"||(r==null?void 0:r.type)==="upload"||(r==null?void 0:r.type)==="prompt")return r;const l=e.params.videoAnalyzerSource,h=String(e.params.videoAnalyzerSourceLabel||"").trim();return l==="youtube"&&h?{type:"youtube",youtubeUrl:h}:l==="prompt"&&h?{type:"prompt",prompt:String(e.params.videoAnalyzerUserPrompt||h),pdfCacheUrl:Vt(e,"pdfCacheUrl")||void 0,pdfName:Vt(e,"pdfName")||void 0,pdfMimeType:Vt(e,"pdfMimeType")||void 0}:null}function or(e,r){const l=new Map(e.map(h=>[h.id,h]));return r.map(h=>{const c=l.get(h.id);return{...h,referenceImageUrl:h.referenceImageUrl||(c==null?void 0:c.referenceImageUrl)}})}function ir(e){var h;const r=(h=e.result)==null?void 0:h.analysisData,l=Array.isArray(r==null?void 0:r.editedShots)?r.editedShots:Array.isArray(r==null?void 0:r.shots)?r.shots:null;return!r||!l?null:{shots:l,characters:Array.isArray(r.characters)?r.characters:void 0,hasCharacters:Object.prototype.hasOwnProperty.call(r,"characters"),videoStyle:String(r.video_style||r.videoStyle||"").trim()||void 0,bgmMood:String(r.bgm_mood||r.bgmMood||"").trim()||void 0,suggestion:String(r.suggestion||"").trim()||void 0}}function lr(e,r){const l=e.params.videoAnalyzerProductInfo;if(!(!l||typeof l!="object"))return Ut(l,r)}async function Lt(e){var N,ie;if(e.status!=="completed")return null;const r=Qa(e);if(!r)return null;if(r==="analyze"||r==="prompt-generate"){const le=await fa(),L=le.find(f=>f.analyzeTaskId===e.id);if(L)return{records:le,record:L};const Q=rr(e),X=nr(e),he=e.params.videoAnalyzerSource,U=he==="prompt"?"prompt":he==="upload"?"upload":"youtube",D=String(e.params.videoAnalyzerSourceLabel||(U==="prompt"?"提示词生成":U==="youtube"?(X==null?void 0:X.type)==="youtube"?X.youtubeUrl:"":"本地视频")),me=lr(e,Q.totalDuration),ae={id:Wa(),createdAt:Date.now(),source:U,sourceLabel:D,sourceSnapshot:X,model:String(e.params.model||""),modelRef:e.params.modelRef||null,analysis:Q,...me?{productInfo:me}:{},starred:!1,analyzeTaskId:e.id};return{records:await is(ae),record:ae}}const l=Vt(e,"videoAnalyzerRecordId");if(!l)return null;const h=await fa(),c=h.find(le=>le.id===l);if(!c)return null;if(c.pendingRewriteTaskId!==e.id)return!c.pendingRewriteTaskId&&c.storyboardGeneratedAt&&(!e.completedAt||c.storyboardGeneratedAt>=e.completedAt)?{records:h,record:c}:null;const k=c.editedShots||c.analysis.shots,g=ir(e),I=g||(()=>{const le=ls(e);if(!le)throw new Error("脚本改编任务缺少结果内容");return cs(le,k)})(),O=I.shots,j=I.hasCharacters?or(c.characters||c.analysis.characters||[],I.characters||[]):void 0,S=I.videoStyle||I.bgmMood?{...Ut(c.productInfo||{prompt:""},c.analysis.totalDuration),...I.videoStyle?{videoStyle:I.videoStyle}:{},...I.bgmMood?{bgmMood:I.bgmMood}:{}}:void 0,T={...c.analysis,suggestion:I.suggestion||""},G=`AI 改编 #${(((N=c.scriptVersions)==null?void 0:N.length)||0)+1}`,Y=us(O,G,(ie=c.productInfo)==null?void 0:ie.prompt,{characters:j||c.characters||c.analysis.characters||[],productInfo:S||c.productInfo}),J=ds(c,Y);return ms(c,{...J,analysis:T,...j!==void 0?{characters:j}:{},...S?{productInfo:S}:{},pendingRewriteTaskId:null,storyboardGeneratedAt:Date.now()},xe)}function cr(e){return Qa(e)!==null}const ia="gemini-3.1-pro-preview",la="video-analyzer:model",At="video-analyzer:video-model",ca="veo3",zt=30,ur="aitu:settings:provider-nav",dr=20*1024*1024;function La(e){return(e/1024/1024).toFixed(1)+"MB"}function mr(e){const r=`${e.id} ${e.label} ${e.shortLabel||""} ${e.sourceProfileName||""}`.toLowerCase();return e.vendor===ja.GEMINI||e.vendor===ja.GOOGLE||r.includes("gemini")}const pr=({existingRecord:e,onComplete:r,onRecordsChange:l,onCreateNew:h,onNext:c})=>{const{setAppState:k}=ha(),[g,I]=s.useState("prompt"),[O,j]=s.useState(""),[S,T]=s.useState(()=>{var m;return((m=e==null?void 0:e.productInfo)==null?void 0:m.videoStyle)||(e==null?void 0:e.analysis.video_style)||""}),[G,Y]=s.useState(()=>{var m;return((m=e==null?void 0:e.productInfo)==null?void 0:m.targetDuration)||(e==null?void 0:e.analysis.totalDuration)||zt}),[J,N]=s.useState({}),[ie,le]=s.useState([]),[L,Q]=s.useState(null),[X,he]=s.useState(""),[U,D]=s.useState(null),[me,ae]=s.useState(()=>(e==null?void 0:e.model)||we(la,ia).modelId),[pe,f]=s.useState(()=>(e==null?void 0:e.modelRef)||we(la,ia).modelRef),R=s.useCallback((m,_)=>{ae(m),f(_||null),ut(la,m,_)},[]),A=dt("video"),[q,$]=s.useState(()=>{var m;return((m=e==null?void 0:e.productInfo)==null?void 0:m.videoModel)||we(At,ca).modelId}),[ee,K]=s.useState(()=>{var m,_;return((m=e==null?void 0:e.productInfo)==null?void 0:m.videoModelRef)||we(At,((_=e==null?void 0:e.productInfo)==null?void 0:_.videoModel)||ca).modelRef}),_e=s.useMemo(()=>Xe(q),[q]),[ce,ye]=s.useState(()=>{var w,F;const m=((w=e==null?void 0:e.productInfo)==null?void 0:w.videoModel)||we(At,ca).modelId,_=Xe(m);return((F=e==null?void 0:e.productInfo)==null?void 0:F.segmentDuration)||parseInt(_.defaultDuration,10)||8}),Oe=s.useMemo(()=>(_e.durationOptions||[]).map(m=>({value:parseInt(m.value,10),label:m.label})),[_e]),Je=s.useCallback((m,_)=>{$(m),K(_||null),ut(At,m,_);const w=Xe(m);ye(parseInt(w.defaultDuration,10)||8)},[]),[ue,Pe]=s.useState(!1),[B,Be]=s.useState(null),[De,de]=s.useState(""),[i,v]=s.useState(""),[p,C]=s.useState((e==null?void 0:e.analysis)||null),be=hs(),W=s.useRef(null),Ne=s.useRef(null),Le=s.useRef(null),Te=s.useRef(!1),Bt=s.useMemo(()=>{if(Le.current&&URL.revokeObjectURL(Le.current),!U)return Le.current=null,null;const m=URL.createObjectURL(U);return Le.current=m,m},[U]);s.useEffect(()=>()=>{Le.current&&URL.revokeObjectURL(Le.current)},[]),s.useEffect(()=>{let m=!1;return(async()=>{var F,se,fe,Me;if(!e){if(B)return;C(null),I("prompt"),j(""),T(""),Y(zt),N({}),Q(null),he(""),D(null),v("");return}if(C(e.analysis||null),ae(e.model||ia),f(e.modelRef||null),v(""),T(((F=e.productInfo)==null?void 0:F.videoStyle)||e.analysis.video_style||""),Y(((se=e.productInfo)==null?void 0:se.targetDuration)||e.analysis.totalDuration||zt),(fe=e.productInfo)!=null&&fe.videoModel){$(e.productInfo.videoModel),K(e.productInfo.videoModelRef||null);const Re=Xe(e.productInfo.videoModel);ye(e.productInfo.segmentDuration||parseInt(Re.defaultDuration,10)||8)}const w=e.sourceSnapshot;if((w==null?void 0:w.type)==="prompt"){I("prompt"),j(w.prompt||e.sourceLabel||""),N(wa((Me=e.productInfo)==null?void 0:Me.creativeBrief)),he(""),D(null),Q(w.pdfCacheUrl?{cacheUrl:w.pdfCacheUrl,name:w.pdfName||"参考资料.pdf",size:w.pdfSize||0,mimeType:w.pdfMimeType||"application/pdf"}:null);return}if((w==null?void 0:w.type)==="upload"){I("upload"),j(""),N({}),Q(null),he("");const Re=await sr(w);if(m)return;D(Re),Re||v("原上传视频缓存已失效,无法自动回填视频");return}if(e.source==="upload"){I("upload"),j(""),N({}),Q(null),he(""),D(null),v("这条旧历史未保存原视频,无法自动回填视频");return}I("youtube"),j(""),N({}),Q(null),D(null),(w==null?void 0:w.type)==="youtube"?he(w.youtubeUrl):e.source==="youtube"?he(e.sourceLabel||""):he("")})(),()=>{m=!0}},[e]);const Qe=dt("text"),Ue=s.useMemo(()=>Qe.filter(mr),[Qe]),et=g!=="prompt"||!!L,Ke=s.useMemo(()=>et?Ue:Qe,[Qe,Ue,et]),Gt=s.useMemo(()=>{const m=be.find(_=>_.id===Qt);return!!(m!=null&&m.apiKey.trim())},[be]),mt=(pe==null?void 0:pe.profileId)===Qt,gt=s.useCallback(()=>{const m={action:"select",profileId:Qt};window.__aituPendingProviderNavigationIntent=m,window.dispatchEvent(new CustomEvent(ur,{detail:m})),k(_=>({..._,openSettings:!0}))},[k]);s.useEffect(()=>{if(Ke.length===0||Aa(Ke,me,pe))return;const _=Ke[0];R(_.id,za(_))},[Ke,me,pe,R]);const yt=s.useCallback(m=>{var w;const _=(w=m.target.files)==null?void 0:w[0];_&&(D(_),v(""),C(null))},[]),Ht=s.useCallback(m=>{m.preventDefault();const _=m.dataTransfer.files[0];_!=null&&_.type.startsWith("video/")&&(D(_),v(""),C(null))},[]),tt=s.useCallback(m=>{m.stopPropagation(),D(null),v(""),W.current&&(W.current.value="")},[]),bt=s.useCallback(()=>{const m=!B;Q(_=>(m&&(_!=null&&_.cacheUrl)&&vt.deleteCache(_.cacheUrl).catch(()=>{}),null)),Ne.current&&(Ne.current.value="")},[B]),_t=s.useCallback(async m=>{var F;const _=(F=m.target.files)==null?void 0:F[0];if(m.target.value="",!_)return;if(!(_.type==="application/pdf"||_.name.toLowerCase().endsWith(".pdf"))){Se.warning("请上传 PDF 文件");return}if(_.size>dr){Se.warning("PDF 不能超过 20MB");return}if(Ue.length===0){Se.warning("PDF 入参需要 Gemini 文本模型,请先配置 Gemini 模型");return}try{const se=`video-prompt-pdf-${Wa()}.pdf`;await vt.cacheToCacheStorageOnly(se,_),Q(fe=>(!B&&(fe!=null&&fe.cacheUrl)&&vt.deleteCache(fe.cacheUrl).catch(()=>{}),{cacheUrl:se,name:_.name,size:_.size,mimeType:_.type||"application/pdf"})),Se.success("PDF 已添加,将作为提示词上下文提交给 Gemini")}catch(se){Se.error(se instanceof Error?se.message:"PDF 上传失败")}},[Ue.length,B]),[Fe,at]=s.useState(!1),[It,je]=s.useState(""),st=s.useCallback(async(m,_)=>{at(!0),je("提取帧图片...");try{const w=_.map(se=>se.startTime),F=await $s(m,w,(se,fe)=>je(`提取帧图片 ${se}/${fe}`));return await Promise.all(_.map(async(se,fe)=>{const Me=F[fe];if(!Me)return se;try{const Re=await Bs(Me,se.id,"first");return{...se,generated_first_frame_url:Re}}catch{return se}}))}catch{return _}finally{at(!1),je("")}},[]),pt=s.useCallback(async()=>{if(!(Te.current||B)){Te.current=!0,Pe(!0),v(""),de("准备中...");try{let m={};if(g==="prompt"){const w=O.trim();if(!w){v("请输入提示词"),Te.current=!1,Pe(!1);return}if(L&&!Aa(Ue,me,pe)){const fe=Ue[0];fe&&R(fe.id,za(fe)),Se.warning("PDF 入参仅支持 Gemini 文本模型"),Te.current=!1,Pe(!1),de("");return}const F=wa(J);m={prompt:vs({userPrompt:w,pdfAttachmentName:L==null?void 0:L.name,creativeBrief:F,videoStyle:S,videoModel:q,segmentDuration:ce,targetDuration:G}),model:me,modelRef:pe,taskLabel:`提示词生成:${w.slice(0,32)}`,videoAnalyzerAction:"prompt-generate",videoAnalyzerSource:"prompt",videoAnalyzerSourceLabel:w.slice(0,80),videoAnalyzerUserPrompt:w,videoAnalyzerSourceSnapshot:{type:"prompt",prompt:w,...L?{pdfCacheUrl:L.cacheUrl,pdfName:L.name,pdfMimeType:L.mimeType,pdfSize:L.size}:{}},videoAnalyzerProductInfo:{prompt:w,videoModel:q,videoModelRef:ee,targetDuration:G,segmentDuration:ce,videoStyle:S,creativeBrief:F},knowledgeContextRefs:ie,...L?{pdfCacheUrl:L.cacheUrl,pdfMimeType:L.mimeType,pdfName:L.name}:{}}}else if(g==="upload"&&U){de("缓存视频文件...");const w=await ar(U);m={videoCacheUrl:w.type==="upload"?w.cacheUrl:void 0,...w.type==="upload"?{mimeType:w.mimeType}:{},model:me,modelRef:pe,taskLabel:`分析视频:${U.name||"本地视频"}`,videoAnalyzerSource:"upload",videoAnalyzerSourceLabel:U.name||"本地视频",videoAnalyzerSourceSnapshot:w}}else if(g==="youtube"&&X)m={youtubeUrl:X,model:me,modelRef:pe,taskLabel:`分析视频:${X}`,videoAnalyzerSource:"youtube",videoAnalyzerSourceLabel:X,videoAnalyzerSourceSnapshot:{type:"youtube",youtubeUrl:X}};else{v("请先输入提示词、选择视频文件或输入 YouTube URL"),Te.current=!1,Pe(!1);return}$e.trackUIInteraction({area:"popular_video_tool",action:"video_analysis_started",control:"analyze_video",source:"video_analyzer_analyze_page",metadata:{inputMode:g,hasPrompt:!!O.trim(),hasPdfAttachment:!!L,hasUpload:!!U,hasYoutubeUrl:!!X,fileSizeBytes:U==null?void 0:U.size,hasModelRef:!!pe}}),de("加入任务队列...");const _=await Os.execute(m,{mode:"queue"});_.success&&_.taskId?(Be(_.taskId||null),de("已加入任务队列,等待分析...")):(Te.current=!1,v(_.error||"创建分析任务失败"))}catch(m){Te.current=!1,v(m.message||"分析失败")}finally{Pe(!1)}}},[g,U,X,O,S,q,ee,G,ce,J,ie,L,B,me,pe,Ue,R]);s.useEffect(()=>{if(!B)return;const m=ze.observeTaskUpdates().subscribe(_=>{var w;if(_.task.id===B){if(_.task.status==="failed"){Te.current=!1,Be(null),de(""),v(((w=_.task.error)==null?void 0:w.message)||"分析失败");return}if(_.task.status==="completed"){Lt(_.task).then(async F=>{if(F&&(l(F.records),r(F.record),C(F.record.analysis),F.record.source==="upload"&&U&&F.record.analysis.shots.length>0)){const se=await st(U,F.record.analysis.shots);C(Me=>Me&&{...Me,shots:se});const fe=await xe(F.record.id,{editedShots:se});l(fe),r({...F.record,editedShots:se})}}).catch(F=>{v(F.message||"分析结果同步失败")}).finally(()=>{Te.current=!1,Be(null),de("")});return}typeof _.task.progress=="number"?de(`分析中 ${Math.round(_.task.progress)}%`):de("分析中,请耐心等待...")}});return()=>m.unsubscribe()},[B,r,l,U,st]);const Kt=s.useCallback(async()=>{var m;p&&(await Ot("text",$t(p.shots,p)),$e.trackUIInteraction({area:"popular_video_tool",action:"analysis_inserted_to_canvas",control:"insert_analysis",source:"video_analyzer_analyze_page",metadata:{shotCount:p.shots.length,productExposureRatio:p.productExposureRatio,characterCount:((m=p.characters)==null?void 0:m.length)||0}}))},[p]);return t.jsxs("div",{className:"va-page",children:[!p&&t.jsxs(t.Fragment,{children:[t.jsxs("div",{className:"va-tabs",children:[t.jsx("button",{className:`va-tab ${g==="prompt"?"active":""}`,onClick:()=>I("prompt"),children:"提示词生成"}),t.jsx("button",{className:`va-tab ${g==="upload"?"active":""}`,onClick:()=>I("upload"),children:"上传视频"}),t.jsx("button",{className:`va-tab ${g==="youtube"?"active":""}`,onClick:()=>I("youtube"),children:"YouTube URL"})]}),g==="prompt"?t.jsxs("div",{className:"va-prompt-start",children:[t.jsxs("div",{className:"va-context-panel",children:[t.jsxs("div",{className:"va-pdf-row",children:[t.jsx("input",{ref:Ne,type:"file",accept:"application/pdf,.pdf",onChange:_t,style:{display:"none"}}),t.jsx("button",{type:"button",className:"va-secondary-btn",onClick:()=>{var m;return(m=Ne.current)==null?void 0:m.click()},disabled:ue||!!B,children:L?"更换 PDF":"上传 PDF"}),L?t.jsxs("div",{className:"va-pdf-chip",children:[t.jsxs("span",{title:L.name,children:[L.name," · ",La(L.size)]}),t.jsx("button",{type:"button","aria-label":"移除 PDF",onClick:bt,disabled:ue||!!B,children:"×"})]}):t.jsx("span",{className:"va-pdf-hint",children:"可选,上传后仅支持 Gemini 模型,PDF 不超过 20MB"})]}),t.jsx(Ls,{value:ie,onChange:le,disabled:ue||!!B,className:"va-knowledge-context-selector"})]}),t.jsx(Ya,{value:J,onChange:N,workflow:"popular_video",videoStyle:S,onVideoStyleChange:T}),t.jsx(qa,{selectedModel:q,selectedSelectionKey:Ee(q,ee),onSelectModel:Je,models:A,segmentDuration:ce,durationOptions:Oe,onSegmentDurationChange:ye,targetDuration:G,onTargetDurationChange:m=>Y(Number.isFinite(m)&&m>0?m:zt),disabled:ue||!!B}),t.jsx("textarea",{className:"va-prompt-textarea",value:O,onChange:m=>{j(m.target.value),v(""),C(null)},placeholder:"输入产品、主题、受众、风格或爆款方向,可附带 PDF 作为上下文",rows:5})]}):g==="upload"?U?t.jsxs("div",{className:"va-video-preview",children:[t.jsx("video",{src:Bt,controls:!0,muted:!0,playsInline:!0}),t.jsx("button",{className:"va-video-preview-close",onClick:tt,children:"✕"}),t.jsxs("div",{className:"va-video-preview-info",children:[t.jsx("span",{className:"va-video-preview-name",children:U.name}),t.jsx("span",{className:"va-video-preview-size",children:La(U.size)})]}),t.jsx("input",{ref:W,type:"file",accept:"video/*",onChange:yt,style:{display:"none"}})]}):t.jsxs("div",{className:"va-dropzone",onDrop:Ht,onDragOver:m=>m.preventDefault(),onClick:()=>{var m;return(m=W.current)==null?void 0:m.click()},children:[t.jsx("input",{ref:W,type:"file",accept:"video/*",onChange:yt,style:{display:"none"}}),t.jsxs("span",{className:"va-placeholder",children:["拖拽视频到此处 或 点击上传",t.jsx("br",{}),t.jsx("span",{className:"va-placeholder-hint",children:"建议视频在6M以内,可用推特或Youtube下载器下载最低分辨率视频"})]})]}):t.jsx("input",{className:"va-url-input",type:"text",placeholder:"https://www.youtube.com/watch?v=...",value:X,onChange:m=>he(m.target.value)}),t.jsxs("div",{className:"va-analyze-control-row",children:[t.jsxs("div",{className:"va-model-select va-model-select--analysis",children:[t.jsx("label",{className:"va-model-label",children:"分析模型"}),t.jsx(Ft,{variant:"form",selectedModel:me,selectedSelectionKey:Ee(me,pe),onSelect:R,models:Ke,placement:"auto",disabled:ue,placeholder:et?"选择 Gemini 模型":"选择文本模型"})]}),t.jsx("button",{className:"va-analyze-btn va-analyze-btn--inline",onClick:pt,disabled:ue||!!B||(g==="prompt"?!O.trim():g==="upload"?!U:!X),children:ue||B?De||"分析中...":g==="prompt"?"生成提示词":"开始分析"})]}),et&&!mt&&t.jsxs("div",{className:"va-model-tip",children:[t.jsx("span",{children:"建议使用 gemini-mix 分组的gemini-3.1-pro-preview"}),!Gt&&t.jsx("button",{type:"button",className:"va-model-tip-link",onClick:gt,children:"去设置"})]}),i&&t.jsx("div",{className:"va-error",children:i})]}),p&&t.jsxs("div",{className:"va-results",children:[t.jsxs("div",{className:"va-stats",children:[t.jsxs("div",{className:"va-stat",children:[t.jsxs("span",{className:"va-stat-value",children:[p.totalDuration,"s"]}),t.jsx("span",{className:"va-stat-label",children:"总时长"})]}),t.jsxs("div",{className:"va-stat",children:[t.jsx("span",{className:"va-stat-value",children:p.shotCount}),t.jsx("span",{className:"va-stat-label",children:"镜头数"})]}),t.jsxs("div",{className:"va-stat",children:[t.jsxs("span",{className:"va-stat-value",children:[p.productExposureRatio,"%"]}),t.jsx("span",{className:"va-stat-label",children:"产品占比"})]}),t.jsxs("div",{className:"va-stat",children:[t.jsx("span",{className:"va-stat-value",children:p.aspect_ratio||"-"}),t.jsx("span",{className:"va-stat-label",children:"画面比例"})]})]}),(p.video_style||p.bgm_mood)&&t.jsxs("div",{className:"va-style-info",children:[p.video_style&&t.jsxs("span",{children:["风格: ",p.video_style]}),p.bgm_mood&&t.jsxs("span",{children:["BGM: ",p.bgm_mood]})]}),t.jsx("div",{className:"va-suggestion",children:p.suggestion}),t.jsx(er,{shots:p.shots,totalDuration:p.totalDuration}),t.jsx("div",{className:"va-shots",children:p.shots.map((m,_)=>t.jsx(va,{shot:m,index:_},m.id))}),t.jsxs("div",{className:"va-page-actions",children:[Fe&&t.jsx("span",{className:"va-frame-progress",children:It}),t.jsx("button",{onClick:Kt,children:"插入画布"}),t.jsx("button",{onClick:()=>{C(null)},children:"重新分析"}),h&&t.jsx("button",{onClick:h,children:"新建分析"}),c&&t.jsx("button",{className:"va-btn-primary",onClick:c,children:"下一步: 编辑脚本 →"})]})]})]})};function He(e){e.style.height="auto",e.style.height=e.scrollHeight+"px"}function We(e,r=30){if(!e)return 1;const l=e.split(`
|
|
2
|
-
`);let h=0;for(const c of l)h+=Math.max(1,Math.ceil(c.length/r));return Math.max(1,h)}function Ye(e){e&&He(e)}function Et(e){const r=Ut(e.productInfo||{prompt:""},e.analysis.totalDuration);return{...r,videoStyle:r.videoStyle??e.analysis.video_style??"",bgmMood:r.bgmMood??e.analysis.bgm_mood??""}}function qe(e,r,l){return e.find(h=>h.id===r)||l}const ua="video-analyzer:script-model",da="video-analyzer:video-model",Ua="gemini-3.1-pro-preview",$a="veo3",fr=["固定镜头 (Static)","缓慢推近 (Dolly In)","缓慢拉远 (Dolly Out)","水平平移 (Pan)","垂直摇移 (Tilt)","跟随拍摄 (Follow)","手持感 (Handheld)","环绕拍摄 (Orbit)","升降镜头 (Crane)","快速推移 (Zoom In)","快速拉远 (Zoom Out)","滑轨移动 (Slider)","航拍俯冲 (Drone Dive)","第一人称 (POV)"],hr=[{label:"无 (none)",value:"none"},{label:"仅旁白 (narration_only)",value:"narration_only"},{label:"仅对白 (dialogue_only)",value:"dialogue_only"},{label:"旁白+对白 (both)",value:"both"}],vr=[{label:"硬切 (cut)",value:"cut"},{label:"溶解 (dissolve)",value:"dissolve"},{label:"匹配切 (match_cut)",value:"match_cut"},{label:"淡出到黑 (fade_to_black)",value:"fade_to_black"}],gr=({record:e,onRecordUpdate:r,onRecordsChange:l,onNext:h})=>{var de;const[c,k]=s.useState(()=>Et(e)),[g,I]=s.useState(e.editedShots||[...e.analysis.shots]),[O,j]=s.useState(!1),[S,T]=s.useState(()=>e.pendingRewriteTaskId||null),[G,Y]=s.useState(""),[J,N]=s.useState(""),[ie,le]=s.useState(!1),L=s.useRef(null),Q=s.useRef(!1),[X,he]=s.useState(()=>we(ua,Ua).modelId),[U,D]=s.useState(()=>we(ua,Ua).modelRef),me=s.useCallback((i,v)=>{he(i),D(v||null),ut(ua,i,v)},[]),ae=dt("text"),pe=dt("video"),[f,R]=s.useState(()=>{var i;return((i=e.productInfo)==null?void 0:i.videoModel)||we(da,$a).modelId}),[A,q]=s.useState(()=>{var i,v;return((i=e.productInfo)==null?void 0:i.videoModelRef)||we(da,((v=e.productInfo)==null?void 0:v.videoModel)||$a).modelRef}),$=s.useCallback((i,v)=>{R(i),q(v||null),ut(da,i,v);const p=Xe(i),C=parseInt(p.defaultDuration,10)||8;k(be=>({...be,videoModel:i,videoModelRef:v||null,segmentDuration:C}))},[]),ee=s.useMemo(()=>Xe(f).durationOptions,[f]),K=s.useMemo(()=>{if(c.segmentDuration&&ee.some(p=>parseInt(p.value,10)===c.segmentDuration))return c.segmentDuration;const i=Xe(f);return parseInt(i.defaultDuration,10)||8},[c.segmentDuration,ee,f]),_e=s.useMemo(()=>{const i=c.targetDuration||e.analysis.totalDuration,v=[{label:`${K}秒`,value:String(K)}];return gs(i,v)},[K,c.targetDuration,e.analysis.totalDuration]),ce=s.useMemo(()=>e.characters||e.analysis.characters||[],[e.characters,e.analysis.characters]);s.useEffect(()=>{k(Et(e)),I(e.editedShots||[...e.analysis.shots]),T(e.pendingRewriteTaskId||null),Y(i=>e.pendingRewriteTaskId?i:"")},[e]);const ye=s.useRef();s.useEffect(()=>(clearTimeout(ye.current),ye.current=setTimeout(async()=>{const i=await xe(e.id,{productInfo:c});l(i),r(qe(i,e.id,{...e,productInfo:c,pendingRewriteTaskId:S}))},500),()=>clearTimeout(ye.current)),[c,S]);const Oe=s.useCallback(async i=>{I(i);const v=Ze(e,i),p=await xe(e.id,{...v,productInfo:c});l(p),r(qe(p,e.id,{...e,...v,productInfo:c,pendingRewriteTaskId:S}))},[e,c,S,r,l]),Je=s.useCallback(async i=>{const v=await xe(e.id,i);l(v),r(qe(v,e.id,{...e,...i,productInfo:c,pendingRewriteTaskId:S}))},[e,c,S,r,l]),ue=s.useCallback((i,v,p)=>{const C=g.map(be=>be.id===i?{...be,[v]:p}:be);Oe(C)},[g,Oe]),Pe=s.useCallback((i,v)=>{const C=(e.characters||e.analysis.characters||[]).map(be=>be.id===i?{...be,description:v}:be);Je({characters:C})},[e.characters,e.analysis.characters,Je]),B=s.useCallback(async()=>{var i;if(!((i=c.prompt)!=null&&i.trim())){N("请填写提示词");return}if(!(Q.current||S)){Q.current=!0,j(!0),N(""),Y("AI 改编中 0%"),$e.trackUIInteraction({area:"popular_video_tool",action:"script_rewrite_started",control:"rewrite_script",source:"video_analyzer_script_page",metadata:{shotCount:g.length,promptLength:c.prompt.trim().length,hasModelRef:!!U}});try{const v=ys({recordAnalysis:e.analysis,productInfo:c,videoModel:f,characters:ce}),p=ze.createTask({prompt:`改编脚本:${c.prompt.slice(0,40)}`,model:X,modelRef:U||null,videoAnalyzerAction:"rewrite",videoAnalyzerPrompt:v,videoAnalyzerRecordId:e.id,autoInsertToCanvas:!1},ge.CHAT);T(p.id),Y(`AI 改编中 ${Math.round(p.progress??0)}%`);const C=await xe(e.id,{pendingRewriteTaskId:p.id});l(C),r(qe(C,e.id,{...e,pendingRewriteTaskId:p.id}))}catch(v){Q.current=!1,N(v.message||"改编失败")}finally{j(!1)}}},[e,c,g,f,ce,X,U,r,l,S]);s.useEffect(()=>{var p;if(!S)return;const i=ze.getTask(S);if((i==null?void 0:i.status)==="failed"){Q.current=!1,T(null),Y(""),N(((p=i.error)==null?void 0:p.message)||"改编失败"),xe(e.id,{pendingRewriteTaskId:null}).then(C=>{l(C),r(qe(C,e.id,{...e,pendingRewriteTaskId:null}))});return}if((i==null?void 0:i.status)==="completed"){Lt(i).then(C=>{if(!C){N("改编任务已完成,但未找到可回填的记录");return}l(C.records),r(C.record),k(Et(C.record)),I(C.record.editedShots||C.record.analysis.shots)}).catch(C=>{N(C.message||"改编结果同步失败")}).finally(()=>{Q.current=!1,T(null),Y("")});return}typeof(i==null?void 0:i.progress)=="number"&&Y(`AI 改编中 ${Math.round(i.progress)}%`);const v=ze.observeTaskUpdates().subscribe(C=>{var be;if(C.task.id===S){if(C.task.status==="failed"){Q.current=!1,T(null),Y(""),N(((be=C.task.error)==null?void 0:be.message)||"改编失败"),xe(e.id,{pendingRewriteTaskId:null}).then(W=>{l(W),r(qe(W,e.id,{...e,pendingRewriteTaskId:null}))});return}if(C.task.status==="completed"){Lt(C.task).then(W=>{if(!W){N("改编任务已完成,但未找到可回填的记录");return}l(W.records),r(W.record),k(Et(W.record)),I(W.record.editedShots||W.record.analysis.shots)}).catch(W=>{N(W.message||"改编结果同步失败")}).finally(()=>{Q.current=!1,T(null),Y("")});return}typeof C.task.progress=="number"&&Y(`AI 改编中 ${Math.round(C.task.progress)}%`)}});return()=>v.unsubscribe()},[S,e.id,r,l]);const Be=s.useCallback(async()=>{await Ot("text",$t(g,e.analysis,c)),$e.trackUIInteraction({area:"popular_video_tool",action:"script_inserted_to_canvas",control:"insert_script",source:"video_analyzer_script_page",metadata:{shotCount:g.length}})},[g,c,e]),De=s.useCallback(async i=>{const v=Za(e,i);if(!v)return;le(!1),I(v.editedShots);const p=await xe(e.id,v);l(p),r(qe(p,e.id,{...e,...v}))},[e,r,l]);return s.useEffect(()=>{if(!ie)return;const i=v=>{L.current&&!L.current.contains(v.target)&&le(!1)};return document.addEventListener("mousedown",i),()=>document.removeEventListener("mousedown",i)},[ie]),t.jsxs("div",{className:"va-page",children:[t.jsxs("div",{className:"va-product-form",children:[t.jsx("textarea",{ref:Ye,className:"va-form-textarea va-auto-resize",placeholder:"描述你想要的视频内容,如:拖鞋,生活用品,主打防滑...",rows:Math.max(3,We(c.prompt)),value:c.prompt,onChange:i=>k(v=>({...v,prompt:i.target.value})),onInput:i=>He(i.currentTarget)}),t.jsx(Ya,{value:c.creativeBrief,onChange:i=>k(v=>({...v,creativeBrief:i})),videoStyle:c.videoStyle||"",onVideoStyleChange:i=>k(v=>({...v,videoStyle:i}))}),t.jsx("div",{className:"va-form-row",children:t.jsxs("div",{style:{flex:1},children:[t.jsx("label",{className:"va-edit-label",children:"BGM 情绪"}),t.jsx("textarea",{ref:Ye,className:"va-edit-textarea va-auto-resize",rows:We(c.bgmMood),value:c.bgmMood||"",onChange:i=>k(v=>({...v,bgmMood:i.target.value})),onInput:i=>He(i.currentTarget),placeholder:"如:轻快、治愈、科技感"})]})}),t.jsxs("div",{className:"va-model-select",children:[t.jsx("label",{className:"va-model-label",children:"改编模型"}),t.jsx(Ft,{variant:"form",selectedModel:X,selectedSelectionKey:Ee(X,U),onSelect:me,models:ae,placement:"down",disabled:O,placeholder:"选择文本模型"})]}),t.jsx(qa,{selectedModel:f,selectedSelectionKey:Ee(f,A),onSelectModel:$,models:pe,segmentDuration:K,durationOptions:ee,onSegmentDurationChange:i=>k(v=>({...v,segmentDuration:i})),targetDuration:c.targetDuration??e.analysis.totalDuration,onTargetDurationChange:i=>k(v=>({...v,targetDuration:i||void 0})),disabled:O,placement:"down",overflowText:_e.overflow>0?`实际 ${_e.actualTotal}s(+${parseFloat(_e.overflow.toFixed(2))}s)`:void 0}),t.jsxs("div",{className:"va-version-row",children:[t.jsx("button",{className:"va-analyze-btn",onClick:B,disabled:O||!!S,style:{flex:1},children:O||S?G||"AI 改编中...":"AI 改编脚本"}),e.scriptVersions&&e.scriptVersions.length>0&&t.jsxs("div",{className:"va-version-select",ref:L,children:[t.jsxs("button",{className:"va-version-btn",onClick:()=>le(i=>!i),children:[e.activeVersionId===ea?"原始分析":((de=e.scriptVersions.find(i=>i.id===e.activeVersionId))==null?void 0:de.label)||`v${e.scriptVersions.length}`," ▾"]}),ie&&t.jsxs("div",{className:"va-version-menu",children:[e.scriptVersions.map(i=>t.jsxs("div",{className:`va-version-item ${i.id===e.activeVersionId?"active":""}`,onClick:()=>De(i.id),children:[t.jsx("span",{children:i.label}),i.prompt&&t.jsx("span",{className:"va-version-prompt",children:i.prompt.length>30?i.prompt.slice(0,30)+"...":i.prompt}),t.jsxs("span",{className:"va-version-time",children:[i.shots.length," 镜头 · ",new Date(i.createdAt).toLocaleTimeString()]})]},i.id)),t.jsxs("div",{className:`va-version-item ${e.activeVersionId===ea||!e.activeVersionId?"active":""}`,onClick:()=>De(ea),children:[t.jsx("span",{children:"原始分析"}),t.jsxs("span",{className:"va-version-time",children:[e.analysis.shots.length," 镜头 · ",new Date(e.createdAt).toLocaleTimeString()]})]})]})]})]}),J&&t.jsx("div",{className:"va-error",children:J})]}),t.jsx(bs,{characters:ce,onChange:Pe}),t.jsx("div",{className:"va-shots",children:g.map((i,v)=>t.jsx(va,{shot:i,index:v,compact:!0,children:t.jsxs("div",{className:"va-edit-fields",children:[t.jsx("label",{className:"va-edit-label",children:"画面描述"}),t.jsx("textarea",{ref:Ye,className:"va-edit-textarea va-auto-resize",rows:We(i.description),value:i.description||"",onChange:p=>ue(i.id,"description",p.target.value),onInput:p=>He(p.currentTarget)}),t.jsx("label",{className:"va-edit-label",children:"旁白"}),t.jsx("textarea",{ref:Ye,className:"va-edit-textarea va-auto-resize",rows:We(i.narration),value:i.narration||"",onChange:p=>ue(i.id,"narration",p.target.value),onInput:p=>He(p.currentTarget)}),t.jsx("label",{className:"va-edit-label",children:"角色说话"}),t.jsx("textarea",{ref:Ye,className:"va-edit-textarea va-auto-resize",rows:We(i.dialogue),value:i.dialogue||"",onChange:p=>ue(i.id,"dialogue",p.target.value),onInput:p=>He(p.currentTarget),placeholder:'多角色时按"角色名: 台词"分行'}),t.jsx("label",{className:"va-edit-label",children:"对白角色"}),t.jsx("input",{className:"va-form-input",type:"text",value:i.dialogue_speakers||"",onChange:p=>ue(i.id,"dialogue_speakers",p.target.value),placeholder:"如:主讲人 或 主讲人|顾客"}),t.jsx("label",{className:"va-edit-label",children:"旁白/对白关系"}),t.jsx(ta,{value:i.speech_relation||"",onChange:p=>ue(i.id,"speech_relation",p),options:hr,placeholder:"选择关系"}),t.jsx("label",{className:"va-edit-label",children:"运镜方式"}),t.jsx(ta,{value:i.camera_movement||"",onChange:p=>ue(i.id,"camera_movement",p),options:fr,placeholder:"选择或输入运镜方式"}),t.jsx("label",{className:"va-edit-label",children:"首帧 Prompt"}),t.jsx("textarea",{ref:Ye,className:"va-edit-textarea va-auto-resize",rows:We(i.first_frame_prompt),value:i.first_frame_prompt||"",onChange:p=>ue(i.id,"first_frame_prompt",p.target.value),onInput:p=>He(p.currentTarget)}),t.jsx("label",{className:"va-edit-label",children:"尾帧 Prompt"}),t.jsx("textarea",{ref:Ye,className:"va-edit-textarea va-auto-resize",rows:We(i.last_frame_prompt),value:i.last_frame_prompt||"",onChange:p=>ue(i.id,"last_frame_prompt",p.target.value),onInput:p=>He(p.currentTarget)}),t.jsx("label",{className:"va-edit-label",children:"转场方式"}),t.jsx(ta,{value:i.transition_hint||"",onChange:p=>ue(i.id,"transition_hint",p),options:vr,placeholder:"选择转场方式"})]})},i.id))}),t.jsxs("div",{className:"va-page-actions",children:[t.jsx("button",{onClick:Be,children:"脚本插入画布"}),h&&t.jsx("button",{className:"va-btn-primary",onClick:h,children:"下一步:批量生成 →"})]})]})};function yr(e,r,l){var h,c,k,g,I;return{recordId:e.id,fileNamePrefix:"va",zipBaseName:"video_analyzer_assets",scriptMarkdown:$t(r,e.analysis,e.productInfo),recordMeta:{id:e.id,source:e.source,sourceLabel:e.sourceLabel,prompt:((h=e.productInfo)==null?void 0:h.prompt)||"",aspectRatio:e.analysis.aspect_ratio||"16x9",videoStyle:((c=e.productInfo)==null?void 0:c.videoStyle)||e.analysis.video_style||"",bgmMood:((k=e.productInfo)==null?void 0:k.bgmMood)||e.analysis.bgm_mood||"",creativeBrief:((g=e.productInfo)==null?void 0:g.creativeBrief)||{},creativeBriefSummary:_s((I=e.productInfo)==null?void 0:I.creativeBrief),shotCount:r.length},shots:r,assets:l}}function br(e,r){const l=e.characters||e.analysis.characters||[];return Gs(r,l)}const Dt="video-analyzer:image-model",Rt="video-analyzer:video-model";function Ba(e,r){const l=Object.keys(e),h=Object.keys(r);return l.length!==h.length?!1:l.every(c=>e[c]===r[c])}function Ga(e,r){return r.reduce((l,h)=>{var g;const c=e[h.id];return(h.valueType==="enum"?(g=h.options)==null?void 0:g.some(I=>I.value===c):typeof c=="string"&&c.trim()!=="")&&c?(l[h.id]=c,l):(h.defaultValue&&(l[h.id]=h.defaultValue),l)},{})}function Ha(e,r,l){return{...e,...r!=null?{duration:String(r)}:{},...l?{size:l}:{}}}function Ka(e,r,l){const{duration:h,size:c,...k}=e;return{extraParams:k,duration:h||r,size:c||l}}function _r(e){if(!e||e==="auto")return;const r=e.trim().replace(/[xX]/g,":");return/^\d+:\d+$/.test(r)?r:void 0}const ma=({size:e=14})=>t.jsxs("svg",{viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round",width:e,height:e,"aria-hidden":"true",children:[t.jsx("rect",{x:"3",y:"3",width:"8",height:"8",rx:"1.5"}),t.jsx("circle",{cx:"17",cy:"7",r:"4"}),t.jsx("rect",{x:"3",y:"13",width:"8",height:"8",rx:"1.5"}),t.jsx("rect",{x:"13",y:"13",width:"8",height:"8",rx:"1.5"})]}),Ir=({record:e,onRecordUpdate:r,onRecordsChange:l,onRestart:h})=>{const c=s.useMemo(()=>e.editedShots||e.analysis.shots,[e.editedShots,e.analysis.shots]),k=e.analysis.aspect_ratio||"16x9",g=e.batchId||`va_${e.id}`,{openDialog:I,board:O}=ha(),j=s.useRef(e),S=s.useRef(c),T=s.useRef(!1),G=s.useRef(!1),Y=s.useRef(null),J=s.useRef(null),N=s.useRef(new Set),ie=s.useRef(new Set),[le,L]=s.useState([]),[Q,X]=s.useState(null),he=dt("image"),U=dt("video"),[D,me]=s.useState(()=>we(Dt,"").modelId),[ae,pe]=s.useState(()=>we(Dt,"").modelRef),[f,R]=s.useState(()=>{const a=we(Dt,"");return a.modelId?Da(a.modelId,Ee(a.modelId,a.modelRef)).extraParams:{}}),[A,q]=s.useState(()=>{var a;return((a=e.productInfo)==null?void 0:a.videoModel)||we(Rt,"veo3").modelId}),[$,ee]=s.useState(()=>{var a,n;return((a=e.productInfo)==null?void 0:a.videoModelRef)||we(Rt,((n=e.productInfo)==null?void 0:n.videoModel)||"veo3").modelRef}),[K,_e]=s.useState(()=>{var y,d,M,x,E;const a=we(Rt,((y=e.productInfo)==null?void 0:y.videoModel)||"veo3"),n=((d=e.productInfo)==null?void 0:d.videoModel)||a.modelId,o=((M=e.productInfo)==null?void 0:M.videoModelRef)||a.modelRef,u=Ra(n,Ee(n,o));return Ha(u.extraParams,((x=e.productInfo)==null?void 0:x.segmentDuration)||u.duration,Ma(n,((E=e.productInfo)==null?void 0:E.videoSize)||u.size,k))}),[ce,ye]=s.useState({running:!1,stopping:!1,currentIndex:-1,retryCount:0,completedCount:0,activeCount:0}),[Oe,Je]=s.useState(!1),ue=s.useMemo(()=>Is(D),[D]),Pe=s.useMemo(()=>xs(A,$||A,K),[A,$,K]),B=s.useMemo(()=>Ss(A,$||A,K),[A,$,K]),Be=s.useMemo(()=>B.sizeOptions,[B]),De=s.useMemo(()=>Ka(K,B.defaultDuration,B.defaultSize),[B.defaultDuration,B.defaultSize,K]),de=De.size,i=Number.parseFloat(De.duration)||8,v=s.useMemo(()=>Object.keys(f).length>0?f:void 0,[f]),p=s.useMemo(()=>e.characters||e.analysis.characters||[],[e.characters,e.analysis.characters]),C=s.useMemo(()=>{const a=e.sourceSnapshot,o=((a==null?void 0:a.type)==="prompt"?a.prompt:"")||(e.source==="prompt"?e.sourceLabel:""),u=[e.source!=="prompt"&&e.sourceLabel?`素材来源:${e.sourceLabel}`:"",(a==null?void 0:a.type)==="prompt"&&a.pdfName?`参考 PDF:${a.pdfName}`:""].filter(Boolean).join(`
|
|
3
|
-
`);return{...e.productInfo||{},generationTopic:o,generationContext:u,generationAdvice:e.analysis.suggestion||""}},[e.analysis.suggestion,e.productInfo,e.source,e.sourceLabel,e.sourceSnapshot]),be=s.useMemo(()=>Hs(c),[c]);s.useEffect(()=>{j.current=e},[e]),s.useEffect(()=>{S.current=c},[c]);const W=s.useCallback(async a=>{const n=j.current,o={...n,...a};j.current=o,o.editedShots&&(S.current=o.editedShots);const u=await xe(n.id,a);return l(u),r(o),o},[r,l]),Ne=s.useCallback(async a=>{const n=j.current,o=Ze(n,a);return S.current=a,await W(o),a},[W]),Le=s.useCallback(async a=>{const n=j.current,o={...Ut(n.productInfo||{prompt:""},n.analysis.totalDuration),...a};return await W({productInfo:o}),o},[W]),Te=s.useCallback(async(a,n)=>{const o=j.current,y=(o.characters||o.analysis.characters||[]).map(d=>d.id===a?{...d,referenceImageUrl:n}:d);await W({characters:y})},[W]),Bt=s.useCallback(a=>{const n=`va_${e.id}_char${a.id}_ref`,o=ka(a,e.analysis,C);I(Tt.aiImageGeneration,{initialPrompt:o,batchId:n,initialAspectRatio:"1:1",initialModel:D||void 0,initialModelRef:ae,assetMetadata:{category:aa.CHARACTER,characterName:a.name,characterPrompt:o}})},[C,e.analysis,e.id,I,D,ae]),Qe=s.useCallback((a,n)=>{const o=n||null;me(a),pe(o),R(Da(a,Ee(a,o)).extraParams),ut(Dt,a,n)},[]),Ue=s.useCallback((a,n)=>{const o=n||null;q(a),ee(o),ut(Rt,a,n);const u=Ra(a,Ee(a,o));_e(Ha(u.extraParams,u.duration,Ma(a,u.size,k)))},[k]),et=s.useCallback((a,n)=>{R(o=>{const u={...o};return!n||n==="default"?delete u[a]:u[a]=n,u})},[]),Ke=s.useCallback((a,n)=>{_e(o=>{const u={...o};return!n||n==="default"?delete u[a]:u[a]=n,u})},[]);s.useEffect(()=>{const a=Ga(f,ue);Ba(f,a)||R(a)},[ue,f]),s.useEffect(()=>{const a=Ga(K,Pe);Ba(K,a)||_e(a)},[Pe,K]),s.useEffect(()=>{const a=Ka(K,B.defaultDuration,B.defaultSize);Zs({currentModel:A,currentSelectionKey:Ee(A,$),extraParams:a.extraParams,duration:a.duration,size:a.size}),Le({videoModel:A,videoModelRef:$||null,segmentDuration:Number.parseFloat(a.duration)||8,videoSize:a.size})},[Le,A,B.defaultDuration,B.defaultSize,$,K]);const Gt=s.useCallback(async()=>{try{const a=j.current,n=S.current;if(!O)throw new Error("画布未就绪");Ea(O);const o=await Ot("text",$t(n,a.analysis,a.productInfo));if(!o.success)throw new Error(o.error||"插入失败,请确认画布已打开");$e.trackUIInteraction({area:"popular_video_tool",action:"script_inserted_to_canvas",control:"insert_script",source:"video_analyzer_generate_page",metadata:{shotCount:n.length}}),Se.success("脚本已插入画布")}catch(a){console.error("[VideoAnalyzer] Failed to insert script to canvas:",a);const n=a instanceof Error?a.message:"脚本插入画布失败";Se.error(n)}},[O]),mt=s.useCallback(async a=>{if(!O)return!1;try{Ea(O);const n=await Ot("video",a);if(!n.success)throw new Error(n.error||"插入失败,请确认画布已打开");return!0}catch(n){return console.error("[VideoAnalyzer] Failed to insert generated video to canvas:",n),!1}},[O]),{isExportingAssets:gt,exportProgress:yt,handleExportAssets:Ht}=Cs({onExport:async a=>{const n=j.current,o=S.current;return await qs({...yr(n,o,be),onProgress:a})},onExportSuccess:a=>{Se.success(`素材导出完成,共 ${a.assetCount} 个文件`)},onExportError:a=>{console.error("[VideoAnalyzer] Failed to export assets:",a),Se.error("素材导出失败")}}),tt=s.useMemo(()=>le.map(a=>a.url).filter(Boolean),[le]),bt=s.useCallback(async()=>{e.batchId||await W({batchId:g})},[e.batchId,g,W]),{tasks:_t}=Xa(),Fe=s.useRef(new Set),at=s.useRef(new Set),It=s.useCallback(async(a,n,o)=>{let u=[...n],y=!1;for(const{shotId:d,videoUrl:M}of o){const x=`auto_${d}`;if(!at.current.has(x)){at.current.add(x);try{const E=u.findIndex(b=>b.id===d);if(E===-1)continue;const z=u[E+1];if(!z)continue;const Z=await Ks(M,z.id,"first","last");if(!Z||z.generated_first_frame_url===Z)continue;u=u.map((b,P)=>P===E+1?{...b,generated_first_frame_url:Z}:b),y=!0}finally{at.current.delete(x)}}}if(y){const d=e;xe(a,Ze(d,u)).then(M=>{l(M),r({...d,editedShots:u})})}},[e,r,l]);s.useEffect(()=>{var x,E,z,Z;const a=`va_${e.id}_shot`,n=`va_${e.id}_char`;let o=!1;const u=e,y=j.current.generatedAssetsResetAt||u.generatedAssetsResetAt;let d=u.editedShots||u.analysis.shots;const M=[];for(const b of _t){if(b.status!==Ve.COMPLETED||Fe.current.has(b.id))continue;const P=(x=b.params)==null?void 0:x.batchId;if(!P)continue;if(P.startsWith(n)){if(y&&b.createdAt<=y){Fe.current.add(b.id);continue}const re=(E=b.result)==null?void 0:E.url;if(Fe.current.add(b.id),re){const ke=P.slice(n.length),it=ke.lastIndexOf("_ref");if(it!==-1){const Pt=ke.slice(0,it),os=(j.current.characters||j.current.analysis.characters||[]).map(Jt=>Jt.id===Pt?{...Jt,referenceImageUrl:re}:Jt);W({characters:os})}}continue}if(!P.startsWith(a))continue;if(y&&b.createdAt<=y){Fe.current.add(b.id);continue}if(e.storyboardGeneratedAt&&b.createdAt<e.storyboardGeneratedAt){Fe.current.add(b.id);continue}const H=(z=b.result)==null?void 0:z.url;if(!H)continue;const te=P.slice(a.length),ne=te.lastIndexOf("_");if(ne===-1)continue;const oe=te.slice(0,ne),V=te.slice(ne+1);if(V!=="first"&&V!=="last"&&V!=="video")continue;const Ae=V==="first"?"generated_first_frame_url":V==="last"?"generated_last_frame_url":"generated_video_url",Ce=d.find(re=>re.id===oe),Ie=V==="video"&&ie.current.has(b.id),ve=(Z=Ce==null?void 0:Ce.suppressed_generated_urls)==null?void 0:Z[V];if(ve&&ve===H){Ie&&ie.current.delete(b.id),Fe.current.add(b.id);continue}if(!Ce||Ce[Ae]===H){Ie&&ie.current.delete(b.id),Fe.current.add(b.id);continue}d=d.map(re=>re.id===oe?{...re,[Ae]:H,suppressed_generated_urls:re.suppressed_generated_urls?{...re.suppressed_generated_urls,[V]:void 0}:void 0}:re),Fe.current.add(b.id),o=!0,V==="video"&&(Ie?ie.current.delete(b.id):M.push({shotId:oe,videoUrl:H}))}o&&xe(u.id,Ze(u,d)).then(b=>{l(b),r({...u,editedShots:d})}),M.length>0&&!G.current&&It(u.id,d,M)},[_t,It,e,r,l,W]);const[je,st]=s.useState(null),pt=s.useCallback((a,n)=>{st({shotId:a,assetType:n})},[]),Kt=s.useCallback(async a=>{if(!je)return;st(null);const{shotId:n,assetType:o}=je,u=o==="first"?"generated_first_frame_url":o==="last"?"generated_last_frame_url":"generated_video_url",d=(e.editedShots||e.analysis.shots).map(x=>x.id===n?{...x,[u]:a.url}:x),M=await xe(e.id,Ze(e,d));l(M),r({...e,editedShots:d})},[je,e,l,r]),[m,_]=s.useState(null),w=s.useRef(null),F=s.useCallback(()=>{w.current!==null&&(window.clearTimeout(w.current),w.current=null)},[]),se=s.useCallback(()=>{F(),_(null)},[F]),fe=s.useCallback(()=>{F(),w.current=window.setTimeout(()=>{w.current=null,_(null)},120)},[F]),Me=s.useCallback((a,n,o)=>{F();const u=o.currentTarget.getBoundingClientRect();_({url:a,type:n,x:u.left+u.width/2,y:u.top-8})},[F]),Re=s.useCallback(()=>{fe()},[fe]),ts=s.useCallback(()=>{F()},[F]),as=s.useCallback(()=>{se()},[se]);s.useEffect(()=>()=>{F()},[F]);const ft=s.useMemo(()=>{var n;const a=(n=Be.find(o=>o.value===de))==null?void 0:n.aspectRatio;if(a)return a;if(de!=null&&de.includes("x")){const[o,u]=de.split("x").map(Number);if(o&&u){const y=(M,x)=>x===0?M:y(x,M%x),d=y(o,u);return`${o/d}:${u/d}`}}return k.replace("x",":")},[k,Be,de]),Wt=ft,rt=_r(f.size),xt=f.size||Wt;s.useEffect(()=>{D&&Xs({currentModel:D,currentSelectionKey:Ee(D,ae),extraParams:f,aspectRatio:rt||Wt})},[Wt,D,ae,f,rt]);const Ge=s.useCallback(a=>a.map(n=>({url:n.url,name:n.name})),[]),St=s.useCallback((a=[],n=[])=>a.length===n.length&&a.every((o,u)=>{var y,d;return o.url===((y=n[u])==null?void 0:y.url)&&o.name===((d=n[u])==null?void 0:d.name)}),[]),Ct=s.useCallback((...a)=>{const n=new Set,o=[];return a.forEach(u=>{u==null||u.forEach(y=>{var M;const d=(M=y.url)==null?void 0:M.trim();!d||n.has(d)||(n.add(d),o.push({url:d,name:y.name||"参考图"}))})}),o.length>0?o:void 0},[]),wt=s.useCallback(a=>{var o;if(!((o=a.character_ids)!=null&&o.length))return[];const n=new Set;return a.character_ids.reduce((u,y)=>{var x;const d=p.find(E=>E.id===y),M=(x=d==null?void 0:d.referenceImageUrl)==null?void 0:x.trim();return!M||n.has(M)||(n.add(M),u.push({url:M,name:d!=null&&d.name?`角色:${d.name}`:"角色参考图"})),u},[])},[p]),nt=s.useCallback(async(a,n,o)=>{let u=!1;const y=Ge(o.images),d=S.current.map(M=>{if(M.id!==a)return M;if(n==="first"){const z=M.first_frame_draft,Z={prompt:o.prompt,images:y,aspectRatio:o.aspectRatio};return(z==null?void 0:z.prompt)===Z.prompt&&(z==null?void 0:z.aspectRatio)===Z.aspectRatio&&St(z==null?void 0:z.images,Z.images)?M:(u=!0,{...M,first_frame_draft:Z})}if(n==="last"){const z=M.last_frame_draft,Z={prompt:o.prompt,images:y,aspectRatio:o.aspectRatio};return(z==null?void 0:z.prompt)===Z.prompt&&(z==null?void 0:z.aspectRatio)===Z.aspectRatio&&St(z==null?void 0:z.images,Z.images)?M:(u=!0,{...M,last_frame_draft:Z})}const x=M.video_draft,E={prompt:o.prompt,images:y,duration:o.duration,size:o.size};return(x==null?void 0:x.prompt)===E.prompt&&(x==null?void 0:x.duration)===E.duration&&(x==null?void 0:x.size)===E.size&&St(x==null?void 0:x.images,E.images)?M:(u=!0,{...M,video_draft:E})});u&&await Ne(d)},[Ne,St,Ge]),Yt=s.useCallback(a=>{const n=a.first_frame_prompt||a.description||"";if(!n)return;$e.trackUIInteraction({area:"popular_video_tool",action:"shot_first_frame_generation_opened",control:"generate_first_frame",source:"video_analyzer_generate_page",metadata:{shotId:a.id,hasDraft:!!a.first_frame_draft}});const o=sa(n,e.analysis,C,{shot:a,characters:p}),u=a.first_frame_draft,y=u?Ge(u.images||[]):void 0,d=!u&&a.generated_first_frame_url?[{url:a.generated_first_frame_url,name:"首帧"}]:void 0,M=wt(a),x=`va_${e.id}_shot${a.id}_first`;I(Tt.aiImageGeneration,{initialPrompt:(u==null?void 0:u.prompt)||o,batchId:x,initialAspectRatio:(u==null?void 0:u.aspectRatio)??rt,initialModel:D||void 0,initialModelRef:ae,initialImages:Ct(y,d,M),onDraftChange:E=>nt(a.id,"first",E)})},[e,C,p,I,D,ae,Ct,wt,nt,rt,Ge]),ht=s.useCallback((a,n)=>{if(a.generated_last_frame_url)return a.generated_last_frame_url;const o=c[n+1];return o==null?void 0:o.generated_first_frame_url},[c]),jt=s.useCallback((a,n)=>{const o=a.last_frame_prompt||"";if(!o)return;$e.trackUIInteraction({area:"popular_video_tool",action:"shot_last_frame_generation_opened",control:"generate_last_frame",source:"video_analyzer_generate_page",metadata:{shotId:a.id,shotIndex:n,hasDraft:!!a.last_frame_draft}});const u=sa(o,e.analysis,C,{shot:a,characters:p}),y=a.last_frame_draft,d=y?Ge(y.images||[]):void 0,M=`va_${e.id}_shot${a.id}_last`,x=ht(a,n),E=!y&&x?[{url:x,name:"尾帧"}]:void 0,z=wt(a);I(Tt.aiImageGeneration,{initialPrompt:(y==null?void 0:y.prompt)||u,batchId:M,initialAspectRatio:(y==null?void 0:y.aspectRatio)??rt,initialModel:D||void 0,initialModelRef:ae,initialImages:Ct(d,E,z),onDraftChange:Z=>nt(a.id,"last",Z)})},[e,C,p,I,ht,D,ae,Ct,wt,nt,rt,Ge]),qt=s.useCallback((a,n)=>{$e.trackUIInteraction({area:"popular_video_tool",action:"shot_video_generation_opened",control:"generate_shot_video",source:"video_analyzer_generate_page",metadata:{shotId:a.id,shotIndex:n,hasDraft:!!a.video_draft}});const o=a.video_draft,u=`va_${e.id}_shot${a.id}_video`,y=[];a.generated_first_frame_url&&y.push({url:a.generated_first_frame_url,name:"首帧"});const d=ht(a,n);d&&y.push({url:d,name:"尾帧"});const M=Ge((o==null?void 0:o.images)||[]),x=M.length>0?M:y.length>0?y:void 0,E=Na(a,e.analysis,C,{referenceImageDescriptions:ws(x)});if(!E)return;const z=String((o==null?void 0:o.duration)??i),Z=B.durationOptions.some(P=>P.value===z)?(o==null?void 0:o.duration)??i:void 0,b=B.sizeOptions.some(P=>P.value===((o==null?void 0:o.size)??de))?(o==null?void 0:o.size)??de:void 0;I(Tt.aiVideoGeneration,{initialPrompt:(o==null?void 0:o.prompt)||E,initialImages:x,initialDuration:Z,initialSize:b,initialModel:A||void 0,initialModelRef:$,batchId:u,onDraftChange:P=>nt(a.id,"video",P)})},[e.id,i,de,A,B,$,I,ht,e.analysis,C,nt,Ge]),Zt=s.useCallback((a,n)=>{const o=n==="first"?"generated_first_frame_url":n==="last"?"generated_last_frame_url":"generated_video_url",y=(e.editedShots||e.analysis.shots).map(d=>d.id===a?{...d,[o]:void 0,suppressed_generated_urls:d[o]?{...d.suppressed_generated_urls||{},[n]:d[o]}:d.suppressed_generated_urls}:d);xe(e.id,Ze(e,y)).then(d=>{l(d),r({...e,editedShots:y})})},[e,r,l]),Mt=s.useCallback(async(a,n,o)=>{var b,P,H;const u=o==="first"?a.first_frame_prompt||a.description||"":a.last_frame_prompt||"";if(!u)return null;const y=sa(u,e.analysis,C,{shot:a,characters:n}),d=[...tt];if(a.character_ids&&a.character_ids.length>0)for(const te of a.character_ids){const ne=n.find(oe=>oe.id===te);ne!=null&&ne.referenceImageUrl&&!d.includes(ne.referenceImageUrl)&&d.push(ne.referenceImageUrl)}const M=`va_${e.id}_shot${a.id}_${o}`,x=await na.executeTool({name:"generate_image",arguments:{prompt:y.trim(),count:1,size:xt,referenceImages:d.length>0?d:void 0,batchId:M,...D?{model:D,modelRef:ae}:{},...v?{params:v}:{}}},{mode:"queue"}),E=x.taskId||((b=x.data)==null?void 0:b.taskId);if(!x.success||!E)return null;N.current.add(E),J.current=E,ye(te=>({...te,activeCount:N.current.size}));let z;try{z=await oa(E,(P=Y.current)==null?void 0:P.signal)}finally{N.current.delete(E),J.current===E&&(J.current=null),ye(te=>({...te,activeCount:N.current.size}))}if(!z.success)return null;const Z=z.task||ze.getTask(E);return((H=Z==null?void 0:Z.result)==null?void 0:H.url)||null},[e,C,v,xt,D,ae,tt]),ga=s.useCallback((a,n)=>Mt(a,n,"first"),[Mt]),ya=s.useCallback((a,n)=>Mt(a,n,"last"),[Mt]),ba=s.useCallback(async(a,n)=>{const o=S.current,u=o.find(d=>d.id===a);if(!u||u.generated_first_frame_url===n)return o;const y=o.map(d=>d.id===a?{...d,generated_first_frame_url:n}:d);return await Ne(y),y},[Ne]),_a=s.useCallback(async(a,n)=>{const o=S.current,u=o.find(d=>d.id===a);if(!u||u.generated_last_frame_url===n)return o;const y=o.map(d=>d.id===a?{...d,generated_last_frame_url:n}:d);return await Ne(y),y},[Ne]),ot=s.useCallback(a=>S.current.find(n=>n.id===a),[]),Ia=s.useCallback(async(a,n)=>{const o=S.current.find(y=>y.id===a);if(!o||o.generated_video_url===n)return S.current;const u=S.current.map(y=>y.id===a?{...y,generated_video_url:n}:y);return await Ne(u),u},[Ne]),xa=s.useCallback(async(a,n)=>{var b;const o=a.generated_first_frame_url,u=n||a.generated_last_frame_url,{referenceImages:y,referenceImageDescriptions:d}=Ws({model:A,firstFrameUrl:o,lastFrameUrl:u,extraReferenceUrls:tt}),M=Na(a,e.analysis,C,{referenceImageDescriptions:d});if(!M)return null;const x=`va_${e.id}_shot${a.id}_video`,E={...De.extraParams,...B.provider==="seedance"?{aspect_ratio:ft}:{}},z=await na.executeTool({name:"generate_video",arguments:{prompt:M,size:De.size,seconds:De.duration,count:1,batchId:x,model:A,modelRef:$,referenceImages:y,params:Object.keys(E).length>0?E:void 0}},{mode:"queue"}),Z=z.taskId||((b=z.data)==null?void 0:b.taskId);if(!z.success||!Z)throw new Error(z.error||"创建视频任务失败");return Z},[e.analysis,e.id,C,tt,De,A,B.provider,$,ft]),ss=s.useCallback(()=>{var a;T.current=!0,ye(n=>n.running?{...n,stopping:!0}:n),J.current&&ze.cancelTask(J.current);for(const n of N.current)ze.cancelTask(n);(a=Y.current)==null||a.abort()},[]),kt=s.useCallback(()=>{ye(a=>({...a,activeCount:N.current.size}))},[]),Xt=s.useCallback((a,n)=>{ye(o=>({...o,currentIndex:a,retryCount:n,activeCount:N.current.size}))},[]);s.useEffect(()=>()=>{var a;T.current=!0,(a=Y.current)==null||a.abort()},[]);const rs=s.useCallback(async()=>{var n,o;if(G.current||ce.running)return;G.current=!0,$e.trackUIInteraction({area:"popular_video_tool",action:"batch_video_generation_started",control:"generate_all_videos",source:"video_analyzer_generate_page",metadata:{shotCount:S.current.length,insertToCanvasRequested:Oe,hasBoard:!!O}});let a=Oe;a&&!O&&(Se.warning("画布未就绪,本次将只生成不插入画布"),a=!1),await bt(),T.current=!1,Y.current=new AbortController,J.current=null,ye({running:!0,stopping:!1,currentIndex:-1,retryCount:0,completedCount:0,activeCount:0});try{const y=(j.current.characters||j.current.analysis.characters||[]).filter(b=>!b.referenceImageUrl);if(y.length>0&&!T.current){const P=(await Promise.all(y.map(async H=>{var oe,V,Ae;if(T.current)return null;const te=`va_${e.id}_char${H.id}_ref`,ne=ka(H,j.current.analysis,C);try{const Ce=await na.executeTool({name:"generate_image",arguments:{prompt:ne,count:1,size:xt,batchId:te,assetMetadata:{category:aa.CHARACTER,characterName:H.name,characterPrompt:ne},...D?{model:D,modelRef:ae}:{},...v?{params:v}:{}}},{mode:"queue"}),Ie=Ce.taskId||((oe=Ce.data)==null?void 0:oe.taskId);if(!Ie)return null;J.current=Ie,N.current.add(Ie),kt();let ve;try{if(T.current)return ze.cancelTask(Ie),null;ve=await oa(Ie,(V=Y.current)==null?void 0:V.signal)}finally{N.current.delete(Ie),J.current===Ie&&(J.current=null),kt()}if(!ve.success)return null;const re=ve.task||ze.getTask(Ie),ke=(Ae=re==null?void 0:re.result)==null?void 0:Ae.url;return ke?{charId:H.id,url:ke}:null}catch(Ce){return T.current||console.error("[VideoAnalyzer] Character reference generation failed:",{characterId:H.id,error:Ce}),null}}))).filter(H=>!!(H!=null&&H.url));if(P.length>0){const H=new Map(P.map(oe=>[oe.charId,oe.url])),ne=(j.current.characters||j.current.analysis.characters||[]).map(oe=>{const V=H.get(oe.id);return V?{...oe,referenceImageUrl:V}:oe});await W({characters:ne})}}const d=S.current,M=()=>{ye(b=>({...b,completedCount:Math.min(b.completedCount+1,d.length),activeCount:N.current.size}))},x=new Map,E=b=>{var ne;const P=ot(b.id)||b;if(P.generated_first_frame_url)return Promise.resolve(P.generated_first_frame_url);const H=(ne=x.get(b.id))==null?void 0:ne.first;if(H)return H;const te=(async()=>{const oe=j.current.characters||j.current.analysis.characters||[],V=await ga(P,oe);return V&&!T.current&&await ba(P.id,V),V})();return x.set(b.id,{...x.get(b.id)||{},first:te}),te},z=b=>{var ne,oe;const P=ot(b.id)||b;if(P.generated_last_frame_url)return Promise.resolve(P.generated_last_frame_url);if(!((ne=P.last_frame_prompt)!=null&&ne.trim()))return Promise.resolve(null);const H=(oe=x.get(b.id))==null?void 0:oe.last;if(H)return H;const te=(async()=>{const V=j.current.characters||j.current.analysis.characters||[],Ae=await ya(P,V);return Ae&&!T.current&&await _a(P.id,Ae),Ae})();return x.set(b.id,{...x.get(b.id)||{},last:te}),te};for(let b=0;b<d.length;b+=1){const P=d[b],H=d[b+1];E(P).catch(te=>(T.current||console.error("[VideoAnalyzer] Batch first frame generation failed:",{shotId:P.id,error:te}),null)),H&&!P.generated_last_frame_url&&!((n=P.last_frame_prompt)!=null&&n.trim())?E(H).catch(te=>(T.current||console.error("[VideoAnalyzer] Batch next first frame generation failed:",{shotId:H.id,error:te}),null)):(o=P.last_frame_prompt)!=null&&o.trim()&&z(P).catch(te=>(T.current||console.error("[VideoAnalyzer] Batch last frame generation failed:",{shotId:P.id,error:te}),null))}const Z=async(b,P)=>{var H,te,ne,oe;try{if(T.current)return;ye(re=>({...re,currentIndex:P}));let V=ot(b.id)||b;if(V.generated_video_url){a&&await mt(V.generated_video_url);return}const Ae=await E(V);if(Ae&&(V={...V,generated_first_frame_url:Ae}),T.current||(V=ot(b.id)||V,!V.generated_first_frame_url))return;let Ce=V.generated_last_frame_url;if(!Ce)if((H=V.last_frame_prompt)!=null&&H.trim())Ce=await z(V)||void 0;else{const re=d[P+1];Ce=re&&await E(re)||void 0}if(T.current)return;let Ie=0,ve=null;for(;!T.current&&(ve||(ve=await xa(ot(V.id)||V,Ce)),!!ve);){ie.current.add(ve),J.current=ve,N.current.add(ve),Xt(P,Ie);let re;try{re=await oa(ve,(te=Y.current)==null?void 0:te.signal)}finally{N.current.delete(ve),J.current===ve&&(J.current=null),kt()}if(T.current)break;const ke=re.task||ze.getTask(ve),it=(ne=ke==null?void 0:ke.result)==null?void 0:ne.url;if(re.success&&ke&&it){await Ia(V.id,it),a&&await mt(it);break}if((ke==null?void 0:ke.status)===Ve.FAILED){const Pt=Ys(ke,re.error);if(Pt){T.current=!0;for(const Sa of N.current)ze.cancelTask(Sa);N.current.clear(),J.current=null,(oe=Y.current)==null||oe.abort(),Se.error(`视频生成失败且不可重试,已停止:${Pt}`);break}Ie+=1,Xt(P,Ie),ze.retryTask(ve);continue}ve=null}}catch(V){T.current||console.error("[VideoAnalyzer] Batch shot pipeline failed:",{shotId:b.id,error:V})}finally{M()}};await Promise.all(d.map((b,P)=>Z(b,P)))}finally{G.current=!1,J.current=null,N.current.clear(),Y.current=null,ye({running:!1,stopping:!1,currentIndex:-1,retryCount:0,completedCount:0,activeCount:0})}},[ce.running,xa,bt,ga,ya,W,ot,e.id,e.analysis,C,D,v,xt,ae,mt,Oe,kt,Xt,ba,_a,Ia,O]),ns=s.useCallback(async()=>{const a=br(j.current,S.current);await W({...Ze(j.current,a.shots),characters:a.characters,generatedAssetsResetAt:Date.now()})},[W]),Nt=s.useMemo(()=>{const[a,n]=ft.split(":").map(Number);if(!a||!n)return{};const o=Math.round(54*a/n);return{width:Math.max(o,48),height:o<48?Math.round(48*n/a):54}},[ft]);return t.jsxs("div",{className:"va-page",children:[t.jsxs("div",{className:"va-batch-config",children:[t.jsx("div",{className:"va-batch-config-title",children:"批量生成配置"}),t.jsx(Js,{images:le,onImagesChange:L,multiple:!0,label:"参考图 (可选)"}),p.length>0&&t.jsxs("div",{className:"va-characters",children:[t.jsx("div",{className:"va-characters-title",children:"角色"}),p.map(a=>t.jsxs("div",{className:"va-character-item",children:[t.jsxs("div",{className:"va-character-info",children:[t.jsx("span",{className:"va-character-name",children:a.name}),t.jsx("span",{className:"va-character-desc",children:a.description})]}),t.jsxs("div",{className:"va-character-ref",children:[a.referenceImageUrl?t.jsxs("div",{className:"va-character-ref-thumb",children:[t.jsx(lt,{src:a.referenceImageUrl,alt:a.name,showSkeleton:!1,eager:!0}),t.jsx("button",{className:"va-shot-frame-delete",onClick:()=>void Te(a.id,void 0),children:"×"})]}):t.jsx("span",{className:"va-character-ref-empty",children:"未设置"}),t.jsx("button",{onClick:()=>Bt(a),children:"生成"}),t.jsx("button",{onClick:()=>X(a.id),children:"选主体"})]})]},a.id))]}),t.jsxs("div",{className:"va-product-form",children:[t.jsxs("div",{className:"va-model-select",children:[t.jsx("label",{className:"va-model-label",children:"图片模型"}),t.jsx(Ft,{variant:"form",selectedModel:D,selectedSelectionKey:Ee(D,ae),onSelect:Qe,models:he,placement:"down",placeholder:"选择图片模型"}),ue.length>0&&t.jsx(Fa,{selectedParams:f,onParamChange:et,compatibleParams:ue,modelId:D,placement:"down"})]}),t.jsxs("div",{className:"va-model-select",children:[t.jsx("label",{className:"va-model-label",children:"视频模型"}),t.jsx(Ft,{variant:"form",selectedModel:A,selectedSelectionKey:Ee(A,$),onSelect:Ue,models:U,placement:"down",placeholder:"选择视频模型"}),Pe.length>0&&t.jsx(Fa,{selectedParams:K,onParamChange:Ke,compatibleParams:Pe,modelId:A,placement:"down"})]})]}),ce.running&&t.jsxs("div",{className:"va-batch-config-title",children:["正在并行生成 ",ce.completedCount,"/",c.length," 段",ce.activeCount>0?`,运行中 ${ce.activeCount} 个任务`:"",ce.retryCount>0?`,已重试 ${ce.retryCount} 次`:""]}),t.jsxs("div",{className:"va-page-actions",children:[h&&t.jsx("button",{onClick:h,children:"重新分析"}),t.jsx("button",{onClick:ns,children:"重置生成"}),t.jsxs("label",{className:"va-inline-checkbox",children:[t.jsx("input",{type:"checkbox",checked:Oe,onChange:a=>Je(a.target.checked)}),"生成后插入画布"]}),t.jsx("button",{onClick:rs,disabled:ce.running,children:"全部→生成视频"}),ce.running&&t.jsx("button",{onClick:ss,children:ce.stopping?"停止中…":"停止全部生成"})]})]}),t.jsx("div",{className:"va-shots",children:c.map((a,n)=>t.jsx(va,{shot:a,index:n,actions:t.jsxs(t.Fragment,{children:[a.generated_first_frame_url?t.jsxs("div",{className:"va-shot-frame-thumb",style:Nt,onMouseEnter:o=>Me(a.generated_first_frame_url,"image",o),onMouseLeave:Re,children:[t.jsx(lt,{src:a.generated_first_frame_url,alt:"首帧",showSkeleton:!1,eager:!0,onClick:()=>Yt(a)}),t.jsx("button",{className:"va-shot-frame-delete",onClick:()=>Zt(a.id,"first"),children:"×"}),t.jsx("button",{className:"va-shot-frame-regen",onClick:()=>Yt(a),children:"↻"})]}):a.first_frame_prompt||a.description?t.jsxs("span",{className:"va-shot-frame-btn-group",children:[t.jsx("button",{onClick:()=>Yt(a),children:"生成首帧"}),t.jsx("button",{className:"va-shot-frame-library-btn",onClick:()=>pt(a.id,"first"),children:t.jsx(ct,{content:"从素材库选择",showArrow:!1,children:t.jsx("span",{children:t.jsx(ma,{})})})})]}):null,(()=>{var y;const o=a.generated_last_frame_url||ht(a,n),u=!a.generated_last_frame_url&&o;return a.generated_last_frame_url?t.jsxs("div",{className:"va-shot-frame-thumb",style:Nt,onMouseEnter:d=>Me(a.generated_last_frame_url,"image",d),onMouseLeave:Re,children:[t.jsx(lt,{src:a.generated_last_frame_url,alt:"尾帧",showSkeleton:!1,eager:!0,onClick:()=>jt(a,n)}),t.jsx("button",{className:"va-shot-frame-delete",onClick:()=>Zt(a.id,"last"),children:"×"}),t.jsx("button",{className:"va-shot-frame-regen",onClick:()=>jt(a,n),children:"↻"})]}):u?t.jsxs("div",{className:"va-shot-frame-thumb va-shot-frame-thumb--borrowed",style:Nt,onMouseEnter:d=>Me(o,"image",d),onMouseLeave:Re,children:[t.jsx(lt,{src:o,alt:"尾帧(下一镜头首帧)",showSkeleton:!1,eager:!0,onClick:()=>jt(a,n)}),t.jsx("span",{className:"va-shot-frame-label",children:"下一镜头首帧"})]}):(y=a.last_frame_prompt)!=null&&y.trim()?t.jsxs("span",{className:"va-shot-frame-btn-group",children:[t.jsx("button",{onClick:()=>jt(a,n),children:"生成尾帧"}),t.jsx("button",{className:"va-shot-frame-library-btn",onClick:()=>pt(a.id,"last"),children:t.jsx(ct,{content:"从素材库选择",showArrow:!1,children:t.jsx("span",{children:t.jsx(ma,{})})})})]}):null})(),a.generated_video_url?t.jsxs("div",{className:"va-shot-frame-thumb",style:Nt,onMouseEnter:o=>Me(a.generated_video_url,"video",o),onMouseLeave:Re,children:[t.jsx(Ja,{src:a.generated_video_url,alt:"生成视频缩略图",className:"va-shot-frame-media",thumbnailSize:"small",onClick:()=>qt(a,n),videoProps:{muted:!0,preload:"metadata"}}),t.jsx("button",{className:"va-shot-frame-delete",onClick:()=>Zt(a.id,"video"),children:"×"}),t.jsx("button",{className:"va-shot-frame-regen",onClick:()=>qt(a,n),children:"↻"})]}):a.description||a.narration||a.dialogue||a.camera_movement||a.first_frame_prompt||a.last_frame_prompt?t.jsxs("span",{className:"va-shot-frame-btn-group",children:[t.jsx("button",{onClick:()=>qt(a,n),children:"生成视频"}),t.jsx("button",{className:"va-shot-frame-library-btn",onClick:()=>pt(a.id,"video"),children:t.jsx(ct,{content:"从素材库插入视频",showArrow:!1,children:t.jsx("span",{children:t.jsx(ma,{})})})})]}):null]})},a.id))}),t.jsxs("div",{className:"va-page-actions mv-generate-footer-actions",children:[t.jsx("button",{onClick:()=>void Gt(),disabled:c.length===0||!O,children:"脚本插入画布"}),t.jsx("button",{onClick:()=>void Ht(),disabled:gt||c.length===0,children:gt?`素材下载 ${yt}%`:"素材下载 ZIP"})]}),t.jsx("div",{className:"mv-generate-footer-hint",children:"若有素材未打包成功,解压后在 ZIP 根目录运行 `sh 00.补全下载.sh` 即可按 manifest 补全下载。"}),t.jsx(Va,{isOpen:!!je,onClose:()=>st(null),mode:Pa.SELECT,filterType:(je==null?void 0:je.assetType)==="video"?ra.VIDEO:ra.IMAGE,onSelect:Kt,selectButtonText:(je==null?void 0:je.assetType)==="video"?"使用此视频":"使用此图片"}),t.jsx(Va,{isOpen:!!Q,onClose:()=>X(null),mode:Pa.SELECT,filterType:ra.IMAGE,filterCategory:aa.CHARACTER,onSelect:a=>{if(Q){const n=j.current,o=(n.characters||n.analysis.characters||[]).find(u=>u.id===Q);Te(Q,a.url),o&&Ms(a,{name:o.name,prompt:o.description}).catch(u=>{console.warn("[VideoAnalyzer] Failed to mark asset as character:",u)})}X(null)},selectButtonText:"使用此主体"}),m&&js.createPortal(t.jsx("div",{className:"mv-hover-preview",style:{left:`${m.x}px`,top:`${m.y}px`},onMouseEnter:ts,onMouseLeave:as,children:m.type==="image"?t.jsx(lt,{src:m.url,alt:"Preview",showSkeleton:!1,eager:!0}):t.jsx("video",{src:m.url,controls:!0,muted:!0,preload:"metadata"})}),document.body)]})};function es(e){var r;return e.result?(r=e.result.urls)!=null&&r.length?e.result.urls.filter(Boolean):e.result.url?[e.result.url]:[]:[]}function xr(e){var r,l;return e.result?e.type===ge.VIDEO?((r=e.result.thumbnailUrls)==null?void 0:r[0])||e.result.thumbnailUrl||null:((l=e.result.thumbnailUrls)==null?void 0:l[0])||e.result.url||null:null}function Sr(e){switch(e){case Ve.COMPLETED:return"已完成";case Ve.PROCESSING:return"进行中";case Ve.PENDING:return"等待中";case Ve.FAILED:return"失败";default:return""}}function Cr(e){switch(e){case Ve.COMPLETED:return"completed";case Ve.PROCESSING:return"processing";case Ve.PENDING:return"pending";case Ve.FAILED:return"failed";default:return"pending"}}function wr(e){const r=new Date(e);return`${r.getMonth()+1}/${r.getDate()} ${String(r.getHours()).padStart(2,"0")}:${String(r.getMinutes()).padStart(2,"0")}`}function jr(e){const r=String(e.params.prompt||"");return r.length>40?`${r.slice(0,40)}…`:r}function Mr(e){return e==="youtube"?"🔗":e==="prompt"?"✦":"📁"}const kr=({record:e,related:r,isExpanded:l,onSelect:h,onToggleStar:c,onDelete:k,onToggleExpand:g,onInsertTask:I,onPreviewOpen:O,onSelectScript:j})=>{const S=!!(r&&r.rewrite.length+r.image.length+r.video.length>0),T=r?[...r.image,...r.video]:[];return t.jsxs("div",{className:"va-history-item",onClick:()=>h(e),children:[t.jsxs("div",{className:"va-history-header",children:[t.jsxs("span",{className:"va-history-source",children:[Mr(e.source)," ",e.sourceLabel]}),t.jsx("button",{className:`va-star-btn ${e.starred?"starred":""}`,onClick:G=>c(G,e),children:e.starred?"★":"☆"})]}),t.jsxs("div",{className:"va-history-meta",children:[S&&t.jsxs("button",{className:`va-history-expand-btn ${l?"expanded":""}`,onClick:G=>g(G,e.id),children:[t.jsx(ks,{size:12}),t.jsx("span",{children:l?"收起":"关联任务"})]}),t.jsx("span",{children:new Date(e.createdAt).toLocaleString()}),t.jsxs("span",{children:[e.analysis.shotCount," 镜头"]}),t.jsx("span",{children:e.model}),t.jsx("button",{className:"va-history-delete",onClick:G=>k(G,e.id),children:"删除"})]}),e.analysis.video_style&&t.jsx("div",{className:"va-history-style",children:e.analysis.video_style}),l&&r&&t.jsx(Nr,{related:r,record:e,previewTasks:T,onInsertTask:I,onPreviewOpen:O,onSelectScript:j})]})},Nr=({related:e,record:r,previewTasks:l,onInsertTask:h,onPreviewOpen:c,onSelectScript:k})=>t.jsxs("div",{className:"va-history-related",onClick:g=>g.stopPropagation(),children:[e.rewrite.length>0&&t.jsxs("div",{children:[t.jsxs("div",{className:"va-history-related-group-title",children:["脚本改编 (",e.rewrite.length,")"]}),e.rewrite.map(g=>t.jsx(pa,{task:g,onClick:I=>k==null?void 0:k(I,r,g)},g.id))]}),e.image.length>0&&t.jsxs("div",{children:[t.jsxs("div",{className:"va-history-related-group-title",children:["图片生成 (",e.image.length,")"]}),e.image.map(g=>t.jsx(pa,{task:g,previewTasks:l,onInsertTask:h,onPreviewOpen:c},g.id))]}),e.video.length>0&&t.jsxs("div",{children:[t.jsxs("div",{className:"va-history-related-group-title",children:["视频生成 (",e.video.length,")"]}),e.video.map(g=>t.jsx(pa,{task:g,previewTasks:l,onInsertTask:h,onPreviewOpen:c},g.id))]})]}),pa=({task:e,previewTasks:r,onClick:l,onInsertTask:h,onPreviewOpen:c})=>{const k=e.status===Ve.COMPLETED,g=es(e),I=k&&g.length>0,O=(e.type===ge.IMAGE||e.type===ge.VIDEO)&&I&&!!(r!=null&&r.length),j=xr(e),S=g[0],T=s.useCallback(G=>{if(O&&r){c==null||c(G,e,r);return}l==null||l(G)},[O,l,c,r,e]);return t.jsx(ct,{content:Sr(e.status),showArrow:!1,children:t.jsxs("div",{className:"va-history-related-task",onClick:T,children:[t.jsx("span",{className:`va-history-related-task-status ${Cr(e.status)}`}),t.jsx("span",{className:"va-history-related-task-prompt",children:jr(e)}),t.jsx("span",{className:"va-history-related-task-time",children:wr(e.createdAt)}),I&&S&&e.type!==ge.CHAT&&t.jsxs("span",{className:"va-history-related-task-thumb",children:[e.type===ge.VIDEO?t.jsx(Ja,{src:S,poster:j||void 0,alt:"",className:"va-history-related-task-thumb-media",thumbnailSize:"small",videoProps:{preload:"metadata",muted:!0,playsInline:!0,"aria-hidden":!0}}):t.jsx(lt,{src:j||S,alt:"",showSkeleton:!1,eager:!0}),e.type===ge.VIDEO&&t.jsx("span",{className:"va-history-related-task-thumb-badge","aria-hidden":"true",children:"▶"})]}),I&&h&&t.jsx(ct,{content:"插入画板",showArrow:!1,children:t.jsx("button",{className:"va-history-related-insert-btn",onClick:G=>h(G,e),"aria-label":"插入画板",children:t.jsx(Ns,{size:16})})})]})})};function Pr(e,r,l){var c;const h=((c=e.result)==null?void 0:c.title)||e.params.title||e.params.prompt||(e.type===ge.VIDEO?"视频预览":"图片预览");return l>1?`${h} (${r+1}/${l})`:h}function Tr(e){var h,c,k;const r=[],l=new Map;for(const g of e){if(g.type!==ge.IMAGE&&g.type!==ge.VIDEO)continue;const I=es(g);if(I.length===0)continue;const O=r.length,j=g.type===ge.VIDEO&&(((c=(h=g.result)==null?void 0:h.thumbnailUrls)==null?void 0:c[0])||((k=g.result)==null?void 0:k.thumbnailUrl))||void 0;I.forEach((S,T)=>{r.push({id:I.length>1?`${g.id}-${T}`:g.id,url:S,type:g.type===ge.VIDEO?"video":"image",title:Pr(g,T,I.length),prompt:g.params.prompt,posterUrl:g.type===ge.VIDEO?j:void 0})}),l.set(g.id,O)}return{items:r,taskIdToIndex:l}}const Ar=({records:e,onSelect:r,onRecordsChange:l,showStarredOnly:h=!1,onInsertTask:c,onSelectScript:k})=>{const g=h?e.filter(f=>f.starred):e,[I,O]=s.useState(null),[j,S]=s.useState(!1),[T,G]=s.useState([]),[Y,J]=s.useState(0),[N,ie]=s.useState(null),{tasks:le}=Xa(),L=s.useMemo(()=>{const f=new Map,R=new Set(e.map(q=>q.id)),A=()=>({rewrite:[],image:[],video:[]});for(const q of le){const $=q.params;if(q.type===ge.CHAT&&$.videoAnalyzerAction==="rewrite"&&typeof $.videoAnalyzerRecordId=="string"&&R.has($.videoAnalyzerRecordId)){const ee=$.videoAnalyzerRecordId;Ta(f,ee,"rewrite",q,A);continue}if((q.type===ge.IMAGE||q.type===ge.VIDEO)&&typeof $.batchId=="string"&&$.batchId.startsWith("va_")){const ee=Ps($.batchId,"va_",R);if(ee){const K=q.type===ge.IMAGE?"image":"video";Ta(f,ee,K,q,A)}}}return Ts(f)},[le,e]),Q=s.useCallback(async(f,R)=>{f.stopPropagation();const A=await xe(R.id,{starred:!R.starred});l(A)},[l]),X=s.useCallback((f,R)=>{f.stopPropagation(),ie(R)},[]),he=s.useCallback(async()=>{if(!N)return;const f=await As(N);l(f),ie(null)},[l,N]),U=s.useCallback((f,R)=>{f.stopPropagation(),O(A=>A===R?null:R)},[]),D=s.useCallback((f,R)=>{f.stopPropagation(),c==null||c(R)},[c]),me=s.useCallback((f,R,A)=>{f.stopPropagation(),k==null||k(R,A)},[k]),ae=s.useCallback((f,R,A)=>{f.stopPropagation();const{items:q,taskIdToIndex:$}=Tr(A),ee=$.get(R.id);!q.length||ee===void 0||(G(q),J(ee),S(!0))},[]),pe=s.useCallback(()=>{S(!1)},[]);return g.length===0?t.jsx("div",{className:"va-page va-empty",children:t.jsx("span",{children:h?"暂无收藏":"暂无分析记录"})}):t.jsxs(t.Fragment,{children:[t.jsx("div",{className:"va-page",children:t.jsx("div",{className:"va-history-list",children:g.map(f=>{const R=L.get(f.id),A=I===f.id;return t.jsx(kr,{record:f,related:R,isExpanded:A,onSelect:r,onToggleStar:Q,onDelete:X,onToggleExpand:U,onInsertTask:D,onPreviewOpen:ae,onSelectScript:me},f.id)})})}),t.jsx(Us,{visible:j,items:T,initialIndex:Y,onClose:pe,showThumbnails:T.length>1}),t.jsx(zs,{open:N!==null,title:"确认删除",description:"确定要删除这条历史记录吗?此操作不可撤销。",confirmText:"删除",cancelText:"取消",danger:!0,onOpenChange:f=>{f||ie(null)},onConfirm:he})]})},zr=[{id:"analyze",label:"分析"},{id:"script",label:"脚本"},{id:"generate",label:"生成"}],Hr=()=>{const{board:e}=ha(),{records:r,setRecords:l,currentRecord:h,setCurrentRecord:c,showStarred:k,setShowStarred:g,starredCount:I,selectRecord:O,updateCurrentRecord:j,restart:S,applySyncedRecord:T}=Es({loadRecords:fa,logPrefix:"[VideoAnalyzer]"}),{page:G,setPage:Y,navigateToStep:J,goToDefaultPage:N,openHistory:ie,openStarred:le,toggleStarred:L}=Ds({initialPage:"analyze",defaultPage:"analyze",historyPage:"history",setShowStarred:g}),Q=s.useCallback(async f=>cr(f)?Lt(f):null,[]);Qs({syncTask:Q,applySyncedRecord:T,logPrefix:"[VideoAnalyzer]"});const X=s.useMemo(()=>zr.map((f,R)=>({...f,disabled:!h&&R>0})),[h]),he=s.useCallback(f=>{j(f)},[j]),U=s.useCallback(f=>{O(f),N()},[N,O]),D=s.useCallback(f=>{j(f)},[j]),me=s.useCallback(()=>{S(),N()},[N,S]),ae=s.useCallback(async f=>{var R,A,q,$;if(!((R=f.result)!=null&&R.url)&&!((q=(A=f.result)==null?void 0:A.urls)!=null&&q.length)||!e){Se.warning("无法插入:白板未就绪");return}try{if(f.type===ge.IMAGE){const ee=($=f.result.urls)!=null&&$.length?f.result.urls:[f.result.url];for(const K of ee)await Rs(e,K);Se.success(ee.length>1?"多图已插入到白板":"图片已插入到白板")}else f.type===ge.VIDEO&&(await Vs(e,f.result.url),Se.success("视频已插入到白板"))}catch(ee){console.error("[VideoAnalyzer] Failed to insert to board:",ee),Se.error(`插入失败: ${ee instanceof Error?ee.message:"未知错误"}`)}},[e]),pe=s.useCallback(async(f,R)=>{const A=String(R.params.videoAnalyzerPrompt||R.params.prompt||""),q=f.scriptVersions||[],$=q.find(K=>K.prompt===A)||q.find(K=>{var _e;return A&&((_e=K.prompt)==null?void 0:_e.includes(A))});let ee=f;if($&&$.id!==f.activeVersionId){const K=Za(f,$.id);if(K){const _e=await xe(f.id,K);ee=_e.find(ce=>ce.id===f.id)||{...f,...K},l(_e)}}c(ee),Y("script")},[c,Y,l]);return t.jsxs("div",{className:"video-analyzer",children:[t.jsx(Fs,{isHistoryPage:G==="history",showStarred:k,recordsCount:r.length,starredCount:I,currentStep:G,steps:X,onStepNavigate:J,onBackFromHistory:N,onOpenHistory:ie,onOpenStarred:le,onToggleStarred:L}),G==="analyze"&&t.jsx(pr,{existingRecord:h,onComplete:he,onRecordsChange:l,onCreateNew:me,onNext:h?()=>Y("script"):void 0}),G==="script"&&h&&t.jsx(gr,{record:h,onRecordUpdate:D,onRecordsChange:l,onNext:()=>Y("generate")}),G==="generate"&&h&&t.jsx(Ir,{record:h,onRecordUpdate:D,onRecordsChange:l,onRestart:me}),G==="history"&&t.jsx(Ar,{records:r,onSelect:U,onRecordsChange:l,showStarredOnly:k,onInsertTask:e?ae:void 0,onSelectScript:pe})]})};export{Hr as default};
|
|
1
|
+
import{j as t,E as ct,n0 as Ca,e0 as vt,n1 as fa,a1 as Wa,n2 as is,mR as Vt,mW as ls,n3 as cs,n4 as Lt,n5 as us,n6 as ds,mU as ms,mZ as ps,m_ as fs,n7 as xe,ck as ha,r as s,aw as we,aB as ut,n8 as Xe,gn as hs,jO as Qt,M as Se,n9 as wa,na as vs,am as $e,bz as ze,nb as $t,nc as Ya,nd as qa,aA as Ft,ne as va,ah as ja,nf as gs,ng as Ze,nh as ys,bg as ge,ni as Za,nj as ea,nk as bs,mq as ta,nl as _s,nm as Ma,iW as Is,iY as xs,jp as Ss,nn as ka,hb as At,db as aa,no as Cs,gU as Xa,dB as Ve,np as sa,nq as Na,nr as ws,b7 as js,R as lt,ef as ra,eK as Pa,ns as Ms,$ as ks,l as Ns,mI as Aa,mJ as Ps,mK as As,nt as Ts,c1 as zs,mM as Es,mN as Ds,d as Rs,c as Vs,mO as Fs}from"./startup-app-M6vjXkRC.js";import{i as dt,j as Ta,k as za,T as Os,R as Ot,K as Us,m as Ee,v as Ea,q as na,V as Ja,U as Ls}from"./ai-chat-D_s8vs6j.js";import{e as $s,c as Bs,r as Gs,a as Hs,b as Ks,w as oa,d as Ws,g as Ys,f as qs}from"./workflow-generation-utils-362XEGgT.js";import{c as Da,f as Ra,g as Zs,d as Xs}from"./ai-generation-preferences-service-rBqGBu1Z.js";import{M as Va}from"./tool-windows-Cf62DjP-.js";/* empty css *//* empty css */import{R as Js}from"./ResizableDivider-tAq9KErj.js";import{P as Fa}from"./ParametersDropdown-wKdOCk_p.js";import{u as Qs}from"./VideoAnalyzer-gVfFvd5A.js";import"./startup-runtime-DTmhLESk.js";const er=({shots:e,totalDuration:r})=>t.jsx("div",{className:"va-timeline",children:e.filter(Boolean).map(l=>t.jsx(ct,{content:`${l.label||"未命名镜头"} ${l.startTime??0}s-${l.endTime??0}s`,showArrow:!1,children:t.jsx("div",{className:"va-timeline-segment",style:{flex:Math.max(((l.endTime??0)-(l.startTime??0))/Math.max(r,1),0),backgroundColor:l.type&&Ca[l.type]||Ca.other}})},l.id))});function Oa(e){return(e||"").trim().toLowerCase().replace(/[^a-z0-9]/g,"")||"mp4"}function tr(e){const r=e.name.split(".").pop();if(r&&r.length<=8)return Oa(r);const l=e.type.split("/")[1];return Oa(l)}async function ar(e,r){const l=tr(e),c=`/__aitu_cache__/video/${`video-analyzer-source-${Date.now()}-${Math.random().toString(36).slice(2,8)}`}.${l}`;return await vt.cacheMediaFromBlob(c,e,"video",{metadata:{source:"video-analyzer-input",fileName:e.name,mimeType:e.type||"video/mp4",size:e.size}}),{type:"upload",cacheUrl:c,fileName:e.name||`video-source.${l}`,mimeType:e.type||"video/mp4",size:e.size}}async function sr(e){if(!e||e.type!=="upload")return null;const r=await vt.getCachedBlob(e.cacheUrl);return r?new File([r],e.fileName||"video-source.mp4",{type:e.mimeType||r.type||"video/mp4",lastModified:Date.now()}):null}function Qa(e){return ps(e,"videoAnalyzerAction",["analyze","rewrite","prompt-generate"])}function rr(e){return fs(e,{missingMessage:"分析任务缺少结果内容",fromStructured:r=>r})}function nr(e){const r=e.params.videoAnalyzerSourceSnapshot;if((r==null?void 0:r.type)==="youtube"||(r==null?void 0:r.type)==="upload"||(r==null?void 0:r.type)==="prompt")return r;const l=e.params.videoAnalyzerSource,h=String(e.params.videoAnalyzerSourceLabel||"").trim();return l==="youtube"&&h?{type:"youtube",youtubeUrl:h}:l==="prompt"&&h?{type:"prompt",prompt:String(e.params.videoAnalyzerUserPrompt||h),pdfCacheUrl:Vt(e,"pdfCacheUrl")||void 0,pdfName:Vt(e,"pdfName")||void 0,pdfMimeType:Vt(e,"pdfMimeType")||void 0}:null}function or(e,r){const l=new Map(e.map(h=>[h.id,h]));return r.map(h=>{const c=l.get(h.id);return{...h,referenceImageUrl:h.referenceImageUrl||(c==null?void 0:c.referenceImageUrl)}})}function ir(e){var h;const r=(h=e.result)==null?void 0:h.analysisData,l=Array.isArray(r==null?void 0:r.editedShots)?r.editedShots:Array.isArray(r==null?void 0:r.shots)?r.shots:null;return!r||!l?null:{shots:l,characters:Array.isArray(r.characters)?r.characters:void 0,hasCharacters:Object.prototype.hasOwnProperty.call(r,"characters"),videoStyle:String(r.video_style||r.videoStyle||"").trim()||void 0,bgmMood:String(r.bgm_mood||r.bgmMood||"").trim()||void 0,suggestion:String(r.suggestion||"").trim()||void 0}}function lr(e,r){const l=e.params.videoAnalyzerProductInfo;if(!(!l||typeof l!="object"))return Lt(l,r)}async function Ut(e){var N,ie;if(e.status!=="completed")return null;const r=Qa(e);if(!r)return null;if(r==="analyze"||r==="prompt-generate"){const le=await fa(),U=le.find(f=>f.analyzeTaskId===e.id);if(U)return{records:le,record:U};const Q=rr(e),X=nr(e),he=e.params.videoAnalyzerSource,L=he==="prompt"?"prompt":he==="upload"?"upload":"youtube",D=String(e.params.videoAnalyzerSourceLabel||(L==="prompt"?"提示词生成":L==="youtube"?(X==null?void 0:X.type)==="youtube"?X.youtubeUrl:"":"本地视频")),me=lr(e,Q.totalDuration),ae={id:Wa(),createdAt:Date.now(),source:L,sourceLabel:D,sourceSnapshot:X,model:String(e.params.model||""),modelRef:e.params.modelRef||null,analysis:Q,...me?{productInfo:me}:{},starred:!1,analyzeTaskId:e.id};return{records:await is(ae),record:ae}}const l=Vt(e,"videoAnalyzerRecordId");if(!l)return null;const h=await fa(),c=h.find(le=>le.id===l);if(!c)return null;if(c.pendingRewriteTaskId!==e.id)return!c.pendingRewriteTaskId&&c.storyboardGeneratedAt&&(!e.completedAt||c.storyboardGeneratedAt>=e.completedAt)?{records:h,record:c}:null;const k=c.editedShots||c.analysis.shots,g=ir(e),I=g||(()=>{const le=ls(e);if(!le)throw new Error("脚本改编任务缺少结果内容");return cs(le,k)})(),O=I.shots,j=I.hasCharacters?or(c.characters||c.analysis.characters||[],I.characters||[]):void 0,S=I.videoStyle||I.bgmMood?{...Lt(c.productInfo||{prompt:""},c.analysis.totalDuration),...I.videoStyle?{videoStyle:I.videoStyle}:{},...I.bgmMood?{bgmMood:I.bgmMood}:{}}:void 0,A={...c.analysis,suggestion:I.suggestion||""},G=`AI 改编 #${(((N=c.scriptVersions)==null?void 0:N.length)||0)+1}`,Y=us(O,G,(ie=c.productInfo)==null?void 0:ie.prompt,{characters:j||c.characters||c.analysis.characters||[],productInfo:S||c.productInfo}),J=ds(c,Y);return ms(c,{...J,analysis:A,...j!==void 0?{characters:j}:{},...S?{productInfo:S}:{},pendingRewriteTaskId:null,storyboardGeneratedAt:Date.now()},xe)}function cr(e){return Qa(e)!==null}const ia="gemini-3.1-pro-preview",la="video-analyzer:model",Tt="video-analyzer:video-model",ca="veo3",zt=30,ur="aitu:settings:provider-nav",dr=20*1024*1024;function Ua(e){return(e/1024/1024).toFixed(1)+"MB"}function mr(e){const r=`${e.id} ${e.label} ${e.shortLabel||""} ${e.sourceProfileName||""}`.toLowerCase();return e.vendor===ja.GEMINI||e.vendor===ja.GOOGLE||r.includes("gemini")}const pr=({existingRecord:e,onComplete:r,onRecordsChange:l,onCreateNew:h,onNext:c})=>{const{setAppState:k}=ha(),[g,I]=s.useState("prompt"),[O,j]=s.useState(""),[S,A]=s.useState(()=>{var m;return((m=e==null?void 0:e.productInfo)==null?void 0:m.videoStyle)||(e==null?void 0:e.analysis.video_style)||""}),[G,Y]=s.useState(()=>{var m;return((m=e==null?void 0:e.productInfo)==null?void 0:m.targetDuration)||(e==null?void 0:e.analysis.totalDuration)||zt}),[J,N]=s.useState({}),[ie,le]=s.useState([]),[U,Q]=s.useState(null),[X,he]=s.useState(""),[L,D]=s.useState(null),[me,ae]=s.useState(()=>(e==null?void 0:e.model)||we(la,ia).modelId),[pe,f]=s.useState(()=>(e==null?void 0:e.modelRef)||we(la,ia).modelRef),R=s.useCallback((m,_)=>{ae(m),f(_||null),ut(la,m,_)},[]),T=dt("video"),[q,$]=s.useState(()=>{var m;return((m=e==null?void 0:e.productInfo)==null?void 0:m.videoModel)||we(Tt,ca).modelId}),[ee,K]=s.useState(()=>{var m,_;return((m=e==null?void 0:e.productInfo)==null?void 0:m.videoModelRef)||we(Tt,((_=e==null?void 0:e.productInfo)==null?void 0:_.videoModel)||ca).modelRef}),_e=s.useMemo(()=>Xe(q),[q]),[ce,ye]=s.useState(()=>{var w,F;const m=((w=e==null?void 0:e.productInfo)==null?void 0:w.videoModel)||we(Tt,ca).modelId,_=Xe(m);return((F=e==null?void 0:e.productInfo)==null?void 0:F.segmentDuration)||parseInt(_.defaultDuration,10)||8}),Oe=s.useMemo(()=>(_e.durationOptions||[]).map(m=>({value:parseInt(m.value,10),label:m.label})),[_e]),Je=s.useCallback((m,_)=>{$(m),K(_||null),ut(Tt,m,_);const w=Xe(m);ye(parseInt(w.defaultDuration,10)||8)},[]),[ue,Pe]=s.useState(!1),[B,Be]=s.useState(null),[De,de]=s.useState(""),[i,v]=s.useState(""),[p,C]=s.useState((e==null?void 0:e.analysis)||null),be=hs(),W=s.useRef(null),Ne=s.useRef(null),Ue=s.useRef(null),Ae=s.useRef(!1),Bt=s.useMemo(()=>{if(Ue.current&&URL.revokeObjectURL(Ue.current),!L)return Ue.current=null,null;const m=URL.createObjectURL(L);return Ue.current=m,m},[L]);s.useEffect(()=>()=>{Ue.current&&URL.revokeObjectURL(Ue.current)},[]),s.useEffect(()=>{let m=!1;return(async()=>{var F,se,fe,Me;if(!e){if(B)return;C(null),I("prompt"),j(""),A(""),Y(zt),N({}),Q(null),he(""),D(null),v("");return}if(C(e.analysis||null),ae(e.model||ia),f(e.modelRef||null),v(""),A(((F=e.productInfo)==null?void 0:F.videoStyle)||e.analysis.video_style||""),Y(((se=e.productInfo)==null?void 0:se.targetDuration)||e.analysis.totalDuration||zt),(fe=e.productInfo)!=null&&fe.videoModel){$(e.productInfo.videoModel),K(e.productInfo.videoModelRef||null);const Re=Xe(e.productInfo.videoModel);ye(e.productInfo.segmentDuration||parseInt(Re.defaultDuration,10)||8)}const w=e.sourceSnapshot;if((w==null?void 0:w.type)==="prompt"){I("prompt"),j(w.prompt||e.sourceLabel||""),N(wa((Me=e.productInfo)==null?void 0:Me.creativeBrief)),he(""),D(null),Q(w.pdfCacheUrl?{cacheUrl:w.pdfCacheUrl,name:w.pdfName||"参考资料.pdf",size:w.pdfSize||0,mimeType:w.pdfMimeType||"application/pdf"}:null);return}if((w==null?void 0:w.type)==="upload"){I("upload"),j(""),N({}),Q(null),he("");const Re=await sr(w);if(m)return;D(Re),Re||v("原上传视频缓存已失效,无法自动回填视频");return}if(e.source==="upload"){I("upload"),j(""),N({}),Q(null),he(""),D(null),v("这条旧历史未保存原视频,无法自动回填视频");return}I("youtube"),j(""),N({}),Q(null),D(null),(w==null?void 0:w.type)==="youtube"?he(w.youtubeUrl):e.source==="youtube"?he(e.sourceLabel||""):he("")})(),()=>{m=!0}},[e]);const Qe=dt("text"),Le=s.useMemo(()=>Qe.filter(mr),[Qe]),et=g!=="prompt"||!!U,Ke=s.useMemo(()=>et?Le:Qe,[Qe,Le,et]),Gt=s.useMemo(()=>{const m=be.find(_=>_.id===Qt);return!!(m!=null&&m.apiKey.trim())},[be]),mt=(pe==null?void 0:pe.profileId)===Qt,gt=s.useCallback(()=>{const m={action:"select",profileId:Qt};window.__aituPendingProviderNavigationIntent=m,window.dispatchEvent(new CustomEvent(ur,{detail:m})),k(_=>({..._,openSettings:!0}))},[k]);s.useEffect(()=>{if(Ke.length===0||Ta(Ke,me,pe))return;const _=Ke[0];R(_.id,za(_))},[Ke,me,pe,R]);const yt=s.useCallback(m=>{var w;const _=(w=m.target.files)==null?void 0:w[0];_&&(D(_),v(""),C(null))},[]),Ht=s.useCallback(m=>{m.preventDefault();const _=m.dataTransfer.files[0];_!=null&&_.type.startsWith("video/")&&(D(_),v(""),C(null))},[]),tt=s.useCallback(m=>{m.stopPropagation(),D(null),v(""),W.current&&(W.current.value="")},[]),bt=s.useCallback(()=>{const m=!B;Q(_=>(m&&(_!=null&&_.cacheUrl)&&vt.deleteCache(_.cacheUrl).catch(()=>{}),null)),Ne.current&&(Ne.current.value="")},[B]),_t=s.useCallback(async m=>{var F;const _=(F=m.target.files)==null?void 0:F[0];if(m.target.value="",!_)return;if(!(_.type==="application/pdf"||_.name.toLowerCase().endsWith(".pdf"))){Se.warning("请上传 PDF 文件");return}if(_.size>dr){Se.warning("PDF 不能超过 20MB");return}if(Le.length===0){Se.warning("PDF 入参需要 Gemini 文本模型,请先配置 Gemini 模型");return}try{const se=`video-prompt-pdf-${Wa()}.pdf`;await vt.cacheToCacheStorageOnly(se,_),Q(fe=>(!B&&(fe!=null&&fe.cacheUrl)&&vt.deleteCache(fe.cacheUrl).catch(()=>{}),{cacheUrl:se,name:_.name,size:_.size,mimeType:_.type||"application/pdf"})),Se.success("PDF 已添加,将作为提示词上下文提交给 Gemini")}catch(se){Se.error(se instanceof Error?se.message:"PDF 上传失败")}},[Le.length,B]),[Fe,at]=s.useState(!1),[It,je]=s.useState(""),st=s.useCallback(async(m,_)=>{at(!0),je("提取帧图片...");try{const w=_.map(se=>se.startTime),F=await $s(m,w,(se,fe)=>je(`提取帧图片 ${se}/${fe}`));return await Promise.all(_.map(async(se,fe)=>{const Me=F[fe];if(!Me)return se;try{const Re=await Bs(Me,se.id,"first");return{...se,generated_first_frame_url:Re}}catch{return se}}))}catch{return _}finally{at(!1),je("")}},[]),pt=s.useCallback(async()=>{if(!(Ae.current||B)){Ae.current=!0,Pe(!0),v(""),de("准备中...");try{let m={};if(g==="prompt"){const w=O.trim();if(!w){v("请输入提示词"),Ae.current=!1,Pe(!1);return}if(U&&!Ta(Le,me,pe)){const fe=Le[0];fe&&R(fe.id,za(fe)),Se.warning("PDF 入参仅支持 Gemini 文本模型"),Ae.current=!1,Pe(!1),de("");return}const F=wa(J);m={prompt:vs({userPrompt:w,pdfAttachmentName:U==null?void 0:U.name,creativeBrief:F,videoStyle:S,videoModel:q,segmentDuration:ce,targetDuration:G}),model:me,modelRef:pe,taskLabel:`提示词生成:${w.slice(0,32)}`,videoAnalyzerAction:"prompt-generate",videoAnalyzerSource:"prompt",videoAnalyzerSourceLabel:w.slice(0,80),videoAnalyzerUserPrompt:w,videoAnalyzerSourceSnapshot:{type:"prompt",prompt:w,...U?{pdfCacheUrl:U.cacheUrl,pdfName:U.name,pdfMimeType:U.mimeType,pdfSize:U.size}:{}},videoAnalyzerProductInfo:{prompt:w,videoModel:q,videoModelRef:ee,targetDuration:G,segmentDuration:ce,videoStyle:S,creativeBrief:F},knowledgeContextRefs:ie,...U?{pdfCacheUrl:U.cacheUrl,pdfMimeType:U.mimeType,pdfName:U.name}:{}}}else if(g==="upload"&&L){de("缓存视频文件...");const w=await ar(L);m={videoCacheUrl:w.type==="upload"?w.cacheUrl:void 0,...w.type==="upload"?{mimeType:w.mimeType}:{},model:me,modelRef:pe,taskLabel:`分析视频:${L.name||"本地视频"}`,videoAnalyzerSource:"upload",videoAnalyzerSourceLabel:L.name||"本地视频",videoAnalyzerSourceSnapshot:w}}else if(g==="youtube"&&X)m={youtubeUrl:X,model:me,modelRef:pe,taskLabel:`分析视频:${X}`,videoAnalyzerSource:"youtube",videoAnalyzerSourceLabel:X,videoAnalyzerSourceSnapshot:{type:"youtube",youtubeUrl:X}};else{v("请先输入提示词、选择视频文件或输入 YouTube URL"),Ae.current=!1,Pe(!1);return}$e.trackUIInteraction({area:"popular_video_tool",action:"video_analysis_started",control:"analyze_video",source:"video_analyzer_analyze_page",metadata:{inputMode:g,hasPrompt:!!O.trim(),hasPdfAttachment:!!U,hasUpload:!!L,hasYoutubeUrl:!!X,fileSizeBytes:L==null?void 0:L.size,hasModelRef:!!pe}}),de("加入任务队列...");const _=await Os.execute(m,{mode:"queue"});_.success&&_.taskId?(Be(_.taskId||null),de("已加入任务队列,等待分析...")):(Ae.current=!1,v(_.error||"创建分析任务失败"))}catch(m){Ae.current=!1,v(m.message||"分析失败")}finally{Pe(!1)}}},[g,L,X,O,S,q,ee,G,ce,J,ie,U,B,me,pe,Le,R]);s.useEffect(()=>{if(!B)return;const m=ze.observeTaskUpdates().subscribe(_=>{var w;if(_.task.id===B){if(_.task.status==="failed"){Ae.current=!1,Be(null),de(""),v(((w=_.task.error)==null?void 0:w.message)||"分析失败");return}if(_.task.status==="completed"){Ut(_.task).then(async F=>{if(F&&(l(F.records),r(F.record),C(F.record.analysis),F.record.source==="upload"&&L&&F.record.analysis.shots.length>0)){const se=await st(L,F.record.analysis.shots);C(Me=>Me&&{...Me,shots:se});const fe=await xe(F.record.id,{editedShots:se});l(fe),r({...F.record,editedShots:se})}}).catch(F=>{v(F.message||"分析结果同步失败")}).finally(()=>{Ae.current=!1,Be(null),de("")});return}typeof _.task.progress=="number"?de(`分析中 ${Math.round(_.task.progress)}%`):de("分析中,请耐心等待...")}});return()=>m.unsubscribe()},[B,r,l,L,st]);const Kt=s.useCallback(async()=>{var m;p&&(await Ot("text",$t(p.shots,p)),$e.trackUIInteraction({area:"popular_video_tool",action:"analysis_inserted_to_canvas",control:"insert_analysis",source:"video_analyzer_analyze_page",metadata:{shotCount:p.shots.length,productExposureRatio:p.productExposureRatio,characterCount:((m=p.characters)==null?void 0:m.length)||0}}))},[p]);return t.jsxs("div",{className:"va-page",children:[!p&&t.jsxs(t.Fragment,{children:[t.jsxs("div",{className:"va-tabs",children:[t.jsx("button",{className:`va-tab ${g==="prompt"?"active":""}`,onClick:()=>I("prompt"),children:"提示词生成"}),t.jsx("button",{className:`va-tab ${g==="upload"?"active":""}`,onClick:()=>I("upload"),children:"上传视频"}),t.jsx("button",{className:`va-tab ${g==="youtube"?"active":""}`,onClick:()=>I("youtube"),children:"YouTube URL"})]}),g==="prompt"?t.jsxs("div",{className:"va-prompt-start",children:[t.jsxs("div",{className:"va-context-panel",children:[t.jsxs("div",{className:"va-pdf-row",children:[t.jsx("input",{ref:Ne,type:"file",accept:"application/pdf,.pdf",onChange:_t,style:{display:"none"}}),t.jsx("button",{type:"button",className:"va-secondary-btn",onClick:()=>{var m;return(m=Ne.current)==null?void 0:m.click()},disabled:ue||!!B,children:U?"更换 PDF":"上传 PDF"}),U?t.jsxs("div",{className:"va-pdf-chip",children:[t.jsxs("span",{title:U.name,children:[U.name," · ",Ua(U.size)]}),t.jsx("button",{type:"button","aria-label":"移除 PDF",onClick:bt,disabled:ue||!!B,children:"×"})]}):t.jsx("span",{className:"va-pdf-hint",children:"可选,上传后仅支持 Gemini 模型,PDF 不超过 20MB"})]}),t.jsx(Us,{value:ie,onChange:le,disabled:ue||!!B,className:"va-knowledge-context-selector"})]}),t.jsx(Ya,{value:J,onChange:N,workflow:"popular_video",videoStyle:S,onVideoStyleChange:A}),t.jsx(qa,{selectedModel:q,selectedSelectionKey:Ee(q,ee),onSelectModel:Je,models:T,segmentDuration:ce,durationOptions:Oe,onSegmentDurationChange:ye,targetDuration:G,onTargetDurationChange:m=>Y(Number.isFinite(m)&&m>0?m:zt),disabled:ue||!!B}),t.jsx("textarea",{className:"va-prompt-textarea",value:O,onChange:m=>{j(m.target.value),v(""),C(null)},placeholder:"输入产品、主题、受众、风格或爆款方向,可附带 PDF 作为上下文",rows:5})]}):g==="upload"?L?t.jsxs("div",{className:"va-video-preview",children:[t.jsx("video",{src:Bt,controls:!0,muted:!0,playsInline:!0}),t.jsx("button",{className:"va-video-preview-close",onClick:tt,children:"✕"}),t.jsxs("div",{className:"va-video-preview-info",children:[t.jsx("span",{className:"va-video-preview-name",children:L.name}),t.jsx("span",{className:"va-video-preview-size",children:Ua(L.size)})]}),t.jsx("input",{ref:W,type:"file",accept:"video/*",onChange:yt,style:{display:"none"}})]}):t.jsxs("div",{className:"va-dropzone",onDrop:Ht,onDragOver:m=>m.preventDefault(),onClick:()=>{var m;return(m=W.current)==null?void 0:m.click()},children:[t.jsx("input",{ref:W,type:"file",accept:"video/*",onChange:yt,style:{display:"none"}}),t.jsxs("span",{className:"va-placeholder",children:["拖拽视频到此处 或 点击上传",t.jsx("br",{}),t.jsx("span",{className:"va-placeholder-hint",children:"建议视频在6M以内,可用推特或Youtube下载器下载最低分辨率视频"})]})]}):t.jsx("input",{className:"va-url-input",type:"text",placeholder:"https://www.youtube.com/watch?v=...",value:X,onChange:m=>he(m.target.value)}),t.jsxs("div",{className:"va-analyze-control-row",children:[t.jsxs("div",{className:"va-model-select va-model-select--analysis",children:[t.jsx("label",{className:"va-model-label",children:"分析模型"}),t.jsx(Ft,{variant:"form",selectedModel:me,selectedSelectionKey:Ee(me,pe),onSelect:R,models:Ke,placement:"auto",disabled:ue,placeholder:et?"选择 Gemini 模型":"选择文本模型"})]}),t.jsx("button",{className:"va-analyze-btn va-analyze-btn--inline",onClick:pt,disabled:ue||!!B||(g==="prompt"?!O.trim():g==="upload"?!L:!X),children:ue||B?De||"分析中...":g==="prompt"?"生成提示词":"开始分析"})]}),et&&!mt&&t.jsxs("div",{className:"va-model-tip",children:[t.jsx("span",{children:"建议使用 gemini-mix 分组的gemini-3.1-pro-preview"}),!Gt&&t.jsx("button",{type:"button",className:"va-model-tip-link",onClick:gt,children:"去设置"})]}),i&&t.jsx("div",{className:"va-error",children:i})]}),p&&t.jsxs("div",{className:"va-results",children:[t.jsxs("div",{className:"va-stats",children:[t.jsxs("div",{className:"va-stat",children:[t.jsxs("span",{className:"va-stat-value",children:[p.totalDuration,"s"]}),t.jsx("span",{className:"va-stat-label",children:"总时长"})]}),t.jsxs("div",{className:"va-stat",children:[t.jsx("span",{className:"va-stat-value",children:p.shotCount}),t.jsx("span",{className:"va-stat-label",children:"镜头数"})]}),t.jsxs("div",{className:"va-stat",children:[t.jsxs("span",{className:"va-stat-value",children:[p.productExposureRatio,"%"]}),t.jsx("span",{className:"va-stat-label",children:"产品占比"})]}),t.jsxs("div",{className:"va-stat",children:[t.jsx("span",{className:"va-stat-value",children:p.aspect_ratio||"-"}),t.jsx("span",{className:"va-stat-label",children:"画面比例"})]})]}),(p.video_style||p.bgm_mood)&&t.jsxs("div",{className:"va-style-info",children:[p.video_style&&t.jsxs("span",{children:["风格: ",p.video_style]}),p.bgm_mood&&t.jsxs("span",{children:["BGM: ",p.bgm_mood]})]}),t.jsx("div",{className:"va-suggestion",children:p.suggestion}),t.jsx(er,{shots:p.shots,totalDuration:p.totalDuration}),t.jsx("div",{className:"va-shots",children:p.shots.map((m,_)=>t.jsx(va,{shot:m,index:_},m.id))}),t.jsxs("div",{className:"va-page-actions",children:[Fe&&t.jsx("span",{className:"va-frame-progress",children:It}),t.jsx("button",{onClick:Kt,children:"插入画布"}),t.jsx("button",{onClick:()=>{C(null)},children:"重新分析"}),h&&t.jsx("button",{onClick:h,children:"新建分析"}),c&&t.jsx("button",{className:"va-btn-primary",onClick:c,children:"下一步: 编辑脚本 →"})]})]})]})};function He(e){e.style.height="auto",e.style.height=e.scrollHeight+"px"}function We(e,r=30){if(!e)return 1;const l=e.split(`
|
|
2
|
+
`);let h=0;for(const c of l)h+=Math.max(1,Math.ceil(c.length/r));return Math.max(1,h)}function Ye(e){e&&He(e)}function Et(e){const r=Lt(e.productInfo||{prompt:""},e.analysis.totalDuration);return{...r,videoStyle:r.videoStyle??e.analysis.video_style??"",bgmMood:r.bgmMood??e.analysis.bgm_mood??""}}function qe(e,r,l){return e.find(h=>h.id===r)||l}const ua="video-analyzer:script-model",da="video-analyzer:video-model",La="gemini-3.1-pro-preview",$a="veo3",fr=["固定镜头 (Static)","缓慢推近 (Dolly In)","缓慢拉远 (Dolly Out)","水平平移 (Pan)","垂直摇移 (Tilt)","跟随拍摄 (Follow)","手持感 (Handheld)","环绕拍摄 (Orbit)","升降镜头 (Crane)","快速推移 (Zoom In)","快速拉远 (Zoom Out)","滑轨移动 (Slider)","航拍俯冲 (Drone Dive)","第一人称 (POV)"],hr=[{label:"无 (none)",value:"none"},{label:"仅旁白 (narration_only)",value:"narration_only"},{label:"仅对白 (dialogue_only)",value:"dialogue_only"},{label:"旁白+对白 (both)",value:"both"}],vr=[{label:"硬切 (cut)",value:"cut"},{label:"溶解 (dissolve)",value:"dissolve"},{label:"匹配切 (match_cut)",value:"match_cut"},{label:"淡出到黑 (fade_to_black)",value:"fade_to_black"}],gr=({record:e,onRecordUpdate:r,onRecordsChange:l,onNext:h})=>{var de;const[c,k]=s.useState(()=>Et(e)),[g,I]=s.useState(e.editedShots||[...e.analysis.shots]),[O,j]=s.useState(!1),[S,A]=s.useState(()=>e.pendingRewriteTaskId||null),[G,Y]=s.useState(""),[J,N]=s.useState(""),[ie,le]=s.useState(!1),U=s.useRef(null),Q=s.useRef(!1),[X,he]=s.useState(()=>we(ua,La).modelId),[L,D]=s.useState(()=>we(ua,La).modelRef),me=s.useCallback((i,v)=>{he(i),D(v||null),ut(ua,i,v)},[]),ae=dt("text"),pe=dt("video"),[f,R]=s.useState(()=>{var i;return((i=e.productInfo)==null?void 0:i.videoModel)||we(da,$a).modelId}),[T,q]=s.useState(()=>{var i,v;return((i=e.productInfo)==null?void 0:i.videoModelRef)||we(da,((v=e.productInfo)==null?void 0:v.videoModel)||$a).modelRef}),$=s.useCallback((i,v)=>{R(i),q(v||null),ut(da,i,v);const p=Xe(i),C=parseInt(p.defaultDuration,10)||8;k(be=>({...be,videoModel:i,videoModelRef:v||null,segmentDuration:C}))},[]),ee=s.useMemo(()=>Xe(f).durationOptions,[f]),K=s.useMemo(()=>{if(c.segmentDuration&&ee.some(p=>parseInt(p.value,10)===c.segmentDuration))return c.segmentDuration;const i=Xe(f);return parseInt(i.defaultDuration,10)||8},[c.segmentDuration,ee,f]),_e=s.useMemo(()=>{const i=c.targetDuration||e.analysis.totalDuration,v=[{label:`${K}秒`,value:String(K)}];return gs(i,v)},[K,c.targetDuration,e.analysis.totalDuration]),ce=s.useMemo(()=>e.characters||e.analysis.characters||[],[e.characters,e.analysis.characters]);s.useEffect(()=>{k(Et(e)),I(e.editedShots||[...e.analysis.shots]),A(e.pendingRewriteTaskId||null),Y(i=>e.pendingRewriteTaskId?i:"")},[e]);const ye=s.useRef();s.useEffect(()=>(clearTimeout(ye.current),ye.current=setTimeout(async()=>{const i=await xe(e.id,{productInfo:c});l(i),r(qe(i,e.id,{...e,productInfo:c,pendingRewriteTaskId:S}))},500),()=>clearTimeout(ye.current)),[c,S]);const Oe=s.useCallback(async i=>{I(i);const v=Ze(e,i),p=await xe(e.id,{...v,productInfo:c});l(p),r(qe(p,e.id,{...e,...v,productInfo:c,pendingRewriteTaskId:S}))},[e,c,S,r,l]),Je=s.useCallback(async i=>{const v=await xe(e.id,i);l(v),r(qe(v,e.id,{...e,...i,productInfo:c,pendingRewriteTaskId:S}))},[e,c,S,r,l]),ue=s.useCallback((i,v,p)=>{const C=g.map(be=>be.id===i?{...be,[v]:p}:be);Oe(C)},[g,Oe]),Pe=s.useCallback((i,v)=>{const C=(e.characters||e.analysis.characters||[]).map(be=>be.id===i?{...be,description:v}:be);Je({characters:C})},[e.characters,e.analysis.characters,Je]),B=s.useCallback(async()=>{var i;if(!((i=c.prompt)!=null&&i.trim())){N("请填写提示词");return}if(!(Q.current||S)){Q.current=!0,j(!0),N(""),Y("AI 改编中 0%"),$e.trackUIInteraction({area:"popular_video_tool",action:"script_rewrite_started",control:"rewrite_script",source:"video_analyzer_script_page",metadata:{shotCount:g.length,promptLength:c.prompt.trim().length,hasModelRef:!!L}});try{const v=ys({recordAnalysis:e.analysis,productInfo:c,videoModel:f,characters:ce}),p=ze.createTask({prompt:`改编脚本:${c.prompt.slice(0,40)}`,model:X,modelRef:L||null,videoAnalyzerAction:"rewrite",videoAnalyzerPrompt:v,videoAnalyzerRecordId:e.id,autoInsertToCanvas:!1},ge.CHAT);A(p.id),Y(`AI 改编中 ${Math.round(p.progress??0)}%`);const C=await xe(e.id,{pendingRewriteTaskId:p.id});l(C),r(qe(C,e.id,{...e,pendingRewriteTaskId:p.id}))}catch(v){Q.current=!1,N(v.message||"改编失败")}finally{j(!1)}}},[e,c,g,f,ce,X,L,r,l,S]);s.useEffect(()=>{var p;if(!S)return;const i=ze.getTask(S);if((i==null?void 0:i.status)==="failed"){Q.current=!1,A(null),Y(""),N(((p=i.error)==null?void 0:p.message)||"改编失败"),xe(e.id,{pendingRewriteTaskId:null}).then(C=>{l(C),r(qe(C,e.id,{...e,pendingRewriteTaskId:null}))});return}if((i==null?void 0:i.status)==="completed"){Ut(i).then(C=>{if(!C){N("改编任务已完成,但未找到可回填的记录");return}l(C.records),r(C.record),k(Et(C.record)),I(C.record.editedShots||C.record.analysis.shots)}).catch(C=>{N(C.message||"改编结果同步失败")}).finally(()=>{Q.current=!1,A(null),Y("")});return}typeof(i==null?void 0:i.progress)=="number"&&Y(`AI 改编中 ${Math.round(i.progress)}%`);const v=ze.observeTaskUpdates().subscribe(C=>{var be;if(C.task.id===S){if(C.task.status==="failed"){Q.current=!1,A(null),Y(""),N(((be=C.task.error)==null?void 0:be.message)||"改编失败"),xe(e.id,{pendingRewriteTaskId:null}).then(W=>{l(W),r(qe(W,e.id,{...e,pendingRewriteTaskId:null}))});return}if(C.task.status==="completed"){Ut(C.task).then(W=>{if(!W){N("改编任务已完成,但未找到可回填的记录");return}l(W.records),r(W.record),k(Et(W.record)),I(W.record.editedShots||W.record.analysis.shots)}).catch(W=>{N(W.message||"改编结果同步失败")}).finally(()=>{Q.current=!1,A(null),Y("")});return}typeof C.task.progress=="number"&&Y(`AI 改编中 ${Math.round(C.task.progress)}%`)}});return()=>v.unsubscribe()},[S,e.id,r,l]);const Be=s.useCallback(async()=>{await Ot("text",$t(g,e.analysis,c)),$e.trackUIInteraction({area:"popular_video_tool",action:"script_inserted_to_canvas",control:"insert_script",source:"video_analyzer_script_page",metadata:{shotCount:g.length}})},[g,c,e]),De=s.useCallback(async i=>{const v=Za(e,i);if(!v)return;le(!1),I(v.editedShots);const p=await xe(e.id,v);l(p),r(qe(p,e.id,{...e,...v}))},[e,r,l]);return s.useEffect(()=>{if(!ie)return;const i=v=>{U.current&&!U.current.contains(v.target)&&le(!1)};return document.addEventListener("mousedown",i),()=>document.removeEventListener("mousedown",i)},[ie]),t.jsxs("div",{className:"va-page",children:[t.jsxs("div",{className:"va-product-form",children:[t.jsx("textarea",{ref:Ye,className:"va-form-textarea va-auto-resize",placeholder:"描述你想要的视频内容,如:拖鞋,生活用品,主打防滑...",rows:Math.max(3,We(c.prompt)),value:c.prompt,onChange:i=>k(v=>({...v,prompt:i.target.value})),onInput:i=>He(i.currentTarget)}),t.jsx(Ya,{value:c.creativeBrief,onChange:i=>k(v=>({...v,creativeBrief:i})),videoStyle:c.videoStyle||"",onVideoStyleChange:i=>k(v=>({...v,videoStyle:i}))}),t.jsx("div",{className:"va-form-row",children:t.jsxs("div",{style:{flex:1},children:[t.jsx("label",{className:"va-edit-label",children:"BGM 情绪"}),t.jsx("textarea",{ref:Ye,className:"va-edit-textarea va-auto-resize",rows:We(c.bgmMood),value:c.bgmMood||"",onChange:i=>k(v=>({...v,bgmMood:i.target.value})),onInput:i=>He(i.currentTarget),placeholder:"如:轻快、治愈、科技感"})]})}),t.jsxs("div",{className:"va-model-select",children:[t.jsx("label",{className:"va-model-label",children:"改编模型"}),t.jsx(Ft,{variant:"form",selectedModel:X,selectedSelectionKey:Ee(X,L),onSelect:me,models:ae,placement:"down",disabled:O,placeholder:"选择文本模型"})]}),t.jsx(qa,{selectedModel:f,selectedSelectionKey:Ee(f,T),onSelectModel:$,models:pe,segmentDuration:K,durationOptions:ee,onSegmentDurationChange:i=>k(v=>({...v,segmentDuration:i})),targetDuration:c.targetDuration??e.analysis.totalDuration,onTargetDurationChange:i=>k(v=>({...v,targetDuration:i||void 0})),disabled:O,placement:"down",overflowText:_e.overflow>0?`实际 ${_e.actualTotal}s(+${parseFloat(_e.overflow.toFixed(2))}s)`:void 0}),t.jsxs("div",{className:"va-version-row",children:[t.jsx("button",{className:"va-analyze-btn",onClick:B,disabled:O||!!S,style:{flex:1},children:O||S?G||"AI 改编中...":"AI 改编脚本"}),e.scriptVersions&&e.scriptVersions.length>0&&t.jsxs("div",{className:"va-version-select",ref:U,children:[t.jsxs("button",{className:"va-version-btn",onClick:()=>le(i=>!i),children:[e.activeVersionId===ea?"原始分析":((de=e.scriptVersions.find(i=>i.id===e.activeVersionId))==null?void 0:de.label)||`v${e.scriptVersions.length}`," ▾"]}),ie&&t.jsxs("div",{className:"va-version-menu",children:[e.scriptVersions.map(i=>t.jsxs("div",{className:`va-version-item ${i.id===e.activeVersionId?"active":""}`,onClick:()=>De(i.id),children:[t.jsx("span",{children:i.label}),i.prompt&&t.jsx("span",{className:"va-version-prompt",children:i.prompt.length>30?i.prompt.slice(0,30)+"...":i.prompt}),t.jsxs("span",{className:"va-version-time",children:[i.shots.length," 镜头 · ",new Date(i.createdAt).toLocaleTimeString()]})]},i.id)),t.jsxs("div",{className:`va-version-item ${e.activeVersionId===ea||!e.activeVersionId?"active":""}`,onClick:()=>De(ea),children:[t.jsx("span",{children:"原始分析"}),t.jsxs("span",{className:"va-version-time",children:[e.analysis.shots.length," 镜头 · ",new Date(e.createdAt).toLocaleTimeString()]})]})]})]})]}),J&&t.jsx("div",{className:"va-error",children:J})]}),t.jsx(bs,{characters:ce,onChange:Pe}),t.jsx("div",{className:"va-shots",children:g.map((i,v)=>t.jsx(va,{shot:i,index:v,compact:!0,children:t.jsxs("div",{className:"va-edit-fields",children:[t.jsx("label",{className:"va-edit-label",children:"画面描述"}),t.jsx("textarea",{ref:Ye,className:"va-edit-textarea va-auto-resize",rows:We(i.description),value:i.description||"",onChange:p=>ue(i.id,"description",p.target.value),onInput:p=>He(p.currentTarget)}),t.jsx("label",{className:"va-edit-label",children:"旁白"}),t.jsx("textarea",{ref:Ye,className:"va-edit-textarea va-auto-resize",rows:We(i.narration),value:i.narration||"",onChange:p=>ue(i.id,"narration",p.target.value),onInput:p=>He(p.currentTarget)}),t.jsx("label",{className:"va-edit-label",children:"角色说话"}),t.jsx("textarea",{ref:Ye,className:"va-edit-textarea va-auto-resize",rows:We(i.dialogue),value:i.dialogue||"",onChange:p=>ue(i.id,"dialogue",p.target.value),onInput:p=>He(p.currentTarget),placeholder:'多角色时按"角色名: 台词"分行'}),t.jsx("label",{className:"va-edit-label",children:"对白角色"}),t.jsx("input",{className:"va-form-input",type:"text",value:i.dialogue_speakers||"",onChange:p=>ue(i.id,"dialogue_speakers",p.target.value),placeholder:"如:主讲人 或 主讲人|顾客"}),t.jsx("label",{className:"va-edit-label",children:"旁白/对白关系"}),t.jsx(ta,{value:i.speech_relation||"",onChange:p=>ue(i.id,"speech_relation",p),options:hr,placeholder:"选择关系"}),t.jsx("label",{className:"va-edit-label",children:"运镜方式"}),t.jsx(ta,{value:i.camera_movement||"",onChange:p=>ue(i.id,"camera_movement",p),options:fr,placeholder:"选择或输入运镜方式"}),t.jsx("label",{className:"va-edit-label",children:"首帧 Prompt"}),t.jsx("textarea",{ref:Ye,className:"va-edit-textarea va-auto-resize",rows:We(i.first_frame_prompt),value:i.first_frame_prompt||"",onChange:p=>ue(i.id,"first_frame_prompt",p.target.value),onInput:p=>He(p.currentTarget)}),t.jsx("label",{className:"va-edit-label",children:"尾帧 Prompt"}),t.jsx("textarea",{ref:Ye,className:"va-edit-textarea va-auto-resize",rows:We(i.last_frame_prompt),value:i.last_frame_prompt||"",onChange:p=>ue(i.id,"last_frame_prompt",p.target.value),onInput:p=>He(p.currentTarget)}),t.jsx("label",{className:"va-edit-label",children:"转场方式"}),t.jsx(ta,{value:i.transition_hint||"",onChange:p=>ue(i.id,"transition_hint",p),options:vr,placeholder:"选择转场方式"})]})},i.id))}),t.jsxs("div",{className:"va-page-actions",children:[t.jsx("button",{onClick:Be,children:"脚本插入画布"}),h&&t.jsx("button",{className:"va-btn-primary",onClick:h,children:"下一步:批量生成 →"})]})]})};function yr(e,r,l){var h,c,k,g,I;return{recordId:e.id,fileNamePrefix:"va",zipBaseName:"video_analyzer_assets",scriptMarkdown:$t(r,e.analysis,e.productInfo),recordMeta:{id:e.id,source:e.source,sourceLabel:e.sourceLabel,prompt:((h=e.productInfo)==null?void 0:h.prompt)||"",aspectRatio:e.analysis.aspect_ratio||"16x9",videoStyle:((c=e.productInfo)==null?void 0:c.videoStyle)||e.analysis.video_style||"",bgmMood:((k=e.productInfo)==null?void 0:k.bgmMood)||e.analysis.bgm_mood||"",creativeBrief:((g=e.productInfo)==null?void 0:g.creativeBrief)||{},creativeBriefSummary:_s((I=e.productInfo)==null?void 0:I.creativeBrief),shotCount:r.length},shots:r,assets:l}}function br(e,r){const l=e.characters||e.analysis.characters||[];return Gs(r,l)}const Dt="video-analyzer:image-model",Rt="video-analyzer:video-model";function Ba(e,r){const l=Object.keys(e),h=Object.keys(r);return l.length!==h.length?!1:l.every(c=>e[c]===r[c])}function Ga(e,r){return r.reduce((l,h)=>{var g;const c=e[h.id];return(h.valueType==="enum"?(g=h.options)==null?void 0:g.some(I=>I.value===c):typeof c=="string"&&c.trim()!=="")&&c?(l[h.id]=c,l):(h.defaultValue&&(l[h.id]=h.defaultValue),l)},{})}function Ha(e,r,l){return{...e,...r!=null?{duration:String(r)}:{},...l?{size:l}:{}}}function Ka(e,r,l){const{duration:h,size:c,...k}=e;return{extraParams:k,duration:h||r,size:c||l}}function _r(e){if(!e||e==="auto")return;const r=e.trim().replace(/[xX]/g,":");return/^\d+:\d+$/.test(r)?r:void 0}const ma=({size:e=14})=>t.jsxs("svg",{viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round",width:e,height:e,"aria-hidden":"true",children:[t.jsx("rect",{x:"3",y:"3",width:"8",height:"8",rx:"1.5"}),t.jsx("circle",{cx:"17",cy:"7",r:"4"}),t.jsx("rect",{x:"3",y:"13",width:"8",height:"8",rx:"1.5"}),t.jsx("rect",{x:"13",y:"13",width:"8",height:"8",rx:"1.5"})]}),Ir=({record:e,onRecordUpdate:r,onRecordsChange:l,onRestart:h})=>{const c=s.useMemo(()=>e.editedShots||e.analysis.shots,[e.editedShots,e.analysis.shots]),k=e.analysis.aspect_ratio||"16x9",g=e.batchId||`va_${e.id}`,{openDialog:I,board:O}=ha(),j=s.useRef(e),S=s.useRef(c),A=s.useRef(!1),G=s.useRef(!1),Y=s.useRef(null),J=s.useRef(null),N=s.useRef(new Set),ie=s.useRef(new Set),[le,U]=s.useState([]),[Q,X]=s.useState(null),he=dt("image"),L=dt("video"),[D,me]=s.useState(()=>we(Dt,"").modelId),[ae,pe]=s.useState(()=>we(Dt,"").modelRef),[f,R]=s.useState(()=>{const a=we(Dt,"");return a.modelId?Da(a.modelId,Ee(a.modelId,a.modelRef)).extraParams:{}}),[T,q]=s.useState(()=>{var a;return((a=e.productInfo)==null?void 0:a.videoModel)||we(Rt,"veo3").modelId}),[$,ee]=s.useState(()=>{var a,n;return((a=e.productInfo)==null?void 0:a.videoModelRef)||we(Rt,((n=e.productInfo)==null?void 0:n.videoModel)||"veo3").modelRef}),[K,_e]=s.useState(()=>{var y,d,M,x,E;const a=we(Rt,((y=e.productInfo)==null?void 0:y.videoModel)||"veo3"),n=((d=e.productInfo)==null?void 0:d.videoModel)||a.modelId,o=((M=e.productInfo)==null?void 0:M.videoModelRef)||a.modelRef,u=Ra(n,Ee(n,o));return Ha(u.extraParams,((x=e.productInfo)==null?void 0:x.segmentDuration)||u.duration,Ma(n,((E=e.productInfo)==null?void 0:E.videoSize)||u.size,k))}),[ce,ye]=s.useState({running:!1,stopping:!1,currentIndex:-1,retryCount:0,completedCount:0,activeCount:0}),[Oe,Je]=s.useState(!1),ue=s.useMemo(()=>Is(D),[D]),Pe=s.useMemo(()=>xs(T,$||T,K),[T,$,K]),B=s.useMemo(()=>Ss(T,$||T,K),[T,$,K]),Be=s.useMemo(()=>B.sizeOptions,[B]),De=s.useMemo(()=>Ka(K,B.defaultDuration,B.defaultSize),[B.defaultDuration,B.defaultSize,K]),de=De.size,i=Number.parseFloat(De.duration)||8,v=s.useMemo(()=>Object.keys(f).length>0?f:void 0,[f]),p=s.useMemo(()=>e.characters||e.analysis.characters||[],[e.characters,e.analysis.characters]),C=s.useMemo(()=>{const a=e.sourceSnapshot,o=((a==null?void 0:a.type)==="prompt"?a.prompt:"")||(e.source==="prompt"?e.sourceLabel:""),u=[e.source!=="prompt"&&e.sourceLabel?`素材来源:${e.sourceLabel}`:"",(a==null?void 0:a.type)==="prompt"&&a.pdfName?`参考 PDF:${a.pdfName}`:""].filter(Boolean).join(`
|
|
3
|
+
`);return{...e.productInfo||{},generationTopic:o,generationContext:u,generationAdvice:e.analysis.suggestion||""}},[e.analysis.suggestion,e.productInfo,e.source,e.sourceLabel,e.sourceSnapshot]),be=s.useMemo(()=>Hs(c),[c]);s.useEffect(()=>{j.current=e},[e]),s.useEffect(()=>{S.current=c},[c]);const W=s.useCallback(async a=>{const n=j.current,o={...n,...a};j.current=o,o.editedShots&&(S.current=o.editedShots);const u=await xe(n.id,a);return l(u),r(o),o},[r,l]),Ne=s.useCallback(async a=>{const n=j.current,o=Ze(n,a);return S.current=a,await W(o),a},[W]),Ue=s.useCallback(async a=>{const n=j.current,o={...Lt(n.productInfo||{prompt:""},n.analysis.totalDuration),...a};return await W({productInfo:o}),o},[W]),Ae=s.useCallback(async(a,n)=>{const o=j.current,y=(o.characters||o.analysis.characters||[]).map(d=>d.id===a?{...d,referenceImageUrl:n}:d);await W({characters:y})},[W]),Bt=s.useCallback(a=>{const n=`va_${e.id}_char${a.id}_ref`,o=ka(a,e.analysis,C);I(At.aiImageGeneration,{initialPrompt:o,batchId:n,initialAspectRatio:"1:1",initialModel:D||void 0,initialModelRef:ae,assetMetadata:{category:aa.CHARACTER,characterName:a.name,characterPrompt:o}})},[C,e.analysis,e.id,I,D,ae]),Qe=s.useCallback((a,n)=>{const o=n||null;me(a),pe(o),R(Da(a,Ee(a,o)).extraParams),ut(Dt,a,n)},[]),Le=s.useCallback((a,n)=>{const o=n||null;q(a),ee(o),ut(Rt,a,n);const u=Ra(a,Ee(a,o));_e(Ha(u.extraParams,u.duration,Ma(a,u.size,k)))},[k]),et=s.useCallback((a,n)=>{R(o=>{const u={...o};return!n||n==="default"?delete u[a]:u[a]=n,u})},[]),Ke=s.useCallback((a,n)=>{_e(o=>{const u={...o};return!n||n==="default"?delete u[a]:u[a]=n,u})},[]);s.useEffect(()=>{const a=Ga(f,ue);Ba(f,a)||R(a)},[ue,f]),s.useEffect(()=>{const a=Ga(K,Pe);Ba(K,a)||_e(a)},[Pe,K]),s.useEffect(()=>{const a=Ka(K,B.defaultDuration,B.defaultSize);Zs({currentModel:T,currentSelectionKey:Ee(T,$),extraParams:a.extraParams,duration:a.duration,size:a.size}),Ue({videoModel:T,videoModelRef:$||null,segmentDuration:Number.parseFloat(a.duration)||8,videoSize:a.size})},[Ue,T,B.defaultDuration,B.defaultSize,$,K]);const Gt=s.useCallback(async()=>{try{const a=j.current,n=S.current;if(!O)throw new Error("画布未就绪");Ea(O);const o=await Ot("text",$t(n,a.analysis,a.productInfo));if(!o.success)throw new Error(o.error||"插入失败,请确认画布已打开");$e.trackUIInteraction({area:"popular_video_tool",action:"script_inserted_to_canvas",control:"insert_script",source:"video_analyzer_generate_page",metadata:{shotCount:n.length}}),Se.success("脚本已插入画布")}catch(a){console.error("[VideoAnalyzer] Failed to insert script to canvas:",a);const n=a instanceof Error?a.message:"脚本插入画布失败";Se.error(n)}},[O]),mt=s.useCallback(async a=>{if(!O)return!1;try{Ea(O);const n=await Ot("video",a);if(!n.success)throw new Error(n.error||"插入失败,请确认画布已打开");return!0}catch(n){return console.error("[VideoAnalyzer] Failed to insert generated video to canvas:",n),!1}},[O]),{isExportingAssets:gt,exportProgress:yt,handleExportAssets:Ht}=Cs({onExport:async a=>{const n=j.current,o=S.current;return await qs({...yr(n,o,be),onProgress:a})},onExportSuccess:a=>{Se.success(`素材导出完成,共 ${a.assetCount} 个文件`)},onExportError:a=>{console.error("[VideoAnalyzer] Failed to export assets:",a),Se.error("素材导出失败")}}),tt=s.useMemo(()=>le.map(a=>a.url).filter(Boolean),[le]),bt=s.useCallback(async()=>{e.batchId||await W({batchId:g})},[e.batchId,g,W]),{tasks:_t}=Xa(),Fe=s.useRef(new Set),at=s.useRef(new Set),It=s.useCallback(async(a,n,o)=>{let u=[...n],y=!1;for(const{shotId:d,videoUrl:M}of o){const x=`auto_${d}`;if(!at.current.has(x)){at.current.add(x);try{const E=u.findIndex(b=>b.id===d);if(E===-1)continue;const z=u[E+1];if(!z)continue;const Z=await Ks(M,z.id,"first","last");if(!Z||z.generated_first_frame_url===Z)continue;u=u.map((b,P)=>P===E+1?{...b,generated_first_frame_url:Z}:b),y=!0}finally{at.current.delete(x)}}}if(y){const d=e;xe(a,Ze(d,u)).then(M=>{l(M),r({...d,editedShots:u})})}},[e,r,l]);s.useEffect(()=>{var x,E,z,Z;const a=`va_${e.id}_shot`,n=`va_${e.id}_char`;let o=!1;const u=e,y=j.current.generatedAssetsResetAt||u.generatedAssetsResetAt;let d=u.editedShots||u.analysis.shots;const M=[];for(const b of _t){if(b.status!==Ve.COMPLETED||Fe.current.has(b.id))continue;const P=(x=b.params)==null?void 0:x.batchId;if(!P)continue;if(P.startsWith(n)){if(y&&b.createdAt<=y){Fe.current.add(b.id);continue}const re=(E=b.result)==null?void 0:E.url;if(Fe.current.add(b.id),re){const ke=P.slice(n.length),it=ke.lastIndexOf("_ref");if(it!==-1){const Pt=ke.slice(0,it),os=(j.current.characters||j.current.analysis.characters||[]).map(Jt=>Jt.id===Pt?{...Jt,referenceImageUrl:re}:Jt);W({characters:os})}}continue}if(!P.startsWith(a))continue;if(y&&b.createdAt<=y){Fe.current.add(b.id);continue}if(e.storyboardGeneratedAt&&b.createdAt<e.storyboardGeneratedAt){Fe.current.add(b.id);continue}const H=(z=b.result)==null?void 0:z.url;if(!H)continue;const te=P.slice(a.length),ne=te.lastIndexOf("_");if(ne===-1)continue;const oe=te.slice(0,ne),V=te.slice(ne+1);if(V!=="first"&&V!=="last"&&V!=="video")continue;const Te=V==="first"?"generated_first_frame_url":V==="last"?"generated_last_frame_url":"generated_video_url",Ce=d.find(re=>re.id===oe),Ie=V==="video"&&ie.current.has(b.id),ve=(Z=Ce==null?void 0:Ce.suppressed_generated_urls)==null?void 0:Z[V];if(ve&&ve===H){Ie&&ie.current.delete(b.id),Fe.current.add(b.id);continue}if(!Ce||Ce[Te]===H){Ie&&ie.current.delete(b.id),Fe.current.add(b.id);continue}d=d.map(re=>re.id===oe?{...re,[Te]:H,suppressed_generated_urls:re.suppressed_generated_urls?{...re.suppressed_generated_urls,[V]:void 0}:void 0}:re),Fe.current.add(b.id),o=!0,V==="video"&&(Ie?ie.current.delete(b.id):M.push({shotId:oe,videoUrl:H}))}o&&xe(u.id,Ze(u,d)).then(b=>{l(b),r({...u,editedShots:d})}),M.length>0&&!G.current&&It(u.id,d,M)},[_t,It,e,r,l,W]);const[je,st]=s.useState(null),pt=s.useCallback((a,n)=>{st({shotId:a,assetType:n})},[]),Kt=s.useCallback(async a=>{if(!je)return;st(null);const{shotId:n,assetType:o}=je,u=o==="first"?"generated_first_frame_url":o==="last"?"generated_last_frame_url":"generated_video_url",d=(e.editedShots||e.analysis.shots).map(x=>x.id===n?{...x,[u]:a.url}:x),M=await xe(e.id,Ze(e,d));l(M),r({...e,editedShots:d})},[je,e,l,r]),[m,_]=s.useState(null),w=s.useRef(null),F=s.useCallback(()=>{w.current!==null&&(window.clearTimeout(w.current),w.current=null)},[]),se=s.useCallback(()=>{F(),_(null)},[F]),fe=s.useCallback(()=>{F(),w.current=window.setTimeout(()=>{w.current=null,_(null)},120)},[F]),Me=s.useCallback((a,n,o)=>{F();const u=o.currentTarget.getBoundingClientRect();_({url:a,type:n,x:u.left+u.width/2,y:u.top-8})},[F]),Re=s.useCallback(()=>{fe()},[fe]),ts=s.useCallback(()=>{F()},[F]),as=s.useCallback(()=>{se()},[se]);s.useEffect(()=>()=>{F()},[F]);const ft=s.useMemo(()=>{var n;const a=(n=Be.find(o=>o.value===de))==null?void 0:n.aspectRatio;if(a)return a;if(de!=null&&de.includes("x")){const[o,u]=de.split("x").map(Number);if(o&&u){const y=(M,x)=>x===0?M:y(x,M%x),d=y(o,u);return`${o/d}:${u/d}`}}return k.replace("x",":")},[k,Be,de]),Wt=ft,rt=_r(f.size),xt=f.size||Wt;s.useEffect(()=>{D&&Xs({currentModel:D,currentSelectionKey:Ee(D,ae),extraParams:f,aspectRatio:rt||Wt})},[Wt,D,ae,f,rt]);const Ge=s.useCallback(a=>a.map(n=>({url:n.url,name:n.name})),[]),St=s.useCallback((a=[],n=[])=>a.length===n.length&&a.every((o,u)=>{var y,d;return o.url===((y=n[u])==null?void 0:y.url)&&o.name===((d=n[u])==null?void 0:d.name)}),[]),Ct=s.useCallback((...a)=>{const n=new Set,o=[];return a.forEach(u=>{u==null||u.forEach(y=>{var M;const d=(M=y.url)==null?void 0:M.trim();!d||n.has(d)||(n.add(d),o.push({url:d,name:y.name||"参考图"}))})}),o.length>0?o:void 0},[]),wt=s.useCallback(a=>{var o;if(!((o=a.character_ids)!=null&&o.length))return[];const n=new Set;return a.character_ids.reduce((u,y)=>{var x;const d=p.find(E=>E.id===y),M=(x=d==null?void 0:d.referenceImageUrl)==null?void 0:x.trim();return!M||n.has(M)||(n.add(M),u.push({url:M,name:d!=null&&d.name?`角色:${d.name}`:"角色参考图"})),u},[])},[p]),nt=s.useCallback(async(a,n,o)=>{let u=!1;const y=Ge(o.images),d=S.current.map(M=>{if(M.id!==a)return M;if(n==="first"){const z=M.first_frame_draft,Z={prompt:o.prompt,images:y,aspectRatio:o.aspectRatio};return(z==null?void 0:z.prompt)===Z.prompt&&(z==null?void 0:z.aspectRatio)===Z.aspectRatio&&St(z==null?void 0:z.images,Z.images)?M:(u=!0,{...M,first_frame_draft:Z})}if(n==="last"){const z=M.last_frame_draft,Z={prompt:o.prompt,images:y,aspectRatio:o.aspectRatio};return(z==null?void 0:z.prompt)===Z.prompt&&(z==null?void 0:z.aspectRatio)===Z.aspectRatio&&St(z==null?void 0:z.images,Z.images)?M:(u=!0,{...M,last_frame_draft:Z})}const x=M.video_draft,E={prompt:o.prompt,images:y,duration:o.duration,size:o.size};return(x==null?void 0:x.prompt)===E.prompt&&(x==null?void 0:x.duration)===E.duration&&(x==null?void 0:x.size)===E.size&&St(x==null?void 0:x.images,E.images)?M:(u=!0,{...M,video_draft:E})});u&&await Ne(d)},[Ne,St,Ge]),Yt=s.useCallback(a=>{const n=a.first_frame_prompt||a.description||"";if(!n)return;$e.trackUIInteraction({area:"popular_video_tool",action:"shot_first_frame_generation_opened",control:"generate_first_frame",source:"video_analyzer_generate_page",metadata:{shotId:a.id,hasDraft:!!a.first_frame_draft}});const o=sa(n,e.analysis,C,{shot:a,characters:p}),u=a.first_frame_draft,y=u?Ge(u.images||[]):void 0,d=!u&&a.generated_first_frame_url?[{url:a.generated_first_frame_url,name:"首帧"}]:void 0,M=wt(a),x=`va_${e.id}_shot${a.id}_first`;I(At.aiImageGeneration,{initialPrompt:(u==null?void 0:u.prompt)||o,batchId:x,initialAspectRatio:(u==null?void 0:u.aspectRatio)??rt,initialModel:D||void 0,initialModelRef:ae,initialImages:Ct(y,d,M),onDraftChange:E=>nt(a.id,"first",E)})},[e,C,p,I,D,ae,Ct,wt,nt,rt,Ge]),ht=s.useCallback((a,n)=>{if(a.generated_last_frame_url)return a.generated_last_frame_url;const o=c[n+1];return o==null?void 0:o.generated_first_frame_url},[c]),jt=s.useCallback((a,n)=>{const o=a.last_frame_prompt||"";if(!o)return;$e.trackUIInteraction({area:"popular_video_tool",action:"shot_last_frame_generation_opened",control:"generate_last_frame",source:"video_analyzer_generate_page",metadata:{shotId:a.id,shotIndex:n,hasDraft:!!a.last_frame_draft}});const u=sa(o,e.analysis,C,{shot:a,characters:p}),y=a.last_frame_draft,d=y?Ge(y.images||[]):void 0,M=`va_${e.id}_shot${a.id}_last`,x=ht(a,n),E=!y&&x?[{url:x,name:"尾帧"}]:void 0,z=wt(a);I(At.aiImageGeneration,{initialPrompt:(y==null?void 0:y.prompt)||u,batchId:M,initialAspectRatio:(y==null?void 0:y.aspectRatio)??rt,initialModel:D||void 0,initialModelRef:ae,initialImages:Ct(d,E,z),onDraftChange:Z=>nt(a.id,"last",Z)})},[e,C,p,I,ht,D,ae,Ct,wt,nt,rt,Ge]),qt=s.useCallback((a,n)=>{$e.trackUIInteraction({area:"popular_video_tool",action:"shot_video_generation_opened",control:"generate_shot_video",source:"video_analyzer_generate_page",metadata:{shotId:a.id,shotIndex:n,hasDraft:!!a.video_draft}});const o=a.video_draft,u=`va_${e.id}_shot${a.id}_video`,y=[];a.generated_first_frame_url&&y.push({url:a.generated_first_frame_url,name:"首帧"});const d=ht(a,n);d&&y.push({url:d,name:"尾帧"});const M=Ge((o==null?void 0:o.images)||[]),x=M.length>0?M:y.length>0?y:void 0,E=Na(a,e.analysis,C,{referenceImageDescriptions:ws(x)});if(!E)return;const z=String((o==null?void 0:o.duration)??i),Z=B.durationOptions.some(P=>P.value===z)?(o==null?void 0:o.duration)??i:void 0,b=B.sizeOptions.some(P=>P.value===((o==null?void 0:o.size)??de))?(o==null?void 0:o.size)??de:void 0;I(At.aiVideoGeneration,{initialPrompt:(o==null?void 0:o.prompt)||E,initialImages:x,initialDuration:Z,initialSize:b,initialModel:T||void 0,initialModelRef:$,batchId:u,onDraftChange:P=>nt(a.id,"video",P)})},[e.id,i,de,T,B,$,I,ht,e.analysis,C,nt,Ge]),Zt=s.useCallback((a,n)=>{const o=n==="first"?"generated_first_frame_url":n==="last"?"generated_last_frame_url":"generated_video_url",y=(e.editedShots||e.analysis.shots).map(d=>d.id===a?{...d,[o]:void 0,suppressed_generated_urls:d[o]?{...d.suppressed_generated_urls||{},[n]:d[o]}:d.suppressed_generated_urls}:d);xe(e.id,Ze(e,y)).then(d=>{l(d),r({...e,editedShots:y})})},[e,r,l]),Mt=s.useCallback(async(a,n,o)=>{var b,P,H;const u=o==="first"?a.first_frame_prompt||a.description||"":a.last_frame_prompt||"";if(!u)return null;const y=sa(u,e.analysis,C,{shot:a,characters:n}),d=[...tt];if(a.character_ids&&a.character_ids.length>0)for(const te of a.character_ids){const ne=n.find(oe=>oe.id===te);ne!=null&&ne.referenceImageUrl&&!d.includes(ne.referenceImageUrl)&&d.push(ne.referenceImageUrl)}const M=`va_${e.id}_shot${a.id}_${o}`,x=await na.executeTool({name:"generate_image",arguments:{prompt:y.trim(),count:1,size:xt,referenceImages:d.length>0?d:void 0,batchId:M,...D?{model:D,modelRef:ae}:{},...v?{params:v}:{}}},{mode:"queue"}),E=x.taskId||((b=x.data)==null?void 0:b.taskId);if(!x.success||!E)return null;N.current.add(E),J.current=E,ye(te=>({...te,activeCount:N.current.size}));let z;try{z=await oa(E,(P=Y.current)==null?void 0:P.signal)}finally{N.current.delete(E),J.current===E&&(J.current=null),ye(te=>({...te,activeCount:N.current.size}))}if(!z.success)return null;const Z=z.task||ze.getTask(E);return((H=Z==null?void 0:Z.result)==null?void 0:H.url)||null},[e,C,v,xt,D,ae,tt]),ga=s.useCallback((a,n)=>Mt(a,n,"first"),[Mt]),ya=s.useCallback((a,n)=>Mt(a,n,"last"),[Mt]),ba=s.useCallback(async(a,n)=>{const o=S.current,u=o.find(d=>d.id===a);if(!u||u.generated_first_frame_url===n)return o;const y=o.map(d=>d.id===a?{...d,generated_first_frame_url:n}:d);return await Ne(y),y},[Ne]),_a=s.useCallback(async(a,n)=>{const o=S.current,u=o.find(d=>d.id===a);if(!u||u.generated_last_frame_url===n)return o;const y=o.map(d=>d.id===a?{...d,generated_last_frame_url:n}:d);return await Ne(y),y},[Ne]),ot=s.useCallback(a=>S.current.find(n=>n.id===a),[]),Ia=s.useCallback(async(a,n)=>{const o=S.current.find(y=>y.id===a);if(!o||o.generated_video_url===n)return S.current;const u=S.current.map(y=>y.id===a?{...y,generated_video_url:n}:y);return await Ne(u),u},[Ne]),xa=s.useCallback(async(a,n)=>{var b;const o=a.generated_first_frame_url,u=n||a.generated_last_frame_url,{referenceImages:y,referenceImageDescriptions:d}=Ws({model:T,firstFrameUrl:o,lastFrameUrl:u,extraReferenceUrls:tt}),M=Na(a,e.analysis,C,{referenceImageDescriptions:d});if(!M)return null;const x=`va_${e.id}_shot${a.id}_video`,E={...De.extraParams,...B.provider==="seedance"?{aspect_ratio:ft}:{}},z=await na.executeTool({name:"generate_video",arguments:{prompt:M,size:De.size,seconds:De.duration,count:1,batchId:x,model:T,modelRef:$,referenceImages:y,params:Object.keys(E).length>0?E:void 0}},{mode:"queue"}),Z=z.taskId||((b=z.data)==null?void 0:b.taskId);if(!z.success||!Z)throw new Error(z.error||"创建视频任务失败");return Z},[e.analysis,e.id,C,tt,De,T,B.provider,$,ft]),ss=s.useCallback(()=>{var a;A.current=!0,ye(n=>n.running?{...n,stopping:!0}:n),J.current&&ze.cancelTask(J.current);for(const n of N.current)ze.cancelTask(n);(a=Y.current)==null||a.abort()},[]),kt=s.useCallback(()=>{ye(a=>({...a,activeCount:N.current.size}))},[]),Xt=s.useCallback((a,n)=>{ye(o=>({...o,currentIndex:a,retryCount:n,activeCount:N.current.size}))},[]);s.useEffect(()=>()=>{var a;A.current=!0,(a=Y.current)==null||a.abort()},[]);const rs=s.useCallback(async()=>{var n,o;if(G.current||ce.running)return;G.current=!0,$e.trackUIInteraction({area:"popular_video_tool",action:"batch_video_generation_started",control:"generate_all_videos",source:"video_analyzer_generate_page",metadata:{shotCount:S.current.length,insertToCanvasRequested:Oe,hasBoard:!!O}});let a=Oe;a&&!O&&(Se.warning("画布未就绪,本次将只生成不插入画布"),a=!1),await bt(),A.current=!1,Y.current=new AbortController,J.current=null,ye({running:!0,stopping:!1,currentIndex:-1,retryCount:0,completedCount:0,activeCount:0});try{const y=(j.current.characters||j.current.analysis.characters||[]).filter(b=>!b.referenceImageUrl);if(y.length>0&&!A.current){const P=(await Promise.all(y.map(async H=>{var oe,V,Te;if(A.current)return null;const te=`va_${e.id}_char${H.id}_ref`,ne=ka(H,j.current.analysis,C);try{const Ce=await na.executeTool({name:"generate_image",arguments:{prompt:ne,count:1,size:xt,batchId:te,assetMetadata:{category:aa.CHARACTER,characterName:H.name,characterPrompt:ne},...D?{model:D,modelRef:ae}:{},...v?{params:v}:{}}},{mode:"queue"}),Ie=Ce.taskId||((oe=Ce.data)==null?void 0:oe.taskId);if(!Ie)return null;J.current=Ie,N.current.add(Ie),kt();let ve;try{if(A.current)return ze.cancelTask(Ie),null;ve=await oa(Ie,(V=Y.current)==null?void 0:V.signal)}finally{N.current.delete(Ie),J.current===Ie&&(J.current=null),kt()}if(!ve.success)return null;const re=ve.task||ze.getTask(Ie),ke=(Te=re==null?void 0:re.result)==null?void 0:Te.url;return ke?{charId:H.id,url:ke}:null}catch(Ce){return A.current||console.error("[VideoAnalyzer] Character reference generation failed:",{characterId:H.id,error:Ce}),null}}))).filter(H=>!!(H!=null&&H.url));if(P.length>0){const H=new Map(P.map(oe=>[oe.charId,oe.url])),ne=(j.current.characters||j.current.analysis.characters||[]).map(oe=>{const V=H.get(oe.id);return V?{...oe,referenceImageUrl:V}:oe});await W({characters:ne})}}const d=S.current,M=()=>{ye(b=>({...b,completedCount:Math.min(b.completedCount+1,d.length),activeCount:N.current.size}))},x=new Map,E=b=>{var ne;const P=ot(b.id)||b;if(P.generated_first_frame_url)return Promise.resolve(P.generated_first_frame_url);const H=(ne=x.get(b.id))==null?void 0:ne.first;if(H)return H;const te=(async()=>{const oe=j.current.characters||j.current.analysis.characters||[],V=await ga(P,oe);return V&&!A.current&&await ba(P.id,V),V})();return x.set(b.id,{...x.get(b.id)||{},first:te}),te},z=b=>{var ne,oe;const P=ot(b.id)||b;if(P.generated_last_frame_url)return Promise.resolve(P.generated_last_frame_url);if(!((ne=P.last_frame_prompt)!=null&&ne.trim()))return Promise.resolve(null);const H=(oe=x.get(b.id))==null?void 0:oe.last;if(H)return H;const te=(async()=>{const V=j.current.characters||j.current.analysis.characters||[],Te=await ya(P,V);return Te&&!A.current&&await _a(P.id,Te),Te})();return x.set(b.id,{...x.get(b.id)||{},last:te}),te};for(let b=0;b<d.length;b+=1){const P=d[b],H=d[b+1];E(P).catch(te=>(A.current||console.error("[VideoAnalyzer] Batch first frame generation failed:",{shotId:P.id,error:te}),null)),H&&!P.generated_last_frame_url&&!((n=P.last_frame_prompt)!=null&&n.trim())?E(H).catch(te=>(A.current||console.error("[VideoAnalyzer] Batch next first frame generation failed:",{shotId:H.id,error:te}),null)):(o=P.last_frame_prompt)!=null&&o.trim()&&z(P).catch(te=>(A.current||console.error("[VideoAnalyzer] Batch last frame generation failed:",{shotId:P.id,error:te}),null))}const Z=async(b,P)=>{var H,te,ne,oe;try{if(A.current)return;ye(re=>({...re,currentIndex:P}));let V=ot(b.id)||b;if(V.generated_video_url){a&&await mt(V.generated_video_url);return}const Te=await E(V);if(Te&&(V={...V,generated_first_frame_url:Te}),A.current||(V=ot(b.id)||V,!V.generated_first_frame_url))return;let Ce=V.generated_last_frame_url;if(!Ce)if((H=V.last_frame_prompt)!=null&&H.trim())Ce=await z(V)||void 0;else{const re=d[P+1];Ce=re&&await E(re)||void 0}if(A.current)return;let Ie=0,ve=null;for(;!A.current&&(ve||(ve=await xa(ot(V.id)||V,Ce)),!!ve);){ie.current.add(ve),J.current=ve,N.current.add(ve),Xt(P,Ie);let re;try{re=await oa(ve,(te=Y.current)==null?void 0:te.signal)}finally{N.current.delete(ve),J.current===ve&&(J.current=null),kt()}if(A.current)break;const ke=re.task||ze.getTask(ve),it=(ne=ke==null?void 0:ke.result)==null?void 0:ne.url;if(re.success&&ke&&it){await Ia(V.id,it),a&&await mt(it);break}if((ke==null?void 0:ke.status)===Ve.FAILED){const Pt=Ys(ke,re.error);if(Pt){A.current=!0;for(const Sa of N.current)ze.cancelTask(Sa);N.current.clear(),J.current=null,(oe=Y.current)==null||oe.abort(),Se.error(`视频生成失败且不可重试,已停止:${Pt}`);break}Ie+=1,Xt(P,Ie),ze.retryTask(ve);continue}ve=null}}catch(V){A.current||console.error("[VideoAnalyzer] Batch shot pipeline failed:",{shotId:b.id,error:V})}finally{M()}};await Promise.all(d.map((b,P)=>Z(b,P)))}finally{G.current=!1,J.current=null,N.current.clear(),Y.current=null,ye({running:!1,stopping:!1,currentIndex:-1,retryCount:0,completedCount:0,activeCount:0})}},[ce.running,xa,bt,ga,ya,W,ot,e.id,e.analysis,C,D,v,xt,ae,mt,Oe,kt,Xt,ba,_a,Ia,O]),ns=s.useCallback(async()=>{const a=br(j.current,S.current);await W({...Ze(j.current,a.shots),characters:a.characters,generatedAssetsResetAt:Date.now()})},[W]),Nt=s.useMemo(()=>{const[a,n]=ft.split(":").map(Number);if(!a||!n)return{};const o=Math.round(54*a/n);return{width:Math.max(o,48),height:o<48?Math.round(48*n/a):54}},[ft]);return t.jsxs("div",{className:"va-page",children:[t.jsxs("div",{className:"va-batch-config",children:[t.jsx("div",{className:"va-batch-config-title",children:"批量生成配置"}),t.jsx(Js,{images:le,onImagesChange:U,multiple:!0,label:"参考图 (可选)"}),p.length>0&&t.jsxs("div",{className:"va-characters",children:[t.jsx("div",{className:"va-characters-title",children:"角色"}),p.map(a=>t.jsxs("div",{className:"va-character-item",children:[t.jsxs("div",{className:"va-character-info",children:[t.jsx("span",{className:"va-character-name",children:a.name}),t.jsx("span",{className:"va-character-desc",children:a.description})]}),t.jsxs("div",{className:"va-character-ref",children:[a.referenceImageUrl?t.jsxs("div",{className:"va-character-ref-thumb",children:[t.jsx(lt,{src:a.referenceImageUrl,alt:a.name,showSkeleton:!1,eager:!0}),t.jsx("button",{className:"va-shot-frame-delete",onClick:()=>void Ae(a.id,void 0),children:"×"})]}):t.jsx("span",{className:"va-character-ref-empty",children:"未设置"}),t.jsx("button",{onClick:()=>Bt(a),children:"生成"}),t.jsx("button",{onClick:()=>X(a.id),children:"选主体"})]})]},a.id))]}),t.jsxs("div",{className:"va-product-form",children:[t.jsxs("div",{className:"va-model-select",children:[t.jsx("label",{className:"va-model-label",children:"图片模型"}),t.jsx(Ft,{variant:"form",selectedModel:D,selectedSelectionKey:Ee(D,ae),onSelect:Qe,models:he,placement:"down",placeholder:"选择图片模型"}),ue.length>0&&t.jsx(Fa,{selectedParams:f,onParamChange:et,compatibleParams:ue,modelId:D,placement:"down"})]}),t.jsxs("div",{className:"va-model-select",children:[t.jsx("label",{className:"va-model-label",children:"视频模型"}),t.jsx(Ft,{variant:"form",selectedModel:T,selectedSelectionKey:Ee(T,$),onSelect:Le,models:L,placement:"down",placeholder:"选择视频模型"}),Pe.length>0&&t.jsx(Fa,{selectedParams:K,onParamChange:Ke,compatibleParams:Pe,modelId:T,placement:"down"})]})]}),ce.running&&t.jsxs("div",{className:"va-batch-config-title",children:["正在并行生成 ",ce.completedCount,"/",c.length," 段",ce.activeCount>0?`,运行中 ${ce.activeCount} 个任务`:"",ce.retryCount>0?`,已重试 ${ce.retryCount} 次`:""]}),t.jsxs("div",{className:"va-page-actions",children:[h&&t.jsx("button",{onClick:h,children:"重新分析"}),t.jsx("button",{onClick:ns,children:"重置生成"}),t.jsxs("label",{className:"va-inline-checkbox",children:[t.jsx("input",{type:"checkbox",checked:Oe,onChange:a=>Je(a.target.checked)}),"生成后插入画布"]}),t.jsx("button",{onClick:rs,disabled:ce.running,children:"全部→生成视频"}),ce.running&&t.jsx("button",{onClick:ss,children:ce.stopping?"停止中…":"停止全部生成"})]})]}),t.jsx("div",{className:"va-shots",children:c.map((a,n)=>t.jsx(va,{shot:a,index:n,actions:t.jsxs(t.Fragment,{children:[a.generated_first_frame_url?t.jsxs("div",{className:"va-shot-frame-thumb",style:Nt,onMouseEnter:o=>Me(a.generated_first_frame_url,"image",o),onMouseLeave:Re,children:[t.jsx(lt,{src:a.generated_first_frame_url,alt:"首帧",showSkeleton:!1,eager:!0,onClick:()=>Yt(a)}),t.jsx("button",{className:"va-shot-frame-delete",onClick:()=>Zt(a.id,"first"),children:"×"}),t.jsx("button",{className:"va-shot-frame-regen",onClick:()=>Yt(a),children:"↻"})]}):a.first_frame_prompt||a.description?t.jsxs("span",{className:"va-shot-frame-btn-group",children:[t.jsx("button",{onClick:()=>Yt(a),children:"生成首帧"}),t.jsx("button",{className:"va-shot-frame-library-btn",onClick:()=>pt(a.id,"first"),children:t.jsx(ct,{content:"从素材库选择",showArrow:!1,children:t.jsx("span",{children:t.jsx(ma,{})})})})]}):null,(()=>{var y;const o=a.generated_last_frame_url||ht(a,n),u=!a.generated_last_frame_url&&o;return a.generated_last_frame_url?t.jsxs("div",{className:"va-shot-frame-thumb",style:Nt,onMouseEnter:d=>Me(a.generated_last_frame_url,"image",d),onMouseLeave:Re,children:[t.jsx(lt,{src:a.generated_last_frame_url,alt:"尾帧",showSkeleton:!1,eager:!0,onClick:()=>jt(a,n)}),t.jsx("button",{className:"va-shot-frame-delete",onClick:()=>Zt(a.id,"last"),children:"×"}),t.jsx("button",{className:"va-shot-frame-regen",onClick:()=>jt(a,n),children:"↻"})]}):u?t.jsxs("div",{className:"va-shot-frame-thumb va-shot-frame-thumb--borrowed",style:Nt,onMouseEnter:d=>Me(o,"image",d),onMouseLeave:Re,children:[t.jsx(lt,{src:o,alt:"尾帧(下一镜头首帧)",showSkeleton:!1,eager:!0,onClick:()=>jt(a,n)}),t.jsx("span",{className:"va-shot-frame-label",children:"下一镜头首帧"})]}):(y=a.last_frame_prompt)!=null&&y.trim()?t.jsxs("span",{className:"va-shot-frame-btn-group",children:[t.jsx("button",{onClick:()=>jt(a,n),children:"生成尾帧"}),t.jsx("button",{className:"va-shot-frame-library-btn",onClick:()=>pt(a.id,"last"),children:t.jsx(ct,{content:"从素材库选择",showArrow:!1,children:t.jsx("span",{children:t.jsx(ma,{})})})})]}):null})(),a.generated_video_url?t.jsxs("div",{className:"va-shot-frame-thumb",style:Nt,onMouseEnter:o=>Me(a.generated_video_url,"video",o),onMouseLeave:Re,children:[t.jsx(Ja,{src:a.generated_video_url,alt:"生成视频缩略图",className:"va-shot-frame-media",thumbnailSize:"small",onClick:()=>qt(a,n),videoProps:{muted:!0,preload:"metadata"}}),t.jsx("button",{className:"va-shot-frame-delete",onClick:()=>Zt(a.id,"video"),children:"×"}),t.jsx("button",{className:"va-shot-frame-regen",onClick:()=>qt(a,n),children:"↻"})]}):a.description||a.narration||a.dialogue||a.camera_movement||a.first_frame_prompt||a.last_frame_prompt?t.jsxs("span",{className:"va-shot-frame-btn-group",children:[t.jsx("button",{onClick:()=>qt(a,n),children:"生成视频"}),t.jsx("button",{className:"va-shot-frame-library-btn",onClick:()=>pt(a.id,"video"),children:t.jsx(ct,{content:"从素材库插入视频",showArrow:!1,children:t.jsx("span",{children:t.jsx(ma,{})})})})]}):null]})},a.id))}),t.jsxs("div",{className:"va-page-actions mv-generate-footer-actions",children:[t.jsx("button",{onClick:()=>void Gt(),disabled:c.length===0||!O,children:"脚本插入画布"}),t.jsx("button",{onClick:()=>void Ht(),disabled:gt||c.length===0,children:gt?`素材下载 ${yt}%`:"素材下载 ZIP"})]}),t.jsx("div",{className:"mv-generate-footer-hint",children:"若有素材未打包成功,解压后在 ZIP 根目录运行 `sh 00.补全下载.sh` 即可按 manifest 补全下载。"}),t.jsx(Va,{isOpen:!!je,onClose:()=>st(null),mode:Pa.SELECT,filterType:(je==null?void 0:je.assetType)==="video"?ra.VIDEO:ra.IMAGE,onSelect:Kt,selectButtonText:(je==null?void 0:je.assetType)==="video"?"使用此视频":"使用此图片"}),t.jsx(Va,{isOpen:!!Q,onClose:()=>X(null),mode:Pa.SELECT,filterType:ra.IMAGE,filterCategory:aa.CHARACTER,onSelect:a=>{if(Q){const n=j.current,o=(n.characters||n.analysis.characters||[]).find(u=>u.id===Q);Ae(Q,a.url),o&&Ms(a,{name:o.name,prompt:o.description}).catch(u=>{console.warn("[VideoAnalyzer] Failed to mark asset as character:",u)})}X(null)},selectButtonText:"使用此主体"}),m&&js.createPortal(t.jsx("div",{className:"mv-hover-preview",style:{left:`${m.x}px`,top:`${m.y}px`},onMouseEnter:ts,onMouseLeave:as,children:m.type==="image"?t.jsx(lt,{src:m.url,alt:"Preview",showSkeleton:!1,eager:!0}):t.jsx("video",{src:m.url,controls:!0,muted:!0,preload:"metadata"})}),document.body)]})};function es(e){var r;return e.result?(r=e.result.urls)!=null&&r.length?e.result.urls.filter(Boolean):e.result.url?[e.result.url]:[]:[]}function xr(e){var r,l;return e.result?e.type===ge.VIDEO?((r=e.result.thumbnailUrls)==null?void 0:r[0])||e.result.thumbnailUrl||null:((l=e.result.thumbnailUrls)==null?void 0:l[0])||e.result.url||null:null}function Sr(e){switch(e){case Ve.COMPLETED:return"已完成";case Ve.PROCESSING:return"进行中";case Ve.PENDING:return"等待中";case Ve.FAILED:return"失败";default:return""}}function Cr(e){switch(e){case Ve.COMPLETED:return"completed";case Ve.PROCESSING:return"processing";case Ve.PENDING:return"pending";case Ve.FAILED:return"failed";default:return"pending"}}function wr(e){const r=new Date(e);return`${r.getMonth()+1}/${r.getDate()} ${String(r.getHours()).padStart(2,"0")}:${String(r.getMinutes()).padStart(2,"0")}`}function jr(e){const r=String(e.params.prompt||"");return r.length>40?`${r.slice(0,40)}…`:r}function Mr(e){return e==="youtube"?"🔗":e==="prompt"?"✦":"📁"}const kr=({record:e,related:r,isExpanded:l,onSelect:h,onToggleStar:c,onDelete:k,onToggleExpand:g,onInsertTask:I,onPreviewOpen:O,onSelectScript:j})=>{const S=!!(r&&r.rewrite.length+r.image.length+r.video.length>0),A=r?[...r.image,...r.video]:[];return t.jsxs("div",{className:"va-history-item",onClick:()=>h(e),children:[t.jsxs("div",{className:"va-history-header",children:[t.jsxs("span",{className:"va-history-source",children:[Mr(e.source)," ",e.sourceLabel]}),t.jsx("button",{className:`va-star-btn ${e.starred?"starred":""}`,onClick:G=>c(G,e),children:e.starred?"★":"☆"})]}),t.jsxs("div",{className:"va-history-meta",children:[S&&t.jsxs("button",{className:`va-history-expand-btn ${l?"expanded":""}`,onClick:G=>g(G,e.id),children:[t.jsx(ks,{size:12}),t.jsx("span",{children:l?"收起":"关联任务"})]}),t.jsx("span",{children:new Date(e.createdAt).toLocaleString()}),t.jsxs("span",{children:[e.analysis.shotCount," 镜头"]}),t.jsx("span",{children:e.model}),t.jsx("button",{className:"va-history-delete",onClick:G=>k(G,e.id),children:"删除"})]}),e.analysis.video_style&&t.jsx("div",{className:"va-history-style",children:e.analysis.video_style}),l&&r&&t.jsx(Nr,{related:r,record:e,previewTasks:A,onInsertTask:I,onPreviewOpen:O,onSelectScript:j})]})},Nr=({related:e,record:r,previewTasks:l,onInsertTask:h,onPreviewOpen:c,onSelectScript:k})=>t.jsxs("div",{className:"va-history-related",onClick:g=>g.stopPropagation(),children:[e.rewrite.length>0&&t.jsxs("div",{children:[t.jsxs("div",{className:"va-history-related-group-title",children:["脚本改编 (",e.rewrite.length,")"]}),e.rewrite.map(g=>t.jsx(pa,{task:g,onClick:I=>k==null?void 0:k(I,r,g)},g.id))]}),e.image.length>0&&t.jsxs("div",{children:[t.jsxs("div",{className:"va-history-related-group-title",children:["图片生成 (",e.image.length,")"]}),e.image.map(g=>t.jsx(pa,{task:g,previewTasks:l,onInsertTask:h,onPreviewOpen:c},g.id))]}),e.video.length>0&&t.jsxs("div",{children:[t.jsxs("div",{className:"va-history-related-group-title",children:["视频生成 (",e.video.length,")"]}),e.video.map(g=>t.jsx(pa,{task:g,previewTasks:l,onInsertTask:h,onPreviewOpen:c},g.id))]})]}),pa=({task:e,previewTasks:r,onClick:l,onInsertTask:h,onPreviewOpen:c})=>{const k=e.status===Ve.COMPLETED,g=es(e),I=k&&g.length>0,O=(e.type===ge.IMAGE||e.type===ge.VIDEO)&&I&&!!(r!=null&&r.length),j=xr(e),S=g[0],A=s.useCallback(G=>{if(O&&r){c==null||c(G,e,r);return}l==null||l(G)},[O,l,c,r,e]);return t.jsx(ct,{content:Sr(e.status),showArrow:!1,children:t.jsxs("div",{className:"va-history-related-task",onClick:A,children:[t.jsx("span",{className:`va-history-related-task-status ${Cr(e.status)}`}),t.jsx("span",{className:"va-history-related-task-prompt",children:jr(e)}),t.jsx("span",{className:"va-history-related-task-time",children:wr(e.createdAt)}),I&&S&&e.type!==ge.CHAT&&t.jsxs("span",{className:"va-history-related-task-thumb",children:[e.type===ge.VIDEO?t.jsx(Ja,{src:S,poster:j||void 0,alt:"",className:"va-history-related-task-thumb-media",thumbnailSize:"small",videoProps:{preload:"metadata",muted:!0,playsInline:!0,"aria-hidden":!0}}):t.jsx(lt,{src:j||S,alt:"",showSkeleton:!1,eager:!0}),e.type===ge.VIDEO&&t.jsx("span",{className:"va-history-related-task-thumb-badge","aria-hidden":"true",children:"▶"})]}),I&&h&&t.jsx(ct,{content:"插入画板",showArrow:!1,children:t.jsx("button",{className:"va-history-related-insert-btn",onClick:G=>h(G,e),"aria-label":"插入画板",children:t.jsx(Ns,{size:16})})})]})})};function Pr(e,r,l){var c;const h=((c=e.result)==null?void 0:c.title)||e.params.title||e.params.prompt||(e.type===ge.VIDEO?"视频预览":"图片预览");return l>1?`${h} (${r+1}/${l})`:h}function Ar(e){var h,c,k;const r=[],l=new Map;for(const g of e){if(g.type!==ge.IMAGE&&g.type!==ge.VIDEO)continue;const I=es(g);if(I.length===0)continue;const O=r.length,j=g.type===ge.VIDEO&&(((c=(h=g.result)==null?void 0:h.thumbnailUrls)==null?void 0:c[0])||((k=g.result)==null?void 0:k.thumbnailUrl))||void 0;I.forEach((S,A)=>{r.push({id:I.length>1?`${g.id}-${A}`:g.id,url:S,type:g.type===ge.VIDEO?"video":"image",title:Pr(g,A,I.length),prompt:g.params.prompt,posterUrl:g.type===ge.VIDEO?j:void 0})}),l.set(g.id,O)}return{items:r,taskIdToIndex:l}}const Tr=({records:e,onSelect:r,onRecordsChange:l,showStarredOnly:h=!1,onInsertTask:c,onSelectScript:k})=>{const g=h?e.filter(f=>f.starred):e,[I,O]=s.useState(null),[j,S]=s.useState(!1),[A,G]=s.useState([]),[Y,J]=s.useState(0),[N,ie]=s.useState(null),{tasks:le}=Xa(),U=s.useMemo(()=>{const f=new Map,R=new Set(e.map(q=>q.id)),T=()=>({rewrite:[],image:[],video:[]});for(const q of le){const $=q.params;if(q.type===ge.CHAT&&$.videoAnalyzerAction==="rewrite"&&typeof $.videoAnalyzerRecordId=="string"&&R.has($.videoAnalyzerRecordId)){const ee=$.videoAnalyzerRecordId;Aa(f,ee,"rewrite",q,T);continue}if((q.type===ge.IMAGE||q.type===ge.VIDEO)&&typeof $.batchId=="string"&&$.batchId.startsWith("va_")){const ee=Ps($.batchId,"va_",R);if(ee){const K=q.type===ge.IMAGE?"image":"video";Aa(f,ee,K,q,T)}}}return As(f)},[le,e]),Q=s.useCallback(async(f,R)=>{f.stopPropagation();const T=await xe(R.id,{starred:!R.starred});l(T)},[l]),X=s.useCallback((f,R)=>{f.stopPropagation(),ie(R)},[]),he=s.useCallback(async()=>{if(!N)return;const f=await Ts(N);l(f),ie(null)},[l,N]),L=s.useCallback((f,R)=>{f.stopPropagation(),O(T=>T===R?null:R)},[]),D=s.useCallback((f,R)=>{f.stopPropagation(),c==null||c(R)},[c]),me=s.useCallback((f,R,T)=>{f.stopPropagation(),k==null||k(R,T)},[k]),ae=s.useCallback((f,R,T)=>{f.stopPropagation();const{items:q,taskIdToIndex:$}=Ar(T),ee=$.get(R.id);!q.length||ee===void 0||(G(q),J(ee),S(!0))},[]),pe=s.useCallback(()=>{S(!1)},[]);return g.length===0?t.jsx("div",{className:"va-page va-empty",children:t.jsx("span",{children:h?"暂无收藏":"暂无分析记录"})}):t.jsxs(t.Fragment,{children:[t.jsx("div",{className:"va-page",children:t.jsx("div",{className:"va-history-list",children:g.map(f=>{const R=U.get(f.id),T=I===f.id;return t.jsx(kr,{record:f,related:R,isExpanded:T,onSelect:r,onToggleStar:Q,onDelete:X,onToggleExpand:L,onInsertTask:D,onPreviewOpen:ae,onSelectScript:me},f.id)})})}),t.jsx(Ls,{visible:j,items:A,initialIndex:Y,onClose:pe,showThumbnails:A.length>1}),t.jsx(zs,{open:N!==null,title:"确认删除",description:"确定要删除这条历史记录吗?此操作不可撤销。",confirmText:"删除",cancelText:"取消",danger:!0,onOpenChange:f=>{f||ie(null)},onConfirm:he})]})},zr=[{id:"analyze",label:"分析"},{id:"script",label:"脚本"},{id:"generate",label:"生成"}],Hr=()=>{const{board:e}=ha(),{records:r,setRecords:l,currentRecord:h,setCurrentRecord:c,showStarred:k,setShowStarred:g,starredCount:I,selectRecord:O,updateCurrentRecord:j,restart:S,applySyncedRecord:A}=Es({loadRecords:fa,logPrefix:"[VideoAnalyzer]"}),{page:G,setPage:Y,navigateToStep:J,goToDefaultPage:N,openHistory:ie,openStarred:le,toggleStarred:U}=Ds({initialPage:"analyze",defaultPage:"analyze",historyPage:"history",setShowStarred:g}),Q=s.useCallback(async f=>cr(f)?Ut(f):null,[]);Qs({syncTask:Q,applySyncedRecord:A,logPrefix:"[VideoAnalyzer]"});const X=s.useMemo(()=>zr.map((f,R)=>({...f,disabled:!h&&R>0})),[h]),he=s.useCallback(f=>{j(f)},[j]),L=s.useCallback(f=>{O(f),N()},[N,O]),D=s.useCallback(f=>{j(f)},[j]),me=s.useCallback(()=>{S(),N()},[N,S]),ae=s.useCallback(async f=>{var R,T,q,$;if(!((R=f.result)!=null&&R.url)&&!((q=(T=f.result)==null?void 0:T.urls)!=null&&q.length)||!e){Se.warning("无法插入:白板未就绪");return}try{if(f.type===ge.IMAGE){const ee=($=f.result.urls)!=null&&$.length?f.result.urls:[f.result.url];for(const K of ee)await Rs(e,K);Se.success(ee.length>1?"多图已插入到白板":"图片已插入到白板")}else f.type===ge.VIDEO&&(await Vs(e,f.result.url),Se.success("视频已插入到白板"))}catch(ee){console.error("[VideoAnalyzer] Failed to insert to board:",ee),Se.error(`插入失败: ${ee instanceof Error?ee.message:"未知错误"}`)}},[e]),pe=s.useCallback(async(f,R)=>{const T=String(R.params.videoAnalyzerPrompt||R.params.prompt||""),q=f.scriptVersions||[],$=q.find(K=>K.prompt===T)||q.find(K=>{var _e;return T&&((_e=K.prompt)==null?void 0:_e.includes(T))});let ee=f;if($&&$.id!==f.activeVersionId){const K=Za(f,$.id);if(K){const _e=await xe(f.id,K);ee=_e.find(ce=>ce.id===f.id)||{...f,...K},l(_e)}}c(ee),Y("script")},[c,Y,l]);return t.jsxs("div",{className:"video-analyzer",children:[t.jsx(Fs,{isHistoryPage:G==="history",showStarred:k,recordsCount:r.length,starredCount:I,currentStep:G,steps:X,onStepNavigate:J,onBackFromHistory:N,onOpenHistory:ie,onOpenStarred:le,onToggleStarred:U}),G==="analyze"&&t.jsx(pr,{existingRecord:h,onComplete:he,onRecordsChange:l,onCreateNew:me,onNext:h?()=>Y("script"):void 0}),G==="script"&&h&&t.jsx(gr,{record:h,onRecordUpdate:D,onRecordsChange:l,onNext:()=>Y("generate")}),G==="generate"&&h&&t.jsx(Ir,{record:h,onRecordUpdate:D,onRecordsChange:l,onRestart:me}),G==="history"&&t.jsx(Tr,{records:r,onSelect:L,onRecordsChange:l,showStarredOnly:k,onInsertTask:e?ae:void 0,onSelectScript:pe})]})};export{Hr as default};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{r as f,bz as u,dB as l}from"./startup-app-
|
|
1
|
+
import{r as f,bz as u,dB as l}from"./startup-app-M6vjXkRC.js";function b(e){return e.status===l.COMPLETED}function y({syncTask:e,applySyncedRecord:n,shouldHandleTask:o=b,logPrefix:a="[WorkflowTaskSync]"}){f.useEffect(()=>{let c=!1;const r=new Set,i=async s=>{if(!(!o(s)||r.has(s.id))){r.add(s.id);try{const t=await e(s);if(!t||c)return;n(t)}catch(t){console.error(`${a} Failed to sync task result:`,t)}finally{r.delete(s.id)}}};u.getAllTasks().forEach(s=>{i(s)});const d=u.observeTaskUpdates().subscribe(s=>{i(s.task)});return()=>{c=!0,d.unsubscribe()}},[n,a,o,e])}export{y as u};
|