"use client"; import { useEffect, useRef, useState, type PointerEvent, type ReactNode } from "react"; import { X, ChevronDown, Download, Frame, Play, Pause, Maximize, Type, Magnet, Plus, Volume2, VolumeX, Undo2, Redo2, ZoomIn, ZoomOut, Shrink, Expand, Eye, EyeOff, Search, Trash2, } from "lucide-react"; import { CaptionFontPicker } from "./CaptionFonts"; import { EditPreview } from "./EditPreview"; import { TransitionPreview } from "./TransitionPreview"; import styles from "./SmartEditEditor.module.css"; import { planTimeline, editableCaptions, defaultCaptionStyle, newCaptionStyle, SECOND, type EditPlan, type TimelineCaption, type CaptionStyle, type AudioClip, defaultVideoTransform, } from "@/lib/video-canvas/smart-edit/contract"; import type { CanvasGenerationTask } from "@/lib/video-canvas/task-contract"; import { downloadCanvasMedia } from "@/lib/video-canvas/download"; const transitionNames = { fade: "淡入淡出", fadeblack: "黑场过渡", fadewhite: "白场过渡" }; const stamp = (s: number) => `${String(Math.floor(s / 60)).padStart(2, "0")}:${String(Math.floor(s % 60)).padStart(2, "0")}`; const frameStamp = (s: number) => `00:${stamp(s)}:${String(Math.floor(s * 30) % 30).padStart(2, "0")}`; const clamp = (v: number, min: number, max: number) => Math.max(min, Math.min(max, v)); function Icon({ title, children, onClick, active = false, disabled = false, extra = "", }: { title: string; children: ReactNode; onClick: () => void; active?: boolean; disabled?: boolean; extra?: string; }) { return ( ); } function Thumb({ url, time, width }: { url: string; time: number; width?: number }) { return (