12345678910111213141516171819202122232425262728293031(* Claude Code
*
* Copyright (C) 2026 Yoann Padioleau
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public License
* (LGPL) as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*)(* See Transition.mli *)typerect={x:float;y:float;w:float;h:float}type'kframe={key:'k;rect:rect;alpha:float}type'kt={moves:('k*rect*rect*float*float)list(* from, to, alpha from, alpha to *)}letlerp(a:float)(b:float)(p:float)=a+.((b-.a)*.p)letlerp_rect(a:rect)(b:rect)(p:float):rect={x=lerpa.xb.xp;y=lerpa.yb.yp;w=lerpa.wb.wp;h=lerpa.hb.hp}letcentre(r:rect):rect={x=r.x+.(r.w/.2.);y=r.y+.(r.h/.2.);w=0.;h=0.}letmake?(enter=fun_r->centrer)?(leave=fun_r->centrer)~(before:('k*rect)list)~(after:('k*rect)list)():'kt=letold=Hashtbl.create64inList.iter(fun(k,r)->Hashtbl.replaceoldkr)before;letnow=Hashtbl.create64inList.iter(fun(k,r)->Hashtbl.replacenowkr)after;letmoving=List.map(fun(k,r)->matchHashtbl.find_optoldkwithSomer0->(k,r0,r,1.,1.)|None->(k,enterkr,r,0.,1.))afterinletleaving=List.filter_map(fun(k,r)->ifHashtbl.memnowkthenNoneelseSome(k,r,leavekr,1.,0.))beforein{moves=moving@leaving}letat(t:'kt)(p:float):'kframelist=List.map(fun(key,a,b,fa,fb)->{key;rect=lerp_rectabp;alpha=Float.max0.(Float.min1.(lerpfafbp))})t.moves