| 302 | for (const script of staleScripts) script.remove(); |
| 303 | |
| 304 | const executeScript = () => { |
| 305 | if (win.MotionPathPlugin && win.gsap?.registerPlugin) { |
| 306 | win.gsap.registerPlugin(win.MotionPathPlugin); |
| 307 | } |
| 308 | const s = doc.createElement("script"); |
| 309 | s.textContent = `(function(){${scriptText}\n})();`; |
| 310 | doc.body.appendChild(s); |
| 311 | // Seek BEFORE rebind: __hfForceTimelineRebind's own internal force-render |
| 312 | // (see init.ts) renders the freshly-created timeline at whatever the |
| 313 | // runtime's internal scrub position already is, not at whatever we pass |
| 314 | // here afterward — a redundant seek() call after rebind can be a GSAP |
| 315 | // no-op if the timeline already reports being at that time internally. |
| 316 | win.__player?.seek?.(currentTime); |
| 317 | win.__hfForceTimelineRebind?.(); |
| 318 | win.__hfStudioManualEditsApply?.(); |
| 319 | }; |
| 320 | |
| 321 | const needsMotionPath = /motionPath\s*[:{]/.test(scriptText); |
| 322 | if (needsMotionPath && !win.MotionPathPlugin && win.gsap) { |