@things-factory/figure-ui 10.1.74 → 10.1.76
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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} +137 -126
- 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-refusals.ts → refusals.ts} +62 -13
- 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/store.js +39 -0
- package/dist-client/graphql/store.js.map +1 -0
- package/dist-client/modeller/ai-proposal.d.ts +51 -0
- package/dist-client/modeller/ai-proposal.js +64 -0
- package/dist-client/modeller/ai-proposal.js.map +1 -0
- package/dist-client/modeller/align.d.ts +30 -0
- package/dist-client/modeller/align.js +75 -0
- package/dist-client/modeller/align.js.map +1 -0
- package/dist-client/modeller/canvas.d.ts +72 -0
- package/dist-client/modeller/canvas.js +379 -0
- package/dist-client/modeller/canvas.js.map +1 -0
- package/dist-client/modeller/clips.d.ts +39 -0
- package/dist-client/modeller/clips.js +58 -0
- package/dist-client/modeller/clips.js.map +1 -0
- package/dist-client/modeller/controls.d.ts +28 -0
- package/dist-client/modeller/controls.js +28 -0
- package/dist-client/modeller/controls.js.map +1 -0
- package/dist-client/modeller/editor.d.ts +203 -0
- package/dist-client/modeller/editor.js +1526 -0
- package/dist-client/modeller/editor.js.map +1 -0
- package/dist-client/modeller/fields.d.ts +45 -0
- package/dist-client/modeller/fields.js +83 -0
- package/dist-client/modeller/fields.js.map +1 -0
- package/dist-client/modeller/figure-capability-panel.d.ts +22 -0
- package/dist-client/modeller/figure-capability-panel.js +141 -0
- package/dist-client/modeller/figure-capability-panel.js.map +1 -0
- package/dist-client/modeller/figure-clips.d.ts +31 -0
- package/dist-client/modeller/figure-clips.js +268 -0
- package/dist-client/modeller/figure-clips.js.map +1 -0
- package/dist-client/modeller/figure-controls.d.ts +36 -0
- package/dist-client/modeller/figure-controls.js +226 -0
- package/dist-client/modeller/figure-controls.js.map +1 -0
- package/dist-client/modeller/figure-facts.d.ts +35 -0
- package/dist-client/modeller/figure-facts.js +55 -0
- package/dist-client/modeller/figure-facts.js.map +1 -0
- package/dist-client/modeller/figure-first-save.d.ts +20 -0
- package/dist-client/modeller/figure-first-save.js +118 -0
- 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-links.d.ts +77 -0
- package/dist-client/modeller/figure-links.js +649 -0
- package/dist-client/modeller/figure-links.js.map +1 -0
- package/dist-client/modeller/figure-material-panel.d.ts +39 -0
- package/dist-client/modeller/figure-material-panel.js +323 -0
- package/dist-client/modeller/figure-material-panel.js.map +1 -0
- package/dist-client/modeller/figure-parts.d.ts +69 -0
- package/dist-client/modeller/figure-parts.js +559 -0
- package/dist-client/modeller/figure-parts.js.map +1 -0
- package/dist-client/modeller/figure-preview.d.ts +34 -0
- package/dist-client/modeller/figure-preview.js +346 -0
- package/dist-client/modeller/figure-preview.js.map +1 -0
- package/dist-client/modeller/figure-properties.d.ts +45 -0
- package/dist-client/modeller/figure-properties.js +239 -0
- package/dist-client/modeller/figure-properties.js.map +1 -0
- package/dist-client/modeller/figure-recipe-catalog.d.ts +38 -0
- package/dist-client/modeller/figure-recipe-catalog.js +399 -0
- package/dist-client/modeller/figure-recipe-catalog.js.map +1 -0
- package/dist-client/modeller/figure-verdict.d.ts +64 -0
- package/dist-client/modeller/figure-verdict.js +787 -0
- package/dist-client/modeller/figure-verdict.js.map +1 -0
- package/dist-client/modeller/first-save.d.ts +17 -0
- package/dist-client/modeller/first-save.js +26 -0
- 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/gizmo.d.ts +72 -0
- package/dist-client/modeller/gizmo.js +111 -0
- package/dist-client/modeller/gizmo.js.map +1 -0
- package/dist-client/modeller/help.d.ts +18 -0
- package/dist-client/modeller/help.js +37 -0
- package/dist-client/modeller/help.js.map +1 -0
- package/dist-client/modeller/joint-drag.d.ts +19 -0
- package/dist-client/modeller/joint-drag.js +97 -0
- package/dist-client/modeller/joint-drag.js.map +1 -0
- package/dist-client/modeller/joint-fan.d.ts +9 -0
- package/dist-client/modeller/joint-fan.js +276 -0
- package/dist-client/modeller/joint-fan.js.map +1 -0
- package/dist-client/modeller/keys.d.ts +22 -0
- package/dist-client/modeller/keys.js +26 -0
- package/dist-client/modeller/keys.js.map +1 -0
- package/dist-client/modeller/links.d.ts +267 -0
- package/dist-client/modeller/links.js +480 -0
- package/dist-client/modeller/links.js.map +1 -0
- package/dist-client/modeller/live.d.ts +37 -0
- package/dist-client/modeller/live.js +68 -0
- package/dist-client/modeller/live.js.map +1 -0
- package/dist-client/modeller/maturity.d.ts +120 -0
- package/dist-client/modeller/maturity.js +313 -0
- 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/occupancy.d.ts +18 -0
- package/dist-client/modeller/occupancy.js +24 -0
- package/dist-client/modeller/occupancy.js.map +1 -0
- package/dist-client/modeller/palette.d.ts +7 -0
- package/dist-client/modeller/palette.js +46 -0
- package/dist-client/modeller/palette.js.map +1 -0
- package/dist-client/modeller/preview-model.d.ts +47 -0
- package/dist-client/modeller/preview-model.js +68 -0
- package/dist-client/modeller/preview-model.js.map +1 -0
- package/dist-client/modeller/product-session.d.ts +510 -0
- package/dist-client/modeller/product-session.js +157 -0
- package/dist-client/modeller/product-session.js.map +1 -0
- package/dist-client/modeller/recipe-source.d.ts +8 -0
- package/dist-client/modeller/recipe-source.js +14 -0
- package/dist-client/modeller/recipe-source.js.map +1 -0
- package/dist-client/modeller/recipes.d.ts +37 -0
- package/dist-client/modeller/recipes.js +103 -0
- package/dist-client/modeller/recipes.js.map +1 -0
- package/dist-client/modeller/refusals.d.ts +68 -0
- package/dist-client/modeller/refusals.js +142 -0
- package/dist-client/modeller/refusals.js.map +1 -0
- package/dist-client/modeller/renderer.d.ts +40 -0
- package/dist-client/modeller/renderer.js +73 -0
- package/dist-client/modeller/renderer.js.map +1 -0
- package/dist-client/modeller/stage-model.d.ts +39 -0
- package/dist-client/modeller/stage-model.js +147 -0
- package/dist-client/modeller/stage-model.js.map +1 -0
- package/dist-client/modeller/thumbnail.d.ts +3 -0
- package/dist-client/modeller/thumbnail.js +75 -0
- package/dist-client/modeller/thumbnail.js.map +1 -0
- package/dist-client/modeller/v3-clips.d.ts +1 -1
- package/dist-client/modeller/v3-editor.d.ts +5 -0
- package/dist-client/modeller/v3-editor.js +21 -10
- package/dist-client/modeller/v3-editor.js.map +1 -1
- package/dist-client/modeller/v3-product-session.d.ts +31 -0
- package/dist-client/modeller/v3-refusals.d.ts +37 -5
- package/dist-client/modeller/v3-refusals.js +59 -16
- package/dist-client/modeller/v3-refusals.js.map +1 -1
- 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-modeller-page.d.ts +102 -0
- package/dist-client/pages/figure-modeller-page.js +548 -0
- 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 +17 -16
- 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} +11 -7
- 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} +10 -10
- package/test/refusals.test.ts +166 -0
- 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 +15 -7
- package/translations/ja.json +15 -7
- package/translations/ko.json +15 -7
- package/translations/ms.json +15 -7
- package/translations/zh.json +15 -7
- package/docs/v3-product-cutover.md +0 -25
- package/test/v3-refusals.test.ts +0 -136
- 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/test/v3-refusals.test.ts
DELETED
|
@@ -1,136 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* 크기 범위 거절을 사람의 말로 (사용자 2026-09-24: 「what is this warning message means?」 — 커널의 영어 원문이 떴다).
|
|
3
|
-
*/
|
|
4
|
-
import { test } from 'node:test'
|
|
5
|
-
import assert from 'node:assert/strict'
|
|
6
|
-
import { readFileSync } from 'node:fs'
|
|
7
|
-
import { fileURLToPath } from 'node:url'
|
|
8
|
-
|
|
9
|
-
import { sizeRangeRefusalOf } from '../client/modeller/v3-refusals.ts'
|
|
10
|
-
|
|
11
|
-
const ko = JSON.parse(readFileSync(fileURLToPath(new URL('../translations/ko.json', import.meta.url)), 'utf8'))
|
|
12
|
-
const say = (key: string, params: Record<string, string>) => ko[key].replace(/\{(\w+)\}/g, (_: string, k: string) => params[k] ?? '')
|
|
13
|
-
const refusal = (message: string) => Object.assign(new Error(message), { code: 'INSTANCE_SIZE_RANGE' })
|
|
14
|
-
|
|
15
|
-
test('화성 트레이의 거절 — 축 · 숫자 · 부품 · 고치는 곳', () => {
|
|
16
|
-
const said = sizeRangeRefusalOf(refusal('INSTANCE_SIZE_RANGE: size.x: below 8.82353 mm a length goes to zero (cell); declare the smallest size at 8.82353 mm or more'), say)!
|
|
17
|
-
assert.ok(said.includes('X 축을') && said.includes('8.8 mm') && said.includes('cell 부품') && said.includes('다시 재기'), said)
|
|
18
|
-
assert.ok(!/declare|below/.test(said))
|
|
19
|
-
})
|
|
20
|
-
|
|
21
|
-
test('위쪽 끝도, 부품 이름이 없어도', () => {
|
|
22
|
-
const said = sizeRangeRefusalOf(refusal('INSTANCE_SIZE_RANGE: size.y: above 15000 mm the figure cannot be drawn; declare the largest size at 15000 mm or less'), say)!
|
|
23
|
-
assert.ok(said.includes('Y 축을') && said.includes('15,000 mm'), said)
|
|
24
|
-
})
|
|
25
|
-
|
|
26
|
-
test('다른 거절은 건드리지 않는다', () => {
|
|
27
|
-
assert.equal(sizeRangeRefusalOf(Object.assign(new Error('x'), { code: 'EDIT_TARGET' }), say), null)
|
|
28
|
-
})
|
|
29
|
-
|
|
30
|
-
test('범위가 받을 수 없는 연결은 같은 연결을 범위를 좁혀 다시 권한다 — 다시 재기로는 풀리지 않는다 (사이징, 2026-09-25)', async () => {
|
|
31
|
-
const { narrowingRetryOf } = await import('../client/modeller/v3-refusals.ts')
|
|
32
|
-
const { addV3Box, applyV3Authoring, createV3Asset } = await import('@hatiolab/figure-model')
|
|
33
|
-
let asset = addV3Box(createV3Asset('Panel'), { id: 'panel', size: { x: 400, y: 400, z: 400 }, position: { x: 0, y: 0, z: 0 } })
|
|
34
|
-
asset = applyV3Authoring(asset, { kind: 'declare-instance-size', range: { x: { min: 1, max: 4000 }, y: { min: 1, max: 4000 }, z: { min: 1, max: 4000 } }, at: { x: 400, y: 400, z: 400 } })
|
|
35
|
-
const link = { kind: 'link-dimension' as const, part: 'panel', axis: 'x' as const, source: { of: 'instance' as const, axis: 'x' as const }, plus: -50 }
|
|
36
|
-
let error: unknown
|
|
37
|
-
try {
|
|
38
|
-
applyV3Authoring(asset, link)
|
|
39
|
-
} catch (e) {
|
|
40
|
-
error = e
|
|
41
|
-
}
|
|
42
|
-
const say = (key: string, p: Record<string, string>) => `${key} ${JSON.stringify(p)}`
|
|
43
|
-
const offer = narrowingRetryOf(link, error, say)!
|
|
44
|
-
assert.ok(offer, '권한다')
|
|
45
|
-
assert.match(offer.label, /figure.button.narrow-range-from .*"axis":"X"/)
|
|
46
|
-
assert.deepEqual(offer.retry, { ...link, narrowRange: true })
|
|
47
|
-
assert.doesNotThrow(() => applyV3Authoring(asset, offer.retry as never), '권한 것은 받아들여진다')
|
|
48
|
-
assert.equal(narrowingRetryOf({ kind: 'attach' }, error, say), null, '연결이 아닌 명령에는 권하지 않는다')
|
|
49
|
-
})
|
|
50
|
-
|
|
51
|
-
test('부품을 못 지우는 까닭을 넷으로 가려 말한다 — 매단 것 · 공간 선언 · 크기를 따르는 것 · 따라 움직이는 것 (2026-09-25)', async () => {
|
|
52
|
-
const { partRefusalOf } = await import('../client/modeller/v3-refusals.ts')
|
|
53
|
-
const fm = await import('@hatiolab/figure-model')
|
|
54
|
-
const say = (key: string, p: Record<string, string>) => `${key} ${JSON.stringify(p)}`
|
|
55
|
-
let a = fm.createV3Asset('Bench')
|
|
56
|
-
a = fm.addV3Box(a, { id: 'leg', size: { x: 60, y: 700, z: 60 }, position: { x: 0, y: 0, z: 0 } })
|
|
57
|
-
a = fm.addV3Box(a, { id: 'top', size: { x: 1200, y: 40, z: 600 }, position: { x: 0, y: 0, z: 0 } })
|
|
58
|
-
a = fm.addV3Box(a, { id: 'lamp', size: { x: 80, y: 80, z: 80 }, position: { x: 0, y: 0, z: 0 } })
|
|
59
|
-
a = fm.addV3Box(a, { id: 'shade', size: { x: 40, y: 40, z: 40 }, position: { x: 0, y: 0, z: 0 } })
|
|
60
|
-
a = fm.applyV3Authoring(a, { kind: 'attach', part: 'leg', face: 'bottom', to: { plane: 'mounting-plane' } })
|
|
61
|
-
a = fm.applyV3Authoring(a, { kind: 'attach', part: 'top', face: 'bottom', to: { part: 'leg', face: 'top' } })
|
|
62
|
-
a = fm.applyV3Authoring(a, { kind: 'attach', part: 'lamp', face: 'bottom', to: { part: 'top', face: 'top' }, align: { x: { mm: -300 } } })
|
|
63
|
-
a = fm.applyV3Authoring(a, { kind: 'attach', part: 'shade', face: 'bottom', to: { part: 'top', face: 'top' }, align: { x: { mm: 300 } } })
|
|
64
|
-
const turn = (asset: typeof a, part: string, extra: object) => fm.applyV3Authoring(asset, { kind: 'set-joint', joint: { ...asset.joints!.find(j => j.body1.part === part)!, type: 'revolute', axis: 'Y', ...extra } as never })
|
|
65
|
-
a = turn(a, 'lamp', { state: { id: 'lamp-turn' } })
|
|
66
|
-
a = turn(a, 'shade', { mimic: { joint: 'lamp', multiplier: 1 } })
|
|
67
|
-
const why = (asset: typeof a, part: string) => {
|
|
68
|
-
try {
|
|
69
|
-
fm.editV3Part(asset, { kind: 'remove-part', target: part })
|
|
70
|
-
return 'removed'
|
|
71
|
-
} catch (e) {
|
|
72
|
-
return partRefusalOf(e, part, say)
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
assert.match(why(a, 'top')!, /part-holds-others .*"others":"lamp, shade"/)
|
|
76
|
-
assert.match(why(a, 'lamp')!, /part-is-led .*"others":"shade"/)
|
|
77
|
-
const declared = fm.applyV3Authoring(a, { kind: 'declare-occupancy', proposal: fm.proposeV3Occupancy(a), placement: 'floor' })
|
|
78
|
-
assert.match(why(declared, 'shade')!, /part-in-declared-space .*"part":"shade"/, '잎인데 공간 선언에 들어 있다')
|
|
79
|
-
})
|
|
80
|
-
|
|
81
|
-
test('공간 선언에 든 부품 — 지우고 공간을 남은 부품에 맞추는 길을 한 번에 권한다(차단기의 떠도는 상자, 09-25)', async () => {
|
|
82
|
-
const { inDeclaredRoom } = await import('../client/modeller/v3-refusals.ts')
|
|
83
|
-
const fm = await import('@hatiolab/figure-model')
|
|
84
|
-
let a = fm.addV3Box(fm.createV3Asset('Gate'), { id: 'housing', size: { x: 300, y: 1000, z: 300 }, position: { x: 0, y: 0, z: 0 } })
|
|
85
|
-
a = fm.addV3Box(a, { id: 'stray', size: { x: 100, y: 100, z: 100 }, position: { x: 0, y: 50, z: 0 } })
|
|
86
|
-
a = fm.applyV3Authoring(a, { kind: 'attach', part: 'housing', face: 'bottom', to: { plane: 'mounting-plane' } })
|
|
87
|
-
a = fm.applyV3Authoring(a, { kind: 'attach', part: 'stray', face: 'bottom', to: { plane: 'mounting-plane' } })
|
|
88
|
-
a = fm.applyV3Authoring(a, { kind: 'declare-occupancy', proposal: fm.proposeV3Occupancy(a), placement: 'floor' })
|
|
89
|
-
let refused: unknown
|
|
90
|
-
try {
|
|
91
|
-
fm.editV3Part(a, { kind: 'remove-part', target: 'stray' })
|
|
92
|
-
} catch (e) {
|
|
93
|
-
refused = e
|
|
94
|
-
}
|
|
95
|
-
assert.equal(inDeclaredRoom(refused), true)
|
|
96
|
-
assert.equal(inDeclaredRoom(Object.assign(new Error('PART_REFERENCED: top: top holds leg; take it off first'), { code: 'PART_REFERENCED' })), false, '매단 것은 이 길이 아니다')
|
|
97
|
-
const after = fm.editV3Part(a, { kind: 'remove-part', target: 'stray', refitRoom: true })
|
|
98
|
-
assert.equal(after.document.model.nodes.some(n => n.id === 'stray'), false)
|
|
99
|
-
assert.ok(after.occupancy?.bounds, '공간은 남은 부품으로 다시 선언된다')
|
|
100
|
-
const editor = readFileSync(fileURLToPath(new URL('../client/modeller/v3-editor.ts', import.meta.url)), 'utf8')
|
|
101
|
-
assert.ok(editor.includes("if (!refitRoom && inDeclaredRoom(error)) this.retry = { label: i18next.t('figure.button.remove-and-refit-room', { part: id }), run: () => this.removePart(id, true) }"))
|
|
102
|
-
assert.ok(ko['figure.button.remove-and-refit-room'].includes('{part}'))
|
|
103
|
-
})
|
|
104
|
-
|
|
105
|
-
test('배치를 바꿀 수 없는 까닭 — 평면에 붙은 부품과 새 평면이 받는 면을 말한다(벽 배치, 09-25)', async () => {
|
|
106
|
-
const { placementRefusalOf } = await import('../client/modeller/v3-refusals.ts')
|
|
107
|
-
const fm = await import('@hatiolab/figure-model')
|
|
108
|
-
let a = fm.addV3Box(fm.createV3Asset('Post'), { id: 'post', size: { x: 100, y: 1000, z: 100 }, position: { x: 0, y: 0, z: 0 } })
|
|
109
|
-
a = fm.applyV3Authoring(a, { kind: 'attach', part: 'post', face: 'bottom', to: { plane: 'mounting-plane' } })
|
|
110
|
-
let refused: unknown
|
|
111
|
-
try {
|
|
112
|
-
fm.applyV3Authoring(a, { kind: 'declare-occupancy', proposal: fm.proposeV3Occupancy(a), placement: 'wall' as never })
|
|
113
|
-
} catch (e) {
|
|
114
|
-
refused = e
|
|
115
|
-
}
|
|
116
|
-
const said = placementRefusalOf(refused, say)!
|
|
117
|
-
assert.ok(said.includes('post (bottom)') && said.includes('벽 기반') && said.includes('back'), said)
|
|
118
|
-
assert.equal(placementRefusalOf(new Error('x'), say), null)
|
|
119
|
-
/* The placement list sends its command through the page, not the editor: the page says it in words too, and the list goes back. */
|
|
120
|
-
const page = readFileSync(fileURLToPath(new URL('../client/pages/figure-v3-modeller-page.ts', import.meta.url)), 'utf8')
|
|
121
|
-
assert.ok(page.includes('placementRefusalOf(error, (key, params) => i18next.t(key, params))'), '페이지 경로도 사람의 말로')
|
|
122
|
-
const props = readFileSync(fileURLToPath(new URL('../client/modeller/figure-v3-properties.ts', import.meta.url)), 'utf8')
|
|
123
|
-
assert.ok(props.includes('select.value = current'), '거절되면 목록이 원래 배치로 돌아온다')
|
|
124
|
-
})
|
|
125
|
-
|
|
126
|
-
test('범위 밖 값은 받을 수 있는 범위를 숫자로 말한다 — 커널의 영어가 아니다 (Figure 레인 :3300, 2026-09-26)', async () => {
|
|
127
|
-
const { inputRangeRefusalOf } = await import('../client/modeller/v3-refusals.ts')
|
|
128
|
-
const range = (message: string) => Object.assign(new Error(message), { code: 'INPUT_RANGE' })
|
|
129
|
-
const size = inputRangeRefusalOf(range('INPUT_RANGE: size.x: 6021100 outside [300,1200]'), say)!
|
|
130
|
-
assert.ok(size.includes('X') && size.includes('300') && size.includes('1,200') && size.includes('6,021,100'), size)
|
|
131
|
-
assert.ok(!/outside|INPUT_RANGE/.test(size))
|
|
132
|
-
const other = inputRangeRefusalOf(range('INPUT_RANGE: lift.stroke: -5 outside [0,1]'), say)!
|
|
133
|
-
assert.ok(other.includes('0') && other.includes('1') && other.includes('-5'), other)
|
|
134
|
-
assert.equal(inputRangeRefusalOf(range('INPUT_RANGE: steps: at the length it is authored (100 mm) a pitch under 1 mm makes more than 50 copies'), say), null)
|
|
135
|
-
assert.equal(inputRangeRefusalOf(Object.assign(new Error('x'), { code: 'EDIT_TARGET' }), say), null)
|
|
136
|
-
})
|
package/test/v3-renderer.test.ts
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import {test} from 'node:test'
|
|
2
|
-
import assert from 'node:assert/strict'
|
|
3
|
-
import * as THREE from 'three'
|
|
4
|
-
import {replaceV3Meshes} from '../client/modeller/v3-renderer.ts'
|
|
5
|
-
import type {V3RenderPart} from '../client/modeller/v3-renderer.ts'
|
|
6
|
-
const box=(id:string):V3RenderPart=>({id,shape:{provider:'box',dimensions:{width:100,height:200,depth:300}},pose:{r:[[1,0,0],[0,1,0],[0,0,1]],t:[0,100,0]},material:{token:'primary'}})
|
|
7
|
-
test('V3 renderer replaces rather than accumulates; empty scene disposes old resources',()=>{
|
|
8
|
-
const group=new THREE.Group();replaceV3Meshes(group,[box('a'),box('b')],{primary:'#123456'})
|
|
9
|
-
assert.equal(group.children.length,2);let disposed=0
|
|
10
|
-
const first=group.children[0] as THREE.Mesh;first.geometry.addEventListener('dispose',()=>disposed++)
|
|
11
|
-
replaceV3Meshes(group,[box('c')],{primary:'#123456'});assert.equal(group.children.length,1);assert.equal(group.children[0].name,'c');assert.equal(disposed,1)
|
|
12
|
-
replaceV3Meshes(group,[],{});assert.equal(group.children.length,0)
|
|
13
|
-
})
|
|
14
|
-
test('V3 renderer preserves scene on unsupported geometry and resolves pose/material',()=>{
|
|
15
|
-
const group=new THREE.Group();replaceV3Meshes(group,[box('a')],{primary:'#123456'})
|
|
16
|
-
const old=group.children[0],bounds=new THREE.Box3().setFromObject(group)
|
|
17
|
-
assert.equal(bounds.min.y,0);assert.equal(bounds.max.y,200)
|
|
18
|
-
assert.throws(()=>replaceV3Meshes(group,[box('b'),{...box('c'),shape:{provider:'unknown',dimensions:{}}}],{primary:'#123456'}),/Unsupported/)
|
|
19
|
-
assert.equal(group.children[0],old)
|
|
20
|
-
const p=box('glow');p.material={token:'primary',preset:'metal',transparent:true,emissive:{token:'primary',intensity:2,on:true}}
|
|
21
|
-
replaceV3Meshes(group,[p],{primary:'#123456'})
|
|
22
|
-
const material=(group.children[0] as THREE.Mesh).material as THREE.MeshStandardMaterial
|
|
23
|
-
assert.equal(material.metalness,0.8);assert.equal(material.transparent,true);assert.equal(material.emissiveIntensity,2)
|
|
24
|
-
})
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|