@things-factory/figure-ui 10.1.211 → 10.1.212

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 (68) hide show
  1. package/client/graphql/index.ts +1 -1
  2. package/client/modeller/angle-dial.ts +1 -1
  3. package/client/modeller/canvas.ts +1 -1
  4. package/client/modeller/figure-history-panel.ts +1 -1
  5. package/client/modeller/figure-parts.ts +3 -3
  6. package/client/modeller/figure-settings.ts +1 -1
  7. package/client/modeller/links.ts +2 -2
  8. package/client/modeller/scene-budget.ts +3 -3
  9. package/client/modeller/thumbnail.ts +1 -1
  10. package/client/pages/figure-list-page.ts +2 -2
  11. package/client/pages/figure-modeller-page.ts +4 -4
  12. package/client/types.ts +2 -2
  13. package/client/viewparts/figure-thumb.ts +1 -1
  14. package/dist-client/graphql/index.d.ts +1 -1
  15. package/dist-client/graphql/index.js +1 -1
  16. package/dist-client/graphql/index.js.map +1 -1
  17. package/dist-client/modeller/angle-dial.d.ts +1 -1
  18. package/dist-client/modeller/angle-dial.js.map +1 -1
  19. package/dist-client/modeller/canvas.js +1 -1
  20. package/dist-client/modeller/canvas.js.map +1 -1
  21. package/dist-client/modeller/figure-history-panel.d.ts +1 -1
  22. package/dist-client/modeller/figure-history-panel.js.map +1 -1
  23. package/dist-client/modeller/figure-parts.d.ts +3 -3
  24. package/dist-client/modeller/figure-parts.js.map +1 -1
  25. package/dist-client/modeller/figure-settings.js +1 -1
  26. package/dist-client/modeller/figure-settings.js.map +1 -1
  27. package/dist-client/modeller/links.d.ts +1 -1
  28. package/dist-client/modeller/links.js +2 -2
  29. package/dist-client/modeller/links.js.map +1 -1
  30. package/dist-client/modeller/scene-budget.d.ts +3 -3
  31. package/dist-client/modeller/scene-budget.js +3 -3
  32. package/dist-client/modeller/scene-budget.js.map +1 -1
  33. package/dist-client/modeller/thumbnail.js +1 -1
  34. package/dist-client/modeller/thumbnail.js.map +1 -1
  35. package/dist-client/pages/figure-list-page.d.ts +1 -1
  36. package/dist-client/pages/figure-list-page.js +2 -2
  37. package/dist-client/pages/figure-list-page.js.map +1 -1
  38. package/dist-client/pages/figure-modeller-page.d.ts +3 -3
  39. package/dist-client/pages/figure-modeller-page.js +4 -4
  40. package/dist-client/pages/figure-modeller-page.js.map +1 -1
  41. package/dist-client/tsconfig.tsbuildinfo +1 -1
  42. package/dist-client/types.d.ts +2 -2
  43. package/dist-client/types.js +1 -1
  44. package/dist-client/types.js.map +1 -1
  45. package/dist-client/viewparts/figure-thumb.js +1 -1
  46. package/dist-client/viewparts/figure-thumb.js.map +1 -1
  47. package/docs/multipart-response-review-2026-10-24.md +1 -1
  48. package/docs/response-authoring-2026-10-24.md +4 -4
  49. package/package.json +6 -6
  50. package/test/ai-proposal.test.ts +1 -1
  51. package/test/align.test.ts +1 -1
  52. package/test/command-preview.test.ts +3 -3
  53. package/test/fields.test.ts +2 -2
  54. package/test/first-minute.test.ts +5 -5
  55. package/test/first-save.test.ts +3 -3
  56. package/test/gizmo.test.ts +3 -3
  57. package/test/keys.test.ts +2 -2
  58. package/test/layout.test.ts +1 -1
  59. package/test/links.test.ts +14 -14
  60. package/test/live.test.ts +4 -4
  61. package/test/material.test.ts +1 -1
  62. package/test/properties.test.ts +1 -1
  63. package/test/proposal-record.test.ts +1 -1
  64. package/test/refusals.test.ts +1 -1
  65. package/test/resize-with-placement.test.ts +1 -1
  66. package/test/scene-budget.test.ts +4 -4
  67. package/test/verdict.test.ts +1 -1
  68. package/translations/ko.json +106 -106
