@things-factory/figure-ui 10.1.270 → 10.1.272

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.
Files changed (113) hide show
  1. package/client/graphql/index.ts +2 -0
  2. package/client/modeller/canvas.ts +4 -2
  3. package/client/modeller/clips.ts +74 -4
  4. package/client/modeller/data-interface.ts +14 -0
  5. package/client/modeller/editor-styles.ts +11 -0
  6. package/client/modeller/editor.ts +39 -11
  7. package/client/modeller/fasten-form.ts +73 -3
  8. package/client/modeller/fasten-geometry.ts +11 -1
  9. package/client/modeller/figure-cavity-drawing.ts +1 -3
  10. package/client/modeller/figure-clips.ts +101 -8
  11. package/client/modeller/figure-fasten-dialog.ts +41 -30
  12. package/client/modeller/figure-fasten-drawing.ts +5 -4
  13. package/client/modeller/figure-first-save.ts +4 -3
  14. package/client/modeller/figure-links.ts +85 -28
  15. package/client/modeller/figure-preview.ts +50 -4
  16. package/client/modeller/figure-size-editor.ts +7 -2
  17. package/client/modeller/first-save.ts +8 -0
  18. package/client/modeller/focus-on-render.ts +4 -0
  19. package/client/modeller/palette.ts +27 -0
  20. package/client/modeller/pivot.ts +76 -0
  21. package/client/modeller/product-session.ts +5 -1
  22. package/client/modeller/size-response.ts +14 -0
  23. package/client/modeller/stage-model.ts +50 -6
  24. package/client/types.ts +2 -0
  25. package/dist-client/graphql/index.js +2 -0
  26. package/dist-client/graphql/index.js.map +1 -1
  27. package/dist-client/modeller/canvas.d.ts +1 -0
  28. package/dist-client/modeller/canvas.js +3 -2
  29. package/dist-client/modeller/canvas.js.map +1 -1
  30. package/dist-client/modeller/clips.d.ts +23 -6
  31. package/dist-client/modeller/clips.js +69 -4
  32. package/dist-client/modeller/clips.js.map +1 -1
  33. package/dist-client/modeller/data-interface.d.ts +5 -0
  34. package/dist-client/modeller/data-interface.js +15 -0
  35. package/dist-client/modeller/data-interface.js.map +1 -1
  36. package/dist-client/modeller/editor-styles.js +11 -0
  37. package/dist-client/modeller/editor-styles.js.map +1 -1
  38. package/dist-client/modeller/editor.d.ts +6 -0
  39. package/dist-client/modeller/editor.js +35 -11
  40. package/dist-client/modeller/editor.js.map +1 -1
  41. package/dist-client/modeller/fasten-form.d.ts +8 -0
  42. package/dist-client/modeller/fasten-form.js +68 -5
  43. package/dist-client/modeller/fasten-form.js.map +1 -1
  44. package/dist-client/modeller/fasten-geometry.d.ts +6 -0
  45. package/dist-client/modeller/fasten-geometry.js +10 -1
  46. package/dist-client/modeller/fasten-geometry.js.map +1 -1
  47. package/dist-client/modeller/figure-cavity-drawing.js +1 -3
  48. package/dist-client/modeller/figure-cavity-drawing.js.map +1 -1
  49. package/dist-client/modeller/figure-clips.d.ts +9 -0
  50. package/dist-client/modeller/figure-clips.js +104 -8
  51. package/dist-client/modeller/figure-clips.js.map +1 -1
  52. package/dist-client/modeller/figure-fasten-dialog.js +39 -24
  53. package/dist-client/modeller/figure-fasten-dialog.js.map +1 -1
  54. package/dist-client/modeller/figure-fasten-drawing.js +5 -4
  55. package/dist-client/modeller/figure-fasten-drawing.js.map +1 -1
  56. package/dist-client/modeller/figure-first-save.js +4 -3
  57. package/dist-client/modeller/figure-first-save.js.map +1 -1
  58. package/dist-client/modeller/figure-links.d.ts +9 -0
  59. package/dist-client/modeller/figure-links.js +89 -35
  60. package/dist-client/modeller/figure-links.js.map +1 -1
  61. package/dist-client/modeller/figure-preview.js +48 -4
  62. package/dist-client/modeller/figure-preview.js.map +1 -1
  63. package/dist-client/modeller/figure-size-editor.js +7 -3
  64. package/dist-client/modeller/figure-size-editor.js.map +1 -1
  65. package/dist-client/modeller/first-save.d.ts +5 -0
  66. package/dist-client/modeller/first-save.js +7 -0
  67. package/dist-client/modeller/first-save.js.map +1 -1
  68. package/dist-client/modeller/focus-on-render.d.ts +2 -0
  69. package/dist-client/modeller/focus-on-render.js +4 -0
  70. package/dist-client/modeller/focus-on-render.js.map +1 -0
  71. package/dist-client/modeller/links.d.ts +1 -1
  72. package/dist-client/modeller/palette.d.ts +14 -0
  73. package/dist-client/modeller/palette.js +23 -0
  74. package/dist-client/modeller/palette.js.map +1 -1
  75. package/dist-client/modeller/pivot.d.ts +12 -0
  76. package/dist-client/modeller/pivot.js +59 -0
  77. package/dist-client/modeller/pivot.js.map +1 -0
  78. package/dist-client/modeller/product-session.js +6 -2
  79. package/dist-client/modeller/product-session.js.map +1 -1
  80. package/dist-client/modeller/size-response.d.ts +6 -0
  81. package/dist-client/modeller/size-response.js +14 -0
  82. package/dist-client/modeller/size-response.js.map +1 -1
  83. package/dist-client/modeller/stage-model.d.ts +17 -3
  84. package/dist-client/modeller/stage-model.js +44 -6
  85. package/dist-client/modeller/stage-model.js.map +1 -1
  86. package/dist-client/route.d.ts +1 -1
  87. package/dist-client/tsconfig.tsbuildinfo +1 -1
  88. package/dist-client/types.d.ts +2 -0
  89. package/dist-client/types.js.map +1 -1
  90. package/package.json +5 -5
  91. package/test/browser/editing.check.mjs +6 -5
  92. package/test/browser/section.check.mjs +21 -0
  93. package/test/clips.test.ts +49 -4
  94. package/test/data-motion.test.ts +8 -0
  95. package/test/fasten-form.test.ts +57 -0
  96. package/test/fasten-geometry.test.ts +25 -1
  97. package/test/first-part-on-plane.test.ts +52 -0
  98. package/test/first-save.test.ts +11 -1
  99. package/test/pivot.test.ts +57 -0
  100. package/test/save-landed.test.ts +20 -1
  101. package/test/size-response.test.ts +10 -2
  102. package/test/stage-model.test.ts +23 -1
  103. package/translations/en.json +9 -0
  104. package/translations/es.json +9 -0
  105. package/translations/ja.json +9 -0
  106. package/translations/ko.json +9 -0
  107. package/translations/ms.json +9 -0
  108. package/translations/zh.json +9 -0
  109. package/tutorial/humanoid/README.md +22 -0
  110. package/tutorial/humanoid/chapters.mjs +247 -0
  111. package/tutorial/humanoid/encode.mjs +26 -0
  112. package/tutorial/humanoid/lib.mjs +197 -0
  113. package/tutorial/humanoid/record.mjs +65 -0
@@ -19,6 +19,13 @@ export function clipsOf(asset) {
19
19
  });
20
20
  clips.set(d.clip, clip);
21
21
  }
22
+ /*
23
+ Tracks in the order the controls are listed, not the order their drivers were last written: an edit writes a
24
+ driver anew at the end, and a track keyed jumped to the bottom of its clip (tutorial run 2026-11-12).
25
+ */
26
+ const order = new Map(asset.document.model.inputs.map((i, n) => [i.id, n]));
27
+ for (const clip of clips.values())
28
+ clip.tracks.sort((a, b) => (order.get(a.state) ?? 0) - (order.get(b.state) ?? 0));
22
29
  return [...clips.values()];
23
30
  }
24
31
  /**
@@ -54,6 +61,23 @@ export const groupEdit = (group, patch = {}) => ({
54
61
  kind: 'set-motion-group',
55
62
  group: { id: group.id, label: patch.label ?? group.label, clips: patch.clips ?? group.clips, defaultClip: patch.defaultClip ?? group.defaultClip, transitionSeconds: patch.transitionSeconds ?? group.transitionSeconds }
56
63
  });
64
+ /**
65
+ * The controls a playing clip drives in the preview, each with that clip: a clip in no group played at a speed above 0,
66
+ * or the clip a motion group plays at a speed above 0 (its default until one is chosen).
67
+ */
68
+ export function playedControlsOf(asset, driving, moving) {
69
+ const playing = new Set(Object.entries(driving).filter(([, speed]) => speed > 0).map(([clip]) => clip));
70
+ for (const group of asset.motionGroups ?? []) {
71
+ const m = moving[group.id];
72
+ if (m && m.speed > 0)
73
+ playing.add(m.clip || group.defaultClip);
74
+ }
75
+ const played = new Map();
76
+ for (const d of asset.drivers ?? [])
77
+ if (playing.has(d.clip) && !played.has(d.state))
78
+ played.set(d.state, d.clip);
79
+ return played;
80
+ }
57
81
  /** The pose a clip gives at a moment, as one batch of state changes -- one step of the history. */
