@operato/scene-storage 10.0.0-beta.43 → 10.0.0-beta.46

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 (50) hide show
  1. package/CHANGELOG.md +37 -0
  2. package/dist/box-3d.d.ts +2 -0
  3. package/dist/box-3d.js +103 -64
  4. package/dist/box-3d.js.map +1 -1
  5. package/dist/crane-3d.d.ts +10 -0
  6. package/dist/crane-3d.js +34 -5
  7. package/dist/crane-3d.js.map +1 -1
  8. package/dist/crane.d.ts +136 -6
  9. package/dist/crane.js +567 -46
  10. package/dist/crane.js.map +1 -1
  11. package/dist/pallet-3d.d.ts +2 -0
  12. package/dist/pallet-3d.js +103 -53
  13. package/dist/pallet-3d.js.map +1 -1
  14. package/dist/parcel-3d.d.ts +1 -0
  15. package/dist/parcel-3d.js +18 -1
  16. package/dist/parcel-3d.js.map +1 -1
  17. package/dist/rack-grid-3d.js +26 -8
  18. package/dist/rack-grid-3d.js.map +1 -1
  19. package/dist/rack-grid.d.ts +94 -10
  20. package/dist/rack-grid.js +468 -86
  21. package/dist/rack-grid.js.map +1 -1
  22. package/dist/storage-rack-3d.js +1 -1
  23. package/dist/storage-rack-3d.js.map +1 -1
  24. package/dist/storage-rack.d.ts +31 -6
  25. package/dist/storage-rack.js +96 -14
  26. package/dist/storage-rack.js.map +1 -1
  27. package/package.json +3 -3
  28. package/src/box-3d.ts +121 -68
  29. package/src/crane-3d.ts +34 -4
  30. package/src/crane.ts +615 -55
  31. package/src/pallet-3d.ts +122 -55
  32. package/src/parcel-3d.ts +19 -1
  33. package/src/rack-grid-3d.ts +31 -8
  34. package/src/rack-grid.ts +488 -82
  35. package/src/storage-rack-3d.ts +1 -1
  36. package/src/storage-rack.ts +96 -14
  37. package/test/test-coord-alignment.ts +2 -2
  38. package/test/test-crane-bay-match.ts +130 -0
  39. package/test/test-crane-binding-resolve.ts +168 -0
  40. package/test/test-crane-duration.ts +90 -0
  41. package/test/test-crane-rotation-reach.ts +218 -0
  42. package/test/test-rack-grid-3d-alignment.ts +235 -0
  43. package/test/test-rack-grid-3d-attach-real.ts +375 -0
  44. package/test/test-rack-grid-cell.ts +2 -2
  45. package/test/test-rack-grid-location.ts +2 -2
  46. package/test/test-rack-grid-occupied-slots.ts +165 -0
  47. package/test/test-rack-grid-picking-position.ts +154 -0
  48. package/test/test-rack-grid-slot-api.ts +483 -0
  49. package/test/test-slot-ids-enumeration.ts +137 -0
  50. package/tsconfig.tsbuildinfo +1 -1