@@ -1 +1 @@
1
- {"version":3,"file":"links.js","sourceRoot":"","sources":["../../client/modeller/links.ts"],"names":[],"mappings":"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","sourcesContent":["import { FIGURE_FACES, figureShapeFaces, figurePartsExtentOf, compileFigureAsset, figureFollowOf, proposeFigureProportion, figureAttachmentsOf, figureBindingsOf, figureInstanceSizeRangeOf, figureFollowableAxesOf, figureShapeProviderOf, figureMimicTermsOf, figureFastenKeptPlaceOf, figureFastenAxesOf, figureJointAsFixed, figureJointWithMotion, figureSurfaceOf, figureAxesOf, figureMotionsOf, motionIdOf, motionStateIdOf } from '@hatiolab/figure-model'\nimport type { FigureFollow, FigureInstanceSizeRange } from '@hatiolab/figure-model'\nimport type { FigureAsset, FigureAuthoringAction, FigureBindingPlace, FigureDimensionSource, FigureFace, FigureFacing, FigureJoint, FigureJointMotion, FigureNamedMotion, FigureSurfacePlace } from '@hatiolab/figure-model'\nimport { startingShapeKindOf } from './starting-shape.js'\nimport { boxOf } from './align.js'\nimport { graphValuesOf, type FigureRevision } from './revision.js'\nimport { jointAxisToken, jointAxisVectorOf, type JointAxisVector } from './joint-axis.js'\n\n/*\n * What a part is tied to — the readers behind the parts' size response, fastening and motion sections. Kept apart from the element so they can be tested without a browser.\n */\n\nexport type Axis = 'x' | 'y' | 'z'\nexport const AXES: readonly Axis[] = ['x', 'y', 'z']\n\ninterface Node {\n id: string\n op: string\n args: string[]\n outputs: Record<string, string>\n}\nconst modelOf = (asset: FigureAsset) =>\n asset.document.model as unknown as { nodes: Node[]; inputs: Array<{ id: string; role?: string; unit?: string; min?: number; max?: number }>; constants: Array<{ id: string; value: number }> }\n\n/** What one dimension of a part is worked out from (figure-model's `FigureFollow`). */\nexport type Follow = FigureFollow\n\n/**\n * `link-dimension` routes a part's dimension through `<part>.dimension.<axis>` and points its first argument at the\n * source, directly or through the nodes that scale it. Walking back through those nodes finds the source: the\n * instance size (`size.<axis>`), another part's dimension (`<part>.dimension.<axis>.value`) or a declared input.\n */\n/** What one measure of a part is worked out from, read back from the graph (figure-model's reader, one copy). */\nexport function followOf(asset: FigureAsset, part: string, axis: Axis): Follow {\n return figureFollowOf(asset, part, axis)\n}\n\n/**\n * The parts whose size follows the figure's size on some axis, in the model's order: the ones that change when the\n * figure is resized on a drawing. Read by figure-model's own follow (`figureFollowOf`), not worked out again here.\n */\nexport function sizeFollowersOf(asset: FigureAsset): string[] {\n const parts = (modelOf(asset).nodes as Array<{ id: string; op: string }>).filter(n => n.op === 'place@1').map(n => n.id)\n return parts.filter(part =>\n AXES.some(axis => {\n try {\n return figureFollowOf(asset, part, axis).of === 'instance'\n } catch {\n return false\n }\n })\n )\n}\n\n/** Whether the asset declares an instance size on an axis — only then can a dimension follow it. */\nexport const hasInstanceSize = (asset: FigureAsset, axis: Axis) => modelOf(asset).inputs.some(i => i.id === `size.${axis}` && i.role === 'design')\n\n/** The part this one is fastened to, or `null`. The mounting plane counts as fastened (the model names no part). */\nexport function fastenedTo(asset: FigureAsset, part: string): string | null {\n return figureAttachmentsOf(asset)[part] ?? null\n}\n\n/**\n * What holds a part: the part it is fastened to, the plane the figure is mounted on, or nothing. The joint record says\n * it; a part standing on the plane had read as fastened to nothing, so the form offered no way to move it and sent\n * no replace -- the fastening was refused as already made (the door's post, 2026-09-25).\n */\nexport function heldBy(asset: FigureAsset, part: string): { part: string } | { plane: true } | null {\n const record = asset.joints?.find(j => j.body1.part === part)\n if (record) return 'plane' in record.body0 ? { plane: true } : { part: record.body0.part }\n const to = fastenedTo(asset, part)\n return to ? { part: to } : null\n}\n\n/** The word for where a joint's body0 end sits: its face's, or the part's origin for an end placed by it (ADR-0107 decision 4). */\nexport const endPlaceKeyOf = (end: object) => ('face' in end ? `figure.label.face-${(end as { face: string }).face}` : 'figure.label.joint-origin')\n\n/** Whether a dimension of this part can follow something — box-shaped, whose three sizes are X, Y and Z. */\nexport function canFollow(asset: FigureAsset, part: string): boolean {\n return followableAxes(asset, part).length > 0\n}\n\n/**\n * The axes whose size can follow something: figure-model's one list (`figureFollowableAxesOf`), which follow-size and\n * the resize plan ask too -- the screen does not keep a list of its own (designer 2026-09-27).\n */\nexport function followableAxes(asset: FigureAsset, part: string): Axis[] {\n const shape = modelOf(asset).nodes.find(n => n.id === `${part}.shape`)\n return shape ? figureFollowableAxesOf(shape as never) : []\n}\n\n/**\n * The directions \"follow the size, attached\" passes to figure-model (designer 2026-09-27):\n * - `chosen`: what the author ticked, and the ones already following, which stay;\n * - `suggested`: a part the author has not chosen for yet and that follows nothing -- every direction, said as\n * \"all three\" on the button, never as a choice the author made;\n * - `none`: the author set every direction back to fixed, or unticked them all -- nothing is taken for all.\n * `pending` is the author's ticks for this part in this screen, when they have ticked or fixed anything.\n */\nexport function resizeAxesOf(asset: FigureAsset, part: string, pending?: readonly Axis[]): { axes: Axis[]; basis: 'chosen' | 'suggested' | 'none' } {\n const editable = followableAxes(asset, part)\n const following = editable.filter(axis => {\n const now = followOf(asset, part, axis)\n return now.of === 'instance' && now.axis === axis\n })\n if (pending) {\n const axes = editable.filter(axis => pending.includes(axis) || following.includes(axis))\n return { axes, basis: axes.length ? 'chosen' : 'none' }\n }\n if (following.length) return { axes: following, basis: 'chosen' }\n return { axes: editable, basis: editable.length ? 'suggested' : 'none' }\n}\n\n/**\n * Korean particles for a word the sentence is built around: the topic (은/는) and \"and/with\" (과/와), by whether the\n * word's last syllable ends in a consonant. Other languages need none.\n */\nexport function particlesOf(word: string, lang: string): { topic: string; with: string } {\n if (!lang.startsWith('ko')) return { topic: word, with: word }\n const last = word.trim().slice(-1).charCodeAt(0)\n const closed = last >= 0xac00 && last <= 0xd7a3 && (last - 0xac00) % 28 !== 0\n return { topic: word + (closed ? '은' : '는'), with: word + (closed ? '과' : '와') }\n}\n\n/**\n * The selected part at the head of its panel: what it is, and -- only when a measure changes by itself -- what it\n * follows, as a sentence a person reads without knowing the model's words: the model's size, a share of it, another\n * part's measure, a field, a calculation (`figureFollowOf`). A size of its own and a part fastened or not say nothing\n * here; the fastening is drawn in its own section (user 2026-10-01: 「규칙을 따름: 높이 (Y)」 -- \"who would know what that\n * means?\", and \"why say anything when all is as usual?\").\n */\nexport function partSummaryOf(\n asset: FigureAsset,\n part: string,\n say: (key: string, params?: Record<string, string>) => string,\n lang = 'ko'\n): { kind: string; size: string } {\n const shape = modelOf(asset).nodes.find(n => n.id === `${part}.shape`)\n const named = startingShapeKindOf(shape as never)\n const kind = named ? say(`figure.label.primitive-${named}`) : ''\n const editable = followableAxes(asset, part)\n const round = editable.length === 2\n const word = (axis: Axis) => say(round && axis === 'x' ? 'figure.label.measure-diameter' : `figure.label.measure-${axis}`)\n const pct = (times: number) => String(Math.round(times * 1000) / 10)\n /* One sentence per way of following; the measures that follow the same way are said together. */\n const lines = new Map<string, { key: string; params: Record<string, string>; axes: Axis[] }>()\n for (const axis of editable) {\n const f = followOf(asset, part, axis)\n let key: string\n let params: Record<string, string> = {}\n if (f.of === 'own') continue\n if (f.of === 'instance') {\n key = f.times === 1 ? 'figure.text.summary-size-follows' : 'figure.text.summary-size-share'\n /* A measure following the figure's own size on its own axis says no measure word, so the axes that do so are one\n sentence -- 「너비 · 높이 · 깊이는 도형 크기를 따라 바뀝니다」, not three (user 2026-10-16). */\n params = f.times === 1 && f.axis === axis && !f.plus ? {} : { pct: pct(f.times), whole: say(`figure.label.measure-${f.axis}`) }\n if (f.plus) (key = key + '-plus'), (params.plus = String(f.plus))\n } else if (f.of === 'part') {\n const other = say(`figure.label.measure-${f.axis}`)\n key = (f.times ?? 1) === 1 ? 'figure.text.summary-size-part' : 'figure.text.summary-size-part-share'\n params = { other: f.part, measure: particlesOf(other, lang).with, measureWord: other, pct: pct(f.times ?? 1) }\n if (f.plus) (key = key + '-plus'), (params.plus = String(f.plus))\n } else if (f.of === 'input') {\n key = 'figure.text.summary-size-input'\n params = { field: fieldWordsOf(f.input, k => say(k)) }\n } else key = 'figure.text.summary-size-worked-out'\n const id = key + JSON.stringify(params)\n lines.set(id, { key, params, axes: [...(lines.get(id)?.axes ?? []), axis] })\n }\n /* Nothing to say when the size is its own: only a measure that changes by itself is news (user 2026-10-01). */\n const size = [...lines.values()].map(l => say(l.key, { ...l.params, axes: particlesOf(l.axes.map(word).join(' · '), lang).topic })).join(' ')\n return { kind, size }\n}\n\n/**\n * A part's own field in the words its row uses -- 「위치 Y」, 「크기 X」, and the turn as one 「회전」 -- so a field the plan\n * replaces, or one only the room reads, is named as the author knows it, not by its id.\n */\nexport function fieldWordsOf(id: string, say: (key: string) => string): string {\n const own = /\\.(position|rotation|size)\\.([xyz])$/.exec(id)\n if (!own) return id\n return own[1] === 'rotation' ? say('figure.label.group-rotation') : `${say(`figure.label.group-${own[1]}`)} ${own[2]!.toUpperCase()}`\n}\n\n/** What a part's own measure on an axis is now (a box's side, a cylinder's radius or length), at the design as it stands. */\nexport function dimensionNow(revision: FigureRevision, part: string, axis: Axis): number | undefined {\n const m = modelOf(revision.asset)\n /* The argument the shape names for this axis (figure-model's provider), not its place among the arguments. */\n const shape = m.nodes.find(n => n.id === `${part}.shape`)\n const edit = shape && figureShapeProviderOf(shape as never)?.edit[axis]\n const ref = edit && !('refused' in edit) ? shape!.args[edit.arg] : undefined\n if (!ref) return undefined\n try {\n const value = graphValuesOf(revision)[ref]\n return typeof value === 'number' && Number.isFinite(value) ? value : undefined\n } catch {\n return undefined\n }\n}\n\n/**\n * The command a dimension's rule chosen in the size form sends (`choice` as `choiceOf` writes it), or nothing to send.\n * The measure as it stands decides the numbers: a dimension stops following at it, and a share is taken of it, so\n * neither choice changes the part's size. A share needs the figure's size on that axis.\n */\nexport function followCommandOf(revision: FigureRevision, part: string, axis: Axis, choice: string, now: Follow): FigureAuthoringAction | undefined {\n const following = now.of !== 'own'\n /* The part's own measure on the axis now (a cylinder's radius, not its width), else its extent as drawn. */\n const current = dimensionNow(revision, part, axis) ?? boxOf(revision, part)?.dims[AXES.indexOf(axis)] ?? 100\n if (choice === 'own') return following ? { kind: 'unlink-dimension', part, axis, mm: Math.max(1, Math.round(current)) } : undefined\n const [of, a, b] = choice.split(':')\n if (of === 'share') {\n const size = revision.asset.designInputs[`size.${a}`]\n if (!size) return undefined\n const times = Math.round((current / size) * 1e6) / 1e6\n return { kind: 'link-dimension', part, axis, source: { of: 'instance', axis: a as Axis }, times, replace: following }\n }\n const source: FigureDimensionSource = of === 'instance' ? { of: 'instance', axis: a as Axis } : { of: 'part', part: a!, axis: b as Axis }\n return { kind: 'link-dimension', part, axis, source, replace: following }\n}\n\n/**\n * How long a part is along one axis now, as it is drawn: the shape's own measure through figure-model's provider (a\n * cylinder's width is twice its radius), read after any rule it follows -- so a linked measure still says its size.\n */\nexport function measureNow(revision: FigureRevision, part: string, axis: Axis): number | undefined {\n const shape = modelOf(revision.asset).nodes.find(n => n.id === `${part}.shape`)\n const edit = shape && figureShapeProviderOf(shape as never)?.edit[axis]\n if (!shape || !edit || 'refused' in edit) return undefined\n try {\n const value = graphValuesOf(revision)[shape.args[edit.arg]!]\n return typeof value === 'number' && Number.isFinite(value) ? value * edit.k : undefined\n } catch {\n return undefined\n }\n}\n\n/**\n * The flat faces a part's shape declares, by name -- figure-model's shape definitions are the one place they are\n * written (a portal's opening sides as well as its outer faces). A sphere has none.\n */\nexport function facesOf(asset: FigureAsset, part: string): string[] {\n const shape = modelOf(asset).nodes.find(n => n.id === `${part}.shape`)\n const faces = (shape && figureShapeFaces(shape as never)) ?? {}\n /* A cylinder's curved side is no face: a part is fastened to a point on it (ADR-0140 3.9, `surfaceOf`). */\n return inScreenOrder(Object.keys(faces).filter(f => faces[f]!.contact !== 'line'))\n}\n\n/** The curved surface a part offers to be fastened to at a point: a cylinder's side or a sphere's round (ADR-0140 3.9). */\nexport function surfaceOf(asset: FigureAsset, part: string): { form: 'around' | 'toward'; axis: Axis } | undefined {\n return figureSurfaceOf(asset, part)\n}\n\n/** Faces in the order the screen lists them: the six outer ones left to front, then the rest as the shape gives them. */\nconst SCREEN_ORDER = ['left', 'right', 'bottom', 'top', 'back', 'front']\nfunction inScreenOrder(names: string[]): string[] {\n const rank = (n: string) => (SCREEN_ORDER.includes(n) ? SCREEN_ORDER.indexOf(n) : SCREEN_ORDER.length)\n return names.map((n, i) => [n, i] as const).sort((a, b) => rank(a[0]) - rank(b[0]) || a[1] - b[1]).map(([n]) => n)\n}\n\n/** The axis a face of a part faces along, from the same definitions. */\nexport function faceAxisOf(asset: FigureAsset, part: string, face: string): Axis | undefined {\n const shape = modelOf(asset).nodes.find(n => n.id === `${part}.shape`)\n return (shape && figureShapeFaces(shape as never)?.[face]?.axis) as Axis | undefined\n}\n\n/** Whether `attach` can take this part: any part whose shape has a flat face. */\nexport function canFasten(asset: FigureAsset, part: string): boolean {\n return facesOf(asset, part).length > 0 || !!surfaceOf(asset, part)\n}\n\nconst OUTER: Record<Axis, [string, string]> = { x: ['left', 'right'], y: ['bottom', 'top'], z: ['back', 'front'] }\n\n/**\n * The axes a part can be made a row along (r3 §8, figure-model `make-repeat`): across the face it is fastened by, when\n * it is fastened fixed to another part and holds nothing. None for a part that is loose, moves, stands on the floor or\n * already repeats -- the command would refuse those, so they are not offered.\n */\nexport function rowAxesOf(asset: FigureAsset, part: string): Axis[] {\n const joints = asset.joints ?? []\n const j = joints.find(o => o.body1.part === part)\n /* A part that moves may be a row too: every copy on the one control, from its own place (designer 2026-09-27). */\n if (!j || j.repeat || !('part' in j.body0)) return []\n if (joints.some(o => 'part' in o.body0 && o.body0.part === part)) return []\n /* Placed by an origin: no face to lay the row across, and the kernel refuses it. */\n if (!('face' in j.body0) || 'at' in j.body1) return []\n return figureFastenAxesOf(asset, { part: j.body0.part, face: j.body0.face })\n}\n\n/**\n * Why a part cannot be made into a row here, in the terms `rowAxesOf` refuses it: said, not hidden (ADR-0097 §5.5).\n * Nothing when it can, or when it already is a row (that row is shown where it stands).\n */\nexport function rowBlockOf(asset: FigureAsset, part: string): 'unfastened' | 'on-plane' | 'holds-parts' | 'at-origin' | 'on-surface' | undefined {\n const joints = asset.joints ?? []\n const j = joints.find(o => o.body1.part === part)\n if (!j) return 'unfastened'\n if (j.repeat) return undefined\n if (!('part' in j.body0)) return 'on-plane'\n if (joints.some(o => 'part' in o.body0 && o.body0.part === part)) return 'holds-parts'\n /* On a point of a curved surface a row has no face to run across (ADR-0140 3.9): the kernel refuses it. */\n if ('surface' in j.body0) return 'on-surface'\n if (!('face' in j.body0) || 'at' in j.body1) return 'at-origin'\n return undefined\n}\n\n/** The row a part is made into, as its fastening's record keeps it. */\nexport const rowOf = (asset: FigureAsset, part: string) => asset.joints?.find(o => o.body1.part === part)?.repeat\n\n/** Where a part sits across the face it is fastened to, on one axis: centred, level with an edge, or a distance off centre. */\n/** `share`: the distance as a share of the figure's size on that axis, so it keeps its place when the figure is resized. */\n/** `input`: the place across the face follows one of the part's position fields -- as \"follow size, attached\" keeps it (ADR-0097). */\nexport type Alignment = 'centre' | 'min' | 'max' | 'mm' | 'share' | 'input'\n\n/**\n * The axes across the face a part is fastened to — the two a fastening does not set by itself. Edges to line up with\n * are offered where both parts have their two outer faces on that axis; the plane the figure is mounted on has none,\n * so on it (X and Z) only centred or a distance is offered.\n */\n/**\n * The mounting plane of this figure, by its placement (ADR-0093): the floor or the ceiling is Y = 0 and a part stands\n * on it or hangs below it; a wall is Z = 0 and a part stands out of it (ADR-0140 3.11).\n */\nexport function mountingPlaneOf(asset: FigureAsset): { normal: Axis; facings: FigureFacing[] } {\n return asset.placement === 'wall' ? { normal: 'z', facings: ['meet'] } : { normal: 'y', facings: ['meet', 'flush'] }\n}\n\nexport function alignAxesOf(asset: FigureAsset, target: { part: string; face: string } | 'plane'): { axis: Axis; edges: boolean }[] {\n /* The plane has no edges, but a figure that declares its size has sides on it (figure-model 0.1.64). */\n if (target === 'plane') return figureFastenAxesOf(asset, 'plane').map(axis => ({ axis, edges: hasInstanceSize(asset, axis) }))\n /* The part is lined up by its real extent in the pose it has (ADR-0140 3.4): the target's two sides are what it needs. */\n const theirs = new Set(facesOf(asset, target.part))\n return figureFastenAxesOf(asset, target).map(axis => ({ axis, edges: OUTER[axis].every(f => theirs.has(f)) }))\n}\n\n/**\n * The axes across the face the fastening form asks about in rows: only where the face drawing (`view`, its axes) cannot\n * set the place -- no drawing at all, an axis it does not draw, a place that follows a position field, or one the\n * figure's size may scale.\n */\nexport function alignRowsOf(\n asset: FigureAsset,\n aim: { part: string; face: string } | 'plane',\n view: { axes: readonly Axis[] } | undefined,\n alignInput: Partial<Record<Axis, string>> = {}\n): { axis: Axis; edges: boolean }[] {\n return alignAxesOf(asset, aim).filter(({ axis }) => !view || !view.axes.includes(axis) || !!alignInput[axis] || hasInstanceSize(asset, axis))\n}\n\n/** The controls a part's showing can follow: the figure's state inputs, with their range and label. */\nexport function visibilityControlsOf(asset: FigureAsset): Array<{ id: string; unit: string; min: number; max: number; label: string }> {\n const labels = (asset as unknown as { stateInputs?: Record<string, { label?: string }> }).stateInputs ?? {}\n return modelOf(asset)\n .inputs.filter(input => input.role === 'state')\n .map(input => ({ id: input.id, unit: input.unit ?? '', min: input.min ?? 0, max: input.max ?? 1, label: labels[input.id]?.label || input.id }))\n}\n\n/** When the part is drawn (figure-model `set-visibility`): always (null), or while a control is at least a value. */\nexport function shownWhenOf(asset: FigureAsset, part: string): { input: string; atLeast: number } | null {\n const look = asset.appearance.find(one => one.target === part) as { visibility?: string } | undefined\n if (!look?.visibility) return null\n const m = modelOf(asset)\n const node = m.nodes.find(n => n.op === 'at-least@1' && Object.values(n.outputs).includes(look.visibility!))\n const at = node && m.constants.find(c => c.id === node.args[1])\n return node && at ? { input: node.args[0]!, atLeast: at.value } : null\n}\n\n/** Whether `part` hangs from `from`, through any number of fastenings. */\nexport function hangsFrom(asset: FigureAsset, part: string, from: string): boolean {\n const seen = new Set<string>()\n for (let at: string | undefined = part; at && !seen.has(at); ) {\n seen.add(at)\n const j = ((asset.joints ?? []) as FigureJoint[]).find(o => o.body1.part === at)\n at = j && 'part' in j.body0 ? (j.body0 as { part: string }).part : undefined\n if (at === from) return true\n }\n return false\n}\n\n/**\n * The fastening a part has, as the fastening form holds it -- so the form opens on what is there (the target and its\n * face, how it meets it, the gap and where across the face) and a change is a change to that.\n * Opening it on the defaults showed a roller fastened by its centre as fastened by its bottom, and fastening again\n * from there broke its turning in place (walk 1, 2026-09-26). Null for a part fastened to nothing.\n */\nexport function fasteningOf(\n revision: FigureRevision,\n part: string\n): {\n toPlane: boolean\n target: string\n targetFace: string\n facing: FigureFacing\n gap: number\n /** The record's gap when it is worked out (a length that follows something): kept as it is until a number is typed. */\n gapKept?: unknown\n align: Partial<Record<Axis, Alignment>>\n alignMm: Partial<Record<Axis, number>>\n /** Placed by a part's origin (ADR-0107 decision 4): no face to fasten by, and the form does not write it. */\n atOrigin?: true\n /** On a point of the target's curved surface (ADR-0140 3.9), as the record says it. */\n surface?: FigureSurfacePlace\n} | null {\n const record = revision.asset.joints?.find(j => j.body1.part === part)\n if (!record) return null\n const toPlane = 'plane' in record.body0\n const target = 'part' in record.body0 ? record.body0.part : ''\n const surface = 'surface' in record.body0 ? record.body0.surface : undefined\n const targetFace = 'face' in record.body0 ? record.body0.face : 'top'\n const atOrigin = !('plane' in record.body0) && ((!('face' in record.body0) && !surface) || 'at' in record.body1)\n if (surface)\n return {\n toPlane,\n target,\n targetFace,\n facing: record.origin?.facing ?? 'meet',\n gap: typeof record.origin?.gap === 'number' ? record.origin.gap : 0,\n ...(record.origin?.gap !== undefined && typeof record.origin.gap !== 'number' ? { gapKept: record.origin.gap } : {}),\n align: {},\n alignMm: {},\n surface,\n ...(atOrigin ? { atOrigin: true as const } : {})\n }\n /* Where across the face: as the record says it, and where it says nothing, where the part stands now. */\n const kept = placeKeptOf(revision, part, toPlane ? 'plane' : { part: target, face: targetFace })\n for (const [axis, how] of Object.entries(record.origin?.align ?? {}) as Array<[Axis, unknown]>) {\n if (how === 'min' || how === 'max' || how === 'centre') {\n kept.align[axis] = how\n delete kept.alignMm[axis]\n } else if (how && typeof how === 'object' && typeof (how as { mm?: unknown }).mm === 'number') {\n kept.align[axis] = 'mm'\n kept.alignMm[axis] = (how as { mm: number }).mm\n } else if ((how as { mm?: { from?: { of?: string; input?: string } } })?.mm?.from?.of === 'input') {\n /* Following a position field: read as that, so fastening again keeps the field and does not fix its number. */\n kept.align[axis] = 'input'\n kept.alignInput[axis] = (how as { mm: { from: { input: string } } }).mm.from.input\n delete kept.alignMm[axis]\n }\n }\n const gap = record.origin?.gap\n return {\n toPlane,\n target,\n targetFace,\n facing: record.origin?.facing ?? 'meet',\n gap: typeof gap === 'number' ? gap : 0,\n ...(gap !== undefined && typeof gap !== 'number' ? { gapKept: gap } : {}),\n ...kept,\n ...(atOrigin ? { atOrigin: true as const } : {})\n }\n}\n\n/**\n * The `gap` an attach command writes from the form: a worked-out gap as it was read, else the number, else none. Read as\n * a number, a gap that follows the legs or the instance height became 0, and opening the form on the part dropped it\n * to the plane (2026-10-13, the robot dog and the forklift).\n */\nexport function fastenGapOf(form: { gap: number; gapKept?: unknown }): { gap?: unknown } {\n if (form.gapKept !== undefined) return { gap: form.gapKept }\n return form.gap ? { gap: form.gap } : {}\n}\n\n/**\n * The alignment that keeps the part where it stands when it is fastened, as the form holds it: the kernel's place\n * (`figureFastenKeptPlaceOf`, ADR-0140 3.7), a distance on each axis it is off the target's centre.\n */\nexport function placeKeptOf(\n revision: FigureRevision,\n part: string,\n target: { part: string; face: string } | 'plane'\n): { align: Partial<Record<Axis, Alignment>>; alignMm: Partial<Record<Axis, number>>; alignInput: Partial<Record<Axis, string>> } {\n const alignMm = figureFastenKeptPlaceOf(revision.asset, part, target, { ...revision.inputs })\n return { align: Object.fromEntries(Object.keys(alignMm).map(axis => [axis, 'mm'])) as Partial<Record<Axis, Alignment>>, alignMm, alignInput: {} }\n}\n\n/** The `align` of an attach command from the form's choices: only the axes across that face, and centred ones left out. */\nexport function alignOf(\n asset: FigureAsset,\n target: { part: string; face: string } | 'plane',\n how: Partial<Record<Axis, Alignment>>,\n mm: Partial<Record<Axis, number>>,\n inputs: Partial<Record<Axis, string>> = {}\n) {\n const align: Partial<Record<Axis, 'min' | 'max' | { mm: number | { from: { of: 'instance'; axis: Axis }; times: number } | { from: { of: 'input'; input: string } } }>> = {}\n for (const { axis, edges } of alignAxesOf(asset, target)) {\n const one = how[axis] ?? 'centre'\n const size = asset.designInputs[`size.${axis}`]\n if (one === 'share' && mm[axis] && hasInstanceSize(asset, axis) && size)\n align[axis] = { mm: { from: { of: 'instance', axis }, times: Math.round((mm[axis]! / size) * 1e6) / 1e6 } }\n else if (one === 'mm' && mm[axis]) align[axis] = { mm: mm[axis]! }\n else if ((one === 'min' || one === 'max') && edges) align[axis] = one\n else if (one === 'input' && inputs[axis]) align[axis] = { mm: { from: { of: 'input', input: inputs[axis]! } } }\n }\n return Object.keys(align).length ? align : undefined\n}\n\n/**\n * The axes on which the part's position is worked out from other values rather than being its own number. `fix-position` makes one its own number where it is now.\n */\nexport function positionsWorkedOut(asset: FigureAsset, part: string): Axis[] {\n const m = modelOf(asset)\n const pose = m.nodes.find(n => n.id === `${part}.pose`)\n if (!pose || pose.op !== 'rigid@1' || fastenedTo(asset, part)) return []\n const own = (ref: string) => ref.startsWith(`${part}.`) && m.inputs.some(i => i.id === ref && i.role === 'design')\n const constant = (ref: string) => m.constants.some(c => c.id === ref)\n return AXES.filter((_axis, i) => !own(pose.args[i]!) && !constant(pose.args[i]!))\n}\n\n/**\n * Whether the part's position on an axis is a share of the instance size (`scale-position`): `size.<axis> × share`.\n * Such a position is worked out too, but it already grows with the figure, so it is not offered again.\n */\nexport function positionIsShare(asset: FigureAsset, part: string, axis: Axis): boolean {\n const m = modelOf(asset)\n const ref = m.nodes.find(n => n.id === `${part}.pose`)?.args[AXES.indexOf(axis)]\n const writer = ref ? m.nodes.find(n => Object.values(n.outputs).includes(ref)) : undefined\n return !!writer && writer.op === 'mul@1' && writer.args[0] === `size.${axis}` && m.constants.some(c => c.id === writer.args[1])\n}\n\n/** How a part moves, if it does: slide or turn, along which axis, driven by which control. */\nexport interface Motion {\n kind: 'slide' | 'turn' | 'continuous'\n axis: Axis | '?'\n /** The record's axis when it is a vector, as written (the graph holds it turned into the parent's frame). */\n vector?: JointAxisVector\n control?: { id: string; unit?: string; min?: number; max?: number }\n /** A joint that moves with another (URDF's mimic): the leader's value times `multiplier`, plus `offset`. */\n /** What it follows, as a sum of leaders each with its multiplier, plus an offset (one leader is a sum of one). */\n follows?: { sum: Array<{ joint: string; multiplier: number }>; offset: number }\n /** A slide whose distance is a part's length (plus a difference): the control is its share. */\n travel?: { part: string; axis: string; plus?: number }\n}\n\nexport function motionOf(asset: FigureAsset, part: string, k = 0): Motion | undefined {\n const m = modelOf(asset)\n const joint = asset.joints?.find(j => j.body1.part === part)\n const record = joint && figureMotionsOf(joint)[k]\n /* A follower has no limits of its own: its range is its leaders', not a turn without end. */\n const endless = record?.type === 'revolute' && record.lowerLimit === undefined && record.upperLimit === undefined && !record.mimic\n const vector = jointAxisVectorOf(record?.axis)\n const one = record?.travel && 'source' in record.travel ? record.travel : undefined\n const travel = one?.source && 'part' in one.source ? { part: one.source.part, axis: one.source.axis, ...(one.plus ? { plus: one.plus } : {}) } : undefined\n const said = { ...(vector ? { vector } : {}), ...(record?.mimic ? { follows: figureMimicTermsOf(record.mimic)! } : {}), ...(travel ? { travel } : {}) }\n /*\n An axis after the first is said as its record writes it -- the joint frame's axis, the control by its id -- the frame\n the form edits it in (ADR-0159). The first is read from its node, `<part>.motion`, as before.\n */\n if (k > 0) {\n if (!record) return undefined\n const input = m.inputs.find(i => i.id === motionStateIdOf(record) && i.role === 'state')\n return {\n kind: endless ? 'continuous' : record.type === 'revolute' ? 'turn' : 'slide',\n axis: jointAxisToken(record.axis) ?? '?',\n ...(record.mimic || !input ? {} : { control: { id: input.id, unit: input.unit, min: input.min, max: input.max } }),\n ...said\n }\n }\n const node = m.nodes.find(n => n.id === `${part}.motion`)\n if (!node) return undefined\n const kind = endless ? 'continuous' : node.op === 'axis-turn@1' ? 'turn' : 'slide'\n const unit = node.args.slice(0, 3).map(ref => m.constants.find(c => c.id === ref)?.value)\n const axis = AXES[unit.findIndex(v => v !== undefined && v !== 0)] ?? '?'\n /* The quantity is the fourth argument, a state input directly or through the nodes that scale it. */\n const quantity = node.args[3]\n const seen = new Set<string>()\n const control = (ref?: string): Motion['control'] => {\n if (!ref || seen.has(ref)) return undefined\n seen.add(ref)\n const input = m.inputs.find(i => i.id === ref && i.role === 'state')\n if (input) return { id: input.id, unit: input.unit, min: input.min, max: input.max }\n const writer = m.nodes.find(n => Object.values(n.outputs).includes(ref))\n for (const arg of writer?.args ?? []) {\n const found = control(arg)\n if (found) return found\n }\n return undefined\n }\n return { kind, axis, control: control(quantity), ...said }\n}\n\n/** What the motion form holds: how the part moves, and either its own control or the joint it moves with. */\nexport interface MotionForm {\n kind: 'slide' | 'turn' | 'continuous'\n axis: Axis\n /** An axis that is a vector (ADR-0107): said, not chosen here, and written back unchanged. */\n axisVector?: JointAxisVector\n id: string\n min: number\n max: number\n /** The joint this one moves with; empty for a joint with its own control. */\n follow: string\n multiplier: number\n offset: number\n /**\n * A slide whose distance follows a part's length (figure-model `travel`): `<part>:<axis>`, empty for a distance in\n * millimetres. The control is then the share of that length, 0..1, and the stroke grows when the part does.\n */\n travel?: string\n travelPlus?: number\n /**\n * Kept as they are and not edited here: a follower of several leaders (`{ sum, offset }`, the offset still in\n * `offset`) and a stroke that is a sum of lengths. The form says them and writes them back unchanged, so saving\n * a range or an axis does not turn a follower into a joint of its own or drop its stroke.\n */\n followSum?: Array<{ joint: string; multiplier: number }>\n travelSum?: Extract<NonNullable<FigureJointMotion['travel']>, { sum: unknown }>\n}\n\n/**\n * The motion form filled from a joint as it is, so a motion can be changed where it is -- its range, the length it\n * travels by, what it follows -- rather than taken away and made again. Taking it away is refused while another joint\n * follows it, which left a leader's stroke fixed for good (the telescopic conveyor, 2026-09-25). The form is the\n * joint's axis `k` (ADR-0159), the first unless said; the other axes are kept as they are when it is written\n * (`motionJoint`). An axis past the last is a new one: a turn about the first of X, Y, Z the joint's axes do not use.\n */\nexport function motionFormOf(joint: FigureJoint, k = 0): MotionForm {\n const axes = figureMotionsOf(joint)\n const a = axes[k]\n if (!a && k > 0) {\n const used = new Set(axes.map(x => jointAxisToken(x.axis)))\n return { kind: 'turn', axis: AXES.find(x => !used.has(x)) ?? 'x', id: '', min: -90, max: 90, follow: '', multiplier: 1, offset: 0, travel: '', travelPlus: 0 }\n }\n const kind: MotionForm['kind'] = a?.type === 'prismatic' ? 'slide' : a?.lowerLimit === undefined && a?.upperLimit === undefined && !a?.mimic ? 'continuous' : 'turn'\n const one = a?.travel && 'source' in a.travel ? a.travel : undefined\n const travel = one?.source && 'part' in one.source ? `${one.source.part}:${one.source.axis}` : ''\n const travelSum = a?.travel && 'sum' in a.travel ? a.travel : undefined\n const terms = figureMimicTermsOf(a?.mimic)\n const single = terms?.sum.length === 1 ? terms.sum[0] : undefined\n const axisVector = jointAxisVectorOf(a?.axis)\n return {\n kind,\n axis: jointAxisToken(a?.axis) ?? 'x',\n ...(axisVector ? { axisVector } : {}),\n /* An axis with no state record is driven by the input named after it (figure-model `motionStateIdOf`): keep that name, so an edit does not rename the control a board or a controller writes to. */\n id: a?.state?.id ?? (a && !a.mimic ? a.id : ''),\n min: travel || travelSum ? 0 : (a?.lowerLimit ?? (kind === 'slide' ? 0 : -90)),\n max: travel || travelSum ? 500 : (a?.upperLimit ?? (kind === 'slide' ? 500 : 90)),\n follow: single?.joint ?? '',\n multiplier: single?.multiplier ?? 1,\n offset: terms?.offset ?? 0,\n travel,\n travelPlus: one?.plus ?? 0,\n ...(terms && !single ? { followSum: terms.sum } : {}),\n ...(travelSum ? { travelSum } : {})\n }\n}\n\n/**\n * The axes a part's joint can move with (URDF's mimic): one of another part's that moves the same way — a slide follows\n * a slide, a turn a turn — and has a control of its own, since a follower follows the axis that is driven (ADR-0159).\n */\nexport function leadersFor(asset: FigureAsset, part: string, kind: MotionForm['kind'], self?: string): Array<FigureNamedMotion & { part: string }> {\n /* Another axis of the same joint may lead (a shoulder's second axis following its first); never the axis itself. */\n return figureAxesOf(asset.joints)\n .filter(({ joint, motion }) => (self === undefined ? joint.body1.part !== part : motion.id !== self) && !motion.mimic && (motion.type === 'prismatic') === (kind === 'slide'))\n .map(({ joint, motion }) => ({ ...motion, part: joint.body1.part }))\n}\n\n/**\n * The joint record the motion form writes for a part fastened by `joint`. A joint of its own gets its limits (none for\n * a turn without end, as in USD) and a control; a follower gets the leader, the multiplier and the offset, and no\n * control or limits of its own — its range is the leader's times the multiplier.\n */\nexport function motionJoint(joint: FigureJoint, m: MotionForm, part: string, k = 0): FigureJoint {\n /*\n Where it is fastened -- its row and its frame's own words too -- is the kernel's to keep (`figureJointWithMotion`,\n ADR-0140 D6). The form writes axis `k` under the name it had, or adds it past the last; the others stay as they are\n (ADR-0159).\n */\n const was = joint.motion?.[k]\n const moving = {\n ...(was?.id !== undefined ? { id: was.id } : {}),\n type: m.kind === 'slide' ? ('prismatic' as const) : ('revolute' as const),\n axis: (m.axisVector ?? m.axis.toUpperCase()) as FigureJointMotion['axis'],\n ...(was?.through ? { through: was.through } : {})\n }\n const axes = joint.motion ?? []\n const given = (motion: Omit<FigureJointMotion, 'type' | 'axis'>) => figureJointWithMotion(joint, [...axes.slice(0, k), { ...moving, ...motion }, ...axes.slice(k + 1)])\n const control = m.id || controlIdFor(part, m.kind, k)\n if (m.follow) return given({ mimic: { motion: m.follow, multiplier: m.multiplier, ...(m.offset ? { offset: m.offset } : {}) } })\n if (m.followSum) return given({ mimic: { sum: m.followSum.map(t => ({ motion: t.joint, multiplier: t.multiplier })), ...(m.offset ? { offset: m.offset } : {}) } })\n if (m.kind === 'slide' && m.travelSum && !m.travel) return given({ travel: m.travelSum, state: { id: control } })\n if (m.kind === 'slide' && m.travel) {\n const [of, axis] = m.travel.split(':')\n return given({ travel: { source: { of: 'part', part: of!, axis: axis as Axis }, ...(m.travelPlus ? { plus: m.travelPlus } : {}) }, state: { id: control } })\n }\n return given({ ...(m.kind === 'continuous' ? {} : { lowerLimit: m.min, upperLimit: m.max }), state: { id: control } })\n}\n\n/** The control an axis gets when the author names none: `<part>-<kind>`, and `<part>-<kind>-<n>` for the n-th axis. */\nexport function controlIdFor(part: string, kind: MotionForm['kind'], k: number): string {\n return k === 0 ? `${part}-${kind}` : `${part}-${kind}-${k + 1}`\n}\n\n/**\n * The joint without its axis `k`. The axes after it keep the names they went by: one named by its place\n * (`<joint>.<k>`, figure-model `motionIdOf`) is given that name before it moves up, so its control is not renamed under\n * a board that writes to it.\n */\nexport function withoutAxis(joint: FigureJoint, k: number): FigureJoint {\n const axes = joint.motion ?? []\n return figureJointWithMotion(joint, [...axes.slice(0, k), ...axes.slice(k + 1).map((a, i) => (a.id !== undefined ? a : { ...a, id: motionIdOf(joint, k + 1 + i) }))])\n}\n\n/**\n * Why the motion form cannot be saved as it stands, as the kernel would refuse it: a follower's multiplier that is not\n * a number or is 0, or a range whose most is not above its least. A range need not hold 0 -- the control starts at the\n * nearest end (a lift that rests at 200 mm).\n */\nexport function motionFormRefusalOf(m: MotionForm, follow: string): 'multiplier' | 'range' | undefined {\n if (m.followSum) return undefined\n if (follow) return Number.isFinite(m.multiplier) && m.multiplier !== 0 ? undefined : 'multiplier'\n if (m.kind === 'continuous' || (m.kind === 'slide' && (m.travel || m.travelSum))) return undefined\n return Number.isFinite(m.min) && Number.isFinite(m.max) && m.max > m.min ? undefined : 'range'\n}\n\n/** The select's value for what a dimension follows now. */\n/**\n * What a measure that is not its own follows, in the words of the choice that set it -- 「도형 X 크기에 비례」, 「bed의 X」 --\n * where the row once said only 「다른 규칙에 연결됨」 (user 2026-10-16: which rule?).\n */\nexport function followWordsOf(follow: Follow, say: (key: string, params?: Record<string, string>) => string): string {\n switch (follow.of) {\n case 'own':\n return say('figure.label.follows-nothing')\n case 'instance':\n return say(follow.times === 1 ? 'figure.label.follows-instance' : 'figure.label.follows-instance-share', { axis: follow.axis.toUpperCase() })\n case 'part':\n return say('figure.label.follows-part-axis', { part: follow.part, axis: follow.axis.toUpperCase() })\n case 'input':\n return follow.input\n case 'expression':\n return say('figure.label.follows-expression')\n }\n}\n\nexport function choiceOf(follow: Follow): string {\n switch (follow.of) {\n case 'own':\n return 'own'\n case 'instance':\n return follow.times === 1 ? `instance:${follow.axis}` : `share:${follow.axis}`\n case 'part':\n return `part:${follow.part}:${follow.axis}`\n case 'input':\n return `input:${follow.input}`\n case 'expression':\n return 'expression'\n }\n}\n\n/**\n * The faces a place can sit on for this part: its flat faces, but not a plane that only touches a curved side along a\n * line (a cylinder's side, Q3) -- nothing is held on a line. A sphere has none.\n */\nexport function placeFacesOf(asset: FigureAsset, part: string): FigureFace[] {\n const shape = modelOf(asset).nodes.find(n => n.id === `${part}.shape`)\n const faces = (shape && figureShapeFaces(shape as never)) ?? {}\n return inScreenOrder(Object.entries(faces).filter(([, f]) => !(f as { contact?: string }).contact).map(([name]) => name)) as FigureFace[]\n}\n\n/** The places things are held that sit on this part. */\nexport function placesOn(asset: FigureAsset, part: string): FigureBindingPlace[] {\n return figureBindingsOf(asset).filter(one => one.part === part)\n}\n\n/** An id for a new place on this part, not yet taken: `<part>-<role>`, then `-2`, `-3`. */\nexport function placeIdFor(asset: FigureAsset, part: string, role: 'seat' | 'grip'): string {\n const taken = new Set(asset.document.capabilities.bindings.map(b => b.id))\n const base = `${part}-${role}`\n if (!taken.has(base)) return base\n let n = 2\n while (taken.has(`${base}-${n}`)) n++\n return `${base}-${n}`\n}\n\n/**\n * Whether a board will hand this figure anything: a place is a slot only on a figure that declares it holds things\n * (`Capacity`, or `FlowNode`, which includes it). Without it the places are declared and nothing arrives.\n */\nexport const holdsThings = (asset: FigureAsset) => (asset.document.capabilities.names ?? []).some(n => n === 'Capacity' || n === 'FlowNode')\n\n/** What `accepts` a person typed: names split on commas, trimmed, blanks and repeats dropped. */\nexport const acceptsOf = (typed: string) => [...new Set(typed.split(',').map(one => one.trim()).filter(Boolean))]\n\n/**\n * The sizes a board may give this figure, per axis: the ends its author narrowed, and the rest as far as its parts\n * allow, computed by figure-model (`figureInstanceSizeRangeOf`, ADR-0087 decision 6) -- the screen does not measure\n * on its own. Nothing when no size is declared.\n */\nexport function instanceRangeOf(asset: FigureAsset): Record<Axis, FigureInstanceSizeRange> | undefined {\n const range = figureInstanceSizeRangeOf(asset)\n return AXES.every(axis => range[axis]) ? (range as Record<Axis, FigureInstanceSizeRange>) : undefined\n}\n\n/**\n * The size to declare for a figure that has none yet: its parts' extent now, the size it is authored at. Undefined when\n * the figure already has a size or has nothing to measure. Without a declared size a board cannot resize the figure,\n * and no part is offered to follow its size -- every figure made in the modeller was left there (user, 2026-09-25).\n */\nexport function instanceSizeToDeclare(asset: FigureAsset): { at: Record<Axis, number> } | undefined {\n if (instanceRangeOf(asset) || !asset.appearance.length) return undefined\n /* The parts as they rest -- not the room their joints swing them through, which declared a door 8208 mm every way. */\n const at = figurePartsExtentOf(asset) as Record<Axis, number>\n if (AXES.some(axis => !(at[axis] > 0))) return undefined\n return { at }\n}\n\n/**\n * The ends the author narrowed, with one end typed or cleared: a number narrows that end, an empty field opens it\n * again to what the parts allow. Whether the figure holds there is the command's to say.\n */\nexport function rangeWith(\n range: Record<Axis, FigureInstanceSizeRange>,\n axis: Axis,\n bound: 'min' | 'max',\n value: number\n): Partial<Record<Axis, { min?: number; max?: number }>> {\n const out: Partial<Record<Axis, { min?: number; max?: number }>> = {}\n for (const a of AXES) {\n const ends: { min?: number; max?: number } = {}\n for (const b of ['min', 'max'] as const) {\n const typed = a === axis && b === bound\n if (typed ? Number.isFinite(value) : range[a].narrowed[b]) ends[b] = typed ? value : range[a][b]\n }\n if (Object.keys(ends).length) out[a] = ends\n }\n return out\n}\n\n/**\n * For a figure that grows by one ratio: how many of its lengths would follow the ratio, and which it leaves with their\n * own number (not those that follow another length -- they grow with it). Nothing for a figure of another sizing.\n */\nexport function proportionToFollow(asset: FigureAsset): { count: number; kept: string[] } | undefined {\n if (asset.sizing !== 'uniform') return undefined\n try {\n const plan = proposeFigureProportion(asset)\n return { count: plan.dimensions.length + plan.lengths.length, kept: plan.skipped.filter(s => !s.follows).map(s => s.what) }\n } catch {\n return undefined\n }\n}\n\n/** A value of the figure as it stands, by its graph reference. */\nexport function valueNow(revision: FigureRevision, ref: string | undefined): number | undefined {\n if (!ref) return undefined\n try {\n const value = graphValuesOf(revision)[ref]\n return typeof value === 'number' && Number.isFinite(value) ? value : undefined\n } catch {\n return undefined\n }\n}\n\n/**\n * Whether the figure is a mechanism -- a part turns about a joint. Such a figure should grow by one ratio (chief\n * architect's ruling 2026-09-24); the modeller proposes it, the author declares it.\n */\nexport function turnsAboutAJoint(asset: FigureAsset): boolean {\n return modelOf(asset).nodes.some(n => n.op === 'axis-turn@1')\n}\n\n/** The joint made still: its fastening, its place and its row kept, its motion gone (the kernel's `figureJointAsFixed`, ADR-0140 D6). */\nexport const fixedJointOf = figureJointAsFixed\n"]}
1
+ {"version":3,"file":"links.js","sourceRoot":"","sources":["../../client/modeller/links.ts"],"names":[],"mappings":"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","sourcesContent":["import { FIGURE_FACES, figureShapeFaces, figurePartsExtentOf, compileFigureAsset, figureFollowOf, proposeFigureProportion, figureAttachmentsOf, figureBindingsOf, figureInstanceSizeRangeOf, figureFollowableAxesOf, figureShapeProviderOf, figureMimicTermsOf, figureFastenKeptPlaceOf, figureFastenAxesOf, figureJointAsFixed, figureJointWithMotion, figureSurfaceOf, figureAxesOf, figureMotionsOf, motionIdOf, motionStateIdOf } from '@hatiolab/figure-model'\nimport type { FigureFollow, FigureInstanceSizeRange } from '@hatiolab/figure-model'\nimport type { FigureAsset, FigureAuthoringAction, FigureBindingPlace, FigureDimensionSource, FigureFace, FigureFacing, FigureJoint, FigureJointMotion, FigureNamedMotion, FigureSurfacePlace } from '@hatiolab/figure-model'\nimport { startingShapeKindOf } from './starting-shape.js'\nimport { boxOf } from './align.js'\nimport { graphValuesOf, type FigureRevision } from './revision.js'\nimport { jointAxisToken, jointAxisVectorOf, type JointAxisVector } from './joint-axis.js'\n\n/*\n * What a part is tied to — the readers behind the parts' size response, fastening and motion sections. Kept apart from the element so they can be tested without a browser.\n */\n\nexport type Axis = 'x' | 'y' | 'z'\nexport const AXES: readonly Axis[] = ['x', 'y', 'z']\n\ninterface Node {\n id: string\n op: string\n args: string[]\n outputs: Record<string, string>\n}\nconst modelOf = (asset: FigureAsset) =>\n asset.document.model as unknown as { nodes: Node[]; inputs: Array<{ id: string; role?: string; unit?: string; min?: number; max?: number }>; constants: Array<{ id: string; value: number }> }\n\n/** What one dimension of a part is worked out from (figure-model's `FigureFollow`). */\nexport type Follow = FigureFollow\n\n/**\n * `link-dimension` routes a part's dimension through `<part>.dimension.<axis>` and points its first argument at the\n * source, directly or through the nodes that scale it. Walking back through those nodes finds the source: the\n * instance size (`size.<axis>`), another part's dimension (`<part>.dimension.<axis>.value`) or a declared input.\n */\n/** What one measure of a part is worked out from, read back from the graph (figure-model's reader, one copy). */\nexport function followOf(asset: FigureAsset, part: string, axis: Axis): Follow {\n return figureFollowOf(asset, part, axis)\n}\n\n/**\n * The parts whose size follows the figure's size on some axis, in the model's order: the ones that change when the\n * figure is resized on a drawing. Read by figure-model's own follow (`figureFollowOf`), not worked out again here.\n */\nexport function sizeFollowersOf(asset: FigureAsset): string[] {\n const parts = (modelOf(asset).nodes as Array<{ id: string; op: string }>).filter(n => n.op === 'place@1').map(n => n.id)\n return parts.filter(part =>\n AXES.some(axis => {\n try {\n return figureFollowOf(asset, part, axis).of === 'instance'\n } catch {\n return false\n }\n })\n )\n}\n\n/** Whether the asset declares an instance size on an axis — only then can a dimension follow it. */\nexport const hasInstanceSize = (asset: FigureAsset, axis: Axis) => modelOf(asset).inputs.some(i => i.id === `size.${axis}` && i.role === 'design')\n\n/** The part this one is fastened to, or `null`. The mounting plane counts as fastened (the model names no part). */\nexport function fastenedTo(asset: FigureAsset, part: string): string | null {\n return figureAttachmentsOf(asset)[part] ?? null\n}\n\n/**\n * What holds a part: the part it is fastened to, the plane the figure is mounted on, or nothing. The joint record says\n * it; a part standing on the plane had read as fastened to nothing, so the form offered no way to move it and sent\n * no replace -- the fastening was refused as already made (the door's post, 2026-09-25).\n */\nexport function heldBy(asset: FigureAsset, part: string): { part: string } | { plane: true } | null {\n const record = asset.joints?.find(j => j.body1.part === part)\n if (record) return 'plane' in record.body0 ? { plane: true } : { part: record.body0.part }\n const to = fastenedTo(asset, part)\n return to ? { part: to } : null\n}\n\n/** The word for where a joint's body0 end sits: its face's, or the part's origin for an end placed by it (ADR-0107 decision 4). */\nexport const endPlaceKeyOf = (end: object) => ('face' in end ? `figure.label.face-${(end as { face: string }).face}` : 'figure.label.joint-origin')\n\n/** Whether a dimension of this part can follow something — box-shaped, whose three sizes are X, Y and Z. */\nexport function canFollow(asset: FigureAsset, part: string): boolean {\n return followableAxes(asset, part).length > 0\n}\n\n/**\n * The axes whose size can follow something: figure-model's one list (`figureFollowableAxesOf`), which follow-size and\n * the resize plan ask too -- the screen does not keep a list of its own (designer 2026-09-27).\n */\nexport function followableAxes(asset: FigureAsset, part: string): Axis[] {\n const shape = modelOf(asset).nodes.find(n => n.id === `${part}.shape`)\n return shape ? figureFollowableAxesOf(shape as never) : []\n}\n\n/**\n * The directions \"follow the size, attached\" passes to figure-model (designer 2026-09-27):\n * - `chosen`: what the author ticked, and the ones already following, which stay;\n * - `suggested`: a part the author has not chosen for yet and that follows nothing -- every direction, said as\n * \"all three\" on the button, never as a choice the author made;\n * - `none`: the author set every direction back to fixed, or unticked them all -- nothing is taken for all.\n * `pending` is the author's ticks for this part in this screen, when they have ticked or fixed anything.\n */\nexport function resizeAxesOf(asset: FigureAsset, part: string, pending?: readonly Axis[]): { axes: Axis[]; basis: 'chosen' | 'suggested' | 'none' } {\n const editable = followableAxes(asset, part)\n const following = editable.filter(axis => {\n const now = followOf(asset, part, axis)\n return now.of === 'instance' && now.axis === axis\n })\n if (pending) {\n const axes = editable.filter(axis => pending.includes(axis) || following.includes(axis))\n return { axes, basis: axes.length ? 'chosen' : 'none' }\n }\n if (following.length) return { axes: following, basis: 'chosen' }\n return { axes: editable, basis: editable.length ? 'suggested' : 'none' }\n}\n\n/**\n * Korean particles for a word the sentence is built around: the topic (은/는) and \"and/with\" (과/와), by whether the\n * word's last syllable ends in a consonant. Other languages need none.\n */\nexport function particlesOf(word: string, lang: string): { topic: string; with: string } {\n if (!lang.startsWith('ko')) return { topic: word, with: word }\n const last = word.trim().slice(-1).charCodeAt(0)\n const closed = last >= 0xac00 && last <= 0xd7a3 && (last - 0xac00) % 28 !== 0\n return { topic: word + (closed ? '은' : '는'), with: word + (closed ? '과' : '와') }\n}\n\n/**\n * The selected part at the head of its panel: what it is, and -- only when a measure changes by itself -- what it\n * follows, as a sentence a person reads without knowing the model's words: the model's size, a share of it, another\n * part's measure, a field, a calculation (`figureFollowOf`). A size of its own and a part fastened or not say nothing\n * here; the fastening is drawn in its own section (user 2026-10-01: 「규칙을 따름: 높이 (Y)」 -- \"who would know what that\n * means?\", and \"why say anything when all is as usual?\").\n */\nexport function partSummaryOf(\n asset: FigureAsset,\n part: string,\n say: (key: string, params?: Record<string, string>) => string,\n lang = 'ko'\n): { kind: string; size: string } {\n const shape = modelOf(asset).nodes.find(n => n.id === `${part}.shape`)\n const named = startingShapeKindOf(shape as never)\n const kind = named ? say(`figure.label.primitive-${named}`) : ''\n const editable = followableAxes(asset, part)\n const round = editable.length === 2\n const word = (axis: Axis) => say(round && axis === 'x' ? 'figure.label.measure-diameter' : `figure.label.measure-${axis}`)\n const pct = (times: number) => String(Math.round(times * 1000) / 10)\n /* One sentence per way of following; the measures that follow the same way are said together. */\n const lines = new Map<string, { key: string; params: Record<string, string>; axes: Axis[] }>()\n for (const axis of editable) {\n const f = followOf(asset, part, axis)\n let key: string\n let params: Record<string, string> = {}\n if (f.of === 'own') continue\n if (f.of === 'instance') {\n key = f.times === 1 ? 'figure.text.summary-size-follows' : 'figure.text.summary-size-share'\n /* A measure following the figure's own size on its own axis says no measure word, so the axes that do so are one\n sentence -- 「너비 · 높이 · 깊이는 피규어 크기를 따라 바뀝니다」, not three (user 2026-10-16). */\n params = f.times === 1 && f.axis === axis && !f.plus ? {} : { pct: pct(f.times), whole: say(`figure.label.measure-${f.axis}`) }\n if (f.plus) (key = key + '-plus'), (params.plus = String(f.plus))\n } else if (f.of === 'part') {\n const other = say(`figure.label.measure-${f.axis}`)\n key = (f.times ?? 1) === 1 ? 'figure.text.summary-size-part' : 'figure.text.summary-size-part-share'\n params = { other: f.part, measure: particlesOf(other, lang).with, measureWord: other, pct: pct(f.times ?? 1) }\n if (f.plus) (key = key + '-plus'), (params.plus = String(f.plus))\n } else if (f.of === 'input') {\n key = 'figure.text.summary-size-input'\n params = { field: fieldWordsOf(f.input, k => say(k)) }\n } else key = 'figure.text.summary-size-worked-out'\n const id = key + JSON.stringify(params)\n lines.set(id, { key, params, axes: [...(lines.get(id)?.axes ?? []), axis] })\n }\n /* Nothing to say when the size is its own: only a measure that changes by itself is news (user 2026-10-01). */\n const size = [...lines.values()].map(l => say(l.key, { ...l.params, axes: particlesOf(l.axes.map(word).join(' · '), lang).topic })).join(' ')\n return { kind, size }\n}\n\n/**\n * A part's own field in the words its row uses -- 「위치 Y」, 「크기 X」, and the turn as one 「회전」 -- so a field the plan\n * replaces, or one only the room reads, is named as the author knows it, not by its id.\n */\nexport function fieldWordsOf(id: string, say: (key: string) => string): string {\n const own = /\\.(position|rotation|size)\\.([xyz])$/.exec(id)\n if (!own) return id\n return own[1] === 'rotation' ? say('figure.label.group-rotation') : `${say(`figure.label.group-${own[1]}`)} ${own[2]!.toUpperCase()}`\n}\n\n/** What a part's own measure on an axis is now (a box's side, a cylinder's radius or length), at the design as it stands. */\nexport function dimensionNow(revision: FigureRevision, part: string, axis: Axis): number | undefined {\n const m = modelOf(revision.asset)\n /* The argument the shape names for this axis (figure-model's provider), not its place among the arguments. */\n const shape = m.nodes.find(n => n.id === `${part}.shape`)\n const edit = shape && figureShapeProviderOf(shape as never)?.edit[axis]\n const ref = edit && !('refused' in edit) ? shape!.args[edit.arg] : undefined\n if (!ref) return undefined\n try {\n const value = graphValuesOf(revision)[ref]\n return typeof value === 'number' && Number.isFinite(value) ? value : undefined\n } catch {\n return undefined\n }\n}\n\n/**\n * The command a dimension's rule chosen in the size form sends (`choice` as `choiceOf` writes it), or nothing to send.\n * The measure as it stands decides the numbers: a dimension stops following at it, and a share is taken of it, so\n * neither choice changes the part's size. A share needs the figure's size on that axis.\n */\nexport function followCommandOf(revision: FigureRevision, part: string, axis: Axis, choice: string, now: Follow): FigureAuthoringAction | undefined {\n const following = now.of !== 'own'\n /* The part's own measure on the axis now (a cylinder's radius, not its width), else its extent as drawn. */\n const current = dimensionNow(revision, part, axis) ?? boxOf(revision, part)?.dims[AXES.indexOf(axis)] ?? 100\n if (choice === 'own') return following ? { kind: 'unlink-dimension', part, axis, mm: Math.max(1, Math.round(current)) } : undefined\n const [of, a, b] = choice.split(':')\n if (of === 'share') {\n const size = revision.asset.designInputs[`size.${a}`]\n if (!size) return undefined\n const times = Math.round((current / size) * 1e6) / 1e6\n return { kind: 'link-dimension', part, axis, source: { of: 'instance', axis: a as Axis }, times, replace: following }\n }\n const source: FigureDimensionSource = of === 'instance' ? { of: 'instance', axis: a as Axis } : { of: 'part', part: a!, axis: b as Axis }\n return { kind: 'link-dimension', part, axis, source, replace: following }\n}\n\n/**\n * How long a part is along one axis now, as it is drawn: the shape's own measure through figure-model's provider (a\n * cylinder's width is twice its radius), read after any rule it follows -- so a linked measure still says its size.\n */\nexport function measureNow(revision: FigureRevision, part: string, axis: Axis): number | undefined {\n const shape = modelOf(revision.asset).nodes.find(n => n.id === `${part}.shape`)\n const edit = shape && figureShapeProviderOf(shape as never)?.edit[axis]\n if (!shape || !edit || 'refused' in edit) return undefined\n try {\n const value = graphValuesOf(revision)[shape.args[edit.arg]!]\n return typeof value === 'number' && Number.isFinite(value) ? value * edit.k : undefined\n } catch {\n return undefined\n }\n}\n\n/**\n * The flat faces a part's shape declares, by name -- figure-model's shape definitions are the one place they are\n * written (a portal's opening sides as well as its outer faces). A sphere has none.\n */\nexport function facesOf(asset: FigureAsset, part: string): string[] {\n const shape = modelOf(asset).nodes.find(n => n.id === `${part}.shape`)\n const faces = (shape && figureShapeFaces(shape as never)) ?? {}\n /* A cylinder's curved side is no face: a part is fastened to a point on it (ADR-0140 3.9, `surfaceOf`). */\n return inScreenOrder(Object.keys(faces).filter(f => faces[f]!.contact !== 'line'))\n}\n\n/** The curved surface a part offers to be fastened to at a point: a cylinder's side or a sphere's round (ADR-0140 3.9). */\nexport function surfaceOf(asset: FigureAsset, part: string): { form: 'around' | 'toward'; axis: Axis } | undefined {\n return figureSurfaceOf(asset, part)\n}\n\n/** Faces in the order the screen lists them: the six outer ones left to front, then the rest as the shape gives them. */\nconst SCREEN_ORDER = ['left', 'right', 'bottom', 'top', 'back', 'front']\nfunction inScreenOrder(names: string[]): string[] {\n const rank = (n: string) => (SCREEN_ORDER.includes(n) ? SCREEN_ORDER.indexOf(n) : SCREEN_ORDER.length)\n return names.map((n, i) => [n, i] as const).sort((a, b) => rank(a[0]) - rank(b[0]) || a[1] - b[1]).map(([n]) => n)\n}\n\n/** The axis a face of a part faces along, from the same definitions. */\nexport function faceAxisOf(asset: FigureAsset, part: string, face: string): Axis | undefined {\n const shape = modelOf(asset).nodes.find(n => n.id === `${part}.shape`)\n return (shape && figureShapeFaces(shape as never)?.[face]?.axis) as Axis | undefined\n}\n\n/** Whether `attach` can take this part: any part whose shape has a flat face. */\nexport function canFasten(asset: FigureAsset, part: string): boolean {\n return facesOf(asset, part).length > 0 || !!surfaceOf(asset, part)\n}\n\nconst OUTER: Record<Axis, [string, string]> = { x: ['left', 'right'], y: ['bottom', 'top'], z: ['back', 'front'] }\n\n/**\n * The axes a part can be made a row along (r3 §8, figure-model `make-repeat`): across the face it is fastened by, when\n * it is fastened fixed to another part and holds nothing. None for a part that is loose, moves, stands on the floor or\n * already repeats -- the command would refuse those, so they are not offered.\n */\nexport function rowAxesOf(asset: FigureAsset, part: string): Axis[] {\n const joints = asset.joints ?? []\n const j = joints.find(o => o.body1.part === part)\n /* A part that moves may be a row too: every copy on the one control, from its own place (designer 2026-09-27). */\n if (!j || j.repeat || !('part' in j.body0)) return []\n if (joints.some(o => 'part' in o.body0 && o.body0.part === part)) return []\n /* Placed by an origin: no face to lay the row across, and the kernel refuses it. */\n if (!('face' in j.body0) || 'at' in j.body1) return []\n return figureFastenAxesOf(asset, { part: j.body0.part, face: j.body0.face })\n}\n\n/**\n * Why a part cannot be made into a row here, in the terms `rowAxesOf` refuses it: said, not hidden (ADR-0097 §5.5).\n * Nothing when it can, or when it already is a row (that row is shown where it stands).\n */\nexport function rowBlockOf(asset: FigureAsset, part: string): 'unfastened' | 'on-plane' | 'holds-parts' | 'at-origin' | 'on-surface' | undefined {\n const joints = asset.joints ?? []\n const j = joints.find(o => o.body1.part === part)\n if (!j) return 'unfastened'\n if (j.repeat) return undefined\n if (!('part' in j.body0)) return 'on-plane'\n if (joints.some(o => 'part' in o.body0 && o.body0.part === part)) return 'holds-parts'\n /* On a point of a curved surface a row has no face to run across (ADR-0140 3.9): the kernel refuses it. */\n if ('surface' in j.body0) return 'on-surface'\n if (!('face' in j.body0) || 'at' in j.body1) return 'at-origin'\n return undefined\n}\n\n/** The row a part is made into, as its fastening's record keeps it. */\nexport const rowOf = (asset: FigureAsset, part: string) => asset.joints?.find(o => o.body1.part === part)?.repeat\n\n/** Where a part sits across the face it is fastened to, on one axis: centred, level with an edge, or a distance off centre. */\n/** `share`: the distance as a share of the figure's size on that axis, so it keeps its place when the figure is resized. */\n/** `input`: the place across the face follows one of the part's position fields -- as \"follow size, attached\" keeps it (ADR-0097). */\nexport type Alignment = 'centre' | 'min' | 'max' | 'mm' | 'share' | 'input'\n\n/**\n * The axes across the face a part is fastened to — the two a fastening does not set by itself. Edges to line up with\n * are offered where both parts have their two outer faces on that axis; the plane the figure is mounted on has none,\n * so on it (X and Z) only centred or a distance is offered.\n */\n/**\n * The mounting plane of this figure, by its placement (ADR-0093): the floor or the ceiling is Y = 0 and a part stands\n * on it or hangs below it; a wall is Z = 0 and a part stands out of it (ADR-0140 3.11).\n */\nexport function mountingPlaneOf(asset: FigureAsset): { normal: Axis; facings: FigureFacing[] } {\n return asset.placement === 'wall' ? { normal: 'z', facings: ['meet'] } : { normal: 'y', facings: ['meet', 'flush'] }\n}\n\nexport function alignAxesOf(asset: FigureAsset, target: { part: string; face: string } | 'plane'): { axis: Axis; edges: boolean }[] {\n /* The plane has no edges, but a figure that declares its size has sides on it (figure-model 0.1.64). */\n if (target === 'plane') return figureFastenAxesOf(asset, 'plane').map(axis => ({ axis, edges: hasInstanceSize(asset, axis) }))\n /* The part is lined up by its real extent in the pose it has (ADR-0140 3.4): the target's two sides are what it needs. */\n const theirs = new Set(facesOf(asset, target.part))\n return figureFastenAxesOf(asset, target).map(axis => ({ axis, edges: OUTER[axis].every(f => theirs.has(f)) }))\n}\n\n/**\n * The axes across the face the fastening form asks about in rows: only where the face drawing (`view`, its axes) cannot\n * set the place -- no drawing at all, an axis it does not draw, a place that follows a position field, or one the\n * figure's size may scale.\n */\nexport function alignRowsOf(\n asset: FigureAsset,\n aim: { part: string; face: string } | 'plane',\n view: { axes: readonly Axis[] } | undefined,\n alignInput: Partial<Record<Axis, string>> = {}\n): { axis: Axis; edges: boolean }[] {\n return alignAxesOf(asset, aim).filter(({ axis }) => !view || !view.axes.includes(axis) || !!alignInput[axis] || hasInstanceSize(asset, axis))\n}\n\n/** The controls a part's showing can follow: the figure's state inputs, with their range and label. */\nexport function visibilityControlsOf(asset: FigureAsset): Array<{ id: string; unit: string; min: number; max: number; label: string }> {\n const labels = (asset as unknown as { stateInputs?: Record<string, { label?: string }> }).stateInputs ?? {}\n return modelOf(asset)\n .inputs.filter(input => input.role === 'state')\n .map(input => ({ id: input.id, unit: input.unit ?? '', min: input.min ?? 0, max: input.max ?? 1, label: labels[input.id]?.label || input.id }))\n}\n\n/** When the part is drawn (figure-model `set-visibility`): always (null), or while a control is at least a value. */\nexport function shownWhenOf(asset: FigureAsset, part: string): { input: string; atLeast: number } | null {\n const look = asset.appearance.find(one => one.target === part) as { visibility?: string } | undefined\n if (!look?.visibility) return null\n const m = modelOf(asset)\n const node = m.nodes.find(n => n.op === 'at-least@1' && Object.values(n.outputs).includes(look.visibility!))\n const at = node && m.constants.find(c => c.id === node.args[1])\n return node && at ? { input: node.args[0]!, atLeast: at.value } : null\n}\n\n/** Whether `part` hangs from `from`, through any number of fastenings. */\nexport function hangsFrom(asset: FigureAsset, part: string, from: string): boolean {\n const seen = new Set<string>()\n for (let at: string | undefined = part; at && !seen.has(at); ) {\n seen.add(at)\n const j = ((asset.joints ?? []) as FigureJoint[]).find(o => o.body1.part === at)\n at = j && 'part' in j.body0 ? (j.body0 as { part: string }).part : undefined\n if (at === from) return true\n }\n return false\n}\n\n/**\n * The fastening a part has, as the fastening form holds it -- so the form opens on what is there (the target and its\n * face, how it meets it, the gap and where across the face) and a change is a change to that.\n * Opening it on the defaults showed a roller fastened by its centre as fastened by its bottom, and fastening again\n * from there broke its turning in place (walk 1, 2026-09-26). Null for a part fastened to nothing.\n */\nexport function fasteningOf(\n revision: FigureRevision,\n part: string\n): {\n toPlane: boolean\n target: string\n targetFace: string\n facing: FigureFacing\n gap: number\n /** The record's gap when it is worked out (a length that follows something): kept as it is until a number is typed. */\n gapKept?: unknown\n align: Partial<Record<Axis, Alignment>>\n alignMm: Partial<Record<Axis, number>>\n /** Placed by a part's origin (ADR-0107 decision 4): no face to fasten by, and the form does not write it. */\n atOrigin?: true\n /** On a point of the target's curved surface (ADR-0140 3.9), as the record says it. */\n surface?: FigureSurfacePlace\n} | null {\n const record = revision.asset.joints?.find(j => j.body1.part === part)\n if (!record) return null\n const toPlane = 'plane' in record.body0\n const target = 'part' in record.body0 ? record.body0.part : ''\n const surface = 'surface' in record.body0 ? record.body0.surface : undefined\n const targetFace = 'face' in record.body0 ? record.body0.face : 'top'\n const atOrigin = !('plane' in record.body0) && ((!('face' in record.body0) && !surface) || 'at' in record.body1)\n if (surface)\n return {\n toPlane,\n target,\n targetFace,\n facing: record.origin?.facing ?? 'meet',\n gap: typeof record.origin?.gap === 'number' ? record.origin.gap : 0,\n ...(record.origin?.gap !== undefined && typeof record.origin.gap !== 'number' ? { gapKept: record.origin.gap } : {}),\n align: {},\n alignMm: {},\n surface,\n ...(atOrigin ? { atOrigin: true as const } : {})\n }\n /* Where across the face: as the record says it, and where it says nothing, where the part stands now. */\n const kept = placeKeptOf(revision, part, toPlane ? 'plane' : { part: target, face: targetFace })\n for (const [axis, how] of Object.entries(record.origin?.align ?? {}) as Array<[Axis, unknown]>) {\n if (how === 'min' || how === 'max' || how === 'centre') {\n kept.align[axis] = how\n delete kept.alignMm[axis]\n } else if (how && typeof how === 'object' && typeof (how as { mm?: unknown }).mm === 'number') {\n kept.align[axis] = 'mm'\n kept.alignMm[axis] = (how as { mm: number }).mm\n } else if ((how as { mm?: { from?: { of?: string; input?: string } } })?.mm?.from?.of === 'input') {\n /* Following a position field: read as that, so fastening again keeps the field and does not fix its number. */\n kept.align[axis] = 'input'\n kept.alignInput[axis] = (how as { mm: { from: { input: string } } }).mm.from.input\n delete kept.alignMm[axis]\n }\n }\n const gap = record.origin?.gap\n return {\n toPlane,\n target,\n targetFace,\n facing: record.origin?.facing ?? 'meet',\n gap: typeof gap === 'number' ? gap : 0,\n ...(gap !== undefined && typeof gap !== 'number' ? { gapKept: gap } : {}),\n ...kept,\n ...(atOrigin ? { atOrigin: true as const } : {})\n }\n}\n\n/**\n * The `gap` an attach command writes from the form: a worked-out gap as it was read, else the number, else none. Read as\n * a number, a gap that follows the legs or the instance height became 0, and opening the form on the part dropped it\n * to the plane (2026-10-13, the robot dog and the forklift).\n */\nexport function fastenGapOf(form: { gap: number; gapKept?: unknown }): { gap?: unknown } {\n if (form.gapKept !== undefined) return { gap: form.gapKept }\n return form.gap ? { gap: form.gap } : {}\n}\n\n/**\n * The alignment that keeps the part where it stands when it is fastened, as the form holds it: the kernel's place\n * (`figureFastenKeptPlaceOf`, ADR-0140 3.7), a distance on each axis it is off the target's centre.\n */\nexport function placeKeptOf(\n revision: FigureRevision,\n part: string,\n target: { part: string; face: string } | 'plane'\n): { align: Partial<Record<Axis, Alignment>>; alignMm: Partial<Record<Axis, number>>; alignInput: Partial<Record<Axis, string>> } {\n const alignMm = figureFastenKeptPlaceOf(revision.asset, part, target, { ...revision.inputs })\n return { align: Object.fromEntries(Object.keys(alignMm).map(axis => [axis, 'mm'])) as Partial<Record<Axis, Alignment>>, alignMm, alignInput: {} }\n}\n\n/** The `align` of an attach command from the form's choices: only the axes across that face, and centred ones left out. */\nexport function alignOf(\n asset: FigureAsset,\n target: { part: string; face: string } | 'plane',\n how: Partial<Record<Axis, Alignment>>,\n mm: Partial<Record<Axis, number>>,\n inputs: Partial<Record<Axis, string>> = {}\n) {\n const align: Partial<Record<Axis, 'min' | 'max' | { mm: number | { from: { of: 'instance'; axis: Axis }; times: number } | { from: { of: 'input'; input: string } } }>> = {}\n for (const { axis, edges } of alignAxesOf(asset, target)) {\n const one = how[axis] ?? 'centre'\n const size = asset.designInputs[`size.${axis}`]\n if (one === 'share' && mm[axis] && hasInstanceSize(asset, axis) && size)\n align[axis] = { mm: { from: { of: 'instance', axis }, times: Math.round((mm[axis]! / size) * 1e6) / 1e6 } }\n else if (one === 'mm' && mm[axis]) align[axis] = { mm: mm[axis]! }\n else if ((one === 'min' || one === 'max') && edges) align[axis] = one\n else if (one === 'input' && inputs[axis]) align[axis] = { mm: { from: { of: 'input', input: inputs[axis]! } } }\n }\n return Object.keys(align).length ? align : undefined\n}\n\n/**\n * The axes on which the part's position is worked out from other values rather than being its own number. `fix-position` makes one its own number where it is now.\n */\nexport function positionsWorkedOut(asset: FigureAsset, part: string): Axis[] {\n const m = modelOf(asset)\n const pose = m.nodes.find(n => n.id === `${part}.pose`)\n if (!pose || pose.op !== 'rigid@1' || fastenedTo(asset, part)) return []\n const own = (ref: string) => ref.startsWith(`${part}.`) && m.inputs.some(i => i.id === ref && i.role === 'design')\n const constant = (ref: string) => m.constants.some(c => c.id === ref)\n return AXES.filter((_axis, i) => !own(pose.args[i]!) && !constant(pose.args[i]!))\n}\n\n/**\n * Whether the part's position on an axis is a share of the instance size (`scale-position`): `size.<axis> × share`.\n * Such a position is worked out too, but it already grows with the figure, so it is not offered again.\n */\nexport function positionIsShare(asset: FigureAsset, part: string, axis: Axis): boolean {\n const m = modelOf(asset)\n const ref = m.nodes.find(n => n.id === `${part}.pose`)?.args[AXES.indexOf(axis)]\n const writer = ref ? m.nodes.find(n => Object.values(n.outputs).includes(ref)) : undefined\n return !!writer && writer.op === 'mul@1' && writer.args[0] === `size.${axis}` && m.constants.some(c => c.id === writer.args[1])\n}\n\n/** How a part moves, if it does: slide or turn, along which axis, driven by which control. */\nexport interface Motion {\n kind: 'slide' | 'turn' | 'continuous'\n axis: Axis | '?'\n /** The record's axis when it is a vector, as written (the graph holds it turned into the parent's frame). */\n vector?: JointAxisVector\n control?: { id: string; unit?: string; min?: number; max?: number }\n /** A joint that moves with another (URDF's mimic): the leader's value times `multiplier`, plus `offset`. */\n /** What it follows, as a sum of leaders each with its multiplier, plus an offset (one leader is a sum of one). */\n follows?: { sum: Array<{ joint: string; multiplier: number }>; offset: number }\n /** A slide whose distance is a part's length (plus a difference): the control is its share. */\n travel?: { part: string; axis: string; plus?: number }\n}\n\nexport function motionOf(asset: FigureAsset, part: string, k = 0): Motion | undefined {\n const m = modelOf(asset)\n const joint = asset.joints?.find(j => j.body1.part === part)\n const record = joint && figureMotionsOf(joint)[k]\n /* A follower has no limits of its own: its range is its leaders', not a turn without end. */\n const endless = record?.type === 'revolute' && record.lowerLimit === undefined && record.upperLimit === undefined && !record.mimic\n const vector = jointAxisVectorOf(record?.axis)\n const one = record?.travel && 'source' in record.travel ? record.travel : undefined\n const travel = one?.source && 'part' in one.source ? { part: one.source.part, axis: one.source.axis, ...(one.plus ? { plus: one.plus } : {}) } : undefined\n const said = { ...(vector ? { vector } : {}), ...(record?.mimic ? { follows: figureMimicTermsOf(record.mimic)! } : {}), ...(travel ? { travel } : {}) }\n /*\n An axis after the first is said as its record writes it -- the joint frame's axis, the control by its id -- the frame\n the form edits it in (ADR-0159). The first is read from its node, `<part>.motion`, as before.\n */\n if (k > 0) {\n if (!record) return undefined\n const input = m.inputs.find(i => i.id === motionStateIdOf(record) && i.role === 'state')\n return {\n kind: endless ? 'continuous' : record.type === 'revolute' ? 'turn' : 'slide',\n axis: jointAxisToken(record.axis) ?? '?',\n ...(record.mimic || !input ? {} : { control: { id: input.id, unit: input.unit, min: input.min, max: input.max } }),\n ...said\n }\n }\n const node = m.nodes.find(n => n.id === `${part}.motion`)\n if (!node) return undefined\n const kind = endless ? 'continuous' : node.op === 'axis-turn@1' ? 'turn' : 'slide'\n const unit = node.args.slice(0, 3).map(ref => m.constants.find(c => c.id === ref)?.value)\n const axis = AXES[unit.findIndex(v => v !== undefined && v !== 0)] ?? '?'\n /* The quantity is the fourth argument, a state input directly or through the nodes that scale it. */\n const quantity = node.args[3]\n const seen = new Set<string>()\n const control = (ref?: string): Motion['control'] => {\n if (!ref || seen.has(ref)) return undefined\n seen.add(ref)\n const input = m.inputs.find(i => i.id === ref && i.role === 'state')\n if (input) return { id: input.id, unit: input.unit, min: input.min, max: input.max }\n const writer = m.nodes.find(n => Object.values(n.outputs).includes(ref))\n for (const arg of writer?.args ?? []) {\n const found = control(arg)\n if (found) return found\n }\n return undefined\n }\n return { kind, axis, control: control(quantity), ...said }\n}\n\n/** What the motion form holds: how the part moves, and either its own control or the joint it moves with. */\nexport interface MotionForm {\n kind: 'slide' | 'turn' | 'continuous'\n axis: Axis\n /** An axis that is a vector (ADR-0107): said, not chosen here, and written back unchanged. */\n axisVector?: JointAxisVector\n id: string\n min: number\n max: number\n /** The joint this one moves with; empty for a joint with its own control. */\n follow: string\n multiplier: number\n offset: number\n /**\n * A slide whose distance follows a part's length (figure-model `travel`): `<part>:<axis>`, empty for a distance in\n * millimetres. The control is then the share of that length, 0..1, and the stroke grows when the part does.\n */\n travel?: string\n travelPlus?: number\n /**\n * Kept as they are and not edited here: a follower of several leaders (`{ sum, offset }`, the offset still in\n * `offset`) and a stroke that is a sum of lengths. The form says them and writes them back unchanged, so saving\n * a range or an axis does not turn a follower into a joint of its own or drop its stroke.\n */\n followSum?: Array<{ joint: string; multiplier: number }>\n travelSum?: Extract<NonNullable<FigureJointMotion['travel']>, { sum: unknown }>\n}\n\n/**\n * The motion form filled from a joint as it is, so a motion can be changed where it is -- its range, the length it\n * travels by, what it follows -- rather than taken away and made again. Taking it away is refused while another joint\n * follows it, which left a leader's stroke fixed for good (the telescopic conveyor, 2026-09-25). The form is the\n * joint's axis `k` (ADR-0159), the first unless said; the other axes are kept as they are when it is written\n * (`motionJoint`). An axis past the last is a new one: a turn about the first of X, Y, Z the joint's axes do not use.\n */\nexport function motionFormOf(joint: FigureJoint, k = 0): MotionForm {\n const axes = figureMotionsOf(joint)\n const a = axes[k]\n if (!a && k > 0) {\n const used = new Set(axes.map(x => jointAxisToken(x.axis)))\n return { kind: 'turn', axis: AXES.find(x => !used.has(x)) ?? 'x', id: '', min: -90, max: 90, follow: '', multiplier: 1, offset: 0, travel: '', travelPlus: 0 }\n }\n const kind: MotionForm['kind'] = a?.type === 'prismatic' ? 'slide' : a?.lowerLimit === undefined && a?.upperLimit === undefined && !a?.mimic ? 'continuous' : 'turn'\n const one = a?.travel && 'source' in a.travel ? a.travel : undefined\n const travel = one?.source && 'part' in one.source ? `${one.source.part}:${one.source.axis}` : ''\n const travelSum = a?.travel && 'sum' in a.travel ? a.travel : undefined\n const terms = figureMimicTermsOf(a?.mimic)\n const single = terms?.sum.length === 1 ? terms.sum[0] : undefined\n const axisVector = jointAxisVectorOf(a?.axis)\n return {\n kind,\n axis: jointAxisToken(a?.axis) ?? 'x',\n ...(axisVector ? { axisVector } : {}),\n /* An axis with no state record is driven by the input named after it (figure-model `motionStateIdOf`): keep that name, so an edit does not rename the control a board or a controller writes to. */\n id: a?.state?.id ?? (a && !a.mimic ? a.id : ''),\n min: travel || travelSum ? 0 : (a?.lowerLimit ?? (kind === 'slide' ? 0 : -90)),\n max: travel || travelSum ? 500 : (a?.upperLimit ?? (kind === 'slide' ? 500 : 90)),\n follow: single?.joint ?? '',\n multiplier: single?.multiplier ?? 1,\n offset: terms?.offset ?? 0,\n travel,\n travelPlus: one?.plus ?? 0,\n ...(terms && !single ? { followSum: terms.sum } : {}),\n ...(travelSum ? { travelSum } : {})\n }\n}\n\n/**\n * The axes a part's joint can move with (URDF's mimic): one of another part's that moves the same way — a slide follows\n * a slide, a turn a turn — and has a control of its own, since a follower follows the axis that is driven (ADR-0159).\n */\nexport function leadersFor(asset: FigureAsset, part: string, kind: MotionForm['kind'], self?: string): Array<FigureNamedMotion & { part: string }> {\n /* Another axis of the same joint may lead (a shoulder's second axis following its first); never the axis itself. */\n return figureAxesOf(asset.joints)\n .filter(({ joint, motion }) => (self === undefined ? joint.body1.part !== part : motion.id !== self) && !motion.mimic && (motion.type === 'prismatic') === (kind === 'slide'))\n .map(({ joint, motion }) => ({ ...motion, part: joint.body1.part }))\n}\n\n/**\n * The joint record the motion form writes for a part fastened by `joint`. A joint of its own gets its limits (none for\n * a turn without end, as in USD) and a control; a follower gets the leader, the multiplier and the offset, and no\n * control or limits of its own — its range is the leader's times the multiplier.\n */\nexport function motionJoint(joint: FigureJoint, m: MotionForm, part: string, k = 0): FigureJoint {\n /*\n Where it is fastened -- its row and its frame's own words too -- is the kernel's to keep (`figureJointWithMotion`,\n ADR-0140 D6). The form writes axis `k` under the name it had, or adds it past the last; the others stay as they are\n (ADR-0159).\n */\n const was = joint.motion?.[k]\n const moving = {\n ...(was?.id !== undefined ? { id: was.id } : {}),\n type: m.kind === 'slide' ? ('prismatic' as const) : ('revolute' as const),\n axis: (m.axisVector ?? m.axis.toUpperCase()) as FigureJointMotion['axis'],\n ...(was?.through ? { through: was.through } : {})\n }\n const axes = joint.motion ?? []\n const given = (motion: Omit<FigureJointMotion, 'type' | 'axis'>) => figureJointWithMotion(joint, [...axes.slice(0, k), { ...moving, ...motion }, ...axes.slice(k + 1)])\n const control = m.id || controlIdFor(part, m.kind, k)\n if (m.follow) return given({ mimic: { motion: m.follow, multiplier: m.multiplier, ...(m.offset ? { offset: m.offset } : {}) } })\n if (m.followSum) return given({ mimic: { sum: m.followSum.map(t => ({ motion: t.joint, multiplier: t.multiplier })), ...(m.offset ? { offset: m.offset } : {}) } })\n if (m.kind === 'slide' && m.travelSum && !m.travel) return given({ travel: m.travelSum, state: { id: control } })\n if (m.kind === 'slide' && m.travel) {\n const [of, axis] = m.travel.split(':')\n return given({ travel: { source: { of: 'part', part: of!, axis: axis as Axis }, ...(m.travelPlus ? { plus: m.travelPlus } : {}) }, state: { id: control } })\n }\n return given({ ...(m.kind === 'continuous' ? {} : { lowerLimit: m.min, upperLimit: m.max }), state: { id: control } })\n}\n\n/** The control an axis gets when the author names none: `<part>-<kind>`, and `<part>-<kind>-<n>` for the n-th axis. */\nexport function controlIdFor(part: string, kind: MotionForm['kind'], k: number): string {\n return k === 0 ? `${part}-${kind}` : `${part}-${kind}-${k + 1}`\n}\n\n/**\n * The joint without its axis `k`. The axes after it keep the names they went by: one named by its place\n * (`<joint>.<k>`, figure-model `motionIdOf`) is given that name before it moves up, so its control is not renamed under\n * a board that writes to it.\n */\nexport function withoutAxis(joint: FigureJoint, k: number): FigureJoint {\n const axes = joint.motion ?? []\n return figureJointWithMotion(joint, [...axes.slice(0, k), ...axes.slice(k + 1).map((a, i) => (a.id !== undefined ? a : { ...a, id: motionIdOf(joint, k + 1 + i) }))])\n}\n\n/**\n * Why the motion form cannot be saved as it stands, as the kernel would refuse it: a follower's multiplier that is not\n * a number or is 0, or a range whose most is not above its least. A range need not hold 0 -- the control starts at the\n * nearest end (a lift that rests at 200 mm).\n */\nexport function motionFormRefusalOf(m: MotionForm, follow: string): 'multiplier' | 'range' | undefined {\n if (m.followSum) return undefined\n if (follow) return Number.isFinite(m.multiplier) && m.multiplier !== 0 ? undefined : 'multiplier'\n if (m.kind === 'continuous' || (m.kind === 'slide' && (m.travel || m.travelSum))) return undefined\n return Number.isFinite(m.min) && Number.isFinite(m.max) && m.max > m.min ? undefined : 'range'\n}\n\n/** The select's value for what a dimension follows now. */\n/**\n * What a measure that is not its own follows, in the words of the choice that set it -- 「피규어 X 크기에 비례」, 「bed의 X」 --\n * where the row once said only 「다른 규칙에 연결됨」 (user 2026-10-16: which rule?).\n */\nexport function followWordsOf(follow: Follow, say: (key: string, params?: Record<string, string>) => string): string {\n switch (follow.of) {\n case 'own':\n return say('figure.label.follows-nothing')\n case 'instance':\n return say(follow.times === 1 ? 'figure.label.follows-instance' : 'figure.label.follows-instance-share', { axis: follow.axis.toUpperCase() })\n case 'part':\n return say('figure.label.follows-part-axis', { part: follow.part, axis: follow.axis.toUpperCase() })\n case 'input':\n return follow.input\n case 'expression':\n return say('figure.label.follows-expression')\n }\n}\n\nexport function choiceOf(follow: Follow): string {\n switch (follow.of) {\n case 'own':\n return 'own'\n case 'instance':\n return follow.times === 1 ? `instance:${follow.axis}` : `share:${follow.axis}`\n case 'part':\n return `part:${follow.part}:${follow.axis}`\n case 'input':\n return `input:${follow.input}`\n case 'expression':\n return 'expression'\n }\n}\n\n/**\n * The faces a place can sit on for this part: its flat faces, but not a plane that only touches a curved side along a\n * line (a cylinder's side, Q3) -- nothing is held on a line. A sphere has none.\n */\nexport function placeFacesOf(asset: FigureAsset, part: string): FigureFace[] {\n const shape = modelOf(asset).nodes.find(n => n.id === `${part}.shape`)\n const faces = (shape && figureShapeFaces(shape as never)) ?? {}\n return inScreenOrder(Object.entries(faces).filter(([, f]) => !(f as { contact?: string }).contact).map(([name]) => name)) as FigureFace[]\n}\n\n/** The places things are held that sit on this part. */\nexport function placesOn(asset: FigureAsset, part: string): FigureBindingPlace[] {\n return figureBindingsOf(asset).filter(one => one.part === part)\n}\n\n/** An id for a new place on this part, not yet taken: `<part>-<role>`, then `-2`, `-3`. */\nexport function placeIdFor(asset: FigureAsset, part: string, role: 'seat' | 'grip'): string {\n const taken = new Set(asset.document.capabilities.bindings.map(b => b.id))\n const base = `${part}-${role}`\n if (!taken.has(base)) return base\n let n = 2\n while (taken.has(`${base}-${n}`)) n++\n return `${base}-${n}`\n}\n\n/**\n * Whether a board will hand this figure anything: a place is a slot only on a figure that declares it holds things\n * (`Capacity`, or `FlowNode`, which includes it). Without it the places are declared and nothing arrives.\n */\nexport const holdsThings = (asset: FigureAsset) => (asset.document.capabilities.names ?? []).some(n => n === 'Capacity' || n === 'FlowNode')\n\n/** What `accepts` a person typed: names split on commas, trimmed, blanks and repeats dropped. */\nexport const acceptsOf = (typed: string) => [...new Set(typed.split(',').map(one => one.trim()).filter(Boolean))]\n\n/**\n * The sizes a board may give this figure, per axis: the ends its author narrowed, and the rest as far as its parts\n * allow, computed by figure-model (`figureInstanceSizeRangeOf`, ADR-0087 decision 6) -- the screen does not measure\n * on its own. Nothing when no size is declared.\n */\nexport function instanceRangeOf(asset: FigureAsset): Record<Axis, FigureInstanceSizeRange> | undefined {\n const range = figureInstanceSizeRangeOf(asset)\n return AXES.every(axis => range[axis]) ? (range as Record<Axis, FigureInstanceSizeRange>) : undefined\n}\n\n/**\n * The size to declare for a figure that has none yet: its parts' extent now, the size it is authored at. Undefined when\n * the figure already has a size or has nothing to measure. Without a declared size a board cannot resize the figure,\n * and no part is offered to follow its size -- every figure made in the modeller was left there (user, 2026-09-25).\n */\nexport function instanceSizeToDeclare(asset: FigureAsset): { at: Record<Axis, number> } | undefined {\n if (instanceRangeOf(asset) || !asset.appearance.length) return undefined\n /* The parts as they rest -- not the room their joints swing them through, which declared a door 8208 mm every way. */\n const at = figurePartsExtentOf(asset) as Record<Axis, number>\n if (AXES.some(axis => !(at[axis] > 0))) return undefined\n return { at }\n}\n\n/**\n * The ends the author narrowed, with one end typed or cleared: a number narrows that end, an empty field opens it\n * again to what the parts allow. Whether the figure holds there is the command's to say.\n */\nexport function rangeWith(\n range: Record<Axis, FigureInstanceSizeRange>,\n axis: Axis,\n bound: 'min' | 'max',\n value: number\n): Partial<Record<Axis, { min?: number; max?: number }>> {\n const out: Partial<Record<Axis, { min?: number; max?: number }>> = {}\n for (const a of AXES) {\n const ends: { min?: number; max?: number } = {}\n for (const b of ['min', 'max'] as const) {\n const typed = a === axis && b === bound\n if (typed ? Number.isFinite(value) : range[a].narrowed[b]) ends[b] = typed ? value : range[a][b]\n }\n if (Object.keys(ends).length) out[a] = ends\n }\n return out\n}\n\n/**\n * For a figure that grows by one ratio: how many of its lengths would follow the ratio, and which it leaves with their\n * own number (not those that follow another length -- they grow with it). Nothing for a figure of another sizing.\n */\nexport function proportionToFollow(asset: FigureAsset): { count: number; kept: string[] } | undefined {\n if (asset.sizing !== 'uniform') return undefined\n try {\n const plan = proposeFigureProportion(asset)\n return { count: plan.dimensions.length + plan.lengths.length, kept: plan.skipped.filter(s => !s.follows).map(s => s.what) }\n } catch {\n return undefined\n }\n}\n\n/** A value of the figure as it stands, by its graph reference. */\nexport function valueNow(revision: FigureRevision, ref: string | undefined): number | undefined {\n if (!ref) return undefined\n try {\n const value = graphValuesOf(revision)[ref]\n return typeof value === 'number' && Number.isFinite(value) ? value : undefined\n } catch {\n return undefined\n }\n}\n\n/**\n * Whether the figure is a mechanism -- a part turns about a joint. Such a figure should grow by one ratio (chief\n * architect's ruling 2026-09-24); the modeller proposes it, the author declares it.\n */\nexport function turnsAboutAJoint(asset: FigureAsset): boolean {\n return modelOf(asset).nodes.some(n => n.op === 'axis-turn@1')\n}\n\n/** The joint made still: its fastening, its place and its row kept, its motion gone (the kernel's `figureJointAsFixed`, ADR-0140 D6). */\nexport const fixedJointOf = figureJointAsFixed\n"]}
@@ -3,7 +3,7 @@
3
3
  *
