@energy8platform/golem 0.7.0 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/editor.js CHANGED
@@ -48944,7 +48944,7 @@ var Key = external_exports.object({
48944
48944
  /** Optional independent easing for numeric-array components (for example Spine RGBA curves). */
48945
48945
  componentEase: external_exports.array(Ease).min(1).optional()
48946
48946
  });
48947
- var Interpolation = { interpolation: external_exports.enum(["segment", "pchip"]).optional() };
48947
+ var Interpolation = { interpolation: external_exports.enum(["segment", "pchip", "spline"]).optional() };
48948
48948
  var Track = external_exports.discriminatedUnion("target", [
48949
48949
  external_exports.object({ target: external_exports.literal("control"), id: Id, prop: external_exports.literal("value"), ...Interpolation, keys: external_exports.array(Key).min(1) }),
48950
48950
  external_exports.object({ target: external_exports.literal("bone"), id: Id, prop: BoneProp, ...Interpolation, keys: external_exports.array(Key).min(1) }),
@@ -49365,6 +49365,57 @@ function smoothValue(track, i6, t5, component, loop2) {
49365
49365
  const u6 = (t5 - k4[i6].t) / h6(i6), u22 = u6 * u6, u32 = u22 * u6;
49366
49366
  return (2 * u32 - 3 * u22 + 1) * v6(i6) + (u32 - 2 * u22 + u6) * h6(i6) * tangent(i6) + (-2 * u32 + 3 * u22) * v6(i6 + 1) + (u32 - u22) * h6(i6) * tangent(i6 + 1);
49367
49367
  }
49368
+ function tridiagonal(a5, b4, c5, r5) {
49369
+ const n4 = b4.length, cp = [], x4 = [];
49370
+ let beta = b4[0];
49371
+ x4[0] = r5[0] / beta;
49372
+ for (let i6 = 1; i6 < n4; i6++) {
49373
+ cp[i6] = c5[i6 - 1] / beta;
49374
+ beta = b4[i6] - a5[i6] * cp[i6];
49375
+ x4[i6] = (r5[i6] - a5[i6] * x4[i6 - 1]) / beta;
49376
+ }
49377
+ for (let i6 = n4 - 2; i6 >= 0; i6--) x4[i6] -= cp[i6 + 1] * x4[i6 + 1];
49378
+ return x4;
49379
+ }
49380
+ function splineMoments(t5, v6, periodic) {
49381
+ const n4 = t5.length, h6 = (j5) => t5[j5 + 1] - t5[j5], d6 = (j5) => (v6[j5 + 1] - v6[j5]) / h6(j5);
49382
+ if (!periodic) {
49383
+ const a6 = [], b5 = [], c6 = [], r7 = [];
49384
+ for (let i6 = 0; i6 < n4; i6++) {
49385
+ const hp = i6 > 0 ? h6(i6 - 1) : 0, hn = i6 < n4 - 1 ? h6(i6) : 0;
49386
+ a6.push(hp);
49387
+ b5.push(2 * (hp + hn));
49388
+ c6.push(hn);
49389
+ r7.push(6 * ((i6 < n4 - 1 ? d6(i6) : 0) - (i6 > 0 ? d6(i6 - 1) : 0)));
49390
+ }
49391
+ return tridiagonal(a6, b5, c6, r7);
49392
+ }
49393
+ const m5 = n4 - 1, a5 = [], b4 = [], c5 = [], r5 = [];
49394
+ for (let i6 = 0; i6 < m5; i6++) {
49395
+ const p6 = (i6 + m5 - 1) % m5;
49396
+ a5.push(h6(p6));
49397
+ b4.push(2 * (h6(p6) + h6(i6)));
49398
+ c5.push(h6(i6));
49399
+ r5.push(6 * (d6(i6) - d6(p6)));
49400
+ }
49401
+ const top = a5[0], bottom = c5[m5 - 1], gamma = -b4[0];
49402
+ const bb = [...b4];
49403
+ bb[0] -= gamma;
49404
+ bb[m5 - 1] -= bottom * top / gamma;
49405
+ const x4 = tridiagonal(a5, bb, c5, r5), u6 = new Array(m5).fill(0);
49406
+ u6[0] = gamma;
49407
+ u6[m5 - 1] = bottom;
49408
+ const z3 = tridiagonal(a5, bb, c5, u6);
49409
+ const f6 = (x4[0] + top * x4[m5 - 1] / gamma) / (1 + z3[0] + top * z3[m5 - 1] / gamma);
49410
+ const M2 = x4.map((xi, i6) => xi - f6 * z3[i6]);
49411
+ return [...M2, M2[0]];
49412
+ }
49413
+ function splineValue(track, i6, t5, component, loop2) {
49414
+ const k4 = track.keys, ts = k4.map((x4) => x4.t), vs = k4.map((x4) => component === void 0 ? x4.v : x4.v[component]);
49415
+ const M2 = splineMoments(ts, vs, loop2 && k4.length > 3 && vs[0] === vs[k4.length - 1]);
49416
+ const H3 = ts[i6 + 1] - ts[i6], A3 = (ts[i6 + 1] - t5) / H3, B3 = (t5 - ts[i6]) / H3;
49417
+ return A3 * vs[i6] + B3 * vs[i6 + 1] + ((A3 ** 3 - A3) * M2[i6] + (B3 ** 3 - B3) * M2[i6 + 1]) * H3 * H3 / 6;
49418
+ }
49368
49419
  function sample(track, t5, loop2 = false) {
49369
49420
  const keys = track.keys;
49370
49421
  if (t5 <= keys[0].t) return keys[0].v;
@@ -49376,11 +49427,13 @@ function sample(track, t5, loop2 = false) {
49376
49427
  if (a5.ease === "step") return a5.v;
49377
49428
  if (typeof a5.v === "number" && typeof b4.v === "number") {
49378
49429
  if (track.interpolation === "pchip") return smoothValue(track, i6, t5, void 0, loop2);
49430
+ if (track.interpolation === "spline") return splineValue(track, i6, t5, void 0, loop2);
49379
49431
  const u6 = ease(a5.ease)((t5 - a5.t) / (b4.t - a5.t));
49380
49432
  return a5.v + (b4.v - a5.v) * u6;
49381
49433
  }
49382
49434
  if (Array.isArray(a5.v) && Array.isArray(b4.v) && typeof a5.v[0] === "number") {
49383
49435
  if (track.interpolation === "pchip") return a5.v.map((_4, j5) => smoothValue(track, i6, t5, j5, loop2));
49436
+ if (track.interpolation === "spline") return a5.v.map((_4, j5) => splineValue(track, i6, t5, j5, loop2));
49384
49437
  const phase = (t5 - a5.t) / (b4.t - a5.t), av = a5.v, bv = b4.v;
49385
49438
  return av.map((v6, k4) => v6 + ((bv[k4] ?? v6) - v6) * ease(a5.componentEase?.[k4] ?? a5.ease)(phase));
49386
49439
  }
@@ -50260,13 +50313,13 @@ function motionQuality(doc2, anim, opts = {}) {
50260
50313
  const before = delta(values(k4.v), values(p6.v)), after = delta(values(n4.v), values(k4.v));
50261
50314
  const pass = before.some((v6, j5) => v6 * after[j5] > 1e-6);
50262
50315
  const speed = Math.max(magnitude(before) / (k4.t - p6.t), magnitude(after) / (n4.t - k4.t));
50263
- if (pass && Math.max(magnitude(left), magnitude(right)) < speed * 0.02) report("pass_key_stop", id, `motion stops at a pass-through key; use track interpolation pchip or matched tangents`, k4.t);
50316
+ if (pass && Math.max(magnitude(left), magnitude(right)) < speed * 0.02) report("pass_key_stop", id, `motion stops at a pass-through key; use track interpolation pchip or spline, or matched tangents`, k4.t);
50264
50317
  const jump = magnitude(delta(left, right));
50265
50318
  if (jump > Math.max(0.1, speed * 0.1)) report("velocity_jump", id, `velocity jumps ${jump.toFixed(3)} units/s across this key`, k4.t);
50266
50319
  const acceleration = (a5, b4, c5) => values(at(b4)).map((v6, j5) => (values(at(c5))[j5] - 2 * v6 + values(at(a5))[j5]) / (h6 * h6));
50267
50320
  const al = acceleration(k4.t - 2 * h6, k4.t - h6, k4.t), ar = acceleration(k4.t, k4.t + h6, k4.t + 2 * h6);
50268
50321
  const aj = magnitude(delta(al, ar));
50269
- if (aj > Math.max(1, speed / Math.min(k4.t - p6.t, n4.t - k4.t) * 2)) report("acceleration_jump", id, `acceleration changes by ${aj.toFixed(2)} units/s\xB2 at this key; PCHIP guarantees velocity, not acceleration continuity`, k4.t, "info");
50322
+ if (aj > Math.max(1, speed / Math.min(k4.t - p6.t, n4.t - k4.t) * 2)) report("acceleration_jump", id, `acceleration changes by ${aj.toFixed(2)} units/s\xB2 at this key; PCHIP guarantees velocity, not acceleration continuity \u2014 spline does both`, k4.t, "info");
50270
50323
  }
50271
50324
  }
50272
50325
  const steps = Math.max(2, Math.ceil(D3 * 60));
@@ -51004,19 +51057,20 @@ var requireSlot = (doc2, id) => {
51004
51057
  if (!s6) throw new Error(`unknown slot "${id}"`);
51005
51058
  return s6;
51006
51059
  };
51007
- function sampled(duration, n4, f6, ease2 = "linear") {
51060
+ function sampled(duration, n4, f6) {
51008
51061
  const keys = [];
51009
51062
  for (let i6 = 0; i6 <= n4; i6++) {
51010
51063
  const t5 = +(duration * i6 / n4).toFixed(4);
51011
- keys.push({ t: t5, v: +f6(t5).toFixed(4) + 0, ease: ease2 });
51064
+ keys.push({ t: t5, v: +f6(t5).toFixed(4) + 0, ease: "linear" });
51012
51065
  }
51013
51066
  return keys;
51014
51067
  }
51015
- function boneTrack(bone, prop, keys) {
51016
- return { target: "bone", id: bone.id, prop, keys };
51068
+ var smooth = "spline";
51069
+ function boneTrack(bone, prop, keys, interpolation) {
51070
+ return { target: "bone", id: bone.id, prop, keys, ...interpolation && { interpolation } };
51017
51071
  }
51018
- function deformTrack(slot, prop, keys) {
51019
- return slot.attachment ? { target: "deform", id: slot.attachment, prop, keys } : void 0;
51072
+ function deformTrack(slot, prop, keys, interpolation) {
51073
+ return slot.attachment ? { target: "deform", id: slot.attachment, prop, keys, ...interpolation && { interpolation } } : void 0;
51020
51074
  }
51021
51075
  var pushTrack = (tracks, t5) => {
51022
51076
  if (t5) tracks.push(t5);
@@ -51040,18 +51094,18 @@ var idleBreathing = {
51040
51094
  const armsR = byRole(doc2, "arm_r", "arm_upper_r");
51041
51095
  const chest = slotOfBone(doc2, torso);
51042
51096
  if (chest?.attachment) {
51043
- pushTrack(tracks, deformTrack(chest, "bulge", sampled(T4, 8, (t5) => p6.amplitude * Math.sin(w5 * t5), "ease_in_out")));
51097
+ pushTrack(tracks, deformTrack(chest, "bulge", sampled(T4, 8, (t5) => p6.amplitude * Math.sin(w5 * t5)), smooth));
51044
51098
  } else {
51045
51099
  const r5 = torso.transform;
51046
- tracks.push(boneTrack(torso, "scaleY", sampled(T4, 8, (t5) => r5.scaleY + p6.amplitude * Math.sin(w5 * t5), "ease_in_out")));
51047
- tracks.push(boneTrack(torso, "scaleX", sampled(T4, 8, (t5) => r5.scaleX - p6.amplitude * 0.4 * Math.sin(w5 * t5), "ease_in_out")));
51100
+ tracks.push(boneTrack(torso, "scaleY", sampled(T4, 8, (t5) => r5.scaleY + p6.amplitude * Math.sin(w5 * t5)), smooth));
51101
+ tracks.push(boneTrack(torso, "scaleX", sampled(T4, 8, (t5) => r5.scaleX - p6.amplitude * 0.4 * Math.sin(w5 * t5)), smooth));
51048
51102
  }
51049
51103
  for (const h6 of heads)
51050
- tracks.push(boneTrack(h6, "y", sampled(T4, 8, (t5) => h6.transform.y - p6.headBob * Math.sin(w5 * t5 + 0.4), "ease_in_out")));
51104
+ tracks.push(boneTrack(h6, "y", sampled(T4, 8, (t5) => h6.transform.y - p6.headBob * Math.sin(w5 * t5 + 0.4)), smooth));
51051
51105
  for (const a5 of armsL)
51052
- tracks.push(boneTrack(a5, "rotation", sampled(T4, 8, (t5) => a5.transform.rotation + p6.armSway * Math.sin(w5 * t5 + 0.8), "ease_in_out")));
51106
+ tracks.push(boneTrack(a5, "rotation", sampled(T4, 8, (t5) => a5.transform.rotation + p6.armSway * Math.sin(w5 * t5 + 0.8)), smooth));
51053
51107
  for (const a5 of armsR)
51054
- tracks.push(boneTrack(a5, "rotation", sampled(T4, 8, (t5) => a5.transform.rotation - p6.armSway * Math.sin(w5 * t5 + 0.8), "ease_in_out")));
51108
+ tracks.push(boneTrack(a5, "rotation", sampled(T4, 8, (t5) => a5.transform.rotation - p6.armSway * Math.sin(w5 * t5 + 0.8)), smooth));
51055
51109
  return finish(this.name, p6.id, T4, true, tracks, p6);
51056
51110
  }
51057
51111
  };
@@ -51060,22 +51114,20 @@ var winBounce = {
51060
51114
  defaults: { id: "win", duration: 1.2, height: 40, bounces: 2, squash: 0.15 },
51061
51115
  build(doc2, p6) {
51062
51116
  const b4 = root(doc2), r5 = b4.transform, tracks = [];
51063
- const yK = [[0, r5.y, "ease_out"]];
51064
- const sxK = [[0, r5.scaleX, "ease_out"]];
51065
- const syK = [[0, r5.scaleY, "ease_out"]];
51117
+ const yK = [[0, r5.y]], sxK = [[0, r5.scaleX]], syK = [[0, r5.scaleY]];
51066
51118
  const per = p6.duration / p6.bounces;
51067
51119
  for (let i6 = 0; i6 < p6.bounces; i6++) {
51068
51120
  const t0 = i6 * per, h6 = p6.height * 0.55 ** i6, s6 = p6.squash * 0.7 ** i6;
51069
- sxK.push([t0 + per * 0.08, r5.scaleX * (1 + s6), "ease_out"], [t0 + per * 0.5, r5.scaleX * (1 - s6 * 0.6), "ease_in"], [t0 + per * 0.95, r5.scaleX * (1 + s6), "ease_out"]);
51070
- syK.push([t0 + per * 0.08, r5.scaleY * (1 - s6), "ease_out"], [t0 + per * 0.5, r5.scaleY * (1 + s6 * 0.6), "ease_in"], [t0 + per * 0.95, r5.scaleY * (1 - s6), "ease_out"]);
51071
- yK.push([t0 + per * 0.08, r5.y, "ease_out"], [t0 + per * 0.5, r5.y - h6, "ease_in"], [t0 + per * 0.95, r5.y, "ease_out"]);
51121
+ sxK.push([t0 + per * 0.08, r5.scaleX * (1 + s6)], [t0 + per * 0.5, r5.scaleX * (1 - s6 * 0.6)], [t0 + per * 0.95, r5.scaleX * (1 + s6)]);
51122
+ syK.push([t0 + per * 0.08, r5.scaleY * (1 - s6)], [t0 + per * 0.5, r5.scaleY * (1 + s6 * 0.6)], [t0 + per * 0.95, r5.scaleY * (1 - s6)]);
51123
+ yK.push([t0 + per * 0.08, r5.y], [t0 + per * 0.5, r5.y - h6], [t0 + per * 0.95, r5.y]);
51072
51124
  }
51073
51125
  yK.push([p6.duration, r5.y]);
51074
51126
  sxK.push([p6.duration, r5.scaleX]);
51075
51127
  syK.push([p6.duration, r5.scaleY]);
51076
- tracks.push(boneTrack(b4, "y", K2(...yK)), boneTrack(b4, "scaleX", K2(...sxK)), boneTrack(b4, "scaleY", K2(...syK)));
51128
+ tracks.push(boneTrack(b4, "y", K2(...yK), "pchip"), boneTrack(b4, "scaleX", K2(...sxK), smooth), boneTrack(b4, "scaleY", K2(...syK), smooth));
51077
51129
  for (const h6 of byRole(doc2, "head"))
51078
- tracks.push(boneTrack(h6, "rotation", K2([0, h6.transform.rotation], [p6.duration * 0.25, h6.transform.rotation - 6, "back_out"], [p6.duration * 0.6, h6.transform.rotation + 4], [p6.duration, h6.transform.rotation])));
51130
+ tracks.push(boneTrack(h6, "rotation", K2([0, h6.transform.rotation], [p6.duration * 0.25, h6.transform.rotation - 6], [p6.duration * 0.6, h6.transform.rotation + 4], [p6.duration, h6.transform.rotation]), smooth));
51079
51131
  const anim = finish(this.name, p6.id, p6.duration, false, tracks, p6);
51080
51132
  anim.events.push({ t: 0, name: "win_start" }, { t: per * 0.95, name: "land" });
51081
51133
  return anim;
@@ -51088,8 +51140,8 @@ var anticipationShake = {
51088
51140
  const b4 = root(doc2), r5 = b4.transform, tracks = [];
51089
51141
  const n4 = Math.ceil(p6.duration * p6.frequency * 4);
51090
51142
  const env = (t5) => p6.grow ? t5 / p6.duration : 1;
51091
- tracks.push(boneTrack(b4, "x", sampled(p6.duration, n4, (t5) => r5.x + p6.amplitude * env(t5) * Math.sin(2 * Math.PI * p6.frequency * t5), "linear")));
51092
- tracks.push(boneTrack(b4, "rotation", sampled(p6.duration, n4, (t5) => r5.rotation + 0.6 * p6.amplitude * env(t5) * Math.sin(2 * Math.PI * p6.frequency * t5 + 1.2), "linear")));
51143
+ tracks.push(boneTrack(b4, "x", sampled(p6.duration, n4, (t5) => r5.x + p6.amplitude * env(t5) * Math.sin(2 * Math.PI * p6.frequency * t5)), smooth));
51144
+ tracks.push(boneTrack(b4, "rotation", sampled(p6.duration, n4, (t5) => r5.rotation + 0.6 * p6.amplitude * env(t5) * Math.sin(2 * Math.PI * p6.frequency * t5 + 1.2)), smooth));
51093
51145
  tracks.push(boneTrack(b4, "scaleX", K2([0, r5.scaleX, "ease_in"], [p6.duration, r5.scaleX * p6.scaleUp])));
51094
51146
  tracks.push(boneTrack(b4, "scaleY", K2([0, r5.scaleY, "ease_in"], [p6.duration, r5.scaleY * p6.scaleUp])));
51095
51147
  return finish(this.name, p6.id, p6.duration, false, tracks, p6);
@@ -51114,6 +51166,7 @@ var mouthTalk = {
51114
51166
  if (!p6.frames.length) throw new Error("mouth_talk: frames must not be empty");
51115
51167
  const n4 = Math.max(1, Math.round(p6.duration * p6.rate));
51116
51168
  const keys = S3(...Array.from({ length: n4 }, (_4, i6) => [+(i6 / p6.rate).toFixed(4), p6.frames[i6 % p6.frames.length]]));
51169
+ if (keys.at(-1).t < p6.duration && keys.at(-1).v !== keys[0].v) keys.push(...S3([p6.duration, keys[0].v]));
51117
51170
  return finish(this.name, p6.id, p6.duration, true, [slotTrack(slot, "attachment", keys)], p6);
51118
51171
  }
51119
51172
  };
@@ -51131,10 +51184,10 @@ var symbolIdle = {
51131
51184
  build(doc2, p6) {
51132
51185
  const b4 = root(doc2), r5 = b4.transform, T4 = p6.period, w5 = 2 * Math.PI / T4, tracks = [];
51133
51186
  const rise = (t5) => 0.5 - 0.5 * Math.cos(w5 * t5);
51134
- tracks.push(boneTrack(b4, "y", sampled(T4, 8, (t5) => r5.y - p6.float * rise(t5), "ease_in_out")));
51135
- if (p6.tilt) tracks.push(boneTrack(b4, "rotation", sampled(T4, 8, (t5) => r5.rotation + p6.tilt * Math.sin(w5 * t5), "ease_in_out")));
51187
+ tracks.push(boneTrack(b4, "y", sampled(T4, 8, (t5) => r5.y - p6.float * rise(t5)), smooth));
51188
+ if (p6.tilt) tracks.push(boneTrack(b4, "rotation", sampled(T4, 8, (t5) => r5.rotation + p6.tilt * Math.sin(w5 * t5)), smooth));
51136
51189
  if (p6.pulse) for (const s6 of doc2.slots.filter((s7) => s7.bone === b4.id && s7.attachment))
51137
- pushTrack(tracks, deformTrack(s6, "bulge", sampled(T4, 8, (t5) => p6.pulse * rise(t5), "ease_in_out")));
51190
+ pushTrack(tracks, deformTrack(s6, "bulge", sampled(T4, 8, (t5) => p6.pulse * rise(t5)), smooth));
51138
51191
  return finish(this.name, p6.id, T4, true, tracks, p6);
51139
51192
  }
51140
51193
  };
@@ -51144,12 +51197,12 @@ var symbolWin = {
51144
51197
  build(doc2, p6) {
51145
51198
  const b4 = root(doc2), r5 = b4.transform, d6 = p6.duration, tracks = [];
51146
51199
  for (const [prop, rest] of [["scaleX", r5.scaleX], ["scaleY", r5.scaleY]])
51147
- tracks.push(boneTrack(b4, prop, K2([0, rest, "ease_out"], [d6 * 0.2, rest * (1 + p6.pop), "ease_in_out"], [d6 * 0.5, rest * (1 - p6.pop * 0.3), "ease_out"], [d6, rest])));
51200
+ tracks.push(boneTrack(b4, prop, K2([0, rest], [d6 * 0.2, rest * (1 + p6.pop)], [d6 * 0.5, rest * (1 - p6.pop * 0.3)], [d6, rest]), smooth));
51148
51201
  if (p6.wobble) {
51149
51202
  const n4 = Math.max(8, p6.wobbles * 4);
51150
- const keys = sampled(d6, n4, (t5) => p6.wobble * Math.exp(-3 * t5 / d6) * Math.sin(2 * Math.PI * p6.wobbles * t5 / d6), "ease_in_out");
51203
+ const keys = sampled(d6, n4, (t5) => p6.wobble * Math.exp(-3 * t5 / d6) * Math.sin(2 * Math.PI * p6.wobbles * t5 / d6));
51151
51204
  keys[keys.length - 1].v = 0;
51152
- for (const s6 of doc2.slots.filter((s7) => s7.bone === b4.id && s7.attachment)) pushTrack(tracks, deformTrack(s6, "sway", keys));
51205
+ for (const s6 of doc2.slots.filter((s7) => s7.bone === b4.id && s7.attachment)) pushTrack(tracks, deformTrack(s6, "sway", keys, smooth));
51153
51206
  }
51154
51207
  const anim = finish(this.name, p6.id, d6, false, tracks, p6);
51155
51208
  anim.events.push({ t: 0, name: "win_start" });
@@ -51163,11 +51216,11 @@ var weightShift = {
51163
51216
  const T4 = p6.period, w5 = 2 * Math.PI / T4, N3 = 16, tracks = [];
51164
51217
  const hips = byRole(doc2, "hips")[0] ?? root(doc2), hr = hips.transform;
51165
51218
  const s6 = (t5) => Math.sin(w5 * t5);
51166
- tracks.push(boneTrack(hips, "x", sampled(T4, N3, (t5) => hr.x + p6.shift * s6(t5))));
51167
- if (p6.dip) tracks.push(boneTrack(hips, "y", sampled(T4, N3, (t5) => hr.y + p6.dip * s6(t5) ** 2)));
51219
+ tracks.push(boneTrack(hips, "x", sampled(T4, N3, (t5) => hr.x + p6.shift * s6(t5)), smooth));
51220
+ if (p6.dip) tracks.push(boneTrack(hips, "y", sampled(T4, N3, (t5) => hr.y + p6.dip * s6(t5) ** 2), smooth));
51168
51221
  const torso = byRole(doc2, "torso", "body")[0];
51169
- if (torso && torso !== hips) tracks.push(boneTrack(torso, "rotation", sampled(T4, N3, (t5) => torso.transform.rotation - p6.lean * s6(t5))));
51170
- for (const h6 of byRole(doc2, "head")) tracks.push(boneTrack(h6, "rotation", sampled(T4, N3, (t5) => h6.transform.rotation + p6.lean / 2 * s6(t5))));
51222
+ if (torso && torso !== hips) tracks.push(boneTrack(torso, "rotation", sampled(T4, N3, (t5) => torso.transform.rotation - p6.lean * s6(t5)), smooth));
51223
+ for (const h6 of byRole(doc2, "head")) tracks.push(boneTrack(h6, "rotation", sampled(T4, N3, (t5) => h6.transform.rotation + p6.lean / 2 * s6(t5)), smooth));
51171
51224
  for (const leg of byRole(doc2, "leg_l", "leg_r")) {
51172
51225
  const slot = slotOfBone(doc2, leg), att = slot && doc2.attachments.find((a5) => a5.id === slot.attachment && a5.type === "region");
51173
51226
  const asset = att && att.type === "region" ? doc2.assets.find((a5) => a5.id === att.asset) : void 0;
@@ -51177,8 +51230,8 @@ var weightShift = {
51177
51230
  length2 = Math.max(...[[0, -h6 / 2], [w6 / 2, 0], [0, h6 / 2], [-w6 / 2, 0]].map(([x4, y5]) => Math.hypot(...apply(m5, x4, y5))));
51178
51231
  }
51179
51232
  if (!(length2 > p6.shift)) continue;
51180
- tracks.push(boneTrack(leg, "rotation", sampled(T4, N3, (t5) => leg.transform.rotation + Math.asin(p6.shift * s6(t5) / length2) * 180 / Math.PI)));
51181
- if (p6.dip) tracks.push(boneTrack(leg, "y", sampled(T4, N3, (t5) => leg.transform.y - p6.dip * s6(t5) ** 2)));
51233
+ tracks.push(boneTrack(leg, "rotation", sampled(T4, N3, (t5) => leg.transform.rotation + Math.asin(p6.shift * s6(t5) / length2) * 180 / Math.PI), smooth));
51234
+ if (p6.dip) tracks.push(boneTrack(leg, "y", sampled(T4, N3, (t5) => leg.transform.y - p6.dip * s6(t5) ** 2), smooth));
51182
51235
  }
51183
51236
  return finish(this.name, p6.id, T4, true, tracks, p6);
51184
51237
  }
@@ -51378,7 +51431,8 @@ function adjustTrack(doc2, animId2, track, adj) {
51378
51431
  return { ...k4, t: r42(adj.timeScale ? k4.t * adj.timeScale : k4.t), v: r42(v6) };
51379
51432
  });
51380
51433
  const duration = Math.max(anim.duration, keys[keys.length - 1].t);
51381
- const next = { ...anim, duration, tracks: anim.tracks.map((t5) => same2(t5) ? { ...t5, keys } : t5), preset: void 0 };
51434
+ const interpolation = track.interpolation ?? tr.interpolation;
51435
+ const next = { ...anim, duration, tracks: anim.tracks.map((t5) => same2(t5) ? { ...t5, keys, ...interpolation && { interpolation } } : t5), preset: void 0 };
51382
51436
  return { ...doc2, animations: doc2.animations.map((a5) => a5.id === animId2 ? next : a5) };
51383
51437
  }
51384
51438
 
@@ -52994,7 +53048,7 @@ function TrackSliders() {
52994
53048
  {
52995
53049
  label: "interpolation",
52996
53050
  value: tr.interpolation ?? "segment",
52997
- options: [["segment", "per-key easing"], ["pchip", "smooth through keys"]],
53051
+ options: [["segment", "per-key easing"], ["pchip", "smooth through keys"], ["spline", "smooth, continuous acceleration"]],
52998
53052
  onCommit: (v6) => void commit("rig_set_keys", { animation: a5.id, ...ref, interpolation: v6, keys: tr.keys })
52999
53053
  }
53000
53054
  );
@@ -53118,7 +53172,7 @@ function KeyEase() {
53118
53172
  const tr = a5.tracks.find((k4) => k4.target === track.target && k4.id === track.id && k4.prop === track.prop);
53119
53173
  const key = tr?.keys.find((k4) => Math.abs(k4.t - times3[0]) < 1e-6);
53120
53174
  if (!key) return null;
53121
- if (tr?.interpolation === "pchip") return /* @__PURE__ */ u4(S, { children: [
53175
+ if (tr?.interpolation === "pchip" || tr?.interpolation === "spline") return /* @__PURE__ */ u4(S, { children: [
53122
53176
  /* @__PURE__ */ u4("h4", { children: [
53123
53177
  "key ",
53124
53178
  fmt2(key.t),