@things-factory/figure-ui 10.1.75 → 10.1.76

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 (235) hide show
  1. package/client/figure-assistant.ts +3 -3
  2. package/client/graphql/{v3-store.ts → store.ts} +6 -6
  3. package/client/modeller/{v3-ai-proposal.ts → ai-proposal.ts} +8 -8
  4. package/client/modeller/{v3-align.ts → align.ts} +14 -14
  5. package/client/modeller/{v3-canvas.ts → canvas.ts} +13 -13
  6. package/client/modeller/{v3-clips.ts → clips.ts} +5 -5
  7. package/client/modeller/{v3-controls.ts → controls.ts} +2 -2
  8. package/client/modeller/{v3-editor.ts → editor.ts} +117 -117
  9. package/client/modeller/{figure-v3-capability.ts → figure-capability-panel.ts} +7 -7
  10. package/client/modeller/{figure-v3-clips.ts → figure-clips.ts} +10 -10
  11. package/client/modeller/{figure-v3-controls.ts → figure-controls.ts} +9 -9
  12. package/client/modeller/{v3-figure-facts.ts → figure-facts.ts} +11 -11
  13. package/client/modeller/{figure-v3-first-save.ts → figure-first-save.ts} +3 -3
  14. package/client/modeller/figure-history-panel.ts +1 -1
  15. package/client/modeller/{figure-v3-links.ts → figure-links.ts} +35 -35
  16. package/client/modeller/{figure-v3-material.ts → figure-material-panel.ts} +20 -20
  17. package/client/modeller/{figure-v3-parts.ts → figure-parts.ts} +15 -15
  18. package/client/modeller/{figure-v3-preview.ts → figure-preview.ts} +14 -14
  19. package/client/modeller/{figure-v3-properties.ts → figure-properties.ts} +25 -25
  20. package/client/modeller/{figure-v3-recipe-catalog.ts → figure-recipe-catalog.ts} +10 -10
  21. package/client/modeller/{figure-v3-verdict.ts → figure-verdict.ts} +24 -24
  22. package/client/modeller/gate-findings.ts +2 -2
  23. package/client/modeller/{v3-gizmo.ts → gizmo.ts} +11 -11
  24. package/client/modeller/{v3-joint-drag.ts → joint-drag.ts} +11 -11
  25. package/client/modeller/{v3-joint-fan.ts → joint-fan.ts} +13 -13
  26. package/client/modeller/{v3-links.ts → links.ts} +59 -59
  27. package/client/modeller/{v3-live.ts → live.ts} +9 -9
  28. package/client/modeller/{v3-maturity.ts → maturity.ts} +65 -65
  29. package/client/modeller/modeller-route.ts +1 -1
  30. package/client/modeller/{v3-occupancy.ts → occupancy.ts} +6 -6
  31. package/client/modeller/{v3-palette.ts → palette.ts} +3 -3
  32. package/client/modeller/{v3-preview-model.ts → preview-model.ts} +8 -8
  33. package/client/modeller/{v3-product-session.ts → product-session.ts} +25 -25
  34. package/client/modeller/{v3-recipe-source.ts → recipe-source.ts} +2 -2
  35. package/client/modeller/{v3-recipes.ts → recipes.ts} +9 -9
  36. package/client/modeller/{v3-renderer.ts → renderer.ts} +16 -16
  37. package/client/modeller/{v3-stage-model.ts → stage-model.ts} +15 -15
  38. package/client/modeller/{v3-thumbnail.ts → thumbnail.ts} +8 -8
  39. package/client/pages/figure-list-page.ts +4 -4
  40. package/client/pages/{figure-v3-modeller-page.ts → figure-modeller-page.ts} +37 -37
  41. package/client/route.ts +1 -5
  42. package/dist-client/figure-assistant.js +3 -3
  43. package/dist-client/figure-assistant.js.map +1 -1
  44. package/dist-client/graphql/store.d.ts +3 -0
  45. package/dist-client/graphql/store.js +39 -0
  46. package/dist-client/graphql/store.js.map +1 -0
  47. package/dist-client/modeller/ai-proposal.d.ts +51 -0
  48. package/dist-client/modeller/ai-proposal.js +64 -0
  49. package/dist-client/modeller/ai-proposal.js.map +1 -0
  50. package/dist-client/modeller/align.d.ts +30 -0
  51. package/dist-client/modeller/align.js +75 -0
  52. package/dist-client/modeller/align.js.map +1 -0
  53. package/dist-client/modeller/canvas.d.ts +72 -0
  54. package/dist-client/modeller/canvas.js +379 -0
  55. package/dist-client/modeller/canvas.js.map +1 -0
  56. package/dist-client/modeller/clips.d.ts +39 -0
  57. package/dist-client/modeller/clips.js +58 -0
  58. package/dist-client/modeller/clips.js.map +1 -0
  59. package/dist-client/modeller/controls.d.ts +28 -0
  60. package/dist-client/modeller/controls.js +28 -0
  61. package/dist-client/modeller/controls.js.map +1 -0
  62. package/dist-client/modeller/editor.d.ts +203 -0
  63. package/dist-client/modeller/editor.js +1526 -0
  64. package/dist-client/modeller/editor.js.map +1 -0
  65. package/dist-client/modeller/fields.d.ts +45 -0
  66. package/dist-client/modeller/fields.js +83 -0
  67. package/dist-client/modeller/fields.js.map +1 -0
  68. package/dist-client/modeller/figure-capability-panel.d.ts +22 -0
  69. package/dist-client/modeller/figure-capability-panel.js +141 -0
  70. package/dist-client/modeller/figure-capability-panel.js.map +1 -0
  71. package/dist-client/modeller/figure-clips.d.ts +31 -0
  72. package/dist-client/modeller/figure-clips.js +268 -0
  73. package/dist-client/modeller/figure-clips.js.map +1 -0
  74. package/dist-client/modeller/figure-controls.d.ts +36 -0
  75. package/dist-client/modeller/figure-controls.js +226 -0
  76. package/dist-client/modeller/figure-controls.js.map +1 -0
  77. package/dist-client/modeller/figure-facts.d.ts +35 -0
  78. package/dist-client/modeller/figure-facts.js +55 -0
  79. package/dist-client/modeller/figure-facts.js.map +1 -0
  80. package/dist-client/modeller/figure-first-save.d.ts +20 -0
  81. package/dist-client/modeller/figure-first-save.js +118 -0
  82. package/dist-client/modeller/figure-first-save.js.map +1 -0
  83. package/dist-client/modeller/figure-history-panel.d.ts +1 -1
  84. package/dist-client/modeller/figure-history-panel.js.map +1 -1
  85. package/dist-client/modeller/figure-links.d.ts +77 -0
  86. package/dist-client/modeller/figure-links.js +649 -0
  87. package/dist-client/modeller/figure-links.js.map +1 -0
  88. package/dist-client/modeller/figure-material-panel.d.ts +39 -0
  89. package/dist-client/modeller/figure-material-panel.js +323 -0
  90. package/dist-client/modeller/figure-material-panel.js.map +1 -0
  91. package/dist-client/modeller/figure-parts.d.ts +69 -0
  92. package/dist-client/modeller/figure-parts.js +559 -0
  93. package/dist-client/modeller/figure-parts.js.map +1 -0
  94. package/dist-client/modeller/figure-preview.d.ts +34 -0
  95. package/dist-client/modeller/figure-preview.js +346 -0
  96. package/dist-client/modeller/figure-preview.js.map +1 -0
  97. package/dist-client/modeller/figure-properties.d.ts +45 -0
  98. package/dist-client/modeller/figure-properties.js +239 -0
  99. package/dist-client/modeller/figure-properties.js.map +1 -0
  100. package/dist-client/modeller/figure-recipe-catalog.d.ts +38 -0
  101. package/dist-client/modeller/figure-recipe-catalog.js +399 -0
  102. package/dist-client/modeller/figure-recipe-catalog.js.map +1 -0
  103. package/dist-client/modeller/figure-verdict.d.ts +64 -0
  104. package/dist-client/modeller/figure-verdict.js +787 -0
  105. package/dist-client/modeller/figure-verdict.js.map +1 -0
  106. package/dist-client/modeller/first-save.d.ts +17 -0
  107. package/dist-client/modeller/first-save.js +26 -0
  108. package/dist-client/modeller/first-save.js.map +1 -0
  109. package/dist-client/modeller/gate-findings.d.ts +2 -2
  110. package/dist-client/modeller/gate-findings.js +2 -2
  111. package/dist-client/modeller/gate-findings.js.map +1 -1
  112. package/dist-client/modeller/gizmo.d.ts +72 -0
  113. package/dist-client/modeller/gizmo.js +111 -0
  114. package/dist-client/modeller/gizmo.js.map +1 -0
  115. package/dist-client/modeller/help.d.ts +18 -0
  116. package/dist-client/modeller/help.js +37 -0
  117. package/dist-client/modeller/help.js.map +1 -0
  118. package/dist-client/modeller/joint-drag.d.ts +19 -0
  119. package/dist-client/modeller/joint-drag.js +97 -0
  120. package/dist-client/modeller/joint-drag.js.map +1 -0
  121. package/dist-client/modeller/joint-fan.d.ts +9 -0
  122. package/dist-client/modeller/joint-fan.js +276 -0
  123. package/dist-client/modeller/joint-fan.js.map +1 -0
  124. package/dist-client/modeller/keys.d.ts +22 -0
  125. package/dist-client/modeller/keys.js +26 -0
  126. package/dist-client/modeller/keys.js.map +1 -0
  127. package/dist-client/modeller/links.d.ts +267 -0
  128. package/dist-client/modeller/links.js +480 -0
  129. package/dist-client/modeller/links.js.map +1 -0
  130. package/dist-client/modeller/live.d.ts +37 -0
  131. package/dist-client/modeller/live.js +68 -0
  132. package/dist-client/modeller/live.js.map +1 -0
  133. package/dist-client/modeller/maturity.d.ts +120 -0
  134. package/dist-client/modeller/maturity.js +313 -0
  135. package/dist-client/modeller/maturity.js.map +1 -0
  136. package/dist-client/modeller/modeller-route.d.ts +1 -1
  137. package/dist-client/modeller/modeller-route.js +1 -1
  138. package/dist-client/modeller/modeller-route.js.map +1 -1
  139. package/dist-client/modeller/occupancy.d.ts +18 -0
  140. package/dist-client/modeller/occupancy.js +24 -0
  141. package/dist-client/modeller/occupancy.js.map +1 -0
  142. package/dist-client/modeller/palette.d.ts +7 -0
  143. package/dist-client/modeller/palette.js +46 -0
  144. package/dist-client/modeller/palette.js.map +1 -0
  145. package/dist-client/modeller/preview-model.d.ts +47 -0
  146. package/dist-client/modeller/preview-model.js +68 -0
  147. package/dist-client/modeller/preview-model.js.map +1 -0
  148. package/dist-client/modeller/product-session.d.ts +510 -0
  149. package/dist-client/modeller/product-session.js +157 -0
  150. package/dist-client/modeller/product-session.js.map +1 -0
  151. package/dist-client/modeller/recipe-source.d.ts +8 -0
  152. package/dist-client/modeller/recipe-source.js +14 -0
  153. package/dist-client/modeller/recipe-source.js.map +1 -0
  154. package/dist-client/modeller/recipes.d.ts +37 -0
  155. package/dist-client/modeller/recipes.js +103 -0
  156. package/dist-client/modeller/recipes.js.map +1 -0
  157. package/dist-client/modeller/refusals.d.ts +68 -0
  158. package/dist-client/modeller/refusals.js +142 -0
  159. package/dist-client/modeller/refusals.js.map +1 -0
  160. package/dist-client/modeller/renderer.d.ts +40 -0
  161. package/dist-client/modeller/renderer.js +73 -0
  162. package/dist-client/modeller/renderer.js.map +1 -0
  163. package/dist-client/modeller/stage-model.d.ts +39 -0
  164. package/dist-client/modeller/stage-model.js +147 -0
  165. package/dist-client/modeller/stage-model.js.map +1 -0
  166. package/dist-client/modeller/thumbnail.d.ts +3 -0
  167. package/dist-client/modeller/thumbnail.js +75 -0
  168. package/dist-client/modeller/thumbnail.js.map +1 -0
  169. package/dist-client/pages/figure-list-page.d.ts +1 -1
  170. package/dist-client/pages/figure-list-page.js +4 -4
  171. package/dist-client/pages/figure-list-page.js.map +1 -1
  172. package/dist-client/pages/figure-modeller-page.d.ts +102 -0
  173. package/dist-client/pages/figure-modeller-page.js +548 -0
  174. package/dist-client/pages/figure-modeller-page.js.map +1 -0
  175. package/dist-client/route.d.ts +1 -1
  176. package/dist-client/route.js +1 -5
  177. package/dist-client/route.js.map +1 -1
  178. package/dist-client/tsconfig.tsbuildinfo +1 -1
  179. package/docs/product-cutover.md +25 -0
  180. package/package.json +5 -5
  181. package/test/{v3-ai-proposal.test.ts → ai-proposal.test.ts} +6 -6
  182. package/test/{v3-align.test.ts → align.test.ts} +8 -8
  183. package/test/browser/modeller-page.js +30 -30
  184. package/test/browser/modeller.check.mjs +14 -14
  185. package/test/browser/serve.mjs +1 -1
  186. package/test/browser/thumbnail-page.js +6 -6
  187. package/test/{v3-clips.test.ts → clips.test.ts} +18 -18
  188. package/test/{v3-controls.test.ts → controls.test.ts} +15 -15
  189. package/test/{v3-fields.test.ts → fields.test.ts} +13 -13
  190. package/test/figure-assistant-surface.test.ts +3 -3
  191. package/test/{v3-first-save.test.ts → first-save.test.ts} +10 -10
  192. package/test/fixtures/joint-column.json +2 -2
  193. package/test/fixtures/joint-roller.json +2 -2
  194. package/test/fixtures/robot-arm-6dof.json +2 -2
  195. package/test/{v3-gizmo.test.ts → gizmo.test.ts} +33 -33
  196. package/test/{v3-joint-drag.test.ts → joint-drag.test.ts} +17 -17
  197. package/test/{v3-joint-fan.test.ts → joint-fan.test.ts} +18 -18
  198. package/test/joints.ts +6 -6
  199. package/test/{v3-keys.test.ts → keys.test.ts} +2 -2
  200. package/test/{v3-layout.test.ts → layout.test.ts} +8 -8
  201. package/test/{v3-links.test.ts → links.test.ts} +201 -201
  202. package/test/{v3-live.test.ts → live.test.ts} +18 -18
  203. package/test/{v3-material.test.ts → material.test.ts} +12 -12
  204. package/test/{v3-maturity.test.ts → maturity.test.ts} +74 -74
  205. package/test/modeller-route.test.ts +5 -6
  206. package/test/{v3-palette-icons.test.ts → palette-icons.test.ts} +1 -1
  207. package/test/{v3-parts-wiring.test.ts → parts-wiring.test.ts} +5 -5
  208. package/test/{v3-preview.test.ts → preview.test.ts} +12 -12
  209. package/test/{v3-product-session.test.ts → product-session.test.ts} +17 -17
  210. package/test/{v3-product-write.test.ts → product-write.test.ts} +20 -20
  211. package/test/{v3-properties.test.ts → properties.test.ts} +24 -24
  212. package/test/{v3-recipes.test.ts → recipes.test.ts} +9 -9
  213. package/test/{v3-refusals.test.ts → refusals.test.ts} +43 -43
  214. package/test/{v3-release-panel.test.ts → release-panel.test.ts} +21 -21
  215. package/test/renderer.test.ts +24 -0
  216. package/test/resolve-ts-siblings.mjs +1 -1
  217. package/test/{v3-scene-canvas.test.ts → scene-canvas.test.ts} +6 -6
  218. package/test/{v3-stage-model.test.ts → stage-model.test.ts} +5 -5
  219. package/test/{v3-theme.test.ts → theme.test.ts} +4 -4
  220. package/test/{v3-thumbnail.test.ts → thumbnail.test.ts} +4 -4
  221. package/test/{v3-verdict.test.ts → verdict.test.ts} +17 -17
  222. package/test/{v3-view.test.ts → view.test.ts} +2 -2
  223. package/things-factory.config.js +2 -3
  224. package/translations/en.json +2 -2
  225. package/translations/ja.json +2 -2
  226. package/translations/ko.json +2 -2
  227. package/translations/ms.json +2 -2
  228. package/translations/zh.json +2 -2
  229. package/docs/v3-product-cutover.md +0 -25
  230. package/test/v3-renderer.test.ts +0 -24
  231. /package/client/modeller/{v3-fields.ts → fields.ts} +0 -0
  232. /package/client/modeller/{v3-first-save.ts → first-save.ts} +0 -0
  233. /package/client/modeller/{v3-help.ts → help.ts} +0 -0
  234. /package/client/modeller/{v3-keys.ts → keys.ts} +0 -0
  235. /package/client/modeller/{v3-refusals.ts → refusals.ts} +0 -0