4
4
  * ## 놓은 개수가 아니라 **보이는 개수**다
5
5
  *
6
- * 3D 는 요청이 있어야 다시 그린다. 가만히 서 있는 도형은 프레임마다 아무 값도 치르지 않는다 —
6
+ * 3D 는 요청이 있어야 다시 그린다. 가만히 서 있는 피규어는 프레임마다 아무 값도 치르지 않는다 —
7
7
  * 900 대를 놓아 두어도 60fps 다. 값을 치르는 것은 **카메라 안에 들어 있고 그 프레임에 다시
8
8
  * 그려지는** 것뿐이다. 그래서 이 파일의 분모는 「한 도면에 놓는 수」가 아니라 「한 화면에 보이는
9
9
  * 부품 묶음 수」다.
@@ -17,8 +17,8 @@
17
17
  * 묶음 9 짜리 6 축 로봇 600 대 보이면 59.5 fps · 700 대에서 56.7 fps
18
18
  * 묶음 2 짜리 컨베이어 1,600 대 보이면 59.3 fps · 2,500 대에서 36.8 fps
19
19
  *
20
- * 두 도형의 꺾이는 지점이 **인스턴스 × 묶음 = 3,600 ~ 5,400** 에 들어온다. 보수적으로 4,000 을
21
- * 쓴다. 도형이 달라도 이 곱이 비슷한 데서 꺾이므로, 분모는 묶음 수로 둔다.
20
+ * 두 피규어의 꺾이는 지점이 **인스턴스 × 묶음 = 3,600 ~ 5,400** 에 들어온다. 보수적으로 4,000 을
21
+ * 쓴다. 피규어가 달라도 이 곱이 비슷한 데서 꺾이므로, 분모는 묶음 수로 둔다.
22
22
  *
