@things-factory/figure-ui 10.1.271 → 10.1.273

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (112) hide show
  1. package/client/modeller/canvas.ts +4 -2
  2. package/client/modeller/clips.ts +74 -4
  3. package/client/modeller/data-interface.ts +30 -18
  4. package/client/modeller/editor-styles.ts +17 -6
  5. package/client/modeller/editor.ts +2 -0
  6. package/client/modeller/fasten-form.ts +81 -6
  7. package/client/modeller/fasten-geometry.ts +5 -3
  8. package/client/modeller/figure-cavity-drawing.ts +1 -3
  9. package/client/modeller/figure-clips.ts +101 -8
  10. package/client/modeller/figure-data-panel.ts +384 -200
  11. package/client/modeller/figure-fasten-dialog.ts +41 -30
  12. package/client/modeller/figure-fasten-drawing.ts +24 -14
  13. package/client/modeller/figure-first-save.ts +4 -3
  14. package/client/modeller/figure-links.ts +109 -37
  15. package/client/modeller/figure-parts.ts +7 -11
  16. package/client/modeller/figure-preview.ts +299 -79
  17. package/client/modeller/figure-size-editor.ts +7 -2
  18. package/client/modeller/first-save.ts +8 -0
  19. package/client/modeller/focus-on-render.ts +4 -0
  20. package/client/modeller/pivot.ts +76 -0
  21. package/client/modeller/size-response.ts +14 -0
  22. package/client/modeller/stage-model.ts +50 -6
  23. package/dist-client/modeller/canvas.d.ts +1 -0
  24. package/dist-client/modeller/canvas.js +3 -2
  25. package/dist-client/modeller/canvas.js.map +1 -1
  26. package/dist-client/modeller/clips.d.ts +17 -3
  27. package/dist-client/modeller/clips.js +69 -4
  28. package/dist-client/modeller/clips.js.map +1 -1
  29. package/dist-client/modeller/data-interface.d.ts +11 -8
  30. package/dist-client/modeller/data-interface.js +27 -17
  31. package/dist-client/modeller/data-interface.js.map +1 -1
  32. package/dist-client/modeller/editor-styles.js +17 -6
  33. package/dist-client/modeller/editor-styles.js.map +1 -1
  34. package/dist-client/modeller/editor.js +2 -0
  35. package/dist-client/modeller/editor.js.map +1 -1
  36. package/dist-client/modeller/fasten-form.d.ts +13 -0
  37. package/dist-client/modeller/fasten-form.js +72 -7
  38. package/dist-client/modeller/fasten-form.js.map +1 -1
  39. package/dist-client/modeller/fasten-geometry.d.ts +3 -2
  40. package/dist-client/modeller/fasten-geometry.js +5 -3
  41. package/dist-client/modeller/fasten-geometry.js.map +1 -1
  42. package/dist-client/modeller/figure-cavity-drawing.js +1 -3
  43. package/dist-client/modeller/figure-cavity-drawing.js.map +1 -1
  44. package/dist-client/modeller/figure-clips.d.ts +9 -0
  45. package/dist-client/modeller/figure-clips.js +104 -8
  46. package/dist-client/modeller/figure-clips.js.map +1 -1
  47. package/dist-client/modeller/figure-data-panel.d.ts +10 -19
  48. package/dist-client/modeller/figure-data-panel.js +382 -190
  49. package/dist-client/modeller/figure-data-panel.js.map +1 -1
  50. package/dist-client/modeller/figure-fasten-dialog.js +39 -24
  51. package/dist-client/modeller/figure-fasten-dialog.js.map +1 -1
  52. package/dist-client/modeller/figure-fasten-drawing.js +24 -14
  53. package/dist-client/modeller/figure-fasten-drawing.js.map +1 -1
  54. package/dist-client/modeller/figure-first-save.js +4 -3
  55. package/dist-client/modeller/figure-first-save.js.map +1 -1
  56. package/dist-client/modeller/figure-links.d.ts +9 -0
  57. package/dist-client/modeller/figure-links.js +120 -51
  58. package/dist-client/modeller/figure-links.js.map +1 -1
  59. package/dist-client/modeller/figure-parts.js +7 -11
  60. package/dist-client/modeller/figure-parts.js.map +1 -1
  61. package/dist-client/modeller/figure-preview.d.ts +13 -0
  62. package/dist-client/modeller/figure-preview.js +296 -80
  63. package/dist-client/modeller/figure-preview.js.map +1 -1
  64. package/dist-client/modeller/figure-size-editor.js +7 -3
  65. package/dist-client/modeller/figure-size-editor.js.map +1 -1
  66. package/dist-client/modeller/first-save.d.ts +5 -0
  67. package/dist-client/modeller/first-save.js +7 -0
  68. package/dist-client/modeller/first-save.js.map +1 -1
  69. package/dist-client/modeller/focus-on-render.d.ts +2 -0
  70. package/dist-client/modeller/focus-on-render.js +4 -0
  71. package/dist-client/modeller/focus-on-render.js.map +1 -0
  72. package/dist-client/modeller/pivot.d.ts +12 -0
  73. package/dist-client/modeller/pivot.js +59 -0
  74. package/dist-client/modeller/pivot.js.map +1 -0
  75. package/dist-client/modeller/size-response.d.ts +6 -0
  76. package/dist-client/modeller/size-response.js +14 -0
  77. package/dist-client/modeller/size-response.js.map +1 -1
  78. package/dist-client/modeller/stage-model.d.ts +17 -3
  79. package/dist-client/modeller/stage-model.js +44 -6
  80. package/dist-client/modeller/stage-model.js.map +1 -1
  81. package/dist-client/tsconfig.tsbuildinfo +1 -1
  82. package/package.json +8 -7
  83. package/test/browser/editing-page.js +1 -1
  84. package/test/browser/editing.check.mjs +6 -5
  85. package/test/browser/links.check.mjs +30 -0
  86. package/test/browser/modeller.check.mjs +2 -2
  87. package/test/browser/parts-page.js +4 -0
  88. package/test/browser/parts.check.mjs +16 -10
  89. package/test/browser/screen-page.js +12 -1
  90. package/test/browser/screen.check.mjs +142 -11
  91. package/test/browser/section.check.mjs +21 -0
  92. package/test/browser/serve-response.mjs +5 -2
  93. package/test/browser/side-panel-sweep.check.mjs +171 -10
  94. package/test/clips.test.ts +49 -4
  95. package/test/data-motion.test.ts +39 -8
  96. package/test/fasten-form.test.ts +69 -0
  97. package/test/fasten-geometry.test.ts +13 -0
  98. package/test/first-save.test.ts +11 -1
  99. package/test/pivot.test.ts +57 -0
  100. package/test/size-response.test.ts +10 -2
  101. package/test/stage-model.test.ts +23 -1
  102. package/translations/en.json +31 -11
  103. package/translations/es.json +30 -10
  104. package/translations/ja.json +30 -10
  105. package/translations/ko.json +32 -12
  106. package/translations/ms.json +30 -10
  107. package/translations/zh.json +30 -10
  108. package/tutorial/humanoid/README.md +22 -0
  109. package/tutorial/humanoid/chapters.mjs +247 -0
  110. package/tutorial/humanoid/encode.mjs +26 -0
  111. package/tutorial/humanoid/lib.mjs +197 -0
  112. package/tutorial/humanoid/record.mjs +65 -0