@@ -4,41 +4,41 @@ import type { OxThreePane } from '@operato/layout'
4
4
  import '@operato/layout'
5
5
  import { customElement, property, state } from 'lit/decorators.js'
6
6
  import { live } from 'lit/directives/live.js'
7
- import { PART_LIMIT, parseV3Recipe, resolveV3Recipe, v3PartCountOf, v3RecipeIdFor } from '@hatiolab/figure-model'
8
- import type { RecipeTemplate } from './v3-recipes.js'
9
- import './figure-v3-recipe-catalog.js'
10
- import type { V3Asset, V3AuthoringAction, V3InputChange, V3PartEdit, V3PrimitiveCreation, V3ProposalStep, V3Recipe, V3RecipeValue } from '@hatiolab/figure-model'
11
- import type { V3ProductSession } from './v3-product-session.js'
12
- import { captureV3Thumbnail } from './v3-thumbnail.js'
13
- import { drawableV3Parts } from './v3-renderer.js'
14
- import './v3-canvas.js'
15
- import './figure-v3-parts.js'
16
- import './figure-v3-material.js'
17
- import './figure-v3-links.js'
18
- import './figure-v3-controls.js'
19
- import './figure-v3-clips.js'
20
- import './figure-v3-preview.js'
7
+ import { PART_LIMIT, parseFigureRecipe, resolveFigureRecipe, figurePartCountOf, figureRecipeIdFor } from '@hatiolab/figure-model'
8
+ import type { RecipeTemplate } from './recipes.js'
9
+ import './figure-recipe-catalog.js'
10
+ import type { FigureAsset, FigureAuthoringAction, FigureInputChange, FigurePartEdit, FigurePrimitiveCreation, FigureProposalStep, FigureRecipe, FigureRecipeValue } from '@hatiolab/figure-model'
11
+ import type { FigureProductSession } from './product-session.js'
12
+ import { captureFigureThumbnail } from './thumbnail.js'
13
+ import { drawableFigureParts } from './renderer.js'
14
+ import './canvas.js'
15
+ import './figure-parts.js'
16
+ import './figure-material-panel.js'
17
+ import './figure-links.js'
18
+ import './figure-controls.js'
19
+ import './figure-clips.js'
20
+ import './figure-preview.js'
21
21
  import './figure-settings.js'
