@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.
- package/client/graphql/index.ts +2 -0
- package/client/modeller/canvas.ts +4 -2
- package/client/modeller/clips.ts +74 -4
- package/client/modeller/data-interface.ts +14 -0
- package/client/modeller/editor-styles.ts +11 -0
- package/client/modeller/editor.ts +39 -11
- package/client/modeller/fasten-form.ts +73 -3
- package/client/modeller/fasten-geometry.ts +11 -1
- package/client/modeller/figure-cavity-drawing.ts +1 -3
- package/client/modeller/figure-clips.ts +101 -8
- package/client/modeller/figure-fasten-dialog.ts +41 -30
- package/client/modeller/figure-fasten-drawing.ts +5 -4
- package/client/modeller/figure-first-save.ts +4 -3
- package/client/modeller/figure-links.ts +85 -28
- package/client/modeller/figure-preview.ts +50 -4
- package/client/modeller/figure-size-editor.ts +7 -2
- package/client/modeller/first-save.ts +8 -0
- package/client/modeller/focus-on-render.ts +4 -0
- package/client/modeller/palette.ts +27 -0
- package/client/modeller/pivot.ts +76 -0
- package/client/modeller/product-session.ts +5 -1
- package/client/modeller/size-response.ts +14 -0
- package/client/modeller/stage-model.ts +50 -6
- package/client/types.ts +2 -0
- package/dist-client/graphql/index.js +2 -0
- package/dist-client/graphql/index.js.map +1 -1
- package/dist-client/modeller/canvas.d.ts +1 -0
- package/dist-client/modeller/canvas.js +3 -2
- package/dist-client/modeller/canvas.js.map +1 -1
- package/dist-client/modeller/clips.d.ts +23 -6
- package/dist-client/modeller/clips.js +69 -4
- package/dist-client/modeller/clips.js.map +1 -1
- package/dist-client/modeller/data-interface.d.ts +5 -0
- package/dist-client/modeller/data-interface.js +15 -0
- package/dist-client/modeller/data-interface.js.map +1 -1
- package/dist-client/modeller/editor-styles.js +11 -0
- package/dist-client/modeller/editor-styles.js.map +1 -1
- package/dist-client/modeller/editor.d.ts +6 -0
- package/dist-client/modeller/editor.js +35 -11
- package/dist-client/modeller/editor.js.map +1 -1
- package/dist-client/modeller/fasten-form.d.ts +8 -0
- package/dist-client/modeller/fasten-form.js +68 -5
- package/dist-client/modeller/fasten-form.js.map +1 -1
- package/dist-client/modeller/fasten-geometry.d.ts +6 -0
- package/dist-client/modeller/fasten-geometry.js +10 -1
- package/dist-client/modeller/fasten-geometry.js.map +1 -1
- package/dist-client/modeller/figure-cavity-drawing.js +1 -3
- package/dist-client/modeller/figure-cavity-drawing.js.map +1 -1
- package/dist-client/modeller/figure-clips.d.ts +9 -0
- package/dist-client/modeller/figure-clips.js +104 -8
- package/dist-client/modeller/figure-clips.js.map +1 -1
- package/dist-client/modeller/figure-fasten-dialog.js +39 -24
- package/dist-client/modeller/figure-fasten-dialog.js.map +1 -1
- package/dist-client/modeller/figure-fasten-drawing.js +5 -4
- package/dist-client/modeller/figure-fasten-drawing.js.map +1 -1
- package/dist-client/modeller/figure-first-save.js +4 -3
- package/dist-client/modeller/figure-first-save.js.map +1 -1
- package/dist-client/modeller/figure-links.d.ts +9 -0
- package/dist-client/modeller/figure-links.js +89 -35
- package/dist-client/modeller/figure-links.js.map +1 -1
- package/dist-client/modeller/figure-preview.js +48 -4
- package/dist-client/modeller/figure-preview.js.map +1 -1
- package/dist-client/modeller/figure-size-editor.js +7 -3
- package/dist-client/modeller/figure-size-editor.js.map +1 -1
- package/dist-client/modeller/first-save.d.ts +5 -0
- package/dist-client/modeller/first-save.js +7 -0
- package/dist-client/modeller/first-save.js.map +1 -1
- package/dist-client/modeller/focus-on-render.d.ts +2 -0
- package/dist-client/modeller/focus-on-render.js +4 -0
- package/dist-client/modeller/focus-on-render.js.map +1 -0
- package/dist-client/modeller/links.d.ts +1 -1
- package/dist-client/modeller/palette.d.ts +14 -0
- package/dist-client/modeller/palette.js +23 -0
- package/dist-client/modeller/palette.js.map +1 -1
- package/dist-client/modeller/pivot.d.ts +12 -0
- package/dist-client/modeller/pivot.js +59 -0
- package/dist-client/modeller/pivot.js.map +1 -0
- package/dist-client/modeller/product-session.js +6 -2
- package/dist-client/modeller/product-session.js.map +1 -1
- package/dist-client/modeller/size-response.d.ts +6 -0
- package/dist-client/modeller/size-response.js +14 -0
- package/dist-client/modeller/size-response.js.map +1 -1
- package/dist-client/modeller/stage-model.d.ts +17 -3
- package/dist-client/modeller/stage-model.js +44 -6
- package/dist-client/modeller/stage-model.js.map +1 -1
- package/dist-client/route.d.ts +1 -1
- package/dist-client/tsconfig.tsbuildinfo +1 -1
- package/dist-client/types.d.ts +2 -0
- package/dist-client/types.js.map +1 -1
- package/package.json +5 -5
- package/test/browser/editing.check.mjs +6 -5
- package/test/browser/section.check.mjs +21 -0
- package/test/clips.test.ts +49 -4
- package/test/data-motion.test.ts +8 -0
- package/test/fasten-form.test.ts +57 -0
- package/test/fasten-geometry.test.ts +25 -1
- package/test/first-part-on-plane.test.ts +52 -0
- package/test/first-save.test.ts +11 -1
- package/test/pivot.test.ts +57 -0
- package/test/save-landed.test.ts +20 -1
- package/test/size-response.test.ts +10 -2
- package/test/stage-model.test.ts +23 -1
- package/translations/en.json +9 -0
- package/translations/es.json +9 -0
- package/translations/ja.json +9 -0
- package/translations/ko.json +9 -0
- package/translations/ms.json +9 -0
- package/translations/zh.json +9 -0
- package/tutorial/humanoid/README.md +22 -0
- package/tutorial/humanoid/chapters.mjs +247 -0
- package/tutorial/humanoid/encode.mjs +26 -0
- package/tutorial/humanoid/lib.mjs +197 -0
- package/tutorial/humanoid/record.mjs +65 -0
|
@@ -25,6 +25,8 @@ export declare class FigureClips extends FigureClips_base {
|
|
|
25
25
|
locked: boolean;
|
|
26
26
|
/** Where each clip is scrubbed to, in seconds. */
|
|
27
27
|
private at;
|
|
28
|
+
/** The clip the pose bar keys: the one last scrubbed. */
|
|
29
|
+
private active;
|
|
28
30
|
private adding;
|
|
29
31
|
private grouping;
|
|
30
32
|
/** The track whose copy is being set up: onto which control, how many seconds later. */
|
|
@@ -34,6 +36,11 @@ export declare class FigureClips extends FigureClips_base {
|
|
|
34
36
|
protected willUpdate(changed: PropertyValues): void;
|
|
35
37
|
render(): import("lit-html").TemplateResult<1> | typeof nothing;
|
|
36
38
|
private renderClip;
|
|
39
|
+
/**
|
|
40
|
+
* The clip being keyed -- the one last scrubbed or chosen here -- with its moment and 「현재 자세 기록」, right under the
|
|
41
|
+
* controls: type the controls, then record, without scrolling to the clip.
|
|
42
|
+
*/
|
|
43
|
+
private renderPoseBar;
|
|
37
44
|
/** 「이 자세 기억하기」: every control moved since the clip's pose was last shown or kept, as keys at this moment, one step. */
|
|
38
45
|
private renderRemember;
|
|
39
46
|
private renderTrack;
|
|
@@ -49,6 +56,8 @@ export declare class FigureClips extends FigureClips_base {
|
|
|
49
56
|
*/
|
|
50
57
|
private renderGroups;
|
|
51
58
|
private renderGroup;
|
|
59
|
+
/** A clip renamed: the pose bar, its moment and its pose stay with it under the new name. */
|
|
60
|
+
private rename;
|
|
52
61
|
/** Show the clip's pose at a moment: one batch of input changes, not saved as the default. */
|
|
53
62
|
/** Show the clip's pose at a moment. While the bar is dragged the pose is live (drawn, not recorded); the release
|
|
54
63
|
* applies it as one batch of input changes. */
|
|
@@ -4,7 +4,7 @@ import { css, html, LitElement, nothing } from 'lit';
|
|
|
4
4
|
import { customElement, property, state } from 'lit/decorators.js';
|
|
5
5
|
import { i18next, localize } from '@operato/i18n';
|
|
6
6
|
import { unitWord } from './unit-words.js';
|
|
7
|
-
import { clipGroupsOf, withKeyChanged, clipsOf, copiedTrackEdit, copyTargetsOf, freeClipNameOf, freeGroupIdOf, groupEdit, newClipEdits, newTrackKeys, poseAt, rememberedPoseEdits, shiftable, shiftOffKeyOf, trackEdit, undrivenOf, withKey, withoutKey } from './clips.js';
|
|
7
|
+
import { clipGroupsOf, withKeyChanged, clipsOf, copiedTrackEdit, copyClipEdits, copyTargetsOf, freeClipNameOf, freeGroupIdOf, groupEdit, newClipEdits, newTrackKeys, poseAt, rememberedPoseEdits, shiftable, shiftOffKeyOf, trackEdit, undrivenOf, withKey, withoutKey } from './clips.js';
|
|
8
8
|
import { SidePanelStyles } from '@things-factory/figure-viewer/dist-client/side-panel-styles.js';
|
|
9
9
|
import { HelpToggles } from './help.js';
|
|
10
10
|
/** A value as a person reads it: at most three decimals, the float's last digits (14.399999999999999) left out. */
|
|
@@ -33,6 +33,8 @@ let FigureClips = class FigureClips extends localize(i18next)(LitElement) {
|
|
|
33
33
|
this.locked = false;
|
|
34
34
|
/** Where each clip is scrubbed to, in seconds. */
|
|
35
35
|
this.at = {};
|
|
36
|
+
/** The clip the pose bar keys: the one last scrubbed. */
|
|
37
|
+
this.active = '';
|
|
36
38
|
this.adding = { state: '', clip: '', name: '', duration: 2 };
|
|
37
39
|
this.grouping = { clip: '', label: '' };
|
|
38
40
|
/** Per clip, the pose it was last shown or kept in: a control that differs from it now has been moved by the person. */
|
|
@@ -42,6 +44,51 @@ let FigureClips = class FigureClips extends localize(i18next)(LitElement) {
|
|
|
42
44
|
:host {
|
|
43
45
|
display: block;
|
|
44
46
|
}
|
|
47
|
+
/*
|
|
48
|
+
The pose bar: the clip being keyed, its moment and 「현재 자세 기록」, first under the controls and held at the top
|
|
49
|
+
while the clips scroll. With walk and run, run's own button stood under all of walk's tracks, a long scroll from
|
|
50
|
+
the controls typed for it (tutorial run 2026-11-12).
|
|
51
|
+
*/
|
|
52
|
+
div[pose-bar] {
|
|
53
|
+
position: sticky;
|
|
54
|
+
top: 0;
|
|
55
|
+
z-index: 1;
|
|
56
|
+
display: flex;
|
|
57
|
+
flex-wrap: wrap;
|
|
58
|
+
align-items: center;
|
|
59
|
+
gap: 6px 10px;
|
|
60
|
+
margin-bottom: 8px;
|
|
61
|
+
padding: 8px;
|
|
62
|
+
background: var(--md-sys-color-surface-container, var(--md-sys-color-surface));
|
|
63
|
+
border: 1px solid var(--md-sys-color-primary);
|
|
64
|
+
border-radius: 8px;
|
|
65
|
+
}
|
|
66
|
+
div[pose-bar] span[clip-choices] {
|
|
67
|
+
display: flex;
|
|
68
|
+
flex-wrap: wrap;
|
|
69
|
+
gap: 4px;
|
|
70
|
+
}
|
|
71
|
+
div[pose-bar] span[clip-choices] button {
|
|
72
|
+
font: inherit;
|
|
73
|
+
color: inherit;
|
|
74
|
+
padding: 1px 10px;
|
|
75
|
+
background: transparent;
|
|
76
|
+
border: 1px solid var(--md-sys-color-outline-variant);
|
|
77
|
+
border-radius: 10px;
|
|
78
|
+
cursor: pointer;
|
|
79
|
+
}
|
|
80
|
+
div[pose-bar] span[clip-choices] button[aria-pressed='true'] {
|
|
81
|
+
background: var(--md-sys-color-secondary-container);
|
|
82
|
+
border-color: var(--md-sys-color-secondary);
|
|
83
|
+
font-weight: 600;
|
|
84
|
+
}
|
|
85
|
+
div[pose-bar] label[at] input {
|
|
86
|
+
width: 64px;
|
|
87
|
+
}
|
|
88
|
+
div[pose-bar] p[hint] {
|
|
89
|
+
flex-basis: 100%;
|
|
90
|
+
margin: 0;
|
|
91
|
+
}
|
|
45
92
|
section[clip] {
|
|
46
93
|
display: grid;
|
|
47
94
|
gap: 8px;
|
|
@@ -172,6 +219,7 @@ let FigureClips = class FigureClips extends localize(i18next)(LitElement) {
|
|
|
172
219
|
/* Nothing to play yet: said inside the section it belongs to, with the section's own margins. */
|
|
173
220
|
const empty = !clips.length && !undrivenOf(asset).length && !asset.motionGroups?.length;
|
|
174
221
|
return html `
|
|
222
|
+
${clips.length ? this.renderPoseBar(clips) : nothing}
|
|
175
223
|
<section>
|
|
176
224
|
<h3>${i18next.t('figure.label.clips')}${this.help.button('figure.text.clips-explained')}</h3>
|
|
177
225
|
${this.help.hint('figure.text.clips-explained')}
|
|
@@ -189,12 +237,16 @@ let FigureClips = class FigureClips extends localize(i18next)(LitElement) {
|
|
|
189
237
|
return html `<section clip>
|
|
190
238
|
<div form>
|
|
191
239
|
<span>${i18next.t('figure.label.clip-name')}</span>
|
|
192
|
-
<input .value=${clip.name} ?disabled=${this.locked} @change=${(e) => this.
|
|
240
|
+
<input .value=${clip.name} ?disabled=${this.locked} @change=${(e) => this.rename(clip, e.target.value)} />
|
|
193
241
|
<span>${i18next.t('figure.label.clip-duration')}</span>
|
|
194
242
|
<input type="number" min="0.1" step="any" .value=${String(clip.duration)} ?disabled=${this.locked} @change=${(e) => this.edit({ kind: 'set-clip', clip: clip.name, duration: number(e) })} />
|
|
195
243
|
</div>
|
|
196
|
-
<button act copy-clip ?disabled=${this.locked
|
|
197
|
-
@click=${() =>
|
|
244
|
+
<button act copy-clip ?disabled=${this.locked} title=${i18next.t(grouped ? 'figure.text.copy-clip-explained' : 'figure.text.copy-clip-makes-group')}
|
|
245
|
+
@click=${() => {
|
|
246
|
+
/* The copy is what is keyed next: the pose bar turns to it. */
|
|
247
|
+
this.active = freeClipNameOf(this.asset, clip.name);
|
|
248
|
+
this.edits(copyClipEdits(this.asset, clip.name, i18next.t('figure.label.motion-group-named')));
|
|
249
|
+
}}>
|
|
198
250
|
<md-icon>content_copy</md-icon>${i18next.t('figure.button.copy-clip')}
|
|
199
251
|
</button>
|
|
200
252
|
<div row>
|
|
@@ -226,6 +278,34 @@ let FigureClips = class FigureClips extends localize(i18next)(LitElement) {
|
|
|
226
278
|
${clip.tracks.map(track => this.renderTrack(clip, track, at))}
|
|
227
279
|
</section>`;
|
|
228
280
|
}
|
|
281
|
+
/**
|
|
282
|
+
* The clip being keyed -- the one last scrubbed or chosen here -- with its moment and 「현재 자세 기록」, right under the
|
|
283
|
+
* controls: type the controls, then record, without scrolling to the clip.
|
|
284
|
+
*/
|
|
285
|
+
renderPoseBar(clips) {
|
|
286
|
+
const clip = clips.find(c => c.name === this.active) ?? clips[0];
|
|
287
|
+
const at = Math.min(this.at[clip.name] ?? 0, clip.duration);
|
|
288
|
+
return html `<div pose-bar>
|
|
289
|
+
${clips.length > 1
|
|
290
|
+
? html `<span clip-choices role="group" aria-label=${i18next.t('figure.label.clips')}>
|
|
291
|
+
${clips.map(c => html `<button type="button" aria-pressed=${String(c === clip)} ?disabled=${this.locked} @click=${() => this.scrub(c, Math.min(this.at[c.name] ?? 0, c.duration))}>${c.name}</button>`)}
|
|
292
|
+
</span>`
|
|
293
|
+
: html `<strong>${clip.name}</strong>`}
|
|
294
|
+
<label at>
|
|
295
|
+
<input
|
|
296
|
+
type="number"
|
|
297
|
+
min="0"
|
|
298
|
+
max=${clip.duration}
|
|
299
|
+
step="any"
|
|
300
|
+
.value=${String(Math.round(at * 1000) / 1000)}
|
|
301
|
+
?disabled=${this.locked}
|
|
302
|
+
aria-label=${i18next.t('figure.label.clip-time')}
|
|
303
|
+
@change=${(e) => this.scrub(clip, Math.min(Math.max(e.target.valueAsNumber, 0), clip.duration))}
|
|
304
|
+
/>s
|
|
305
|
+
</label>
|
|
306
|
+
${this.renderRemember(clip, at)}
|
|
307
|
+
</div>`;
|
|
308
|
+
}
|
|
229
309
|
/** 「이 자세 기억하기」: every control moved since the clip's pose was last shown or kept, as keys at this moment, one step. */
|
|
230
310
|
renderRemember(clip, at) {
|
|
231
311
|
const { edits, skipped } = rememberedPoseEdits(this.asset, clip.name, at, this.values, this.base[clip.name] ?? this.values);
|
|
@@ -365,11 +445,13 @@ let FigureClips = class FigureClips extends localize(i18next)(LitElement) {
|
|
|
365
445
|
const taken = !joining && clips.some(c => c.name === name);
|
|
366
446
|
const ready = !!name && !taken && duration > 0 && !!input;
|
|
367
447
|
const join = !joining && input && name ? newClipEdits(asset, stateId, name, duration, []).join : undefined;
|
|
368
|
-
|
|
448
|
+
/* A track that holds the pose now is the start of a move from pose to pose: smooth (review 2026-11-11, a walk's nine
|
|
449
|
+
tracks each changed by hand). The range preset sweeps at a steady rate, as before. */
|
|
450
|
+
const add = (keys, interpolation) => {
|
|
369
451
|
if (joining)
|
|
370
|
-
this.edit({ kind: 'set-driver', state: stateId, clip: name, keys });
|
|
452
|
+
this.edit({ kind: 'set-driver', state: stateId, clip: name, keys, ...(interpolation ? { interpolation } : {}) });
|
|
371
453
|
else
|
|
372
|
-
this.edits(newClipEdits(asset, stateId, name, duration, keys).edits);
|
|
454
|
+
this.edits(newClipEdits(asset, stateId, name, duration, keys, interpolation).edits);
|
|
373
455
|
/* The name was this clip's; the next new clip is named again. */
|
|
374
456
|
this.adding = { ...a, name: '', state: '' };
|
|
375
457
|
};
|
|
@@ -396,7 +478,7 @@ let FigureClips = class FigureClips extends localize(i18next)(LitElement) {
|
|
|
396
478
|
: join?.kind === 'group'
|
|
397
479
|
? html `<p hint track-join>${i18next.t('figure.text.track-joins-group', { name, group: join.label })}</p>`
|
|
398
480
|
: nothing}
|
|
399
|
-
<button act ?disabled=${this.locked || !ready} @click=${() => add(newTrackKeys(input, this.values[stateId], duration))}>
|
|
481
|
+
<button act ?disabled=${this.locked || !ready} @click=${() => add(newTrackKeys(input, this.values[stateId], duration), 'smooth')}>
|
|
400
482
|
<md-icon>add</md-icon>${i18next.t('figure.button.add-track')}
|
|
401
483
|
</button>
|
|
402
484
|
<button act range-track ?disabled=${this.locked || !ready} title=${i18next.t('figure.text.add-track-range-explained')}
|
|
@@ -499,6 +581,15 @@ let FigureClips = class FigureClips extends localize(i18next)(LitElement) {
|
|
|
499
581
|
: nothing}
|
|
500
582
|
</section>`;
|
|
501
583
|
}
|
|
584
|
+
/** A clip renamed: the pose bar, its moment and its pose stay with it under the new name. */
|
|
585
|
+
rename(clip, name) {
|
|
586
|
+
const moved = (by) => (clip.name in by ? { ...by, [name]: by[clip.name] } : by);
|
|
587
|
+
this.at = moved(this.at);
|
|
588
|
+
this.base = moved(this.base);
|
|
589
|
+
if (this.active === clip.name)
|
|
590
|
+
this.active = name;
|
|
591
|
+
this.edit({ kind: 'set-clip', clip: clip.name, name });
|
|
592
|
+
}
|
|
502
593
|
/** Show the clip's pose at a moment: one batch of input changes, not saved as the default. */
|
|
503
594
|
/** Show the clip's pose at a moment. While the bar is dragged the pose is live (drawn, not recorded); the release
|
|
504
595
|
* applies it as one batch of input changes. */
|
|
@@ -506,6 +597,7 @@ let FigureClips = class FigureClips extends localize(i18next)(LitElement) {
|
|
|
506
597
|
if (!this.asset || !Number.isFinite(seconds))
|
|
507
598
|
return;
|
|
508
599
|
this.at = { ...this.at, [clip.name]: seconds };
|
|
600
|
+
this.active = clip.name;
|
|
509
601
|
const changes = poseAt(this.asset, clip.name, seconds);
|
|
510
602
|
if (!changes.length)
|
|
511
603
|
return;
|
|
@@ -555,6 +647,10 @@ __decorate([
|
|
|
555
647
|
state(),
|
|
556
648
|
__metadata("design:type", Object)
|
|
557
649
|
], FigureClips.prototype, "at", void 0);
|
|
650
|
+
__decorate([
|
|
651
|
+
state(),
|
|
652
|
+
__metadata("design:type", Object)
|
|
653
|
+
], FigureClips.prototype, "active", void 0);
|
|
558
654
|
__decorate([
|
|
559
655
|
state(),
|
|
560
656
|
__metadata("design:type", Object)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"figure-clips.js","sourceRoot":"","sources":["../../client/modeller/figure-clips.ts"],"names":[],"mappings":"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","sourcesContent":["import '@material/web/icon/icon.js'\n\nimport { css, html, LitElement, nothing } from 'lit'\nimport type { PropertyValues } from 'lit'\nimport { customElement, property, state } from 'lit/decorators.js'\n\nimport { i18next, localize } from '@operato/i18n'\nimport { unitWord } from './unit-words.js'\nimport type { FigureAsset } from '@hatiolab/figure-model'\n\nimport { clipGroupsOf, withKeyChanged, clipsOf, copiedTrackEdit, copyTargetsOf, freeClipNameOf, freeGroupIdOf, groupEdit, newClipEdits, newTrackKeys, poseAt, rememberedPoseEdits, shiftable, shiftOffKeyOf, trackEdit, undrivenOf, withKey, withoutKey, type Clip, type ClipGroup, type ClipKey, type ClipTrack } from './clips.js'\nimport { SidePanelStyles } from '@things-factory/figure-viewer/dist-client/side-panel-styles.js'\nimport { HelpToggles } from './help.js'\n\n/** A value as a person reads it: at most three decimals, the float's last digits (14.399999999999999) left out. */\nconst shown = (value: number) => value.toLocaleString(undefined, { maximumFractionDigits: 3 })\n/* A number field's value: no grouping, to a thousandth. */\nconst typed = (value: number) => String(Math.round(value * 1000) / 1000)\n\n/**\n * 클립 — controls played by keys over time. A clip is one clock; each track plays one\n * control. Scrubbing a clip shows its pose at that moment (one batch of input changes, not saved as the default); a key\n * is added at the scrubbed moment with the control's value there, so a pose is made with the controls' sliders and\n * then kept as a key. Every change is one part edit.\n *\n * Clips of one motion group play one at a time on the same controls -- idle, walk, run (ADR-0051 §3.2): only clips of\n * one group may play the same control. A new clip on a control another clip plays is put in a group as it is made --\n * that clip's, or one made of the two -- and the panel says so before the button is pressed (review 2026-11-09).\n *\n * 「이 자세 기억하기」 keeps the pose the figure stands in now at the scrubbed moment, every control that moved, in one\n * step. What moved is read against the pose the clip was last shown or kept in (`base`).\n */\n@customElement('figure-clips')\nexport class FigureClips extends localize(i18next)(LitElement) {\n private readonly help = new HelpToggles(this)\n static styles = [SidePanelStyles, css`\n :host {\n display: block;\n }\n section[clip] {\n display: grid;\n gap: 8px;\n padding: 8px;\n border: 1px solid var(--md-sys-color-outline-variant);\n border-radius: 8px;\n }\n div[row] {\n display: grid;\n grid-template-columns: minmax(0, 1fr) 72px;\n gap: 6px;\n align-items: center;\n }\n div[track] {\n display: grid;\n gap: 4px;\n padding-top: 6px;\n border-top: 1px dashed var(--md-sys-color-outline-variant);\n }\n /*\n The track's name on its own line, then how it repeats and the button that removes it. A flex row let the shared\n full-width select and button squeeze the name to one letter a line (user, 2026-09-24).\n */\n div[track-head] {\n display: grid;\n grid-template-columns: minmax(0, 1fr) 30px 30px;\n gap: 4px 6px;\n align-items: center;\n }\n div[track-head] strong {\n grid-column: 1 / -1;\n min-width: 0;\n overflow-wrap: anywhere;\n }\n /* How it moves between keys: its own row under the head, as wide as the track, its words not cut. */\n div[track-head] select[interpolation] {\n grid-row: 3;\n grid-column: 1 / -1;\n }\n div[track-head] button[act] {\n width: 30px;\n min-height: var(--figure-control-height);\n margin: 0;\n padding: 0;\n }\n /* A track copied onto a control, moved round its loop: under its head, in the panel's form look. */\n div[copy-form] {\n display: grid;\n gap: 6px;\n padding: 6px 8px;\n border-radius: 6px;\n background: var(--md-sys-color-surface-container);\n }\n div[copy-form] div[pair] {\n display: flex;\n gap: 6px;\n justify-content: flex-end;\n }\n div[keys] {\n display: flex;\n flex-wrap: wrap;\n gap: 4px;\n }\n span[key] {\n display: inline-flex;\n align-items: center;\n gap: 2px;\n padding: 0 2px 0 8px;\n border-radius: 999em;\n background: var(--md-sys-color-surface-container);\n font-variant-numeric: tabular-nums;\n }\n /* A key's moment and value, typed in the chip: as narrow as their numbers, on the chip's ground. */\n span[key] input {\n width: 44px;\n min-width: 0;\n height: 20px;\n padding: 0 2px;\n font: inherit;\n text-align: right;\n font-variant-numeric: tabular-nums;\n color: inherit;\n background: transparent;\n border: none;\n border-bottom: 1px solid var(--md-sys-color-outline-variant);\n }\n span[key] input[readonly] {\n border-bottom-color: transparent;\n }\n label[at] {\n display: inline-flex;\n align-items: center;\n gap: 2px;\n font-variant-numeric: tabular-nums;\n }\n label[at] input {\n width: 52px;\n min-width: 0;\n text-align: right;\n }\n span[key] button {\n width: 22px;\n height: 22px;\n padding: 0;\n border: none;\n background: none;\n }\n md-icon {\n font-size: 16px;\n width: 16px;\n height: 16px;\n }\n `]\n\n @property({ attribute: false }) asset?: FigureAsset\n /** The values the editor holds now, by input id -- what a new key takes. */\n @property({ attribute: false }) values: Record<string, number> = {}\n @property({ type: Boolean }) locked = false\n\n /** Where each clip is scrubbed to, in seconds. */\n @state() private at: Record<string, number> = {}\n @state() private adding = { state: '', clip: '', name: '', duration: 2 }\n @state() private grouping = { clip: '', label: '' }\n /** The track whose copy is being set up: onto which control, how many seconds later. */\n @state() private copying?: { clip: string; state: string; target: string; seconds: number }\n /** Per clip, the pose it was last shown or kept in: a control that differs from it now has been moved by the person. */\n @state() private base: Record<string, Record<string, number>> = {}\n\n protected willUpdate(changed: PropertyValues) {\n if (!changed.has('asset') || !this.asset) return\n /* A clip seen for the first time takes the pose the figure stands in now as where its moves are read from. */\n const names = clipsOf(this.asset).map(c => c.name)\n const fresh = names.filter(n => !this.base[n])\n if (fresh.length) this.base = { ...Object.fromEntries(Object.entries(this.base).filter(([n]) => names.includes(n))), ...Object.fromEntries(fresh.map(n => [n, { ...this.values }])) }\n }\n\n render() {\n const asset = this.asset\n if (!asset) return nothing\n const clips = clipsOf(asset)\n /* Nothing to play yet: said inside the section it belongs to, with the section's own margins. */\n const empty = !clips.length && !undrivenOf(asset).length && !asset.motionGroups?.length\n return html`\n <section>\n <h3>${i18next.t('figure.label.clips')}${this.help.button('figure.text.clips-explained')}</h3>\n ${this.help.hint('figure.text.clips-explained')}\n ${clips.map(clip => this.renderClip(clip))}\n ${empty ? html`<p hint>${i18next.t('figure.text.no-clips')}</p>` : nothing}\n </section>\n ${empty ? nothing : this.renderAdd(asset, clips)} ${this.renderGroups(asset)}\n `\n }\n\n private renderClip(clip: Clip) {\n const at = Math.min(this.at[clip.name] ?? 0, clip.duration)\n const number = (e: Event) => (e.target as HTMLInputElement).valueAsNumber\n /* A copy plays the same controls: only clips of one motion group may (ADR-0051 §3.2). */\n const grouped = !!this.asset?.motionGroups?.some(g => g.clips.includes(clip.name))\n return html`<section clip>\n <div form>\n <span>${i18next.t('figure.label.clip-name')}</span>\n <input .value=${clip.name} ?disabled=${this.locked} @change=${(e: Event) => this.edit({ kind: 'set-clip', clip: clip.name, name: (e.target as HTMLInputElement).value })} />\n <span>${i18next.t('figure.label.clip-duration')}</span>\n <input type=\"number\" min=\"0.1\" step=\"any\" .value=${String(clip.duration)} ?disabled=${this.locked} @change=${(e: Event) => this.edit({ kind: 'set-clip', clip: clip.name, duration: number(e) })} />\n </div>\n <button act copy-clip ?disabled=${this.locked || !grouped} title=${i18next.t(grouped ? 'figure.text.copy-clip-explained' : 'figure.text.copy-clip-needs-group')}\n @click=${() => this.edit({ kind: 'copy-clip', clip: clip.name, name: freeClipNameOf(this.asset!, clip.name) })}>\n <md-icon>content_copy</md-icon>${i18next.t('figure.button.copy-clip')}\n </button>\n <div row>\n <input\n type=\"range\"\n min=\"0\"\n max=${clip.duration}\n step=${clip.duration / 100}\n .value=${String(at)}\n ?disabled=${this.locked}\n aria-label=${i18next.t('figure.label.clip-time')}\n @input=${(e: Event) => this.scrub(clip, number(e), true)}\n @change=${(e: Event) => this.scrub(clip, number(e))}\n />\n <label at>\n <input\n type=\"number\"\n min=\"0\"\n max=${clip.duration}\n step=\"any\"\n .value=${String(Math.round(at * 1000) / 1000)}\n ?disabled=${this.locked}\n aria-label=${i18next.t('figure.label.clip-time')}\n @change=${(e: Event) => this.scrub(clip, Math.min(Math.max(number(e), 0), clip.duration))}\n />s\n </label>\n </div>\n ${this.renderRemember(clip, at)}\n ${clip.tracks.map(track => this.renderTrack(clip, track, at))}\n </section>`\n }\n\n /** 「이 자세 기억하기」: every control moved since the clip's pose was last shown or kept, as keys at this moment, one step. */\n private renderRemember(clip: Clip, at: number) {\n const { edits, skipped } = rememberedPoseEdits(this.asset!, clip.name, at, this.values, this.base[clip.name] ?? this.values)\n const label = (id: string) => this.asset!.stateInputs?.[id]?.label ?? id\n return html`<button act remember-pose ?disabled=${this.locked || !edits.length} title=${edits.length ? '' : i18next.t('figure.text.remember-pose-nothing')}\n @click=${() => {\n this.edits(edits)\n this.base = { ...this.base, [clip.name]: { ...this.values } }\n }}>\n <md-icon>photo_camera</md-icon>${i18next.t('figure.button.remember-pose', { seconds: at.toFixed(2) })}\n </button>\n ${skipped.length ? html`<p hint>${i18next.t('figure.text.remember-pose-skipped', { controls: skipped.map(label).join(', ') })}</p>` : nothing}`\n }\n\n private renderTrack(clip: Clip, track: ClipTrack, at: number) {\n const current = this.values[track.state]\n return html`<div track>\n <div track-head>\n <strong>${track.label} <small>(${unitWord(track.unit)})</small></strong>\n <select\n aria-label=${i18next.t('figure.label.clip-loop')}\n ?disabled=${this.locked}\n @change=${(e: Event) => this.edit(trackEdit(clip, track, { loop: (e.target as HTMLSelectElement).value as 'wrap' | 'hold' }))}\n >\n <option value=\"wrap\" ?selected=${track.loop === 'wrap'}>${i18next.t('figure.label.clip-loop-wrap')}</option>\n <option value=\"hold\" ?selected=${track.loop === 'hold'}>${i18next.t('figure.label.clip-loop-hold')}</option>\n </select>\n <select\n interpolation\n aria-label=${i18next.t('figure.label.clip-interpolation')}\n title=${i18next.t('figure.label.clip-interpolation')}\n ?disabled=${this.locked}\n @change=${(e: Event) => this.edit(trackEdit(clip, track, { interpolation: (e.target as HTMLSelectElement).value as ClipTrack['interpolation'] }))}\n >\n ${(['linear', 'smooth', 'step'] as const).map(i => html`<option value=${i} ?selected=${track.interpolation === i}>${i18next.t(`figure.label.clip-interpolation-${i}`)}</option>`)}\n </select>\n <button act copy-track ?disabled=${this.locked} title=${i18next.t('figure.button.copy-track')} aria-label=${i18next.t('figure.button.copy-track')}\n @click=${() => (this.copying = this.copying?.clip === clip.name && this.copying.state === track.state ? undefined : { clip: clip.name, state: track.state, target: track.state, seconds: 0 })}>\n <md-icon>content_copy</md-icon>\n </button>\n <button act ?disabled=${this.locked} title=${i18next.t('figure.button.remove-track')} @click=${() => this.edit({ kind: 'remove-driver', state: track.state, clip: clip.name })}>\n <md-icon>close</md-icon>\n </button>\n </div>\n ${this.copying?.clip === clip.name && this.copying.state === track.state ? this.renderCopy(clip, track) : nothing}\n <div keys>\n ${track.keys.map(\n (key, i) => html`<span key\n ><input\n type=\"number\"\n step=\"any\"\n min=\"0\"\n max=${clip.duration}\n ?readonly=${i === 0}\n ?disabled=${this.locked}\n title=${i === 0 ? i18next.t('figure.text.key-starts-the-clip') : ''}\n aria-label=${`${i18next.t('figure.label.key-seconds')} ${i + 1}`}\n .value=${typed(key.seconds)}\n @change=${(e: Event) => this.changeKey(clip, track, i, { seconds: (e.target as HTMLInputElement).valueAsNumber }, e)}\n />s →\n <input\n type=\"number\"\n step=\"any\"\n ?disabled=${this.locked}\n aria-label=${`${i18next.t('figure.label.key-value')} ${i + 1}`}\n .value=${typed(key.value)}\n @change=${(e: Event) => this.changeKey(clip, track, i, { value: (e.target as HTMLInputElement).valueAsNumber }, e)}\n />\n <button\n ?disabled=${this.locked || !withoutKey(track.keys, i)}\n title=${i18next.t('figure.button.remove-key')}\n aria-label=${i18next.t('figure.button.remove-key')}\n @click=${() => this.edit(trackEdit(clip, track, { keys: withoutKey(track.keys, i)! }))}\n >\n <md-icon>close</md-icon>\n </button></span\n >`\n )}\n </div>\n <button\n act\n ?disabled=${this.locked || current === undefined}\n @click=${() => this.edit(trackEdit(clip, track, { keys: withKey(track.keys, { seconds: Math.round(at * 1000) / 1000, value: current! }) }))}\n >\n <md-icon>add</md-icon>${i18next.t('figure.button.add-key-here', { seconds: at.toFixed(2), value: current === undefined ? '' : shown(current) })}\n </button>\n </div>`\n }\n\n /**\n * A track onto a control -- itself, or another -- moved round its loop by some seconds: one leg's curve given to the\n * next on its own beat (robot dog 2026-11-03). Only a wrapping track moves round; any track is copied.\n */\n private renderCopy(clip: Clip, track: ClipTrack) {\n const c = this.copying!\n const asset = this.asset!\n const targets = copyTargetsOf(asset, clip.name)\n const moves = shiftable(track)\n const seconds = moves && Number.isFinite(c.seconds) ? c.seconds : 0\n const same = c.target === track.state && !seconds\n /* A smooth track goes round only onto one of its keys: said, with the moments it can go to, and not applied. */\n const fits = moves ? shiftOffKeyOf(track, clip.duration, seconds) : null\n return html`<div copy-form>\n <div form>\n <span>${i18next.t('figure.label.copy-track-onto')}</span>\n <select aria-label=${i18next.t('figure.label.copy-track-onto')} @change=${(e: Event) => (this.copying = { ...c, target: (e.target as HTMLSelectElement).value })}>\n ${targets.map(id => html`<option value=${id} ?selected=${id === c.target}>${id === track.state ? i18next.t('figure.label.copy-track-itself') : (asset.stateInputs?.[id]?.label ?? id)}</option>`)}\n </select>\n <span>${i18next.t('figure.label.copy-track-later')}</span>\n <label at title=${moves ? '' : i18next.t('figure.text.copy-track-no-loop')}>\n <input type=\"number\" step=\"any\" aria-label=${i18next.t('figure.label.copy-track-later')} ?disabled=${!moves} .value=${typed(seconds)}\n @change=${(e: Event) => (this.copying = { ...c, seconds: (e.target as HTMLInputElement).valueAsNumber })} />s\n <small>/ ${typed(clip.duration)}s</small>\n </label>\n </div>\n ${fits ? html`<p hint off-key>${i18next.t('figure.text.copy-track-off-key', { seconds: fits.map(typed).join(', ') })}</p>` : nothing}\n <div pair>\n <button act ?disabled=${this.locked || same || !!fits}\n @click=${() => {\n this.edit(copiedTrackEdit(asset, clip, track, c.target, seconds))\n this.copying = undefined\n }}>${i18next.t(c.target === track.state ? 'figure.button.shift-track' : 'figure.button.copy-track-apply')}</button>\n <button act @click=${() => (this.copying = undefined)}>${i18next.t('figure.button.cancel')}</button>\n </div>\n </div>`\n }\n\n private renderAdd(asset: FigureAsset, clips: Clip[]) {\n const a = this.adding\n const joining = clips.find(c => c.name === a.clip)\n /*\n The controls a track can take. Joining a clip: those it may play. A new clip: any control -- one another clip\n plays puts the new clip in a group with it, said below before the button is pressed (review 2026-11-09: the\n controls used to vanish from the list, and the group had to be designed first).\n */\n const free = joining ? undrivenOf(asset, joining.name) : asset.document.model.inputs.filter(i => i.role === 'state').map(i => i.id)\n const stateId = free.includes(a.state) ? a.state : free[0]\n const name = joining ? joining.name : a.name.trim()\n const input = asset.document.model.inputs.find(i => i.id === stateId)\n const duration = joining ? joining.duration : a.duration\n /* A new clip takes a name no clip has: the same name would rewrite that clip's track, not add one. */\n const taken = !joining && clips.some(c => c.name === name)\n const ready = !!name && !taken && duration > 0 && !!input\n const join = !joining && input && name ? newClipEdits(asset, stateId!, name, duration, []).join : undefined\n const add = (keys: ClipKey[]) => {\n if (joining) this.edit({ kind: 'set-driver', state: stateId, clip: name, keys })\n else this.edits(newClipEdits(asset, stateId!, name, duration, keys).edits)\n /* The name was this clip's; the next new clip is named again. */\n this.adding = { ...a, name: '', state: '' }\n }\n return html`<section><h3>${i18next.t('figure.label.add-track')}</h3>\n <div form>\n <span>${i18next.t('figure.label.controls')}</span>\n <select ?disabled=${!free.length} @change=${(e: Event) => (this.adding = { ...a, state: (e.target as HTMLSelectElement).value })}>\n ${free.map(id => html`<option value=${id} ?selected=${id === stateId}>${asset.stateInputs?.[id]?.label ?? id}</option>`)}\n </select>\n <span>${i18next.t('figure.label.clip')}</span>\n <select @change=${(e: Event) => (this.adding = { ...a, clip: (e.target as HTMLSelectElement).value })}>\n <option value=\"\" ?selected=${!joining}>${i18next.t('figure.label.new-clip')}</option>\n ${clips.map(c => html`<option value=${c.name} ?selected=${c === joining}>${c.name}</option>`)}\n </select>\n ${joining\n ? nothing\n : html`<span>${i18next.t('figure.label.clip-name')}</span>\n <input .value=${a.name} placeholder=\"cycle\" @input=${(e: Event) => (this.adding = { ...a, name: (e.target as HTMLInputElement).value })} />\n <span>${i18next.t('figure.label.clip-duration')}</span>\n <input type=\"number\" min=\"0.1\" step=\"any\" .value=${String(a.duration)} @change=${(e: Event) => (this.adding = { ...a, duration: (e.target as HTMLInputElement).valueAsNumber })} />`}\n </div>\n ${join?.kind === 'new-group'\n ? html`<p hint track-join>${i18next.t('figure.text.track-makes-group', { clip: join.clip, name, group: join.label })}</p>`\n : join?.kind === 'group'\n ? html`<p hint track-join>${i18next.t('figure.text.track-joins-group', { name, group: join.label })}</p>`\n : nothing}\n <button act ?disabled=${this.locked || !ready} @click=${() => add(newTrackKeys(input!, this.values[stateId!], duration))}>\n <md-icon>add</md-icon>${i18next.t('figure.button.add-track')}\n </button>\n <button act range-track ?disabled=${this.locked || !ready} title=${i18next.t('figure.text.add-track-range-explained')}\n @click=${() => add(newTrackKeys(input!, this.values[stateId!], duration, 'range'))}>\n <md-icon>swap_horiz</md-icon>${i18next.t('figure.button.add-track-range')}\n </button></section>`\n }\n\n /**\n * The motion groups: a name, the clip that plays until another is chosen, how long a change of clip blends, and the\n * clips each holds. A group is made from a clip in none; a clip in none joins one here. Every change is one edit.\n */\n private renderGroups(asset: FigureAsset) {\n const { groups, free } = clipGroupsOf(asset)\n if (!groups.length && !free.length) return nothing\n const g = this.grouping\n const first = free.includes(g.clip) ? g.clip : free[0]\n return html`<section>\n <h3>${i18next.t('figure.label.motion-groups')}${this.help.button('figure.text.motion-groups-explained')}</h3>\n ${this.help.hint('figure.text.motion-groups-explained')}\n ${groups.map(group => this.renderGroup(group, free))}\n ${free.length\n ? html`<div form>\n <span>${i18next.t('figure.label.motion-group-name')}</span>\n <input .value=${g.label} placeholder=${i18next.t('figure.label.motion-group')} @input=${(e: Event) => (this.grouping = { ...g, label: (e.target as HTMLInputElement).value })} />\n <span>${i18next.t('figure.label.clip')}</span>\n <select @change=${(e: Event) => (this.grouping = { ...g, clip: (e.target as HTMLSelectElement).value })}>\n ${free.map(c => html`<option value=${c} ?selected=${c === first}>${c}</option>`)}\n </select>\n </div>\n <button\n act\n ?disabled=${this.locked || !first || !g.label.trim()}\n @click=${() => {\n this.edit({ kind: 'set-motion-group', group: { id: freeGroupIdOf(asset), label: g.label.trim(), clips: [first!], defaultClip: first!, transitionSeconds: 0.2 } })\n this.grouping = { clip: '', label: '' }\n }}\n >\n <md-icon>add</md-icon>${i18next.t('figure.button.add-motion-group')}\n </button>`\n : nothing}\n </section>`\n }\n\n private renderGroup(group: ClipGroup, free: string[]) {\n const value = (e: Event) => (e.target as HTMLInputElement | HTMLSelectElement).value\n return html`<section clip>\n <div track-head>\n <strong>${group.label}</strong>\n <button act ?disabled=${this.locked} title=${i18next.t('figure.button.remove-motion-group')} @click=${() => this.edit({ kind: 'remove-motion-group', id: group.id })}>\n <md-icon>close</md-icon>\n </button>\n </div>\n <div form>\n <span>${i18next.t('figure.label.motion-group-name')}</span>\n <input .value=${group.label} ?disabled=${this.locked} @change=${(e: Event) => value(e).trim() && this.edit(groupEdit(group, { label: value(e).trim() }))} />\n <span>${i18next.t('figure.label.motion-group-default')}</span>\n <select ?disabled=${this.locked} @change=${(e: Event) => this.edit(groupEdit(group, { defaultClip: value(e) }))}>\n ${group.clips.map(c => html`<option value=${c} ?selected=${c === group.defaultClip}>${c}</option>`)}\n </select>\n <span>${i18next.t('figure.label.motion-group-transition')}</span>\n <input\n type=\"number\"\n min=\"0\"\n step=\"any\"\n .value=${String(group.transitionSeconds)}\n ?disabled=${this.locked}\n @change=${(e: Event) => this.edit(groupEdit(group, { transitionSeconds: (e.target as HTMLInputElement).valueAsNumber }))}\n />\n </div>\n <div keys>\n ${group.clips.map(\n c => html`<span key\n >${c}\n <button\n ?disabled=${this.locked || group.clips.length < 2}\n title=${i18next.t('figure.button.remove-clip-from-group')}\n aria-label=${i18next.t('figure.button.remove-clip-from-group')}\n @click=${() => {\n const clips = group.clips.filter(x => x !== c)\n this.edit(groupEdit(group, { clips, defaultClip: group.defaultClip === c ? clips[0]! : group.defaultClip }))\n }}\n >\n <md-icon>close</md-icon>\n </button></span\n >`\n )}\n </div>\n ${free.length\n ? html`<select\n aria-label=${i18next.t('figure.button.add-clip-to-group')}\n ?disabled=${this.locked}\n @change=${(e: Event) => {\n const c = value(e)\n if (c) this.edit(groupEdit(group, { clips: [...group.clips, c] }))\n ;(e.target as HTMLSelectElement).value = ''\n }}\n >\n <option value=\"\" selected>${i18next.t('figure.button.add-clip-to-group')}</option>\n ${free.map(c => html`<option value=${c}>${c}</option>`)}\n </select>`\n : nothing}\n </section>`\n }\n\n /** Show the clip's pose at a moment: one batch of input changes, not saved as the default. */\n /** Show the clip's pose at a moment. While the bar is dragged the pose is live (drawn, not recorded); the release\n * applies it as one batch of input changes. */\n private scrub(clip: Clip, seconds: number, live = false) {\n if (!this.asset || !Number.isFinite(seconds)) return\n this.at = { ...this.at, [clip.name]: seconds }\n const changes = poseAt(this.asset, clip.name, seconds)\n if (!changes.length) return\n if (live) {\n const values = Object.fromEntries(changes.map(c => [c.input, c.value]))\n this.dispatchEvent(new CustomEvent('states-live', { detail: { values }, bubbles: true, composed: true }))\n return\n }\n this.dispatchEvent(new CustomEvent('states', { detail: { changes }, bubbles: true, composed: true }))\n /* The clip's pose shown: what moves from here is the person's. */\n this.base = { ...this.base, [clip.name]: { ...this.values, ...Object.fromEntries(changes.map(c => [c.input, c.value])) } }\n }\n\n /** A key's moment or value typed: one edit of the track; a moment the track cannot take puts the field back. */\n private changeKey(clip: Clip, track: ClipTrack, index: number, patch: Partial<{ seconds: number; value: number }>, e: Event) {\n const keys = withKeyChanged(track.keys, index, patch, clip.duration)\n if (!keys) {\n const field = e.target as HTMLInputElement\n const was = track.keys[index]!\n field.value = 'seconds' in patch ? typed(was.seconds) : typed(was.value)\n return\n }\n this.edit(trackEdit(clip, track, { keys }))\n }\n\n private edit(edit: unknown) {\n this.dispatchEvent(new CustomEvent('part-edit', { detail: { edit }, bubbles: true, composed: true }))\n }\n\n /** Several edits as one step of the history. */\n private edits(edits: unknown[]) {\n if (edits.length === 1) return this.edit(edits[0])\n this.dispatchEvent(new CustomEvent('part-edits', { detail: { edits }, bubbles: true, composed: true }))\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"figure-clips.js","sourceRoot":"","sources":["../../client/modeller/figure-clips.ts"],"names":[],"mappings":";AAAA,OAAO,4BAA4B,CAAA;AAEnC,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,KAAK,CAAA;AAEpD,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAA;AAElE,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AACjD,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAA;AAG1C,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,aAAa,EAAE,cAAc,EAAE,aAAa,EAAE,SAAS,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,EAAE,mBAAmB,EAAE,SAAS,EAAE,aAAa,EAAE,SAAS,EAAE,UAAU,EAAE,OAAO,EAAE,UAAU,EAA2D,MAAM,YAAY,CAAA;AACnV,OAAO,EAAE,eAAe,EAAE,MAAM,gEAAgE,CAAA;AAChG,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAA;AAEvC,mHAAmH;AACnH,MAAM,KAAK,GAAG,CAAC,KAAa,EAAE,EAAE,CAAC,KAAK,CAAC,cAAc,CAAC,SAAS,EAAE,EAAE,qBAAqB,EAAE,CAAC,EAAE,CAAC,CAAA;AAC9F,2DAA2D;AAC3D,MAAM,KAAK,GAAG,CAAC,KAAa,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC,CAAA;AAExE;;;;;;;;;;;;GAYG;AAEI,IAAM,WAAW,GAAjB,MAAM,WAAY,SAAQ,QAAQ,CAAC,OAAO,CAAC,CAAC,UAAU,CAAC;IAAvD;;QACY,SAAI,GAAG,IAAI,WAAW,CAAC,IAAI,CAAC,CAAA;QAqK7C,4EAA4E;QAC5C,WAAM,GAA2B,EAAE,CAAA;QACtC,WAAM,GAAG,KAAK,CAAA;QAE3C,kDAAkD;QACjC,OAAE,GAA2B,EAAE,CAAA;QAChD,yDAAyD;QACxC,WAAM,GAAG,EAAE,CAAA;QACX,WAAM,GAAG,EAAE,KAAK,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAA;QACvD,aAAQ,GAAG,EAAE,IAAI,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,CAAA;QAGnD,wHAAwH;QACvG,SAAI,GAA2C,EAAE,CAAA;IAqbpE,CAAC;aAtmBQ,WAAM,GAAG,CAAC,eAAe,EAAE,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiKpC,CAAC,AAjKW,CAiKX;IAkBQ,UAAU,CAAC,OAAuB;QAC1C,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK;YAAE,OAAM;QAChD,8GAA8G;QAC9G,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAA;QAClD,MAAM,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAA;QAC9C,IAAI,KAAK,CAAC,MAAM;YAAE,IAAI,CAAC,IAAI,GAAG,EAAE,GAAG,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,MAAM,CAAC,WAAW,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAA;IACvL,CAAC;IAED,MAAM;QACJ,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAA;QACxB,IAAI,CAAC,KAAK;YAAE,OAAO,OAAO,CAAA;QAC1B,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,CAAA;QAC5B,iGAAiG;QACjG,MAAM,KAAK,GAAG,CAAC,KAAK,CAAC,MAAM,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,MAAM,IAAI,CAAC,KAAK,CAAC,YAAY,EAAE,MAAM,CAAA;QACvF,OAAO,IAAI,CAAA;QACP,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO;;cAE5C,OAAO,CAAC,CAAC,CAAC,oBAAoB,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,6BAA6B,CAAC;UACrF,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,6BAA6B,CAAC;UAC7C,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;UACxC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAA,WAAW,OAAO,CAAC,CAAC,CAAC,sBAAsB,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO;;QAE1E,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,KAAK,CAAC,IAAI,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC;KAC7E,CAAA;IACH,CAAC;IAEO,UAAU,CAAC,IAAU;QAC3B,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAA;QAC3D,MAAM,MAAM,GAAG,CAAC,CAAQ,EAAE,EAAE,CAAE,CAAC,CAAC,MAA2B,CAAC,aAAa,CAAA;QACzE,yFAAyF;QACzF,MAAM,OAAO,GAAG,CAAC,CAAC,IAAI,CAAC,KAAK,EAAE,YAAY,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAA;QAClF,OAAO,IAAI,CAAA;;gBAEC,OAAO,CAAC,CAAC,CAAC,wBAAwB,CAAC;wBAC3B,IAAI,CAAC,IAAI,cAAc,IAAI,CAAC,MAAM,YAAY,CAAC,CAAQ,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,EAAG,CAAC,CAAC,MAA2B,CAAC,KAAK,CAAC;gBAC3H,OAAO,CAAC,CAAC,CAAC,4BAA4B,CAAC;2DACI,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,cAAc,IAAI,CAAC,MAAM,YAAY,CAAC,CAAQ,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;;wCAEhK,IAAI,CAAC,MAAM,UAAU,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,iCAAiC,CAAC,CAAC,CAAC,mCAAmC,CAAC;iBACxI,GAAG,EAAE;YACZ,+DAA+D;YAC/D,IAAI,CAAC,MAAM,GAAG,cAAc,CAAC,IAAI,CAAC,KAAM,EAAE,IAAI,CAAC,IAAI,CAAC,CAAA;YACpD,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,IAAI,CAAC,KAAM,EAAE,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,iCAAiC,CAAC,CAAC,CAAC,CAAA;QACjG,CAAC;yCACgC,OAAO,CAAC,CAAC,CAAC,yBAAyB,CAAC;;;;;;gBAM7D,IAAI,CAAC,QAAQ;iBACZ,IAAI,CAAC,QAAQ,GAAG,GAAG;mBACjB,MAAM,CAAC,EAAE,CAAC;sBACP,IAAI,CAAC,MAAM;uBACV,OAAO,CAAC,CAAC,CAAC,wBAAwB,CAAC;mBACvC,CAAC,CAAQ,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC;oBAC9C,CAAC,CAAQ,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC;;;;;;kBAM3C,IAAI,CAAC,QAAQ;;qBAEV,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC;wBACjC,IAAI,CAAC,MAAM;yBACV,OAAO,CAAC,CAAC,CAAC,wBAAwB,CAAC;sBACtC,CAAC,CAAQ,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;;;;QAI7F,IAAI,CAAC,cAAc,CAAC,IAAI,EAAE,EAAE,CAAC;QAC7B,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC;eACpD,CAAA;IACb,CAAC;IAED;;;OAGG;IACK,aAAa,CAAC,KAAa;QACjC,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,CAAC,CAAE,CAAA;QACjE,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAA;QAC3D,OAAO,IAAI,CAAA;QACP,KAAK,CAAC,MAAM,GAAG,CAAC;YAChB,CAAC,CAAC,IAAI,CAAA,8CAA8C,OAAO,CAAC,CAAC,CAAC,oBAAoB,CAAC;cAC7E,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAA,sCAAsC,MAAM,CAAC,CAAC,KAAK,IAAI,CAAC,cAAc,IAAI,CAAC,MAAM,WAAW,GAAG,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,WAAW,CAAC;kBAChM;YACV,CAAC,CAAC,IAAI,CAAA,WAAW,IAAI,CAAC,IAAI,WAAW;;;;;gBAK7B,IAAI,CAAC,QAAQ;;mBAEV,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC;sBACjC,IAAI,CAAC,MAAM;uBACV,OAAO,CAAC,CAAC,CAAC,wBAAwB,CAAC;oBACtC,CAAC,CAAQ,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAE,CAAC,CAAC,MAA2B,CAAC,aAAa,EAAE,CAAC,CAAC,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;;;QAG9H,IAAI,CAAC,cAAc,CAAC,IAAI,EAAE,EAAE,CAAC;WAC1B,CAAA;IACT,CAAC;IAED,uHAAuH;IAC/G,cAAc,CAAC,IAAU,EAAE,EAAU;QAC3C,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,mBAAmB,CAAC,IAAI,CAAC,KAAM,EAAE,IAAI,CAAC,IAAI,EAAE,EAAE,EAAE,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,CAAA;QAC5H,MAAM,KAAK,GAAG,CAAC,EAAU,EAAE,EAAE,CAAC,IAAI,CAAC,KAAM,CAAC,WAAW,EAAE,CAAC,EAAE,CAAC,EAAE,KAAK,IAAI,EAAE,CAAA;QACxE,OAAO,IAAI,CAAA,uCAAuC,IAAI,CAAC,MAAM,IAAI,CAAC,KAAK,CAAC,MAAM,UAAU,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,mCAAmC,CAAC;iBAC7I,GAAG,EAAE;YACZ,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAA;YACjB,IAAI,CAAC,IAAI,GAAG,EAAE,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,GAAG,IAAI,CAAC,MAAM,EAAE,EAAE,CAAA;QAC/D,CAAC;yCACgC,OAAO,CAAC,CAAC,CAAC,6BAA6B,EAAE,EAAE,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;;QAErG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAA,WAAW,OAAO,CAAC,CAAC,CAAC,mCAAmC,EAAE,EAAE,QAAQ,EAAE,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,EAAE,CAAA;IACnJ,CAAC;IAEO,WAAW,CAAC,IAAU,EAAE,KAAgB,EAAE,EAAU;QAC1D,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAA;QACxC,OAAO,IAAI,CAAA;;kBAEG,KAAK,CAAC,KAAK,YAAY,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC;;uBAEtC,OAAO,CAAC,CAAC,CAAC,wBAAwB,CAAC;sBACpC,IAAI,CAAC,MAAM;oBACb,CAAC,CAAQ,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,IAAI,EAAG,CAAC,CAAC,MAA4B,CAAC,KAAwB,EAAE,CAAC,CAAC;;2CAE5F,KAAK,CAAC,IAAI,KAAK,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,6BAA6B,CAAC;2CACjE,KAAK,CAAC,IAAI,KAAK,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,6BAA6B,CAAC;;;;uBAIrF,OAAO,CAAC,CAAC,CAAC,iCAAiC,CAAC;kBACjD,OAAO,CAAC,CAAC,CAAC,iCAAiC,CAAC;sBACxC,IAAI,CAAC,MAAM;oBACb,CAAC,CAAQ,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,aAAa,EAAG,CAAC,CAAC,MAA4B,CAAC,KAAmC,EAAE,CAAC,CAAC;;YAE9I,CAAC,QAAQ,EAAE,QAAQ,EAAE,MAAM,CAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAA,iBAAiB,CAAC,cAAc,KAAK,CAAC,aAAa,KAAK,CAAC,IAAI,OAAO,CAAC,CAAC,CAAC,mCAAmC,CAAC,EAAE,CAAC,WAAW,CAAC;;2CAEhJ,IAAI,CAAC,MAAM,UAAU,OAAO,CAAC,CAAC,CAAC,0BAA0B,CAAC,eAAe,OAAO,CAAC,CAAC,CAAC,0BAA0B,CAAC;mBACtI,GAAG,EAAE,CAAC,CAAC,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,OAAO,EAAE,IAAI,KAAK,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,OAAO,CAAC,KAAK,KAAK,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,KAAK,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC;;;gCAGvK,IAAI,CAAC,MAAM,UAAU,OAAO,CAAC,CAAC,CAAC,4BAA4B,CAAC,WAAW,GAAG,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,eAAe,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC;;;;QAI9K,IAAI,CAAC,OAAO,EAAE,IAAI,KAAK,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,OAAO,CAAC,KAAK,KAAK,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO;;UAE7G,KAAK,CAAC,IAAI,CAAC,GAAG,CACd,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,CAAA;;;;;oBAKN,IAAI,CAAC,QAAQ;0BACP,CAAC,KAAK,CAAC;0BACP,IAAI,CAAC,MAAM;sBACf,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,iCAAiC,CAAC,CAAC,CAAC,CAAC,EAAE;2BACtD,GAAG,OAAO,CAAC,CAAC,CAAC,0BAA0B,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE;uBACvD,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC;wBACjB,CAAC,CAAQ,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE,OAAO,EAAG,CAAC,CAAC,MAA2B,CAAC,aAAa,EAAE,EAAE,CAAC,CAAC;;;;;0BAKxG,IAAI,CAAC,MAAM;2BACV,GAAG,OAAO,CAAC,CAAC,CAAC,wBAAwB,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE;uBACrD,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC;wBACf,CAAC,CAAQ,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE,KAAK,EAAG,CAAC,CAAC,MAA2B,CAAC,aAAa,EAAE,EAAE,CAAC,CAAC;;;0BAGtG,IAAI,CAAC,MAAM,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;sBAC7C,OAAO,CAAC,CAAC,CAAC,0BAA0B,CAAC;2BAChC,OAAO,CAAC,CAAC,CAAC,0BAA0B,CAAC;uBACzC,GAAG,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,UAAU,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAE,EAAE,CAAC,CAAC;;;;YAIxF,CACH;;;;oBAIW,IAAI,CAAC,MAAM,IAAI,OAAO,KAAK,SAAS;iBACvC,GAAG,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,OAAO,CAAC,KAAK,CAAC,IAAI,EAAE,EAAE,OAAO,EAAE,IAAI,CAAC,KAAK,CAAC,EAAE,GAAG,IAAI,CAAC,GAAG,IAAI,EAAE,KAAK,EAAE,OAAQ,EAAE,CAAC,EAAE,CAAC,CAAC;;gCAEnH,OAAO,CAAC,CAAC,CAAC,4BAA4B,EAAE,EAAE,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC;;WAE5I,CAAA;IACT,CAAC;IAED;;;OAGG;IACK,UAAU,CAAC,IAAU,EAAE,KAAgB;QAC7C,MAAM,CAAC,GAAG,IAAI,CAAC,OAAQ,CAAA;QACvB,MAAM,KAAK,GAAG,IAAI,CAAC,KAAM,CAAA;QACzB,MAAM,OAAO,GAAG,aAAa,CAAC,KAAK,EAAE,IAAI,CAAC,IAAI,CAAC,CAAA;QAC/C,MAAM,KAAK,GAAG,SAAS,CAAC,KAAK,CAAC,CAAA;QAC9B,MAAM,OAAO,GAAG,KAAK,IAAI,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAA;QACnE,MAAM,IAAI,GAAG,CAAC,CAAC,MAAM,KAAK,KAAK,CAAC,KAAK,IAAI,CAAC,OAAO,CAAA;QACjD,gHAAgH;QAChH,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,aAAa,CAAC,KAAK,EAAE,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;QACxE,OAAO,IAAI,CAAA;;gBAEC,OAAO,CAAC,CAAC,CAAC,8BAA8B,CAAC;6BAC5B,OAAO,CAAC,CAAC,CAAC,8BAA8B,CAAC,YAAY,CAAC,CAAQ,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,OAAO,GAAG,EAAE,GAAG,CAAC,EAAE,MAAM,EAAG,CAAC,CAAC,MAA4B,CAAC,KAAK,EAAE,CAAC;YAC5J,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAA,iBAAiB,EAAE,cAAc,EAAE,KAAK,CAAC,CAAC,MAAM,IAAI,EAAE,KAAK,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,gCAAgC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,EAAE,CAAC,EAAE,KAAK,IAAI,EAAE,CAAC,WAAW,CAAC;;gBAE3L,OAAO,CAAC,CAAC,CAAC,+BAA+B,CAAC;0BAChC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,gCAAgC,CAAC;uDAC3B,OAAO,CAAC,CAAC,CAAC,+BAA+B,CAAC,cAAc,CAAC,KAAK,WAAW,KAAK,CAAC,OAAO,CAAC;sBACxH,CAAC,CAAQ,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,OAAO,GAAG,EAAE,GAAG,CAAC,EAAE,OAAO,EAAG,CAAC,CAAC,MAA2B,CAAC,aAAa,EAAE,CAAC;qBAC/F,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC;;;QAGjC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAA,mBAAmB,OAAO,CAAC,CAAC,CAAC,gCAAgC,EAAE,EAAE,OAAO,EAAE,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO;;gCAE1G,IAAI,CAAC,MAAM,IAAI,IAAI,IAAI,CAAC,CAAC,IAAI;mBAC1C,GAAG,EAAE;YACZ,IAAI,CAAC,IAAI,CAAC,eAAe,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAA;YACjE,IAAI,CAAC,OAAO,GAAG,SAAS,CAAA;QAC1B,CAAC,IAAI,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,KAAK,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,2BAA2B,CAAC,CAAC,CAAC,gCAAgC,CAAC;6BACtF,GAAG,EAAE,CAAC,CAAC,IAAI,CAAC,OAAO,GAAG,SAAS,CAAC,IAAI,OAAO,CAAC,CAAC,CAAC,sBAAsB,CAAC;;WAEvF,CAAA;IACT,CAAC;IAEO,SAAS,CAAC,KAAkB,EAAE,KAAa;QACjD,MAAM,CAAC,GAAG,IAAI,CAAC,MAAM,CAAA;QACrB,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,IAAI,CAAC,CAAA;QAClD;;;;UAIE;QACF,MAAM,IAAI,GAAG,OAAO,CAAC,CAAC,CAAC,UAAU,CAAC,KAAK,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAA;QACnI,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;QAC1D,MAAM,IAAI,GAAG,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,CAAA;QACnD,MAAM,KAAK,GAAG,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,OAAO,CAAC,CAAA;QACrE,MAAM,QAAQ,GAAG,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAA;QACxD,sGAAsG;QACtG,MAAM,KAAK,GAAG,CAAC,OAAO,IAAI,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,CAAA;QAC1D,MAAM,KAAK,GAAG,CAAC,CAAC,IAAI,IAAI,CAAC,KAAK,IAAI,QAAQ,GAAG,CAAC,IAAI,CAAC,CAAC,KAAK,CAAA;QACzD,MAAM,IAAI,GAAG,CAAC,OAAO,IAAI,KAAK,IAAI,IAAI,CAAC,CAAC,CAAC,YAAY,CAAC,KAAK,EAAE,OAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAA;QAC3G;gGACwF;QACxF,MAAM,GAAG,GAAG,CAAC,IAAe,EAAE,aAAwB,EAAE,EAAE;YACxD,IAAI,OAAO;gBAAE,IAAI,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAA;;gBACxH,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,KAAK,EAAE,OAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,aAAa,CAAC,CAAC,KAAK,CAAC,CAAA;YACzF,iEAAiE;YACjE,IAAI,CAAC,MAAM,GAAG,EAAE,GAAG,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,CAAA;QAC7C,CAAC,CAAA;QACD,OAAO,IAAI,CAAA,gBAAgB,OAAO,CAAC,CAAC,CAAC,wBAAwB,CAAC;;gBAElD,OAAO,CAAC,CAAC,CAAC,uBAAuB,CAAC;4BACtB,CAAC,IAAI,CAAC,MAAM,YAAY,CAAC,CAAQ,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,MAAM,GAAG,EAAE,GAAG,CAAC,EAAE,KAAK,EAAG,CAAC,CAAC,MAA4B,CAAC,KAAK,EAAE,CAAC;YAC5H,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAA,iBAAiB,EAAE,cAAc,EAAE,KAAK,OAAO,IAAI,KAAK,CAAC,WAAW,EAAE,CAAC,EAAE,CAAC,EAAE,KAAK,IAAI,EAAE,WAAW,CAAC;;gBAElH,OAAO,CAAC,CAAC,CAAC,mBAAmB,CAAC;0BACpB,CAAC,CAAQ,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,MAAM,GAAG,EAAE,GAAG,CAAC,EAAE,IAAI,EAAG,CAAC,CAAC,MAA4B,CAAC,KAAK,EAAE,CAAC;uCACtE,CAAC,OAAO,IAAI,OAAO,CAAC,CAAC,CAAC,uBAAuB,CAAC;YACzE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAA,iBAAiB,CAAC,CAAC,IAAI,cAAc,CAAC,KAAK,OAAO,IAAI,CAAC,CAAC,IAAI,WAAW,CAAC;;UAE7F,OAAO;YACP,CAAC,CAAC,OAAO;YACT,CAAC,CAAC,IAAI,CAAA,SAAS,OAAO,CAAC,CAAC,CAAC,wBAAwB,CAAC;8BAC9B,CAAC,CAAC,IAAI,+BAA+B,CAAC,CAAQ,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,MAAM,GAAG,EAAE,GAAG,CAAC,EAAE,IAAI,EAAG,CAAC,CAAC,MAA2B,CAAC,KAAK,EAAE,CAAC;sBAC/H,OAAO,CAAC,CAAC,CAAC,4BAA4B,CAAC;iEACI,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAQ,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,MAAM,GAAG,EAAE,GAAG,CAAC,EAAE,QAAQ,EAAG,CAAC,CAAC,MAA2B,CAAC,aAAa,EAAE,CAAC,KAAK;;QAE1L,IAAI,EAAE,IAAI,KAAK,WAAW;YAC1B,CAAC,CAAC,IAAI,CAAA,sBAAsB,OAAO,CAAC,CAAC,CAAC,+BAA+B,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC,MAAM;YAC1H,CAAC,CAAC,IAAI,EAAE,IAAI,KAAK,OAAO;gBACtB,CAAC,CAAC,IAAI,CAAA,sBAAsB,OAAO,CAAC,CAAC,CAAC,+BAA+B,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC,MAAM;gBACzG,CAAC,CAAC,OAAO;8BACW,IAAI,CAAC,MAAM,IAAI,CAAC,KAAK,WAAW,GAAG,EAAE,CAAC,GAAG,CAAC,YAAY,CAAC,KAAM,EAAE,IAAI,CAAC,MAAM,CAAC,OAAQ,CAAC,EAAE,QAAQ,CAAC,EAAE,QAAQ,CAAC;gCACxG,OAAO,CAAC,CAAC,CAAC,yBAAyB,CAAC;;0CAE1B,IAAI,CAAC,MAAM,IAAI,CAAC,KAAK,UAAU,OAAO,CAAC,CAAC,CAAC,uCAAuC,CAAC;iBAC1G,GAAG,EAAE,CAAC,GAAG,CAAC,YAAY,CAAC,KAAM,EAAE,IAAI,CAAC,MAAM,CAAC,OAAQ,CAAC,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;uCACnD,OAAO,CAAC,CAAC,CAAC,+BAA+B,CAAC;0BACvD,CAAA;IACxB,CAAC;IAED;;;OAGG;IACK,YAAY,CAAC,KAAkB;QACrC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,YAAY,CAAC,KAAK,CAAC,CAAA;QAC5C,IAAI,CAAC,MAAM,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,MAAM;YAAE,OAAO,OAAO,CAAA;QAClD,MAAM,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAA;QACvB,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;QACtD,OAAO,IAAI,CAAA;YACH,OAAO,CAAC,CAAC,CAAC,4BAA4B,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,qCAAqC,CAAC;QACrG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,qCAAqC,CAAC;QACrD,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;QAClD,IAAI,CAAC,MAAM;YACX,CAAC,CAAC,IAAI,CAAA;sBACQ,OAAO,CAAC,CAAC,CAAC,gCAAgC,CAAC;8BACnC,CAAC,CAAC,KAAK,gBAAgB,OAAO,CAAC,CAAC,CAAC,2BAA2B,CAAC,WAAW,CAAC,CAAQ,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,QAAQ,GAAG,EAAE,GAAG,CAAC,EAAE,KAAK,EAAG,CAAC,CAAC,MAA2B,CAAC,KAAK,EAAE,CAAC;sBACrK,OAAO,CAAC,CAAC,CAAC,mBAAmB,CAAC;gCACpB,CAAC,CAAQ,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,QAAQ,GAAG,EAAE,GAAG,CAAC,EAAE,IAAI,EAAG,CAAC,CAAC,MAA4B,CAAC,KAAK,EAAE,CAAC;kBACnG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAA,iBAAiB,CAAC,cAAc,CAAC,KAAK,KAAK,IAAI,CAAC,WAAW,CAAC;;;;;0BAKtE,IAAI,CAAC,MAAM,IAAI,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,EAAE;uBAC3C,GAAG,EAAE;gBACZ,IAAI,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,kBAAkB,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE,aAAa,CAAC,KAAK,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,CAAC,KAAM,CAAC,EAAE,WAAW,EAAE,KAAM,EAAE,iBAAiB,EAAE,GAAG,EAAE,EAAE,CAAC,CAAA;gBACjK,IAAI,CAAC,QAAQ,GAAG,EAAE,IAAI,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,CAAA;YACzC,CAAC;;sCAEuB,OAAO,CAAC,CAAC,CAAC,gCAAgC,CAAC;sBAC3D;YACd,CAAC,CAAC,OAAO;eACF,CAAA;IACb,CAAC;IAEO,WAAW,CAAC,KAAgB,EAAE,IAAc;QAClD,MAAM,KAAK,GAAG,CAAC,CAAQ,EAAE,EAAE,CAAE,CAAC,CAAC,MAA+C,CAAC,KAAK,CAAA;QACpF,OAAO,IAAI,CAAA;;kBAEG,KAAK,CAAC,KAAK;gCACG,IAAI,CAAC,MAAM,UAAU,OAAO,CAAC,CAAC,CAAC,mCAAmC,CAAC,WAAW,GAAG,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,qBAAqB,EAAE,EAAE,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC;;;;;gBAK5J,OAAO,CAAC,CAAC,CAAC,gCAAgC,CAAC;wBACnC,KAAK,CAAC,KAAK,cAAc,IAAI,CAAC,MAAM,YAAY,CAAC,CAAQ,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,IAAI,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;gBAChJ,OAAO,CAAC,CAAC,CAAC,mCAAmC,CAAC;4BAClC,IAAI,CAAC,MAAM,YAAY,CAAC,CAAQ,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,EAAE,WAAW,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YAC3G,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAA,iBAAiB,CAAC,cAAc,CAAC,KAAK,KAAK,CAAC,WAAW,IAAI,CAAC,WAAW,CAAC;;gBAE7F,OAAO,CAAC,CAAC,CAAC,sCAAsC,CAAC;;;;;mBAK9C,MAAM,CAAC,KAAK,CAAC,iBAAiB,CAAC;sBAC5B,IAAI,CAAC,MAAM;oBACb,CAAC,CAAQ,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,EAAE,iBAAiB,EAAG,CAAC,CAAC,MAA2B,CAAC,aAAa,EAAE,CAAC,CAAC;;;;UAIxH,KAAK,CAAC,KAAK,CAAC,GAAG,CACf,CAAC,CAAC,EAAE,CAAC,IAAI,CAAA;eACJ,CAAC;;0BAEU,IAAI,CAAC,MAAM,IAAI,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC;sBACzC,OAAO,CAAC,CAAC,CAAC,sCAAsC,CAAC;2BAC5C,OAAO,CAAC,CAAC,CAAC,sCAAsC,CAAC;uBACrD,GAAG,EAAE;YACZ,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAA;YAC9C,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,EAAE,KAAK,EAAE,WAAW,EAAE,KAAK,CAAC,WAAW,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAE,CAAC,CAAC,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC,CAAA;QAC9G,CAAC;;;;YAIH,CACH;;QAED,IAAI,CAAC,MAAM;YACX,CAAC,CAAC,IAAI,CAAA;yBACW,OAAO,CAAC,CAAC,CAAC,iCAAiC,CAAC;wBAC7C,IAAI,CAAC,MAAM;sBACb,CAAC,CAAQ,EAAE,EAAE;gBACrB,MAAM,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAA;gBAClB,IAAI,CAAC;oBAAE,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,EAAE,KAAK,EAAE,CAAC,GAAG,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CACjE;gBAAC,CAAC,CAAC,MAA4B,CAAC,KAAK,GAAG,EAAE,CAAA;YAC7C,CAAC;;wCAE2B,OAAO,CAAC,CAAC,CAAC,iCAAiC,CAAC;cACtE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAA,iBAAiB,CAAC,IAAI,CAAC,WAAW,CAAC;oBAC/C;YACZ,CAAC,CAAC,OAAO;eACF,CAAA;IACb,CAAC;IAED,6FAA6F;IACrF,MAAM,CAAC,IAAU,EAAE,IAAY;QACrC,MAAM,KAAK,GAAG,CAAK,EAAqB,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAA;QACvG,IAAI,CAAC,EAAE,GAAG,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;QACxB,IAAI,CAAC,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QAC5B,IAAI,IAAI,CAAC,MAAM,KAAK,IAAI,CAAC,IAAI;YAAE,IAAI,CAAC,MAAM,GAAG,IAAI,CAAA;QACjD,IAAI,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAA;IACxD,CAAC;IAED,8FAA8F;IAC9F;mDAC+C;IACvC,KAAK,CAAC,IAAU,EAAE,OAAe,EAAE,IAAI,GAAG,KAAK;QACrD,IAAI,CAAC,IAAI,CAAC,KAAK,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC;YAAE,OAAM;QACpD,IAAI,CAAC,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,CAAA;QAC9C,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,IAAI,CAAA;QACvB,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC,CAAA;QACtD,IAAI,CAAC,OAAO,CAAC,MAAM;YAAE,OAAM;QAC3B,IAAI,IAAI,EAAE,CAAC;YACT,MAAM,MAAM,GAAG,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;YACvE,IAAI,CAAC,aAAa,CAAC,IAAI,WAAW,CAAC,aAAa,EAAE,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,CAAA;YACzG,OAAM;QACR,CAAC;QACD,IAAI,CAAC,aAAa,CAAC,IAAI,WAAW,CAAC,QAAQ,EAAE,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,CAAA;QACrG,kEAAkE;QAClE,IAAI,CAAC,IAAI,GAAG,EAAE,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,GAAG,IAAI,CAAC,MAAM,EAAE,GAAG,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAA;IAC5H,CAAC;IAED,gHAAgH;IACxG,SAAS,CAAC,IAAU,EAAE,KAAgB,EAAE,KAAa,EAAE,KAAkD,EAAE,CAAQ;QACzH,MAAM,IAAI,GAAG,cAAc,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAA;QACpE,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,MAAM,KAAK,GAAG,CAAC,CAAC,MAA0B,CAAA;YAC1C,MAAM,GAAG,GAAG,KAAK,CAAC,IAAI,CAAC,KAAK,CAAE,CAAA;YAC9B,KAAK,CAAC,KAAK,GAAG,SAAS,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,CAAA;YACxE,OAAM;QACR,CAAC;QACD,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,CAAA;IAC7C,CAAC;IAEO,IAAI,CAAC,IAAa;QACxB,IAAI,CAAC,aAAa,CAAC,IAAI,WAAW,CAAC,WAAW,EAAE,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,CAAA;IACvG,CAAC;IAED,gDAAgD;IACxC,KAAK,CAAC,KAAgB;QAC5B,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAA;QAClD,IAAI,CAAC,aAAa,CAAC,IAAI,WAAW,CAAC,YAAY,EAAE,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,CAAA;IACzG,CAAC;;AAlc+B;IAA/B,QAAQ,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;;0CAAoB;AAEnB;IAA/B,QAAQ,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;;2CAAoC;AACtC;IAA5B,QAAQ,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;;2CAAe;AAG1B;IAAhB,KAAK,EAAE;;uCAAwC;AAE/B;IAAhB,KAAK,EAAE;;2CAAoB;AACX;IAAhB,KAAK,EAAE;;2CAAgE;AACvD;IAAhB,KAAK,EAAE;;6CAA2C;AAElC;IAAhB,KAAK,EAAE;;4CAAmF;AAE1E;IAAhB,KAAK,EAAE;;yCAA0D;AAnLvD,WAAW;IADvB,aAAa,CAAC,cAAc,CAAC;GACjB,WAAW,CAwmBvB","sourcesContent":["import '@material/web/icon/icon.js'\n\nimport { css, html, LitElement, nothing } from 'lit'\nimport type { PropertyValues } from 'lit'\nimport { customElement, property, state } from 'lit/decorators.js'\n\nimport { i18next, localize } from '@operato/i18n'\nimport { unitWord } from './unit-words.js'\nimport type { FigureAsset } from '@hatiolab/figure-model'\n\nimport { clipGroupsOf, withKeyChanged, clipsOf, copiedTrackEdit, copyClipEdits, copyTargetsOf, freeClipNameOf, freeGroupIdOf, groupEdit, newClipEdits, newTrackKeys, poseAt, rememberedPoseEdits, shiftable, shiftOffKeyOf, trackEdit, undrivenOf, withKey, withoutKey, type Clip, type ClipGroup, type ClipKey, type ClipTrack } from './clips.js'\nimport { SidePanelStyles } from '@things-factory/figure-viewer/dist-client/side-panel-styles.js'\nimport { HelpToggles } from './help.js'\n\n/** A value as a person reads it: at most three decimals, the float's last digits (14.399999999999999) left out. */\nconst shown = (value: number) => value.toLocaleString(undefined, { maximumFractionDigits: 3 })\n/* A number field's value: no grouping, to a thousandth. */\nconst typed = (value: number) => String(Math.round(value * 1000) / 1000)\n\n/**\n * 클립 — controls played by keys over time. A clip is one clock; each track plays one\n * control. Scrubbing a clip shows its pose at that moment (one batch of input changes, not saved as the default); a key\n * is added at the scrubbed moment with the control's value there, so a pose is made with the controls' sliders and\n * then kept as a key. Every change is one part edit.\n *\n * Clips of one motion group play one at a time on the same controls -- idle, walk, run (ADR-0051 §3.2): only clips of\n * one group may play the same control. A new clip on a control another clip plays is put in a group as it is made --\n * that clip's, or one made of the two -- and the panel says so before the button is pressed (review 2026-11-09).\n *\n * 「이 자세 기억하기」 keeps the pose the figure stands in now at the scrubbed moment, every control that moved, in one\n * step. What moved is read against the pose the clip was last shown or kept in (`base`).\n */\n@customElement('figure-clips')\nexport class FigureClips extends localize(i18next)(LitElement) {\n private readonly help = new HelpToggles(this)\n static styles = [SidePanelStyles, css`\n :host {\n display: block;\n }\n /*\n The pose bar: the clip being keyed, its moment and 「현재 자세 기록」, first under the controls and held at the top\n while the clips scroll. With walk and run, run's own button stood under all of walk's tracks, a long scroll from\n the controls typed for it (tutorial run 2026-11-12).\n */\n div[pose-bar] {\n position: sticky;\n top: 0;\n z-index: 1;\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: 6px 10px;\n margin-bottom: 8px;\n padding: 8px;\n background: var(--md-sys-color-surface-container, var(--md-sys-color-surface));\n border: 1px solid var(--md-sys-color-primary);\n border-radius: 8px;\n }\n div[pose-bar] span[clip-choices] {\n display: flex;\n flex-wrap: wrap;\n gap: 4px;\n }\n div[pose-bar] span[clip-choices] button {\n font: inherit;\n color: inherit;\n padding: 1px 10px;\n background: transparent;\n border: 1px solid var(--md-sys-color-outline-variant);\n border-radius: 10px;\n cursor: pointer;\n }\n div[pose-bar] span[clip-choices] button[aria-pressed='true'] {\n background: var(--md-sys-color-secondary-container);\n border-color: var(--md-sys-color-secondary);\n font-weight: 600;\n }\n div[pose-bar] label[at] input {\n width: 64px;\n }\n div[pose-bar] p[hint] {\n flex-basis: 100%;\n margin: 0;\n }\n section[clip] {\n display: grid;\n gap: 8px;\n padding: 8px;\n border: 1px solid var(--md-sys-color-outline-variant);\n border-radius: 8px;\n }\n div[row] {\n display: grid;\n grid-template-columns: minmax(0, 1fr) 72px;\n gap: 6px;\n align-items: center;\n }\n div[track] {\n display: grid;\n gap: 4px;\n padding-top: 6px;\n border-top: 1px dashed var(--md-sys-color-outline-variant);\n }\n /*\n The track's name on its own line, then how it repeats and the button that removes it. A flex row let the shared\n full-width select and button squeeze the name to one letter a line (user, 2026-09-24).\n */\n div[track-head] {\n display: grid;\n grid-template-columns: minmax(0, 1fr) 30px 30px;\n gap: 4px 6px;\n align-items: center;\n }\n div[track-head] strong {\n grid-column: 1 / -1;\n min-width: 0;\n overflow-wrap: anywhere;\n }\n /* How it moves between keys: its own row under the head, as wide as the track, its words not cut. */\n div[track-head] select[interpolation] {\n grid-row: 3;\n grid-column: 1 / -1;\n }\n div[track-head] button[act] {\n width: 30px;\n min-height: var(--figure-control-height);\n margin: 0;\n padding: 0;\n }\n /* A track copied onto a control, moved round its loop: under its head, in the panel's form look. */\n div[copy-form] {\n display: grid;\n gap: 6px;\n padding: 6px 8px;\n border-radius: 6px;\n background: var(--md-sys-color-surface-container);\n }\n div[copy-form] div[pair] {\n display: flex;\n gap: 6px;\n justify-content: flex-end;\n }\n div[keys] {\n display: flex;\n flex-wrap: wrap;\n gap: 4px;\n }\n span[key] {\n display: inline-flex;\n align-items: center;\n gap: 2px;\n padding: 0 2px 0 8px;\n border-radius: 999em;\n background: var(--md-sys-color-surface-container);\n font-variant-numeric: tabular-nums;\n }\n /* A key's moment and value, typed in the chip: as narrow as their numbers, on the chip's ground. */\n span[key] input {\n width: 44px;\n min-width: 0;\n height: 20px;\n padding: 0 2px;\n font: inherit;\n text-align: right;\n font-variant-numeric: tabular-nums;\n color: inherit;\n background: transparent;\n border: none;\n border-bottom: 1px solid var(--md-sys-color-outline-variant);\n }\n span[key] input[readonly] {\n border-bottom-color: transparent;\n }\n label[at] {\n display: inline-flex;\n align-items: center;\n gap: 2px;\n font-variant-numeric: tabular-nums;\n }\n label[at] input {\n width: 52px;\n min-width: 0;\n text-align: right;\n }\n span[key] button {\n width: 22px;\n height: 22px;\n padding: 0;\n border: none;\n background: none;\n }\n md-icon {\n font-size: 16px;\n width: 16px;\n height: 16px;\n }\n `]\n\n @property({ attribute: false }) asset?: FigureAsset\n /** The values the editor holds now, by input id -- what a new key takes. */\n @property({ attribute: false }) values: Record<string, number> = {}\n @property({ type: Boolean }) locked = false\n\n /** Where each clip is scrubbed to, in seconds. */\n @state() private at: Record<string, number> = {}\n /** The clip the pose bar keys: the one last scrubbed. */\n @state() private active = ''\n @state() private adding = { state: '', clip: '', name: '', duration: 2 }\n @state() private grouping = { clip: '', label: '' }\n /** The track whose copy is being set up: onto which control, how many seconds later. */\n @state() private copying?: { clip: string; state: string; target: string; seconds: number }\n /** Per clip, the pose it was last shown or kept in: a control that differs from it now has been moved by the person. */\n @state() private base: Record<string, Record<string, number>> = {}\n\n protected willUpdate(changed: PropertyValues) {\n if (!changed.has('asset') || !this.asset) return\n /* A clip seen for the first time takes the pose the figure stands in now as where its moves are read from. */\n const names = clipsOf(this.asset).map(c => c.name)\n const fresh = names.filter(n => !this.base[n])\n if (fresh.length) this.base = { ...Object.fromEntries(Object.entries(this.base).filter(([n]) => names.includes(n))), ...Object.fromEntries(fresh.map(n => [n, { ...this.values }])) }\n }\n\n render() {\n const asset = this.asset\n if (!asset) return nothing\n const clips = clipsOf(asset)\n /* Nothing to play yet: said inside the section it belongs to, with the section's own margins. */\n const empty = !clips.length && !undrivenOf(asset).length && !asset.motionGroups?.length\n return html`\n ${clips.length ? this.renderPoseBar(clips) : nothing}\n <section>\n <h3>${i18next.t('figure.label.clips')}${this.help.button('figure.text.clips-explained')}</h3>\n ${this.help.hint('figure.text.clips-explained')}\n ${clips.map(clip => this.renderClip(clip))}\n ${empty ? html`<p hint>${i18next.t('figure.text.no-clips')}</p>` : nothing}\n </section>\n ${empty ? nothing : this.renderAdd(asset, clips)} ${this.renderGroups(asset)}\n `\n }\n\n private renderClip(clip: Clip) {\n const at = Math.min(this.at[clip.name] ?? 0, clip.duration)\n const number = (e: Event) => (e.target as HTMLInputElement).valueAsNumber\n /* A copy plays the same controls: only clips of one motion group may (ADR-0051 §3.2). */\n const grouped = !!this.asset?.motionGroups?.some(g => g.clips.includes(clip.name))\n return html`<section clip>\n <div form>\n <span>${i18next.t('figure.label.clip-name')}</span>\n <input .value=${clip.name} ?disabled=${this.locked} @change=${(e: Event) => this.rename(clip, (e.target as HTMLInputElement).value)} />\n <span>${i18next.t('figure.label.clip-duration')}</span>\n <input type=\"number\" min=\"0.1\" step=\"any\" .value=${String(clip.duration)} ?disabled=${this.locked} @change=${(e: Event) => this.edit({ kind: 'set-clip', clip: clip.name, duration: number(e) })} />\n </div>\n <button act copy-clip ?disabled=${this.locked} title=${i18next.t(grouped ? 'figure.text.copy-clip-explained' : 'figure.text.copy-clip-makes-group')}\n @click=${() => {\n /* The copy is what is keyed next: the pose bar turns to it. */\n this.active = freeClipNameOf(this.asset!, clip.name)\n this.edits(copyClipEdits(this.asset!, clip.name, i18next.t('figure.label.motion-group-named')))\n }}>\n <md-icon>content_copy</md-icon>${i18next.t('figure.button.copy-clip')}\n </button>\n <div row>\n <input\n type=\"range\"\n min=\"0\"\n max=${clip.duration}\n step=${clip.duration / 100}\n .value=${String(at)}\n ?disabled=${this.locked}\n aria-label=${i18next.t('figure.label.clip-time')}\n @input=${(e: Event) => this.scrub(clip, number(e), true)}\n @change=${(e: Event) => this.scrub(clip, number(e))}\n />\n <label at>\n <input\n type=\"number\"\n min=\"0\"\n max=${clip.duration}\n step=\"any\"\n .value=${String(Math.round(at * 1000) / 1000)}\n ?disabled=${this.locked}\n aria-label=${i18next.t('figure.label.clip-time')}\n @change=${(e: Event) => this.scrub(clip, Math.min(Math.max(number(e), 0), clip.duration))}\n />s\n </label>\n </div>\n ${this.renderRemember(clip, at)}\n ${clip.tracks.map(track => this.renderTrack(clip, track, at))}\n </section>`\n }\n\n /**\n * The clip being keyed -- the one last scrubbed or chosen here -- with its moment and 「현재 자세 기록」, right under the\n * controls: type the controls, then record, without scrolling to the clip.\n */\n private renderPoseBar(clips: Clip[]) {\n const clip = clips.find(c => c.name === this.active) ?? clips[0]!\n const at = Math.min(this.at[clip.name] ?? 0, clip.duration)\n return html`<div pose-bar>\n ${clips.length > 1\n ? html`<span clip-choices role=\"group\" aria-label=${i18next.t('figure.label.clips')}>\n ${clips.map(c => html`<button type=\"button\" aria-pressed=${String(c === clip)} ?disabled=${this.locked} @click=${() => this.scrub(c, Math.min(this.at[c.name] ?? 0, c.duration))}>${c.name}</button>`)}\n </span>`\n : html`<strong>${clip.name}</strong>`}\n <label at>\n <input\n type=\"number\"\n min=\"0\"\n max=${clip.duration}\n step=\"any\"\n .value=${String(Math.round(at * 1000) / 1000)}\n ?disabled=${this.locked}\n aria-label=${i18next.t('figure.label.clip-time')}\n @change=${(e: Event) => this.scrub(clip, Math.min(Math.max((e.target as HTMLInputElement).valueAsNumber, 0), clip.duration))}\n />s\n </label>\n ${this.renderRemember(clip, at)}\n </div>`\n }\n\n /** 「이 자세 기억하기」: every control moved since the clip's pose was last shown or kept, as keys at this moment, one step. */\n private renderRemember(clip: Clip, at: number) {\n const { edits, skipped } = rememberedPoseEdits(this.asset!, clip.name, at, this.values, this.base[clip.name] ?? this.values)\n const label = (id: string) => this.asset!.stateInputs?.[id]?.label ?? id\n return html`<button act remember-pose ?disabled=${this.locked || !edits.length} title=${edits.length ? '' : i18next.t('figure.text.remember-pose-nothing')}\n @click=${() => {\n this.edits(edits)\n this.base = { ...this.base, [clip.name]: { ...this.values } }\n }}>\n <md-icon>photo_camera</md-icon>${i18next.t('figure.button.remember-pose', { seconds: at.toFixed(2) })}\n </button>\n ${skipped.length ? html`<p hint>${i18next.t('figure.text.remember-pose-skipped', { controls: skipped.map(label).join(', ') })}</p>` : nothing}`\n }\n\n private renderTrack(clip: Clip, track: ClipTrack, at: number) {\n const current = this.values[track.state]\n return html`<div track>\n <div track-head>\n <strong>${track.label} <small>(${unitWord(track.unit)})</small></strong>\n <select\n aria-label=${i18next.t('figure.label.clip-loop')}\n ?disabled=${this.locked}\n @change=${(e: Event) => this.edit(trackEdit(clip, track, { loop: (e.target as HTMLSelectElement).value as 'wrap' | 'hold' }))}\n >\n <option value=\"wrap\" ?selected=${track.loop === 'wrap'}>${i18next.t('figure.label.clip-loop-wrap')}</option>\n <option value=\"hold\" ?selected=${track.loop === 'hold'}>${i18next.t('figure.label.clip-loop-hold')}</option>\n </select>\n <select\n interpolation\n aria-label=${i18next.t('figure.label.clip-interpolation')}\n title=${i18next.t('figure.label.clip-interpolation')}\n ?disabled=${this.locked}\n @change=${(e: Event) => this.edit(trackEdit(clip, track, { interpolation: (e.target as HTMLSelectElement).value as ClipTrack['interpolation'] }))}\n >\n ${(['linear', 'smooth', 'step'] as const).map(i => html`<option value=${i} ?selected=${track.interpolation === i}>${i18next.t(`figure.label.clip-interpolation-${i}`)}</option>`)}\n </select>\n <button act copy-track ?disabled=${this.locked} title=${i18next.t('figure.button.copy-track')} aria-label=${i18next.t('figure.button.copy-track')}\n @click=${() => (this.copying = this.copying?.clip === clip.name && this.copying.state === track.state ? undefined : { clip: clip.name, state: track.state, target: track.state, seconds: 0 })}>\n <md-icon>content_copy</md-icon>\n </button>\n <button act ?disabled=${this.locked} title=${i18next.t('figure.button.remove-track')} @click=${() => this.edit({ kind: 'remove-driver', state: track.state, clip: clip.name })}>\n <md-icon>close</md-icon>\n </button>\n </div>\n ${this.copying?.clip === clip.name && this.copying.state === track.state ? this.renderCopy(clip, track) : nothing}\n <div keys>\n ${track.keys.map(\n (key, i) => html`<span key\n ><input\n type=\"number\"\n step=\"any\"\n min=\"0\"\n max=${clip.duration}\n ?readonly=${i === 0}\n ?disabled=${this.locked}\n title=${i === 0 ? i18next.t('figure.text.key-starts-the-clip') : ''}\n aria-label=${`${i18next.t('figure.label.key-seconds')} ${i + 1}`}\n .value=${typed(key.seconds)}\n @change=${(e: Event) => this.changeKey(clip, track, i, { seconds: (e.target as HTMLInputElement).valueAsNumber }, e)}\n />s →\n <input\n type=\"number\"\n step=\"any\"\n ?disabled=${this.locked}\n aria-label=${`${i18next.t('figure.label.key-value')} ${i + 1}`}\n .value=${typed(key.value)}\n @change=${(e: Event) => this.changeKey(clip, track, i, { value: (e.target as HTMLInputElement).valueAsNumber }, e)}\n />\n <button\n ?disabled=${this.locked || !withoutKey(track.keys, i)}\n title=${i18next.t('figure.button.remove-key')}\n aria-label=${i18next.t('figure.button.remove-key')}\n @click=${() => this.edit(trackEdit(clip, track, { keys: withoutKey(track.keys, i)! }))}\n >\n <md-icon>close</md-icon>\n </button></span\n >`\n )}\n </div>\n <button\n act\n ?disabled=${this.locked || current === undefined}\n @click=${() => this.edit(trackEdit(clip, track, { keys: withKey(track.keys, { seconds: Math.round(at * 1000) / 1000, value: current! }) }))}\n >\n <md-icon>add</md-icon>${i18next.t('figure.button.add-key-here', { seconds: at.toFixed(2), value: current === undefined ? '' : shown(current) })}\n </button>\n </div>`\n }\n\n /**\n * A track onto a control -- itself, or another -- moved round its loop by some seconds: one leg's curve given to the\n * next on its own beat (robot dog 2026-11-03). Only a wrapping track moves round; any track is copied.\n */\n private renderCopy(clip: Clip, track: ClipTrack) {\n const c = this.copying!\n const asset = this.asset!\n const targets = copyTargetsOf(asset, clip.name)\n const moves = shiftable(track)\n const seconds = moves && Number.isFinite(c.seconds) ? c.seconds : 0\n const same = c.target === track.state && !seconds\n /* A smooth track goes round only onto one of its keys: said, with the moments it can go to, and not applied. */\n const fits = moves ? shiftOffKeyOf(track, clip.duration, seconds) : null\n return html`<div copy-form>\n <div form>\n <span>${i18next.t('figure.label.copy-track-onto')}</span>\n <select aria-label=${i18next.t('figure.label.copy-track-onto')} @change=${(e: Event) => (this.copying = { ...c, target: (e.target as HTMLSelectElement).value })}>\n ${targets.map(id => html`<option value=${id} ?selected=${id === c.target}>${id === track.state ? i18next.t('figure.label.copy-track-itself') : (asset.stateInputs?.[id]?.label ?? id)}</option>`)}\n </select>\n <span>${i18next.t('figure.label.copy-track-later')}</span>\n <label at title=${moves ? '' : i18next.t('figure.text.copy-track-no-loop')}>\n <input type=\"number\" step=\"any\" aria-label=${i18next.t('figure.label.copy-track-later')} ?disabled=${!moves} .value=${typed(seconds)}\n @change=${(e: Event) => (this.copying = { ...c, seconds: (e.target as HTMLInputElement).valueAsNumber })} />s\n <small>/ ${typed(clip.duration)}s</small>\n </label>\n </div>\n ${fits ? html`<p hint off-key>${i18next.t('figure.text.copy-track-off-key', { seconds: fits.map(typed).join(', ') })}</p>` : nothing}\n <div pair>\n <button act ?disabled=${this.locked || same || !!fits}\n @click=${() => {\n this.edit(copiedTrackEdit(asset, clip, track, c.target, seconds))\n this.copying = undefined\n }}>${i18next.t(c.target === track.state ? 'figure.button.shift-track' : 'figure.button.copy-track-apply')}</button>\n <button act @click=${() => (this.copying = undefined)}>${i18next.t('figure.button.cancel')}</button>\n </div>\n </div>`\n }\n\n private renderAdd(asset: FigureAsset, clips: Clip[]) {\n const a = this.adding\n const joining = clips.find(c => c.name === a.clip)\n /*\n The controls a track can take. Joining a clip: those it may play. A new clip: any control -- one another clip\n plays puts the new clip in a group with it, said below before the button is pressed (review 2026-11-09: the\n controls used to vanish from the list, and the group had to be designed first).\n */\n const free = joining ? undrivenOf(asset, joining.name) : asset.document.model.inputs.filter(i => i.role === 'state').map(i => i.id)\n const stateId = free.includes(a.state) ? a.state : free[0]\n const name = joining ? joining.name : a.name.trim()\n const input = asset.document.model.inputs.find(i => i.id === stateId)\n const duration = joining ? joining.duration : a.duration\n /* A new clip takes a name no clip has: the same name would rewrite that clip's track, not add one. */\n const taken = !joining && clips.some(c => c.name === name)\n const ready = !!name && !taken && duration > 0 && !!input\n const join = !joining && input && name ? newClipEdits(asset, stateId!, name, duration, []).join : undefined\n /* A track that holds the pose now is the start of a move from pose to pose: smooth (review 2026-11-11, a walk's nine\n tracks each changed by hand). The range preset sweeps at a steady rate, as before. */\n const add = (keys: ClipKey[], interpolation?: 'smooth') => {\n if (joining) this.edit({ kind: 'set-driver', state: stateId, clip: name, keys, ...(interpolation ? { interpolation } : {}) })\n else this.edits(newClipEdits(asset, stateId!, name, duration, keys, interpolation).edits)\n /* The name was this clip's; the next new clip is named again. */\n this.adding = { ...a, name: '', state: '' }\n }\n return html`<section><h3>${i18next.t('figure.label.add-track')}</h3>\n <div form>\n <span>${i18next.t('figure.label.controls')}</span>\n <select ?disabled=${!free.length} @change=${(e: Event) => (this.adding = { ...a, state: (e.target as HTMLSelectElement).value })}>\n ${free.map(id => html`<option value=${id} ?selected=${id === stateId}>${asset.stateInputs?.[id]?.label ?? id}</option>`)}\n </select>\n <span>${i18next.t('figure.label.clip')}</span>\n <select @change=${(e: Event) => (this.adding = { ...a, clip: (e.target as HTMLSelectElement).value })}>\n <option value=\"\" ?selected=${!joining}>${i18next.t('figure.label.new-clip')}</option>\n ${clips.map(c => html`<option value=${c.name} ?selected=${c === joining}>${c.name}</option>`)}\n </select>\n ${joining\n ? nothing\n : html`<span>${i18next.t('figure.label.clip-name')}</span>\n <input .value=${a.name} placeholder=\"cycle\" @input=${(e: Event) => (this.adding = { ...a, name: (e.target as HTMLInputElement).value })} />\n <span>${i18next.t('figure.label.clip-duration')}</span>\n <input type=\"number\" min=\"0.1\" step=\"any\" .value=${String(a.duration)} @change=${(e: Event) => (this.adding = { ...a, duration: (e.target as HTMLInputElement).valueAsNumber })} />`}\n </div>\n ${join?.kind === 'new-group'\n ? html`<p hint track-join>${i18next.t('figure.text.track-makes-group', { clip: join.clip, name, group: join.label })}</p>`\n : join?.kind === 'group'\n ? html`<p hint track-join>${i18next.t('figure.text.track-joins-group', { name, group: join.label })}</p>`\n : nothing}\n <button act ?disabled=${this.locked || !ready} @click=${() => add(newTrackKeys(input!, this.values[stateId!], duration), 'smooth')}>\n <md-icon>add</md-icon>${i18next.t('figure.button.add-track')}\n </button>\n <button act range-track ?disabled=${this.locked || !ready} title=${i18next.t('figure.text.add-track-range-explained')}\n @click=${() => add(newTrackKeys(input!, this.values[stateId!], duration, 'range'))}>\n <md-icon>swap_horiz</md-icon>${i18next.t('figure.button.add-track-range')}\n </button></section>`\n }\n\n /**\n * The motion groups: a name, the clip that plays until another is chosen, how long a change of clip blends, and the\n * clips each holds. A group is made from a clip in none; a clip in none joins one here. Every change is one edit.\n */\n private renderGroups(asset: FigureAsset) {\n const { groups, free } = clipGroupsOf(asset)\n if (!groups.length && !free.length) return nothing\n const g = this.grouping\n const first = free.includes(g.clip) ? g.clip : free[0]\n return html`<section>\n <h3>${i18next.t('figure.label.motion-groups')}${this.help.button('figure.text.motion-groups-explained')}</h3>\n ${this.help.hint('figure.text.motion-groups-explained')}\n ${groups.map(group => this.renderGroup(group, free))}\n ${free.length\n ? html`<div form>\n <span>${i18next.t('figure.label.motion-group-name')}</span>\n <input .value=${g.label} placeholder=${i18next.t('figure.label.motion-group')} @input=${(e: Event) => (this.grouping = { ...g, label: (e.target as HTMLInputElement).value })} />\n <span>${i18next.t('figure.label.clip')}</span>\n <select @change=${(e: Event) => (this.grouping = { ...g, clip: (e.target as HTMLSelectElement).value })}>\n ${free.map(c => html`<option value=${c} ?selected=${c === first}>${c}</option>`)}\n </select>\n </div>\n <button\n act\n ?disabled=${this.locked || !first || !g.label.trim()}\n @click=${() => {\n this.edit({ kind: 'set-motion-group', group: { id: freeGroupIdOf(asset), label: g.label.trim(), clips: [first!], defaultClip: first!, transitionSeconds: 0.2 } })\n this.grouping = { clip: '', label: '' }\n }}\n >\n <md-icon>add</md-icon>${i18next.t('figure.button.add-motion-group')}\n </button>`\n : nothing}\n </section>`\n }\n\n private renderGroup(group: ClipGroup, free: string[]) {\n const value = (e: Event) => (e.target as HTMLInputElement | HTMLSelectElement).value\n return html`<section clip>\n <div track-head>\n <strong>${group.label}</strong>\n <button act ?disabled=${this.locked} title=${i18next.t('figure.button.remove-motion-group')} @click=${() => this.edit({ kind: 'remove-motion-group', id: group.id })}>\n <md-icon>close</md-icon>\n </button>\n </div>\n <div form>\n <span>${i18next.t('figure.label.motion-group-name')}</span>\n <input .value=${group.label} ?disabled=${this.locked} @change=${(e: Event) => value(e).trim() && this.edit(groupEdit(group, { label: value(e).trim() }))} />\n <span>${i18next.t('figure.label.motion-group-default')}</span>\n <select ?disabled=${this.locked} @change=${(e: Event) => this.edit(groupEdit(group, { defaultClip: value(e) }))}>\n ${group.clips.map(c => html`<option value=${c} ?selected=${c === group.defaultClip}>${c}</option>`)}\n </select>\n <span>${i18next.t('figure.label.motion-group-transition')}</span>\n <input\n type=\"number\"\n min=\"0\"\n step=\"any\"\n .value=${String(group.transitionSeconds)}\n ?disabled=${this.locked}\n @change=${(e: Event) => this.edit(groupEdit(group, { transitionSeconds: (e.target as HTMLInputElement).valueAsNumber }))}\n />\n </div>\n <div keys>\n ${group.clips.map(\n c => html`<span key\n >${c}\n <button\n ?disabled=${this.locked || group.clips.length < 2}\n title=${i18next.t('figure.button.remove-clip-from-group')}\n aria-label=${i18next.t('figure.button.remove-clip-from-group')}\n @click=${() => {\n const clips = group.clips.filter(x => x !== c)\n this.edit(groupEdit(group, { clips, defaultClip: group.defaultClip === c ? clips[0]! : group.defaultClip }))\n }}\n >\n <md-icon>close</md-icon>\n </button></span\n >`\n )}\n </div>\n ${free.length\n ? html`<select\n aria-label=${i18next.t('figure.button.add-clip-to-group')}\n ?disabled=${this.locked}\n @change=${(e: Event) => {\n const c = value(e)\n if (c) this.edit(groupEdit(group, { clips: [...group.clips, c] }))\n ;(e.target as HTMLSelectElement).value = ''\n }}\n >\n <option value=\"\" selected>${i18next.t('figure.button.add-clip-to-group')}</option>\n ${free.map(c => html`<option value=${c}>${c}</option>`)}\n </select>`\n : nothing}\n </section>`\n }\n\n /** A clip renamed: the pose bar, its moment and its pose stay with it under the new name. */\n private rename(clip: Clip, name: string) {\n const moved = <T,>(by: Record<string, T>) => (clip.name in by ? { ...by, [name]: by[clip.name]! } : by)\n this.at = moved(this.at)\n this.base = moved(this.base)\n if (this.active === clip.name) this.active = name\n this.edit({ kind: 'set-clip', clip: clip.name, name })\n }\n\n /** Show the clip's pose at a moment: one batch of input changes, not saved as the default. */\n /** Show the clip's pose at a moment. While the bar is dragged the pose is live (drawn, not recorded); the release\n * applies it as one batch of input changes. */\n private scrub(clip: Clip, seconds: number, live = false) {\n if (!this.asset || !Number.isFinite(seconds)) return\n this.at = { ...this.at, [clip.name]: seconds }\n this.active = clip.name\n const changes = poseAt(this.asset, clip.name, seconds)\n if (!changes.length) return\n if (live) {\n const values = Object.fromEntries(changes.map(c => [c.input, c.value]))\n this.dispatchEvent(new CustomEvent('states-live', { detail: { values }, bubbles: true, composed: true }))\n return\n }\n this.dispatchEvent(new CustomEvent('states', { detail: { changes }, bubbles: true, composed: true }))\n /* The clip's pose shown: what moves from here is the person's. */\n this.base = { ...this.base, [clip.name]: { ...this.values, ...Object.fromEntries(changes.map(c => [c.input, c.value])) } }\n }\n\n /** A key's moment or value typed: one edit of the track; a moment the track cannot take puts the field back. */\n private changeKey(clip: Clip, track: ClipTrack, index: number, patch: Partial<{ seconds: number; value: number }>, e: Event) {\n const keys = withKeyChanged(track.keys, index, patch, clip.duration)\n if (!keys) {\n const field = e.target as HTMLInputElement\n const was = track.keys[index]!\n field.value = 'seconds' in patch ? typed(was.seconds) : typed(was.value)\n return\n }\n this.edit(trackEdit(clip, track, { keys }))\n }\n\n private edit(edit: unknown) {\n this.dispatchEvent(new CustomEvent('part-edit', { detail: { edit }, bubbles: true, composed: true }))\n }\n\n /** Several edits as one step of the history. */\n private edits(edits: unknown[]) {\n if (edits.length === 1) return this.edit(edits[0])\n this.dispatchEvent(new CustomEvent('part-edits', { detail: { edits }, bubbles: true, composed: true }))\n }\n}\n"]}
|
|
@@ -122,7 +122,28 @@ let FigureFastenDialog = class FigureFastenDialog extends localize(i18next)(LitE
|
|
|
122
122
|
}
|
|
123
123
|
details[fasten-detail] > div[form] {
|
|
124
124
|
margin-top: 8px;
|
|
125
|
-
max-width:
|
|
125
|
+
max-width: 420px;
|
|
126
|
+
}
|
|
127
|
+
/* Where across the face, as buttons: a list the system draws is not seen in a recording, nor reached by a key in every browser. */
|
|
128
|
+
div[align-choices] {
|
|
129
|
+
display: flex;
|
|
130
|
+
flex-wrap: wrap;
|
|
131
|
+
gap: 4px;
|
|
132
|
+
}
|
|
133
|
+
div[align-choices] button {
|
|
134
|
+
font: inherit;
|
|
135
|
+
font-size: var(--ui-t-small, 11.5px);
|
|
136
|
+
padding: 3px 8px;
|
|
137
|
+
border-radius: 12px;
|
|
138
|
+
border: 1px solid var(--md-sys-color-outline-variant, #c4c7c5);
|
|
139
|
+
background: transparent;
|
|
140
|
+
color: inherit;
|
|
141
|
+
cursor: pointer;
|
|
142
|
+
}
|
|
143
|
+
div[align-choices] button[aria-pressed='true'] {
|
|
144
|
+
border-color: var(--md-sys-color-primary, #0d8f86);
|
|
145
|
+
background: var(--md-sys-color-primary-container, #cdeeea);
|
|
146
|
+
font-weight: 600;
|
|
126
147
|
}
|
|
127
148
|
span[fasten-summary] {
|
|
128
149
|
opacity: 0.8;
|
|
@@ -255,7 +276,7 @@ let FigureFastenDialog = class FigureFastenDialog extends localize(i18next)(LitE
|
|
|
255
276
|
<summary>
|
|
256
277
|
${i18next.t('figure.label.fasten-detail')}${detail.length ? html ` · <span fasten-summary>${detail.join(' · ')}</span>` : nothing}
|
|
257
278
|
</summary>
|
|
258
|
-
${plan.alignRows.length ? this.renderAlignment(plan.alignRows) : nothing}
|
|
279
|
+
${(plan.alignAxes ?? plan.alignRows).length ? this.renderAlignment(plan.alignAxes ?? plan.alignRows) : nothing}
|
|
259
280
|
<div form>
|
|
260
281
|
<span>${i18next.t('figure.label.gap')}</span>
|
|
261
282
|
<input
|
|
@@ -380,28 +401,22 @@ let FigureFastenDialog = class FigureFastenDialog extends localize(i18next)(LitE
|
|
|
380
401
|
: 'centre'
|
|
381
402
|
: (f.align[axis] ?? 'centre');
|
|
382
403
|
return html `<span>${i18next.t('figure.label.align-' + axis)}</span>
|
|
383
|
-
<
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
${this.revision && hasInstanceSize(this.revision.asset, axis)
|
|
400
|
-
? html `<option value="share" ?selected=${how === 'share'}>
|
|
401
|
-
${i18next.t('figure.label.align-share')}
|
|
402
|
-
</option>`
|
|
403
|
-
: nothing}
|
|
404
|
-
</select>
|
|
404
|
+
<div align-choices role="group" aria-label=${i18next.t('figure.label.align-' + axis)}>
|
|
405
|
+
${[
|
|
406
|
+
{ value: 'centre', words: i18next.t('figure.label.align-centre'), shown: true },
|
|
407
|
+
{ value: 'min', words: i18next.t(`figure.label.align-${axis}-min`), shown: edges },
|
|
408
|
+
{ value: 'max', words: i18next.t(`figure.label.align-${axis}-max`), shown: edges },
|
|
409
|
+
{
|
|
410
|
+
value: 'input',
|
|
411
|
+
words: f.alignInput?.[axis] ? i18next.t('figure.label.align-input', { field: fieldWordsOf(f.alignInput[axis], key => i18next.t(key)) }) : '',
|
|
412
|
+
shown: !!f.alignInput?.[axis]
|
|
413
|
+
},
|
|
414
|
+
{ value: 'mm', words: i18next.t('figure.label.align-mm'), shown: true },
|
|
415
|
+
{ value: 'share', words: i18next.t('figure.label.align-share'), shown: !!this.revision && hasInstanceSize(this.revision.asset, axis) }
|
|
416
|
+
]
|
|
417
|
+
.filter(choice => choice.shown)
|
|
418
|
+
.map(choice => html `<button type="button" aria-pressed=${String(how === choice.value)} @click=${() => set(axis, choice.value)}>${choice.words}</button>`)}
|
|
419
|
+
</div>
|
|
405
420
|
${how === 'mm' || how === 'share'
|
|
406
421
|
? html `<span></span
|
|
407
422
|
><input
|