@@ -1 +1 @@
1
- {"version":3,"file":"figure-cavity-drawing.js","sourceRoot":"","sources":["../../client/modeller/figure-cavity-drawing.ts"],"names":[],"mappings":"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","sourcesContent":["import { css, html, LitElement, nothing, svg } from 'lit'\nimport { customElement, property, state } from 'lit/decorators.js'\nimport { ref } from 'lit/directives/ref.js'\n\nimport { i18next, localize } from '@operato/i18n'\nimport { figureCavitySectionOf } from '@hatiolab/figure-model'\nimport type { FigureAuthoringAction, FigureCavityRequest, FigureEvaluatedShape, FigureSection } from '@hatiolab/figure-model'\nimport { cavityRefusalWordsOf, cavityWorkingOf, END_FACE, endToggled, mm, SIDE_FACE, wallDragged } from './section-controls.js'\n\ntype Axis = 'x' | 'y' | 'z'\n\n/** A field opened by a press takes the keys at once. */\nconst focusOnRender = () => ref(el => el && requestAnimationFrame(() => (el as HTMLInputElement).select()))\ntype End = 'start' | 'end'\ntype Body = { id: string; shape: FigureEvaluatedShape }\n\n/** How the section is laid on the screen, by the axis it is pushed along: across to the right, then down. */\nconst SCREEN: Record<Axis, [Axis, Axis]> = { y: ['x', 'z'], x: ['z', 'y'], z: ['x', 'y'] }\n\n/**\n * 속 공간 그림 — the inside of a pushed part drawn, and edited by drawing (user 2026-10-01: 「이해와 편집이 직관적이지 않다」).\n *\n * Seen along the push, the section and its inside: a handle in the middle of each wall is dragged to its thickness,\n * every wall together unless 면마다 벽 is on. Cut along the push, the walls and the two ends: an end pressed opens or\n * closes it, a closed end's inner line is dragged to its thickness. While dragging, the figure behind shows what the\n * inside makes (`command-live`); letting go sends one `set-cavity`. What the kernel would refuse is drawn in the error\n * colour and said, by the kernel's own check, and is not sent.\n */\n@customElement('figure-cavity-drawing')\nexport class FigureCavityDrawing extends localize(i18next)(LitElement) {\n static styles = css`\n :host {\n display: grid;\n gap: 6px;\n }\n svg {\n width: 100%;\n display: block;\n touch-action: none;\n user-select: none;\n }\n svg text {\n font: inherit;\n }\n small[refusal] {\n color: var(--md-sys-color-error);\n }\n div[pane] {\n position: relative;\n }\n div[pane] input {\n position: absolute;\n width: 64px;\n transform: translate(-50%, -50%);\n font: inherit;\n }\n text[typed] {\n cursor: text;\n text-decoration: underline dotted;\n }\n `\n\n @property({ attribute: false }) body?: Body\n @property({ type: Boolean }) locked = false\n /** Walls one per side: a handle moves its own wall only. */\n @property({ type: Boolean }) perSide = false\n\n /** What is being dragged, and the inside it makes; undefined when nothing is. */\n @state() private working?: ReturnType<typeof cavityWorkingOf>\n @state() private refusal = ''\n private dragging: { kind: 'wall'; side: string } | { kind: 'end'; end: End } | null = null\n /** A number pressed to be typed: which, and where on its picture (percent of the picture's box). */\n @state() private typing?: ({ kind: 'wall'; side: string } | { kind: 'end'; end: End }) & { x: number; y: number; pane: 'top' | 'side'; value: number }\n private pressedAt = 0\n\n private get now() {\n return this.working ?? (this.body ? cavityWorkingOf(this.body.shape) : undefined)\n }\n\n private request(w: NonNullable<ReturnType<typeof cavityWorkingOf>>): FigureCavityRequest {\n return { wall: { ...w.wall }, start: w.start, end: w.end }\n }\n\n private action(w: NonNullable<ReturnType<typeof cavityWorkingOf>>): FigureAuthoringAction {\n return { kind: 'set-cavity', part: this.body!.id, cavity: this.request(w) }\n }\n\n /** What the kernel would refuse, in words; for one side's wall, the most that side can be with the opposite kept. */\n private judge(w: NonNullable<ReturnType<typeof cavityWorkingOf>>, side?: string): string {\n const words = cavityRefusalWordsOf(this.body!.shape, w, this.perSide, side)\n return words ? i18next.t(words.key, words.params) : ''\n }\n\n /** The working inside while dragging: drawn, judged, and previewed behind when the kernel would take it. */\n private hold(w: NonNullable<ReturnType<typeof cavityWorkingOf>>, side?: string) {\n this.working = w\n this.refusal = this.judge(w, side)\n this.emit('command-live', this.refusal ? null : this.action(w))\n }\n\n private release() {\n const w = this.working\n this.dragging = null\n this.working = undefined\n if (!w) return\n /* Refused: nothing is sent, and the reason stays said until the next drag -- letting go must not look like taking it. */\n if (this.refusal) {\n this.emit('command-live', null)\n return\n }\n this.emit('command', this.action(w))\n }\n\n private emit(name: 'command' | 'command-live', action: FigureAuthoringAction | null) {\n this.dispatchEvent(new CustomEvent(name, { detail: { action }, bubbles: true, composed: true }))\n }\n\n private point(ev: PointerEvent, el: SVGSVGElement) {\n const pt = el.createSVGPoint()\n pt.x = ev.clientX\n pt.y = ev.clientY\n return pt.matrixTransform(el.getScreenCTM()!.inverse())\n }\n\n render() {\n const e = this.body?.shape.extrusion\n const w = this.now\n if (!e || !w || (e.section.kind !== 'rectangle' && e.section.kind !== 'ellipse')) return nothing\n return html`<div pane>${this.top(e, w)}${this.typing?.pane === 'top' ? this.renderTyping() : nothing}</div>\n <div pane>${this.side(e, w)}${this.typing?.pane === 'side' ? this.renderTyping() : nothing}</div>\n ${this.refusal ? html`<small refusal role=\"alert\">${this.refusal}</small>` : nothing}`\n }\n\n /** Press a number, type it, Enter: the same one set-cavity a drag sends; Esc or leaving puts it back. */\n private type(ev: PointerEvent, what: { kind: 'wall'; side: string } | { kind: 'end'; end: End }, pane: 'top' | 'side', value: number) {\n if (this.locked) return\n ev.stopPropagation()\n const svgEl = (ev.target as Element).closest('svg')!\n const box = svgEl.getBoundingClientRect()\n this.refusal = ''\n this.typing = { ...what, pane, value, x: ((ev.clientX - box.left) / box.width) * 100, y: ((ev.clientY - box.top) / box.height) * 100 }\n }\n\n private renderTyping() {\n const t = this.typing!\n return html`<input type=\"number\" step=\"1\" min=\"1\" .value=${String(t.value)} style=${`left:${t.x}%;top:${t.y}%`}\n aria-label=${t.kind === 'wall' ? i18next.t('figure.label.section-wall') : i18next.t('figure.label.face-' + END_FACE(this.body!.shape.extrusion!.axis, t.end))}\n @keydown=${(ev: KeyboardEvent) => {\n ev.stopPropagation()\n if (ev.key === 'Escape') this.typing = undefined\n if (ev.key !== 'Enter') return\n const value = Number((ev.target as HTMLInputElement).value)\n this.typing = undefined\n if (!(Number.isFinite(value) && value > 0)) return\n const now = this.now!\n const next = t.kind === 'wall' ? { ...now, wall: wallDragged(now.wall, t.side, value, this.perSide) } : { ...now, [t.end]: { closed: Math.round(value) } }\n this.refusal = this.judge(next, t.kind === 'wall' ? t.side : undefined)\n if (!this.refusal) this.emit('command', this.action(next))\n }}\n @blur=${() => (this.typing = undefined)}\n ${focusOnRender()} />`\n }\n\n /** Seen along the push: the section, its inside and a handle on each wall. */\n private top(e: NonNullable<FigureEvaluatedShape['extrusion']>, w: NonNullable<ReturnType<typeof cavityWorkingOf>>) {\n const [h, v] = SCREEN[e.axis]\n const s = e.section\n const across = (a: Axis) => (s.kind === 'rectangle' ? s.size[a]! : 2 * (s as { radius: Record<string, number> }).radius[a]!)\n const W = 300,\n H = 170,\n pad = 26\n /* Wider room left and right: a wall's number stands outside the section there. */\n const k = Math.min((W - 2 * (pad + 10)) / across(h), (H - 2 * pad) / across(v))\n const ox = W / 2,\n oy = H / 2\n const inside = figureCavitySectionOf(s as FigureSection, e.axis, w.wall)\n const bad = !!this.refusal || !('section' in inside)\n const shape = (sec: FigureSection, c: Partial<Record<Axis, number>>, attrs: string) => {\n const cx = ox + (c[h] ?? 0) * k,\n cy = oy + (c[v] ?? 0) * k\n if (sec.kind === 'ellipse') return svg`<ellipse cx=${cx} cy=${cy} rx=${sec.radius[h]! * k} ry=${sec.radius[v]! * k} style=${attrs} />`\n const r = sec as { size: Record<string, number>; corner?: Record<string, number> }\n return svg`<rect x=${cx - (r.size[h]! * k) / 2} y=${cy - (r.size[v]! * k) / 2} width=${r.size[h]! * k} height=${r.size[v]! * k}\n rx=${(r.corner?.[h] ?? 0) * k} ry=${(r.corner?.[v] ?? 0) * k} style=${attrs} />`\n }\n const half = { [h]: (across(h) * k) / 2, [v]: (across(v) * k) / 2 } as Record<Axis, number>\n /* Each wall's handle sits on the inside's edge, half way along it; the value is the wall's own. */\n const handles = [`${h}-`, `${h}+`, `${v}-`, `${v}+`].map(side => {\n const a = side[0] as Axis,\n low = side[1] === '-'\n const sign = low ? -1 : 1\n const edge = sign * (half[a] - w.wall[side]! * k)\n /* The two handles across a narrow inside would stand on each other: then each steps aside, the low one first. */\n const room = 2 * half[a] - (w.wall[`${a}-`]! + w.wall[`${a}+`]!) * k\n const aside = room < 16 ? sign * 9 : 0\n const x = a === h ? ox + edge : ox + aside,\n y = a === v ? oy + edge : oy + aside\n /*\n The number stands just past the section's outer edge on its own side, so the opposite wall's never meets it\n however thin the walls or shallow the section (2026-10-02: at 70 mm deep the two walls' numbers lay on each other).\n */\n const tx = a === h ? ox + sign * (half[a] + 5) : ox,\n ty = a === v ? oy + sign * (half[a] + (low ? 5 : 13)) : oy + 4\n return svg`<g wall=${side} style=${`cursor:${a === h ? 'ew-resize' : 'ns-resize'}`}\n @pointerdown=${(ev: PointerEvent) => this.grab(ev, { kind: 'wall', side })}>\n <rect x=${x - 6} y=${y - 6} width=\"12\" height=\"12\" rx=\"2\" style=\"fill:var(--md-sys-color-surface);stroke:var(--md-sys-color-primary);stroke-width:1.5\" />\n <text typed x=${tx} y=${ty} font-size=\"11\" text-anchor=${a === h ? (low ? 'end' : 'start') : 'middle'} style=\"fill:var(--md-sys-color-on-surface)\"\n @pointerdown=${(ev: PointerEvent) => this.type(ev, { kind: 'wall', side }, 'top', w.wall[side]!)}>${mm(w.wall[side]!)}</text>\n <title>${i18next.t('figure.label.face-' + SIDE_FACE[side])} ${i18next.t('figure.label.section-wall')}</title>\n </g>`\n })\n return svg`<svg viewBox=${`0 0 ${W} ${H}`} role=\"img\" aria-label=${i18next.t('figure.label.section-cavity-top')}\n @pointermove=${(ev: PointerEvent) => this.drag(ev, e, k, ox, oy, half)}\n @pointerup=${() => this.release()} @pointercancel=${() => this.release()}>\n ${shape(s as FigureSection, {}, 'fill:var(--md-sys-color-primary-container);stroke:var(--md-sys-color-primary);stroke-width:1.5')}\n ${'section' in inside\n ? shape(inside.section, inside.centre, `fill:var(--md-sys-color-surface);stroke:${bad ? 'var(--md-sys-color-error)' : 'var(--md-sys-color-primary)'};stroke-width:1.2;stroke-dasharray:4 3`)\n : nothing}\n ${this.locked ? nothing : handles}\n </svg>`\n }\n\n /** Cut along the push: the walls across the first plane axis, and the two ends -- pressed to open or close. */\n private side(e: NonNullable<FigureEvaluatedShape['extrusion']>, w: NonNullable<ReturnType<typeof cavityWorkingOf>>) {\n const [h] = SCREEN[e.axis]\n const s = e.section\n const width = s.kind === 'rectangle' ? s.size[h]! : 2 * (s as { radius: Record<string, number> }).radius[h]!\n const length = e.end - e.start\n const W = 300,\n H = 170,\n padX = 40,\n padY = 26\n const k = Math.min((W - 2 * padX) / width, (H - 2 * padY) / length)\n const x0 = W / 2 - (width * k) / 2,\n x1 = W / 2 + (width * k) / 2,\n yTop = H / 2 - (length * k) / 2,\n yBot = H / 2 + (length * k) / 2\n const wl = w.wall[`${h}-`]! * k,\n wr = w.wall[`${h}+`]! * k\n const thick = (end: End) => (w[end] === 'open' ? 0 : (w[end] as { closed: number }).closed * k)\n /* The push's start is drawn at the bottom: a tote stands on its floor. */\n const floor = thick('start'),\n lid = thick('end')\n const fill = 'fill:var(--md-sys-color-primary-container);stroke:var(--md-sys-color-primary);stroke-width:1.2'\n const endZone = (end: End, y: number, t: number) => {\n const open = w[end] === 'open'\n const words = open\n ? i18next.t('figure.label.section-end-open')\n : `${i18next.t('figure.label.section-end-closed')} ${mm((w[end] as { closed: number }).closed)}`\n const label = `${i18next.t('figure.label.face-' + END_FACE(e.axis, end))}: ${words}`\n const inner = end === 'start' ? y - t : y + t\n return svg`<g end=${end} style=${`cursor:${open ? 'pointer' : 'ns-resize'}`}\n @pointerdown=${(ev: PointerEvent) => this.grab(ev, { kind: 'end', end })}>\n <rect x=${x0 + wl} y=${Math.min(y, inner) - 8} width=${x1 - x0 - wl - wr} height=${Math.abs(t) + 16} style=\"fill:transparent\" />\n ${open ? svg`<line x1=${x0 + wl} y1=${y} x2=${x1 - wr} y2=${y} style=\"stroke:var(--md-sys-color-outline);stroke-dasharray:3 3\" />` : nothing}\n <text ?typed=${!open} x=${W / 2} y=${end === 'start' ? yBot + 16 : yTop - 8} font-size=\"11\" text-anchor=\"middle\" style=\"fill:var(--md-sys-color-primary)\"\n @pointerdown=${(ev: PointerEvent) => !open && this.type(ev, { kind: 'end', end }, 'side', (w[end] as { closed: number }).closed)}>${label}</text>\n <title>${label}</title>\n </g>`\n }\n return svg`<svg viewBox=${`0 0 ${W} ${H + 8}`} role=\"img\" aria-label=${i18next.t('figure.label.section-cavity-side')}\n @pointermove=${(ev: PointerEvent) => this.dragEnd(ev, k, yTop, yBot)}\n @pointerup=${(ev: PointerEvent) => this.releaseEnd(ev)} @pointercancel=${() => this.release()}>\n <rect x=${x0} y=${yTop} width=${wl} height=${yBot - yTop} style=${fill} />\n <rect x=${x1 - wr} y=${yTop} width=${wr} height=${yBot - yTop} style=${fill} />\n ${floor ? svg`<rect x=${x0 + wl} y=${yBot - floor} width=${x1 - x0 - wl - wr} height=${floor} style=${fill} />` : nothing}\n ${lid ? svg`<rect x=${x0 + wl} y=${yTop} width=${x1 - x0 - wl - wr} height=${lid} style=${fill} />` : nothing}\n ${this.locked ? nothing : [endZone('start', yBot, floor), endZone('end', yTop, lid)]}\n </svg>`\n }\n\n private grab(ev: PointerEvent, what: NonNullable<FigureCavityDrawing['dragging']>) {\n if (this.locked) return\n ev.stopPropagation()\n ;(ev.currentTarget as Element).closest('svg')!.setPointerCapture(ev.pointerId)\n this.dragging = what\n this.pressedAt = ev.clientY\n this.refusal = ''\n }\n\n private drag(ev: PointerEvent, e: NonNullable<FigureEvaluatedShape['extrusion']>, k: number, ox: number, oy: number, half: Record<Axis, number>) {\n const d = this.dragging\n if (d?.kind !== 'wall') return\n const [h] = SCREEN[e.axis]\n const p = this.point(ev, ev.currentTarget as SVGSVGElement)\n const a = d.side[0] as Axis,\n low = d.side[1] === '-'\n const at = a === h ? p.x - ox : p.y - oy\n const value = (half[a] - (low ? -at : at)) / k\n this.hold({ ...this.now!, wall: wallDragged(this.now!.wall, d.side, value, this.perSide) }, d.side)\n }\n\n private dragEnd(ev: PointerEvent, k: number, yTop: number, yBot: number) {\n const d = this.dragging\n if (d?.kind !== 'end' || this.now![d.end] === 'open') return\n if (Math.abs(ev.clientY - this.pressedAt) < 3 && !this.working) return\n const p = this.point(ev, ev.currentTarget as SVGSVGElement)\n const t = d.end === 'start' ? (yBot - p.y) / k : (p.y - yTop) / k\n this.hold({ ...this.now!, [d.end]: { closed: Math.max(1, Math.round(t)) } })\n }\n\n /** A press on an end that did not move is a toggle; a drag was a thickness. */\n private releaseEnd(ev: PointerEvent) {\n const d = this.dragging\n if (d?.kind === 'end' && !this.working && Math.abs(ev.clientY - this.pressedAt) < 3) {\n this.dragging = null\n const next = { ...this.now!, [d.end]: endToggled(this.body!.shape, this.now![d.end]) }\n this.refusal = this.judge(next)\n if (!this.refusal) this.emit('command', this.action(next))\n return\n }\n this.release()\n }\n}\n\n"]}
1
+ {"version":3,"file":"figure-cavity-drawing.js","sourceRoot":"","sources":["../../client/modeller/figure-cavity-drawing.ts"],"names":[],"mappings":"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","sourcesContent":["import { css, html, LitElement, nothing, svg } from 'lit'\nimport { customElement, property, state } from 'lit/decorators.js'\n\nimport { i18next, localize } from '@operato/i18n'\nimport { figureCavitySectionOf } from '@hatiolab/figure-model'\nimport type { FigureAuthoringAction, FigureCavityRequest, FigureEvaluatedShape, FigureSection } from '@hatiolab/figure-model'\nimport { focusOnRender } from './focus-on-render.js'\nimport { cavityRefusalWordsOf, cavityWorkingOf, END_FACE, endToggled, mm, SIDE_FACE, wallDragged } from './section-controls.js'\n\ntype Axis = 'x' | 'y' | 'z'\n\ntype End = 'start' | 'end'\ntype Body = { id: string; shape: FigureEvaluatedShape }\n\n/** How the section is laid on the screen, by the axis it is pushed along: across to the right, then down. */\nconst SCREEN: Record<Axis, [Axis, Axis]> = { y: ['x', 'z'], x: ['z', 'y'], z: ['x', 'y'] }\n\n/**\n * 속 공간 그림 — the inside of a pushed part drawn, and edited by drawing (user 2026-10-01: 「이해와 편집이 직관적이지 않다」).\n *\n * Seen along the push, the section and its inside: a handle in the middle of each wall is dragged to its thickness,\n * every wall together unless 면마다 벽 is on. Cut along the push, the walls and the two ends: an end pressed opens or\n * closes it, a closed end's inner line is dragged to its thickness. While dragging, the figure behind shows what the\n * inside makes (`command-live`); letting go sends one `set-cavity`. What the kernel would refuse is drawn in the error\n * colour and said, by the kernel's own check, and is not sent.\n */\n@customElement('figure-cavity-drawing')\nexport class FigureCavityDrawing extends localize(i18next)(LitElement) {\n static styles = css`\n :host {\n display: grid;\n gap: 6px;\n }\n svg {\n width: 100%;\n display: block;\n touch-action: none;\n user-select: none;\n }\n svg text {\n font: inherit;\n }\n small[refusal] {\n color: var(--md-sys-color-error);\n }\n div[pane] {\n position: relative;\n }\n div[pane] input {\n position: absolute;\n width: 64px;\n transform: translate(-50%, -50%);\n font: inherit;\n }\n text[typed] {\n cursor: text;\n text-decoration: underline dotted;\n }\n `\n\n @property({ attribute: false }) body?: Body\n @property({ type: Boolean }) locked = false\n /** Walls one per side: a handle moves its own wall only. */\n @property({ type: Boolean }) perSide = false\n\n /** What is being dragged, and the inside it makes; undefined when nothing is. */\n @state() private working?: ReturnType<typeof cavityWorkingOf>\n @state() private refusal = ''\n private dragging: { kind: 'wall'; side: string } | { kind: 'end'; end: End } | null = null\n /** A number pressed to be typed: which, and where on its picture (percent of the picture's box). */\n @state() private typing?: ({ kind: 'wall'; side: string } | { kind: 'end'; end: End }) & { x: number; y: number; pane: 'top' | 'side'; value: number }\n private pressedAt = 0\n\n private get now() {\n return this.working ?? (this.body ? cavityWorkingOf(this.body.shape) : undefined)\n }\n\n private request(w: NonNullable<ReturnType<typeof cavityWorkingOf>>): FigureCavityRequest {\n return { wall: { ...w.wall }, start: w.start, end: w.end }\n }\n\n private action(w: NonNullable<ReturnType<typeof cavityWorkingOf>>): FigureAuthoringAction {\n return { kind: 'set-cavity', part: this.body!.id, cavity: this.request(w) }\n }\n\n /** What the kernel would refuse, in words; for one side's wall, the most that side can be with the opposite kept. */\n private judge(w: NonNullable<ReturnType<typeof cavityWorkingOf>>, side?: string): string {\n const words = cavityRefusalWordsOf(this.body!.shape, w, this.perSide, side)\n return words ? i18next.t(words.key, words.params) : ''\n }\n\n /** The working inside while dragging: drawn, judged, and previewed behind when the kernel would take it. */\n private hold(w: NonNullable<ReturnType<typeof cavityWorkingOf>>, side?: string) {\n this.working = w\n this.refusal = this.judge(w, side)\n this.emit('command-live', this.refusal ? null : this.action(w))\n }\n\n private release() {\n const w = this.working\n this.dragging = null\n this.working = undefined\n if (!w) return\n /* Refused: nothing is sent, and the reason stays said until the next drag -- letting go must not look like taking it. */\n if (this.refusal) {\n this.emit('command-live', null)\n return\n }\n this.emit('command', this.action(w))\n }\n\n private emit(name: 'command' | 'command-live', action: FigureAuthoringAction | null) {\n this.dispatchEvent(new CustomEvent(name, { detail: { action }, bubbles: true, composed: true }))\n }\n\n private point(ev: PointerEvent, el: SVGSVGElement) {\n const pt = el.createSVGPoint()\n pt.x = ev.clientX\n pt.y = ev.clientY\n return pt.matrixTransform(el.getScreenCTM()!.inverse())\n }\n\n render() {\n const e = this.body?.shape.extrusion\n const w = this.now\n if (!e || !w || (e.section.kind !== 'rectangle' && e.section.kind !== 'ellipse')) return nothing\n return html`<div pane>${this.top(e, w)}${this.typing?.pane === 'top' ? this.renderTyping() : nothing}</div>\n <div pane>${this.side(e, w)}${this.typing?.pane === 'side' ? this.renderTyping() : nothing}</div>\n ${this.refusal ? html`<small refusal role=\"alert\">${this.refusal}</small>` : nothing}`\n }\n\n /** Press a number, type it, Enter: the same one set-cavity a drag sends; Esc or leaving puts it back. */\n private type(ev: PointerEvent, what: { kind: 'wall'; side: string } | { kind: 'end'; end: End }, pane: 'top' | 'side', value: number) {\n if (this.locked) return\n ev.stopPropagation()\n const svgEl = (ev.target as Element).closest('svg')!\n const box = svgEl.getBoundingClientRect()\n this.refusal = ''\n this.typing = { ...what, pane, value, x: ((ev.clientX - box.left) / box.width) * 100, y: ((ev.clientY - box.top) / box.height) * 100 }\n }\n\n private renderTyping() {\n const t = this.typing!\n return html`<input type=\"number\" step=\"1\" min=\"1\" .value=${String(t.value)} style=${`left:${t.x}%;top:${t.y}%`}\n aria-label=${t.kind === 'wall' ? i18next.t('figure.label.section-wall') : i18next.t('figure.label.face-' + END_FACE(this.body!.shape.extrusion!.axis, t.end))}\n @keydown=${(ev: KeyboardEvent) => {\n ev.stopPropagation()\n if (ev.key === 'Escape') this.typing = undefined\n if (ev.key !== 'Enter') return\n const value = Number((ev.target as HTMLInputElement).value)\n this.typing = undefined\n if (!(Number.isFinite(value) && value > 0)) return\n const now = this.now!\n const next = t.kind === 'wall' ? { ...now, wall: wallDragged(now.wall, t.side, value, this.perSide) } : { ...now, [t.end]: { closed: Math.round(value) } }\n this.refusal = this.judge(next, t.kind === 'wall' ? t.side : undefined)\n if (!this.refusal) this.emit('command', this.action(next))\n }}\n @blur=${() => (this.typing = undefined)}\n ${focusOnRender()} />`\n }\n\n /** Seen along the push: the section, its inside and a handle on each wall. */\n private top(e: NonNullable<FigureEvaluatedShape['extrusion']>, w: NonNullable<ReturnType<typeof cavityWorkingOf>>) {\n const [h, v] = SCREEN[e.axis]\n const s = e.section\n const across = (a: Axis) => (s.kind === 'rectangle' ? s.size[a]! : 2 * (s as { radius: Record<string, number> }).radius[a]!)\n const W = 300,\n H = 170,\n pad = 26\n /* Wider room left and right: a wall's number stands outside the section there. */\n const k = Math.min((W - 2 * (pad + 10)) / across(h), (H - 2 * pad) / across(v))\n const ox = W / 2,\n oy = H / 2\n const inside = figureCavitySectionOf(s as FigureSection, e.axis, w.wall)\n const bad = !!this.refusal || !('section' in inside)\n const shape = (sec: FigureSection, c: Partial<Record<Axis, number>>, attrs: string) => {\n const cx = ox + (c[h] ?? 0) * k,\n cy = oy + (c[v] ?? 0) * k\n if (sec.kind === 'ellipse') return svg`<ellipse cx=${cx} cy=${cy} rx=${sec.radius[h]! * k} ry=${sec.radius[v]! * k} style=${attrs} />`\n const r = sec as { size: Record<string, number>; corner?: Record<string, number> }\n return svg`<rect x=${cx - (r.size[h]! * k) / 2} y=${cy - (r.size[v]! * k) / 2} width=${r.size[h]! * k} height=${r.size[v]! * k}\n rx=${(r.corner?.[h] ?? 0) * k} ry=${(r.corner?.[v] ?? 0) * k} style=${attrs} />`\n }\n const half = { [h]: (across(h) * k) / 2, [v]: (across(v) * k) / 2 } as Record<Axis, number>\n /* Each wall's handle sits on the inside's edge, half way along it; the value is the wall's own. */\n const handles = [`${h}-`, `${h}+`, `${v}-`, `${v}+`].map(side => {\n const a = side[0] as Axis,\n low = side[1] === '-'\n const sign = low ? -1 : 1\n const edge = sign * (half[a] - w.wall[side]! * k)\n /* The two handles across a narrow inside would stand on each other: then each steps aside, the low one first. */\n const room = 2 * half[a] - (w.wall[`${a}-`]! + w.wall[`${a}+`]!) * k\n const aside = room < 16 ? sign * 9 : 0\n const x = a === h ? ox + edge : ox + aside,\n y = a === v ? oy + edge : oy + aside\n /*\n The number stands just past the section's outer edge on its own side, so the opposite wall's never meets it\n however thin the walls or shallow the section (2026-10-02: at 70 mm deep the two walls' numbers lay on each other).\n */\n const tx = a === h ? ox + sign * (half[a] + 5) : ox,\n ty = a === v ? oy + sign * (half[a] + (low ? 5 : 13)) : oy + 4\n return svg`<g wall=${side} style=${`cursor:${a === h ? 'ew-resize' : 'ns-resize'}`}\n @pointerdown=${(ev: PointerEvent) => this.grab(ev, { kind: 'wall', side })}>\n <rect x=${x - 6} y=${y - 6} width=\"12\" height=\"12\" rx=\"2\" style=\"fill:var(--md-sys-color-surface);stroke:var(--md-sys-color-primary);stroke-width:1.5\" />\n <text typed x=${tx} y=${ty} font-size=\"11\" text-anchor=${a === h ? (low ? 'end' : 'start') : 'middle'} style=\"fill:var(--md-sys-color-on-surface)\"\n @pointerdown=${(ev: PointerEvent) => this.type(ev, { kind: 'wall', side }, 'top', w.wall[side]!)}>${mm(w.wall[side]!)}</text>\n <title>${i18next.t('figure.label.face-' + SIDE_FACE[side])} ${i18next.t('figure.label.section-wall')}</title>\n </g>`\n })\n return svg`<svg viewBox=${`0 0 ${W} ${H}`} role=\"img\" aria-label=${i18next.t('figure.label.section-cavity-top')}\n @pointermove=${(ev: PointerEvent) => this.drag(ev, e, k, ox, oy, half)}\n @pointerup=${() => this.release()} @pointercancel=${() => this.release()}>\n ${shape(s as FigureSection, {}, 'fill:var(--md-sys-color-primary-container);stroke:var(--md-sys-color-primary);stroke-width:1.5')}\n ${'section' in inside\n ? shape(inside.section, inside.centre, `fill:var(--md-sys-color-surface);stroke:${bad ? 'var(--md-sys-color-error)' : 'var(--md-sys-color-primary)'};stroke-width:1.2;stroke-dasharray:4 3`)\n : nothing}\n ${this.locked ? nothing : handles}\n </svg>`\n }\n\n /** Cut along the push: the walls across the first plane axis, and the two ends -- pressed to open or close. */\n private side(e: NonNullable<FigureEvaluatedShape['extrusion']>, w: NonNullable<ReturnType<typeof cavityWorkingOf>>) {\n const [h] = SCREEN[e.axis]\n const s = e.section\n const width = s.kind === 'rectangle' ? s.size[h]! : 2 * (s as { radius: Record<string, number> }).radius[h]!\n const length = e.end - e.start\n const W = 300,\n H = 170,\n padX = 40,\n padY = 26\n const k = Math.min((W - 2 * padX) / width, (H - 2 * padY) / length)\n const x0 = W / 2 - (width * k) / 2,\n x1 = W / 2 + (width * k) / 2,\n yTop = H / 2 - (length * k) / 2,\n yBot = H / 2 + (length * k) / 2\n const wl = w.wall[`${h}-`]! * k,\n wr = w.wall[`${h}+`]! * k\n const thick = (end: End) => (w[end] === 'open' ? 0 : (w[end] as { closed: number }).closed * k)\n /* The push's start is drawn at the bottom: a tote stands on its floor. */\n const floor = thick('start'),\n lid = thick('end')\n const fill = 'fill:var(--md-sys-color-primary-container);stroke:var(--md-sys-color-primary);stroke-width:1.2'\n const endZone = (end: End, y: number, t: number) => {\n const open = w[end] === 'open'\n const words = open\n ? i18next.t('figure.label.section-end-open')\n : `${i18next.t('figure.label.section-end-closed')} ${mm((w[end] as { closed: number }).closed)}`\n const label = `${i18next.t('figure.label.face-' + END_FACE(e.axis, end))}: ${words}`\n const inner = end === 'start' ? y - t : y + t\n return svg`<g end=${end} style=${`cursor:${open ? 'pointer' : 'ns-resize'}`}\n @pointerdown=${(ev: PointerEvent) => this.grab(ev, { kind: 'end', end })}>\n <rect x=${x0 + wl} y=${Math.min(y, inner) - 8} width=${x1 - x0 - wl - wr} height=${Math.abs(t) + 16} style=\"fill:transparent\" />\n ${open ? svg`<line x1=${x0 + wl} y1=${y} x2=${x1 - wr} y2=${y} style=\"stroke:var(--md-sys-color-outline);stroke-dasharray:3 3\" />` : nothing}\n <text ?typed=${!open} x=${W / 2} y=${end === 'start' ? yBot + 16 : yTop - 8} font-size=\"11\" text-anchor=\"middle\" style=\"fill:var(--md-sys-color-primary)\"\n @pointerdown=${(ev: PointerEvent) => !open && this.type(ev, { kind: 'end', end }, 'side', (w[end] as { closed: number }).closed)}>${label}</text>\n <title>${label}</title>\n </g>`\n }\n return svg`<svg viewBox=${`0 0 ${W} ${H + 8}`} role=\"img\" aria-label=${i18next.t('figure.label.section-cavity-side')}\n @pointermove=${(ev: PointerEvent) => this.dragEnd(ev, k, yTop, yBot)}\n @pointerup=${(ev: PointerEvent) => this.releaseEnd(ev)} @pointercancel=${() => this.release()}>\n <rect x=${x0} y=${yTop} width=${wl} height=${yBot - yTop} style=${fill} />\n <rect x=${x1 - wr} y=${yTop} width=${wr} height=${yBot - yTop} style=${fill} />\n ${floor ? svg`<rect x=${x0 + wl} y=${yBot - floor} width=${x1 - x0 - wl - wr} height=${floor} style=${fill} />` : nothing}\n ${lid ? svg`<rect x=${x0 + wl} y=${yTop} width=${x1 - x0 - wl - wr} height=${lid} style=${fill} />` : nothing}\n ${this.locked ? nothing : [endZone('start', yBot, floor), endZone('end', yTop, lid)]}\n </svg>`\n }\n\n private grab(ev: PointerEvent, what: NonNullable<FigureCavityDrawing['dragging']>) {\n if (this.locked) return\n ev.stopPropagation()\n ;(ev.currentTarget as Element).closest('svg')!.setPointerCapture(ev.pointerId)\n this.dragging = what\n this.pressedAt = ev.clientY\n this.refusal = ''\n }\n\n private drag(ev: PointerEvent, e: NonNullable<FigureEvaluatedShape['extrusion']>, k: number, ox: number, oy: number, half: Record<Axis, number>) {\n const d = this.dragging\n if (d?.kind !== 'wall') return\n const [h] = SCREEN[e.axis]\n const p = this.point(ev, ev.currentTarget as SVGSVGElement)\n const a = d.side[0] as Axis,\n low = d.side[1] === '-'\n const at = a === h ? p.x - ox : p.y - oy\n const value = (half[a] - (low ? -at : at)) / k\n this.hold({ ...this.now!, wall: wallDragged(this.now!.wall, d.side, value, this.perSide) }, d.side)\n }\n\n private dragEnd(ev: PointerEvent, k: number, yTop: number, yBot: number) {\n const d = this.dragging\n if (d?.kind !== 'end' || this.now![d.end] === 'open') return\n if (Math.abs(ev.clientY - this.pressedAt) < 3 && !this.working) return\n const p = this.point(ev, ev.currentTarget as SVGSVGElement)\n const t = d.end === 'start' ? (yBot - p.y) / k : (p.y - yTop) / k\n this.hold({ ...this.now!, [d.end]: { closed: Math.max(1, Math.round(t)) } })\n }\n\n /** A press on an end that did not move is a toggle; a drag was a thickness. */\n private releaseEnd(ev: PointerEvent) {\n const d = this.dragging\n if (d?.kind === 'end' && !this.working && Math.abs(ev.clientY - this.pressedAt) < 3) {\n this.dragging = null\n const next = { ...this.now!, [d.end]: endToggled(this.body!.shape, this.now![d.end]) }\n this.refusal = this.judge(next)\n if (!this.refusal) this.emit('command', this.action(next))\n return\n }\n this.release()\n }\n}\n\n"]}
@@ -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.edit({ kind: 'set-clip', clip: clip.name, name: e.target.value })} />
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 || !grouped} title=${i18next.t(grouped ? 'figure.text.copy-clip-explained' : 'figure.text.copy-clip-needs-group')}
197
- @click=${() => this.edit({ kind: 'copy-clip', clip: clip.name, name: freeClipNameOf(this.asset, clip.name) })}>
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
- const add = (keys) => {
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)