22
22
  import { DEFAULT_VIEW, type ViewSettings } from './figure-view.js'
23
- import './figure-v3-capability.js'
24
- import { gizmoChanges, gizmoReachOf, keepBottomChanges, type GizmoReach, type GizmoResult } from './v3-gizmo.js'
25
- import { keyActionOf } from './v3-keys.js'
26
- import { groupFields, ownerOf, partLabelOf, repeatOf, type FieldLike, type FieldGroup } from './v3-fields.js'
23
+ import './figure-capability-panel.js'
24
+ import { gizmoChanges, gizmoReachOf, keepBottomChanges, type GizmoReach, type GizmoResult } from './gizmo.js'
25
+ import { keyActionOf } from './keys.js'
26
+ import { groupFields, ownerOf, partLabelOf, repeatOf, type FieldLike, type FieldGroup } from './fields.js'
27
27
  import { SidePanelStyles } from './side-panel-styles.js'
28
28
  import { ScrollbarStyles } from '@operato/styles'
29
- import { alignChanges, boxOf, canMirror, mirrorChanges, type AlignTool } from './v3-align.js'
30
- import type { V3PaletteKind, V3PartRow } from './figure-v3-parts.js'
31
- import { paletteRecipe } from './v3-palette.js'
32
- import type { FigureV3Canvas } from './v3-canvas.js'
33
- import { nudgeOf } from './v3-stage-model.js'
34
- import { editRefusalOf, inDeclaredRoom, inputRangeRefusalOf, narrowingRetryOf, partRefusalOf, placementRefusalOf, recipeRefusalOf, removalNoticeOf, sizeRangeRefusalOf } from './v3-refusals.js'
35
- import type { V3RenderPart } from './v3-renderer.js'
36
- import type { V3BudgetLine } from './v3-maturity.js'
37
- import { instanceRangeOf, instanceRangeToDeclare, proportionToFollow, rangeDiffers, rangeWith, turnsAboutAJoint, valueNow } from './v3-links.js'
38
- import { jointFanOf } from './v3-joint-fan.js'
39
- import { jointDragOf } from './v3-joint-drag.js'
40
- import type { FirstSave } from './v3-first-save.js'
41
- import { isLive, livePartsOf, liveOverSession, NOTHING_LIVE, scrubbed, scrubStep, type LiveValues } from './v3-live.js'
29
+ import { alignChanges, boxOf, canMirror, mirrorChanges, type AlignTool } from './align.js'
30
+ import type { FigurePaletteKind, FigurePartRow } from './figure-parts.js'
31
+ import { paletteRecipe } from './palette.js'
32
+ import type { FigureCanvas } from './canvas.js'
33
+ import { nudgeOf } from './stage-model.js'
34
+ import { editRefusalOf, inDeclaredRoom, inputRangeRefusalOf, narrowingRetryOf, partRefusalOf, placementRefusalOf, recipeRefusalOf, removalNoticeOf, sizeRangeRefusalOf } from './refusals.js'
35
+ import type { FigureRenderPart } from './renderer.js'
36
+ import type { FigureBudgetLine } from './maturity.js'
37
+ import { instanceRangeOf, instanceRangeToDeclare, proportionToFollow, rangeDiffers, rangeWith, turnsAboutAJoint, valueNow } from './links.js'
38
+ import { jointFanOf } from './joint-fan.js'
39
+ import { jointDragOf } from './joint-drag.js'
40
+ import type { FirstSave } from './first-save.js'
41
+ import { isLive, livePartsOf, liveOverSession, NOTHING_LIVE, scrubbed, scrubStep, type LiveValues } from './live.js'
42
42
 
43
43
 