23
23
  * ⚠ 이 수는 **이 기계에서 이 씬으로** 잰 값이다. 더 낮은 GPU 나 브라우저에서는 더 일찍 꺾인다.
24
24
  * 화면에는 잰 기계와 날짜를 함께 적는다 — 적지 않으면 어디서나 참인 수처럼 읽힌다.
@@ -3,7 +3,7 @@
3
3
  *
4
4
  * ## 놓은 개수가 아니라 **보이는 개수**다
5
5
  *
6
- * 3D 는 요청이 있어야 다시 그린다. 가만히 서 있는 도형은 프레임마다 아무 값도 치르지 않는다 —
6
+ * 3D 는 요청이 있어야 다시 그린다. 가만히 서 있는 피규어는 프레임마다 아무 값도 치르지 않는다 —
7
7
  * 900 대를 놓아 두어도 60fps 다. 값을 치르는 것은 **카메라 안에 들어 있고 그 프레임에 다시
8
8
  * 그려지는** 것뿐이다. 그래서 이 파일의 분모는 「한 도면에 놓는 수」가 아니라 「한 화면에 보이는
9
9
  * 부품 묶음 수」다.
@@ -17,8 +17,8 @@
17
17
  * 묶음 9 짜리 6 축 로봇 600 대 보이면 59.5 fps · 700 대에서 56.7 fps
