@hatiolab/figure-model 0.1.93 → 0.1.95

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 (63) hide show
  1. package/dist/asset-types.d.ts +7 -1
  2. package/dist/asset-types.d.ts.map +1 -1
  3. package/dist/asset.d.ts +12 -0
  4. package/dist/asset.d.ts.map +1 -1
  5. package/dist/asset.js +29 -8
  6. package/dist/asset.js.map +1 -1
  7. package/dist/authoring-actions.d.ts +13 -2
  8. package/dist/authoring-actions.d.ts.map +1 -1
  9. package/dist/authoring-actions.js +58 -31
  10. package/dist/authoring-actions.js.map +1 -1
  11. package/dist/authoring-session.d.ts +2 -0
  12. package/dist/authoring-session.d.ts.map +1 -1
  13. package/dist/authoring-session.js.map +1 -1
  14. package/dist/clip-keeping.d.ts +30 -0
  15. package/dist/clip-keeping.d.ts.map +1 -0
  16. package/dist/clip-keeping.js +77 -0
  17. package/dist/clip-keeping.js.map +1 -0
  18. package/dist/command-preview.d.ts +125 -0
  19. package/dist/command-preview.d.ts.map +1 -0
  20. package/dist/command-preview.js +246 -0
  21. package/dist/command-preview.js.map +1 -0
  22. package/dist/editor-workspace.d.ts +65 -1
  23. package/dist/editor-workspace.d.ts.map +1 -1
  24. package/dist/editor-workspace.js +48 -6
  25. package/dist/editor-workspace.js.map +1 -1
  26. package/dist/gate.d.ts +8 -0
  27. package/dist/gate.d.ts.map +1 -1
  28. package/dist/gate.js +13 -7
  29. package/dist/gate.js.map +1 -1
  30. package/dist/index.d.ts +8 -2
  31. package/dist/index.d.ts.map +1 -1
  32. package/dist/index.js +7 -1
  33. package/dist/index.js.map +1 -1
  34. package/dist/kernel-version.d.ts +1 -1
  35. package/dist/kernel-version.js +1 -1
  36. package/dist/part-edit.d.ts +3 -2
  37. package/dist/part-edit.d.ts.map +1 -1
  38. package/dist/part-edit.js +22 -6
  39. package/dist/part-edit.js.map +1 -1
  40. package/dist/proposal.d.ts +15 -2
  41. package/dist/proposal.d.ts.map +1 -1
  42. package/dist/proposal.js +12 -4
  43. package/dist/proposal.js.map +1 -1
  44. package/dist/release-contract.d.ts.map +1 -1
  45. package/dist/release-contract.js +3 -2
  46. package/dist/release-contract.js.map +1 -1
  47. package/dist/resize-plan.d.ts +61 -0
  48. package/dist/resize-plan.d.ts.map +1 -0
  49. package/dist/resize-plan.js +189 -0
  50. package/dist/resize-plan.js.map +1 -0
  51. package/dist/room.d.ts +53 -0
  52. package/dist/room.d.ts.map +1 -0
  53. package/dist/room.js +90 -0
  54. package/dist/room.js.map +1 -0
  55. package/dist/shape-provider.d.ts +37 -0
  56. package/dist/shape-provider.d.ts.map +1 -0
  57. package/dist/shape-provider.js +69 -0
  58. package/dist/shape-provider.js.map +1 -0
  59. package/dist/size-edit.d.ts +38 -0
  60. package/dist/size-edit.d.ts.map +1 -0
  61. package/dist/size-edit.js +178 -0
  62. package/dist/size-edit.js.map +1 -0
  63. package/package.json +1 -1