44
44
  /**
@@ -48,8 +48,8 @@ import { isLive, livePartsOf, liveOverSession, NOTHING_LIVE, scrubbed, scrubStep
48
48
  type SideTab = 'properties' | 'capability' | 'motion' | 'verdict' | 'view' | 'history'
49
49
 
50
50
  /** Product editor surface. The injected session is shared by page persistence and AI commands. */
51
- @customElement('figure-v3-editor')
52
- export class FigureV3Editor extends LitElement {
51
+ @customElement('figure-editor')
52
+ export class FigureEditor extends LitElement {
53
53
  /* The operato scrollbar, as every scrolling panel of the app has it -- the side panel scrolled with the browser's own. */
54
54
  static styles = [ScrollbarStyles, SidePanelStyles, css`
55
55
  :host {
@@ -105,7 +105,7 @@ export class FigureV3Editor extends LitElement {
105
105
  opacity: 0.38;
106
106
  cursor: default;
107
107
  }
108
- figure-v3-preview {
108
+ figure-preview {
109
109
  min-width: 0;
110
110
  min-height: 0;
111
111
  }
@@ -131,10 +131,10 @@ export class FigureV3Editor extends LitElement {
131
131
  flex: 1;
132
132
  min-height: 0;
133
133
  }
134
- figure-v3-parts {
134
+ figure-parts {
135
135
  min-height: 0;
136
136
  }
137
- figure-v3-canvas {
137
+ figure-canvas {
138
138
  min-width: 0;
139
139
  min-height: 0;
140
140
  }
@@ -263,7 +263,7 @@ export class FigureV3Editor extends LitElement {
263
263
  line-height: 1.5;
264
264
  }
265
265
  `]
266
- @property({ attribute: false }) session?: V3ProductSession
266
+ @property({ attribute: false }) session?: FigureProductSession
267
267
  /** The recipe templates (ADR-0095), read by the page from the server. */
268
268
  @property({ attribute: false }) templates: RecipeTemplate[] = []
269
269
  /** Reads a template's guide; given by the page. */
@@ -278,7 +278,7 @@ export class FigureV3Editor extends LitElement {
278
278
  /** The verdict's count, drawn on its tab so it stays in sight while another tab is open. */
279
279
  @property({ type: Number }) instances?: number
280
280
  /** The cost line the parts list shows, from the maturity report. */
281
- @property({ attribute: false }) budget?: V3BudgetLine
281
+ @property({ attribute: false }) budget?: FigureBudgetLine
282
282
  /**
283
283
  * Asks the type and name of a figure saved for the first time (the host has the catalogue's names); undefined
284
284
  * when the author cancels, and then nothing is saved. Without it a new figure is saved under a temporary type.
@@ -287,7 +287,7 @@ export class FigureV3Editor extends LitElement {
287
287
  @state() private selected = ''
288
288
  @state() private error = ''
289
289
  /** The same link offered again with the size range narrowed, after a link the declared range could not hold. */
290
- @state() private retry?: { label: string; action?: V3AuthoringAction; run?: () => void }
290
+ @state() private retry?: { label: string; action?: FigureAuthoringAction; run?: () => void }
291
291
  @state() private tab: SideTab = 'properties'
292
292
  /** The frame the bar folds - found after the first render, since the bar is drawn before it. */
293
293
  @state() private panes?: OxThreePane
@@ -301,10 +301,10 @@ export class FigureV3Editor extends LitElement {
301
301
  * How the workbench shows the figure, in the board's own state names. The viewer's, kept in
302
302
  * their browser, never in the figure.
303
303
  */
304
- @state() private view: ViewSettings = FigureV3Editor.storedView()
304
+ @state() private view: ViewSettings = FigureEditor.storedView()
305
305
  private static storedView(): ViewSettings {
306
306
  try {
307
- const stored = JSON.parse(localStorage.getItem('figure-v3-view') ?? 'null')
307
+ const stored = JSON.parse(localStorage.getItem('figure-view') ?? 'null')
308
308
  return stored && typeof stored === 'object' ? { ...DEFAULT_VIEW, ...stored } : { ...DEFAULT_VIEW }
309
309
  } catch {
310
310
  return { ...DEFAULT_VIEW }
@@ -313,7 +313,7 @@ export class FigureV3Editor extends LitElement {
313
313
  private setView(view: ViewSettings) {
314
314
  this.view = { ...DEFAULT_VIEW, ...view }
315
315
  try {
316
- localStorage.setItem('figure-v3-view', JSON.stringify(this.view))
316
+ localStorage.setItem('figure-view', JSON.stringify(this.view))
317
317
  } catch {
318
318
  /* A browser that keeps nothing still shows the change for this visit. */
319
319
  }
@@ -353,11 +353,11 @@ export class FigureV3Editor extends LitElement {
353
353
  )}
354
354
  </span>`
355
355
  }
356
- /** The modeller's keys (`v3-keys.ts`): undo, redo, duplicate, remove, back to the whole figure, the gizmo's modes. */
356
+ /** The modeller's keys (`keys.ts`): undo, redo, duplicate, remove, back to the whole figure, the gizmo's modes. */
357
357
  private onKey = (e: KeyboardEvent) => {
358
358
  const view = this.session?.read()
359
359
  if (!view || view.loading || view.saving || !view.context || !this.isConnected) return
360
- const canvas = this.renderRoot.querySelector<FigureV3Canvas>('figure-v3-canvas')
360
+ const canvas = this.renderRoot.querySelector<FigureCanvas>('figure-canvas')
361
361
  const path = e.composedPath()
362
362
  const action = keyActionOf(
363
363
  { key: e.key, ctrlKey: e.ctrlKey, metaKey: e.metaKey, shiftKey: e.shiftKey, altKey: e.altKey, target: path[0] as HTMLElement, inScene: !!canvas && path.includes(canvas) },
@@ -399,7 +399,7 @@ export class FigureV3Editor extends LitElement {
399
399
  }
400
400
  /** The scene toggles: the mode already shown takes the gizmo away. */
401
401
  private useGizmo(mode: 'translate' | 'rotate' | 'scale') {
402
- this.renderRoot.querySelector<FigureV3Canvas>('figure-v3-canvas')?.gizmo(mode)
402
+ this.renderRoot.querySelector<FigureCanvas>('figure-canvas')?.gizmo(mode)
403
403
  this.gizmoMode = this.gizmoMode === mode ? undefined : mode
404
404
  }
405
405
  /**
@@ -425,15 +425,15 @@ export class FigureV3Editor extends LitElement {
425
425
  }
426
426
  }
427
427
  /** What the canvas draws: the figure with the value in hand when there is one, and without the parts hidden on the workbench. */
428
- private drawnParts(geometry: Parameters<typeof drawableV3Parts>[0] | undefined, asset: unknown) {
429
- const parts = (asset ? liveOverSession(asset as V3Asset, this.currentInputs(), this.live) : null) ?? drawableV3Parts(geometry ?? [])
428
+ private drawnParts(geometry: Parameters<typeof drawableFigureParts>[0] | undefined, asset: unknown) {
429
+ const parts = (asset ? liveOverSession(asset as FigureAsset, this.currentInputs(), this.live) : null) ?? drawableFigureParts(geometry ?? [])
430
430
  return parts.filter(body => !this.hiddenParts.has(ownerOf((body as { id: string }).id)))
431
431
  }
432
432
  /**
433
433
  * Where the selected part turns and how far, with the pose as it is drawn now -- a value in hand included, so the
434
- * fan follows the arm while a control is dragged. Its size comes from what the joint turns (`v3-joint-fan`).
434
+ * fan follows the arm while a control is dragged. Its size comes from what the joint turns (`joint-fan`).
435
435
  */
436
- private fanOf(asset: V3Asset | undefined) {
436
+ private fanOf(asset: FigureAsset | undefined) {
437
437
  if (!asset || !this.selected || this.hiddenParts.has(this.selected)) return null
438
438
  try {
439
439
  return jointFanOf(asset, this.selected, { ...this.currentInputs(), ...this.live.values })
@@ -451,12 +451,12 @@ export class FigureV3Editor extends LitElement {
451
451
  return view ? Object.fromEntries(view.fields.map(field => [field.id, field.value as number])) : {}
452
452
  }
453
453
  /** A value in hand: an input's value (design or pose) or a part edit. Nothing is recorded. */
454
- private hold(values: Record<string, number>, edit?: V3PartEdit) {
454
+ private hold(values: Record<string, number>, edit?: FigurePartEdit) {
455
455
  this.live = { values: { ...this.live.values, ...values }, ...(edit ? { edit } : this.live.edit ? { edit: this.live.edit } : {}) }
456
456
  }
457
457
  private changed() {
458
458
  this.requestUpdate()
459
- this.dispatchEvent(new CustomEvent('v3-changed', { bubbles: true, composed: true }))
459
+ this.dispatchEvent(new CustomEvent('changed', { bubbles: true, composed: true }))
460
460
  }
461
461
  private async save() {
462
462
  if (!this.session) return
@@ -464,7 +464,7 @@ export class FigureV3Editor extends LitElement {
464
464
  /*
465
465
  The card's picture is taken before the save starts, from a canvas of its own at the card's size —
466
466
  not from the one on screen, which stands wherever the author left it turned. A picture that cannot
467
- be taken is not an error: the save goes on without it (see `v3-thumbnail.ts`).
467
+ be taken is not an error: the save goes on without it (see `thumbnail.ts`).
468
468
  */
469
469
  let type: string | undefined
470
470
  if (!this.session.read().id && this.firstSave) {
@@ -478,7 +478,7 @@ export class FigureV3Editor extends LitElement {
478
478
  type = answer.type
479
479
  }
480
480
  const view = this.session.read()
481
- const thumbnail = await captureV3Thumbnail(drawableV3Parts(view.geometry ?? []), view.palette ?? {})
481
+ const thumbnail = await captureFigureThumbnail(drawableFigureParts(view.geometry ?? []), view.palette ?? {})
482
482
  const promise = this.session.save({ thumbnail, type })
483
483
  this.changed()
484
484
  await promise
@@ -489,7 +489,7 @@ export class FigureV3Editor extends LitElement {
489
489
  this.changed()
490
490
  }
491
491
  }
492
- private add(kind: V3PaletteKind) {
492
+ private add(kind: FigurePaletteKind) {
493
493
  if (!this.session) return
494
494
  this.run(() => {
495
495
  const ids = new Set(this.session!.read().geometry.map(g => g.id))
@@ -501,7 +501,7 @@ export class FigureV3Editor extends LitElement {
501
501
  })
502
502
  }
503
503
  /**
504
- * The list's own operations, as V3 part edits — each one step of the session's history. The copy and the moved
504
+ * The list's own operations, as part edits — each one step of the session's history. The copy and the moved
505
505
  * part stay selected.
506
506
  */
507
507
  private duplicatePart(id: string) {
@@ -545,12 +545,12 @@ export class FigureV3Editor extends LitElement {
545
545
  * A recipe put in (ADR-0095): resolved on the figure as it stands -- its parts take the next free name, onto the part
546
546
  * chosen -- and applied as one step. Refused, the kernel's sentence goes to the form as it is (condition 3).
547
547
  */
548
- private insertRecipe(recipe: V3Recipe, values: Record<string, V3RecipeValue>) {
548
+ private insertRecipe(recipe: FigureRecipe, values: Record<string, FigureRecipeValue>) {
549
549
  try {
550
- const asset = JSON.parse(this.session!.source()) as V3Asset
551
- const checked = parseV3Recipe(recipe)
552
- const id = v3RecipeIdFor(asset, checked)
553
- const steps = resolveV3Recipe(checked, { id, ...(checked.target === 'part' ? { target: this.selected } : {}), values })
550
+ const asset = JSON.parse(this.session!.source()) as FigureAsset
551
+ const checked = parseFigureRecipe(recipe)
552
+ const id = figureRecipeIdFor(asset, checked)
553
+ const steps = resolveFigureRecipe(checked, { id, ...(checked.target === 'part' ? { target: this.selected } : {}), values })
554
554
  this.session!.applyRecipe(steps)
555
555
  this.recipeError = ''
556
556
  this.catalogOpen = false
@@ -583,8 +583,8 @@ export class FigureV3Editor extends LitElement {
583
583
  private transformed(id: string, result: GizmoResult) {
584
584
  const view = this.session!.read()
585
585
  /* A part hanging from a joint: the drag edits the joint -- its value, or where it sits (ADR-0093). */
586
- const asset = JSON.parse(this.session!.source()) as V3Asset
587
- const drawn = view.geometry.find(g => g.id === id) as unknown as V3RenderPart | undefined
586
+ const asset = JSON.parse(this.session!.source()) as FigureAsset
587
+ const drawn = view.geometry.find(g => g.id === id) as unknown as FigureRenderPart | undefined
588
588
  const drag = drawn ? jointDragOf(asset, ownerOf(id), drawn, result, this.currentInputs()) : null
589
589
  if (drag) {
590
590
  if (drag.kind === 'value') this.run(() => this.session!.apply([{ kind: 'set-state', input: drag.input, unit: drag.unit, value: drag.value }]))
@@ -618,7 +618,7 @@ export class FigureV3Editor extends LitElement {
618
618
  its rule (`nudge-part`). A part a joint or a fastening places, or a size that is worked out, is refused -- said in
619
619
  words, not by the part silently springing back (user, 2026-09-24: 「기즈모 컨트롤도 전혀 작동이 안되는군」).
620
620
  */
621
- const body = view.geometry.find(g => g.id === id) as unknown as V3RenderPart | undefined
621
+ const body = view.geometry.find(g => g.id === id) as unknown as FigureRenderPart | undefined
622
622
  if (!body) return this.requestUpdate()
623
623
  const { by, turn } = nudgeOf(body, result)
624
624
  /* A size worked out from the figure's: the drag's factor beside its rule, so it still follows. */
@@ -745,15 +745,15 @@ export class FigureV3Editor extends LitElement {
745
745
  } catch {
746
746
  dims = undefined
747
747
  }
748
- return html`<figure-v3-links
748
+ return html`<figure-links
749
749
  .asset=${asset}
750
750
  .section=${section}
751
751
  .partId=${this.selected}
752
752
  .dims=${dims}
753
753
  ?locked=${unavailable}
754
- @v3-command=${(e: CustomEvent) => this.linkCommand(e.detail.action)}
755
- @v3-part-edit=${(e: CustomEvent) => this.run(() => this.session!.edit(e.detail.edit))}
756
- ></figure-v3-links>`
754
+ @command=${(e: CustomEvent) => this.linkCommand(e.detail.action)}
755
+ @part-edit=${(e: CustomEvent) => this.run(() => this.session!.edit(e.detail.edit))}
756
+ ></figure-links>`
757
757
  }
758
758
  /** The figure's controls: try a value, name it, set its range and travel time, keep the pose. */
759
759
  private renderControls(view: { fields: Array<{ id: string; role?: string; value: number }> }, unavailable: boolean) {
@@ -764,25 +764,25 @@ export class FigureV3Editor extends LitElement {
764
764
  return null
765
765
  }
766
766
  const values = Object.fromEntries(view.fields.filter(f => f.role === 'state').map(f => [f.id, f.value]))
767
- return html`<figure-v3-controls
767
+ return html`<figure-controls
768
768
  .asset=${asset}
769
769
  .values=${values}
770
770
  ?locked=${unavailable}
771
- @v3-state=${(e: CustomEvent) => this.run(() => this.session!.apply([{ kind: 'set-state', input: e.detail.input, unit: e.detail.unit, value: e.detail.value }]))}
772
- @v3-state-live=${(e: CustomEvent) => this.hold({ [e.detail.input]: e.detail.value })}
773
- @v3-part-edit=${(e: CustomEvent) => this.run(() => this.session!.edit(e.detail.edit))}
774
- ></figure-v3-controls>
775
- <figure-v3-clips
771
+ @state=${(e: CustomEvent) => this.run(() => this.session!.apply([{ kind: 'set-state', input: e.detail.input, unit: e.detail.unit, value: e.detail.value }]))}
772
+ @state-live=${(e: CustomEvent) => this.hold({ [e.detail.input]: e.detail.value })}
773
+ @part-edit=${(e: CustomEvent) => this.run(() => this.session!.edit(e.detail.edit))}
774
+ ></figure-controls>
775
+ <figure-clips
776
776
  .asset=${asset}
777
777
  .values=${values}
778
778
  ?locked=${unavailable}
779
- @v3-states=${(e: CustomEvent) => this.run(() => this.session!.apply(e.detail.changes))}
780
- @v3-states-live=${(e: CustomEvent) => this.hold(e.detail.values)}
781
- @v3-part-edit=${(e: CustomEvent) => this.run(() => this.session!.edit(e.detail.edit))}
782
- ></figure-v3-clips>`
779
+ @states=${(e: CustomEvent) => this.run(() => this.session!.apply(e.detail.changes))}
780
+ @states-live=${(e: CustomEvent) => this.hold(e.detail.values)}
781
+ @part-edit=${(e: CustomEvent) => this.run(() => this.session!.edit(e.detail.edit))}
782
+ ></figure-clips>`
783
783
  }
784
784
  /** One command, one step of the history. A refusal a person can meet here is said in their words. */
785
- private linkCommand(action: V3AuthoringAction) {
785
+ private linkCommand(action: FigureAuthoringAction) {
786
786
  this.retry = undefined
787
787
  this.notice = ''
788
788
  const hadSize = this.hasSize()
@@ -804,7 +804,7 @@ export class FigureV3Editor extends LitElement {
804
804
  const narrowing = narrowingRetryOf(action, error, (key, params) => i18next.t(key, params))
805
805
  if (narrowing) {
806
806
  this.error = narrowing.message
807
- this.retry = { label: narrowing.label, action: narrowing.retry as V3AuthoringAction }
807
+ this.retry = { label: narrowing.label, action: narrowing.retry as FigureAuthoringAction }
808
808
  return
809
809
  }
810
810
  this.error =
@@ -817,7 +817,7 @@ export class FigureV3Editor extends LitElement {
817
817
  this.said(error)
818
818
  }
819
819
  }
820
- private changeField(field: { id: string; unit: V3InputChange['unit']; role?: string }, event: Event) {
820
+ private changeField(field: { id: string; unit: FigureInputChange['unit']; role?: string }, event: Event) {
821
821
  const input = event.target as HTMLInputElement,
822
822
  value = input.valueAsNumber
823
823
  /* A height typed in keeps the part's bottom where it is, as the scale gizmo does. */
@@ -841,7 +841,7 @@ export class FigureV3Editor extends LitElement {
841
841
  * Drag a field's label (or an axis letter) sideways to scrub its value, as vector tools do: the figure follows the
842
842
  * pointer, and the release records one step. The field's number follows too, so the value in hand is always read.
843
843
  */
844
- private scrub(field: { id: string; unit: V3InputChange['unit']; role?: string; value: number }, down: PointerEvent, unavailable: boolean) {
844
+ private scrub(field: { id: string; unit: FigureInputChange['unit']; role?: string; value: number }, down: PointerEvent, unavailable: boolean) {
845
845
  if (unavailable || down.button !== 0) return
846
846
  const label = down.currentTarget as HTMLElement
847
847
  const input = (label.closest('div[cell]')?.querySelector('input') ?? label.nextElementSibling) as HTMLInputElement | null
@@ -876,7 +876,7 @@ export class FigureV3Editor extends LitElement {
876
876
  /** The measured range, kept for the revision it was measured at: measuring evaluates the figure at its edges. */
877
877
  private range?: { at: string; of: ReturnType<typeof instanceRangeOf>; toDeclare?: ReturnType<typeof instanceRangeToDeclare> }
878
878
  /** The sizes a board may give the figure, and the way to measure them again after its parts changed. */
879
- private renderInstanceRange(asset: V3Asset | undefined, unavailable: boolean) {
879
+ private renderInstanceRange(asset: FigureAsset | undefined, unavailable: boolean) {
880
880
  if (!asset) return nothing
881
881
  /* Another figure, or another step of this one, is measured again. */
882
882
  const at = `${this.session?.read().context ?? ''}:${this.revision}`
@@ -951,7 +951,7 @@ export class FigureV3Editor extends LitElement {
951
951
  * How the figure grows. One ratio (`sizing: 'uniform'`) is said as it is; a figure with joints that has not declared
952
952
  * it is offered it -- a mechanism does not shear -- and the author decides (chief architect's ruling 2026-09-24).
953
953
  */
954
- private renderSizingRule(asset: V3Asset, unavailable: boolean) {
954
+ private renderSizingRule(asset: FigureAsset, unavailable: boolean) {
955
955
  if (asset.sizing === 'uniform') {
956
956
  /* One ratio reaches only what reads the size: every other length is offered to follow it, in one step. */
957
957
  const follow = proportionToFollow(asset)
@@ -973,8 +973,8 @@ export class FigureV3Editor extends LitElement {
973
973
  * The parts list, one row per part the author made: a repeat is one row with how many copies it makes now
974
974
  * (user, 2026-09-24: the conveyor's sixteen rollers were sixteen rows).
975
975
  */
976
- private partRows(geometry: readonly { id: string }[]): V3PartRow[] {
977
- const rows = new Map<string, V3PartRow>()
976
+ private partRows(geometry: readonly { id: string }[]): FigurePartRow[] {
977
+ const rows = new Map<string, FigurePartRow>()
978
978
  for (const g of geometry) {
979
979
  const id = ownerOf(g.id)
980
980
  const row = rows.get(id)
@@ -993,10 +993,10 @@ export class FigureV3Editor extends LitElement {
993
993
  return [...rows.values()]
994
994
  }
995
995
  /** The detail level's part budget for the list's head, from figure-model's count (a repeat once). */
996
- private partBudgetOf(asset: V3Asset | undefined) {
996
+ private partBudgetOf(asset: FigureAsset | undefined) {
997
997
  if (!asset) return undefined
998
998
  try {
999
- return { level: asset.detailLevel ?? null, used: v3PartCountOf(asset), limit: asset.detailLevel ? PART_LIMIT[asset.detailLevel] : null }
999
+ return { level: asset.detailLevel ?? null, used: figurePartCountOf(asset), limit: asset.detailLevel ? PART_LIMIT[asset.detailLevel] : null }
1000
1000
  } catch {
1001
1001
  return undefined
1002
1002
  }
@@ -1006,7 +1006,7 @@ export class FigureV3Editor extends LitElement {
1006
1006
  * The pitch of a row that fills its length is edited as a number (`set-repeat` makes it the part's own the first
1007
1007
  * time); a row of a fixed count says its pitch cannot be set yet (figure-model refuses it the same way).
1008
1008
  */
1009
- private renderRepeat(asset: V3Asset | undefined, geometry: readonly { id: string }[], unavailable: boolean) {
1009
+ private renderRepeat(asset: FigureAsset | undefined, geometry: readonly { id: string }[], unavailable: boolean) {
1010
1010
  const repeat = repeatOf(this.selected, geometry)
1011
1011
  if (!asset || !repeat || repeat.index) return nothing
1012
1012
  /* The row is set on its part; what hangs from that part is copied with it and has no row of its own. */
@@ -1062,7 +1062,7 @@ export class FigureV3Editor extends LitElement {
1062
1062
  </section>`
1063
1063
  }
1064
1064
  /** The design input a row's pitch is read from, when it is read from one (ADR-0096). */
1065
- private pitchInputOf(asset: V3Asset, part: string): string | undefined {
1065
+ private pitchInputOf(asset: FigureAsset, part: string): string | undefined {
1066
1066
  const pitch = asset.joints?.find(j => j.body1.part === part && j.repeat)?.repeat?.pitch as { from?: { of?: string; input?: string } } | number | undefined
1067
1067
  return typeof pitch === 'object' && pitch?.from?.of === 'input' ? pitch.from.input : undefined
1068
1068
  }
@@ -1070,7 +1070,7 @@ export class FigureV3Editor extends LitElement {
1070
1070
  * 「보드에서 바꿀 수 있음」 (ADR-0096): the row's pitch made a design input the figure publishes -- a name on the board and
1071
1071
  * a range the board's value is held to -- in one step; changed or withdrawn the same way. Only a row with a record.
1072
1072
  */
1073
- private renderPublicPitch(asset: V3Asset, pitch: number, unavailable: boolean) {
1073
+ private renderPublicPitch(asset: FigureAsset, pitch: number, unavailable: boolean) {
1074
1074
  const part = this.selected
1075
1075
  if (!asset.joints?.some(j => j.body1.part === part && j.repeat)) return nothing
1076
1076
  const from = this.pitchInputOf(asset, part)
@@ -1088,18 +1088,18 @@ export class FigureV3Editor extends LitElement {
1088
1088
  const base = form ?? { part, label: '', min: 0, max: 0 }
1089
1089
  this.publishing = { ...base, [key]: key === 'label' ? target.value : target.valueAsNumber }
1090
1090
  }
1091
- const steps = (): V3ProposalStep[] => {
1091
+ const steps = (): FigureProposalStep[] => {
1092
1092
  const f = form!
1093
1093
  const id = from ?? `${part}.pitch`
1094
- if (listed) return [{ kind: 'set-input-range', input: id, min: f.min, max: f.max }, { kind: 'publish-input', input: id, label: f.label }] as V3ProposalStep[]
1094
+ if (listed) return [{ kind: 'set-input-range', input: id, min: f.min, max: f.max }, { kind: 'publish-input', input: id, label: f.label }] as FigureProposalStep[]
1095
1095
  const exists = asset.document.model.inputs.some(i => i.id === id)
1096
1096
  return [
1097
1097
  ...(exists ? [{ kind: 'set-input-range', input: id, min: f.min, max: f.max }] : [{ kind: 'add-design-input', id, unit: 'mm', min: f.min, max: f.max, value: pitch }]),
1098
1098
  ...(from ? [] : [{ kind: 'set-repeat', part, pitch: { from: { of: 'input', input: id } } }]),
1099
1099
  { kind: 'publish-input', input: id, label: f.label }
1100
- ] as V3ProposalStep[]
1100
+ ] as FigureProposalStep[]
1101
1101
  }
1102
- const run = (list: V3ProposalStep[]) => {
1102
+ const run = (list: FigureProposalStep[]) => {
1103
1103
  try {
1104
1104
  this.session!.applyRecipe(list)
1105
1105
  this.publishing = undefined
@@ -1120,7 +1120,7 @@ export class FigureV3Editor extends LitElement {
1120
1120
  (e.target as HTMLInputElement).checked
1121
1121
  ? (this.publishing = { part, label: i18next.t('figure.label.repeat-gap'), min: Math.max(1, Math.round(pitch / 2)), max: Math.round(pitch * 2) })
1122
1122
  : listed
1123
- ? run([{ kind: 'unpublish-input', input: from }, { kind: 'set-repeat', part, pitch }] as V3ProposalStep[])
1123
+ ? run([{ kind: 'unpublish-input', input: from }, { kind: 'set-repeat', part, pitch }] as FigureProposalStep[])
1124
1124
  : (this.publishing = undefined)}
1125
1125
  />
1126
1126
  ${i18next.t('figure.label.board-sets')}
@@ -1145,7 +1145,7 @@ export class FigureV3Editor extends LitElement {
1145
1145
  const pitch = input.valueAsNumber
1146
1146
  if (!Number.isFinite(pitch) || pitch === field.value) return
1147
1147
  /* Read from a design input the board may set: the input's value changes, the row keeps reading it (ADR-0096). */
1148
- const from = this.pitchInputOf(JSON.parse(this.session!.source()) as V3Asset, this.selected)
1148
+ const from = this.pitchInputOf(JSON.parse(this.session!.source()) as FigureAsset, this.selected)
1149
1149
  if (from) {
1150
1150
  this.run(() => this.session!.apply([{ kind: 'set-design', input: from, unit: 'mm', value: pitch }]))
1151
1151
  input.value = String(this.session!.read().fields.find(i => i.id === from)?.value ?? field.value)
@@ -1227,7 +1227,7 @@ export class FigureV3Editor extends LitElement {
1227
1227
  .pane=${this.panes}
1228
1228
  @canvas-undo=${() => this.run(() => this.session!.undo())}
1229
1229
  @canvas-redo=${() => this.run(() => this.session!.redo())}
1230
- @canvas-fit=${() => this.renderRoot.querySelector<FigureV3Canvas>('figure-v3-canvas')?.fit()}
1230
+ @canvas-fit=${() => this.renderRoot.querySelector<FigureCanvas>('figure-canvas')?.fit()}
1231
1231
  >
1232
1232
  ${this.renderGizmoTools(!unavailable && this.middle === 'edit')}
1233
1233
  ${(['edit', 'preview'] as const).map(
@@ -1248,7 +1248,7 @@ export class FigureV3Editor extends LitElement {
1248
1248
  : null}
1249
1249
  ${this.notice ? html`<div role="status" class="notice">${this.notice}</div>` : null}
1250
1250
  ${this.catalogOpen
1251
- ? html`<figure-v3-recipe-catalog
1251
+ ? html`<figure-recipe-catalog
1252
1252
  .templates=${this.templates}
1253
1253
  .selected=${this.selected}
1254
1254
  .error=${this.recipeError}
@@ -1257,15 +1257,15 @@ export class FigureV3Editor extends LitElement {
1257
1257
  ?locked=${unavailable}
1258
1258
  @insert-recipe=${(e: CustomEvent) => this.insertRecipe(e.detail.recipe, e.detail.values)}
1259
1259
  @close-catalog=${() => (this.catalogOpen = false)}
1260
- ></figure-v3-recipe-catalog>`
1260
+ ></figure-recipe-catalog>`
1261
1261
  : null}
1262
1262
  <ox-three-pane>
1263
- <figure-v3-parts
1263
+ <figure-parts
1264
1264
  slot="start"
1265
1265
  .budget=${this.budget}
1266
1266
  @show-maturity=${() => (this.tab = 'verdict')}
1267
1267
  .parts=${this.partRows(view.geometry)}
1268
- .partBudget=${this.partBudgetOf(asset as V3Asset | undefined)}
1268
+ .partBudget=${this.partBudgetOf(asset as FigureAsset | undefined)}
1269
1269
  @set-detail-level=${(e: CustomEvent) => this.linkCommand({ kind: 'set-detail-level', level: e.detail.level })}
1270
1270
  .selected=${this.selected}
1271
1271
  ?locked=${unavailable}
@@ -1280,18 +1280,18 @@ export class FigureV3Editor extends LitElement {
1280
1280
  @move-part-down=${(e: CustomEvent) => this.movePart(e.detail.id, e.detail.to)}
1281
1281
  @duplicate-part=${(e: CustomEvent) => this.duplicatePart(e.detail.id)}
1282
1282
  @remove-part=${(e: CustomEvent) => this.removePart(e.detail.id)}
1283
- ></figure-v3-parts>
1283
+ ></figure-parts>
1284
1284
  ${this.middle === 'preview'
1285
- ? html`<figure-v3-preview
1285
+ ? html`<figure-preview
1286
1286
  .asset=${asset}
1287
1287
  .context=${view.context ?? ''}
1288
1288
  .view=${this.view}
1289
- @v3-part-edit=${(e: CustomEvent) => this.run(() => this.session!.edit(e.detail.edit))}
1290
- ></figure-v3-preview>`
1291
- : html`<figure-v3-canvas
1289
+ @part-edit=${(e: CustomEvent) => this.run(() => this.session!.edit(e.detail.edit))}
1290
+ ></figure-preview>`
1291
+ : html`<figure-canvas
1292
1292
  .view=${this.view}
1293
1293
  .parts=${this.drawnParts(view.geometry, asset)}
1294
- .fan=${this.fanOf(asset as V3Asset | undefined)}
1294
+ .fan=${this.fanOf(asset as FigureAsset | undefined)}
1295
1295
  .palette=${view.palette ?? {}}
1296
1296
  .context=${view.context ?? ''}
1297
1297
  .selected=${this.selected}
@@ -1301,7 +1301,7 @@ export class FigureV3Editor extends LitElement {
1301
1301
  @render-error=${(e: CustomEvent<Error>) => {
1302
1302
  this.error = e.detail.message
1303
1303
  }}
1304
- ></figure-v3-canvas>`}
1304
+ ></figure-canvas>`}
1305
1305
  <aside slot="end">
1306
1306
  <div tabs>
1307
1307
  ${this.renderTab('properties', 'tune', i18next.t('figure.label.properties'))}
@@ -1329,30 +1329,30 @@ export class FigureV3Editor extends LitElement {
1329
1329
  </div>
1330
1330
  ${this.renderRepeatNote(view.geometry)}
1331
1331
  </section>
1332
- ${this.renderRepeat(asset as V3Asset | undefined, view.geometry, unavailable)}
1332
+ ${this.renderRepeat(asset as FigureAsset | undefined, view.geometry, unavailable)}
1333
1333
  ${this.renderGroups(groupFields(own, this.selected), 'figure.label.group-placement-size', 'figure.label.group-shape', unavailable, this.renderTools(unavailable))}
1334
1334
  ${this.renderLinks(unavailable, 'shape')}
1335
- <figure-v3-material
1335
+ <figure-material-panel
1336
1336
  .body=${{ ...part, id: this.selected }}
1337
1337
  .palette=${view.palette ?? {}}
1338
1338
  ?locked=${unavailable}
1339
- @v3-part-edit=${(e: CustomEvent) => this.run(() => this.session!.edit(e.detail.edit))}
1340
- @v3-part-live=${(e: CustomEvent) => this.hold({}, e.detail.edit)}
1341
- ></figure-v3-material>`
1339
+ @part-edit=${(e: CustomEvent) => this.run(() => this.session!.edit(e.detail.edit))}
1340
+ @part-live=${(e: CustomEvent) => this.hold({}, e.detail.edit)}
1341
+ ></figure-material-panel>`
1342
1342
  : html`<slot name="figure"></slot>
1343
1343
  ${this.renderGroups(groupFields(common), 'figure.label.group-figure-size', 'figure.label.design-inputs', unavailable)}
1344
- ${this.renderInstanceRange(asset as V3Asset | undefined, unavailable)}`}
1344
+ ${this.renderInstanceRange(asset as FigureAsset | undefined, unavailable)}`}
1345
1345
  </div>
1346
1346
  <div panel ?off=${tab !== 'capability'}>
1347
1347
  ${this.renderSubject()}
1348
1348
  ${this.selected && part ? this.renderLinks(unavailable, 'places') : null}
1349
- <figure-v3-capability
1349
+ <figure-capability-panel
1350
1350
  .asset=${asset}
1351
1351
  .selected=${this.selected}
1352
1352
  ?locked=${unavailable}
1353
1353
  @select-part=${(e: CustomEvent) => this.choose(e.detail.id)}
1354
- @v3-part-edit=${(e: CustomEvent) => this.run(() => this.session!.edit(e.detail.edit))}
1355
- ></figure-v3-capability>
1354
+ @part-edit=${(e: CustomEvent) => this.run(() => this.session!.edit(e.detail.edit))}
1355
+ ></figure-capability-panel>
1356
1356
  </div>
1357
1357
  <div panel ?off=${tab !== 'motion'}>
1358
1358
  ${this.renderSubject()}
@@ -3,8 +3,8 @@ import { customElement, property } from 'lit/decorators.js'
3
3
  import { live } from 'lit/directives/live.js'
4
4
 
5
5
  import { i18next, localize } from '@operato/i18n'
6
- import { v3BindingsOf } from '@hatiolab/figure-model'
7
- import type { FigureCapability, V3Asset } from '@hatiolab/figure-model'
6
+ import { figureBindingsOf } from '@hatiolab/figure-model'
7
+ import type { FigureCapability, FigureAsset } from '@hatiolab/figure-model'
8
8
  import { SidePanelStyles } from './side-panel-styles.js'
9
9
 
10
10
  /*
@@ -32,8 +32,8 @@ export function rungOf(names: readonly string[] | undefined): Rung | null {
32
32
  * holding things, to passing them on, and every place things are held, whatever part it is on. A place is not drawn,
33
33
  * so the list is the only way to find one; choosing a row selects its part, where the place is edited.
34
34
  */
35
- @customElement('figure-v3-capability')
36
- export class FigureV3Capability extends localize(i18next)(LitElement) {
35
+ @customElement('figure-capability-panel')
36
+ export class FigureCapabilityPanel extends localize(i18next)(LitElement) {
37
37
  static styles = [SidePanelStyles, css`
38
38
  :host {
39
39
  display: block;
@@ -84,7 +84,7 @@ export class FigureV3Capability extends localize(i18next)(LitElement) {
84
84
  }
85
85
  `]
86
86
 
87
- @property({ attribute: false }) asset?: V3Asset
87
+ @property({ attribute: false }) asset?: FigureAsset
88
88
  /** The selected part, whose places are marked. */
89
89
  @property() selected = ''
90
90
  @property({ type: Boolean }) locked = false
@@ -94,7 +94,7 @@ export class FigureV3Capability extends localize(i18next)(LitElement) {
94
94
  if (!asset) return nothing
95
95
  const names = asset.document.capabilities.names ?? []
96
96
  const rung = rungOf(names)
97
- const places = v3BindingsOf(asset)
97
+ const places = figureBindingsOf(asset)
98
98
  return html`<section>
99
99
  <h3>${i18next.t('figure.label.what-this-does')}</h3>
100
100
  ${(['none', 'hold', 'flow'] as const).map(
@@ -128,7 +128,7 @@ export class FigureV3Capability extends localize(i18next)(LitElement) {
128
128
  }
129
129
 
130
130
  private setRung(which: Rung) {
131
- this.dispatchEvent(new CustomEvent('v3-part-edit', { detail: { edit: { kind: 'set-capabilities', names: [...RUNGS[which]] } }, bubbles: true, composed: true }))
131
+ this.dispatchEvent(new CustomEvent('part-edit', { detail: { edit: { kind: 'set-capabilities', names: [...RUNGS[which]] } }, bubbles: true, composed: true }))
132
132
  }
133
133
 
134
134
  private pick(part: string) {