18
18
  * 묶음 2 짜리 컨베이어 1,600 대 보이면 59.3 fps · 2,500 대에서 36.8 fps
19
19
  *
20
- * 두 도형의 꺾이는 지점이 **인스턴스 × 묶음 = 3,600 ~ 5,400** 에 들어온다. 보수적으로 4,000 을
21
- * 쓴다. 도형이 달라도 이 곱이 비슷한 데서 꺾이므로, 분모는 묶음 수로 둔다.
20
+ * 두 피규어의 꺾이는 지점이 **인스턴스 × 묶음 = 3,600 ~ 5,400** 에 들어온다. 보수적으로 4,000 을
21
+ * 쓴다. 피규어가 달라도 이 곱이 비슷한 데서 꺾이므로, 분모는 묶음 수로 둔다.
22
22
  *
23
23
  * ⚠ 이 수는 **이 기계에서 이 씬으로** 잰 값이다. 더 낮은 GPU 나 브라우저에서는 더 일찍 꺾인다.
24
24
  * 화면에는 잰 기계와 날짜를 함께 적는다 — 적지 않으면 어디서나 참인 수처럼 읽힌다.
@@ -1 +1 @@
1
- {"version":3,"file":"scene-budget.js","sourceRoot":"","sources":["../../client/modeller/scene-budget.ts"],"names":[],"mappings":"AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAEH,MAAM,CAAC,MAAM,YAAY,GAAG;IAC1B,2CAA2C;IAC3C,cAAc,EAAE,IAAI;IACpB,iDAAiD;IACjD,SAAS,EAAE,OAAO;CACV,CAAA;AAEV,0DAA0D;AAC1D,MAAM,CAAC,MAAM,QAAQ,GAAG,EAAE,GAAG,EAAE,UAAU,EAAE,EAAE,EAAE,YAAY,EAAE,GAAG,EAAE,EAAE,EAAW,CAAA;AAgB/E;;;;;;;GAOG;AACH,MAAM,UAAU,YAAY,CAAC,MAAc,EAAE,SAAiB;IAC5D,2CAA2C;IAC3C,IAAI,MAAM,IAAI,CAAC,IAAI,SAAS,IAAI,CAAC,EAAE,CAAC;QAClC,OAAO,SAAS,CAAA;IAClB,CAAC;IAED,MAAM,QAAQ,GAAG,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,cAAc,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAA;IACzF,MAAM,WAAW,GAAG,SAAS,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,SAAS,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAA;IAE7F,OAAO,QAAQ,IAAI,WAAW;QAC5B,CAAC,CAAC,EAAE,SAAS,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,YAAY,CAAC,cAAc,EAAE;QAC5F,CAAC,CAAC,EAAE,SAAS,EAAE,WAAW,EAAE,KAAK,EAAE,WAAW,EAAE,GAAG,EAAE,SAAS,EAAE,MAAM,EAAE,YAAY,CAAC,SAAS,EAAE,CAAA;AACpG,CAAC","sourcesContent":["\n/**\n * 한 화면이 감당하는 양 — 「몇 개까지 편한가」의 분모.\n *\n * ## 놓은 개수가 아니라 **보이는 개수**다\n *\n * 3D 는 요청이 있어야 다시 그린다. 가만히 서 있는 도형은 프레임마다 아무 값도 치르지 않는다 —\n * 900 대를 놓아 두어도 60fps 다. 값을 치르는 것은 **카메라 안에 들어 있고 그 프레임에 다시\n * 그려지는** 것뿐이다. 그래서 이 파일의 분모는 「한 도면에 놓는 수」가 아니라 「한 화면에 보이는\n * 부품 묶음 수」다.\n *\n * ## 이 수는 잰 값이다\n *\n * 전에는 설계 문서의 목표치(도면당 draw call 2,500)를 썼고, 그 문서가 스스로 「측정 없이 정한\n * 목표」라고 적어 두었다. 2026-09-18 에 실기에서 쟀다\n * (`things-scene/test/browser/measure-figure-frames.mjs`, Apple M5, 저작 화면과 같은 조명 · 그림자):\n *\n * 묶음 9 짜리 6 축 로봇 600 대 보이면 59.5 fps · 700 대에서 56.7 fps\n * 묶음 2 짜리 컨베이어 1,600 대 보이면 59.3 fps · 2,500 대에서 36.8 fps\n *\n * 두 도형의 꺾이는 지점이 **인스턴스 × 묶음 = 3,600 ~ 5,400** 에 들어온다. 보수적으로 4,000 을\n * 쓴다. 도형이 달라도 이 곱이 비슷한 데서 꺾이므로, 분모는 묶음 수로 둔다.\n *\n * ⚠ 이 수는 **이 기계에서 이 씬으로** 잰 값이다. 더 낮은 GPU 나 브라우저에서는 더 일찍 꺾인다.\n * 화면에는 잰 기계와 날짜를 함께 적는다 — 적지 않으면 어디서나 참인 수처럼 읽힌다.\n *\n * ## 그림자는 이미 들어 있다\n *\n * 2026-09-05 에는 draw call 을 figure-model 의 예측과 견주며 그림자 패스가 두 배로 만든다고\n * 쟀다. 지금 값은 **그림자를 켠 채 프레임 시간을 직접 잰 것**이라 그 배수가 이미 안에 있다.\n * 다시 곱하면 두 번 세는 것이다.\n */\n\nexport const SCENE_BUDGET = {\n /** 한 화면에 보이는 부품 묶음. 60fps 가 꺾이는 지점, 실측. */\n groupsOnScreen: 4000,\n /** 한 화면의 삼각형. **이 수는 아직 안 쟀다** — 설계 문서의 목표치다. */\n triangles: 500_000\n} as const\n\n/** 어디서 언제 잰 값인가. 화면이 함께 보여 준다 — 적지 않으면 어디서나 참인 수로 읽힌다. */\nexport const MEASURED = { gpu: 'Apple M5', on: '2026-09-18', fps: 60 } as const\n\n/** 무엇이 먼저 차나. */\nexport type BindingBudget = 'groups' | 'triangles'\n\nexport interface FigureCapacity {\n /** 이 형상이 **한 화면에 몇 개 보일 때까지** 60fps 로 도나. */\n instances: number\n /** 먼저 차는 예산. **여기부터 고치면 된다.** */\n bound: BindingBudget\n /** 인스턴스 하나가 무는 값. */\n per: number\n /** 그 예산의 한 도면 총량. */\n budget: number\n}\n\n/**\n * 저장된 값만으로 셈한다.\n *\n * 목록은 정본을 받아 오지 않는다 — 카드 수십 장마다 컴파일하면 목록이 무거워진다.\n * 대신 서버가 저장해 둔 `groups` · `triangles` 를 쓴다. **목록과 저작면이 같은 함수를\n * 쓰는 것**이 요점이다. 카드가 제 나름대로 셈하면 같은 형상이 두 화면에서 다른 개수로\n * 나온다.\n */\nexport function capacityFrom(groups: number, triangles: number): FigureCapacity | undefined {\n // 부품이 없으면 「무한히 놓을 수 있다」가 아니라 **답할 것이 없다**.\n if (groups <= 0 && triangles <= 0) {\n return undefined\n }\n\n const byGroups = groups > 0 ? Math.floor(SCENE_BUDGET.groupsOnScreen / groups) : Infinity\n const byTriangles = triangles > 0 ? Math.floor(SCENE_BUDGET.triangles / triangles) : Infinity\n\n return byGroups <= byTriangles\n ? { instances: byGroups, bound: 'groups', per: groups, budget: SCENE_BUDGET.groupsOnScreen }\n : { instances: byTriangles, bound: 'triangles', per: triangles, budget: SCENE_BUDGET.triangles }\n}\n\n"]}
1
+ {"version":3,"file":"scene-budget.js","sourceRoot":"","sources":["../../client/modeller/scene-budget.ts"],"names":[],"mappings":"AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAEH,MAAM,CAAC,MAAM,YAAY,GAAG;IAC1B,2CAA2C;IAC3C,cAAc,EAAE,IAAI;IACpB,iDAAiD;IACjD,SAAS,EAAE,OAAO;CACV,CAAA;AAEV,0DAA0D;AAC1D,MAAM,CAAC,MAAM,QAAQ,GAAG,EAAE,GAAG,EAAE,UAAU,EAAE,EAAE,EAAE,YAAY,EAAE,GAAG,EAAE,EAAE,EAAW,CAAA;AAgB/E;;;;;;;GAOG;AACH,MAAM,UAAU,YAAY,CAAC,MAAc,EAAE,SAAiB;IAC5D,2CAA2C;IAC3C,IAAI,MAAM,IAAI,CAAC,IAAI,SAAS,IAAI,CAAC,EAAE,CAAC;QAClC,OAAO,SAAS,CAAA;IAClB,CAAC;IAED,MAAM,QAAQ,GAAG,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,cAAc,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAA;IACzF,MAAM,WAAW,GAAG,SAAS,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,SAAS,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAA;IAE7F,OAAO,QAAQ,IAAI,WAAW;QAC5B,CAAC,CAAC,EAAE,SAAS,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,YAAY,CAAC,cAAc,EAAE;QAC5F,CAAC,CAAC,EAAE,SAAS,EAAE,WAAW,EAAE,KAAK,EAAE,WAAW,EAAE,GAAG,EAAE,SAAS,EAAE,MAAM,EAAE,YAAY,CAAC,SAAS,EAAE,CAAA;AACpG,CAAC","sourcesContent":["\n/**\n * 한 화면이 감당하는 양 — 「몇 개까지 편한가」의 분모.\n *\n * ## 놓은 개수가 아니라 **보이는 개수**다\n *\n * 3D 는 요청이 있어야 다시 그린다. 가만히 서 있는 피규어는 프레임마다 아무 값도 치르지 않는다 —\n * 900 대를 놓아 두어도 60fps 다. 값을 치르는 것은 **카메라 안에 들어 있고 그 프레임에 다시\n * 그려지는** 것뿐이다. 그래서 이 파일의 분모는 「한 도면에 놓는 수」가 아니라 「한 화면에 보이는\n * 부품 묶음 수」다.\n *\n * ## 이 수는 잰 값이다\n *\n * 전에는 설계 문서의 목표치(도면당 draw call 2,500)를 썼고, 그 문서가 스스로 「측정 없이 정한\n * 목표」라고 적어 두었다. 2026-09-18 에 실기에서 쟀다\n * (`things-scene/test/browser/measure-figure-frames.mjs`, Apple M5, 저작 화면과 같은 조명 · 그림자):\n *\n * 묶음 9 짜리 6 축 로봇 600 대 보이면 59.5 fps · 700 대에서 56.7 fps\n * 묶음 2 짜리 컨베이어 1,600 대 보이면 59.3 fps · 2,500 대에서 36.8 fps\n *\n * 두 피규어의 꺾이는 지점이 **인스턴스 × 묶음 = 3,600 ~ 5,400** 에 들어온다. 보수적으로 4,000 을\n * 쓴다. 피규어가 달라도 이 곱이 비슷한 데서 꺾이므로, 분모는 묶음 수로 둔다.\n *\n * ⚠ 이 수는 **이 기계에서 이 씬으로** 잰 값이다. 더 낮은 GPU 나 브라우저에서는 더 일찍 꺾인다.\n * 화면에는 잰 기계와 날짜를 함께 적는다 — 적지 않으면 어디서나 참인 수처럼 읽힌다.\n *\n * ## 그림자는 이미 들어 있다\n *\n * 2026-09-05 에는 draw call 을 figure-model 의 예측과 견주며 그림자 패스가 두 배로 만든다고\n * 쟀다. 지금 값은 **그림자를 켠 채 프레임 시간을 직접 잰 것**이라 그 배수가 이미 안에 있다.\n * 다시 곱하면 두 번 세는 것이다.\n */\n\nexport const SCENE_BUDGET = {\n /** 한 화면에 보이는 부품 묶음. 60fps 가 꺾이는 지점, 실측. */\n groupsOnScreen: 4000,\n /** 한 화면의 삼각형. **이 수는 아직 안 쟀다** — 설계 문서의 목표치다. */\n triangles: 500_000\n} as const\n\n/** 어디서 언제 잰 값인가. 화면이 함께 보여 준다 — 적지 않으면 어디서나 참인 수로 읽힌다. */\nexport const MEASURED = { gpu: 'Apple M5', on: '2026-09-18', fps: 60 } as const\n\n/** 무엇이 먼저 차나. */\nexport type BindingBudget = 'groups' | 'triangles'\n\nexport interface FigureCapacity {\n /** 이 형상이 **한 화면에 몇 개 보일 때까지** 60fps 로 도나. */\n instances: number\n /** 먼저 차는 예산. **여기부터 고치면 된다.** */\n bound: BindingBudget\n /** 인스턴스 하나가 무는 값. */\n per: number\n /** 그 예산의 한 도면 총량. */\n budget: number\n}\n\n/**\n * 저장된 값만으로 셈한다.\n *\n * 목록은 정본을 받아 오지 않는다 — 카드 수십 장마다 컴파일하면 목록이 무거워진다.\n * 대신 서버가 저장해 둔 `groups` · `triangles` 를 쓴다. **목록과 저작면이 같은 함수를\n * 쓰는 것**이 요점이다. 카드가 제 나름대로 셈하면 같은 형상이 두 화면에서 다른 개수로\n * 나온다.\n */\nexport function capacityFrom(groups: number, triangles: number): FigureCapacity | undefined {\n // 부품이 없으면 「무한히 놓을 수 있다」가 아니라 **답할 것이 없다**.\n if (groups <= 0 && triangles <= 0) {\n return undefined\n }\n\n const byGroups = groups > 0 ? Math.floor(SCENE_BUDGET.groupsOnScreen / groups) : Infinity\n const byTriangles = triangles > 0 ? Math.floor(SCENE_BUDGET.triangles / triangles) : Infinity\n\n return byGroups <= byTriangles\n ? { instances: byGroups, bound: 'groups', per: groups, budget: SCENE_BUDGET.groupsOnScreen }\n : { instances: byTriangles, bound: 'triangles', per: triangles, budget: SCENE_BUDGET.triangles }\n}\n\n"]}
@@ -12,7 +12,7 @@ import './canvas.js';
12
12
  *
