# 5.15 labs

> Contract 2.0.0 · package sha256 `a857eca95b35921109faf997094bb4192f12527d9d0fcd4be7e97f06425bad6e` · generated from `examples/section-5/5.15-labs.ts` by `services/onsite-scripter/scripts/build-contract-docs.mjs`; edit the source, not this file.

Imports: values (`has`, `validate`, the `Holo*Error` classes, the pure helpers) from `@holostep-configurators/runtime-client`, types from `@holostep-configurators/runtime-client/contract`, `/math` and `/testing` names from those entries; `boot` from the runtime module the root's `loadRuntimeAtFloor` resolves to. A type your page defines is your app's: declare it there, never import it from the package.

```ts
import type { GeometryData, Session } from '@holostep-configurators/runtime-client/contract';
declare const session: Session;
declare const signal: AbortSignal;
declare const moduleId: string;                                     // the placed module's nodeId
declare const surface: { widthM: number; heightM: number };         // app data: the wrap's size on the door
declare function buildPanel(src: readonly GeometryData[], surface: { widthM: number; heightM: number }): {
  position: Float32Array; index: Uint32Array; uv0: Float32Array; joints: Uint16Array; weights: Float32Array };
const src = await session.labs.geometry.read({ node: moduleId, name: 'door' }, ['position', 'index', 'joints', 'weights'], { from: 'authored' });
const panel = buildPanel(src, surface);               // app code: positions in the door's bind space, uv0, joints and weights
const wrap = session.collection('wrap', { signal });
await wrap.set({ items: [{ key: 'panel', kind: 'mesh', shape: { kind: 'mesh', position: panel.position, index: panel.index, uvs: [panel.uv0] } }] });
await session.labs.skin(wrap.part('panel'),           // column vertices carry weights 0,0,0,0: rigid to the model's root
  { node: moduleId, skeletonOf: 'door', joints: panel.joints, weights: panel.weights });
```

Back to [the examples](README.md) · [llms.txt](../llms.txt)
