From 7f8042f39a3ce479ac135de5dd9690f44c256532 Mon Sep 17 00:00:00 2001 From: Miguel Angel Simon Sierra Date: Wed, 8 Jul 2026 17:08:46 -0400 Subject: [PATCH 1/2] feat(scripts): gsap-to-anime codemod with classification (U9) --- package.json | 2 +- .../__fixtures__/eases.after.html | 15 + .../__fixtures__/eases.before.html | 16 + .../__fixtures__/fromto-set.after.html | 16 + .../__fixtures__/fromto-set.before.html | 18 + .../motionpath-manual.before.html | 23 + .../__fixtures__/positions.after.html | 12 + .../__fixtures__/positions.before.html | 14 + .../__fixtures__/repeat-yoyo.after.html | 10 + .../__fixtures__/repeat-yoyo.before.html | 11 + .../__fixtures__/simple-to.after.html | 11 + .../__fixtures__/simple-to.before.html | 12 + .../__fixtures__/splittext-manual.before.html | 13 + .../__fixtures__/stagger-grid.after.html | 20 + .../__fixtures__/stagger-grid.before.html | 21 + scripts/gsap-to-anime/classifier.ts | 258 + scripts/gsap-to-anime/cli.ts | 82 + scripts/gsap-to-anime/converter.ts | 276 + scripts/gsap-to-anime/dry-run-report.json | 5791 +++++++++++++++++ scripts/gsap-to-anime/dry-run-report.md | 169 + scripts/gsap-to-anime/gsap-to-anime.test.ts | 94 + scripts/gsap-to-anime/html.ts | 39 + scripts/gsap-to-anime/index.ts | 56 + scripts/gsap-to-anime/notes.ts | 27 + scripts/gsap-to-anime/registration.ts | 46 + scripts/gsap-to-anime/report.ts | 219 + scripts/gsap-to-anime/types.ts | 56 + 27 files changed, 7326 insertions(+), 1 deletion(-) create mode 100644 scripts/gsap-to-anime/__fixtures__/eases.after.html create mode 100644 scripts/gsap-to-anime/__fixtures__/eases.before.html create mode 100644 scripts/gsap-to-anime/__fixtures__/fromto-set.after.html create mode 100644 scripts/gsap-to-anime/__fixtures__/fromto-set.before.html create mode 100644 scripts/gsap-to-anime/__fixtures__/motionpath-manual.before.html create mode 100644 scripts/gsap-to-anime/__fixtures__/positions.after.html create mode 100644 scripts/gsap-to-anime/__fixtures__/positions.before.html create mode 100644 scripts/gsap-to-anime/__fixtures__/repeat-yoyo.after.html create mode 100644 scripts/gsap-to-anime/__fixtures__/repeat-yoyo.before.html create mode 100644 scripts/gsap-to-anime/__fixtures__/simple-to.after.html create mode 100644 scripts/gsap-to-anime/__fixtures__/simple-to.before.html create mode 100644 scripts/gsap-to-anime/__fixtures__/splittext-manual.before.html create mode 100644 scripts/gsap-to-anime/__fixtures__/stagger-grid.after.html create mode 100644 scripts/gsap-to-anime/__fixtures__/stagger-grid.before.html create mode 100644 scripts/gsap-to-anime/classifier.ts create mode 100644 scripts/gsap-to-anime/cli.ts create mode 100644 scripts/gsap-to-anime/converter.ts create mode 100644 scripts/gsap-to-anime/dry-run-report.json create mode 100644 scripts/gsap-to-anime/dry-run-report.md create mode 100644 scripts/gsap-to-anime/gsap-to-anime.test.ts create mode 100644 scripts/gsap-to-anime/html.ts create mode 100644 scripts/gsap-to-anime/index.ts create mode 100644 scripts/gsap-to-anime/notes.ts create mode 100644 scripts/gsap-to-anime/registration.ts create mode 100644 scripts/gsap-to-anime/report.ts create mode 100644 scripts/gsap-to-anime/types.ts diff --git a/package.json b/package.json index 33b4b16ce2..d884ebec1e 100644 --- a/package.json +++ b/package.json @@ -32,7 +32,7 @@ "player:perf": "bun run --filter @hyperframes/player perf", "format:check": "oxfmt --check .", "knip": "knip", - "test:scripts": "node --import tsx --test scripts/validate-release-channel.test.mjs scripts/draft-changelog.test.ts scripts/set-version.test.ts scripts/release-prepare.test.ts scripts/cli-options.test.ts scripts/changelog-weekly.test.ts scripts/claude-plugin-compression.test.ts scripts/verify-packed-manifests.test.mjs", + "test:scripts": "node --import tsx --test scripts/validate-release-channel.test.mjs scripts/draft-changelog.test.ts scripts/set-version.test.ts scripts/release-prepare.test.ts scripts/cli-options.test.ts scripts/changelog-weekly.test.ts scripts/claude-plugin-compression.test.ts scripts/verify-packed-manifests.test.mjs scripts/gsap-to-anime/*.test.ts", "test:skills": "node --test 'skills/**/*.test.mjs'", "generate:previews": "tsx scripts/generate-template-previews.ts", "generate:catalog-previews": "tsx scripts/generate-catalog-previews.ts", diff --git a/scripts/gsap-to-anime/__fixtures__/eases.after.html b/scripts/gsap-to-anime/__fixtures__/eases.after.html new file mode 100644 index 0000000000..a65ee69ef9 --- /dev/null +++ b/scripts/gsap-to-anime/__fixtures__/eases.after.html @@ -0,0 +1,15 @@ + + + + + + diff --git a/scripts/gsap-to-anime/__fixtures__/eases.before.html b/scripts/gsap-to-anime/__fixtures__/eases.before.html new file mode 100644 index 0000000000..decf1230d0 --- /dev/null +++ b/scripts/gsap-to-anime/__fixtures__/eases.before.html @@ -0,0 +1,16 @@ + + + + + + diff --git a/scripts/gsap-to-anime/__fixtures__/fromto-set.after.html b/scripts/gsap-to-anime/__fixtures__/fromto-set.after.html new file mode 100644 index 0000000000..881be90b9d --- /dev/null +++ b/scripts/gsap-to-anime/__fixtures__/fromto-set.after.html @@ -0,0 +1,16 @@ + + + +
+ + + diff --git a/scripts/gsap-to-anime/__fixtures__/fromto-set.before.html b/scripts/gsap-to-anime/__fixtures__/fromto-set.before.html new file mode 100644 index 0000000000..5dca45105e --- /dev/null +++ b/scripts/gsap-to-anime/__fixtures__/fromto-set.before.html @@ -0,0 +1,18 @@ + + + +
+ + + diff --git a/scripts/gsap-to-anime/__fixtures__/motionpath-manual.before.html b/scripts/gsap-to-anime/__fixtures__/motionpath-manual.before.html new file mode 100644 index 0000000000..b381feef7b --- /dev/null +++ b/scripts/gsap-to-anime/__fixtures__/motionpath-manual.before.html @@ -0,0 +1,23 @@ + + + + + + diff --git a/scripts/gsap-to-anime/__fixtures__/positions.after.html b/scripts/gsap-to-anime/__fixtures__/positions.after.html new file mode 100644 index 0000000000..cc6eeeb31e --- /dev/null +++ b/scripts/gsap-to-anime/__fixtures__/positions.after.html @@ -0,0 +1,12 @@ + + + + + + diff --git a/scripts/gsap-to-anime/__fixtures__/positions.before.html b/scripts/gsap-to-anime/__fixtures__/positions.before.html new file mode 100644 index 0000000000..0929c23caa --- /dev/null +++ b/scripts/gsap-to-anime/__fixtures__/positions.before.html @@ -0,0 +1,14 @@ + + + + + + diff --git a/scripts/gsap-to-anime/__fixtures__/repeat-yoyo.after.html b/scripts/gsap-to-anime/__fixtures__/repeat-yoyo.after.html new file mode 100644 index 0000000000..974ca39d20 --- /dev/null +++ b/scripts/gsap-to-anime/__fixtures__/repeat-yoyo.after.html @@ -0,0 +1,10 @@ + + + + + + diff --git a/scripts/gsap-to-anime/__fixtures__/repeat-yoyo.before.html b/scripts/gsap-to-anime/__fixtures__/repeat-yoyo.before.html new file mode 100644 index 0000000000..03ab726b41 --- /dev/null +++ b/scripts/gsap-to-anime/__fixtures__/repeat-yoyo.before.html @@ -0,0 +1,11 @@ + + + + + + diff --git a/scripts/gsap-to-anime/__fixtures__/simple-to.after.html b/scripts/gsap-to-anime/__fixtures__/simple-to.after.html new file mode 100644 index 0000000000..52f575cfa4 --- /dev/null +++ b/scripts/gsap-to-anime/__fixtures__/simple-to.after.html @@ -0,0 +1,11 @@ + + + +
+ + + diff --git a/scripts/gsap-to-anime/__fixtures__/simple-to.before.html b/scripts/gsap-to-anime/__fixtures__/simple-to.before.html new file mode 100644 index 0000000000..c6ff93fd55 --- /dev/null +++ b/scripts/gsap-to-anime/__fixtures__/simple-to.before.html @@ -0,0 +1,12 @@ + + + +
+ + + diff --git a/scripts/gsap-to-anime/__fixtures__/splittext-manual.before.html b/scripts/gsap-to-anime/__fixtures__/splittext-manual.before.html new file mode 100644 index 0000000000..af31740953 --- /dev/null +++ b/scripts/gsap-to-anime/__fixtures__/splittext-manual.before.html @@ -0,0 +1,13 @@ + + + + + + diff --git a/scripts/gsap-to-anime/__fixtures__/stagger-grid.after.html b/scripts/gsap-to-anime/__fixtures__/stagger-grid.after.html new file mode 100644 index 0000000000..4a2253f799 --- /dev/null +++ b/scripts/gsap-to-anime/__fixtures__/stagger-grid.after.html @@ -0,0 +1,20 @@ + + + + + + diff --git a/scripts/gsap-to-anime/__fixtures__/stagger-grid.before.html b/scripts/gsap-to-anime/__fixtures__/stagger-grid.before.html new file mode 100644 index 0000000000..61cfd174bd --- /dev/null +++ b/scripts/gsap-to-anime/__fixtures__/stagger-grid.before.html @@ -0,0 +1,21 @@ + + + + + + diff --git a/scripts/gsap-to-anime/classifier.ts b/scripts/gsap-to-anime/classifier.ts new file mode 100644 index 0000000000..e900baddd7 --- /dev/null +++ b/scripts/gsap-to-anime/classifier.ts @@ -0,0 +1,258 @@ +import { resolveEase } from "@hyperframes/core"; +import type { GsapAnimation, ParsedGsap } from "@hyperframes/parsers"; +import { SUPPORTED_PROPS } from "@hyperframes/parsers/gsap-constants"; +import { addUniqueNote, note, statusFor } from "./notes.ts"; +import { parseRegistrationPostamble } from "./registration.ts"; +import type { ClassificationNote, CodemodClassification } from "./types.ts"; + +const SUPPORTED_PROP_SET = new Set(SUPPORTED_PROPS); +const ALLOWED_EXTRAS = new Set(["stagger", "repeat", "yoyo"]); +const PLUGIN_NAMES = [ + "ScrollTrigger", + "Draggable", + "Flip", + "TextPlugin", + "DrawSVGPlugin", + "MorphSVGPlugin", + "Physics2DPlugin", + "CustomWiggle", +]; + +export function classifyGsapScript(script: string, parsed: ParsedGsap): CodemodClassification { + const reasons: ClassificationNote[] = []; + const warnings: ClassificationNote[] = []; + + addRawSourceReasons(script, reasons); + addParsedReasons(parsed, reasons); + addAnimationReasons(parsed.animations, reasons, warnings); + if (parseRegistrationPostamble(parsed.postamble, parsed.timelineVar) === null) { + addUniqueNote( + reasons, + note("unrecognized-postamble", "postamble is not only timeline registration"), + ); + } + + return { + status: statusFor(reasons, warnings), + reasons, + warnings, + parsed, + }; +} + +function addRawSourceReasons(script: string, reasons: ClassificationNote[]): void { + if (/SplitText/i.test(script) || hasHandRolledTextSplit(script)) { + addUniqueNote( + reasons, + note("splitText", "SplitText or hand-rolled text splitting feeds the timeline"), + ); + } + if (/CustomEase\.create\s*\(/.test(script)) { + addUniqueNote( + reasons, + note("customEase-beyond-shim", "CustomEase registrations are outside the inline path shim"), + ); + } + if (/MotionPathPlugin|motionPath\s*:/.test(script)) { + addUniqueNote(reasons, note("motionPath", "motionPath requires manual conversion")); + } + if (hasAdvancedGsapUtils(script)) { + addUniqueNote(reasons, note("gsap-utils-advanced", "gsap.utils usage beyond toArray")); + } + if (/(\.call|\.add|\.addPause)\s*\(/.test(script)) { + addUniqueNote( + reasons, + note("computed-timeline", "timeline call/add/addPause is not rewritten safely"), + ); + } + if (/\b(onComplete|onStart|onUpdate|onRepeat|onReverseComplete)\s*:/.test(script)) { + addUniqueNote( + reasons, + note("computed-timeline", "timeline callback properties need manual review"), + ); + } + if (/\bdelay\s*:/.test(script)) { + addUniqueNote( + reasons, + note("computed-timeline", "GSAP delay is not represented in parsed placement data"), + ); + } + addPluginReasons(script, reasons); +} + +function hasHandRolledTextSplit(script: string): boolean { + return ( + /\.split\s*\(\s*["'](?:\s?|)["']\s*\)/.test(script) && + /chars|words|createElement|innerHTML/.test(script) + ); +} + +function hasAdvancedGsapUtils(script: string): boolean { + for (const match of script.matchAll(/gsap\.utils\.([A-Za-z_$][\w$]*)/g)) { + if (match[1] !== "toArray") return true; + } + return false; +} + +function addPluginReasons(script: string, reasons: ClassificationNote[]): void { + if (/gsap\.registerPlugin\s*\([^)]*CustomEase/.test(script)) { + addUniqueNote( + reasons, + note("customEase-beyond-shim", "registered CustomEase name needs manual review"), + ); + } + if (/gsap\.registerPlugin\s*\([^)]*MotionPathPlugin/.test(script)) { + addUniqueNote(reasons, note("motionPath", "registered MotionPathPlugin needs manual review")); + } + for (const plugin of PLUGIN_NAMES) { + if (new RegExp(`\\b${plugin}\\b`).test(script)) { + addUniqueNote( + reasons, + note(`plugin:${plugin}`, `${plugin} plugin usage needs manual review`), + ); + } + } +} + +function addParsedReasons(parsed: ParsedGsap, reasons: ClassificationNote[]): void { + if (!/^[A-Za-z_$][\w$]*$/.test(parsed.timelineVar)) { + addUniqueNote(reasons, note("computed-timeline", "timeline is not a simple identifier")); + } + if (parsed.multipleTimelines || parsed.unsupportedTimelinePattern) { + addUniqueNote(reasons, note("computed-timeline", "multiple or unsupported timelines")); + } +} + +function addAnimationReasons( + animations: GsapAnimation[], + reasons: ClassificationNote[], + warnings: ClassificationNote[], +): void { + for (const animation of animations) { + if (animation.arcPath) + addUniqueNote(reasons, note("motionPath", "motionPath requires manual conversion")); + if ( + (animation.hasUnresolvedKeyframes || animation.hasUnresolvedSelector) && + !hasReason(reasons, "splitText") + ) { + addUniqueNote(reasons, note("computed-timeline", "unresolved selector or keyframes")); + } + if (animation.keyframes && !animation.extras?.stagger && !animation.arcPath) { + addUniqueNote(reasons, note("keyframes", "native GSAP keyframes need manual review")); + } + if (animation.resolvedStart === undefined) { + addUniqueNote(reasons, note("computed-timeline", "animation start could not be resolved")); + } + if (animation.provenance && animation.provenance.kind !== "literal") { + addUniqueNote(reasons, note("computed-timeline", "computed timeline construction")); + } + addPropertyReasons(animation, reasons, warnings); + addExtraReasons(animation, reasons, warnings); + addEaseReasons(animation, reasons, warnings); + } +} + +function hasReason(reasons: ClassificationNote[], code: string): boolean { + return reasons.some((reason) => reason.code === code); +} + +function addPropertyReasons( + animation: GsapAnimation, + reasons: ClassificationNote[], + warnings: ClassificationNote[], +): void { + for (const key of propertyKeys(animation)) { + if (!SUPPORTED_PROP_SET.has(key)) { + addUniqueNote(reasons, note("unsupported-property", `Unsupported GSAP property: ${key}`)); + } + if (key === "autoAlpha") { + addUniqueNote( + warnings, + note("autoAlpha-expansion", "autoAlpha expands to opacity and visibility"), + ); + } + if (key === "transformPerspective") { + addUniqueNote( + warnings, + note("transformPerspective-perspective", "transformPerspective maps to CSS perspective"), + ); + } + } +} + +function propertyKeys(animation: GsapAnimation): string[] { + const keys = new Set(Object.keys(animation.properties)); + for (const key of Object.keys(animation.fromProperties ?? {})) keys.add(key); + return [...keys]; +} + +function addExtraReasons( + animation: GsapAnimation, + reasons: ClassificationNote[], + warnings: ClassificationNote[], +): void { + for (const key of Object.keys(animation.extras ?? {})) { + if (!ALLOWED_EXTRAS.has(key)) { + addUniqueNote(reasons, note("unsupported-extra", `Unsupported GSAP extra: ${key}`)); + } + } + const repeat = animation.extras?.repeat; + if (isInfiniteRepeat(repeat)) { + addUniqueNote( + warnings, + note("infinite-repeat", "repeat:-1 or repeat:Infinity creates an infinite loop"), + ); + } +} + +function isInfiniteRepeat(value: unknown): boolean { + const raw = rawText(value); + return raw === "-1" || raw === "Infinity"; +} + +function addEaseReasons( + animation: GsapAnimation, + reasons: ClassificationNote[], + warnings: ClassificationNote[], +): void { + const eases = animationEases(animation); + for (const ease of eases) { + if (isEaseShimDivergence(ease)) { + addUniqueNote(warnings, note("ease-shim-divergence", "ease shim divergence")); + } + const resolved = resolveEase(ease); + if (resolved.warning) { + addUniqueNote( + reasons, + note( + "customEase-beyond-shim", + `Unrecognized or fallback ease needs manual review: ${ease}`, + ), + ); + } + } +} + +function animationEases(animation: GsapAnimation): string[] { + const eases: string[] = []; + if (animation.ease) eases.push(animation.ease); + const keyframes = animation.keyframes; + if (keyframes?.ease) eases.push(keyframes.ease); + if (keyframes?.easeEach) eases.push(keyframes.easeEach); + for (const keyframe of keyframes?.keyframes ?? []) { + if (keyframe.ease) eases.push(keyframe.ease); + } + return eases; +} + +function isEaseShimDivergence(ease: string): boolean { + const compact = ease.trim().replace(/\s+/g, "").toLowerCase(); + return compact.startsWith("expo.") || /^steps\(\d+\)$/.test(compact); +} + +function rawText(value: unknown): string | null { + if (typeof value === "string") + return value.startsWith("__raw:") ? value.slice(6).trim() : value.trim(); + if (typeof value === "number" || typeof value === "boolean") return String(value); + return null; +} diff --git a/scripts/gsap-to-anime/cli.ts b/scripts/gsap-to-anime/cli.ts new file mode 100644 index 0000000000..931ff2b09a --- /dev/null +++ b/scripts/gsap-to-anime/cli.ts @@ -0,0 +1,82 @@ +#!/usr/bin/env tsx + +import { existsSync, readFileSync, statSync, writeFileSync } from "node:fs"; +import { resolve } from "node:path"; +import { + assertTotalsReconcile, + renderMarkdownReport, + scanRegistryTree, + transformHtml, +} from "./index.ts"; + +interface Options { + target: string; + dryRun: boolean; + write: boolean; + reportJson: string; + reportMd: string; +} + +function main(): void { + const options = parseArgs(process.argv.slice(2)); + const target = resolve(options.target); + if (!existsSync(target)) fail(`Path not found: ${target}`); + if (statSync(target).isDirectory()) { + runDirectory(target, options); + return; + } + runFile(target, options); +} + +function parseArgs(args: string[]): Options { + let target = ""; + let dryRun = false; + let write = false; + let reportJson = "scripts/gsap-to-anime/dry-run-report.json"; + let reportMd = "scripts/gsap-to-anime/dry-run-report.md"; + for (let index = 0; index < args.length; index += 1) { + const arg = args[index]; + if (arg === "--dry-run") dryRun = true; + else if (arg === "--write") write = true; + else if (arg === "--report-json") reportJson = readValue(args, (index += 1), arg); + else if (arg === "--report-md") reportMd = readValue(args, (index += 1), arg); + else if (arg && !arg.startsWith("--") && target === "") target = arg; + else fail(`Unknown argument: ${arg ?? ""}`); + } + if (!target) + fail( + "Usage: node --import tsx scripts/gsap-to-anime/cli.ts [--dry-run] [--write]", + ); + return { target, dryRun, write, reportJson, reportMd }; +} + +function readValue(args: string[], index: number, flag: string): string { + const value = args[index]; + if (!value) fail(`${flag} requires a value`); + return value; +} + +function runFile(path: string, options: Options): void { + const html = readFileSync(path, "utf-8"); + const result = transformHtml(html); + console.log(JSON.stringify(result.classification, null, 2)); + if (options.write && !options.dryRun && result.changed) { + writeFileSync(path, result.html, "utf-8"); + } +} + +function runDirectory(path: string, options: Options): void { + if (!options.dryRun) fail("Directory mode is dry-run only for this codemod unit"); + const report = scanRegistryTree(path); + assertTotalsReconcile(report); + writeFileSync(resolve(options.reportJson), `${JSON.stringify(report, null, 2)}\n`, "utf-8"); + writeFileSync(resolve(options.reportMd), renderMarkdownReport(report), "utf-8"); + console.log(JSON.stringify(report.totals)); +} + +function fail(message: string): never { + console.error(message); + process.exit(1); +} + +main(); diff --git a/scripts/gsap-to-anime/converter.ts b/scripts/gsap-to-anime/converter.ts new file mode 100644 index 0000000000..431b78e4e8 --- /dev/null +++ b/scripts/gsap-to-anime/converter.ts @@ -0,0 +1,276 @@ +import { resolveEase } from "@hyperframes/core"; +import type { GsapAnimation, ParsedGsap } from "@hyperframes/parsers"; +import { extractGsapLabels } from "@hyperframes/parsers/gsap-parser-acorn"; +import { parseRegistrationPostamble, stripLegacyRegistrySetup } from "./registration.ts"; + +interface AnimeProperty { + key: string; + code: string; +} + +const PROP_RENAMES = new Map([ + ["x", "translateX"], + ["y", "translateY"], + ["z", "translateZ"], + ["rotation", "rotate"], + ["rotationX", "rotateX"], + ["rotationY", "rotateY"], + ["rotationZ", "rotateZ"], + // anime.js v4 animates CSS perspective directly; GSAP's transformPerspective + // is folded into that CSS property and separately classified with a warning. + ["transformPerspective", "perspective"], +]); + +export function convertGsapScript(script: string, parsed: ParsedGsap): string { + const registration = parseRegistrationPostamble(parsed.postamble, parsed.timelineVar); + const registrationId = registration?.id ?? "main"; + const lines = [ + convertPreamble(parsed.preamble, parsed.timelineVar), + ...parsed.animations.map((animation) => convertAnimation(animation, parsed.timelineVar)), + renderRegistration(registrationId, parsed.timelineVar, extractGsapLabels(script)), + ]; + return `\n${lines.filter((line) => line.length > 0).join("\n")}\n`; +} + +function convertPreamble(preamble: string, timelineVar: string): string { + const withoutRegistry = stripLegacyRegistrySetup(preamble).trim(); + const rewrittenUtils = rewriteGsapToArray(withoutRegistry); + const timelineDecl = new RegExp( + `\\b(const|let|var)\\s+${escapeRegExp(timelineVar)}\\s*=\\s*gsap\\.timeline\\s*\\([^;]*\\)\\s*;?`, + ); + const converted = rewrittenUtils.replace( + timelineDecl, + `const ${timelineVar} = anime.createTimeline({ autoplay: false });`, + ); + return converted + .split("\n") + .map((line) => line.trimStart()) + .join("\n"); +} + +function rewriteGsapToArray(source: string): string { + return source.replace( + /gsap\.utils\.toArray\s*\(\s*(["'][^"']+["'])\s*\)/g, + "[...document.querySelectorAll($1)]", + ); +} + +function convertAnimation(animation: GsapAnimation, timelineVar: string): string { + const target = JSON.stringify(animation.targetSelector); + const properties = buildProperties(animation); + const position = milliseconds(animation.resolvedStart ?? 0); + return renderAddCall(timelineVar, target, properties, position); +} + +function buildProperties(animation: GsapAnimation): AnimeProperty[] { + const entries: AnimeProperty[] = []; + for (const [key, value] of Object.entries(animation.properties)) { + pushConvertedProperty(entries, animation, key, value); + } + entries.push({ key: "duration", code: String(durationMs(animation)) }); + if (animation.ease) + entries.push({ key: "ease", code: JSON.stringify(resolveEase(animation.ease).animeEase) }); + const stagger = renderStagger(animation.extras?.stagger); + if (stagger) entries.push({ key: "delay", code: stagger }); + const repeat = renderRepeat(animation.extras?.repeat); + if (repeat) entries.push({ key: "loop", code: repeat }); + if (rawBoolean(animation.extras?.yoyo) === true) entries.push({ key: "alternate", code: "true" }); + return entries; +} + +function pushConvertedProperty( + entries: AnimeProperty[], + animation: GsapAnimation, + key: string, + value: number | string, +): void { + if (key === "autoAlpha") { + pushAutoAlpha(entries, animation, value); + return; + } + const animeKey = PROP_RENAMES.get(key) ?? key; + entries.push({ key: animeKey, code: renderTweenValue(animation, key, value) }); +} + +function pushAutoAlpha( + entries: AnimeProperty[], + animation: GsapAnimation, + value: number | string, +): void { + const from = animation.fromProperties?.autoAlpha; + if (typeof from === "number" || typeof from === "string") { + entries.push({ key: "opacity", code: serializeArray([from, value]) }); + entries.push({ + key: "visibility", + code: serializeArray([visibilityFor(from), visibilityFor(value)]), + }); + return; + } + entries.push({ key: "opacity", code: serializeValue(value) }); + entries.push({ key: "visibility", code: serializeValue(visibilityFor(value)) }); +} + +function renderTweenValue(animation: GsapAnimation, key: string, value: number | string): string { + if (animation.method === "fromTo") { + const fromValue = animation.fromProperties?.[key]; + return fromValue === undefined ? serializeValue(value) : serializeArray([fromValue, value]); + } + if (animation.method === "from") { + return serializeArray([value, identityValue(key)]); + } + if (animation.method === "to") { + const fromValue = animation.fromProperties?.[key]; + return fromValue === undefined ? serializeValue(value) : serializeArray([fromValue, value]); + } + return serializeValue(value); +} + +function identityValue(key: string): number | string { + if (key === "opacity" || key === "autoAlpha") return 1; + if (key === "visibility") return "visible"; + if (key.startsWith("scale")) return 1; + return 0; +} + +function visibilityFor(value: number | string): string { + if (typeof value === "number") return value <= 0 ? "hidden" : "visible"; + return value === "0" || value === "hidden" ? "hidden" : "visible"; +} + +function durationMs(animation: GsapAnimation): number { + if (animation.method === "set") return 0; + return milliseconds(animation.duration ?? 0.5); +} + +function milliseconds(seconds: number): number { + return Math.round(seconds * 1000); +} + +function renderStagger(value: unknown): string | null { + const raw = rawText(value); + if (!raw) return null; + if (/function|=>/.test(raw)) return null; + const numeric = Number(raw); + if (Number.isFinite(numeric)) return `anime.stagger(${milliseconds(numeric)})`; + if (!raw.trim().startsWith("{")) return null; + return renderObjectStagger(raw); +} + +function renderObjectStagger(raw: string): string | null { + const keys = [...raw.matchAll(/([A-Za-z_$][\w$]*)\s*:/g)].map((match) => match[1] ?? ""); + if ( + keys.some((key) => !["each", "amount", "from", "grid", "axis", "start", "ease"].includes(key)) + ) { + return null; + } + const seconds = numericField(raw, "each") ?? numericField(raw, "amount"); + if (seconds === null) return null; + const options: string[] = []; + const grid = /\bgrid\s*:\s*(\[[^\]]+\])/.exec(raw)?.[1]; + const from = /\bfrom\s*:\s*("[^"]+"|'[^']+'|[A-Za-z_$][\w$]*)/.exec(raw)?.[1]; + const axis = /\baxis\s*:\s*("[^"]+"|'[^']+'|[A-Za-z_$][\w$]*)/.exec(raw)?.[1]; + const start = numericField(raw, "start"); + const ease = /\bease\s*:\s*("[^"]+"|'[^']+')/.exec(raw)?.[1]; + if (grid) options.push(`grid: ${grid}`); + if (from) options.push(`from: ${normalizeStringLiteral(from)}`); + if (axis) options.push(`axis: ${normalizeStringLiteral(axis)}`); + if (start !== null) options.push(`start: ${milliseconds(start)}`); + if (ease) options.push(`ease: ${normalizeStringLiteral(ease)}`); + return options.length > 0 + ? `anime.stagger(${milliseconds(seconds)}, { ${options.join(", ")} })` + : `anime.stagger(${milliseconds(seconds)})`; +} + +function numericField(raw: string, key: string): number | null { + const match = new RegExp(`\\b${key}\\s*:\\s*(-?\\d+(?:\\.\\d+)?)`).exec(raw); + if (!match?.[1]) return null; + const value = Number(match[1]); + return Number.isFinite(value) ? value : null; +} + +function renderRepeat(value: unknown): string | null { + const raw = rawText(value); + if (!raw) return null; + if (raw === "-1" || raw === "Infinity") return "true"; + const repeat = Number(raw); + if (!Number.isFinite(repeat)) return null; + return String(Math.max(0, Math.floor(repeat)) + 1); +} + +function rawBoolean(value: unknown): boolean | null { + const raw = rawText(value); + if (raw === "true") return true; + if (raw === "false") return false; + return null; +} + +function rawText(value: unknown): string | null { + if (typeof value === "string") + return value.startsWith("__raw:") ? value.slice(6).trim() : value.trim(); + if (typeof value === "number" || typeof value === "boolean") return String(value); + return null; +} + +function normalizeStringLiteral(value: string): string { + if (value.startsWith("'") && value.endsWith("'")) return JSON.stringify(value.slice(1, -1)); + return value; +} + +function renderRegistration( + id: string, + timelineVar: string, + labels: Array<{ name: string; position: number }>, +): string { + if (labels.length === 0) + return `hyperframesAnime.register(${JSON.stringify(id)}, ${timelineVar});`; + const labelEntries = labels.map( + (label) => `${safeKey(label.name)}: ${formatNumber(label.position)}`, + ); + return `hyperframesAnime.register(${JSON.stringify(id)}, ${timelineVar}, { labels: { ${labelEntries.join(", ")} } });`; +} + +function serializeProperties(properties: AnimeProperty[]): string { + return `{ ${properties.map((property) => `${safeKey(property.key)}: ${property.code}`).join(", ")} }`; +} + +function renderAddCall( + timelineVar: string, + target: string, + properties: AnimeProperty[], + position: number, +): string { + const props = serializeProperties(properties); + const oneLine = `${timelineVar}.add(${target}, ${props}, ${position});`; + if (properties.some((property) => property.code.startsWith("[")) && oneLine.length > 95) { + return `${timelineVar}.add(\n ${target},\n ${props},\n ${position},\n);`; + } + if (oneLine.length <= 110) return oneLine; + if (properties.some((property) => property.code.includes("anime.stagger"))) { + const propLines = properties.map( + (property) => ` ${safeKey(property.key)}: ${property.code},`, + ); + return `${timelineVar}.add(\n ${target},\n {\n${propLines.join("\n")}\n },\n ${position},\n);`; + } + return `${timelineVar}.add(\n ${target},\n ${props},\n ${position},\n);`; +} + +function serializeArray(values: Array): string { + return `[${values.map(serializeValue).join(", ")}]`; +} + +function serializeValue(value: number | string): string { + return typeof value === "number" ? formatNumber(value) : JSON.stringify(value); +} + +function safeKey(key: string): string { + return /^[A-Za-z_$][\w$]*$/.test(key) ? key : JSON.stringify(key); +} + +function formatNumber(value: number): string { + const rounded = Math.round(value * 100000) / 100000; + return String(rounded); +} + +function escapeRegExp(value: string): string { + return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); +} diff --git a/scripts/gsap-to-anime/dry-run-report.json b/scripts/gsap-to-anime/dry-run-report.json new file mode 100644 index 0000000000..2a2d716004 --- /dev/null +++ b/scripts/gsap-to-anime/dry-run-report.json @@ -0,0 +1,5791 @@ +{ + "root": "/Users/miguel07code/dev/hyperframes-oss/.claude/worktrees/animejs-u9/registry", + "totals": { + "converted": 24, + "converted-with-warnings": 0, + "manual": 123 + }, + "items": [ + { + "kind": "block", + "name": "app-showcase", + "path": "blocks/app-showcase", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "unresolved selector or keyframes" + }, + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: strokeDashoffset" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [ + { + "code": "ease-shim-divergence", + "message": "ease shim divergence" + } + ], + "files": [ + { + "path": "blocks/app-showcase/app-showcase.html", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "unresolved selector or keyframes" + }, + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: strokeDashoffset" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [ + { + "code": "ease-shim-divergence", + "message": "ease shim divergence" + } + ] + } + ] + }, + { + "kind": "block", + "name": "apple-money-count", + "path": "blocks/apple-money-count", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "timeline callback properties need manual review" + }, + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: value" + } + ], + "warnings": [], + "files": [ + { + "path": "blocks/apple-money-count/apple-money-count.html", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "timeline callback properties need manual review" + }, + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: value" + } + ], + "warnings": [] + } + ] + }, + { + "kind": "block", + "name": "blue-sweater-intro-video", + "path": "blocks/blue-sweater-intro-video", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "unsupported-extra", + "message": "Unsupported GSAP extra: overwrite" + }, + { + "code": "computed-timeline", + "message": "unresolved selector or keyframes" + }, + { + "code": "keyframes", + "message": "native GSAP keyframes need manual review" + } + ], + "warnings": [ + { + "code": "ease-shim-divergence", + "message": "ease shim divergence" + } + ], + "files": [ + { + "path": "blocks/blue-sweater-intro-video/blue-sweater-intro-video.html", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "unsupported-extra", + "message": "Unsupported GSAP extra: overwrite" + }, + { + "code": "computed-timeline", + "message": "unresolved selector or keyframes" + }, + { + "code": "keyframes", + "message": "native GSAP keyframes need manual review" + } + ], + "warnings": [ + { + "code": "ease-shim-divergence", + "message": "ease shim divergence" + } + ] + } + ] + }, + { + "kind": "block", + "name": "chromatic-radial-split", + "path": "blocks/chromatic-radial-split", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "timeline callback properties need manual review" + } + ], + "warnings": [], + "files": [ + { + "path": "blocks/chromatic-radial-split/chromatic-radial-split.html", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "timeline callback properties need manual review" + } + ], + "warnings": [] + } + ] + }, + { + "kind": "block", + "name": "cinematic-zoom", + "path": "blocks/cinematic-zoom", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "timeline callback properties need manual review" + } + ], + "warnings": [], + "files": [ + { + "path": "blocks/cinematic-zoom/cinematic-zoom.html", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "timeline callback properties need manual review" + } + ], + "warnings": [] + } + ] + }, + { + "kind": "block", + "name": "code-3d-extrude", + "path": "blocks/code-3d-extrude", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "timeline call/add/addPause is not rewritten safely" + }, + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: rotY" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [], + "files": [ + { + "path": "blocks/code-3d-extrude/code-3d-extrude.html", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "timeline call/add/addPause is not rewritten safely" + }, + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: rotY" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [] + } + ] + }, + { + "kind": "block", + "name": "code-diff", + "path": "blocks/code-diff", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "unresolved selector or keyframes" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [], + "files": [ + { + "path": "blocks/code-diff/code-diff.html", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "unresolved selector or keyframes" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [] + } + ] + }, + { + "kind": "block", + "name": "code-highlight", + "path": "blocks/code-highlight", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "unresolved selector or keyframes" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [], + "files": [ + { + "path": "blocks/code-highlight/code-highlight.html", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "unresolved selector or keyframes" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [] + } + ] + }, + { + "kind": "block", + "name": "code-morph", + "path": "blocks/code-morph", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "timeline call/add/addPause is not rewritten safely" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [], + "files": [ + { + "path": "blocks/code-morph/code-morph.html", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "timeline call/add/addPause is not rewritten safely" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [] + } + ] + }, + { + "kind": "block", + "name": "code-particle-assemble", + "path": "blocks/code-particle-assemble", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "timeline call/add/addPause is not rewritten safely" + }, + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: value" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [], + "files": [ + { + "path": "blocks/code-particle-assemble/code-particle-assemble.html", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "timeline call/add/addPause is not rewritten safely" + }, + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: value" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [] + } + ] + }, + { + "kind": "block", + "name": "code-scroll", + "path": "blocks/code-scroll", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "unresolved selector or keyframes" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [], + "files": [ + { + "path": "blocks/code-scroll/code-scroll.html", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "unresolved selector or keyframes" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [] + } + ] + }, + { + "kind": "block", + "name": "code-shader-dissolve", + "path": "blocks/code-shader-dissolve", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "timeline call/add/addPause is not rewritten safely" + }, + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: value" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [], + "files": [ + { + "path": "blocks/code-shader-dissolve/code-shader-dissolve.html", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "timeline call/add/addPause is not rewritten safely" + }, + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: value" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [] + } + ] + }, + { + "kind": "block", + "name": "code-snippet-apple-terminal-basic", + "path": "blocks/code-snippet-apple-terminal-basic", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "splitText", + "message": "SplitText or hand-rolled text splitting feeds the timeline" + }, + { + "code": "computed-timeline", + "message": "timeline call/add/addPause is not rewritten safely" + }, + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: text" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [], + "files": [ + { + "path": "blocks/code-snippet-apple-terminal-basic/code-snippet-apple-terminal-basic.html", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "splitText", + "message": "SplitText or hand-rolled text splitting feeds the timeline" + }, + { + "code": "computed-timeline", + "message": "timeline call/add/addPause is not rewritten safely" + }, + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: text" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [] + } + ] + }, + { + "kind": "block", + "name": "code-snippet-apple-terminal-clear-dark", + "path": "blocks/code-snippet-apple-terminal-clear-dark", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "splitText", + "message": "SplitText or hand-rolled text splitting feeds the timeline" + }, + { + "code": "computed-timeline", + "message": "timeline call/add/addPause is not rewritten safely" + }, + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: text" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [], + "files": [ + { + "path": "blocks/code-snippet-apple-terminal-clear-dark/code-snippet-apple-terminal-clear-dark.html", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "splitText", + "message": "SplitText or hand-rolled text splitting feeds the timeline" + }, + { + "code": "computed-timeline", + "message": "timeline call/add/addPause is not rewritten safely" + }, + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: text" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [] + } + ] + }, + { + "kind": "block", + "name": "code-snippet-apple-terminal-clear-light", + "path": "blocks/code-snippet-apple-terminal-clear-light", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "splitText", + "message": "SplitText or hand-rolled text splitting feeds the timeline" + }, + { + "code": "computed-timeline", + "message": "timeline call/add/addPause is not rewritten safely" + }, + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: text" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [], + "files": [ + { + "path": "blocks/code-snippet-apple-terminal-clear-light/code-snippet-apple-terminal-clear-light.html", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "splitText", + "message": "SplitText or hand-rolled text splitting feeds the timeline" + }, + { + "code": "computed-timeline", + "message": "timeline call/add/addPause is not rewritten safely" + }, + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: text" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [] + } + ] + }, + { + "kind": "block", + "name": "code-snippet-apple-terminal-grass", + "path": "blocks/code-snippet-apple-terminal-grass", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "splitText", + "message": "SplitText or hand-rolled text splitting feeds the timeline" + }, + { + "code": "computed-timeline", + "message": "timeline call/add/addPause is not rewritten safely" + }, + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: text" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [], + "files": [ + { + "path": "blocks/code-snippet-apple-terminal-grass/code-snippet-apple-terminal-grass.html", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "splitText", + "message": "SplitText or hand-rolled text splitting feeds the timeline" + }, + { + "code": "computed-timeline", + "message": "timeline call/add/addPause is not rewritten safely" + }, + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: text" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [] + } + ] + }, + { + "kind": "block", + "name": "code-snippet-apple-terminal-homebrew", + "path": "blocks/code-snippet-apple-terminal-homebrew", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "splitText", + "message": "SplitText or hand-rolled text splitting feeds the timeline" + }, + { + "code": "computed-timeline", + "message": "timeline call/add/addPause is not rewritten safely" + }, + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: text" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [], + "files": [ + { + "path": "blocks/code-snippet-apple-terminal-homebrew/code-snippet-apple-terminal-homebrew.html", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "splitText", + "message": "SplitText or hand-rolled text splitting feeds the timeline" + }, + { + "code": "computed-timeline", + "message": "timeline call/add/addPause is not rewritten safely" + }, + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: text" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [] + } + ] + }, + { + "kind": "block", + "name": "code-snippet-apple-terminal-man-page", + "path": "blocks/code-snippet-apple-terminal-man-page", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "splitText", + "message": "SplitText or hand-rolled text splitting feeds the timeline" + }, + { + "code": "computed-timeline", + "message": "timeline call/add/addPause is not rewritten safely" + }, + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: text" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [], + "files": [ + { + "path": "blocks/code-snippet-apple-terminal-man-page/code-snippet-apple-terminal-man-page.html", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "splitText", + "message": "SplitText or hand-rolled text splitting feeds the timeline" + }, + { + "code": "computed-timeline", + "message": "timeline call/add/addPause is not rewritten safely" + }, + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: text" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [] + } + ] + }, + { + "kind": "block", + "name": "code-snippet-apple-terminal-novel", + "path": "blocks/code-snippet-apple-terminal-novel", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "splitText", + "message": "SplitText or hand-rolled text splitting feeds the timeline" + }, + { + "code": "computed-timeline", + "message": "timeline call/add/addPause is not rewritten safely" + }, + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: text" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [], + "files": [ + { + "path": "blocks/code-snippet-apple-terminal-novel/code-snippet-apple-terminal-novel.html", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "splitText", + "message": "SplitText or hand-rolled text splitting feeds the timeline" + }, + { + "code": "computed-timeline", + "message": "timeline call/add/addPause is not rewritten safely" + }, + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: text" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [] + } + ] + }, + { + "kind": "block", + "name": "code-snippet-apple-terminal-ocean", + "path": "blocks/code-snippet-apple-terminal-ocean", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "splitText", + "message": "SplitText or hand-rolled text splitting feeds the timeline" + }, + { + "code": "computed-timeline", + "message": "timeline call/add/addPause is not rewritten safely" + }, + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: text" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [], + "files": [ + { + "path": "blocks/code-snippet-apple-terminal-ocean/code-snippet-apple-terminal-ocean.html", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "splitText", + "message": "SplitText or hand-rolled text splitting feeds the timeline" + }, + { + "code": "computed-timeline", + "message": "timeline call/add/addPause is not rewritten safely" + }, + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: text" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [] + } + ] + }, + { + "kind": "block", + "name": "code-snippet-apple-terminal-pro", + "path": "blocks/code-snippet-apple-terminal-pro", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "splitText", + "message": "SplitText or hand-rolled text splitting feeds the timeline" + }, + { + "code": "computed-timeline", + "message": "timeline call/add/addPause is not rewritten safely" + }, + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: text" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [], + "files": [ + { + "path": "blocks/code-snippet-apple-terminal-pro/code-snippet-apple-terminal-pro.html", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "splitText", + "message": "SplitText or hand-rolled text splitting feeds the timeline" + }, + { + "code": "computed-timeline", + "message": "timeline call/add/addPause is not rewritten safely" + }, + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: text" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [] + } + ] + }, + { + "kind": "block", + "name": "code-snippet-apple-terminal-red-sands", + "path": "blocks/code-snippet-apple-terminal-red-sands", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "splitText", + "message": "SplitText or hand-rolled text splitting feeds the timeline" + }, + { + "code": "computed-timeline", + "message": "timeline call/add/addPause is not rewritten safely" + }, + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: text" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [], + "files": [ + { + "path": "blocks/code-snippet-apple-terminal-red-sands/code-snippet-apple-terminal-red-sands.html", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "splitText", + "message": "SplitText or hand-rolled text splitting feeds the timeline" + }, + { + "code": "computed-timeline", + "message": "timeline call/add/addPause is not rewritten safely" + }, + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: text" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [] + } + ] + }, + { + "kind": "block", + "name": "code-snippet-apple-terminal-silver-aerogel", + "path": "blocks/code-snippet-apple-terminal-silver-aerogel", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "splitText", + "message": "SplitText or hand-rolled text splitting feeds the timeline" + }, + { + "code": "computed-timeline", + "message": "timeline call/add/addPause is not rewritten safely" + }, + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: text" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [], + "files": [ + { + "path": "blocks/code-snippet-apple-terminal-silver-aerogel/code-snippet-apple-terminal-silver-aerogel.html", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "splitText", + "message": "SplitText or hand-rolled text splitting feeds the timeline" + }, + { + "code": "computed-timeline", + "message": "timeline call/add/addPause is not rewritten safely" + }, + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: text" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [] + } + ] + }, + { + "kind": "block", + "name": "code-snippet-apple-terminal-solid-colors", + "path": "blocks/code-snippet-apple-terminal-solid-colors", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "splitText", + "message": "SplitText or hand-rolled text splitting feeds the timeline" + }, + { + "code": "computed-timeline", + "message": "timeline call/add/addPause is not rewritten safely" + }, + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: text" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [], + "files": [ + { + "path": "blocks/code-snippet-apple-terminal-solid-colors/code-snippet-apple-terminal-solid-colors.html", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "splitText", + "message": "SplitText or hand-rolled text splitting feeds the timeline" + }, + { + "code": "computed-timeline", + "message": "timeline call/add/addPause is not rewritten safely" + }, + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: text" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [] + } + ] + }, + { + "kind": "block", + "name": "code-snippet-dark-2026", + "path": "blocks/code-snippet-dark-2026", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "timeline call/add/addPause is not rewritten safely" + }, + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: rotateY" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [ + { + "code": "ease-shim-divergence", + "message": "ease shim divergence" + } + ], + "files": [ + { + "path": "blocks/code-snippet-dark-2026/code-snippet-dark-2026.html", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "timeline call/add/addPause is not rewritten safely" + }, + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: rotateY" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [ + { + "code": "ease-shim-divergence", + "message": "ease shim divergence" + } + ] + } + ] + }, + { + "kind": "block", + "name": "code-snippet-dark-modern", + "path": "blocks/code-snippet-dark-modern", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "timeline call/add/addPause is not rewritten safely" + }, + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: rotateY" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [ + { + "code": "ease-shim-divergence", + "message": "ease shim divergence" + } + ], + "files": [ + { + "path": "blocks/code-snippet-dark-modern/code-snippet-dark-modern.html", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "timeline call/add/addPause is not rewritten safely" + }, + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: rotateY" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [ + { + "code": "ease-shim-divergence", + "message": "ease shim divergence" + } + ] + } + ] + }, + { + "kind": "block", + "name": "code-snippet-dark-plus", + "path": "blocks/code-snippet-dark-plus", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "timeline call/add/addPause is not rewritten safely" + }, + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: rotateY" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [ + { + "code": "ease-shim-divergence", + "message": "ease shim divergence" + } + ], + "files": [ + { + "path": "blocks/code-snippet-dark-plus/code-snippet-dark-plus.html", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "timeline call/add/addPause is not rewritten safely" + }, + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: rotateY" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [ + { + "code": "ease-shim-divergence", + "message": "ease shim divergence" + } + ] + } + ] + }, + { + "kind": "block", + "name": "code-snippet-flight", + "path": "blocks/code-snippet-flight", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "unresolved selector or keyframes" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [], + "files": [ + { + "path": "blocks/code-snippet-flight/code-snippet-flight.html", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "unresolved selector or keyframes" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [] + } + ] + }, + { + "kind": "block", + "name": "code-snippet-high-contrast", + "path": "blocks/code-snippet-high-contrast", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "timeline call/add/addPause is not rewritten safely" + }, + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: rotateY" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [ + { + "code": "ease-shim-divergence", + "message": "ease shim divergence" + } + ], + "files": [ + { + "path": "blocks/code-snippet-high-contrast/code-snippet-high-contrast.html", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "timeline call/add/addPause is not rewritten safely" + }, + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: rotateY" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [ + { + "code": "ease-shim-divergence", + "message": "ease shim divergence" + } + ] + } + ] + }, + { + "kind": "block", + "name": "code-snippet-high-contrast-light", + "path": "blocks/code-snippet-high-contrast-light", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "timeline call/add/addPause is not rewritten safely" + }, + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: rotateY" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [ + { + "code": "ease-shim-divergence", + "message": "ease shim divergence" + } + ], + "files": [ + { + "path": "blocks/code-snippet-high-contrast-light/code-snippet-high-contrast-light.html", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "timeline call/add/addPause is not rewritten safely" + }, + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: rotateY" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [ + { + "code": "ease-shim-divergence", + "message": "ease shim divergence" + } + ] + } + ] + }, + { + "kind": "block", + "name": "code-snippet-light-2026", + "path": "blocks/code-snippet-light-2026", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "timeline call/add/addPause is not rewritten safely" + }, + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: rotateY" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [ + { + "code": "ease-shim-divergence", + "message": "ease shim divergence" + } + ], + "files": [ + { + "path": "blocks/code-snippet-light-2026/code-snippet-light-2026.html", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "timeline call/add/addPause is not rewritten safely" + }, + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: rotateY" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [ + { + "code": "ease-shim-divergence", + "message": "ease shim divergence" + } + ] + } + ] + }, + { + "kind": "block", + "name": "code-snippet-light-modern", + "path": "blocks/code-snippet-light-modern", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "timeline call/add/addPause is not rewritten safely" + }, + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: rotateY" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [ + { + "code": "ease-shim-divergence", + "message": "ease shim divergence" + } + ], + "files": [ + { + "path": "blocks/code-snippet-light-modern/code-snippet-light-modern.html", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "timeline call/add/addPause is not rewritten safely" + }, + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: rotateY" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [ + { + "code": "ease-shim-divergence", + "message": "ease shim divergence" + } + ] + } + ] + }, + { + "kind": "block", + "name": "code-snippet-light-plus", + "path": "blocks/code-snippet-light-plus", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "timeline call/add/addPause is not rewritten safely" + }, + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: rotateY" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [ + { + "code": "ease-shim-divergence", + "message": "ease shim divergence" + } + ], + "files": [ + { + "path": "blocks/code-snippet-light-plus/code-snippet-light-plus.html", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "timeline call/add/addPause is not rewritten safely" + }, + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: rotateY" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [ + { + "code": "ease-shim-divergence", + "message": "ease shim divergence" + } + ] + } + ] + }, + { + "kind": "block", + "name": "code-snippet-monokai", + "path": "blocks/code-snippet-monokai", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "timeline call/add/addPause is not rewritten safely" + }, + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: rotateY" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [ + { + "code": "ease-shim-divergence", + "message": "ease shim divergence" + } + ], + "files": [ + { + "path": "blocks/code-snippet-monokai/code-snippet-monokai.html", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "timeline call/add/addPause is not rewritten safely" + }, + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: rotateY" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [ + { + "code": "ease-shim-divergence", + "message": "ease shim divergence" + } + ] + } + ] + }, + { + "kind": "block", + "name": "code-snippet-solarized-light", + "path": "blocks/code-snippet-solarized-light", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "timeline call/add/addPause is not rewritten safely" + }, + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: rotateY" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [ + { + "code": "ease-shim-divergence", + "message": "ease shim divergence" + } + ], + "files": [ + { + "path": "blocks/code-snippet-solarized-light/code-snippet-solarized-light.html", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "timeline call/add/addPause is not rewritten safely" + }, + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: rotateY" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [ + { + "code": "ease-shim-divergence", + "message": "ease shim divergence" + } + ] + } + ] + }, + { + "kind": "block", + "name": "code-snippet-visual-studio-dark", + "path": "blocks/code-snippet-visual-studio-dark", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "timeline call/add/addPause is not rewritten safely" + }, + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: rotateY" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [ + { + "code": "ease-shim-divergence", + "message": "ease shim divergence" + } + ], + "files": [ + { + "path": "blocks/code-snippet-visual-studio-dark/code-snippet-visual-studio-dark.html", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "timeline call/add/addPause is not rewritten safely" + }, + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: rotateY" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [ + { + "code": "ease-shim-divergence", + "message": "ease shim divergence" + } + ] + } + ] + }, + { + "kind": "block", + "name": "code-snippet-visual-studio-light", + "path": "blocks/code-snippet-visual-studio-light", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "timeline call/add/addPause is not rewritten safely" + }, + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: rotateY" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [ + { + "code": "ease-shim-divergence", + "message": "ease shim divergence" + } + ], + "files": [ + { + "path": "blocks/code-snippet-visual-studio-light/code-snippet-visual-studio-light.html", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "timeline call/add/addPause is not rewritten safely" + }, + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: rotateY" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [ + { + "code": "ease-shim-divergence", + "message": "ease shim divergence" + } + ] + } + ] + }, + { + "kind": "block", + "name": "code-typing", + "path": "blocks/code-typing", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "unresolved selector or keyframes" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [], + "files": [ + { + "path": "blocks/code-typing/code-typing.html", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "unresolved selector or keyframes" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [] + } + ] + }, + { + "kind": "block", + "name": "cross-warp-morph", + "path": "blocks/cross-warp-morph", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "timeline callback properties need manual review" + } + ], + "warnings": [], + "files": [ + { + "path": "blocks/cross-warp-morph/cross-warp-morph.html", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "timeline callback properties need manual review" + } + ], + "warnings": [] + } + ] + }, + { + "kind": "block", + "name": "data-chart", + "path": "blocks/data-chart", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "timeline callback properties need manual review" + }, + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: attr" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [], + "files": [ + { + "path": "blocks/data-chart/data-chart.html", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "timeline callback properties need manual review" + }, + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: attr" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [] + } + ] + }, + { + "kind": "block", + "name": "domain-warp-dissolve", + "path": "blocks/domain-warp-dissolve", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "timeline callback properties need manual review" + } + ], + "warnings": [], + "files": [ + { + "path": "blocks/domain-warp-dissolve/domain-warp-dissolve.html", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "timeline callback properties need manual review" + } + ], + "warnings": [] + } + ] + }, + { + "kind": "block", + "name": "flash-through-white", + "path": "blocks/flash-through-white", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "timeline callback properties need manual review" + } + ], + "warnings": [], + "files": [ + { + "path": "blocks/flash-through-white/flash-through-white.html", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "timeline callback properties need manual review" + } + ], + "warnings": [] + } + ] + }, + { + "kind": "block", + "name": "flowchart", + "path": "blocks/flowchart", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "timeline call/add/addPause is not rewritten safely" + }, + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: strokeDashoffset" + }, + { + "code": "unsupported-extra", + "message": "Unsupported GSAP extra: overwrite" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [], + "files": [ + { + "path": "blocks/flowchart/flowchart.html", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "timeline call/add/addPause is not rewritten safely" + }, + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: strokeDashoffset" + }, + { + "code": "unsupported-extra", + "message": "Unsupported GSAP extra: overwrite" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [] + } + ] + }, + { + "kind": "block", + "name": "flowchart-vertical", + "path": "blocks/flowchart-vertical", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "timeline call/add/addPause is not rewritten safely" + }, + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: strokeDashoffset" + }, + { + "code": "unsupported-extra", + "message": "Unsupported GSAP extra: overwrite" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [], + "files": [ + { + "path": "blocks/flowchart-vertical/flowchart-vertical.html", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "timeline call/add/addPause is not rewritten safely" + }, + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: strokeDashoffset" + }, + { + "code": "unsupported-extra", + "message": "Unsupported GSAP extra: overwrite" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [] + } + ] + }, + { + "kind": "block", + "name": "glitch", + "path": "blocks/glitch", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "timeline callback properties need manual review" + } + ], + "warnings": [], + "files": [ + { + "path": "blocks/glitch/glitch.html", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "timeline callback properties need manual review" + } + ], + "warnings": [] + } + ] + }, + { + "kind": "block", + "name": "gravitational-lens", + "path": "blocks/gravitational-lens", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "timeline callback properties need manual review" + } + ], + "warnings": [], + "files": [ + { + "path": "blocks/gravitational-lens/gravitational-lens.html", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "timeline callback properties need manual review" + } + ], + "warnings": [] + } + ] + }, + { + "kind": "block", + "name": "instagram-follow", + "path": "blocks/instagram-follow", + "status": "converted", + "changed": true, + "reasons": [], + "warnings": [], + "files": [ + { + "path": "blocks/instagram-follow/instagram-follow.html", + "status": "converted", + "changed": true, + "reasons": [], + "warnings": [] + } + ] + }, + { + "kind": "block", + "name": "ios26-liquid-glass", + "path": "blocks/ios26-liquid-glass", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "timeline call/add/addPause is not rewritten safely" + }, + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: p" + }, + { + "code": "customEase-beyond-shim", + "message": "Unrecognized or fallback ease needs manual review: __raw:driftEase" + } + ], + "warnings": [], + "files": [ + { + "path": "blocks/ios26-liquid-glass/ios26-liquid-glass.html", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "timeline call/add/addPause is not rewritten safely" + }, + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: p" + }, + { + "code": "customEase-beyond-shim", + "message": "Unrecognized or fallback ease needs manual review: __raw:driftEase" + } + ], + "warnings": [] + } + ] + }, + { + "kind": "block", + "name": "light-leak", + "path": "blocks/light-leak", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "timeline callback properties need manual review" + } + ], + "warnings": [], + "files": [ + { + "path": "blocks/light-leak/light-leak.html", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "timeline callback properties need manual review" + } + ], + "warnings": [] + } + ] + }, + { + "kind": "block", + "name": "liquid-glass-context-menu", + "path": "blocks/liquid-glass-context-menu", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "timeline call/add/addPause is not rewritten safely" + }, + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: top" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [], + "files": [ + { + "path": "blocks/liquid-glass-context-menu/liquid-glass-context-menu.html", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "timeline call/add/addPause is not rewritten safely" + }, + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: top" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [] + } + ] + }, + { + "kind": "block", + "name": "liquid-glass-media-controls", + "path": "blocks/liquid-glass-media-controls", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "timeline call/add/addPause is not rewritten safely" + }, + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: top" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [], + "files": [ + { + "path": "blocks/liquid-glass-media-controls/liquid-glass-media-controls.html", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "timeline call/add/addPause is not rewritten safely" + }, + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: top" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [] + } + ] + }, + { + "kind": "block", + "name": "liquid-glass-notification", + "path": "blocks/liquid-glass-notification", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "timeline call/add/addPause is not rewritten safely" + }, + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: left" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [], + "files": [ + { + "path": "blocks/liquid-glass-notification/liquid-glass-notification.html", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "timeline call/add/addPause is not rewritten safely" + }, + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: left" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [] + } + ] + }, + { + "kind": "block", + "name": "liquid-glass-widgets", + "path": "blocks/liquid-glass-widgets", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "timeline call/add/addPause is not rewritten safely" + }, + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: top" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [], + "files": [ + { + "path": "blocks/liquid-glass-widgets/liquid-glass-widgets.html", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "timeline call/add/addPause is not rewritten safely" + }, + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: top" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [] + } + ] + }, + { + "kind": "block", + "name": "logo-outro", + "path": "blocks/logo-outro", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "unresolved selector or keyframes" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [], + "files": [ + { + "path": "blocks/logo-outro/logo-outro.html", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "unresolved selector or keyframes" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [] + } + ] + }, + { + "kind": "block", + "name": "lower-third-bild", + "path": "blocks/lower-third-bild", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [], + "files": [ + { + "path": "blocks/lower-third-bild/lower-third-bild.html", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [] + } + ] + }, + { + "kind": "block", + "name": "lt-accent-underline", + "path": "blocks/lt-accent-underline", + "status": "converted", + "changed": true, + "reasons": [], + "warnings": [], + "files": [ + { + "path": "blocks/lt-accent-underline/lt-accent-underline.html", + "status": "converted", + "changed": true, + "reasons": [], + "warnings": [] + } + ] + }, + { + "kind": "block", + "name": "lt-bold-block", + "path": "blocks/lt-bold-block", + "status": "converted", + "changed": true, + "reasons": [], + "warnings": [], + "files": [ + { + "path": "blocks/lt-bold-block/lt-bold-block.html", + "status": "converted", + "changed": true, + "reasons": [], + "warnings": [] + } + ] + }, + { + "kind": "block", + "name": "lt-clean-bar", + "path": "blocks/lt-clean-bar", + "status": "converted", + "changed": true, + "reasons": [], + "warnings": [], + "files": [ + { + "path": "blocks/lt-clean-bar/lt-clean-bar.html", + "status": "converted", + "changed": true, + "reasons": [], + "warnings": [] + } + ] + }, + { + "kind": "block", + "name": "lt-color-block", + "path": "blocks/lt-color-block", + "status": "converted", + "changed": true, + "reasons": [], + "warnings": [], + "files": [ + { + "path": "blocks/lt-color-block/lt-color-block.html", + "status": "converted", + "changed": true, + "reasons": [], + "warnings": [] + } + ] + }, + { + "kind": "block", + "name": "lt-dark-card", + "path": "blocks/lt-dark-card", + "status": "converted", + "changed": true, + "reasons": [], + "warnings": [], + "files": [ + { + "path": "blocks/lt-dark-card/lt-dark-card.html", + "status": "converted", + "changed": true, + "reasons": [], + "warnings": [] + } + ] + }, + { + "kind": "block", + "name": "lt-kicker-name", + "path": "blocks/lt-kicker-name", + "status": "converted", + "changed": true, + "reasons": [], + "warnings": [], + "files": [ + { + "path": "blocks/lt-kicker-name/lt-kicker-name.html", + "status": "converted", + "changed": true, + "reasons": [], + "warnings": [] + } + ] + }, + { + "kind": "block", + "name": "lt-mask-reveal", + "path": "blocks/lt-mask-reveal", + "status": "converted", + "changed": true, + "reasons": [], + "warnings": [], + "files": [ + { + "path": "blocks/lt-mask-reveal/lt-mask-reveal.html", + "status": "converted", + "changed": true, + "reasons": [], + "warnings": [] + } + ] + }, + { + "kind": "block", + "name": "lt-side-rule", + "path": "blocks/lt-side-rule", + "status": "converted", + "changed": true, + "reasons": [], + "warnings": [], + "files": [ + { + "path": "blocks/lt-side-rule/lt-side-rule.html", + "status": "converted", + "changed": true, + "reasons": [], + "warnings": [] + } + ] + }, + { + "kind": "block", + "name": "lt-soft-pill", + "path": "blocks/lt-soft-pill", + "status": "converted", + "changed": true, + "reasons": [], + "warnings": [], + "files": [ + { + "path": "blocks/lt-soft-pill/lt-soft-pill.html", + "status": "converted", + "changed": true, + "reasons": [], + "warnings": [] + } + ] + }, + { + "kind": "block", + "name": "lt-stack-bars", + "path": "blocks/lt-stack-bars", + "status": "converted", + "changed": true, + "reasons": [], + "warnings": [], + "files": [ + { + "path": "blocks/lt-stack-bars/lt-stack-bars.html", + "status": "converted", + "changed": true, + "reasons": [], + "warnings": [] + } + ] + }, + { + "kind": "block", + "name": "macos-notification", + "path": "blocks/macos-notification", + "status": "converted", + "changed": true, + "reasons": [], + "warnings": [], + "files": [ + { + "path": "blocks/macos-notification/macos-notification.html", + "status": "converted", + "changed": true, + "reasons": [], + "warnings": [] + } + ] + }, + { + "kind": "block", + "name": "macos-tahoe-liquid-glass", + "path": "blocks/macos-tahoe-liquid-glass", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "timeline call/add/addPause is not rewritten safely" + }, + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: p" + }, + { + "code": "customEase-beyond-shim", + "message": "Unrecognized or fallback ease needs manual review: __raw:driftEase" + } + ], + "warnings": [], + "files": [ + { + "path": "blocks/macos-tahoe-liquid-glass/macos-tahoe-liquid-glass.html", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "timeline call/add/addPause is not rewritten safely" + }, + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: p" + }, + { + "code": "customEase-beyond-shim", + "message": "Unrecognized or fallback ease needs manual review: __raw:driftEase" + } + ], + "warnings": [] + } + ] + }, + { + "kind": "block", + "name": "news-ticker", + "path": "blocks/news-ticker", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: boxShadow" + } + ], + "warnings": [], + "files": [ + { + "path": "blocks/news-ticker/news-ticker.html", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: boxShadow" + } + ], + "warnings": [] + } + ] + }, + { + "kind": "block", + "name": "north-korea-locked-down", + "path": "blocks/north-korea-locked-down", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: strokeDashoffset" + } + ], + "warnings": [ + { + "code": "ease-shim-divergence", + "message": "ease shim divergence" + } + ], + "files": [ + { + "path": "blocks/north-korea-locked-down/north-korea-locked-down.html", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: strokeDashoffset" + } + ], + "warnings": [ + { + "code": "ease-shim-divergence", + "message": "ease shim divergence" + } + ] + } + ] + }, + { + "kind": "block", + "name": "nyc-paris-flight", + "path": "blocks/nyc-paris-flight", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: strokeDashoffset" + } + ], + "warnings": [ + { + "code": "ease-shim-divergence", + "message": "ease shim divergence" + } + ], + "files": [ + { + "path": "blocks/nyc-paris-flight/nyc-paris-flight.html", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: strokeDashoffset" + } + ], + "warnings": [ + { + "code": "ease-shim-divergence", + "message": "ease shim divergence" + } + ] + } + ] + }, + { + "kind": "block", + "name": "reddit-post", + "path": "blocks/reddit-post", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "timeline callback properties need manual review" + }, + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: attr" + } + ], + "warnings": [], + "files": [ + { + "path": "blocks/reddit-post/reddit-post.html", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "timeline callback properties need manual review" + }, + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: attr" + } + ], + "warnings": [] + } + ] + }, + { + "kind": "block", + "name": "ridged-burn", + "path": "blocks/ridged-burn", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "timeline callback properties need manual review" + } + ], + "warnings": [], + "files": [ + { + "path": "blocks/ridged-burn/ridged-burn.html", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "timeline callback properties need manual review" + } + ], + "warnings": [] + } + ] + }, + { + "kind": "block", + "name": "ripple-waves", + "path": "blocks/ripple-waves", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "timeline callback properties need manual review" + } + ], + "warnings": [], + "files": [ + { + "path": "blocks/ripple-waves/ripple-waves.html", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "timeline callback properties need manual review" + } + ], + "warnings": [] + } + ] + }, + { + "kind": "block", + "name": "sdf-iris", + "path": "blocks/sdf-iris", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "timeline callback properties need manual review" + } + ], + "warnings": [], + "files": [ + { + "path": "blocks/sdf-iris/sdf-iris.html", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "timeline callback properties need manual review" + } + ], + "warnings": [] + } + ] + }, + { + "kind": "block", + "name": "spain-map", + "path": "blocks/spain-map", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: stroke" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [], + "files": [ + { + "path": "blocks/spain-map/spain-map.html", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: stroke" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [] + } + ] + }, + { + "kind": "block", + "name": "spotify-card", + "path": "blocks/spotify-card", + "status": "converted", + "changed": true, + "reasons": [], + "warnings": [], + "files": [ + { + "path": "blocks/spotify-card/spotify-card.html", + "status": "converted", + "changed": true, + "reasons": [], + "warnings": [] + } + ] + }, + { + "kind": "block", + "name": "swirl-vortex", + "path": "blocks/swirl-vortex", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "timeline callback properties need manual review" + } + ], + "warnings": [], + "files": [ + { + "path": "blocks/swirl-vortex/swirl-vortex.html", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "timeline callback properties need manual review" + } + ], + "warnings": [] + } + ] + }, + { + "kind": "block", + "name": "thermal-distortion", + "path": "blocks/thermal-distortion", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "timeline callback properties need manual review" + } + ], + "warnings": [], + "files": [ + { + "path": "blocks/thermal-distortion/thermal-distortion.html", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "timeline callback properties need manual review" + } + ], + "warnings": [] + } + ] + }, + { + "kind": "block", + "name": "tiktok-follow", + "path": "blocks/tiktok-follow", + "status": "converted", + "changed": true, + "reasons": [], + "warnings": [], + "files": [ + { + "path": "blocks/tiktok-follow/tiktok-follow.html", + "status": "converted", + "changed": true, + "reasons": [], + "warnings": [] + } + ] + }, + { + "kind": "block", + "name": "transitions-3d", + "path": "blocks/transitions-3d", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "plugin:Flip", + "message": "Flip plugin usage needs manual review" + }, + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: zIndex" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [], + "files": [ + { + "path": "blocks/transitions-3d/transitions-3d.html", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "plugin:Flip", + "message": "Flip plugin usage needs manual review" + }, + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: zIndex" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [] + } + ] + }, + { + "kind": "block", + "name": "transitions-blur", + "path": "blocks/transitions-blur", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: zIndex" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [], + "files": [ + { + "path": "blocks/transitions-blur/transitions-blur.html", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: zIndex" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [] + } + ] + }, + { + "kind": "block", + "name": "transitions-cover", + "path": "blocks/transitions-cover", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: textContent" + }, + { + "code": "computed-timeline", + "message": "unresolved selector or keyframes" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [], + "files": [ + { + "path": "blocks/transitions-cover/transitions-cover.html", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: textContent" + }, + { + "code": "computed-timeline", + "message": "unresolved selector or keyframes" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [] + } + ] + }, + { + "kind": "block", + "name": "transitions-destruction", + "path": "blocks/transitions-destruction", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "timeline call/add/addPause is not rewritten safely" + }, + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: zIndex" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [], + "files": [ + { + "path": "blocks/transitions-destruction/transitions-destruction.html", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "timeline call/add/addPause is not rewritten safely" + }, + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: zIndex" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [] + } + ] + }, + { + "kind": "block", + "name": "transitions-dissolve", + "path": "blocks/transitions-dissolve", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: zIndex" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [], + "files": [ + { + "path": "blocks/transitions-dissolve/transitions-dissolve.html", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: zIndex" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [] + } + ] + }, + { + "kind": "block", + "name": "transitions-distortion", + "path": "blocks/transitions-distortion", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "timeline call/add/addPause is not rewritten safely" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [], + "files": [ + { + "path": "blocks/transitions-distortion/transitions-distortion.html", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "timeline call/add/addPause is not rewritten safely" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [] + } + ] + }, + { + "kind": "block", + "name": "transitions-grid", + "path": "blocks/transitions-grid", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "timeline call/add/addPause is not rewritten safely" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [], + "files": [ + { + "path": "blocks/transitions-grid/transitions-grid.html", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "timeline call/add/addPause is not rewritten safely" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [] + } + ] + }, + { + "kind": "block", + "name": "transitions-light", + "path": "blocks/transitions-light", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: textContent" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [], + "files": [ + { + "path": "blocks/transitions-light/transitions-light.html", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: textContent" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [] + } + ] + }, + { + "kind": "block", + "name": "transitions-mechanical", + "path": "blocks/transitions-mechanical", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: zIndex" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [], + "files": [ + { + "path": "blocks/transitions-mechanical/transitions-mechanical.html", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: zIndex" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [] + } + ] + }, + { + "kind": "block", + "name": "transitions-other", + "path": "blocks/transitions-other", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: zIndex" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [], + "files": [ + { + "path": "blocks/transitions-other/transitions-other.html", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: zIndex" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [] + } + ] + }, + { + "kind": "block", + "name": "transitions-push", + "path": "blocks/transitions-push", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: zIndex" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [], + "files": [ + { + "path": "blocks/transitions-push/transitions-push.html", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: zIndex" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [] + } + ] + }, + { + "kind": "block", + "name": "transitions-radial", + "path": "blocks/transitions-radial", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: zIndex" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [], + "files": [ + { + "path": "blocks/transitions-radial/transitions-radial.html", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: zIndex" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [] + } + ] + }, + { + "kind": "block", + "name": "transitions-scale", + "path": "blocks/transitions-scale", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: zIndex" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [], + "files": [ + { + "path": "blocks/transitions-scale/transitions-scale.html", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: zIndex" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [] + } + ] + }, + { + "kind": "block", + "name": "ui-3d-reveal", + "path": "blocks/ui-3d-reveal", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "unresolved selector or keyframes" + }, + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: strokeDashoffset" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [ + { + "code": "ease-shim-divergence", + "message": "ease shim divergence" + } + ], + "files": [ + { + "path": "blocks/ui-3d-reveal/ui-3d-reveal.html", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "unresolved selector or keyframes" + }, + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: strokeDashoffset" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [ + { + "code": "ease-shim-divergence", + "message": "ease shim divergence" + } + ] + } + ] + }, + { + "kind": "block", + "name": "us-map", + "path": "blocks/us-map", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: stroke" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [], + "files": [ + { + "path": "blocks/us-map/us-map.html", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: stroke" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [] + } + ] + }, + { + "kind": "block", + "name": "us-map-bubble", + "path": "blocks/us-map-bubble", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: strokeDashoffset" + }, + { + "code": "computed-timeline", + "message": "unresolved selector or keyframes" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [], + "files": [ + { + "path": "blocks/us-map-bubble/us-map-bubble.html", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: strokeDashoffset" + }, + { + "code": "computed-timeline", + "message": "unresolved selector or keyframes" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [] + } + ] + }, + { + "kind": "block", + "name": "us-map-flow", + "path": "blocks/us-map-flow", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "timeline callback properties need manual review" + }, + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: strokeDashoffset" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [], + "files": [ + { + "path": "blocks/us-map-flow/us-map-flow.html", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "timeline callback properties need manual review" + }, + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: strokeDashoffset" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [] + } + ] + }, + { + "kind": "block", + "name": "us-map-hex", + "path": "blocks/us-map-hex", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "unresolved selector or keyframes" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [], + "files": [ + { + "path": "blocks/us-map-hex/us-map-hex.html", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "unresolved selector or keyframes" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [] + } + ] + }, + { + "kind": "block", + "name": "vfx-iphone-device", + "path": "blocks/vfx-iphone-device", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "timeline call/add/addPause is not rewritten safely" + }, + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: p" + }, + { + "code": "customEase-beyond-shim", + "message": "Unrecognized or fallback ease needs manual review: __raw:breatheEase" + } + ], + "warnings": [], + "files": [ + { + "path": "blocks/vfx-iphone-device/vfx-iphone-device.html", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "timeline call/add/addPause is not rewritten safely" + }, + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: p" + }, + { + "code": "customEase-beyond-shim", + "message": "Unrecognized or fallback ease needs manual review: __raw:breatheEase" + } + ], + "warnings": [] + } + ] + }, + { + "kind": "block", + "name": "vfx-liquid-background", + "path": "blocks/vfx-liquid-background", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "splitText", + "message": "SplitText or hand-rolled text splitting feeds the timeline" + }, + { + "code": "computed-timeline", + "message": "timeline call/add/addPause is not rewritten safely" + }, + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: value" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [], + "files": [ + { + "path": "blocks/vfx-liquid-background/vfx-liquid-background.html", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "splitText", + "message": "SplitText or hand-rolled text splitting feeds the timeline" + }, + { + "code": "computed-timeline", + "message": "timeline call/add/addPause is not rewritten safely" + }, + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: value" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [] + } + ] + }, + { + "kind": "block", + "name": "vfx-liquid-glass", + "path": "blocks/vfx-liquid-glass", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "timeline call/add/addPause is not rewritten safely" + }, + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: _" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [], + "files": [ + { + "path": "blocks/vfx-liquid-glass/vfx-liquid-glass.html", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "timeline call/add/addPause is not rewritten safely" + }, + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: _" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [] + } + ] + }, + { + "kind": "block", + "name": "vfx-magnetic", + "path": "blocks/vfx-magnetic", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "timeline callback properties need manual review" + }, + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: progress" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [], + "files": [ + { + "path": "blocks/vfx-magnetic/vfx-magnetic.html", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "timeline callback properties need manual review" + }, + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: progress" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [] + } + ] + }, + { + "kind": "block", + "name": "vfx-portal", + "path": "blocks/vfx-portal", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "timeline call/add/addPause is not rewritten safely" + }, + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: energyIntensity" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [], + "files": [ + { + "path": "blocks/vfx-portal/vfx-portal.html", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "timeline call/add/addPause is not rewritten safely" + }, + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: energyIntensity" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [] + } + ] + }, + { + "kind": "block", + "name": "vfx-shatter", + "path": "blocks/vfx-shatter", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "timeline call/add/addPause is not rewritten safely" + }, + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: t" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [], + "files": [ + { + "path": "blocks/vfx-shatter/vfx-shatter.html", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "timeline call/add/addPause is not rewritten safely" + }, + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: t" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [] + } + ] + }, + { + "kind": "block", + "name": "vfx-text-cursor", + "path": "blocks/vfx-text-cursor", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "timeline call/add/addPause is not rewritten safely" + }, + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: logoY" + }, + { + "code": "customEase-beyond-shim", + "message": "Unrecognized or fallback ease needs manual review: __raw:entryEase" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [ + { + "code": "ease-shim-divergence", + "message": "ease shim divergence" + } + ], + "files": [ + { + "path": "blocks/vfx-text-cursor/vfx-text-cursor.html", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "timeline call/add/addPause is not rewritten safely" + }, + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: logoY" + }, + { + "code": "customEase-beyond-shim", + "message": "Unrecognized or fallback ease needs manual review: __raw:entryEase" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [ + { + "code": "ease-shim-divergence", + "message": "ease shim divergence" + } + ] + } + ] + }, + { + "kind": "block", + "name": "vpn-youtube-spot", + "path": "blocks/vpn-youtube-spot", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: outlineWidth" + } + ], + "warnings": [], + "files": [ + { + "path": "blocks/vpn-youtube-spot/vpn-youtube-spot.html", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: outlineWidth" + } + ], + "warnings": [] + } + ] + }, + { + "kind": "block", + "name": "whip-pan", + "path": "blocks/whip-pan", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "timeline callback properties need manual review" + } + ], + "warnings": [], + "files": [ + { + "path": "blocks/whip-pan/whip-pan.html", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "timeline callback properties need manual review" + } + ], + "warnings": [] + } + ] + }, + { + "kind": "block", + "name": "world-map", + "path": "blocks/world-map", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "unresolved selector or keyframes" + }, + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: stroke" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [], + "files": [ + { + "path": "blocks/world-map/world-map.html", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "unresolved selector or keyframes" + }, + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: stroke" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [] + } + ] + }, + { + "kind": "block", + "name": "x-post", + "path": "blocks/x-post", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "timeline callback properties need manual review" + } + ], + "warnings": [], + "files": [ + { + "path": "blocks/x-post/x-post.html", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "timeline callback properties need manual review" + } + ], + "warnings": [] + } + ] + }, + { + "kind": "block", + "name": "yt-lower-third", + "path": "blocks/yt-lower-third", + "status": "converted", + "changed": true, + "reasons": [], + "warnings": [], + "files": [ + { + "path": "blocks/yt-lower-third/yt-lower-third.html", + "status": "converted", + "changed": true, + "reasons": [], + "warnings": [] + } + ] + }, + { + "kind": "component", + "name": "caption-blend-difference", + "path": "components/caption-blend-difference", + "status": "converted", + "changed": false, + "reasons": [], + "warnings": [], + "files": [ + { + "path": "components/caption-blend-difference/caption-blend-difference.html", + "status": "converted", + "changed": false, + "reasons": [], + "warnings": [] + } + ] + }, + { + "kind": "component", + "name": "caption-clip-wipe", + "path": "components/caption-clip-wipe", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "unresolved selector or keyframes" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [], + "files": [ + { + "path": "components/caption-clip-wipe/caption-clip-wipe.html", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "unresolved selector or keyframes" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [] + } + ] + }, + { + "kind": "component", + "name": "caption-editorial-emphasis", + "path": "components/caption-editorial-emphasis", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "unresolved selector or keyframes" + } + ], + "warnings": [], + "files": [ + { + "path": "components/caption-editorial-emphasis/caption-editorial-emphasis.html", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "unresolved selector or keyframes" + } + ], + "warnings": [] + } + ] + }, + { + "kind": "component", + "name": "caption-emoji-pop", + "path": "components/caption-emoji-pop", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "unresolved selector or keyframes" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [], + "files": [ + { + "path": "components/caption-emoji-pop/caption-emoji-pop.html", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "unresolved selector or keyframes" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [] + } + ] + }, + { + "kind": "component", + "name": "caption-glitch-rgb", + "path": "components/caption-glitch-rgb", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "unresolved selector or keyframes" + }, + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: textShadow" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [], + "files": [ + { + "path": "components/caption-glitch-rgb/caption-glitch-rgb.html", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "unresolved selector or keyframes" + }, + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: textShadow" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [] + } + ] + }, + { + "kind": "component", + "name": "caption-gradient-fill", + "path": "components/caption-gradient-fill", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "unresolved selector or keyframes" + }, + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: backgroundPosition" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [], + "files": [ + { + "path": "components/caption-gradient-fill/caption-gradient-fill.html", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "unresolved selector or keyframes" + }, + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: backgroundPosition" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [] + } + ] + }, + { + "kind": "component", + "name": "caption-highlight", + "path": "components/caption-highlight", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "unresolved selector or keyframes" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [], + "files": [ + { + "path": "components/caption-highlight/caption-highlight.html", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "unresolved selector or keyframes" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [] + } + ] + }, + { + "kind": "component", + "name": "caption-kinetic-slam", + "path": "components/caption-kinetic-slam", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "unresolved selector or keyframes" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [ + { + "code": "ease-shim-divergence", + "message": "ease shim divergence" + } + ], + "files": [ + { + "path": "components/caption-kinetic-slam/caption-kinetic-slam.html", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "unresolved selector or keyframes" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [ + { + "code": "ease-shim-divergence", + "message": "ease shim divergence" + } + ] + } + ] + }, + { + "kind": "component", + "name": "caption-matrix-decode", + "path": "components/caption-matrix-decode", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "unresolved selector or keyframes" + }, + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: display" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [], + "files": [ + { + "path": "components/caption-matrix-decode/caption-matrix-decode.html", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "unresolved selector or keyframes" + }, + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: display" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [] + } + ] + }, + { + "kind": "component", + "name": "caption-neon-accent", + "path": "components/caption-neon-accent", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "unresolved selector or keyframes" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [], + "files": [ + { + "path": "components/caption-neon-accent/caption-neon-accent.html", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "unresolved selector or keyframes" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [] + } + ] + }, + { + "kind": "component", + "name": "caption-neon-glow", + "path": "components/caption-neon-glow", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "unresolved selector or keyframes" + }, + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: textShadow" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [ + { + "code": "ease-shim-divergence", + "message": "ease shim divergence" + } + ], + "files": [ + { + "path": "components/caption-neon-glow/caption-neon-glow.html", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "unresolved selector or keyframes" + }, + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: textShadow" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [ + { + "code": "ease-shim-divergence", + "message": "ease shim divergence" + } + ] + } + ] + }, + { + "kind": "component", + "name": "caption-parallax-layers", + "path": "components/caption-parallax-layers", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "unresolved selector or keyframes" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [], + "files": [ + { + "path": "components/caption-parallax-layers/caption-parallax-layers.html", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "unresolved selector or keyframes" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [] + } + ] + }, + { + "kind": "component", + "name": "caption-particle-burst", + "path": "components/caption-particle-burst", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "unresolved selector or keyframes" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [], + "files": [ + { + "path": "components/caption-particle-burst/caption-particle-burst.html", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "unresolved selector or keyframes" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [] + } + ] + }, + { + "kind": "component", + "name": "caption-pill-karaoke", + "path": "components/caption-pill-karaoke", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [], + "files": [ + { + "path": "components/caption-pill-karaoke/caption-pill-karaoke.html", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [] + } + ] + }, + { + "kind": "component", + "name": "caption-texture", + "path": "components/caption-texture", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "unresolved selector or keyframes" + }, + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: --mask-position" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [], + "files": [ + { + "path": "components/caption-texture/caption-texture.html", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "unresolved selector or keyframes" + }, + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: --mask-position" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [] + } + ] + }, + { + "kind": "component", + "name": "caption-weight-shift", + "path": "components/caption-weight-shift", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "unresolved selector or keyframes" + }, + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: fontWeight" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [], + "files": [ + { + "path": "components/caption-weight-shift/caption-weight-shift.html", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "unresolved selector or keyframes" + }, + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: fontWeight" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [] + } + ] + }, + { + "kind": "component", + "name": "grain-overlay", + "path": "components/grain-overlay", + "status": "converted", + "changed": false, + "reasons": [], + "warnings": [], + "files": [ + { + "path": "components/grain-overlay/grain-overlay.html", + "status": "converted", + "changed": false, + "reasons": [], + "warnings": [] + } + ] + }, + { + "kind": "component", + "name": "grid-pixelate-wipe", + "path": "components/grid-pixelate-wipe", + "status": "converted", + "changed": false, + "reasons": [], + "warnings": [], + "files": [ + { + "path": "components/grid-pixelate-wipe/grid-pixelate-wipe.html", + "status": "converted", + "changed": false, + "reasons": [], + "warnings": [] + } + ] + }, + { + "kind": "component", + "name": "morph-text", + "path": "components/morph-text", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "timeline callback properties need manual review" + }, + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: t" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [], + "files": [ + { + "path": "components/morph-text/morph-text.html", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "timeline callback properties need manual review" + }, + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: t" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [] + } + ] + }, + { + "kind": "component", + "name": "motion-blur", + "path": "components/motion-blur", + "status": "converted", + "changed": false, + "reasons": [], + "warnings": [], + "files": [ + { + "path": "components/motion-blur/motion-blur.html", + "status": "converted", + "changed": false, + "reasons": [], + "warnings": [] + } + ] + }, + { + "kind": "component", + "name": "parallax-unzoom", + "path": "components/parallax-unzoom", + "status": "converted", + "changed": false, + "reasons": [], + "warnings": [], + "files": [ + { + "path": "components/parallax-unzoom/parallax-unzoom.html", + "status": "converted", + "changed": false, + "reasons": [], + "warnings": [] + } + ] + }, + { + "kind": "component", + "name": "parallax-zoom", + "path": "components/parallax-zoom", + "status": "converted", + "changed": false, + "reasons": [], + "warnings": [], + "files": [ + { + "path": "components/parallax-zoom/parallax-zoom.html", + "status": "converted", + "changed": false, + "reasons": [], + "warnings": [] + } + ] + }, + { + "kind": "component", + "name": "shimmer-sweep", + "path": "components/shimmer-sweep", + "status": "converted", + "changed": false, + "reasons": [], + "warnings": [], + "files": [ + { + "path": "components/shimmer-sweep/shimmer-sweep.html", + "status": "converted", + "changed": false, + "reasons": [], + "warnings": [] + } + ] + }, + { + "kind": "component", + "name": "texture-mask-text", + "path": "components/texture-mask-text", + "status": "converted", + "changed": false, + "reasons": [], + "warnings": [], + "files": [ + { + "path": "components/texture-mask-text/texture-mask-text.html", + "status": "converted", + "changed": false, + "reasons": [], + "warnings": [] + } + ] + }, + { + "kind": "component", + "name": "vignette", + "path": "components/vignette", + "status": "converted", + "changed": false, + "reasons": [], + "warnings": [], + "files": [ + { + "path": "components/vignette/vignette.html", + "status": "converted", + "changed": false, + "reasons": [], + "warnings": [] + } + ] + }, + { + "kind": "example", + "name": "airbnb-deck", + "path": "examples/airbnb-deck", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [], + "files": [ + { + "path": "examples/airbnb-deck/demo.html", + "status": "converted", + "changed": false, + "reasons": [], + "warnings": [] + }, + { + "path": "examples/airbnb-deck/index.html", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [] + } + ] + }, + { + "kind": "example", + "name": "decision-tree", + "path": "examples/decision-tree", + "status": "manual", + "changed": true, + "reasons": [ + { + "code": "computed-timeline", + "message": "timeline call/add/addPause is not rewritten safely" + }, + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: strokeDashoffset" + }, + { + "code": "unsupported-extra", + "message": "Unsupported GSAP extra: overwrite" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [], + "files": [ + { + "path": "examples/decision-tree/compositions/decision_tree.html", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "timeline call/add/addPause is not rewritten safely" + }, + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: strokeDashoffset" + }, + { + "code": "unsupported-extra", + "message": "Unsupported GSAP extra: overwrite" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [] + }, + { + "path": "examples/decision-tree/index.html", + "status": "converted", + "changed": true, + "reasons": [], + "warnings": [] + } + ] + }, + { + "kind": "example", + "name": "kinetic-type", + "path": "examples/kinetic-type", + "status": "manual", + "changed": true, + "reasons": [ + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: xPercent" + } + ], + "warnings": [ + { + "code": "ease-shim-divergence", + "message": "ease shim divergence" + } + ], + "files": [ + { + "path": "examples/kinetic-type/compositions/main-graphics.html", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: xPercent" + } + ], + "warnings": [ + { + "code": "ease-shim-divergence", + "message": "ease shim divergence" + } + ] + }, + { + "path": "examples/kinetic-type/index.html", + "status": "converted", + "changed": true, + "reasons": [], + "warnings": [] + } + ] + }, + { + "kind": "example", + "name": "motion-blur", + "path": "examples/motion-blur", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "timeline callback properties need manual review" + }, + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: t" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [], + "files": [ + { + "path": "examples/motion-blur/index.html", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "timeline callback properties need manual review" + }, + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: t" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [] + } + ] + }, + { + "kind": "example", + "name": "nyt-graph", + "path": "examples/nyt-graph", + "status": "manual", + "changed": true, + "reasons": [ + { + "code": "computed-timeline", + "message": "timeline callback properties need manual review" + }, + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: attr" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [], + "files": [ + { + "path": "examples/nyt-graph/compositions/nyt-chart.html", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "timeline callback properties need manual review" + }, + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: attr" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [] + }, + { + "path": "examples/nyt-graph/index.html", + "status": "converted", + "changed": true, + "reasons": [], + "warnings": [] + } + ] + }, + { + "kind": "example", + "name": "play-mode", + "path": "examples/play-mode", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "unresolved selector or keyframes" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [ + { + "code": "autoAlpha-expansion", + "message": "autoAlpha expands to opacity and visibility" + } + ], + "files": [ + { + "path": "examples/play-mode/compositions/captions.html", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "unresolved selector or keyframes" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [ + { + "code": "autoAlpha-expansion", + "message": "autoAlpha expands to opacity and visibility" + } + ] + }, + { + "path": "examples/play-mode/compositions/intro.html", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "GSAP delay is not represented in parsed placement data" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [] + }, + { + "path": "examples/play-mode/compositions/stats.html", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "timeline callback properties need manual review" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [] + }, + { + "path": "examples/play-mode/index.html", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [] + } + ] + }, + { + "kind": "example", + "name": "product-promo", + "path": "examples/product-promo", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "GSAP delay is not represented in parsed placement data" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + }, + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: xPercent" + }, + { + "code": "unsupported-extra", + "message": "Unsupported GSAP extra: overwrite" + } + ], + "warnings": [ + { + "code": "ease-shim-divergence", + "message": "ease shim divergence" + } + ], + "files": [ + { + "path": "examples/product-promo/compositions/scene1-logo-intro.html", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "GSAP delay is not represented in parsed placement data" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [ + { + "code": "ease-shim-divergence", + "message": "ease shim divergence" + } + ] + }, + { + "path": "examples/product-promo/compositions/scene2-4-canvas.html", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "timeline callback properties need manual review" + }, + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: xPercent" + }, + { + "code": "unsupported-extra", + "message": "Unsupported GSAP extra: overwrite" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [ + { + "code": "ease-shim-divergence", + "message": "ease shim divergence" + } + ] + }, + { + "path": "examples/product-promo/compositions/scene5-logo-outro.html", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "unresolved selector or keyframes" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [] + }, + { + "path": "examples/product-promo/index.html", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [] + } + ] + }, + { + "kind": "example", + "name": "slideshow-demo", + "path": "examples/slideshow-demo", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [], + "files": [ + { + "path": "examples/slideshow-demo/index.html", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [] + } + ] + }, + { + "kind": "example", + "name": "startup-pitch", + "path": "examples/startup-pitch", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [], + "files": [ + { + "path": "examples/startup-pitch/demo.html", + "status": "converted", + "changed": false, + "reasons": [], + "warnings": [] + }, + { + "path": "examples/startup-pitch/index.html", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [] + } + ] + }, + { + "kind": "example", + "name": "swiss-grid", + "path": "examples/swiss-grid", + "status": "manual", + "changed": true, + "reasons": [ + { + "code": "computed-timeline", + "message": "unresolved selector or keyframes" + }, + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: display" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [ + { + "code": "ease-shim-divergence", + "message": "ease shim divergence" + } + ], + "files": [ + { + "path": "examples/swiss-grid/compositions/captions.html", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "unresolved selector or keyframes" + }, + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: display" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [] + }, + { + "path": "examples/swiss-grid/compositions/graphics.html", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [] + }, + { + "path": "examples/swiss-grid/compositions/intro.html", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [] + }, + { + "path": "examples/swiss-grid/index.html", + "status": "converted-with-warnings", + "changed": true, + "reasons": [], + "warnings": [ + { + "code": "ease-shim-divergence", + "message": "ease shim divergence" + } + ] + } + ] + }, + { + "kind": "example", + "name": "vignelli", + "path": "examples/vignelli", + "status": "manual", + "changed": true, + "reasons": [ + { + "code": "computed-timeline", + "message": "unresolved selector or keyframes" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + }, + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: xPercent" + } + ], + "warnings": [ + { + "code": "ease-shim-divergence", + "message": "ease shim divergence" + } + ], + "files": [ + { + "path": "examples/vignelli/compositions/captions.html", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "unresolved selector or keyframes" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [ + { + "code": "ease-shim-divergence", + "message": "ease shim divergence" + } + ] + }, + { + "path": "examples/vignelli/compositions/overlays.html", + "status": "converted-with-warnings", + "changed": true, + "reasons": [], + "warnings": [ + { + "code": "ease-shim-divergence", + "message": "ease shim divergence" + } + ] + }, + { + "path": "examples/vignelli/index.html", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: xPercent" + } + ], + "warnings": [] + } + ] + }, + { + "kind": "example", + "name": "vscode-theme-visualizer", + "path": "examples/vscode-theme-visualizer", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "timeline is not a simple identifier" + } + ], + "warnings": [], + "files": [ + { + "path": "examples/vscode-theme-visualizer/index.html", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "timeline is not a simple identifier" + } + ], + "warnings": [] + } + ] + }, + { + "kind": "example", + "name": "warm-grain", + "path": "examples/warm-grain", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "timeline callback properties need manual review" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + }, + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: xPercent" + } + ], + "warnings": [], + "files": [ + { + "path": "examples/warm-grain/compositions/captions.html", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "computed-timeline", + "message": "timeline callback properties need manual review" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [] + }, + { + "path": "examples/warm-grain/compositions/graphics.html", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [] + }, + { + "path": "examples/warm-grain/compositions/intro.html", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: xPercent" + }, + { + "code": "unrecognized-postamble", + "message": "postamble is not only timeline registration" + } + ], + "warnings": [] + }, + { + "path": "examples/warm-grain/index.html", + "status": "manual", + "changed": false, + "reasons": [ + { + "code": "unsupported-property", + "message": "Unsupported GSAP property: xPercent" + } + ], + "warnings": [] + } + ] + } + ] +} diff --git a/scripts/gsap-to-anime/dry-run-report.md b/scripts/gsap-to-anime/dry-run-report.md new file mode 100644 index 0000000000..f85fbd3eb1 --- /dev/null +++ b/scripts/gsap-to-anime/dry-run-report.md @@ -0,0 +1,169 @@ +# GSAP to anime.js dry-run report + +## Totals + +- converted: 24 +- converted-with-warnings: 0 +- manual: 123 +- total: 147 + +## Manual reason breakdown + +- computed-timeline: 102 +- unrecognized-postamble: 95 +- unsupported-property: 82 +- splitText: 13 +- unsupported-extra: 5 +- customEase-beyond-shim: 4 +- keyframes: 1 +- plugin:Flip: 1 + +## Items + +- manual: blocks/app-showcase (computed-timeline, unsupported-property, unrecognized-postamble) +- manual: blocks/apple-money-count (computed-timeline, unsupported-property) +- manual: blocks/blue-sweater-intro-video (unsupported-extra, computed-timeline, keyframes) +- manual: blocks/chromatic-radial-split (computed-timeline) +- manual: blocks/cinematic-zoom (computed-timeline) +- manual: blocks/code-3d-extrude (computed-timeline, unsupported-property, unrecognized-postamble) +- manual: blocks/code-diff (computed-timeline, unrecognized-postamble) +- manual: blocks/code-highlight (computed-timeline, unrecognized-postamble) +- manual: blocks/code-morph (computed-timeline, unrecognized-postamble) +- manual: blocks/code-particle-assemble (computed-timeline, unsupported-property, unrecognized-postamble) +- manual: blocks/code-scroll (computed-timeline, unrecognized-postamble) +- manual: blocks/code-shader-dissolve (computed-timeline, unsupported-property, unrecognized-postamble) +- manual: blocks/code-snippet-apple-terminal-basic (splitText, computed-timeline, unsupported-property, unrecognized-postamble) +- manual: blocks/code-snippet-apple-terminal-clear-dark (splitText, computed-timeline, unsupported-property, unrecognized-postamble) +- manual: blocks/code-snippet-apple-terminal-clear-light (splitText, computed-timeline, unsupported-property, unrecognized-postamble) +- manual: blocks/code-snippet-apple-terminal-grass (splitText, computed-timeline, unsupported-property, unrecognized-postamble) +- manual: blocks/code-snippet-apple-terminal-homebrew (splitText, computed-timeline, unsupported-property, unrecognized-postamble) +- manual: blocks/code-snippet-apple-terminal-man-page (splitText, computed-timeline, unsupported-property, unrecognized-postamble) +- manual: blocks/code-snippet-apple-terminal-novel (splitText, computed-timeline, unsupported-property, unrecognized-postamble) +- manual: blocks/code-snippet-apple-terminal-ocean (splitText, computed-timeline, unsupported-property, unrecognized-postamble) +- manual: blocks/code-snippet-apple-terminal-pro (splitText, computed-timeline, unsupported-property, unrecognized-postamble) +- manual: blocks/code-snippet-apple-terminal-red-sands (splitText, computed-timeline, unsupported-property, unrecognized-postamble) +- manual: blocks/code-snippet-apple-terminal-silver-aerogel (splitText, computed-timeline, unsupported-property, unrecognized-postamble) +- manual: blocks/code-snippet-apple-terminal-solid-colors (splitText, computed-timeline, unsupported-property, unrecognized-postamble) +- manual: blocks/code-snippet-dark-2026 (computed-timeline, unsupported-property, unrecognized-postamble) +- manual: blocks/code-snippet-dark-modern (computed-timeline, unsupported-property, unrecognized-postamble) +- manual: blocks/code-snippet-dark-plus (computed-timeline, unsupported-property, unrecognized-postamble) +- manual: blocks/code-snippet-flight (computed-timeline, unrecognized-postamble) +- manual: blocks/code-snippet-high-contrast (computed-timeline, unsupported-property, unrecognized-postamble) +- manual: blocks/code-snippet-high-contrast-light (computed-timeline, unsupported-property, unrecognized-postamble) +- manual: blocks/code-snippet-light-2026 (computed-timeline, unsupported-property, unrecognized-postamble) +- manual: blocks/code-snippet-light-modern (computed-timeline, unsupported-property, unrecognized-postamble) +- manual: blocks/code-snippet-light-plus (computed-timeline, unsupported-property, unrecognized-postamble) +- manual: blocks/code-snippet-monokai (computed-timeline, unsupported-property, unrecognized-postamble) +- manual: blocks/code-snippet-solarized-light (computed-timeline, unsupported-property, unrecognized-postamble) +- manual: blocks/code-snippet-visual-studio-dark (computed-timeline, unsupported-property, unrecognized-postamble) +- manual: blocks/code-snippet-visual-studio-light (computed-timeline, unsupported-property, unrecognized-postamble) +- manual: blocks/code-typing (computed-timeline, unrecognized-postamble) +- manual: blocks/cross-warp-morph (computed-timeline) +- manual: blocks/data-chart (computed-timeline, unsupported-property, unrecognized-postamble) +- manual: blocks/domain-warp-dissolve (computed-timeline) +- manual: blocks/flash-through-white (computed-timeline) +- manual: blocks/flowchart (computed-timeline, unsupported-property, unsupported-extra, unrecognized-postamble) +- manual: blocks/flowchart-vertical (computed-timeline, unsupported-property, unsupported-extra, unrecognized-postamble) +- manual: blocks/glitch (computed-timeline) +- manual: blocks/gravitational-lens (computed-timeline) +- converted: blocks/instagram-follow +- manual: blocks/ios26-liquid-glass (computed-timeline, unsupported-property, customEase-beyond-shim) +- manual: blocks/light-leak (computed-timeline) +- manual: blocks/liquid-glass-context-menu (computed-timeline, unsupported-property, unrecognized-postamble) +- manual: blocks/liquid-glass-media-controls (computed-timeline, unsupported-property, unrecognized-postamble) +- manual: blocks/liquid-glass-notification (computed-timeline, unsupported-property, unrecognized-postamble) +- manual: blocks/liquid-glass-widgets (computed-timeline, unsupported-property, unrecognized-postamble) +- manual: blocks/logo-outro (computed-timeline, unrecognized-postamble) +- manual: blocks/lower-third-bild (unrecognized-postamble) +- converted: blocks/lt-accent-underline +- converted: blocks/lt-bold-block +- converted: blocks/lt-clean-bar +- converted: blocks/lt-color-block +- converted: blocks/lt-dark-card +- converted: blocks/lt-kicker-name +- converted: blocks/lt-mask-reveal +- converted: blocks/lt-side-rule +- converted: blocks/lt-soft-pill +- converted: blocks/lt-stack-bars +- converted: blocks/macos-notification +- manual: blocks/macos-tahoe-liquid-glass (computed-timeline, unsupported-property, customEase-beyond-shim) +- manual: blocks/news-ticker (unsupported-property) +- manual: blocks/north-korea-locked-down (unsupported-property) +- manual: blocks/nyc-paris-flight (unsupported-property) +- manual: blocks/reddit-post (computed-timeline, unsupported-property) +- manual: blocks/ridged-burn (computed-timeline) +- manual: blocks/ripple-waves (computed-timeline) +- manual: blocks/sdf-iris (computed-timeline) +- manual: blocks/spain-map (unsupported-property, unrecognized-postamble) +- converted: blocks/spotify-card +- manual: blocks/swirl-vortex (computed-timeline) +- manual: blocks/thermal-distortion (computed-timeline) +- converted: blocks/tiktok-follow +- manual: blocks/transitions-3d (plugin:Flip, unsupported-property, unrecognized-postamble) +- manual: blocks/transitions-blur (unsupported-property, unrecognized-postamble) +- manual: blocks/transitions-cover (unsupported-property, computed-timeline, unrecognized-postamble) +- manual: blocks/transitions-destruction (computed-timeline, unsupported-property, unrecognized-postamble) +- manual: blocks/transitions-dissolve (unsupported-property, unrecognized-postamble) +- manual: blocks/transitions-distortion (computed-timeline, unrecognized-postamble) +- manual: blocks/transitions-grid (computed-timeline, unrecognized-postamble) +- manual: blocks/transitions-light (unsupported-property, unrecognized-postamble) +- manual: blocks/transitions-mechanical (unsupported-property, unrecognized-postamble) +- manual: blocks/transitions-other (unsupported-property, unrecognized-postamble) +- manual: blocks/transitions-push (unsupported-property, unrecognized-postamble) +- manual: blocks/transitions-radial (unsupported-property, unrecognized-postamble) +- manual: blocks/transitions-scale (unsupported-property, unrecognized-postamble) +- manual: blocks/ui-3d-reveal (computed-timeline, unsupported-property, unrecognized-postamble) +- manual: blocks/us-map (unsupported-property, unrecognized-postamble) +- manual: blocks/us-map-bubble (unsupported-property, computed-timeline, unrecognized-postamble) +- manual: blocks/us-map-flow (computed-timeline, unsupported-property, unrecognized-postamble) +- manual: blocks/us-map-hex (computed-timeline, unrecognized-postamble) +- manual: blocks/vfx-iphone-device (computed-timeline, unsupported-property, customEase-beyond-shim) +- manual: blocks/vfx-liquid-background (splitText, computed-timeline, unsupported-property, unrecognized-postamble) +- manual: blocks/vfx-liquid-glass (computed-timeline, unsupported-property, unrecognized-postamble) +- manual: blocks/vfx-magnetic (computed-timeline, unsupported-property, unrecognized-postamble) +- manual: blocks/vfx-portal (computed-timeline, unsupported-property, unrecognized-postamble) +- manual: blocks/vfx-shatter (computed-timeline, unsupported-property, unrecognized-postamble) +- manual: blocks/vfx-text-cursor (computed-timeline, unsupported-property, customEase-beyond-shim, unrecognized-postamble) +- manual: blocks/vpn-youtube-spot (unsupported-property) +- manual: blocks/whip-pan (computed-timeline) +- manual: blocks/world-map (computed-timeline, unsupported-property, unrecognized-postamble) +- manual: blocks/x-post (computed-timeline) +- converted: blocks/yt-lower-third +- converted: components/caption-blend-difference +- manual: components/caption-clip-wipe (computed-timeline, unrecognized-postamble) +- manual: components/caption-editorial-emphasis (computed-timeline) +- manual: components/caption-emoji-pop (computed-timeline, unrecognized-postamble) +- manual: components/caption-glitch-rgb (computed-timeline, unsupported-property, unrecognized-postamble) +- manual: components/caption-gradient-fill (computed-timeline, unsupported-property, unrecognized-postamble) +- manual: components/caption-highlight (computed-timeline, unrecognized-postamble) +- manual: components/caption-kinetic-slam (computed-timeline, unrecognized-postamble) +- manual: components/caption-matrix-decode (computed-timeline, unsupported-property, unrecognized-postamble) +- manual: components/caption-neon-accent (computed-timeline, unrecognized-postamble) +- manual: components/caption-neon-glow (computed-timeline, unsupported-property, unrecognized-postamble) +- manual: components/caption-parallax-layers (computed-timeline, unrecognized-postamble) +- manual: components/caption-particle-burst (computed-timeline, unrecognized-postamble) +- manual: components/caption-pill-karaoke (unrecognized-postamble) +- manual: components/caption-texture (computed-timeline, unsupported-property, unrecognized-postamble) +- manual: components/caption-weight-shift (computed-timeline, unsupported-property, unrecognized-postamble) +- converted: components/grain-overlay +- converted: components/grid-pixelate-wipe +- manual: components/morph-text (computed-timeline, unsupported-property, unrecognized-postamble) +- converted: components/motion-blur +- converted: components/parallax-unzoom +- converted: components/parallax-zoom +- converted: components/shimmer-sweep +- converted: components/texture-mask-text +- converted: components/vignette +- manual: examples/airbnb-deck (unrecognized-postamble) +- manual: examples/decision-tree (computed-timeline, unsupported-property, unsupported-extra, unrecognized-postamble) +- manual: examples/kinetic-type (unsupported-property) +- manual: examples/motion-blur (computed-timeline, unsupported-property, unrecognized-postamble) +- manual: examples/nyt-graph (computed-timeline, unsupported-property, unrecognized-postamble) +- manual: examples/play-mode (computed-timeline, unrecognized-postamble) +- manual: examples/product-promo (computed-timeline, unrecognized-postamble, unsupported-property, unsupported-extra) +- manual: examples/slideshow-demo (unrecognized-postamble) +- manual: examples/startup-pitch (unrecognized-postamble) +- manual: examples/swiss-grid (computed-timeline, unsupported-property, unrecognized-postamble) +- manual: examples/vignelli (computed-timeline, unrecognized-postamble, unsupported-property) +- manual: examples/vscode-theme-visualizer (computed-timeline) +- manual: examples/warm-grain (computed-timeline, unrecognized-postamble, unsupported-property) diff --git a/scripts/gsap-to-anime/gsap-to-anime.test.ts b/scripts/gsap-to-anime/gsap-to-anime.test.ts new file mode 100644 index 0000000000..b5f78606f1 --- /dev/null +++ b/scripts/gsap-to-anime/gsap-to-anime.test.ts @@ -0,0 +1,94 @@ +import assert from "node:assert/strict"; +import { readFileSync } from "node:fs"; +import { join } from "node:path"; +import { describe, it } from "node:test"; +import { transformHtml } from "./index.ts"; + +const FIXTURES = join(import.meta.dirname, "__fixtures__"); + +function fixture(name: string): string { + return readFileSync(join(FIXTURES, name), "utf-8"); +} + +function reasonCodes(result: ReturnType): string[] { + return result.classification.reasons.map((reason) => reason.code); +} + +function warningCodes(result: ReturnType): string[] { + return result.classification.warnings.map((warning) => warning.code); +} + +describe("gsap-to-anime transform", () => { + it("converts a simple to chain", () => { + const result = transformHtml(fixture("simple-to.before.html")); + + assert.equal(result.classification.status, "converted"); + assert.equal(result.changed, true); + assert.equal(result.html, fixture("simple-to.after.html")); + }); + + it("converts fromTo and set calls", () => { + const result = transformHtml(fixture("fromto-set.before.html")); + + assert.equal(result.classification.status, "converted"); + assert.equal(result.html, fixture("fromto-set.after.html")); + }); + + it("uses absolute millisecond positions for labels and relative GSAP positions", () => { + const result = transformHtml(fixture("positions.before.html")); + + assert.equal(result.classification.status, "converted"); + assert.equal(result.html, fixture("positions.after.html")); + }); + + it("converts a stagger grid to anime.stagger", () => { + const result = transformHtml(fixture("stagger-grid.before.html")); + + assert.equal(result.classification.status, "converted"); + assert.equal(result.html, fixture("stagger-grid.after.html")); + }); + + it("converts supported ease families and warns for expo or steps shim divergence", () => { + const result = transformHtml(fixture("eases.before.html")); + + assert.equal(result.classification.status, "converted-with-warnings"); + assert.deepEqual(warningCodes(result), ["ease-shim-divergence"]); + assert.equal(result.html, fixture("eases.after.html")); + }); + + it("converts repeat and yoyo to loop and alternate", () => { + const result = transformHtml(fixture("repeat-yoyo.before.html")); + + assert.equal(result.classification.status, "converted"); + assert.equal(result.html, fixture("repeat-yoyo.after.html")); + }); + + it("classifies motionPath as manual and leaves the file unchanged", () => { + const before = fixture("motionpath-manual.before.html"); + const result = transformHtml(before); + + assert.equal(result.classification.status, "manual"); + assert.deepEqual(reasonCodes(result), ["motionPath"]); + assert.equal(result.changed, false); + assert.equal(result.html, before); + }); + + it("classifies a mixed convertible and SplitText script as manual as a whole", () => { + const before = fixture("splittext-manual.before.html"); + const result = transformHtml(before); + + assert.equal(result.classification.status, "manual"); + assert.deepEqual(reasonCodes(result), ["splitText"]); + assert.equal(result.changed, false); + assert.equal(result.html, before); + }); + + it("is idempotent on already-converted anime code", () => { + const html = fixture("simple-to.after.html"); + const result = transformHtml(html); + + assert.equal(result.classification.status, "converted"); + assert.equal(result.changed, false); + assert.equal(result.html, html); + }); +}); diff --git a/scripts/gsap-to-anime/html.ts b/scripts/gsap-to-anime/html.ts new file mode 100644 index 0000000000..db058dc098 --- /dev/null +++ b/scripts/gsap-to-anime/html.ts @@ -0,0 +1,39 @@ +import type { ScriptBlock } from "./types.ts"; + +const INLINE_SCRIPT_RE = /]*\bsrc\s*=)[^>]*>([\s\S]*?)<\/script>/gi; + +export function findGsapScriptBlock(html: string): ScriptBlock | null { + let best: ScriptBlock | null = null; + let bestScore = -1; + for (const match of html.matchAll(INLINE_SCRIPT_RE)) { + const fullMatch = match[0]; + const scriptText = match[1] ?? ""; + const matchIndex = match.index; + if (matchIndex === undefined) continue; + if (!scriptText.includes("gsap.timeline")) continue; + const openTagEnd = fullMatch.indexOf(">") + 1; + const block = { + scriptText, + start: matchIndex + openTagEnd, + end: matchIndex + fullMatch.length - "".length, + }; + const score = timelineMethodScore(scriptText); + if (score > bestScore) { + best = block; + bestScore = score; + } + } + return best; +} + +export function replaceScriptBlock(html: string, block: ScriptBlock, scriptText: string): string { + return `${html.slice(0, block.start)}${scriptText}${html.slice(block.end)}`; +} + +function timelineMethodScore(scriptText: string): number { + let score = 0; + for (const match of scriptText.matchAll(/\.(?:set|to|from|fromTo)\s*\(/g)) { + if (match[0]) score += 1; + } + return score; +} diff --git a/scripts/gsap-to-anime/index.ts b/scripts/gsap-to-anime/index.ts new file mode 100644 index 0000000000..ecd9e0810f --- /dev/null +++ b/scripts/gsap-to-anime/index.ts @@ -0,0 +1,56 @@ +import { parseGsapScriptAcorn } from "@hyperframes/parsers/gsap-parser-acorn"; +import { classifyGsapScript } from "./classifier.ts"; +import { convertGsapScript } from "./converter.ts"; +import { findGsapScriptBlock, replaceScriptBlock } from "./html.ts"; +import type { TransformResult } from "./types.ts"; + +export type { + ClassificationNote, + CodemodClassification, + CodemodStatus, + RegistryFileReport, + RegistryItemReport, + RegistryReport, + TransformResult, +} from "./types.ts"; +export { classifyGsapScript } from "./classifier.ts"; +export { scanRegistryTree, renderMarkdownReport, assertTotalsReconcile } from "./report.ts"; + +export function transformHtml(html: string): TransformResult { + const block = findGsapScriptBlock(html); + if (block === null) { + return { + html, + changed: false, + classification: { status: "converted", reasons: [], warnings: [] }, + }; + } + + const parsed = parseGsapScriptAcorn(block.scriptText); + const classification = classifyGsapScript(block.scriptText, parsed); + if (classification.status === "manual") { + return { html, changed: false, classification }; + } + + const script = preserveClosingIndent( + convertGsapScript(block.scriptText, parsed), + block.scriptText, + ); + const nextHtml = replaceScriptBlock(html, block, script); + return { html: nextHtml, changed: nextHtml !== html, classification }; +} + +function preserveClosingIndent(script: string, previousScript: string): string { + const codeIndent = /\n([ \t]*)\S/.exec(previousScript)?.[1] ?? ""; + const closingIndent = /\n([ \t]*)$/.exec(previousScript)?.[1] ?? ""; + const lines = trimCommonIndent(script.trim().split("\n")); + return `\n${lines.map((line) => `${codeIndent}${line}`).join("\n")}\n${closingIndent}`; +} + +function trimCommonIndent(lines: string[]): string[] { + const indents = lines + .filter((line) => line.trim().length > 0) + .map((line) => line.match(/^[ \t]*/)?.[0].length ?? 0); + const common = indents.length > 0 ? Math.min(...indents) : 0; + return common > 0 ? lines.map((line) => line.slice(common)) : lines; +} diff --git a/scripts/gsap-to-anime/notes.ts b/scripts/gsap-to-anime/notes.ts new file mode 100644 index 0000000000..b5855584d6 --- /dev/null +++ b/scripts/gsap-to-anime/notes.ts @@ -0,0 +1,27 @@ +import type { ClassificationNote, CodemodStatus } from "./types.ts"; + +export function note(code: string, message = code): ClassificationNote { + return { code, message }; +} + +export function addUniqueNote(notes: ClassificationNote[], next: ClassificationNote): void { + if (notes.some((note) => note.code === next.code)) return; + notes.push(next); +} + +export function statusFor( + reasons: ClassificationNote[], + warnings: ClassificationNote[], +): CodemodStatus { + if (reasons.length > 0) return "manual"; + if (warnings.length > 0) return "converted-with-warnings"; + return "converted"; +} + +export function mergeNotes(groups: ClassificationNote[][]): ClassificationNote[] { + const merged: ClassificationNote[] = []; + for (const group of groups) { + for (const entry of group) addUniqueNote(merged, entry); + } + return merged; +} diff --git a/scripts/gsap-to-anime/registration.ts b/scripts/gsap-to-anime/registration.ts new file mode 100644 index 0000000000..ccb501a6cd --- /dev/null +++ b/scripts/gsap-to-anime/registration.ts @@ -0,0 +1,46 @@ +import type { RegistrationInfo } from "./types.ts"; + +function escapeRegExp(value: string): string { + return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); +} + +function stripComments(source: string): string { + return source.replace(/\/\*[\s\S]*?\*\//g, "").replace(/(^|\s)\/\/[^\n\r]*/g, "$1"); +} + +function removeRegistrySetup(source: string): string { + return source + .replace(/window\.__timelines\s*=\s*window\.__timelines\s*\|\|\s*\{\}\s*;?/g, "") + .replace(/window\.__timelines\s*=\s*window\.__timelines\s*\|\|\s*\[\]\s*;?/g, "") + .replace( + /if\s*\(\s*!window\.__timelines\s*\)\s*\{\s*window\.__timelines\s*=\s*\{\}\s*;?\s*\}/g, + "", + ); +} + +export function parseRegistrationPostamble( + postamble: string, + timelineVar: string, +): RegistrationInfo | null { + const trimmed = stripComments(postamble).trim(); + if (trimmed === "") return { id: "main" }; + + const withoutSetup = removeRegistrySetup(trimmed); + const escapedVar = escapeRegExp(timelineVar); + const assignment = new RegExp( + `window\\.__timelines\\s*\\[\\s*["']([^"']+)["']\\s*\\]\\s*=\\s*${escapedVar}\\s*;?`, + "g", + ); + const push = new RegExp(`window\\.__timelines\\.push\\s*\\(\\s*${escapedVar}\\s*\\)\\s*;?`, "g"); + let id = "main"; + let consumed = withoutSetup.replace(assignment, (_match, key: string) => { + id = key; + return ""; + }); + consumed = consumed.replace(push, ""); + return consumed.trim() === "" ? { id } : null; +} + +export function stripLegacyRegistrySetup(preamble: string): string { + return removeRegistrySetup(preamble); +} diff --git a/scripts/gsap-to-anime/report.ts b/scripts/gsap-to-anime/report.ts new file mode 100644 index 0000000000..b3399f380d --- /dev/null +++ b/scripts/gsap-to-anime/report.ts @@ -0,0 +1,219 @@ +import { existsSync, readdirSync, readFileSync } from "node:fs"; +import { join, relative } from "node:path"; +import { transformHtml } from "./index.ts"; +import { mergeNotes } from "./notes.ts"; +import type { + CodemodStatus, + RegistryFileReport, + RegistryItemReport, + RegistryReport, +} from "./types.ts"; + +interface RegistryFileEntry { + path: string; + type: string; +} + +interface RegistryManifest { + name: string; + type: string; + files: RegistryFileEntry[]; +} + +const STATUSES: CodemodStatus[] = ["converted", "converted-with-warnings", "manual"]; + +export function scanRegistryTree(root: string): RegistryReport { + const items = discoverRegistryItems(root).map((item) => scanRegistryItem(root, item)); + const totals = createTotals(); + for (const item of items) totals[item.status] += 1; + return { root, totals, items }; +} + +export function renderMarkdownReport(report: RegistryReport): string { + const manualBreakdown = manualReasonCounts(report); + const lines = [ + "# GSAP to anime.js dry-run report", + "", + "## Totals", + "", + `- converted: ${report.totals.converted}`, + `- converted-with-warnings: ${report.totals["converted-with-warnings"]}`, + `- manual: ${report.totals.manual}`, + `- total: ${report.items.length}`, + "", + "## Manual reason breakdown", + "", + ...renderReasonLines(manualBreakdown), + "", + "## Items", + "", + ...report.items.map(renderItemLine), + "", + ]; + return `${lines.join("\n")}`; +} + +function discoverRegistryItems(root: string): RegistryManifest[] { + const manifests: RegistryManifest[] = []; + for (const kind of ["blocks", "components", "examples"]) { + const dir = join(root, kind); + if (!existsSync(dir)) continue; + for (const entry of readdirSync(dir, { withFileTypes: true })) { + if (!entry.isDirectory()) continue; + const itemDir = join(dir, entry.name); + const manifest = readManifest(join(itemDir, "registry-item.json")); + manifests.push(manifest ?? fallbackManifest(kind, entry.name, itemDir)); + } + } + return manifests.sort((a, b) => a.type.localeCompare(b.type) || a.name.localeCompare(b.name)); +} + +function readManifest(path: string): RegistryManifest | null { + if (!existsSync(path)) return null; + const raw: unknown = JSON.parse(readFileSync(path, "utf-8")); + if (!isRecord(raw)) return null; + const name = typeof raw.name === "string" ? raw.name : null; + const type = typeof raw.type === "string" ? raw.type : null; + const files = Array.isArray(raw.files) ? readFiles(raw.files) : []; + return name && type ? { name, type, files } : null; +} + +function fallbackManifest(kind: string, name: string, itemDir: string): RegistryManifest { + return { + name, + type: `hyperframes:${kind.slice(0, -1)}`, + files: discoverHtmlFiles(itemDir, itemDir).map((path) => ({ + path, + type: "hyperframes:composition", + })), + }; +} + +function discoverHtmlFiles(root: string, dir: string): string[] { + const files: string[] = []; + for (const entry of readdirSync(dir, { withFileTypes: true })) { + const path = join(dir, entry.name); + if (entry.isDirectory()) { + files.push(...discoverHtmlFiles(root, path)); + } else if (entry.isFile() && entry.name.endsWith(".html")) { + files.push(relative(root, path)); + } + } + return files.sort((a, b) => a.localeCompare(b)); +} + +function readFiles(files: unknown[]): RegistryFileEntry[] { + const entries: RegistryFileEntry[] = []; + for (const file of files) { + if (!isRecord(file)) continue; + if (typeof file.path !== "string" || typeof file.type !== "string") continue; + entries.push({ path: file.path, type: file.type }); + } + return entries; +} + +function scanRegistryItem(root: string, manifest: RegistryManifest): RegistryItemReport { + const kindDir = kindDirectory(manifest.type); + const itemDir = join(root, kindDir, manifest.name); + const files = compositionFiles(itemDir, manifest) + .map((file) => scanRegistryFile(root, itemDir, file)) + .sort((a, b) => a.path.localeCompare(b.path)); + const status = combineStatus(files); + return { + kind: kindDir.slice(0, -1), + name: manifest.name, + path: relative(root, itemDir), + status, + changed: files.some((file) => file.changed), + reasons: mergeNotes(files.map((file) => file.reasons)), + warnings: mergeNotes(files.map((file) => file.warnings)), + files, + }; +} + +function compositionFiles(itemDir: string, manifest: RegistryManifest): RegistryFileEntry[] { + const htmlFiles = manifest.files.filter( + (file) => + file.path.endsWith(".html") && + existsSync(join(itemDir, file.path)) && + (file.type === "hyperframes:composition" || file.type === "hyperframes:snippet"), + ); + if (htmlFiles.length > 0) return htmlFiles; + const present = manifest.files.filter( + (file) => file.path.endsWith(".html") && existsSync(join(itemDir, file.path)), + ); + if (present.length > 0) return present; + return readdirSync(itemDir, { withFileTypes: true }) + .filter((entry) => entry.isFile() && entry.name.endsWith(".html")) + .map((entry) => ({ path: entry.name, type: "hyperframes:composition" })); +} + +function scanRegistryFile( + root: string, + itemDir: string, + file: RegistryFileEntry, +): RegistryFileReport { + const path = join(itemDir, file.path); + const result = transformHtml(readFileSync(path, "utf-8")); + return { + path: relative(root, path), + status: result.classification.status, + changed: result.changed, + reasons: result.classification.reasons, + warnings: result.classification.warnings, + }; +} + +function combineStatus(files: RegistryFileReport[]): CodemodStatus { + if (files.some((file) => file.status === "manual")) return "manual"; + if (files.some((file) => file.status === "converted-with-warnings")) + return "converted-with-warnings"; + return "converted"; +} + +function kindDirectory(type: string): string { + if (type.endsWith(":component")) return "components"; + if (type.endsWith(":example")) return "examples"; + return "blocks"; +} + +function createTotals(): Record { + return { + converted: 0, + "converted-with-warnings": 0, + manual: 0, + }; +} + +function manualReasonCounts(report: RegistryReport): Map { + const counts = new Map(); + for (const item of report.items) { + if (item.status !== "manual") continue; + for (const reason of item.reasons) counts.set(reason.code, (counts.get(reason.code) ?? 0) + 1); + } + return new Map([...counts.entries()].sort((a, b) => b[1] - a[1] || a[0].localeCompare(b[0]))); +} + +function renderReasonLines(counts: Map): string[] { + if (counts.size === 0) return ["- none"]; + return [...counts.entries()].map(([reason, count]) => `- ${reason}: ${count}`); +} + +function renderItemLine(item: RegistryItemReport): string { + const notes = + item.reasons.length > 0 ? ` (${item.reasons.map((reason) => reason.code).join(", ")})` : ""; + return `- ${item.status}: ${item.path}${notes}`; +} + +function isRecord(value: unknown): value is Record { + return typeof value === "object" && value !== null; +} + +export function assertTotalsReconcile(report: RegistryReport): void { + const total = STATUSES.reduce((sum, status) => sum + report.totals[status], 0); + if (total !== report.items.length) { + throw new Error( + `Dry-run totals do not reconcile: ${total} totals for ${report.items.length} items`, + ); + } +} diff --git a/scripts/gsap-to-anime/types.ts b/scripts/gsap-to-anime/types.ts new file mode 100644 index 0000000000..f428e19dae --- /dev/null +++ b/scripts/gsap-to-anime/types.ts @@ -0,0 +1,56 @@ +import type { ParsedGsap } from "@hyperframes/parsers"; + +export type CodemodStatus = "converted" | "converted-with-warnings" | "manual"; + +export interface ClassificationNote { + code: string; + message: string; +} + +export interface CodemodClassification { + status: CodemodStatus; + reasons: ClassificationNote[]; + warnings: ClassificationNote[]; + parsed?: ParsedGsap; +} + +export interface TransformResult { + html: string; + changed: boolean; + classification: CodemodClassification; +} + +export interface ScriptBlock { + scriptText: string; + start: number; + end: number; +} + +export interface RegistrationInfo { + id: string; +} + +export interface RegistryFileReport { + path: string; + status: CodemodStatus; + changed: boolean; + reasons: ClassificationNote[]; + warnings: ClassificationNote[]; +} + +export interface RegistryItemReport { + kind: string; + name: string; + path: string; + status: CodemodStatus; + changed: boolean; + reasons: ClassificationNote[]; + warnings: ClassificationNote[]; + files: RegistryFileReport[]; +} + +export interface RegistryReport { + root: string; + totals: Record; + items: RegistryItemReport[]; +} From 82f6d13b4306cb027252d35a41706685963818b0 Mon Sep 17 00:00:00 2001 From: Miguel Angel Simon Sierra Date: Wed, 8 Jul 2026 17:27:31 -0400 Subject: [PATCH 2/2] fix(scripts): reduce gsap-to-anime false manual classifications --- .../__fixtures__/iife-postamble.after.html | 13 + .../__fixtures__/iife-postamble.before.html | 14 + .../__fixtures__/onupdate-manual.before.html | 23 + .../passthrough-properties.after.html | 13 + .../passthrough-properties.before.html | 14 + .../__fixtures__/unrelated-add.after.html | 14 + .../__fixtures__/unrelated-add.before.html | 15 + .../unrelated-callback-config.after.html | 12 + .../unrelated-callback-config.before.html | 13 + scripts/gsap-to-anime/attr.ts | 117 ++ scripts/gsap-to-anime/classifier.ts | 134 +- scripts/gsap-to-anime/converter.ts | 73 +- scripts/gsap-to-anime/dry-run-report.json | 1634 ++++------------- scripts/gsap-to-anime/dry-run-report.md | 223 +-- scripts/gsap-to-anime/gsap-to-anime.test.ts | 39 + scripts/gsap-to-anime/registration.ts | 8 +- scripts/gsap-to-anime/types.ts | 1 + 17 files changed, 951 insertions(+), 1409 deletions(-) create mode 100644 scripts/gsap-to-anime/__fixtures__/iife-postamble.after.html create mode 100644 scripts/gsap-to-anime/__fixtures__/iife-postamble.before.html create mode 100644 scripts/gsap-to-anime/__fixtures__/onupdate-manual.before.html create mode 100644 scripts/gsap-to-anime/__fixtures__/passthrough-properties.after.html create mode 100644 scripts/gsap-to-anime/__fixtures__/passthrough-properties.before.html create mode 100644 scripts/gsap-to-anime/__fixtures__/unrelated-add.after.html create mode 100644 scripts/gsap-to-anime/__fixtures__/unrelated-add.before.html create mode 100644 scripts/gsap-to-anime/__fixtures__/unrelated-callback-config.after.html create mode 100644 scripts/gsap-to-anime/__fixtures__/unrelated-callback-config.before.html create mode 100644 scripts/gsap-to-anime/attr.ts diff --git a/scripts/gsap-to-anime/__fixtures__/iife-postamble.after.html b/scripts/gsap-to-anime/__fixtures__/iife-postamble.after.html new file mode 100644 index 0000000000..83048f344f --- /dev/null +++ b/scripts/gsap-to-anime/__fixtures__/iife-postamble.after.html @@ -0,0 +1,13 @@ + + + +
+ + + diff --git a/scripts/gsap-to-anime/__fixtures__/iife-postamble.before.html b/scripts/gsap-to-anime/__fixtures__/iife-postamble.before.html new file mode 100644 index 0000000000..ab86786273 --- /dev/null +++ b/scripts/gsap-to-anime/__fixtures__/iife-postamble.before.html @@ -0,0 +1,14 @@ + + + +
+ + + diff --git a/scripts/gsap-to-anime/__fixtures__/onupdate-manual.before.html b/scripts/gsap-to-anime/__fixtures__/onupdate-manual.before.html new file mode 100644 index 0000000000..5f776f0a86 --- /dev/null +++ b/scripts/gsap-to-anime/__fixtures__/onupdate-manual.before.html @@ -0,0 +1,23 @@ + + + +
+ + + diff --git a/scripts/gsap-to-anime/__fixtures__/passthrough-properties.after.html b/scripts/gsap-to-anime/__fixtures__/passthrough-properties.after.html new file mode 100644 index 0000000000..20059c7e48 --- /dev/null +++ b/scripts/gsap-to-anime/__fixtures__/passthrough-properties.after.html @@ -0,0 +1,13 @@ + + + + + + + + + diff --git a/scripts/gsap-to-anime/__fixtures__/passthrough-properties.before.html b/scripts/gsap-to-anime/__fixtures__/passthrough-properties.before.html new file mode 100644 index 0000000000..59483ea50c --- /dev/null +++ b/scripts/gsap-to-anime/__fixtures__/passthrough-properties.before.html @@ -0,0 +1,14 @@ + + + + + + + + + diff --git a/scripts/gsap-to-anime/__fixtures__/unrelated-add.after.html b/scripts/gsap-to-anime/__fixtures__/unrelated-add.after.html new file mode 100644 index 0000000000..8e076f3a88 --- /dev/null +++ b/scripts/gsap-to-anime/__fixtures__/unrelated-add.after.html @@ -0,0 +1,14 @@ + + + +
+ + + diff --git a/scripts/gsap-to-anime/__fixtures__/unrelated-add.before.html b/scripts/gsap-to-anime/__fixtures__/unrelated-add.before.html new file mode 100644 index 0000000000..7237e99d6e --- /dev/null +++ b/scripts/gsap-to-anime/__fixtures__/unrelated-add.before.html @@ -0,0 +1,15 @@ + + + +
+ + + diff --git a/scripts/gsap-to-anime/__fixtures__/unrelated-callback-config.after.html b/scripts/gsap-to-anime/__fixtures__/unrelated-callback-config.after.html new file mode 100644 index 0000000000..16c5a1efb9 --- /dev/null +++ b/scripts/gsap-to-anime/__fixtures__/unrelated-callback-config.after.html @@ -0,0 +1,12 @@ + + + +
+ + + diff --git a/scripts/gsap-to-anime/__fixtures__/unrelated-callback-config.before.html b/scripts/gsap-to-anime/__fixtures__/unrelated-callback-config.before.html new file mode 100644 index 0000000000..ff4ec82c57 --- /dev/null +++ b/scripts/gsap-to-anime/__fixtures__/unrelated-callback-config.before.html @@ -0,0 +1,13 @@ + + + +
+ + + diff --git a/scripts/gsap-to-anime/attr.ts b/scripts/gsap-to-anime/attr.ts new file mode 100644 index 0000000000..1640928a4f --- /dev/null +++ b/scripts/gsap-to-anime/attr.ts @@ -0,0 +1,117 @@ +export interface AttrEntry { + key: string; + value: number | string; +} + +export function parseAttrWrapper(value: unknown): AttrEntry[] | null { + const raw = rawText(value); + if (!raw?.startsWith("{") || !raw.endsWith("}")) return null; + const body = raw.slice(1, -1).trim(); + if (body.length === 0) return []; + + const entries: AttrEntry[] = []; + for (const part of splitTopLevel(body, ",")) { + const property = splitProperty(part); + if (property === null) return null; + const key = parseKey(property.key.trim()); + const parsedValue = parseValue(property.value.trim()); + if (key === null || parsedValue === null) return null; + entries.push({ key, value: parsedValue }); + } + return entries; +} + +function splitProperty(source: string): { key: string; value: string } | null { + const colon = findTopLevelColon(source); + if (colon === null) return null; + return { + key: source.slice(0, colon), + value: source.slice(colon + 1), + }; +} + +function splitTopLevel(source: string, separator: string): string[] { + const parts: string[] = []; + let start = 0; + let depth = 0; + let quote: string | null = null; + let escaped = false; + + for (let index = 0; index < source.length; index += 1) { + const char = source[index] ?? ""; + if (quote !== null) { + if (escaped) escaped = false; + else if (char === "\\") escaped = true; + else if (char === quote) quote = null; + continue; + } + if (char === "'" || char === '"' || char === "`") { + quote = char; + continue; + } + if (char === "{" || char === "[" || char === "(") depth += 1; + if (char === "}" || char === "]" || char === ")") depth -= 1; + if (char === separator && depth === 0) { + parts.push(source.slice(start, index).trim()); + start = index + 1; + } + } + parts.push(source.slice(start).trim()); + return parts.filter((part) => part.length > 0); +} + +function findTopLevelColon(source: string): number | null { + let depth = 0; + let quote: string | null = null; + let escaped = false; + + for (let index = 0; index < source.length; index += 1) { + const char = source[index] ?? ""; + if (quote !== null) { + if (escaped) escaped = false; + else if (char === "\\") escaped = true; + else if (char === quote) quote = null; + continue; + } + if (char === "'" || char === '"' || char === "`") { + quote = char; + continue; + } + if (char === "{" || char === "[" || char === "(") depth += 1; + if (char === "}" || char === "]" || char === ")") depth -= 1; + if (char === ":" && depth === 0) return index; + } + return null; +} + +function parseKey(value: string): string | null { + if (/^[A-Za-z_$][\w$]*$/.test(value)) return value; + return parseStringLiteral(value); +} + +function parseValue(value: string): number | string | null { + const numeric = Number(value); + if (value.length > 0 && Number.isFinite(numeric)) return numeric; + return parseStringLiteral(value); +} + +function parseStringLiteral(value: string): string | null { + const quote = value[0]; + if ((quote !== "'" && quote !== '"') || value[value.length - 1] !== quote) return null; + if (quote === '"') { + try { + const parsed: unknown = JSON.parse(value); + return typeof parsed === "string" ? parsed : null; + } catch { + return null; + } + } + return value.slice(1, -1).replace(/\\'/g, "'").replace(/\\\\/g, "\\"); +} + +function rawText(value: unknown): string | null { + if (typeof value === "string") + return value.startsWith("__raw:") ? value.slice(6).trim() : value.trim(); + if (typeof value === "number" || typeof value === "boolean") return String(value); + return null; +} diff --git a/scripts/gsap-to-anime/classifier.ts b/scripts/gsap-to-anime/classifier.ts index e900baddd7..67c6f83d49 100644 --- a/scripts/gsap-to-anime/classifier.ts +++ b/scripts/gsap-to-anime/classifier.ts @@ -1,11 +1,10 @@ import { resolveEase } from "@hyperframes/core"; import type { GsapAnimation, ParsedGsap } from "@hyperframes/parsers"; -import { SUPPORTED_PROPS } from "@hyperframes/parsers/gsap-constants"; +import { parseAttrWrapper } from "./attr.ts"; import { addUniqueNote, note, statusFor } from "./notes.ts"; import { parseRegistrationPostamble } from "./registration.ts"; import type { ClassificationNote, CodemodClassification } from "./types.ts"; -const SUPPORTED_PROP_SET = new Set(SUPPORTED_PROPS); const ALLOWED_EXTRAS = new Set(["stagger", "repeat", "yoyo"]); const PLUGIN_NAMES = [ "ScrollTrigger", @@ -22,7 +21,7 @@ export function classifyGsapScript(script: string, parsed: ParsedGsap): CodemodC const reasons: ClassificationNote[] = []; const warnings: ClassificationNote[] = []; - addRawSourceReasons(script, reasons); + addRawSourceReasons(script, parsed, reasons); addParsedReasons(parsed, reasons); addAnimationReasons(parsed.animations, reasons, warnings); if (parseRegistrationPostamble(parsed.postamble, parsed.timelineVar) === null) { @@ -40,7 +39,11 @@ export function classifyGsapScript(script: string, parsed: ParsedGsap): CodemodC }; } -function addRawSourceReasons(script: string, reasons: ClassificationNote[]): void { +function addRawSourceReasons( + script: string, + parsed: ParsedGsap, + reasons: ClassificationNote[], +): void { if (/SplitText/i.test(script) || hasHandRolledTextSplit(script)) { addUniqueNote( reasons, @@ -59,19 +62,20 @@ function addRawSourceReasons(script: string, reasons: ClassificationNote[]): voi if (hasAdvancedGsapUtils(script)) { addUniqueNote(reasons, note("gsap-utils-advanced", "gsap.utils usage beyond toArray")); } - if (/(\.call|\.add|\.addPause)\s*\(/.test(script)) { + if (hasTimelineControlCall(script, parsed.timelineVar)) { addUniqueNote( reasons, note("computed-timeline", "timeline call/add/addPause is not rewritten safely"), ); } - if (/\b(onComplete|onStart|onUpdate|onRepeat|onReverseComplete)\s*:/.test(script)) { + const tweenBodies = gsapTweenArgumentSources(script, parsed.timelineVar); + if (tweenBodies.some(hasTweenCallback)) { addUniqueNote( reasons, note("computed-timeline", "timeline callback properties need manual review"), ); } - if (/\bdelay\s*:/.test(script)) { + if (tweenBodies.some((body) => /\bdelay\s*:/.test(body))) { addUniqueNote( reasons, note("computed-timeline", "GSAP delay is not represented in parsed placement data"), @@ -80,6 +84,93 @@ function addRawSourceReasons(script: string, reasons: ClassificationNote[]): voi addPluginReasons(script, reasons); } +function hasTimelineControlCall(script: string, timelineVar: string): boolean { + const escapedVar = escapeRegExp(timelineVar); + return new RegExp(`\\b${escapedVar}\\s*\\.\\s*(?:call|add|addPause)\\s*\\(`).test(script); +} + +function gsapTweenArgumentSources(script: string, timelineVar: string): string[] { + const escapedVar = escapeRegExp(timelineVar); + const calls = new RegExp( + `(?:\\b${escapedVar}\\s*\\.\\s*(?:fromTo|from|to|set)|\\bgsap\\s*\\.\\s*set)\\s*\\(`, + "g", + ); + const bodies: string[] = []; + for (const match of script.matchAll(calls)) { + const start = match.index ?? 0; + const open = script.indexOf("(", start); + const close = findMatchingParen(script, open); + if (close !== null) bodies.push(script.slice(open + 1, close)); + } + return bodies; +} + +function findMatchingParen(source: string, open: number): number | null { + if (open < 0) return null; + let depth = 0; + let state: "code" | "lineComment" | "blockComment" | "string" = "code"; + let quote = ""; + let escaped = false; + + for (let index = open; index < source.length; index += 1) { + const char = source[index] ?? ""; + const next = source[index + 1] ?? ""; + const stateResult = updateScanState(state, char, next, quote, escaped); + state = stateResult.state; + quote = stateResult.quote; + escaped = stateResult.escaped; + if (stateResult.skipNext) index += 1; + if (state !== "code") continue; + if (char === "(") depth += 1; + if (char === ")") { + depth -= 1; + if (depth === 0) return index; + } + } + return null; +} + +function updateScanState( + state: "code" | "lineComment" | "blockComment" | "string", + char: string, + next: string, + quote: string, + escaped: boolean, +): { + state: "code" | "lineComment" | "blockComment" | "string"; + quote: string; + escaped: boolean; + skipNext: boolean; +} { + if (state === "lineComment") { + return char === "\n" || char === "\r" + ? { state: "code", quote, escaped: false, skipNext: false } + : { state, quote, escaped: false, skipNext: false }; + } + if (state === "blockComment") { + return char === "*" && next === "/" + ? { state: "code", quote, escaped: false, skipNext: true } + : { state, quote, escaped: false, skipNext: false }; + } + if (state === "string") { + if (escaped) return { state, quote, escaped: false, skipNext: false }; + if (char === "\\") return { state, quote, escaped: true, skipNext: false }; + if (char === quote) return { state: "code", quote: "", escaped: false, skipNext: false }; + return { state, quote, escaped: false, skipNext: false }; + } + if (char === "/" && next === "/") + return { state: "lineComment", quote, escaped: false, skipNext: true }; + if (char === "/" && next === "*") + return { state: "blockComment", quote, escaped: false, skipNext: true }; + if (char === "'" || char === '"' || char === "`") + return { state: "string", quote: char, escaped: false, skipNext: false }; + return { state, quote, escaped: false, skipNext: false }; +} + +function hasTweenCallback(source: string): boolean { + return /\b(onComplete|onStart|onUpdate|onRepeat|onReverseComplete)\s*(?::|\()/.test(source); +} + function hasHandRolledTextSplit(script: string): boolean { return ( /\.split\s*\(\s*["'](?:\s?|)["']\s*\)/.test(script) && @@ -146,6 +237,12 @@ function addAnimationReasons( if (animation.provenance && animation.provenance.kind !== "literal") { addUniqueNote(reasons, note("computed-timeline", "computed timeline construction")); } + if (isNonSelectorTarget(animation.targetSelector)) { + addUniqueNote( + reasons, + note("non-selector-target", "tween target is not a CSS selector string"), + ); + } addPropertyReasons(animation, reasons, warnings); addExtraReasons(animation, reasons, warnings); addEaseReasons(animation, reasons, warnings); @@ -161,9 +258,9 @@ function addPropertyReasons( reasons: ClassificationNote[], warnings: ClassificationNote[], ): void { - for (const key of propertyKeys(animation)) { - if (!SUPPORTED_PROP_SET.has(key)) { - addUniqueNote(reasons, note("unsupported-property", `Unsupported GSAP property: ${key}`)); + for (const [key, value] of propertyEntries(animation)) { + if (key === "attr" && parseAttrWrapper(value) === null) { + addUniqueNote(reasons, note("attr-wrapper", "GSAP attr wrapper is not statically literal")); } if (key === "autoAlpha") { addUniqueNote( @@ -180,10 +277,15 @@ function addPropertyReasons( } } -function propertyKeys(animation: GsapAnimation): string[] { - const keys = new Set(Object.keys(animation.properties)); - for (const key of Object.keys(animation.fromProperties ?? {})) keys.add(key); - return [...keys]; +function propertyEntries(animation: GsapAnimation): Array<[string, number | string]> { + return [ + ...Object.entries(animation.properties), + ...Object.entries(animation.fromProperties ?? {}), + ]; +} + +function isNonSelectorTarget(selector: string): boolean { + return selector === "dwell/hold" || selector.startsWith("proxy "); } function addExtraReasons( @@ -256,3 +358,7 @@ function rawText(value: unknown): string | null { if (typeof value === "number" || typeof value === "boolean") return String(value); return null; } + +function escapeRegExp(value: string): string { + return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); +} diff --git a/scripts/gsap-to-anime/converter.ts b/scripts/gsap-to-anime/converter.ts index 431b78e4e8..0cf7078818 100644 --- a/scripts/gsap-to-anime/converter.ts +++ b/scripts/gsap-to-anime/converter.ts @@ -1,6 +1,7 @@ import { resolveEase } from "@hyperframes/core"; import type { GsapAnimation, ParsedGsap } from "@hyperframes/parsers"; import { extractGsapLabels } from "@hyperframes/parsers/gsap-parser-acorn"; +import { parseAttrWrapper, type AttrEntry } from "./attr.ts"; import { parseRegistrationPostamble, stripLegacyRegistrySetup } from "./registration.ts"; interface AnimeProperty { @@ -16,18 +17,27 @@ const PROP_RENAMES = new Map([ ["rotationX", "rotateX"], ["rotationY", "rotateY"], ["rotationZ", "rotateZ"], - // anime.js v4 animates CSS perspective directly; GSAP's transformPerspective - // is folded into that CSS property and separately classified with a warning. + // anime.js v4 uses transformOrigin and perspective unchanged. GSAP's + // transformPerspective alias is folded into CSS perspective and warned on. ["transformPerspective", "perspective"], ]); export function convertGsapScript(script: string, parsed: ParsedGsap): string { const registration = parseRegistrationPostamble(parsed.postamble, parsed.timelineVar); const registrationId = registration?.id ?? "main"; - const lines = [ - convertPreamble(parsed.preamble, parsed.timelineVar), - ...parsed.animations.map((animation) => convertAnimation(animation, parsed.timelineVar)), + const rawPreamble = convertPreamble(parsed.preamble, parsed.timelineVar); + const bodyIndent = wrapperBodyIndent(rawPreamble); + const preamble = bodyIndent ? indentPreambleBody(rawPreamble, bodyIndent) : rawPreamble; + const registrationCall = `${indentBlock( renderRegistration(registrationId, parsed.timelineVar, extractGsapLabels(script)), + bodyIndent, + )}${renderTrailingCloser(registration?.trailing ?? "")}`; + const lines = [ + preamble, + ...parsed.animations.map((animation) => + indentBlock(convertAnimation(animation, parsed.timelineVar), bodyIndent), + ), + registrationCall, ]; return `\n${lines.filter((line) => line.length > 0).join("\n")}\n`; } @@ -55,6 +65,26 @@ function rewriteGsapToArray(source: string): string { ); } +function wrapperBodyIndent(preamble: string): string { + const firstLine = preamble.split("\n").find((line) => line.trim().length > 0); + return firstLine?.trimEnd().endsWith("{") ? " " : ""; +} + +function indentPreambleBody(preamble: string, indent: string): string { + const lines = preamble.split("\n"); + return lines + .map((line, index) => (index === 0 || line.trim().length === 0 ? line : `${indent}${line}`)) + .join("\n"); +} + +function indentBlock(block: string, indent: string): string { + if (indent.length === 0) return block; + return block + .split("\n") + .map((line) => (line.trim().length === 0 ? line : `${indent}${line}`)) + .join("\n"); +} + function convertAnimation(animation: GsapAnimation, timelineVar: string): string { const target = JSON.stringify(animation.targetSelector); const properties = buildProperties(animation); @@ -84,6 +114,10 @@ function pushConvertedProperty( key: string, value: number | string, ): void { + if (key === "attr") { + pushAttrProperties(entries, animation, value); + return; + } if (key === "autoAlpha") { pushAutoAlpha(entries, animation, value); return; @@ -92,6 +126,30 @@ function pushConvertedProperty( entries.push({ key: animeKey, code: renderTweenValue(animation, key, value) }); } +function pushAttrProperties( + entries: AnimeProperty[], + animation: GsapAnimation, + value: number | string, +): void { + const attrs = parseAttrWrapper(value); + if (attrs === null) return; + const fromAttrs = parseAttrWrapper(animation.fromProperties?.attr); + for (const attr of attrs) { + entries.push({ key: attr.key, code: renderAttrTweenValue(animation.method, attr, fromAttrs) }); + } +} + +function renderAttrTweenValue( + method: GsapAnimation["method"], + attr: AttrEntry, + fromAttrs: AttrEntry[] | null, +): string { + const from = fromAttrs?.find((entry) => entry.key === attr.key); + if (method === "fromTo" && from) return serializeArray([from.value, attr.value]); + if (method === "from") return serializeArray([attr.value, identityValue(attr.key)]); + return serializeValue(attr.value); +} + function pushAutoAlpha( entries: AnimeProperty[], animation: GsapAnimation, @@ -229,6 +287,11 @@ function renderRegistration( return `hyperframesAnime.register(${JSON.stringify(id)}, ${timelineVar}, { labels: { ${labelEntries.join(", ")} } });`; } +function renderTrailingCloser(trailing: string): string { + const closer = trailing.trim(); + return closer.length === 0 ? "" : `\n${closer}`; +} + function serializeProperties(properties: AnimeProperty[]): string { return `{ ${properties.map((property) => `${safeKey(property.key)}: ${property.code}`).join(", ")} }`; } diff --git a/scripts/gsap-to-anime/dry-run-report.json b/scripts/gsap-to-anime/dry-run-report.json index 2a2d716004..ff9d18bd5c 100644 --- a/scripts/gsap-to-anime/dry-run-report.json +++ b/scripts/gsap-to-anime/dry-run-report.json @@ -1,9 +1,9 @@ { "root": "/Users/miguel07code/dev/hyperframes-oss/.claude/worktrees/animejs-u9/registry", "totals": { - "converted": 24, - "converted-with-warnings": 0, - "manual": 123 + "converted": 39, + "converted-with-warnings": 3, + "manual": 105 }, "items": [ { @@ -16,14 +16,6 @@ { "code": "computed-timeline", "message": "unresolved selector or keyframes" - }, - { - "code": "unsupported-property", - "message": "Unsupported GSAP property: strokeDashoffset" - }, - { - "code": "unrecognized-postamble", - "message": "postamble is not only timeline registration" } ], "warnings": [ @@ -41,14 +33,6 @@ { "code": "computed-timeline", "message": "unresolved selector or keyframes" - }, - { - "code": "unsupported-property", - "message": "Unsupported GSAP property: strokeDashoffset" - }, - { - "code": "unrecognized-postamble", - "message": "postamble is not only timeline registration" } ], "warnings": [ @@ -72,8 +56,8 @@ "message": "timeline callback properties need manual review" }, { - "code": "unsupported-property", - "message": "Unsupported GSAP property: value" + "code": "non-selector-target", + "message": "tween target is not a CSS selector string" } ], "warnings": [], @@ -88,8 +72,8 @@ "message": "timeline callback properties need manual review" }, { - "code": "unsupported-property", - "message": "Unsupported GSAP property: value" + "code": "non-selector-target", + "message": "tween target is not a CSS selector string" } ], "warnings": [] @@ -159,7 +143,7 @@ "reasons": [ { "code": "computed-timeline", - "message": "timeline callback properties need manual review" + "message": "timeline is not a simple identifier" } ], "warnings": [], @@ -171,7 +155,7 @@ "reasons": [ { "code": "computed-timeline", - "message": "timeline callback properties need manual review" + "message": "timeline is not a simple identifier" } ], "warnings": [] @@ -187,7 +171,7 @@ "reasons": [ { "code": "computed-timeline", - "message": "timeline callback properties need manual review" + "message": "timeline is not a simple identifier" } ], "warnings": [], @@ -199,7 +183,7 @@ "reasons": [ { "code": "computed-timeline", - "message": "timeline callback properties need manual review" + "message": "timeline is not a simple identifier" } ], "warnings": [] @@ -214,12 +198,8 @@ "changed": false, "reasons": [ { - "code": "computed-timeline", - "message": "timeline call/add/addPause is not rewritten safely" - }, - { - "code": "unsupported-property", - "message": "Unsupported GSAP property: rotY" + "code": "non-selector-target", + "message": "tween target is not a CSS selector string" }, { "code": "unrecognized-postamble", @@ -234,12 +214,8 @@ "changed": false, "reasons": [ { - "code": "computed-timeline", - "message": "timeline call/add/addPause is not rewritten safely" - }, - { - "code": "unsupported-property", - "message": "Unsupported GSAP property: rotY" + "code": "non-selector-target", + "message": "tween target is not a CSS selector string" }, { "code": "unrecognized-postamble", @@ -261,6 +237,10 @@ "code": "computed-timeline", "message": "unresolved selector or keyframes" }, + { + "code": "non-selector-target", + "message": "tween target is not a CSS selector string" + }, { "code": "unrecognized-postamble", "message": "postamble is not only timeline registration" @@ -277,6 +257,10 @@ "code": "computed-timeline", "message": "unresolved selector or keyframes" }, + { + "code": "non-selector-target", + "message": "tween target is not a CSS selector string" + }, { "code": "unrecognized-postamble", "message": "postamble is not only timeline registration" @@ -297,6 +281,10 @@ "code": "computed-timeline", "message": "unresolved selector or keyframes" }, + { + "code": "non-selector-target", + "message": "tween target is not a CSS selector string" + }, { "code": "unrecognized-postamble", "message": "postamble is not only timeline registration" @@ -313,6 +301,10 @@ "code": "computed-timeline", "message": "unresolved selector or keyframes" }, + { + "code": "non-selector-target", + "message": "tween target is not a CSS selector string" + }, { "code": "unrecognized-postamble", "message": "postamble is not only timeline registration" @@ -331,7 +323,7 @@ "reasons": [ { "code": "computed-timeline", - "message": "timeline call/add/addPause is not rewritten safely" + "message": "multiple or unsupported timelines" }, { "code": "unrecognized-postamble", @@ -347,7 +339,7 @@ "reasons": [ { "code": "computed-timeline", - "message": "timeline call/add/addPause is not rewritten safely" + "message": "multiple or unsupported timelines" }, { "code": "unrecognized-postamble", @@ -367,11 +359,11 @@ "reasons": [ { "code": "computed-timeline", - "message": "timeline call/add/addPause is not rewritten safely" + "message": "unresolved selector or keyframes" }, { - "code": "unsupported-property", - "message": "Unsupported GSAP property: value" + "code": "non-selector-target", + "message": "tween target is not a CSS selector string" }, { "code": "unrecognized-postamble", @@ -387,11 +379,11 @@ "reasons": [ { "code": "computed-timeline", - "message": "timeline call/add/addPause is not rewritten safely" + "message": "unresolved selector or keyframes" }, { - "code": "unsupported-property", - "message": "Unsupported GSAP property: value" + "code": "non-selector-target", + "message": "tween target is not a CSS selector string" }, { "code": "unrecognized-postamble", @@ -413,6 +405,10 @@ "code": "computed-timeline", "message": "unresolved selector or keyframes" }, + { + "code": "non-selector-target", + "message": "tween target is not a CSS selector string" + }, { "code": "unrecognized-postamble", "message": "postamble is not only timeline registration" @@ -429,6 +425,10 @@ "code": "computed-timeline", "message": "unresolved selector or keyframes" }, + { + "code": "non-selector-target", + "message": "tween target is not a CSS selector string" + }, { "code": "unrecognized-postamble", "message": "postamble is not only timeline registration" @@ -447,11 +447,11 @@ "reasons": [ { "code": "computed-timeline", - "message": "timeline call/add/addPause is not rewritten safely" + "message": "unresolved selector or keyframes" }, { - "code": "unsupported-property", - "message": "Unsupported GSAP property: value" + "code": "non-selector-target", + "message": "tween target is not a CSS selector string" }, { "code": "unrecognized-postamble", @@ -467,11 +467,11 @@ "reasons": [ { "code": "computed-timeline", - "message": "timeline call/add/addPause is not rewritten safely" + "message": "unresolved selector or keyframes" }, { - "code": "unsupported-property", - "message": "Unsupported GSAP property: value" + "code": "non-selector-target", + "message": "tween target is not a CSS selector string" }, { "code": "unrecognized-postamble", @@ -497,10 +497,6 @@ "code": "computed-timeline", "message": "timeline call/add/addPause is not rewritten safely" }, - { - "code": "unsupported-property", - "message": "Unsupported GSAP property: text" - }, { "code": "unrecognized-postamble", "message": "postamble is not only timeline registration" @@ -521,10 +517,6 @@ "code": "computed-timeline", "message": "timeline call/add/addPause is not rewritten safely" }, - { - "code": "unsupported-property", - "message": "Unsupported GSAP property: text" - }, { "code": "unrecognized-postamble", "message": "postamble is not only timeline registration" @@ -549,10 +541,6 @@ "code": "computed-timeline", "message": "timeline call/add/addPause is not rewritten safely" }, - { - "code": "unsupported-property", - "message": "Unsupported GSAP property: text" - }, { "code": "unrecognized-postamble", "message": "postamble is not only timeline registration" @@ -573,10 +561,6 @@ "code": "computed-timeline", "message": "timeline call/add/addPause is not rewritten safely" }, - { - "code": "unsupported-property", - "message": "Unsupported GSAP property: text" - }, { "code": "unrecognized-postamble", "message": "postamble is not only timeline registration" @@ -601,10 +585,6 @@ "code": "computed-timeline", "message": "timeline call/add/addPause is not rewritten safely" }, - { - "code": "unsupported-property", - "message": "Unsupported GSAP property: text" - }, { "code": "unrecognized-postamble", "message": "postamble is not only timeline registration" @@ -625,10 +605,6 @@ "code": "computed-timeline", "message": "timeline call/add/addPause is not rewritten safely" }, - { - "code": "unsupported-property", - "message": "Unsupported GSAP property: text" - }, { "code": "unrecognized-postamble", "message": "postamble is not only timeline registration" @@ -653,10 +629,6 @@ "code": "computed-timeline", "message": "timeline call/add/addPause is not rewritten safely" }, - { - "code": "unsupported-property", - "message": "Unsupported GSAP property: text" - }, { "code": "unrecognized-postamble", "message": "postamble is not only timeline registration" @@ -677,10 +649,6 @@ "code": "computed-timeline", "message": "timeline call/add/addPause is not rewritten safely" }, - { - "code": "unsupported-property", - "message": "Unsupported GSAP property: text" - }, { "code": "unrecognized-postamble", "message": "postamble is not only timeline registration" @@ -705,10 +673,6 @@ "code": "computed-timeline", "message": "timeline call/add/addPause is not rewritten safely" }, - { - "code": "unsupported-property", - "message": "Unsupported GSAP property: text" - }, { "code": "unrecognized-postamble", "message": "postamble is not only timeline registration" @@ -729,10 +693,6 @@ "code": "computed-timeline", "message": "timeline call/add/addPause is not rewritten safely" }, - { - "code": "unsupported-property", - "message": "Unsupported GSAP property: text" - }, { "code": "unrecognized-postamble", "message": "postamble is not only timeline registration" @@ -757,10 +717,6 @@ "code": "computed-timeline", "message": "timeline call/add/addPause is not rewritten safely" }, - { - "code": "unsupported-property", - "message": "Unsupported GSAP property: text" - }, { "code": "unrecognized-postamble", "message": "postamble is not only timeline registration" @@ -781,10 +737,6 @@ "code": "computed-timeline", "message": "timeline call/add/addPause is not rewritten safely" }, - { - "code": "unsupported-property", - "message": "Unsupported GSAP property: text" - }, { "code": "unrecognized-postamble", "message": "postamble is not only timeline registration" @@ -809,10 +761,6 @@ "code": "computed-timeline", "message": "timeline call/add/addPause is not rewritten safely" }, - { - "code": "unsupported-property", - "message": "Unsupported GSAP property: text" - }, { "code": "unrecognized-postamble", "message": "postamble is not only timeline registration" @@ -833,10 +781,6 @@ "code": "computed-timeline", "message": "timeline call/add/addPause is not rewritten safely" }, - { - "code": "unsupported-property", - "message": "Unsupported GSAP property: text" - }, { "code": "unrecognized-postamble", "message": "postamble is not only timeline registration" @@ -861,10 +805,6 @@ "code": "computed-timeline", "message": "timeline call/add/addPause is not rewritten safely" }, - { - "code": "unsupported-property", - "message": "Unsupported GSAP property: text" - }, { "code": "unrecognized-postamble", "message": "postamble is not only timeline registration" @@ -885,10 +825,6 @@ "code": "computed-timeline", "message": "timeline call/add/addPause is not rewritten safely" }, - { - "code": "unsupported-property", - "message": "Unsupported GSAP property: text" - }, { "code": "unrecognized-postamble", "message": "postamble is not only timeline registration" @@ -913,10 +849,6 @@ "code": "computed-timeline", "message": "timeline call/add/addPause is not rewritten safely" }, - { - "code": "unsupported-property", - "message": "Unsupported GSAP property: text" - }, { "code": "unrecognized-postamble", "message": "postamble is not only timeline registration" @@ -937,10 +869,6 @@ "code": "computed-timeline", "message": "timeline call/add/addPause is not rewritten safely" }, - { - "code": "unsupported-property", - "message": "Unsupported GSAP property: text" - }, { "code": "unrecognized-postamble", "message": "postamble is not only timeline registration" @@ -965,10 +893,6 @@ "code": "computed-timeline", "message": "timeline call/add/addPause is not rewritten safely" }, - { - "code": "unsupported-property", - "message": "Unsupported GSAP property: text" - }, { "code": "unrecognized-postamble", "message": "postamble is not only timeline registration" @@ -989,10 +913,6 @@ "code": "computed-timeline", "message": "timeline call/add/addPause is not rewritten safely" }, - { - "code": "unsupported-property", - "message": "Unsupported GSAP property: text" - }, { "code": "unrecognized-postamble", "message": "postamble is not only timeline registration" @@ -1017,10 +937,6 @@ "code": "computed-timeline", "message": "timeline call/add/addPause is not rewritten safely" }, - { - "code": "unsupported-property", - "message": "Unsupported GSAP property: text" - }, { "code": "unrecognized-postamble", "message": "postamble is not only timeline registration" @@ -1041,10 +957,6 @@ "code": "computed-timeline", "message": "timeline call/add/addPause is not rewritten safely" }, - { - "code": "unsupported-property", - "message": "Unsupported GSAP property: text" - }, { "code": "unrecognized-postamble", "message": "postamble is not only timeline registration" @@ -1069,10 +981,6 @@ "code": "computed-timeline", "message": "timeline call/add/addPause is not rewritten safely" }, - { - "code": "unsupported-property", - "message": "Unsupported GSAP property: text" - }, { "code": "unrecognized-postamble", "message": "postamble is not only timeline registration" @@ -1093,10 +1001,6 @@ "code": "computed-timeline", "message": "timeline call/add/addPause is not rewritten safely" }, - { - "code": "unsupported-property", - "message": "Unsupported GSAP property: text" - }, { "code": "unrecognized-postamble", "message": "postamble is not only timeline registration" @@ -1117,10 +1021,6 @@ "code": "computed-timeline", "message": "timeline call/add/addPause is not rewritten safely" }, - { - "code": "unsupported-property", - "message": "Unsupported GSAP property: rotateY" - }, { "code": "unrecognized-postamble", "message": "postamble is not only timeline registration" @@ -1142,10 +1042,6 @@ "code": "computed-timeline", "message": "timeline call/add/addPause is not rewritten safely" }, - { - "code": "unsupported-property", - "message": "Unsupported GSAP property: rotateY" - }, { "code": "unrecognized-postamble", "message": "postamble is not only timeline registration" @@ -1171,10 +1067,6 @@ "code": "computed-timeline", "message": "timeline call/add/addPause is not rewritten safely" }, - { - "code": "unsupported-property", - "message": "Unsupported GSAP property: rotateY" - }, { "code": "unrecognized-postamble", "message": "postamble is not only timeline registration" @@ -1196,10 +1088,6 @@ "code": "computed-timeline", "message": "timeline call/add/addPause is not rewritten safely" }, - { - "code": "unsupported-property", - "message": "Unsupported GSAP property: rotateY" - }, { "code": "unrecognized-postamble", "message": "postamble is not only timeline registration" @@ -1225,10 +1113,6 @@ "code": "computed-timeline", "message": "timeline call/add/addPause is not rewritten safely" }, - { - "code": "unsupported-property", - "message": "Unsupported GSAP property: rotateY" - }, { "code": "unrecognized-postamble", "message": "postamble is not only timeline registration" @@ -1250,10 +1134,6 @@ "code": "computed-timeline", "message": "timeline call/add/addPause is not rewritten safely" }, - { - "code": "unsupported-property", - "message": "Unsupported GSAP property: rotateY" - }, { "code": "unrecognized-postamble", "message": "postamble is not only timeline registration" @@ -1279,6 +1159,10 @@ "code": "computed-timeline", "message": "unresolved selector or keyframes" }, + { + "code": "non-selector-target", + "message": "tween target is not a CSS selector string" + }, { "code": "unrecognized-postamble", "message": "postamble is not only timeline registration" @@ -1295,6 +1179,10 @@ "code": "computed-timeline", "message": "unresolved selector or keyframes" }, + { + "code": "non-selector-target", + "message": "tween target is not a CSS selector string" + }, { "code": "unrecognized-postamble", "message": "postamble is not only timeline registration" @@ -1315,10 +1203,6 @@ "code": "computed-timeline", "message": "timeline call/add/addPause is not rewritten safely" }, - { - "code": "unsupported-property", - "message": "Unsupported GSAP property: rotateY" - }, { "code": "unrecognized-postamble", "message": "postamble is not only timeline registration" @@ -1340,10 +1224,6 @@ "code": "computed-timeline", "message": "timeline call/add/addPause is not rewritten safely" }, - { - "code": "unsupported-property", - "message": "Unsupported GSAP property: rotateY" - }, { "code": "unrecognized-postamble", "message": "postamble is not only timeline registration" @@ -1369,10 +1249,6 @@ "code": "computed-timeline", "message": "timeline call/add/addPause is not rewritten safely" }, - { - "code": "unsupported-property", - "message": "Unsupported GSAP property: rotateY" - }, { "code": "unrecognized-postamble", "message": "postamble is not only timeline registration" @@ -1394,10 +1270,6 @@ "code": "computed-timeline", "message": "timeline call/add/addPause is not rewritten safely" }, - { - "code": "unsupported-property", - "message": "Unsupported GSAP property: rotateY" - }, { "code": "unrecognized-postamble", "message": "postamble is not only timeline registration" @@ -1423,10 +1295,6 @@ "code": "computed-timeline", "message": "timeline call/add/addPause is not rewritten safely" }, - { - "code": "unsupported-property", - "message": "Unsupported GSAP property: rotateY" - }, { "code": "unrecognized-postamble", "message": "postamble is not only timeline registration" @@ -1448,10 +1316,6 @@ "code": "computed-timeline", "message": "timeline call/add/addPause is not rewritten safely" }, - { - "code": "unsupported-property", - "message": "Unsupported GSAP property: rotateY" - }, { "code": "unrecognized-postamble", "message": "postamble is not only timeline registration" @@ -1477,10 +1341,6 @@ "code": "computed-timeline", "message": "timeline call/add/addPause is not rewritten safely" }, - { - "code": "unsupported-property", - "message": "Unsupported GSAP property: rotateY" - }, { "code": "unrecognized-postamble", "message": "postamble is not only timeline registration" @@ -1502,10 +1362,6 @@ "code": "computed-timeline", "message": "timeline call/add/addPause is not rewritten safely" }, - { - "code": "unsupported-property", - "message": "Unsupported GSAP property: rotateY" - }, { "code": "unrecognized-postamble", "message": "postamble is not only timeline registration" @@ -1531,10 +1387,6 @@ "code": "computed-timeline", "message": "timeline call/add/addPause is not rewritten safely" }, - { - "code": "unsupported-property", - "message": "Unsupported GSAP property: rotateY" - }, { "code": "unrecognized-postamble", "message": "postamble is not only timeline registration" @@ -1556,10 +1408,6 @@ "code": "computed-timeline", "message": "timeline call/add/addPause is not rewritten safely" }, - { - "code": "unsupported-property", - "message": "Unsupported GSAP property: rotateY" - }, { "code": "unrecognized-postamble", "message": "postamble is not only timeline registration" @@ -1585,10 +1433,6 @@ "code": "computed-timeline", "message": "timeline call/add/addPause is not rewritten safely" }, - { - "code": "unsupported-property", - "message": "Unsupported GSAP property: rotateY" - }, { "code": "unrecognized-postamble", "message": "postamble is not only timeline registration" @@ -1610,10 +1454,6 @@ "code": "computed-timeline", "message": "timeline call/add/addPause is not rewritten safely" }, - { - "code": "unsupported-property", - "message": "Unsupported GSAP property: rotateY" - }, { "code": "unrecognized-postamble", "message": "postamble is not only timeline registration" @@ -1639,10 +1479,6 @@ "code": "computed-timeline", "message": "timeline call/add/addPause is not rewritten safely" }, - { - "code": "unsupported-property", - "message": "Unsupported GSAP property: rotateY" - }, { "code": "unrecognized-postamble", "message": "postamble is not only timeline registration" @@ -1664,10 +1500,6 @@ "code": "computed-timeline", "message": "timeline call/add/addPause is not rewritten safely" }, - { - "code": "unsupported-property", - "message": "Unsupported GSAP property: rotateY" - }, { "code": "unrecognized-postamble", "message": "postamble is not only timeline registration" @@ -1693,10 +1525,6 @@ "code": "computed-timeline", "message": "timeline call/add/addPause is not rewritten safely" }, - { - "code": "unsupported-property", - "message": "Unsupported GSAP property: rotateY" - }, { "code": "unrecognized-postamble", "message": "postamble is not only timeline registration" @@ -1718,10 +1546,6 @@ "code": "computed-timeline", "message": "timeline call/add/addPause is not rewritten safely" }, - { - "code": "unsupported-property", - "message": "Unsupported GSAP property: rotateY" - }, { "code": "unrecognized-postamble", "message": "postamble is not only timeline registration" @@ -1747,10 +1571,6 @@ "code": "computed-timeline", "message": "timeline call/add/addPause is not rewritten safely" }, - { - "code": "unsupported-property", - "message": "Unsupported GSAP property: rotateY" - }, { "code": "unrecognized-postamble", "message": "postamble is not only timeline registration" @@ -1772,10 +1592,6 @@ "code": "computed-timeline", "message": "timeline call/add/addPause is not rewritten safely" }, - { - "code": "unsupported-property", - "message": "Unsupported GSAP property: rotateY" - }, { "code": "unrecognized-postamble", "message": "postamble is not only timeline registration" @@ -1801,6 +1617,10 @@ "code": "computed-timeline", "message": "unresolved selector or keyframes" }, + { + "code": "non-selector-target", + "message": "tween target is not a CSS selector string" + }, { "code": "unrecognized-postamble", "message": "postamble is not only timeline registration" @@ -1817,6 +1637,10 @@ "code": "computed-timeline", "message": "unresolved selector or keyframes" }, + { + "code": "non-selector-target", + "message": "tween target is not a CSS selector string" + }, { "code": "unrecognized-postamble", "message": "postamble is not only timeline registration" @@ -1835,7 +1659,7 @@ "reasons": [ { "code": "computed-timeline", - "message": "timeline callback properties need manual review" + "message": "timeline is not a simple identifier" } ], "warnings": [], @@ -1847,7 +1671,7 @@ "reasons": [ { "code": "computed-timeline", - "message": "timeline callback properties need manual review" + "message": "timeline is not a simple identifier" } ], "warnings": [] @@ -1866,12 +1690,12 @@ "message": "timeline callback properties need manual review" }, { - "code": "unsupported-property", - "message": "Unsupported GSAP property: attr" + "code": "attr-wrapper", + "message": "GSAP attr wrapper is not statically literal" }, { - "code": "unrecognized-postamble", - "message": "postamble is not only timeline registration" + "code": "non-selector-target", + "message": "tween target is not a CSS selector string" } ], "warnings": [], @@ -1886,12 +1710,12 @@ "message": "timeline callback properties need manual review" }, { - "code": "unsupported-property", - "message": "Unsupported GSAP property: attr" + "code": "attr-wrapper", + "message": "GSAP attr wrapper is not statically literal" }, { - "code": "unrecognized-postamble", - "message": "postamble is not only timeline registration" + "code": "non-selector-target", + "message": "tween target is not a CSS selector string" } ], "warnings": [] @@ -1907,7 +1731,7 @@ "reasons": [ { "code": "computed-timeline", - "message": "timeline callback properties need manual review" + "message": "timeline is not a simple identifier" } ], "warnings": [], @@ -1919,7 +1743,7 @@ "reasons": [ { "code": "computed-timeline", - "message": "timeline callback properties need manual review" + "message": "timeline is not a simple identifier" } ], "warnings": [] @@ -1935,7 +1759,7 @@ "reasons": [ { "code": "computed-timeline", - "message": "timeline callback properties need manual review" + "message": "timeline is not a simple identifier" } ], "warnings": [], @@ -1947,7 +1771,7 @@ "reasons": [ { "code": "computed-timeline", - "message": "timeline callback properties need manual review" + "message": "timeline is not a simple identifier" } ], "warnings": [] @@ -1965,17 +1789,9 @@ "code": "computed-timeline", "message": "timeline call/add/addPause is not rewritten safely" }, - { - "code": "unsupported-property", - "message": "Unsupported GSAP property: strokeDashoffset" - }, { "code": "unsupported-extra", "message": "Unsupported GSAP extra: overwrite" - }, - { - "code": "unrecognized-postamble", - "message": "postamble is not only timeline registration" } ], "warnings": [], @@ -1989,17 +1805,9 @@ "code": "computed-timeline", "message": "timeline call/add/addPause is not rewritten safely" }, - { - "code": "unsupported-property", - "message": "Unsupported GSAP property: strokeDashoffset" - }, { "code": "unsupported-extra", "message": "Unsupported GSAP extra: overwrite" - }, - { - "code": "unrecognized-postamble", - "message": "postamble is not only timeline registration" } ], "warnings": [] @@ -2017,17 +1825,9 @@ "code": "computed-timeline", "message": "timeline call/add/addPause is not rewritten safely" }, - { - "code": "unsupported-property", - "message": "Unsupported GSAP property: strokeDashoffset" - }, { "code": "unsupported-extra", "message": "Unsupported GSAP extra: overwrite" - }, - { - "code": "unrecognized-postamble", - "message": "postamble is not only timeline registration" } ], "warnings": [], @@ -2041,17 +1841,9 @@ "code": "computed-timeline", "message": "timeline call/add/addPause is not rewritten safely" }, - { - "code": "unsupported-property", - "message": "Unsupported GSAP property: strokeDashoffset" - }, { "code": "unsupported-extra", "message": "Unsupported GSAP extra: overwrite" - }, - { - "code": "unrecognized-postamble", - "message": "postamble is not only timeline registration" } ], "warnings": [] @@ -2067,7 +1859,7 @@ "reasons": [ { "code": "computed-timeline", - "message": "timeline callback properties need manual review" + "message": "timeline is not a simple identifier" } ], "warnings": [], @@ -2079,7 +1871,7 @@ "reasons": [ { "code": "computed-timeline", - "message": "timeline callback properties need manual review" + "message": "timeline is not a simple identifier" } ], "warnings": [] @@ -2095,7 +1887,7 @@ "reasons": [ { "code": "computed-timeline", - "message": "timeline callback properties need manual review" + "message": "timeline is not a simple identifier" } ], "warnings": [], @@ -2107,7 +1899,7 @@ "reasons": [ { "code": "computed-timeline", - "message": "timeline callback properties need manual review" + "message": "timeline is not a simple identifier" } ], "warnings": [] @@ -2141,11 +1933,11 @@ "reasons": [ { "code": "computed-timeline", - "message": "timeline call/add/addPause is not rewritten safely" + "message": "timeline callback properties need manual review" }, { - "code": "unsupported-property", - "message": "Unsupported GSAP property: p" + "code": "non-selector-target", + "message": "tween target is not a CSS selector string" }, { "code": "customEase-beyond-shim", @@ -2161,11 +1953,11 @@ "reasons": [ { "code": "computed-timeline", - "message": "timeline call/add/addPause is not rewritten safely" + "message": "timeline callback properties need manual review" }, { - "code": "unsupported-property", - "message": "Unsupported GSAP property: p" + "code": "non-selector-target", + "message": "tween target is not a CSS selector string" }, { "code": "customEase-beyond-shim", @@ -2185,7 +1977,7 @@ "reasons": [ { "code": "computed-timeline", - "message": "timeline callback properties need manual review" + "message": "timeline is not a simple identifier" } ], "warnings": [], @@ -2197,7 +1989,7 @@ "reasons": [ { "code": "computed-timeline", - "message": "timeline callback properties need manual review" + "message": "timeline is not a simple identifier" } ], "warnings": [] @@ -2212,16 +2004,8 @@ "changed": false, "reasons": [ { - "code": "computed-timeline", - "message": "timeline call/add/addPause is not rewritten safely" - }, - { - "code": "unsupported-property", - "message": "Unsupported GSAP property: top" - }, - { - "code": "unrecognized-postamble", - "message": "postamble is not only timeline registration" + "code": "non-selector-target", + "message": "tween target is not a CSS selector string" } ], "warnings": [], @@ -2232,16 +2016,8 @@ "changed": false, "reasons": [ { - "code": "computed-timeline", - "message": "timeline call/add/addPause is not rewritten safely" - }, - { - "code": "unsupported-property", - "message": "Unsupported GSAP property: top" - }, - { - "code": "unrecognized-postamble", - "message": "postamble is not only timeline registration" + "code": "non-selector-target", + "message": "tween target is not a CSS selector string" } ], "warnings": [] @@ -2260,12 +2036,8 @@ "message": "timeline call/add/addPause is not rewritten safely" }, { - "code": "unsupported-property", - "message": "Unsupported GSAP property: top" - }, - { - "code": "unrecognized-postamble", - "message": "postamble is not only timeline registration" + "code": "non-selector-target", + "message": "tween target is not a CSS selector string" } ], "warnings": [], @@ -2280,12 +2052,8 @@ "message": "timeline call/add/addPause is not rewritten safely" }, { - "code": "unsupported-property", - "message": "Unsupported GSAP property: top" - }, - { - "code": "unrecognized-postamble", - "message": "postamble is not only timeline registration" + "code": "non-selector-target", + "message": "tween target is not a CSS selector string" } ], "warnings": [] @@ -2304,12 +2072,8 @@ "message": "timeline call/add/addPause is not rewritten safely" }, { - "code": "unsupported-property", - "message": "Unsupported GSAP property: left" - }, - { - "code": "unrecognized-postamble", - "message": "postamble is not only timeline registration" + "code": "non-selector-target", + "message": "tween target is not a CSS selector string" } ], "warnings": [], @@ -2324,12 +2088,8 @@ "message": "timeline call/add/addPause is not rewritten safely" }, { - "code": "unsupported-property", - "message": "Unsupported GSAP property: left" - }, - { - "code": "unrecognized-postamble", - "message": "postamble is not only timeline registration" + "code": "non-selector-target", + "message": "tween target is not a CSS selector string" } ], "warnings": [] @@ -2348,12 +2108,8 @@ "message": "timeline call/add/addPause is not rewritten safely" }, { - "code": "unsupported-property", - "message": "Unsupported GSAP property: top" - }, - { - "code": "unrecognized-postamble", - "message": "postamble is not only timeline registration" + "code": "non-selector-target", + "message": "tween target is not a CSS selector string" } ], "warnings": [], @@ -2368,12 +2124,8 @@ "message": "timeline call/add/addPause is not rewritten safely" }, { - "code": "unsupported-property", - "message": "Unsupported GSAP property: top" - }, - { - "code": "unrecognized-postamble", - "message": "postamble is not only timeline registration" + "code": "non-selector-target", + "message": "tween target is not a CSS selector string" } ], "warnings": [] @@ -2390,10 +2142,6 @@ { "code": "computed-timeline", "message": "unresolved selector or keyframes" - }, - { - "code": "unrecognized-postamble", - "message": "postamble is not only timeline registration" } ], "warnings": [], @@ -2406,10 +2154,6 @@ { "code": "computed-timeline", "message": "unresolved selector or keyframes" - }, - { - "code": "unrecognized-postamble", - "message": "postamble is not only timeline registration" } ], "warnings": [] @@ -2420,26 +2164,16 @@ "kind": "block", "name": "lower-third-bild", "path": "blocks/lower-third-bild", - "status": "manual", - "changed": false, - "reasons": [ - { - "code": "unrecognized-postamble", - "message": "postamble is not only timeline registration" - } - ], + "status": "converted", + "changed": true, + "reasons": [], "warnings": [], "files": [ { "path": "blocks/lower-third-bild/lower-third-bild.html", - "status": "manual", - "changed": false, - "reasons": [ - { - "code": "unrecognized-postamble", - "message": "postamble is not only timeline registration" - } - ], + "status": "converted", + "changed": true, + "reasons": [], "warnings": [] } ] @@ -2651,11 +2385,11 @@ "reasons": [ { "code": "computed-timeline", - "message": "timeline call/add/addPause is not rewritten safely" + "message": "timeline callback properties need manual review" }, { - "code": "unsupported-property", - "message": "Unsupported GSAP property: p" + "code": "non-selector-target", + "message": "tween target is not a CSS selector string" }, { "code": "customEase-beyond-shim", @@ -2671,11 +2405,11 @@ "reasons": [ { "code": "computed-timeline", - "message": "timeline call/add/addPause is not rewritten safely" + "message": "timeline callback properties need manual review" }, { - "code": "unsupported-property", - "message": "Unsupported GSAP property: p" + "code": "non-selector-target", + "message": "tween target is not a CSS selector string" }, { "code": "customEase-beyond-shim", @@ -2690,26 +2424,16 @@ "kind": "block", "name": "news-ticker", "path": "blocks/news-ticker", - "status": "manual", - "changed": false, - "reasons": [ - { - "code": "unsupported-property", - "message": "Unsupported GSAP property: boxShadow" - } - ], + "status": "converted", + "changed": true, + "reasons": [], "warnings": [], "files": [ { "path": "blocks/news-ticker/news-ticker.html", - "status": "manual", - "changed": false, - "reasons": [ - { - "code": "unsupported-property", - "message": "Unsupported GSAP property: boxShadow" - } - ], + "status": "converted", + "changed": true, + "reasons": [], "warnings": [] } ] @@ -2718,14 +2442,9 @@ "kind": "block", "name": "north-korea-locked-down", "path": "blocks/north-korea-locked-down", - "status": "manual", - "changed": false, - "reasons": [ - { - "code": "unsupported-property", - "message": "Unsupported GSAP property: strokeDashoffset" - } - ], + "status": "converted-with-warnings", + "changed": true, + "reasons": [], "warnings": [ { "code": "ease-shim-divergence", @@ -2735,14 +2454,9 @@ "files": [ { "path": "blocks/north-korea-locked-down/north-korea-locked-down.html", - "status": "manual", - "changed": false, - "reasons": [ - { - "code": "unsupported-property", - "message": "Unsupported GSAP property: strokeDashoffset" - } - ], + "status": "converted-with-warnings", + "changed": true, + "reasons": [], "warnings": [ { "code": "ease-shim-divergence", @@ -2756,14 +2470,9 @@ "kind": "block", "name": "nyc-paris-flight", "path": "blocks/nyc-paris-flight", - "status": "manual", - "changed": false, - "reasons": [ - { - "code": "unsupported-property", - "message": "Unsupported GSAP property: strokeDashoffset" - } - ], + "status": "converted-with-warnings", + "changed": true, + "reasons": [], "warnings": [ { "code": "ease-shim-divergence", @@ -2773,14 +2482,9 @@ "files": [ { "path": "blocks/nyc-paris-flight/nyc-paris-flight.html", - "status": "manual", - "changed": false, - "reasons": [ - { - "code": "unsupported-property", - "message": "Unsupported GSAP property: strokeDashoffset" - } - ], + "status": "converted-with-warnings", + "changed": true, + "reasons": [], "warnings": [ { "code": "ease-shim-divergence", @@ -2800,10 +2504,6 @@ { "code": "computed-timeline", "message": "timeline callback properties need manual review" - }, - { - "code": "unsupported-property", - "message": "Unsupported GSAP property: attr" } ], "warnings": [], @@ -2816,10 +2516,6 @@ { "code": "computed-timeline", "message": "timeline callback properties need manual review" - }, - { - "code": "unsupported-property", - "message": "Unsupported GSAP property: attr" } ], "warnings": [] @@ -2835,7 +2531,7 @@ "reasons": [ { "code": "computed-timeline", - "message": "timeline callback properties need manual review" + "message": "timeline is not a simple identifier" } ], "warnings": [], @@ -2847,7 +2543,7 @@ "reasons": [ { "code": "computed-timeline", - "message": "timeline callback properties need manual review" + "message": "timeline is not a simple identifier" } ], "warnings": [] @@ -2863,7 +2559,7 @@ "reasons": [ { "code": "computed-timeline", - "message": "timeline callback properties need manual review" + "message": "timeline is not a simple identifier" } ], "warnings": [], @@ -2875,7 +2571,7 @@ "reasons": [ { "code": "computed-timeline", - "message": "timeline callback properties need manual review" + "message": "timeline is not a simple identifier" } ], "warnings": [] @@ -2891,7 +2587,7 @@ "reasons": [ { "code": "computed-timeline", - "message": "timeline callback properties need manual review" + "message": "timeline is not a simple identifier" } ], "warnings": [], @@ -2903,7 +2599,7 @@ "reasons": [ { "code": "computed-timeline", - "message": "timeline callback properties need manual review" + "message": "timeline is not a simple identifier" } ], "warnings": [] @@ -2914,34 +2610,16 @@ "kind": "block", "name": "spain-map", "path": "blocks/spain-map", - "status": "manual", - "changed": false, - "reasons": [ - { - "code": "unsupported-property", - "message": "Unsupported GSAP property: stroke" - }, - { - "code": "unrecognized-postamble", - "message": "postamble is not only timeline registration" - } - ], + "status": "converted", + "changed": true, + "reasons": [], "warnings": [], "files": [ { "path": "blocks/spain-map/spain-map.html", - "status": "manual", - "changed": false, - "reasons": [ - { - "code": "unsupported-property", - "message": "Unsupported GSAP property: stroke" - }, - { - "code": "unrecognized-postamble", - "message": "postamble is not only timeline registration" - } - ], + "status": "converted", + "changed": true, + "reasons": [], "warnings": [] } ] @@ -2973,7 +2651,7 @@ "reasons": [ { "code": "computed-timeline", - "message": "timeline callback properties need manual review" + "message": "timeline is not a simple identifier" } ], "warnings": [], @@ -2985,7 +2663,7 @@ "reasons": [ { "code": "computed-timeline", - "message": "timeline callback properties need manual review" + "message": "timeline is not a simple identifier" } ], "warnings": [] @@ -3001,7 +2679,7 @@ "reasons": [ { "code": "computed-timeline", - "message": "timeline callback properties need manual review" + "message": "timeline is not a simple identifier" } ], "warnings": [], @@ -3013,7 +2691,7 @@ "reasons": [ { "code": "computed-timeline", - "message": "timeline callback properties need manual review" + "message": "timeline is not a simple identifier" } ], "warnings": [] @@ -3048,14 +2726,6 @@ { "code": "plugin:Flip", "message": "Flip plugin usage needs manual review" - }, - { - "code": "unsupported-property", - "message": "Unsupported GSAP property: zIndex" - }, - { - "code": "unrecognized-postamble", - "message": "postamble is not only timeline registration" } ], "warnings": [], @@ -3068,14 +2738,6 @@ { "code": "plugin:Flip", "message": "Flip plugin usage needs manual review" - }, - { - "code": "unsupported-property", - "message": "Unsupported GSAP property: zIndex" - }, - { - "code": "unrecognized-postamble", - "message": "postamble is not only timeline registration" } ], "warnings": [] @@ -3086,34 +2748,16 @@ "kind": "block", "name": "transitions-blur", "path": "blocks/transitions-blur", - "status": "manual", - "changed": false, - "reasons": [ - { - "code": "unsupported-property", - "message": "Unsupported GSAP property: zIndex" - }, - { - "code": "unrecognized-postamble", - "message": "postamble is not only timeline registration" - } - ], + "status": "converted", + "changed": true, + "reasons": [], "warnings": [], "files": [ { "path": "blocks/transitions-blur/transitions-blur.html", - "status": "manual", - "changed": false, - "reasons": [ - { - "code": "unsupported-property", - "message": "Unsupported GSAP property: zIndex" - }, - { - "code": "unrecognized-postamble", - "message": "postamble is not only timeline registration" - } - ], + "status": "converted", + "changed": true, + "reasons": [], "warnings": [] } ] @@ -3125,17 +2769,9 @@ "status": "manual", "changed": false, "reasons": [ - { - "code": "unsupported-property", - "message": "Unsupported GSAP property: textContent" - }, { "code": "computed-timeline", "message": "unresolved selector or keyframes" - }, - { - "code": "unrecognized-postamble", - "message": "postamble is not only timeline registration" } ], "warnings": [], @@ -3145,17 +2781,9 @@ "status": "manual", "changed": false, "reasons": [ - { - "code": "unsupported-property", - "message": "Unsupported GSAP property: textContent" - }, { "code": "computed-timeline", "message": "unresolved selector or keyframes" - }, - { - "code": "unrecognized-postamble", - "message": "postamble is not only timeline registration" } ], "warnings": [] @@ -3174,12 +2802,8 @@ "message": "timeline call/add/addPause is not rewritten safely" }, { - "code": "unsupported-property", - "message": "Unsupported GSAP property: zIndex" - }, - { - "code": "unrecognized-postamble", - "message": "postamble is not only timeline registration" + "code": "non-selector-target", + "message": "tween target is not a CSS selector string" } ], "warnings": [], @@ -3194,12 +2818,8 @@ "message": "timeline call/add/addPause is not rewritten safely" }, { - "code": "unsupported-property", - "message": "Unsupported GSAP property: zIndex" - }, - { - "code": "unrecognized-postamble", - "message": "postamble is not only timeline registration" + "code": "non-selector-target", + "message": "tween target is not a CSS selector string" } ], "warnings": [] @@ -3210,34 +2830,16 @@ "kind": "block", "name": "transitions-dissolve", "path": "blocks/transitions-dissolve", - "status": "manual", - "changed": false, - "reasons": [ - { - "code": "unsupported-property", - "message": "Unsupported GSAP property: zIndex" - }, - { - "code": "unrecognized-postamble", - "message": "postamble is not only timeline registration" - } - ], + "status": "converted", + "changed": true, + "reasons": [], "warnings": [], "files": [ { "path": "blocks/transitions-dissolve/transitions-dissolve.html", - "status": "manual", - "changed": false, - "reasons": [ - { - "code": "unsupported-property", - "message": "Unsupported GSAP property: zIndex" - }, - { - "code": "unrecognized-postamble", - "message": "postamble is not only timeline registration" - } - ], + "status": "converted", + "changed": true, + "reasons": [], "warnings": [] } ] @@ -3252,10 +2854,6 @@ { "code": "computed-timeline", "message": "timeline call/add/addPause is not rewritten safely" - }, - { - "code": "unrecognized-postamble", - "message": "postamble is not only timeline registration" } ], "warnings": [], @@ -3268,10 +2866,6 @@ { "code": "computed-timeline", "message": "timeline call/add/addPause is not rewritten safely" - }, - { - "code": "unrecognized-postamble", - "message": "postamble is not only timeline registration" } ], "warnings": [] @@ -3288,10 +2882,6 @@ { "code": "computed-timeline", "message": "timeline call/add/addPause is not rewritten safely" - }, - { - "code": "unrecognized-postamble", - "message": "postamble is not only timeline registration" } ], "warnings": [], @@ -3304,10 +2894,6 @@ { "code": "computed-timeline", "message": "timeline call/add/addPause is not rewritten safely" - }, - { - "code": "unrecognized-postamble", - "message": "postamble is not only timeline registration" } ], "warnings": [] @@ -3318,34 +2904,16 @@ "kind": "block", "name": "transitions-light", "path": "blocks/transitions-light", - "status": "manual", - "changed": false, - "reasons": [ - { - "code": "unsupported-property", - "message": "Unsupported GSAP property: textContent" - }, - { - "code": "unrecognized-postamble", - "message": "postamble is not only timeline registration" - } - ], + "status": "converted", + "changed": true, + "reasons": [], "warnings": [], "files": [ { "path": "blocks/transitions-light/transitions-light.html", - "status": "manual", - "changed": false, - "reasons": [ - { - "code": "unsupported-property", - "message": "Unsupported GSAP property: textContent" - }, - { - "code": "unrecognized-postamble", - "message": "postamble is not only timeline registration" - } - ], + "status": "converted", + "changed": true, + "reasons": [], "warnings": [] } ] @@ -3354,34 +2922,16 @@ "kind": "block", "name": "transitions-mechanical", "path": "blocks/transitions-mechanical", - "status": "manual", - "changed": false, - "reasons": [ - { - "code": "unsupported-property", - "message": "Unsupported GSAP property: zIndex" - }, - { - "code": "unrecognized-postamble", - "message": "postamble is not only timeline registration" - } - ], + "status": "converted", + "changed": true, + "reasons": [], "warnings": [], "files": [ { "path": "blocks/transitions-mechanical/transitions-mechanical.html", - "status": "manual", - "changed": false, - "reasons": [ - { - "code": "unsupported-property", - "message": "Unsupported GSAP property: zIndex" - }, - { - "code": "unrecognized-postamble", - "message": "postamble is not only timeline registration" - } - ], + "status": "converted", + "changed": true, + "reasons": [], "warnings": [] } ] @@ -3390,34 +2940,16 @@ "kind": "block", "name": "transitions-other", "path": "blocks/transitions-other", - "status": "manual", - "changed": false, - "reasons": [ - { - "code": "unsupported-property", - "message": "Unsupported GSAP property: zIndex" - }, - { - "code": "unrecognized-postamble", - "message": "postamble is not only timeline registration" - } - ], + "status": "converted", + "changed": true, + "reasons": [], "warnings": [], "files": [ { "path": "blocks/transitions-other/transitions-other.html", - "status": "manual", - "changed": false, - "reasons": [ - { - "code": "unsupported-property", - "message": "Unsupported GSAP property: zIndex" - }, - { - "code": "unrecognized-postamble", - "message": "postamble is not only timeline registration" - } - ], + "status": "converted", + "changed": true, + "reasons": [], "warnings": [] } ] @@ -3426,34 +2958,16 @@ "kind": "block", "name": "transitions-push", "path": "blocks/transitions-push", - "status": "manual", - "changed": false, - "reasons": [ - { - "code": "unsupported-property", - "message": "Unsupported GSAP property: zIndex" - }, - { - "code": "unrecognized-postamble", - "message": "postamble is not only timeline registration" - } - ], + "status": "converted", + "changed": true, + "reasons": [], "warnings": [], "files": [ { "path": "blocks/transitions-push/transitions-push.html", - "status": "manual", - "changed": false, - "reasons": [ - { - "code": "unsupported-property", - "message": "Unsupported GSAP property: zIndex" - }, - { - "code": "unrecognized-postamble", - "message": "postamble is not only timeline registration" - } - ], + "status": "converted", + "changed": true, + "reasons": [], "warnings": [] } ] @@ -3462,34 +2976,16 @@ "kind": "block", "name": "transitions-radial", "path": "blocks/transitions-radial", - "status": "manual", - "changed": false, - "reasons": [ - { - "code": "unsupported-property", - "message": "Unsupported GSAP property: zIndex" - }, - { - "code": "unrecognized-postamble", - "message": "postamble is not only timeline registration" - } - ], + "status": "converted", + "changed": true, + "reasons": [], "warnings": [], "files": [ { "path": "blocks/transitions-radial/transitions-radial.html", - "status": "manual", - "changed": false, - "reasons": [ - { - "code": "unsupported-property", - "message": "Unsupported GSAP property: zIndex" - }, - { - "code": "unrecognized-postamble", - "message": "postamble is not only timeline registration" - } - ], + "status": "converted", + "changed": true, + "reasons": [], "warnings": [] } ] @@ -3498,34 +2994,16 @@ "kind": "block", "name": "transitions-scale", "path": "blocks/transitions-scale", - "status": "manual", - "changed": false, - "reasons": [ - { - "code": "unsupported-property", - "message": "Unsupported GSAP property: zIndex" - }, - { - "code": "unrecognized-postamble", - "message": "postamble is not only timeline registration" - } - ], + "status": "converted", + "changed": true, + "reasons": [], "warnings": [], "files": [ { "path": "blocks/transitions-scale/transitions-scale.html", - "status": "manual", - "changed": false, - "reasons": [ - { - "code": "unsupported-property", - "message": "Unsupported GSAP property: zIndex" - }, - { - "code": "unrecognized-postamble", - "message": "postamble is not only timeline registration" - } - ], + "status": "converted", + "changed": true, + "reasons": [], "warnings": [] } ] @@ -3540,14 +3018,6 @@ { "code": "computed-timeline", "message": "unresolved selector or keyframes" - }, - { - "code": "unsupported-property", - "message": "Unsupported GSAP property: strokeDashoffset" - }, - { - "code": "unrecognized-postamble", - "message": "postamble is not only timeline registration" } ], "warnings": [ @@ -3565,14 +3035,6 @@ { "code": "computed-timeline", "message": "unresolved selector or keyframes" - }, - { - "code": "unsupported-property", - "message": "Unsupported GSAP property: strokeDashoffset" - }, - { - "code": "unrecognized-postamble", - "message": "postamble is not only timeline registration" } ], "warnings": [ @@ -3588,34 +3050,16 @@ "kind": "block", "name": "us-map", "path": "blocks/us-map", - "status": "manual", - "changed": false, - "reasons": [ - { - "code": "unsupported-property", - "message": "Unsupported GSAP property: stroke" - }, - { - "code": "unrecognized-postamble", - "message": "postamble is not only timeline registration" - } - ], + "status": "converted", + "changed": true, + "reasons": [], "warnings": [], "files": [ { "path": "blocks/us-map/us-map.html", - "status": "manual", - "changed": false, - "reasons": [ - { - "code": "unsupported-property", - "message": "Unsupported GSAP property: stroke" - }, - { - "code": "unrecognized-postamble", - "message": "postamble is not only timeline registration" - } - ], + "status": "converted", + "changed": true, + "reasons": [], "warnings": [] } ] @@ -3627,17 +3071,13 @@ "status": "manual", "changed": false, "reasons": [ - { - "code": "unsupported-property", - "message": "Unsupported GSAP property: strokeDashoffset" - }, { "code": "computed-timeline", "message": "unresolved selector or keyframes" }, { - "code": "unrecognized-postamble", - "message": "postamble is not only timeline registration" + "code": "attr-wrapper", + "message": "GSAP attr wrapper is not statically literal" } ], "warnings": [], @@ -3647,17 +3087,13 @@ "status": "manual", "changed": false, "reasons": [ - { - "code": "unsupported-property", - "message": "Unsupported GSAP property: strokeDashoffset" - }, { "code": "computed-timeline", "message": "unresolved selector or keyframes" }, { - "code": "unrecognized-postamble", - "message": "postamble is not only timeline registration" + "code": "attr-wrapper", + "message": "GSAP attr wrapper is not statically literal" } ], "warnings": [] @@ -3676,12 +3112,8 @@ "message": "timeline callback properties need manual review" }, { - "code": "unsupported-property", - "message": "Unsupported GSAP property: strokeDashoffset" - }, - { - "code": "unrecognized-postamble", - "message": "postamble is not only timeline registration" + "code": "non-selector-target", + "message": "tween target is not a CSS selector string" } ], "warnings": [], @@ -3696,12 +3128,8 @@ "message": "timeline callback properties need manual review" }, { - "code": "unsupported-property", - "message": "Unsupported GSAP property: strokeDashoffset" - }, - { - "code": "unrecognized-postamble", - "message": "postamble is not only timeline registration" + "code": "non-selector-target", + "message": "tween target is not a CSS selector string" } ], "warnings": [] @@ -3718,10 +3146,6 @@ { "code": "computed-timeline", "message": "unresolved selector or keyframes" - }, - { - "code": "unrecognized-postamble", - "message": "postamble is not only timeline registration" } ], "warnings": [], @@ -3734,10 +3158,6 @@ { "code": "computed-timeline", "message": "unresolved selector or keyframes" - }, - { - "code": "unrecognized-postamble", - "message": "postamble is not only timeline registration" } ], "warnings": [] @@ -3753,11 +3173,11 @@ "reasons": [ { "code": "computed-timeline", - "message": "timeline call/add/addPause is not rewritten safely" + "message": "timeline callback properties need manual review" }, { - "code": "unsupported-property", - "message": "Unsupported GSAP property: p" + "code": "non-selector-target", + "message": "tween target is not a CSS selector string" }, { "code": "customEase-beyond-shim", @@ -3773,11 +3193,11 @@ "reasons": [ { "code": "computed-timeline", - "message": "timeline call/add/addPause is not rewritten safely" + "message": "timeline callback properties need manual review" }, { - "code": "unsupported-property", - "message": "Unsupported GSAP property: p" + "code": "non-selector-target", + "message": "tween target is not a CSS selector string" }, { "code": "customEase-beyond-shim", @@ -3801,11 +3221,11 @@ }, { "code": "computed-timeline", - "message": "timeline call/add/addPause is not rewritten safely" + "message": "timeline callback properties need manual review" }, { - "code": "unsupported-property", - "message": "Unsupported GSAP property: value" + "code": "non-selector-target", + "message": "tween target is not a CSS selector string" }, { "code": "unrecognized-postamble", @@ -3825,11 +3245,11 @@ }, { "code": "computed-timeline", - "message": "timeline call/add/addPause is not rewritten safely" + "message": "timeline callback properties need manual review" }, { - "code": "unsupported-property", - "message": "Unsupported GSAP property: value" + "code": "non-selector-target", + "message": "tween target is not a CSS selector string" }, { "code": "unrecognized-postamble", @@ -3848,12 +3268,8 @@ "changed": false, "reasons": [ { - "code": "computed-timeline", - "message": "timeline call/add/addPause is not rewritten safely" - }, - { - "code": "unsupported-property", - "message": "Unsupported GSAP property: _" + "code": "non-selector-target", + "message": "tween target is not a CSS selector string" }, { "code": "unrecognized-postamble", @@ -3868,12 +3284,8 @@ "changed": false, "reasons": [ { - "code": "computed-timeline", - "message": "timeline call/add/addPause is not rewritten safely" - }, - { - "code": "unsupported-property", - "message": "Unsupported GSAP property: _" + "code": "non-selector-target", + "message": "tween target is not a CSS selector string" }, { "code": "unrecognized-postamble", @@ -3896,8 +3308,8 @@ "message": "timeline callback properties need manual review" }, { - "code": "unsupported-property", - "message": "Unsupported GSAP property: progress" + "code": "non-selector-target", + "message": "tween target is not a CSS selector string" }, { "code": "unrecognized-postamble", @@ -3916,8 +3328,8 @@ "message": "timeline callback properties need manual review" }, { - "code": "unsupported-property", - "message": "Unsupported GSAP property: progress" + "code": "non-selector-target", + "message": "tween target is not a CSS selector string" }, { "code": "unrecognized-postamble", @@ -3937,11 +3349,11 @@ "reasons": [ { "code": "computed-timeline", - "message": "timeline call/add/addPause is not rewritten safely" + "message": "timeline callback properties need manual review" }, { - "code": "unsupported-property", - "message": "Unsupported GSAP property: energyIntensity" + "code": "non-selector-target", + "message": "tween target is not a CSS selector string" }, { "code": "unrecognized-postamble", @@ -3957,11 +3369,11 @@ "reasons": [ { "code": "computed-timeline", - "message": "timeline call/add/addPause is not rewritten safely" + "message": "timeline callback properties need manual review" }, { - "code": "unsupported-property", - "message": "Unsupported GSAP property: energyIntensity" + "code": "non-selector-target", + "message": "tween target is not a CSS selector string" }, { "code": "unrecognized-postamble", @@ -3981,11 +3393,11 @@ "reasons": [ { "code": "computed-timeline", - "message": "timeline call/add/addPause is not rewritten safely" + "message": "timeline callback properties need manual review" }, { - "code": "unsupported-property", - "message": "Unsupported GSAP property: t" + "code": "non-selector-target", + "message": "tween target is not a CSS selector string" }, { "code": "unrecognized-postamble", @@ -4001,11 +3413,11 @@ "reasons": [ { "code": "computed-timeline", - "message": "timeline call/add/addPause is not rewritten safely" + "message": "timeline callback properties need manual review" }, { - "code": "unsupported-property", - "message": "Unsupported GSAP property: t" + "code": "non-selector-target", + "message": "tween target is not a CSS selector string" }, { "code": "unrecognized-postamble", @@ -4028,16 +3440,12 @@ "message": "timeline call/add/addPause is not rewritten safely" }, { - "code": "unsupported-property", - "message": "Unsupported GSAP property: logoY" + "code": "non-selector-target", + "message": "tween target is not a CSS selector string" }, { "code": "customEase-beyond-shim", "message": "Unrecognized or fallback ease needs manual review: __raw:entryEase" - }, - { - "code": "unrecognized-postamble", - "message": "postamble is not only timeline registration" } ], "warnings": [ @@ -4057,16 +3465,12 @@ "message": "timeline call/add/addPause is not rewritten safely" }, { - "code": "unsupported-property", - "message": "Unsupported GSAP property: logoY" + "code": "non-selector-target", + "message": "tween target is not a CSS selector string" }, { "code": "customEase-beyond-shim", "message": "Unrecognized or fallback ease needs manual review: __raw:entryEase" - }, - { - "code": "unrecognized-postamble", - "message": "postamble is not only timeline registration" } ], "warnings": [ @@ -4082,26 +3486,16 @@ "kind": "block", "name": "vpn-youtube-spot", "path": "blocks/vpn-youtube-spot", - "status": "manual", - "changed": false, - "reasons": [ - { - "code": "unsupported-property", - "message": "Unsupported GSAP property: outlineWidth" - } - ], + "status": "converted", + "changed": true, + "reasons": [], "warnings": [], "files": [ { "path": "blocks/vpn-youtube-spot/vpn-youtube-spot.html", - "status": "manual", - "changed": false, - "reasons": [ - { - "code": "unsupported-property", - "message": "Unsupported GSAP property: outlineWidth" - } - ], + "status": "converted", + "changed": true, + "reasons": [], "warnings": [] } ] @@ -4115,7 +3509,7 @@ "reasons": [ { "code": "computed-timeline", - "message": "timeline callback properties need manual review" + "message": "timeline is not a simple identifier" } ], "warnings": [], @@ -4127,7 +3521,7 @@ "reasons": [ { "code": "computed-timeline", - "message": "timeline callback properties need manual review" + "message": "timeline is not a simple identifier" } ], "warnings": [] @@ -4144,14 +3538,6 @@ { "code": "computed-timeline", "message": "unresolved selector or keyframes" - }, - { - "code": "unsupported-property", - "message": "Unsupported GSAP property: stroke" - }, - { - "code": "unrecognized-postamble", - "message": "postamble is not only timeline registration" } ], "warnings": [], @@ -4164,14 +3550,6 @@ { "code": "computed-timeline", "message": "unresolved selector or keyframes" - }, - { - "code": "unsupported-property", - "message": "Unsupported GSAP property: stroke" - }, - { - "code": "unrecognized-postamble", - "message": "postamble is not only timeline registration" } ], "warnings": [] @@ -4252,10 +3630,6 @@ { "code": "computed-timeline", "message": "unresolved selector or keyframes" - }, - { - "code": "unrecognized-postamble", - "message": "postamble is not only timeline registration" } ], "warnings": [], @@ -4268,10 +3642,6 @@ { "code": "computed-timeline", "message": "unresolved selector or keyframes" - }, - { - "code": "unrecognized-postamble", - "message": "postamble is not only timeline registration" } ], "warnings": [] @@ -4288,6 +3658,10 @@ { "code": "computed-timeline", "message": "unresolved selector or keyframes" + }, + { + "code": "non-selector-target", + "message": "tween target is not a CSS selector string" } ], "warnings": [], @@ -4300,6 +3674,10 @@ { "code": "computed-timeline", "message": "unresolved selector or keyframes" + }, + { + "code": "non-selector-target", + "message": "tween target is not a CSS selector string" } ], "warnings": [] @@ -4316,10 +3694,6 @@ { "code": "computed-timeline", "message": "unresolved selector or keyframes" - }, - { - "code": "unrecognized-postamble", - "message": "postamble is not only timeline registration" } ], "warnings": [], @@ -4332,10 +3706,6 @@ { "code": "computed-timeline", "message": "unresolved selector or keyframes" - }, - { - "code": "unrecognized-postamble", - "message": "postamble is not only timeline registration" } ], "warnings": [] @@ -4352,14 +3722,6 @@ { "code": "computed-timeline", "message": "unresolved selector or keyframes" - }, - { - "code": "unsupported-property", - "message": "Unsupported GSAP property: textShadow" - }, - { - "code": "unrecognized-postamble", - "message": "postamble is not only timeline registration" } ], "warnings": [], @@ -4372,14 +3734,6 @@ { "code": "computed-timeline", "message": "unresolved selector or keyframes" - }, - { - "code": "unsupported-property", - "message": "Unsupported GSAP property: textShadow" - }, - { - "code": "unrecognized-postamble", - "message": "postamble is not only timeline registration" } ], "warnings": [] @@ -4396,14 +3750,6 @@ { "code": "computed-timeline", "message": "unresolved selector or keyframes" - }, - { - "code": "unsupported-property", - "message": "Unsupported GSAP property: backgroundPosition" - }, - { - "code": "unrecognized-postamble", - "message": "postamble is not only timeline registration" } ], "warnings": [], @@ -4416,14 +3762,6 @@ { "code": "computed-timeline", "message": "unresolved selector or keyframes" - }, - { - "code": "unsupported-property", - "message": "Unsupported GSAP property: backgroundPosition" - }, - { - "code": "unrecognized-postamble", - "message": "postamble is not only timeline registration" } ], "warnings": [] @@ -4440,10 +3778,6 @@ { "code": "computed-timeline", "message": "unresolved selector or keyframes" - }, - { - "code": "unrecognized-postamble", - "message": "postamble is not only timeline registration" } ], "warnings": [], @@ -4456,10 +3790,6 @@ { "code": "computed-timeline", "message": "unresolved selector or keyframes" - }, - { - "code": "unrecognized-postamble", - "message": "postamble is not only timeline registration" } ], "warnings": [] @@ -4476,10 +3806,6 @@ { "code": "computed-timeline", "message": "unresolved selector or keyframes" - }, - { - "code": "unrecognized-postamble", - "message": "postamble is not only timeline registration" } ], "warnings": [ @@ -4497,10 +3823,6 @@ { "code": "computed-timeline", "message": "unresolved selector or keyframes" - }, - { - "code": "unrecognized-postamble", - "message": "postamble is not only timeline registration" } ], "warnings": [ @@ -4522,14 +3844,6 @@ { "code": "computed-timeline", "message": "unresolved selector or keyframes" - }, - { - "code": "unsupported-property", - "message": "Unsupported GSAP property: display" - }, - { - "code": "unrecognized-postamble", - "message": "postamble is not only timeline registration" } ], "warnings": [], @@ -4542,14 +3856,6 @@ { "code": "computed-timeline", "message": "unresolved selector or keyframes" - }, - { - "code": "unsupported-property", - "message": "Unsupported GSAP property: display" - }, - { - "code": "unrecognized-postamble", - "message": "postamble is not only timeline registration" } ], "warnings": [] @@ -4566,10 +3872,6 @@ { "code": "computed-timeline", "message": "unresolved selector or keyframes" - }, - { - "code": "unrecognized-postamble", - "message": "postamble is not only timeline registration" } ], "warnings": [], @@ -4582,10 +3884,6 @@ { "code": "computed-timeline", "message": "unresolved selector or keyframes" - }, - { - "code": "unrecognized-postamble", - "message": "postamble is not only timeline registration" } ], "warnings": [] @@ -4602,14 +3900,6 @@ { "code": "computed-timeline", "message": "unresolved selector or keyframes" - }, - { - "code": "unsupported-property", - "message": "Unsupported GSAP property: textShadow" - }, - { - "code": "unrecognized-postamble", - "message": "postamble is not only timeline registration" } ], "warnings": [ @@ -4627,14 +3917,6 @@ { "code": "computed-timeline", "message": "unresolved selector or keyframes" - }, - { - "code": "unsupported-property", - "message": "Unsupported GSAP property: textShadow" - }, - { - "code": "unrecognized-postamble", - "message": "postamble is not only timeline registration" } ], "warnings": [ @@ -4657,6 +3939,10 @@ "code": "computed-timeline", "message": "unresolved selector or keyframes" }, + { + "code": "non-selector-target", + "message": "tween target is not a CSS selector string" + }, { "code": "unrecognized-postamble", "message": "postamble is not only timeline registration" @@ -4673,6 +3959,10 @@ "code": "computed-timeline", "message": "unresolved selector or keyframes" }, + { + "code": "non-selector-target", + "message": "tween target is not a CSS selector string" + }, { "code": "unrecognized-postamble", "message": "postamble is not only timeline registration" @@ -4692,10 +3982,6 @@ { "code": "computed-timeline", "message": "unresolved selector or keyframes" - }, - { - "code": "unrecognized-postamble", - "message": "postamble is not only timeline registration" } ], "warnings": [], @@ -4708,10 +3994,6 @@ { "code": "computed-timeline", "message": "unresolved selector or keyframes" - }, - { - "code": "unrecognized-postamble", - "message": "postamble is not only timeline registration" } ], "warnings": [] @@ -4722,26 +4004,16 @@ "kind": "component", "name": "caption-pill-karaoke", "path": "components/caption-pill-karaoke", - "status": "manual", - "changed": false, - "reasons": [ - { - "code": "unrecognized-postamble", - "message": "postamble is not only timeline registration" - } - ], + "status": "converted", + "changed": true, + "reasons": [], "warnings": [], "files": [ { "path": "components/caption-pill-karaoke/caption-pill-karaoke.html", - "status": "manual", - "changed": false, - "reasons": [ - { - "code": "unrecognized-postamble", - "message": "postamble is not only timeline registration" - } - ], + "status": "converted", + "changed": true, + "reasons": [], "warnings": [] } ] @@ -4756,14 +4028,6 @@ { "code": "computed-timeline", "message": "unresolved selector or keyframes" - }, - { - "code": "unsupported-property", - "message": "Unsupported GSAP property: --mask-position" - }, - { - "code": "unrecognized-postamble", - "message": "postamble is not only timeline registration" } ], "warnings": [], @@ -4776,14 +4040,6 @@ { "code": "computed-timeline", "message": "unresolved selector or keyframes" - }, - { - "code": "unsupported-property", - "message": "Unsupported GSAP property: --mask-position" - }, - { - "code": "unrecognized-postamble", - "message": "postamble is not only timeline registration" } ], "warnings": [] @@ -4800,14 +4056,6 @@ { "code": "computed-timeline", "message": "unresolved selector or keyframes" - }, - { - "code": "unsupported-property", - "message": "Unsupported GSAP property: fontWeight" - }, - { - "code": "unrecognized-postamble", - "message": "postamble is not only timeline registration" } ], "warnings": [], @@ -4820,14 +4068,6 @@ { "code": "computed-timeline", "message": "unresolved selector or keyframes" - }, - { - "code": "unsupported-property", - "message": "Unsupported GSAP property: fontWeight" - }, - { - "code": "unrecognized-postamble", - "message": "postamble is not only timeline registration" } ], "warnings": [] @@ -4882,12 +4122,8 @@ "message": "timeline callback properties need manual review" }, { - "code": "unsupported-property", - "message": "Unsupported GSAP property: t" - }, - { - "code": "unrecognized-postamble", - "message": "postamble is not only timeline registration" + "code": "non-selector-target", + "message": "tween target is not a CSS selector string" } ], "warnings": [], @@ -4902,12 +4138,8 @@ "message": "timeline callback properties need manual review" }, { - "code": "unsupported-property", - "message": "Unsupported GSAP property: t" - }, - { - "code": "unrecognized-postamble", - "message": "postamble is not only timeline registration" + "code": "non-selector-target", + "message": "tween target is not a CSS selector string" } ], "warnings": [] @@ -5030,8 +4262,8 @@ "changed": false, "reasons": [ { - "code": "unrecognized-postamble", - "message": "postamble is not only timeline registration" + "code": "non-selector-target", + "message": "tween target is not a CSS selector string" } ], "warnings": [], @@ -5049,8 +4281,8 @@ "changed": false, "reasons": [ { - "code": "unrecognized-postamble", - "message": "postamble is not only timeline registration" + "code": "non-selector-target", + "message": "tween target is not a CSS selector string" } ], "warnings": [] @@ -5068,17 +4300,9 @@ "code": "computed-timeline", "message": "timeline call/add/addPause is not rewritten safely" }, - { - "code": "unsupported-property", - "message": "Unsupported GSAP property: strokeDashoffset" - }, { "code": "unsupported-extra", "message": "Unsupported GSAP extra: overwrite" - }, - { - "code": "unrecognized-postamble", - "message": "postamble is not only timeline registration" } ], "warnings": [], @@ -5092,17 +4316,9 @@ "code": "computed-timeline", "message": "timeline call/add/addPause is not rewritten safely" }, - { - "code": "unsupported-property", - "message": "Unsupported GSAP property: strokeDashoffset" - }, { "code": "unsupported-extra", "message": "Unsupported GSAP extra: overwrite" - }, - { - "code": "unrecognized-postamble", - "message": "postamble is not only timeline registration" } ], "warnings": [] @@ -5120,14 +4336,9 @@ "kind": "example", "name": "kinetic-type", "path": "examples/kinetic-type", - "status": "manual", + "status": "converted-with-warnings", "changed": true, - "reasons": [ - { - "code": "unsupported-property", - "message": "Unsupported GSAP property: xPercent" - } - ], + "reasons": [], "warnings": [ { "code": "ease-shim-divergence", @@ -5137,14 +4348,9 @@ "files": [ { "path": "examples/kinetic-type/compositions/main-graphics.html", - "status": "manual", - "changed": false, - "reasons": [ - { - "code": "unsupported-property", - "message": "Unsupported GSAP property: xPercent" - } - ], + "status": "converted-with-warnings", + "changed": true, + "reasons": [], "warnings": [ { "code": "ease-shim-divergence", @@ -5173,8 +4379,8 @@ "message": "timeline callback properties need manual review" }, { - "code": "unsupported-property", - "message": "Unsupported GSAP property: t" + "code": "non-selector-target", + "message": "tween target is not a CSS selector string" }, { "code": "unrecognized-postamble", @@ -5193,8 +4399,8 @@ "message": "timeline callback properties need manual review" }, { - "code": "unsupported-property", - "message": "Unsupported GSAP property: t" + "code": "non-selector-target", + "message": "tween target is not a CSS selector string" }, { "code": "unrecognized-postamble", @@ -5217,12 +4423,12 @@ "message": "timeline callback properties need manual review" }, { - "code": "unsupported-property", - "message": "Unsupported GSAP property: attr" + "code": "attr-wrapper", + "message": "GSAP attr wrapper is not statically literal" }, { - "code": "unrecognized-postamble", - "message": "postamble is not only timeline registration" + "code": "non-selector-target", + "message": "tween target is not a CSS selector string" } ], "warnings": [], @@ -5237,12 +4443,12 @@ "message": "timeline callback properties need manual review" }, { - "code": "unsupported-property", - "message": "Unsupported GSAP property: attr" + "code": "attr-wrapper", + "message": "GSAP attr wrapper is not statically literal" }, { - "code": "unrecognized-postamble", - "message": "postamble is not only timeline registration" + "code": "non-selector-target", + "message": "tween target is not a CSS selector string" } ], "warnings": [] @@ -5261,15 +4467,11 @@ "name": "play-mode", "path": "examples/play-mode", "status": "manual", - "changed": false, + "changed": true, "reasons": [ { "code": "computed-timeline", "message": "unresolved selector or keyframes" - }, - { - "code": "unrecognized-postamble", - "message": "postamble is not only timeline registration" } ], "warnings": [ @@ -5287,10 +4489,6 @@ { "code": "computed-timeline", "message": "unresolved selector or keyframes" - }, - { - "code": "unrecognized-postamble", - "message": "postamble is not only timeline registration" } ], "warnings": [ @@ -5308,10 +4506,6 @@ { "code": "computed-timeline", "message": "GSAP delay is not represented in parsed placement data" - }, - { - "code": "unrecognized-postamble", - "message": "postamble is not only timeline registration" } ], "warnings": [] @@ -5324,24 +4518,15 @@ { "code": "computed-timeline", "message": "timeline callback properties need manual review" - }, - { - "code": "unrecognized-postamble", - "message": "postamble is not only timeline registration" } ], "warnings": [] }, { "path": "examples/play-mode/index.html", - "status": "manual", - "changed": false, - "reasons": [ - { - "code": "unrecognized-postamble", - "message": "postamble is not only timeline registration" - } - ], + "status": "converted", + "changed": true, + "reasons": [], "warnings": [] } ] @@ -5351,23 +4536,19 @@ "name": "product-promo", "path": "examples/product-promo", "status": "manual", - "changed": false, + "changed": true, "reasons": [ { "code": "computed-timeline", "message": "GSAP delay is not represented in parsed placement data" }, - { - "code": "unrecognized-postamble", - "message": "postamble is not only timeline registration" - }, - { - "code": "unsupported-property", - "message": "Unsupported GSAP property: xPercent" - }, { "code": "unsupported-extra", "message": "Unsupported GSAP extra: overwrite" + }, + { + "code": "non-selector-target", + "message": "tween target is not a CSS selector string" } ], "warnings": [ @@ -5385,10 +4566,6 @@ { "code": "computed-timeline", "message": "GSAP delay is not represented in parsed placement data" - }, - { - "code": "unrecognized-postamble", - "message": "postamble is not only timeline registration" } ], "warnings": [ @@ -5407,17 +4584,13 @@ "code": "computed-timeline", "message": "timeline callback properties need manual review" }, - { - "code": "unsupported-property", - "message": "Unsupported GSAP property: xPercent" - }, { "code": "unsupported-extra", "message": "Unsupported GSAP extra: overwrite" }, { - "code": "unrecognized-postamble", - "message": "postamble is not only timeline registration" + "code": "non-selector-target", + "message": "tween target is not a CSS selector string" } ], "warnings": [ @@ -5435,24 +4608,15 @@ { "code": "computed-timeline", "message": "unresolved selector or keyframes" - }, - { - "code": "unrecognized-postamble", - "message": "postamble is not only timeline registration" } ], "warnings": [] }, { "path": "examples/product-promo/index.html", - "status": "manual", - "changed": false, - "reasons": [ - { - "code": "unrecognized-postamble", - "message": "postamble is not only timeline registration" - } - ], + "status": "converted", + "changed": true, + "reasons": [], "warnings": [] } ] @@ -5461,26 +4625,16 @@ "kind": "example", "name": "slideshow-demo", "path": "examples/slideshow-demo", - "status": "manual", - "changed": false, - "reasons": [ - { - "code": "unrecognized-postamble", - "message": "postamble is not only timeline registration" - } - ], + "status": "converted", + "changed": true, + "reasons": [], "warnings": [], "files": [ { "path": "examples/slideshow-demo/index.html", - "status": "manual", - "changed": false, - "reasons": [ - { - "code": "unrecognized-postamble", - "message": "postamble is not only timeline registration" - } - ], + "status": "converted", + "changed": true, + "reasons": [], "warnings": [] } ] @@ -5493,8 +4647,8 @@ "changed": false, "reasons": [ { - "code": "unrecognized-postamble", - "message": "postamble is not only timeline registration" + "code": "non-selector-target", + "message": "tween target is not a CSS selector string" } ], "warnings": [], @@ -5512,8 +4666,8 @@ "changed": false, "reasons": [ { - "code": "unrecognized-postamble", - "message": "postamble is not only timeline registration" + "code": "non-selector-target", + "message": "tween target is not a CSS selector string" } ], "warnings": [] @@ -5530,14 +4684,6 @@ { "code": "computed-timeline", "message": "unresolved selector or keyframes" - }, - { - "code": "unsupported-property", - "message": "Unsupported GSAP property: display" - }, - { - "code": "unrecognized-postamble", - "message": "postamble is not only timeline registration" } ], "warnings": [ @@ -5555,40 +4701,22 @@ { "code": "computed-timeline", "message": "unresolved selector or keyframes" - }, - { - "code": "unsupported-property", - "message": "Unsupported GSAP property: display" - }, - { - "code": "unrecognized-postamble", - "message": "postamble is not only timeline registration" } ], "warnings": [] }, { "path": "examples/swiss-grid/compositions/graphics.html", - "status": "manual", - "changed": false, - "reasons": [ - { - "code": "unrecognized-postamble", - "message": "postamble is not only timeline registration" - } - ], + "status": "converted", + "changed": true, + "reasons": [], "warnings": [] }, { "path": "examples/swiss-grid/compositions/intro.html", - "status": "manual", - "changed": false, - "reasons": [ - { - "code": "unrecognized-postamble", - "message": "postamble is not only timeline registration" - } - ], + "status": "converted", + "changed": true, + "reasons": [], "warnings": [] }, { @@ -5615,14 +4743,6 @@ { "code": "computed-timeline", "message": "unresolved selector or keyframes" - }, - { - "code": "unrecognized-postamble", - "message": "postamble is not only timeline registration" - }, - { - "code": "unsupported-property", - "message": "Unsupported GSAP property: xPercent" } ], "warnings": [ @@ -5640,10 +4760,6 @@ { "code": "computed-timeline", "message": "unresolved selector or keyframes" - }, - { - "code": "unrecognized-postamble", - "message": "postamble is not only timeline registration" } ], "warnings": [ @@ -5667,14 +4783,9 @@ }, { "path": "examples/vignelli/index.html", - "status": "manual", - "changed": false, - "reasons": [ - { - "code": "unsupported-property", - "message": "Unsupported GSAP property: xPercent" - } - ], + "status": "converted", + "changed": true, + "reasons": [], "warnings": [] } ] @@ -5712,19 +4823,11 @@ "name": "warm-grain", "path": "examples/warm-grain", "status": "manual", - "changed": false, + "changed": true, "reasons": [ { "code": "computed-timeline", "message": "timeline callback properties need manual review" - }, - { - "code": "unrecognized-postamble", - "message": "postamble is not only timeline registration" - }, - { - "code": "unsupported-property", - "message": "Unsupported GSAP property: xPercent" } ], "warnings": [], @@ -5737,52 +4840,29 @@ { "code": "computed-timeline", "message": "timeline callback properties need manual review" - }, - { - "code": "unrecognized-postamble", - "message": "postamble is not only timeline registration" } ], "warnings": [] }, { "path": "examples/warm-grain/compositions/graphics.html", - "status": "manual", - "changed": false, - "reasons": [ - { - "code": "unrecognized-postamble", - "message": "postamble is not only timeline registration" - } - ], + "status": "converted", + "changed": true, + "reasons": [], "warnings": [] }, { "path": "examples/warm-grain/compositions/intro.html", - "status": "manual", - "changed": false, - "reasons": [ - { - "code": "unsupported-property", - "message": "Unsupported GSAP property: xPercent" - }, - { - "code": "unrecognized-postamble", - "message": "postamble is not only timeline registration" - } - ], + "status": "converted", + "changed": true, + "reasons": [], "warnings": [] }, { "path": "examples/warm-grain/index.html", - "status": "manual", - "changed": false, - "reasons": [ - { - "code": "unsupported-property", - "message": "Unsupported GSAP property: xPercent" - } - ], + "status": "converted", + "changed": true, + "reasons": [], "warnings": [] } ] diff --git a/scripts/gsap-to-anime/dry-run-report.md b/scripts/gsap-to-anime/dry-run-report.md index f85fbd3eb1..2c7138241e 100644 --- a/scripts/gsap-to-anime/dry-run-report.md +++ b/scripts/gsap-to-anime/dry-run-report.md @@ -2,79 +2,80 @@ ## Totals -- converted: 24 -- converted-with-warnings: 0 -- manual: 123 +- converted: 39 +- converted-with-warnings: 3 +- manual: 105 - total: 147 ## Manual reason breakdown -- computed-timeline: 102 -- unrecognized-postamble: 95 -- unsupported-property: 82 +- computed-timeline: 99 +- unrecognized-postamble: 40 +- non-selector-target: 33 - splitText: 13 - unsupported-extra: 5 - customEase-beyond-shim: 4 +- attr-wrapper: 3 - keyframes: 1 - plugin:Flip: 1 ## Items -- manual: blocks/app-showcase (computed-timeline, unsupported-property, unrecognized-postamble) -- manual: blocks/apple-money-count (computed-timeline, unsupported-property) +- manual: blocks/app-showcase (computed-timeline) +- manual: blocks/apple-money-count (computed-timeline, non-selector-target) - manual: blocks/blue-sweater-intro-video (unsupported-extra, computed-timeline, keyframes) - manual: blocks/chromatic-radial-split (computed-timeline) - manual: blocks/cinematic-zoom (computed-timeline) -- manual: blocks/code-3d-extrude (computed-timeline, unsupported-property, unrecognized-postamble) -- manual: blocks/code-diff (computed-timeline, unrecognized-postamble) -- manual: blocks/code-highlight (computed-timeline, unrecognized-postamble) +- manual: blocks/code-3d-extrude (non-selector-target, unrecognized-postamble) +- manual: blocks/code-diff (computed-timeline, non-selector-target, unrecognized-postamble) +- manual: blocks/code-highlight (computed-timeline, non-selector-target, unrecognized-postamble) - manual: blocks/code-morph (computed-timeline, unrecognized-postamble) -- manual: blocks/code-particle-assemble (computed-timeline, unsupported-property, unrecognized-postamble) -- manual: blocks/code-scroll (computed-timeline, unrecognized-postamble) -- manual: blocks/code-shader-dissolve (computed-timeline, unsupported-property, unrecognized-postamble) -- manual: blocks/code-snippet-apple-terminal-basic (splitText, computed-timeline, unsupported-property, unrecognized-postamble) -- manual: blocks/code-snippet-apple-terminal-clear-dark (splitText, computed-timeline, unsupported-property, unrecognized-postamble) -- manual: blocks/code-snippet-apple-terminal-clear-light (splitText, computed-timeline, unsupported-property, unrecognized-postamble) -- manual: blocks/code-snippet-apple-terminal-grass (splitText, computed-timeline, unsupported-property, unrecognized-postamble) -- manual: blocks/code-snippet-apple-terminal-homebrew (splitText, computed-timeline, unsupported-property, unrecognized-postamble) -- manual: blocks/code-snippet-apple-terminal-man-page (splitText, computed-timeline, unsupported-property, unrecognized-postamble) -- manual: blocks/code-snippet-apple-terminal-novel (splitText, computed-timeline, unsupported-property, unrecognized-postamble) -- manual: blocks/code-snippet-apple-terminal-ocean (splitText, computed-timeline, unsupported-property, unrecognized-postamble) -- manual: blocks/code-snippet-apple-terminal-pro (splitText, computed-timeline, unsupported-property, unrecognized-postamble) -- manual: blocks/code-snippet-apple-terminal-red-sands (splitText, computed-timeline, unsupported-property, unrecognized-postamble) -- manual: blocks/code-snippet-apple-terminal-silver-aerogel (splitText, computed-timeline, unsupported-property, unrecognized-postamble) -- manual: blocks/code-snippet-apple-terminal-solid-colors (splitText, computed-timeline, unsupported-property, unrecognized-postamble) -- manual: blocks/code-snippet-dark-2026 (computed-timeline, unsupported-property, unrecognized-postamble) -- manual: blocks/code-snippet-dark-modern (computed-timeline, unsupported-property, unrecognized-postamble) -- manual: blocks/code-snippet-dark-plus (computed-timeline, unsupported-property, unrecognized-postamble) -- manual: blocks/code-snippet-flight (computed-timeline, unrecognized-postamble) -- manual: blocks/code-snippet-high-contrast (computed-timeline, unsupported-property, unrecognized-postamble) -- manual: blocks/code-snippet-high-contrast-light (computed-timeline, unsupported-property, unrecognized-postamble) -- manual: blocks/code-snippet-light-2026 (computed-timeline, unsupported-property, unrecognized-postamble) -- manual: blocks/code-snippet-light-modern (computed-timeline, unsupported-property, unrecognized-postamble) -- manual: blocks/code-snippet-light-plus (computed-timeline, unsupported-property, unrecognized-postamble) -- manual: blocks/code-snippet-monokai (computed-timeline, unsupported-property, unrecognized-postamble) -- manual: blocks/code-snippet-solarized-light (computed-timeline, unsupported-property, unrecognized-postamble) -- manual: blocks/code-snippet-visual-studio-dark (computed-timeline, unsupported-property, unrecognized-postamble) -- manual: blocks/code-snippet-visual-studio-light (computed-timeline, unsupported-property, unrecognized-postamble) -- manual: blocks/code-typing (computed-timeline, unrecognized-postamble) +- manual: blocks/code-particle-assemble (computed-timeline, non-selector-target, unrecognized-postamble) +- manual: blocks/code-scroll (computed-timeline, non-selector-target, unrecognized-postamble) +- manual: blocks/code-shader-dissolve (computed-timeline, non-selector-target, unrecognized-postamble) +- manual: blocks/code-snippet-apple-terminal-basic (splitText, computed-timeline, unrecognized-postamble) +- manual: blocks/code-snippet-apple-terminal-clear-dark (splitText, computed-timeline, unrecognized-postamble) +- manual: blocks/code-snippet-apple-terminal-clear-light (splitText, computed-timeline, unrecognized-postamble) +- manual: blocks/code-snippet-apple-terminal-grass (splitText, computed-timeline, unrecognized-postamble) +- manual: blocks/code-snippet-apple-terminal-homebrew (splitText, computed-timeline, unrecognized-postamble) +- manual: blocks/code-snippet-apple-terminal-man-page (splitText, computed-timeline, unrecognized-postamble) +- manual: blocks/code-snippet-apple-terminal-novel (splitText, computed-timeline, unrecognized-postamble) +- manual: blocks/code-snippet-apple-terminal-ocean (splitText, computed-timeline, unrecognized-postamble) +- manual: blocks/code-snippet-apple-terminal-pro (splitText, computed-timeline, unrecognized-postamble) +- manual: blocks/code-snippet-apple-terminal-red-sands (splitText, computed-timeline, unrecognized-postamble) +- manual: blocks/code-snippet-apple-terminal-silver-aerogel (splitText, computed-timeline, unrecognized-postamble) +- manual: blocks/code-snippet-apple-terminal-solid-colors (splitText, computed-timeline, unrecognized-postamble) +- manual: blocks/code-snippet-dark-2026 (computed-timeline, unrecognized-postamble) +- manual: blocks/code-snippet-dark-modern (computed-timeline, unrecognized-postamble) +- manual: blocks/code-snippet-dark-plus (computed-timeline, unrecognized-postamble) +- manual: blocks/code-snippet-flight (computed-timeline, non-selector-target, unrecognized-postamble) +- manual: blocks/code-snippet-high-contrast (computed-timeline, unrecognized-postamble) +- manual: blocks/code-snippet-high-contrast-light (computed-timeline, unrecognized-postamble) +- manual: blocks/code-snippet-light-2026 (computed-timeline, unrecognized-postamble) +- manual: blocks/code-snippet-light-modern (computed-timeline, unrecognized-postamble) +- manual: blocks/code-snippet-light-plus (computed-timeline, unrecognized-postamble) +- manual: blocks/code-snippet-monokai (computed-timeline, unrecognized-postamble) +- manual: blocks/code-snippet-solarized-light (computed-timeline, unrecognized-postamble) +- manual: blocks/code-snippet-visual-studio-dark (computed-timeline, unrecognized-postamble) +- manual: blocks/code-snippet-visual-studio-light (computed-timeline, unrecognized-postamble) +- manual: blocks/code-typing (computed-timeline, non-selector-target, unrecognized-postamble) - manual: blocks/cross-warp-morph (computed-timeline) -- manual: blocks/data-chart (computed-timeline, unsupported-property, unrecognized-postamble) +- manual: blocks/data-chart (computed-timeline, attr-wrapper, non-selector-target) - manual: blocks/domain-warp-dissolve (computed-timeline) - manual: blocks/flash-through-white (computed-timeline) -- manual: blocks/flowchart (computed-timeline, unsupported-property, unsupported-extra, unrecognized-postamble) -- manual: blocks/flowchart-vertical (computed-timeline, unsupported-property, unsupported-extra, unrecognized-postamble) +- manual: blocks/flowchart (computed-timeline, unsupported-extra) +- manual: blocks/flowchart-vertical (computed-timeline, unsupported-extra) - manual: blocks/glitch (computed-timeline) - manual: blocks/gravitational-lens (computed-timeline) - converted: blocks/instagram-follow -- manual: blocks/ios26-liquid-glass (computed-timeline, unsupported-property, customEase-beyond-shim) +- manual: blocks/ios26-liquid-glass (computed-timeline, non-selector-target, customEase-beyond-shim) - manual: blocks/light-leak (computed-timeline) -- manual: blocks/liquid-glass-context-menu (computed-timeline, unsupported-property, unrecognized-postamble) -- manual: blocks/liquid-glass-media-controls (computed-timeline, unsupported-property, unrecognized-postamble) -- manual: blocks/liquid-glass-notification (computed-timeline, unsupported-property, unrecognized-postamble) -- manual: blocks/liquid-glass-widgets (computed-timeline, unsupported-property, unrecognized-postamble) -- manual: blocks/logo-outro (computed-timeline, unrecognized-postamble) -- manual: blocks/lower-third-bild (unrecognized-postamble) +- manual: blocks/liquid-glass-context-menu (non-selector-target) +- manual: blocks/liquid-glass-media-controls (computed-timeline, non-selector-target) +- manual: blocks/liquid-glass-notification (computed-timeline, non-selector-target) +- manual: blocks/liquid-glass-widgets (computed-timeline, non-selector-target) +- manual: blocks/logo-outro (computed-timeline) +- converted: blocks/lower-third-bild - converted: blocks/lt-accent-underline - converted: blocks/lt-bold-block - converted: blocks/lt-clean-bar @@ -86,84 +87,84 @@ - converted: blocks/lt-soft-pill - converted: blocks/lt-stack-bars - converted: blocks/macos-notification -- manual: blocks/macos-tahoe-liquid-glass (computed-timeline, unsupported-property, customEase-beyond-shim) -- manual: blocks/news-ticker (unsupported-property) -- manual: blocks/north-korea-locked-down (unsupported-property) -- manual: blocks/nyc-paris-flight (unsupported-property) -- manual: blocks/reddit-post (computed-timeline, unsupported-property) +- manual: blocks/macos-tahoe-liquid-glass (computed-timeline, non-selector-target, customEase-beyond-shim) +- converted: blocks/news-ticker +- converted-with-warnings: blocks/north-korea-locked-down +- converted-with-warnings: blocks/nyc-paris-flight +- manual: blocks/reddit-post (computed-timeline) - manual: blocks/ridged-burn (computed-timeline) - manual: blocks/ripple-waves (computed-timeline) - manual: blocks/sdf-iris (computed-timeline) -- manual: blocks/spain-map (unsupported-property, unrecognized-postamble) +- converted: blocks/spain-map - converted: blocks/spotify-card - manual: blocks/swirl-vortex (computed-timeline) - manual: blocks/thermal-distortion (computed-timeline) - converted: blocks/tiktok-follow -- manual: blocks/transitions-3d (plugin:Flip, unsupported-property, unrecognized-postamble) -- manual: blocks/transitions-blur (unsupported-property, unrecognized-postamble) -- manual: blocks/transitions-cover (unsupported-property, computed-timeline, unrecognized-postamble) -- manual: blocks/transitions-destruction (computed-timeline, unsupported-property, unrecognized-postamble) -- manual: blocks/transitions-dissolve (unsupported-property, unrecognized-postamble) -- manual: blocks/transitions-distortion (computed-timeline, unrecognized-postamble) -- manual: blocks/transitions-grid (computed-timeline, unrecognized-postamble) -- manual: blocks/transitions-light (unsupported-property, unrecognized-postamble) -- manual: blocks/transitions-mechanical (unsupported-property, unrecognized-postamble) -- manual: blocks/transitions-other (unsupported-property, unrecognized-postamble) -- manual: blocks/transitions-push (unsupported-property, unrecognized-postamble) -- manual: blocks/transitions-radial (unsupported-property, unrecognized-postamble) -- manual: blocks/transitions-scale (unsupported-property, unrecognized-postamble) -- manual: blocks/ui-3d-reveal (computed-timeline, unsupported-property, unrecognized-postamble) -- manual: blocks/us-map (unsupported-property, unrecognized-postamble) -- manual: blocks/us-map-bubble (unsupported-property, computed-timeline, unrecognized-postamble) -- manual: blocks/us-map-flow (computed-timeline, unsupported-property, unrecognized-postamble) -- manual: blocks/us-map-hex (computed-timeline, unrecognized-postamble) -- manual: blocks/vfx-iphone-device (computed-timeline, unsupported-property, customEase-beyond-shim) -- manual: blocks/vfx-liquid-background (splitText, computed-timeline, unsupported-property, unrecognized-postamble) -- manual: blocks/vfx-liquid-glass (computed-timeline, unsupported-property, unrecognized-postamble) -- manual: blocks/vfx-magnetic (computed-timeline, unsupported-property, unrecognized-postamble) -- manual: blocks/vfx-portal (computed-timeline, unsupported-property, unrecognized-postamble) -- manual: blocks/vfx-shatter (computed-timeline, unsupported-property, unrecognized-postamble) -- manual: blocks/vfx-text-cursor (computed-timeline, unsupported-property, customEase-beyond-shim, unrecognized-postamble) -- manual: blocks/vpn-youtube-spot (unsupported-property) +- manual: blocks/transitions-3d (plugin:Flip) +- converted: blocks/transitions-blur +- manual: blocks/transitions-cover (computed-timeline) +- manual: blocks/transitions-destruction (computed-timeline, non-selector-target) +- converted: blocks/transitions-dissolve +- manual: blocks/transitions-distortion (computed-timeline) +- manual: blocks/transitions-grid (computed-timeline) +- converted: blocks/transitions-light +- converted: blocks/transitions-mechanical +- converted: blocks/transitions-other +- converted: blocks/transitions-push +- converted: blocks/transitions-radial +- converted: blocks/transitions-scale +- manual: blocks/ui-3d-reveal (computed-timeline) +- converted: blocks/us-map +- manual: blocks/us-map-bubble (computed-timeline, attr-wrapper) +- manual: blocks/us-map-flow (computed-timeline, non-selector-target) +- manual: blocks/us-map-hex (computed-timeline) +- manual: blocks/vfx-iphone-device (computed-timeline, non-selector-target, customEase-beyond-shim) +- manual: blocks/vfx-liquid-background (splitText, computed-timeline, non-selector-target, unrecognized-postamble) +- manual: blocks/vfx-liquid-glass (non-selector-target, unrecognized-postamble) +- manual: blocks/vfx-magnetic (computed-timeline, non-selector-target, unrecognized-postamble) +- manual: blocks/vfx-portal (computed-timeline, non-selector-target, unrecognized-postamble) +- manual: blocks/vfx-shatter (computed-timeline, non-selector-target, unrecognized-postamble) +- manual: blocks/vfx-text-cursor (computed-timeline, non-selector-target, customEase-beyond-shim) +- converted: blocks/vpn-youtube-spot - manual: blocks/whip-pan (computed-timeline) -- manual: blocks/world-map (computed-timeline, unsupported-property, unrecognized-postamble) +- manual: blocks/world-map (computed-timeline) - manual: blocks/x-post (computed-timeline) - converted: blocks/yt-lower-third - converted: components/caption-blend-difference -- manual: components/caption-clip-wipe (computed-timeline, unrecognized-postamble) -- manual: components/caption-editorial-emphasis (computed-timeline) -- manual: components/caption-emoji-pop (computed-timeline, unrecognized-postamble) -- manual: components/caption-glitch-rgb (computed-timeline, unsupported-property, unrecognized-postamble) -- manual: components/caption-gradient-fill (computed-timeline, unsupported-property, unrecognized-postamble) -- manual: components/caption-highlight (computed-timeline, unrecognized-postamble) -- manual: components/caption-kinetic-slam (computed-timeline, unrecognized-postamble) -- manual: components/caption-matrix-decode (computed-timeline, unsupported-property, unrecognized-postamble) -- manual: components/caption-neon-accent (computed-timeline, unrecognized-postamble) -- manual: components/caption-neon-glow (computed-timeline, unsupported-property, unrecognized-postamble) -- manual: components/caption-parallax-layers (computed-timeline, unrecognized-postamble) -- manual: components/caption-particle-burst (computed-timeline, unrecognized-postamble) -- manual: components/caption-pill-karaoke (unrecognized-postamble) -- manual: components/caption-texture (computed-timeline, unsupported-property, unrecognized-postamble) -- manual: components/caption-weight-shift (computed-timeline, unsupported-property, unrecognized-postamble) +- manual: components/caption-clip-wipe (computed-timeline) +- manual: components/caption-editorial-emphasis (computed-timeline, non-selector-target) +- manual: components/caption-emoji-pop (computed-timeline) +- manual: components/caption-glitch-rgb (computed-timeline) +- manual: components/caption-gradient-fill (computed-timeline) +- manual: components/caption-highlight (computed-timeline) +- manual: components/caption-kinetic-slam (computed-timeline) +- manual: components/caption-matrix-decode (computed-timeline) +- manual: components/caption-neon-accent (computed-timeline) +- manual: components/caption-neon-glow (computed-timeline) +- manual: components/caption-parallax-layers (computed-timeline, non-selector-target, unrecognized-postamble) +- manual: components/caption-particle-burst (computed-timeline) +- converted: components/caption-pill-karaoke +- manual: components/caption-texture (computed-timeline) +- manual: components/caption-weight-shift (computed-timeline) - converted: components/grain-overlay - converted: components/grid-pixelate-wipe -- manual: components/morph-text (computed-timeline, unsupported-property, unrecognized-postamble) +- manual: components/morph-text (computed-timeline, non-selector-target) - converted: components/motion-blur - converted: components/parallax-unzoom - converted: components/parallax-zoom - converted: components/shimmer-sweep - converted: components/texture-mask-text - converted: components/vignette -- manual: examples/airbnb-deck (unrecognized-postamble) -- manual: examples/decision-tree (computed-timeline, unsupported-property, unsupported-extra, unrecognized-postamble) -- manual: examples/kinetic-type (unsupported-property) -- manual: examples/motion-blur (computed-timeline, unsupported-property, unrecognized-postamble) -- manual: examples/nyt-graph (computed-timeline, unsupported-property, unrecognized-postamble) -- manual: examples/play-mode (computed-timeline, unrecognized-postamble) -- manual: examples/product-promo (computed-timeline, unrecognized-postamble, unsupported-property, unsupported-extra) -- manual: examples/slideshow-demo (unrecognized-postamble) -- manual: examples/startup-pitch (unrecognized-postamble) -- manual: examples/swiss-grid (computed-timeline, unsupported-property, unrecognized-postamble) -- manual: examples/vignelli (computed-timeline, unrecognized-postamble, unsupported-property) +- manual: examples/airbnb-deck (non-selector-target) +- manual: examples/decision-tree (computed-timeline, unsupported-extra) +- converted-with-warnings: examples/kinetic-type +- manual: examples/motion-blur (computed-timeline, non-selector-target, unrecognized-postamble) +- manual: examples/nyt-graph (computed-timeline, attr-wrapper, non-selector-target) +- manual: examples/play-mode (computed-timeline) +- manual: examples/product-promo (computed-timeline, unsupported-extra, non-selector-target) +- converted: examples/slideshow-demo +- manual: examples/startup-pitch (non-selector-target) +- manual: examples/swiss-grid (computed-timeline) +- manual: examples/vignelli (computed-timeline) - manual: examples/vscode-theme-visualizer (computed-timeline) -- manual: examples/warm-grain (computed-timeline, unrecognized-postamble, unsupported-property) +- manual: examples/warm-grain (computed-timeline) diff --git a/scripts/gsap-to-anime/gsap-to-anime.test.ts b/scripts/gsap-to-anime/gsap-to-anime.test.ts index b5f78606f1..86fade9721 100644 --- a/scripts/gsap-to-anime/gsap-to-anime.test.ts +++ b/scripts/gsap-to-anime/gsap-to-anime.test.ts @@ -63,6 +63,34 @@ describe("gsap-to-anime transform", () => { assert.equal(result.html, fixture("repeat-yoyo.after.html")); }); + it("ignores unrelated .add calls outside the parsed timeline", () => { + const result = transformHtml(fixture("unrelated-add.before.html")); + + assert.equal(result.classification.status, "converted"); + assert.equal(result.html, fixture("unrelated-add.after.html")); + }); + + it("passes through arbitrary properties and unwraps GSAP attr wrappers", () => { + const result = transformHtml(fixture("passthrough-properties.before.html")); + + assert.equal(result.classification.status, "converted"); + assert.equal(result.html, fixture("passthrough-properties.after.html")); + }); + + it("preserves a trailing IIFE close after timeline registration", () => { + const result = transformHtml(fixture("iife-postamble.before.html")); + + assert.equal(result.classification.status, "converted"); + assert.equal(result.html, fixture("iife-postamble.after.html")); + }); + + it("scopes callback and delay scans to GSAP tween arguments", () => { + const result = transformHtml(fixture("unrelated-callback-config.before.html")); + + assert.equal(result.classification.status, "converted"); + assert.equal(result.html, fixture("unrelated-callback-config.after.html")); + }); + it("classifies motionPath as manual and leaves the file unchanged", () => { const before = fixture("motionpath-manual.before.html"); const result = transformHtml(before); @@ -83,6 +111,17 @@ describe("gsap-to-anime transform", () => { assert.equal(result.html, before); }); + it("classifies real tween callbacks as manual", () => { + const before = fixture("onupdate-manual.before.html"); + const result = transformHtml(before); + + assert.equal(result.classification.status, "manual"); + assert.equal(result.changed, false); + assert.ok(reasonCodes(result).includes("computed-timeline")); + assert.ok(reasonCodes(result).includes("non-selector-target")); + assert.equal(result.html, before); + }); + it("is idempotent on already-converted anime code", () => { const html = fixture("simple-to.after.html"); const result = transformHtml(html); diff --git a/scripts/gsap-to-anime/registration.ts b/scripts/gsap-to-anime/registration.ts index ccb501a6cd..c9eddc2ba5 100644 --- a/scripts/gsap-to-anime/registration.ts +++ b/scripts/gsap-to-anime/registration.ts @@ -23,7 +23,7 @@ export function parseRegistrationPostamble( timelineVar: string, ): RegistrationInfo | null { const trimmed = stripComments(postamble).trim(); - if (trimmed === "") return { id: "main" }; + if (trimmed === "") return { id: "main", trailing: "" }; const withoutSetup = removeRegistrySetup(trimmed); const escapedVar = escapeRegExp(timelineVar); @@ -38,9 +38,13 @@ export function parseRegistrationPostamble( return ""; }); consumed = consumed.replace(push, ""); - return consumed.trim() === "" ? { id } : null; + return isClosingTail(consumed) ? { id, trailing: consumed } : null; } export function stripLegacyRegistrySetup(preamble: string): string { return removeRegistrySetup(preamble); } + +function isClosingTail(source: string): boolean { + return /^[\s});(]*$/.test(source); +} diff --git a/scripts/gsap-to-anime/types.ts b/scripts/gsap-to-anime/types.ts index f428e19dae..20261a2e6b 100644 --- a/scripts/gsap-to-anime/types.ts +++ b/scripts/gsap-to-anime/types.ts @@ -28,6 +28,7 @@ export interface ScriptBlock { export interface RegistrationInfo { id: string; + trailing: string; } export interface RegistryFileReport {