58
82
  export function poseAt(asset, clip, seconds) {
59
83
  const units = new Map(asset.document.model.inputs.map(i => [i.id, i.unit]));
@@ -94,6 +118,26 @@ export function withoutKey(keys, index) {
94
118
  return keys.filter((_, i) => i !== index);
95
119
  }
96
120
  /** A name no clip has, for a copy: `walk-copy`, then `walk-copy-2`, … */
121
+ /**
122
+ * A clip copied as one step (review 2026-11-11: a walk copied into a run had to be put in a motion group first, by a
123
+ * section further down, the button grey until then). A copy plays the same controls, so the two are one group: a clip in
124
+ * none is put in a new one, named after it, before it is copied.
125
+ */
126
+ export function copyClipEdits(asset, clip, named = 'motion') {
127
+ const copy = { kind: 'copy-clip', clip, name: freeClipNameOf(asset, clip) };
128
+ if ((asset.motionGroups ?? []).some(g => g.clips.includes(clip)))
129
+ return [copy];
130
+ /*
131
+ The group is named for what it is, not after the first clip: the preview reads "<group> clip · walk | run", and a
132
+ group named "walk" read as if run were a kind of walk (tutorial run 2026-11-12).
133
+ */
134
+ const labels = new Set((asset.motionGroups ?? []).map(g => g.label));
135
+ let label = named;
136
+ for (let n = 2; labels.has(label); n++)
137
+ label = `${named} ${n}`;
138
+ const group = { id: freeGroupIdOf(asset), label, clips: [clip], defaultClip: clip, transitionSeconds: 0.2 };
139
+ return [{ kind: 'set-motion-group', group }, copy];
140
+ }
97
141
  export function freeClipNameOf(asset, clip) {
98
142
  const taken = new Set((asset.drivers ?? []).map(d => d.clip));
99
143
  const base = `${clip}-copy`;
@@ -169,8 +213,8 @@ export function newTrackKeys(input, current, duration, how = 'hold') {
169
213
  * door that has 「닫기」, and the two become one group, one playing at a time, without having to design the group first.
170
214
  * All of it one step of the history.
171
215
  */
172
- export function newClipEdits(asset, state, clip, duration, keys) {
173
- const track = { kind: 'set-driver', state, clip, duration, keys };
216
+ export function newClipEdits(asset, state, clip, duration, keys, interpolation) {
217
+ const track = { kind: 'set-driver', state, clip, duration, keys, ...(interpolation ? { interpolation } : {}) };
174
218
  const writers = [...new Set((asset.drivers ?? []).filter(d => d.state === state).map(d => d.clip))];
175
219
  if (!writers.length)
176
220
  return { edits: [track], join: { kind: 'free' } };
@@ -201,7 +245,27 @@ export function rememberedPoseEdits(asset, clip, seconds, values, base) {
201
245
  const edits = [];
202
246
  for (const track of found.tracks) {
203
247
  const now = values[track.state];
204
- if (now === undefined || same(now, there.get(track.state) ?? now))
248
+ if (now === undefined)
249
+ continue;
250
+ /*
251
+ * A wrapping track's end reads as its start (review 2026-11-11: a walk kept at its end changed nothing, and a pose
252
+ * kept at 0 left the end key behind -- the loop jumped at its seam). So at either end the key there is compared and
253
+ * written itself, and a loop that closed -- start and end alike -- stays closed. A loop left open on purpose (a ramp
254
+ * that starts over) keeps its other end. A track that adds up turns on past its end and is read as before.
255
+ */
256
+ if (shiftable(track) && (at === 0 || at === found.duration)) {
257
+ const keyAt = (s) => track.keys.find(k => k.seconds === s)?.value;
258
+ const start = keyAt(0);
259
+ const end = keyAt(found.duration);
260
+ const mine = at === 0 ? start : end;
261
+ if (same(now, mine ?? (there.get(track.state) ?? now)))
262
+ continue;
263
+ const closed = start !== undefined && end !== undefined && same(start, end);
264
+ const keys = withKey(track.keys, { seconds: at, value: now });
265
+ edits.push(trackEdit(found, track, { keys: closed ? withKey(keys, { seconds: at === 0 ? found.duration : 0, value: now }) : keys }));
266
+ continue;
267
+ }
268
+ if (same(now, there.get(track.state) ?? now))
205
269
  continue;
206
270
  edits.push(trackEdit(found, track, { keys: withKey(track.keys, { seconds: at, value: now }) }));
207
271
  }
@@ -220,7 +284,8 @@ export function rememberedPoseEdits(asset, clip, seconds, values, base) {
220
284
  continue;
221
285
  }
222
286
  const keys = at === 0 ? [{ seconds: 0, value: now }, { seconds: found.duration, value: now }] : [{ seconds: 0, value: was }, { seconds: at, value: now }];
223
- edits.push({ kind: 'set-driver', state: input.id, clip, keys });
287
+ /* A track a kept pose starts goes from pose to pose: eased in and out of each, as a shown move is (motion contract). */
288
+ edits.push({ kind: 'set-driver', state: input.id, clip, keys, interpolation: 'smooth' });
224
289
  }
225
290
  return { edits, skipped };
226
291
  }
@@ -1 +1 @@
1
- {"version":3,"file":"clips.js","sourceRoot":"","sources":["../../client/modeller/clips.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAA;AA4B7E,MAAM,KAAK,GAAG,CAAC,CAAS,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,IAAI,CAAA;AAExD,MAAM,UAAU,OAAO,CAAC,KAAkB;IACxC,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAA;IACvE,MAAM,KAAK,GAAG,IAAI,GAAG,EAAgB,CAAA;IACrC,KAAK,MAAM,CAAC,IAAI,KAAK,CAAC,OAAO,IAAI,EAAE,EAAE,CAAC;QACpC,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAA;QACjC,MAAM,IAAI,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC,IAAI,CAAC,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,CAAA;QACzF,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC;YACf,KAAK,EAAE,CAAC,CAAC,KAAK;YACd,KAAK,EAAE,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,KAAK,IAAI,CAAC,CAAC,KAAK;YACrD,IAAI,EAAE,KAAK,EAAE,IAAI,IAAI,EAAE;YACvB,GAAG,EAAE,KAAK,EAAE,GAAG,IAAI,CAAC;YACpB,GAAG,EAAE,KAAK,EAAE,GAAG,IAAI,CAAC;YACpB,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC;YACnF,aAAa,EAAE,CAAC,CAAC,aAAa;YAC9B,IAAI,EAAE,CAAC,CAAC,IAAI;YACZ,WAAW,EAAE,CAAC,CAAC,WAAW;SAC3B,CAAC,CAAA;QACF,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,CAAA;IACzB,CAAC;IACD,OAAO,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,CAAA;AAC5B,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,UAAU,CAAC,KAAkB,EAAE,IAAI,GAAG,EAAE,EAAE,KAAc;IACtE,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,CAAC,KAAK,CAAC,YAAY,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAU,CAAC,CAAC,CAAC,CAAA;IACtG,MAAM,IAAI,GAAG,KAAK,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAA;IAC5D,MAAM,KAAK,GAAG,CAAC,KAAa,EAAE,EAAE,CAC9B,CAAC,KAAK,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,IAAI,IAAI,KAAK,SAAS,IAAI,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,IAAI,CAAC,CAAC,CAAA;IAC/H,OAAO,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAA;AACnG,CAAC;AAWD,sFAAsF;AACtF,MAAM,UAAU,YAAY,CAAC,KAAkB;IAC7C,MAAM,MAAM,GAAG,CAAC,KAAK,CAAC,YAAY,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAA;IACnF,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAA;IACrD,MAAM,IAAI,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAA;IAC9F,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,CAAA;AACzB,CAAC;AAED,wHAAwH;AACxH,MAAM,UAAU,aAAa,CAAC,KAAkB;IAC9C,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,CAAC,KAAK,CAAC,YAAY,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;IAChE,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC;QAAE,OAAO,QAAQ,CAAA;IACzC,IAAI,CAAC,GAAG,CAAC,CAAA;IACT,OAAO,KAAK,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC;QAAE,CAAC,EAAE,CAAA;IACpC,OAAO,UAAU,CAAC,EAAE,CAAA;AACtB,CAAC;AAED,gGAAgG;AAChG,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,KAAgB,EAAE,QAAwC,EAAE,EAAE,EAAE,CAAC,CAAC;IAC1F,IAAI,EAAE,kBAA2B;IACjC,KAAK,EAAE,EAAE,EAAE,EAAE,KAAK,CAAC,EAAE,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,IAAI,KAAK,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,IAAI,KAAK,CAAC,KAAK,EAAE,WAAW,EAAE,KAAK,CAAC,WAAW,IAAI,KAAK,CAAC,WAAW,EAAE,iBAAiB,EAAE,KAAK,CAAC,iBAAiB,IAAI,KAAK,CAAC,iBAAiB,EAAE;CAC1N,CAAC,CAAA;AAEF,mGAAmG;AACnG,MAAM,UAAU,MAAM,CAAC,KAAkB,EAAE,IAAY,EAAE,OAAe;IACtE,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IAC3E,OAAO,CAAC,KAAK,CAAC,OAAO,IAAI,EAAE,CAAC;SACzB,MAAM,CAAC,CAAC,CAAe,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC;SAC5C,GAAG,CAAC,CAAC,CAAC,EAAE;QACP,MAAM,IAAI,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAE,CAAA;QAChC,OAAO,EAAE,IAAI,EAAE,WAAoB,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,WAAW,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAA;IAChJ,CAAC,CAAC,CAAA;AACN,CAAC;AAED,yFAAyF;AACzF,MAAM,UAAU,OAAO,CAAC,IAAwB,EAAE,GAAY;IAC5D,OAAO,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,KAAK,GAAG,CAAC,OAAO,CAAC,EAAE,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,GAAG,CAAC,CAAC,OAAO,CAAC,CAAA;AACpG,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,cAAc,CAAC,IAAwB,EAAE,KAAa,EAAE,KAAuB,EAAE,QAAgB;IAC/G,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,CAAA;IACvB,IAAI,CAAC,GAAG;QAAE,OAAO,IAAI,CAAA;IACrB,MAAM,IAAI,GAAG,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,IAAI,GAAG,CAAC,OAAO,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,IAAI,GAAG,CAAC,KAAK,EAAE,CAAA;IACvF,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC;QAAE,OAAO,IAAI,CAAA;IAC/E,IAAI,KAAK,KAAK,CAAC,IAAI,IAAI,CAAC,OAAO,KAAK,CAAC;QAAE,OAAO,IAAI,CAAA;IAClD,IAAI,IAAI,CAAC,OAAO,GAAG,CAAC,IAAI,IAAI,CAAC,OAAO,GAAG,QAAQ;QAAE,OAAO,IAAI,CAAA;IAC5D,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,KAAK,IAAI,CAAC,CAAC,OAAO,KAAK,IAAI,CAAC,OAAO,CAAC;QAAE,OAAO,IAAI,CAAA;IAC/E,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,GAAG,CAAC,CAAC,OAAO,CAAC,CAAA;AAC3F,CAAC;AAED,2FAA2F;AAC3F,MAAM,UAAU,UAAU,CAAC,IAAwB,EAAE,KAAa;IAChE,IAAI,IAAI,CAAC,MAAM,IAAI,CAAC,IAAI,KAAK,KAAK,CAAC;QAAE,OAAO,IAAI,CAAA;IAChD,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,KAAK,CAAC,CAAA;AAC3C,CAAC;AAED,yEAAyE;AACzE,MAAM,UAAU,cAAc,CAAC,KAAkB,EAAE,IAAY;IAC7D,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAA;IAC7D,MAAM,IAAI,GAAG,GAAG,IAAI,OAAO,CAAA;IAC3B,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAA;IACjC,IAAI,CAAC,GAAG,CAAC,CAAA;IACT,OAAO,KAAK,CAAC,GAAG,CAAC,GAAG,IAAI,IAAI,CAAC,EAAE,CAAC;QAAE,CAAC,EAAE,CAAA;IACrC,OAAO,GAAG,IAAI,IAAI,CAAC,EAAE,CAAA;AACvB,CAAC;AAED,wGAAwG;AACxG,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,KAAkB,EAAE,IAAY,EAAY,EAAE,CAAC;IAC3E,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,GAAG,UAAU,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC;CAClH,CAAA;AAED;;;GAGG;AACH,MAAM,UAAU,aAAa,CAAC,KAAgB,EAAE,QAAgB,EAAE,OAAe;IAC/E,IAAI,KAAK,CAAC,aAAa,KAAK,QAAQ,IAAI,CAAC,OAAO;QAAE,OAAO,IAAI,CAAA;IAC7D,MAAM,CAAC,GAAG,QAAQ,CAAA;IAClB,MAAM,KAAK,GAAG,CAAC,CAAC,OAAO,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAA;IACrC,MAAM,IAAI,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAA;IAChG,OAAO,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,KAAK,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAA;AACjE,CAAC;AAED,6GAA6G;AAC7G,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,KAAgB,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,KAAK,MAAM,IAAI,CAAC,KAAK,CAAC,WAAW,CAAA;AAE1F;;;GAGG;AACH,MAAM,UAAU,eAAe,CAAC,KAAkB,EAAE,IAAU,EAAE,KAAgB,EAAE,MAAc,EAAE,OAAe;IAC/G,MAAM,MAAM,GAAG,CAAC,KAAK,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,IAAI,IAAI,CAAC,CAAC,KAAK,KAAK,KAAK,CAAC,KAAK,CAAE,CAAA;IAChG,OAAO;QACL,IAAI,EAAE,YAAqB;QAC3B,KAAK,EAAE,MAAM;QACb,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,uBAAuB,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI;QACrE,IAAI,EAAE,KAAK,CAAC,IAAI;QAChB,aAAa,EAAE,KAAK,CAAC,aAAa;QAClC,WAAW,EAAE,KAAK,CAAC,WAAW;KAC/B,CAAA;AACH,CAAC;AAED,yCAAyC;AACzC,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,IAAU,EAAE,KAAgB,EAAE,QAAqE,EAAE,EAAE,EAAE,CAAC,CAAC;IACnI,IAAI,EAAE,YAAqB;IAC3B,KAAK,EAAE,KAAK,CAAC,KAAK;IAClB,IAAI,EAAE,IAAI,CAAC,IAAI;IACf,IAAI,EAAE,KAAK,CAAC,IAAI,IAAI,KAAK,CAAC,IAAI;IAC9B,IAAI,EAAE,KAAK,CAAC,IAAI,IAAI,KAAK,CAAC,IAAI;IAC9B,aAAa,EAAE,KAAK,CAAC,aAAa,IAAI,KAAK,CAAC,aAAa;CAC1D,CAAC,CAAA;AAEF,mGAAmG;AACnG,MAAM,IAAI,GAAG,CAAC,CAAS,EAAE,CAAS,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,IAAI,CAAA;AAE7D;;;;GAIG;AACH,MAAM,UAAU,YAAY,CAAC,KAAqC,EAAE,OAA2B,EAAE,QAAgB,EAAE,MAAwB,MAAM;IAC/I,MAAM,GAAG,GAAG,KAAK,CAAC,GAAG,IAAI,CAAC,CAAA;IAC1B,MAAM,GAAG,GAAG,KAAK,CAAC,GAAG,IAAI,GAAG,CAAA;IAC5B,IAAI,GAAG,KAAK,OAAO;QAAE,OAAO,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE,EAAE,OAAO,EAAE,KAAK,CAAC,QAAQ,GAAG,CAAC,CAAC,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE,EAAE,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,CAAA;IACzI,MAAM,KAAK,GAAG,OAAO,IAAI,GAAG,CAAA;IAC5B,OAAO,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAA;AAC9D,CAAC;AAKD;;;;;;GAMG;AACH,MAAM,UAAU,YAAY,CAAC,KAAkB,EAAE,KAAa,EAAE,IAAY,EAAE,QAAgB,EAAE,IAAe;IAC7G,MAAM,KAAK,GAAG,EAAE,IAAI,EAAE,YAAqB,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAA;IAC1E,MAAM,OAAO,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACnG,IAAI,CAAC,OAAO,CAAC,MAAM;QAAE,OAAO,EAAE,KAAK,EAAE,CAAC,KAAK,CAAC,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,CAAA;IACtE,MAAM,KAAK,GAAG,CAAC,KAAK,CAAC,YAAY,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;IAC1F,IAAI,KAAK;QAAE,OAAO,EAAE,KAAK,EAAE,CAAC,EAAE,GAAG,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,CAAC,EAAE,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,EAAE,CAAA;IAC1H,MAAM,EAAE,GAAG,aAAa,CAAC,KAAK,CAAC,CAAA;IAC/B,MAAM,KAAK,GAAG,KAAK,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,EAAE,KAAK,IAAI,KAAK,CAAA;IACxD,MAAM,KAAK,GAAG,OAAO,CAAC,CAAC,CAAE,CAAA;IACzB,OAAO;QACL,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,kBAA2B,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,KAAK,CAAC,EAAE,WAAW,EAAE,KAAK,EAAE,iBAAiB,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,GAAG,KAAK,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC;QACzJ,IAAI,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE,KAAK,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE;KAC3D,CAAA;AACH,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,mBAAmB,CAAC,KAAkB,EAAE,IAAY,EAAE,OAAe,EAAE,MAA8B,EAAE,IAA4B;IACjJ,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,CAAA;IACvD,IAAI,CAAC,KAAK;QAAE,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,CAAA;IAC7C,MAAM,EAAE,GAAG,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAA;IAChE,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;IAC3E,MAAM,KAAK,GAAc,EAAE,CAAA;IAC3B,KAAK,MAAM,KAAK,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC;QACjC,MAAM,GAAG,GAAG,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAA;QAC/B,IAAI,GAAG,KAAK,SAAS,IAAI,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,GAAG,CAAC;YAAE,SAAQ;QAC3E,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,OAAO,CAAC,KAAK,CAAC,IAAI,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC,CAAA;IACjG,CAAC;IACD,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,UAAU,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,CAAA;IAC7C,MAAM,OAAO,GAAa,EAAE,CAAA;IAC5B,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAA;IACtD,KAAK,MAAM,KAAK,IAAI,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;QAChD,IAAI,KAAK,CAAC,IAAI,KAAK,OAAO,IAAI,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;YAAE,SAAQ;QAC5D,MAAM,GAAG,GAAG,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAA;QAC5B,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAA;QAC1B,IAAI,GAAG,KAAK,SAAS,IAAI,GAAG,KAAK,SAAS,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC;YAAE,SAAQ;QACtE,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC;YACxB,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAA;YACtB,SAAQ;QACV,CAAC;QACD,MAAM,IAAI,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE,EAAE,OAAO,EAAE,KAAK,CAAC,QAAQ,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,CAAA;QACzJ,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,YAAqB,EAAE,KAAK,EAAE,KAAK,CAAC,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAA;IAC1E,CAAC;IACD,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,CAAA;AAC3B,CAAC","sourcesContent":["import { driverValue, figureShiftedDriverKeys } from '@hatiolab/figure-model'\nimport type { FigureAsset, FigureDriver, FigureInputChange } from '@hatiolab/figure-model'\n\n/*\n * The figure's clips: controls played by keys over time, grouped into clips that each run on one\n * clock. Kept apart from the element so the reading is tested without a browser.\n */\nexport interface ClipKey {\n seconds: number\n value: number\n}\nexport interface ClipTrack {\n state: string\n label: string\n unit: string\n min: number\n max: number\n keys: ClipKey[]\n interpolation: 'linear' | 'step' | 'smooth'\n loop: 'wrap' | 'hold'\n accumulates: boolean\n}\nexport interface Clip {\n name: string\n duration: number\n tracks: ClipTrack[]\n}\n\nconst round = (n: number) => Math.round(n * 1000) / 1000\n\nexport function clipsOf(asset: FigureAsset): Clip[] {\n const inputs = new Map(asset.document.model.inputs.map(i => [i.id, i]))\n const clips = new Map<string, Clip>()\n for (const d of asset.drivers ?? []) {\n const input = inputs.get(d.state)\n const clip = clips.get(d.clip) ?? { name: d.clip, duration: d.time.duration, tracks: [] }\n clip.tracks.push({\n state: d.state,\n label: asset.stateInputs?.[d.state]?.label ?? d.state,\n unit: input?.unit ?? '',\n min: input?.min ?? 0,\n max: input?.max ?? 0,\n keys: d.keys.map(k => ({ seconds: round(k.at * d.time.duration), value: k.value })),\n interpolation: d.interpolation,\n loop: d.loop,\n accumulates: d.accumulates\n })\n clips.set(d.clip, clip)\n }\n return [...clips.values()]\n}\n\n/**\n * The controls a new track of `clip` can take (ADR-0051 §3.2): one the clip does not play yet, and that no clip plays\n * outside the clip's motion group -- `group` for a clip not made yet. A clip in no group takes only a control no clip\n * plays. Without a clip, the controls no clip plays at all.\n */\nexport function undrivenOf(asset: FigureAsset, clip = '', group?: string): string[] {\n const groupOf = new Map((asset.motionGroups ?? []).flatMap(g => g.clips.map(c => [c, g.id] as const)))\n const mine = group ?? (clip ? groupOf.get(clip) : undefined)\n const taken = (state: string) =>\n (asset.drivers ?? []).some(d => d.state === state && (d.clip === clip || mine === undefined || groupOf.get(d.clip) !== mine))\n return asset.document.model.inputs.filter(i => i.role === 'state' && !taken(i.id)).map(i => i.id)\n}\n\n/** A motion group as the panel shows it: its setting, and the clips it holds in the clips' order. */\nexport interface ClipGroup {\n id: string\n label: string\n clips: string[]\n defaultClip: string\n transitionSeconds: number\n}\n\n/** The figure's motion groups, and the clips in none -- the ones a group can take. */\nexport function clipGroupsOf(asset: FigureAsset): { groups: ClipGroup[]; free: string[] } {\n const groups = (asset.motionGroups ?? []).map(g => ({ ...g, clips: [...g.clips] }))\n const grouped = new Set(groups.flatMap(g => g.clips))\n const free = [...new Set((asset.drivers ?? []).map(d => d.clip))].filter(c => !grouped.has(c))\n return { groups, free }\n}\n\n/** A group id not yet taken: `motion`, then `motion-2`, `motion-3`, … An id is not made from a label a person types. */\nexport function freeGroupIdOf(asset: FigureAsset): string {\n const taken = new Set((asset.motionGroups ?? []).map(g => g.id))\n if (!taken.has('motion')) return 'motion'\n let n = 2\n while (taken.has(`motion-${n}`)) n++\n return `motion-${n}`\n}\n\n/** The edit that writes a group back with a change: one whole group, as the kernel takes it. */\nexport const groupEdit = (group: ClipGroup, patch: Partial<Omit<ClipGroup, 'id'>> = {}) => ({\n kind: 'set-motion-group' as const,\n group: { id: group.id, label: patch.label ?? group.label, clips: patch.clips ?? group.clips, defaultClip: patch.defaultClip ?? group.defaultClip, transitionSeconds: patch.transitionSeconds ?? group.transitionSeconds }\n})\n\n/** The pose a clip gives at a moment, as one batch of state changes -- one step of the history. */\nexport function poseAt(asset: FigureAsset, clip: string, seconds: number): FigureInputChange[] {\n const units = new Map(asset.document.model.inputs.map(i => [i.id, i.unit]))\n return (asset.drivers ?? [])\n .filter((d: FigureDriver) => d.clip === clip)\n .map(d => {\n const unit = units.get(d.state)!\n return { kind: 'set-state' as const, input: d.state, unit, value: driverValue(d, seconds, unit === 'deg' || unit === 'rad' ? unit : 'other') }\n })\n}\n\n/** A key added at a moment, replacing one already there; the keys stay in time order. */\nexport function withKey(keys: readonly ClipKey[], key: ClipKey): ClipKey[] {\n return [...keys.filter(k => k.seconds !== key.seconds), key].sort((a, b) => a.seconds - b.seconds)\n}\n\n/**\n * A key typed where it stands: its moment, its value, or both. The first key stays at 0 (a track starts there); a moment\n * outside the clip, or on another key's, is refused (null) rather than taking that key's place unseen.\n */\nexport function withKeyChanged(keys: readonly ClipKey[], index: number, patch: Partial<ClipKey>, duration: number): ClipKey[] | null {\n const was = keys[index]\n if (!was) return null\n const next = { seconds: patch.seconds ?? was.seconds, value: patch.value ?? was.value }\n if (!Number.isFinite(next.seconds) || !Number.isFinite(next.value)) return null\n if (index === 0 && next.seconds !== 0) return null\n if (next.seconds < 0 || next.seconds > duration) return null\n if (keys.some((k, i) => i !== index && k.seconds === next.seconds)) return null\n return keys.map((k, i) => (i === index ? next : k)).sort((a, b) => a.seconds - b.seconds)\n}\n\n/** A track's keys without one; a track keeps at least its two ends, as the format asks. */\nexport function withoutKey(keys: readonly ClipKey[], index: number): ClipKey[] | null {\n if (keys.length <= 2 || index === 0) return null\n return keys.filter((_, i) => i !== index)\n}\n\n/** A name no clip has, for a copy: `walk-copy`, then `walk-copy-2`, … */\nexport function freeClipNameOf(asset: FigureAsset, clip: string): string {\n const taken = new Set((asset.drivers ?? []).map(d => d.clip))\n const base = `${clip}-copy`\n if (!taken.has(base)) return base\n let n = 2\n while (taken.has(`${base}-${n}`)) n++\n return `${base}-${n}`\n}\n\n/** The controls a track of `clip` can be copied onto: those it plays already, and those it may take. */\nexport const copyTargetsOf = (asset: FigureAsset, clip: string): string[] => [\n ...new Set([...(asset.drivers ?? []).filter(d => d.clip === clip).map(d => d.state), ...undrivenOf(asset, clip)])\n]\n\n/**\n * Where a smooth track may be moved round its loop to, in seconds later, when `seconds` is not one of them: figure-model\n * moves a smooth track only so that its new start is one of its keys (`driver-shift-off-key`). Null when it may go there.\n */\nexport function shiftOffKeyOf(track: ClipTrack, duration: number, seconds: number): number[] | null {\n if (track.interpolation !== 'smooth' || !seconds) return null\n const D = duration\n const phase = ((seconds % D) + D) % D\n const fits = [...new Set(track.keys.map(k => round((D - k.seconds) % D)))].sort((a, b) => a - b)\n return fits.some(s => Math.abs(s - phase) < 1e-6) ? null : fits\n}\n\n/** Whether a track can be moved round its loop: one that wraps and does not add up (figure-model's rule). */\nexport const shiftable = (track: ClipTrack) => track.loop === 'wrap' && !track.accumulates\n\n/**\n * A track copied onto `target` -- itself, or another control -- played `seconds` later round its loop (robot dog\n * 2026-11-03: a leg's swing half a period after another's). One edit; a track the clip plays on `target` is replaced.\n */\nexport function copiedTrackEdit(asset: FigureAsset, clip: Clip, track: ClipTrack, target: string, seconds: number) {\n const driver = (asset.drivers ?? []).find(d => d.clip === clip.name && d.state === track.state)!\n return {\n kind: 'set-driver' as const,\n state: target,\n clip: clip.name,\n keys: seconds ? figureShiftedDriverKeys(driver, seconds) : track.keys,\n loop: track.loop,\n interpolation: track.interpolation,\n accumulates: track.accumulates\n }\n}\n\n/** The edit that writes a track back. */\nexport const trackEdit = (clip: Clip, track: ClipTrack, patch: Partial<Pick<ClipTrack, 'keys' | 'loop' | 'interpolation'>> = {}) => ({\n kind: 'set-driver' as const,\n state: track.state,\n clip: clip.name,\n keys: patch.keys ?? track.keys,\n loop: patch.loop ?? track.loop,\n interpolation: patch.interpolation ?? track.interpolation\n})\n\n/** Whether two control values are one: the figure's numbers carry float noise past a millionth. */\nconst same = (a: number, b: number) => Math.abs(a - b) < 1e-6\n\n/**\n * A new track's keys. By default it holds the pose the figure stands in now, from start to end: a track added to a pose\n * made with care does not throw it to the control's ends (review 2026-11-09). `range` is the preset that swings the\n * control over its whole range and back, so the loop closes where it began.\n */\nexport function newTrackKeys(input: { min?: number; max?: number }, current: number | undefined, duration: number, how: 'hold' | 'range' = 'hold'): ClipKey[] {\n const min = input.min ?? 0\n const max = input.max ?? min\n if (how === 'range') return [{ seconds: 0, value: min }, { seconds: round(duration / 2), value: max }, { seconds: duration, value: min }]\n const value = current ?? min\n return [{ seconds: 0, value }, { seconds: duration, value }]\n}\n\n/** What a new clip on a control joins, so that it may play it: nothing, a group already there, or a group made with the clip that plays it now. */\nexport type TrackJoin = { kind: 'free' } | { kind: 'group'; group: string; label: string } | { kind: 'new-group'; group: string; label: string; clip: string }\n\n/**\n * The edits that make a new clip `clip` with one track on `state` (ADR-0051 §3.2: only clips of one motion group play\n * one control). A control no clip plays is taken as it is. A control a group's clips play puts the new clip in that\n * group. A control one clip in no group plays makes a group of that clip and the new one -- the person adds 「열기」 to a\n * door that has 「닫기」, and the two become one group, one playing at a time, without having to design the group first.\n * All of it one step of the history.\n */\nexport function newClipEdits(asset: FigureAsset, state: string, clip: string, duration: number, keys: ClipKey[]): { edits: unknown[]; join: TrackJoin } {\n const track = { kind: 'set-driver' as const, state, clip, duration, keys }\n const writers = [...new Set((asset.drivers ?? []).filter(d => d.state === state).map(d => d.clip))]\n if (!writers.length) return { edits: [track], join: { kind: 'free' } }\n const group = (asset.motionGroups ?? []).find(g => writers.some(c => g.clips.includes(c)))\n if (group) return { edits: [{ ...track, group: group.id }], join: { kind: 'group', group: group.id, label: group.label } }\n const id = freeGroupIdOf(asset)\n const label = asset.stateInputs?.[state]?.label ?? state\n const other = writers[0]!\n return {\n edits: [{ kind: 'set-motion-group' as const, group: { id, label, clips: [other], defaultClip: other, transitionSeconds: 0.2 } }, { ...track, group: id }],\n join: { kind: 'new-group', group: id, label, clip: other }\n }\n}\n\n/**\n * 「이 자세 기억하기」: the pose the figure stands in now, kept in `clip` at `seconds` in one step (review 2026-11-09:\n * a six-axis pose was six tracks keyed one by one). A track whose value there differs gets a key; a control the clip\n * does not play yet and that moved since `base` -- the pose the clip was last shown or kept in -- gets a track that\n * starts from where it was and reaches the pose at that moment (from the start when the moment is 0). A moved control\n * another clip outside this clip's group plays is not taken; it is named in `skipped`.\n */\nexport function rememberedPoseEdits(asset: FigureAsset, clip: string, seconds: number, values: Record<string, number>, base: Record<string, number>): { edits: unknown[]; skipped: string[] } {\n const found = clipsOf(asset).find(c => c.name === clip)\n if (!found) return { edits: [], skipped: [] }\n const at = round(Math.min(Math.max(seconds, 0), found.duration))\n const there = new Map(poseAt(asset, clip, at).map(c => [c.input, c.value]))\n const edits: unknown[] = []\n for (const track of found.tracks) {\n const now = values[track.state]\n if (now === undefined || same(now, there.get(track.state) ?? now)) continue\n edits.push(trackEdit(found, track, { keys: withKey(track.keys, { seconds: at, value: now }) }))\n }\n const free = new Set(undrivenOf(asset, clip))\n const skipped: string[] = []\n const played = new Set(found.tracks.map(t => t.state))\n for (const input of asset.document.model.inputs) {\n if (input.role !== 'state' || played.has(input.id)) continue\n const now = values[input.id]\n const was = base[input.id]\n if (now === undefined || was === undefined || same(now, was)) continue\n if (!free.has(input.id)) {\n skipped.push(input.id)\n continue\n }\n const keys = at === 0 ? [{ seconds: 0, value: now }, { seconds: found.duration, value: now }] : [{ seconds: 0, value: was }, { seconds: at, value: now }]\n edits.push({ kind: 'set-driver' as const, state: input.id, clip, keys })\n }\n return { edits, skipped }\n}\n"]}
1
+ {"version":3,"file":"clips.js","sourceRoot":"","sources":["../../client/modeller/clips.ts"],"names":[],"mappings":"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","sourcesContent":["import { driverValue, figureShiftedDriverKeys } from '@hatiolab/figure-model'\nimport type { FigureAsset, FigureDriver, FigureInputChange } from '@hatiolab/figure-model'\n\n/*\n * The figure's clips: controls played by keys over time, grouped into clips that each run on one\n * clock. Kept apart from the element so the reading is tested without a browser.\n */\nexport interface ClipKey {\n seconds: number\n value: number\n}\nexport interface ClipTrack {\n state: string\n label: string\n unit: string\n min: number\n max: number\n keys: ClipKey[]\n interpolation: 'linear' | 'step' | 'smooth'\n loop: 'wrap' | 'hold'\n accumulates: boolean\n}\nexport interface Clip {\n name: string\n duration: number\n tracks: ClipTrack[]\n}\n\nconst round = (n: number) => Math.round(n * 1000) / 1000\n\nexport function clipsOf(asset: FigureAsset): Clip[] {\n const inputs = new Map(asset.document.model.inputs.map(i => [i.id, i]))\n const clips = new Map<string, Clip>()\n for (const d of asset.drivers ?? []) {\n const input = inputs.get(d.state)\n const clip = clips.get(d.clip) ?? { name: d.clip, duration: d.time.duration, tracks: [] }\n clip.tracks.push({\n state: d.state,\n label: asset.stateInputs?.[d.state]?.label ?? d.state,\n unit: input?.unit ?? '',\n min: input?.min ?? 0,\n max: input?.max ?? 0,\n keys: d.keys.map(k => ({ seconds: round(k.at * d.time.duration), value: k.value })),\n interpolation: d.interpolation,\n loop: d.loop,\n accumulates: d.accumulates\n })\n clips.set(d.clip, clip)\n }\n /*\n Tracks in the order the controls are listed, not the order their drivers were last written: an edit writes a\n driver anew at the end, and a track keyed jumped to the bottom of its clip (tutorial run 2026-11-12).\n */\n const order = new Map(asset.document.model.inputs.map((i, n) => [i.id, n]))\n for (const clip of clips.values()) clip.tracks.sort((a, b) => (order.get(a.state) ?? 0) - (order.get(b.state) ?? 0))\n return [...clips.values()]\n}\n\n/**\n * The controls a new track of `clip` can take (ADR-0051 §3.2): one the clip does not play yet, and that no clip plays\n * outside the clip's motion group -- `group` for a clip not made yet. A clip in no group takes only a control no clip\n * plays. Without a clip, the controls no clip plays at all.\n */\nexport function undrivenOf(asset: FigureAsset, clip = '', group?: string): string[] {\n const groupOf = new Map((asset.motionGroups ?? []).flatMap(g => g.clips.map(c => [c, g.id] as const)))\n const mine = group ?? (clip ? groupOf.get(clip) : undefined)\n const taken = (state: string) =>\n (asset.drivers ?? []).some(d => d.state === state && (d.clip === clip || mine === undefined || groupOf.get(d.clip) !== mine))\n return asset.document.model.inputs.filter(i => i.role === 'state' && !taken(i.id)).map(i => i.id)\n}\n\n/** A motion group as the panel shows it: its setting, and the clips it holds in the clips' order. */\nexport interface ClipGroup {\n id: string\n label: string\n clips: string[]\n defaultClip: string\n transitionSeconds: number\n}\n\n/** The figure's motion groups, and the clips in none -- the ones a group can take. */\nexport function clipGroupsOf(asset: FigureAsset): { groups: ClipGroup[]; free: string[] } {\n const groups = (asset.motionGroups ?? []).map(g => ({ ...g, clips: [...g.clips] }))\n const grouped = new Set(groups.flatMap(g => g.clips))\n const free = [...new Set((asset.drivers ?? []).map(d => d.clip))].filter(c => !grouped.has(c))\n return { groups, free }\n}\n\n/** A group id not yet taken: `motion`, then `motion-2`, `motion-3`, … An id is not made from a label a person types. */\nexport function freeGroupIdOf(asset: FigureAsset): string {\n const taken = new Set((asset.motionGroups ?? []).map(g => g.id))\n if (!taken.has('motion')) return 'motion'\n let n = 2\n while (taken.has(`motion-${n}`)) n++\n return `motion-${n}`\n}\n\n/** The edit that writes a group back with a change: one whole group, as the kernel takes it. */\nexport const groupEdit = (group: ClipGroup, patch: Partial<Omit<ClipGroup, 'id'>> = {}) => ({\n kind: 'set-motion-group' as const,\n group: { id: group.id, label: patch.label ?? group.label, clips: patch.clips ?? group.clips, defaultClip: patch.defaultClip ?? group.defaultClip, transitionSeconds: patch.transitionSeconds ?? group.transitionSeconds }\n})\n\n/**\n * The controls a playing clip drives in the preview, each with that clip: a clip in no group played at a speed above 0,\n * or the clip a motion group plays at a speed above 0 (its default until one is chosen).\n */\nexport function playedControlsOf(\n asset: FigureAsset,\n driving: Record<string, number>,\n moving: Record<string, { clip: string; speed: number }>\n): Map<string, string> {\n const playing = new Set(Object.entries(driving).filter(([, speed]) => speed > 0).map(([clip]) => clip))\n for (const group of asset.motionGroups ?? []) {\n const m = moving[group.id]\n if (m && m.speed > 0) playing.add(m.clip || group.defaultClip)\n }\n const played = new Map<string, string>()\n for (const d of asset.drivers ?? []) if (playing.has(d.clip) && !played.has(d.state)) played.set(d.state, d.clip)\n return played\n}\n\n/** The pose a clip gives at a moment, as one batch of state changes -- one step of the history. */\nexport function poseAt(asset: FigureAsset, clip: string, seconds: number): FigureInputChange[] {\n const units = new Map(asset.document.model.inputs.map(i => [i.id, i.unit]))\n return (asset.drivers ?? [])\n .filter((d: FigureDriver) => d.clip === clip)\n .map(d => {\n const unit = units.get(d.state)!\n return { kind: 'set-state' as const, input: d.state, unit, value: driverValue(d, seconds, unit === 'deg' || unit === 'rad' ? unit : 'other') }\n })\n}\n\n/** A key added at a moment, replacing one already there; the keys stay in time order. */\nexport function withKey(keys: readonly ClipKey[], key: ClipKey): ClipKey[] {\n return [...keys.filter(k => k.seconds !== key.seconds), key].sort((a, b) => a.seconds - b.seconds)\n}\n\n/**\n * A key typed where it stands: its moment, its value, or both. The first key stays at 0 (a track starts there); a moment\n * outside the clip, or on another key's, is refused (null) rather than taking that key's place unseen.\n */\nexport function withKeyChanged(keys: readonly ClipKey[], index: number, patch: Partial<ClipKey>, duration: number): ClipKey[] | null {\n const was = keys[index]\n if (!was) return null\n const next = { seconds: patch.seconds ?? was.seconds, value: patch.value ?? was.value }\n if (!Number.isFinite(next.seconds) || !Number.isFinite(next.value)) return null\n if (index === 0 && next.seconds !== 0) return null\n if (next.seconds < 0 || next.seconds > duration) return null\n if (keys.some((k, i) => i !== index && k.seconds === next.seconds)) return null\n return keys.map((k, i) => (i === index ? next : k)).sort((a, b) => a.seconds - b.seconds)\n}\n\n/** A track's keys without one; a track keeps at least its two ends, as the format asks. */\nexport function withoutKey(keys: readonly ClipKey[], index: number): ClipKey[] | null {\n if (keys.length <= 2 || index === 0) return null\n return keys.filter((_, i) => i !== index)\n}\n\n/** A name no clip has, for a copy: `walk-copy`, then `walk-copy-2`, … */\n/**\n * A clip copied as one step (review 2026-11-11: a walk copied into a run had to be put in a motion group first, by a\n * section further down, the button grey until then). A copy plays the same controls, so the two are one group: a clip in\n * none is put in a new one, named after it, before it is copied.\n */\nexport function copyClipEdits(asset: FigureAsset, clip: string, named = 'motion'): unknown[] {\n const copy = { kind: 'copy-clip' as const, clip, name: freeClipNameOf(asset, clip) }\n if ((asset.motionGroups ?? []).some(g => g.clips.includes(clip))) return [copy]\n /*\n The group is named for what it is, not after the first clip: the preview reads \"<group> clip · walk | run\", and a\n group named \"walk\" read as if run were a kind of walk (tutorial run 2026-11-12).\n */\n const labels = new Set((asset.motionGroups ?? []).map(g => g.label))\n let label = named\n for (let n = 2; labels.has(label); n++) label = `${named} ${n}`\n const group = { id: freeGroupIdOf(asset), label, clips: [clip], defaultClip: clip, transitionSeconds: 0.2 }\n return [{ kind: 'set-motion-group' as const, group }, copy]\n}\n\nexport function freeClipNameOf(asset: FigureAsset, clip: string): string {\n const taken = new Set((asset.drivers ?? []).map(d => d.clip))\n const base = `${clip}-copy`\n if (!taken.has(base)) return base\n let n = 2\n while (taken.has(`${base}-${n}`)) n++\n return `${base}-${n}`\n}\n\n/** The controls a track of `clip` can be copied onto: those it plays already, and those it may take. */\nexport const copyTargetsOf = (asset: FigureAsset, clip: string): string[] => [\n ...new Set([...(asset.drivers ?? []).filter(d => d.clip === clip).map(d => d.state), ...undrivenOf(asset, clip)])\n]\n\n/**\n * Where a smooth track may be moved round its loop to, in seconds later, when `seconds` is not one of them: figure-model\n * moves a smooth track only so that its new start is one of its keys (`driver-shift-off-key`). Null when it may go there.\n */\nexport function shiftOffKeyOf(track: ClipTrack, duration: number, seconds: number): number[] | null {\n if (track.interpolation !== 'smooth' || !seconds) return null\n const D = duration\n const phase = ((seconds % D) + D) % D\n const fits = [...new Set(track.keys.map(k => round((D - k.seconds) % D)))].sort((a, b) => a - b)\n return fits.some(s => Math.abs(s - phase) < 1e-6) ? null : fits\n}\n\n/** Whether a track can be moved round its loop: one that wraps and does not add up (figure-model's rule). */\nexport const shiftable = (track: ClipTrack) => track.loop === 'wrap' && !track.accumulates\n\n/**\n * A track copied onto `target` -- itself, or another control -- played `seconds` later round its loop (robot dog\n * 2026-11-03: a leg's swing half a period after another's). One edit; a track the clip plays on `target` is replaced.\n */\nexport function copiedTrackEdit(asset: FigureAsset, clip: Clip, track: ClipTrack, target: string, seconds: number) {\n const driver = (asset.drivers ?? []).find(d => d.clip === clip.name && d.state === track.state)!\n return {\n kind: 'set-driver' as const,\n state: target,\n clip: clip.name,\n keys: seconds ? figureShiftedDriverKeys(driver, seconds) : track.keys,\n loop: track.loop,\n interpolation: track.interpolation,\n accumulates: track.accumulates\n }\n}\n\n/** The edit that writes a track back. */\nexport const trackEdit = (clip: Clip, track: ClipTrack, patch: Partial<Pick<ClipTrack, 'keys' | 'loop' | 'interpolation'>> = {}) => ({\n kind: 'set-driver' as const,\n state: track.state,\n clip: clip.name,\n keys: patch.keys ?? track.keys,\n loop: patch.loop ?? track.loop,\n interpolation: patch.interpolation ?? track.interpolation\n})\n\n/** Whether two control values are one: the figure's numbers carry float noise past a millionth. */\nconst same = (a: number, b: number) => Math.abs(a - b) < 1e-6\n\n/**\n * A new track's keys. By default it holds the pose the figure stands in now, from start to end: a track added to a pose\n * made with care does not throw it to the control's ends (review 2026-11-09). `range` is the preset that swings the\n * control over its whole range and back, so the loop closes where it began.\n */\nexport function newTrackKeys(input: { min?: number; max?: number }, current: number | undefined, duration: number, how: 'hold' | 'range' = 'hold'): ClipKey[] {\n const min = input.min ?? 0\n const max = input.max ?? min\n if (how === 'range') return [{ seconds: 0, value: min }, { seconds: round(duration / 2), value: max }, { seconds: duration, value: min }]\n const value = current ?? min\n return [{ seconds: 0, value }, { seconds: duration, value }]\n}\n\n/** What a new clip on a control joins, so that it may play it: nothing, a group already there, or a group made with the clip that plays it now. */\nexport type TrackJoin = { kind: 'free' } | { kind: 'group'; group: string; label: string } | { kind: 'new-group'; group: string; label: string; clip: string }\n\n/**\n * The edits that make a new clip `clip` with one track on `state` (ADR-0051 §3.2: only clips of one motion group play\n * one control). A control no clip plays is taken as it is. A control a group's clips play puts the new clip in that\n * group. A control one clip in no group plays makes a group of that clip and the new one -- the person adds 「열기」 to a\n * door that has 「닫기」, and the two become one group, one playing at a time, without having to design the group first.\n * All of it one step of the history.\n */\nexport function newClipEdits(\n asset: FigureAsset,\n state: string,\n clip: string,\n duration: number,\n keys: ClipKey[],\n interpolation?: ClipTrack['interpolation']\n): { edits: unknown[]; join: TrackJoin } {\n const track = { kind: 'set-driver' as const, state, clip, duration, keys, ...(interpolation ? { interpolation } : {}) }\n const writers = [...new Set((asset.drivers ?? []).filter(d => d.state === state).map(d => d.clip))]\n if (!writers.length) return { edits: [track], join: { kind: 'free' } }\n const group = (asset.motionGroups ?? []).find(g => writers.some(c => g.clips.includes(c)))\n if (group) return { edits: [{ ...track, group: group.id }], join: { kind: 'group', group: group.id, label: group.label } }\n const id = freeGroupIdOf(asset)\n const label = asset.stateInputs?.[state]?.label ?? state\n const other = writers[0]!\n return {\n edits: [{ kind: 'set-motion-group' as const, group: { id, label, clips: [other], defaultClip: other, transitionSeconds: 0.2 } }, { ...track, group: id }],\n join: { kind: 'new-group', group: id, label, clip: other }\n }\n}\n\n/**\n * 「이 자세 기억하기」: the pose the figure stands in now, kept in `clip` at `seconds` in one step (review 2026-11-09:\n * a six-axis pose was six tracks keyed one by one). A track whose value there differs gets a key; a control the clip\n * does not play yet and that moved since `base` -- the pose the clip was last shown or kept in -- gets a track that\n * starts from where it was and reaches the pose at that moment (from the start when the moment is 0). A moved control\n * another clip outside this clip's group plays is not taken; it is named in `skipped`.\n */\nexport function rememberedPoseEdits(asset: FigureAsset, clip: string, seconds: number, values: Record<string, number>, base: Record<string, number>): { edits: unknown[]; skipped: string[] } {\n const found = clipsOf(asset).find(c => c.name === clip)\n if (!found) return { edits: [], skipped: [] }\n const at = round(Math.min(Math.max(seconds, 0), found.duration))\n const there = new Map(poseAt(asset, clip, at).map(c => [c.input, c.value]))\n const edits: unknown[] = []\n for (const track of found.tracks) {\n const now = values[track.state]\n if (now === undefined) continue\n /*\n * A wrapping track's end reads as its start (review 2026-11-11: a walk kept at its end changed nothing, and a pose\n * kept at 0 left the end key behind -- the loop jumped at its seam). So at either end the key there is compared and\n * written itself, and a loop that closed -- start and end alike -- stays closed. A loop left open on purpose (a ramp\n * that starts over) keeps its other end. A track that adds up turns on past its end and is read as before.\n */\n if (shiftable(track) && (at === 0 || at === found.duration)) {\n const keyAt = (s: number) => track.keys.find(k => k.seconds === s)?.value\n const start = keyAt(0)\n const end = keyAt(found.duration)\n const mine = at === 0 ? start : end\n if (same(now, mine ?? (there.get(track.state) ?? now))) continue\n const closed = start !== undefined && end !== undefined && same(start, end)\n const keys = withKey(track.keys, { seconds: at, value: now })\n edits.push(trackEdit(found, track, { keys: closed ? withKey(keys, { seconds: at === 0 ? found.duration : 0, value: now }) : keys }))\n continue\n }\n if (same(now, there.get(track.state) ?? now)) continue\n edits.push(trackEdit(found, track, { keys: withKey(track.keys, { seconds: at, value: now }) }))\n }\n const free = new Set(undrivenOf(asset, clip))\n const skipped: string[] = []\n const played = new Set(found.tracks.map(t => t.state))\n for (const input of asset.document.model.inputs) {\n if (input.role !== 'state' || played.has(input.id)) continue\n const now = values[input.id]\n const was = base[input.id]\n if (now === undefined || was === undefined || same(now, was)) continue\n if (!free.has(input.id)) {\n skipped.push(input.id)\n continue\n }\n const keys = at === 0 ? [{ seconds: 0, value: now }, { seconds: found.duration, value: now }] : [{ seconds: 0, value: was }, { seconds: at, value: now }]\n /* A track a kept pose starts goes from pose to pose: eased in and out of each, as a shown move is (motion contract). */\n edits.push({ kind: 'set-driver' as const, state: input.id, clip, keys, interpolation: 'smooth' as const })\n }\n return { edits, skipped }\n}\n"]}
@@ -122,6 +122,11 @@ export declare function sampleOf(asset: FigureAsset, sample: unknown, legends?:
122
122
  uses: Readonly<Record<string, FigureTableUse>>;
123
123
  notes: FigureRuntimeIssue[];
124
124
  };
125
+ /**
126
+ * The state inputs a sample of data sets on this figure, by id: what the preview shows for them instead of a slider. None
127
+ * when there is no sample, or the figure refuses it.
128
+ */
129
+ export declare function sampledStatesOf(asset: FigureAsset, sample: unknown): Record<string, number>;
125
130
  /** The rows a person gives a value by hand, as a board's saved values: one value, read by a binding, not inside a list. */
126
131
  export declare const valueRowsOf: (asset: FigureAsset) => FigureDataRow[];
127
132
  /**
@@ -340,6 +340,21 @@ export function sampleOf(asset, sample, legends = {}) {
340
340
  notes: inputs.diagnostics().filter(i => i.severity === 'note')
341
341
  };
342
342
  }
343
+ /**
344
+ * The state inputs a sample of data sets on this figure, by id: what the preview shows for them instead of a slider. None
345
+ * when there is no sample, or the figure refuses it.
346
+ */
347
+ export function sampledStatesOf(asset, sample) {
348
+ if (sample === null || sample === undefined || !asset.dataInterface)
349
+ return {};
350
+ try {
351
+ const read = sampleOf(asset, sample);
352
+ return read.issues.length ? {} : Object.fromEntries(Object.entries(read.result.states).map(([id, s]) => [id, s.value]));
353
+ }
354
+ catch {
355
+ return {};
356
+ }
357
+ }
343
358
  /** The rows a person gives a value by hand, as a board's saved values: one value, read by a binding, not inside a list. */
344
359
  export const valueRowsOf = (asset) => schemaRowsOf(asset).filter(r => isValue(r.node) && r.bindings.length > 0 && !r.path.includes('[]'));
345
360
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"data-interface.js","sourceRoot":"","sources":["../../client/modeller/data-interface.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * The figure's data and what it moves (ADR-0051 §8, ADR-0166): what the data tab offers and shows -- one binding, its\n * method as the field's kind allows (as it is, scaled, a code table, a range table). Every rule is figure-model's -- which accessor holds, which rule's results a behavior takes -- and the reading\n * of data is things-scene's; this only lists what there is to choose, drafts a binding the kernel then checks, and edits\n * the schema as a tree. Kept apart from the element so it is tested without a browser.\n */\nimport { FIGURE_PART_ID, FIGURE_MOTION_SPEED_MAX, FigureContractError, figureAxesOf, figureDataRows, motionStateIdOf, parseFigureAccessor } from '@hatiolab/figure-model'\nimport type {\n FigureAsset,\n FigureDataBehavior,\n FigureDataBinding,\n FigureDataField,\n FigureDataNode,\n FigureDataRow,\n FigureDataTableBinding,\n FigureDataTableEntry,\n FigureDataTargets,\n FigureDataValue,\n FigureDataValueBinding,\n FigureDataValueIssue,\n FigureProposalStep\n} from '@hatiolab/figure-model'\nimport { FigureInputs, type FigureDataResult, type FigureRuntimeIssue, type FigureTableUse } from '@hatiolab/things-scene'\n\n/** Something a binding can move, with what the screen shows of it. */\nexport interface BehaviorChoice {\n /** One string per behavior, for a select's value. */\n key: string\n behavior: FigureDataBehavior\n /** The screen's word for the kind: a control, a colour, a group's clip, … */\n kind: FigureDataBehavior['kind']\n /** The control's label, the colour token, the group's label, the axis. */\n name: string\n unit?: string\n min?: number\n max?: number\n /** A motion group's clips. */\n clips?: string[]\n}\n\nexport const behaviorKeyOf = (b: FigureDataBehavior): string =>\n b.kind === 'state'\n ? `state:${b.input}`\n : b.kind === 'palette'\n ? `palette:${b.token}`\n : b.kind === 'pose'\n ? `pose:${b.axis}`\n : b.kind === 'items'\n ? `items:${b.slot ?? ''}`\n : `${b.kind}:${b.group}`\n\n/**\n * Everything a value binding may drive: each control, each colour, each motion group's clip, speed and pause, its\n * position and heading, and -- when it has places -- the items in them.\n */\nexport function behaviorsOf(asset: FigureAsset): BehaviorChoice[] {\n const out: BehaviorChoice[] = []\n const add = (behavior: FigureDataBehavior, name: string, more: Partial<BehaviorChoice> = {}) => out.push({ key: behaviorKeyOf(behavior), behavior, kind: behavior.kind, name, ...more })\n for (const input of asset.document.model.inputs) {\n if (input.role !== 'state') continue\n add({ kind: 'state', input: input.id, sourceMode: 'observed' }, asset.stateInputs?.[input.id]?.label ?? input.id, { unit: input.unit, min: input.min, max: input.max })\n }\n for (const token of Object.keys(asset.palette)) add({ kind: 'palette', token }, token)\n for (const group of asset.motionGroups ?? []) {\n add({ kind: 'motion-clip', group: group.id }, group.label, { clips: [...group.clips] })\n add({ kind: 'motion-speed', group: group.id }, group.label, { min: 0, max: FIGURE_MOTION_SPEED_MAX })\n add({ kind: 'motion-paused', group: group.id }, group.label)\n }\n for (const axis of ['x', 'z', 'y', 'heading'] as const) add({ kind: 'pose', axis, seconds: 1 }, axis, { unit: axis === 'heading' ? 'deg' : 'mm' })\n if (asset.document.capabilities.slotLayout || asset.document.capabilities.names?.includes('Holdable')) add({ kind: 'items' }, asset.document.capabilities.slotLayout?.label ?? 'items')\n return out\n}\n\nconst isValue = (n: FigureDataNode): n is Extract<FigureDataNode, { kind: 'number' | 'boolean' | 'text' }> => n.kind === 'number' || n.kind === 'boolean' || n.kind === 'text'\n\n/**\n * Whether a field of this kind drives the behavior as it is or scaled -- the choices a value binding offers for it. A\n * value that picks a look per code is a table (ADR-0166 2).\n */\nexport function fitsField(node: FigureDataNode, choice: BehaviorChoice): boolean {\n if (choice.kind === 'items') return node.kind === 'list' || node.kind === 'text' || node.kind === 'number'\n if (!isValue(node)) return false\n if (choice.kind === 'motion-paused') return node.kind === 'boolean'\n if (choice.kind === 'palette') return node.kind === 'text' && !!node.values?.every(v => /^#[0-9a-f]{6}$/i.test(v))\n if (choice.kind === 'motion-clip') {\n const clips = choice.behavior.kind === 'motion-clip' ? choice.clips : undefined\n return node.kind === 'text' && !!node.values && (!clips || node.values.every(v => clips.includes(v)))\n }\n return node.kind === 'number'\n}\n\n/** How a binding turns a value into what the figure shows (ADR-0166 1): the screen's four methods, figure-viewer's words for every screen. */\nimport { methodOf, type DataMethod } from '@things-factory/figure-viewer/dist-client/data-connection.js'\nexport { methodOf, type DataMethod }\n\n/**\n * The methods a field allows (ADR-0166 2): a number as it is, scaled or by a range table; a text or true/false by a code\n * table, or as it is where a behavior takes it so; a list as it is (its items). A new field is made by a table.\n */\nexport function methodsOf(node: FigureDataNode | null, choices: BehaviorChoice[]): DataMethod[] {\n if (!node) return ['code', 'ranges']\n const fitting = choices.some(c => fitsField(node, c))\n if (node.kind === 'number') return [...(fitting ? (['value', 'scale'] as const) : []), 'ranges']\n if (node.kind === 'text' || node.kind === 'boolean') return [...(fitting ? (['value'] as const) : []), 'code']\n return fitting ? ['value'] : []\n}\n\n/** The method a binding is shown by. */\n\n/** An id not taken among `taken`: `base`, then `base-2`, `base-3`, … made into the kernel's id shape. */\nexport function freeIdOf(taken: Iterable<string>, base: string): string {\n const used = new Set(taken)\n const cleaned = base.replace(/[^a-zA-Z0-9_-]+/g, '-').replace(/^[^a-zA-Z]+/, '').replace(/-+$/, '') || 'binding'\n const id = FIGURE_PART_ID.test(cleaned) ? cleaned : 'binding'\n if (!used.has(id)) return id\n let n = 2\n while (used.has(`${id}-${n}`)) n++\n return `${id}-${n}`\n}\n\n/** How many mm, or degrees, one of a unit is: only lengths and angles are converted. */\nconst TO_MM: Record<string, number> = { mm: 1, cm: 10, m: 1000 }\nconst TO_DEG: Record<string, number> = { deg: 1, rad: 180 / Math.PI }\n\n/** The values a closed field takes: a closed text's values, both booleans. Empty when open. */\nexport const domainOf = (node: FigureDataNode): FigureDataValue[] => (node.kind === 'boolean' ? [false, true] : node.kind === 'text' && node.values ? [...node.values] : [])\n\n/**\n * A first value binding of a field to a behavior, for the author to adjust: the value as it is when it already fits, a\n * scale when only its unit or range differs -- or the method the author chose. The kernel says whether it holds.\n */\nexport function bindingDraftOf(asset: FigureAsset, accessor: string, node: FigureDataNode, choice: BehaviorChoice, method?: 'value' | 'scale'): FigureDataValueBinding {\n const taken = (asset.dataInterface?.bindings ?? []).map(b => b.id)\n const name = accessor.replace(/\\[\\d+\\]/g, '').split('.').pop() ?? accessor\n const id = freeIdOf(taken, `${name}-${choice.kind === 'state' ? (choice.behavior as { input: string }).input : choice.kind}`)\n const behavior = choice.behavior\n const make = (rule: 'value' | 'scale', param?: FigureDataValueBinding['param']): FigureDataValueBinding => ({ id, accessor, behavior, rule, ...(param ? { param } : {}) })\n\n if (behavior.kind === 'items') {\n if (node.kind !== 'list') return make('value')\n const fields = node.item.kind === 'object' ? node.item.fields : []\n const pick = (...words: RegExp[]) => fields.find(f => isValue(f) && words.some(w => w.test(f.name)))?.name\n const itemId = pick(/^id$/i, /name$/i, /id$/i) ?? fields.find(isValue)?.name\n const type = pick(/type$/i)\n const place = pick(/^slot/i, /place/i, /port/i)\n const stack = pick(/stack/i, /level/i)\n return { id, accessor, behavior: { kind: 'items', ...(itemId ? { id: itemId } : {}), ...(type ? { type } : {}), ...(place ? { place } : {}), ...(stack ? { stack } : {}) }, rule: 'value' }\n }\n if (node.kind !== 'number') return make('value')\n if (behavior.kind === 'pose') {\n const want = behavior.axis === 'heading' ? TO_DEG : TO_MM\n const unit = node.unit ?? ''\n if (method === 'value' || unit === (behavior.axis === 'heading' ? 'deg' : 'mm') || (method === undefined && !(unit in want))) return make('value')\n return make('scale', { scale: want[unit] ?? 1, offset: 0 })\n }\n /* state and motion-speed: a number into a range. */\n const [lo, hi, unit] =\n behavior.kind === 'motion-speed' ? [0, FIGURE_MOTION_SPEED_MAX, 'ratio'] : [choice.min ?? 0, choice.max ?? 1, choice.unit ?? '']\n const sameUnit = behavior.kind === 'motion-speed' ? node.unit === undefined || node.unit === 'ratio' : node.unit === unit\n const inside = node.min !== undefined && node.max !== undefined && node.min >= lo && node.max <= hi\n if (method === 'value' || (method === undefined && sameUnit && inside)) return make('value')\n if (node.min !== undefined && node.max !== undefined && node.max > node.min) {\n /* The field's range laid onto the behavior's. */\n const scale = (hi - lo) / (node.max - node.min)\n return make('scale', { scale: round(scale), offset: round(lo - scale * node.min) })\n }\n return method === 'scale' ? make('scale', { scale: 1, offset: 0 }) : make('value')\n}\n\n/* ---------------------------------------------------------------- tables (ADR-0166 3) */\n\n/** The first code a new code table names, and the next ones: `CODE`, `CODE2`, … */\nexport function freeCodeOf(taken: string[]): string {\n if (!taken.includes('CODE')) return 'CODE'\n let n = 2\n while (taken.includes(`CODE${n}`)) n++\n return `CODE${n}`\n}\n\n/** A legend role from a binding's id: lower case letters, digits and `-`. */\nexport const legendRoleOf = (id: string): string =>\n id\n .toLowerCase()\n .replace(/[^a-z0-9-]+/g, '-')\n .replace(/^-+|-+$/g, '') || 'legend'\n\n/**\n * A first table on a field (ADR-0166 10): a row per value of a closed field, an open field's rows typed later, one\n * interval over the whole of a number. A new field is made by the table (P2): a code table's a text whose values are the\n * table's keys, starting with one code; a range table's a number. Returns the binding and, for a new field, the schema\n * with it.\n */\nexport function tableDraftOf(\n asset: FigureAsset,\n field: { path: string; node: FigureDataNode } | { name: string },\n method: 'code' | 'ranges',\n targets: FigureDataTargets\n): { binding: FigureDataTableBinding; schema?: FigureDataField[] } {\n const taken = (asset.dataInterface?.bindings ?? []).map(b => b.id)\n const made = 'name' in field\n const name = made ? field.name : (field.path.replace(/\\[\\]/g, '').split('.').pop() ?? field.path)\n const id = freeIdOf(taken, name.toLowerCase())\n const node: FigureDataNode = made ? (method === 'code' ? { kind: 'text', values: ['CODE'] } : { kind: 'number' }) : field.node\n const accessor = made ? field.name : accessorOfRow(field.path)\n const table: Record<string, FigureDataTableEntry> =\n method === 'code' ? Object.fromEntries(domainOf(node).map(v => [String(v), {}])) : { [`${node.kind === 'number' ? (node.min ?? '') : ''}~`]: {} }\n const binding: FigureDataTableBinding = { id, accessor, rule: 'table', lookup: method, targets: tidyTargets(targets), table }\n if (!made) return { binding }\n const schema = [...(asset.dataInterface?.schema ?? []), { name: field.name, ...node } as FigureDataField]\n return { binding, schema }\n}\n\n/** Targets with empty lists left out, as the kernel keeps them. */\nconst tidyTargets = (t: FigureDataTargets): FigureDataTargets => ({\n ...(t.parts?.length ? { parts: [...t.parts] } : {}),\n ...(t.inputs?.length ? { inputs: [...t.inputs] } : {}),\n ...(t.group ? { group: t.group } : {})\n})\n\n/** A look with only the columns its targets take: a target taken away takes its columns with it. */\nfunction lookFor(look: FigureDataTableEntry, t: FigureDataTargets): FigureDataTableEntry {\n const out: FigureDataTableEntry = {}\n if (t.parts?.length) {\n if (look.color !== undefined) out.color = look.color\n if (look.effect !== undefined) out.effect = look.effect\n }\n if (t.inputs?.length && look.values) {\n const values = Object.fromEntries(Object.entries(look.values).filter(([id]) => t.inputs!.includes(id)))\n if (Object.keys(values).length) out.values = values\n }\n if (t.group) {\n if (look.clip !== undefined) out.clip = look.clip\n if (look.speed !== undefined) out.speed = look.speed\n if (look.paused !== undefined) out.paused = look.paused\n }\n return out\n}\n\n/** The table with these targets: each look keeps only the columns they take. */\nexport function tableWithTargets(b: FigureDataTableBinding, targets: FigureDataTargets): FigureDataTableBinding {\n const t = tidyTargets(targets)\n return { ...b, targets: t, table: Object.fromEntries(Object.entries(b.table).map(([k, look]) => [k, lookFor(look, t)])) }\n}\n\n/** The table with one look set: the whole look given, a column left out cleared. */\nexport const tableWithLook = (b: FigureDataTableBinding, key: string, look: FigureDataTableEntry): FigureDataTableBinding => ({ ...b, table: { ...b.table, [key]: lookFor(look, b.targets) } })\n\n/** The table's rows renamed, added or taken away, in order; `default` kept last. */\nexport function tableWithKeys(b: FigureDataTableBinding, rows: Array<[string, FigureDataTableEntry]>): FigureDataTableBinding {\n const d = b.table.default\n return { ...b, table: { ...Object.fromEntries(rows), ...(d !== undefined ? { default: d } : {}) } }\n}\n\n/**\n * The columns a table's targets give its looks, as the row editor shows them: colour and effect for parts, a value per\n * state input (its unit and range), the clip, speed and pause of the group.\n */\nexport function tableColumnsOf(asset: FigureAsset, b: FigureDataTableBinding): TableColumn[] {\n const out: TableColumn[] = []\n if (b.targets.parts?.length) out.push({ kind: 'color' }, { kind: 'effect' })\n for (const id of b.targets.inputs ?? []) {\n const input = asset.document.model.inputs.find(i => i.id === id)\n out.push({ kind: 'value', id, label: asset.stateInputs?.[id]?.label ?? id, unit: input?.unit, min: input?.min, max: input?.max })\n }\n if (b.targets.group) {\n const group = (asset.motionGroups ?? []).find(g => g.id === b.targets.group)\n out.push({ kind: 'clip', clips: group?.clips ?? [] }, { kind: 'speed' }, { kind: 'paused' })\n }\n return out\n}\nexport type TableColumn =\n | { kind: 'color' | 'effect' | 'speed' | 'paused' }\n | { kind: 'value'; id: string; label: string; unit?: string; min?: number; max?: number }\n | { kind: 'clip'; clips: string[] }\n\n/** The state inputs a table may give values to: each control, with its label. */\nexport const stateInputsOf = (asset: FigureAsset): Array<{ id: string; label: string }> =>\n asset.document.model.inputs.filter(i => i.role === 'state').map(i => ({ id: i.id, label: asset.stateInputs?.[i.id]?.label ?? i.id }))\n\n/**\n * A code table's field follows its keys (ADR-0166 risk 3): when the field is a closed text, its values are the table's\n * codes. The schema with the field so, or undefined when the field is open or already so.\n */\nexport function schemaFollowingCodes(asset: FigureAsset, b: FigureDataTableBinding, codes: string[]): FigureDataField[] | undefined {\n const schema = asset.dataInterface?.schema ?? []\n const path = b.accessor.replace(/\\[\\d+\\]/g, '[]')\n const field = fieldAt(schema, path)\n if (field?.kind !== 'text' || !field.values || !codes.length) return undefined\n if (field.values.length === codes.length && field.values.every((v, i) => v === codes[i])) return undefined\n const next = { ...field, values: [...codes] } as FigureDataField & { default?: string }\n if (next.default !== undefined && !codes.includes(next.default)) delete next.default\n return schemaWithFieldReplaced(schema, path, next)\n}\n\nconst round = (v: number) => Math.round(v * 1e6) / 1e6\n\n/* ---------------------------------------------------------------- the schema as a tree */\n\n/** A row's path (`L[].F`) as the accessor a value binding reads (`L[0].F`): the first element of each list. */\nexport const accessorOfRow = (path: string): string => path.replace(/\\[\\]/g, '[0]')\n\n/** The field at a row's path, or undefined. */\nexport function fieldAt(schema: readonly FigureDataField[], path: string): FigureDataField | undefined {\n let list: readonly FigureDataField[] = schema\n let found: FigureDataField | undefined\n for (const part of path.split('.')) {\n const name = part.replace(/\\[\\]/g, '')\n found = list.find(f => f.name === name)\n if (!found) return undefined\n let node: FigureDataNode = found\n while (node.kind === 'list') node = node.item\n list = node.kind === 'object' ? node.fields : []\n }\n return found\n}\n\n/** The fields under a row's path, where a new field goes: the top, an object's fields, a list's element's fields. */\nfunction fieldsUnder(schema: FigureDataField[], path: string): FigureDataField[] | undefined {\n if (!path) return schema\n const field = fieldAt(schema, path)\n if (!field) return undefined\n let node: FigureDataNode = field\n while (node.kind === 'list') node = node.item\n return node.kind === 'object' ? node.fields : undefined\n}\n\n/** The schema with a field added under a path ('' for the top): a copy, the given one left as it is. */\nexport function schemaWithField(schema: readonly FigureDataField[], under: string, field: FigureDataField): FigureDataField[] {\n const out = structuredClone(schema) as FigureDataField[]\n fieldsUnder(out, under)?.push(field)\n return out\n}\n\n/** The schema with the field at a path replaced (its name kept unless the new one says another). */\nexport function schemaWithFieldReplaced(schema: readonly FigureDataField[], path: string, field: FigureDataField): FigureDataField[] {\n const out = structuredClone(schema) as FigureDataField[]\n const parent = path.includes('.') ? path.slice(0, path.lastIndexOf('.')) : ''\n const list = fieldsUnder(out, parent)\n const name = path.split('.').pop()!.replace(/\\[\\]/g, '')\n const at = list?.findIndex(f => f.name === name) ?? -1\n if (list && at >= 0) list[at] = field\n return out\n}\n\n/** The schema without the field at a path. */\nexport function schemaWithoutField(schema: readonly FigureDataField[], path: string): FigureDataField[] {\n const out = structuredClone(schema) as FigureDataField[]\n const parent = path.includes('.') ? path.slice(0, path.lastIndexOf('.')) : ''\n const list = fieldsUnder(out, parent)\n const name = path.split('.').pop()!.replace(/\\[\\]/g, '')\n const at = list?.findIndex(f => f.name === name) ?? -1\n if (list && at >= 0) list.splice(at, 1)\n return out\n}\n\n/** A field of another kind, its name, label and json flag kept, the rest started fresh. */\nexport function fieldOfKind(field: FigureDataField, kind: FigureDataNode['kind']): FigureDataField {\n const head = { name: field.name, ...(field.label ? { label: field.label } : {}) }\n if (kind === 'object') return { ...head, kind, fields: field.kind === 'object' ? field.fields : [] }\n if (kind === 'list') return { ...head, kind, item: field.kind === 'list' ? field.item : { kind: 'object', fields: [] } }\n return { ...head, kind } as FigureDataField\n}\n\n/** The rows of the schema, each with the bindings that read it (figure-model's view). */\nexport const schemaRowsOf = (asset: FigureAsset): FigureDataRow[] => (asset.dataInterface ? figureDataRows(asset.dataInterface) : [])\n\n/* ---------------------------------------------------------------- reading a sample */\n\n/**\n * What a sample of data would do on this figure, read the one way a placed figure reads it (things-scene's figure\n * inputs): what it moves, or why it is refused, each value's reason; each table's look and where it came from, and what\n * of a legend was left out. `legends`: sample legends by role, as a scene's legend of the role's name would be.\n */\nexport function sampleOf(\n asset: FigureAsset,\n sample: unknown,\n legends: Record<string, unknown> = {}\n): { issues: FigureDataValueIssue[]; result: FigureDataResult; uses: Readonly<Record<string, FigureTableUse>>; notes: FigureRuntimeIssue[] } {\n const inputs = new FigureInputs(asset)\n inputs.setThemes({ legends: Object.fromEntries(Object.entries(legends).map(([role, legend]) => [role, { legend, source: 'domain' as const, name: role }])) })\n const taken = inputs.setData(sample)\n return {\n issues: taken.accepted ? [] : (taken.issues[0]?.issues ?? []),\n result: inputs.data,\n uses: inputs.tableUses,\n notes: inputs.diagnostics().filter(i => i.severity === 'note')\n }\n}\n\n/** The rows a person gives a value by hand, as a board's saved values: one value, read by a binding, not inside a list. */\nexport const valueRowsOf = (asset: FigureAsset): FigureDataRow[] => schemaRowsOf(asset).filter(r => isValue(r.node) && r.bindings.length > 0 && !r.path.includes('[]'))\n\n/**\n * What the data gives a row, read the way a placed figure reads its data: when it is there, it is what the figure shows,\n * and a value saved by hand for the row is not read (things-scene's FigureDataReader: live data first). Undefined when\n * the data leaves the row out, or gives it null.\n */\nexport function dataValueAt(data: unknown, path: string): unknown {\n const steps = parseFigureAccessor(path)\n if (!steps) return undefined\n let at: unknown = data\n for (const step of steps) {\n if (at === null || typeof at !== 'object') return undefined\n at = 'field' in step ? (at as Record<string, unknown>)[step.field] : (at as unknown[])[step.index]\n }\n return at === null ? undefined : at\n}\n\n/** A value typed or chosen for a row, as its kind reads it: a number (NaN when empty), true or false, or the text. */\nexport function typedValueOf(node: FigureDataNode, typed: string): FigureDataValue {\n if (node.kind === 'number') return typed.trim() === '' ? Number.NaN : Number(typed)\n if (node.kind === 'boolean') return typed === 'true'\n return typed\n}\n\n/** The parts a table may show on: the parts the figure's appearance names. */\nexport const partsOf = (asset: FigureAsset): string[] => [...new Set(asset.appearance.map(a => a.target))]\n\n/** Whether a text is an accessor the kernel takes. */\nexport const accessorTaken = (accessor: string): boolean => parseFigureAccessor(accessor) !== null\n\n/**\n * Which fields of each motion group the data binds: its clip, its speed. A field bound wins over the group's own setting\n * whenever the data, a saved value or the schema's default gives it a value, so the preview drives it through the data.\n */\nexport function motionWrittenByData(asset: FigureAsset): Record<string, { clip: boolean; speed: boolean }> {\n const out: Record<string, { clip: boolean; speed: boolean }> = {}\n for (const b of asset.dataInterface?.bindings ?? []) {\n if (b.rule === 'table') {\n if (!b.targets.group) continue\n const one = (out[b.targets.group] ??= { clip: false, speed: false })\n const looks = Object.values(b.table)\n if (looks.some(l => l.clip !== undefined)) one.clip = true\n if (looks.some(l => l.speed !== undefined)) one.speed = true\n continue\n }\n if (b.behavior.kind !== 'motion-clip' && b.behavior.kind !== 'motion-speed') continue\n const one = (out[b.behavior.group] ??= { clip: false, speed: false })\n if (b.behavior.kind === 'motion-clip') one.clip = true\n else one.speed = true\n }\n return out\n}\n\n/* ---------------------------------------------------------------- the rotation card */\n\n/** A joint that turns without end (a roller, a fan, a turntable): its control, by the id the clips write. */\nexport interface EndlessJoint {\n input: string\n label: string\n unit: 'deg' | 'rad'\n}\n\n/** The axes that turn without end: revolute, with no limits, following no one (ADR-0159: every axis of every joint). */\nexport function endlessJointsOf(asset: FigureAsset): EndlessJoint[] {\n const out: EndlessJoint[] = []\n for (const { motion: a } of figureAxesOf(asset.joints)) {\n if (a.type !== 'revolute' || a.lowerLimit !== undefined || a.upperLimit !== undefined || a.mimic) continue\n const input = motionStateIdOf(a)\n const unit = asset.document.model.inputs.find(i => i.id === input)?.unit\n if (unit !== 'deg' && unit !== 'rad') continue\n if (!out.some(e => e.input === input)) out.push({ input, label: asset.stateInputs?.[input]?.label ?? input, unit })\n }\n return out\n}\n\n/** What the rotation card is told: the joint, and the data fields that turn it on, set its speed and its direction. */\nexport interface RotationChoice {\n input: string\n /** The motion group's name, shown to a person. */\n label: string\n /** A boolean field: true turns, false stops where it is. */\n on?: string\n /** A number field in turns per minute, and the most it gives; the field's range is set to 0..max when it has none. */\n speed?: { path: string; max: number }\n /** A closed text field, and its value that turns forward and the one that turns back. */\n direction?: { path: string; forward: string; reverse: string }\n}\n\n/**\n * The rotation card's commands (data binding design decision 1, 「회전」): a clip that turns the joint once around and\n * keeps adding the turn (wrap, accumulating), a reverse one when a direction is given, the motion group holding them,\n * and the bindings -- on, by a table, to the group's pause, speed to its speed, direction, by a table, to its clip. Nothing new runs them: they\n * are the drivers, the group and the bindings any author could write, and stay editable one by one.\n *\n * The clip lasts `T = 3 × 60 / max rpm` seconds, so the most the field gives plays at the group's top speed, 3 -- the\n * speed range is not widened. One turn per `T` at speed 1, and speed = rpm × T / 60. A stop is a pause: the joint stays\n * where it is, where a stopped clip would jump back to its first key.\n */\nexport function rotationStepsOf(asset: FigureAsset, c: RotationChoice): FigureProposalStep[] {\n const joint = endlessJointsOf(asset).find(j => j.input === c.input)\n if (!joint) throw new FigureContractError('TARGET_ABSENT', c.input, `${c.input} is not a joint that turns without end`)\n const turn = joint.unit === 'deg' ? 360 : 2 * Math.PI\n const seconds = c.speed && c.speed.max > 0 ? round((3 * 60) / c.speed.max) : 1\n const group = freeIdOf((asset.motionGroups ?? []).map(g => g.id), `${joint.input}-spin`)\n const forward = group\n const reverse = `${group}-reverse`\n const steps: FigureProposalStep[] = []\n const schema = asset.dataInterface?.schema ?? []\n if (c.speed) {\n const field = fieldAt(schema, c.speed.path)\n if (field?.kind === 'number' && (field.min === undefined || field.max === undefined))\n steps.push({ kind: 'set-data-schema', schema: schemaWithFieldReplaced(schema, c.speed.path, { ...field, min: field.min ?? 0, max: field.max ?? c.speed.max }) })\n }\n const spin = (clip: string, way: 1 | -1, inGroup: boolean): FigureProposalStep => ({\n kind: 'set-driver',\n state: joint.input,\n clip,\n duration: seconds,\n keys: [\n { seconds: 0, value: 0 },\n { seconds, value: way * turn }\n ],\n interpolation: 'linear',\n loop: 'wrap',\n accumulates: true,\n ...(inGroup ? { group } : {})\n })\n const clips = c.direction ? [forward, reverse] : [forward]\n steps.push(spin(forward, 1, false))\n steps.push({ kind: 'set-motion-group', group: { id: group, label: c.label, clips: [forward], defaultClip: forward, transitionSeconds: 0 } })\n if (c.direction) {\n steps.push(spin(reverse, -1, true))\n steps.push({ kind: 'set-motion-group', group: { id: group, label: c.label, clips, defaultClip: forward, transitionSeconds: 0 } })\n }\n const taken = (asset.dataInterface?.bindings ?? []).map(b => b.id)\n const bind = (base: string, binding: Omit<FigureDataValueBinding, 'id'> | Omit<FigureDataTableBinding, 'id'>): FigureProposalStep => {\n const id = freeIdOf(taken, base)\n taken.push(id)\n return { kind: 'set-data-binding', binding: { id, ...binding } as FigureDataBinding }\n }\n if (c.on) steps.push(bind(`${group}-on`, { accessor: c.on, rule: 'table', lookup: 'code', targets: { group }, table: { true: { paused: false }, false: { paused: true } } }))\n if (c.speed) steps.push(bind(`${group}-speed`, { accessor: c.speed.path, behavior: { kind: 'motion-speed', group }, rule: 'scale', param: { scale: round(seconds / 60), offset: 0 } }))\n if (c.direction) {\n const values = domainOf(fieldAt(schema, c.direction.path) ?? { kind: 'text' }).map(String)\n const covered = values.every(v => v === c.direction!.forward || v === c.direction!.reverse)\n steps.push(\n bind(`${group}-direction`, {\n accessor: c.direction.path,\n rule: 'table',\n lookup: 'code',\n targets: { group },\n table: { [c.direction.forward]: { clip: forward }, [c.direction.reverse]: { clip: reverse }, ...(covered ? {} : { default: { clip: forward } }) }\n })\n )\n }\n return steps\n}\n"]}
1
+ {"version":3,"file":"data-interface.js","sourceRoot":"","sources":["../../client/modeller/data-interface.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * The figure's data and what it moves (ADR-0051 §8, ADR-0166): what the data tab offers and shows -- one binding, its\n * method as the field's kind allows (as it is, scaled, a code table, a range table). Every rule is figure-model's -- which accessor holds, which rule's results a behavior takes -- and the reading\n * of data is things-scene's; this only lists what there is to choose, drafts a binding the kernel then checks, and edits\n * the schema as a tree. Kept apart from the element so it is tested without a browser.\n */\nimport { FIGURE_PART_ID, FIGURE_MOTION_SPEED_MAX, FigureContractError, figureAxesOf, figureDataRows, motionStateIdOf, parseFigureAccessor } from '@hatiolab/figure-model'\nimport type {\n FigureAsset,\n FigureDataBehavior,\n FigureDataBinding,\n FigureDataField,\n FigureDataNode,\n FigureDataRow,\n FigureDataTableBinding,\n FigureDataTableEntry,\n FigureDataTargets,\n FigureDataValue,\n FigureDataValueBinding,\n FigureDataValueIssue,\n FigureProposalStep\n} from '@hatiolab/figure-model'\nimport { FigureInputs, type FigureDataResult, type FigureRuntimeIssue, type FigureTableUse } from '@hatiolab/things-scene'\n\n/** Something a binding can move, with what the screen shows of it. */\nexport interface BehaviorChoice {\n /** One string per behavior, for a select's value. */\n key: string\n behavior: FigureDataBehavior\n /** The screen's word for the kind: a control, a colour, a group's clip, … */\n kind: FigureDataBehavior['kind']\n /** The control's label, the colour token, the group's label, the axis. */\n name: string\n unit?: string\n min?: number\n max?: number\n /** A motion group's clips. */\n clips?: string[]\n}\n\nexport const behaviorKeyOf = (b: FigureDataBehavior): string =>\n b.kind === 'state'\n ? `state:${b.input}`\n : b.kind === 'palette'\n ? `palette:${b.token}`\n : b.kind === 'pose'\n ? `pose:${b.axis}`\n : b.kind === 'items'\n ? `items:${b.slot ?? ''}`\n : `${b.kind}:${b.group}`\n\n/**\n * Everything a value binding may drive: each control, each colour, each motion group's clip, speed and pause, its\n * position and heading, and -- when it has places -- the items in them.\n */\nexport function behaviorsOf(asset: FigureAsset): BehaviorChoice[] {\n const out: BehaviorChoice[] = []\n const add = (behavior: FigureDataBehavior, name: string, more: Partial<BehaviorChoice> = {}) => out.push({ key: behaviorKeyOf(behavior), behavior, kind: behavior.kind, name, ...more })\n for (const input of asset.document.model.inputs) {\n if (input.role !== 'state') continue\n add({ kind: 'state', input: input.id, sourceMode: 'observed' }, asset.stateInputs?.[input.id]?.label ?? input.id, { unit: input.unit, min: input.min, max: input.max })\n }\n for (const token of Object.keys(asset.palette)) add({ kind: 'palette', token }, token)\n for (const group of asset.motionGroups ?? []) {\n add({ kind: 'motion-clip', group: group.id }, group.label, { clips: [...group.clips] })\n add({ kind: 'motion-speed', group: group.id }, group.label, { min: 0, max: FIGURE_MOTION_SPEED_MAX })\n add({ kind: 'motion-paused', group: group.id }, group.label)\n }\n for (const axis of ['x', 'z', 'y', 'heading'] as const) add({ kind: 'pose', axis, seconds: 1 }, axis, { unit: axis === 'heading' ? 'deg' : 'mm' })\n if (asset.document.capabilities.slotLayout || asset.document.capabilities.names?.includes('Holdable')) add({ kind: 'items' }, asset.document.capabilities.slotLayout?.label ?? 'items')\n return out\n}\n\nconst isValue = (n: FigureDataNode): n is Extract<FigureDataNode, { kind: 'number' | 'boolean' | 'text' }> => n.kind === 'number' || n.kind === 'boolean' || n.kind === 'text'\n\n/**\n * Whether a field of this kind drives the behavior as it is or scaled -- the choices a value binding offers for it. A\n * value that picks a look per code is a table (ADR-0166 2).\n */\nexport function fitsField(node: FigureDataNode, choice: BehaviorChoice): boolean {\n if (choice.kind === 'items') return node.kind === 'list' || node.kind === 'text' || node.kind === 'number'\n if (!isValue(node)) return false\n if (choice.kind === 'motion-paused') return node.kind === 'boolean'\n if (choice.kind === 'palette') return node.kind === 'text' && !!node.values?.every(v => /^#[0-9a-f]{6}$/i.test(v))\n if (choice.kind === 'motion-clip') {\n const clips = choice.behavior.kind === 'motion-clip' ? choice.clips : undefined\n return node.kind === 'text' && !!node.values && (!clips || node.values.every(v => clips.includes(v)))\n }\n return node.kind === 'number'\n}\n\n/** How a binding turns a value into what the figure shows (ADR-0166 1): the screen's four methods, figure-viewer's words for every screen. */\nimport { methodOf, type DataMethod } from '@things-factory/figure-viewer/dist-client/data-connection.js'\nexport { methodOf, type DataMethod }\n\n/**\n * The methods a field allows (ADR-0166 2): a number as it is, scaled or by a range table; a text or true/false by a code\n * table, or as it is where a behavior takes it so; a list as it is (its items). A new field is made by a table.\n */\nexport function methodsOf(node: FigureDataNode | null, choices: BehaviorChoice[]): DataMethod[] {\n if (!node) return ['code', 'ranges']\n const fitting = choices.some(c => fitsField(node, c))\n if (node.kind === 'number') return [...(fitting ? (['value', 'scale'] as const) : []), 'ranges']\n if (node.kind === 'text' || node.kind === 'boolean') return [...(fitting ? (['value'] as const) : []), 'code']\n return fitting ? ['value'] : []\n}\n\n/** The method a binding is shown by. */\n\n/** An id not taken among `taken`: `base`, then `base-2`, `base-3`, … made into the kernel's id shape. */\nexport function freeIdOf(taken: Iterable<string>, base: string): string {\n const used = new Set(taken)\n const cleaned = base.replace(/[^a-zA-Z0-9_-]+/g, '-').replace(/^[^a-zA-Z]+/, '').replace(/-+$/, '') || 'binding'\n const id = FIGURE_PART_ID.test(cleaned) ? cleaned : 'binding'\n if (!used.has(id)) return id\n let n = 2\n while (used.has(`${id}-${n}`)) n++\n return `${id}-${n}`\n}\n\n/** How many mm, or degrees, one of a unit is: only lengths and angles are converted. */\nconst TO_MM: Record<string, number> = { mm: 1, cm: 10, m: 1000 }\nconst TO_DEG: Record<string, number> = { deg: 1, rad: 180 / Math.PI }\n\n/** The values a closed field takes: a closed text's values, both booleans. Empty when open. */\nexport const domainOf = (node: FigureDataNode): FigureDataValue[] => (node.kind === 'boolean' ? [false, true] : node.kind === 'text' && node.values ? [...node.values] : [])\n\n/**\n * A first value binding of a field to a behavior, for the author to adjust: the value as it is when it already fits, a\n * scale when only its unit or range differs -- or the method the author chose. The kernel says whether it holds.\n */\nexport function bindingDraftOf(asset: FigureAsset, accessor: string, node: FigureDataNode, choice: BehaviorChoice, method?: 'value' | 'scale'): FigureDataValueBinding {\n const taken = (asset.dataInterface?.bindings ?? []).map(b => b.id)\n const name = accessor.replace(/\\[\\d+\\]/g, '').split('.').pop() ?? accessor\n const id = freeIdOf(taken, `${name}-${choice.kind === 'state' ? (choice.behavior as { input: string }).input : choice.kind}`)\n const behavior = choice.behavior\n const make = (rule: 'value' | 'scale', param?: FigureDataValueBinding['param']): FigureDataValueBinding => ({ id, accessor, behavior, rule, ...(param ? { param } : {}) })\n\n if (behavior.kind === 'items') {\n if (node.kind !== 'list') return make('value')\n const fields = node.item.kind === 'object' ? node.item.fields : []\n const pick = (...words: RegExp[]) => fields.find(f => isValue(f) && words.some(w => w.test(f.name)))?.name\n const itemId = pick(/^id$/i, /name$/i, /id$/i) ?? fields.find(isValue)?.name\n const type = pick(/type$/i)\n const place = pick(/^slot/i, /place/i, /port/i)\n const stack = pick(/stack/i, /level/i)\n return { id, accessor, behavior: { kind: 'items', ...(itemId ? { id: itemId } : {}), ...(type ? { type } : {}), ...(place ? { place } : {}), ...(stack ? { stack } : {}) }, rule: 'value' }\n }\n if (node.kind !== 'number') return make('value')\n if (behavior.kind === 'pose') {\n const want = behavior.axis === 'heading' ? TO_DEG : TO_MM\n const unit = node.unit ?? ''\n if (method === 'value' || unit === (behavior.axis === 'heading' ? 'deg' : 'mm') || (method === undefined && !(unit in want))) return make('value')\n return make('scale', { scale: want[unit] ?? 1, offset: 0 })\n }\n /* state and motion-speed: a number into a range. */\n const [lo, hi, unit] =\n behavior.kind === 'motion-speed' ? [0, FIGURE_MOTION_SPEED_MAX, 'ratio'] : [choice.min ?? 0, choice.max ?? 1, choice.unit ?? '']\n const sameUnit = behavior.kind === 'motion-speed' ? node.unit === undefined || node.unit === 'ratio' : node.unit === unit\n const inside = node.min !== undefined && node.max !== undefined && node.min >= lo && node.max <= hi\n if (method === 'value' || (method === undefined && sameUnit && inside)) return make('value')\n if (node.min !== undefined && node.max !== undefined && node.max > node.min) {\n /* The field's range laid onto the behavior's. */\n const scale = (hi - lo) / (node.max - node.min)\n return make('scale', { scale: round(scale), offset: round(lo - scale * node.min) })\n }\n return method === 'scale' ? make('scale', { scale: 1, offset: 0 }) : make('value')\n}\n\n/* ---------------------------------------------------------------- tables (ADR-0166 3) */\n\n/** The first code a new code table names, and the next ones: `CODE`, `CODE2`, … */\nexport function freeCodeOf(taken: string[]): string {\n if (!taken.includes('CODE')) return 'CODE'\n let n = 2\n while (taken.includes(`CODE${n}`)) n++\n return `CODE${n}`\n}\n\n/** A legend role from a binding's id: lower case letters, digits and `-`. */\nexport const legendRoleOf = (id: string): string =>\n id\n .toLowerCase()\n .replace(/[^a-z0-9-]+/g, '-')\n .replace(/^-+|-+$/g, '') || 'legend'\n\n/**\n * A first table on a field (ADR-0166 10): a row per value of a closed field, an open field's rows typed later, one\n * interval over the whole of a number. A new field is made by the table (P2): a code table's a text whose values are the\n * table's keys, starting with one code; a range table's a number. Returns the binding and, for a new field, the schema\n * with it.\n */\nexport function tableDraftOf(\n asset: FigureAsset,\n field: { path: string; node: FigureDataNode } | { name: string },\n method: 'code' | 'ranges',\n targets: FigureDataTargets\n): { binding: FigureDataTableBinding; schema?: FigureDataField[] } {\n const taken = (asset.dataInterface?.bindings ?? []).map(b => b.id)\n const made = 'name' in field\n const name = made ? field.name : (field.path.replace(/\\[\\]/g, '').split('.').pop() ?? field.path)\n const id = freeIdOf(taken, name.toLowerCase())\n const node: FigureDataNode = made ? (method === 'code' ? { kind: 'text', values: ['CODE'] } : { kind: 'number' }) : field.node\n const accessor = made ? field.name : accessorOfRow(field.path)\n const table: Record<string, FigureDataTableEntry> =\n method === 'code' ? Object.fromEntries(domainOf(node).map(v => [String(v), {}])) : { [`${node.kind === 'number' ? (node.min ?? '') : ''}~`]: {} }\n const binding: FigureDataTableBinding = { id, accessor, rule: 'table', lookup: method, targets: tidyTargets(targets), table }\n if (!made) return { binding }\n const schema = [...(asset.dataInterface?.schema ?? []), { name: field.name, ...node } as FigureDataField]\n return { binding, schema }\n}\n\n/** Targets with empty lists left out, as the kernel keeps them. */\nconst tidyTargets = (t: FigureDataTargets): FigureDataTargets => ({\n ...(t.parts?.length ? { parts: [...t.parts] } : {}),\n ...(t.inputs?.length ? { inputs: [...t.inputs] } : {}),\n ...(t.group ? { group: t.group } : {})\n})\n\n/** A look with only the columns its targets take: a target taken away takes its columns with it. */\nfunction lookFor(look: FigureDataTableEntry, t: FigureDataTargets): FigureDataTableEntry {\n const out: FigureDataTableEntry = {}\n if (t.parts?.length) {\n if (look.color !== undefined) out.color = look.color\n if (look.effect !== undefined) out.effect = look.effect\n }\n if (t.inputs?.length && look.values) {\n const values = Object.fromEntries(Object.entries(look.values).filter(([id]) => t.inputs!.includes(id)))\n if (Object.keys(values).length) out.values = values\n }\n if (t.group) {\n if (look.clip !== undefined) out.clip = look.clip\n if (look.speed !== undefined) out.speed = look.speed\n if (look.paused !== undefined) out.paused = look.paused\n }\n return out\n}\n\n/** The table with these targets: each look keeps only the columns they take. */\nexport function tableWithTargets(b: FigureDataTableBinding, targets: FigureDataTargets): FigureDataTableBinding {\n const t = tidyTargets(targets)\n return { ...b, targets: t, table: Object.fromEntries(Object.entries(b.table).map(([k, look]) => [k, lookFor(look, t)])) }\n}\n\n/** The table with one look set: the whole look given, a column left out cleared. */\nexport const tableWithLook = (b: FigureDataTableBinding, key: string, look: FigureDataTableEntry): FigureDataTableBinding => ({ ...b, table: { ...b.table, [key]: lookFor(look, b.targets) } })\n\n/** The table's rows renamed, added or taken away, in order; `default` kept last. */\nexport function tableWithKeys(b: FigureDataTableBinding, rows: Array<[string, FigureDataTableEntry]>): FigureDataTableBinding {\n const d = b.table.default\n return { ...b, table: { ...Object.fromEntries(rows), ...(d !== undefined ? { default: d } : {}) } }\n}\n\n/**\n * The columns a table's targets give its looks, as the row editor shows them: colour and effect for parts, a value per\n * state input (its unit and range), the clip, speed and pause of the group.\n */\nexport function tableColumnsOf(asset: FigureAsset, b: FigureDataTableBinding): TableColumn[] {\n const out: TableColumn[] = []\n if (b.targets.parts?.length) out.push({ kind: 'color' }, { kind: 'effect' })\n for (const id of b.targets.inputs ?? []) {\n const input = asset.document.model.inputs.find(i => i.id === id)\n out.push({ kind: 'value', id, label: asset.stateInputs?.[id]?.label ?? id, unit: input?.unit, min: input?.min, max: input?.max })\n }\n if (b.targets.group) {\n const group = (asset.motionGroups ?? []).find(g => g.id === b.targets.group)\n out.push({ kind: 'clip', clips: group?.clips ?? [] }, { kind: 'speed' }, { kind: 'paused' })\n }\n return out\n}\nexport type TableColumn =\n | { kind: 'color' | 'effect' | 'speed' | 'paused' }\n | { kind: 'value'; id: string; label: string; unit?: string; min?: number; max?: number }\n | { kind: 'clip'; clips: string[] }\n\n/** The state inputs a table may give values to: each control, with its label. */\nexport const stateInputsOf = (asset: FigureAsset): Array<{ id: string; label: string }> =>\n asset.document.model.inputs.filter(i => i.role === 'state').map(i => ({ id: i.id, label: asset.stateInputs?.[i.id]?.label ?? i.id }))\n\n/**\n * A code table's field follows its keys (ADR-0166 risk 3): when the field is a closed text, its values are the table's\n * codes. The schema with the field so, or undefined when the field is open or already so.\n */\nexport function schemaFollowingCodes(asset: FigureAsset, b: FigureDataTableBinding, codes: string[]): FigureDataField[] | undefined {\n const schema = asset.dataInterface?.schema ?? []\n const path = b.accessor.replace(/\\[\\d+\\]/g, '[]')\n const field = fieldAt(schema, path)\n if (field?.kind !== 'text' || !field.values || !codes.length) return undefined\n if (field.values.length === codes.length && field.values.every((v, i) => v === codes[i])) return undefined\n const next = { ...field, values: [...codes] } as FigureDataField & { default?: string }\n if (next.default !== undefined && !codes.includes(next.default)) delete next.default\n return schemaWithFieldReplaced(schema, path, next)\n}\n\nconst round = (v: number) => Math.round(v * 1e6) / 1e6\n\n/* ---------------------------------------------------------------- the schema as a tree */\n\n/** A row's path (`L[].F`) as the accessor a value binding reads (`L[0].F`): the first element of each list. */\nexport const accessorOfRow = (path: string): string => path.replace(/\\[\\]/g, '[0]')\n\n/** The field at a row's path, or undefined. */\nexport function fieldAt(schema: readonly FigureDataField[], path: string): FigureDataField | undefined {\n let list: readonly FigureDataField[] = schema\n let found: FigureDataField | undefined\n for (const part of path.split('.')) {\n const name = part.replace(/\\[\\]/g, '')\n found = list.find(f => f.name === name)\n if (!found) return undefined\n let node: FigureDataNode = found\n while (node.kind === 'list') node = node.item\n list = node.kind === 'object' ? node.fields : []\n }\n return found\n}\n\n/** The fields under a row's path, where a new field goes: the top, an object's fields, a list's element's fields. */\nfunction fieldsUnder(schema: FigureDataField[], path: string): FigureDataField[] | undefined {\n if (!path) return schema\n const field = fieldAt(schema, path)\n if (!field) return undefined\n let node: FigureDataNode = field\n while (node.kind === 'list') node = node.item\n return node.kind === 'object' ? node.fields : undefined\n}\n\n/** The schema with a field added under a path ('' for the top): a copy, the given one left as it is. */\nexport function schemaWithField(schema: readonly FigureDataField[], under: string, field: FigureDataField): FigureDataField[] {\n const out = structuredClone(schema) as FigureDataField[]\n fieldsUnder(out, under)?.push(field)\n return out\n}\n\n/** The schema with the field at a path replaced (its name kept unless the new one says another). */\nexport function schemaWithFieldReplaced(schema: readonly FigureDataField[], path: string, field: FigureDataField): FigureDataField[] {\n const out = structuredClone(schema) as FigureDataField[]\n const parent = path.includes('.') ? path.slice(0, path.lastIndexOf('.')) : ''\n const list = fieldsUnder(out, parent)\n const name = path.split('.').pop()!.replace(/\\[\\]/g, '')\n const at = list?.findIndex(f => f.name === name) ?? -1\n if (list && at >= 0) list[at] = field\n return out\n}\n\n/** The schema without the field at a path. */\nexport function schemaWithoutField(schema: readonly FigureDataField[], path: string): FigureDataField[] {\n const out = structuredClone(schema) as FigureDataField[]\n const parent = path.includes('.') ? path.slice(0, path.lastIndexOf('.')) : ''\n const list = fieldsUnder(out, parent)\n const name = path.split('.').pop()!.replace(/\\[\\]/g, '')\n const at = list?.findIndex(f => f.name === name) ?? -1\n if (list && at >= 0) list.splice(at, 1)\n return out\n}\n\n/** A field of another kind, its name, label and json flag kept, the rest started fresh. */\nexport function fieldOfKind(field: FigureDataField, kind: FigureDataNode['kind']): FigureDataField {\n const head = { name: field.name, ...(field.label ? { label: field.label } : {}) }\n if (kind === 'object') return { ...head, kind, fields: field.kind === 'object' ? field.fields : [] }\n if (kind === 'list') return { ...head, kind, item: field.kind === 'list' ? field.item : { kind: 'object', fields: [] } }\n return { ...head, kind } as FigureDataField\n}\n\n/** The rows of the schema, each with the bindings that read it (figure-model's view). */\nexport const schemaRowsOf = (asset: FigureAsset): FigureDataRow[] => (asset.dataInterface ? figureDataRows(asset.dataInterface) : [])\n\n/* ---------------------------------------------------------------- reading a sample */\n\n/**\n * What a sample of data would do on this figure, read the one way a placed figure reads it (things-scene's figure\n * inputs): what it moves, or why it is refused, each value's reason; each table's look and where it came from, and what\n * of a legend was left out. `legends`: sample legends by role, as a scene's legend of the role's name would be.\n */\nexport function sampleOf(\n asset: FigureAsset,\n sample: unknown,\n legends: Record<string, unknown> = {}\n): { issues: FigureDataValueIssue[]; result: FigureDataResult; uses: Readonly<Record<string, FigureTableUse>>; notes: FigureRuntimeIssue[] } {\n const inputs = new FigureInputs(asset)\n inputs.setThemes({ legends: Object.fromEntries(Object.entries(legends).map(([role, legend]) => [role, { legend, source: 'domain' as const, name: role }])) })\n const taken = inputs.setData(sample)\n return {\n issues: taken.accepted ? [] : (taken.issues[0]?.issues ?? []),\n result: inputs.data,\n uses: inputs.tableUses,\n notes: inputs.diagnostics().filter(i => i.severity === 'note')\n }\n}\n\n/**\n * The state inputs a sample of data sets on this figure, by id: what the preview shows for them instead of a slider. None\n * when there is no sample, or the figure refuses it.\n */\nexport function sampledStatesOf(asset: FigureAsset, sample: unknown): Record<string, number> {\n if (sample === null || sample === undefined || !asset.dataInterface) return {}\n try {\n const read = sampleOf(asset, sample)\n return read.issues.length ? {} : Object.fromEntries(Object.entries(read.result.states).map(([id, s]) => [id, s.value]))\n } catch {\n return {}\n }\n}\n\n/** The rows a person gives a value by hand, as a board's saved values: one value, read by a binding, not inside a list. */\nexport const valueRowsOf = (asset: FigureAsset): FigureDataRow[] => schemaRowsOf(asset).filter(r => isValue(r.node) && r.bindings.length > 0 && !r.path.includes('[]'))\n\n/**\n * What the data gives a row, read the way a placed figure reads its data: when it is there, it is what the figure shows,\n * and a value saved by hand for the row is not read (things-scene's FigureDataReader: live data first). Undefined when\n * the data leaves the row out, or gives it null.\n */\nexport function dataValueAt(data: unknown, path: string): unknown {\n const steps = parseFigureAccessor(path)\n if (!steps) return undefined\n let at: unknown = data\n for (const step of steps) {\n if (at === null || typeof at !== 'object') return undefined\n at = 'field' in step ? (at as Record<string, unknown>)[step.field] : (at as unknown[])[step.index]\n }\n return at === null ? undefined : at\n}\n\n/** A value typed or chosen for a row, as its kind reads it: a number (NaN when empty), true or false, or the text. */\nexport function typedValueOf(node: FigureDataNode, typed: string): FigureDataValue {\n if (node.kind === 'number') return typed.trim() === '' ? Number.NaN : Number(typed)\n if (node.kind === 'boolean') return typed === 'true'\n return typed\n}\n\n/** The parts a table may show on: the parts the figure's appearance names. */\nexport const partsOf = (asset: FigureAsset): string[] => [...new Set(asset.appearance.map(a => a.target))]\n\n/** Whether a text is an accessor the kernel takes. */\nexport const accessorTaken = (accessor: string): boolean => parseFigureAccessor(accessor) !== null\n\n/**\n * Which fields of each motion group the data binds: its clip, its speed. A field bound wins over the group's own setting\n * whenever the data, a saved value or the schema's default gives it a value, so the preview drives it through the data.\n */\nexport function motionWrittenByData(asset: FigureAsset): Record<string, { clip: boolean; speed: boolean }> {\n const out: Record<string, { clip: boolean; speed: boolean }> = {}\n for (const b of asset.dataInterface?.bindings ?? []) {\n if (b.rule === 'table') {\n if (!b.targets.group) continue\n const one = (out[b.targets.group] ??= { clip: false, speed: false })\n const looks = Object.values(b.table)\n if (looks.some(l => l.clip !== undefined)) one.clip = true\n if (looks.some(l => l.speed !== undefined)) one.speed = true\n continue\n }\n if (b.behavior.kind !== 'motion-clip' && b.behavior.kind !== 'motion-speed') continue\n const one = (out[b.behavior.group] ??= { clip: false, speed: false })\n if (b.behavior.kind === 'motion-clip') one.clip = true\n else one.speed = true\n }\n return out\n}\n\n/* ---------------------------------------------------------------- the rotation card */\n\n/** A joint that turns without end (a roller, a fan, a turntable): its control, by the id the clips write. */\nexport interface EndlessJoint {\n input: string\n label: string\n unit: 'deg' | 'rad'\n}\n\n/** The axes that turn without end: revolute, with no limits, following no one (ADR-0159: every axis of every joint). */\nexport function endlessJointsOf(asset: FigureAsset): EndlessJoint[] {\n const out: EndlessJoint[] = []\n for (const { motion: a } of figureAxesOf(asset.joints)) {\n if (a.type !== 'revolute' || a.lowerLimit !== undefined || a.upperLimit !== undefined || a.mimic) continue\n const input = motionStateIdOf(a)\n const unit = asset.document.model.inputs.find(i => i.id === input)?.unit\n if (unit !== 'deg' && unit !== 'rad') continue\n if (!out.some(e => e.input === input)) out.push({ input, label: asset.stateInputs?.[input]?.label ?? input, unit })\n }\n return out\n}\n\n/** What the rotation card is told: the joint, and the data fields that turn it on, set its speed and its direction. */\nexport interface RotationChoice {\n input: string\n /** The motion group's name, shown to a person. */\n label: string\n /** A boolean field: true turns, false stops where it is. */\n on?: string\n /** A number field in turns per minute, and the most it gives; the field's range is set to 0..max when it has none. */\n speed?: { path: string; max: number }\n /** A closed text field, and its value that turns forward and the one that turns back. */\n direction?: { path: string; forward: string; reverse: string }\n}\n\n/**\n * The rotation card's commands (data binding design decision 1, 「회전」): a clip that turns the joint once around and\n * keeps adding the turn (wrap, accumulating), a reverse one when a direction is given, the motion group holding them,\n * and the bindings -- on, by a table, to the group's pause, speed to its speed, direction, by a table, to its clip. Nothing new runs them: they\n * are the drivers, the group and the bindings any author could write, and stay editable one by one.\n *\n * The clip lasts `T = 3 × 60 / max rpm` seconds, so the most the field gives plays at the group's top speed, 3 -- the\n * speed range is not widened. One turn per `T` at speed 1, and speed = rpm × T / 60. A stop is a pause: the joint stays\n * where it is, where a stopped clip would jump back to its first key.\n */\nexport function rotationStepsOf(asset: FigureAsset, c: RotationChoice): FigureProposalStep[] {\n const joint = endlessJointsOf(asset).find(j => j.input === c.input)\n if (!joint) throw new FigureContractError('TARGET_ABSENT', c.input, `${c.input} is not a joint that turns without end`)\n const turn = joint.unit === 'deg' ? 360 : 2 * Math.PI\n const seconds = c.speed && c.speed.max > 0 ? round((3 * 60) / c.speed.max) : 1\n const group = freeIdOf((asset.motionGroups ?? []).map(g => g.id), `${joint.input}-spin`)\n const forward = group\n const reverse = `${group}-reverse`\n const steps: FigureProposalStep[] = []\n const schema = asset.dataInterface?.schema ?? []\n if (c.speed) {\n const field = fieldAt(schema, c.speed.path)\n if (field?.kind === 'number' && (field.min === undefined || field.max === undefined))\n steps.push({ kind: 'set-data-schema', schema: schemaWithFieldReplaced(schema, c.speed.path, { ...field, min: field.min ?? 0, max: field.max ?? c.speed.max }) })\n }\n const spin = (clip: string, way: 1 | -1, inGroup: boolean): FigureProposalStep => ({\n kind: 'set-driver',\n state: joint.input,\n clip,\n duration: seconds,\n keys: [\n { seconds: 0, value: 0 },\n { seconds, value: way * turn }\n ],\n interpolation: 'linear',\n loop: 'wrap',\n accumulates: true,\n ...(inGroup ? { group } : {})\n })\n const clips = c.direction ? [forward, reverse] : [forward]\n steps.push(spin(forward, 1, false))\n steps.push({ kind: 'set-motion-group', group: { id: group, label: c.label, clips: [forward], defaultClip: forward, transitionSeconds: 0 } })\n if (c.direction) {\n steps.push(spin(reverse, -1, true))\n steps.push({ kind: 'set-motion-group', group: { id: group, label: c.label, clips, defaultClip: forward, transitionSeconds: 0 } })\n }\n const taken = (asset.dataInterface?.bindings ?? []).map(b => b.id)\n const bind = (base: string, binding: Omit<FigureDataValueBinding, 'id'> | Omit<FigureDataTableBinding, 'id'>): FigureProposalStep => {\n const id = freeIdOf(taken, base)\n taken.push(id)\n return { kind: 'set-data-binding', binding: { id, ...binding } as FigureDataBinding }\n }\n if (c.on) steps.push(bind(`${group}-on`, { accessor: c.on, rule: 'table', lookup: 'code', targets: { group }, table: { true: { paused: false }, false: { paused: true } } }))\n if (c.speed) steps.push(bind(`${group}-speed`, { accessor: c.speed.path, behavior: { kind: 'motion-speed', group }, rule: 'scale', param: { scale: round(seconds / 60), offset: 0 } }))\n if (c.direction) {\n const values = domainOf(fieldAt(schema, c.direction.path) ?? { kind: 'text' }).map(String)\n const covered = values.every(v => v === c.direction!.forward || v === c.direction!.reverse)\n steps.push(\n bind(`${group}-direction`, {\n accessor: c.direction.path,\n rule: 'table',\n lookup: 'code',\n targets: { group },\n table: { [c.direction.forward]: { clip: forward }, [c.direction.reverse]: { clip: reverse }, ...(covered ? {} : { default: { clip: forward } }) }\n })\n )\n }\n return steps\n}\n"]}
@@ -93,6 +93,17 @@ export const EditorStyles = css `
93
93
  a promise to whoever draws the figure, is outlined.
94
94
  */
95
95
  ox-canvas-bar button[save],
96
+ div[release-blockers] button[as-new-type] {
97
+ justify-self: start;
98
+ margin-top: 4px;
99
+ padding: 4px 10px;
100
+ border: 1px solid var(--md-sys-color-outline);
101
+ border-radius: 999px;
102
+ color: var(--md-sys-color-primary);
103
+ background: var(--md-sys-color-surface);
104
+ font: inherit;
105
+ cursor: pointer;
106
+ }
96
107
  ox-canvas-bar button[publish] {
97
108
  display: inline-flex;
98
109
  align-items: center;