@bylqwjc/media-editor-video 1.0.0

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.
Files changed (60) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +55 -0
  3. package/dist/chunk-EK7ODJWE.js +1 -0
  4. package/dist/index-CX2iAapm.d.ts +51 -0
  5. package/dist/index.d.ts +61 -0
  6. package/dist/index.js +2273 -0
  7. package/dist/lazy.d.ts +7 -0
  8. package/dist/lazy.js +1 -0
  9. package/dist/legacy.js +65 -0
  10. package/node_modules/@media-editor/client/LICENSE +21 -0
  11. package/node_modules/@media-editor/client/README.md +27 -0
  12. package/node_modules/@media-editor/client/dist/index.d.ts +24 -0
  13. package/node_modules/@media-editor/client/dist/index.js +1 -0
  14. package/node_modules/@media-editor/client/package.json +22 -0
  15. package/node_modules/@media-editor/core/LICENSE +21 -0
  16. package/node_modules/@media-editor/core/README.md +14 -0
  17. package/node_modules/@media-editor/core/dist/browser.d.ts +100 -0
  18. package/node_modules/@media-editor/core/dist/browser.js +3 -0
  19. package/node_modules/@media-editor/core/dist/chunk-MGKYVYOH.js +1 -0
  20. package/node_modules/@media-editor/core/dist/chunk-USY6UDGL.js +1 -0
  21. package/node_modules/@media-editor/core/dist/chunk-XCBM7P7N.js +1 -0
  22. package/node_modules/@media-editor/core/dist/engine.d.ts +359 -0
  23. package/node_modules/@media-editor/core/dist/engine.js +1 -0
  24. package/node_modules/@media-editor/core/dist/index.d.ts +264 -0
  25. package/node_modules/@media-editor/core/dist/index.js +1 -0
  26. package/node_modules/@media-editor/core/dist/platform-presets-B-o4C6uY.d.ts +80 -0
  27. package/node_modules/@media-editor/core/dist/state-B85vkf7_.d.ts +1027 -0
  28. package/node_modules/@media-editor/core/node_modules/zod/LICENSE +21 -0
  29. package/node_modules/@media-editor/core/node_modules/zod/README.md +208 -0
  30. package/node_modules/@media-editor/core/node_modules/zod/index.d.cts +4 -0
  31. package/node_modules/@media-editor/core/node_modules/zod/index.js +1 -0
  32. package/node_modules/@media-editor/core/node_modules/zod/package.json +74 -0
  33. package/node_modules/@media-editor/core/node_modules/zod/v3/ZodError.d.cts +164 -0
  34. package/node_modules/@media-editor/core/node_modules/zod/v3/ZodError.js +1 -0
  35. package/node_modules/@media-editor/core/node_modules/zod/v3/errors.d.cts +5 -0
  36. package/node_modules/@media-editor/core/node_modules/zod/v3/errors.js +1 -0
  37. package/node_modules/@media-editor/core/node_modules/zod/v3/external.d.cts +6 -0
  38. package/node_modules/@media-editor/core/node_modules/zod/v3/external.js +1 -0
  39. package/node_modules/@media-editor/core/node_modules/zod/v3/helpers/enumUtil.d.cts +8 -0
  40. package/node_modules/@media-editor/core/node_modules/zod/v3/helpers/enumUtil.js +0 -0
  41. package/node_modules/@media-editor/core/node_modules/zod/v3/helpers/errorUtil.d.cts +9 -0
  42. package/node_modules/@media-editor/core/node_modules/zod/v3/helpers/errorUtil.js +1 -0
  43. package/node_modules/@media-editor/core/node_modules/zod/v3/helpers/parseUtil.d.cts +78 -0
  44. package/node_modules/@media-editor/core/node_modules/zod/v3/helpers/parseUtil.js +1 -0
  45. package/node_modules/@media-editor/core/node_modules/zod/v3/helpers/partialUtil.d.cts +8 -0
  46. package/node_modules/@media-editor/core/node_modules/zod/v3/helpers/partialUtil.js +0 -0
  47. package/node_modules/@media-editor/core/node_modules/zod/v3/helpers/typeAliases.d.cts +2 -0
  48. package/node_modules/@media-editor/core/node_modules/zod/v3/helpers/typeAliases.js +0 -0
  49. package/node_modules/@media-editor/core/node_modules/zod/v3/helpers/util.d.cts +85 -0
  50. package/node_modules/@media-editor/core/node_modules/zod/v3/helpers/util.js +1 -0
  51. package/node_modules/@media-editor/core/node_modules/zod/v3/index.d.cts +4 -0
  52. package/node_modules/@media-editor/core/node_modules/zod/v3/index.js +1 -0
  53. package/node_modules/@media-editor/core/node_modules/zod/v3/locales/en.d.cts +3 -0
  54. package/node_modules/@media-editor/core/node_modules/zod/v3/locales/en.js +1 -0
  55. package/node_modules/@media-editor/core/node_modules/zod/v3/standard-schema.d.cts +102 -0
  56. package/node_modules/@media-editor/core/node_modules/zod/v3/standard-schema.js +0 -0
  57. package/node_modules/@media-editor/core/node_modules/zod/v3/types.d.cts +1031 -0
  58. package/node_modules/@media-editor/core/node_modules/zod/v3/types.js +1 -0
  59. package/node_modules/@media-editor/core/package.json +34 -0
  60. package/package.json +33 -0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 media-editor-sdk contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,27 @@