package/dist/crane.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"crane.js","sourceRoot":"","sources":["../src/crane.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * Copyright © HatioLab Inc. All rights reserved.\n */\nimport { Component, ComponentNature, ContainerAbstract, ContainerCapacity, RealObject, Transfer, getWorldPose, sceneComponent } from '@hatiolab/things-scene'\nimport type { SlotDef, State, Material3D, Transferable } from '@hatiolab/things-scene'\nimport {\n CarrierHolder,\n Legendable,\n Mover,\n Placeable,\n type AttachFrame,\n type Alignment,\n type Heights,\n type LegendBinding,\n type MoveOptions,\n type PlacementArchetype\n} from '@operato/scene-base'\n\nimport { Crane3D } from './crane-3d.js'\n\n/**\n * Crane status — the operating state of a stacker crane.\n *\n * - `idle` — parked at home position\n * - `moving` — translating (horizontal) or along the mast (vertical);\n * typically combined\n * - `loading` — extracting a carrier from a rack cell\n * - `unloading` — placing a carrier into a rack cell\n * - `error` — fault / e-stop / collision warning\n */\nexport type CraneStatus = 'idle' | 'moving' | 'loading' | 'unloading' | 'error'\n\n/** Crane 컴포넌트 state */\nexport interface CraneState extends State {\n // ── 운영 상태 ──\n status?: CraneStatus\n\n // ── 액추에이터 ──\n /** 마스트 따라 carriage 의 수직 위치 (mm). */\n carriageHeight?: number\n /**\n * Fork prong 의 최대 신축 가능 길이 (mm). cell 깊이 + 여유.\n * 일반적으로 pallet 깊이 (1200mm) + 여유 ≈ 1300mm 또는 그 이하 (default 600).\n */\n forkLength?: number\n /**\n * Fork 의 *현재 신축 거리* (mm). 0 = collapsed (shuttle 안 들어가있음),\n * forkLength = fully extended (cell 안 carrier 의 fork pocket 도달).\n *\n * 시뮬레이션 흐름:\n * idle: 0\n * approach → 0\n * pick / place: 0 → forkLength (extending) → 0 (retracting with carrier)\n */\n forkExtension?: number\n /**\n * Fork 가 carrier 를 *cell shelf 에서 분리하기 위해 들어올리는 높이* (mm).\n * 사용자가 board 에서 설정하는 *configured 진폭*. engage 의 lift 단계 target.\n * 미명시 시 default 30mm.\n *\n * Note: 시뮬 *진행 중 current 들림 값* 은 별도 internal transient — `forkLiftRT`\n * state. 3D / 2D render 가 carriage Y 결정 시 그 값을 사용.\n */\n forkLift?: number\n\n /**\n * Fork lift *runtime current value* (mm). engage 가 시뮬 진행 중 매 frame\n * setState 로 lerp. *사용자가 설정하는 값 아님* — internal transient.\n */\n forkLiftRT?: number\n\n /**\n * 자동 random simulate (visual smoke test) 시작 여부.\n * - `undefined` 또는 `false` (default): 자동 시작 안 함. application 이 crane.\n * pickAndPlace 등 직접 제어 시 사용.\n * - `true`: added() 시 자동 시작.\n */\n simulate?: boolean\n\n /**\n * Carriage 의 rail-local X 위치 (0 ~ crane.width). Crane.moveTo / simulate 가\n * lerp. crane 본체 (rail) 는 안 움직임 — carriage assembly (masts + carriage +\n * forks) 만 rail 안 X 만 슬라이드.\n */\n carriagePosition?: number\n\n /**\n * Carriage 의 폭 (rail-local X 방향). 미명시 시 rail (crane.width) 의 ~10%.\n * Target rack 의 cell 폭과 매칭 권유.\n */\n carriageWidth?: number\n\n // ── 3D 재질 ──\n material3d?: Material3D\n}\n\nconst BODY_LEGEND = {\n idle: '#888',\n moving: '#aabbcc',\n loading: '#ffaa00',\n unloading: '#ffaa00',\n error: '#c66',\n default: '#888'\n}\n\nconst LAMP_EMISSIVE_LEGEND = {\n idle: '#222222',\n moving: '#44ff44',\n loading: '#ffaa00',\n unloading: '#ffaa00',\n error: '#ff3333',\n default: '#222222'\n}\n\nconst NATURE: ComponentNature = {\n mutable: false,\n resizable: true,\n rotatable: true,\n properties: [\n {\n type: 'select',\n label: 'status',\n name: 'status',\n property: {\n options: [\n { display: 'Idle', value: 'idle' },\n { display: 'Moving', value: 'moving' },\n { display: 'Loading', value: 'loading' },\n { display: 'Unloading', value: 'unloading' },\n { display: 'Error', value: 'error' }\n ]\n }\n },\n {\n type: 'checkbox',\n label: 'simulate',\n name: 'simulate'\n },\n {\n type: 'number',\n label: 'carriage-position',\n name: 'carriagePosition',\n placeholder: 'rail-local X (0 ~ rail width). Crane.moveTo 가 lerp.'\n },\n {\n type: 'number',\n label: 'carriage-width',\n name: 'carriageWidth',\n placeholder: 'rail-local 폭 (mm). 미명시 rail width × 10%.'\n },\n {\n type: 'number',\n label: 'carriage-height',\n name: 'carriageHeight',\n placeholder: 'mm — height of carriage on mast'\n },\n {\n type: 'number',\n label: 'fork-length',\n name: 'forkLength',\n placeholder: 'mm — fork prong 최대 신축 길이 (default 600)'\n },\n {\n type: 'number',\n label: 'fork-extension',\n name: 'forkExtension',\n placeholder: 'mm — 현재 신축 거리 (0 = collapsed)'\n },\n {\n type: 'number',\n label: 'fork-lift',\n name: 'forkLift',\n placeholder: 'mm — carrier 들어올림 높이 (+ 위로)'\n }\n ],\n help: 'scene/component/crane'\n}\n\n// Mixin chain: Mover → CarrierHolder → ContainerCapacity → Legendable → Placeable → ContainerAbstract\n//\n// Mover: pick / place / pickAndPlace / moveTo / engage primitives\n// CarrierHolder: attachPointFor() — where the carrier sits on the crane (carriage fork)\n// ContainerCapacity: receive() / dispatch() / canReceive() / slots — slot tracking +\n// TRANSFER_SLOT_KEY bookkeeping during transit\n// Legendable: status → bodyColor / lampEmissive colour mapping\n// Placeable: floor-archetype 3D positioning\n// ContainerAbstract: child management — carrier becomes a child while in transit\n//\n// Note: ContainerAbstract replaces Shape. The 2D outline is drawn manually in\n// render() below (a simple top-down rectangle), matching the old Shape output\n// without the Shape base-class overhead.\n/**\n * Crane — a stacker / retrieval picker. Picker contract instance.\n *\n * Moves carriers between rack cells (or any Placeable target). The crane\n * is *picker-side* of the Phase G/H Pickable contract — it knows how to\n * `pick(carrier)` / `place(carrier, target)` and `engage(target, kind)`\n * to align its actuators. It is *storage-agnostic* — any Rack / Cell /\n * Spot / Conveyor that implements the receive/dispatch protocol is a\n * valid target.\n *\n * Structure: a tall vertical mast that translates horizontally on a rail\n * or free floor path, with a carriage that slides up/down the mast carrying\n * a shuttle / forks.\n *\n * **Monitoring mode**: crane status is driven by external data binding\n * (`state.status`, `state.carriageHeight`). The carrier is referenced\n * via data binding — it is NOT a child of the crane in monitoring mode.\n *\n * **Simulation mode**: call `crane.pick(carrier)` / `crane.place(carrier, target)`\n * (or `crane.pickAndPlace(carrier, target)`). Mover handles navigation +\n * engage + reparent. During transit the carrier IS a child of the crane.\n */\n@sceneComponent('crane')\nexport default class Crane extends Mover(CarrierHolder(ContainerCapacity(Legendable(Placeable(ContainerAbstract))))) {\n declare state: CraneState\n declare _realObject?: Crane3D\n\n static legends: Record<string, LegendBinding> = {\n bodyColor: { from: 'status', legend: BODY_LEGEND },\n lampEmissive: { from: 'status', legend: LAMP_EMISSIVE_LEGEND }\n }\n\n static placement: PlacementArchetype = 'floor'\n static align: Alignment = 'bottom'\n static defaultDepth = (h: Heights) => h.ceiling - h.floor\n\n /** Yaw offset: crane model is drawn with the rail axis along X (right = forward). */\n static yawOffset = 0\n\n /**\n * Phase H — the crane uses telescoping forks to pick up a carrier in a rack\n * cell. Same mechanism as a forklift fork — engages the pallet's fork pocket.\n * (Mover mixin chain is `: any` so override keyword is not usable, only the\n * getter is defined.)\n */\n get toolType(): string {\n return 'forklift-fork'\n }\n\n get nature() {\n return NATURE\n }\n\n get anchors() {\n return []\n }\n\n // ── ContainerCapacity ─────────────────────────────────────────────────────\n\n /**\n * Stacker crane carries at most one load at a time on its forks.\n *\n * localPosition.z = 0 명시 — ContainerCapacity.receive 의 atomic setState 가\n * `carrier.state.zPos = slot.localPosition.z + parentGeoOffset = 0` 강제.\n * 미명시 시 zPos update skip → carrier 의 *이전 holder 또는 board model 의\n * 임의 zPos (음수 가능)* 그대로 → _realObject 미빌드 시점 (transient placement\n * 미설정 = state-driven) 에 carrier 가 *지하* 로 가는 결함.\n */\n get slots(): SlotDef[] {\n return [{ id: 'forks', maxCount: 1, localPosition: { x: 0, y: 0, z: 0 } }]\n }\n\n /**\n * Acceptance rotation — carrier 가 crane.fork 에 attach 시 *crane 의 local\n * axis (전방)* 으로 정렬. identity quaternion 반환 → atomic setState 가\n * carrier.state.rotation/X/Y = 0 강제. _realObject 미빌드 시점 (transient\n * placement 미설정 = state-driven) fallback 에서도 자세 정렬.\n *\n * follow-holder carryPolicy 와 짝 — 두 path 모두 동일 결과 (local identity).\n */\n acceptanceRotation(_carrier: Component, _slot?: SlotDef): { x: number; y: number; z: number; w: number } {\n return { x: 0, y: 0, z: 0, w: 1 }\n }\n\n /**\n * Arrangement — carrier.state.left/top 의 *기준* 이 *crane 전체 footprint* 가\n * 아닌 *carriage X (carriagePosition) + fork Z (bladeMidZ)*. carriage / fork\n * 의 위치가 carrier 의 위치.\n *\n * left = carriagePosition − carrier.w/2 (carriage X 중심)\n * top = crane.h/2 + bladeMidZ − carrier.h/2 (fork Z 중심)\n */\n get arrangementStrategy() {\n const crane = this as any\n return {\n positionAt(_idx: number, _slot: any, _occ: number, component?: any) {\n const cw = numOr(crane.state?.width, 100)\n const ch = numOr(crane.state?.height, 100)\n const carrierW = numOr(component?.state?.width, 0)\n const carrierH = numOr(component?.state?.height, 0)\n const carriagePos = numOr(crane.state?.carriagePosition, cw / 2)\n const bladeMidZ = numOr(crane._realObject?.bladeMidZ, 0)\n return {\n x: carriagePos - carrierW / 2,\n y: ch / 2 + bladeMidZ - carrierH / 2,\n z: 0\n }\n },\n capacity(slot: any) {\n return slot.maxCount ?? Infinity\n }\n }\n }\n\n // ── CarrierHolder — attach frame (carriage fork position) ─────────────────\n\n /**\n * Return the 3D attach frame on the crane's carriage (fork tip).\n * Carriers are attached here while the crane is in transit (pick phase).\n *\n * The Crane3D exposes `getCarriageFrame()` — a sub-Object3D that\n * tracks the carriage height and sits at the fork TCP. If the 3D object\n * isn't built yet (e.g. before scene initialization), fall back to the\n * crane's own object3d centre.\n */\n attachPointFor(carrier: Component): AttachFrame | null {\n const ro = this._realObject\n const frame = ro?.getCarriageFrame?.()\n if (!frame) return null\n const carrierDepth = resolveCarrierDepth(carrier)\n const carrierBaseY = ro?.carrierBaseY ?? 0\n const bladeMidZ = ro?.bladeMidZ ?? 0\n // carrier 외부 bottom = fork blade bottom. carryPolicy: 'follow-holder' —\n // carrier 가 crane 의 *local axis (전방)* 정렬.\n return {\n attach: frame,\n localPosition: { x: 0, y: carrierBaseY + carrierDepth / 2, z: bladeMidZ },\n carryPolicy: 'follow-holder'\n }\n }\n\n // ── Mover overrides ───────────────────────────────────────────────────────\n\n /**\n * Domain-specific actuation between arrival and reparent.\n *\n * Simulation sequence for PICK:\n * 1. Mover.pick() navigates crane to carrier position (moveTo).\n * 2. engage('pick') → snap carriage height + status 'loading'.\n * 3. Carrier is reparented to crane (becomes child).\n *\n * For now: set status and snap carriage height. A full simulation\n * would tween the carriageHeight here (animate Crane3D).\n *\n * Status lifecycle:\n * idle → (moveTo running) → engage fires → loading/unloading → (reparent) → idle\n * The 'moving' state is not set from Mover.moveTo() because TypeScript\n * can't call super.moveTo() on an `: any`-typed mixin. External data\n * binding sets 'moving' in monitoring mode; override pick()/place() to\n * set it in full simulation environments.\n */\n /**\n * Crane.moveTo — **Crane 본체 (rail) 은 안 움직임**. *내부 carriage 의 rail-\n * local X 위치 (carriagePosition) 만 lerp*. 실제 gantry / AS/RS crane 의\n * 자연스러운 운동 패턴.\n *\n * target.center 의 world 좌표를 *crane 의 local frame (rail-aligned)* 로\n * 변환 → rail-local X 추출 → carriagePosition setState.\n *\n * Crane.state.rotation = rail 방향. carriage 가 rail 위 X 만 이동.\n */\n async moveTo(target: Component, options: MoveOptions = {}): Promise<void> {\n // target.center 는 *parent-local* 좌표 — child component (cell) 의 경우\n // *rack-local*. board-absolute 변환 필요 (= toScene).\n const tcLocal = target?.center\n if (!tcLocal || typeof tcLocal.x !== 'number' || typeof tcLocal.y !== 'number') {\n return\n }\n const tcAbs = typeof (target as any).toScene === 'function'\n ? (target as any).toScene(tcLocal.x, tcLocal.y)\n : tcLocal\n const tcx = tcAbs.x\n const tcy = tcAbs.y\n\n // Crane 도 자체 center 를 toScene 으로 (crane 이 다른 container 의 child 일 수도)\n const W = (this.state.width as number) ?? 100\n const craneCenterLocal = (this as any).center ?? { x: 0, y: 0 }\n const craneCenterAbs = typeof (this as any).toScene === 'function'\n ? (this as any).toScene(craneCenterLocal.x, craneCenterLocal.y)\n : craneCenterLocal\n const ccx = craneCenterAbs.x\n const ccy = craneCenterAbs.y\n const rotation = (this.state.rotation as number) ?? 0\n const cos = Math.cos(rotation)\n const sin = Math.sin(rotation)\n\n const dx = tcx - ccx\n const dy = tcy - ccy\n const railLocalX = dx * cos + dy * sin\n\n const cw = (this.state.carriageWidth as number) ?? W * 0.1\n const minPos = cw / 2\n const maxPos = W - cw / 2\n const newCarriagePos = Math.max(minPos, Math.min(maxPos, railLocalX + W / 2))\n\n // X + Y 동시 lerp — carriage 의 횡 (rail) + 종 (mast) 운동 동기.\n //\n // 진입 위치 (= fork blade bottom world Y):\n // pick (no holding): cellBottom\n // place (holding): cellBottom + liftH (들린 carrier 와 함께 진입)\n const tween: Record<string, number> = { carriagePosition: newCarriagePos }\n const targetBottomWorldY = resolveCarrierBottomY(target)\n if (targetBottomWorldY !== null) {\n const isHoldingCarrier = ((this as any).components as any[] | undefined)?.some?.(\n (c: any) => c?._transferSlotId === 'forks'\n ) ?? false\n const liftH = numOr((this.state as any).forkLift, 30)\n const approachWorldY = targetBottomWorldY + (isHoldingCarrier ? liftH : 0)\n\n const ro = this._realObject\n const currentForkLift = numOr((this.state as any).forkLiftRT, 0)\n const solver = ro?.solveCarriageHeightForCarrierBaseWorldY\n if (typeof solver === 'function') {\n tween.carriageHeight = solver.call(ro, approachWorldY, currentForkLift)\n } else {\n tween.carriageHeight = approachWorldY\n }\n }\n\n const duration = (options.duration as number) ?? 1500\n this.setState({ status: 'moving' as CraneStatus })\n await this._tween(tween, duration)\n this.setState({ status: 'idle' as CraneStatus })\n }\n\n async engage(\n target: Component,\n kind: 'pick' | 'place',\n _options: MoveOptions = {}\n ): Promise<void> {\n // carriageHeight 는 moveTo 안 X+Y 동시 lerp 에서 처리.\n // engage 가 책임: fork extension → lift / drop → retract.\n const forkLen = numOr((this.state as any).forkLength, 600)\n // liftH — 사용자 설정 `forkLift` (= configured 진폭). 미설정 시 default 30mm.\n // 시뮬 lerp 는 *forkLiftRT* (runtime current) state 에 적용 — `forkLift` 자체\n // 는 *진폭 의미 보존* 위해 안 건드림.\n const liftH = numOr((this.state as any).forkLift, 30)\n\n // Fork side 결정 — target 이 crane 의 어느 *local Z 방향* (cross-rail, fork\n // axis) 인지. things-scene 의 `getWorldPose` 로 양쪽 world pose 산출 후\n // delta 를 crane local frame 으로 inverse-rotate → local Z 부호 = side.\n // pick/place 동일하게 동작 (이전 코드는 carrier=cell.child 케이스에서\n // rack-local vs world 좌표계 혼선으로 pick 시 방향 반대였음).\n let side: 1 | -1 = +1\n try {\n const cranePose = getWorldPose(this)\n const targetPose = getWorldPose(target)\n const dv = targetPose.position.clone().sub(cranePose.position)\n dv.applyQuaternion(cranePose.rotation.clone().invert())\n side = dv.z >= 0 ? +1 : -1\n } catch {\n // fallback — pose 계산 실패 시 +1 (rotation 무관, 의미적으로 안전한 default).\n }\n\n // Animation duration — fork extend/retract 1000ms, lift/lower 600ms.\n // 이전 (500ms / 300ms) 보다 2배 — 시각 자연스러움 강화.\n const D_EXT = 1000\n const D_LIFT = 600\n\n // fork extension target — target 의 local Z 와 _bladeMidZ 매칭. helper 가\n // inverse-solve. mismatch 시 carrier 가 *fork tip 위치 (= local Z 미일치)*\n // 로 jump → 텔레포트 결함. helper 가 정확 일치 보장.\n let extTarget = side * forkLen\n try {\n const cranePose = getWorldPose(this)\n const targetPose = getWorldPose(target)\n const dv = targetPose.position.clone().sub(cranePose.position)\n dv.applyQuaternion(cranePose.rotation.clone().invert())\n const localZ = dv.z\n const solver = (this._realObject as any)?.solveForkExtensionForLocalZ\n if (typeof solver === 'function') {\n const ext = solver.call(this._realObject, localZ)\n if (Number.isFinite(ext)) extTarget = ext\n }\n } catch {\n // fallback — 기존 side * forkLen.\n }\n\n if (kind === 'pick') {\n this.setState({ status: 'loading' as CraneStatus })\n await this._tween({ forkExtension: extTarget }, D_EXT)\n\n // Mid-engage reparent — fork 가 cell 안 도달. carrier 를 fork 위로 *즉시\n // snap* (animated:false). Transfer 객체 통과 → monitor panel 추적.\n const source = (target as any).parent\n if (source) {\n try {\n new Transfer({\n source,\n target: this as unknown as Transferable,\n carrier: target,\n options: { animated: false }\n }).executeSync()\n } catch (e) {\n // Transfer 실패 — carrier 그대로. 후속 Mover.pick receive 가 처리.\n }\n }\n\n await this._tween({ forkLiftRT: liftH }, D_LIFT)\n await this._tween({ forkExtension: 0 }, D_EXT)\n } else {\n this.setState({ status: 'unloading' as CraneStatus })\n // 1. fork extend (cell 위에서 carrier 자리 위로 진입). extTarget = inverse-\n // solved target.local.z 매칭 위치.\n await this._tween({ forkExtension: extTarget }, D_EXT)\n\n // 2. carrier lower — forkLiftRT liftH → 0. carrier 가 cell 바닥 안착.\n await this._tween({ forkLiftRT: 0 }, D_LIFT)\n\n // 3. dispatch — carrier world 위치 = cell 내 attach 위치, jump 없음. Transfer 추적.\n const comps = (this as any).components as any[] | undefined\n const carrier = comps?.find?.((c: any) => c?._transferSlotId === 'forks')\n ?? comps?.[0]\n if (carrier) {\n try {\n new Transfer({\n source: this as unknown as Transferable,\n target: target as unknown as Transferable,\n carrier,\n options: { animated: false }\n }).executeSync()\n } catch (e) {\n // dispatch 실패 — Mover.place 가 후속 처리.\n }\n }\n\n // 4. fork retract — 빈 fork.\n await this._tween({ forkExtension: 0 }, D_EXT)\n }\n }\n\n // ── Domain aliases ────────────────────────────────────────────────────────\n\n /** Fetch a carrier from a rack cell (semantically = pick). */\n fetch(carrier: Component, options?: MoveOptions): Promise<void> {\n return this.pick(carrier, options)\n }\n\n /** Deposit a carrier into a rack cell (semantically = place). */\n deposit(carrier: Component, cell: Component, options?: MoveOptions): Promise<void> {\n return this.place(carrier, cell, options)\n }\n\n // ── 2D rendering ─────────────────────────────────────────────────────────\n\n /**\n * 2D top-down 표현 — 크레인으로 명확히 인식되도록 핵심 부품 그림:\n *\n * - rail (테두리 양쪽 가장자리, dark gray)\n * - twin masts (orange, 옆으로 배치) ← 시각 identity 핵심\n * - carriage (yellow, mast 사이) ← 작은 사각형\n * - forks (yellow, 두 평행선, cross-rail 방향으로 forkLength × extension 비율로 신축)\n * - carrier (lift 됐을 때만, gray 박스 + 들림 표시 ▲)\n *\n * 숨은 축 표현:\n * - carriageHeight (mast Y): 오른쪽 mast 옆 세로 게이지 — fill 비율 = carriageHeight/depth\n * - forkLift (carrier 들기): carrier 가 lift 상태일 때 outline + ▲ 마크\n *\n * 컨벤션: width = rail (X), height = cross-rail (Y, fork 신축 방향).\n * state.rotation 은 canvas 가 처리 (다른 컴포넌트와 동일).\n */\n render(ctx: CanvasRenderingContext2D) {\n const state = this.state as any\n const width = num(state.width, 100)\n const height = num(state.height, 200)\n const left = num(state.left, 0)\n const top = num(state.top, 0)\n\n const depth = num(state.depth, Math.max(width, height) * 4)\n const carriageHeight = clamp(num(state.carriageHeight, 0), 0, depth)\n const forkExtension = num(state.forkExtension, 0) // ± (rail 양쪽 rack)\n // forkLiftRT — *시뮬 runtime current 들림*. *configured 진폭* (state.forkLift)\n // 와 분리. 시뮬 미진행 시 0 (carriage 가 mast 위 carriageHeight 만큼).\n const forkLift = num(state.forkLiftRT, 0)\n\n // carriagePosition: rail-local X (0 ~ width). default = rail center.\n // 사용자 의도 — Crane 본체 (rail) 안 움직이고 carriage assembly 만 X 슬라이드.\n const carriagePosition = clamp(num(state.carriagePosition, width / 2), 0, width)\n const cx = left + carriagePosition // masts/carriage/forks 의 중심 X\n const cy = top + height / 2\n // 적재 여부 — forkLift > 0 (시뮬 중 들어올린 상태) 또는 state.loaded 명시.\n // monitoring 모드는 외부 데이터로 state.loaded 바인딩.\n const carrying = forkLift > 0 || !!state.loaded || !!state.carrying\n\n // 높이 비율 (1F=0 → 최상층=1). carriage / carrier 의 크기 scale 에 공통 사용.\n const heightRatio = depth > 0 ? clamp(carriageHeight / depth, 0, 1) : 0\n const sizeMul = 0.5 + heightRatio * 0.5 // 50% (1F) → 100% (최상층)\n\n const MAST = '#ff7a00' // 주황 — 마스트\n const CARRIAGE_C = '#ffcc00' // 노랑 — carriage shuttle 본체\n const FORK_C = '#a8b0b8' // 은회색 — fork prong (금속 느낌, carriage 와 구분)\n const DARK = '#3a4048'\n // Carrier — 팔레트 갈색 (carriage 노랑 위에서 대비). lift 시 darker + 두꺼운 외곽.\n const CARRIER = forkLift > 0 ? '#7d5530' : '#a08864'\n const CARRIER_LINE = '#3a2a18'\n\n ctx.save()\n\n // 0. Rail footprint — 반투명 회색 fill + 외곽선. 사용자가 board 에서 crane 의\n // *rail 영역* 을 명확히 인식 + 편집 핸들 가능.\n ctx.fillStyle = '#aab0b8'\n ctx.globalAlpha = 0.15\n ctx.fillRect(left, top, width, height)\n ctx.globalAlpha = 1\n ctx.strokeStyle = DARK\n ctx.lineWidth = 1\n ctx.strokeRect(left, top, width, height)\n\n // 1. Rail — 하단 한 줄 (얇은 가이드). 톤 절제 — outer footprint 가 이미 영역 표시.\n const railW = Math.max(1, height * 0.02)\n ctx.fillStyle = DARK\n ctx.globalAlpha = 0.6\n ctx.fillRect(left, top + height - railW, width, railW)\n ctx.globalAlpha = 1\n\n // 2. Twin masts — *carriageWidth 기반* (crane.width 와 분리). rail (= crane.width)\n // 이 넓어져도 carriage assembly 는 *carriageWidth 만큼* 만.\n const carriageW = num(state.carriageWidth, width * 0.1) // default rail 의 10%\n const mastW = Math.max(2.5, carriageW * 0.15)\n const mastSpacing = carriageW * 0.85\n const mastY = top + railW\n const mastH = height - railW * 2\n const mastX1 = cx - mastSpacing / 2 - mastW / 2\n const mastX2 = cx + mastSpacing / 2 - mastW / 2\n ctx.fillStyle = MAST\n ctx.fillRect(mastX1, mastY, mastW, mastH)\n ctx.fillRect(mastX2, mastY, mastW, mastH)\n\n // 2-a. Floor tick marks — mast 위에 N 단계 (예: 5 단) 가로 줄. 층 가늠.\n const numFloors = 5\n ctx.fillStyle = 'rgba(0,0,0,0.25)'\n for (let i = 1; i < numFloors; i++) {\n const tickY = mastY + (mastH * i) / numFloors - 0.5\n ctx.fillRect(mastX1, tickY, mastW, 1)\n ctx.fillRect(mastX2, tickY, mastW, 1)\n }\n\n // 2-b. Carriage 위치 indicator — 마스트 *중심 고정* + *size = carriageHeight 비율*.\n // 1층 (=0): 얇은 선. 최상층 (=depth): 마스트 길이의 100%. 성장/수축 = 상승/하강.\n const indLen = Math.max(2, mastH * heightRatio)\n const indY = mastY + mastH / 2 - indLen / 2\n const indWidth = mastW + 4\n ctx.fillStyle = '#5a3a00' // 어두운 갈색 — orange mast 위에서 강한 대비\n ctx.fillRect(mastX1 - 2, indY, indWidth, indLen)\n ctx.fillRect(mastX2 - 2, indY, indWidth, indLen)\n\n // 3. Carriage deck — 팔레트 1200×800mm aspect 반영. *폭만* sizeMul 적용 (높이감),\n // 길이 (Y) 고정. carrier / fork 모두 이 deck 기준으로 derive.\n const deckW = (mastSpacing - mastW) * sizeMul\n const carriageH = Math.min((mastSpacing - mastW) * 1.3, (height - railW * 2) * 0.55)\n const carriageX = cx - deckW / 2\n const carriageY = cy - carriageH / 2\n ctx.fillStyle = CARRIAGE_C\n ctx.fillRect(carriageX, carriageY, deckW, carriageH)\n\n // 4. Fork — 좌우 균형:\n // - 양쪽 모두 *작은 stub* 항상 표시 (crane 이 양쪽 rack 사이 있는 인상)\n // - extension 부호 (+/-) 에 따라 active 쪽이 추가로 신축\n // - 신축 길이 = |forkExtension| (실제 reach 만큼)\n const stubLen = Math.max(2, carriageH * 0.5)\n // 포크 폭 — deck 의 80%.\n const forkW = deckW * 0.8\n const forkX = cx - forkW / 2\n const extLen = Math.abs(forkExtension)\n const sign = forkExtension >= 0 ? 1 : -1\n ctx.fillStyle = FORK_C\n // 항상 양쪽 stub\n ctx.fillRect(forkX, carriageY - stubLen, forkW, stubLen) // top stub\n ctx.fillRect(forkX, carriageY + carriageH, forkW, stubLen) // bottom stub\n // active 쪽 추가 신축\n if (extLen > 0.5) {\n if (sign > 0) {\n ctx.fillRect(forkX, carriageY + carriageH + stubLen, forkW, extLen)\n } else {\n ctx.fillRect(forkX, carriageY - stubLen - extLen, forkW, extLen)\n }\n }\n\n // 5. Carrier — *팔레트 크기* 정사각형. 신축 시 fork 끝 (cell 안쪽) 에 배치.\n // - extLen > 0: carrier 가 fork 끝 (cell 안) — pallet 이 cell 로 들어가는 인상\n // - retracted (extLen=0): carriage 중심 — transit 자세\n // - forkLift > 0: 진한 갈색 + 두꺼운 outline (들린 상태 시인)\n if (carrying) {\n // 팔레트 — 항상 carriage 의 90% (폭/길이 모두). carriage 가 sizeMul 적용된 폭이라\n // carrier 도 자동으로 sizeMul 반영. 길이는 carriage 길이 고정에 따라 고정.\n const carrW = deckW * 0.9\n const carrH = carriageH * 0.9\n // Carrier 2D 위치 — 3D _bladeMidZ 와 동일 공식 (sign * extLen).\n // extLen=0 → carriage 정중앙. extLen 증가 → cell 방향 으로 진출.\n const offset = extLen\n const carrCenterY = sign > 0\n ? carriageY + carriageH / 2 + offset\n : carriageY + carriageH / 2 - offset\n const carrX = cx - carrW / 2\n const carrY = carrCenterY - carrH / 2\n\n // 들린 상태 — drop shadow 로 *떠 있는* 인상 (forkLift > 0). offset 비율 = lift 강도.\n if (forkLift > 0) {\n const liftMax = Math.max(num(state.forkLift, 30), 20) // configured 진폭\n const liftRatio = clamp(forkLift / liftMax, 0.3, 1) // 최소 30% 표시 (있다는 것만 보이게)\n const shadowOff = Math.max(2, Math.min(carrW, carrH) * 0.14) * liftRatio\n ctx.fillStyle = 'rgba(0, 0, 0, 0.4)'\n ctx.fillRect(carrX + shadowOff, carrY + shadowOff, carrW, carrH)\n }\n\n // Carrier 본체\n ctx.fillStyle = CARRIER\n ctx.fillRect(carrX, carrY, carrW, carrH)\n ctx.strokeStyle = CARRIER_LINE\n ctx.lineWidth = forkLift > 0 ? 1.5 : 0.8\n ctx.strokeRect(carrX, carrY, carrW, carrH)\n }\n\n // Cargo (carrier) 가 fork 위에 얹혀 fork 신축과 함께 이동하므로 그 자체로 방향\n // (loading/unloading) 이 자연 인식. 별도 status 배지 없음.\n\n // (carriageHeight 시각화는 mast 위 dark band + floor ticks 로 통합 — 별도 측면 게이지 제거)\n\n ctx.restore()\n }\n\n // ── Lifecycle — simulate() 자동 시작 ────────────────────────────────────\n\n added(parent: any): void {\n super.added?.(parent)\n\n // state ↔ visual single source of truth. state 미설정 시 _canonicalDefault\n // 로 명시 초기화 — build / _tween / 외부 read 모두 동일 값.\n const init: Record<string, number> = {}\n for (const k of ['carriagePosition', 'carriageHeight', 'forkExtension', 'forkLiftRT']) {\n if (typeof (this.state as any)[k] !== 'number') {\n init[k] = this._canonicalDefault(k)\n }\n }\n if (Object.keys(init).length > 0) this.setState(init)\n\n // state.simulate === true 명시 시만 자동 시작. mode 연동은 board view layer\n // 책임 — 컴포넌트 자체는 simulate state 만 본다 (sorter/conveyor 등 다른\n // 시뮬 컴포넌트와 동일 패턴).\n if ((this.state as CraneState).simulate !== true) return\n this._startAutoSimulate()\n }\n\n /**\n * Actuator state 의 *canonical default*. state 미설정 시 모든 read 경로\n * (build / _tween / 외부) 가 *동일 값* 보도록.\n *\n * single source 패턴 — visual fallback 과 state fallback 이 *분리* 되어\n * 첫 _tween 시 start 가 visual current 와 어긋나는 jump 결함을 근본 차단.\n */\n _canonicalDefault(key: string): number {\n const state = this.state as any\n const W = numOr(state.width, 100)\n const H = numOr(state.height, 100)\n const D = numOr(state.depth, Math.max(W, H) * 4)\n switch (key) {\n case 'carriagePosition': return W / 2\n case 'carriageHeight': return D * 0.4\n case 'forkExtension':\n case 'forkLiftRT':\n case 'forkLift':\n return 0\n default: return 0\n }\n }\n\n private _startAutoSimulate(): void {\n if (this._simStarted) return\n this._simStarted = true\n // 초기 지연 800~2800ms 사이 random — 여러 crane 이 동기적으로 시작하지 않도록.\n const initialDelay = 800 + Math.random() * 2000\n setTimeout(() => {\n if (this._simAbort || (this.state as CraneState).simulate !== true) return\n this.simulate().catch(e => console.error('[Crane] simulate', e))\n }, initialDelay)\n }\n\n /**\n * state.simulate 변경 시 자동 simulate 시작/중단. application 이 런타임 toggle\n * 가능 (예: editor 에서 simulate off, view 에서 on).\n */\n onchange(after: Record<string, unknown>, before: Record<string, unknown>): void {\n super.onchange(after as any, before as any)\n // carriage 관련 state 변경 시 2D render 명시 invalidate. things-scene 의\n // setState → trigger change 가 render queue 에 자동 등록 못 하는 케이스 방어.\n if (\n 'carriagePosition' in after ||\n 'carriageWidth' in after ||\n 'carriageHeight' in after ||\n 'forkExtension' in after ||\n 'forkLift' in after ||\n 'forkLiftRT' in after\n ) {\n ;(this as any).invalidate?.()\n }\n if ('simulate' in after) {\n if (after.simulate === true) {\n // 명시 true → 자동 시작 (이미 시작 중이면 noop). mode gating 은\n // frameClock (animate 의 simTime) 이 자동 처리 — modeler 면 simTime\n // 안 흐름, _tween step 호출 안 됨.\n this._simAbort = false\n this._simStarted = false\n this._startAutoSimulate()\n } else {\n this._simAbort = true\n }\n }\n }\n\n // ── 3D ───────────────────────────────────────────────────────────────────\n\n buildRealObject(): RealObject | undefined {\n return new Crane3D(this)\n }\n\n // ── Random animation (visual smoke test) ─────────────────────────────────\n // things-scene 의 component.animate() (frameClock 기반, pause/speed 대응) 를 사용.\n\n private _simStarted = false\n private _simRunning = false\n private _simAbort = false\n // Rail = crane 의 *로컬 X 축* (state.rotation 적용). simulate 진입 시 1회 계산해서 캐시.\n private _railOriginX = 0\n private _railOriginY = 0\n private _railCos = 1\n private _railSin = 0\n private _railMin = NaN // local-X 축 rail offset min\n private _railMax = NaN // local-X 축 rail offset max\n private _targetSide = 1 // +Z (fork +Z 로 뻗어야 하나) / -Z\n\n /** Continuous random pick → transport → place cycles. Visual smoke test. */\n async simulate(): Promise<void> {\n if (this._simRunning) return\n this._simRunning = true\n this._simAbort = false\n try {\n this._initRailRange()\n while (!this._simAbort) {\n await this._oneCycle()\n }\n } finally {\n this._simRunning = false\n }\n }\n\n /**\n * state.target bbox 를 crane 의 *로컬 X 축* 으로 projection 해서 rail range 1회 계산.\n * Rotation 적용된 crane 의 local X (= rail) 방향으로 움직이도록 cos/sin 캐시.\n */\n private _initRailRange(): void {\n this._railMin = this._railMax = NaN\n\n // simulate cycle 의 random pickAndPlace range — crane 의 parent 컨테이너\n // (= 보통 rack 또는 board) 의 bbox 를 기준으로. parent 가 top-level\n // (root/model-layer) 이면 bbox 의미 없음 → skip.\n const root = (this as any).root\n const parent = (this as any).parent\n let target: any = null\n if (parent && parent !== root && (parent.state as any)?.width > 0) {\n target = parent\n }\n if (!target) return\n\n const tState = target.state ?? {}\n const tl = numOr(tState.left, 0)\n const tt = numOr(tState.top, 0)\n const tw = numOr(tState.width, 0)\n const th = numOr(tState.height, 0)\n if (tw <= 0 || th <= 0) return\n\n const W = numOr((this.state as any).width, 100)\n const H = numOr((this.state as any).height, 100)\n const rotation = numOr((this.state as any).rotation, 0)\n const cos = Math.cos(rotation)\n const sin = Math.sin(rotation)\n\n // Rail origin = crane 의 현재 canvas center. 이 점에서 local X 방향으로 ±rail offset.\n this._railOriginX = numOr((this.state as any).left, 0) + W / 2\n this._railOriginY = numOr((this.state as any).top, 0) + H / 2\n this._railCos = cos\n this._railSin = sin\n\n // Target bbox 4 corner 를 crane local frame 으로 projection.\n // local X (rail) = dx*cos + dy*sin\n // local Z (aisle) = -dx*sin + dy*cos\n const corners = [\n { x: tl, y: tt },\n { x: tl + tw, y: tt },\n { x: tl, y: tt + th },\n { x: tl + tw, y: tt + th }\n ]\n let minRail = Infinity\n let maxRail = -Infinity\n let aisleSum = 0\n for (const c of corners) {\n const dx = c.x - this._railOriginX\n const dy = c.y - this._railOriginY\n const rail = dx * cos + dy * sin\n const aisle = -dx * sin + dy * cos\n if (rail < minRail) minRail = rail\n if (rail > maxRail) maxRail = rail\n aisleSum += aisle\n }\n // Crane 자체 W 만큼 안쪽으로 좁혀 — crane center 가 [minRail+W/2, maxRail-W/2] 안에\n // 있으면 crane 전체가 target bbox 안 (local X 방향).\n this._railMin = minRail + W / 2\n this._railMax = Math.max(this._railMin, maxRail - W / 2)\n this._targetSide = aisleSum >= 0 ? +1 : -1\n }\n\n stopSimulate(): void {\n this._simAbort = true\n // 진행 중인 animate() controller 도 즉시 정지 — onComplete 가 호출되어 _tween Promise\n // 가 resolve → simulate() while 루프가 다음 반복에서 _simAbort 보고 종료. 이걸로\n // 루프 stack 의 strong ref 해소, frameClock subscription 해제.\n const ctrl = (this as any)._animate\n if (ctrl && typeof ctrl.stop === 'function') {\n try { ctrl.stop() } catch {}\n }\n }\n\n /**\n * 컴포넌트 dispose 시 (보드 종료, scene reload 등) 진행 중 simulate 루프와 animate\n * subscription 을 정리. 미정리 시 루프의 await stack 이 component 를 strong reference\n * 로 잡아 GC 안 됨 + frameClock 콜백 살아남음.\n */\n dispose(): void {\n this.stopSimulate()\n super.dispose?.()\n }\n\n private async _oneCycle(): Promise<void> {\n const W = numOr((this.state as any).width, 100)\n const H = numOr((this.state as any).height, 100)\n const D = numOr((this.state as any).depth, W * 4)\n const forkLen = numOr((this.state as any).forkLength, H * 0.6)\n const cw = numOr((this.state as any).carriageWidth, W * 0.1)\n\n // carriagePosition 의 valid range — rail 안 [cw/2, W - cw/2].\n // crane 본체 (rail) 는 안 움직임 — *carriage assembly 만* X 슬라이드.\n const minPos = cw / 2\n const maxPos = Math.max(minPos, W - cw / 2)\n const pickPos = () => minPos + Math.random() * (maxPos - minPos)\n\n const sourcePos = pickPos()\n const destPos = pickPos()\n\n const sourceCH = Math.random() * D * 0.75\n const destCH = Math.random() * D * 0.75\n const liftH = Math.max(20, D * 0.02)\n // 양쪽 rack 모두 서비스 — source/dest 각각 ±Z random (cycle 별 다름).\n const sideA = Math.random() < 0.5 ? -1 : +1\n const sideB = Math.random() < 0.5 ? -1 : +1\n\n // Tween duration 은 base 의 70~130% 사이 random — 여러 crane 이 같은 타이밍으로 안 보이도록.\n const jitter = (base: number): number => base * (0.7 + Math.random() * 0.6)\n\n // 이동: carriagePosition 만 변경 (crane.left/top 안 건드림).\n await this._tween({ status: 'moving', carriagePosition: sourcePos, carriageHeight: sourceCH }, jitter(1500))\n await this._tween({ status: 'loading', forkExtension: sideA * forkLen }, jitter(700))\n await this._tween({ forkLiftRT: liftH }, jitter(400))\n await this._tween({ forkExtension: 0 }, jitter(700))\n await this._tween({ status: 'moving', carriagePosition: destPos, carriageHeight: destCH }, jitter(1500))\n await this._tween({ status: 'unloading', forkExtension: sideB * forkLen }, jitter(700))\n await this._tween({ forkLiftRT: 0 }, jitter(400))\n await this._tween({ status: 'idle', forkExtension: 0 }, jitter(700))\n\n // 사이클 사이 짧은 idle (200~1000ms) — 자연스러운 phase 분산\n await new Promise(r => setTimeout(r, 200 + Math.random() * 800))\n }\n\n /**\n * frameClock 기반 tween — things-scene 의 표준 `Component.animate()` 사용.\n * frameClock.simTime 진행 (view mode + scene 활성) 시에만 step 호출 → modeler\n * 또는 paused 시 자동 정지. scene.simulationSpeed 도 자동 대응.\n */\n private _tween(targets: Record<string, any>, duration: number): Promise<void> {\n const start: Record<string, number> = {}\n for (const k of Object.keys(targets)) {\n if (k === 'status') continue\n const v = (this.state as any)[k]\n start[k] = typeof v === 'number' && Number.isFinite(v) ? v : this._canonicalDefault(k)\n }\n if (typeof targets.status === 'string') {\n this.setState({ status: targets.status })\n }\n return new Promise<void>(resolve => {\n let resolved = false\n const finish = () => {\n if (resolved) return\n resolved = true\n resolve()\n }\n const controller = (this as any).animate({\n duration,\n ease: 'inout',\n delta: 'quad',\n step: (dx: number) => {\n const update: Record<string, number> = {}\n for (const k of Object.keys(start)) {\n const tgt = targets[k]\n if (typeof tgt !== 'number') continue\n update[k] = start[k] + (tgt - start[k]) * dx\n }\n this.setState(update as any)\n },\n onComplete: finish\n })\n controller.start()\n })\n }\n}\n\nfunction resolveCarrierDepth(c: Component): number {\n const eff = (c as any)._realObject?.effectiveDepth\n if (typeof eff === 'number' && Number.isFinite(eff)) return eff\n return numOr((c as any)?.state?.depth, 0)\n}\n\n\n/**\n * Target 의 *world bottom Y* — fork blade 가 위치해야 할 높이.\n *\n * `getWorldPose(c).position.y` 는 *center Y*. fork 는 carrier 의 *바닥* (pallet\n * pocket 진입 면) 에 위치해야 함 → center 에서 depth/2 만큼 빼서 bottom.\n *\n * `effectiveDepth` 는 RealObject 가 자동 계산한 실제 3D Y 키. 미가용 시 state.\n * depth fallback.\n */\nfunction resolveCarrierBottomY(c: Component): number | null {\n if (!c) return null\n try {\n const pose = getWorldPose(c)\n const centerY = pose?.position?.y\n if (typeof centerY !== 'number' || !Number.isFinite(centerY)) return null\n const ro = (c as any)._realObject\n const eff = ro?.effectiveDepth\n const depth = typeof eff === 'number' && Number.isFinite(eff)\n ? eff\n : numOr((c as any)?.state?.depth, 0)\n return centerY - depth / 2\n } catch {\n return null\n }\n}\n\nfunction numOr(v: unknown, dflt: number): number {\n return typeof v === 'number' && Number.isFinite(v) ? v : dflt\n}\n\n// ── 2D render helpers ────────────────────────────────────────────────────\nfunction num(v: unknown, dflt: number): number {\n return typeof v === 'number' && Number.isFinite(v) ? v : dflt\n}\n\nfunction clamp(v: number, min: number, max: number): number {\n return v < min ? min : v > max ? max : v\n}\n\n/** \"#rrggbb\" 또는 \"name\" 색에 alpha 적용. 실패 시 fallback rgba. */\nfunction withAlpha(color: string, alpha: number): string {\n // \"#rrggbb\" 형식만 지원 — name color 는 rgba 직접 변환 못해서 그대로 사용\n if (color && color[0] === '#' && color.length === 7) {\n const r = parseInt(color.slice(1, 3), 16)\n const g = parseInt(color.slice(3, 5), 16)\n const b = parseInt(color.slice(5, 7), 16)\n return `rgba(${r},${g},${b},${alpha})`\n }\n return color\n}\n"]}
1
+ {"version":3,"file":"crane.js","sourceRoot":"","sources":["../src/crane.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * Copyright © HatioLab Inc. All rights reserved.\n */\nimport { Component, ComponentNature, ContainerAbstract, ContainerCapacity, RealObject, Transfer, getWorldPose, sceneComponent } from '@hatiolab/things-scene'\nimport type { SlotDef, State, Material3D, Transferable } from '@hatiolab/things-scene'\nimport {\n CarrierHolder,\n Legendable,\n Mover,\n Placeable,\n isSlottedHolder,\n findDispatcher,\n resolveTransferTarget,\n type AttachFrame,\n type Alignment,\n type Dispatcher,\n type Heights,\n type LegendBinding,\n type MoveOptions,\n type PlacementArchetype,\n type SlottedHolder,\n type TransferTicket\n} from '@operato/scene-base'\nimport * as THREE from 'three'\n\nimport { Crane3D } from './crane-3d.js'\n\n/**\n * AdjacentSlot — crane 의 작업 reach 영역 안에 있는 slot 의 정보. simulate /\n * 자동 transfer 의 source/dest 후보.\n */\nexport interface AdjacentSlot {\n holder: SlottedHolder & { state?: any }\n slotId: string\n anchor: THREE.Object3D\n world: THREE.Vector3\n}\n\n/**\n * Crane status — the operating state of a stacker crane.\n *\n * - `idle` — parked at home position\n * - `moving` — translating (horizontal) or along the mast (vertical);\n * typically combined\n * - `loading` — extracting a carrier from a rack cell\n * - `unloading` — placing a carrier into a rack cell\n * - `error` — fault / e-stop / collision warning\n */\nexport type CraneStatus = 'idle' | 'moving' | 'loading' | 'unloading' | 'error'\n\n/** Crane 컴포넌트 state */\nexport interface CraneState extends State {\n // ── 운영 상태 ──\n status?: CraneStatus\n\n // ── 액추에이터 ──\n /** 마스트 따라 carriage 의 수직 위치 (mm). */\n carriageHeight?: number\n /**\n * Fork prong 의 최대 신축 가능 길이 (mm). cell 깊이 + 여유.\n * 일반적으로 pallet 깊이 (1200mm) + 여유 ≈ 1300mm 또는 그 이하 (default 600).\n */\n forkLength?: number\n /**\n * Fork 의 *현재 신축 거리* (mm). 0 = collapsed (shuttle 안 들어가있음),\n * forkLength = fully extended (cell 안 carrier 의 fork pocket 도달).\n *\n * 시뮬레이션 흐름:\n * idle: 0\n * approach → 0\n * pick / place: 0 → forkLength (extending) → 0 (retracting with carrier)\n */\n forkExtension?: number\n /**\n * Fork 가 carrier 를 *cell shelf 에서 분리하기 위해 들어올리는 높이* (mm).\n * 사용자가 board 에서 설정하는 *configured 진폭*. engage 의 lift 단계 target.\n * 미명시 시 default 30mm.\n *\n * Note: 시뮬 *진행 중 current 들림 값* 은 별도 internal transient — `forkLiftRT`\n * state. 3D / 2D render 가 carriage Y 결정 시 그 값을 사용.\n */\n forkLift?: number\n\n /**\n * Fork lift *runtime current value* (mm). engage 가 시뮬 진행 중 매 frame\n * setState 로 lerp. *사용자가 설정하는 값 아님* — internal transient.\n */\n forkLiftRT?: number\n\n /**\n * 자동 random simulate 시작 여부. capability 기반 — crane.findAdjacentSlots()\n * 으로 인접 SlottedHolder 발견 후 random source/dest transfer.\n * - `undefined` 또는 `false` (default): 자동 시작 안 함. application 이 crane.\n * pickAndPlace 등 직접 제어 시 사용.\n * - `true`: added() 시 자동 시작 + state runtime toggle 가능.\n */\n simulate?: boolean\n\n /**\n * 1:N binding — 이 crane 이 *작업 대상으로 인지할 holder id 들*. 모델링 시\n * 사용자가 명시. 명시 시 *findAdjacentSlots 가 그 list 의 holder 만 traverse*\n * → broad scene scan 회피. 미명시 시 *scene 전체 SlottedHolder fallback*\n * (BC, 기존 모델 호환).\n *\n * 입력 형식 — comma-separated id string (\"rack-1, rack-2\") 또는 array.\n * editor 의 *id-list-input* widget 부재 시 string 으로.\n */\n boundHolders?: string | string[]\n\n /**\n * Carriage 의 rail-local X 위치 (0 ~ crane.width). Crane.moveTo / simulate 가\n * lerp. crane 본체 (rail) 는 안 움직임 — carriage assembly (masts + carriage +\n * forks) 만 rail 안 X 만 슬라이드.\n */\n carriagePosition?: number\n\n /**\n * Carriage 의 폭 (rail-local X 방향). 미명시 시 rail (crane.width) 의 ~10%.\n * Target rack 의 cell 폭과 매칭 권유.\n */\n carriageWidth?: number\n\n /**\n * Carriage 운동 속도 (scene units / sec). 각 crane 별로 다르게 설정 가능 — 같은\n * 거리도 crane 마다 다른 시간. 미명시 시 default 250 u/s.\n *\n * Crane.moveTo 가 *carriage 의 X 및 Y 운동 거리* / speed 로 duration 계산 → 한 칸\n * 이동 vs rail 끝~끝 이동 의 시간 자연 차이. 여러 crane 의 cycle 시간 분산 → 동시\n * 동기화 회귀 차단.\n */\n speed?: number\n\n // ── 3D 재질 ──\n material3d?: Material3D\n}\n\nconst BODY_LEGEND = {\n idle: '#888',\n moving: '#aabbcc',\n loading: '#ffaa00',\n unloading: '#ffaa00',\n error: '#c66',\n default: '#888'\n}\n\nconst LAMP_EMISSIVE_LEGEND = {\n idle: '#222222',\n moving: '#44ff44',\n loading: '#ffaa00',\n unloading: '#ffaa00',\n error: '#ff3333',\n default: '#222222'\n}\n\nconst NATURE: ComponentNature = {\n mutable: false,\n resizable: true,\n rotatable: true,\n properties: [\n {\n type: 'select',\n label: 'status',\n name: 'status',\n property: {\n options: [\n { display: 'Idle', value: 'idle' },\n { display: 'Moving', value: 'moving' },\n { display: 'Loading', value: 'loading' },\n { display: 'Unloading', value: 'unloading' },\n { display: 'Error', value: 'error' }\n ]\n }\n },\n {\n type: 'checkbox',\n label: 'simulate',\n name: 'simulate'\n },\n {\n type: 'string',\n label: 'bound-holders',\n name: 'boundHolders',\n placeholder: 'SlottedHolder id (rack-1, rack-2, ...). 미명시 시 scene 전체 fallback.'\n },\n {\n type: 'number',\n label: 'carriage-position',\n name: 'carriagePosition',\n placeholder: 'rail-local X (0 ~ rail width). Crane.moveTo 가 lerp.'\n },\n {\n type: 'number',\n label: 'carriage-width',\n name: 'carriageWidth',\n placeholder: 'rail-local 폭 (mm). 미명시 rail width × 10%.'\n },\n {\n type: 'number',\n label: 'carriage-height',\n name: 'carriageHeight',\n placeholder: 'mm — height of carriage on mast'\n },\n {\n type: 'number',\n label: 'fork-length',\n name: 'forkLength',\n placeholder: 'mm — fork prong 최대 신축 길이 (default 600)'\n },\n {\n type: 'number',\n label: 'speed',\n name: 'speed',\n placeholder: 'scene units/sec — carriage 운동 속도 (default 250)'\n },\n {\n type: 'number',\n label: 'fork-extension',\n name: 'forkExtension',\n placeholder: 'mm — 현재 신축 거리 (0 = collapsed)'\n },\n {\n type: 'number',\n label: 'fork-lift',\n name: 'forkLift',\n placeholder: 'mm — carrier 들어올림 높이 (+ 위로)'\n }\n ],\n help: 'scene/component/crane'\n}\n\n// Mixin chain: Mover → CarrierHolder → ContainerCapacity → Legendable → Placeable → ContainerAbstract\n//\n// Mover: pick / place / pickAndPlace / moveTo / engage primitives\n// CarrierHolder: attachPointFor() — where the carrier sits on the crane (carriage fork)\n// ContainerCapacity: receive() / dispatch() / canReceive() / slots — slot tracking +\n// TRANSFER_SLOT_KEY bookkeeping during transit\n// Legendable: status → bodyColor / lampEmissive colour mapping\n// Placeable: floor-archetype 3D positioning\n// ContainerAbstract: child management — carrier becomes a child while in transit\n//\n// Note: ContainerAbstract replaces Shape. The 2D outline is drawn manually in\n// render() below (a simple top-down rectangle), matching the old Shape output\n// without the Shape base-class overhead.\n/**\n * Crane — a stacker / retrieval picker. Picker contract instance.\n *\n * Moves carriers between rack cells (or any Placeable target). The crane\n * is *picker-side* of the Phase G/H Pickable contract — it knows how to\n * `pick(carrier)` / `place(carrier, target)` and `engage(target, kind)`\n * to align its actuators. It is *storage-agnostic* — any Rack / Cell /\n * Spot / Conveyor that implements the receive/dispatch protocol is a\n * valid target.\n *\n * Structure: a tall vertical mast that translates horizontally on a rail\n * or free floor path, with a carriage that slides up/down the mast carrying\n * a shuttle / forks.\n *\n * **Monitoring mode**: crane status is driven by external data binding\n * (`state.status`, `state.carriageHeight`). The carrier is referenced\n * via data binding — it is NOT a child of the crane in monitoring mode.\n *\n * **Simulation mode**: call `crane.pick(carrier)` / `crane.place(carrier, target)`\n * (or `crane.pickAndPlace(carrier, target)`). Mover handles navigation +\n * engage + reparent. During transit the carrier IS a child of the crane.\n */\n@sceneComponent('crane')\nexport default class Crane extends Mover(CarrierHolder(ContainerCapacity(Legendable(Placeable(ContainerAbstract))))) {\n declare state: CraneState\n declare _realObject?: Crane3D\n\n static legends: Record<string, LegendBinding> = {\n bodyColor: { from: 'status', legend: BODY_LEGEND },\n lampEmissive: { from: 'status', legend: LAMP_EMISSIVE_LEGEND }\n }\n\n static placement: PlacementArchetype = 'floor'\n static align: Alignment = 'bottom'\n static defaultDepth = (h: Heights) => h.ceiling - h.floor\n\n /** Yaw offset: crane model is drawn with the rail axis along X (right = forward). */\n static yawOffset = 0\n\n /**\n * Phase H — the crane uses telescoping forks to pick up a carrier in a rack\n * cell. Same mechanism as a forklift fork — engages the pallet's fork pocket.\n * (Mover mixin chain is `: any` so override keyword is not usable, only the\n * getter is defined.)\n */\n get toolType(): string {\n return 'forklift-fork'\n }\n\n get nature() {\n return NATURE\n }\n\n get anchors() {\n return []\n }\n\n // ── ContainerCapacity ─────────────────────────────────────────────────────\n\n /**\n * Stacker crane carries at most one load at a time on its forks.\n *\n * localPosition.z = 0 명시 — ContainerCapacity.receive 의 atomic setState 가\n * `carrier.state.zPos = slot.localPosition.z + parentGeoOffset = 0` 강제.\n * 미명시 시 zPos update skip → carrier 의 *이전 holder 또는 board model 의\n * 임의 zPos (음수 가능)* 그대로 → _realObject 미빌드 시점 (transient placement\n * 미설정 = state-driven) 에 carrier 가 *지하* 로 가는 결함.\n */\n get slots(): SlotDef[] {\n return [{ id: 'forks', maxCount: 1, localPosition: { x: 0, y: 0, z: 0 } }]\n }\n\n /**\n * Acceptance rotation — carrier 가 crane.fork 에 attach 시 *crane 의 local\n * axis (전방)* 으로 정렬. identity quaternion 반환 → atomic setState 가\n * carrier.state.rotation/X/Y = 0 강제. _realObject 미빌드 시점 (transient\n * placement 미설정 = state-driven) fallback 에서도 자세 정렬.\n *\n * follow-holder carryPolicy 와 짝 — 두 path 모두 동일 결과 (local identity).\n */\n acceptanceRotation(_carrier: Component, _slot?: SlotDef): { x: number; y: number; z: number; w: number } {\n return { x: 0, y: 0, z: 0, w: 1 }\n }\n\n /**\n * Arrangement — carrier.state.left/top 의 *기준* 이 *crane 전체 footprint* 가\n * 아닌 *carriage X (carriagePosition) + fork Z (bladeMidZ)*. carriage / fork\n * 의 위치가 carrier 의 위치.\n *\n * left = carriagePosition − carrier.w/2 (carriage X 중심)\n * top = crane.h/2 + bladeMidZ − carrier.h/2 (fork Z 중심)\n */\n get arrangementStrategy() {\n const crane = this as any\n return {\n positionAt(_idx: number, _slot: any, _occ: number, component?: any) {\n const cw = numOr(crane.state?.width, 100)\n const ch = numOr(crane.state?.height, 100)\n const carrierW = numOr(component?.state?.width, 0)\n const carrierH = numOr(component?.state?.height, 0)\n const carriagePos = numOr(crane.state?.carriagePosition, cw / 2)\n const bladeMidZ = numOr(crane._realObject?.bladeMidZ, 0)\n return {\n x: carriagePos - carrierW / 2,\n y: ch / 2 + bladeMidZ - carrierH / 2,\n z: 0\n }\n },\n capacity(slot: any) {\n return slot.maxCount ?? Infinity\n }\n }\n }\n\n // ── CarrierHolder — attach frame (carriage fork position) ─────────────────\n\n /**\n * Return the 3D attach frame on the crane's carriage (fork tip).\n * Carriers are attached here while the crane is in transit (pick phase).\n *\n * The Crane3D exposes `getCarriageFrame()` — a sub-Object3D that\n * tracks the carriage height and sits at the fork TCP. If the 3D object\n * isn't built yet (e.g. before scene initialization), fall back to the\n * crane's own object3d centre.\n */\n attachPointFor(carrier: Component): AttachFrame | null {\n const ro = this._realObject\n const frame = ro?.getCarriageFrame?.()\n if (!frame) return null\n const carrierDepth = resolveCarrierDepth(carrier)\n const carrierBaseY = ro?.carrierBaseY ?? 0\n const bladeMidZ = ro?.bladeMidZ ?? 0\n // carrier 외부 bottom = fork blade bottom. carryPolicy: 'follow-holder' —\n // carrier 가 crane 의 *local axis (전방)* 정렬.\n return {\n attach: frame,\n localPosition: { x: 0, y: carrierBaseY + carrierDepth / 2, z: bladeMidZ },\n carryPolicy: 'follow-holder'\n }\n }\n\n // ── Mover overrides ───────────────────────────────────────────────────────\n\n /**\n * Domain-specific actuation between arrival and reparent.\n *\n * Simulation sequence for PICK:\n * 1. Mover.pick() navigates crane to carrier position (moveTo).\n * 2. engage('pick') → snap carriage height + status 'loading'.\n * 3. Carrier is reparented to crane (becomes child).\n *\n * For now: set status and snap carriage height. A full simulation\n * would tween the carriageHeight here (animate Crane3D).\n *\n * Status lifecycle:\n * idle → (moveTo running) → engage fires → loading/unloading → (reparent) → idle\n * The 'moving' state is not set from Mover.moveTo() because TypeScript\n * can't call super.moveTo() on an `: any`-typed mixin. External data\n * binding sets 'moving' in monitoring mode; override pick()/place() to\n * set it in full simulation environments.\n */\n /**\n * Crane.moveTo — **Crane 본체 (rail) 은 안 움직임**. *내부 carriage 의 rail-\n * local X 위치 (carriagePosition) 만 lerp*. 실제 gantry / AS/RS crane 의\n * 자연스러운 운동 패턴.\n *\n * target.center 의 world 좌표를 *crane 의 local frame (rail-aligned)* 로\n * 변환 → rail-local X 추출 → carriagePosition setState.\n *\n * Crane.state.rotation = rail 방향. carriage 가 rail 위 X 만 이동.\n */\n async moveTo(target: Component, options: MoveOptions = {}): Promise<void> {\n // target.center 는 *parent-local* 좌표 — child component (cell) 의 경우\n // *rack-local*. board-absolute 변환 필요 (= toScene).\n const tcLocal = target?.center\n if (!tcLocal || typeof tcLocal.x !== 'number' || typeof tcLocal.y !== 'number') {\n return\n }\n const tcAbs = typeof (target as any).toScene === 'function'\n ? (target as any).toScene(tcLocal.x, tcLocal.y)\n : tcLocal\n const tcx = tcAbs.x\n const tcy = tcAbs.y\n\n // Crane 도 자체 center 를 toScene 으로 (crane 이 다른 container 의 child 일 수도)\n const W = (this.state.width as number) ?? 100\n const craneCenterLocal = (this as any).center ?? { x: 0, y: 0 }\n const craneCenterAbs = typeof (this as any).toScene === 'function'\n ? (this as any).toScene(craneCenterLocal.x, craneCenterLocal.y)\n : craneCenterLocal\n const ccx = craneCenterAbs.x\n const ccy = craneCenterAbs.y\n\n const dx = tcx - ccx\n const dy = tcy - ccy\n\n // Rail axis 결정 — *2D state.rotation 무관*. 실제 3D scene 안의 crane mesh 가\n // *어떤 방향* 에 놓였든 *그 visual rail 방향* 따라 carriage 운동. crane.object3d\n // 의 matrixWorld 에서 local X axis (= rail mesh 의 long axis = BoxGeometry(width,..)\n // 의 X 방향) 의 world 방향 벡터 추출. 2D rotation→3D 매핑 컨벤션 (.rotation.y vs\n // rotation.z, 부호) 영향 0 — 실 visual 방향 그대로 사용.\n const ro: any = this._realObject\n const obj3d: THREE.Object3D | undefined = ro?.object3d\n let railLocalX: number\n if (obj3d) {\n obj3d.updateMatrixWorld(true)\n const m = obj3d.matrixWorld.elements\n // 3D world frame: local X axis = (m[0], m[1], m[2]). 2D Y == 3D Z 매핑.\n // 사용자 (dx, dy) = 2D scene 좌표 차이 = 3D (X, Z) 차이.\n const axisX = m[0]\n const axisZ = m[2]\n const len = Math.hypot(axisX, axisZ)\n if (len > 1e-9) {\n const ux = axisX / len\n const uz = axisZ / len\n railLocalX = dx * ux + dy * uz\n } else {\n railLocalX = dx\n }\n } else {\n railLocalX = dx\n }\n\n const cw = (this.state.carriageWidth as number) ?? W * 0.1\n const minPos = cw / 2\n const maxPos = W - cw / 2\n const newCarriagePos = Math.max(minPos, Math.min(maxPos, railLocalX + W / 2))\n\n // X + Y 동시 lerp — carriage 의 횡 (rail) + 종 (mast) 운동 동기.\n //\n // 진입 위치 (= fork blade bottom world Y):\n // pick (no holding): cellBottom\n // place (holding): cellBottom + liftH (들린 carrier 와 함께 진입)\n const tween: Record<string, number> = { carriagePosition: newCarriagePos }\n const targetBottomWorldY = resolveCarrierBottomY(target)\n if (targetBottomWorldY !== null) {\n const isHoldingCarrier = ((this as any).components as any[] | undefined)?.some?.(\n (c: any) => c?._transferSlotId === 'forks'\n ) ?? false\n const liftH = numOr((this.state as any).forkLift, 30)\n const approachWorldY = targetBottomWorldY + (isHoldingCarrier ? liftH : 0)\n\n const ro = this._realObject\n const currentForkLift = numOr((this.state as any).forkLiftRT, 0)\n const solver = ro?.solveCarriageHeightForCarrierBaseWorldY\n if (typeof solver === 'function') {\n tween.carriageHeight = solver.call(ro, approachWorldY, currentForkLift)\n } else {\n tween.carriageHeight = approachWorldY\n }\n // Mast 높이 한계 (= crane.state.depth) 초과 시 carriageHeight 가 *clamp* 되어\n // fork 가 *상한까지만* 도달 → 더 높은 cell 은 *한 층 아래에서 포킹*. 데이터\n // 결함 (rack 보다 짧은 crane) 을 silent 무시 안 하도록 명시 경고.\n const mastMax = numOr((this.state as any).depth, Math.max(numOr((this.state as any).width, 200), numOr((this.state as any).height, 200)) * 4)\n if (typeof tween.carriageHeight === 'number' && tween.carriageHeight > mastMax) {\n console.warn(\n `[crane] carriageHeight=${tween.carriageHeight.toFixed(1)} > mast max=${mastMax.toFixed(1)} (state.depth)` +\n ` — fork 가 mast 상한에서 멈춰 target 한 층 아래에서 포킹 가능. crane.state.depth 증가 필요.`\n )\n }\n }\n\n // Duration = *carriage 실 운동 거리 / speed*. 한 cycle 이 이동 거리 비례 시간.\n // - X 운동 거리 = |newCarriagePos - 현재 carriagePosition|\n // - Y 운동 거리 = |tween.carriageHeight - 현재 carriageHeight| (carrier 있는 경우)\n // - 두 운동은 *동시 lerp* → max 거리 만큼 시간 소요.\n // options.duration 명시 시 그 값 우선. 미명시 시 state.speed 또는 default.\n let duration: number\n if (typeof options.duration === 'number') {\n duration = options.duration\n } else {\n const curCP = numOr((this.state as any).carriagePosition, this._canonicalDefault('carriagePosition'))\n const curCH = numOr((this.state as any).carriageHeight, this._canonicalDefault('carriageHeight'))\n const dxRail = Math.abs((tween.carriagePosition as number) - curCP)\n const dyMast = typeof tween.carriageHeight === 'number' ? Math.abs(tween.carriageHeight - curCH) : 0\n const dist = Math.max(dxRail, dyMast)\n const speed =\n (typeof options.speed === 'number' ? options.speed : undefined) ??\n (typeof (this.state as any).speed === 'number' ? (this.state as any).speed : undefined) ??\n 250 // DEFAULT_SPEED — scene units/sec (이전 500 → 사용자 체감 빠름 → 절반)\n duration = speed > 0 ? Math.max(200, (dist / speed) * 1000) : 1500\n }\n this.setState({ status: 'moving' as CraneStatus })\n await this._tween(tween, duration)\n this.setState({ status: 'idle' as CraneStatus })\n }\n\n async engage(\n target: Component,\n kind: 'pick' | 'place',\n _options: MoveOptions = {}\n ): Promise<void> {\n // carriageHeight 는 moveTo 안 X+Y 동시 lerp 에서 처리.\n // engage 가 책임: fork extension → lift / drop → retract.\n const forkLen = numOr((this.state as any).forkLength, 600)\n // liftH — 사용자 설정 `forkLift` (= configured 진폭). 미설정 시 default 30mm.\n // 시뮬 lerp 는 *forkLiftRT* (runtime current) state 에 적용 — `forkLift` 자체\n // 는 *진폭 의미 보존* 위해 안 건드림.\n const liftH = numOr((this.state as any).forkLift, 30)\n\n // Fork side 결정 — target 이 crane 의 어느 *local Z 방향* (cross-rail, fork\n // axis) 인지. things-scene 의 `getWorldPose` 로 양쪽 world pose 산출 후\n // delta 를 crane local frame 으로 inverse-rotate → local Z 부호 = side.\n // pick/place 동일하게 동작 (이전 코드는 carrier=cell.child 케이스에서\n // rack-local vs world 좌표계 혼선으로 pick 시 방향 반대였음).\n let side: 1 | -1 = +1\n try {\n const cranePose = getWorldPose(this)\n const targetPose = getWorldPose(target)\n const dv = targetPose.position.clone().sub(cranePose.position)\n dv.applyQuaternion(cranePose.rotation.clone().invert())\n side = dv.z >= 0 ? +1 : -1\n } catch {\n // fallback — pose 계산 실패 시 +1 (rotation 무관, 의미적으로 안전한 default).\n }\n\n // Animation duration — fork extend/retract 1000ms, lift/lower 600ms.\n // 이전 (500ms / 300ms) 보다 2배 — 시각 자연스러움 강화.\n const D_EXT = 1000\n const D_LIFT = 600\n\n // fork extension target — target 의 local Z 와 _bladeMidZ 매칭. helper 가\n // inverse-solve. mismatch 시 carrier 가 *fork tip 위치 (= local Z 미일치)*\n // 로 jump → 텔레포트 결함. helper 가 정확 일치 보장.\n let extTarget = side * forkLen\n try {\n const cranePose = getWorldPose(this)\n const targetPose = getWorldPose(target)\n const dv = targetPose.position.clone().sub(cranePose.position)\n dv.applyQuaternion(cranePose.rotation.clone().invert())\n const localZ = dv.z\n const solver = (this._realObject as any)?.solveForkExtensionForLocalZ\n if (typeof solver === 'function') {\n const ext = solver.call(this._realObject, localZ)\n if (Number.isFinite(ext)) extTarget = ext\n }\n } catch {\n // fallback — 기존 side * forkLen.\n }\n\n if (kind === 'pick') {\n this.setState({ status: 'loading' as CraneStatus })\n await this._tween({ forkExtension: extTarget }, D_EXT)\n\n // Mid-engage reparent — fork 가 cell 안 도달. carrier 를 fork 위로 *즉시\n // snap* (animated:false). Transfer 객체 통과 → monitor panel 추적.\n const source = (target as any).parent\n if (source) {\n try {\n new Transfer({\n source,\n target: this as unknown as Transferable,\n carrier: target,\n options: { animated: false }\n }).executeSync()\n } catch (e) {\n // Transfer 실패 — carrier 그대로. 후속 Mover.pick receive 가 처리.\n }\n }\n\n await this._tween({ forkLiftRT: liftH }, D_LIFT)\n await this._tween({ forkExtension: 0 }, D_EXT)\n } else {\n this.setState({ status: 'unloading' as CraneStatus })\n // 1. fork extend (cell 위에서 carrier 자리 위로 진입). extTarget = inverse-\n // solved target.local.z 매칭 위치.\n await this._tween({ forkExtension: extTarget }, D_EXT)\n\n // 2. carrier lower — forkLiftRT liftH → 0. carrier 가 cell 바닥 안착.\n await this._tween({ forkLiftRT: 0 }, D_LIFT)\n\n // 3. dispatch — carrier world 위치 = cell 내 attach 위치, jump 없음. Transfer 추적.\n const comps = (this as any).components as any[] | undefined\n const carrier = comps?.find?.((c: any) => c?._transferSlotId === 'forks')\n ?? comps?.[0]\n if (carrier) {\n try {\n new Transfer({\n source: this as unknown as Transferable,\n target: target as unknown as Transferable,\n carrier,\n options: { animated: false }\n }).executeSync()\n } catch (e) {\n // dispatch 실패 — Mover.place 가 후속 처리.\n }\n }\n\n // 4. fork retract — 빈 fork.\n await this._tween({ forkExtension: 0 }, D_EXT)\n }\n }\n\n // ── Domain aliases ────────────────────────────────────────────────────────\n\n /** Fetch a carrier from a rack cell (semantically = pick). */\n fetch(carrier: Component, options?: MoveOptions): Promise<void> {\n return this.pick(carrier, options)\n }\n\n /** Deposit a carrier into a rack cell (semantically = place). */\n deposit(carrier: Component, cell: Component, options?: MoveOptions): Promise<void> {\n return this.place(carrier, cell, options)\n }\n\n // ── Capability-based adjacency discovery ──────────────────────────────────\n\n /**\n * scene 의 모든 SlottedHolder 의 *slot 중에서 crane 의 작업 reach 안에 들어\n * 오는 slot 들* 을 반환. 자동 simulate / WCS-less 시나리오의 enumeration entry.\n *\n * 매칭 알고리즘 (공간 reach 박스):\n * - crane.world center (axis-aligned 가정 — rotation 무시)\n * - 각 slot.anchor.world position 이\n * |x - cx| ≤ width/2 + reachXZ AND |z - cz| ≤ height/2 + reachXZ\n * AND |y - cy| ≤ depth/2 + reachY\n * 범위 안인가\n * - reachXZ = `crane.state.height` (fork forward 폭). reachY = `crane.state.depth`/2.\n *\n * RackGrid 의 *isEmpty aisle 통로 자리에 crane 이 배치* 된 케이스도 자동 cover —\n * 통로 양옆 bay 의 slot anchor world 가 reach 안에 자연히 들어옴.\n *\n * @param opts.includeSelf 자기 자신을 holder 로 포함할지 (default false — crane\n * 은 SlottedHolder 아니지만 안전 차원).\n */\n /**\n * Cycle 단위 cache 없음 — **매 cycle 협의** (capability negotiation 의 본질).\n * crane.carriagePosition 변경 / rack 추가-이동 / 동적 forkLength 등 *runtime\n * 변화 대응*. cost 는 *slotWorldPosition (anchor 0 생성) + canReach (cheap\n * 좌표 비교)* — 매 cycle 호출 부담 작음.\n *\n * 이 field 는 *_oneCycle 사용을 위한 *호출 당 임시 holder grouping** —\n * findAdjacentSlots 결과의 byHolder mapping. caller (_oneCycle) 가 사용 후\n * 폐기.\n */\n private _adjacentByHolder?: Map<SlottedHolder & { state?: any }, Set<string>>\n\n /** Cache 없음 — invalidate 호출도 no-op (호환 차원 keep). */\n invalidateAdjacentSlots(): void {\n this._adjacentByHolder = undefined\n }\n\n /**\n * 자동 detect 결과 cache — *boundHolders 미명시 시* 사용. crane / rack 위치가\n * 정적이라 *1회 detect 후 영구 cache 안전*. 위치/회전/차원 변경 시 invalidate.\n */\n private _autoBoundCache?: Array<SlottedHolder & { state?: any }>\n\n /** Auto bound cache invalidate — crane state 변경 시 호출. */\n invalidateBoundCache(): void {\n this._autoBoundCache = undefined\n }\n\n /**\n * Scene traverse + reach 검사 — 어느 slot 1개라도 reach 안인 holder 들 list.\n * boundHolders 미명시 시 *runtime auto-detect* 결과. crane/rack 정적 위치\n * 가정 — 1회 호출 후 cache.\n */\n detectBoundHolders(): Array<SlottedHolder & { state?: any }> {\n const ro = this._realObject as any\n const obj3d: THREE.Object3D | undefined = ro?.object3d\n if (!obj3d) return []\n const craneWorld = new THREE.Vector3()\n obj3d.getWorldPosition(craneWorld)\n\n const s: any = this.state\n const craneW = typeof s?.width === 'number' && Number.isFinite(s.width) ? s.width : 1000\n const craneH = typeof s?.height === 'number' && Number.isFinite(s.height) ? s.height : 600\n const forkLen: number = typeof s?.forkLength === 'number' && Number.isFinite(s.forkLength)\n ? s.forkLength : craneH * 0.6\n const xHalf = craneW / 2\n const zHalf = forkLen\n\n const root: any = (this as any).root\n if (!root) return []\n const result: Array<SlottedHolder & { state?: any }> = []\n const seen = new Set<any>()\n const visit = (component: any) => {\n if (!component || seen.has(component)) return\n seen.add(component)\n if (component !== this && isSlottedHolder(component)) {\n const holder = component as SlottedHolder & { state?: any }\n const slots = holder.slotIds?.()\n if (slots && slots.length > 0) {\n const getPos = (holder as any).slotWorldPosition?.bind(holder) as\n ((id: string) => { x: number; y: number; z: number } | undefined) | undefined\n // 랙 자동 인식 — *fork 가 닿는 Z 거리* 만 검사. X 는 무관 — 사용자 의도:\n // 크레인 옆 (포크가 닿는 거리) 에 있는 랙은 *X 방향 어디에 있든* 담당.\n // rail 의 실 X 길이 = 그 랙의 X 길이 (자동 정렬 모델링 가정).\n let matched = false\n for (const slotId of slots) {\n let pos: { x: number; y: number; z: number } | undefined\n if (getPos) {\n pos = getPos(slotId)\n } else {\n const anchor = holder.getSlotAttachObject3d(slotId)\n if (anchor) {\n const w = new THREE.Vector3()\n anchor.getWorldPosition(w)\n pos = { x: w.x, y: w.y, z: w.z }\n }\n }\n if (!pos) continue\n if (Math.abs(pos.z - craneWorld.z) <= zHalf) {\n matched = true\n break\n }\n }\n if (matched) result.push(holder)\n }\n }\n const children = (component as any).components\n if (Array.isArray(children)) for (const c of children) visit(c)\n }\n visit(root)\n return result\n }\n\n /**\n * Bound holder instance resolve.\n * 1. boundHolders state 명시 → 그 id list resolve (explicit binding)\n * 2. 미명시 → detectBoundHolders() 1회 + auto-cache (implicit binding,\n * crane / rack 정적 위치 가정)\n *\n * 둘 다 *binding scope* — findAdjacentSlots 가 그 list 만 traverse.\n */\n boundHolderInstances(): Array<SlottedHolder & { state?: any }> {\n const raw = (this.state as any)?.boundHolders\n let ids: string[] = []\n if (typeof raw === 'string') {\n ids = raw.split(',').map(s => s.trim()).filter(s => s.length > 0)\n } else if (Array.isArray(raw)) {\n ids = raw.filter((x: any) => typeof x === 'string' && x.length > 0)\n }\n if (ids.length > 0) {\n // 명시 binding — explicit list resolve\n const root: any = (this as any).root\n if (!root) return []\n const result: Array<SlottedHolder & { state?: any }> = []\n for (const id of ids) {\n const c = typeof root.findById === 'function' ? root.findById(id) : undefined\n if (c && isSlottedHolder(c)) result.push(c as any)\n }\n return result\n }\n // 미명시 — auto-detect cache\n if (this._autoBoundCache === undefined) {\n this._autoBoundCache = this.detectBoundHolders()\n }\n return this._autoBoundCache\n }\n\n findAdjacentSlots(opts: { includeSelf?: boolean } = {}): AdjacentSlot[] {\n const ro = this._realObject as any\n const obj3d: THREE.Object3D | undefined = ro?.object3d\n if (!obj3d) return []\n\n // crane 은 고정 rail 따라 움직임 (회전 없음) — axis-aligned 박스 비교.\n const craneWorld = new THREE.Vector3()\n obj3d.getWorldPosition(craneWorld)\n\n const s: any = this.state\n const craneW = typeof s?.width === 'number' && Number.isFinite(s.width) ? s.width : 1000\n const craneH = typeof s?.height === 'number' && Number.isFinite(s.height) ? s.height : 600\n const forkLen: number = typeof s?.forkLength === 'number' && Number.isFinite(s.forkLength)\n ? s.forkLength : craneH * 0.6\n\n // X reach 정책:\n // - bound holder 명시/auto-detect 시 → *X 무관*. bound 자체가 scope 정의 —\n // bound rack 의 *X 영역 전체* 가 rail 의 실 X 영역. carriage 가 그 X 안\n // 의 모든 bay 까지 자동 도달.\n // - 미bound 시 → state.width 기반 axis-aligned (fallback).\n const boundCandidates = this.boundHolderInstances()\n\n // slotId format = \"{col-or-bay}-{row}-{shelf-or-level}\" (양쪽 holder 동일).\n // 매칭 단위 = (col, row) pair = *last '-' 앞 부분*. row 별로 Z 좌표 다르고\n // crane.fork 의 reach 가 row 마다 도달 여부 다름 → *(col, row) 단위 정밀\n // 매칭*. 통과한 (col, row) 의 *모든 shelves slot* 만 adjacent.\n const bayKeyOf = (slotId: string): string => {\n const i = slotId.lastIndexOf('-')\n return i > 0 ? slotId.substring(0, i) : slotId\n }\n\n // Reach 박스 — *crane mesh 의 실 visual 방향* 따라 검사 (2D state.rotation 무관).\n // rail axis (X) = crane.width / 2 — carriage 도달 범위.\n // perpendicular (Z) = forkLength — fork tip extend.\n // matrixWorld 의 local X axis vector 로 projection — Crane.moveTo 와 동일 식.\n const xHalf = craneW / 2\n const zHalf = forkLen\n obj3d.updateMatrixWorld(true)\n const _mc = obj3d.matrixWorld.elements\n const _axisX = _mc[0], _axisZ = _mc[2]\n const _len = Math.hypot(_axisX, _axisZ)\n const ux = _len > 1e-9 ? _axisX / _len : 1\n const uz = _len > 1e-9 ? _axisZ / _len : 0\n // rail-perpendicular axis (= fork 방향) = rail axis 90° rotated (XZ 평면).\n const px = -uz\n const pz = ux\n\n const root: any = (this as any).root\n if (!root) return []\n\n const result: AdjacentSlot[] = []\n const byHolder = new Map<SlottedHolder & { state?: any }, Set<string>>()\n\n // *binding scope* — boundHolders 명시 시 그 holder 만 traverse (broad scan 0).\n // 미명시 시 scene 전체 traverse fallback (BC, 기존 모델 호환).\n const bound = this.boundHolderInstances()\n const candidates: any[] = bound.length > 0 ? bound : []\n\n const visit = (component: any) => {\n if (!component) return\n if ((opts.includeSelf || component !== this) && isSlottedHolder(component)) {\n const holder = component as SlottedHolder & { state?: any }\n const ids = holder.slotIds?.()\n if (ids && ids.length > 0) {\n // col 별: 모든 row 의 *대표 (shelf=0) slot* 추출 + col 안 모든 id 목록.\n // bay 매칭 시 *어느 row 의 대표 anchor 라도 reach 안* 이면 그 col 전체\n // 매칭 (row 별 z 가 달라도 *crane 의 fork 가 ±Z extend 로 모두 도달*).\n const repsByBay = new Map<string, string[]>()\n const allByBay = new Map<string, string[]>()\n for (const id of ids) {\n const bay = bayKeyOf(id)\n const lastIdx = id.lastIndexOf('-')\n const lastSeg = lastIdx >= 0 ? id.substring(lastIdx + 1) : id\n let allList = allByBay.get(bay)\n if (!allList) { allList = []; allByBay.set(bay, allList) }\n allList.push(id)\n // shelf=0 (또는 level=0) 인 것만 대표\n if (lastSeg === '0') {\n let reps = repsByBay.get(bay)\n if (!reps) { reps = []; repsByBay.set(bay, reps) }\n reps.push(id)\n }\n }\n // bay 가 *대표 없음* (shelf=0 미존재) — fallback: 첫 id 사용\n for (const [bay, allList] of allByBay) {\n if (!repsByBay.has(bay)) repsByBay.set(bay, [allList[0]])\n }\n\n const adjSet = new Set<string>()\n // *holder.slotWorldPosition* 지원 시 *anchor 생성 0* — match 전 단계의\n // 직접 좌표 계산 path. 미지원 holder 는 fallback 으로 getSlotAttachObject3d.\n const getPos = (holder as any).slotWorldPosition?.bind(holder) as\n ((id: string) => { x: number; y: number; z: number } | undefined) | undefined\n\n // X 매칭 정책:\n // - bound holder 존재 시: *X 무관* (bound 자체가 reach scope — rail 의\n // 실 X 영역 = bound rack 의 X 영역. carriage 가 그 전체 X 까지 도달).\n // Z (fork) 만 검사 — fork tip 도달 여부.\n // - 미bound 시: state.width 기반 axis-aligned 박스 (fallback).\n const useBoundScope = boundCandidates.length > 0\n for (const [bay, reps] of repsByBay) {\n let matched = false\n let matchedX = 0, matchedY = 0, matchedZ = 0\n for (const repId of reps) {\n let pos: { x: number; y: number; z: number } | undefined\n if (getPos) {\n pos = getPos(repId)\n } else {\n const anchor = holder.getSlotAttachObject3d(repId)\n if (anchor) {\n const w = new THREE.Vector3()\n anchor.getWorldPosition(w)\n pos = { x: w.x, y: w.y, z: w.z }\n }\n }\n if (!pos) continue\n // *visual rail 의 실제 world 방향* 따라 projection — 2D rotation 매핑 무관.\n // rail-local X = (pos - crane) · rail axis. rail-local Z = (pos - crane) · perp axis.\n const ddx = pos.x - craneWorld.x\n const ddz = pos.z - craneWorld.z\n const railLocal = ddx * ux + ddz * uz\n const perpLocal = ddx * px + ddz * pz\n const xOk = Math.abs(railLocal) <= xHalf\n const zOk = Math.abs(perpLocal) <= zHalf\n if (xOk && zOk) {\n matched = true\n matchedX = pos.x; matchedY = pos.y; matchedZ = pos.z\n break\n }\n }\n if (matched) {\n const all = allByBay.get(bay) ?? []\n const sharedWorld = new THREE.Vector3(matchedX, matchedY, matchedZ)\n // result 의 anchor field 는 *lazy*. 사용처가 *실제 attach 필요* 시\n // holder.getSlotAttachObject3d(slotId) 별도 호출 (그때 lazy 생성).\n // match 검사 자체에선 anchor 0 생성.\n for (const id of all) {\n adjSet.add(id)\n result.push({ holder, slotId: id, anchor: undefined as any, world: sharedWorld })\n }\n }\n }\n if (adjSet.size > 0) byHolder.set(holder, adjSet)\n }\n }\n const children = (component as any).components\n if (Array.isArray(children)) {\n for (const c of children) visit(c)\n }\n }\n // binding scope 우선 — bound 시 그 list 만 visit (broad scan 0). 미명시\n // 시 scene root 부터 fallback traverse.\n if (candidates.length > 0) {\n for (const c of candidates) visit(c)\n } else {\n visit(root)\n }\n // 매 cycle 협의 — cache 없음. _oneCycle 가 *바로 *byHolder 사용 후 폐기*.\n this._adjacentByHolder = byHolder\n return result\n }\n\n // ── 2D rendering ─────────────────────────────────────────────────────────\n\n /**\n * 2D top-down 표현 — 크레인으로 명확히 인식되도록 핵심 부품 그림:\n *\n * - rail (테두리 양쪽 가장자리, dark gray)\n * - twin masts (orange, 옆으로 배치) ← 시각 identity 핵심\n * - carriage (yellow, mast 사이) ← 작은 사각형\n * - forks (yellow, 두 평행선, cross-rail 방향으로 forkLength × extension 비율로 신축)\n * - carrier (lift 됐을 때만, gray 박스 + 들림 표시 ▲)\n *\n * 숨은 축 표현:\n * - carriageHeight (mast Y): 오른쪽 mast 옆 세로 게이지 — fill 비율 = carriageHeight/depth\n * - forkLift (carrier 들기): carrier 가 lift 상태일 때 outline + ▲ 마크\n *\n * 컨벤션: width = rail (X), height = cross-rail (Y, fork 신축 방향).\n * state.rotation 은 canvas 가 처리 (다른 컴포넌트와 동일).\n */\n render(ctx: CanvasRenderingContext2D) {\n const state = this.state as any\n const width = num(state.width, 100)\n const height = num(state.height, 200)\n const left = num(state.left, 0)\n const top = num(state.top, 0)\n\n const depth = num(state.depth, Math.max(width, height) * 4)\n const carriageHeight = clamp(num(state.carriageHeight, 0), 0, depth)\n const forkExtension = num(state.forkExtension, 0) // ± (rail 양쪽 rack)\n // forkLiftRT — *시뮬 runtime current 들림*. *configured 진폭* (state.forkLift)\n // 와 분리. 시뮬 미진행 시 0 (carriage 가 mast 위 carriageHeight 만큼).\n const forkLift = num(state.forkLiftRT, 0)\n\n // carriagePosition: rail-local X (0 ~ width). default = rail center.\n // 사용자 의도 — Crane 본체 (rail) 안 움직이고 carriage assembly 만 X 슬라이드.\n const carriagePosition = clamp(num(state.carriagePosition, width / 2), 0, width)\n const cx = left + carriagePosition // masts/carriage/forks 의 중심 X\n const cy = top + height / 2\n // 적재 여부 — forkLift > 0 (시뮬 중 들어올린 상태) 또는 state.loaded 명시.\n // monitoring 모드는 외부 데이터로 state.loaded 바인딩.\n const carrying = forkLift > 0 || !!state.loaded || !!state.carrying\n\n // 높이 비율 (1F=0 → 최상층=1). carriage / carrier 의 크기 scale 에 공통 사용.\n const heightRatio = depth > 0 ? clamp(carriageHeight / depth, 0, 1) : 0\n const sizeMul = 0.5 + heightRatio * 0.5 // 50% (1F) → 100% (최상층)\n\n const MAST = '#ff7a00' // 주황 — 마스트\n const CARRIAGE_C = '#ffcc00' // 노랑 — carriage shuttle 본체\n const FORK_C = '#a8b0b8' // 은회색 — fork prong (금속 느낌, carriage 와 구분)\n const DARK = '#3a4048'\n // Carrier — 팔레트 갈색 (carriage 노랑 위에서 대비). lift 시 darker + 두꺼운 외곽.\n const CARRIER = forkLift > 0 ? '#7d5530' : '#a08864'\n const CARRIER_LINE = '#3a2a18'\n\n ctx.save()\n\n // 0. Rail footprint — 반투명 회색 fill + 외곽선. 사용자가 board 에서 crane 의\n // *rail 영역* 을 명확히 인식 + 편집 핸들 가능.\n ctx.fillStyle = '#aab0b8'\n ctx.globalAlpha = 0.15\n ctx.fillRect(left, top, width, height)\n ctx.globalAlpha = 1\n ctx.strokeStyle = DARK\n ctx.lineWidth = 1\n ctx.strokeRect(left, top, width, height)\n\n // 1. Rail — 하단 한 줄 (얇은 가이드). 톤 절제 — outer footprint 가 이미 영역 표시.\n const railW = Math.max(1, height * 0.02)\n ctx.fillStyle = DARK\n ctx.globalAlpha = 0.6\n ctx.fillRect(left, top + height - railW, width, railW)\n ctx.globalAlpha = 1\n\n // 2. Twin masts — *carriageWidth 기반* (crane.width 와 분리). rail (= crane.width)\n // 이 넓어져도 carriage assembly 는 *carriageWidth 만큼* 만.\n const carriageW = num(state.carriageWidth, width * 0.1) // default rail 의 10%\n const mastW = Math.max(2.5, carriageW * 0.15)\n const mastSpacing = carriageW * 0.85\n const mastY = top + railW\n const mastH = height - railW * 2\n const mastX1 = cx - mastSpacing / 2 - mastW / 2\n const mastX2 = cx + mastSpacing / 2 - mastW / 2\n ctx.fillStyle = MAST\n ctx.fillRect(mastX1, mastY, mastW, mastH)\n ctx.fillRect(mastX2, mastY, mastW, mastH)\n\n // 2-a. Floor tick marks — mast 위에 N 단계 (예: 5 단) 가로 줄. 층 가늠.\n const numFloors = 5\n ctx.fillStyle = 'rgba(0,0,0,0.25)'\n for (let i = 1; i < numFloors; i++) {\n const tickY = mastY + (mastH * i) / numFloors - 0.5\n ctx.fillRect(mastX1, tickY, mastW, 1)\n ctx.fillRect(mastX2, tickY, mastW, 1)\n }\n\n // 2-b. Carriage 위치 indicator — 마스트 *중심 고정* + *size = carriageHeight 비율*.\n // 1층 (=0): 얇은 선. 최상층 (=depth): 마스트 길이의 100%. 성장/수축 = 상승/하강.\n const indLen = Math.max(2, mastH * heightRatio)\n const indY = mastY + mastH / 2 - indLen / 2\n const indWidth = mastW + 4\n ctx.fillStyle = '#5a3a00' // 어두운 갈색 — orange mast 위에서 강한 대비\n ctx.fillRect(mastX1 - 2, indY, indWidth, indLen)\n ctx.fillRect(mastX2 - 2, indY, indWidth, indLen)\n\n // 3. Carriage deck — 팔레트 1200×800mm aspect 반영. *폭만* sizeMul 적용 (높이감),\n // 길이 (Y) 고정. carrier / fork 모두 이 deck 기준으로 derive.\n const deckW = (mastSpacing - mastW) * sizeMul\n const carriageH = Math.min((mastSpacing - mastW) * 1.3, (height - railW * 2) * 0.55)\n const carriageX = cx - deckW / 2\n const carriageY = cy - carriageH / 2\n ctx.fillStyle = CARRIAGE_C\n ctx.fillRect(carriageX, carriageY, deckW, carriageH)\n\n // 4. Fork — 좌우 균형:\n // - 양쪽 모두 *작은 stub* 항상 표시 (crane 이 양쪽 rack 사이 있는 인상)\n // - extension 부호 (+/-) 에 따라 active 쪽이 추가로 신축\n // - 신축 길이 = |forkExtension| (실제 reach 만큼)\n const stubLen = Math.max(2, carriageH * 0.5)\n // 포크 폭 — deck 의 80%.\n const forkW = deckW * 0.8\n const forkX = cx - forkW / 2\n const extLen = Math.abs(forkExtension)\n const sign = forkExtension >= 0 ? 1 : -1\n ctx.fillStyle = FORK_C\n // 항상 양쪽 stub\n ctx.fillRect(forkX, carriageY - stubLen, forkW, stubLen) // top stub\n ctx.fillRect(forkX, carriageY + carriageH, forkW, stubLen) // bottom stub\n // active 쪽 추가 신축\n if (extLen > 0.5) {\n if (sign > 0) {\n ctx.fillRect(forkX, carriageY + carriageH + stubLen, forkW, extLen)\n } else {\n ctx.fillRect(forkX, carriageY - stubLen - extLen, forkW, extLen)\n }\n }\n\n // 5. Carrier — *팔레트 크기* 정사각형. 신축 시 fork 끝 (cell 안쪽) 에 배치.\n // - extLen > 0: carrier 가 fork 끝 (cell 안) — pallet 이 cell 로 들어가는 인상\n // - retracted (extLen=0): carriage 중심 — transit 자세\n // - forkLift > 0: 진한 갈색 + 두꺼운 outline (들린 상태 시인)\n if (carrying) {\n // 팔레트 — 항상 carriage 의 90% (폭/길이 모두). carriage 가 sizeMul 적용된 폭이라\n // carrier 도 자동으로 sizeMul 반영. 길이는 carriage 길이 고정에 따라 고정.\n const carrW = deckW * 0.9\n const carrH = carriageH * 0.9\n // Carrier 2D 위치 — 3D _bladeMidZ 와 동일 공식 (sign * extLen).\n // extLen=0 → carriage 정중앙. extLen 증가 → cell 방향 으로 진출.\n const offset = extLen\n const carrCenterY = sign > 0\n ? carriageY + carriageH / 2 + offset\n : carriageY + carriageH / 2 - offset\n const carrX = cx - carrW / 2\n const carrY = carrCenterY - carrH / 2\n\n // 들린 상태 — drop shadow 로 *떠 있는* 인상 (forkLift > 0). offset 비율 = lift 강도.\n if (forkLift > 0) {\n const liftMax = Math.max(num(state.forkLift, 30), 20) // configured 진폭\n const liftRatio = clamp(forkLift / liftMax, 0.3, 1) // 최소 30% 표시 (있다는 것만 보이게)\n const shadowOff = Math.max(2, Math.min(carrW, carrH) * 0.14) * liftRatio\n ctx.fillStyle = 'rgba(0, 0, 0, 0.4)'\n ctx.fillRect(carrX + shadowOff, carrY + shadowOff, carrW, carrH)\n }\n\n // Carrier 본체\n ctx.fillStyle = CARRIER\n ctx.fillRect(carrX, carrY, carrW, carrH)\n ctx.strokeStyle = CARRIER_LINE\n ctx.lineWidth = forkLift > 0 ? 1.5 : 0.8\n ctx.strokeRect(carrX, carrY, carrW, carrH)\n }\n\n // Cargo (carrier) 가 fork 위에 얹혀 fork 신축과 함께 이동하므로 그 자체로 방향\n // (loading/unloading) 이 자연 인식. 별도 status 배지 없음.\n\n // (carriageHeight 시각화는 mast 위 dark band + floor ticks 로 통합 — 별도 측면 게이지 제거)\n\n ctx.restore()\n }\n\n // ── Lifecycle — simulate() 자동 시작 ────────────────────────────────────\n\n added(parent: any): void {\n super.added?.(parent)\n\n // state ↔ visual single source of truth. state 미설정 시 _canonicalDefault\n // 로 명시 초기화 — build / _tween / 외부 read 모두 동일 값.\n const init: Record<string, number> = {}\n for (const k of ['carriagePosition', 'carriageHeight', 'forkExtension', 'forkLiftRT']) {\n if (typeof (this.state as any)[k] !== 'number') {\n init[k] = this._canonicalDefault(k)\n }\n }\n if (Object.keys(init).length > 0) this.setState(init)\n\n // state.simulate === true + *view mode* 모두 만족 시만 자동 시작. modeler\n // 모드에서 simulate 진행 시 *_oneCycle 의 obtainCarrier 가 RackGrid 자식 추가\n // + state.data 변경* — 모델 영구 변형 위험. mode 검사로 차단.\n if ((this.state as CraneState).simulate !== true) return\n if (!(this as any).app?.isViewMode) return\n this._startAutoSimulate()\n }\n\n /**\n * Actuator state 의 *canonical default*. state 미설정 시 모든 read 경로\n * (build / _tween / 외부) 가 *동일 값* 보도록.\n *\n * single source 패턴 — visual fallback 과 state fallback 이 *분리* 되어\n * 첫 _tween 시 start 가 visual current 와 어긋나는 jump 결함을 근본 차단.\n */\n _canonicalDefault(key: string): number {\n const state = this.state as any\n const W = numOr(state.width, 100)\n const H = numOr(state.height, 100)\n const D = numOr(state.depth, Math.max(W, H) * 4)\n switch (key) {\n case 'carriagePosition': return W / 2\n case 'carriageHeight': return D * 0.4\n case 'forkExtension':\n case 'forkLiftRT':\n case 'forkLift':\n return 0\n default: return 0\n }\n }\n\n private _startAutoSimulate(): void {\n if (this._simStarted) return\n this._simStarted = true\n // 초기 지연 800~2800ms 사이 random — 여러 crane 이 동기적으로 시작하지 않도록.\n const initialDelay = 800 + Math.random() * 2000\n // prefetch 제거 — 너무 일찍 (rack 의 _realObject 미빌드) 호출 시 0 매칭이\n // cache 됐던 회귀. 0 결과 cache 안 함으로 fix됐지만, prefetch 자체도 불필요\n // (_oneCycle 첫 호출에 자동 cache).\n setTimeout(() => {\n if (this._simAbort || (this.state as CraneState).simulate !== true) return\n this.simulate().catch(e => console.error('[Crane] simulate', e))\n }, initialDelay)\n }\n\n /**\n * state.simulate 변경 시 자동 simulate 시작/중단. application 이 런타임 toggle\n * 가능 (예: editor 에서 simulate off, view 에서 on).\n */\n onchange(after: Record<string, unknown>, before: Record<string, unknown>): void {\n super.onchange(after as any, before as any)\n // carriage 관련 state 변경 시 2D render 명시 invalidate. things-scene 의\n // setState → trigger change 가 render queue 에 자동 등록 못 하는 케이스 방어.\n if (\n 'carriagePosition' in after ||\n 'carriageWidth' in after ||\n 'carriageHeight' in after ||\n 'forkExtension' in after ||\n 'forkLift' in after ||\n 'forkLiftRT' in after\n ) {\n ;(this as any).invalidate?.()\n }\n // crane 또는 rack 의 위치/회전/차원 변경 시 adjacent slot cache + bound\n // holder cache 둘 다 invalidate. boundHolders 명시 변경 시도 bound cache\n // 무관 (명시 우선) — but invalidate 안전.\n if (\n 'left' in after ||\n 'top' in after ||\n 'rotation' in after ||\n 'width' in after ||\n 'height' in after ||\n 'depth' in after ||\n 'forkLength' in after ||\n 'boundHolders' in after\n ) {\n this.invalidateAdjacentSlots()\n this.invalidateBoundCache()\n }\n if ('simulate' in after) {\n if (after.simulate === true) {\n // simulate=true 명시 — *view mode 일 때만 자동 시작*. modeler 모드 시\n // 시작 시 _oneCycle 의 obtainCarrier 가 RackGrid 자식/state.data 변형\n // 위험. _oneCycle 도 매번 isViewMode 재검사 (mode 전환 대응).\n this._simAbort = false\n this._simStarted = false\n if ((this as any).app?.isViewMode) {\n this._startAutoSimulate()\n }\n } else {\n this._simAbort = true\n }\n }\n }\n\n // ── 3D ───────────────────────────────────────────────────────────────────\n\n buildRealObject(): RealObject | undefined {\n return new Crane3D(this)\n }\n\n // ── Random animation (visual smoke test) ─────────────────────────────────\n // things-scene 의 component.animate() (frameClock 기반, pause/speed 대응) 를 사용.\n\n private _simStarted = false\n private _simRunning = false\n private _simAbort = false\n // Rail = crane 의 *로컬 X 축* (state.rotation 적용). simulate 진입 시 1회 계산해서 캐시.\n private _railOriginX = 0\n private _railOriginY = 0\n private _railCos = 1\n private _railSin = 0\n private _railMin = NaN // local-X 축 rail offset min\n private _railMax = NaN // local-X 축 rail offset max\n private _targetSide = 1 // +Z (fork +Z 로 뻗어야 하나) / -Z\n\n /**\n * Main loop — 통합 처리.\n *\n * 1. dispatcher 의 명시 작업 take → execute (priority 큰 작업 우선)\n * 2. dispatcher 작업 없음 + state.simulate=true → 기존 random fallback (_oneCycle)\n * 3. 둘 다 없음 → longer idle (dispatcher 작업 enqueue 대기)\n *\n * Phase Z 통합 — 사용자 application 의 `holder.putaway / picking` 호출이 즉시 자연\n * 처리. simulate=true 시 큐 비면 random visual smoke 도 유지. 작업 사이 자연 idle.\n */\n async simulate(): Promise<void> {\n if (this._simRunning) return\n this._simRunning = true\n this._simAbort = false\n try {\n this._initRailRange()\n while (!this._simAbort) {\n // Modeling 모드 진입 시 즉시 중단\n if (!(this as any).app?.isViewMode) {\n this._simAbort = true\n break\n }\n\n // 1. Dispatcher 의 명시 작업 우선 take\n const dispatcher = findDispatcher(this as any)\n const ticket = dispatcher?.takeNextFor(this as any) ?? null\n if (ticket) {\n await this._executeTicket(ticket, dispatcher!)\n // 작업 사이 짧은 idle — 명시 작업 중심 처리 → 다음 작업 빠르게\n await new Promise(r => setTimeout(r, 200 + Math.random() * 600))\n continue\n }\n\n // 2. Dispatcher 작업 없음 — state.simulate 켜져 있으면 random fallback\n if ((this.state as CraneState).simulate === true) {\n await this._oneCycle()\n continue\n }\n\n // 3. simulate OFF + 큐 비어있음 — 작업 들어오기 기다림. 긴 idle.\n await new Promise(r => setTimeout(r, 500 + Math.random() * 2500))\n }\n } finally {\n this._simRunning = false\n }\n }\n\n /**\n * Dispatcher 가 할당한 ticket 처리. lifecycle:\n * assigned (이미 takeNextFor 가 set) → in_progress → completed / failed\n *\n * 흐름:\n * 1. request.from / to 를 resolve (string id → SlotTarget, SlotTarget 그대로 등)\n * 2. carrier obtain — request.carrier 명시 시 그것, 미명시 시 from.holder.obtainCarrier\n * 3. pickAndPlace(carrier, dest)\n * 4. ticket status notify\n *\n * 실패 처리:\n * - target resolve 실패 → failed (resolve-target)\n * - carrier obtain 실패 → failed (no-carrier)\n * - pickAndPlace throw → failed (그 error)\n */\n private async _executeTicket(ticket: TransferTicket, dispatcher: Dispatcher): Promise<void> {\n const req = ticket.request\n try {\n dispatcher.notifyInProgress?.(ticket as any) ?? (ticket as any)._setStatus('in_progress')\n\n // resolve source / dest\n const source = resolveTransferTarget(req.from, dispatcher)\n const dest = resolveTransferTarget(req.to, dispatcher)\n if (!source || !dest) {\n const err = new Error('resolve-target')\n dispatcher.notifyFailed?.(ticket as any, err) ?? (ticket as any)._setStatus('failed', { error: err })\n return\n }\n\n // carrier obtain — 명시 carrier 우선\n let carrier: Component | null = req.carrier ?? null\n if (!carrier) {\n // source 가 SlotTarget — holder.obtainCarrier(slotId)\n const holder = (source as any).holder as SlottedHolder | undefined\n const slotId = (source as any).slotId as string | undefined\n if (holder && slotId) {\n carrier = holder.obtainCarrier(slotId) ?? null\n }\n }\n if (!carrier) {\n const err = new Error('no-carrier')\n dispatcher.notifyFailed?.(ticket as any, err) ?? (ticket as any)._setStatus('failed', { error: err })\n return\n }\n\n // pickAndPlace\n await this.pickAndPlace(carrier, dest as Component)\n\n // 성공\n dispatcher.notifyCompleted?.(ticket as any) ?? (ticket as any)._setStatus('completed')\n } catch (e) {\n const err = e instanceof Error ? e : new Error(String(e))\n dispatcher.notifyFailed?.(ticket as any, err) ?? (ticket as any)._setStatus('failed', { error: err })\n }\n }\n\n /**\n * state.target bbox 를 crane 의 *로컬 X 축* 으로 projection 해서 rail range 1회 계산.\n * Rotation 적용된 crane 의 local X (= rail) 방향으로 움직이도록 cos/sin 캐시.\n */\n private _initRailRange(): void {\n this._railMin = this._railMax = NaN\n\n // simulate cycle 의 random pickAndPlace range — crane 의 parent 컨테이너\n // (= 보통 rack 또는 board) 의 bbox 를 기준으로. parent 가 top-level\n // (root/model-layer) 이면 bbox 의미 없음 → skip.\n const root = (this as any).root\n const parent = (this as any).parent\n let target: any = null\n if (parent && parent !== root && (parent.state as any)?.width > 0) {\n target = parent\n }\n if (!target) return\n\n const tState = target.state ?? {}\n const tl = numOr(tState.left, 0)\n const tt = numOr(tState.top, 0)\n const tw = numOr(tState.width, 0)\n const th = numOr(tState.height, 0)\n if (tw <= 0 || th <= 0) return\n\n const W = numOr((this.state as any).width, 100)\n const H = numOr((this.state as any).height, 100)\n const rotation = numOr((this.state as any).rotation, 0)\n const cos = Math.cos(rotation)\n const sin = Math.sin(rotation)\n\n // Rail origin = crane 의 현재 canvas center. 이 점에서 local X 방향으로 ±rail offset.\n this._railOriginX = numOr((this.state as any).left, 0) + W / 2\n this._railOriginY = numOr((this.state as any).top, 0) + H / 2\n this._railCos = cos\n this._railSin = sin\n\n // Target bbox 4 corner 를 crane local frame 으로 projection.\n // local X (rail) = dx*cos + dy*sin\n // local Z (aisle) = -dx*sin + dy*cos\n const corners = [\n { x: tl, y: tt },\n { x: tl + tw, y: tt },\n { x: tl, y: tt + th },\n { x: tl + tw, y: tt + th }\n ]\n let minRail = Infinity\n let maxRail = -Infinity\n let aisleSum = 0\n for (const c of corners) {\n const dx = c.x - this._railOriginX\n const dy = c.y - this._railOriginY\n const rail = dx * cos + dy * sin\n const aisle = -dx * sin + dy * cos\n if (rail < minRail) minRail = rail\n if (rail > maxRail) maxRail = rail\n aisleSum += aisle\n }\n // Crane 자체 W 만큼 안쪽으로 좁혀 — crane center 가 [minRail+W/2, maxRail-W/2] 안에\n // 있으면 crane 전체가 target bbox 안 (local X 방향).\n this._railMin = minRail + W / 2\n this._railMax = Math.max(this._railMin, maxRail - W / 2)\n this._targetSide = aisleSum >= 0 ? +1 : -1\n }\n\n stopSimulate(): void {\n this._simAbort = true\n // 진행 중인 animate() controller 도 즉시 정지 — onComplete 가 호출되어 _tween Promise\n // 가 resolve → simulate() while 루프가 다음 반복에서 _simAbort 보고 종료. 이걸로\n // 루프 stack 의 strong ref 해소, frameClock subscription 해제.\n const ctrl = (this as any)._animate\n if (ctrl && typeof ctrl.stop === 'function') {\n try { ctrl.stop() } catch {}\n }\n }\n\n /**\n * 컴포넌트 dispose 시 (보드 종료, scene reload 등) 진행 중 simulate 루프와 animate\n * subscription 을 정리. 미정리 시 루프의 await stack 이 component 를 strong reference\n * 로 잡아 GC 안 됨 + frameClock 콜백 살아남음.\n */\n dispose(): void {\n this.stopSimulate()\n super.dispose?.()\n }\n\n /**\n * 1 cycle = *capability 기반 random transfer*.\n *\n * 1. findAdjacentSlots() — scene 의 인접 SlottedHolder 의 slot 들\n * 2. occupied / empty 분리 — hasCarrierAt / canReceiveAt\n * 3. random source / dest 선택 — 같은 slot 자가 transfer 회피\n * 4. obtainCarrier + pickAndPlace — Mover.pickAndPlace 가 pick + place 진행\n *\n * 인접 slot / occupied / empty 어느 하나라도 비어있으면 짧은 delay 후 next.\n * 진짜 carrier 가 fork 위 visible 로 이동 — 시각 simulate 가 *동시에 *진짜\n * 데이타 전환* 도 수행 (Plan A: 데이타 → 실물 → 데이타 atomic 전환).\n */\n private async _oneCycle(): Promise<void> {\n // *Modeling 모드 진입 시 즉시 정지* — runtime 에서 mode 전환 (view → modeler)\n // 대응. obtainCarrier / pickAndPlace 가 modeler 에서 발동하면 *RackGrid 자식\n // 추가 + state.data 변경* = 모델 영구 변형. 매 cycle 검사 안전.\n if (!(this as any).app?.isViewMode) {\n this._simAbort = true\n return\n }\n this.findAdjacentSlots() // cache 채우기 (already-cached 면 no-op)\n const byHolder = this._adjacentByHolder\n if (!byHolder || byHolder.size === 0) {\n await new Promise(r => setTimeout(r, 800 + Math.random() * 800))\n return\n }\n\n // holder 단위로 *occupiedSlotIds / emptySlotIds* 한 번에 조회 + adjacent set\n // 와 교집합. holder 내부 sweep (records + child) 이라 *slot.length × records.\n // length* iteration 없이 *records + children* 1 회 sweep.\n // holder.occupiedSlotIds / emptySlotIds 에 *adjacent set 멤버 predicate* 전달\n // — holder 가 sweep 중 즉시 reject. crane 측은 *holder 결과 그대로 사용*.\n const occupied: { holder: SlottedHolder & { state?: any }; slotId: string }[] = []\n const empty: { holder: SlottedHolder & { state?: any }; slotId: string }[] = []\n for (const [holder, adjSet] of byHolder) {\n const inAdj = (id: string) => adjSet.has(id)\n for (const id of holder.occupiedSlotIds(inAdj)) occupied.push({ holder, slotId: id })\n for (const id of holder.emptySlotIds(inAdj)) empty.push({ holder, slotId: id })\n }\n\n if (occupied.length === 0 || empty.length === 0) {\n await new Promise(r => setTimeout(r, 500 + Math.random() * 800))\n return\n }\n\n const source = occupied[Math.floor(Math.random() * occupied.length)]\n\n // dest 선택 — source 와 같은 (holder, slotId) 회피. attempts 제한.\n let dest = empty[Math.floor(Math.random() * empty.length)]\n let attempts = 0\n while (dest.holder === source.holder && dest.slotId === source.slotId && attempts < 10) {\n dest = empty[Math.floor(Math.random() * empty.length)]\n attempts++\n }\n if (dest.holder === source.holder && dest.slotId === source.slotId) {\n await new Promise(r => setTimeout(r, 500))\n return\n }\n\n try {\n const carrier = source.holder.obtainCarrier(source.slotId)\n if (!carrier) {\n await new Promise(r => setTimeout(r, 400))\n return\n }\n const destTarget = dest.holder.slotTargetAt(dest.slotId)\n await this.pickAndPlace(carrier, destTarget as unknown as Component)\n } catch (e) {\n // 한 cycle 실패해도 simulate 루프는 계속. 다음 cycle 에서 다른 source/dest 시도.\n // (Mover.pickAndPlace 내부 rollback 이 carrier 복귀 시도함.)\n }\n\n // 사이클 사이 idle — 여러 crane 의 phase 자연 분산 (= 동시 동기화 회귀 차단).\n // 범위 확장 (500~3500ms) — duration 거리 비례와 결합되어 cycle 총 시간 다양.\n await new Promise(r => setTimeout(r, 500 + Math.random() * 3000))\n }\n\n /**\n * frameClock 기반 tween — things-scene 의 표준 `Component.animate()` 사용.\n * frameClock.simTime 진행 (view mode + scene 활성) 시에만 step 호출 → modeler\n * 또는 paused 시 자동 정지. scene.simulationSpeed 도 자동 대응.\n */\n private _tween(targets: Record<string, any>, duration: number): Promise<void> {\n const start: Record<string, number> = {}\n for (const k of Object.keys(targets)) {\n if (k === 'status') continue\n const v = (this.state as any)[k]\n start[k] = typeof v === 'number' && Number.isFinite(v) ? v : this._canonicalDefault(k)\n }\n if (typeof targets.status === 'string') {\n this.setState({ status: targets.status })\n }\n return new Promise<void>(resolve => {\n let resolved = false\n const finish = () => {\n if (resolved) return\n resolved = true\n resolve()\n }\n const controller = (this as any).animate({\n duration,\n ease: 'inout',\n delta: 'quad',\n step: (dx: number) => {\n const update: Record<string, number> = {}\n for (const k of Object.keys(start)) {\n const tgt = targets[k]\n if (typeof tgt !== 'number') continue\n update[k] = start[k] + (tgt - start[k]) * dx\n }\n this.setState(update as any)\n },\n onComplete: finish\n })\n controller.start()\n })\n }\n}\n\nfunction resolveCarrierDepth(c: Component): number {\n const eff = (c as any)._realObject?.effectiveDepth\n if (typeof eff === 'number' && Number.isFinite(eff)) return eff\n return numOr((c as any)?.state?.depth, 0)\n}\n\n\n/**\n * Target 의 *world bottom Y* — fork blade 가 위치해야 할 높이.\n *\n * `getWorldPose(c).position.y` 는 *center Y*. fork 는 carrier 의 *바닥* (pallet\n * pocket 진입 면) 에 위치해야 함 → center 에서 depth/2 만큼 빼서 bottom.\n *\n * `effectiveDepth` 는 RealObject 가 자동 계산한 실제 3D Y 키. 미가용 시 state.\n * depth fallback.\n */\nfunction resolveCarrierBottomY(c: Component): number | null {\n if (!c) return null\n try {\n const pose = getWorldPose(c)\n const centerY = pose?.position?.y\n if (typeof centerY !== 'number' || !Number.isFinite(centerY)) return null\n const ro = (c as any)._realObject\n const eff = ro?.effectiveDepth\n const depth = typeof eff === 'number' && Number.isFinite(eff)\n ? eff\n : numOr((c as any)?.state?.depth, 0)\n return centerY - depth / 2\n } catch {\n return null\n }\n}\n\nfunction numOr(v: unknown, dflt: number): number {\n return typeof v === 'number' && Number.isFinite(v) ? v : dflt\n}\n\n// ── 2D render helpers ────────────────────────────────────────────────────\nfunction num(v: unknown, dflt: number): number {\n return typeof v === 'number' && Number.isFinite(v) ? v : dflt\n}\n\nfunction clamp(v: number, min: number, max: number): number {\n return v < min ? min : v > max ? max : v\n}\n\n/** \"#rrggbb\" 또는 \"name\" 색에 alpha 적용. 실패 시 fallback rgba. */\nfunction withAlpha(color: string, alpha: number): string {\n // \"#rrggbb\" 형식만 지원 — name color 는 rgba 직접 변환 못해서 그대로 사용\n if (color && color[0] === '#' && color.length === 7) {\n const r = parseInt(color.slice(1, 3), 16)\n const g = parseInt(color.slice(3, 5), 16)\n const b = parseInt(color.slice(5, 7), 16)\n return `rgba(${r},${g},${b},${alpha})`\n }\n return color\n}\n"]}
@@ -3,8 +3,10 @@ export declare class Pallet3D extends RealObjectGroup {
3
3
  build(): void;
4
4
  /** Wood EUR-style: 7 top slats + 3 stringers + 5 bottom slats. */
5
5
  private buildWood;
6
+ private getWoodGeometries;
6
7
  /** Plastic molded: solid top deck + ribbed underside / feet. */
7
8
  private buildPlastic;
9
+ private getPlasticGeometries;
8
10
  updateDimension(): void;
9
11
  onchange(after: Record<string, unknown>, before: Record<string, unknown>): void;
10
12
  updateAlpha(): void;