@things-factory/figure-ui 10.1.75 → 10.1.77
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/client/figure-assistant.ts +3 -3
- package/client/graphql/{v3-store.ts → store.ts} +6 -6
- package/client/modeller/{v3-ai-proposal.ts → ai-proposal.ts} +8 -8
- package/client/modeller/{v3-align.ts → align.ts} +14 -14
- package/client/modeller/{v3-canvas.ts → canvas.ts} +13 -13
- package/client/modeller/{v3-clips.ts → clips.ts} +5 -5
- package/client/modeller/{v3-controls.ts → controls.ts} +2 -2
- package/client/modeller/{v3-editor.ts → editor.ts} +117 -117
- package/client/modeller/{figure-v3-capability.ts → figure-capability-panel.ts} +7 -7
- package/client/modeller/{figure-v3-clips.ts → figure-clips.ts} +10 -10
- package/client/modeller/{figure-v3-controls.ts → figure-controls.ts} +9 -9
- package/client/modeller/{v3-figure-facts.ts → figure-facts.ts} +11 -11
- package/client/modeller/{figure-v3-first-save.ts → figure-first-save.ts} +3 -3
- package/client/modeller/figure-history-panel.ts +1 -1
- package/client/modeller/{figure-v3-links.ts → figure-links.ts} +35 -35
- package/client/modeller/{figure-v3-material.ts → figure-material-panel.ts} +20 -20
- package/client/modeller/{figure-v3-parts.ts → figure-parts.ts} +15 -15
- package/client/modeller/{figure-v3-preview.ts → figure-preview.ts} +14 -14
- package/client/modeller/{figure-v3-properties.ts → figure-properties.ts} +25 -25
- package/client/modeller/{figure-v3-recipe-catalog.ts → figure-recipe-catalog.ts} +10 -10
- package/client/modeller/{figure-v3-verdict.ts → figure-verdict.ts} +24 -24
- package/client/modeller/gate-findings.ts +2 -2
- package/client/modeller/{v3-gizmo.ts → gizmo.ts} +11 -11
- package/client/modeller/{v3-joint-drag.ts → joint-drag.ts} +11 -11
- package/client/modeller/{v3-joint-fan.ts → joint-fan.ts} +13 -13
- package/client/modeller/{v3-links.ts → links.ts} +59 -59
- package/client/modeller/{v3-live.ts → live.ts} +9 -9
- package/client/modeller/{v3-maturity.ts → maturity.ts} +65 -65
- package/client/modeller/modeller-route.ts +1 -1
- package/client/modeller/{v3-occupancy.ts → occupancy.ts} +6 -6
- package/client/modeller/{v3-palette.ts → palette.ts} +3 -3
- package/client/modeller/{v3-preview-model.ts → preview-model.ts} +8 -8
- package/client/modeller/{v3-product-session.ts → product-session.ts} +25 -25
- package/client/modeller/{v3-recipe-source.ts → recipe-source.ts} +2 -2
- package/client/modeller/{v3-recipes.ts → recipes.ts} +9 -9
- package/client/modeller/{v3-renderer.ts → renderer.ts} +16 -16
- package/client/modeller/{v3-stage-model.ts → stage-model.ts} +15 -15
- package/client/modeller/{v3-thumbnail.ts → thumbnail.ts} +8 -8
- package/client/pages/figure-list-page.ts +4 -4
- package/client/pages/{figure-v3-modeller-page.ts → figure-modeller-page.ts} +37 -37
- package/client/route.ts +1 -5
- package/dist-client/figure-assistant.js +3 -3
- package/dist-client/figure-assistant.js.map +1 -1
- package/dist-client/graphql/store.d.ts +3 -0
- package/dist-client/graphql/{v3-store.js → store.js} +6 -6
- package/dist-client/graphql/store.js.map +1 -0
- package/dist-client/modeller/{v3-ai-proposal.d.ts → ai-proposal.d.ts} +7 -7
- package/dist-client/modeller/{v3-ai-proposal.js → ai-proposal.js} +1 -1
- package/dist-client/modeller/ai-proposal.js.map +1 -0
- package/dist-client/modeller/{v3-align.d.ts → align.d.ts} +8 -8
- package/dist-client/modeller/{v3-align.js → align.js} +6 -6
- package/dist-client/modeller/align.js.map +1 -0
- package/dist-client/modeller/{v3-canvas.d.ts → canvas.d.ts} +7 -7
- package/dist-client/modeller/{v3-canvas.js → canvas.js} +20 -20
- package/dist-client/modeller/canvas.js.map +1 -0
- package/dist-client/modeller/{v3-clips.d.ts → clips.d.ts} +4 -4
- package/dist-client/modeller/{v3-clips.js → clips.js} +1 -1
- package/dist-client/modeller/clips.js.map +1 -0
- package/dist-client/modeller/{v3-controls.d.ts → controls.d.ts} +2 -2
- package/dist-client/modeller/{v3-controls.js → controls.js} +1 -1
- package/dist-client/modeller/controls.js.map +1 -0
- package/dist-client/modeller/{v3-editor.d.ts → editor.d.ts} +19 -19
- package/dist-client/modeller/{v3-editor.js → editor.js} +103 -103
- package/dist-client/modeller/editor.js.map +1 -0
- package/dist-client/modeller/{v3-fields.js → fields.js} +1 -1
- package/dist-client/modeller/fields.js.map +1 -0
- package/dist-client/modeller/{figure-v3-capability.d.ts → figure-capability-panel.d.ts} +4 -4
- package/dist-client/modeller/{figure-v3-capability.js → figure-capability-panel.js} +12 -12
- package/dist-client/modeller/figure-capability-panel.js.map +1 -0
- package/dist-client/modeller/{figure-v3-clips.d.ts → figure-clips.d.ts} +4 -4
- package/dist-client/modeller/{figure-v3-clips.js → figure-clips.js} +16 -16
- package/dist-client/modeller/figure-clips.js.map +1 -0
- package/dist-client/modeller/{figure-v3-controls.d.ts → figure-controls.d.ts} +5 -5
- package/dist-client/modeller/{figure-v3-controls.js → figure-controls.js} +16 -16
- package/dist-client/modeller/figure-controls.js.map +1 -0
- package/dist-client/modeller/{v3-figure-facts.d.ts → figure-facts.d.ts} +5 -5
- package/dist-client/modeller/{v3-figure-facts.js → figure-facts.js} +5 -5
- package/dist-client/modeller/figure-facts.js.map +1 -0
- package/dist-client/modeller/{figure-v3-first-save.d.ts → figure-first-save.d.ts} +1 -1
- package/dist-client/modeller/{figure-v3-first-save.js → figure-first-save.js} +11 -11
- package/dist-client/modeller/figure-first-save.js.map +1 -0
- package/dist-client/modeller/figure-history-panel.d.ts +1 -1
- package/dist-client/modeller/figure-history-panel.js.map +1 -1
- package/dist-client/modeller/{figure-v3-links.d.ts → figure-links.d.ts} +5 -5
- package/dist-client/modeller/{figure-v3-links.js → figure-links.js} +24 -24
- package/dist-client/modeller/figure-links.js.map +1 -0
- package/dist-client/modeller/{figure-v3-material.d.ts → figure-material-panel.d.ts} +9 -9
- package/dist-client/modeller/{figure-v3-material.js → figure-material-panel.js} +19 -19
- package/dist-client/modeller/figure-material-panel.js.map +1 -0
- package/dist-client/modeller/{figure-v3-parts.d.ts → figure-parts.d.ts} +12 -12
- package/dist-client/modeller/{figure-v3-parts.js → figure-parts.js} +14 -14
- package/dist-client/modeller/figure-parts.js.map +1 -0
- package/dist-client/modeller/{figure-v3-preview.d.ts → figure-preview.d.ts} +4 -4
- package/dist-client/modeller/{figure-v3-preview.js → figure-preview.js} +21 -21
- package/dist-client/modeller/figure-preview.js.map +1 -0
- package/dist-client/modeller/{figure-v3-properties.d.ts → figure-properties.d.ts} +8 -8
- package/dist-client/modeller/{figure-v3-properties.js → figure-properties.js} +25 -25
- package/dist-client/modeller/figure-properties.js.map +1 -0
- package/dist-client/modeller/{figure-v3-recipe-catalog.d.ts → figure-recipe-catalog.d.ts} +4 -4
- package/dist-client/modeller/{figure-v3-recipe-catalog.js → figure-recipe-catalog.js} +21 -21
- package/dist-client/modeller/figure-recipe-catalog.js.map +1 -0
- package/dist-client/modeller/{figure-v3-verdict.d.ts → figure-verdict.d.ts} +2 -2
- package/dist-client/modeller/{figure-v3-verdict.js → figure-verdict.js} +26 -26
- package/dist-client/modeller/figure-verdict.js.map +1 -0
- package/dist-client/modeller/{v3-first-save.js → first-save.js} +1 -1
- package/dist-client/modeller/first-save.js.map +1 -0
- package/dist-client/modeller/gate-findings.d.ts +2 -2
- package/dist-client/modeller/gate-findings.js +2 -2
- package/dist-client/modeller/gate-findings.js.map +1 -1
- package/dist-client/modeller/{v3-gizmo.d.ts → gizmo.d.ts} +5 -5
- package/dist-client/modeller/{v3-gizmo.js → gizmo.js} +3 -3
- package/dist-client/modeller/gizmo.js.map +1 -0
- package/dist-client/modeller/{v3-help.js → help.js} +1 -1
- package/dist-client/modeller/help.js.map +1 -0
- package/dist-client/modeller/joint-drag.d.ts +19 -0
- package/dist-client/modeller/{v3-joint-drag.js → joint-drag.js} +4 -4
- package/dist-client/modeller/joint-drag.js.map +1 -0
- package/dist-client/modeller/{v3-joint-fan.d.ts → joint-fan.d.ts} +3 -3
- package/dist-client/modeller/{v3-joint-fan.js → joint-fan.js} +6 -6
- package/dist-client/modeller/joint-fan.js.map +1 -0
- package/dist-client/modeller/{v3-keys.js → keys.js} +1 -1
- package/dist-client/modeller/keys.js.map +1 -0
- package/dist-client/modeller/{v3-links.d.ts → links.d.ts} +48 -48
- package/dist-client/modeller/{v3-links.js → links.js} +15 -15
- package/dist-client/modeller/links.js.map +1 -0
- package/dist-client/modeller/{v3-live.d.ts → live.d.ts} +6 -6
- package/dist-client/modeller/{v3-live.js → live.js} +5 -5
- package/dist-client/modeller/live.js.map +1 -0
- package/dist-client/modeller/{v3-maturity.d.ts → maturity.d.ts} +26 -26
- package/dist-client/modeller/{v3-maturity.js → maturity.js} +28 -28
- package/dist-client/modeller/maturity.js.map +1 -0
- package/dist-client/modeller/modeller-route.d.ts +1 -1
- package/dist-client/modeller/modeller-route.js +1 -1
- package/dist-client/modeller/modeller-route.js.map +1 -1
- package/dist-client/modeller/{v3-occupancy.d.ts → occupancy.d.ts} +4 -4
- package/dist-client/modeller/{v3-occupancy.js → occupancy.js} +6 -6
- package/dist-client/modeller/occupancy.js.map +1 -0
- package/dist-client/modeller/palette.d.ts +7 -0
- package/dist-client/modeller/{v3-palette.js → palette.js} +1 -1
- package/dist-client/modeller/palette.js.map +1 -0
- package/dist-client/modeller/{v3-preview-model.d.ts → preview-model.d.ts} +3 -3
- package/dist-client/modeller/{v3-preview-model.js → preview-model.js} +6 -6
- package/dist-client/modeller/preview-model.js.map +1 -0
- package/dist-client/modeller/{v3-product-session.d.ts → product-session.d.ts} +56 -56
- package/dist-client/modeller/{v3-product-session.js → product-session.js} +7 -7
- package/dist-client/modeller/product-session.js.map +1 -0
- package/dist-client/modeller/{v3-recipe-source.d.ts → recipe-source.d.ts} +2 -2
- package/dist-client/modeller/{v3-recipe-source.js → recipe-source.js} +3 -3
- package/dist-client/modeller/recipe-source.js.map +1 -0
- package/dist-client/modeller/{v3-recipes.d.ts → recipes.d.ts} +7 -7
- package/dist-client/modeller/{v3-recipes.js → recipes.js} +4 -4
- package/dist-client/modeller/recipes.js.map +1 -0
- package/dist-client/modeller/{v3-refusals.js → refusals.js} +1 -1
- package/dist-client/modeller/refusals.js.map +1 -0
- package/dist-client/modeller/{v3-renderer.d.ts → renderer.d.ts} +6 -6
- package/dist-client/modeller/{v3-renderer.js → renderer.js} +13 -13
- package/dist-client/modeller/renderer.js.map +1 -0
- package/dist-client/modeller/{v3-stage-model.d.ts → stage-model.d.ts} +7 -7
- package/dist-client/modeller/{v3-stage-model.js → stage-model.js} +5 -5
- package/dist-client/modeller/stage-model.js.map +1 -0
- package/dist-client/modeller/thumbnail.d.ts +3 -0
- package/dist-client/modeller/{v3-thumbnail.js → thumbnail.js} +6 -6
- package/dist-client/modeller/thumbnail.js.map +1 -0
- package/dist-client/pages/figure-list-page.d.ts +1 -1
- package/dist-client/pages/figure-list-page.js +4 -4
- package/dist-client/pages/figure-list-page.js.map +1 -1
- package/dist-client/pages/{figure-v3-modeller-page.d.ts → figure-modeller-page.d.ts} +10 -10
- package/dist-client/pages/{figure-v3-modeller-page.js → figure-modeller-page.js} +42 -42
- package/dist-client/pages/figure-modeller-page.js.map +1 -0
- package/dist-client/route.d.ts +1 -1
- package/dist-client/route.js +1 -5
- package/dist-client/route.js.map +1 -1
- package/dist-client/tsconfig.tsbuildinfo +1 -1
- package/docs/product-cutover.md +25 -0
- package/package.json +5 -5
- package/test/{v3-ai-proposal.test.ts → ai-proposal.test.ts} +6 -6
- package/test/{v3-align.test.ts → align.test.ts} +8 -8
- package/test/browser/modeller-page.js +30 -30
- package/test/browser/modeller.check.mjs +14 -14
- package/test/browser/serve.mjs +1 -1
- package/test/browser/thumbnail-page.js +6 -6
- package/test/{v3-clips.test.ts → clips.test.ts} +18 -18
- package/test/{v3-controls.test.ts → controls.test.ts} +15 -15
- package/test/{v3-fields.test.ts → fields.test.ts} +13 -13
- package/test/figure-assistant-surface.test.ts +3 -3
- package/test/{v3-first-save.test.ts → first-save.test.ts} +10 -10
- package/test/fixtures/joint-column.json +2 -2
- package/test/fixtures/joint-roller.json +2 -2
- package/test/fixtures/robot-arm-6dof.json +2 -2
- package/test/{v3-gizmo.test.ts → gizmo.test.ts} +33 -33
- package/test/{v3-joint-drag.test.ts → joint-drag.test.ts} +17 -17
- package/test/{v3-joint-fan.test.ts → joint-fan.test.ts} +18 -18
- package/test/joints.ts +6 -6
- package/test/{v3-keys.test.ts → keys.test.ts} +2 -2
- package/test/{v3-layout.test.ts → layout.test.ts} +8 -8
- package/test/{v3-links.test.ts → links.test.ts} +201 -201
- package/test/{v3-live.test.ts → live.test.ts} +18 -18
- package/test/{v3-material.test.ts → material.test.ts} +12 -12
- package/test/{v3-maturity.test.ts → maturity.test.ts} +74 -74
- package/test/modeller-route.test.ts +5 -6
- package/test/{v3-palette-icons.test.ts → palette-icons.test.ts} +1 -1
- package/test/{v3-parts-wiring.test.ts → parts-wiring.test.ts} +5 -5
- package/test/{v3-preview.test.ts → preview.test.ts} +12 -12
- package/test/{v3-product-session.test.ts → product-session.test.ts} +17 -17
- package/test/{v3-product-write.test.ts → product-write.test.ts} +20 -20
- package/test/{v3-properties.test.ts → properties.test.ts} +24 -24
- package/test/{v3-recipes.test.ts → recipes.test.ts} +9 -9
- package/test/{v3-refusals.test.ts → refusals.test.ts} +43 -43
- package/test/{v3-release-panel.test.ts → release-panel.test.ts} +21 -21
- package/test/renderer.test.ts +24 -0
- package/test/resolve-ts-siblings.mjs +1 -1
- package/test/{v3-scene-canvas.test.ts → scene-canvas.test.ts} +6 -6
- package/test/{v3-stage-model.test.ts → stage-model.test.ts} +5 -5
- package/test/{v3-theme.test.ts → theme.test.ts} +4 -4
- package/test/{v3-thumbnail.test.ts → thumbnail.test.ts} +4 -4
- package/test/{v3-verdict.test.ts → verdict.test.ts} +17 -17
- package/test/{v3-view.test.ts → view.test.ts} +2 -2
- package/things-factory.config.js +2 -3
- package/translations/en.json +2 -2
- package/translations/ja.json +2 -2
- package/translations/ko.json +2 -2
- package/translations/ms.json +2 -2
- package/translations/zh.json +2 -2
- package/dist-client/graphql/v3-store.d.ts +0 -3
- package/dist-client/graphql/v3-store.js.map +0 -1
- package/dist-client/modeller/figure-v3-capability.js.map +0 -1
- package/dist-client/modeller/figure-v3-clips.js.map +0 -1
- package/dist-client/modeller/figure-v3-controls.js.map +0 -1
- package/dist-client/modeller/figure-v3-first-save.js.map +0 -1
- package/dist-client/modeller/figure-v3-links.js.map +0 -1
- package/dist-client/modeller/figure-v3-material.js.map +0 -1
- package/dist-client/modeller/figure-v3-parts.js.map +0 -1
- package/dist-client/modeller/figure-v3-preview.js.map +0 -1
- package/dist-client/modeller/figure-v3-properties.js.map +0 -1
- package/dist-client/modeller/figure-v3-recipe-catalog.js.map +0 -1
- package/dist-client/modeller/figure-v3-verdict.js.map +0 -1
- package/dist-client/modeller/v3-ai-proposal.js.map +0 -1
- package/dist-client/modeller/v3-align.js.map +0 -1
- package/dist-client/modeller/v3-canvas.js.map +0 -1
- package/dist-client/modeller/v3-clips.js.map +0 -1
- package/dist-client/modeller/v3-controls.js.map +0 -1
- package/dist-client/modeller/v3-editor.js.map +0 -1
- package/dist-client/modeller/v3-fields.js.map +0 -1
- package/dist-client/modeller/v3-figure-facts.js.map +0 -1
- package/dist-client/modeller/v3-first-save.js.map +0 -1
- package/dist-client/modeller/v3-gizmo.js.map +0 -1
- package/dist-client/modeller/v3-help.js.map +0 -1
- package/dist-client/modeller/v3-joint-drag.d.ts +0 -19
- package/dist-client/modeller/v3-joint-drag.js.map +0 -1
- package/dist-client/modeller/v3-joint-fan.js.map +0 -1
- package/dist-client/modeller/v3-keys.js.map +0 -1
- package/dist-client/modeller/v3-links.js.map +0 -1
- package/dist-client/modeller/v3-live.js.map +0 -1
- package/dist-client/modeller/v3-maturity.js.map +0 -1
- package/dist-client/modeller/v3-occupancy.js.map +0 -1
- package/dist-client/modeller/v3-palette.d.ts +0 -7
- package/dist-client/modeller/v3-palette.js.map +0 -1
- package/dist-client/modeller/v3-preview-model.js.map +0 -1
- package/dist-client/modeller/v3-product-session.js.map +0 -1
- package/dist-client/modeller/v3-recipe-source.js.map +0 -1
- package/dist-client/modeller/v3-recipes.js.map +0 -1
- package/dist-client/modeller/v3-refusals.js.map +0 -1
- package/dist-client/modeller/v3-renderer.js.map +0 -1
- package/dist-client/modeller/v3-stage-model.js.map +0 -1
- package/dist-client/modeller/v3-thumbnail.d.ts +0 -3
- package/dist-client/modeller/v3-thumbnail.js.map +0 -1
- package/dist-client/pages/figure-v3-modeller-page.js.map +0 -1
- package/dist-client/tsconfig.chk.tsbuildinfo +0 -1
- package/dist-client/tsconfig.fui.tsbuildinfo +0 -1
- package/dist-client/tsconfig.scratch-fm.tsbuildinfo +0 -1
- package/docs/v3-product-cutover.md +0 -25
- package/test/v3-renderer.test.ts +0 -24
- /package/client/modeller/{v3-fields.ts → fields.ts} +0 -0
- /package/client/modeller/{v3-first-save.ts → first-save.ts} +0 -0
- /package/client/modeller/{v3-help.ts → help.ts} +0 -0
- /package/client/modeller/{v3-keys.ts → keys.ts} +0 -0
- /package/client/modeller/{v3-refusals.ts → refusals.ts} +0 -0
- /package/dist-client/modeller/{v3-fields.d.ts → fields.d.ts} +0 -0
- /package/dist-client/modeller/{v3-first-save.d.ts → first-save.d.ts} +0 -0
- /package/dist-client/modeller/{v3-help.d.ts → help.d.ts} +0 -0
- /package/dist-client/modeller/{v3-keys.d.ts → keys.d.ts} +0 -0
- /package/dist-client/modeller/{v3-refusals.d.ts → refusals.d.ts} +0 -0
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { type
|
|
2
|
-
export interface
|
|
1
|
+
import { type FigureInputChange, type FigurePrimitiveCreation, type FigurePartEdit, type FigureAuthoringAction, type FigureProposalStep } from '@hatiolab/figure-model';
|
|
2
|
+
export interface FigureProductRecord {
|
|
3
3
|
id: string;
|
|
4
4
|
source: string;
|
|
5
5
|
}
|
|
6
6
|
/** Persistence is injected; neither the model engine nor the renderer owns the product ID. */
|
|
7
|
-
export interface
|
|
8
|
-
load(id: string): Promise<
|
|
7
|
+
export interface FigureProductStore {
|
|
8
|
+
load(id: string): Promise<FigureProductRecord>;
|
|
9
9
|
save(request: {
|
|
10
10
|
id?: string;
|
|
11
11
|
source: string;
|
|
@@ -15,10 +15,10 @@ export interface V3ProductStore {
|
|
|
15
15
|
thumbnail?: string;
|
|
16
16
|
/** The type name a new figure is created under (the first save asks for it). Not sent for an existing one. */
|
|
17
17
|
type?: string;
|
|
18
|
-
}): Promise<
|
|
18
|
+
}): Promise<FigureProductRecord>;
|
|
19
19
|
}
|
|
20
20
|
/** Product lifecycle boundary. A late response can never change another editor's asset or ID. */
|
|
21
|
-
export declare function
|
|
21
|
+
export declare function createFigureProductSession(store: FigureProductStore): {
|
|
22
22
|
read: () => {
|
|
23
23
|
id: string | undefined;
|
|
24
24
|
loading: boolean;
|
|
@@ -48,13 +48,13 @@ export declare function createV3ProductSession(store: V3ProductStore): {
|
|
|
48
48
|
fields: {
|
|
49
49
|
value: number;
|
|
50
50
|
id: string;
|
|
51
|
-
unit: import("@hatiolab/figure-model").
|
|
51
|
+
unit: import("@hatiolab/figure-model").FigureUnit;
|
|
52
52
|
min: number;
|
|
53
53
|
max: number;
|
|
54
54
|
role?: "design" | "state";
|
|
55
55
|
}[];
|
|
56
|
-
geometry: import("@hatiolab/figure-model").
|
|
57
|
-
bindings: import("@hatiolab/figure-model").
|
|
56
|
+
geometry: import("@hatiolab/figure-model").FigureAssetGeometry[];
|
|
57
|
+
bindings: import("@hatiolab/figure-model").FigureEvaluatedBinding[];
|
|
58
58
|
palette: Record<string, string>;
|
|
59
59
|
};
|
|
60
60
|
startNew({ discard }?: {
|
|
@@ -88,13 +88,13 @@ export declare function createV3ProductSession(store: V3ProductStore): {
|
|
|
88
88
|
fields: {
|
|
89
89
|
value: number;
|
|
90
90
|
id: string;
|
|
91
|
-
unit: import("@hatiolab/figure-model").
|
|
91
|
+
unit: import("@hatiolab/figure-model").FigureUnit;
|
|
92
92
|
min: number;
|
|
93
93
|
max: number;
|
|
94
94
|
role?: "design" | "state";
|
|
95
95
|
}[];
|
|
96
|
-
geometry: import("@hatiolab/figure-model").
|
|
97
|
-
bindings: import("@hatiolab/figure-model").
|
|
96
|
+
geometry: import("@hatiolab/figure-model").FigureAssetGeometry[];
|
|
97
|
+
bindings: import("@hatiolab/figure-model").FigureEvaluatedBinding[];
|
|
98
98
|
palette: Record<string, string>;
|
|
99
99
|
};
|
|
100
100
|
open(nextId: string, { discard }?: {
|
|
@@ -128,13 +128,13 @@ export declare function createV3ProductSession(store: V3ProductStore): {
|
|
|
128
128
|
fields: {
|
|
129
129
|
value: number;
|
|
130
130
|
id: string;
|
|
131
|
-
unit: import("@hatiolab/figure-model").
|
|
131
|
+
unit: import("@hatiolab/figure-model").FigureUnit;
|
|
132
132
|
min: number;
|
|
133
133
|
max: number;
|
|
134
134
|
role?: "design" | "state";
|
|
135
135
|
}[];
|
|
136
|
-
geometry: import("@hatiolab/figure-model").
|
|
137
|
-
bindings: import("@hatiolab/figure-model").
|
|
136
|
+
geometry: import("@hatiolab/figure-model").FigureAssetGeometry[];
|
|
137
|
+
bindings: import("@hatiolab/figure-model").FigureEvaluatedBinding[];
|
|
138
138
|
palette: Record<string, string>;
|
|
139
139
|
}>;
|
|
140
140
|
close({ discard }?: {
|
|
@@ -168,16 +168,16 @@ export declare function createV3ProductSession(store: V3ProductStore): {
|
|
|
168
168
|
fields: {
|
|
169
169
|
value: number;
|
|
170
170
|
id: string;
|
|
171
|
-
unit: import("@hatiolab/figure-model").
|
|
171
|
+
unit: import("@hatiolab/figure-model").FigureUnit;
|
|
172
172
|
min: number;
|
|
173
173
|
max: number;
|
|
174
174
|
role?: "design" | "state";
|
|
175
175
|
}[];
|
|
176
|
-
geometry: import("@hatiolab/figure-model").
|
|
177
|
-
bindings: import("@hatiolab/figure-model").
|
|
176
|
+
geometry: import("@hatiolab/figure-model").FigureAssetGeometry[];
|
|
177
|
+
bindings: import("@hatiolab/figure-model").FigureEvaluatedBinding[];
|
|
178
178
|
palette: Record<string, string>;
|
|
179
179
|
};
|
|
180
|
-
apply(changes:
|
|
180
|
+
apply(changes: FigureInputChange[], origin?: "ui" | "ai", expectedRevision?: number, context?: string): {
|
|
181
181
|
context: null;
|
|
182
182
|
name: null;
|
|
183
183
|
fields: never[];
|
|
@@ -198,20 +198,20 @@ export declare function createV3ProductSession(store: V3ProductStore): {
|
|
|
198
198
|
fields: {
|
|
199
199
|
value: number;
|
|
200
200
|
id: string;
|
|
201
|
-
unit: import("@hatiolab/figure-model").
|
|
201
|
+
unit: import("@hatiolab/figure-model").FigureUnit;
|
|
202
202
|
min: number;
|
|
203
203
|
max: number;
|
|
204
204
|
role?: "design" | "state";
|
|
205
205
|
}[];
|
|
206
|
-
geometry: import("@hatiolab/figure-model").
|
|
207
|
-
bindings: import("@hatiolab/figure-model").
|
|
206
|
+
geometry: import("@hatiolab/figure-model").FigureAssetGeometry[];
|
|
207
|
+
bindings: import("@hatiolab/figure-model").FigureEvaluatedBinding[];
|
|
208
208
|
palette: Record<string, string>;
|
|
209
209
|
};
|
|
210
210
|
/**
|
|
211
211
|
* An AI proposal (ADR-0094): the modeller's commands, as one step of the history, on the version the model saw.
|
|
212
212
|
* Never on the current one instead -- a person's edit in between makes the proposal stale, and it is refused.
|
|
213
213
|
*/
|
|
214
|
-
applyProposal(steps: readonly
|
|
214
|
+
applyProposal(steps: readonly FigureProposalStep[], expectedRevision: number, context: string): {
|
|
215
215
|
context: null;
|
|
216
216
|
name: null;
|
|
217
217
|
fields: never[];
|
|
@@ -232,20 +232,20 @@ export declare function createV3ProductSession(store: V3ProductStore): {
|
|
|
232
232
|
fields: {
|
|
233
233
|
value: number;
|
|
234
234
|
id: string;
|
|
235
|
-
unit: import("@hatiolab/figure-model").
|
|
235
|
+
unit: import("@hatiolab/figure-model").FigureUnit;
|
|
236
236
|
min: number;
|
|
237
237
|
max: number;
|
|
238
238
|
role?: "design" | "state";
|
|
239
239
|
}[];
|
|
240
|
-
geometry: import("@hatiolab/figure-model").
|
|
241
|
-
bindings: import("@hatiolab/figure-model").
|
|
240
|
+
geometry: import("@hatiolab/figure-model").FigureAssetGeometry[];
|
|
241
|
+
bindings: import("@hatiolab/figure-model").FigureEvaluatedBinding[];
|
|
242
242
|
palette: Record<string, string>;
|
|
243
243
|
};
|
|
244
244
|
/**
|
|
245
245
|
* A recipe put in by the person (ADR-0095): its resolved commands, as one step of the history, on the version open
|
|
246
246
|
* now. The same path as a proposal; the person is its origin.
|
|
247
247
|
*/
|
|
248
|
-
applyRecipe(steps: readonly
|
|
248
|
+
applyRecipe(steps: readonly FigureProposalStep[]): {
|
|
249
249
|
context: null;
|
|
250
250
|
name: null;
|
|
251
251
|
fields: never[];
|
|
@@ -266,16 +266,16 @@ export declare function createV3ProductSession(store: V3ProductStore): {
|
|
|
266
266
|
fields: {
|
|
267
267
|
value: number;
|
|
268
268
|
id: string;
|
|
269
|
-
unit: import("@hatiolab/figure-model").
|
|
269
|
+
unit: import("@hatiolab/figure-model").FigureUnit;
|
|
270
270
|
min: number;
|
|
271
271
|
max: number;
|
|
272
272
|
role?: "design" | "state";
|
|
273
273
|
}[];
|
|
274
|
-
geometry: import("@hatiolab/figure-model").
|
|
275
|
-
bindings: import("@hatiolab/figure-model").
|
|
274
|
+
geometry: import("@hatiolab/figure-model").FigureAssetGeometry[];
|
|
275
|
+
bindings: import("@hatiolab/figure-model").FigureEvaluatedBinding[];
|
|
276
276
|
palette: Record<string, string>;
|
|
277
277
|
};
|
|
278
|
-
add(part:
|
|
278
|
+
add(part: FigurePrimitiveCreation): {
|
|
279
279
|
context: null;
|
|
280
280
|
name: null;
|
|
281
281
|
fields: never[];
|
|
@@ -296,16 +296,16 @@ export declare function createV3ProductSession(store: V3ProductStore): {
|
|
|
296
296
|
fields: {
|
|
297
297
|
value: number;
|
|
298
298
|
id: string;
|
|
299
|
-
unit: import("@hatiolab/figure-model").
|
|
299
|
+
unit: import("@hatiolab/figure-model").FigureUnit;
|
|
300
300
|
min: number;
|
|
301
301
|
max: number;
|
|
302
302
|
role?: "design" | "state";
|
|
303
303
|
}[];
|
|
304
|
-
geometry: import("@hatiolab/figure-model").
|
|
305
|
-
bindings: import("@hatiolab/figure-model").
|
|
304
|
+
geometry: import("@hatiolab/figure-model").FigureAssetGeometry[];
|
|
305
|
+
bindings: import("@hatiolab/figure-model").FigureEvaluatedBinding[];
|
|
306
306
|
palette: Record<string, string>;
|
|
307
307
|
};
|
|
308
|
-
edit(edit:
|
|
308
|
+
edit(edit: FigurePartEdit): {
|
|
309
309
|
context: null;
|
|
310
310
|
name: null;
|
|
311
311
|
fields: never[];
|
|
@@ -326,13 +326,13 @@ export declare function createV3ProductSession(store: V3ProductStore): {
|
|
|
326
326
|
fields: {
|
|
327
327
|
value: number;
|
|
328
328
|
id: string;
|
|
329
|
-
unit: import("@hatiolab/figure-model").
|
|
329
|
+
unit: import("@hatiolab/figure-model").FigureUnit;
|
|
330
330
|
min: number;
|
|
331
331
|
max: number;
|
|
332
332
|
role?: "design" | "state";
|
|
333
333
|
}[];
|
|
334
|
-
geometry: import("@hatiolab/figure-model").
|
|
335
|
-
bindings: import("@hatiolab/figure-model").
|
|
334
|
+
geometry: import("@hatiolab/figure-model").FigureAssetGeometry[];
|
|
335
|
+
bindings: import("@hatiolab/figure-model").FigureEvaluatedBinding[];
|
|
336
336
|
palette: Record<string, string>;
|
|
337
337
|
} | {
|
|
338
338
|
removal: import("@hatiolab/figure-model").RemovalNotice;
|
|
@@ -357,17 +357,17 @@ export declare function createV3ProductSession(store: V3ProductStore): {
|
|
|
357
357
|
fields: {
|
|
358
358
|
value: number;
|
|
359
359
|
id: string;
|
|
360
|
-
unit: import("@hatiolab/figure-model").
|
|
360
|
+
unit: import("@hatiolab/figure-model").FigureUnit;
|
|
361
361
|
min: number;
|
|
362
362
|
max: number;
|
|
363
363
|
role?: "design" | "state";
|
|
364
364
|
}[];
|
|
365
|
-
geometry: import("@hatiolab/figure-model").
|
|
366
|
-
bindings: import("@hatiolab/figure-model").
|
|
365
|
+
geometry: import("@hatiolab/figure-model").FigureAssetGeometry[];
|
|
366
|
+
bindings: import("@hatiolab/figure-model").FigureEvaluatedBinding[];
|
|
367
367
|
palette: Record<string, string>;
|
|
368
368
|
};
|
|
369
369
|
/** One authoring command — what a person means, not a graph edit — as one step of the same history. */
|
|
370
|
-
command(action:
|
|
370
|
+
command(action: FigureAuthoringAction): {
|
|
371
371
|
context: null;
|
|
372
372
|
name: null;
|
|
373
373
|
fields: never[];
|
|
@@ -388,13 +388,13 @@ export declare function createV3ProductSession(store: V3ProductStore): {
|
|
|
388
388
|
fields: {
|
|
389
389
|
value: number;
|
|
390
390
|
id: string;
|
|
391
|
-
unit: import("@hatiolab/figure-model").
|
|
391
|
+
unit: import("@hatiolab/figure-model").FigureUnit;
|
|
392
392
|
min: number;
|
|
393
393
|
max: number;
|
|
394
394
|
role?: "design" | "state";
|
|
395
395
|
}[];
|
|
396
|
-
geometry: import("@hatiolab/figure-model").
|
|
397
|
-
bindings: import("@hatiolab/figure-model").
|
|
396
|
+
geometry: import("@hatiolab/figure-model").FigureAssetGeometry[];
|
|
397
|
+
bindings: import("@hatiolab/figure-model").FigureEvaluatedBinding[];
|
|
398
398
|
palette: Record<string, string>;
|
|
399
399
|
};
|
|
400
400
|
undo(): {
|
|
@@ -418,13 +418,13 @@ export declare function createV3ProductSession(store: V3ProductStore): {
|
|
|
418
418
|
fields: {
|
|
419
419
|
value: number;
|
|
420
420
|
id: string;
|
|
421
|
-
unit: import("@hatiolab/figure-model").
|
|
421
|
+
unit: import("@hatiolab/figure-model").FigureUnit;
|
|
422
422
|
min: number;
|
|
423
423
|
max: number;
|
|
424
424
|
role?: "design" | "state";
|
|
425
425
|
}[];
|
|
426
|
-
geometry: import("@hatiolab/figure-model").
|
|
427
|
-
bindings: import("@hatiolab/figure-model").
|
|
426
|
+
geometry: import("@hatiolab/figure-model").FigureAssetGeometry[];
|
|
427
|
+
bindings: import("@hatiolab/figure-model").FigureEvaluatedBinding[];
|
|
428
428
|
palette: Record<string, string>;
|
|
429
429
|
};
|
|
430
430
|
redo(): {
|
|
@@ -448,13 +448,13 @@ export declare function createV3ProductSession(store: V3ProductStore): {
|
|
|
448
448
|
fields: {
|
|
449
449
|
value: number;
|
|
450
450
|
id: string;
|
|
451
|
-
unit: import("@hatiolab/figure-model").
|
|
451
|
+
unit: import("@hatiolab/figure-model").FigureUnit;
|
|
452
452
|
min: number;
|
|
453
453
|
max: number;
|
|
454
454
|
role?: "design" | "state";
|
|
455
455
|
}[];
|
|
456
|
-
geometry: import("@hatiolab/figure-model").
|
|
457
|
-
bindings: import("@hatiolab/figure-model").
|
|
456
|
+
geometry: import("@hatiolab/figure-model").FigureAssetGeometry[];
|
|
457
|
+
bindings: import("@hatiolab/figure-model").FigureEvaluatedBinding[];
|
|
458
458
|
palette: Record<string, string>;
|
|
459
459
|
};
|
|
460
460
|
source(): string;
|
|
@@ -463,7 +463,7 @@ export declare function createV3ProductSession(store: V3ProductStore): {
|
|
|
463
463
|
*
|
|
464
464
|
* The picture is the caller's because taking it needs a canvas, and this session is the place that knows
|
|
465
465
|
* nothing about drawing. A save with no picture is a save: a tab in the background cannot draw, and the
|
|
466
|
-
* source matters more than the card (see `
|
|
466
|
+
* source matters more than the card (see `thumbnail.ts`).
|
|
467
467
|
*/
|
|
468
468
|
save({ thumbnail, type }?: {
|
|
469
469
|
thumbnail?: string;
|
|
@@ -497,14 +497,14 @@ export declare function createV3ProductSession(store: V3ProductStore): {
|
|
|
497
497
|
fields: {
|
|
498
498
|
value: number;
|
|
499
499
|
id: string;
|
|
500
|
-
unit: import("@hatiolab/figure-model").
|
|
500
|
+
unit: import("@hatiolab/figure-model").FigureUnit;
|
|
501
501
|
min: number;
|
|
502
502
|
max: number;
|
|
503
503
|
role?: "design" | "state";
|
|
504
504
|
}[];
|
|
505
|
-
geometry: import("@hatiolab/figure-model").
|
|
506
|
-
bindings: import("@hatiolab/figure-model").
|
|
505
|
+
geometry: import("@hatiolab/figure-model").FigureAssetGeometry[];
|
|
506
|
+
bindings: import("@hatiolab/figure-model").FigureEvaluatedBinding[];
|
|
507
507
|
palette: Record<string, string>;
|
|
508
508
|
}>;
|
|
509
509
|
};
|
|
510
|
-
export type
|
|
510
|
+
export type FigureProductSession = ReturnType<typeof createFigureProductSession>;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { createFigureAsset, createFigureEditorWorkspace, serializeFigureAsset, parseFigureAsset } from '@hatiolab/figure-model';
|
|
2
2
|
/** Product lifecycle boundary. A late response can never change another editor's asset or ID. */
|
|
3
|
-
export function
|
|
4
|
-
const workspace =
|
|
3
|
+
export function createFigureProductSession(store) {
|
|
4
|
+
const workspace = createFigureEditorWorkspace();
|
|
5
5
|
let epoch = 0, id, baseline;
|
|
6
6
|
let loading = false, saving = false, error;
|
|
7
7
|
let creationId;
|
|
@@ -38,7 +38,7 @@ export function createV3ProductSession(store) {
|
|
|
38
38
|
++epoch;
|
|
39
39
|
clear();
|
|
40
40
|
loading = false;
|
|
41
|
-
workspace.open(
|
|
41
|
+
workspace.open(serializeFigureAsset(createFigureAsset('새 Figure')));
|
|
42
42
|
creationId = crypto.randomUUID();
|
|
43
43
|
return read();
|
|
44
44
|
},
|
|
@@ -128,7 +128,7 @@ export function createV3ProductSession(store) {
|
|
|
128
128
|
*
|
|
129
129
|
* The picture is the caller's because taking it needs a canvas, and this session is the place that knows
|
|
130
130
|
* nothing about drawing. A save with no picture is a save: a tab in the background cannot draw, and the
|
|
131
|
-
* source matters more than the card (see `
|
|
131
|
+
* source matters more than the card (see `thumbnail.ts`).
|
|
132
132
|
*/
|
|
133
133
|
async save({ thumbnail, type } = {}) {
|
|
134
134
|
const control = writable(), requestEpoch = epoch;
|
|
@@ -140,7 +140,7 @@ export function createV3ProductSession(store) {
|
|
|
140
140
|
return read();
|
|
141
141
|
if (!record.id || (id !== undefined && record.id !== id))
|
|
142
142
|
throw Error('저장 응답의 Figure 대상이 다릅니다.');
|
|
143
|
-
if (
|
|
143
|
+
if (serializeFigureAsset(parseFigureAsset(record.source)) !== exported.text)
|
|
144
144
|
throw Error('저장 응답이 보낸 모델과 다릅니다. 저장 상태를 다시 확인해 주세요.');
|
|
145
145
|
workspace.acknowledgeSaved(exported);
|
|
146
146
|
id = record.id;
|
|
@@ -154,4 +154,4 @@ export function createV3ProductSession(store) {
|
|
|
154
154
|
}
|
|
155
155
|
};
|
|
156
156
|
}
|
|
157
|
-
//# sourceMappingURL=
|
|
157
|
+
//# sourceMappingURL=product-session.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"product-session.js","sourceRoot":"","sources":["../../client/modeller/product-session.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n createFigureAsset,\n createFigureEditorWorkspace,\n serializeFigureAsset,\n parseFigureAsset,\n type FigureInputChange,\n type FigurePrimitiveCreation,\n type FigurePartEdit,\n type FigureAuthoringAction,\n type FigureProposalStep\n} from '@hatiolab/figure-model'\n\nexport interface FigureProductRecord {\n id: string\n source: string\n}\n\n/** Persistence is injected; neither the model engine nor the renderer owns the product ID. */\nexport interface FigureProductStore {\n load(id: string): Promise<FigureProductRecord>\n save(request: {\n id?: string\n source: string\n expectedSource?: string\n creationId?: string\n /** The card's picture. Absent when the browser could not draw one; the source is saved either way. */\n thumbnail?: string\n /** The type name a new figure is created under (the first save asks for it). Not sent for an existing one. */\n type?: string\n }): Promise<FigureProductRecord>\n}\n\n/** Product lifecycle boundary. A late response can never change another editor's asset or ID. */\nexport function createFigureProductSession(store: FigureProductStore) {\n const workspace = createFigureEditorWorkspace()\n let epoch = 0,\n id: string | undefined,\n baseline: string | undefined\n let loading = false,\n saving = false,\n error: string | undefined\n let creationId: string | undefined\n function read() {\n return { ...workspace.read(), id, loading, saving, error }\n }\n function writable() {\n const view = workspace.read()\n if (loading || error || !view.context || view.revision === null) throw Error('먼저 모델을 정상적으로 열어 주세요.')\n // Serializing writes also makes create retries safe: no second create while the first is pending.\n if (saving) throw Error('저장이 끝난 뒤 편집해 주세요.')\n return { context: view.context, expectedRevision: view.revision, origin: 'ui' as const }\n }\n function clear() {\n workspace.close({ discardDesignChanges: true })\n id = undefined\n baseline = undefined\n error = undefined\n saving = false\n creationId = undefined\n }\n function canLeave(discard: boolean) {\n if (saving) throw Error('저장이 끝난 뒤 모델을 전환해 주세요.')\n if (workspace.read().dirty && !discard) throw Error('저장하지 않은 변경이 있습니다.')\n }\n return {\n read,\n startNew({ discard = false } = {}) {\n canLeave(discard)\n ++epoch\n clear()\n loading = false\n workspace.open(serializeFigureAsset(createFigureAsset('새 Figure')))\n creationId = crypto.randomUUID()\n return read()\n },\n async open(nextId: string, { discard = false } = {}) {\n canLeave(discard)\n const requestEpoch = ++epoch\n clear()\n loading = true\n try {\n const record = await store.load(nextId)\n if (requestEpoch !== epoch) return read()\n if (record.id !== nextId) throw Error('요청한 Figure와 응답의 대상이 다릅니다.')\n workspace.open(record.source)\n id = nextId\n baseline = record.source\n } catch (cause) {\n if (requestEpoch === epoch) error = cause instanceof Error ? cause.message : String(cause)\n } finally {\n if (requestEpoch === epoch) loading = false\n }\n return read()\n },\n close({ discard = false } = {}) {\n canLeave(discard)\n ++epoch\n clear()\n loading = false\n return read()\n },\n apply(changes: FigureInputChange[], origin: 'ui' | 'ai' = 'ui', expectedRevision?: number, context?: string) {\n const control = writable()\n // AI must supply the context AND revision captured when it started. Never substitute current values.\n if (origin === 'ai' && (context === undefined || expectedRevision === undefined))\n throw Error('AI 편집에는 요청 당시의 모델 문맥과 리비전이 필요합니다.')\n return workspace.apply({\n ...control,\n origin,\n context: context ?? control.context,\n expectedRevision: expectedRevision ?? control.expectedRevision,\n changes\n })\n },\n /**\n * An AI proposal (ADR-0094): the modeller's commands, as one step of the history, on the version the model saw.\n * Never on the current one instead -- a person's edit in between makes the proposal stale, and it is refused.\n */\n applyProposal(steps: readonly FigureProposalStep[], expectedRevision: number, context: string) {\n writable()\n return workspace.applyProposal({ origin: 'ai', context, expectedRevision, steps })\n },\n /**\n * A recipe put in by the person (ADR-0095): its resolved commands, as one step of the history, on the version open\n * now. The same path as a proposal; the person is its origin.\n */\n applyRecipe(steps: readonly FigureProposalStep[]) {\n const at = writable()\n return workspace.applyProposal({ origin: 'ui', context: at.context, expectedRevision: at.expectedRevision, steps })\n },\n add(part: FigurePrimitiveCreation) {\n return workspace.addPrimitive({ ...writable(), part })\n },\n edit(edit: FigurePartEdit) {\n return workspace.editPart({ ...writable(), edit })\n },\n /** One authoring command — what a person means, not a graph edit — as one step of the same history. */\n command(action: FigureAuthoringAction) {\n return workspace.command({ ...writable(), action })\n },\n undo() {\n return workspace.undo(writable())\n },\n redo() {\n return workspace.redo(writable())\n },\n source() {\n const { context } = writable()\n return workspace.export({ context }).text\n },\n /**\n * Saves the model, and the card's picture when the caller managed to take one.\n *\n * The picture is the caller's because taking it needs a canvas, and this session is the place that knows\n * nothing about drawing. A save with no picture is a save: a tab in the background cannot draw, and the\n * source matters more than the card (see `thumbnail.ts`).\n */\n async save({ thumbnail, type }: { thumbnail?: string; type?: string } = {}) {\n const control = writable(),\n requestEpoch = epoch\n const exported = workspace.export(control)\n saving = true\n try {\n const record = await store.save({ id, source: exported.text, expectedSource: baseline, creationId, thumbnail, ...(id || !type ? {} : { type }) })\n if (requestEpoch !== epoch) return read()\n if (!record.id || (id !== undefined && record.id !== id)) throw Error('저장 응답의 Figure 대상이 다릅니다.')\n if (serializeFigureAsset(parseFigureAsset(record.source)) !== exported.text)\n throw Error('저장 응답이 보낸 모델과 다릅니다. 저장 상태를 다시 확인해 주세요.')\n workspace.acknowledgeSaved(exported)\n id = record.id\n baseline = record.source\n } finally {\n if (requestEpoch === epoch) saving = false\n }\n return read()\n }\n }\n}\nexport type FigureProductSession = ReturnType<typeof createFigureProductSession>\n"]}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { type RecipeTemplate } from './
|
|
1
|
+
import { type RecipeTemplate } from './recipes.js';
|
|
2
2
|
/**
|
|
3
3
|
* Where the modeller gets its recipe templates: the server's static files (ADR-0095, amended 2026-09-26). The one place
|
|
4
|
-
* they are read -- the rules in `
|
|
4
|
+
* they are read -- the rules in `recipes.ts` stay free of the network so they are tested without it.
|
|
5
5
|
*/
|
|
6
6
|
export declare function availableRecipes(lang: string): Promise<RecipeTemplate[]>;
|
|
7
7
|
/** One template's guide, or '' while none is written -- the screen then shows no guide and no word about one. */
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { fetchRecipeGuide, fetchRecipeTemplates } from '../graphql/index.js';
|
|
2
|
-
import { templatesOf } from './
|
|
2
|
+
import { templatesOf } from './recipes.js';
|
|
3
3
|
/**
|
|
4
4
|
* Where the modeller gets its recipe templates: the server's static files (ADR-0095, amended 2026-09-26). The one place
|
|
5
|
-
* they are read -- the rules in `
|
|
5
|
+
* they are read -- the rules in `recipes.ts` stay free of the network so they are tested without it.
|
|
6
6
|
*/
|
|
7
7
|
export async function availableRecipes(lang) {
|
|
8
8
|
return templatesOf(await fetchRecipeTemplates(lang));
|
|
@@ -11,4 +11,4 @@ export async function availableRecipes(lang) {
|
|
|
11
11
|
export function recipeGuide(name, lang) {
|
|
12
12
|
return fetchRecipeGuide(name, lang);
|
|
13
13
|
}
|
|
14
|
-
//# sourceMappingURL=
|
|
14
|
+
//# sourceMappingURL=recipe-source.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recipe-source.js","sourceRoot":"","sources":["../../client/modeller/recipe-source.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAA;AAC5E,OAAO,EAAE,WAAW,EAAuB,MAAM,cAAc,CAAA;AAE/D;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,IAAY;IACjD,OAAO,WAAW,CAAC,MAAM,oBAAoB,CAAC,IAAI,CAAC,CAAC,CAAA;AACtD,CAAC;AAED,iHAAiH;AACjH,MAAM,UAAU,WAAW,CAAC,IAAY,EAAE,IAAY;IACpD,OAAO,gBAAgB,CAAC,IAAI,EAAE,IAAI,CAAC,CAAA;AACrC,CAAC","sourcesContent":["import { fetchRecipeGuide, fetchRecipeTemplates } from '../graphql/index.js'\nimport { templatesOf, type RecipeTemplate } from './recipes.js'\n\n/**\n * Where the modeller gets its recipe templates: the server's static files (ADR-0095, amended 2026-09-26). The one place\n * they are read -- the rules in `recipes.ts` stay free of the network so they are tested without it.\n */\nexport async function availableRecipes(lang: string): Promise<RecipeTemplate[]> {\n return templatesOf(await fetchRecipeTemplates(lang))\n}\n\n/** One template's guide, or '' while none is written -- the screen then shows no guide and no word about one. */\nexport function recipeGuide(name: string, lang: string): Promise<string> {\n return fetchRecipeGuide(name, lang)\n}\n"]}
|
|
@@ -1,32 +1,32 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { FigureRecipe, FigureRecipeParam, FigureRecipeValue } from '@hatiolab/figure-model';
|
|
2
2
|
import type { RecipeTemplateRow } from '../graphql/index.js';
|
|
3
3
|
/** A template in the catalog: the server's row, its recipe parsed. */
|
|
4
4
|
export interface RecipeTemplate extends Omit<RecipeTemplateRow, 'source'> {
|
|
5
|
-
recipe:
|
|
5
|
+
recipe: FigureRecipe;
|
|
6
6
|
}
|
|
7
7
|
/** The server's rows as templates. A row that is not a recipe is left out rather than breaking the catalog. */
|
|
8
8
|
export declare function templatesOf(rows: ReadonlyArray<RecipeTemplateRow>): RecipeTemplate[];
|
|
9
9
|
/** A part the recipe makes, as the catalog names it: its own name, the placeholder left off. */
|
|
10
10
|
export declare const recipePartName: (part: string) => string;
|
|
11
11
|
/**
|
|
12
|
-
* How a template works, in lines the catalog shows -- worked out from its steps (figure-model `
|
|
12
|
+
* How a template works, in lines the catalog shows -- worked out from its steps (figure-model `describeFigureRecipe`), each
|
|
13
13
|
* a translation key and its words.
|
|
14
14
|
*/
|
|
15
|
-
export declare function recipeWorkings(recipe:
|
|
15
|
+
export declare function recipeWorkings(recipe: FigureRecipe): Array<{
|
|
16
16
|
key: string;
|
|
17
17
|
words: Record<string, string | number>;
|
|
18
18
|
}>;
|
|
19
19
|
/** A recipe's words in the language on screen: that language, else English, else the first it has. */
|
|
20
20
|
export declare function recipeWord(words: Record<string, string> | undefined, language: string): string;
|
|
21
21
|
/** Whether a recipe can be put in now: one for a part needs a part chosen. */
|
|
22
|
-
export declare function recipeReady(recipe: Pick<
|
|
22
|
+
export declare function recipeReady(recipe: Pick<FigureRecipe, 'target'>, selected: string): boolean;
|
|
23
23
|
/**
|
|
24
24
|
* A field's value as the recipe takes it. A ratio is shown and typed as a percentage (35 for 0.35), since that is how a
|
|
25
25
|
* person says a share; the rest are taken as they are. A number field left empty or not a number keeps the default.
|
|
26
26
|
*/
|
|
27
|
-
export declare function recipeValueOf(param:
|
|
27
|
+
export declare function recipeValueOf(param: FigureRecipeParam, typed: string | boolean): FigureRecipeValue;
|
|
28
28
|
/** What a field shows for a value: a ratio as a percentage. */
|
|
29
|
-
export declare function recipeFieldOf(param:
|
|
29
|
+
export declare function recipeFieldOf(param: FigureRecipeParam, value: FigureRecipeValue): string;
|
|
30
30
|
/** The templates a category and words find: a word matches the title, the description, the name or a tag. */
|
|
31
31
|
export declare function recipesMatching<T extends {
|
|
32
32
|
category: string;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { describeFigureRecipe } from '@hatiolab/figure-model';
|
|
2
2
|
/*
|
|
3
3
|
* The recipe section's rules (ADR-0095), kept apart from the element so they can be tested without a browser.
|
|
4
4
|
*/
|
|
@@ -20,11 +20,11 @@ export function templatesOf(rows) {
|
|
|
20
20
|
/** A part the recipe makes, as the catalog names it: its own name, the placeholder left off. */
|
|
21
21
|
export const recipePartName = (part) => part.replace(/^\{id\}-/, '');
|
|
22
22
|
/**
|
|
23
|
-
* How a template works, in lines the catalog shows -- worked out from its steps (figure-model `
|
|
23
|
+
* How a template works, in lines the catalog shows -- worked out from its steps (figure-model `describeFigureRecipe`), each
|
|
24
24
|
* a translation key and its words.
|
|
25
25
|
*/
|
|
26
26
|
export function recipeWorkings(recipe) {
|
|
27
|
-
const d =
|
|
27
|
+
const d = describeFigureRecipe(recipe);
|
|
28
28
|
const lines = [];
|
|
29
29
|
for (const m of d.moves)
|
|
30
30
|
lines.push(m.follows
|
|
@@ -100,4 +100,4 @@ export function recipesMatching(templates, category, query) {
|
|
|
100
100
|
};
|
|
101
101
|
return found.map((t, i) => ({ t, i, r: rank(t) })).sort((a, b) => a.r - b.r || a.i - b.i).map(x => x.t);
|
|
102
102
|
}
|
|
103
|
-
//# sourceMappingURL=
|
|
103
|
+
//# sourceMappingURL=recipes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recipes.js","sourceRoot":"","sources":["../../client/modeller/recipes.ts"],"names":[],"mappings":"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","sourcesContent":["import { describeFigureRecipe } from '@hatiolab/figure-model'\nimport type { FigureRecipe, FigureRecipeParam, FigureRecipeValue } from '@hatiolab/figure-model'\n\nimport type { RecipeTemplateRow } from '../graphql/index.js'\n\n/** A template in the catalog: the server's row, its recipe parsed. */\nexport interface RecipeTemplate extends Omit<RecipeTemplateRow, 'source'> {\n recipe: FigureRecipe\n}\n\n/*\n * The recipe section's rules (ADR-0095), kept apart from the element so they can be tested without a browser.\n */\n\n/** The server's rows as templates. A row that is not a recipe is left out rather than breaking the catalog. */\nexport function templatesOf(rows: ReadonlyArray<RecipeTemplateRow>): RecipeTemplate[] {\n const out: RecipeTemplate[] = []\n for (const { source, ...row } of rows) {\n try {\n const recipe = JSON.parse(source)\n if (recipe && typeof recipe.name === 'string' && Array.isArray(recipe.steps)) out.push({ ...row, recipe })\n } catch {\n /* not a recipe */\n }\n }\n return out\n}\n\n/** A part the recipe makes, as the catalog names it: its own name, the placeholder left off. */\nexport const recipePartName = (part: string) => part.replace(/^\\{id\\}-/, '')\n\n/**\n * How a template works, in lines the catalog shows -- worked out from its steps (figure-model `describeFigureRecipe`), each\n * a translation key and its words.\n */\nexport function recipeWorkings(recipe: FigureRecipe): Array<{ key: string; words: Record<string, string | number> }> {\n const d = describeFigureRecipe(recipe)\n const lines: Array<{ key: string; words: Record<string, string | number> }> = []\n for (const m of d.moves)\n lines.push(\n m.follows\n ? { key: 'figure.text.recipe-moves-with', words: { part: recipePartName(m.part), leader: recipePartName(m.follows) } }\n : { key: m.kind === 'slide' ? 'figure.text.recipe-slides' : 'figure.text.recipe-turns', words: { part: recipePartName(m.part) } }\n )\n if (d.controls.length) lines.push({ key: 'figure.text.recipe-controls', words: { count: d.controls.length } })\n if (d.shownByControl.length) lines.push({ key: 'figure.text.recipe-shown-by-control', words: { parts: d.shownByControl.map(recipePartName).join(', ') } })\n for (const row of d.rows) lines.push({ key: 'figure.text.recipe-row', words: { part: recipePartName(row) } })\n return lines\n}\n\n/** A recipe's words in the language on screen: that language, else English, else the first it has. */\nexport function recipeWord(words: Record<string, string> | undefined, language: string): string {\n if (!words) return ''\n return words[language] ?? words[language.split('-')[0]!] ?? words.en ?? Object.values(words)[0] ?? ''\n}\n\n/** Whether a recipe can be put in now: one for a part needs a part chosen. */\nexport function recipeReady(recipe: Pick<FigureRecipe, 'target'>, selected: string): boolean {\n return recipe.target === 'figure' || !!selected\n}\n\n/**\n * A field's value as the recipe takes it. A ratio is shown and typed as a percentage (35 for 0.35), since that is how a\n * person says a share; the rest are taken as they are. A number field left empty or not a number keeps the default.\n */\nexport function recipeValueOf(param: FigureRecipeParam, typed: string | boolean): FigureRecipeValue {\n if (param.kind === 'flag') return typed === true || typed === 'true'\n if (param.kind === 'ratio' || param.kind === 'mm') {\n const n = typeof typed === 'string' && typed.trim() !== '' ? Number(typed) : NaN\n if (!Number.isFinite(n)) return param.default\n return param.kind === 'ratio' ? Math.round(n * 1e4) / 1e6 : n\n }\n const option = (param.options ?? []).find(o => String(o) === String(typed))\n return option ?? param.default\n}\n\n/** What a field shows for a value: a ratio as a percentage. */\nexport function recipeFieldOf(param: FigureRecipeParam, value: FigureRecipeValue): string {\n if (param.kind === 'ratio' && typeof value === 'number') return String(Math.round(value * 1e6) / 1e4)\n return String(value)\n}\n\n\n/** The templates a category and words find: a word matches the title, the description, the name or a tag. */\nexport function recipesMatching<T extends { category: string; title: string; description: string; name: string; tags: string[] }>(templates: readonly T[], category: string, query: string): T[] {\n const words = query.trim().toLowerCase().split(/\\s+/).filter(Boolean)\n const found = templates.filter(t => {\n if (category && t.category !== category) return false\n const text = [t.title, t.description, t.name, ...t.tags].join(' ').toLowerCase()\n return words.every(w => text.includes(w))\n })\n if (!words.length) return found\n /*\n What the search names comes first: a title that is the words, then one that starts with them, then a title word that\n does, then the rest in their order. 「다리」 listed 사다리 before 다리 넷 (walk 1, 2026-09-26).\n */\n const rank = (t: T) => {\n const title = t.title.toLowerCase()\n const query = words.join(' ')\n if (title === query) return 0\n if (title.startsWith(query)) return 1\n if (words.every(w => title.split(/\\s+/).some(part => part.startsWith(w)))) return 2\n if (words.every(w => title.includes(w))) return 3\n return 4\n }\n return found.map((t, i) => ({ t, i, r: rank(t) })).sort((a, b) => a.r - b.r || a.i - b.i).map(x => x.t)\n}\n"]}
|
|
@@ -139,4 +139,4 @@ export function inputRangeRefusalOf(error, say) {
|
|
|
139
139
|
const params = { value: number(value), min: number(min), max: number(max) };
|
|
140
140
|
return axis ? say('figure.text.input-range-size', { ...params, axis: axis.toUpperCase() }) : say('figure.text.input-range', params);
|
|
141
141
|
}
|
|
142
|
-
//# sourceMappingURL=
|
|
142
|
+
//# sourceMappingURL=refusals.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"refusals.js","sourceRoot":"","sources":["../../client/modeller/refusals.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * A command refused because the figure could not be drawn at an end of its declared size range, in the author's words\n * with the numbers and where to put it right -- not the kernel's English (user, 2026-09-24: 「what is this warning\n * message means?」). Kept apart from the element so it is tested without a browser.\n */\n\ntype Say = (key: string, params: Record<string, string>) => string\n\n/** The refusal in words, or nothing for any other refusal. */\nexport function sizeRangeRefusalOf(error: unknown, say: Say): string | null {\n if ((error as { code?: string })?.code !== 'INSTANCE_SIZE_RANGE') return null\n const message = error instanceof Error ? error.message : String(error)\n const found = /size\\.([xyz]):\\s*(below|above) ([\\d.]+) mm [^(;]*(?:\\(([^)]+)\\))?;/.exec(message)\n if (!found) return null\n const [, axis, side, mm, part] = found\n return say(side === 'below' ? 'figure.text.size-range-too-small' : 'figure.text.size-range-too-large', {\n axis: axis!.toUpperCase(),\n mm: Number(mm).toLocaleString(undefined, { maximumFractionDigits: 1 }),\n part: part ?? ''\n })\n}\n\n/**\n * A link refused because the size range it would leave cannot hold: measuring again cannot help (the link is not there\n * to measure), so the author is offered the same link that narrows the range to what the figure then allows.\n */\nexport function narrowingRetryOf<A extends { kind: string }>(action: A, error: unknown, say: Say): { message: string; label: string; retry: A & { narrowRange: true } } | null {\n if (action.kind !== 'link-dimension' || (error as { code?: string })?.code !== 'INSTANCE_SIZE_RANGE') return null\n const message = error instanceof Error ? error.message : String(error)\n const found = /size\\.([xyz]):\\s*(below|above) ([\\d.]+) mm [^(;]*(?:\\(([^)]+)\\))?;/.exec(message)\n if (!found) return null\n const [, axis, side, raw, part] = found\n const mm = Number(raw).toLocaleString(undefined, { maximumFractionDigits: 1 })\n const words = { axis: axis!.toUpperCase(), mm, part: part ?? '' }\n return {\n message: say(side === 'below' ? 'figure.text.link-needs-smaller-range' : 'figure.text.link-needs-larger-range', words),\n label: say(side === 'below' ? 'figure.button.narrow-range-from' : 'figure.button.narrow-range-to', words),\n retry: { ...action, narrowRange: true }\n }\n}\n\n/**\n * A placement refused because a part is fastened to the mounting plane by a face the new plane does not take (a bottom\n * on the floor, when the figure is to hang on a wall), said in the author's words with the parts it names.\n */\nexport function placementRefusalOf(error: unknown, say: Say): string | null {\n if ((error as { code?: string })?.code !== 'PLACEMENT_PLANE') return null\n const message = error instanceof Error ? error.message : String(error)\n const found = /: (.+?) (?:is|are) fastened to the mounting plane by a face an? (\\w+) does not take \\(([^)]+)\\)/.exec(message)\n if (!found) return null\n return say('figure.text.placement-plane-refused', { parts: found[1]!, placement: say('figure.label.placement-' + found[2]!, {}), faces: found[3]! })\n}\n\n/** A part refused because the declared room reads it -- the one refusal deleting it with the room refitted answers. */\nexport function inDeclaredRoom(error: unknown): boolean {\n return (error as { code?: string })?.code === 'PART_REFERENCED' && /is in the space the figure declares/.test(error instanceof Error ? error.message : String(error))\n}\n\n/**\n * Why a part cannot be deleted, in the author's words. Since the chief architect's ruling of 2026-09-27 a part that\n * holds others, leads a motion or is followed goes, and what depended on it is let go of (`removalNoticeOf`); what is\n * left is the declared space (with a way on: fit it again) and a row -- one laid along the part, or hanging in its row.\n */\nexport function partRefusalOf(error: unknown, part: string, say: Say): string | null {\n const code = (error as { code?: string })?.code\n if (code !== 'PART_REFERENCED' && code !== 'PART_ROW') return null\n /* figure-model's sentence after its code and path: 「PART_ROW: bed: roller is a row laid along bed; …」. */\n const message = (error instanceof Error ? error.message : String(error)).replace(/^[A-Z_]+: [^:]+: /, '')\n if (/is in the space the figure declares/.test(message)) return say('figure.text.part-in-declared-space', { part })\n const along = /^(.+?) (?:is a row|are rows) laid along /.exec(message)\n if (along) return say('figure.text.part-row-along', { part, rows: along[1]! })\n const carried = /^(.+?) hangs? in the row /.exec(message)\n if (carried) return say('figure.text.part-row-carries', { part, others: carried[1]! })\n return say('figure.text.part-is-referenced', { part })\n}\n\n/** What removing a part let go of (figure-model's `RemovalNotice`), said in one line, or nothing when it let go of nothing. */\nexport function removalNoticeOf(\n notice:\n | {\n released: Array<{ part: string; control?: string }>\n fixed: Array<{ part: string }>\n controls: Array<{ part: string; control: string; min: number; max: number }>\n mountingFace?: boolean\n bindings?: Array<{ id: string; label?: string }>\n }\n | undefined,\n say: Say\n): string | null {\n if (!notice) return null\n const number = (v: number) => v.toLocaleString(undefined, { maximumFractionDigits: 3 })\n const lines: string[] = []\n const still = notice.released.filter(r => !r.control).map(r => r.part)\n if (still.length) lines.push(say('figure.text.removal-released', { parts: still.join(', ') }))\n for (const r of notice.released.filter(r => r.control)) lines.push(say('figure.text.removal-released-motion', { part: r.part, control: r.control! }))\n for (const c of notice.controls) lines.push(say('figure.text.removal-own-control', { part: c.part, control: c.control, min: number(c.min), max: number(c.max) }))\n const fixed = [...new Set(notice.fixed.map(f => f.part))]\n if (fixed.length) lines.push(say('figure.text.removal-fixed', { parts: fixed.join(', ') }))\n if (notice.bindings?.length) lines.push(say('figure.text.removal-bindings', { places: notice.bindings.map(b => b.label ?? b.id).join(', ') }))\n if (notice.mountingFace) lines.push(say('figure.text.removal-mounting-face', {}))\n return lines.length ? lines.join(' ') : null\n}\n\n/**\n * A recipe refused at one of its steps: which step, and why -- the particular sentence when there is one (a size\n * range, a value's range, a placement), otherwise the kernel's code. The kernel says 「steps[2]: attach: …」.\n */\nexport function recipeRefusalOf(error: unknown, say: Say): string | null {\n const step = /^steps\\[(\\d+)\\]$/.exec((error as { path?: string })?.path ?? '')\n if (!step) return null\n const why = sizeRangeRefusalOf(error, say) ?? inputRangeRefusalOf(error, say) ?? placementRefusalOf(error, say)\n return say('figure.text.recipe-step-refused', { step: String(Number(step[1]) + 1), why: why ?? '', code: (error as { code?: string })?.code ?? '' })\n}\n\n/**\n * A refusal no sentence above knows, said as a refusal with its code -- never the kernel's English on the screen (the\n * duplicate of a row's part showed 「EDIT_TARGET: … not a repeated template」, 2026-09-27). The figure's node limit\n * is said with its number.\n */\nexport function editRefusalOf(error: unknown, say: Say): string {\n const code = (error as { code?: string })?.code\n const message = error instanceof Error ? error.message : String(error)\n if (code === 'DOCUMENT_LIMIT') return say('figure.text.edit-refused-node-limit', { max: /maximum (\\d+) nodes/.exec(message)?.[1] ?? '' })\n return say('figure.text.edit-refused', { code: code ?? '' })\n}\n\n/**\n * A value outside the range its input declares, with the range and the value given -- the kernel says\n * 「size.x: 6021100 outside [300,1200]」. The figure's own size is named by its axis; any other input by its range only.\n * The repeat pitch's refusal shares the code and has its own words (`figure.text.repeat-pitch-too-small`).\n */\nexport function inputRangeRefusalOf(error: unknown, say: Say): string | null {\n if ((error as { code?: string })?.code !== 'INPUT_RANGE') return null\n const message = error instanceof Error ? error.message : String(error)\n const found = /([\\w.-]+): (-?[\\d.e+]+) outside \\[(-?[\\d.e+]+),\\s*(-?[\\d.e+]+)\\]/.exec(message)\n if (!found) return null\n const [, input, value, min, max] = found\n const number = (text: string) => Number(text).toLocaleString(undefined, { maximumFractionDigits: 3 })\n const axis = /^size\\.([xyz])$/.exec(input!)?.[1]\n const params = { value: number(value!), min: number(min!), max: number(max!) }\n return axis ? say('figure.text.input-range-size', { ...params, axis: axis.toUpperCase() }) : say('figure.text.input-range', params)\n}\n"]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as THREE from 'three';
|
|
2
|
-
/** Evaluated
|
|
3
|
-
export interface
|
|
2
|
+
/** Evaluated boundary: graph values are resolved before reaching the renderer. */
|
|
3
|
+
export interface FigureRenderPart {
|
|
4
4
|
id: string;
|
|
5
5
|
shape: {
|
|
6
6
|
provider: string;
|
|
@@ -31,10 +31,10 @@ export interface V3RenderPart {
|
|
|
31
31
|
*
|
|
32
32
|
* Two are left out. A scalar body carries no shape or pose — it is a number the graph produced, not something
|
|
33
33
|
* on screen. A body the asset hides is evaluated, placed and gated exactly as a shown one, and excluded from
|
|
34
|
-
* rendering, from shadows and from pointer picking (
|
|
34
|
+
* rendering, from shadows and from pointer picking (designer's ruling 2026-09-22); drawing it would make
|
|
35
35
|
* "hidden" mean nothing in the modeller while it means something on a board.
|
|
36
36
|
*/
|
|
37
|
-
export declare function
|
|
38
|
-
export declare function
|
|
37
|
+
export declare function drawableFigureParts(geometry: readonly unknown[]): FigureRenderPart[];
|
|
38
|
+
export declare function disposeFigureMeshes(group: THREE.Group): void;
|
|
39
39
|
/** Build first, then swap; failed rendering must not erase the previous scene. No old meshes survive a successful swap. */
|
|
40
|
-
export declare function
|
|
40
|
+
export declare function replaceFigureMeshes(group: THREE.Group, parts: readonly FigureRenderPart[], palette: Record<string, string>): void;
|