@@ -0,0 +1,189 @@
1
+ import { applyFigureAuthoring } from "./authoring-actions.js";
2
+ import { figurePlacementOf, upgradeFigurePlacement } from "./asset.js";
3
+ import { compileFigureGraph } from "./graph.js";
4
+ import { figurePartsExtentOf } from "./gate.js";
5
+ import { defaultInstanceSizeRange, foldInstanceSizeRange, figureInstanceSizeLimitsOf, FIGURE_INSTANCE_SIZE_INPUTS } from "./instance-size.js";
6
+ import { figureFollowOf } from "./follow.js";
7
+ import { figureShapeProviderOf, figureFollowableAxesOf } from "./shape-provider.js";
8
+ import { AXES } from "./words.js";
9
+ /** The face each placement keeps, and the axis the plane faces along. The ceiling and the floor are Y = 0, a wall Z = 0. */
10
+ export const KEPT_FACE = {
11
+ floor: { face: 'bottom', normal: 'y', outward: 1 },
12
+ ceiling: { face: 'top', normal: 'y', outward: -1 },
13
+ wall: { face: 'back', normal: 'z', outward: 1 },
14
+ center: undefined
15
+ };
16
+ const round6 = (v) => Math.round(v * 1e6) / 1e6;
17
+ export function planFigureResize(asset, request) {
18
+ asset = upgradeFigurePlacement(asset);
19
+ const mode = figurePlacementOf(asset);
20
+ const kept = KEPT_FACE[mode];
21
+ const plan = { part: request.part, mode, ...(kept ? { face: kept.face } : {}), steps: [], keeps: [], replaces: [], moves: [], roomReads: [] };
22
+ const refuse = (code, reason, choice, about = {}) => ({
23
+ ...plan,
24
+ steps: [],
25
+ keeps: [],
26
+ replaces: [],
27
+ moves: [],
28
+ roomReads: [],
29
+ refusal: { code, reason, ...(choice ? { choice } : {}), ...about }
30
+ });
31
+ const m = asset.document.model;
32
+ const node = (id) => m.nodes.find((n) => n.id === id);
33
+ const part = request.part;
34
+ const place = node(part);
35
+ if (!place || (place.op !== 'place@1' && place.op !== 'member@1'))
36
+ return refuse('TARGET_ABSENT', `${part} is not a part`);
37
+ if (place.op === 'member@1')
38
+ return refuse('HELD', `${part} is a copy in a row; its row places it`);
39
+ const shape = m.nodes.find((n) => Object.values(n.outputs ?? {}).includes(place.args[0]));
40
+ const pose = node(`${part}.pose`);
41
+ if (!shape || pose?.op !== 'rigid@1')
42
+ return refuse('TARGET_ABSENT', `${part} has no shape and pose this plan can read`);
43
+ /* What the author set stays theirs: a joint, a fastening, a figure that grows by one ratio. */
44
+ const joint = (asset.joints ?? []).find((j) => j.body1?.part === part);
45
+ if (joint)
46
+ return refuse('HELD', `${part} is fastened (${joint.id}); edit that joint to change how it stands`);
47
+ if (node(`${part}.chain`) || node(`${part}.seat.rigid`))
48
+ return refuse('HELD', `${part} is fastened; edit its fastening to change how it stands`);
49
+ if (asset.sizing === 'uniform')
50
+ return refuse('UNIFORM_POLICY', 'this figure grows by one ratio; change that policy before giving a part its own size rule');
51
+ const values = compileFigureGraph(m).evaluate({ ...asset.designInputs, ...asset.stateDefaults }).values;
52
+ const input = (ref) => m.inputs.find((i) => i.id === ref);
53
+ const constant = (ref) => m.constants.find((c) => c.id === ref);
54
+ const turn = pose.args.slice(3, 6).map(ref => (constant(ref) ? constant(ref).value : input(ref)?.role === 'design' ? asset.designInputs[ref] : undefined));
55
+ if (turn.some(t => t !== 0))
56
+ return refuse('TURNED', `${part} is turned (${turn.map((t, i) => `${AXES[i].toUpperCase()} ${t ?? '?'}°`).join(', ')}); this plan does not turn or fix a turn`);
57
+ /* The measures: what the shape can edit, each read back as it is worked out now. */
58
+ const provider = figureShapeProviderOf(shape.op);
59
+ const editable = figureFollowableAxesOf(shape.op);
60
+ const axes = request.axes ?? editable;
61
+ if (!axes.length)
62
+ return refuse('SHAPE_EDIT', `${part} is a ${shape.op}; following the figure's size is not offered for it`);
63
+ for (const axis of axes) {
64
+ if (!editable.includes(axis))
65
+ return refuse('SHAPE_EDIT', `${part} is a ${shape.op}; following the figure's size along ${axis} is not offered for it`);
66
+ const edit = provider.edit[axis];
67
+ /*
68
+ Linking reads a shape's measure along X, Y and Z at its first three arguments. Shapes whose measure is elsewhere or
69
+ moves with another (an elliptic cylinder's length, a frustum's two ends) are not linked by this plan yet.
70
+ */
71
+ if (edit.arg !== AXES.indexOf(axis) || edit.with?.length)
72
+ return refuse('SHAPE_EDIT', `${part} is a ${shape.op}; following the size along ${axis} is not supported for it yet`);
73
+ }
74
+ const link = [];
75
+ const stopsReading = [];
76
+ for (const axis of axes) {
77
+ const now = figureFollowOf(asset, part, axis);
78
+ if (now.of === 'own') {
79
+ link.push(axis);
80
+ const was = node(`${part}.dimension.${axis}`)?.args?.[0] ?? shape.args[AXES.indexOf(axis)];
81
+ if (input(was))
82
+ stopsReading.push(was);
83
+ }
84
+ else if (now.of === 'instance' && now.axis === axis)
85
+ plan.keeps.push(`${part}.${axis} follows size.${axis}`);
86
+ else
87
+ return refuse('DIMENSION_RULE', `${part}'s ${axis} follows ${now.of === 'input' ? now.input : now.of === 'part' ? `${now.part}'s ${now.axis}` : now.of === 'instance' ? `size.${now.axis}` : 'a rule of its own'}; edit that rule itself to change it`);
88
+ }
89
+ /* The fastening: the kept face at the gap it has now, and the place across the plane as the author set it. */
90
+ let fasten;
91
+ if (kept) {
92
+ const face = provider?.faces[kept.face];
93
+ if (!face || face.axis !== kept.normal)
94
+ return refuse('NO_FACE', `${part} is a ${shape.op}; it has no flat ${kept.face} face to keep on the ${mode === 'wall' ? 'wall' : mode}`);
95
+ const at = (axis) => values[pose.args[AXES.indexOf(axis)]];
96
+ const plane = face.plane.reduce((sum, p) => sum + p.k * values[shape.args[p.arg]], 0);
97
+ /* How far the face stands out of the plane: a bottom above the floor, a top below the ceiling, a back off the wall. */
98
+ let gap = round6(kept.outward * (at(kept.normal) + plane));
99
+ /* Touching, it is fastened as it is. Off the plane or through it, the author says which: both are meant sometimes. */
100
+ if (gap !== 0) {
101
+ if (request.gap === undefined)
102
+ return refuse('GAP_CHOICE', `${part}'s ${kept.face} is ${gap > 0 ? `${gap} mm off` : `${-gap} mm through`} the ${mode}; keep that distance, or bring it onto the plane`, 'gap', { axis: kept.normal, mm: gap });
103
+ if (request.gap === 'plane') {
104
+ plan.moves.push({ axis: kept.normal, from: round6(at(kept.normal)), to: round6(at(kept.normal) - kept.outward * gap) });
105
+ gap = 0;
106
+ }
107
+ else if (request.gap !== 'keep')
108
+ return refuse('COMMAND_REFUSED', `${String(request.gap)} is neither keep nor plane`);
109
+ }
110
+ const normalRef = pose.args[AXES.indexOf(kept.normal)];
111
+ const ownField = (ref) => ref.startsWith(`${part}.`) && input(ref)?.role === 'design';
112
+ if (!constant(normalRef) && !ownField(normalRef) && !request.replacePosition)
113
+ return refuse('POSITION_RULE', `${part}'s ${kept.normal} position is worked out from ${input(normalRef) ? normalRef : 'an expression'}; keeping its ${kept.face} on the plane replaces that`, 'replacePosition', { axis: kept.normal });
114
+ if (input(normalRef))
115
+ plan.replaces.push(normalRef);
116
+ const align = {};
117
+ for (const axis of AXES.filter(a => a !== kept.normal)) {
118
+ const ref = pose.args[AXES.indexOf(axis)];
119
+ if (constant(ref))
120
+ align[axis] = { mm: constant(ref).value };
121
+ else if (input(ref)?.role === 'design') {
122
+ align[axis] = { mm: { from: { of: 'input', input: ref } } };
123
+ plan.keeps.push(ref);
124
+ }
125
+ else if (request.replacePosition)
126
+ align[axis] = { mm: round6(at(axis)) };
127
+ else
128
+ return refuse('POSITION_RULE', `${part}'s ${axis} position is worked out from an expression; fastening it would fix it at ${round6(at(axis))}`, 'replacePosition', { axis });
129
+ }
130
+ /*
131
+ A fastened part's turn is its joint record's (ADR-0093): its own turn fields give way to it, at the turn they hold
132
+ now -- nothing turns, but the fields go, and the plan says so before it is applied (browser check 2026-09-27).
133
+ */
134
+ for (const ref of pose.args.slice(3, 6))
135
+ if (input(ref))
136
+ plan.replaces.push(ref);
137
+ fasten = { kind: 'attach', part, face: kept.face, to: { plane: 'mounting-plane' }, ...(gap ? { gap } : {}), align };
138
+ }
139
+ else
140
+ plan.keeps.push(...pose.args.slice(0, 3).filter(ref => input(ref)));
141
+ /* Worked out on a copy, in the order the commands need: a size to follow, the measures, then the face. */
142
+ let candidate = asset;
143
+ const step = (s) => {
144
+ candidate = applyFigureAuthoring(candidate, s);
145
+ plan.steps.push(s);
146
+ };
147
+ try {
148
+ const declared = AXES.filter(axis => asset.document.model.inputs.some((i) => i.id === FIGURE_INSTANCE_SIZE_INPUTS[axis]));
149
+ if (link.length && declared.length < 3) {
150
+ const at = figurePartsExtentOf(asset);
151
+ const start = defaultInstanceSizeRange(at);
152
+ const range = foldInstanceSizeRange(start, figureInstanceSizeLimitsOf(asset, start)).range;
153
+ step({ kind: 'declare-instance-size', at, range, replace: declared.length > 0 });
154
+ }
155
+ for (const axis of link) {
156
+ const measure = values[shape.args[AXES.indexOf(axis)]];
157
+ const size = candidate.designInputs[FIGURE_INSTANCE_SIZE_INPUTS[axis]];
158
+ step({ kind: 'link-dimension', part, axis, source: { of: 'instance', axis }, times: measure / size, narrowRange: true });
159
+ }
160
+ if (fasten)
161
+ step(fasten);
162
+ plan.roomReads = [...stopsReading, ...plan.replaces].filter(roomReading(candidate));
163
+ }
164
+ catch (e) {
165
+ const error = e;
166
+ return refuse('COMMAND_REFUSED', `${error.code ?? ''} ${String(error.message ?? e)}`.trim());
167
+ }
168
+ return plan;
169
+ }
170
+ /** Whether the declared room is worked out from a value: the room's bounds, followed back through the graph. */
171
+ function roomReading(asset) {
172
+ const m = asset.document.model;
173
+ const bounds = asset.occupancy?.bounds;
174
+ const read = new Set();
175
+ const walk = (ref) => {
176
+ if (read.has(ref))
177
+ return;
178
+ read.add(ref);
179
+ const writer = m.nodes.find((n) => Object.values(n.outputs ?? {}).includes(ref));
180
+ for (const arg of writer?.args ?? [])
181
+ walk(arg);
182
+ };
183
+ for (const axis of AXES)
184
+ if (bounds?.[axis])
185
+ for (const end of ['min', 'max'])
186
+ walk(bounds[axis][end]);
187
+ return ref => read.has(ref);
188
+ }
189
+ //# sourceMappingURL=resize-plan.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resize-plan.js","sourceRoot":"","sources":["../src/resize-plan.ts"],"names":[],"mappings":"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"}
package/dist/room.d.ts ADDED
@@ -0,0 +1,53 @@
1
+ import type { FigureAsset } from './asset-types.ts';
2
+ import type { FigureAuthoringAction } from './authoring-actions.ts';
3
+ import { type Axis } from './words.ts';
4
+ type Bounds = Record<Axis, {
5
+ min: number;
6
+ max: number;
7
+ }>;
8
+ /**
9
+ * Design inputs the declared room reads and nothing drawn does: a part's old position or size, left when a rule took
10
+ * its place, which the room was measured from. They move no part; typing into one changes only the room. With `part`,
11
+ * only that part's own (`<part>.…`).
12
+ */
13
+ export declare function figureRoomOnlyInputsOf(asset: FigureAsset, part?: string): string[];
14
+ export interface FigureRoomRefit {
15
+ /** The command that declares the room again from the parts, as proposed now: apply it only when the author confirms. */
16
+ step: Extract<FigureAuthoringAction, {
17
+ kind: 'declare-occupancy';
18
+ }>;
19
+ /** The room as declared and as proposed, at the authored size and, when the figure declares its size, at the largest. */
20
+ declared: {
21
+ authored: Bounds;
22
+ largest?: Bounds;
23
+ };
24
+ proposed: {
25
+ authored: Bounds;
26
+ largest?: Bounds;
27
+ };
28
+ /** Parts the release gate finds outside each room, and how it checked: proven over the range, or sampled. */
29
+ /** Inputs that confirming removes: read by nothing once the room is declared again -- a part's old position or size. */
30
+ drops: string[];
31
+ outside: {
32
+ declared: FigureRoomFinding;
33
+ proposed: FigureRoomFinding;
34
+ };
35
+ }
36
+ /** A part outside the room: on which axis, and by how much at worst. */
37
+ export type FigureRoomOutside = {
38
+ part: string;
39
+ axis: Axis;
40
+ mm: number;
41
+ };
42
+ /** The parts outside, and how the gate checked: `proven` over the whole range, or `sampled` at `states` states. */
43
+ export type FigureRoomFinding = {
44
+ parts: FigureRoomOutside[];
45
+ coverage: {
46
+ method: 'proven' | 'sampled' | 'defaults';
47
+ states: number;
48
+ };
49
+ };
50
+ /** What declaring the room again would change, or undefined for a figure with no room declared. */
51
+ export declare function figureRoomRefitOf(asset: FigureAsset): FigureRoomRefit | undefined;
52
+ export {};
53
+ //# sourceMappingURL=room.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"room.d.ts","sourceRoot":"","sources":["../src/room.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AACnD,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAA;AAKnE,OAAO,EAAQ,KAAK,IAAI,EAAE,MAAM,YAAY,CAAA;AAG5C,KAAK,MAAM,GAAG,MAAM,CAAC,IAAI,EAAE;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAAC,CAAA;AAoBxD;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,WAAW,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAiBlF;AAED,MAAM,WAAW,eAAe;IAC9B,wHAAwH;IACxH,IAAI,EAAE,OAAO,CAAC,qBAAqB,EAAE;QAAE,IAAI,EAAE,mBAAmB,CAAA;KAAE,CAAC,CAAA;IACnE,yHAAyH;IACzH,QAAQ,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;IAChD,QAAQ,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;IAChD,6GAA6G;IAC7G,wHAAwH;IACxH,KAAK,EAAE,MAAM,EAAE,CAAA;IACf,OAAO,EAAE;QAAE,QAAQ,EAAE,iBAAiB,CAAC;QAAC,QAAQ,EAAE,iBAAiB,CAAA;KAAE,CAAA;CACtE;AACD,wEAAwE;AACxE,MAAM,MAAM,iBAAiB,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,IAAI,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,CAAA;AACxE,mHAAmH;AACnH,MAAM,MAAM,iBAAiB,GAAG;IAAE,KAAK,EAAE,iBAAiB,EAAE,CAAC;IAAC,QAAQ,EAAE;QAAE,MAAM,EAAE,QAAQ,GAAG,SAAS,GAAG,UAAU,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,CAAA;AAEvI,mGAAmG;AACnG,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,WAAW,GAAG,eAAe,GAAG,SAAS,CAgCjF"}
package/dist/room.js ADDED
@@ -0,0 +1,90 @@
1
+ /*
2
+ * The declared room, read for the author (ADR-0097 §6): which inputs only the room still reads, and what declaring it
3
+ * again from the parts would change. The room is never widened or rewritten as a side effect of another command; a
4
+ * person sees the room as declared and as proposed, and what the gate finds outside each, before confirming.
5
+ */
6
+ import { upgradeFigurePlacement } from "./asset.js";
7
+ import { applyFigureAuthoring, proposeFigureOccupancy } from "./authoring-actions.js";
8
+ import { compileFigureGraph } from "./graph.js";
9
+ import { inspectFigureAsset } from "./gate.js";
10
+ import { FIGURE_INSTANCE_SIZE_INPUTS } from "./instance-size.js";
11
+ import { AXES } from "./words.js";
12
+ const stringsIn = (value) => typeof value === 'string' ? [value] : Array.isArray(value) ? value.flatMap(stringsIn) : value && typeof value === 'object' ? Object.values(value).flatMap(stringsIn) : [];
13
+ /** Every value a set of references is worked out from, inputs included. */
14
+ function readFrom(m, from) {
15
+ const writers = new Map();
16
+ for (const n of m.nodes)
17
+ for (const ref of Object.values(n.outputs ?? {}))
18
+ writers.set(ref, n);
19
+ const read = new Set();
20
+ for (const pending = [...from]; pending.length;) {
21
+ const ref = pending.pop();
22
+ if (read.has(ref))
23
+ continue;
24
+ read.add(ref);
25
+ const writer = writers.get(ref);
26
+ if (writer)
27
+ pending.push(...writer.args, ...stringsIn(writer.params));
28
+ }
29
+ return read;
30
+ }
31
+ /**
32
+ * Design inputs the declared room reads and nothing drawn does: a part's old position or size, left when a rule took
33
+ * its place, which the room was measured from. They move no part; typing into one changes only the room. With `part`,
34
+ * only that part's own (`<part>.…`).
35
+ */
36
+ export function figureRoomOnlyInputsOf(asset, part) {
37
+ asset = upgradeFigurePlacement(asset);
38
+ const a = asset;
39
+ const m = a.document.model;
40
+ if (!a.occupancy)
41
+ return [];
42
+ const drawn = readFrom(m, [
43
+ ...m.nodes.filter((n) => n.op === 'place@1' || n.op === 'member@1' || n.op === 'repeat@1').flatMap((n) => n.args),
44
+ ...stringsIn(a.appearance),
45
+ ...stringsIn(a.document.capabilities),
46
+ ...stringsIn(a.drivers),
47
+ ...stringsIn(a.publicInputs),
48
+ ...stringsIn(a.joints)
49
+ ]);
50
+ const room = readFrom(m, stringsIn(a.occupancy));
51
+ return m.inputs
52
+ .filter((i) => i.role === 'design' && room.has(i.id) && !drawn.has(i.id) && (!part || i.id.startsWith(`${part}.`)))
53
+ .map((i) => i.id);
54
+ }
55
+ /** What declaring the room again would change, or undefined for a figure with no room declared. */
56
+ export function figureRoomRefitOf(asset) {
57
+ asset = upgradeFigurePlacement(asset);
58
+ if (!asset.occupancy)
59
+ return undefined;
60
+ const step = { kind: 'declare-occupancy', proposal: proposeFigureOccupancy(asset, { over: 'range' }) };
61
+ const refit = applyFigureAuthoring(asset, step);
62
+ const m = asset.document.model;
63
+ const sizes = AXES.map(axis => m.inputs.find((i) => i.id === FIGURE_INSTANCE_SIZE_INPUTS[axis]));
64
+ const largest = sizes.every(Boolean) ? Object.fromEntries(sizes.map(i => [i.id, i.max])) : undefined;
65
+ const boundsOf = (a, at = {}) => {
66
+ const values = compileFigureGraph(a.document.model).evaluate({ ...a.designInputs, ...a.stateDefaults, ...at }).values;
67
+ const b = a.occupancy.bounds;
68
+ return Object.fromEntries(AXES.map(axis => [axis, { min: values[b[axis].min], max: values[b[axis].max] }]));
69
+ };
70
+ /*
71
+ What lies outside, as the release gate finds it over the sizes and states the figure allows -- with its coverage:
72
+ proven over the whole range, or sampled at so many states, which is not a bound (designer 2026-09-27: a check of a
73
+ few corners is not a proof of the range).
74
+ */
75
+ const outside = (a) => {
76
+ const report = inspectFigureAsset(a);
77
+ return {
78
+ parts: report.violations.filter(v => v.code === 'PART_OUTSIDE_OCCUPANCY').map(v => ({ part: v.part, axis: v.axis, mm: v.mm })),
79
+ coverage: { method: report.coverage.method, states: report.coverage.states }
80
+ };
81
+ };
82
+ return {
83
+ step,
84
+ drops: Object.keys(asset.designInputs).filter(id => !(id in refit.designInputs)),
85
+ declared: { authored: boundsOf(asset), ...(largest ? { largest: boundsOf(asset, largest) } : {}) },
86
+ proposed: { authored: boundsOf(refit), ...(largest ? { largest: boundsOf(refit, largest) } : {}) },
87
+ outside: { declared: outside(asset), proposed: outside(refit) }
88
+ };
89
+ }
90
+ //# sourceMappingURL=room.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"room.js","sourceRoot":"","sources":["../src/room.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,37 @@
1
+ import type { Axis } from './words.ts';
2
+ import { type FigureShapeFace } from './graph.ts';
3
+ /**
4
+ * What a shape offers the commands that size and place a part (ADR-0097 §6): how far it reaches along each of its own
5
+ * axes, which of those a size can edit and how, and the flat faces it can be attached by. Three separate answers: a
6
+ * sphere is measured along every axis and edited along every axis, yet has no face to attach by; a section is measured
7
+ * across by its corners and edited across by none. Nothing reads a shape's arguments by their order to find X, Y or Z.
8
+ */
9
+ export interface FigureShapeProvider {
10
+ /** Along each axis, candidates whose largest is the reach -- `Σ k × argument` each (a frustum is as wide as its wider end). */
11
+ measure: Readonly<Record<Axis, ReadonlyArray<FigureShapeTerm> | 'profile'>>;
12
+ /** Along each axis, how a size edits the shape, or why it cannot. */
13
+ edit: Readonly<Record<Axis, FigureShapeEdit>>;
14
+ /** The flat faces a part can be attached by, as the shape's operator declares them; none for a sphere. */
15
+ faces: Readonly<Record<string, FigureShapeFace>>;
16
+ }
17
+ export type FigureShapeTerm = {
18
+ arg: number;
19
+ k: number;
20
+ };
21
+ export type FigureShapeEdit = {
22
+ arg: number;
23
+ k: number;
24
+ with?: readonly number[];
25
+ sameAs?: Axis;
26
+ } | {
27
+ refused: FigureShapeEditRefusal;
28
+ };
29
+ /** Why an axis cannot be edited: its measure is its section's corners, or the shape has no measure along it. */
30
+ export type FigureShapeEditRefusal = 'SECTION_CORNERS' | 'NO_MEASURE';
31
+ /** The provider for a shape operator, or undefined for an operator that is not a shape. */
32
+ export declare function figureShapeProviderOf(op: string): FigureShapeProvider | undefined;
33
+ /** The axes a size can edit on its own: every editable axis but one that is another's measure. */
34
+ export declare function figureEditableAxesOf(op: string): Axis[];
35
+ /** The axes a part of this shape can make follow the figure's size, or another's measure, now. */
36
+ export declare function figureFollowableAxesOf(op: string): Axis[];
37
+ //# sourceMappingURL=shape-provider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shape-provider.d.ts","sourceRoot":"","sources":["../src/shape-provider.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAA;AACtC,OAAO,EAAoB,KAAK,eAAe,EAAE,MAAM,YAAY,CAAA;AAEnE;;;;;GAKG;AACH,MAAM,WAAW,mBAAmB;IAClC,+HAA+H;IAC/H,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,IAAI,EAAE,aAAa,CAAC,eAAe,CAAC,GAAG,SAAS,CAAC,CAAC,CAAA;IAC3E,qEAAqE;IACrE,IAAI,EAAE,QAAQ,CAAC,MAAM,CAAC,IAAI,EAAE,eAAe,CAAC,CAAC,CAAA;IAC7C,0GAA0G;IAC1G,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC,CAAA;CACjD;AAED,MAAM,MAAM,eAAe,GAAG;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAA;CAAE,CAAA;AAExD,MAAM,MAAM,eAAe,GAMvB;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAAC,MAAM,CAAC,EAAE,IAAI,CAAA;CAAE,GACnE;IAAE,OAAO,EAAE,sBAAsB,CAAA;CAAE,CAAA;AAEvC,gHAAgH;AAChH,MAAM,MAAM,sBAAsB,GAAG,iBAAiB,GAAG,YAAY,CAAA;AA6CrE,2FAA2F;AAC3F,wBAAgB,qBAAqB,CAAC,EAAE,EAAE,MAAM,GAAG,mBAAmB,GAAG,SAAS,CAGjF;AAED,kGAAkG;AAClG,wBAAgB,oBAAoB,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,EAAE,CAOvD;AAUD,kGAAkG;AAClG,wBAAgB,sBAAsB,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,EAAE,CAEzD"}
@@ -0,0 +1,69 @@
1
+ import { figureShapeFaces } from "./graph.js";
2
+ const term = (arg, k = 1) => [{ arg, k }];
3
+ const BOX_MEASURE = { x: term(0), y: term(1), z: term(2) };
4
+ const BOX_EDIT = { x: { arg: 0, k: 1 }, y: { arg: 1, k: 1 }, z: { arg: 2, k: 1 } };
5
+ const PROVIDERS = {
6
+ 'box-shape@1': { measure: BOX_MEASURE, edit: BOX_EDIT },
7
+ /* A rounded, hollow or framed box measures and edits as a box; its corners, walls, jambs and head keep their own numbers. */
8
+ 'rounded-box@1': { measure: BOX_MEASURE, edit: BOX_EDIT },
9
+ 'rounded-box@2': { measure: BOX_MEASURE, edit: BOX_EDIT },
10
+ 'hollow-box@1': { measure: BOX_MEASURE, edit: BOX_EDIT },
11
+ 'hollow-box@2': { measure: BOX_MEASURE, edit: BOX_EDIT },
12
+ 'portal-profile@2': { measure: BOX_MEASURE, edit: BOX_EDIT },
13
+ /* A cylinder stands along its Y: its radius across (X, and Z with it), its length along. */
14
+ 'cylinder-shape@1': {
15
+ measure: { x: term(0, 2), y: term(1), z: term(0, 2) },
16
+ edit: { x: { arg: 0, k: 2 }, y: { arg: 1, k: 1 }, z: { arg: 0, k: 2, sameAs: 'x' } }
17
+ },
18
+ /* An elliptic cylinder: (radiusX, radiusZ, length) -- a radius across each way, its length along Y. */
19
+ 'cylinder-shape@2': {
20
+ measure: { x: term(0, 2), y: term(2), z: term(1, 2) },
21
+ edit: { x: { arg: 0, k: 2 }, y: { arg: 2, k: 1 }, z: { arg: 1, k: 2 } }
22
+ },
23
+ /* An ellipsoid: a radius each way. */
24
+ 'sphere-shape@1': {
25
+ measure: { x: term(0, 2), y: term(1, 2), z: term(2, 2) },
26
+ edit: { x: { arg: 0, k: 2 }, y: { arg: 1, k: 2 }, z: { arg: 2, k: 2 } }
27
+ },
28
+ /*
29
+ A frustum (radiusTop, radiusBottom, height): as wide as the wider of its two ends, whichever that is. A width edits
30
+ both ends in proportion, so the taper stays and an end of radius 0 -- a cone's point -- stays a point; editing one
31
+ radius alone is not a change of width.
32
+ */
33
+ 'frustum-shape@1': {
34
+ measure: { x: [{ arg: 0, k: 2 }, { arg: 1, k: 2 }], y: term(2), z: [{ arg: 0, k: 2 }, { arg: 1, k: 2 }] },
35
+ edit: { x: { arg: 1, k: 2, with: [0] }, y: { arg: 2, k: 1 }, z: { arg: 1, k: 2, with: [0], sameAs: 'x' } }
36
+ },
37
+ /* A section (height, then its corners) pushed along Y: measured across by its corners, which no size edits. */
38
+ 'polygon-shape@1': {
39
+ measure: { x: 'profile', y: term(0), z: 'profile' },
40
+ edit: { x: { refused: 'SECTION_CORNERS' }, y: { arg: 0, k: 1 }, z: { refused: 'SECTION_CORNERS' } }
41
+ }
42
+ };
43
+ /** The provider for a shape operator, or undefined for an operator that is not a shape. */
44
+ export function figureShapeProviderOf(op) {
45
+ const own = PROVIDERS[op];
46
+ return own && { ...own, faces: figureShapeFaces(op) ?? {} };
47
+ }
48
+ /** The axes a size can edit on its own: every editable axis but one that is another's measure. */
49
+ export function figureEditableAxesOf(op) {
50
+ const edit = PROVIDERS[op]?.edit;
51
+ if (!edit)
52
+ return [];
53
+ return ['x', 'y', 'z'].filter(axis => {
54
+ const e = edit[axis];
55
+ return !('refused' in e) && !e.sameAs;
56
+ });
57
+ }
58
+ /*
59
+ * The shapes whose size can follow something today: a measure is linked through the shape's argument at the axis's
60
+ * place, so only shapes whose edited measures sit there are taken. Every command and screen that offers "follow"
61
+ * asks here -- follow-size, the resize plan, the modeller -- so no two lists decide it apart (designer 2026-09-27).
62
+ * The other shapes wait for linking to read the provider's `edit`.
63
+ */
64
+ const FOLLOWS_NOW = new Set(['box-shape@1', 'rounded-box@1', 'portal-profile@2', 'hollow-box@2', 'cylinder-shape@1']);
65
+ /** The axes a part of this shape can make follow the figure's size, or another's measure, now. */
66
+ export function figureFollowableAxesOf(op) {
67
+ return FOLLOWS_NOW.has(op) ? figureEditableAxesOf(op) : [];
68
+ }
69
+ //# sourceMappingURL=shape-provider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shape-provider.js","sourceRoot":"","sources":["../src/shape-provider.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,38 @@
1
+ import type { FigureAsset } from './asset-types.ts';
2
+ import type { FigureInputChange } from './authoring-session.ts';
3
+ export declare function figureSizeEditChanges(asset: FigureAsset, part: string, changes: readonly FigureInputChange[]): FigureInputChange[];
4
+ /**
5
+ * Per axis of the part's own frame, the face a size change keeps: 1 the low face (the part grows toward +), -1 the high
6
+ * face, 0 its centre -- what `figureSizeEditChanges` writes for a part placed by its own numbers, and what a fastening
7
+ * keeps for a fastened one (its face along the normal, its edges where it is aligned min or max). A gizmo drag shows
8
+ * this while it is dragged, so what the author sees is what is written (designer 2026-09-27: 「드래그 중 미리보기와
9
+ * 확정에 같은 기준면·간격 규칙」). Undefined where it cannot be said in the part's own axes -- a fastening turned or
10
+ * twisted -- and the caller must not guess one.
11
+ */
12
+ export declare function figureScaleAnchorOf(asset: FigureAsset, part: string): Record<'x' | 'y' | 'z', -1 | 0 | 1> | undefined;
13
+ export type FigurePlaneAlignRefusal = 'HELD' | 'POSITION_RULE' | 'NO_FACE';
14
+ /**
15
+ * How the part meets the plane once aligned: `face` -- its named face lies on it; `tilted` -- it has that face but stands
16
+ * turned off the plane, so only its lowest (highest, backmost) point or edge touches, and the turn is left as it is;
17
+ * `extreme` -- no face of its own is known there (a ball), and its lowest (highest, backmost) extent touches; `centre` --
18
+ * a centred figure's part, its centre brought to the origin's height. The screen says which (designer 2026-09-27: a
19
+ * point touching is not a face attached; a ball is not said to be tilted).
20
+ */
21
+ export type FigurePlaneContact = 'face' | 'tilted' | 'extreme' | 'centre';
22
+ /**
23
+ * "Put it on the plane, this once" -- the modeller's one-off align tool, by the figure's placement (designer 2026-09-27):
24
+ * a floor figure's part brings its bottom to Y 0, a ceiling one's its top, a wall one's its back to Z 0, and a centred
25
+ * figure's part its centre to the origin's height. Only the part's own position number moves; nothing is fastened, so a
26
+ * later change of size keeps the face by the size rule, not by a fastening (ADR-0097 §5.2: aligning once is not
27
+ * attaching). A part standing turned is aligned by the extent it covers turned, its lowest (highest, backmost) point,
28
+ * since its named face no longer lies along the plane.
29
+ *
30
+ * Refused, with the reason: a fastened part (its fastening places it), and a part whose position is worked out. The
31
+ * part's turn is never changed: only the one position number is written.
32
+ */
33
+ export declare function figurePlaneAlignChanges(asset: FigureAsset, part: string): {
34
+ changes: FigureInputChange[];
35
+ contact?: FigurePlaneContact;
36
+ refusal?: FigurePlaneAlignRefusal;
37
+ };
38
+ //# sourceMappingURL=size-edit.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"size-edit.d.ts","sourceRoot":"","sources":["../src/size-edit.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,WAAW,EAAmB,MAAM,kBAAkB,CAAA;AACpE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAA;AA0B/D,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,SAAS,iBAAiB,EAAE,GAAG,iBAAiB,EAAE,CA0ClI;AAED;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC,GAAG,GAAG,GAAG,GAAG,GAAG,EAAE,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,SAAS,CAiCrH;AAED,MAAM,MAAM,uBAAuB,GAAG,MAAM,GAAG,eAAe,GAAG,SAAS,CAAA;AAC1E;;;;;;GAMG;AACH,MAAM,MAAM,kBAAkB,GAAG,MAAM,GAAG,QAAQ,GAAG,SAAS,GAAG,QAAQ,CAAA;AAEzE;;;;;;;;;;GAUG;AACH,wBAAgB,uBAAuB,CACrC,KAAK,EAAE,WAAW,EAClB,IAAI,EAAE,MAAM,GACX;IAAE,OAAO,EAAE,iBAAiB,EAAE,CAAC;IAAC,OAAO,CAAC,EAAE,kBAAkB,CAAC;IAAC,OAAO,CAAC,EAAE,uBAAuB,CAAA;CAAE,CAsCnG"}