1
+ # @media-editor/client
2
+
3
+ 浏览器端导出客户端,用于把视频导出和封面抽取请求发送到后端。
4
+
5
+ ## 使用
6
+
7
+ ```ts
8
+ import { createEditorClient } from '@media-editor/client';
9
+
10
+ const client = createEditorClient({
11
+ baseUrl: '/api',
12
+ paths: {
13
+ video: '/editor/video',
14
+ poster: '/editor/poster',
15
+ },
16
+ });
17
+
18
+ const videoBlob = await client.exportVideo(formData);
19
+ const posterBlob = await client.extractPoster(file, 3.5);
20
+ ```
21
+
22
+ 默认路径:
23
+
24
+ - 视频导出: `/api/editor/video`
25
+ - 封面抽取: `/api/editor/poster`
26
+
27
+ 也可以传自定义 `fetch` 以接入鉴权、监控或测试环境。
@@ -0,0 +1,24 @@
1
+ /**
2
+ * @media-editor/client —— 浏览器端传输:把导出请求发往可配置的后端 baseURL。
3
+ * 取代原 SocialEcho 的 apiUrl()(写死 NEXT_PUBLIC_BASE_PATH)。引擎与封面弹层消费它。
4
+ */
5
+ interface EditorClient {
6
+ /** 视频导出:FormData(video_0../audio_0../editState/overlay) → mp4 Blob */
7
+ exportVideo(fd: FormData): Promise<Blob>;
8
+ /** 封面抽帧:file + time(秒) → jpeg Blob */
9
+ extractPoster(file: File, time: number): Promise<Blob>;
10
+ }
11
+ interface EditorClientOptions {
12
+ /** 后端基址,如 'https://api.example.com' 或子路径 '/socialecho-agent-demo';默认同源 '' */
13
+ baseUrl?: string;
14
+ /** 自定义 fetch(SSR/测试注入);默认全局 fetch */
15
+ fetch?: typeof fetch;
16
+ /** 端点路径覆盖 */
17
+ paths?: {
18
+ video?: string;
19
+ poster?: string;
20
+ };
21
+ }
22
+ declare function createEditorClient(opts?: EditorClientOptions): EditorClient;
23
+
24
+ export { type EditorClient, type EditorClientOptions, createEditorClient };
@@ -0,0 +1 @@
1
+ function c(t,o){const e=t.replace(/\/$/,""),a=o.startsWith("/")?o:`/${o}`;return`${e}${a}`}async function u(t,o){const e=await t.json().catch(()=>({}));return new Error(e.message||e.error||o)}function h(t={}){const o=t.baseUrl??"",e=t.fetch??globalThis.fetch,a=t.paths?.video??"/api/editor/video",d=t.paths?.poster??"/api/editor/poster";return{async exportVideo(n){const r=await e(c(o,a),{method:"POST",body:n});if(!r.ok)throw await u(r,"\u89C6\u9891\u5904\u7406\u5931\u8D25");return r.blob()},async extractPoster(n,r){const s=new FormData;s.append("file",n,n.name||"video.mp4"),s.append("time",String(r));const i=await e(c(o,d),{method:"POST",body:s});if(!i.ok)throw await u(i,"\u5C01\u9762\u62BD\u53D6\u5931\u8D25");return i.blob()}}}export{h as createEditorClient};
@@ -0,0 +1,22 @@
1
+ {
2
+ "name": "@media-editor/client",
3
+ "version": "1.0.18",
4
+ "description": "媒体编辑器浏览器端传输(可配置 baseURL 的导出/封面客户端)",
5
+ "type": "module",
6
+ "license": "MIT",
7
+ "exports": {
8
+ ".": {
9
+ "types": "./dist/index.d.ts",
10
+ "import": "./dist/index.js"
11
+ }
12
+ },
13
+ "publishConfig": {
14
+ "access": "public"
15
+ },
16
+ "files": [
17
+ "dist"
18
+ ],
19
+ "main": "./dist/index.js",
20
+ "module": "./dist/index.js",
21
+ "types": "./dist/index.d.ts"
22
+ }
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 media-editor-sdk contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,14 @@
1
+ # @media-editor/core
2
+
3
+ 框架无关核心包。包含视频编辑状态、时间轴、导出参数、滤镜、平台比例、图片编辑器配置工厂和浏览器 canvas 工具。
4
+
5
+ ## 子路径
6
+
7
+ ```ts
8
+ import { defaultVideoEditState } from '@media-editor/core';
9
+ import { VideoEditorEngine } from '@media-editor/core/engine';
10
+ import { buildVideoExportFormData } from '@media-editor/core/browser';
11
+ import { createImageEditorConfig } from '@media-editor/core/filerobot';
12
+ ```
13
+
14
+ `@media-editor/core` 不依赖 React 或 Vue,适合服务端和自定义 UI 复用。
@@ -0,0 +1,100 @@
1
+ import { O as OverlayT, V as VideoEditStateT } from './state-B85vkf7_.js';
2
+ import { VideoEditorEngine } from './engine.js';
3
+ import 'zod';
4
+
5
+ /**
6
+ * editor-core/overlay-render —— 标注/贴纸绘制(浏览器环境,Canvas API;零框架依赖)。
7
+ * 交互画布与导出 PNG 共用 drawOverlays,保证所见即所得。
8
+ * 坐标系 = 最终输出空间(旋转/裁剪/缩放后),导出 PNG 即按输出分辨率渲染。
9
+ */
10
+
11
+ declare function getOverlayRotation(o: OverlayT): number;
12
+ declare function overlayBBox(o: OverlayT): {
13
+ x: number;
14
+ y: number;
15
+ w: number;
16
+ h: number;
17
+ };
18
+ /** 单个对象绘制;sticker 的位图经 imageCache 提供(加载由调用方负责) */
19
+ declare function drawOverlay(ctx: CanvasRenderingContext2D, o: OverlayT, imageCache?: Map<string, HTMLImageElement>): void;
20
+ declare function drawOverlays(ctx: CanvasRenderingContext2D, overlays: OverlayT[], imageCache?: Map<string, HTMLImageElement>): void;
21
+ /** sticker 位图预加载(dataURL → HTMLImageElement) */
22
+ declare function loadOverlayImages(overlays: OverlayT[]): Promise<Map<string, HTMLImageElement>>;
23
+ /** 导出:把 overlays 渲染成输出分辨率的透明 PNG Blob(无 overlay 返回 null) */
24
+ declare function renderOverlaysToPng(overlays: OverlayT[] | undefined, width: number, height: number): Promise<Blob | null>;
25
+ /** 命中检测(选中/拖动用):返回最上层命中的 overlay 下标,无命中 -1 */
26
+ declare function hitTestOverlay(overlays: OverlayT[], x: number, y: number, tolerance?: number): number;
27
+ /**
28
+ * 贴纸图片等比落盒:长边 = boxSide、短边按原始宽高比,下限 8px。
29
+ * 上传任意比例图片不再被压成正方形(drawImage 是拉伸语义,入库 w/h 必须等比)。
30
+ */
31
+ declare function fitStickerBox(natW: number, natH: number, boxSide: number): {
32
+ w: number;
33
+ h: number;
34
+ };
35
+ /**
36
+ * 缩放 overlay(选中后拖右下角把手):以对象左上角为锚,按 ratio 等比。
37
+ * sticker/rect/ellipse 改 w/h;text 改 fontSize;pen/line/arrow 不支持(原样返回)。
38
+ */
39
+ declare function scaleOverlay(o: OverlayT, ratio: number): OverlayT;
40
+ /** 旋转 overlay:以对象 bbox 中心为视觉锚点;坐标本身不变,绘制/命中检测按 rotation 处理。 */
41
+ declare function rotateOverlay(o: OverlayT, deg: number): OverlayT;
42
+ /** 平移 overlay(拖动选中对象) */
43
+ declare function translateOverlay(o: OverlayT, dx: number, dy: number): OverlayT;
44
+
45
+ /**
46
+ * 把引擎导出计划 + 浏览器端 File 组装成服务端约定的 FormData
47
+ * (video_0../audio_0../overlay/editState),供 @media-editor/client.exportVideo 直接发。
48
+ * 触碰 DOM(overlay → canvas PNG),故归 @media-editor/core/browser,React/Vue 共用。
49
+ */
50
+
51
+ /**
52
+ * @param videoFiles 以「原始 srcIdx」为下标的视频 File 数组(引擎按 videoSrcOrder 取并重排)
53
+ * @param audioFiles 同上(音频)
54
+ */
55
+ declare function buildVideoExportFormData(engine: VideoEditorEngine, videoFiles: ReadonlyArray<File | undefined>, audioFiles?: ReadonlyArray<File | undefined>): Promise<FormData>;
56
+
57
+ /**
58
+ * 帧合成器(框架无关 canvas)—— 把「源帧 → 输出画布 + 完整效果链 + overlays」绘到 canvas。
59
+ * 从 SocialEcho VideoFramePreview.drawFinalFrame 抽出,供实时预览与封面导出复用。
60
+ *
61
+ * 效果链与 ffmpeg 导出严格同构:源→画布 cover 归一 → flips → rotate → crop → scale + 调色/滤镜 css。
62
+ */
63
+
64
+ /** drawImage 可接受的源(video / image / canvas) */
65
+ type FrameSource = CanvasImageSource;
66
+ /**
67
+ * 把一帧合成绘到 canvas(物理分辨率 = 输出尺寸 × k)。
68
+ * @param srcDims 活动源原始分辨率(逐片段可能不同)
69
+ * @param canvasDims 输出画布(= 首素材分辨率),全局效果链的「源 dims」
70
+ * @param k 物理像素倍率(预览用 ≤1 控带宽,封面导出用 1 全分辨率)
71
+ * @param imageCache 贴纸图片缓存(loadOverlayImages 产出)
72
+ */
73
+ declare function drawVideoFrame(canvas: HTMLCanvasElement, source: FrameSource, srcDims: {
74
+ w: number;
75
+ h: number;
76
+ }, canvasDims: {
77
+ w: number;
78
+ h: number;
79
+ }, state: VideoEditStateT, k?: number, imageCache?: Map<string, HTMLImageElement>, withOverlays?: boolean): void;
80
+ /**
81
+ * 抽 count 张等距缩略图(dataURL,jpeg)。供时间轴缩略图条 / 封面条。
82
+ * 传入**专用离屏 video 元素**(勿用主预览源,seek 会打断播放)。
83
+ */
84
+ declare function generateThumbnails(videoEl: HTMLVideoElement, count: number, maxW?: number): Promise<string[]>;
85
+
86
+ /**
87
+ * 全屏切换按钮(框架无关 DOM)。点按对 host 进/出全屏;监听 fullscreenchange 切图标和 host 状态类。
88
+ * 图片/视频 mount 共用:默认可作为覆盖按钮,也可放进宿主自己的返回工具栏。
89
+ */
90
+ interface FullscreenToggle {
91
+ button: HTMLButtonElement;
92
+ dispose: () => void;
93
+ }
94
+ interface FullscreenToggleOptions {
95
+ mode?: 'overlay' | 'inline';
96
+ className?: string;
97
+ }
98
+ declare function createFullscreenToggle(host: HTMLElement, options?: FullscreenToggleOptions): FullscreenToggle;
99
+
100
+ export { type FrameSource, type FullscreenToggle, type FullscreenToggleOptions, buildVideoExportFormData, createFullscreenToggle, drawOverlay, drawOverlays, drawVideoFrame, fitStickerBox, generateThumbnails, getOverlayRotation, hitTestOverlay, loadOverlayImages, overlayBBox, renderOverlaysToPng, rotateOverlay, scaleOverlay, translateOverlay };
@@ -0,0 +1,3 @@
1
+ import{outputSize as G,rotatedSize as Tt,fitRects as it,buildFilterCss as at,DEG2RAD as St,findFilterPreset as Ft}from"./chunk-USY6UDGL.js";var st=Math.PI/180;function D(t,e,r){t.strokeStyle=e,t.lineWidth=r,t.lineCap="round",t.lineJoin="round"}function Ct(t,e,r,n,i,a){const c=Math.atan2(i-r,n-e),o=Math.max(12,a*3.5);t.beginPath(),t.moveTo(n,i),t.lineTo(n-o*Math.cos(c-Math.PI/7),i-o*Math.sin(c-Math.PI/7)),t.moveTo(n,i),t.lineTo(n-o*Math.cos(c+Math.PI/7),i-o*Math.sin(c+Math.PI/7)),t.stroke()}function ot(t){if(!Number.isFinite(t))return 0;let e=t%360;return e>180&&(e-=360),e<-180&&(e+=360),Math.abs(e)<.001?0:e}var At=.84;function Nt(t){const e=Math.max(8,Number(t?.w)||0),r=Math.max(8,Number(t?.h)||0),n=Math.max(8,Math.min(e,r)*At);return{x:(Number(t?.x)||0)+(e-n)/2,y:(Number(t?.y)||0)+(r-n)/2,size:n}}var V=null;function Ot(){return typeof document>"u"?null:(V??(V=document.createElement("canvas")),V.getContext("2d"))}function ct(t){return Math.min(512,Math.max(8,Number(t.fontSize)||24))}function kt(t,e){return Number.isFinite(t.paddingX)?Math.max(0,t.paddingX):Math.max(8,Math.round(e*.18))}function Pt(t,e){return Number.isFinite(t.paddingY)?Math.max(0,t.paddingY):Math.max(6,Math.round(e*.14))}function Et(t,e){return(Number.isFinite(t.lineHeight)?Math.max(.9,t.lineHeight):1.1)*e}function Wt(t){return t.textAlign==="center"||t.textAlign==="right"?t.textAlign:"left"}function It(t){const e=ct(t),r=t.fontStyle||"normal",n=t.fontWeight||"700",i=t.fontFamily||'-apple-system, "PingFang SC", "Microsoft YaHei", sans-serif';return`${r} ${n} ${e}px ${i}`}function zt(t,e){const r=t==null?"":String(t);switch(e){case"uppercase":return r.toUpperCase();case"lowercase":return r.toLowerCase();case"capitalize":return r.toLowerCase().replace(/(^|\s)(\S)/g,(n,i,a)=>`${i}${a.toUpperCase()}`);default:return r}}function Lt(t,e){const n=zt(t,e).replace(/\r\n/g,`
2
+ `).split(`
3
+ `);return n.length?n:[""]}function j(t){return Number.isFinite(t)&&t>=0}function Yt(t){if(!J(t))return null;const e=j(t.startAt)?Number(t.startAt):null,r=j(t.endAt)?Number(t.endAt):null;if(e==null&&r==null)return null;const n=Math.max(0,e??0),i=Math.max(n,r??n);return{start:n,end:i}}function lt(t){const e=Yt(t);return!!e&&e.end>e.start}function J(t){return t?.type==="pen"||t?.type==="line"||t?.type==="arrow"||t?.type==="rect"||t?.type==="ellipse"||t?.type==="text"||t?.type==="sticker"}function Bt(t){if(!J(t)&&t?.type!=="filter"&&t?.type!=="adjust")return null;const e=j(t.startAt)?Number(t.startAt):null,r=j(t.endAt)?Number(t.endAt):null;if(e==null&&r==null)return null;const n=Math.max(0,e??0),i=Math.max(n,r??n);return{start:n,end:i}}function Xt(t,e){const r=Bt(t);return r?Number.isFinite(e)?e>=r.start&&e<=r.end:!1:!0}function jt(t,e){return t?.length?Number.isFinite(e)?t.filter(r=>Xt(r,e)):t:[]}function ut(t){return t?.type==="text"||t?.type==="sticker"||t?.type==="filter"||t?.type==="adjust"}function ht(t){return Number.isFinite(t?.timelineTrack)?Math.max(0,Math.round(Number(t.timelineTrack))):0}function dt(t){return j(t?.startAt)?Number(t.startAt):0}function q(t){const e=ct(t),r=kt(t,e),n=Pt(t,e),i=Et(t,e),a=Lt(t.text,t.textTransform),c=Ot(),o=It(t);c&&(c.font=o);const m=a.map(F=>{const T=F===""?" ":F;return c?c.measureText(T).width:Math.max(1,T.length)*e*.6}),s=m.length?Math.max(...m):e*.6,f=Math.max(e,a.length*i),p=Math.max(Number.isFinite(t.width)?t.width:0,s+r*2),w=f+n*2;return{font:o,fontSize:e,paddingX:r,paddingY:n,lineHeight:i,lines:a,widths:m,boxWidth:p,boxHeight:w,align:Wt(t)}}function Rt(t,e,r){return e.align==="center"?t.x+e.boxWidth/2-r/2:e.align==="right"?t.x+e.boxWidth-e.paddingX-r:t.x+e.paddingX}function Ht(t,e,r,n,i,a){if(!e.textDecoration||a<=0)return;const c=r.fontSize,o=String(e.textDecoration).includes("underline"),m=String(e.textDecoration).includes("line-through");if(!(!o&&!m)){if(t.save(),t.strokeStyle=e.color||"#fff",t.lineWidth=Math.max(1,c/18),o){const s=i+c+Math.max(1,c*.08);t.beginPath(),t.moveTo(n,s),t.lineTo(n+a,s),t.stroke()}if(m){const s=i+c*.56;t.beginPath(),t.moveTo(n,s),t.lineTo(n+a,s),t.stroke()}t.restore()}}function K(t){return ot(t.rotation??0)}function mt(t){switch(t.type){case"pen":{let e=1/0,r=1/0,n=-1/0,i=-1/0;for(let a=0;a<t.points.length;a+=2)e=Math.min(e,t.points[a]),n=Math.max(n,t.points[a]),r=Math.min(r,t.points[a+1]),i=Math.max(i,t.points[a+1]);return{x:e,y:r,w:n-e,h:i-r}}case"line":case"arrow":return{x:Math.min(t.x1,t.x2),y:Math.min(t.y1,t.y2),w:Math.abs(t.x2-t.x1),h:Math.abs(t.y2-t.y1)};case"rect":case"ellipse":case"sticker":return{x:t.x,y:t.y,w:t.w,h:t.h};case"text":{const e=q(t);return{x:t.x,y:t.y,w:e.boxWidth,h:e.boxHeight}}}}function Q(t){const e=mt(t);return{x:e.x+e.w/2,y:e.y+e.h/2}}function $t(t,e,r,n,i){const a=i*st,c=Math.cos(a),o=Math.sin(a),m=t-r,s=e-n;return{x:r+m*c-s*o,y:n+m*o+s*c}}function ft(t,e,r,n,i){return{x:r+(t-r)*i,y:n+(e-n)*i}}function Z(t,e,r){const n=K(e);if(n){const i=Q(e);t.save(),t.translate(i.x,i.y),t.rotate(n*st),t.translate(-i.x,-i.y),pt(t,e,r),t.restore();return}pt(t,e,r)}function pt(t,e,r){switch(e.type){case"pen":{D(t,e.color,e.width),t.beginPath(),t.moveTo(e.points[0],e.points[1]);for(let n=2;n<e.points.length;n+=2)t.lineTo(e.points[n],e.points[n+1]);t.stroke();break}case"line":case"arrow":{D(t,e.color,e.width),t.beginPath(),t.moveTo(e.x1,e.y1),t.lineTo(e.x2,e.y2),t.stroke(),e.type==="arrow"&&Ct(t,e.x1,e.y1,e.x2,e.y2,e.width);break}case"rect":{D(t,e.color,e.width),t.strokeRect(e.x,e.y,e.w,e.h);break}case"ellipse":{D(t,e.color,e.width),t.beginPath(),t.ellipse(e.x+e.w/2,e.y+e.h/2,Math.abs(e.w/2),Math.abs(e.h/2),0,0,Math.PI*2),t.stroke();break}case"text":{const n=q(e),i=Number.isFinite(e.opacity)?Math.min(1,Math.max(0,e.opacity/100)):1,a=Number.isFinite(e.borderWidth)?Math.max(0,e.borderWidth):0,c=e.autoOutline!==!1;t.save(),t.globalAlpha*=i,e.backgroundColor&&e.backgroundColor!=="transparent"&&(t.fillStyle=e.backgroundColor,t.fillRect(e.x,e.y,n.boxWidth,n.boxHeight)),t.fillStyle=e.color||"#fff",t.font=n.font,t.textBaseline="top",t.lineJoin="round";const o=e.boxShadow;o&&(t.shadowColor=o.color||"transparent",t.shadowOffsetX=o.x||0,t.shadowOffsetY=o.y||0,t.shadowBlur=o.blur||0),n.lines.forEach((m,s)=>{const f=n.widths[s]??0,p=Rt(e,n,f),w=e.y+n.paddingY+s*n.lineHeight;(a>0||c)&&(t.strokeStyle=a>0?e.borderColor||"#000":e.strokeColor||"rgba(0,0,0,0.45)",t.lineWidth=a>0?a:Math.max(1,n.fontSize/18),t.strokeText(m,p,w)),t.fillText(m,p,w),Ht(t,e,n,p,w,f)}),t.restore();break}case"sticker":{if(e.emoji){const n=Nt(e);t.save(),t.font=`${n.size}px -apple-system, "Apple Color Emoji", "Segoe UI Emoji", sans-serif`,t.textAlign="center",t.textBaseline="middle",t.fillText(e.emoji,n.x+n.size/2,n.y+n.size/2),t.restore()}else if(e.src){const n=r?.get(e.src);n&&t.drawImage(n,e.x,e.y,e.w,e.h)}break}}}function tt(t,e,r){for(const n of e)Z(t,n,r)}async function gt(t){const e=new Map,r=[...new Set(t.filter(n=>n.type==="sticker"&&n.src).map(n=>n.src))];return await Promise.all(r.map(n=>new Promise(i=>{const a=new Image;a.onload=()=>{e.set(n,a),i()},a.onerror=()=>i(),a.src=n}))),e}async function et(t,e,r){if(!t?.length)return null;const n=document.createElement("canvas");n.width=e,n.height=r;const i=n.getContext("2d");if(!i)return null;const a=await gt(t);return tt(i,t,a),new Promise(c=>n.toBlob(o=>c(o),"image/png"))}function Dt(t,e,r,n=12){for(let i=t.length-1;i>=0;i--){const a=t[i];if(Ut(a,e,r,n))return i}return-1}function _t(t,e,r,n,i){return Math.abs(t-r)<=i&&Math.abs(e-n)<=i}function yt(t,e,r,n,i,a,c){const o=i-r,m=a-n,s=o*o+m*m||1,f=Math.max(0,Math.min(1,((t-r)*o+(e-n)*m)/s)),p=r+f*o,w=n+f*m;return(t-p)**2+(e-w)**2<=c*c}function Ut(t,e,r,n){const i=K(t);if(i){const a=Q(t),c=$t(e,r,a.x,a.y,-i);return wt(t,c.x,c.y,n)}return wt(t,e,r,n)}function wt(t,e,r,n){switch(t.type){case"pen":{for(let i=0;i+3<t.points.length;i+=2)if(yt(e,r,t.points[i],t.points[i+1],t.points[i+2],t.points[i+3],n+t.width/2))return!0;return!1}case"line":case"arrow":return yt(e,r,t.x1,t.y1,t.x2,t.y2,n+t.width/2);case"rect":case"ellipse":return e>=t.x-n&&e<=t.x+t.w+n&&r>=t.y-n&&r<=t.y+t.h+n;case"text":{const i=q(t);return e>=t.x-n&&e<=t.x+i.boxWidth+n&&r>=t.y-n&&r<=t.y+i.boxHeight+n}case"sticker":return _t(e,r,t.x+t.w/2,t.y+t.h/2,Math.max(t.w,t.h)/2+n)}}function Gt(t,e,r){const n=Math.max(8,r);if(!(t>0)||!(e>0))return{w:n,h:n};const i=n/Math.max(t,e);return{w:Math.max(8,Math.round(t*i)),h:Math.max(8,Math.round(e*i))}}function Vt(t,e){const r=Math.max(.05,e),n=Q(t);switch(t.type){case"pen":return{...t,points:t.points.map((i,a)=>a%2===0?n.x+(i-n.x)*r:n.y+(i-n.y)*r)};case"line":case"arrow":{const i=ft(t.x1,t.y1,n.x,n.y,r),a=ft(t.x2,t.y2,n.x,n.y,r);return{...t,x1:i.x,y1:i.y,x2:a.x,y2:a.y}}case"rect":case"ellipse":case"sticker":return{...t,w:Math.max(8,t.w*r),h:Math.max(8,t.h*r)};case"text":return{...t,fontSize:Math.min(512,Math.max(8,t.fontSize*r)),width:Number.isFinite(t.width)?Math.max(80,t.width*r):t.width,paddingX:Number.isFinite(t.paddingX)?Math.max(0,t.paddingX*r):t.paddingX,paddingY:Number.isFinite(t.paddingY)?Math.max(0,t.paddingY*r):t.paddingY,borderWidth:Number.isFinite(t.borderWidth)?Math.max(0,t.borderWidth*r):t.borderWidth,boxShadow:t.boxShadow?{...t.boxShadow,x:(t.boxShadow.x||0)*r,y:(t.boxShadow.y||0)*r,blur:(t.boxShadow.blur||0)*r}:t.boxShadow};default:return t}}function Jt(t,e){return{...t,rotation:ot(e)}}function qt(t,e,r){switch(t.type){case"pen":{const n=t.points.map((i,a)=>a%2===0?i+e:i+r);return{...t,points:n}}case"line":case"arrow":return{...t,x1:t.x1+e,y1:t.y1+r,x2:t.x2+e,y2:t.y2+r};case"rect":case"ellipse":case"sticker":return{...t,x:t.x+e,y:t.y+r};case"text":return{...t,x:t.x+e,y:t.y+r}}}function B(t,e){const r=Math.min(8192,Math.max(2,Math.round(Number(t)||e)));return r%2===0?r:r-1}function oe(t){const e=G(t.canvas,t),r=t?.exportSettings??null;if(!r)return e;const n=Number.isFinite(Number(r.width))&&Number(r.width)>0,i=Number.isFinite(Number(r.height))&&Number(r.height)>0;if(!n&&!i)return e;const a=e.w>0&&e.h>0?e.w/e.h:1;if(n&&i)return{w:B(r.width,e.w),h:B(r.height,e.h)};if(n){const o=B(r.width,e.w);return{w:o,h:B(o/a,e.h)}}const c=B(r.height,e.h);return{w:B(c*a,e.w),h:c}}async function Kt(t,e,r=[]){const n=t.getExportPlan(),i=new FormData;n.videoSrcOrder.forEach((f,p)=>{const w=e[f];w&&i.append(`video_${p}`,w,w.name||`video_${p}.mp4`)}),n.audioSrcOrder.forEach((f,p)=>{const w=r[f];w&&i.append(`audio_${p}`,w,w.name||`audio_${p}`)});const a=G(n.state.canvas,n.state),c=n.state.overlays??[],o=c.filter(f=>lt(f)),m=c.filter(f=>!lt(f)&&J(f)),s=await et(m,a.w,a.h);s&&i.append("overlay",s,"overlay.png");for(let f=0;f<o.length;f++){const p=await et([o[f]],a.w,a.h);p&&i.append(`textOverlay_${f}`,p,`text-overlay-${f}.png`)}return i.append("editState",JSON.stringify(n.state)),i}function C(t){return Math.max(-1,Math.min(1,Number(t)||0))}function X(t){return Math.max(0,Math.min(1,Number(t)||0))}function M(t){return Math.max(0,Math.min(1,t))}function N(t){return Math.max(0,Math.min(255,t))}function W(t,e,r){if(t===e)return r<t?0:1;const n=Math.max(0,Math.min(1,(r-t)/(e-t)));return n*n*(3-2*n)}function nt(t){const e=W(.08,.4,t),r=1-W(.6,.92,t);return M(e*r*2.2)}function bt(t,e,r=0){const n=Math.sin(t*12.9898+e*78.233+r*37.719)*43758.5453;return n-Math.floor(n)}var I=null;function Qt(t,e){return typeof document>"u"?null:(I??(I=document.createElement("canvas")),I.width!==t&&(I.width=t),I.height!==e&&(I.height=e),I)}function xt(t,e,r,n){if(!n||n==="none")return;const i=Qt(e,r),a=i?.getContext("2d");!i||!a||(a.setTransform(1,0,0,1,0,0),a.clearRect(0,0,e,r),a.drawImage(t.canvas,0,0,e,r),t.save(),t.setTransform(1,0,0,1,0,0),t.clearRect(0,0,e,r),t.filter=n,t.drawImage(i,0,0,e,r),t.restore(),t.filter="none")}function Zt(t,e,r,n){const i=Ft(n?.filterPreset)?.css??"";xt(t,e,r,i)}function te(t,e,r,n){xt(t,e,r,at(n??{},"")),Mt(t,e,r,n??{})}function ee(t={}){return["temperature","tint","vibrance","gamma","highlights","shadows","whites","blacks","lightSense"].some(r=>Math.abs(C(t[r]))>1e-4)?!0:["sharpen","clarity","grain","fade","vignette"].some(r=>X(t[r])>1e-4)}function Mt(t,e,r,n={}){if(!ee(n))return;let i;try{i=t.getImageData(0,0,e,r)}catch{return}const a=C(n.temperature),c=C(n.tint),o=C(n.vibrance),m=C(n.gamma),s=C(n.highlights),f=C(n.shadows),p=C(n.whites),w=C(n.blacks),F=C(n.lightSense),T=X(n.sharpen),O=X(n.clarity),z=X(n.grain),k=X(n.fade),R=X(n.vignette),_=1+m*(m>0?1:.5),b=m===0?1:1/Math.max(.01,_),P=a*.18,H=a*.02,$=-a*.18,rt=c*.1,vt=-c*.12,y=i.data;for(let u=0;u<y.length;u+=4){let d=y[u]/255,g=y[u+1]/255,h=y[u+2]/255;if((a!==0||c!==0)&&(d=M(d+P+rt),g=M(g+H+vt),h=M(h+$+rt)),o!==0){const l=Math.max(d,g,h),v=Math.min(d,g,h),S=l-v,x=(d+g+h)/3,A=o>0?o*(1-S):o*(.35+S*.65);d=M(x+(d-x)*(1+A)),g=M(x+(g-x)*(1+A)),h=M(x+(h-x)*(1+A))}if(m!==0&&(d=M(Math.pow(d,b)),g=M(Math.pow(g,b)),h=M(Math.pow(h,b))),s!==0||f!==0||p!==0||w!==0||F!==0||k!==0){const l=.2126*d+.7152*g+.0722*h,v=1-W(.18,.62,l),S=1-W(.04,.32,l),x=W(.38,.84,l),A=W(.7,.98,l),L=nt(l),E=f*v*.28+s*x*.24+w*S*.2+p*A*.2+F*L*.18+k*(.12+v*.06);if(d=M(d+E),g=M(g+E),h=M(h+E),k>0){const U=(d+g+h)/3,Y=k*.16;d=M(d*(1-Y)+U*Y),g=M(g*(1-Y)+U*Y),h=M(h*(1-Y)+U*Y)}}y[u]=Math.round(d*255),y[u+1]=Math.round(g*255),y[u+2]=Math.round(h*255)}if(T>1e-4||O>1e-4){const u=new Uint8ClampedArray(y),d=e*4;for(let g=1;g<r-1;g++)for(let h=1;h<e-1;h++){const l=g*d+h*4,v=(u[l-4]+u[l+4]+u[l-d]+u[l+d]+u[l]*4)/8,S=(u[l-3]+u[l+5]+u[l-d+1]+u[l+d+1]+u[l+1]*4)/8,x=(u[l-2]+u[l+6]+u[l-d+2]+u[l+d+2]+u[l+2]*4)/8,A=(.2126*u[l]+.7152*u[l+1]+.0722*u[l+2])/255,L=Math.min(1.8,T*1.45+O*.9*nt(A));y[l]=N(u[l]+(u[l]-v)*L),y[l+1]=N(u[l+1]+(u[l+1]-S)*L),y[l+2]=N(u[l+2]+(u[l+2]-x)*L)}}if(z>1e-4){const u=z*26;for(let d=0;d<r;d++)for(let g=0;g<e;g++){const h=(d*e+g)*4,l=(.2126*y[h]+.7152*y[h+1]+.0722*y[h+2])/255,v=.4+nt(l)*.9,S=(bt(g,d)-.5)*u*v,x=(bt(g,d,1)-.5)*u*.22*z;y[h]=N(y[h]+S+x),y[h+1]=N(y[h+1]+S*.88),y[h+2]=N(y[h+2]+S-x)}}if(R>1e-4){const u=(e-1)/2,d=(r-1)/2,g=Math.sqrt(u*u+d*d)||1;for(let h=0;h<r;h++)for(let l=0;l<e;l++){const v=(h*e+l)*4,S=l-u,x=h-d,A=Math.sqrt(S*S+x*x)/g,E=1-W(.32,1,A)*R*.62;y[v]=N(y[v]*E),y[v+1]=N(y[v+1]*E),y[v+2]=N(y[v+2]*E)}}t.putImageData(i,0,0)}function ne(t,e,r,n,i,a=1,c,o=!0){const m=G(n,i);t.width=Math.max(2,Math.round(m.w*a)),t.height=Math.max(2,Math.round(m.h*a));const s=t.getContext("2d");if(!s)return;const f=Tt(n.w,n.h,i.rotation),p=i.crop??{x:0,y:0,width:f.w,height:f.h},w=i.scale?.fit??"force",{src:F,dst:T}=it({width:p.width,height:p.height},m,w);w==="contain"&&(s.fillStyle="#000",s.fillRect(0,0,t.width,t.height)),s.filter=at(i.filters,i.filterPreset),s.save(),w==="contain"&&(s.beginPath(),s.rect(a*T.x,a*T.y,a*T.width,a*T.height),s.clip()),s.translate(a*T.x,a*T.y),s.scale(a*T.width/F.width,a*T.height/F.height),s.translate(-(p.x+F.x),-(p.y+F.y)),s.translate(f.w/2,f.h/2),s.rotate(i.rotation*St),s.scale(i.flipX?-1:1,i.flipY?-1:1);const O=it({width:r.w,height:r.h},{w:n.w,h:n.h},"cover");if(s.drawImage(e,O.src.x,O.src.y,O.src.width,O.src.height,-n.w/2,-n.h/2,n.w,n.h),s.restore(),s.filter="none",Mt(s,t.width,t.height,i.filters),o&&i.overlays?.length){const z=Number.isFinite(i?.__mePreviewTimelineTime)?Number(i.__mePreviewTimelineTime):null,k=z==null?i.overlays:jt(i.overlays,z),R=k.map((b,P)=>({overlay:b,index:P})).filter(b=>ut(b.overlay)).sort((b,P)=>{const H=ht(P.overlay)-ht(b.overlay);if(H!==0)return H;const $=dt(b.overlay)-dt(P.overlay);return Math.abs($)>1e-6?$:b.index-P.index}),_=k.filter(b=>!ut(b));s.setTransform(a,0,0,a,0,0),R.forEach(b=>{if(b.overlay?.type==="filter"){s.setTransform(1,0,0,1,0,0),Zt(s,t.width,t.height,b.overlay),s.setTransform(a,0,0,a,0,0);return}if(b.overlay?.type==="adjust"){s.setTransform(1,0,0,1,0,0),te(s,t.width,t.height,b.overlay),s.setTransform(a,0,0,a,0,0);return}Z(s,b.overlay,c)}),tt(s,_,c),s.setTransform(1,0,0,1,0,0)}}function re(t,e){return new Promise(r=>{const n=()=>{t.removeEventListener("seeked",n),r()};t.addEventListener("seeked",n),t.currentTime=Math.min(Math.max(0,e),t.duration||e)})}async function ie(t,e,r=160){const n=t.duration;if(!n||!isFinite(n)||e<=0)return[];const i=t.videoWidth||16,a=t.videoHeight||9,c=Math.min(r,i),o=Math.max(1,Math.round(c*a/i)),m=document.createElement("canvas");m.width=c,m.height=o;const s=m.getContext("2d");if(!s)return[];const f=[];for(let p=0;p<e;p++)await re(t,n*(p+.5)/e),s.drawImage(t,0,0,c,o),f.push(m.toDataURL("image/jpeg",.6));return f}function ae(t,e={}){const r=e.mode??"overlay",n=document.createElement("button");n.type="button",n.className=["me-fullscreen-toggle",e.className].filter(Boolean).join(" "),n.dataset.meFullscreenToggle="true",n.dataset.mode=r,n.title="\u5168\u5C4F / \u9000\u51FA\u5168\u5C4F",n.style.cssText=[r==="overlay"?"position:absolute;left:8px;bottom:8px;z-index:30;":"position:static;","width:32px;height:32px;padding:0;","display:inline-flex;align-items:center;justify-content:center;","border:1px solid var(--me-border,#26262b);border-radius:6px;","background:var(--me-chip,#1c1c20);color:var(--me-fg,#e7e7ee);","cursor:pointer;font-size:15px;line-height:1;opacity:0.9;font:inherit;"].join(""),t.classList.add("me-fullscreen-host");const i=()=>{const o=document.fullscreenElement===t;n.textContent=o?"\xD7":"\u26F6",n.setAttribute("aria-label",o?"\u9000\u51FA\u5168\u5C4F":"\u5168\u5C4F"),t.classList.toggle("me-is-fullscreen",o),t.dataset.meFullscreen=o?"true":"false"};i();const a=()=>i(),c=()=>{(document.fullscreenElement===t?document.exitFullscreen?.():t.requestFullscreen?.())?.catch?.(()=>{})};return n.addEventListener("click",c),document.addEventListener("fullscreenchange",a),{button:n,dispose:()=>{document.removeEventListener("fullscreenchange",a),n.removeEventListener("click",c),n.remove(),t.classList.remove("me-fullscreen-host","me-is-fullscreen"),delete t.dataset.meFullscreen}}}export{Kt as buildVideoExportFormData,ae as createFullscreenToggle,Z as drawOverlay,tt as drawOverlays,ne as drawVideoFrame,Gt as fitStickerBox,ie as generateThumbnails,K as getOverlayRotation,Dt as hitTestOverlay,gt as loadOverlayImages,mt as overlayBBox,et as renderOverlaysToPng,Jt as rotateOverlay,Vt as scaleOverlay,qt as translateOverlay};
@@ -0,0 +1 @@
1
+ import{z as t}from"zod";var l={color:t.string().max(32),width:t.number().positive().max(200)},m={rotation:t.number().min(-180).max(180).optional()},f={startAt:t.number().min(0).optional(),endAt:t.number().min(0).optional(),timelineTrack:t.number().int().min(0).max(99).optional()},p=t.discriminatedUnion("type",[t.object({type:t.literal("pen"),points:t.array(t.number()).min(4),...l,...m}),t.object({type:t.literal("line"),x1:t.number(),y1:t.number(),x2:t.number(),y2:t.number(),...l,...m}),t.object({type:t.literal("arrow"),x1:t.number(),y1:t.number(),x2:t.number(),y2:t.number(),...l,...m}),t.object({type:t.literal("rect"),x:t.number(),y:t.number(),w:t.number(),h:t.number(),...l,...m}),t.object({type:t.literal("ellipse"),x:t.number(),y:t.number(),w:t.number(),h:t.number(),...l,...m}),t.object({type:t.literal("text"),x:t.number(),y:t.number(),text:t.string().max(500),color:t.string().max(32),fontSize:t.number().positive().max(512),startAt:t.number().min(0).optional(),endAt:t.number().min(0).optional(),timelineTrack:t.number().int().min(0).max(99).optional(),...m}),t.object({type:t.literal("sticker"),x:t.number(),y:t.number(),w:t.number().positive(),h:t.number().positive(),emoji:t.string().max(16).optional(),src:t.string().optional(),startAt:t.number().min(0).optional(),endAt:t.number().min(0).optional(),timelineTrack:t.number().int().min(0).max(99).optional(),...m}),t.object({type:t.literal("filter"),x:t.number(),y:t.number(),w:t.number().positive(),h:t.number().positive(),filterPreset:t.string().max(32).optional(),...f,...m}),t.object({type:t.literal("adjust"),x:t.number(),y:t.number(),w:t.number().positive(),h:t.number().positive(),brightness:t.number().min(-1).max(1).default(0),contrast:t.number().min(-1).max(1).default(0),saturation:t.number().min(-1).max(1).default(0),temperature:t.number().min(-1).max(1).default(0),tint:t.number().min(-1).max(1).default(0),vibrance:t.number().min(-1).max(1).default(0),gamma:t.number().min(-1).max(1).default(0),highlights:t.number().min(-1).max(1).default(0),shadows:t.number().min(-1).max(1).default(0),whites:t.number().min(-1).max(1).default(0),blacks:t.number().min(-1).max(1).default(0),lightSense:t.number().min(-1).max(1).default(0),sharpen:t.number().min(0).max(1).default(0),clarity:t.number().min(0).max(1).default(0),grain:t.number().min(0).max(1).default(0),fade:t.number().min(0).max(1).default(0),vignette:t.number().min(0).max(1).default(0),...f,...m})]),x=t.object({srcIdx:t.number().int().min(0).max(7),in:t.number().min(0),out:t.number().min(0)}),h=t.object({srcIdx:t.number().int().min(0).max(2),track:t.number().int().min(0).default(0),startAt:t.number().min(0),in:t.number().min(0),out:t.number().min(0),speed:t.number().min(.5).max(2).default(1),volume:t.number().min(0).max(2),fadeIn:t.number().min(0).default(0),fadeOut:t.number().min(0).default(0)}),C=t.object({type:t.enum(["none","fade","slide","wipe","flip","clockWipe","star","circle","rectangle"]).default("none"),duration:t.number().min(0).max(2).default(.4)}),I=t.object({fileName:t.string().max(120).optional(),format:t.enum(["mp4","mov","mxf"]).default("mp4"),width:t.number().int().min(2).max(8192).optional(),height:t.number().int().min(2).max(8192).optional(),frameRate:t.number().int().min(12).max(120).default(30),videoBitrateKbps:t.number().int().min(100).max(5e4).optional(),audioBitrateKbps:t.number().int().min(32).max(1024).optional(),audioCodec:t.enum(["aac","mp3"]).default("aac")}).optional(),S=t.object({clips:t.array(x).min(1).max(50),audioClips:t.array(h).max(8).default([]),canvas:t.object({w:t.number().int().min(2).max(4096),h:t.number().int().min(2).max(4096)}),crop:t.object({x:t.number().min(0),y:t.number().min(0),width:t.number().positive(),height:t.number().positive()}).optional(),scale:t.object({width:t.number().positive(),height:t.number().positive(),fit:t.enum(["contain","cover","force"])}).optional(),rotation:t.number().min(-180).max(180).default(0),flipX:t.boolean().default(!1),flipY:t.boolean().default(!1),filters:t.object({brightness:t.number().min(-1).max(1).default(0),contrast:t.number().min(-1).max(1).default(0),saturation:t.number().min(-1).max(1).default(0),temperature:t.number().min(-1).max(1).default(0),tint:t.number().min(-1).max(1).default(0),vibrance:t.number().min(-1).max(1).default(0),gamma:t.number().min(-1).max(1).default(0),highlights:t.number().min(-1).max(1).default(0),shadows:t.number().min(-1).max(1).default(0),whites:t.number().min(-1).max(1).default(0),blacks:t.number().min(-1).max(1).default(0),lightSense:t.number().min(-1).max(1).default(0),sharpen:t.number().min(0).max(1).default(0),clarity:t.number().min(0).max(1).default(0),grain:t.number().min(0).max(1).default(0),fade:t.number().min(0).max(1).default(0),vignette:t.number().min(0).max(1).default(0)}).default({brightness:0,contrast:0,saturation:0,temperature:0,tint:0,vibrance:0,gamma:0,highlights:0,shadows:0,whites:0,blacks:0,lightSense:0,sharpen:0,clarity:0,grain:0,fade:0,vignette:0}),filterPreset:t.string().max(32).optional(),overlays:t.array(p).max(200).optional(),transitions:t.array(C).max(49).default([]),keepAudio:t.boolean().default(!0),poster:t.object({time:t.number().min(0)}).optional(),exportSettings:I}).superRefine((e,r)=>{e.clips.forEach((n,i)=>{n.out<=n.in&&r.addIssue({code:t.ZodIssueCode.custom,message:`clips[${i}].out \u5FC5\u987B\u5927\u4E8E in`,path:["clips",i,"out"]})}),e.audioClips?.forEach((n,i)=>{n.out<=n.in&&r.addIssue({code:t.ZodIssueCode.custom,message:`audioClips[${i}].out \u5FC5\u987B\u5927\u4E8E in`,path:["audioClips",i,"out"]})}),(e.canvas.w%2!==0||e.canvas.h%2!==0)&&r.addIssue({code:t.ZodIssueCode.custom,message:"canvas \u5BBD\u9AD8\u5FC5\u987B\u4E3A\u5076\u6570",path:["canvas"]}),e.exportSettings?.width!=null&&e.exportSettings.width%2!==0&&r.addIssue({code:t.ZodIssueCode.custom,message:"exportSettings.width \u5FC5\u987B\u4E3A\u5076\u6570",path:["exportSettings","width"]}),e.exportSettings?.height!=null&&e.exportSettings.height%2!==0&&r.addIssue({code:t.ZodIssueCode.custom,message:"exportSettings.height \u5FC5\u987B\u4E3A\u5076\u6570",path:["exportSettings","height"]})});function j(){return{clips:[],audioClips:[],canvas:{w:2,h:2},rotation:0,flipX:!1,flipY:!1,filters:{brightness:0,contrast:0,saturation:0,temperature:0,tint:0,vibrance:0,gamma:0,highlights:0,shadows:0,whites:0,blacks:0,lightSense:0,sharpen:0,clarity:0,grain:0,fade:0,vignette:0},transitions:[],keepAudio:!0}}var o=.1;function b(e){return e.out-e.in}function g(e){return e.reduce((r,n)=>r+b(n),0)}function k(e,r){let n=0;for(let i=0;i<r&&i<e.length;i++)n+=b(e[i]);return n}function v(e,r){if(!e.length||r<0)return null;let n=0;for(let i=0;i<e.length;i++){const a=b(e[i]);if(r<n+a)return{idx:i,srcTime:e[i].in+(r-n)};n+=a}if(Math.abs(r-n)<1e-9||r<=n){const i=e.length-1;return{idx:i,srcTime:e[i].out}}return null}function E(e,r){const n=v(e,r);if(!n)return e;const i=e[n.idx];return n.srcTime<i.in+o||n.srcTime>i.out-o?e:[...e.slice(0,n.idx),{...i,out:n.srcTime},{...i,in:n.srcTime},...e.slice(n.idx+1)]}function T(e,r){return e.length<=1||!e[r]?e:e.filter((n,i)=>i!==r)}function N(e,r){const n=e[r];return n?[...e.slice(0,r+1),{...n},...e.slice(r+1)]:e}function B(e,r,n){if(r===n||!e[r]||n<0||n>=e.length)return e;const i=[...e],[a]=i.splice(r,1);return i.splice(n,0,a),i}function D(e,r,n,i,a){if(!e[r])return e;const u=e.map(s=>({...s}));return n==="in"?u[r].in=Math.min(Math.max(i,0),u[r].out-o):u[r].out=Math.max(Math.min(i,a),u[r].in+o),u}function F(e,r,n){const i=Math.max(Math.min(e.out,r),o),a=Math.min(Math.max(e.in,0),i-o),d=Math.min(Math.max(e.startAt,0),Math.max(0,n-o)),u=Math.max(o,i-a),s=Math.min(Math.max(Number(e.speed)||1,.5),2),M=Number.isInteger(e.track)&&e.track>=0?e.track:0,c=Math.min(Math.max(Number(e.fadeIn)||0,0),u),A=Math.min(Math.max(Number(e.fadeOut)||0,0),Math.max(0,u-c));return{...e,track:M,in:a,out:i,startAt:d,speed:s,fadeIn:c,fadeOut:A}}function O(e=[]){return(e??[]).reduce((r,n)=>{if(n?.type!=="text"&&n?.type!=="sticker")return r;const i=Number.isFinite(n?.startAt)?Math.max(0,Number(n.startAt)):0,a=Number.isFinite(n?.endAt)?Math.max(i,Number(n.endAt)):i;return Math.max(r,a)},0)}function P(e,r=[],n=[]){const i=g(e),a=r.reduce((u,s)=>Math.max(u,s.startAt+(s.out-s.in)),0),d=O(n);return Math.max(i,a,d)}function Z(e){return[...new Set(e.map(r=>r.srcIdx))].sort((r,n)=>r-n)}function R(e,r){const n=new Map(r.map((i,a)=>[i,a]));return e.map(i=>({...i,srcIdx:n.get(i.srcIdx)??0}))}var H=100;function V(e){return{past:[],present:e,future:[]}}function X(e,r){if(r===e.present)return e;const n=[...e.past,e.present];return n.length>H&&n.shift(),{past:n,present:r,future:[]}}function _(e,r){return r===e.present?e:{...e,present:r}}function y(e){return e.past.length>0}function w(e){return e.future.length>0}function z(e){return y(e)?{past:e.past.slice(0,-1),present:e.past[e.past.length-1],future:[e.present,...e.future]}:e}function K(e){if(!w(e))return e;const[r,...n]=e.future;return{past:[...e.past,e.present],present:r,future:n}}export{h as AudioClip,x as Clip,o as MIN_CLIP,p as Overlay,S as VideoEditState,w as canRedo,y as canUndo,F as clampAudioClip,b as clipDuration,k as clipStartsAt,P as contentDuration,V as createHistory,j as defaultVideoEditState,N as duplicateClip,v as locateOutput,X as pushHistory,K as redo,R as remapSrcIndices,T as removeClip,B as reorderClips,_ as replacePresent,E as splitAtOutput,g as totalDuration,D as trimClipEdge,z as undo,Z as usedVideoSrcIndices};
@@ -0,0 +1 @@
1
+ var s=Math.PI/180;function c(t,h,n){const r=o(n);if(r===0||r===180)return{w:t,h};if(r===90||r===270)return{w:h,h:t};const a=r*s;return{w:Math.round(Math.abs(t*Math.cos(a))+Math.abs(h*Math.sin(a))),h:Math.round(Math.abs(t*Math.sin(a))+Math.abs(h*Math.cos(a)))}}function o(t){return(t%360+360)%360}function i(t){const h=Math.round(t);return h-h%2}function w(t,h,n=40){const r=Math.min(Math.max(n,t.width),h.w),a=Math.min(Math.max(n,t.height),h.h),l=Math.min(Math.max(0,t.x),h.w-r),M=Math.min(Math.max(0,t.y),h.h-a);return{x:Math.round(l),y:Math.round(M),width:Math.round(r),height:Math.round(a)}}function e(t,h){let n=t.w,r=n/h;return r>t.h&&(r=t.h,n=r*h),{x:Math.round((t.w-n)/2),y:Math.round((t.h-r)/2),width:Math.round(n),height:Math.round(r)}}function f(t,h,n){const r={x:0,y:0,width:t.width,height:t.height},a={x:0,y:0,width:h.w,height:h.h};return n==="cover"?{src:e({w:t.width,h:t.height},h.w/h.h),dst:a}:n==="contain"?{src:r,dst:e({w:h.w,h:h.h},t.width/t.height)}:{src:r,dst:a}}function g(t,h){if(h.scale)return{w:i(h.scale.width),h:i(h.scale.height)};if(h.crop)return{w:i(h.crop.width),h:i(h.crop.height)};const n=c(t.w,t.h,h.rotation);return{w:i(n.w),h:i(n.h)}}var u=[{id:"bw",label:"\u9ED1\u767D",vf:"hue=s=0",css:"grayscale(1)"},{id:"sepia",label:"\u590D\u53E4",vf:"colorchannelmixer=.393:.769:.189:0:.349:.686:.168:0:.272:.534:.131",css:"sepia(0.85)"},{id:"warm",label:"\u6696\u9633",vf:"colorbalance=rs=.15:gs=.04:bs=-.15",css:"sepia(0.25) saturate(1.25) brightness(1.03)"},{id:"cool",label:"\u51B7\u8C03",vf:"colorbalance=rs=-.14:bs=.16",css:"hue-rotate(12deg) saturate(0.95) brightness(1.02)"},{id:"vivid",label:"\u9C9C\u8273",vf:"eq=saturation=1.45:contrast=1.08",css:"saturate(1.45) contrast(1.08)"}];function d(t){return t?u.find(h=>h.id===t):void 0}function v(t,h){const n=d(h)?.css??"";return[`brightness(${1+t.brightness})`,`contrast(${1+t.contrast})`,`saturate(${1+t.saturation})`,n].filter(Boolean).join(" ")}export{s as DEG2RAD,u as FILTER_PRESETS,v as buildFilterCss,e as centeredMaxRect,w as clampRect,i as evenize,d as findFilterPreset,f as fitRects,o as normalizeDeg,g as outputSize,c as rotatedSize};
@@ -0,0 +1 @@
1
+ var c={"tool.trim":"\u526A\u8F91","tool.crop":"\u88C1\u526A","tool.tune":"\u8C03\u8272","tool.filter":"\u6EE4\u955C","tool.annotate":"\u6807\u6CE8","tool.sticker":"\u8D34\u7EB8","tool.resize":"\u6BD4\u4F8B","tune.brightness":"\u4EAE\u5EA6","tune.contrast":"\u5BF9\u6BD4","tune.saturation":"\u9971\u548C","tune.gamma":"Gamma","overlay.select":"\u9009\u62E9","overlay.pen":"\u753B\u7B14","overlay.eraser":"\u6A61\u76AE","overlay.line":"\u76F4\u7EBF","overlay.arrow":"\u7BAD\u5934","overlay.rect":"\u77E9\u5F62","overlay.ellipse":"\u692D\u5706","overlay.text":"\u6587\u5B57","overlay.color":"\u7EBF\u8272","overlay.width":"\u7EBF\u5BBD","overlay.copySelected":"\u590D\u5236","overlay.delSelected":"\u5220\u9664\u9009\u4E2D","overlay.editSelected":"\u7F16\u8F91","overlay.pickImage":"\u9009\u62E9\u56FE\u7247","overlay.hint":"\u70B9 emoji/\u56FE\u7247\u6DFB\u52A0 \u2192 \u753B\u5E03\u4E0A\u62D6\u52A8\u6446\u4F4D,\u62D6\u53F3\u4E0B\u89D2\u7D2B\u8272\u628A\u624B\u7F29\u653E","overlay.textPlaceholder":"\u8F93\u5165\u6587\u5B57,\u56DE\u8F66\u786E\u8BA4","filter.none":"\u539F\u56FE","filter.bw":"\u9ED1\u767D","filter.sepia":"\u590D\u53E4","filter.warm":"\u6696\u9633","filter.cool":"\u51B7\u8C03","filter.vivid":"\u9C9C\u8273","ratio.orig":"\u539F\u59CB","ratio.free":"\u81EA\u7531\u6BD4\u4F8B","ratio.9:16":"\u7AD6\u5C4F 9:16","ratio.16:9":"\u6A2A\u5C4F 16:9","ratio.1:1":"\u65B9\u5F62 1:1","ratio.4:5":"\u7AD6\u56FE 4:5","act.fit":"\u9002\u5E94","act.zoomFit":"\u7F29\u653E\u81F3\u9002\u5F53\u5927\u5C0F","act.zoomTo":"\u7F29\u653E\u81F3 {value}%","act.split":"\u5206\u5272","act.copy":"\u590D\u5236","act.delete":"\u5220\u9664","act.restore":"\u8FD8\u539F","act.deleteMusic":"\u5220\u9664\u97F3\u4E50","act.cancel":"\u53D6\u6D88","act.exportPoster":"\u5BFC\u51FA\u5C01\u9762","act.exporting":"\u5BFC\u51FA\u4E2D\u2026","act.poster":"\u{1F5BC} \u5C01\u9762","act.again":"\u518D\u6B21\u4E0B\u8F7D","act.saveDrive":"\u5B58\u7F51\u76D8","act.changeImage":"\u2190 \u6362\u4E00\u5F20","act.changeVideo":"\u2190 \u6362\u4E00\u4E2A","crop.rotateLeft":"\u21BA \u5411\u5DE6\u65CB\u8F6C","crop.flipX":"\u21CB \u6C34\u5E73\u7FFB\u8F6C","crop.flipY":"\u21F5 \u5782\u76F4\u7FFB\u8F6C","crop.rotateLeftShort":"\u5DE6\u8F6C","crop.flipXShort":"\u6A2A\u7FFB","crop.flipYShort":"\u7AD6\u7FFB","tip.close":"\u5173\u95ED(\u6362\u6587\u4EF6)","tip.undo":"\u64A4\u9500","tip.redo":"\u91CD\u505A","tip.resetOpened":"\u91CD\u7F6E\u5230\u6253\u5F00\u6587\u4EF6\u65F6","tip.previewZoom":"\u9884\u89C8\u7F29\u653E\u6BD4\u4F8B","tip.previewZoomOut":"\u7F29\u5C0F\u9884\u89C8","tip.previewZoomIn":"\u653E\u5927\u9884\u89C8","tip.previewZoomFit":"\u9002\u5E94\u9884\u89C8","tip.previewPointer":"\u6307\u9488\u5DE5\u5177","tip.previewPan":"\u624B\u5DE5\u5177\uFF1A\u62D6\u52A8\u753B\u9762","tip.poster":"\u9884\u89C8\u5E76\u9009\u62E9\u5C01\u9762\u5E27","tip.keepAudio":"\u539F\u89C6\u9891\u58F0\u97F3\u5F00\u5173(\u4E0E\u97F3\u4E50\u6DF7\u97F3;\u9884\u89C8\u540C\u6B65)","tip.split":"\u5728\u64AD\u653E\u5934\u5904\u628A\u5F53\u524D\u7247\u6BB5\u4E00\u5206\u4E3A\u4E8C","tip.zoomOut":"\u7F29\u5C0F\u65F6\u95F4\u8F74(Ctrl+\u6EDA\u8F6E)","tip.zoomIn":"\u653E\u5927\u65F6\u95F4\u8F74(Ctrl+\u6EDA\u8F6E)","tip.fit":"\u7F29\u653E\u5230\u9002\u5E94\u5BBD\u5EA6","tip.addVideo":"\u6DFB\u52A0\u89C6\u9891\u7247\u6BB5","tip.addAudio":"\u6DFB\u52A0\u97F3\u4E50(\u97F3\u9891\u6587\u4EF6,\u6216\u9009\u542B\u58F0\u97F3\u7684\u89C6\u9891\u81EA\u52A8\u63D0\u53D6\u97F3\u8F68;\u4E0E\u539F\u58F0\u6DF7\u97F3)","tip.dupClip":"\u590D\u5236\u8BE5\u7247\u6BB5(\u63D2\u5230\u5176\u540E)","tip.delClip":"\u5220\u9664\u8BE5\u7247\u6BB5","tip.lockAspect":"\u9501\u5B9A\u7EB5\u6A2A\u6BD4","tip.dblConfirm":"\u53CC\u51FB\u786E\u8BA4\u88C1\u526A","err.notVideo":"\u8BF7\u9009\u62E9\u89C6\u9891\u6587\u4EF6","err.maxVideo":"\u6700\u591A {max} \u4E2A\u89C6\u9891\u7D20\u6750","err.videoLoad":"\u89C6\u9891\u52A0\u8F7D\u5931\u8D25,\u8BF7\u6362\u4E00\u4E2A\u6587\u4EF6","err.notAudio":"\u8BF7\u9009\u62E9\u97F3\u9891\u6587\u4EF6(mp3/wav/m4a),\u6216\u542B\u58F0\u97F3\u7684\u89C6\u9891(\u81EA\u52A8\u63D0\u53D6\u97F3\u8F68)","err.maxAudio":"\u6700\u591A {max} \u4E2A\u97F3\u9891\u7D20\u6750","err.audioLoad":"\u97F3\u9891\u52A0\u8F7D\u5931\u8D25,\u8BF7\u6362\u4E00\u4E2A\u6587\u4EF6","err.processFailed":"\u5904\u7406\u5931\u8D25","err.posterFailed":"\u5C01\u9762\u6E32\u67D3\u5931\u8D25","err.canvas":"canvas \u4E0D\u53EF\u7528","err.imageRead":"\u56FE\u7247\u8BFB\u53D6\u5931\u8D25,\u8BF7\u6362\u4E00\u5F20","err.notImage":"\u8BF7\u9009\u62E9\u56FE\u7247\u6587\u4EF6","err.fileType":"\u53EA\u652F\u6301\u56FE\u7247\u6216\u89C6\u9891\u6587\u4EF6","err.saveDrive":"\u5B58\u7F51\u76D8\u5931\u8D25","msg.processing":"\u6B63\u5728\u5BFC\u51FA\u4E2D\u2026","msg.exportingHint":"\u8BF7\u7A0D\u5019\uFF0C\u5BFC\u51FA\u5B8C\u6210\u540E\u4F1A\u81EA\u52A8\u8FD4\u56DE\u7ED3\u679C\u3002","msg.done":"\u5B8C\u6210 \u2713","msg.loading":"\u7D20\u6750\u52A0\u8F7D\u4E2D\u2026","msg.exported":"\u5DF2\u5BFC\u51FA\uFF1A","msg.saving":"\u5B58\u7F51\u76D8\u4E2D\u2026","msg.saved":"\u5DF2\u5B58\u5230\u7F51\u76D8 \u2713","lbl.ratioSection":"\u753B\u9762\u6BD4\u4F8B(\u88C1\u526A,\u4E0D\u53D8\u5F62)","lbl.dragToReposition":"\u2194 \u62D6\u52A8\u9884\u89C8\u53EF\u8C03\u6574\u88C1\u526A\u4F4D\u7F6E","lbl.sizeSection":"\u5BFC\u51FA\u5C3A\u5BF8(\u50CF\u7D20;\u6BD4\u4F8B\u4E0D\u7B26\u65F6 cover \u5C45\u4E2D\u88C1\u526A)","lbl.currentOut":"\u5F53\u524D\u8F93\u51FA","lbl.zoomSize":"\u5927\u5C0F","lbl.noScale":"(\u672A\u7F29\u653E)","lbl.coverNote":"\xB7 \u6BD4\u4F8B\u4E0D\u4E00\u81F4\u65F6\u5C45\u4E2D\u88C1\u526A(cover),\u4E0D\u53D8\u5F62","lbl.audioTrackHint":"\u266A \u97F3\u9891\u8F68(\u53F3\u4FA7 \uFF0B \u6DFB\u52A0\u97F3\u4E50,\u4E0E\u539F\u58F0\u6DF7\u97F3)","lbl.volume":"\u97F3\u91CF","lbl.volNote":"(\u9884\u89C8\u6700\u5927 100%,\u5BFC\u51FA\u6309\u8BBE\u5B9A\u503C)","lbl.music":"\u97F3\u4E50","kbd.fit":"\u21E7 F","poster.title":"\u9009\u62E9\u5C01\u9762\u5E27","panel.title":"\u5A92\u4F53\u7F16\u8F91\u5668","panel.subtitle":"\u4E0A\u4F20\u56FE\u7247 / \u89C6\u9891\uFF0C\u88C1\u526A \xB7 \u6EE4\u955C \xB7 \u6587\u5B57 \xB7 \u5BFC\u51FA","panel.pick":"\u70B9\u51FB\u9009\u62E9\u56FE\u7247\u6216\u89C6\u9891","panel.pickHint":"\u56FE\u7247\u7528 Filerobot \xB7 \u89C6\u9891\u53EF\u88C1\u526A/\u9759\u97F3/\u5C01\u9762"},B={"tool.trim":"Trim","tool.crop":"Crop","tool.tune":"Tune","tool.filter":"Filters","tool.annotate":"Annotate","tool.sticker":"Stickers","tool.resize":"Ratio","tune.brightness":"Brightness","tune.contrast":"Contrast","tune.saturation":"Saturation","tune.gamma":"Gamma","overlay.select":"Select","overlay.pen":"Pen","overlay.eraser":"Eraser","overlay.line":"Line","overlay.arrow":"Arrow","overlay.rect":"Rect","overlay.ellipse":"Ellipse","overlay.text":"Text","overlay.color":"Color","overlay.width":"Width","overlay.copySelected":"Copy","overlay.delSelected":"Delete selected","overlay.editSelected":"Edit","overlay.pickImage":"Pick image","overlay.hint":"Tap emoji/image to add \u2192 drag to place, drag the purple corner handle to scale","overlay.textPlaceholder":"Type text, Enter to confirm","filter.none":"Original","filter.bw":"B&W","filter.sepia":"Sepia","filter.warm":"Warm","filter.cool":"Cool","filter.vivid":"Vivid","ratio.orig":"Original","ratio.free":"Free ratio","ratio.9:16":"Portrait 9:16","ratio.16:9":"Landscape 16:9","ratio.1:1":"Square 1:1","ratio.4:5":"Vertical 4:5","act.fit":"Fit","act.zoomFit":"Zoom to fit","act.zoomTo":"Zoom to {value}%","act.split":"Split","act.copy":"Copy","act.delete":"Delete","act.restore":"Reset","act.deleteMusic":"Remove music","act.cancel":"Cancel","act.exportPoster":"Export cover","act.exporting":"Exporting\u2026","act.poster":"\u{1F5BC} Cover","act.again":"Download again","act.saveDrive":"Save to drive","act.changeImage":"\u2190 Change image","act.changeVideo":"\u2190 Change file","crop.rotateLeft":"\u21BA Rotate left","crop.flipX":"\u21CB Flip horizontal","crop.flipY":"\u21F5 Flip vertical","crop.rotateLeftShort":"Rot","crop.flipXShort":"Flip","crop.flipYShort":"Flip","tip.close":"Close (change file)","tip.undo":"Undo","tip.redo":"Redo","tip.resetOpened":"Reset to opened file","tip.previewZoom":"Preview zoom","tip.previewZoomOut":"Zoom out preview","tip.previewZoomIn":"Zoom in preview","tip.previewZoomFit":"Fit preview","tip.previewPointer":"Pointer tool","tip.previewPan":"Hand tool: pan canvas","tip.poster":"Preview and pick a cover frame","tip.keepAudio":"Original audio on/off (mixed with music; preview follows)","tip.split":"Split the current clip at the playhead","tip.zoomOut":"Zoom out timeline (Ctrl+wheel)","tip.zoomIn":"Zoom in timeline (Ctrl+wheel)","tip.fit":"Fit to width","tip.addVideo":"Add video clip","tip.addAudio":"Add music (audio file, or a video with sound to extract its track; mixed with original)","tip.dupClip":"Duplicate clip (insert after)","tip.delClip":"Delete clip","tip.lockAspect":"Lock aspect ratio","tip.dblConfirm":"Double-click to confirm crop","err.notVideo":"Please choose a video file","err.maxVideo":"Up to {max} video sources","err.videoLoad":"Failed to load video, try another file","err.notAudio":"Choose an audio file (mp3/wav/m4a), or a video with sound (audio auto-extracted)","err.maxAudio":"Up to {max} audio sources","err.audioLoad":"Failed to load audio, try another file","err.processFailed":"Processing failed","err.posterFailed":"Failed to render cover","err.canvas":"Canvas unavailable","err.imageRead":"Failed to read image, try another","err.notImage":"Please choose an image file","err.fileType":"Only image or video files are supported","err.saveDrive":"Failed to save to drive","msg.processing":"Exporting\u2026","msg.exportingHint":"Please wait. The result will be returned automatically when export finishes.","msg.done":"Done \u2713","msg.loading":"Loading media\u2026","msg.exported":"Exported: ","msg.saving":"Saving\u2026","msg.saved":"Saved to drive \u2713","lbl.ratioSection":"Frame ratio (crop, no distortion)","lbl.dragToReposition":"\u2194 Drag the preview to reposition the crop","lbl.sizeSection":"Export size (px; cover center-crop when ratios differ)","lbl.currentOut":"Output","lbl.zoomSize":"Size","lbl.noScale":"(no scaling)","lbl.coverNote":"\xB7 center-cropped (cover) when ratios differ, no distortion","lbl.audioTrackHint":"\u266A Audio track (\uFF0B on the right to add music, mixed with original)","lbl.volume":"Volume","lbl.volNote":"(preview caps at 100%, export uses the set value)","lbl.music":"Music","kbd.fit":"\u21E7 F","poster.title":"Pick a cover frame","panel.title":"Media Editor","panel.subtitle":"Upload an image / video \u2014 crop \xB7 filters \xB7 text \xB7 export","panel.pick":"Click to choose an image or video","panel.pickHint":"Images via Filerobot \xB7 videos: trim/mute/cover"},A={"tool.trim":"Editar","tool.crop":"Recortar","tool.tune":"Ajustar color","tool.filter":"Filtros","tool.annotate":"Anotar","tool.sticker":"Stickers","tool.resize":"Proporci\xF3n","tune.brightness":"Brillo","tune.contrast":"Contraste","tune.saturation":"Saturaci\xF3n","tune.gamma":"Gamma","overlay.select":"Seleccionar","overlay.pen":"Pincel","overlay.eraser":"Borrador","overlay.line":"L\xEDnea","overlay.arrow":"Flecha","overlay.rect":"Rect\xE1ngulo","overlay.ellipse":"Elipse","overlay.text":"Texto","overlay.color":"Color","overlay.width":"Grosor","overlay.copySelected":"Copiar","overlay.delSelected":"Eliminar seleccionado","overlay.editSelected":"Editar","overlay.pickImage":"Elegir imagen","overlay.hint":"Toca un emoji/imagen para a\xF1adirlo \u2192 arrastra para colocarlo, arrastra el tirador morado para escalar","overlay.textPlaceholder":"Escribe texto, Enter para confirmar","filter.none":"Original","filter.bw":"Blanco y negro","filter.sepia":"Sepia","filter.warm":"C\xE1lido","filter.cool":"Fr\xEDo","filter.vivid":"Intenso","ratio.orig":"Original","ratio.free":"Libre","ratio.9:16":"Vertical 9:16","ratio.16:9":"Horizontal 16:9","ratio.1:1":"Cuadrado 1:1","ratio.4:5":"Vertical 4:5","act.fit":"Ajustar","act.zoomFit":"Ajustar a pantalla","act.zoomTo":"Zoom al {value}%","act.split":"Dividir","act.copy":"Copiar","act.delete":"Eliminar","act.restore":"Restablecer","act.deleteMusic":"Quitar m\xFAsica","act.cancel":"Cancelar","act.exportPoster":"Exportar portada","act.exporting":"Exportando\u2026","act.poster":"\u{1F5BC} Portada","act.again":"Descargar de nuevo","act.saveDrive":"Guardar en disco","act.changeImage":"\u2190 Cambiar imagen","act.changeVideo":"\u2190 Cambiar archivo","crop.rotateLeft":"\u21BA Girar a la izquierda","crop.flipX":"\u21CB Voltear horizontal","crop.flipY":"\u21F5 Voltear vertical","crop.rotateLeftShort":"Giro","crop.flipXShort":"Flip","crop.flipYShort":"Flip","tip.close":"Cerrar (cambiar archivo)","tip.undo":"Deshacer","tip.redo":"Rehacer","tip.resetOpened":"Restablecer al archivo abierto","tip.previewZoom":"Zoom de vista previa","tip.previewZoomOut":"Reducir vista previa","tip.previewZoomIn":"Ampliar vista previa","tip.previewZoomFit":"Ajustar vista previa","tip.previewPointer":"Herramienta de puntero","tip.previewPan":"Mano: desplazar lienzo","tip.poster":"Previsualizar y elegir portada","tip.keepAudio":"Activar/desactivar audio original (mezclado con m\xFAsica; la vista previa lo refleja)","tip.split":"Dividir el clip actual en el cursor","tip.zoomOut":"Reducir l\xEDnea de tiempo (Ctrl+rueda)","tip.zoomIn":"Ampliar l\xEDnea de tiempo (Ctrl+rueda)","tip.fit":"Ajustar al ancho","tip.addVideo":"A\xF1adir clip de v\xEDdeo","tip.addAudio":"A\xF1adir m\xFAsica (archivo de audio o v\xEDdeo con sonido para extraer la pista; se mezcla con el original)","tip.dupClip":"Duplicar clip (insertar despu\xE9s)","tip.delClip":"Eliminar clip","tip.lockAspect":"Bloquear proporci\xF3n","tip.dblConfirm":"Doble clic para confirmar recorte","err.notVideo":"Elige un archivo de v\xEDdeo","err.maxVideo":"M\xE1ximo {max} v\xEDdeos","err.videoLoad":"No se pudo cargar el v\xEDdeo, prueba con otro archivo","err.notAudio":"Elige un audio (mp3/wav/m4a) o un v\xEDdeo con sonido (se extrae autom\xE1ticamente)","err.maxAudio":"M\xE1ximo {max} audios","err.audioLoad":"No se pudo cargar el audio, prueba con otro archivo","err.processFailed":"Error de procesamiento","err.posterFailed":"No se pudo renderizar la portada","err.canvas":"Canvas no disponible","err.imageRead":"No se pudo leer la imagen, prueba con otra","err.notImage":"Elige un archivo de imagen","err.fileType":"Solo se admiten archivos de imagen o v\xEDdeo","err.saveDrive":"No se pudo guardar en disco","msg.processing":"Exportando\u2026","msg.exportingHint":"Espera un momento. El resultado se devolver\xE1 autom\xE1ticamente al finalizar.","msg.done":"Listo \u2713","msg.loading":"Cargando medios\u2026","msg.exported":"Exportado: ","msg.saving":"Guardando\u2026","msg.saved":"Guardado en disco \u2713","lbl.ratioSection":"Proporci\xF3n de imagen (recorte, sin deformar)","lbl.dragToReposition":"\u2194 Arrastra la vista previa para reposicionar el recorte","lbl.sizeSection":"Tama\xF1o de exportaci\xF3n (px; recorte cover centrado si la proporci\xF3n difiere)","lbl.currentOut":"Salida","lbl.zoomSize":"Tama\xF1o","lbl.noScale":"(sin escala)","lbl.coverNote":"\xB7 recorte centrado (cover) cuando la proporci\xF3n difiere, sin deformar","lbl.audioTrackHint":"\u266A Pista de audio (\uFF0B a la derecha para a\xF1adir m\xFAsica, mezclada con el original)","lbl.volume":"Volumen","lbl.volNote":"(la vista previa limita a 100%, la exportaci\xF3n usa el valor definido)","lbl.music":"M\xFAsica","kbd.fit":"\u21E7 F","poster.title":"Elegir portada","panel.title":"Editor multimedia","panel.subtitle":"Sube una imagen / v\xEDdeo \u2014 recorta \xB7 filtros \xB7 texto \xB7 exporta","panel.pick":"Haz clic para elegir una imagen o v\xEDdeo","panel.pickHint":"Im\xE1genes con Filerobot \xB7 v\xEDdeos: cortar/silenciar/portada"},D={\u7B80:"\u7C21",\u4F53:"\u9AD4",\u56FE:"\u5716",\u9891:"\u983B",\u89C6:"\u8996",\u8F91:"\u8F2F",\u8C03:"\u8ABF",\u6EE4:"\u6FFE",\u6807:"\u6A19",\u6CE8:"\u8A3B",\u8D34:"\u8CBC",\u9009:"\u9078",\u62E9:"\u64C7",\u7EBF:"\u7DDA",\u7BAD:"\u7BAD",\u5934:"\u982D",\u590D:"\u8907",\u5220:"\u522A",\u9664:"\u9664",\u7F16:"\u7DE8",\u8FB9:"\u908A",\u8F93:"\u8F38",\u5165:"\u5165",\u786E:"\u78BA",\u8BA4:"\u8A8D",\u9971:"\u98FD",\u5BF9:"\u5C0D",\u6696:"\u6696",\u9633:"\u967D",\u51B7:"\u51B7",\u7EB5:"\u7E31",\u6A2A:"\u6A6B",\u9002:"\u9069",\u5E94:"\u61C9",\u7F29:"\u7E2E",\u5B9E:"\u5BE6",\u9645:"\u969B",\u5BFC:"\u5C0E",\u51FA:"\u51FA",\u5C01:"\u5C01",\u9762:"\u9762",\u6362:"\u63DB",\u5F20:"\u5F35",\u9884:"\u9810",\u89C8:"\u89BD",\u52A8:"\u52D5",\u58F0:"\u8072",\u5F00:"\u958B",\u5173:"\u95DC",\u4E0E:"\u8207",\u4E50:"\u6A02",\u6DF7:"\u6DF7",\u5904:"\u8655",\u8F7D:"\u8F09",\u9519:"\u932F",\u8BEF:"\u8AA4",\u8BFB:"\u8B80",\u4EC5:"\u50C5",\u7EC8:"\u7D42",\u7A0D:"\u7A0D",\u5019:"\u5019",\u8FD4\u56DE:"\u8FD4\u56DE",\u5F53\u524D:"\u76EE\u524D",\u8F93\u51FA:"\u8F38\u51FA",\u753B:"\u756B",\u53D8:"\u8B8A",\u97F3\u9891:"\u97F3\u8A0A",\u97F3\u8F68:"\u97F3\u8ECC",\u6DFB\u52A0:"\u65B0\u589E",\u5220\u9664:"\u522A\u9664",\u4FDD\u5B58:"\u5132\u5B58",\u52A0\u8F7D:"\u8F09\u5165",\u7F51\u76D8:"\u7DB2\u76E4"},d=t=>{let u=t;for(const[o,e]of Object.entries(D).sort((a,i)=>i[0].length-a[0].length))u=u.replaceAll(o,e);return u},f=Object.fromEntries(Object.entries(c).map(([t,u])=>[t,d(u)])),n={zh:c,en:B,es:A,"zh-Hant":f};function g(t,u,o){let e=n[t]?.[u]??n.zh[u]??u;if(o)for(const[a,i]of Object.entries(o))e=e.replaceAll(`{${a}}`,String(i));return e}var l=[{platform:"tiktok",postType:"video",label:"TikTok Video",shortLabel:"TT\xB7Video",ratio:"9:16",imageSize:"1440x2560",videoRatio:"9:16",videoResolution:"720p"},{platform:"instagram",postType:"post",label:"Instagram Post",shortLabel:"IG\xB7Post",ratio:"1:1",imageSize:"2048x2048"},{platform:"instagram",postType:"reels",label:"Instagram Reels",shortLabel:"IG\xB7Reels",ratio:"9:16",imageSize:"1440x2560",videoRatio:"9:16",videoResolution:"720p"},{platform:"instagram",postType:"story",label:"Instagram Story",shortLabel:"IG\xB7Story",ratio:"9:16",imageSize:"1440x2560",videoRatio:"9:16",videoResolution:"720p"},{platform:"facebook",postType:"post",label:"Facebook Post",shortLabel:"FB\xB7Post",ratio:"1:1",imageSize:"2048x2048"},{platform:"facebook",postType:"reels",label:"Facebook Reels",shortLabel:"FB\xB7Reels",ratio:"9:16",imageSize:"1440x2560",videoRatio:"9:16",videoResolution:"720p"},{platform:"youtube",postType:"video",label:"YouTube Video",shortLabel:"YT\xB7Video",ratio:"16:9",imageSize:"2560x1440",videoRatio:"16:9",videoResolution:"1080p"},{platform:"youtube",postType:"shorts",label:"YouTube Shorts",shortLabel:"YT\xB7Shorts",ratio:"9:16",imageSize:"1440x2560",videoRatio:"9:16",videoResolution:"720p"},{platform:"pinterest",postType:"pin",label:"Pinterest Pin",shortLabel:"PIN",ratio:"2:3",imageSize:"1664x2496",videoRatio:"9:16",videoResolution:"720p"},{platform:"x",postType:"post",label:"X Post",shortLabel:"X\xB7Post",ratio:"16:9",imageSize:"2560x1440",videoRatio:"16:9",videoResolution:"720p"},{platform:"linkedin",postType:"post",label:"LinkedIn Post",shortLabel:"LI\xB7Post",ratio:"1:1",imageSize:"2048x2048"},{platform:"linkedin",postType:"video",label:"LinkedIn Video",shortLabel:"LI\xB7Video",ratio:"16:9",imageSize:"2560x1440",videoRatio:"16:9",videoResolution:"1080p"},{platform:"threads",postType:"post",label:"Threads Post",shortLabel:"TH\xB7Post",ratio:"1:1",imageSize:"2048x2048"},{platform:"telegram",postType:"post",label:"Telegram Post",shortLabel:"TG\xB7Post",ratio:"1:1",imageSize:"2048x2048",videoRatio:"9:16",videoResolution:"720p"},{platform:"reddit",postType:"post",label:"Reddit Post",shortLabel:"RD\xB7Post",ratio:"16:9",imageSize:"2560x1440",videoRatio:"16:9",videoResolution:"720p"}],x={"1:1":"\u65B9\u5F62 1:1","4:5":"\u7AD6\u56FE 4:5","3:4":"\u7AD6\u56FE 3:4","9:16":"\u7AD6\u5C4F 9:16","16:9":"\u6A2A\u5C4F 16:9","2:3":"\u7AD6\u56FE 2:3","1.91:1":"\u6A2A\u5E45 1.91:1"};function r(t){const[u,o]=t.split(":").map(Number);return!u||!o?1:u/o}function F(t){const u=new Set,o=[];for(const e of t)!e||u.has(e)||(u.add(e),o.push({ratio:e,value:r(e),label:x[e]??e}));return o}var C=F(["1:1","4:5","3:4","2:3","9:16","16:9","1.91:1"]),b=F(["9:16","16:9","1:1","4:5"]);function m(t=l){const u=new Set,o=[];for(const e of t){if(!e.videoRatio)continue;const a=`${e.platform}:${e.postType}:${e.videoRatio}`;if(u.has(a))continue;u.add(a);const i=e.label.split(" ").slice(0,-1).join(" ")||e.label;o.push({platform:e.platform,postType:e.postType,label:`${i} ${e.videoRatio}`,ratio:e.videoRatio,value:r(e.videoRatio)})}return o}var h=m();function v(t=l){const u=new Map;for(const o of t){const e=u.get(o.platform);(!e||e.postType!=="post"&&o.postType==="post")&&u.set(o.platform,o)}return Array.from(u.values()).map(o=>{const[e,a]=o.imageSize.split("x").map(Number),i=o.label.split(" ").slice(0,-1).join(" ")||o.label;return{platform:o.platform,label:`${i} ${o.ratio}`,ratio:o.ratio,value:r(o.ratio),w:e,h:a}})}var y=v();function S(t,u){return t>=1?{w:Math.round(u*t/2)*2,h:u}:{w:u,h:Math.round(u/t/2)*2}}function E(t=l){const u=new Set,o=[];for(const e of t){if(!e.videoRatio||!e.videoResolution)continue;const a=e.videoResolution==="1080p"?1080:720,{w:i,h:p}=S(r(e.videoRatio),a),s=`${i}x${p}`;u.has(s)||(u.add(s),o.push({label:`${e.shortLabel} ${i}\xD7${p}`,w:i,h:p}))}return o}var R=E();function T(t,u){if(t.isDuplicated)return{};if((t.rotation??0)!==0)return{};const o=u.adjustments?.rotation??0;return o?{rotation:-o}:{}}export{l as DEFAULT_PLATFORM_TARGETS,n as EDITOR_MESSAGES,y as IMAGE_PLATFORM_PRESETS,C as IMAGE_RATIO_PRESETS,h as VIDEO_PLATFORM_RATIO_PRESETS,b as VIDEO_RATIO_PRESETS,R as VIDEO_SIZE_PRESETS,v as buildImagePlatformPresets,m as buildVideoPlatformRatioPresets,E as buildVideoSizePresets,T as compensateAnnotationRotation,r as parseRatio,g as tEditor,d as toHant};