# Procedural Demo Routing Integration
Milestone 4 now exposes the procedural animation lab as a mounted application route instead of a detached demo page.
## Mounted routes
The route adapter in `src/routes/proceduralDemoRoutes.tsx` recognises:
- `/procedural-demos`
- `/procedural-demos/:machineId`
- `/procedural-demo/:machineId`
- `/viewer/:machineId` when `machineId` is one of the procedural demo IDs
- `/machines/:machineId` when `machineId` is one of the procedural demo IDs
- `/machines/procedural/:machineId`
The current `src/App.tsx` mounts `ProceduralDemoPage` for machine routes and renders a premium catalogue landing view for `/`, `/catalogue`, `/catalog`, and `/procedural-demos`.
## Route utilities
Use these helpers when integrating with a different router shell:
```tsx
import {
buildProceduralDemoPath,
matchProceduralDemoRoute,
ProceduralDemoRouteOutlet,
} from './routes/proceduralDemoRoutes';
const href = buildProceduralDemoPath('four-stroke-petrol-engine');
const match = matchProceduralDemoRoute(location.pathname, location.search);
```
`ProceduralDemoRouteOutlet` is router-neutral and can be embedded in a legacy shell without adding `react-router-dom`:
```tsx
}
/>
```
For React Router, mount `ProceduralDemoPage` directly:
```tsx
} />
} />
```
## Direct typed imports
`ProceduralDemoExperience` now imports the catalogue directly:
```ts
import {
getDefaultProceduralDemoId,
getProceduralDemoMachine,
listProceduralDemoMachines,
requireProceduralDemoMachine,
} from './proceduralDemoCatalog';
```
There is no CommonJS `require()` indirection in the runtime path. The catalogue uses namespace imports for the eight procedural machine modules and normalises their exported definitions, scene components, animation modules, part metadata, engineering facts, and guided tours.
## Shareable state
The viewer updates the URL with:
- `rpm`
- `ts`
- `explode`
- `wire`
- `labels`
- `section`, `axis`, `cut`
- `selected`
- `hidden`
- `opacity`
- `cam`
- `target`
Example:
```text
/procedural-demos/wankel-rotary-engine?rpm=1200&ts=1.4&explode=0.8&wire=1&selected=rotor
```
The copy-link button emits an absolute URL with the same encoded view state.