diff --git a/.fallowrc.jsonc b/.fallowrc.jsonc index 6d92412e6..eafdcc708 100644 --- a/.fallowrc.jsonc +++ b/.fallowrc.jsonc @@ -79,6 +79,12 @@ "refreshDomEditSelection", ], }, + // domEditing barrel: re-exports consumed throughout the studio but + // fallow's static analyzer can't trace re-exports through barrel files. + { + "file": "packages/studio/src/components/editor/domEditing.ts", + "exports": ["*"], + }, // Exported for render.test.ts (exported-for-tests pattern). { "file": "packages/cli/src/commands/render.ts", diff --git a/packages/core/src/lint/rules/gsap.test.ts b/packages/core/src/lint/rules/gsap.test.ts index 167fc261b..cae448ead 100644 --- a/packages/core/src/lint/rules/gsap.test.ts +++ b/packages/core/src/lint/rules/gsap.test.ts @@ -865,4 +865,57 @@ describe("GSAP rules", () => { const finding = result.findings.find((f) => f.code === "gsap_from_opacity_noop"); expect(finding).toBeUndefined(); }); + + it("warns when gsap.timeline is created but not registered in __timelines", async () => { + const html = ` + +
+
Hello
+
+ + +`; + const result = await lintHyperframeHtml(html); + const finding = result.findings.find((f) => f.code === "gsap_timeline_not_registered"); + expect(finding).toBeDefined(); + expect(finding?.severity).toBe("warning"); + }); + + it("does NOT warn when timeline is registered in __timelines", async () => { + const html = ` + +
+
Hello
+
+ + +`; + const result = await lintHyperframeHtml(html); + const finding = result.findings.find((f) => f.code === "gsap_timeline_not_registered"); + expect(finding).toBeUndefined(); + }); + + it("does NOT warn for sub-compositions (template-based)", async () => { + const html = ` +`; + const result = await lintHyperframeHtml(html); + const finding = result.findings.find((f) => f.code === "gsap_timeline_not_registered"); + expect(finding).toBeUndefined(); + }); }); diff --git a/packages/core/src/lint/rules/gsap.ts b/packages/core/src/lint/rules/gsap.ts index 5938cb4a9..43745f619 100644 --- a/packages/core/src/lint/rules/gsap.ts +++ b/packages/core/src/lint/rules/gsap.ts @@ -785,6 +785,33 @@ export const gsapRules: LintRule[] = [ return findings; }, + // gsap_timeline_not_registered + ({ scripts, rawSource, options }) => { + const findings: HyperframeLintFinding[] = []; + const canInheritFromHost = + options.isSubComposition || rawSource.trimStart().toLowerCase().startsWith(" { const findings: HyperframeLintFinding[] = []; diff --git a/packages/core/src/runtime/init.test.ts b/packages/core/src/runtime/init.test.ts index 12d712a19..c1fa09bad 100644 --- a/packages/core/src/runtime/init.test.ts +++ b/packages/core/src/runtime/init.test.ts @@ -692,4 +692,23 @@ describe("initSandboxRuntimeModular", () => { expect(window.__playerReady).toBe(true); expect(window.__renderReady).toBe(true); }); + + it("seeks captured timeline to currentTime on initial bind", () => { + const seekTimes: number[] = []; + const tl = createMockTimeline(5); + const origTotalTime = tl.totalTime; + tl.totalTime = ((time: number, ...rest: unknown[]) => { + seekTimes.push(time); + (origTotalTime as Function).call(tl, time, ...rest); + }) as RuntimeTimelineLike["totalTime"]; + + document.body.innerHTML = ` +
+ `; + window.__timelines = { root: tl }; + initSandboxRuntimeModular(); + + expect(seekTimes.length).toBeGreaterThan(0); + expect(seekTimes[0]).toBe(0); + }); }); diff --git a/packages/core/src/runtime/init.ts b/packages/core/src/runtime/init.ts index 64c046427..5c46f7a9c 100644 --- a/packages/core/src/runtime/init.ts +++ b/packages/core/src/runtime/init.ts @@ -948,6 +948,10 @@ export function initSandboxRuntimeModular(): void { // clock not yet initialized — duration will be set during TransportClock setup } state.capturedTimeline.pause(); + const seekTime = Math.max(0, state.currentTime || 0); + if (typeof state.capturedTimeline.totalTime === "function") { + state.capturedTimeline.totalTime(seekTime, false); + } } if (resolution.diagnostics) { postRuntimeMessage({ diff --git a/packages/core/src/studio-api/routes/files.test.ts b/packages/core/src/studio-api/routes/files.test.ts index a45a988ff..6279d9852 100644 --- a/packages/core/src/studio-api/routes/files.test.ts +++ b/packages/core/src/studio-api/routes/files.test.ts @@ -327,6 +327,34 @@ const tl = gsap.timeline(); expect(anim.properties.opacity).toBe(1); }); + it("add mutation returns 400 when fromProperties provided for non-fromTo method", async () => { + const projectDir = createProjectDir(); + const EMPTY_COMP = `
`; + writeHtml(projectDir, "empty.html", EMPTY_COMP); + const app = new Hono(); + registerFileRoutes(app, createAdapter(projectDir)); + + const res = await app.request("http://localhost/projects/demo/gsap-mutations/empty.html", { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ + type: "add", + targetSelector: "#el", + method: "to", + position: 0, + duration: 0.5, + ease: "power2.out", + properties: { opacity: 1 }, + fromProperties: { opacity: 0 }, + }), + }); + expect(res.status).toBe(400); + const body = (await res.json()) as { error: string }; + expect(body.error).toContain("fromProperties"); + }); + it("edits a template-wrapped tween in place, preserving gsap.set and the IIFE", async () => { const projectDir = createProjectDir(); writeComp(projectDir, "scene.html", TEMPLATE_COMP); diff --git a/packages/core/src/studio-api/routes/files.ts b/packages/core/src/studio-api/routes/files.ts index 4e32155c6..596d79ba8 100644 --- a/packages/core/src/studio-api/routes/files.ts +++ b/packages/core/src/studio-api/routes/files.ts @@ -17,6 +17,7 @@ import { isAudioFile } from "../helpers/mime.js"; import { generateWaveformCache } from "../helpers/waveform.js"; import { validateUploadedMediaBuffer } from "../helpers/mediaValidation.js"; import { isSafePath } from "../helpers/safePath.js"; +import type { GsapAnimation } from "../../parsers/gsapSerialize.js"; import { removeElementFromHtml, patchElementInHtml, @@ -600,26 +601,44 @@ export function registerFileRoutes(api: Hono, adapter: StudioApiAdapter): void { removeAnimationFromScript, } = await loadGsapParser(); + function requireAnimation( + scriptText: string, + animationId: string, + ): { anim: GsapAnimation } | { err: Response } { + const parsed = parseGsapScript(scriptText); + const anim = parsed.animations.find((a) => a.id === animationId); + if (!anim) return { err: c.json({ error: "animation not found" }, 404) }; + return { anim }; + } + + function requireFromToAnimation( + scriptText: string, + animationId: string, + ): { anim: GsapAnimation } | { err: Response } { + const result = requireAnimation(scriptText, animationId); + if ("err" in result) return result; + if (result.anim.method !== "fromTo") + return { err: c.json({ error: "animation is not a fromTo" }, 400) }; + return result; + } + let newScript: string; // fallow-ignore-next-line complexity switch (body.type) { case "update-property": { - const parsed = parseGsapScript(block.scriptText); - const anim = parsed.animations.find((a) => a.id === body.animationId); - if (!anim) return c.json({ error: "animation not found" }, 404); + const r = requireAnimation(block.scriptText, body.animationId); + if ("err" in r) return r.err; newScript = updateAnimationInScript(block.scriptText, body.animationId, { - properties: { ...anim.properties, [body.property]: body.value }, + properties: { ...r.anim.properties, [body.property]: body.value }, }); break; } case "update-from-property": { - const parsed = parseGsapScript(block.scriptText); - const anim = parsed.animations.find((a) => a.id === body.animationId); - if (!anim) return c.json({ error: "animation not found" }, 404); - if (anim.method !== "fromTo") return c.json({ error: "animation is not a fromTo" }, 400); + const r = requireFromToAnimation(block.scriptText, body.animationId); + if ("err" in r) return r.err; newScript = updateAnimationInScript(block.scriptText, body.animationId, { - fromProperties: { ...(anim.fromProperties ?? {}), [body.property]: body.value }, + fromProperties: { ...(r.anim.fromProperties ?? {}), [body.property]: body.value }, }); break; } @@ -628,6 +647,9 @@ export function registerFileRoutes(api: Hono, adapter: StudioApiAdapter): void { break; } case "add": { + if (body.fromProperties && body.method !== "fromTo") { + return c.json({ error: "fromProperties is only valid for method=fromTo" }, 400); + } const result = addAnimationToScript(block.scriptText, { targetSelector: body.targetSelector, method: body.method, @@ -645,29 +667,25 @@ export function registerFileRoutes(api: Hono, adapter: StudioApiAdapter): void { break; } case "add-property": { - const parsed = parseGsapScript(block.scriptText); - const anim = parsed.animations.find((a) => a.id === body.animationId); - if (!anim) return c.json({ error: "animation not found" }, 404); + const r = requireAnimation(block.scriptText, body.animationId); + if ("err" in r) return r.err; newScript = updateAnimationInScript(block.scriptText, body.animationId, { - properties: { ...anim.properties, [body.property]: body.defaultValue }, + properties: { ...r.anim.properties, [body.property]: body.defaultValue }, }); break; } case "add-from-property": { - const parsed = parseGsapScript(block.scriptText); - const anim = parsed.animations.find((a) => a.id === body.animationId); - if (!anim) return c.json({ error: "animation not found" }, 404); - if (anim.method !== "fromTo") return c.json({ error: "animation is not a fromTo" }, 400); + const r = requireFromToAnimation(block.scriptText, body.animationId); + if ("err" in r) return r.err; newScript = updateAnimationInScript(block.scriptText, body.animationId, { - fromProperties: { ...(anim.fromProperties ?? {}), [body.property]: body.defaultValue }, + fromProperties: { ...(r.anim.fromProperties ?? {}), [body.property]: body.defaultValue }, }); break; } case "remove-property": { - const parsed = parseGsapScript(block.scriptText); - const anim = parsed.animations.find((a) => a.id === body.animationId); - if (!anim) return c.json({ error: "animation not found" }, 404); - const filtered = { ...anim.properties }; + const r = requireAnimation(block.scriptText, body.animationId); + if ("err" in r) return r.err; + const filtered = { ...r.anim.properties }; delete filtered[body.property]; newScript = updateAnimationInScript(block.scriptText, body.animationId, { properties: filtered, @@ -675,11 +693,9 @@ export function registerFileRoutes(api: Hono, adapter: StudioApiAdapter): void { break; } case "remove-from-property": { - const parsed = parseGsapScript(block.scriptText); - const anim = parsed.animations.find((a) => a.id === body.animationId); - if (!anim) return c.json({ error: "animation not found" }, 404); - if (anim.method !== "fromTo") return c.json({ error: "animation is not a fromTo" }, 400); - const filtered = { ...(anim.fromProperties ?? {}) }; + const r = requireFromToAnimation(block.scriptText, body.animationId); + if ("err" in r) return r.err; + const filtered = { ...(r.anim.fromProperties ?? {}) }; delete filtered[body.property]; newScript = updateAnimationInScript(block.scriptText, body.animationId, { fromProperties: filtered, diff --git a/packages/core/src/studio-api/routes/projects.ts b/packages/core/src/studio-api/routes/projects.ts index 738775de8..3627a1f04 100644 --- a/packages/core/src/studio-api/routes/projects.ts +++ b/packages/core/src/studio-api/routes/projects.ts @@ -1,7 +1,26 @@ +import { readFile } from "node:fs/promises"; +import { join } from "node:path"; import type { Hono } from "hono"; import type { StudioApiAdapter } from "../types.js"; import { walkDir } from "../helpers/safePath.js"; +const COMPOSITION_ID_RE = /data-composition-id\s*=/; + +async function filterCompositionFiles(projectDir: string, files: string[]): Promise { + const htmlFiles = files.filter((f) => f.endsWith(".html")); + const checks = await Promise.all( + htmlFiles.map(async (f) => { + try { + const content = await readFile(join(projectDir, f), "utf-8"); + return COMPOSITION_ID_RE.test(content); + } catch { + return false; + } + }), + ); + return htmlFiles.filter((_, i) => checks[i]); +} + export function registerProjectRoutes(api: Hono, adapter: StudioApiAdapter): void { // List all projects api.get("/projects", async (c) => { @@ -25,6 +44,7 @@ export function registerProjectRoutes(api: Hono, adapter: StudioApiAdapter): voi const project = await adapter.resolveProject(c.req.param("id")); if (!project) return c.json({ error: "not found" }, 404); const files = walkDir(project.dir); - return c.json({ id: project.id, dir: project.dir, title: project.title, files }); + const compositions = await filterCompositionFiles(project.dir, files); + return c.json({ id: project.id, dir: project.dir, title: project.title, files, compositions }); }); } diff --git a/packages/producer/tests/iframe-render-compat/failures/frames/actual_0_00s.png b/packages/producer/tests/iframe-render-compat/failures/frames/actual_0_00s.png index 4f0b0f1dd..b9dfb6776 100644 Binary files a/packages/producer/tests/iframe-render-compat/failures/frames/actual_0_00s.png and b/packages/producer/tests/iframe-render-compat/failures/frames/actual_0_00s.png differ diff --git a/packages/producer/tests/iframe-render-compat/failures/frames/actual_0_05s.png b/packages/producer/tests/iframe-render-compat/failures/frames/actual_0_05s.png index 334b558a0..2938802e4 100644 Binary files a/packages/producer/tests/iframe-render-compat/failures/frames/actual_0_05s.png and b/packages/producer/tests/iframe-render-compat/failures/frames/actual_0_05s.png differ diff --git a/packages/producer/tests/iframe-render-compat/failures/frames/actual_0_10s.png b/packages/producer/tests/iframe-render-compat/failures/frames/actual_0_10s.png index 4bc9a2068..64a3659b7 100644 Binary files a/packages/producer/tests/iframe-render-compat/failures/frames/actual_0_10s.png and b/packages/producer/tests/iframe-render-compat/failures/frames/actual_0_10s.png differ diff --git a/packages/producer/tests/iframe-render-compat/failures/frames/actual_0_15s.png b/packages/producer/tests/iframe-render-compat/failures/frames/actual_0_15s.png index f27c555b2..4378791ab 100644 Binary files a/packages/producer/tests/iframe-render-compat/failures/frames/actual_0_15s.png and b/packages/producer/tests/iframe-render-compat/failures/frames/actual_0_15s.png differ diff --git a/packages/producer/tests/iframe-render-compat/failures/frames/actual_0_20s.png b/packages/producer/tests/iframe-render-compat/failures/frames/actual_0_20s.png index ad7dc83e4..6da914846 100644 Binary files a/packages/producer/tests/iframe-render-compat/failures/frames/actual_0_20s.png and b/packages/producer/tests/iframe-render-compat/failures/frames/actual_0_20s.png differ diff --git a/packages/producer/tests/iframe-render-compat/failures/frames/actual_0_25s.png b/packages/producer/tests/iframe-render-compat/failures/frames/actual_0_25s.png index f4fb427ff..85ba77d53 100644 Binary files a/packages/producer/tests/iframe-render-compat/failures/frames/actual_0_25s.png and b/packages/producer/tests/iframe-render-compat/failures/frames/actual_0_25s.png differ diff --git a/packages/producer/tests/iframe-render-compat/failures/frames/actual_0_30s.png b/packages/producer/tests/iframe-render-compat/failures/frames/actual_0_30s.png index b01eb18f2..e5c54cbef 100644 Binary files a/packages/producer/tests/iframe-render-compat/failures/frames/actual_0_30s.png and b/packages/producer/tests/iframe-render-compat/failures/frames/actual_0_30s.png differ diff --git a/packages/producer/tests/iframe-render-compat/failures/frames/actual_0_35s.png b/packages/producer/tests/iframe-render-compat/failures/frames/actual_0_35s.png index de27589aa..96b1cd095 100644 Binary files a/packages/producer/tests/iframe-render-compat/failures/frames/actual_0_35s.png and b/packages/producer/tests/iframe-render-compat/failures/frames/actual_0_35s.png differ diff --git a/packages/producer/tests/iframe-render-compat/failures/frames/actual_0_40s.png b/packages/producer/tests/iframe-render-compat/failures/frames/actual_0_40s.png index d933b6d91..d8abe531b 100644 Binary files a/packages/producer/tests/iframe-render-compat/failures/frames/actual_0_40s.png and b/packages/producer/tests/iframe-render-compat/failures/frames/actual_0_40s.png differ diff --git a/packages/producer/tests/iframe-render-compat/failures/frames/actual_0_45s.png b/packages/producer/tests/iframe-render-compat/failures/frames/actual_0_45s.png index 03edb5d01..9e82e12c0 100644 Binary files a/packages/producer/tests/iframe-render-compat/failures/frames/actual_0_45s.png and b/packages/producer/tests/iframe-render-compat/failures/frames/actual_0_45s.png differ diff --git a/packages/producer/tests/iframe-render-compat/failures/frames/expected_0_00s.png b/packages/producer/tests/iframe-render-compat/failures/frames/expected_0_00s.png index f207e2525..666c80993 100644 Binary files a/packages/producer/tests/iframe-render-compat/failures/frames/expected_0_00s.png and b/packages/producer/tests/iframe-render-compat/failures/frames/expected_0_00s.png differ diff --git a/packages/producer/tests/iframe-render-compat/failures/frames/expected_0_05s.png b/packages/producer/tests/iframe-render-compat/failures/frames/expected_0_05s.png index 69610663a..d54db4341 100644 Binary files a/packages/producer/tests/iframe-render-compat/failures/frames/expected_0_05s.png and b/packages/producer/tests/iframe-render-compat/failures/frames/expected_0_05s.png differ diff --git a/packages/producer/tests/iframe-render-compat/failures/frames/expected_0_10s.png b/packages/producer/tests/iframe-render-compat/failures/frames/expected_0_10s.png index ed2b4817d..baa173263 100644 Binary files a/packages/producer/tests/iframe-render-compat/failures/frames/expected_0_10s.png and b/packages/producer/tests/iframe-render-compat/failures/frames/expected_0_10s.png differ diff --git a/packages/producer/tests/iframe-render-compat/failures/frames/expected_0_15s.png b/packages/producer/tests/iframe-render-compat/failures/frames/expected_0_15s.png index a2ea5d801..cd1b3f110 100644 Binary files a/packages/producer/tests/iframe-render-compat/failures/frames/expected_0_15s.png and b/packages/producer/tests/iframe-render-compat/failures/frames/expected_0_15s.png differ diff --git a/packages/producer/tests/iframe-render-compat/failures/frames/expected_0_20s.png b/packages/producer/tests/iframe-render-compat/failures/frames/expected_0_20s.png index e97deb062..51c766438 100644 Binary files a/packages/producer/tests/iframe-render-compat/failures/frames/expected_0_20s.png and b/packages/producer/tests/iframe-render-compat/failures/frames/expected_0_20s.png differ diff --git a/packages/producer/tests/iframe-render-compat/failures/frames/expected_0_25s.png b/packages/producer/tests/iframe-render-compat/failures/frames/expected_0_25s.png index 9c9e8f108..1f2ba6b34 100644 Binary files a/packages/producer/tests/iframe-render-compat/failures/frames/expected_0_25s.png and b/packages/producer/tests/iframe-render-compat/failures/frames/expected_0_25s.png differ diff --git a/packages/producer/tests/iframe-render-compat/failures/frames/expected_0_30s.png b/packages/producer/tests/iframe-render-compat/failures/frames/expected_0_30s.png index c415c4e02..05f2cb87e 100644 Binary files a/packages/producer/tests/iframe-render-compat/failures/frames/expected_0_30s.png and b/packages/producer/tests/iframe-render-compat/failures/frames/expected_0_30s.png differ diff --git a/packages/producer/tests/iframe-render-compat/failures/frames/expected_0_35s.png b/packages/producer/tests/iframe-render-compat/failures/frames/expected_0_35s.png index 63e01dce7..062a4acf6 100644 Binary files a/packages/producer/tests/iframe-render-compat/failures/frames/expected_0_35s.png and b/packages/producer/tests/iframe-render-compat/failures/frames/expected_0_35s.png differ diff --git a/packages/producer/tests/iframe-render-compat/failures/frames/expected_0_40s.png b/packages/producer/tests/iframe-render-compat/failures/frames/expected_0_40s.png index dd141901c..1c3cdc133 100644 Binary files a/packages/producer/tests/iframe-render-compat/failures/frames/expected_0_40s.png and b/packages/producer/tests/iframe-render-compat/failures/frames/expected_0_40s.png differ diff --git a/packages/producer/tests/iframe-render-compat/failures/frames/expected_0_45s.png b/packages/producer/tests/iframe-render-compat/failures/frames/expected_0_45s.png index 320625274..69ad3cbf5 100644 Binary files a/packages/producer/tests/iframe-render-compat/failures/frames/expected_0_45s.png and b/packages/producer/tests/iframe-render-compat/failures/frames/expected_0_45s.png differ diff --git a/packages/producer/tests/iframe-render-compat/failures/visual-failures.json b/packages/producer/tests/iframe-render-compat/failures/visual-failures.json index acd2abc1a..badb71fa1 100644 --- a/packages/producer/tests/iframe-render-compat/failures/visual-failures.json +++ b/packages/producer/tests/iframe-render-compat/failures/visual-failures.json @@ -2,508 +2,509 @@ "summary": { "totalCheckpoints": 100, "failedCheckpoints": 100, - "threshold": 30 + "threshold": 30, + "fixtureThreshold": 30 }, "failedFrames": [ { "time": 0, - "psnr": 25.532776, - "belowThresholdBy": 4.467224000000002 + "psnr": 25.670173, + "belowThresholdBy": 4.329827000000002 }, { - "time": 0.05, - "psnr": 25.527491, - "belowThresholdBy": 4.472508999999999 + "time": 0.049666666666666665, + "psnr": 25.665257, + "belowThresholdBy": 4.334743 }, { - "time": 0.1, - "psnr": 25.527085, - "belowThresholdBy": 4.472915 + "time": 0.09933333333333333, + "psnr": 25.664898, + "belowThresholdBy": 4.335101999999999 }, { - "time": 0.15, - "psnr": 25.527803, - "belowThresholdBy": 4.472197000000001 + "time": 0.149, + "psnr": 25.66572, + "belowThresholdBy": 4.33428 }, { - "time": 0.2, - "psnr": 25.528707, - "belowThresholdBy": 4.471292999999999 + "time": 0.19866666666666666, + "psnr": 25.666527, + "belowThresholdBy": 4.3334730000000015 }, { - "time": 0.25, - "psnr": 25.528334, - "belowThresholdBy": 4.471665999999999 + "time": 0.24833333333333335, + "psnr": 25.665789, + "belowThresholdBy": 4.334211 }, { - "time": 0.3, - "psnr": 25.52862, - "belowThresholdBy": 4.47138 + "time": 0.298, + "psnr": 25.66605, + "belowThresholdBy": 4.3339500000000015 }, { - "time": 0.35, - "psnr": 25.528897, - "belowThresholdBy": 4.471102999999999 + "time": 0.3476666666666667, + "psnr": 25.666633, + "belowThresholdBy": 4.333366999999999 }, { - "time": 0.4, - "psnr": 25.528203, - "belowThresholdBy": 4.471796999999999 + "time": 0.3973333333333333, + "psnr": 25.666045, + "belowThresholdBy": 4.333955 }, { - "time": 0.45, - "psnr": 25.527721, - "belowThresholdBy": 4.472279 + "time": 0.447, + "psnr": 25.667801, + "belowThresholdBy": 4.332198999999999 }, { - "time": 0.5, - "psnr": 25.528982, - "belowThresholdBy": 4.471018000000001 + "time": 0.4966666666666667, + "psnr": 25.665958, + "belowThresholdBy": 4.334042 }, { - "time": 0.55, - "psnr": 25.52819, - "belowThresholdBy": 4.471810000000001 + "time": 0.5463333333333333, + "psnr": 25.66534, + "belowThresholdBy": 4.3346599999999995 }, { - "time": 0.6, - "psnr": 25.528268, - "belowThresholdBy": 4.471731999999999 + "time": 0.596, + "psnr": 25.667488, + "belowThresholdBy": 4.332512000000001 }, { - "time": 0.65, - "psnr": 25.528628, - "belowThresholdBy": 4.471371999999999 + "time": 0.6456666666666666, + "psnr": 25.665683, + "belowThresholdBy": 4.334316999999999 }, { - "time": 0.7, - "psnr": 25.527501, - "belowThresholdBy": 4.472498999999999 + "time": 0.6953333333333334, + "psnr": 25.666654, + "belowThresholdBy": 4.333345999999999 }, { - "time": 0.75, - "psnr": 25.527646, - "belowThresholdBy": 4.472353999999999 + "time": 0.745, + "psnr": 25.665803, + "belowThresholdBy": 4.334197 }, { - "time": 0.8, - "psnr": 25.528598, - "belowThresholdBy": 4.471402000000001 + "time": 0.7946666666666666, + "psnr": 25.665768, + "belowThresholdBy": 4.334232 }, { - "time": 0.85, - "psnr": 25.528406, - "belowThresholdBy": 4.471594 + "time": 0.8443333333333334, + "psnr": 25.666026, + "belowThresholdBy": 4.333974000000001 }, { - "time": 0.9, - "psnr": 25.528198, - "belowThresholdBy": 4.471802 + "time": 0.894, + "psnr": 25.665989, + "belowThresholdBy": 4.334011 }, { - "time": 0.95, - "psnr": 25.528123, - "belowThresholdBy": 4.471876999999999 + "time": 0.9436666666666668, + "psnr": 25.666062, + "belowThresholdBy": 4.333938 }, { - "time": 1, - "psnr": 25.530176, - "belowThresholdBy": 4.469823999999999 + "time": 0.9933333333333334, + "psnr": 25.665957, + "belowThresholdBy": 4.334043000000001 }, { - "time": 1.05, - "psnr": 25.529038, - "belowThresholdBy": 4.470962 + "time": 1.043, + "psnr": 25.665319, + "belowThresholdBy": 4.334681 }, { - "time": 1.1, - "psnr": 25.527842, - "belowThresholdBy": 4.472158 + "time": 1.0926666666666667, + "psnr": 25.66539, + "belowThresholdBy": 4.334610000000001 }, { - "time": 1.15, - "psnr": 25.528373, - "belowThresholdBy": 4.471627000000002 + "time": 1.1423333333333334, + "psnr": 25.665835, + "belowThresholdBy": 4.334164999999999 }, { - "time": 1.2, - "psnr": 25.529091, - "belowThresholdBy": 4.470908999999999 + "time": 1.192, + "psnr": 25.666256, + "belowThresholdBy": 4.333743999999999 }, { - "time": 1.25, - "psnr": 25.528298, - "belowThresholdBy": 4.4717020000000005 + "time": 1.2416666666666667, + "psnr": 25.6659, + "belowThresholdBy": 4.334099999999999 }, { - "time": 1.3, - "psnr": 25.529338, - "belowThresholdBy": 4.470662000000001 + "time": 1.2913333333333332, + "psnr": 25.666521, + "belowThresholdBy": 4.3334790000000005 }, { - "time": 1.35, - "psnr": 25.528646, - "belowThresholdBy": 4.471354000000002 + "time": 1.341, + "psnr": 25.666418, + "belowThresholdBy": 4.333582 }, { - "time": 1.4, - "psnr": 25.529207, - "belowThresholdBy": 4.4707930000000005 + "time": 1.3906666666666667, + "psnr": 25.666516, + "belowThresholdBy": 4.333483999999999 }, { - "time": 1.45, - "psnr": 25.529405, - "belowThresholdBy": 4.470594999999999 + "time": 1.4403333333333332, + "psnr": 25.666238, + "belowThresholdBy": 4.333762 }, { - "time": 1.5, - "psnr": 25.530795, - "belowThresholdBy": 4.469204999999999 + "time": 1.49, + "psnr": 25.665819, + "belowThresholdBy": 4.334181000000001 }, { - "time": 1.55, - "psnr": 25.529347, - "belowThresholdBy": 4.470652999999999 + "time": 1.5396666666666667, + "psnr": 25.666459, + "belowThresholdBy": 4.333541 }, { - "time": 1.6, - "psnr": 25.529177, - "belowThresholdBy": 4.470822999999999 + "time": 1.5893333333333333, + "psnr": 25.666325, + "belowThresholdBy": 4.3336749999999995 }, { - "time": 1.65, - "psnr": 25.529121, - "belowThresholdBy": 4.470879 + "time": 1.639, + "psnr": 25.665563, + "belowThresholdBy": 4.334437000000001 }, { - "time": 1.7, - "psnr": 25.529399, - "belowThresholdBy": 4.4706009999999985 + "time": 1.6886666666666668, + "psnr": 25.665991, + "belowThresholdBy": 4.334008999999998 }, { - "time": 1.75, - "psnr": 25.528421, - "belowThresholdBy": 4.471578999999998 + "time": 1.7383333333333335, + "psnr": 25.665225, + "belowThresholdBy": 4.3347750000000005 }, { - "time": 1.8, - "psnr": 25.529416, - "belowThresholdBy": 4.470583999999999 + "time": 1.788, + "psnr": 25.666288, + "belowThresholdBy": 4.3337119999999985 }, { - "time": 1.85, - "psnr": 25.528221, - "belowThresholdBy": 4.4717790000000015 + "time": 1.8376666666666668, + "psnr": 25.665266, + "belowThresholdBy": 4.334734000000001 }, { - "time": 1.9, - "psnr": 25.527902, - "belowThresholdBy": 4.472097999999999 + "time": 1.8873333333333335, + "psnr": 25.665011, + "belowThresholdBy": 4.334989 }, { - "time": 1.95, - "psnr": 25.52892, - "belowThresholdBy": 4.471080000000001 + "time": 1.9370000000000003, + "psnr": 25.665971, + "belowThresholdBy": 4.334029000000001 }, { - "time": 2, - "psnr": 25.530678, - "belowThresholdBy": 4.469321999999998 + "time": 1.9866666666666668, + "psnr": 25.665508, + "belowThresholdBy": 4.334492000000001 }, { - "time": 2.05, - "psnr": 25.528809, - "belowThresholdBy": 4.471191000000001 + "time": 2.0363333333333333, + "psnr": 25.665407, + "belowThresholdBy": 4.334593000000002 }, { - "time": 2.1, - "psnr": 25.528916, - "belowThresholdBy": 4.471084000000001 + "time": 2.086, + "psnr": 25.665667, + "belowThresholdBy": 4.334333000000001 }, { - "time": 2.15, - "psnr": 25.528841, - "belowThresholdBy": 4.471159 + "time": 2.135666666666667, + "psnr": 25.665722, + "belowThresholdBy": 4.334278000000001 }, { - "time": 2.2, - "psnr": 25.528685, - "belowThresholdBy": 4.471315000000001 + "time": 2.1853333333333333, + "psnr": 25.665476, + "belowThresholdBy": 4.334523999999998 }, { - "time": 2.25, - "psnr": 25.528494, - "belowThresholdBy": 4.4715060000000015 + "time": 2.235, + "psnr": 25.665359, + "belowThresholdBy": 4.334641000000001 }, { - "time": 2.3, - "psnr": 25.529056, - "belowThresholdBy": 4.470943999999999 + "time": 2.284666666666667, + "psnr": 25.664999, + "belowThresholdBy": 4.335000999999998 }, { - "time": 2.35, - "psnr": 25.529042, - "belowThresholdBy": 4.4709579999999995 + "time": 2.3343333333333334, + "psnr": 25.666587, + "belowThresholdBy": 4.333413 }, { - "time": 2.4, - "psnr": 25.529264, - "belowThresholdBy": 4.470735999999999 + "time": 2.384, + "psnr": 25.665216, + "belowThresholdBy": 4.334783999999999 }, { - "time": 2.45, - "psnr": 25.527758, - "belowThresholdBy": 4.472242000000001 + "time": 2.433666666666667, + "psnr": 25.664701, + "belowThresholdBy": 4.335298999999999 }, { - "time": 2.5, - "psnr": 25.529451, - "belowThresholdBy": 4.470548999999998 + "time": 2.4833333333333334, + "psnr": 25.663834, + "belowThresholdBy": 4.336165999999999 }, { - "time": 2.55, - "psnr": 25.529187, - "belowThresholdBy": 4.470813 + "time": 2.533, + "psnr": 25.664359, + "belowThresholdBy": 4.335640999999999 }, { - "time": 2.6, - "psnr": 25.527694, - "belowThresholdBy": 4.472306 + "time": 2.5826666666666664, + "psnr": 25.665088, + "belowThresholdBy": 4.334911999999999 }, { - "time": 2.65, - "psnr": 25.528983, - "belowThresholdBy": 4.471017 + "time": 2.6323333333333334, + "psnr": 25.665297, + "belowThresholdBy": 4.334703000000001 }, { - "time": 2.7, - "psnr": 25.528599, - "belowThresholdBy": 4.471401 + "time": 2.682, + "psnr": 25.665352, + "belowThresholdBy": 4.334648000000001 }, { - "time": 2.75, - "psnr": 25.528595, - "belowThresholdBy": 4.471405000000001 + "time": 2.731666666666667, + "psnr": 25.666831, + "belowThresholdBy": 4.333169000000002 }, { - "time": 2.8, - "psnr": 25.528584, - "belowThresholdBy": 4.471416000000001 + "time": 2.7813333333333334, + "psnr": 25.664831, + "belowThresholdBy": 4.3351690000000005 }, { - "time": 2.85, - "psnr": 25.528495, - "belowThresholdBy": 4.4715050000000005 + "time": 2.8310000000000004, + "psnr": 25.664452, + "belowThresholdBy": 4.335547999999999 }, { - "time": 2.9, - "psnr": 25.528314, - "belowThresholdBy": 4.471685999999998 + "time": 2.8806666666666665, + "psnr": 25.665043, + "belowThresholdBy": 4.334956999999999 }, { - "time": 2.95, - "psnr": 25.528935, - "belowThresholdBy": 4.471064999999999 + "time": 2.9303333333333335, + "psnr": 25.664478, + "belowThresholdBy": 4.335522000000001 }, { - "time": 3, - "psnr": 25.530156, - "belowThresholdBy": 4.469843999999998 + "time": 2.98, + "psnr": 25.665427, + "belowThresholdBy": 4.334572999999999 }, { - "time": 3.05, - "psnr": 25.527974, - "belowThresholdBy": 4.472026 + "time": 3.029666666666667, + "psnr": 25.66538, + "belowThresholdBy": 4.334620000000001 }, { - "time": 3.1, - "psnr": 25.528024, - "belowThresholdBy": 4.4719760000000015 + "time": 3.0793333333333335, + "psnr": 25.66421, + "belowThresholdBy": 4.335789999999999 }, { - "time": 3.15, - "psnr": 25.527788, - "belowThresholdBy": 4.472211999999999 + "time": 3.1290000000000004, + "psnr": 25.664635, + "belowThresholdBy": 4.3353649999999995 }, { - "time": 3.2, - "psnr": 25.52833, - "belowThresholdBy": 4.47167 + "time": 3.1786666666666665, + "psnr": 25.664152, + "belowThresholdBy": 4.335847999999999 }, { - "time": 3.25, - "psnr": 25.528662, - "belowThresholdBy": 4.471337999999999 + "time": 3.228333333333333, + "psnr": 25.664572, + "belowThresholdBy": 4.335428 }, { - "time": 3.3, - "psnr": 25.528834, - "belowThresholdBy": 4.471166 + "time": 3.278, + "psnr": 25.665011, + "belowThresholdBy": 4.334989 }, { - "time": 3.35, - "psnr": 25.528553, - "belowThresholdBy": 4.471447000000001 + "time": 3.3276666666666666, + "psnr": 25.664758, + "belowThresholdBy": 4.335242000000001 }, { - "time": 3.4, - "psnr": 25.528278, - "belowThresholdBy": 4.471722 + "time": 3.3773333333333335, + "psnr": 25.664574, + "belowThresholdBy": 4.335425999999998 }, { - "time": 3.45, - "psnr": 25.533727, - "belowThresholdBy": 4.466273000000001 + "time": 3.427, + "psnr": 25.668833, + "belowThresholdBy": 4.331167000000001 }, { - "time": 3.5, - "psnr": 25.536056, - "belowThresholdBy": 4.4639440000000015 + "time": 3.476666666666667, + "psnr": 25.671263, + "belowThresholdBy": 4.328737 }, { - "time": 3.55, - "psnr": 25.540891, - "belowThresholdBy": 4.4591090000000015 + "time": 3.526333333333333, + "psnr": 25.67407, + "belowThresholdBy": 4.32593 }, { - "time": 3.6, - "psnr": 25.542596, - "belowThresholdBy": 4.457404 + "time": 3.576, + "psnr": 25.677632, + "belowThresholdBy": 4.322368000000001 }, { - "time": 3.65, - "psnr": 25.5418, - "belowThresholdBy": 4.4582000000000015 + "time": 3.6256666666666666, + "psnr": 25.679291, + "belowThresholdBy": 4.320709000000001 }, { - "time": 3.7, - "psnr": 25.542324, - "belowThresholdBy": 4.457675999999999 + "time": 3.6753333333333336, + "psnr": 25.679101, + "belowThresholdBy": 4.320899000000001 }, { - "time": 3.75, - "psnr": 25.542259, - "belowThresholdBy": 4.457740999999999 + "time": 3.725, + "psnr": 25.679923, + "belowThresholdBy": 4.320077000000001 }, { - "time": 3.8, - "psnr": 25.542141, - "belowThresholdBy": 4.457858999999999 + "time": 3.774666666666667, + "psnr": 25.680906, + "belowThresholdBy": 4.319094 }, { - "time": 3.85, - "psnr": 25.542145, - "belowThresholdBy": 4.457854999999999 + "time": 3.8243333333333336, + "psnr": 25.679413, + "belowThresholdBy": 4.320587 }, { - "time": 3.9, - "psnr": 25.542386, - "belowThresholdBy": 4.4576139999999995 + "time": 3.8740000000000006, + "psnr": 25.679453, + "belowThresholdBy": 4.320547000000001 }, { - "time": 3.95, - "psnr": 25.542825, - "belowThresholdBy": 4.457174999999999 + "time": 3.9236666666666666, + "psnr": 25.679127, + "belowThresholdBy": 4.320872999999999 }, { - "time": 4, - "psnr": 25.544485, - "belowThresholdBy": 4.455514999999998 + "time": 3.9733333333333336, + "psnr": 25.679337, + "belowThresholdBy": 4.320663 }, { - "time": 4.05, - "psnr": 25.542551, - "belowThresholdBy": 4.457449 + "time": 4.023, + "psnr": 25.678418, + "belowThresholdBy": 4.321581999999999 }, { - "time": 4.1, - "psnr": 25.541994, - "belowThresholdBy": 4.458006000000001 + "time": 4.072666666666667, + "psnr": 25.679278, + "belowThresholdBy": 4.320722 }, { - "time": 4.15, - "psnr": 25.541748, - "belowThresholdBy": 4.458252000000002 + "time": 4.122333333333334, + "psnr": 25.679084, + "belowThresholdBy": 4.320916 }, { - "time": 4.2, - "psnr": 25.542627, - "belowThresholdBy": 4.4573730000000005 + "time": 4.172, + "psnr": 25.67842, + "belowThresholdBy": 4.321580000000001 }, { - "time": 4.25, - "psnr": 25.551196, - "belowThresholdBy": 4.448803999999999 + "time": 4.221666666666667, + "psnr": 25.682599, + "belowThresholdBy": 4.317401 }, { - "time": 4.3, - "psnr": 25.552091, - "belowThresholdBy": 4.447908999999999 + "time": 4.271333333333334, + "psnr": 25.690067, + "belowThresholdBy": 4.309933000000001 }, { - "time": 4.35, - "psnr": 25.551437, - "belowThresholdBy": 4.448563 + "time": 4.321000000000001, + "psnr": 25.691069, + "belowThresholdBy": 4.308931000000001 }, { - "time": 4.4, - "psnr": 25.552455, - "belowThresholdBy": 4.447545000000002 + "time": 4.370666666666667, + "psnr": 25.689988, + "belowThresholdBy": 4.310012 }, { - "time": 4.45, - "psnr": 25.565069, - "belowThresholdBy": 4.434930999999999 + "time": 4.420333333333334, + "psnr": 25.701076, + "belowThresholdBy": 4.2989239999999995 }, { - "time": 4.5, - "psnr": 25.566134, - "belowThresholdBy": 4.433865999999998 + "time": 4.47, + "psnr": 25.703625, + "belowThresholdBy": 4.296375000000001 }, { - "time": 4.55, - "psnr": 25.565799, - "belowThresholdBy": 4.434201000000002 + "time": 4.519666666666667, + "psnr": 25.703902, + "belowThresholdBy": 4.296098000000001 }, { - "time": 4.6, - "psnr": 25.565537, - "belowThresholdBy": 4.434463000000001 + "time": 4.569333333333334, + "psnr": 25.704101, + "belowThresholdBy": 4.295898999999999 }, { - "time": 4.65, - "psnr": 25.56569, - "belowThresholdBy": 4.43431 + "time": 4.619000000000001, + "psnr": 25.703541, + "belowThresholdBy": 4.296458999999999 }, { - "time": 4.7, - "psnr": 25.565667, - "belowThresholdBy": 4.434332999999999 + "time": 4.668666666666667, + "psnr": 25.703907, + "belowThresholdBy": 4.296092999999999 }, { - "time": 4.75, - "psnr": 25.556324, - "belowThresholdBy": 4.443676 + "time": 4.718333333333334, + "psnr": 25.701013, + "belowThresholdBy": 4.298987 }, { - "time": 4.8, - "psnr": 25.556492, - "belowThresholdBy": 4.443508000000001 + "time": 4.768, + "psnr": 25.693049, + "belowThresholdBy": 4.3069510000000015 }, { - "time": 4.85, - "psnr": 25.555055, - "belowThresholdBy": 4.444945000000001 + "time": 4.817666666666667, + "psnr": 25.691654, + "belowThresholdBy": 4.308346 }, { - "time": 4.9, - "psnr": 25.555276, - "belowThresholdBy": 4.444724000000001 + "time": 4.867333333333334, + "psnr": 25.692159, + "belowThresholdBy": 4.307841 }, { - "time": 4.95, - "psnr": 25.541661, - "belowThresholdBy": 4.458338999999999 + "time": 4.917, + "psnr": 25.68271, + "belowThresholdBy": 4.31729 } ] } \ No newline at end of file diff --git a/packages/producer/tests/render-symlinked-assets/failures/frames/actual_0_00s.png b/packages/producer/tests/render-symlinked-assets/failures/frames/actual_0_00s.png index dc46ab368..fc9dce12d 100644 Binary files a/packages/producer/tests/render-symlinked-assets/failures/frames/actual_0_00s.png and b/packages/producer/tests/render-symlinked-assets/failures/frames/actual_0_00s.png differ diff --git a/packages/producer/tests/render-symlinked-assets/failures/frames/actual_0_05s.png b/packages/producer/tests/render-symlinked-assets/failures/frames/actual_0_05s.png index f629f37e8..7fa9d13cb 100644 Binary files a/packages/producer/tests/render-symlinked-assets/failures/frames/actual_0_05s.png and b/packages/producer/tests/render-symlinked-assets/failures/frames/actual_0_05s.png differ diff --git a/packages/producer/tests/render-symlinked-assets/failures/frames/actual_0_10s.png b/packages/producer/tests/render-symlinked-assets/failures/frames/actual_0_10s.png index ca564dc6a..0c6b770b4 100644 Binary files a/packages/producer/tests/render-symlinked-assets/failures/frames/actual_0_10s.png and b/packages/producer/tests/render-symlinked-assets/failures/frames/actual_0_10s.png differ diff --git a/packages/producer/tests/render-symlinked-assets/failures/frames/actual_0_15s.png b/packages/producer/tests/render-symlinked-assets/failures/frames/actual_0_15s.png index ca564dc6a..0c6b770b4 100644 Binary files a/packages/producer/tests/render-symlinked-assets/failures/frames/actual_0_15s.png and b/packages/producer/tests/render-symlinked-assets/failures/frames/actual_0_15s.png differ diff --git a/packages/producer/tests/render-symlinked-assets/failures/frames/actual_0_20s.png b/packages/producer/tests/render-symlinked-assets/failures/frames/actual_0_20s.png index f629f37e8..0c6b770b4 100644 Binary files a/packages/producer/tests/render-symlinked-assets/failures/frames/actual_0_20s.png and b/packages/producer/tests/render-symlinked-assets/failures/frames/actual_0_20s.png differ diff --git a/packages/producer/tests/render-symlinked-assets/failures/frames/actual_0_25s.png b/packages/producer/tests/render-symlinked-assets/failures/frames/actual_0_25s.png index ca564dc6a..0c6b770b4 100644 Binary files a/packages/producer/tests/render-symlinked-assets/failures/frames/actual_0_25s.png and b/packages/producer/tests/render-symlinked-assets/failures/frames/actual_0_25s.png differ diff --git a/packages/producer/tests/render-symlinked-assets/failures/frames/actual_0_30s.png b/packages/producer/tests/render-symlinked-assets/failures/frames/actual_0_30s.png index f629f37e8..0c6b770b4 100644 Binary files a/packages/producer/tests/render-symlinked-assets/failures/frames/actual_0_30s.png and b/packages/producer/tests/render-symlinked-assets/failures/frames/actual_0_30s.png differ diff --git a/packages/producer/tests/render-symlinked-assets/failures/frames/actual_0_35s.png b/packages/producer/tests/render-symlinked-assets/failures/frames/actual_0_35s.png index ca564dc6a..0c6b770b4 100644 Binary files a/packages/producer/tests/render-symlinked-assets/failures/frames/actual_0_35s.png and b/packages/producer/tests/render-symlinked-assets/failures/frames/actual_0_35s.png differ diff --git a/packages/producer/tests/render-symlinked-assets/failures/frames/actual_0_40s.png b/packages/producer/tests/render-symlinked-assets/failures/frames/actual_0_40s.png index ca564dc6a..0c6b770b4 100644 Binary files a/packages/producer/tests/render-symlinked-assets/failures/frames/actual_0_40s.png and b/packages/producer/tests/render-symlinked-assets/failures/frames/actual_0_40s.png differ diff --git a/packages/producer/tests/render-symlinked-assets/failures/frames/actual_0_45s.png b/packages/producer/tests/render-symlinked-assets/failures/frames/actual_0_45s.png index f629f37e8..0c6b770b4 100644 Binary files a/packages/producer/tests/render-symlinked-assets/failures/frames/actual_0_45s.png and b/packages/producer/tests/render-symlinked-assets/failures/frames/actual_0_45s.png differ diff --git a/packages/producer/tests/render-symlinked-assets/failures/frames/expected_0_00s.png b/packages/producer/tests/render-symlinked-assets/failures/frames/expected_0_00s.png index d948dff8b..ea2084cb5 100644 Binary files a/packages/producer/tests/render-symlinked-assets/failures/frames/expected_0_00s.png and b/packages/producer/tests/render-symlinked-assets/failures/frames/expected_0_00s.png differ diff --git a/packages/producer/tests/render-symlinked-assets/failures/frames/expected_0_05s.png b/packages/producer/tests/render-symlinked-assets/failures/frames/expected_0_05s.png index 32683cfdd..7b07b27e6 100644 Binary files a/packages/producer/tests/render-symlinked-assets/failures/frames/expected_0_05s.png and b/packages/producer/tests/render-symlinked-assets/failures/frames/expected_0_05s.png differ diff --git a/packages/producer/tests/render-symlinked-assets/failures/frames/expected_0_10s.png b/packages/producer/tests/render-symlinked-assets/failures/frames/expected_0_10s.png index f47a7d46d..9e93662b8 100644 Binary files a/packages/producer/tests/render-symlinked-assets/failures/frames/expected_0_10s.png and b/packages/producer/tests/render-symlinked-assets/failures/frames/expected_0_10s.png differ diff --git a/packages/producer/tests/render-symlinked-assets/failures/frames/expected_0_15s.png b/packages/producer/tests/render-symlinked-assets/failures/frames/expected_0_15s.png index 0380f40fc..c5e613beb 100644 Binary files a/packages/producer/tests/render-symlinked-assets/failures/frames/expected_0_15s.png and b/packages/producer/tests/render-symlinked-assets/failures/frames/expected_0_15s.png differ diff --git a/packages/producer/tests/render-symlinked-assets/failures/frames/expected_0_20s.png b/packages/producer/tests/render-symlinked-assets/failures/frames/expected_0_20s.png index 0380f40fc..c5e613beb 100644 Binary files a/packages/producer/tests/render-symlinked-assets/failures/frames/expected_0_20s.png and b/packages/producer/tests/render-symlinked-assets/failures/frames/expected_0_20s.png differ diff --git a/packages/producer/tests/render-symlinked-assets/failures/frames/expected_0_25s.png b/packages/producer/tests/render-symlinked-assets/failures/frames/expected_0_25s.png index 0380f40fc..c5e613beb 100644 Binary files a/packages/producer/tests/render-symlinked-assets/failures/frames/expected_0_25s.png and b/packages/producer/tests/render-symlinked-assets/failures/frames/expected_0_25s.png differ diff --git a/packages/producer/tests/render-symlinked-assets/failures/frames/expected_0_30s.png b/packages/producer/tests/render-symlinked-assets/failures/frames/expected_0_30s.png index 0380f40fc..c5e613beb 100644 Binary files a/packages/producer/tests/render-symlinked-assets/failures/frames/expected_0_30s.png and b/packages/producer/tests/render-symlinked-assets/failures/frames/expected_0_30s.png differ diff --git a/packages/producer/tests/render-symlinked-assets/failures/frames/expected_0_35s.png b/packages/producer/tests/render-symlinked-assets/failures/frames/expected_0_35s.png index 0380f40fc..c5e613beb 100644 Binary files a/packages/producer/tests/render-symlinked-assets/failures/frames/expected_0_35s.png and b/packages/producer/tests/render-symlinked-assets/failures/frames/expected_0_35s.png differ diff --git a/packages/producer/tests/render-symlinked-assets/failures/frames/expected_0_40s.png b/packages/producer/tests/render-symlinked-assets/failures/frames/expected_0_40s.png index 0380f40fc..c5e613beb 100644 Binary files a/packages/producer/tests/render-symlinked-assets/failures/frames/expected_0_40s.png and b/packages/producer/tests/render-symlinked-assets/failures/frames/expected_0_40s.png differ diff --git a/packages/producer/tests/render-symlinked-assets/failures/frames/expected_0_45s.png b/packages/producer/tests/render-symlinked-assets/failures/frames/expected_0_45s.png index 0380f40fc..c5e613beb 100644 Binary files a/packages/producer/tests/render-symlinked-assets/failures/frames/expected_0_45s.png and b/packages/producer/tests/render-symlinked-assets/failures/frames/expected_0_45s.png differ diff --git a/packages/producer/tests/render-symlinked-assets/failures/visual-failures.json b/packages/producer/tests/render-symlinked-assets/failures/visual-failures.json index 3d2e3a0d3..4ad485247 100644 --- a/packages/producer/tests/render-symlinked-assets/failures/visual-failures.json +++ b/packages/producer/tests/render-symlinked-assets/failures/visual-failures.json @@ -2,508 +2,509 @@ "summary": { "totalCheckpoints": 100, "failedCheckpoints": 100, - "threshold": 30 + "threshold": 30, + "fixtureThreshold": 30 }, "failedFrames": [ { "time": 0, - "psnr": 22.729066, - "belowThresholdBy": 7.2709340000000005 + "psnr": 21.623923, + "belowThresholdBy": 8.376076999999999 }, { - "time": 0.05, - "psnr": 22.728686, - "belowThresholdBy": 7.271314 + "time": 0.04958333333333333, + "psnr": 21.623061, + "belowThresholdBy": 8.376939 }, { - "time": 0.1, - "psnr": 22.728667, - "belowThresholdBy": 7.2713329999999985 + "time": 0.09916666666666667, + "psnr": 21.623088, + "belowThresholdBy": 8.376912 }, { - "time": 0.15, - "psnr": 22.728643, - "belowThresholdBy": 7.271356999999998 + "time": 0.14875, + "psnr": 21.623194, + "belowThresholdBy": 8.376805999999998 }, { - "time": 0.2, - "psnr": 22.728644, - "belowThresholdBy": 7.271356000000001 + "time": 0.19833333333333333, + "psnr": 21.623194, + "belowThresholdBy": 8.376805999999998 }, { - "time": 0.25, - "psnr": 22.728643, - "belowThresholdBy": 7.271356999999998 + "time": 0.24791666666666665, + "psnr": 21.623194, + "belowThresholdBy": 8.376805999999998 }, { - "time": 0.3, - "psnr": 22.728644, - "belowThresholdBy": 7.271356000000001 + "time": 0.2975, + "psnr": 21.623194, + "belowThresholdBy": 8.376805999999998 }, { - "time": 0.35, - "psnr": 22.728643, - "belowThresholdBy": 7.271356999999998 + "time": 0.3470833333333333, + "psnr": 21.623194, + "belowThresholdBy": 8.376805999999998 }, { - "time": 0.4, - "psnr": 22.728643, - "belowThresholdBy": 7.271356999999998 + "time": 0.39666666666666667, + "psnr": 21.623194, + "belowThresholdBy": 8.376805999999998 }, { - "time": 0.45, - "psnr": 22.728644, - "belowThresholdBy": 7.271356000000001 + "time": 0.44625, + "psnr": 21.623194, + "belowThresholdBy": 8.376805999999998 }, { - "time": 0.5, - "psnr": 22.728643, - "belowThresholdBy": 7.271356999999998 + "time": 0.4958333333333333, + "psnr": 21.623194, + "belowThresholdBy": 8.376805999999998 }, { - "time": 0.55, - "psnr": 22.728644, - "belowThresholdBy": 7.271356000000001 + "time": 0.5454166666666667, + "psnr": 21.623194, + "belowThresholdBy": 8.376805999999998 }, { - "time": 0.6, - "psnr": 22.728643, - "belowThresholdBy": 7.271356999999998 + "time": 0.595, + "psnr": 21.623194, + "belowThresholdBy": 8.376805999999998 }, { - "time": 0.65, - "psnr": 22.728643, - "belowThresholdBy": 7.271356999999998 + "time": 0.6445833333333333, + "psnr": 21.623194, + "belowThresholdBy": 8.376805999999998 }, { - "time": 0.7, - "psnr": 22.728644, - "belowThresholdBy": 7.271356000000001 + "time": 0.6941666666666666, + "psnr": 21.623194, + "belowThresholdBy": 8.376805999999998 }, { - "time": 0.75, - "psnr": 22.728643, - "belowThresholdBy": 7.271356999999998 + "time": 0.74375, + "psnr": 21.623194, + "belowThresholdBy": 8.376805999999998 }, { - "time": 0.8, - "psnr": 22.728644, - "belowThresholdBy": 7.271356000000001 + "time": 0.7933333333333333, + "psnr": 21.623194, + "belowThresholdBy": 8.376805999999998 }, { - "time": 0.85, - "psnr": 22.728643, - "belowThresholdBy": 7.271356999999998 + "time": 0.8429166666666665, + "psnr": 21.623194, + "belowThresholdBy": 8.376805999999998 }, { - "time": 0.9, - "psnr": 22.728643, - "belowThresholdBy": 7.271356999999998 + "time": 0.8925, + "psnr": 21.623194, + "belowThresholdBy": 8.376805999999998 }, { - "time": 0.95, - "psnr": 22.728644, - "belowThresholdBy": 7.271356000000001 + "time": 0.9420833333333333, + "psnr": 21.623194, + "belowThresholdBy": 8.376805999999998 }, { - "time": 1, - "psnr": 22.728643, - "belowThresholdBy": 7.271356999999998 + "time": 0.9916666666666666, + "psnr": 21.623194, + "belowThresholdBy": 8.376805999999998 }, { - "time": 1.05, - "psnr": 22.728644, - "belowThresholdBy": 7.271356000000001 + "time": 1.04125, + "psnr": 21.623194, + "belowThresholdBy": 8.376805999999998 }, { - "time": 1.1, - "psnr": 22.728643, - "belowThresholdBy": 7.271356999999998 + "time": 1.0908333333333333, + "psnr": 21.623194, + "belowThresholdBy": 8.376805999999998 }, { - "time": 1.15, - "psnr": 22.728643, - "belowThresholdBy": 7.271356999999998 + "time": 1.1404166666666666, + "psnr": 21.623194, + "belowThresholdBy": 8.376805999999998 }, { - "time": 1.2, - "psnr": 22.728644, - "belowThresholdBy": 7.271356000000001 + "time": 1.19, + "psnr": 21.623194, + "belowThresholdBy": 8.376805999999998 }, { - "time": 1.25, - "psnr": 22.728643, - "belowThresholdBy": 7.271356999999998 + "time": 1.2395833333333333, + "psnr": 21.623194, + "belowThresholdBy": 8.376805999999998 }, { - "time": 1.3, - "psnr": 22.728644, - "belowThresholdBy": 7.271356000000001 + "time": 1.2891666666666666, + "psnr": 21.623194, + "belowThresholdBy": 8.376805999999998 }, { - "time": 1.35, - "psnr": 22.728643, - "belowThresholdBy": 7.271356999999998 + "time": 1.33875, + "psnr": 21.623194, + "belowThresholdBy": 8.376805999999998 }, { - "time": 1.4, - "psnr": 22.728643, - "belowThresholdBy": 7.271356999999998 + "time": 1.3883333333333332, + "psnr": 21.623194, + "belowThresholdBy": 8.376805999999998 }, { - "time": 1.45, - "psnr": 22.728644, - "belowThresholdBy": 7.271356000000001 + "time": 1.4379166666666665, + "psnr": 21.623194, + "belowThresholdBy": 8.376805999999998 }, { - "time": 1.5, - "psnr": 22.728643, - "belowThresholdBy": 7.271356999999998 + "time": 1.4875, + "psnr": 21.623194, + "belowThresholdBy": 8.376805999999998 }, { - "time": 1.55, - "psnr": 22.728644, - "belowThresholdBy": 7.271356000000001 + "time": 1.5370833333333331, + "psnr": 21.623194, + "belowThresholdBy": 8.376805999999998 }, { - "time": 1.6, - "psnr": 22.728643, - "belowThresholdBy": 7.271356999999998 + "time": 1.5866666666666667, + "psnr": 21.623194, + "belowThresholdBy": 8.376805999999998 }, { - "time": 1.65, - "psnr": 22.728643, - "belowThresholdBy": 7.271356999999998 + "time": 1.63625, + "psnr": 21.623194, + "belowThresholdBy": 8.376805999999998 }, { - "time": 1.7, - "psnr": 22.728644, - "belowThresholdBy": 7.271356000000001 + "time": 1.685833333333333, + "psnr": 21.623194, + "belowThresholdBy": 8.376805999999998 }, { - "time": 1.75, - "psnr": 22.728643, - "belowThresholdBy": 7.271356999999998 + "time": 1.7354166666666666, + "psnr": 21.623194, + "belowThresholdBy": 8.376805999999998 }, { - "time": 1.8, - "psnr": 22.728644, - "belowThresholdBy": 7.271356000000001 + "time": 1.785, + "psnr": 21.623194, + "belowThresholdBy": 8.376805999999998 }, { - "time": 1.85, - "psnr": 22.728643, - "belowThresholdBy": 7.271356999999998 + "time": 1.8345833333333332, + "psnr": 21.623194, + "belowThresholdBy": 8.376805999999998 }, { - "time": 1.9, - "psnr": 22.728643, - "belowThresholdBy": 7.271356999999998 + "time": 1.8841666666666665, + "psnr": 21.623194, + "belowThresholdBy": 8.376805999999998 }, { - "time": 1.95, - "psnr": 22.728644, - "belowThresholdBy": 7.271356000000001 + "time": 1.93375, + "psnr": 21.623194, + "belowThresholdBy": 8.376805999999998 }, { - "time": 2, - "psnr": 22.728643, - "belowThresholdBy": 7.271356999999998 + "time": 1.9833333333333332, + "psnr": 21.623194, + "belowThresholdBy": 8.376805999999998 }, { - "time": 2.05, - "psnr": 22.728644, - "belowThresholdBy": 7.271356000000001 + "time": 2.0329166666666665, + "psnr": 21.623194, + "belowThresholdBy": 8.376805999999998 }, { - "time": 2.1, - "psnr": 22.728643, - "belowThresholdBy": 7.271356999999998 + "time": 2.0825, + "psnr": 21.623194, + "belowThresholdBy": 8.376805999999998 }, { - "time": 2.15, - "psnr": 22.728643, - "belowThresholdBy": 7.271356999999998 + "time": 2.132083333333333, + "psnr": 21.623194, + "belowThresholdBy": 8.376805999999998 }, { - "time": 2.2, - "psnr": 22.728644, - "belowThresholdBy": 7.271356000000001 + "time": 2.1816666666666666, + "psnr": 21.623194, + "belowThresholdBy": 8.376805999999998 }, { - "time": 2.25, - "psnr": 22.728643, - "belowThresholdBy": 7.271356999999998 + "time": 2.23125, + "psnr": 21.623194, + "belowThresholdBy": 8.376805999999998 }, { - "time": 2.3, - "psnr": 22.728644, - "belowThresholdBy": 7.271356000000001 + "time": 2.2808333333333333, + "psnr": 21.623194, + "belowThresholdBy": 8.376805999999998 }, { - "time": 2.35, - "psnr": 22.728643, - "belowThresholdBy": 7.271356999999998 + "time": 2.3304166666666664, + "psnr": 21.623194, + "belowThresholdBy": 8.376805999999998 }, { - "time": 2.4, - "psnr": 22.728643, - "belowThresholdBy": 7.271356999999998 + "time": 2.38, + "psnr": 21.623194, + "belowThresholdBy": 8.376805999999998 }, { - "time": 2.45, - "psnr": 22.728644, - "belowThresholdBy": 7.271356000000001 + "time": 2.429583333333333, + "psnr": 21.623194, + "belowThresholdBy": 8.376805999999998 }, { - "time": 2.5, - "psnr": 22.728643, - "belowThresholdBy": 7.271356999999998 + "time": 2.4791666666666665, + "psnr": 21.623194, + "belowThresholdBy": 8.376805999999998 }, { - "time": 2.55, - "psnr": 22.728644, - "belowThresholdBy": 7.271356000000001 + "time": 2.5287499999999996, + "psnr": 21.623194, + "belowThresholdBy": 8.376805999999998 }, { - "time": 2.6, - "psnr": 22.728643, - "belowThresholdBy": 7.271356999999998 + "time": 2.578333333333333, + "psnr": 21.623194, + "belowThresholdBy": 8.376805999999998 }, { - "time": 2.65, - "psnr": 22.728643, - "belowThresholdBy": 7.271356999999998 + "time": 2.6279166666666662, + "psnr": 21.623194, + "belowThresholdBy": 8.376805999999998 }, { - "time": 2.7, - "psnr": 22.728644, - "belowThresholdBy": 7.271356000000001 + "time": 2.6775, + "psnr": 21.623194, + "belowThresholdBy": 8.376805999999998 }, { - "time": 2.75, - "psnr": 22.728643, - "belowThresholdBy": 7.271356999999998 + "time": 2.7270833333333333, + "psnr": 21.623194, + "belowThresholdBy": 8.376805999999998 }, { - "time": 2.8, - "psnr": 22.728644, - "belowThresholdBy": 7.271356000000001 + "time": 2.7766666666666664, + "psnr": 21.623194, + "belowThresholdBy": 8.376805999999998 }, { - "time": 2.85, - "psnr": 22.728643, - "belowThresholdBy": 7.271356999999998 + "time": 2.82625, + "psnr": 21.623194, + "belowThresholdBy": 8.376805999999998 }, { - "time": 2.9, - "psnr": 22.728643, - "belowThresholdBy": 7.271356999999998 + "time": 2.875833333333333, + "psnr": 21.623194, + "belowThresholdBy": 8.376805999999998 }, { - "time": 2.95, - "psnr": 22.728644, - "belowThresholdBy": 7.271356000000001 + "time": 2.925416666666666, + "psnr": 21.623194, + "belowThresholdBy": 8.376805999999998 }, { - "time": 3, - "psnr": 22.728643, - "belowThresholdBy": 7.271356999999998 + "time": 2.975, + "psnr": 21.623194, + "belowThresholdBy": 8.376805999999998 }, { - "time": 3.05, - "psnr": 22.728644, - "belowThresholdBy": 7.271356000000001 + "time": 3.024583333333333, + "psnr": 21.623194, + "belowThresholdBy": 8.376805999999998 }, { - "time": 3.1, - "psnr": 22.728643, - "belowThresholdBy": 7.271356999999998 + "time": 3.0741666666666663, + "psnr": 21.623194, + "belowThresholdBy": 8.376805999999998 }, { - "time": 3.15, - "psnr": 22.728643, - "belowThresholdBy": 7.271356999999998 + "time": 3.12375, + "psnr": 21.623194, + "belowThresholdBy": 8.376805999999998 }, { - "time": 3.2, - "psnr": 22.728555, - "belowThresholdBy": 7.271445 + "time": 3.1733333333333333, + "psnr": 21.623194, + "belowThresholdBy": 8.376805999999998 }, { - "time": 3.25, - "psnr": 22.728555, - "belowThresholdBy": 7.271445 + "time": 3.2229166666666664, + "psnr": 21.623186, + "belowThresholdBy": 8.376814 }, { - "time": 3.3, - "psnr": 22.728555, - "belowThresholdBy": 7.271445 + "time": 3.2725, + "psnr": 21.623186, + "belowThresholdBy": 8.376814 }, { - "time": 3.35, - "psnr": 22.728555, - "belowThresholdBy": 7.271445 + "time": 3.322083333333333, + "psnr": 21.623186, + "belowThresholdBy": 8.376814 }, { - "time": 3.4, - "psnr": 22.728555, - "belowThresholdBy": 7.271445 + "time": 3.371666666666666, + "psnr": 21.623186, + "belowThresholdBy": 8.376814 }, { - "time": 3.45, - "psnr": 22.728565, - "belowThresholdBy": 7.271435 + "time": 3.42125, + "psnr": 21.623186, + "belowThresholdBy": 8.376814 }, { - "time": 3.5, - "psnr": 22.728565, - "belowThresholdBy": 7.271435 + "time": 3.470833333333333, + "psnr": 21.623186, + "belowThresholdBy": 8.376814 }, { - "time": 3.55, - "psnr": 22.728565, - "belowThresholdBy": 7.271435 + "time": 3.5204166666666663, + "psnr": 21.623186, + "belowThresholdBy": 8.376814 }, { - "time": 3.6, - "psnr": 22.728565, - "belowThresholdBy": 7.271435 + "time": 3.57, + "psnr": 21.623186, + "belowThresholdBy": 8.376814 }, { - "time": 3.65, - "psnr": 22.728565, - "belowThresholdBy": 7.271435 + "time": 3.619583333333333, + "psnr": 21.623186, + "belowThresholdBy": 8.376814 }, { - "time": 3.7, - "psnr": 22.728565, - "belowThresholdBy": 7.271435 + "time": 3.6691666666666665, + "psnr": 21.623186, + "belowThresholdBy": 8.376814 }, { - "time": 3.75, - "psnr": 22.728565, - "belowThresholdBy": 7.271435 + "time": 3.71875, + "psnr": 21.623186, + "belowThresholdBy": 8.376814 }, { - "time": 3.8, - "psnr": 22.728565, - "belowThresholdBy": 7.271435 + "time": 3.768333333333333, + "psnr": 21.623186, + "belowThresholdBy": 8.376814 }, { - "time": 3.85, - "psnr": 22.728565, - "belowThresholdBy": 7.271435 + "time": 3.817916666666666, + "psnr": 21.623186, + "belowThresholdBy": 8.376814 }, { - "time": 3.9, - "psnr": 22.728565, - "belowThresholdBy": 7.271435 + "time": 3.8675, + "psnr": 21.623186, + "belowThresholdBy": 8.376814 }, { - "time": 3.95, - "psnr": 22.728565, - "belowThresholdBy": 7.271435 + "time": 3.9170833333333333, + "psnr": 21.623186, + "belowThresholdBy": 8.376814 }, { - "time": 4, - "psnr": 22.728565, - "belowThresholdBy": 7.271435 + "time": 3.9666666666666663, + "psnr": 21.623186, + "belowThresholdBy": 8.376814 }, { - "time": 4.05, - "psnr": 22.728565, - "belowThresholdBy": 7.271435 + "time": 4.01625, + "psnr": 21.623186, + "belowThresholdBy": 8.376814 }, { - "time": 4.1, - "psnr": 22.728565, - "belowThresholdBy": 7.271435 + "time": 4.065833333333333, + "psnr": 21.623186, + "belowThresholdBy": 8.376814 }, { - "time": 4.15, - "psnr": 22.728681, - "belowThresholdBy": 7.271318999999998 + "time": 4.1154166666666665, + "psnr": 21.623186, + "belowThresholdBy": 8.376814 }, { - "time": 4.2, - "psnr": 22.728681, - "belowThresholdBy": 7.271318999999998 + "time": 4.165, + "psnr": 21.623201, + "belowThresholdBy": 8.376798999999998 }, { - "time": 4.25, - "psnr": 22.728681, - "belowThresholdBy": 7.271318999999998 + "time": 4.214583333333334, + "psnr": 21.623201, + "belowThresholdBy": 8.376798999999998 }, { - "time": 4.3, - "psnr": 22.728681, - "belowThresholdBy": 7.271318999999998 + "time": 4.264166666666666, + "psnr": 21.623201, + "belowThresholdBy": 8.376798999999998 }, { - "time": 4.35, - "psnr": 22.728681, - "belowThresholdBy": 7.271318999999998 + "time": 4.31375, + "psnr": 21.623201, + "belowThresholdBy": 8.376798999999998 }, { - "time": 4.4, - "psnr": 22.728681, - "belowThresholdBy": 7.271318999999998 + "time": 4.363333333333333, + "psnr": 21.623201, + "belowThresholdBy": 8.376798999999998 }, { - "time": 4.45, - "psnr": 22.728681, - "belowThresholdBy": 7.271318999999998 + "time": 4.412916666666666, + "psnr": 21.623201, + "belowThresholdBy": 8.376798999999998 }, { - "time": 4.5, - "psnr": 22.728681, - "belowThresholdBy": 7.271318999999998 + "time": 4.4625, + "psnr": 21.623201, + "belowThresholdBy": 8.376798999999998 }, { - "time": 4.55, - "psnr": 22.728681, - "belowThresholdBy": 7.271318999999998 + "time": 4.512083333333333, + "psnr": 21.623201, + "belowThresholdBy": 8.376798999999998 }, { - "time": 4.6, - "psnr": 22.728681, - "belowThresholdBy": 7.271318999999998 + "time": 4.5616666666666665, + "psnr": 21.623201, + "belowThresholdBy": 8.376798999999998 }, { - "time": 4.65, - "psnr": 22.728681, - "belowThresholdBy": 7.271318999999998 + "time": 4.61125, + "psnr": 21.623201, + "belowThresholdBy": 8.376798999999998 }, { - "time": 4.7, - "psnr": 22.728681, - "belowThresholdBy": 7.271318999999998 + "time": 4.660833333333333, + "psnr": 21.623201, + "belowThresholdBy": 8.376798999999998 }, { - "time": 4.75, - "psnr": 22.728681, - "belowThresholdBy": 7.271318999999998 + "time": 4.710416666666666, + "psnr": 21.623201, + "belowThresholdBy": 8.376798999999998 }, { - "time": 4.8, - "psnr": 22.728681, - "belowThresholdBy": 7.271318999999998 + "time": 4.76, + "psnr": 21.623201, + "belowThresholdBy": 8.376798999999998 }, { - "time": 4.85, - "psnr": 22.728681, - "belowThresholdBy": 7.271318999999998 + "time": 4.809583333333333, + "psnr": 21.623201, + "belowThresholdBy": 8.376798999999998 }, { - "time": 4.9, - "psnr": 22.728681, - "belowThresholdBy": 7.271318999999998 + "time": 4.859166666666666, + "psnr": 21.623201, + "belowThresholdBy": 8.376798999999998 }, { - "time": 4.95, - "psnr": 22.728681, - "belowThresholdBy": 7.271318999999998 + "time": 4.9087499999999995, + "psnr": 21.623201, + "belowThresholdBy": 8.376798999999998 } ] } \ No newline at end of file diff --git a/packages/producer/tests/vfr-screen-recording/failures/frames/actual_0_09s.png b/packages/producer/tests/vfr-screen-recording/failures/frames/actual_0_09s.png index 035d31014..f7901ed72 100644 Binary files a/packages/producer/tests/vfr-screen-recording/failures/frames/actual_0_09s.png and b/packages/producer/tests/vfr-screen-recording/failures/frames/actual_0_09s.png differ diff --git a/packages/producer/tests/vfr-screen-recording/failures/frames/actual_0_12s.png b/packages/producer/tests/vfr-screen-recording/failures/frames/actual_0_12s.png index 48117d335..a7a6b291c 100644 Binary files a/packages/producer/tests/vfr-screen-recording/failures/frames/actual_0_12s.png and b/packages/producer/tests/vfr-screen-recording/failures/frames/actual_0_12s.png differ diff --git a/packages/producer/tests/vfr-screen-recording/failures/frames/actual_0_15s.png b/packages/producer/tests/vfr-screen-recording/failures/frames/actual_0_15s.png index 83696e4af..a7a6b291c 100644 Binary files a/packages/producer/tests/vfr-screen-recording/failures/frames/actual_0_15s.png and b/packages/producer/tests/vfr-screen-recording/failures/frames/actual_0_15s.png differ diff --git a/packages/producer/tests/vfr-screen-recording/failures/frames/actual_0_18s.png b/packages/producer/tests/vfr-screen-recording/failures/frames/actual_0_18s.png index 83696e4af..b4ed6d417 100644 Binary files a/packages/producer/tests/vfr-screen-recording/failures/frames/actual_0_18s.png and b/packages/producer/tests/vfr-screen-recording/failures/frames/actual_0_18s.png differ diff --git a/packages/producer/tests/vfr-screen-recording/failures/frames/actual_0_21s.png b/packages/producer/tests/vfr-screen-recording/failures/frames/actual_0_21s.png index 5ee1187ad..070347914 100644 Binary files a/packages/producer/tests/vfr-screen-recording/failures/frames/actual_0_21s.png and b/packages/producer/tests/vfr-screen-recording/failures/frames/actual_0_21s.png differ diff --git a/packages/producer/tests/vfr-screen-recording/failures/frames/expected_0_09s.png b/packages/producer/tests/vfr-screen-recording/failures/frames/expected_0_09s.png index 4c8fbfc78..ef44d7fbe 100644 Binary files a/packages/producer/tests/vfr-screen-recording/failures/frames/expected_0_09s.png and b/packages/producer/tests/vfr-screen-recording/failures/frames/expected_0_09s.png differ diff --git a/packages/producer/tests/vfr-screen-recording/failures/frames/expected_0_12s.png b/packages/producer/tests/vfr-screen-recording/failures/frames/expected_0_12s.png index 6a071bad0..44db4bdf7 100644 Binary files a/packages/producer/tests/vfr-screen-recording/failures/frames/expected_0_12s.png and b/packages/producer/tests/vfr-screen-recording/failures/frames/expected_0_12s.png differ diff --git a/packages/producer/tests/vfr-screen-recording/failures/frames/expected_0_15s.png b/packages/producer/tests/vfr-screen-recording/failures/frames/expected_0_15s.png index 914867d10..44db4bdf7 100644 Binary files a/packages/producer/tests/vfr-screen-recording/failures/frames/expected_0_15s.png and b/packages/producer/tests/vfr-screen-recording/failures/frames/expected_0_15s.png differ diff --git a/packages/producer/tests/vfr-screen-recording/failures/frames/expected_0_18s.png b/packages/producer/tests/vfr-screen-recording/failures/frames/expected_0_18s.png index 914867d10..e6d28d5a5 100644 Binary files a/packages/producer/tests/vfr-screen-recording/failures/frames/expected_0_18s.png and b/packages/producer/tests/vfr-screen-recording/failures/frames/expected_0_18s.png differ diff --git a/packages/producer/tests/vfr-screen-recording/failures/frames/expected_0_21s.png b/packages/producer/tests/vfr-screen-recording/failures/frames/expected_0_21s.png index 54703b661..bcf1bfd84 100644 Binary files a/packages/producer/tests/vfr-screen-recording/failures/frames/expected_0_21s.png and b/packages/producer/tests/vfr-screen-recording/failures/frames/expected_0_21s.png differ diff --git a/packages/producer/tests/vfr-screen-recording/failures/visual-failures.json b/packages/producer/tests/vfr-screen-recording/failures/visual-failures.json index 90f0a5a74..18a411b47 100644 --- a/packages/producer/tests/vfr-screen-recording/failures/visual-failures.json +++ b/packages/producer/tests/vfr-screen-recording/failures/visual-failures.json @@ -1,279 +1,270 @@ { "summary": { "totalCheckpoints": 100, - "failedCheckpoints": 54, - "threshold": 28 + "failedCheckpoints": 52, + "threshold": 28, + "fixtureThreshold": 28 }, "failedFrames": [ { - "time": 0.09, - "psnr": 22.256128, - "belowThresholdBy": 5.743872 + "time": 0.029666666666666668, + "psnr": 24.44885, + "belowThresholdBy": 3.55115 }, { - "time": 0.12, - "psnr": 22.140487, - "belowThresholdBy": 5.859513 + "time": 0.059333333333333335, + "psnr": 22.568789, + "belowThresholdBy": 5.431211000000001 }, { - "time": 0.15, - "psnr": 22.179456, - "belowThresholdBy": 5.820544000000002 + "time": 0.08900000000000001, + "psnr": 22.349581, + "belowThresholdBy": 5.650418999999999 }, { - "time": 0.18, - "psnr": 22.179456, - "belowThresholdBy": 5.820544000000002 + "time": 0.11866666666666667, + "psnr": 22.391461, + "belowThresholdBy": 5.608539 }, { - "time": 0.21, - "psnr": 21.965369, - "belowThresholdBy": 6.034631000000001 + "time": 0.14833333333333334, + "psnr": 22.391461, + "belowThresholdBy": 5.608539 }, { - "time": 0.72, - "psnr": 22.124397, - "belowThresholdBy": 5.875603000000002 + "time": 0.17800000000000002, + "psnr": 22.660384, + "belowThresholdBy": 5.3396159999999995 }, { - "time": 0.75, - "psnr": 21.974375, - "belowThresholdBy": 6.025625000000002 + "time": 0.20766666666666667, + "psnr": 24.714207, + "belowThresholdBy": 3.2857930000000017 }, { - "time": 0.78, - "psnr": 21.974375, - "belowThresholdBy": 6.025625000000002 + "time": 0.23733333333333334, + "psnr": 21.961888, + "belowThresholdBy": 6.038112000000002 }, { - "time": 0.81, - "psnr": 21.576887, - "belowThresholdBy": 6.423113000000001 + "time": 0.267, + "psnr": 22.13149, + "belowThresholdBy": 5.868510000000001 }, { - "time": 0.84, - "psnr": 20.875483, - "belowThresholdBy": 7.124517000000001 + "time": 0.7416666666666667, + "psnr": 22.157503, + "belowThresholdBy": 5.842497000000002 }, { - "time": 0.87, - "psnr": 20.573199, - "belowThresholdBy": 7.426801000000001 + "time": 0.7713333333333334, + "psnr": 21.703576, + "belowThresholdBy": 6.296423999999998 }, { - "time": 0.9, - "psnr": 20.659209, - "belowThresholdBy": 7.340790999999999 + "time": 0.801, + "psnr": 21.979018, + "belowThresholdBy": 6.020982 }, { - "time": 0.93, - "psnr": 20.660655, - "belowThresholdBy": 7.339345000000002 + "time": 0.8306666666666667, + "psnr": 20.468804, + "belowThresholdBy": 7.531196000000001 }, { - "time": 0.96, - "psnr": 20.661614, - "belowThresholdBy": 7.338386 + "time": 0.8603333333333333, + "psnr": 20.24634, + "belowThresholdBy": 7.75366 }, { - "time": 0.99, - "psnr": 20.660907, - "belowThresholdBy": 7.339092999999998 + "time": 1.1866666666666668, + "psnr": 20.358821, + "belowThresholdBy": 7.641179000000001 }, { - "time": 1.02, - "psnr": 20.663712, - "belowThresholdBy": 7.336288 + "time": 1.2163333333333335, + "psnr": 20.358821, + "belowThresholdBy": 7.641179000000001 }, { - "time": 1.05, - "psnr": 20.661661, - "belowThresholdBy": 7.338339000000001 + "time": 1.246, + "psnr": 20.304962, + "belowThresholdBy": 7.695038 }, { - "time": 1.08, - "psnr": 20.661661, - "belowThresholdBy": 7.338339000000001 + "time": 1.2756666666666667, + "psnr": 21.366366, + "belowThresholdBy": 6.633634000000001 }, { - "time": 1.11, - "psnr": 20.658796, - "belowThresholdBy": 7.341204000000001 + "time": 1.3053333333333332, + "psnr": 21.759025, + "belowThresholdBy": 6.240974999999999 }, { - "time": 1.17, - "psnr": 21.79722, - "belowThresholdBy": 6.202780000000001 + "time": 1.335, + "psnr": 21.92549, + "belowThresholdBy": 6.07451 }, { - "time": 1.2, - "psnr": 21.556139, - "belowThresholdBy": 6.443860999999998 + "time": 1.3646666666666667, + "psnr": 22.279441, + "belowThresholdBy": 5.7205590000000015 }, { - "time": 1.23, - "psnr": 20.188096, - "belowThresholdBy": 7.811903999999998 + "time": 1.3943333333333334, + "psnr": 22.363145, + "belowThresholdBy": 5.636855000000001 }, { - "time": 1.29, - "psnr": 22.406725, - "belowThresholdBy": 5.593274999999998 + "time": 1.4240000000000002, + "psnr": 24.205173, + "belowThresholdBy": 3.7948270000000015 }, { - "time": 1.32, - "psnr": 22.786094, - "belowThresholdBy": 5.2139060000000015 + "time": 1.4536666666666667, + "psnr": 22.777445, + "belowThresholdBy": 5.222555 }, { - "time": 1.35, - "psnr": 23.352752, - "belowThresholdBy": 4.647248000000001 + "time": 1.9580000000000002, + "psnr": 26.75451, + "belowThresholdBy": 1.2454900000000002 }, { - "time": 1.38, - "psnr": 23.352752, - "belowThresholdBy": 4.647248000000001 + "time": 1.9876666666666667, + "psnr": 23.394872, + "belowThresholdBy": 4.6051280000000006 }, { - "time": 1.41, - "psnr": 22.211662, - "belowThresholdBy": 5.7883379999999995 + "time": 2.0173333333333336, + "psnr": 23.247368, + "belowThresholdBy": 4.752631999999998 }, { - "time": 1.92, - "psnr": 25.090316, - "belowThresholdBy": 2.9096839999999986 + "time": 2.047, + "psnr": 23.247368, + "belowThresholdBy": 4.752631999999998 }, { - "time": 1.95, - "psnr": 23.673743, - "belowThresholdBy": 4.326256999999998 + "time": 2.0766666666666667, + "psnr": 23.111096, + "belowThresholdBy": 4.888904 }, { - "time": 1.98, - "psnr": 23.673743, - "belowThresholdBy": 4.326256999999998 + "time": 2.1063333333333336, + "psnr": 23.118457, + "belowThresholdBy": 4.881543000000001 }, { - "time": 2.01, - "psnr": 22.642487, - "belowThresholdBy": 5.357513000000001 + "time": 2.136, + "psnr": 23.530627, + "belowThresholdBy": 4.469373000000001 }, { - "time": 2.04, - "psnr": 22.718313, - "belowThresholdBy": 5.281687000000002 + "time": 2.1656666666666666, + "psnr": 23.264726, + "belowThresholdBy": 4.735274 }, { - "time": 2.07, - "psnr": 23.028197, - "belowThresholdBy": 4.971803000000001 + "time": 2.195333333333333, + "psnr": 23.406522, + "belowThresholdBy": 4.593478000000001 }, { - "time": 2.1, - "psnr": 23.751957, - "belowThresholdBy": 4.248042999999999 + "time": 2.225, + "psnr": 23.253297, + "belowThresholdBy": 4.746703 }, { - "time": 2.13, - "psnr": 25.975816, - "belowThresholdBy": 2.0241840000000018 + "time": 2.2546666666666666, + "psnr": 23.241565, + "belowThresholdBy": 4.758434999999999 }, { - "time": 2.16, - "psnr": 22.928774, - "belowThresholdBy": 5.071225999999999 + "time": 2.2843333333333335, + "psnr": 23.046583, + "belowThresholdBy": 4.953417000000002 }, { - "time": 2.19, - "psnr": 26.324329, - "belowThresholdBy": 1.6756710000000012 + "time": 2.314, + "psnr": 23.046583, + "belowThresholdBy": 4.953417000000002 }, { - "time": 2.22, - "psnr": 25.537279, - "belowThresholdBy": 2.4627209999999984 + "time": 2.3436666666666666, + "psnr": 23.321539, + "belowThresholdBy": 4.678460999999999 }, { - "time": 2.25, - "psnr": 26.382274, - "belowThresholdBy": 1.617726000000001 + "time": 2.3733333333333335, + "psnr": 23.2271, + "belowThresholdBy": 4.7729 }, { - "time": 2.28, - "psnr": 26.382274, - "belowThresholdBy": 1.617726000000001 + "time": 2.403, + "psnr": 23.022527, + "belowThresholdBy": 4.977473 }, { - "time": 2.31, - "psnr": 23.573514, - "belowThresholdBy": 4.426486000000001 + "time": 2.432666666666667, + "psnr": 23.017229, + "belowThresholdBy": 4.982771 }, { - "time": 2.46, - "psnr": 24.578146, - "belowThresholdBy": 3.4218539999999997 + "time": 2.4623333333333335, + "psnr": 22.887764, + "belowThresholdBy": 5.112235999999999 }, { - "time": 2.49, - "psnr": 24.501098, - "belowThresholdBy": 3.498902000000001 + "time": 2.492, + "psnr": 22.827383, + "belowThresholdBy": 5.172616999999999 }, { - "time": 2.52, - "psnr": 24.404203, - "belowThresholdBy": 3.595797000000001 + "time": 2.521666666666667, + "psnr": 22.876932, + "belowThresholdBy": 5.123068 }, { - "time": 2.55, - "psnr": 25.122537, - "belowThresholdBy": 2.8774629999999988 + "time": 2.5513333333333335, + "psnr": 23.549837, + "belowThresholdBy": 4.450163 }, { - "time": 2.58, - "psnr": 25.122537, - "belowThresholdBy": 2.8774629999999988 + "time": 2.5810000000000004, + "psnr": 23.549837, + "belowThresholdBy": 4.450163 }, { - "time": 2.61, - "psnr": 26.335585, - "belowThresholdBy": 1.6644150000000018 + "time": 2.6106666666666665, + "psnr": 22.929946, + "belowThresholdBy": 5.070053999999999 }, { - "time": 2.64, - "psnr": 24.310134, - "belowThresholdBy": 3.6898659999999985 + "time": 2.6403333333333334, + "psnr": 26.268077, + "belowThresholdBy": 1.7319229999999983 }, { - "time": 2.67, - "psnr": 25.824841, - "belowThresholdBy": 2.1751590000000007 + "time": 2.818333333333334, + "psnr": 25.377759, + "belowThresholdBy": 2.622240999999999 }, { - "time": 2.85, - "psnr": 22.968464, - "belowThresholdBy": 5.031535999999999 + "time": 2.8480000000000003, + "psnr": 25.377759, + "belowThresholdBy": 2.622240999999999 }, { - "time": 2.88, - "psnr": 22.968464, - "belowThresholdBy": 5.031535999999999 + "time": 2.9073333333333333, + "psnr": 22.824227, + "belowThresholdBy": 5.1757729999999995 }, { - "time": 2.91, - "psnr": 22.524879, - "belowThresholdBy": 5.4751210000000015 - }, - { - "time": 2.94, - "psnr": 23.12954, - "belowThresholdBy": 4.870460000000001 - }, - { - "time": 2.97, - "psnr": 23.497156, - "belowThresholdBy": 4.502844 + "time": 2.937, + "psnr": 22.829516, + "belowThresholdBy": 5.170483999999998 } ] } \ No newline at end of file diff --git a/packages/studio/src/App.tsx b/packages/studio/src/App.tsx index 2e9f68a4a..56af6bef2 100644 --- a/packages/studio/src/App.tsx +++ b/packages/studio/src/App.tsx @@ -26,10 +26,11 @@ import { useCompositionDimensions } from "./hooks/useCompositionDimensions"; import { useToast } from "./hooks/useToast"; import { useStudioUrlState } from "./hooks/useStudioUrlState"; import { - STUDIO_INSPECTOR_PANELS_ENABLED, - STUDIO_MOTION_PANEL_ENABLED, -} from "./components/editor/manualEditingAvailability"; -import { readStudioMotionFromElement } from "./components/editor/studioMotion"; + buildStudioContextValue, + useDragOverlay, + useInspectorState, +} from "./hooks/useStudioContextValue"; +import { buildAgentContextPreview } from "./components/editor/domEditingAgentPrompt"; import type { DomEditSelection } from "./components/editor/domEditing"; import { AskAgentModal } from "./components/AskAgentModal"; import { StudioGlobalDragOverlay } from "./components/StudioGlobalDragOverlay"; @@ -38,7 +39,7 @@ import { StudioLeftSidebar } from "./components/StudioLeftSidebar"; import { StudioPreviewArea } from "./components/StudioPreviewArea"; import { StudioRightPanel } from "./components/StudioRightPanel"; import { TimelineToolbar } from "./components/TimelineToolbar"; -import { StudioProvider, type StudioContextValue } from "./contexts/StudioContext"; +import { StudioProvider } from "./contexts/StudioContext"; import { PanelLayoutProvider } from "./contexts/PanelLayoutContext"; import { FileManagerProvider } from "./contexts/FileManagerContext"; import { DomEditProvider } from "./contexts/DomEditContext"; @@ -51,6 +52,7 @@ import { import { trackStudioSessionStart } from "./telemetry/events"; import { hasFiredSessionStart, markSessionStartFired } from "./telemetry/config"; +// fallow-ignore-next-line complexity export function StudioApp() { const { projectId, resolving, waitingForServer } = useServerConnection(); const initialUrlStateRef = useRef(readStudioUrlStateFromWindow()); @@ -184,6 +186,26 @@ export function StudioApp() { uploadProjectFiles: fileManager.uploadProjectFiles, }); + const blockCtx = useMemo( + () => ({ + activeCompPath, + timelineElements, + readProjectFile: fileManager.readProjectFile, + writeProjectFile: fileManager.writeProjectFile, + recordEdit: editHistory.recordEdit, + refreshFileTree: fileManager.refreshFileTree, + reloadPreview, + showToast, + }), + [ + activeCompPath, + timelineElements, + fileManager, + editHistory.recordEdit, + reloadPreview, + showToast, + ], + ); const handleAddBlock = useCallback( (blockName: string) => { if (!projectId) return; @@ -191,16 +213,9 @@ export function StudioApp() { const result = await addBlockToProject({ projectId, blockName, - activeCompPath, + ...blockCtx, previewIframe: previewIframeRef.current, currentTime: usePlayerStore.getState().currentTime, - timelineElements, - readProjectFile: fileManager.readProjectFile, - writeProjectFile: fileManager.writeProjectFile, - recordEdit: editHistory.recordEdit, - refreshFileTree: fileManager.refreshFileTree, - reloadPreview, - showToast, }); const params = result?.block.type === "hyperframes:block" ? result.block.params : undefined; if (params?.length) { @@ -215,82 +230,35 @@ export function StudioApp() { } })(); }, - [ - projectId, - activeCompPath, - timelineElements, - fileManager.readProjectFile, - fileManager.writeProjectFile, - fileManager.refreshFileTree, - editHistory.recordEdit, - reloadPreview, - showToast, - panelLayout, - ], + [projectId, blockCtx, panelLayout], ); - const handleTimelineBlockDrop = useCallback( (blockName: string, placement: { start: number; track: number }) => { if (!projectId) return; void addBlockToProject({ projectId, blockName, - activeCompPath, placement, + ...blockCtx, previewIframe: previewIframeRef.current, currentTime: usePlayerStore.getState().currentTime, - timelineElements, - readProjectFile: fileManager.readProjectFile, - writeProjectFile: fileManager.writeProjectFile, - recordEdit: editHistory.recordEdit, - refreshFileTree: fileManager.refreshFileTree, - reloadPreview, - showToast, }); }, - [ - projectId, - activeCompPath, - timelineElements, - fileManager.readProjectFile, - fileManager.writeProjectFile, - fileManager.refreshFileTree, - editHistory.recordEdit, - reloadPreview, - showToast, - ], + [projectId, blockCtx], ); - const handlePreviewBlockDrop = useCallback( (blockName: string, position: { left: number; top: number }) => { if (!projectId) return; void addBlockToProject({ projectId, blockName, - activeCompPath, visualPosition: position, + ...blockCtx, previewIframe: previewIframeRef.current, currentTime: usePlayerStore.getState().currentTime, - timelineElements, - readProjectFile: fileManager.readProjectFile, - writeProjectFile: fileManager.writeProjectFile, - recordEdit: editHistory.recordEdit, - refreshFileTree: fileManager.refreshFileTree, - reloadPreview, - showToast, }); }, - [ - projectId, - activeCompPath, - timelineElements, - fileManager.readProjectFile, - fileManager.writeProjectFile, - fileManager.refreshFileTree, - editHistory.recordEdit, - reloadPreview, - showToast, - ], + [projectId, blockCtx], ); const clearDomSelectionRef = useRef<() => void>(() => {}); @@ -414,30 +382,22 @@ export function StudioApp() { resetErrors: resetConsoleErrors, } = useConsoleErrorCapture(previewIframe); - const [globalDragOver, setGlobalDragOver] = useState(false); - const dragCounterRef = useRef(0); + const dragOverlay = useDragOverlay(fileManager.handleImportFiles); - const { syncPreviewTimelineHotkey, syncPreviewHistoryHotkey } = appHotkeys; const handlePreviewIframeRef = useCallback( (iframe: HTMLIFrameElement | null) => { previewIframeRef.current = iframe; setPreviewIframe(iframe); - syncPreviewTimelineHotkey(iframe); - syncPreviewHistoryHotkey(iframe); + appHotkeys.syncPreviewTimelineHotkey(iframe); + appHotkeys.syncPreviewHistoryHotkey(iframe); resetConsoleErrors(); refreshPreviewDocumentVersion(); }, - [ - refreshPreviewDocumentVersion, - resetConsoleErrors, - syncPreviewHistoryHotkey, - syncPreviewTimelineHotkey, - ], + [appHotkeys, resetConsoleErrors, refreshPreviewDocumentVersion], ); - const handleSelectComposition = useCallback( (comp: string) => { - setActiveCompPath(comp === "index.html" || comp.startsWith("compositions/") ? comp : null); + setActiveCompPath(comp.endsWith(".html") ? comp : null); fileManager.setEditingFile({ path: comp, content: null }); fetch(`/api/projects/${projectId}/files/${comp}`) .then((r) => r.json()) @@ -447,23 +407,19 @@ export function StudioApp() { [projectId, fileManager], ); - const selectedStudioMotion = - STUDIO_INSPECTOR_PANELS_ENABLED && domEditSession.domEditSelection - ? readStudioMotionFromElement(domEditSession.domEditSelection.element) - : null; - const layersPanelActive = - STUDIO_INSPECTOR_PANELS_ENABLED && panelLayout.rightPanelTab === "layers"; - const designPanelActive = - STUDIO_INSPECTOR_PANELS_ENABLED && panelLayout.rightPanelTab === "design"; - const motionPanelActive = - STUDIO_INSPECTOR_PANELS_ENABLED && - STUDIO_MOTION_PANEL_ENABLED && - panelLayout.rightPanelTab === "motion"; - const inspectorPanelActive = layersPanelActive || designPanelActive || motionPanelActive; - const shouldShowSelectedDomBounds = - inspectorPanelActive && !panelLayout.rightCollapsed && !isPlaying; - const inspectorButtonActive = - STUDIO_INSPECTOR_PANELS_ENABLED && !panelLayout.rightCollapsed && inspectorPanelActive; + const { + selectedStudioMotion, + designPanelActive, + motionPanelActive, + inspectorPanelActive, + inspectorButtonActive, + shouldShowSelectedDomBounds, + } = useInspectorState( + panelLayout.rightPanelTab, + panelLayout.rightCollapsed, + isPlaying, + domEditSession.domEditSelection, + ); useStudioUrlState({ projectId, @@ -484,8 +440,7 @@ export function StudioApp() { initialState: initialUrlStateRef.current, }); - // StudioProvider performs its own useMemo — no need for a second memo here. - const studioCtxValue: StudioContextValue = { + const studioCtxValue = buildStudioContextValue({ projectId: projectId!, activeCompPath, setActiveCompPath, @@ -498,12 +453,7 @@ export function StudioApp() { currentTime, timelineElements, isPlaying, - editHistory: { - canUndo: editHistory.canUndo, - canRedo: editHistory.canRedo, - undoLabel: editHistory.undoLabel, - redoLabel: editHistory.redoLabel, - }, + editHistory, handleUndo: appHotkeys.handleUndo, handleRedo: appHotkeys.handleRedo, renderQueue: { @@ -519,7 +469,7 @@ export function StudioApp() { refreshPreviewDocumentVersion, timelineVisible, toggleTimelineVisibility, - }; + }); if (resolving || waitingForServer || !projectId) { return ; @@ -533,28 +483,10 @@ export function StudioApp() {
{ - if (!e.dataTransfer.types.includes("Files")) return; - e.preventDefault(); - }} - onDragEnter={(e) => { - if (!e.dataTransfer.types.includes("Files")) return; - e.preventDefault(); - dragCounterRef.current++; - setGlobalDragOver(true); - }} - onDragLeave={() => { - dragCounterRef.current--; - if (dragCounterRef.current === 0) setGlobalDragOver(false); - }} - onDrop={(e) => { - dragCounterRef.current = 0; - setGlobalDragOver(false); - if (e.defaultPrevented) return; - e.preventDefault(); - if (e.dataTransfer.files.length) - fileManager.handleImportFiles(e.dataTransfer.files); - }} + onDragOver={dragOverlay.onDragOver} + onDragEnter={dragOverlay.onDragEnter} + onDragLeave={dragOverlay.onDragLeave} + onDrop={dragOverlay.onDrop} > { @@ -630,7 +566,7 @@ export function StudioApp() { /> )} - {globalDragOver && } + {dragOverlay.active && } {appToast && (
void; onClose: () => void; @@ -66,7 +68,7 @@ export function AskAgentModal({ >
-

Ask agent

+

Copy prompt to AI agent

{selectionLabel.length > 50 ? `${selectionLabel.slice(0, 49)}…` : selectionLabel}

@@ -89,7 +91,7 @@ export function AskAgentModal({
-
+