13
13
  * ## 왜 서버가 아니라 브라우저인가
14
14
  *
15
- * 백엔드에 GPU 가 없는 배포가 많아 헤드리스로 3D 를 찍는 것이 자주 실패한다. 도형을 그릴 GPU 는
15
+ * 백엔드에 GPU 가 없는 배포가 많아 헤드리스로 3D 를 찍는 것이 자주 실패한다. 피규어를 그릴 GPU 는
16
16
  * 이미 보는 사람 손에 있다.
17
17
  *
18
18
  * ## 못 찍어도 저장은 간다
@@ -1 +1 @@
1
- {"version":3,"file":"thumbnail.js","sourceRoot":"","sources":["../../client/modeller/thumbnail.ts"],"names":[],"mappings":"AAAA,OAAO,aAAa,CAAA;AAIpB;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,kBAAkB;AAClB,MAAM,KAAK,GAAG,GAAG,CAAA;AACjB,MAAM,MAAM,GAAG,GAAG,CAAA;AAElB,mDAAmD;AACnD,MAAM,QAAQ,GAAG,IAAI,CAAA;AAWrB,MAAM,KAAK,GAAG,CAAC,EAAU,EAAE,EAAE,CAAC,IAAI,OAAO,CAAO,OAAO,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAA;AAEnF,yDAAyD;AACzD,SAAS,MAAM;IACb,MAAM,MAAM,GAAG,IAAI,OAAO,CAAO,OAAO,CAAC,EAAE,CACzC,qBAAqB,CAAC,GAAG,EAAE,CAAC,qBAAqB,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,CAAC,CACnF,CAAA;IACD,OAAO,OAAO,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAA;AAC3C,CAAC;AAED,SAAS,MAAM,CAAI,IAAgB,EAAE,EAAU;IAC7C,OAAO,OAAO,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,CAAA;AAC9D,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAC1C,KAAyB,EACzB,OAA+B;IAE/B,IAAI,CAAC,KAAK,CAAC,MAAM;QAAE,OAAO,SAAS,CAAA;IAEnC;;;MAGE;IACF,MAAM,IAAI,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAA;IAC1C,IAAI,CAAC,YAAY,CAAC,wBAAwB,EAAE,EAAE,CAAC,CAAA;IAC/C,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,mDAAmD,KAAK,eAAe,MAAM,2BAA2B,CAAA;IAC7H,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAA;IAE/B,MAAM,OAAO,GAAG,QAAQ,CAAC,aAAa,CAAC,eAAe,CAAY,CAAA;IAClE,OAAO,CAAC,KAAK,GAAG,KAAK,CAAA;IACrB,OAAO,CAAC,OAAO,GAAG,OAAO,CAAA;IACzB,OAAO,CAAC,OAAO,GAAG,WAAW,CAAA;IAC7B,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAA;IACvB,OAAO,CAAC,KAAK,CAAC,OAAO,GAAG,4CAA4C,CAAA;IAEpE,IAAI,CAAC;QACH,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,CAAA;QACzB,MAAM,IAAI,GAAG,MAAM,MAAM,CACvB,CAAC,KAAK,IAAI,EAAE;YACV,MAAM,MAAM,EAAE,CAAA;YACd,OAAO,CAAC,GAAG,EAAE,EAAE,CAAA;YACf,MAAM,MAAM,EAAE,CAAA;YACd,OAAO,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,OAAO,CAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;QAC7E,CAAC,CAAC,EAAE,EACJ,QAAQ,CACT,CAAA;QACD,IAAI,CAAC,IAAI;YAAE,OAAO,CAAC,IAAI,CAAC,eAAe,QAAQ,6BAA6B,CAAC,CAAA;QAC7E,OAAO,IAAI,CAAA;IACb,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,OAAO,CAAC,IAAI,CAAC,2BAA4B,CAAW,CAAC,OAAO,EAAE,CAAC,CAAA;QAC/D,OAAO,SAAS,CAAA;IAClB,CAAC;YAAS,CAAC;QACT,IAAI,CAAC,MAAM,EAAE,CAAA;IACf,CAAC;AACH,CAAC","sourcesContent":["import './canvas.js'\n\nimport type { FigureRenderPart } from './renderer.js'\n\n/**\n * 카드에 쓸 그림을 찍는다 — **숨은 자리에 캔버스를 하나 더 세워서.**\n *\n * ## 왜 보이는 캔버스를 찍지 않나\n *\n * 저작면의 캔버스는 저작자가 돌려 둔 각도와 확대로 서 있다. 그것을 찍으면 카드마다 프레임이\n * 달라지고, 방금 확대해 보던 나사 하나가 그 자산의 얼굴이 된다. 목록은 견주는 자리이므로 그림은\n * **정해진 크기와 정해진 카메라**로 찍는다 — 새로 세운 캔버스(`viewOnly`)가 스스로 `fit()` 한 자리에서\n * `snapshot()` 으로 찍는다. 캔버스가 씬 위로 옮겨 가면서 찍는 길이 빠졌고, 그동안 저장은 그림 없이 갔다\n * (사용자 2026-09-24).\n *\n * ## 왜 서버가 아니라 브라우저인가\n *\n * 백엔드에 GPU 가 없는 배포가 많아 헤드리스로 3D 를 찍는 것이 자주 실패한다. 도형을 그릴 GPU 는\n * 이미 보는 사람 손에 있다.\n *\n * ## 못 찍어도 저장은 간다\n *\n * 탭이 뒤로 가면 브라우저가 `requestAnimationFrame` 을 멈춘다. 그 위에 저장이 얹혀 있으면 저장이\n * 통째로 멈춘다 — 단추는 잠긴 채로, 아무 말도 없이. 그래서 시계와 경주시키고, 늦으면 그림 없이\n * 간다. 정본이 그림보다 중하고, 그림은 다음에 저작면을 열 때 다시 채운다.\n */\n\n/** 카드는 4:3 이다. */\nconst WIDTH = 480\nconst HEIGHT = 360\n\n/** 넘으면 그림 없이 저장한다. 빠르기가 아니라 저장이 멈추지 않는 것이 목적이다. */\nconst PATIENCE = 5000\n\ninterface Shooter extends HTMLElement {\n parts?: FigureRenderPart[]\n palette?: Record<string, string>\n context?: string\n viewOnly?: boolean\n snapshot?: (width?: number, height?: number) => Promise<string | undefined>\n fit?: () => void\n}\n\nconst delay = (ms: number) => new Promise<void>(resolve => setTimeout(resolve, ms))\n\n/** 씬이 서고 카메라가 자리를 잡을 틈. rAF 가 멈춘 탭에서도 풀리도록 시계와 경주시킨다. */\nfunction settle(): Promise<void> {\n const frames = new Promise<void>(resolve =>\n requestAnimationFrame(() => requestAnimationFrame(() => setTimeout(resolve, 150)))\n )\n return Promise.race([frames, delay(600)])\n}\n\nfunction within<T>(work: Promise<T>, ms: number): Promise<T | undefined> {\n return Promise.race([work, delay(ms).then(() => undefined)])\n}\n\nexport async function captureFigureThumbnail(\n parts: FigureRenderPart[],\n palette: Record<string, string>\n): Promise<string | undefined> {\n if (!parts.length) return undefined\n\n /*\n 화면 밖에 둔다. `display: none` 이면 캔버스가 크기를 못 얻어 아무것도 그리지 못한다.\n WebGL context 는 브라우저가 8~16개에서 끊으므로 찍은 뒤 반드시 버린다(아래 finally).\n */\n const host = document.createElement('div')\n host.setAttribute('figure-thumbnail-stage', '')\n host.style.cssText = `position: fixed; left: -10000px; top: 0; width: ${WIDTH}px; height: ${HEIGHT}px; pointer-events: none;`\n document.body.appendChild(host)\n\n const shooter = document.createElement('figure-canvas') as Shooter\n shooter.parts = parts\n shooter.palette = palette\n shooter.context = 'thumbnail'\n shooter.viewOnly = true\n shooter.style.cssText = 'display: block; width: 100%; height: 100%;'\n\n try {\n host.appendChild(shooter)\n const shot = await within(\n (async () => {\n await settle()\n shooter.fit?.()\n await settle()\n return shooter.snapshot ? await shooter.snapshot(WIDTH, HEIGHT) : undefined\n })(),\n PATIENCE\n )\n if (!shot) console.warn(`[thumbnail] ${PATIENCE}ms 안에 못 찍었습니다 — 그림 없이 저장합니다`)\n return shot\n } catch (e) {\n console.warn(`[thumbnail] 세우지 못했습니다 — ${(e as Error).message}`)\n return undefined\n } finally {\n host.remove()\n }\n}\n"]}
1
+ {"version":3,"file":"thumbnail.js","sourceRoot":"","sources":["../../client/modeller/thumbnail.ts"],"names":[],"mappings":"AAAA,OAAO,aAAa,CAAA;AAIpB;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,kBAAkB;AAClB,MAAM,KAAK,GAAG,GAAG,CAAA;AACjB,MAAM,MAAM,GAAG,GAAG,CAAA;AAElB,mDAAmD;AACnD,MAAM,QAAQ,GAAG,IAAI,CAAA;AAWrB,MAAM,KAAK,GAAG,CAAC,EAAU,EAAE,EAAE,CAAC,IAAI,OAAO,CAAO,OAAO,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAA;AAEnF,yDAAyD;AACzD,SAAS,MAAM;IACb,MAAM,MAAM,GAAG,IAAI,OAAO,CAAO,OAAO,CAAC,EAAE,CACzC,qBAAqB,CAAC,GAAG,EAAE,CAAC,qBAAqB,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,CAAC,CACnF,CAAA;IACD,OAAO,OAAO,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAA;AAC3C,CAAC;AAED,SAAS,MAAM,CAAI,IAAgB,EAAE,EAAU;IAC7C,OAAO,OAAO,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,CAAA;AAC9D,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAC1C,KAAyB,EACzB,OAA+B;IAE/B,IAAI,CAAC,KAAK,CAAC,MAAM;QAAE,OAAO,SAAS,CAAA;IAEnC;;;MAGE;IACF,MAAM,IAAI,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAA;IAC1C,IAAI,CAAC,YAAY,CAAC,wBAAwB,EAAE,EAAE,CAAC,CAAA;IAC/C,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,mDAAmD,KAAK,eAAe,MAAM,2BAA2B,CAAA;IAC7H,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAA;IAE/B,MAAM,OAAO,GAAG,QAAQ,CAAC,aAAa,CAAC,eAAe,CAAY,CAAA;IAClE,OAAO,CAAC,KAAK,GAAG,KAAK,CAAA;IACrB,OAAO,CAAC,OAAO,GAAG,OAAO,CAAA;IACzB,OAAO,CAAC,OAAO,GAAG,WAAW,CAAA;IAC7B,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAA;IACvB,OAAO,CAAC,KAAK,CAAC,OAAO,GAAG,4CAA4C,CAAA;IAEpE,IAAI,CAAC;QACH,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,CAAA;QACzB,MAAM,IAAI,GAAG,MAAM,MAAM,CACvB,CAAC,KAAK,IAAI,EAAE;YACV,MAAM,MAAM,EAAE,CAAA;YACd,OAAO,CAAC,GAAG,EAAE,EAAE,CAAA;YACf,MAAM,MAAM,EAAE,CAAA;YACd,OAAO,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,OAAO,CAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;QAC7E,CAAC,CAAC,EAAE,EACJ,QAAQ,CACT,CAAA;QACD,IAAI,CAAC,IAAI;YAAE,OAAO,CAAC,IAAI,CAAC,eAAe,QAAQ,6BAA6B,CAAC,CAAA;QAC7E,OAAO,IAAI,CAAA;IACb,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,OAAO,CAAC,IAAI,CAAC,2BAA4B,CAAW,CAAC,OAAO,EAAE,CAAC,CAAA;QAC/D,OAAO,SAAS,CAAA;IAClB,CAAC;YAAS,CAAC;QACT,IAAI,CAAC,MAAM,EAAE,CAAA;IACf,CAAC;AACH,CAAC","sourcesContent":["import './canvas.js'\n\nimport type { FigureRenderPart } from './renderer.js'\n\n/**\n * 카드에 쓸 그림을 찍는다 — **숨은 자리에 캔버스를 하나 더 세워서.**\n *\n * ## 왜 보이는 캔버스를 찍지 않나\n *\n * 저작면의 캔버스는 저작자가 돌려 둔 각도와 확대로 서 있다. 그것을 찍으면 카드마다 프레임이\n * 달라지고, 방금 확대해 보던 나사 하나가 그 자산의 얼굴이 된다. 목록은 견주는 자리이므로 그림은\n * **정해진 크기와 정해진 카메라**로 찍는다 — 새로 세운 캔버스(`viewOnly`)가 스스로 `fit()` 한 자리에서\n * `snapshot()` 으로 찍는다. 캔버스가 씬 위로 옮겨 가면서 찍는 길이 빠졌고, 그동안 저장은 그림 없이 갔다\n * (사용자 2026-09-24).\n *\n * ## 왜 서버가 아니라 브라우저인가\n *\n * 백엔드에 GPU 가 없는 배포가 많아 헤드리스로 3D 를 찍는 것이 자주 실패한다. 피규어를 그릴 GPU 는\n * 이미 보는 사람 손에 있다.\n *\n * ## 못 찍어도 저장은 간다\n *\n * 탭이 뒤로 가면 브라우저가 `requestAnimationFrame` 을 멈춘다. 그 위에 저장이 얹혀 있으면 저장이\n * 통째로 멈춘다 — 단추는 잠긴 채로, 아무 말도 없이. 그래서 시계와 경주시키고, 늦으면 그림 없이\n * 간다. 정본이 그림보다 중하고, 그림은 다음에 저작면을 열 때 다시 채운다.\n */\n\n/** 카드는 4:3 이다. */\nconst WIDTH = 480\nconst HEIGHT = 360\n\n/** 넘으면 그림 없이 저장한다. 빠르기가 아니라 저장이 멈추지 않는 것이 목적이다. */\nconst PATIENCE = 5000\n\ninterface Shooter extends HTMLElement {\n parts?: FigureRenderPart[]\n palette?: Record<string, string>\n context?: string\n viewOnly?: boolean\n snapshot?: (width?: number, height?: number) => Promise<string | undefined>\n fit?: () => void\n}\n\nconst delay = (ms: number) => new Promise<void>(resolve => setTimeout(resolve, ms))\n\n/** 씬이 서고 카메라가 자리를 잡을 틈. rAF 가 멈춘 탭에서도 풀리도록 시계와 경주시킨다. */\nfunction settle(): Promise<void> {\n const frames = new Promise<void>(resolve =>\n requestAnimationFrame(() => requestAnimationFrame(() => setTimeout(resolve, 150)))\n )\n return Promise.race([frames, delay(600)])\n}\n\nfunction within<T>(work: Promise<T>, ms: number): Promise<T | undefined> {\n return Promise.race([work, delay(ms).then(() => undefined)])\n}\n\nexport async function captureFigureThumbnail(\n parts: FigureRenderPart[],\n palette: Record<string, string>\n): Promise<string | undefined> {\n if (!parts.length) return undefined\n\n /*\n 화면 밖에 둔다. `display: none` 이면 캔버스가 크기를 못 얻어 아무것도 그리지 못한다.\n WebGL context 는 브라우저가 8~16개에서 끊으므로 찍은 뒤 반드시 버린다(아래 finally).\n */\n const host = document.createElement('div')\n host.setAttribute('figure-thumbnail-stage', '')\n host.style.cssText = `position: fixed; left: -10000px; top: 0; width: ${WIDTH}px; height: ${HEIGHT}px; pointer-events: none;`\n document.body.appendChild(host)\n\n const shooter = document.createElement('figure-canvas') as Shooter\n shooter.parts = parts\n shooter.palette = palette\n shooter.context = 'thumbnail'\n shooter.viewOnly = true\n shooter.style.cssText = 'display: block; width: 100%; height: 100%;'\n\n try {\n host.appendChild(shooter)\n const shot = await within(\n (async () => {\n await settle()\n shooter.fit?.()\n await settle()\n return shooter.snapshot ? await shooter.snapshot(WIDTH, HEIGHT) : undefined\n })(),\n PATIENCE\n )\n if (!shot) console.warn(`[thumbnail] ${PATIENCE}ms 안에 못 찍었습니다 — 그림 없이 저장합니다`)\n return shot\n } catch (e) {\n console.warn(`[thumbnail] 세우지 못했습니다 — ${(e as Error).message}`)\n return undefined\n } finally {\n host.remove()\n }\n}\n"]}
@@ -55,7 +55,7 @@ export declare class FigureListPage extends FigureListPageBase {
55
55
  * 검색창에 그 말을 채워 넣는다. 격자에 조건만 걸고 창을 비워 두면 저작자는 **왜 목록이
56
56
  * 줄었는지 모른 채** 보게 되고, 되돌리려면 무엇을 지워야 하는지도 알 수 없다.
57
57
  *
58
- * 서버가 `tags` 뿐 아니라 이름·타입·설명·분류를 함께 훑으므로, 그 말이 다른 칸에 든 도형도
58
+ * 서버가 `tags` 뿐 아니라 이름·타입·설명·분류를 함께 훑으므로, 그 말이 다른 칸에 든 피규어도
59
59
  * 같이 온다. 태그만 정확히 거르는 것이 아니라 **찾기**다.
60
60
  */
61
61
  private findByTag;
@@ -164,7 +164,7 @@ let FigureListPage = class FigureListPage extends FigureListPageBase {
164
164
  * 검색창에 그 말을 채워 넣는다. 격자에 조건만 걸고 창을 비워 두면 저작자는 **왜 목록이
165
165
  * 줄었는지 모른 채** 보게 되고, 되돌리려면 무엇을 지워야 하는지도 알 수 없다.
166
166
  *
167
- * 서버가 `tags` 뿐 아니라 이름·타입·설명·분류를 함께 훑으므로, 그 말이 다른 칸에 든 도형도
167
+ * 서버가 `tags` 뿐 아니라 이름·타입·설명·분류를 함께 훑으므로, 그 말이 다른 칸에 든 피규어도
168
168
  * 같이 온다. 태그만 정확히 거르는 것이 아니라 **찾기**다.
169
169
  */
170
170
  findByTag(tag) {
@@ -262,7 +262,7 @@ let FigureListPage = class FigureListPage extends FigureListPageBase {
262
262
  정렬은 걸지 않는다. 배열이라 무엇을 기준으로 줄을 세우는지 답할 수 없다.
263
263
 
264
264
  **카드에서는 이 컬럼이 그리지 않는다.** 본문에 한 줄로 두었더니 태그가 있는 카드만
265
- 높아져 격자가 어긋났다 — 개수가 도형마다 다르므로 본문에 두는 한 남는 문제다.
265
+ 높아져 격자가 어긋났다 — 개수가 피규어마다 다르므로 본문에 두는 한 남는 문제다.
266
266
  카드에서는 `figure-thumb` 이 그림 위에 얹는다. 여기 남은 것은 표 모드의 칸이다.
267
267
  */
268
268
  type: 'string',