# Offene Punkte — bei jedem Start prüfen und abhaken

Keine offenen Punkte.

jq -Rs '{systemMessage: ., hookSpecificOutput:{hookEventName:"SessionStart", additionalContext: .}}' /Users/marcus.hinz/claude-projects/robotunits/OFFENE-PUNKTE.md


# Offene Punkte — bei jedem Start prüfen und abhaken

Keine offenen Punkte.


ok -- ein Problem mit den Assets
Wiur bekommen die Assets erst später
Können wir die vorhanden so anpassen - oder alte nehmen - dass Positionieren rechts und lkinks wiederr möglich ist
dann können wir mit der Geko Integration weiter machen


CronCreate CronDelete CronList DesignSync EnterPlanMode EnterWorktree ExitPlanMode ExitWorktree Monitor NotebookEdit PushNotification RemoteTrigger SendMessage TaskCreate TaskGet TaskList TaskOutput TaskStop TaskUpdate WebFetch WebSearch


claude claude-code-guide Explore general-purpose Plan statusline-setup

- claude: Catch-all for any task that doesn't fit a more specific agent. FleetView's default when no agent name is typed. (Tools: *)

- claude-code-guide: Use this agent when the user asks questions ("Can Claude...", "Does Claude...", "How do I...") about: (1) Claude Code (the CLI tool) - features, hooks, slash commands, MCP servers, settings, IDE integrations, keyboard shortcuts; (2) Claude Agent SDK - building custom agents; (3) Claude API (formerly Anthropic API) - API usage, tool use, Anthropic SDK usage. **IMPORTANT:** Before spawning a new agent, check if there is already a running or recently completed claude-code-guide agent that you can continue via SendMessage. (Tools: Bash, Read, WebFetch, WebSearch)

- Explore: Read-only search agent for broad fan-out searches — when answering means sweeping many files, directories, or naming conventions and you only need the conclusion, not the file dumps. It reads excerpts rather than whole files, so it locates code; it doesn't review or audit it. Specify search breadth: "medium" for moderate exploration, "very thorough" for multiple locations and naming conventions. (Tools: All tools except Agent, Artifact, ExitPlanMode, Edit, Write, NotebookEdit)

- general-purpose: General-purpose agent for researching complex questions, searching for code, and executing multi-step tasks. When you are searching for a keyword or file and are not confident that you will find the right match in the first few tries use this agent to perform the search for you. (Tools: *)

- Plan: Software architect agent for designing implementation plans. Use this when you need to plan the implementation strategy for a task. Returns step-by-step plans, identifies critical files, and considers architectural trade-offs. (Tools: All tools except Agent, Artifact, ExitPlanMode, Edit, Write, NotebookEdit)

- statusline-setup: Use this agent to configure the user's Claude Code status line setting. (Tools: Read, Edit)


- git-sync: Commit + Push aller persistent konfigurierten Projekt-Repos
- deep-research: Deep research harness — fan-out web searches, fetch sources, adversarially verify claims, synthesize a cited report. - When the user wants a deep, multi-source, fact-checked research report on any topic. BEFORE invoking, check if the question is specific enough to research directly — if underspecified (e.g., "what car to buy" without budget/use-case/region), ask 2-3 clarifying questions to narrow scope. Then pass the refined question as args, weaving the answers in.
- dataviz: Use this skill whenever you are about to create ANY chart, graph, plot, dashboard, or data visualization, in ANY output medium — an HTML or React artifact, inline SVG, plotting code in any library (matplotlib, plotly, d3, Recharts, …), an image/PNG you will render and upload, or a chart shared into Slack. Read it BEFORE writing the first line of chart code, choosing chart colors, building a stat tile / meter / KPI row, or laying out a dashboard. Produces visualizations that read as one system — elegant, accessible, consistent in light and dark — using a brand-neutral placeholder palette you swap for your own. Teaches a design-system-agnostic method: a form heuristic, a color formula with a runnable validator, mark specs, and interaction rules. A validated default palette is documented in `references/palette.md` — swap that file's values for your brand's. Triggers on: "chart", "graph", "plot", "data viz", "visualization", "dashboard", "analytics", "visualize data", "categorical colors", "sequential / diverging palette", "stat tile", "sparkline", "heatmap", "legend", "axis", "tooltip", "chart colors", "color by series".
- artifact-design: Design guidance and fundamentals for Artifacts.
- update-config: Use this skill to configure the Claude Code harness via settings.json. Automated behaviors ("from now on when X", "each time X", "whenever X", "before/after X") require hooks configured in settings.json - the harness executes these, not Claude, so memory/preferences cannot fulfill them. Also use for: permissions ("allow X", "add permission", "move permission to"), env vars ("set X=Y"), hook troubleshooting, or any changes to settings.json/settings.local.json files. Examples: "allow npm commands", "add bq permission to global settings", "move permission to user settings", "set DEBUG=true", "when claude stops show X". For simple settings like theme/model, suggest the /config command.
- keybindings-help: Use when the user wants to customize keyboard shortcuts, rebind keys, add chord bindings, or modify ~/.claude/keybindings.json. Examples: "rebind ctrl+s", "add a chord shortcut", "change the submit key", "customize keybindings".
- verify: Verify that a code change actually does what it's supposed to by exercising it end-to-end and observing behavior — drive the affected flow, not just tests or typecheck. Run before committing nontrivial changes; bootstraps this repo's project verify skill if none exists yet. Don't invoke it on a diff that only touches tests, docs, or other code with no runtime surface to drive (a change to product source always has one) — there's nothing to observe.
- code-review: Review the current diff for correctness bugs and reuse/simplification/efficiency cleanups at the given effort level (low/medium: fewer, high-confidence findings; high→max: broader coverage, may include uncertain findings; ultra: deep multi-agent review in the cloud). Pass --comment to post findings as inline PR comments, or --fix to apply the findings to the working tree after the review.
- simplify: Review the changed code for reuse, simplification, efficiency, and altitude cleanups, then apply the fixes. Quality only — it does not hunt for bugs; use /code-review for that.
- fewer-permission-prompts: Scan your transcripts for common read-only Bash and MCP tool calls, then add a prioritized allowlist to project .claude/settings.json to reduce permission prompts.
- loop: Run a prompt or slash command on a recurring interval (e.g. /loop 5m /foo). Omit the interval to let the model self-pace. - When the user wants to set up a recurring task, poll for status, or run something repeatedly on an interval (e.g. "check the deploy every 5 minutes", "keep running /babysit-prs"). Do NOT invoke for one-off tasks.
- schedule: Create, update, list, or run scheduled cloud agents (routines) that execute on a cron schedule. - When the user wants to schedule a recurring cloud agent, set up automated tasks, create a cron job for Claude Code, or manage their scheduled agents/routines. Also use when the user wants a one-time scheduled run ("run this once at 3pm", "remind me to check X tomorrow").
- claude-api: Reference for the Claude API / Anthropic SDK — model ids, pricing, params, streaming, tool use, MCP, agents, caching, token counting, model migration.
TRIGGER — read BEFORE opening the target file; don't skip because it "looks like a one-liner" — whenever: the prompt names Claude/Anthropic in any form (Claude, Anthropic, Fable, Opus, Sonnet, Haiku, `anthropic`, `@anthropic-ai`, `claude-*`, `us.anthropic.*`, `[1m]`); the user asks about an LLM (pricing/model choice/limits/caching) — never answer from memory; OR the task is LLM-shaped with provider unstated (agent/MCP/tool-definition/multi-agent/RAG/LLM-judge/computer-use; generate/summarize/extract/classify/rewrite/converse over NL; debugging refusals/cutoffs/streaming/tool-calls/tokens).
SKIP only when another provider is being worked on (overrides all triggers): OpenAI/GPT/Gemini/Llama/Mistral/Cohere/Ollama named in the query; OR `grep -rE 'openai|langchain_openai|google.generativeai|genai|mistralai|cohere|ollama'` over the project hits (run this grep FIRST if no provider named — don't Read the file).
- run: Launch and drive this project's app to see a change working. Use when asked to run, start, or screenshot the app, or to confirm a change works in the real app (not just tests). First looks for a project skill that already covers launching the app; otherwise falls back to built-in patterns per project type (CLI, server, TUI, Electron, browser-driven, library).
- init: Initialize a new CLAUDE.md file with codebase documentation
- review: Review a GitHub pull request; for your working diff use /code-review
- security-review: Complete a security review of the pending changes on the current branch

git-sync deep-research dataviz artifact-design update-config keybindings-help verify code-review simplify fewer-permission-prompts loop schedule claude-api run init review security-review


<system-reminder>This memory is 8 days old. Memories are point-in-time observations, not live state — claims about code behavior or file:line citations may be outdated. Verify against current code before asserting as fact.</system-reminder>
1	---
2	name: fire-visual-placement-mode
3	description: "fire-visual Placement-Mode (snap-to-point) — Architektur, Settings, Algorithmus, DropPoints, Commands; Pfade im threed/interaction- und threed/pmi-Modul"
4	metadata:
5	  node_type: memory
6	  type: project
7	  originSessionId: 733f7054-ac76-49cd-ba04-516ef015d4f3
8	---
9
10	Projekt `fire-visual` (`~/projects/fire-visual`, erlaubter Ordner). Placement-Mode = snap-to-point-Platzierung eines Subjects über Drag-Points/Drop-Points. Teil des Moduls `@fire-visual/interaction`.
11
12	## Pfade
13	- Mode: `threed/interaction/module/src/interactionMode/placementMode.ts`
14	- Verdrahtung/Command: `threed/interaction/module/src/feature/interactionFeature.ts` (ab Zeile 259)
15	- Options-Typen: `threed/interaction/module/src/options/modeOptions.ts`
16	- Modul-Doku: `threed/interaction/MODULE.md`
17	- Test: `threed/interaction/module/tests/placementMode.test.ts`
18	- DropPoint-Implementierungen (PMI): `threed/pmi/module/src/dropPoint/{pmiDropPoint,planeDropPoint,pointDropPoint,lineDropPoint}.ts`
19	- DropPoint-Factory: `threed/pmi/module/src/component/pmiComponent.ts` → `getDropPoint()` (Zeile 422)
20
21	## Grundbegriffe
22	- **Subject**: das zu platzierende Objekt (`Handle`).
23	- **Drag-Point**: Punkt am Subject (lokaler `transform: Matrix4_4`), an dem „angefasst" wird. Visualisiert als Kugel (Sphere). Aktiv = gelb, inaktiv = blau.
24	- **Drop-Point**: Ziel-Snap-Geometrie in der Szene; liefert über `assessRay` eine Bewertung. Implementiert Interface `DropPoint`.
25	- **activeDragPointIndex**: aktiver Drag-Point; `-1` = „alle Drag-Points" (nur erlaubt wenn `allowAllDragPoints !== false`). Start: `-1`, oder `0` falls `allowAllDragPoints === false`.
26
27	## PlacementModeSettings
28	- `camera: CameraComponent`, `subject: Handle`
29	- `dragPoints[]`: je `{ transform, dropPoints: Partial<DropPointProvider>[], selector? }`
30	- `defaultCursorTransform?` (Fallback = `dragPoints[0].transform`)
31	- `allowAllDragPoints?` (Default true) — false: Index -1 verboten, Cycling hält immer einen konkreten DP aktiv
32	- `allowDragPointCycling?` (Default true) — false: User kann aktiven DP nicht ändern, „alle DP" bleibt aktiv
33	- `maxJumpDistance?` — überschreibt globalen Wert aus `ModeOptionProvider`
34
35	## Globale Optionen (ModeOptionProvider.options.placement, Typ PlacementModeOptions)
36	`maxJumpDistance`, `highlightColor` (Default Color.yellow), `dragPointActiveColor` (Default yellow), `dragPointInactiveColor` (Default blue), `dragPointRadius` (Default 0.1). Plus `gizmoScale` (Default 1) skaliert Kugelradius.
37
38	## Algorithmus processInput(input) je Frame
39	Input: `pointerNormalizedPosition`, `nextDragPoint`, `previousDragPoint`, `interactionClick`.
40	1. Ohne Pointer/Camera → false.
41	2. **Grab-Gating**: Rising edge von `interactionClick` setzt `_grabActive = true`. Solange nicht grab-aktiv: nur prevClick merken, return true (Subject bewegt sich nicht).
42	3. Cycling: bei `nextDragPoint`/`previousDragPoint` Index zyklen (wenn Cycling erlaubt).
43	4. Alle Drop-Point-Visualisierungen zurücksetzen (erst `false`+Highlight null), dann die zum aktiven DP gehörenden aktivieren (Index -1 ⇒ alle).
44	5. Ray von Kamera durch Pointer; Schnitt mit XZ-Ebene (`Plane` durch Ursprung, Normale up) → `intersectionPoint`.
45	6. Für jeden aktiven Drag-Point × dessen Drop-Points: Ray um `dropPoint.predictDragPointRotation(ray) * (dragPoint.transform⁻¹ * cursorTransform) * 0` versetzen, dann `dropPoint.assessRay(offsetRay)` → RayAssessment.
46	7. Beste Assessment über `betterRayAssessment`: kleinste `jumpDistance`; bei Gleichstand (Toleranz 0.05) kleinste `rayDistance`.
47	8. Wenn `best.jumpDistance < maxJumpDistance`: Drop-Point highlighten und Subject snappen: `subject.matrix = compose(best.position, best.rotation, 1) * dragPointTransform⁻¹`. Sonst: Subject auf `intersectionPoint` auf XZ-Ebene setzen (`* cursorTransform⁻¹`), rotation identity.
48	9. `_lastPlacement` (PlacementUpdateData) merken: position, rotation, dragPointSelector, dropPointSelector (jeweils null bei XZ-Fallback).
49	10. Drag-Point-Kugeln neu positionieren (`subjectMatrix * dragPoint.transform * 0`), Material gelb/blau je aktiv.
50	11. **Falling edge** von `interactionClick`: `_grabActive = false`, `_lastPlacement` per `emitUpdateEvent` (subject als selectorElementReferenceRepresentation) ausgeben.
51
52	## Cycling-Logik
53	- allowAllDragPoints true: Reihenfolge … last → -1 (alle) → 0 → … (wrap über -1).
54	- allowAllDragPoints false: -1 wird übersprungen, Wrap last → 0.
55
56	## Lifecycle
57	- `startMode`: Drop-Points je Drag-Point aus Providern extrahieren (`getDropPoint()`), Drag-Point-Visuals (Sphere-Handles, BasicMaterial transparent opacity 0.75) per `addInteractionScene` erzeugen, Handles via `find('.drag-point-i')`.
58	- `stopMode`: dropPoints/dragPointHandles leeren.
59
60	## Command (Environment): start_placement_mode(params)
61	params: `subject: string`, `cursorTransform?`, `allowAllDragPoints?`, `allowDragPointCycling?`, `maxJumpDistance?`, `dragPoints: Array<{ selector?, transform?:{position,rotation}, dropPoints: string[] }>`.
62	Auflösung in interactionFeature:
63	- Subject-Selector → Handle (wirft wenn nicht gefunden).
64	- Pro Drag-Point: `dropPoints`-Selektoren via `selectorEngine.findAll` → DropPointProvider.
65	- Ohne `selector`: ein Drag-Point mit `transform` (aus position/rotation, sonst identity), selector undefined.
66	- Mit `selector`: `findAll(selector, subjectHandle)` → je Sub-Entity ein Drag-Point mit `transform = subject.LTW⁻¹ * dpe.LTW * transform`, selector = `selectorEngine.selector(dpe)`.
67	Weitere Commands: `placement_mode_next_drag_point`, `placement_mode_previous_drag_point` (werfen TypeError wenn aktueller Mode kein PlacementMode), `stop_interaction_mode`, `observe_interaction_events`.
68
69	## DropPoint-Interface
70	`assessRay(ray): RayAssessment {jumpDistance, rayDistance, position, rotation}`, `predictDragPointRotation(ray): Matrix4_4`, `setVisualization(state)`, `setVisualizationHighlight(color|null)`, `selector(): string|null`.
71
72	PMI-Implementierungen (`PmiDropPoint` Basis, hält `LTW`, `dragPointRotation = decompose(LTW)[1]`, predictRotation = konstant):
73	- **PointDropPoint** (PMIType point/matrix): position = LTW·0; jumpDistance = Abstand Punkt↔nächster Punkt auf Strahl.
74	- **LineDropPoint** (line): Segment LTW·0 → parentLTW·endpoint; closest segment-on-line.
75	- **PlaneDropPoint** (plane): Ebene aus LTW; Ray-Schnitt, in Ebenen-Koords auf `size`/2 geclampt, zurück nach Welt; jumpDistance = clampedPoint↔rayPoint.
76	`PMIComponent.getDropPoint()` mappt PMIType → Klasse (point/matrix→Point, line→Line, plane→Plane, sonst null).
77
78	Verwandt: [[cpq-verbau-architektur]] (CPQ-seitige Verbau/Platzierung).
79

---
name: fire-visual-placement-mode
description: "fire-visual Placement-Mode (snap-to-point) — Architektur, Settings, Algorithmus, DropPoints, Commands; Pfade im threed/interaction- und threed/pmi-Modul"
metadata:
  node_type: memory
  type: project
  originSessionId: 733f7054-ac76-49cd-ba04-516ef015d4f3
---

Projekt `fire-visual` (`~/projects/fire-visual`, erlaubter Ordner). Placement-Mode = snap-to-point-Platzierung eines Subjects über Drag-Points/Drop-Points. Teil des Moduls `@fire-visual/interaction`.

## Pfade
- Mode: `threed/interaction/module/src/interactionMode/placementMode.ts`
- Verdrahtung/Command: `threed/interaction/module/src/feature/interactionFeature.ts` (ab Zeile 259)
- Options-Typen: `threed/interaction/module/src/options/modeOptions.ts`
- Modul-Doku: `threed/interaction/MODULE.md`
- Test: `threed/interaction/module/tests/placementMode.test.ts`
- DropPoint-Implementierungen (PMI): `threed/pmi/module/src/dropPoint/{pmiDropPoint,planeDropPoint,pointDropPoint,lineDropPoint}.ts`
- DropPoint-Factory: `threed/pmi/module/src/component/pmiComponent.ts` → `getDropPoint()` (Zeile 422)

## Grundbegriffe
- **Subject**: das zu platzierende Objekt (`Handle`).
- **Drag-Point**: Punkt am Subject (lokaler `transform: Matrix4_4`), an dem „angefasst" wird. Visualisiert als Kugel (Sphere). Aktiv = gelb, inaktiv = blau.
- **Drop-Point**: Ziel-Snap-Geometrie in der Szene; liefert über `assessRay` eine Bewertung. Implementiert Interface `DropPoint`.
- **activeDragPointIndex**: aktiver Drag-Point; `-1` = „alle Drag-Points" (nur erlaubt wenn `allowAllDragPoints !== false`). Start: `-1`, oder `0` falls `allowAllDragPoints === false`.

## PlacementModeSettings
- `camera: CameraComponent`, `subject: Handle`
- `dragPoints[]`: je `{ transform, dropPoints: Partial<DropPointProvider>[], selector? }`
- `defaultCursorTransform?` (Fallback = `dragPoints[0].transform`)
- `allowAllDragPoints?` (Default true) — false: Index -1 verboten, Cycling hält immer einen konkreten DP aktiv
- `allowDragPointCycling?` (Default true) — false: User kann aktiven DP nicht ändern, „alle DP" bleibt aktiv
- `maxJumpDistance?` — überschreibt globalen Wert aus `ModeOptionProvider`

## Globale Optionen (ModeOptionProvider.options.placement, Typ PlacementModeOptions)
`maxJumpDistance`, `highlightColor` (Default Color.yellow), `dragPointActiveColor` (Default yellow), `dragPointInactiveColor` (Default blue), `dragPointRadius` (Default 0.1). Plus `gizmoScale` (Default 1) skaliert Kugelradius.

## Algorithmus processInput(input) je Frame
Input: `pointerNormalizedPosition`, `nextDragPoint`, `previousDragPoint`, `interactionClick`.
1. Ohne Pointer/Camera → false.
2. **Grab-Gating**: Rising edge von `interactionClick` setzt `_grabActive = true`. Solange nicht grab-aktiv: nur prevClick merken, return true (Subject bewegt sich nicht).
3. Cycling: bei `nextDragPoint`/`previousDragPoint` Index zyklen (wenn Cycling erlaubt).
4. Alle Drop-Point-Visualisierungen zurücksetzen (erst `false`+Highlight null), dann die zum aktiven DP gehörenden aktivieren (Index -1 ⇒ alle).
5. Ray von Kamera durch Pointer; Schnitt mit XZ-Ebene (`Plane` durch Ursprung, Normale up) → `intersectionPoint`.
6. Für jeden aktiven Drag-Point × dessen Drop-Points: Ray um `dropPoint.predictDragPointRotation(ray) * (dragPoint.transform⁻¹ * cursorTransform) * 0` versetzen, dann `dropPoint.assessRay(offsetRay)` → RayAssessment.
7. Beste Assessment über `betterRayAssessment`: kleinste `jumpDistance`; bei Gleichstand (Toleranz 0.05) kleinste `rayDistance`.
8. Wenn `best.jumpDistance < maxJumpDistance`: Drop-Point highlighten und Subject snappen: `subject.matrix = compose(best.position, best.rotation, 1) * dragPointTransform⁻¹`. Sonst: Subject auf `intersectionPoint` auf XZ-Ebene setzen (`* cursorTransform⁻¹`), rotation identity.
9. `_lastPlacement` (PlacementUpdateData) merken: position, rotation, dragPointSelector, dropPointSelector (jeweils null bei XZ-Fallback).
10. Drag-Point-Kugeln neu positionieren (`subjectMatrix * dragPoint.transform * 0`), Material gelb/blau je aktiv.
11. **Falling edge** von `interactionClick`: `_grabActive = false`, `_lastPlacement` per `emitUpdateEvent` (subject als selectorElementReferenceRepresentation) ausgeben.

## Cycling-Logik
- allowAllDragPoints true: Reihenfolge … last → -1 (alle) → 0 → … (wrap über -1).
- allowAllDragPoints false: -1 wird übersprungen, Wrap last → 0.

## Lifecycle
- `startMode`: Drop-Points je Drag-Point aus Providern extrahieren (`getDropPoint()`), Drag-Point-Visuals (Sphere-Handles, BasicMaterial transparent opacity 0.75) per `addInteractionScene` erzeugen, Handles via `find('.drag-point-i')`.
- `stopMode`: dropPoints/dragPointHandles leeren.

## Command (Environment): start_placement_mode(params)
params: `subject: string`, `cursorTransform?`, `allowAllDragPoints?`, `allowDragPointCycling?`, `maxJumpDistance?`, `dragPoints: Array<{ selector?, transform?:{position,rotation}, dropPoints: string[] }>`.
Auflösung in interactionFeature:
- Subject-Selector → Handle (wirft wenn nicht gefunden).
- Pro Drag-Point: `dropPoints`-Selektoren via `selectorEngine.findAll` → DropPointProvider.
- Ohne `selector`: ein Drag-Point mit `transform` (aus position/rotation, sonst identity), selector undefined.
- Mit `selector`: `findAll(selector, subjectHandle)` → je Sub-Entity ein Drag-Point mit `transform = subject.LTW⁻¹ * dpe.LTW * transform`, selector = `selectorEngine.selector(dpe)`.
Weitere Commands: `placement_mode_next_drag_point`, `placement_mode_previous_drag_point` (werfen TypeError wenn aktueller Mode kein PlacementMode), `stop_interaction_mode`, `observe_interaction_events`.

## DropPoint-Interface
`assessRay(ray): RayAssessment {jumpDistance, rayDistance, position, rotation}`, `predictDragPointRotation(ray): Matrix4_4`, `setVisualization(state)`, `setVisualizationHighlight(color|null)`, `selector(): string|null`.

PMI-Implementierungen (`PmiDropPoint` Basis, hält `LTW`, `dragPointRotation = decompose(LTW)[1]`, predictRotation = konstant):
- **PointDropPoint** (PMIType point/matrix): position = LTW·0; jumpDistance = Abstand Punkt↔nächster Punkt auf Strahl.
- **LineDropPoint** (line): Segment LTW·0 → parentLTW·endpoint; closest segment-on-line.
- **PlaneDropPoint** (plane): Ebene aus LTW; Ray-Schnitt, in Ebenen-Koords auf `size`/2 geclampt, zurück nach Welt; jumpDistance = clampedPoint↔rayPoint.
`PMIComponent.getDropPoint()` mappt PMIType → Klasse (point/matrix→Point, line→Line, plane→Plane, sonst null).

Verwandt: [[cpq-verbau-architektur]] (CPQ-seitige Verbau/Platzierung).


ok -- ein Problem mit den Assets Wiur bekommen die Assets erst später Können wir die vorhanden so anpassen - oder alte nehmen - dass Positionieren rechts und lkinks wiederr möglich ist dann können wir…


<system-reminder>This memory is 11 days old. Memories are point-in-time observations, not live state — claims about code behavior or file:line citations may be outdated. Verify against current code before asserting as fact.</system-reminder>
1	---
2	name: cpq-verbau-architektur
3	description: "adesso-cpq Verbau/Modell-Architektur (Product/Modell/Graph, BLAST-Validierung) + nächster Schritt für morgen früh"
4	metadata:
5	  node_type: memory
6	  type: project
7	  originSessionId: d789290f-6631-426e-9639-e7ea7a60e8f9
8	---
9
10	Stand der Architektur-Diskussion adesso-cpq (Schutzzaun-Konfigurator). Repos: ~/projects/adesso-cpq (frontend/CPQ), ~/projects/geko-core (Speedmaxx-Backend). Constraint-Typen folgen noch; jetzt erst Infrastruktur.
11
12	## Kernmodell (erarbeitet, trägt)
13	- **Product = zweigeteilt:** (1) Graph mit PMIs/Collidern/Transforms = der „wertlose" Graph (keine Autorität, nur Darstellung + Approximationsdaten); (2) Variablen = Config + Constraints.
14	- **Product = Entity** (BaseEntity, BLAST-validiert). **Konstrukt aus Produkten = auch Entity = Modell.** Rekursiv: Modell = Produkt (Blatt) | Konstrukt aus Modellen. Aus den Entities wird am Ende der wertlose Graph projiziert.
15	- **Quellen (mehrere!):** Speedmaxx ist führend (~60%), daneben eigene Modelle (optimaler gestaltbar) + weitere Lieferanten. Darum muss BLAST gegen ein **normalisiertes** Modell validieren, nicht gegen Quell-Spezifika oder den rohen Graphen. Im Zweifel ein **Converter**, der Speedmaxx & whatever normalisiert.
16
17	## Speedmaxx-Realität (Quelle der Wahrheit, NICHT der cpq-Mock)
18	- Branch geko-core `feature/get-scene-from-speedmaxx`: `executeCommand` → `ExecuteCommandResponse { ui: Record<string,SpeedmaxxVariable>, viewing, error }`.
19	- `ui` = Config+Constraints: `domain.{min,max,step,valuelist,default}`, `required/visible/editable/multivalue/datatype/unit/...`. Hier stecken „≤6m / ≤10 Teile".
20	- `viewing` = die Szene (wertloser Graph). Controller `loadScene` ruft `combo1_cmd`, ProductCategory "Schutzzaun", Variables wizard → gibt `result.viewing`.
21	- Format des Graphen (= Alttool = `assets/scenes/zaun.json`): `sceneGraph_entity { handles[] }`; Hierarchie flach über `component_transform.key/parentKey` (root → asm_root → produkt-node → ~50 Blatt-Teile); `component_pmi` (z.B. CS_SVS/CS_BASIS am Produkt-Knoten) = Andockpunkte; `component_collider`; Länge teils in `scale.z` eingebacken.
22	- **FALSCH in cpq:** `packages/frontend/src/util/speedMaxx2Visual.ts` erfindet `{environmentId, nodes:[{id,label}]}` — gibt es bei Speedmaxx nicht. Muss korrigiert werden.
23
24	## Validierung / BLAST (entschieden)
25	- Variablen → BLAST direkt (per-Produkt + Querregeln).
26	- Geometrie-Constraints (≤10 Teile, Gesamtlänge, PMI-Kompatibilität, Platz/Kollision) stehen NICHT in Variablen → ergeben sich aus PMIs/Collidern/Transforms.
27	- Geometrie-RECHNUNG läuft in der Engine (nicht im BLAST-Kern, der ist geometrie-agnostisch). Aber: **Engine wird AUS BLAST getriggert.** BLAST ist der Orchestrator und reaktiv (Änderung → sofort wirksam), Cache sparse pro Entity-ID → Engine läuft nur für den betroffenen Bauzug.
28	- Zwei Topos-Ebenen: per Einzelteil + konsolidiert (Bauzug). Konsolidierter Topos ruft die Engine, holt Verdikt, validiert.
29	- Hebel = Abhängigkeitsschärfe (welcher Topos hängt woran). Wird über Constraint-Typen geregelt (kommt noch).
30	- Roher Graph geht NIE nach BLAST; nur Variablen + destillierte Graph-Fakten/Verdikte.
31
32	## Schichten (Zielbild)
33	- **UI** spricht nur mit dem **Scene/Model-Service** (Name noch offen), gibt dessen Ergebnis als Graph/Commands an fire.
34	- **Scene/Model-Service** (core): hält Modell/Bauzüge, PMI-Verbindungen, rechnet Constraints, projiziert Modell → Graph. Intern getrennt: Modell/Constraint (entscheidet, kennt Platz) vs. Projektion (stumpf, entscheidet nichts).
35	- **ProductService** (gehört nach **core**, FE-agnostisch): getProduct/updateProduct, liefert nur Einzelteile, **quelle-agnostisch** über die Asset-Abstraktion (datamanager-Connectors in environment.config.json: path+typeKey-Templates; dev=Assets, live=Server). Darf NICHT wissen, woher.
36	- **fire/Graph**: rendert, ist außerhalb unserer Engine interaktiv und arbeitet mit Näherungen (Collider). Wir haben das letzte Wort; nach jeder Interaktion **Vollaustausch** des Graphen.
37	- **Gemeinsame Constraint-Sprache nötig** (3x bestätigt): zwischen zwei gemeldeten Interaktionen handelt fire autonom; es braucht dieselben Constraints. Lösung: **deklarative Daten im Graph** (Collider/PMI/Grenzen), kein geteilter Code. Offen: diese deklarativen Constraints und die exakten BLAST-Regeln müssen aus EINER Quelle stammen, sonst Drift.
38
39	## Bestand an Typen (adesso-cpq)
40	- shared: `BaseEntity { id }`. core: nur `EntityStore`, keine Typen.
41	- blast: `ObjectSchema<T extends BaseEntity>`, `ToposKey`, `BehaviourResolver`, `HintResolver`, `Diagnostic`, `Severity('error'|'warn'|'info')`, `Behaviours`, `Hint`, `FieldState`, `ItemResult`, `BlastValidator`.
42	- visual-runtime: `Visual3D` (setScene/execute/subscribe/camera), `CameraTransformation{translation,rotation,scale}`, `ConnectorConfig`, `Visual3DConfig`, `Observable<T>`.
43	- **Szenegraph-Format-Typen (SceneGraph/Handle/Component, component_transform/pmi/collider) sind HEIMATLOS** — nur in `utils/sceneMerger.ts` (fliegt raus) und als `any` in Fire3D.vue/DefaultCommandProzessor/SceneReplayProcessor. Brauchen EINEN Besitzer (Fundament für Product/Scene/fire).
44	- `utils/sceneMerger.ts`: addProductInstance/mergeScene/generateUniqueIds/positionScene/calculateNextPosition — fliegt raus (falscher Ort `utils`, zu groß, vermischt Mechanik/Platzierung/Instanz). generateUniqueIds vom User als „Mist" markiert.
45
46	## Offene Baustelle aus dieser Session
47	- `packages/frontend/src/services/product-service.ts` habe ich angelegt (getProduct/updateProduct, AssetLoader, lokaler SceneGraph-Typ). User-Kritik: zu nah an UI (gehört nach core), zuviel vorab definiert (Interfaces/Typen ohne Plan). Morgen entscheiden: behalten/verschieben/löschen. NICHT eigenmächtig Typen streuen.
48
49	## MORGEN FRÜH ZUERST
50	1. GENAU auf die **Entities für BLAST** schauen: was ist exakt die normalisierte Entity (Product, Modell). Wahrscheinlich ein **Converter** rein, der Speedmaxx (ui+viewing) und andere Quellen normalisiert. Das MUSS sitzen, sonst Schmerzen.
51	2. Dann Infrastruktur/Schichten verorten (ProductService → core, Format-Typen-Heimat).
52	3. Constraint-Typen erst danach.
53
54	## Arbeitsregeln des Users (hart)
55	- Sehr knapp, exakt das Gefragte, KEINE ungefragten Optionen/Vorschläge/Typen. Eins nach dem anderen, langsam. Nicht 3 Schritte vorausbauen. Keine Antwort mit Rückfrage/Angebot beenden. Kein Claude-Hinweis in Commits. Vor verändernden Aktionen kurz Plan + Go abwarten.
56	- Branch+MR-Workflow (adesso-CLAUDE.md); frontend→core ist paketübergreifend → nur mit explizitem Go. Git-Remotes heron.at: HTTPS+Token (osxkeychain), SSH (Port 22) ist geblockt.
57

---
name: cpq-verbau-architektur
description: "adesso-cpq Verbau/Modell-Architektur (Product/Modell/Graph, BLAST-Validierung) + nächster Schritt für morgen früh"
metadata:
  node_type: memory
  type: project
  originSessionId: d789290f-6631-426e-9639-e7ea7a60e8f9
---

Stand der Architektur-Diskussion adesso-cpq (Schutzzaun-Konfigurator). Repos: ~/projects/adesso-cpq (frontend/CPQ), ~/projects/geko-core (Speedmaxx-Backend). Constraint-Typen folgen noch; jetzt erst Infrastruktur.

## Kernmodell (erarbeitet, trägt)
- **Product = zweigeteilt:** (1) Graph mit PMIs/Collidern/Transforms = der „wertlose" Graph (keine Autorität, nur Darstellung + Approximationsdaten); (2) Variablen = Config + Constraints.
- **Product = Entity** (BaseEntity, BLAST-validiert). **Konstrukt aus Produkten = auch Entity = Modell.** Rekursiv: Modell = Produkt (Blatt) | Konstrukt aus Modellen. Aus den Entities wird am Ende der wertlose Graph projiziert.
- **Quellen (mehrere!):** Speedmaxx ist führend (~60%), daneben eigene Modelle (optimaler gestaltbar) + weitere Lieferanten. Darum muss BLAST gegen ein **normalisiertes** Modell validieren, nicht gegen Quell-Spezifika oder den rohen Graphen. Im Zweifel ein **Converter**, der Speedmaxx & whatever normalisiert.

## Speedmaxx-Realität (Quelle der Wahrheit, NICHT der cpq-Mock)
- Branch geko-core `feature/get-scene-from-speedmaxx`: `executeCommand` → `ExecuteCommandResponse { ui: Record<string,SpeedmaxxVariable>, viewing, error }`.
- `ui` = Config+Constraints: `domain.{min,max,step,valuelist,default}`, `required/visible/editable/multivalue/datatype/unit/...`. Hier stecken „≤6m / ≤10 Teile".
- `viewing` = die Szene (wertloser Graph). Controller `loadScene` ruft `combo1_cmd`, ProductCategory "Schutzzaun", Variables wizard → gibt `result.viewing`.
- Format des Graphen (= Alttool = `assets/scenes/zaun.json`): `sceneGraph_entity { handles[] }`; Hierarchie flach über `component_transform.key/parentKey` (root → asm_root → produkt-node → ~50 Blatt-Teile); `component_pmi` (z.B. CS_SVS/CS_BASIS am Produkt-Knoten) = Andockpunkte; `component_collider`; Länge teils in `scale.z` eingebacken.
- **FALSCH in cpq:** `packages/frontend/src/util/speedMaxx2Visual.ts` erfindet `{environmentId, nodes:[{id,label}]}` — gibt es bei Speedmaxx nicht. Muss korrigiert werden.

## Validierung / BLAST (entschieden)
- Variablen → BLAST direkt (per-Produkt + Querregeln).
- Geometrie-Constraints (≤10 Teile, Gesamtlänge, PMI-Kompatibilität, Platz/Kollision) stehen NICHT in Variablen → ergeben sich aus PMIs/Collidern/Transforms.
- Geometrie-RECHNUNG läuft in der Engine (nicht im BLAST-Kern, der ist geometrie-agnostisch). Aber: **Engine wird AUS BLAST getriggert.** BLAST ist der Orchestrator und reaktiv (Änderung → sofort wirksam), Cache sparse pro Entity-ID → Engine läuft nur für den betroffenen Bauzug.
- Zwei Topos-Ebenen: per Einzelteil + konsolidiert (Bauzug). Konsolidierter Topos ruft die Engine, holt Verdikt, validiert.
- Hebel = Abhängigkeitsschärfe (welcher Topos hängt woran). Wird über Constraint-Typen geregelt (kommt noch).
- Roher Graph geht NIE nach BLAST; nur Variablen + destillierte Graph-Fakten/Verdikte.

## Schichten (Zielbild)
- **UI** spricht nur mit dem **Scene/Model-Service** (Name noch offen), gibt dessen Ergebnis als Graph/Commands an fire.
- **Scene/Model-Service** (core): hält Modell/Bauzüge, PMI-Verbindungen, rechnet Constraints, projiziert Modell → Graph. Intern getrennt: Modell/Constraint (entscheidet, kennt Platz) vs. Projektion (stumpf, entscheidet nichts).
- **ProductService** (gehört nach **core**, FE-agnostisch): getProduct/updateProduct, liefert nur Einzelteile, **quelle-agnostisch** über die Asset-Abstraktion (datamanager-Connectors in environment.config.json: path+typeKey-Templates; dev=Assets, live=Server). Darf NICHT wissen, woher.
- **fire/Graph**: rendert, ist außerhalb unserer Engine interaktiv und arbeitet mit Näherungen (Collider). Wir haben das letzte Wort; nach jeder Interaktion **Vollaustausch** des Graphen.
- **Gemeinsame Constraint-Sprache nötig** (3x bestätigt): zwischen zwei gemeldeten Interaktionen handelt fire autonom; es braucht dieselben Constraints. Lösung: **deklarative Daten im Graph** (Collider/PMI/Grenzen), kein geteilter Code. Offen: diese deklarativen Constraints und die exakten BLAST-Regeln müssen aus EINER Quelle stammen, sonst Drift.

## Bestand an Typen (adesso-cpq)
- shared: `BaseEntity { id }`. core: nur `EntityStore`, keine Typen.
- blast: `ObjectSchema<T extends BaseEntity>`, `ToposKey`, `BehaviourResolver`, `HintResolver`, `Diagnostic`, `Severity('error'|'warn'|'info')`, `Behaviours`, `Hint`, `FieldState`, `ItemResult`, `BlastValidator`.
- visual-runtime: `Visual3D` (setScene/execute/subscribe/camera), `CameraTransformation{translation,rotation,scale}`, `ConnectorConfig`, `Visual3DConfig`, `Observable<T>`.
- **Szenegraph-Format-Typen (SceneGraph/Handle/Component, component_transform/pmi/collider) sind HEIMATLOS** — nur in `utils/sceneMerger.ts` (fliegt raus) und als `any` in Fire3D.vue/DefaultCommandProzessor/SceneReplayProcessor. Brauchen EINEN Besitzer (Fundament für Product/Scene/fire).
- `utils/sceneMerger.ts`: addProductInstance/mergeScene/generateUniqueIds/positionScene/calculateNextPosition — fliegt raus (falscher Ort `utils`, zu groß, vermischt Mechanik/Platzierung/Instanz). generateUniqueIds vom User als „Mist" markiert.

## Offene Baustelle aus dieser Session
- `packages/frontend/src/services/product-service.ts` habe ich angelegt (getProduct/updateProduct, AssetLoader, lokaler SceneGraph-Typ). User-Kritik: zu nah an UI (gehört nach core), zuviel vorab definiert (Interfaces/Typen ohne Plan). Morgen entscheiden: behalten/verschieben/löschen. NICHT eigenmächtig Typen streuen.

## MORGEN FRÜH ZUERST
1. GENAU auf die **Entities für BLAST** schauen: was ist exakt die normalisierte Entity (Product, Modell). Wahrscheinlich ein **Converter** rein, der Speedmaxx (ui+viewing) und andere Quellen normalisiert. Das MUSS sitzen, sonst Schmerzen.
2. Dann Infrastruktur/Schichten verorten (ProductService → core, Format-Typen-Heimat).
3. Constraint-Typen erst danach.

## Arbeitsregeln des Users (hart)
- Sehr knapp, exakt das Gefragte, KEINE ungefragten Optionen/Vorschläge/Typen. Eins nach dem anderen, langsam. Nicht 3 Schritte vorausbauen. Keine Antwort mit Rückfrage/Angebot beenden. Kein Claude-Hinweis in Commits. Vor verändernden Aktionen kurz Plan + Go abwarten.
- Branch+MR-Workflow (adesso-CLAUDE.md); frontend→core ist paketübergreifend → nur mit explizitem Go. Git-Remotes heron.at: HTTPS+Token (osxkeychain), SSH (Port 22) ist geblockt.


Zwei Punkte muss ich klären, bevor ich das beurteilen kann:

1. Um welche Assets geht es — die Speedmaxx-Szenen (`viewing` / `zaun.json`-Format) oder eigene Modelldateien?
2. Was fehlt den aktuellen Assets konkret, dass links/rechts nicht mehr geht — die PMI-Andockpunkte (CS_SVS/CS_BASIS o. ä.) an den Seiten?

Aus dem Stand der letzten Sessions kenne ich nur, dass die PMIs am Produkt-Knoten die Andockpunkte fürs Positionieren sind. Ob die vorhandenen Assets anpassbar sind, hängt davon ab, was ihnen fehlt — das weiß ich aus dem aktuellen Stand nicht.


es geht um die Zaun assets
wir hatten die mal so aufgerabeitet, dass man rechts und links einbauen komnnte
Die aktuellen Asstts sind kaput (w/ PMIS) -> müssen wieder einen stand haben, in dem etwas geht, um die Geko integration testen zu können


Plan: In `~/projects/adesso-cpq` die Git-Historie der Zaun-Assets (u. a. `assets/scenes/zaun.json`) durchsehen, den letzten Stand mit intakten PMIs (Andockpunkte links/rechts) identifizieren und diese Asset-Dateien aus dem Commit wiederherstellen — nur die Assets, kein Code. Damit ist Positionieren rechts/links wieder testbar, bis die neuen Assets kommen.

Auf Go suche ich den Stand heraus und zeige, welcher Commit es ist, bevor ich etwas zurückhole.


genau so


Bash

find /Users/marcus.hinz/projects/adesso-cpq -path '*/node_modules' -prune -o -iname '*zaun*' -print 2>/dev/null

Find Zaun asset files in adesso-cpq


Continue from where you left off.


No response requested.


List Zaun asset directories


/Users/marcus.hinz/projects/adesso-cpq/packages/frontend/.storybook/assets/glb/katalog/schutzzaun_basic:
total 32
drwx------  79 marcus.hinz  staff   2528 Jun 29 16:46 .
drwx------   6 marcus.hinz  staff    192 Jun 29 16:45 ..
-rw-r--r--@  1 marcus.hinz  staff  14340 Jun 29 16:47 .DS_Store
drwx------   2 marcus.hinz  staff     64 May 20 11:04 SBD2083PLA
drwx------   2 marcus.hinz  staff     64 May 20 11:04 SBD2083PRA
drwx------   2 marcus.hinz  staff     64 May 20 11:04 SBD2083SLA
drwx------   2 marcus.hinz  staff     64 May 20 11:04 SBD2083SRA
drwx------   2 marcus.hinz  staff     64 May 20 11:04 SBE0174PNA
drwx------   2 marcus.hinz  staff     64 May 20 11:04 SBE0174SNA
drwx------   2 marcus.hinz  staff     64 May 20 11:04 SBE0217PNA
drwx------   2 marcus.hinz  staff     64 May 20 11:04 SBE0217SNA
drwx------   2 marcus.hinz  staff     64 May 20 11:04 SBE0260PNA
drwx------   2 marcus.hinz  staff     64 May 20 11:04 SBE0260SNA
drwx------   2 marcus.hinz  staff     64 May 20 11:04 SBE0303PNA
drwx------   2 marcus.hinz  staff     64 May 20 11:04 SBE0303SNA
drwx------   2 marcus.hinz  staff     64 May 20 11:04 SBE0313SNA
drwx------   2 marcus.hinz  staff     64 May 20 11:04 SBE0346PNA
drwx------   2 marcus.hinz  staff     64 May 20 11:04 SBE0346SNA
drwx------   2 marcus.hinz  staff     64 May 20 11:04 SBE0389PNA
drwx------   2 marcus.hinz  staff     64 May 20 11:04 SBE0389SNA
drwx------   2 marcus.hinz  staff     64 May 20 11:04 SBE0432PNA
drwx------   2 marcus.hinz  staff     64 May 20 11:04 SBE0432SNA
drwx------   2 marcus.hinz  staff     64 May 20 11:04 SBE0475PNA
drwx------   2 marcus.hinz  staff     64 May 20 11:04 SBE0475SNA
drwx------   2 marcus.hinz  staff     64 May 20 11:04 SBE0518PNA
drwx------   2 marcus.hinz  staff     64 May 20 11:04 SBE0518SNA
drwx------   2 marcus.hinz  staff     64 May 20 11:04 SBE0561PNA
drwx------   2 marcus.hinz  staff     64 May 20 11:04 SBE0561SNA
drwx------   2 marcus.hinz  staff     64 May 20 11:04 SBE0604PNA
drwx------   2 marcus.hinz  staff     64 May 20 11:04 SBE0604SNA
drwx------   2 marcus.hinz  staff     64 May 20 11:04 SBE0647PNA
drwx------   2 marcus.hinz  staff     64 May 20 11:04 SBE0647SNA
drwx------   2 marcus.hinz  staff     64 May 20 11:04 SBE0690PNA
drwx------   2 marcus.hinz  staff     64 May 20 11:04 SBE0690SNA
drwx------   2 marcus.hinz  staff     64 May 20 11:04 SBE0733PNA
drwx------   2 marcus.hinz  staff     64 May 20 11:04 SBE0733SNA
drwx------   2 marcus.hinz  staff     64 May 20 11:04 SBE0776PNA
drwx------   2 marcus.hinz  staff     64 May 20 11:04 SBE0776SNA
drwx------   2 marcus.hinz  staff     64 May 20 11:04 SBE0819PNA
drwx------   2 marcus.hinz  staff     64 May 20 11:04 SBE0819SNA
drwx------   2 marcus.hinz  staff     64 May 20 11:04 SBE0862PNA
drwx------   2 marcus.hinz  staff     64 May 20 11:04 SBE0862SNA
drwx------   2 marcus.hinz  staff     64 May 20 11:04 SBE0905PNA
drwx------   2 marcus.hinz  staff     64 May 20 11:04 SBE0905SNA
drwx------   2 marcus.hinz  staff     64 May 20 11:04 SBE0948PNA
drwx------   2 marcus.hinz  staff     64 May 20 11:04 SBE0948SNA
drwx------   2 marcus.hinz  staff     64 May 20 11:04 SBE0991PNA
drwx------   2 marcus.hinz  staff     64 May 20 11:04 SBE0991SNA
drwx------   2 marcus.hinz  staff     64 May 20 11:04 SBE1034PNA
drwx------   2 marcus.hinz  staff     64 May 20 11:04 SBE1034SNA
drwx------   2 marcus.hinz  staff     64 May 20 11:04 SBE1077PNA
drwx------   2 marcus.hinz  staff     64 May 20 11:04 SBE1077SNA
drwx------   2 marcus.hinz  staff     64 May 20 11:04 SBE1120PNA
drwx------   2 marcus.hinz  staff     64 May 20 11:04 SBE1120SNA
drwx------   2 marcus.hinz  staff     64 May 20 11:04 SBE1163PNA
drwx------   2 marcus.hinz  staff     64 May 20 11:04 SBE1163SNA
drwx------   2 marcus.hinz  staff     64 May 20 11:04 SBE1206SNA
drwx------   2 marcus.hinz  staff     64 May 20 11:04 SBE1249PNA
drwx------   2 marcus.hinz  staff     64 May 20 11:04 SBE1249SNA
drwx------   2 marcus.hinz  staff     64 May 20 11:04 SBE1292PNA
drwx------   2 marcus.hinz  staff     64 May 20 11:04 SBE1292SNA
drwx------   2 marcus.hinz  staff     64 May 20 11:04 SBE1335PNA
drwx------   2 marcus.hinz  staff     64 May 20 11:04 SBE1335SNA
drwx------   2 marcus.hinz  staff     64 May 20 11:04 SBE1378PNA
drwx------   2 marcus.hinz  staff     64 May 20 11:04 SBE1378SNA
drwx------   2 marcus.hinz  staff     64 May 20 11:04 SBE1421PNA
drwx------   2 marcus.hinz  staff     64 May 20 11:04 SBE1421SNA
drwx------   2 marcus.hinz  staff     64 May 20 11:04 SBE1464PNA
drwx------   2 marcus.hinz  staff     64 May 20 11:04 SBE1464SNA
drwx------   2 marcus.hinz  staff     64 May 20 11:04 SBE1507PNA
drwx------   2 marcus.hinz  staff     64 May 20 11:04 SBE1507SNA
drwx------   2 marcus.hinz  staff     64 May 20 11:04 SBF0872PLA
drwx------   2 marcus.hinz  staff     64 May 20 11:04 SBF0872PRA
drwx------   2 marcus.hinz  staff     64 May 20 11:04 SBF0872SLA
drwx------   2 marcus.hinz  staff     64 May 20 11:04 SBF0872SRA
drwx------   2 marcus.hinz  staff     64 May 20 11:04 SBS1044PLA
drwx------   2 marcus.hinz  staff     64 May 20 11:04 SBS1044PRA
drwx------   2 marcus.hinz  staff     64 May 20 11:04 SBS1044SLA
drwx------   2 marcus.hinz  staff     64 May 20 11:04 SBS1044SRA

/Users/marcus.hinz/projects/adesso-cpq/packages/frontend/.storybook/products/schutzzaun_basic:
total 38688
drwxr-xr-x  157 marcus.hinz  staff    5024 Jul  1 16:53 .
drwxr-xr-x   10 marcus.hinz  staff     320 Jun 26 15:25 ..
-rw-rw-rw-@   1 marcus.hinz  staff  137111 Jul  2 10:00 SBD2083PLA.json
-rw-r--r--@   1 marcus.hinz  staff  112644 Jun 26 13:51 SBD2083PLA.png
-rw-rw-rw-@   1 marcus.hinz  staff  137095 Jul  2 10:00 SBD2083PRA.json
-rw-r--r--@   1 marcus.hinz  staff  112677 Jun 26 13:51 SBD2083PRA.png
-rw-rw-rw-@   1 marcus.hinz  staff  273744 Jul  2 10:00 SBD2083SLA.json
-rw-r--r--@   1 marcus.hinz  staff  538096 Jun 26 13:50 SBD2083SLA.png
-rw-rw-rw-@   1 marcus.hinz  staff  273728 Jul  2 10:00 SBD2083SRA.json
-rw-r--r--    1 marcus.hinz  staff  538293 Jun 26 13:51 SBD2083SRA.png
-rw-rw-rw-@   1 marcus.hinz  staff    7794 Jul  2 10:00 SBE0131SNA.json
-rw-r--r--    1 marcus.hinz  staff   39089 Jun 26 13:50 SBE0131SNA.png
-rw-rw-rw-@   1 marcus.hinz  staff   57666 Jul  2 10:00 SBE0174PNA.json
-rw-r--r--    1 marcus.hinz  staff   22182 Jun 26 13:50 SBE0174PNA.png
-rw-rw-rw-@   1 marcus.hinz  staff   96096 Jul  2 10:00 SBE0174SNA.json
-rw-r--r--@   1 marcus.hinz  staff   49676 Jun 26 13:50 SBE0174SNA.png
-rw-rw-rw-@   1 marcus.hinz  staff   57680 Jul  2 10:00 SBE0217PNA.json
-rw-r--r--@   1 marcus.hinz  staff   24838 Jun 26 13:50 SBE0217PNA.png
-rw-rw-rw-@   1 marcus.hinz  staff   97565 Jul  2 10:00 SBE0217SNA.json
-rw-r--r--    1 marcus.hinz  staff   60240 Jun 26 13:50 SBE0217SNA.png
-rw-rw-rw-@   1 marcus.hinz  staff   57693 Jul  2 10:00 SBE0260PNA.json
-rw-r--r--    1 marcus.hinz  staff   27202 Jun 26 13:50 SBE0260PNA.png
-rw-rw-rw-@   1 marcus.hinz  staff   99023 Jul  2 10:00 SBE0260SNA.json
-rw-r--r--    1 marcus.hinz  staff   71721 Jun 26 13:50 SBE0260SNA.png
-rw-rw-rw-@   1 marcus.hinz  staff   57693 Jul  2 10:00 SBE0303PNA.json
-rw-r--r--    1 marcus.hinz  staff   29487 Jun 26 13:50 SBE0303PNA.png
-rw-rw-rw-@   1 marcus.hinz  staff  100481 Jul  2 10:00 SBE0303SNA.json
-rw-r--r--    1 marcus.hinz  staff   82307 Jun 26 13:50 SBE0303SNA.png
-rw-rw-rw-@   1 marcus.hinz  staff   57694 Jul  2 10:00 SBE0346PNA.json
-rw-r--r--    1 marcus.hinz  staff   30532 Jun 26 13:50 SBE0346PNA.png
-rw-rw-rw-@   1 marcus.hinz  staff  101939 Jul  2 10:00 SBE0346SNA.json
-rw-r--r--    1 marcus.hinz  staff   91168 Jun 26 13:50 SBE0346SNA.png
-rw-rw-rw-@   1 marcus.hinz  staff   57693 Jul  2 10:00 SBE0389PNA.json
-rw-r--r--    1 marcus.hinz  staff   32626 Jun 26 13:50 SBE0389PNA.png
-rw-rw-rw-@   1 marcus.hinz  staff  103397 Jul  2 10:00 SBE0389SNA.json
-rw-r--r--    1 marcus.hinz  staff  102859 Jun 26 13:50 SBE0389SNA.png
-rw-rw-rw-@   1 marcus.hinz  staff   57694 Jul  2 10:00 SBE0432PNA.json
-rw-r--r--    1 marcus.hinz  staff   34729 Jun 26 13:50 SBE0432PNA.png
-rw-rw-rw-@   1 marcus.hinz  staff  104855 Jul  2 10:00 SBE0432SNA.json
-rw-r--r--    1 marcus.hinz  staff  113070 Jun 26 13:50 SBE0432SNA.png
-rw-rw-rw-@   1 marcus.hinz  staff   57693 Jul  2 10:00 SBE0475PNA.json
-rw-r--r--    1 marcus.hinz  staff   37085 Jun 26 13:50 SBE0475PNA.png
-rw-rw-rw-@   1 marcus.hinz  staff  106313 Jul  2 10:00 SBE0475SNA.json
-rw-r--r--    1 marcus.hinz  staff  124017 Jun 26 13:50 SBE0475SNA.png
-rw-rw-rw-@   1 marcus.hinz  staff   57694 Jul  2 10:00 SBE0518PNA.json
-rw-r--r--    1 marcus.hinz  staff   39468 Jun 26 13:50 SBE0518PNA.png
-rw-rw-rw-@   1 marcus.hinz  staff  107772 Jul  2 10:00 SBE0518SNA.json
-rw-r--r--    1 marcus.hinz  staff  134970 Jun 26 13:50 SBE0518SNA.png
-rw-rw-rw-@   1 marcus.hinz  staff   57693 Jul  2 10:00 SBE0561PNA.json
-rw-r--r--    1 marcus.hinz  staff   39793 Jun 26 13:50 SBE0561PNA.png
-rw-rw-rw-@   1 marcus.hinz  staff  109231 Jul  2 10:00 SBE0561SNA.json
-rw-r--r--    1 marcus.hinz  staff  144567 Jun 26 13:50 SBE0561SNA.png
-rw-rw-rw-@   1 marcus.hinz  staff   57694 Jul  2 10:00 SBE0604PNA.json
-rw-r--r--    1 marcus.hinz  staff   41982 Jun 26 13:50 SBE0604PNA.png
-rw-rw-rw-@   1 marcus.hinz  staff  110690 Jul  2 10:00 SBE0604SNA.json
-rw-r--r--    1 marcus.hinz  staff  156397 Jun 26 13:50 SBE0604SNA.png
-rw-rw-rw-@   1 marcus.hinz  staff   57693 Jul  2 10:00 SBE0647PNA.json
-rw-r--r--    1 marcus.hinz  staff   43747 Jun 26 13:50 SBE0647PNA.png
-rw-rw-rw-@   1 marcus.hinz  staff  112149 Jul  2 10:00 SBE0647SNA.json
-rw-r--r--    1 marcus.hinz  staff  165522 Jun 26 13:50 SBE0647SNA.png
-rw-rw-rw-@   1 marcus.hinz  staff   57694 Jul  2 10:00 SBE0690PNA.json
-rw-r--r--    1 marcus.hinz  staff   45558 Jun 26 13:50 SBE0690PNA.png
-rw-rw-rw-@   1 marcus.hinz  staff  113608 Jul  2 10:00 SBE0690SNA.json
-rw-r--r--    1 marcus.hinz  staff  176091 Jun 26 13:50 SBE0690SNA.png
-rw-rw-rw-@   1 marcus.hinz  staff   57694 Jul  2 10:00 SBE0733PNA.json
-rw-r--r--    1 marcus.hinz  staff   46318 Jun 26 13:50 SBE0733PNA.png
-rw-rw-rw-@   1 marcus.hinz  staff  115068 Jul  2 10:00 SBE0733SNA.json
-rw-r--r--    1 marcus.hinz  staff  184869 Jun 26 13:50 SBE0733SNA.png
-rw-rw-rw-@   1 marcus.hinz  staff   57695 Jul  2 10:00 SBE0776PNA.json
-rw-r--r--    1 marcus.hinz  staff   48053 Jun 26 13:50 SBE0776PNA.png
-rw-rw-rw-@   1 marcus.hinz  staff  116527 Jul  2 10:00 SBE0776SNA.json
-rw-r--r--    1 marcus.hinz  staff  196991 Jun 26 13:50 SBE0776SNA.png
-rw-rw-rw-@   1 marcus.hinz  staff   57694 Jul  2 10:00 SBE0819PNA.json
-rw-r--r--    1 marcus.hinz  staff   48864 Jun 26 13:50 SBE0819PNA.png
-rw-rw-rw-@   1 marcus.hinz  staff  117986 Jul  2 10:00 SBE0819SNA.json
-rw-r--r--    1 marcus.hinz  staff  205894 Jun 26 13:50 SBE0819SNA.png
-rw-rw-rw-@   1 marcus.hinz  staff   57695 Jul  2 10:00 SBE0862PNA.json
-rw-r--r--    1 marcus.hinz  staff   50053 Jun 26 13:50 SBE0862PNA.png
-rw-rw-rw-@   1 marcus.hinz  staff  119445 Jul  2 10:00 SBE0862SNA.json
-rw-r--r--    1 marcus.hinz  staff  218049 Jun 26 13:50 SBE0862SNA.png
-rw-rw-rw-@   1 marcus.hinz  staff   57694 Jul  2 10:00 SBE0905PNA.json
-rw-r--r--    1 marcus.hinz  staff   51874 Jun 26 13:50 SBE0905PNA.png
-rw-rw-rw-@   1 marcus.hinz  staff  120904 Jul  2 10:00 SBE0905SNA.json
-rw-r--r--    1 marcus.hinz  staff  226619 Jun 26 13:50 SBE0905SNA.png
-rw-rw-rw-@   1 marcus.hinz  staff   57695 Jul  2 10:00 SBE0948PNA.json
-rw-r--r--    1 marcus.hinz  staff   53481 Jun 26 13:50 SBE0948PNA.png
-rw-rw-rw-@   1 marcus.hinz  staff  122363 Jul  2 10:00 SBE0948SNA.json
-rw-r--r--    1 marcus.hinz  staff  237935 Jun 26 13:50 SBE0948SNA.png
-rw-rw-rw-@   1 marcus.hinz  staff   57697 Jul  2 10:00 SBE0991PNA.json
-rw-r--r--    1 marcus.hinz  staff   53850 Jun 26 13:50 SBE0991PNA.png
-rw-rw-rw-@   1 marcus.hinz  staff  123825 Jul  2 10:00 SBE0991SNA.json
-rw-r--r--    1 marcus.hinz  staff  246138 Jun 26 13:50 SBE0991SNA.png
-rw-rw-rw-@   1 marcus.hinz  staff   57704 Jul  2 10:00 SBE1034PNA.json
-rw-r--r--    1 marcus.hinz  staff   53347 Jun 26 13:50 SBE1034PNA.png
-rw-rw-rw-@   1 marcus.hinz  staff  125290 Jul  2 10:00 SBE1034SNA.json
-rw-r--r--    1 marcus.hinz  staff  256279 Jun 26 13:50 SBE1034SNA.png
-rw-rw-rw-@   1 marcus.hinz  staff   57706 Jul  2 10:00 SBE1077PNA.json
-rw-r--r--    1 marcus.hinz  staff   54611 Jun 26 13:50 SBE1077PNA.png
-rw-rw-rw-@   1 marcus.hinz  staff  126797 Jul  2 10:00 SBE1077SNA.json
-rw-r--r--    1 marcus.hinz  staff  265389 Jun 26 13:50 SBE1077SNA.png
-rw-rw-rw-@   1 marcus.hinz  staff   57722 Jul  2 10:00 SBE1120PNA.json
-rw-r--r--    1 marcus.hinz  staff   54161 Jun 26 13:50 SBE1120PNA.png
-rw-rw-rw-@   1 marcus.hinz  staff  128268 Jul  2 10:00 SBE1120SNA.json
-rw-r--r--    1 marcus.hinz  staff  277076 Jun 26 13:50 SBE1120SNA.png
-rw-rw-rw-@   1 marcus.hinz  staff   57733 Jul  2 10:00 SBE1163PNA.json
-rw-r--r--    1 marcus.hinz  staff   54471 Jun 26 13:50 SBE1163PNA.png
-rw-rw-rw-@   1 marcus.hinz  staff  129728 Jul  2 10:00 SBE1163SNA.json
-rw-r--r--    1 marcus.hinz  staff  285382 Jun 26 13:50 SBE1163SNA.png
-rw-rw-rw-@   1 marcus.hinz  staff    8076 Jul  2 10:00 SBE1206PNA.json
-rw-r--r--    1 marcus.hinz  staff   54542 Jun 26 13:50 SBE1206PNA.png
-rw-rw-rw-@   1 marcus.hinz  staff  131188 Jul  2 10:00 SBE1206SNA.json
-rw-r--r--    1 marcus.hinz  staff  294440 Jun 26 13:50 SBE1206SNA.png
-rw-rw-rw-@   1 marcus.hinz  staff   57733 Jul  2 10:00 SBE1249PNA.json
-rw-r--r--    1 marcus.hinz  staff   55225 Jun 26 13:50 SBE1249PNA.png
-rw-rw-rw-@   1 marcus.hinz  staff  132648 Jul  2 10:00 SBE1249SNA.json
-rw-r--r--    1 marcus.hinz  staff  303176 Jun 26 13:50 SBE1249SNA.png
-rw-rw-rw-@   1 marcus.hinz  staff   57734 Jul  2 10:00 SBE1292PNA.json
-rw-r--r--    1 marcus.hinz  staff   55821 Jun 26 13:50 SBE1292PNA.png
-rw-rw-rw-@   1 marcus.hinz  staff  134108 Jul  2 10:00 SBE1292SNA.json
-rw-r--r--    1 marcus.hinz  staff  315261 Jun 26 13:50 SBE1292SNA.png
-rw-rw-rw-@   1 marcus.hinz  staff   57733 Jul  2 10:00 SBE1335PNA.json
-rw-r--r--    1 marcus.hinz  staff   57788 Jun 26 13:50 SBE1335PNA.png
-rw-rw-rw-@   1 marcus.hinz  staff  135568 Jul  2 10:00 SBE1335SNA.json
-rw-r--r--    1 marcus.hinz  staff  323997 Jun 26 13:50 SBE1335SNA.png
-rw-rw-rw-@   1 marcus.hinz  staff   57734 Jul  2 10:00 SBE1378PNA.json
-rw-r--r--    1 marcus.hinz  staff   59455 Jun 26 13:50 SBE1378PNA.png
-rw-rw-rw-@   1 marcus.hinz  staff  137028 Jul  2 10:00 SBE1378SNA.json
-rw-r--r--    1 marcus.hinz  staff  338129 Jun 26 13:50 SBE1378SNA.png
-rw-rw-rw-@   1 marcus.hinz  staff   57733 Jul  2 10:00 SBE1421PNA.json
-rw-r--r--    1 marcus.hinz  staff   59439 Jun 26 13:50 SBE1421PNA.png
-rw-rw-rw-@   1 marcus.hinz  staff  138488 Jul  2 10:00 SBE1421SNA.json
-rw-r--r--    1 marcus.hinz  staff  285048 Jun 26 13:50 SBE1421SNA.png
-rw-rw-rw-@   1 marcus.hinz  staff   57734 Jul  2 10:00 SBE1464PNA.json
-rw-r--r--    1 marcus.hinz  staff   63026 Jun 26 13:50 SBE1464PNA.png
-rw-rw-rw-@   1 marcus.hinz  staff  139948 Jul  2 10:00 SBE1464SNA.json
-rw-r--r--    1 marcus.hinz  staff  358644 Jun 26 13:50 SBE1464SNA.png
-rw-rw-rw-@   1 marcus.hinz  staff   57733 Jul  2 10:00 SBE1507PNA.json
-rw-r--r--    1 marcus.hinz  staff   63684 Jun 26 13:50 SBE1507PNA.png
-rw-rw-rw-@   1 marcus.hinz  staff  141408 Jul  2 10:00 SBE1507SNA.json
-rw-r--r--    1 marcus.hinz  staff  369346 Jun 26 13:50 SBE1507SNA.png
-rw-rw-rw-@   1 marcus.hinz  staff  157522 Jul  2 10:00 SBF0872PLA.json
-rw-r--r--    1 marcus.hinz  staff  102863 Jun 26 13:51 SBF0872PLA.png
-rw-rw-rw-@   1 marcus.hinz  staff  157525 Jul  2 10:00 SBF0872PRA.json
-rw-r--r--    1 marcus.hinz  staff   98759 Jun 26 13:51 SBF0872PRA.png
-rw-rw-rw-@   1 marcus.hinz  staff  291254 Jul  2 10:00 SBF0872SLA.json
-rw-r--r--    1 marcus.hinz  staff  501493 Jun 26 13:51 SBF0872SLA.png
-rw-rw-rw-@   1 marcus.hinz  staff  291301 Jul  2 10:00 SBF0872SRA.json
-rw-r--r--    1 marcus.hinz  staff  502557 Jun 26 13:51 SBF0872SRA.png
-rw-rw-rw-@   1 marcus.hinz  staff   87091 Jul  2 15:24 SBS1044PLA.json
-rw-r--r--    1 marcus.hinz  staff   83544 Jun 26 13:50 SBS1044PLA.png
-rw-rw-rw-@   1 marcus.hinz  staff   87076 Jul  2 14:27 SBS1044PRA.json
-rw-r--r--    1 marcus.hinz  staff   83140 Jun 26 13:50 SBS1044PRA.png
-rw-rw-rw-@   1 marcus.hinz  staff  155152 Jul  2 14:27 SBS1044SLA.json
-rw-r--r--    1 marcus.hinz  staff  289117 Jun 26 13:50 SBS1044SLA.png
-rw-rw-rw-@   1 marcus.hinz  staff  155137 Jul  2 14:27 SBS1044SRA.json
-rw-r--r--@   1 marcus.hinz  staff  289286 Jun 26 13:50 SBS1044SRA.png
-rw-rw-rw-@   1 marcus.hinz  staff  164553 Jul  2 10:00 schutzzaun_basic.json

/Users/marcus.hinz/projects/adesso-cpq/ressources/katalog/schutzzaun_basic:
total 12520
drwxrwxrwx@ 157 marcus.hinz  staff    5024 Jun 26 12:31 .
drwx------@   6 marcus.hinz  staff     192 Jun 26 12:30 ..
-rw-r--r--@   1 marcus.hinz  staff    6148 Jun 26 13:49 .DS_Store
drwxrwxrwx@  21 marcus.hinz  staff     672 Jun 26 12:29 SBD2083PLA
-rw-rw-rw-@   1 marcus.hinz  staff   37936 Jun 26 12:17 SBD2083PLA.json
drwxrwxrwx@  21 marcus.hinz  staff     672 Jun 26 12:29 SBD2083PRA
-rw-rw-rw-@   1 marcus.hinz  staff   37920 Jun 26 12:18 SBD2083PRA.json
drwxrwxrwx@  19 marcus.hinz  staff     608 Jun 26 12:29 SBD2083SLA
-rw-rw-rw-@   1 marcus.hinz  staff  119455 Jun 26 12:18 SBD2083SLA.json
drwxrwxrwx@  19 marcus.hinz  staff     608 Jun 26 12:29 SBD2083SRA
-rw-rw-rw-@   1 marcus.hinz  staff  119439 Jun 26 12:18 SBD2083SRA.json
-rw-rw-rw-@   1 marcus.hinz  staff    2202 Jun 26 12:18 SBE0131SNA.json
drwxrwxrwx@  12 marcus.hinz  staff     384 Jun 26 12:29 SBE0174PNA
-rw-rw-rw-@   1 marcus.hinz  staff   52460 Jun 26 12:18 SBE0174PNA.json
drwxrwxrwx@  10 marcus.hinz  staff     320 Jun 26 12:29 SBE0174SNA
-rw-rw-rw-@   1 marcus.hinz  staff   91218 Jun 26 12:18 SBE0174SNA.json
drwxrwxrwx@  12 marcus.hinz  staff     384 Jun 26 12:29 SBE0217PNA
-rw-rw-rw-@   1 marcus.hinz  staff   52474 Jun 26 12:18 SBE0217PNA.json
drwxrwxrwx@  10 marcus.hinz  staff     320 Jun 26 12:29 SBE0217SNA
-rw-rw-rw-@   1 marcus.hinz  staff   92699 Jun 26 12:18 SBE0217SNA.json
drwxrwxrwx@  12 marcus.hinz  staff     384 Jun 26 12:29 SBE0260PNA
-rw-rw-rw-@   1 marcus.hinz  staff   52487 Jun 26 12:18 SBE0260PNA.json
drwxrwxrwx@  10 marcus.hinz  staff     320 Jun 26 12:29 SBE0260SNA
-rw-rw-rw-@   1 marcus.hinz  staff   94169 Jun 26 12:18 SBE0260SNA.json
drwxrwxrwx@  12 marcus.hinz  staff     384 Jun 26 12:29 SBE0303PNA
-rw-rw-rw-@   1 marcus.hinz  staff   52487 Jun 26 12:18 SBE0303PNA.json
drwxrwxrwx@  10 marcus.hinz  staff     320 Jun 26 12:29 SBE0303SNA
-rw-rw-rw-@   1 marcus.hinz  staff   95639 Jun 26 12:18 SBE0303SNA.json
drwxrwxrwx@  10 marcus.hinz  staff     320 Jun 26 12:29 SBE0313SNA
drwxrwxrwx@  12 marcus.hinz  staff     384 Jun 26 12:29 SBE0346PNA
-rw-rw-rw-@   1 marcus.hinz  staff   52488 Jun 26 12:19 SBE0346PNA.json
drwxrwxrwx@  10 marcus.hinz  staff     320 Jun 26 12:29 SBE0346SNA
-rw-rw-rw-@   1 marcus.hinz  staff   97109 Jun 26 12:19 SBE0346SNA.json
drwxrwxrwx@  12 marcus.hinz  staff     384 Jun 26 12:29 SBE0389PNA
-rw-rw-rw-@   1 marcus.hinz  staff   52487 Jun 26 12:19 SBE0389PNA.json
drwxrwxrwx@  10 marcus.hinz  staff     320 Jun 26 12:29 SBE0389SNA
-rw-rw-rw-@   1 marcus.hinz  staff   98579 Jun 26 12:19 SBE0389SNA.json
drwxrwxrwx@  12 marcus.hinz  staff     384 Jun 26 12:29 SBE0432PNA
-rw-rw-rw-@   1 marcus.hinz  staff   52488 Jun 26 12:19 SBE0432PNA.json
drwxrwxrwx@  10 marcus.hinz  staff     320 Jun 26 12:29 SBE0432SNA
-rw-rw-rw-@   1 marcus.hinz  staff  100049 Jun 26 12:19 SBE0432SNA.json
drwxrwxrwx@  12 marcus.hinz  staff     384 Jun 26 12:29 SBE0475PNA
-rw-rw-rw-@   1 marcus.hinz  staff   52487 Jun 26 12:19 SBE0475PNA.json
drwxrwxrwx@  10 marcus.hinz  staff     320 Jun 26 12:29 SBE0475SNA
-rw-rw-rw-@   1 marcus.hinz  staff  101519 Jun 26 12:19 SBE0475SNA.json
drwxrwxrwx@  12 marcus.hinz  staff     384 Jun 26 12:29 SBE0518PNA
-rw-rw-rw-@   1 marcus.hinz  staff   52488 Jun 26 12:19 SBE0518PNA.json
drwxrwxrwx@  10 marcus.hinz  staff     320 Jun 26 12:29 SBE0518SNA
-rw-rw-rw-@   1 marcus.hinz  staff  102990 Jun 26 12:19 SBE0518SNA.json
drwxrwxrwx@  12 marcus.hinz  staff     384 Jun 26 12:29 SBE0561PNA
-rw-rw-rw-@   1 marcus.hinz  staff   52487 Jun 26 12:19 SBE0561PNA.json
drwxrwxrwx@  10 marcus.hinz  staff     320 Jun 26 12:29 SBE0561SNA
-rw-rw-rw-@   1 marcus.hinz  staff  104461 Jun 26 12:19 SBE0561SNA.json
drwxrwxrwx@  12 marcus.hinz  staff     384 Jun 26 12:29 SBE0604PNA
-rw-rw-rw-@   1 marcus.hinz  staff   52488 Jun 26 12:19 SBE0604PNA.json
drwxrwxrwx@  10 marcus.hinz  staff     320 Jun 26 12:29 SBE0604SNA
-rw-rw-rw-@   1 marcus.hinz  staff  105932 Jun 26 12:19 SBE0604SNA.json
drwxrwxrwx@  12 marcus.hinz  staff     384 Jun 26 12:29 SBE0647PNA
-rw-rw-rw-@   1 marcus.hinz  staff   52487 Jun 26 12:19 SBE0647PNA.json
drwxrwxrwx@  10 marcus.hinz  staff     320 Jun 26 12:29 SBE0647SNA
-rw-rw-rw-@   1 marcus.hinz  staff  107403 Jun 26 12:19 SBE0647SNA.json
drwxrwxrwx@  12 marcus.hinz  staff     384 Jun 26 12:29 SBE0690PNA
-rw-rw-rw-@   1 marcus.hinz  staff   52488 Jun 26 12:19 SBE0690PNA.json
drwxrwxrwx@  10 marcus.hinz  staff     320 Jun 26 12:29 SBE0690SNA
-rw-rw-rw-@   1 marcus.hinz  staff  108874 Jun 26 12:20 SBE0690SNA.json
drwxrwxrwx@  12 marcus.hinz  staff     384 Jun 26 12:29 SBE0733PNA
-rw-rw-rw-@   1 marcus.hinz  staff   52487 Jun 26 12:20 SBE0733PNA.json
drwxrwxrwx@  10 marcus.hinz  staff     320 Jun 26 12:29 SBE0733SNA
-rw-rw-rw-@   1 marcus.hinz  staff  110345 Jun 26 12:20 SBE0733SNA.json
drwxrwxrwx@  12 marcus.hinz  staff     384 Jun 26 12:29 SBE0776PNA
-rw-rw-rw-@   1 marcus.hinz  staff   52488 Jun 26 12:20 SBE0776PNA.json
drwxrwxrwx@  10 marcus.hinz  staff     320 Jun 26 12:29 SBE0776SNA
-rw-rw-rw-@   1 marcus.hinz  staff  111816 Jun 26 12:20 SBE0776SNA.json
drwxrwxrwx@  12 marcus.hinz  staff     384 Jun 26 12:29 SBE0819PNA
-rw-rw-rw-@   1 marcus.hinz  staff   52487 Jun 26 12:20 SBE0819PNA.json
drwxrwxrwx@  10 marcus.hinz  staff     320 Jun 26 12:29 SBE0819SNA
-rw-rw-rw-@   1 marcus.hinz  staff  113287 Jun 26 12:20 SBE0819SNA.json
drwxrwxrwx@  12 marcus.hinz  staff     384 Jun 26 12:29 SBE0862PNA
-rw-rw-rw-@   1 marcus.hinz  staff   52488 Jun 26 12:20 SBE0862PNA.json
drwxrwxrwx@  10 marcus.hinz  staff     320 Jun 26 12:29 SBE0862SNA
-rw-rw-rw-@   1 marcus.hinz  staff  114758 Jun 26 12:20 SBE0862SNA.json
drwxrwxrwx@  12 marcus.hinz  staff     384 Jun 26 12:29 SBE0905PNA
-rw-rw-rw-@   1 marcus.hinz  staff   52487 Jun 26 12:20 SBE0905PNA.json
drwxrwxrwx@  10 marcus.hinz  staff     320 Jun 26 12:29 SBE0905SNA
-rw-rw-rw-@   1 marcus.hinz  staff  116229 Jun 26 12:20 SBE0905SNA.json
drwxrwxrwx@  12 marcus.hinz  staff     384 Jun 26 12:29 SBE0948PNA
-rw-rw-rw-@   1 marcus.hinz  staff   52488 Jun 26 12:20 SBE0948PNA.json
drwxrwxrwx@  10 marcus.hinz  staff     320 Jun 26 12:29 SBE0948SNA
-rw-rw-rw-@   1 marcus.hinz  staff  117700 Jun 26 12:20 SBE0948SNA.json
drwxrwxrwx@  12 marcus.hinz  staff     384 Jun 26 12:29 SBE0991PNA
-rw-rw-rw-@   1 marcus.hinz  staff   52487 Jun 26 12:20 SBE0991PNA.json
drwxrwxrwx@  10 marcus.hinz  staff     320 Jun 26 12:29 SBE0991SNA
-rw-rw-rw-@   1 marcus.hinz  staff  119171 Jun 26 12:20 SBE0991SNA.json
drwxrwxrwx@  12 marcus.hinz  staff     384 Jun 26 12:29 SBE1034PNA
-rw-rw-rw-@   1 marcus.hinz  staff   52488 Jun 26 12:20 SBE1034PNA.json
drwxrwxrwx@  10 marcus.hinz  staff     320 Jun 26 12:29 SBE1034SNA
-rw-rw-rw-@   1 marcus.hinz  staff  120642 Jun 26 12:20 SBE1034SNA.json
drwxrwxrwx@  12 marcus.hinz  staff     384 Jun 26 12:29 SBE1077PNA
-rw-rw-rw-@   1 marcus.hinz  staff   52490 Jun 26 12:20 SBE1077PNA.json
drwxrwxrwx@  10 marcus.hinz  staff     320 Jun 26 12:29 SBE1077SNA
-rw-rw-rw-@   1 marcus.hinz  staff  122161 Jun 26 12:21 SBE1077SNA.json
drwxrwxrwx@  12 marcus.hinz  staff     384 Jun 26 12:29 SBE1120PNA
-rw-rw-rw-@   1 marcus.hinz  staff   52506 Jun 26 12:21 SBE1120PNA.json
drwxrwxrwx@  10 marcus.hinz  staff     320 Jun 26 12:29 SBE1120SNA
-rw-rw-rw-@   1 marcus.hinz  staff  123644 Jun 26 12:21 SBE1120SNA.json
drwxrwxrwx@  12 marcus.hinz  staff     384 Jun 26 12:29 SBE1163PNA
-rw-rw-rw-@   1 marcus.hinz  staff   52517 Jun 26 12:21 SBE1163PNA.json
drwxrwxrwx@  10 marcus.hinz  staff     320 Jun 26 12:29 SBE1163SNA
-rw-rw-rw-@   1 marcus.hinz  staff  125116 Jun 26 12:21 SBE1163SNA.json
-rw-rw-rw-@   1 marcus.hinz  staff    2474 Jun 26 12:21 SBE1206PNA.json
drwxrwxrwx@  10 marcus.hinz  staff     320 Jun 26 12:29 SBE1206SNA
-rw-rw-rw-@   1 marcus.hinz  staff  126588 Jun 26 12:21 SBE1206SNA.json
drwxrwxrwx@  12 marcus.hinz  staff     384 Jun 26 12:29 SBE1249PNA
-rw-rw-rw-@   1 marcus.hinz  staff   52517 Jun 26 12:21 SBE1249PNA.json
drwxrwxrwx@  10 marcus.hinz  staff     320 Jun 26 12:29 SBE1249SNA
-rw-rw-rw-@   1 marcus.hinz  staff  128060 Jun 26 12:21 SBE1249SNA.json
drwxrwxrwx@  12 marcus.hinz  staff     384 Jun 26 12:29 SBE1292PNA
-rw-rw-rw-@   1 marcus.hinz  staff   52518 Jun 26 12:21 SBE1292PNA.json
drwxrwxrwx@  10 marcus.hinz  staff     320 Jun 26 12:29 SBE1292SNA
-rw-rw-rw-@   1 marcus.hinz  staff  129532 Jun 26 12:21 SBE1292SNA.json
drwxrwxrwx@  12 marcus.hinz  staff     384 Jun 26 12:29 SBE1335PNA
-rw-rw-rw-@   1 marcus.hinz  staff   52517 Jun 26 12:21 SBE1335PNA.json
drwxrwxrwx@  10 marcus.hinz  staff     320 Jun 26 12:29 SBE1335SNA
-rw-rw-rw-@   1 marcus.hinz  staff  131004 Jun 26 12:21 SBE1335SNA.json
drwxrwxrwx@  12 marcus.hinz  staff     384 Jun 26 12:29 SBE1378PNA
-rw-rw-rw-@   1 marcus.hinz  staff   52518 Jun 26 12:21 SBE1378PNA.json
drwxrwxrwx@  10 marcus.hinz  staff     320 Jun 26 12:29 SBE1378SNA
-rw-rw-rw-@   1 marcus.hinz  staff  132476 Jun 26 12:21 SBE1378SNA.json
drwxrwxrwx@  12 marcus.hinz  staff     384 Jun 26 12:29 SBE1421PNA
-rw-rw-rw-@   1 marcus.hinz  staff   52517 Jun 26 12:21 SBE1421PNA.json
drwxrwxrwx@  10 marcus.hinz  staff     320 Jun 26 12:29 SBE1421SNA
-rw-rw-rw-@   1 marcus.hinz  staff  133948 Jun 26 12:22 SBE1421SNA.json
drwxrwxrwx@  12 marcus.hinz  staff     384 Jun 26 12:29 SBE1464PNA
-rw-rw-rw-@   1 marcus.hinz  staff   52518 Jun 26 12:22 SBE1464PNA.json
drwxrwxrwx@  10 marcus.hinz  staff     320 Jun 26 12:29 SBE1464SNA
-rw-rw-rw-@   1 marcus.hinz  staff  135420 Jun 26 12:22 SBE1464SNA.json
drwxrwxrwx@  12 marcus.hinz  staff     384 Jun 26 12:29 SBE1507PNA
-rw-rw-rw-@   1 marcus.hinz  staff   52517 Jun 26 12:22 SBE1507PNA.json
drwxrwxrwx@  10 marcus.hinz  staff     320 Jun 26 12:29 SBE1507SNA
-rw-rw-rw-@   1 marcus.hinz  staff  136892 Jun 26 12:22 SBE1507SNA.json
drwxrwxrwx@  28 marcus.hinz  staff     896 Jun 26 12:29 SBF0872PLA
-rw-rw-rw-@   1 marcus.hinz  staff   41648 Jun 26 12:22 SBF0872PLA.json
drwxrwxrwx@  28 marcus.hinz  staff     896 Jun 26 12:29 SBF0872PRA
-rw-rw-rw-@   1 marcus.hinz  staff   41651 Jun 26 12:22 SBF0872PRA.json
drwxrwxrwx@  25 marcus.hinz  staff     800 Jun 26 12:29 SBF0872SLA
-rw-rw-rw-@   1 marcus.hinz  staff  121828 Jun 26 12:22 SBF0872SLA.json
drwxrwxrwx@  25 marcus.hinz  staff     800 Jun 26 12:29 SBF0872SRA
-rw-rw-rw-@   1 marcus.hinz  staff  121875 Jun 26 12:23 SBF0872SRA.json
drwxrwxrwx@  20 marcus.hinz  staff     640 Jun 26 12:29 SBS1044PLA
-rw-rw-rw-@   1 marcus.hinz  staff   25383 Jun 26 12:23 SBS1044PLA.json
drwxrwxrwx@  20 marcus.hinz  staff     640 Jun 26 12:29 SBS1044PRA
-rw-rw-rw-@   1 marcus.hinz  staff   25368 Jun 26 12:23 SBS1044PRA.json
drwxrwxrwx@  18 marcus.hinz  staff     576 Jun 26 12:29 SBS1044SLA
-rw-rw-rw-@   1 marcus.hinz  staff   65887 Jun 26 12:23 SBS1044SLA.json
drwxrwxrwx@  18 marcus.hinz  staff     576 Jun 26 12:29 SBS1044SRA
-rw-rw-rw-@   1 marcus.hinz  staff   65872 Jun 26 12:23 SBS1044SRA.json
-rw-rw-rw-@   1 marcus.hinz  staff  164553 Mar 27 17:17 schutzzaun_basic.json


cd /Users/marcus.hinz/projects/adesso-cpq && git log --oneline -15 && git status --short | head -30

Show recent commits and working tree status


297a73c update 1.06
cc927c5 @ad/fire auf 1.0.6
36ec21b eob
0633a88 git-sync: 2026-06-30 13:35
b961242 refactor
95bfb26 git-sync: 2026-06-29 20:16
5c8eaec git-sync: 2026-06-29 18:39
ce6f85c git-sync: 2026-06-29 16:38
f641410 Verbau: verbundene Zaunteile platzieren, bewegen, rotieren
1436730 git-sync: 2026-06-26 22:05
4b0e73f Produktbrowser: Einfuegen wieder per Klick (childClicked); Fire3D: JSON-Download bei Szenenwechsel entfernt
842b84b initial / eob
5aaf58b style: Prettier-Format über die gesamte Codebasis
adb0f82 Merge branch 'chore/dev-tooling-and-hygiene' into 'main'
4dab7fe Merge origin/main into chore/dev-tooling-and-hygiene
D  packages/frontend/.storybook/assets/catalog/catalog.json
D  packages/frontend/.storybook/assets/catalog/construction_geometry.png
D  packages/frontend/.storybook/assets/catalog/powered_roller_conveyor_curve.png
D  packages/frontend/.storybook/assets/catalog/powered_roller_conveyor_dreheinheit.png
D  packages/frontend/.storybook/assets/catalog/powered_roller_conveyor_straight.png
D  packages/frontend/.storybook/assets/catalog/safety_fence_allround_double_door.png
D  packages/frontend/.storybook/assets/catalog/safety_fence_allround_panel.png
D  packages/frontend/.storybook/assets/catalog/safety_fence_allround_post.png
D  packages/frontend/.storybook/assets/catalog/safety_fence_allround_single_door.png
D  packages/frontend/.storybook/assets/catalog/safety_fence_allround_sliding_door.png
D  packages/frontend/.storybook/assets/catalog/safety_fence_basic_double_door.png
D  packages/frontend/.storybook/assets/catalog/safety_fence_basic_panel.png
D  packages/frontend/.storybook/assets/catalog/safety_fence_basic_single_door.png
D  packages/frontend/.storybook/assets/catalog/safety_fence_basic_sliding_door.png
D  packages/frontend/.storybook/assets/environment.config.json_bak
D  packages/frontend/.storybook/assets/fbx/screw.fbx
 D packages/frontend/.storybook/assets/icons/duplicate.svg
 D packages/frontend/.storybook/assets/icons/edit.svg
 D packages/frontend/.storybook/assets/icons/trash.svg
D  packages/frontend/.storybook/assets/scenes/collision-2.json
D  packages/frontend/.storybook/assets/scenes/collision-simple.json
D  packages/frontend/.storybook/assets/scenes/empty.json
D  packages/frontend/.storybook/assets/scenes/nestedGraph.json
D  packages/frontend/.storybook/assets/scenes/profile.json
D  packages/frontend/.storybook/assets/scenes/rolle.json
D  packages/frontend/.storybook/assets/scenes/zaun.json
D  packages/frontend/.storybook/assets/scenes/zaun2.json
D  packages/frontend/.storybook/assets/scenes/zaun3.json
D  packages/frontend/.storybook/assets/shader/blend_additiveAlpha.json
D  packages/frontend/.storybook/assets/shader/blend_multiply.json


git status --short -- packages/frontend/.storybook/products/ | head -20; echo ---; git log --oneline --follow -- packages/frontend/.storybook/products/schutzzaun_basic/schutzzaun_basic.json | head; echo ---; git log --oneline -- packages/frontend/.storybook/products/ | head

Git status and history of Zaun product JSONs


AM packages/frontend/.storybook/products/catalog.json
A  packages/frontend/.storybook/products/powered_roller_conveyor.png
A  packages/frontend/.storybook/products/rollenfoerderer/rollenfoerderer.json
AM packages/frontend/.storybook/products/rollenfoerderer/rollenfoerdererprofil_aussenradius.json
A  packages/frontend/.storybook/products/safety_fence_allround.png
A  packages/frontend/.storybook/products/safety_fence_basic.png
A  packages/frontend/.storybook/products/schutzzaun_allround/SAD2083PLA.glb
AM packages/frontend/.storybook/products/schutzzaun_allround/SAD2083PLA.json
A  packages/frontend/.storybook/products/schutzzaun_allround/SAD2083PLA.png
A  packages/frontend/.storybook/products/schutzzaun_allround/SAD2083PRA.glb
AM packages/frontend/.storybook/products/schutzzaun_allround/SAD2083PRA.json
A  packages/frontend/.storybook/products/schutzzaun_allround/SAD2083PRA.png
A  packages/frontend/.storybook/products/schutzzaun_allround/SAD2083SLA.glb
AM packages/frontend/.storybook/products/schutzzaun_allround/SAD2083SLA.json
A  packages/frontend/.storybook/products/schutzzaun_allround/SAD2083SLA.png
A  packages/frontend/.storybook/products/schutzzaun_allround/SAD2083SRA.glb
AM packages/frontend/.storybook/products/schutzzaun_allround/SAD2083SRA.json
A  packages/frontend/.storybook/products/schutzzaun_allround/SAD2083SRA.png
A  packages/frontend/.storybook/products/schutzzaun_allround/SAE0131SNN.glb
AM packages/frontend/.storybook/products/schutzzaun_allround/SAE0131SNN.json
---
---


f=packages/frontend/.storybook/products/schutzzaun_basic/SBE0174PNA.json && echo "== WORKING TREE =="; python3 -c "
import json,sys
d=json.load(open('$f'))
def walk(o):
    hs=o.get('handles') or o.get('sceneGraph_entity',{}).get('handles') or []
    return hs
hs=walk(d)
print('handles:',len(hs))
for h in hs:
    for c in h.get('components',[]):
        t=c.get('type','')
        if 'pmi' in t.lower():
            print(t, json.dumps(c)[:200])
" 2>&1 | head -30

Inspect PMI components in current Zaun product JSON


== WORKING TREE ==
Traceback (most recent call last):
  File "<string>", line 12, in <module>
AttributeError: 'int' object has no attribute 'lower'
handles: 20


f=packages/frontend/.storybook/products/schutzzaun_basic/SBE0174PNA.json && python3 -c "
import json
d=json.load(open('$f'))
print(list(d.keys()))
hs=d.get('handles',[])
h0=hs[0]
print(json.dumps(h0)[:600])
"

Show top-level structure of Zaun product JSON


['_resourceClass', 'handles']
{"id": "X-34cd52e5-137b-4a37-9b18-15f13786b705", "properties": {"custom-selection": {"type": "string", "value": "self"}}, "components": [{"_resourceClass": "component_transform", "key": "root", "translation": [0, 0, 0], "rotation": [0, 0, 0], "scale": [1, 1, 1]}, {"_resourceClass": "component_pmi", "id": "CS_BASE_PRE", "tags": ["name-CS_BASE_PRE"], "type": "point", "properties": {"position": {"type": "vector3", "value": [0, 0, 0], "usage": "position"}, "rotation": {"type": "quaternion", "value": [90, 0, 0], "usage": "rotation"}}}, {"_resourceClass": "component_pmi", "id": "CS_BASE", "tags": ["


python3 - <<'EOF'
import json, subprocess

def pmis(data):
    out=[]
    for h in data.get('handles',[]):
        for c in h.get('components',[]):
            if c.get('_resourceClass')=='component_pmi':
                pos=c.get('properties',{}).get('position',{}).get('value')
                rot=c.get('properties',{}).get('rotation',{}).get('value')
                out.append((c.get('id'), c.get('type'), pos, rot))
    return out

f='packages/frontend/.storybook/products/schutzzaun_basic/SBE0174PNA.json'
wt=json.load(open(f))
staged=json.loads(subprocess.run(['git','show',':'+f],capture_output=True,text=True).stdout)
kat=json.load(open('ressources/katalog/schutzzaun_basic/SBE0174PNA.json'))

for name,d in [('WORKING TREE',wt),('STAGED (Index)',staged),('ressources/katalog',kat)]:
    print('==',name,'==')
    for p in pmis(d): print(' ',p)
EOF

Compare PMIs: working tree vs staged vs katalog version (Steher SBE0174PNA)


== WORKING TREE ==
  ('CS_BASE_PRE', 'point', [0, 0, 0], [90, 0, 0])
  ('CS_BASE', 'point', [0, 0, 0], [0, 0, 180])
  ('CS_EIN_L', 'point', [-20, 1100, -20], [0, 0, 0])
  ('CS_EIN_R', 'point', [-20, 1100, -154], [0, 180, 0])
  ('CS_EIN_START_L', 'point', [-20, 0, 0], [0, 0, 0])
  ('CS_EIN_START_R', 'point', [-20, 0, -174], [0, 180, 0])
  ('CS_OUT_R_0', 'point', [-20, 1100, -204], [0, 0, 0])
  ('CS_OUT_L_0', 'point', [-20, 1100, 30], [0, 180, 0])
  ('CS_OUT_R_90', 'point', [-70, 1100, -154], [0, 90, 0])
  ('CS_OUT_L_90', 'point', [-70, 1100, -20], [0, 90, 0])
  ('CS_OUT_R_90_B', 'point', [-20, 1100, -204], [0, 90, 0])
  ('CS_OUT_L_90_B', 'point', [-20, 1100, 30], [0, 90, 0])
  ('CS_OUT_R_270', 'point', [30, 1100, -154], [0, 270, 0])
  ('CS_OUT_L_270', 'point', [30, 1100, -20], [0, 270, 0])
  ('CS_OUT_R_270_B', 'point', [-20, 1100, -204], [0, 270, 0])
  ('CS_OUT_L_270_B', 'point', [-20, 1100, 30], [0, 270, 0])
  ('CS_SELECT_L_0', 'point', [-20, 1100, 300], [0, 0, 0])
  ('CS_SELECT_R_0', 'point', [-20, 1100, -474], [0, 180, 0])
  ('CS_SELECT_L_90', 'point', [-340, 1100, 0], [0, 270, 0])
  ('CS_SELECT_R_90', 'point', [-340, 1100, -174], [0, 270, 0])
  ('CS_SELECT_L_270', 'point', [300, 1100, 0], [0, 90, 0])
  ('CS_SELECT_R_270', 'point', [300, 1100, -174], [0, 90, 0])
  ('CS_SVS', 'point', [0.0, 0.0, 0.0], [0.0, -0.0, 0.0])
  ('CS_EIN_QUER', 'point', [19.9999999998, 19.9999999998, -21670.0], [0.0, -90.0, 180.0])
  ('CS_EIN_STEHER', 'point', [19.9999999998, 19.9999999998, -21670.0], [90.0, 0.0, 90.0])
  ('CS_EIN_STUMMEL', 'point', [19.9999999998, 18.7499999998, -21670.0], [180.0, -0.0, 0.0])
  ('CS_SVS', 'point', [0.0, 0.0, 0.0], [0.0, -0.0, 0.0])
  ('CS_EIN_QUER', 'point', [19.9999999998, 19.9999999998, -21670.0], [0.0, -90.0, 180.0])
  ('CS_EIN_STEHER', 'point', [19.9999999998, 19.9999999998, -21670.0], [90.0, 0.0, 90.0])
  ('CS_EIN_STUMMEL', 'point', [19.9999999998, 18.7499999998, -21670.0], [180.0, -0.0, 0.0])
  ('CS_SVS', 'point', [0.0, 0.0, 0.0], [0.0, -0.0, 0.0])
  ('CS_EIN_STEHER_OBEN', 'point', [20.0, -40.0, 0.0], [90.0, -0.0, 180.0])
  ('CS_EIN_STEHER_UNTEN', 'point', [-20.0, -40.0, 0.0], [-90.0, -0.0, 90.0])
  ('CS_EIN_STEHER_VORNE', 'point', [20.0, -40.0, 0.0], [0.0, -0.0, 180.0])
  ('CS_EIN_STEHER_HINTEN', 'point', [20.0, -40.0, 0.0], [180.0, -0.0, 180.0])
  ('CS_EIN_QUER_RECHTS', 'point', [-20.0, -40.0, 0.0], [0.0, -90.0, 180.0])
  ('CS_EIN_QUER_LINKS', 'point', [20.0, 0.0, 0.0], [0.0, 90.0, 180.0])
  ('CS_EIN', 'point', [20.0, -40.0, 0.0], [90.0, -0.0, 180.0])
  ('CS_EIN_180_0_0', 'point', [20.0, -40.0, 0.0], [-90.0, -0.0, 180.0])
  ('CS_EIN_90_0_180', 'point', [20.0, -40.0, 0.0], [0.0, -0.0, 0.0])
  ('CS_EIN_90_0_0', 'point', [20.0, -40.0, 0.0], [0.0, -0.0, 180.0])
  ('CS_EIN_270_0_0', 'point', [20.0, -40.0, 0.0], [180.0, -0.0, 180.0])
  ('CS_EIN_C4F_H_RECHTS', 'point', [20.0, 0.0, 0.0], [0.0, -90.0, 0.0])
  ('CS_EIN_C4F_H_LINKS', 'point', [20.0, 0.0, 0.0], [0.0, 90.0, 0.0])
  ('CS_SVS', 'point', [0.0, 0.0, 0.0], [0.0, -0.0, 0.0])
  ('CS_EIN_STEHER_OBEN', 'point', [20.0, -40.0, 0.0], [90.0, -0.0, 180.0])
  ('CS_EIN_STEHER_UNTEN', 'point', [-20.0, -40.0, 0.0], [-90.0, -0.0, 90.0])
  ('CS_EIN_STEHER_VORNE', 'point', [20.0, -40.0, 0.0], [0.0, -0.0, 180.0])
  ('CS_EIN_STEHER_HINTEN', 'point', [20.0, -40.0, 0.0], [180.0, -0.0, 180.0])
  ('CS_EIN_QUER_RECHTS', 'point', [-20.0, -40.0, 0.0], [0.0, -90.0, 180.0])
  ('CS_EIN_QUER_LINKS', 'point', [20.0, 0.0, 0.0], [0.0, 90.0, 180.0])
  ('CS_EIN', 'point', [20.0, -40.0, 0.0], [90.0, -0.0, 180.0])
  ('CS_EIN_180_0_0', 'point', [20.0, -40.0, 0.0], [-90.0, -0.0, 180.0])
  ('CS_EIN_90_0_180', 'point', [20.0, -40.0, 0.0], [0.0, -0.0, 0.0])
  ('CS_EIN_90_0_0', 'point', [20.0, -40.0, 0.0], [0.0, -0.0, 180.0])
  ('CS_EIN_270_0_0', 'point', [20.0, -40.0, 0.0], [180.0, -0.0, 180.0])
  ('CS_EIN_C4F_H_RECHTS', 'point', [20.0, 0.0, 0.0], [0.0, -90.0, 0.0])
  ('CS_EIN_C4F_H_LINKS', 'point', [20.0, 0.0, 0.0], [0.0, 90.0, 0.0])
  ('CS_SVS', 'point', [0.0, 0.0, 0.0], [0.0, -0.0, 0.0])
  ('CS_EIN_HINTEN', 'point', [19.5, 20.0, 33.0], [90.0, -0.0, -90.0])
  ('CS_EIN_VORNE', 'point', [19.5, 20.0, 33.0], [90.0, 0.0, 90.0])
  ('CS_SVS', 'point', [0.0, 0.0, 0.0], [0.0, -0.0, 0.0])
  ('CS_EIN_HINTEN', 'point', [19.5, 20.0, 33.0], [90.0, -0.0, -90.0])
  ('CS_EIN_VORNE', 'point', [19.5, 20.0, 33.0], [90.0, 0.0, 90.0])
  ('CS_SVS', 'point', [0.0, 0.0, 0.0], [0.0, -0.0, 0.0])
  ('CS_EIN_QUER', 'point', [19.9999999998, 19.9999999998, -940.0], [0.0, -90.0, 180.0])
  ('CS_EIN_STEHER', 'point', [19.9999999998, 19.9999999998, -940.0], [90.0, 0.0, 90.0])
  ('CS_EIN_STUMMEL', 'point', [19.9999999998, 18.7499999998, -940.0], [180.0, -0.0, 0.0])
  ('CS_SVS', 'point', [0.0, 0.0, 0.0], [0.0, -0.0, 0.0])
  ('CS_EIN_QUER', 'point', [19.9999999998, 19.9999999998, -940.0], [0.0, -90.0, 180.0])
  ('CS_EIN_STEHER', 'point', [19.9999999998, 19.9999999998, -940.0], [90.0, 0.0, 90.0])
  ('CS_EIN_STUMMEL', 'point', [19.9999999998, 18.7499999998, -940.0], [180.0, -0.0, 0.0])
  ('CS_SVS', 'point', [0.0, 0.0, 0.0], [0.0, -0.0, 0.0])
  ('CS_EIN_HINTEN_RECHTS', 'point', [20.0, 20.0, 4.0], [0.0, -0.0, 0.0])
  ('CS_EIN_VORNE_LINKS', 'point', [20.0, 20.0, 4.0], [180.0, -0.0, 180.0])
  ('CS_SVS', 'point', [0.0, 0.0, 0.0], [0.0, -0.0, 0.0])
  ('CS_EIN', 'point', [0.0, 0.0, 0.0], [90.0, -0.0, 0.0])
  ('CS_EIN_270_0_270', 'point', [0.0, 0.0, 0.0], [0.0, -90.0, 180.0])
  ('CS_EIN_0_270_0', 'point', [0.0, 0.0, 0.0], [90.0, 0.0, 90.0])
  ('CS_EIN_QUER', 'point', [0.0, 0.0, 1926.0], [0.0, 90.0, 90.0])
  ('CS_EIN_0_90_0', 'point', [0.0, 0.0, 1926.0], [180.0, 0.0, -90.0])
  ('CS_EIN_90_0_0', 'point', [0.0, 0.0, 1926.0], [0.0, 90.0, 0.0])
  ('CS_SVS', 'point', [0.0, 0.0, 0.0], [0.0, -0.0, 0.0])
  ('CS_EIN_LINKS_UNTEN', 'point', [0.0, 0.0, -36.0], [0.0, -90.0, 0.0])
  ('CS_EIN_RECHTS_UNTEN', 'point', [0.0, 0.0, -36.0], [90.0, -0.0, -90.0])
  ('CS_EIN_LINKS_OBEN', 'point', [0.0, 0.0, -36.0], [-90.0, -0.0, 90.0])
  ('CS_EIN_RECHTS_OBEN', 'point', [0.0, 0.0, -36.0], [0.0, 90.0, 180.0])
  ('CS_EIN', 'point', [17.0, 0.0, -36.0], [0.0, -90.0, -90.0])
  ('CS_EIN_0_0_180', 'point', [17.0, 0.0, -36.0], [0.0, 90.0, 90.0])
  ('CS_EIN_0_90_0', 'point', [17.0, 0.0, -36.0], [180.0, -0.0, 90.0])
  ('CS_EIN_0_180_0', 'point', [17.0, 0.0, -36.0], [90.0, 90.0, 0.0])
  ('CS_SVS', 'point', [0.0, 0.0, 0.0], [0.0, -0.0, 0.0])
  ('CS_EIN_LINKS_UNTEN', 'point', [0.0, 0.0, -36.0], [0.0, -90.0, 0.0])
  ('CS_EIN_RECHTS_UNTEN', 'point', [0.0, 0.0, -36.0], [90.0, -0.0, -90.0])
  ('CS_EIN_LINKS_OBEN', 'point', [0.0, 0.0, -36.0], [-90.0, -0.0, 90.0])
  ('CS_EIN_RECHTS_OBEN', 'point', [0.0, 0.0, -36.0], [0.0, 90.0, 180.0])
  ('CS_EIN', 'point', [17.0, 0.0, -36.0], [0.0, -90.0, -90.0])
  ('CS_EIN_0_0_180', 'point', [17.0, 0.0, -36.0], [0.0, 90.0, 90.0])
  ('CS_EIN_0_90_0', 'point', [17.0, 0.0, -36.0], [180.0, -0.0, 90.0])
  ('CS_EIN_0_180_0', 'point', [17.0, 0.0, -36.0], [90.0, 90.0, 0.0])
  ('CS_SVS', 'point', [0.0, 0.0, 0.0], [0.0, -0.0, 0.0])
  ('CS_EIN_LINKS_UNTEN', 'point', [0.0, 0.0, -36.0], [0.0, -90.0, 0.0])
  ('CS_EIN_RECHTS_UNTEN', 'point', [0.0, 0.0, -36.0], [90.0, -0.0, -90.0])
  ('CS_EIN_LINKS_OBEN', 'point', [0.0, 0.0, -36.0], [-90.0, -0.0, 90.0])
  ('CS_EIN_RECHTS_OBEN', 'point', [0.0, 0.0, -36.0], [0.0, 90.0, 180.0])
  ('CS_EIN', 'point', [17.0, 0.0, -36.0], [0.0, -90.0, -90.0])
  ('CS_EIN_0_0_180', 'point', [17.0, 0.0, -36.0], [0.0, 90.0, 90.0])
  ('CS_EIN_0_90_0', 'point', [17.0, 0.0, -36.0], [180.0, -0.0, 90.0])
  ('CS_EIN_0_180_0', 'point', [17.0, 0.0, -36.0], [90.0, 90.0, 0.0])
  ('CS_SVS', 'point', [0.0, 0.0, 0.0], [0.0, -0.0, 0.0])
  ('CS_EIN_LINKS_UNTEN', 'point', [0.0, 0.0, -36.0], [0.0, -90.0, 0.0])
  ('CS_EIN_RECHTS_UNTEN', 'point', [0.0, 0.0, -36.0], [90.0, -0.0, -90.0])
  ('CS_EIN_LINKS_OBEN', 'point', [0.0, 0.0, -36.0], [-90.0, -0.0, 90.0])
  ('CS_EIN_RECHTS_OBEN', 'point', [0.0, 0.0, -36.0], [0.0, 90.0, 180.0])
  ('CS_EIN', 'point', [17.0, 0.0, -36.0], [0.0, -90.0, -90.0])
  ('CS_EIN_0_0_180', 'point', [17.0, 0.0, -36.0], [0.0, 90.0, 90.0])
  ('CS_EIN_0_90_0', 'point', [17.0, 0.0, -36.0], [180.0, -0.0, 90.0])
  ('CS_EIN_0_180_0', 'point', [17.0, 0.0, -36.0], [90.0, 90.0, 0.0])
  ('CS_SVS', 'point', [0.0, 0.0, 0.0], [0.0, -0.0, 0.0])
  ('CS_EIN_LINKS', 'point', [11.8, 0.0, 0.0], [90.0, 0.0, 90.0])
  ('CS_EIN_RECHTS', 'point', [11.8, 0.0, 0.0], [-90.0, 0.0, -90.0])
  ('CS_EIN_UNTEN', 'point', [11.8, 0.0, 0.0], [0.0, -90.0, 0.0])
  ('CS_EIN_OBEN', 'point', [11.8, 0.0, 0.0], [0.0, 90.0, 180.0])
  ('CS_EIN', 'point', [11.8, 0.0, 1888.0], [90.0, 0.0, 90.0])
  ('CS_EIN_90_180_0', 'point', [11.8, 0.0, 1888.0], [180.0, 0.0, -90.0])
  ('CS_EIN_90_0_0', 'point', [11.8, 0.0, 1888.0], [180.0, -0.0, 90.0])
  ('CS_EIN_QUER', 'point', [11.8, 0.0, 0.0], [90.0, 0.0, 90.0])
  ('CS_EIN_QUER_270_180_90x', 'point', [11.8, 0.0, 0.0], [90.0, 90.0, 0.0])
  ('CS_EIN_QUER_90_0_90', 'point', [11.8, 0.0, 1888.0], [0.0, -90.0, -90.0])
  ('CS_EIN_QUER_270_180_90', 'point', [11.8, 0.0, 1888.0], [90.0, 90.0, 0.0])
  ('CS_SVS', 'point', [0.0, 0.0, 0.0], [0.0, -0.0, 0.0])
  ('CS_EIN_LINKS', 'point', [11.8, 0.0, 0.0], [90.0, 0.0, 90.0])
  ('CS_EIN_RECHTS', 'point', [11.8, 0.0, 0.0], [-90.0, 0.0, -90.0])
  ('CS_EIN_UNTEN', 'point', [11.8, 0.0, 0.0], [0.0, -90.0, 0.0])
  ('CS_EIN_OBEN', 'point', [11.8, 0.0, 0.0], [0.0, 90.0, 180.0])
  ('CS_EIN', 'point', [11.8, 0.0, 1888.0], [90.0, 0.0, 90.0])
  ('CS_EIN_90_180_0', 'point', [11.8, 0.0, 1888.0], [180.0, 0.0, -90.0])
  ('CS_EIN_90_0_0', 'point', [11.8, 0.0, 1888.0], [180.0, -0.0, 90.0])
  ('CS_EIN_QUER', 'point', [11.8, 0.0, 0.0], [90.0, 0.0, 90.0])
  ('CS_EIN_QUER_270_180_90x', 'point', [11.8, 0.0, 0.0], [90.0, 90.0, 0.0])
  ('CS_EIN_QUER_90_0_90', 'point', [11.8, 0.0, 1888.0], [0.0, -90.0, -90.0])
  ('CS_EIN_QUER_270_180_90', 'point', [11.8, 0.0, 1888.0], [90.0, 90.0, 0.0])
  ('CS_SVS', 'point', [0.0, 0.0, 0.0], [0.0, -0.0, 0.0])
  ('CS_EIN_LINKS', 'point', [11.8, 0.0, 0.0], [90.0, 0.0, 90.0])
  ('CS_EIN_RECHTS', 'point', [11.8, 0.0, 0.0], [-90.0, 0.0, -90.0])
  ('CS_EIN_UNTEN', 'point', [11.8, 0.0, 0.0], [0.0, -90.0, 0.0])
  ('CS_EIN_OBEN', 'point', [11.8, 0.0, 0.0], [0.0, 90.0, 180.0])
  ('CS_EIN', 'point', [11.8, 0.0, 41.0], [90.0, 0.0, 90.0])
  ('CS_EIN_90_180_0', 'point', [11.8, 0.0, 41.0], [180.0, 0.0, -90.0])
  ('CS_EIN_90_0_0', 'point', [11.8, 0.0, 41.0], [180.0, -0.0, 90.0])
  ('CS_EIN_QUER', 'point', [11.8, 0.0, 0.0], [90.0, 0.0, 90.0])
  ('CS_EIN_QUER_270_180_90x', 'point', [11.8, 0.0, 0.0], [90.0, 90.0, 0.0])
  ('CS_EIN_QUER_90_0_90', 'point', [11.8, 0.0, 41.0], [0.0, -90.0, -90.0])
  ('CS_EIN_QUER_270_180_90', 'point', [11.8, 0.0, 41.0], [90.0, 90.0, 0.0])
  ('CS_SVS', 'point', [0.0, 0.0, 0.0], [0.0, -0.0, 0.0])
  ('CS_EIN_LINKS', 'point', [11.8, 0.0, 0.0], [90.0, 0.0, 90.0])
  ('CS_EIN_RECHTS', 'point', [11.8, 0.0, 0.0], [-90.0, 0.0, -90.0])
  ('CS_EIN_UNTEN', 'point', [11.8, 0.0, 0.0], [0.0, -90.0, 0.0])
  ('CS_EIN_OBEN', 'point', [11.8, 0.0, 0.0], [0.0, 90.0, 180.0])
  ('CS_EIN', 'point', [11.8, 0.0, 41.0], [90.0, 0.0, 90.0])
  ('CS_EIN_90_180_0', 'point', [11.8, 0.0, 41.0], [180.0, 0.0, -90.0])
  ('CS_EIN_90_0_0', 'point', [11.8, 0.0, 41.0], [180.0, -0.0, 90.0])
  ('CS_EIN_QUER', 'point', [11.8, 0.0, 0.0], [90.0, 0.0, 90.0])
  ('CS_EIN_QUER_270_180_90x', 'point', [11.8, 0.0, 0.0], [90.0, 90.0, 0.0])
  ('CS_EIN_QUER_90_0_90', 'point', [11.8, 0.0, 41.0], [0.0, -90.0, -90.0])
  ('CS_EIN_QUER_270_180_90', 'point', [11.8, 0.0, 41.0], [90.0, 90.0, 0.0])
== STAGED (Index) ==
  ('CS_SVS', 'adapter', [0.0, 0.0, 0.0], [0.0, -0.0, 0.0])
  ('CS_SVS', 'adapter', [0.0, 0.0, 0.0], [0.0, -0.0, 0.0])
  ('CS_SVS', 'adapter', [0.0, 0.0, 0.0], [0.0, -0.0, 0.0])
  ('CS_SVS', 'adapter', [0.0, 0.0, 0.0], [0.0, -0.0, 0.0])
  ('CS_SVS', 'adapter', [0.0, 0.0, 0.0], [0.0, -0.0, 0.0])
  ('CS_EIN_HINTEN', 'adapter', [19.5, 20.0, 33.0], [90.0, -0.0, -90.0])
  ('CS_EIN_VORNE', 'adapter', [19.5, 20.0, 33.0], [90.0, 0.0, 90.0])
  ('CS_SVS', 'adapter', [0.0, 0.0, 0.0], [0.0, -0.0, 0.0])
  ('CS_EIN_HINTEN', 'adapter', [19.5, 20.0, 33.0], [90.0, -0.0, -90.0])
  ('CS_EIN_VORNE', 'adapter', [19.5, 20.0, 33.0], [90.0, 0.0, 90.0])
  ('CS_SVS', 'adapter', [0.0, 0.0, 0.0], [0.0, -0.0, 0.0])
  ('CS_SVS', 'adapter', [0.0, 0.0, 0.0], [0.0, -0.0, 0.0])
  ('CS_SVS', 'adapter', [0.0, 0.0, 0.0], [0.0, -0.0, 0.0])
  ('CS_SVS', 'adapter', [0.0, 0.0, 0.0], [0.0, -0.0, 0.0])
  ('CS_SVS', 'adapter', [0.0, 0.0, 0.0], [0.0, -0.0, 0.0])
  ('CS_SVS', 'adapter', [0.0, 0.0, 0.0], [0.0, -0.0, 0.0])
  ('CS_SVS', 'adapter', [0.0, 0.0, 0.0], [0.0, -0.0, 0.0])
  ('CS_SVS', 'adapter', [0.0, 0.0, 0.0], [0.0, -0.0, 0.0])
  ('CS_SVS', 'adapter', [0.0, 0.0, 0.0], [0.0, -0.0, 0.0])
  ('CS_SVS', 'adapter', [0.0, 0.0, 0.0], [0.0, -0.0, 0.0])
  ('CS_SVS', 'adapter', [0.0, 0.0, 0.0], [0.0, -0.0, 0.0])
  ('CS_SVS', 'adapter', [0.0, 0.0, 0.0], [0.0, -0.0, 0.0])
== ressources/katalog ==
  ('CS_SVS', 'adapter', [0.0, 0.0, 0.0], [0.0, -0.0, 0.0])
  ('CS_EIN_QUER', 'adapter', [19.9999999998, 19.9999999998, -21670.0], [0.0, -90.0, 180.0])
  ('CS_EIN_STEHER', 'adapter', [19.9999999998, 19.9999999998, -21670.0], [90.0, 0.0, 90.0])
  ('CS_EIN_STUMMEL', 'adapter', [19.9999999998, 18.7499999998, -21670.0], [180.0, -0.0, 0.0])
  ('CS_SVS', 'adapter', [0.0, 0.0, 0.0], [0.0, -0.0, 0.0])
  ('CS_EIN_QUER', 'adapter', [19.9999999998, 19.9999999998, -21670.0], [0.0, -90.0, 180.0])
  ('CS_EIN_STEHER', 'adapter', [19.9999999998, 19.9999999998, -21670.0], [90.0, 0.0, 90.0])
  ('CS_EIN_STUMMEL', 'adapter', [19.9999999998, 18.7499999998, -21670.0], [180.0, -0.0, 0.0])
  ('CS_SVS', 'adapter', [0.0, 0.0, 0.0], [0.0, -0.0, 0.0])
  ('CS_EIN_STEHER_OBEN', 'adapter', [20.0, -40.0, 0.0], [90.0, -0.0, 180.0])
  ('CS_EIN_STEHER_UNTEN', 'adapter', [-20.0, -40.0, 0.0], [-90.0, -0.0, 90.0])
  ('CS_EIN_STEHER_VORNE', 'adapter', [20.0, -40.0, 0.0], [0.0, -0.0, 180.0])
  ('CS_EIN_STEHER_HINTEN', 'adapter', [20.0, -40.0, 0.0], [180.0, -0.0, 180.0])
  ('CS_EIN_QUER_RECHTS', 'adapter', [-20.0, -40.0, 0.0], [0.0, -90.0, 180.0])
  ('CS_EIN_QUER_LINKS', 'adapter', [20.0, 0.0, 0.0], [0.0, 90.0, 180.0])
  ('CS_EIN', 'adapter', [20.0, -40.0, 0.0], [90.0, -0.0, 180.0])
  ('CS_EIN_180_0_0', 'adapter', [20.0, -40.0, 0.0], [-90.0, -0.0, 180.0])
  ('CS_EIN_90_0_180', 'adapter', [20.0, -40.0, 0.0], [0.0, -0.0, 0.0])
  ('CS_EIN_90_0_0', 'adapter', [20.0, -40.0, 0.0], [0.0, -0.0, 180.0])
  ('CS_EIN_270_0_0', 'adapter', [20.0, -40.0, 0.0], [180.0, -0.0, 180.0])
  ('CS_EIN_C4F_H_RECHTS', 'adapter', [20.0, 0.0, 0.0], [0.0, -90.0, 0.0])
  ('CS_EIN_C4F_H_LINKS', 'adapter', [20.0, 0.0, 0.0], [0.0, 90.0, 0.0])
  ('CS_SVS', 'adapter', [0.0, 0.0, 0.0], [0.0, -0.0, 0.0])
  ('CS_EIN_STEHER_OBEN', 'adapter', [20.0, -40.0, 0.0], [90.0, -0.0, 180.0])
  ('CS_EIN_STEHER_UNTEN', 'adapter', [-20.0, -40.0, 0.0], [-90.0, -0.0, 90.0])
  ('CS_EIN_STEHER_VORNE', 'adapter', [20.0, -40.0, 0.0], [0.0, -0.0, 180.0])
  ('CS_EIN_STEHER_HINTEN', 'adapter', [20.0, -40.0, 0.0], [180.0, -0.0, 180.0])
  ('CS_EIN_QUER_RECHTS', 'adapter', [-20.0, -40.0, 0.0], [0.0, -90.0, 180.0])
  ('CS_EIN_QUER_LINKS', 'adapter', [20.0, 0.0, 0.0], [0.0, 90.0, 180.0])
  ('CS_EIN', 'adapter', [20.0, -40.0, 0.0], [90.0, -0.0, 180.0])
  ('CS_EIN_180_0_0', 'adapter', [20.0, -40.0, 0.0], [-90.0, -0.0, 180.0])
  ('CS_EIN_90_0_180', 'adapter', [20.0, -40.0, 0.0], [0.0, -0.0, 0.0])
  ('CS_EIN_90_0_0', 'adapter', [20.0, -40.0, 0.0], [0.0, -0.0, 180.0])
  ('CS_EIN_270_0_0', 'adapter', [20.0, -40.0, 0.0], [180.0, -0.0, 180.0])
  ('CS_EIN_C4F_H_RECHTS', 'adapter', [20.0, 0.0, 0.0], [0.0, -90.0, 0.0])
  ('CS_EIN_C4F_H_LINKS', 'adapter', [20.0, 0.0, 0.0], [0.0, 90.0, 0.0])
  ('CS_SVS', 'adapter', [0.0, 0.0, 0.0], [0.0, -0.0, 0.0])
  ('CS_EIN_HINTEN', 'adapter', [19.5, 20.0, 33.0], [90.0, -0.0, -90.0])
  ('CS_EIN_VORNE', 'adapter', [19.5, 20.0, 33.0], [90.0, 0.0, 90.0])
  ('CS_SVS', 'adapter', [0.0, 0.0, 0.0], [0.0, -0.0, 0.0])
  ('CS_EIN_HINTEN', 'adapter', [19.5, 20.0, 33.0], [90.0, -0.0, -90.0])
  ('CS_EIN_VORNE', 'adapter', [19.5, 20.0, 33.0], [90.0, 0.0, 90.0])
  ('CS_SVS', 'adapter', [0.0, 0.0, 0.0], [0.0, -0.0, 0.0])
  ('CS_EIN_QUER', 'adapter', [19.9999999998, 19.9999999998, -940.0], [0.0, -90.0, 180.0])
  ('CS_EIN_STEHER', 'adapter', [19.9999999998, 19.9999999998, -940.0], [90.0, 0.0, 90.0])
  ('CS_EIN_STUMMEL', 'adapter', [19.9999999998, 18.7499999998, -940.0], [180.0, -0.0, 0.0])
  ('CS_SVS', 'adapter', [0.0, 0.0, 0.0], [0.0, -0.0, 0.0])
  ('CS_EIN_QUER', 'adapter', [19.9999999998, 19.9999999998, -940.0], [0.0, -90.0, 180.0])
  ('CS_EIN_STEHER', 'adapter', [19.9999999998, 19.9999999998, -940.0], [90.0, 0.0, 90.0])
  ('CS_EIN_STUMMEL', 'adapter', [19.9999999998, 18.7499999998, -940.0], [180.0, -0.0, 0.0])
  ('CS_SVS', 'adapter', [0.0, 0.0, 0.0], [0.0, -0.0, 0.0])
  ('CS_EIN_HINTEN_RECHTS', 'adapter', [20.0, 20.0, 4.0], [0.0, -0.0, 0.0])
  ('CS_EIN_VORNE_LINKS', 'adapter', [20.0, 20.0, 4.0], [180.0, -0.0, 180.0])
  ('CS_SVS', 'adapter', [0.0, 0.0, 0.0], [0.0, -0.0, 0.0])
  ('CS_EIN', 'adapter', [0.0, 0.0, 0.0], [90.0, -0.0, 0.0])
  ('CS_EIN_270_0_270', 'adapter', [0.0, 0.0, 0.0], [0.0, -90.0, 180.0])
  ('CS_EIN_0_270_0', 'adapter', [0.0, 0.0, 0.0], [90.0, 0.0, 90.0])
  ('CS_EIN_QUER', 'adapter', [0.0, 0.0, 1926.0], [0.0, 90.0, 90.0])
  ('CS_EIN_0_90_0', 'adapter', [0.0, 0.0, 1926.0], [180.0, 0.0, -90.0])
  ('CS_EIN_90_0_0', 'adapter', [0.0, 0.0, 1926.0], [0.0, 90.0, 0.0])
  ('CS_SVS', 'adapter', [0.0, 0.0, 0.0], [0.0, -0.0, 0.0])
  ('CS_EIN_LINKS_UNTEN', 'adapter', [0.0, 0.0, -36.0], [0.0, -90.0, 0.0])
  ('CS_EIN_RECHTS_UNTEN', 'adapter', [0.0, 0.0, -36.0], [90.0, -0.0, -90.0])
  ('CS_EIN_LINKS_OBEN', 'adapter', [0.0, 0.0, -36.0], [-90.0, -0.0, 90.0])
  ('CS_EIN_RECHTS_OBEN', 'adapter', [0.0, 0.0, -36.0], [0.0, 90.0, 180.0])
  ('CS_EIN', 'adapter', [17.0, 0.0, -36.0], [0.0, -90.0, -90.0])
  ('CS_EIN_0_0_180', 'adapter', [17.0, 0.0, -36.0], [0.0, 90.0, 90.0])
  ('CS_EIN_0_90_0', 'adapter', [17.0, 0.0, -36.0], [180.0, -0.0, 90.0])
  ('CS_EIN_0_180_0', 'adapter', [17.0, 0.0, -36.0], [90.0, 90.0, 0.0])
  ('CS_SVS', 'adapter', [0.0, 0.0, 0.0], [0.0, -0.0, 0.0])
  ('CS_EIN_LINKS_UNTEN', 'adapter', [0.0, 0.0, -36.0], [0.0, -90.0, 0.0])
  ('CS_EIN_RECHTS_UNTEN', 'adapter', [0.0, 0.0, -36.0], [90.0, -0.0, -90.0])
  ('CS_EIN_LINKS_OBEN', 'adapter', [0.0, 0.0, -36.0], [-90.0, -0.0, 90.0])
  ('CS_EIN_RECHTS_OBEN', 'adapter', [0.0, 0.0, -36.0], [0.0, 90.0, 180.0])
  ('CS_EIN', 'adapter', [17.0, 0.0, -36.0], [0.0, -90.0, -90.0])
  ('CS_EIN_0_0_180', 'adapter', [17.0, 0.0, -36.0], [0.0, 90.0, 90.0])
  ('CS_EIN_0_90_0', 'adapter', [17.0, 0.0, -36.0], [180.0, -0.0, 90.0])
  ('CS_EIN_0_180_0', 'adapter', [17.0, 0.0, -36.0], [90.0, 90.0, 0.0])
  ('CS_SVS', 'adapter', [0.0, 0.0, 0.0], [0.0, -0.0, 0.0])
  ('CS_EIN_LINKS_UNTEN', 'adapter', [0.0, 0.0, -36.0], [0.0, -90.0, 0.0])
  ('CS_EIN_RECHTS_UNTEN', 'adapter', [0.0, 0.0, -36.0], [90.0, -0.0, -90.0])
  ('CS_EIN_LINKS_OBEN', 'adapter', [0.0, 0.0, -36.0], [-90.0, -0.0, 90.0])
  ('CS_EIN_RECHTS_OBEN', 'adapter', [0.0, 0.0, -36.0], [0.0, 90.0, 180.0])
  ('CS_EIN', 'adapter', [17.0, 0.0, -36.0], [0.0, -90.0, -90.0])
  ('CS_EIN_0_0_180', 'adapter', [17.0, 0.0, -36.0], [0.0, 90.0, 90.0])
  ('CS_EIN_0_90_0', 'adapter', [17.0, 0.0, -36.0], [180.0, -0.0, 90.0])
  ('CS_EIN_0_180_0', 'adapter', [17.0, 0.0, -36.0], [90.0, 90.0, 0.0])
  ('CS_SVS', 'adapter', [0.0, 0.0, 0.0], [0.0, -0.0, 0.0])
  ('CS_EIN_LINKS_UNTEN', 'adapter', [0.0, 0.0, -36.0], [0.0, -90.0, 0.0])
  ('CS_EIN_RECHTS_UNTEN', 'adapter', [0.0, 0.0, -36.0], [90.0, -0.0, -90.0])
  ('CS_EIN_LINKS_OBEN', 'adapter', [0.0, 0.0, -36.0], [-90.0, -0.0, 90.0])
  ('CS_EIN_RECHTS_OBEN', 'adapter', [0.0, 0.0, -36.0], [0.0, 90.0, 180.0])
  ('CS_EIN', 'adapter', [17.0, 0.0, -36.0], [0.0, -90.0, -90.0])
  ('CS_EIN_0_0_180', 'adapter', [17.0, 0.0, -36.0], [0.0, 90.0, 90.0])
  ('CS_EIN_0_90_0', 'adapter', [17.0, 0.0, -36.0], [180.0, -0.0, 90.0])
  ('CS_EIN_0_180_0', 'adapter', [17.0, 0.0, -36.0], [90.0, 90.0, 0.0])
  ('CS_SVS', 'adapter', [0.0, 0.0, 0.0], [0.0, -0.0, 0.0])
  ('CS_EIN_LINKS', 'adapter', [11.8, 0.0, 0.0], [90.0, 0.0, 90.0])
  ('CS_EIN_RECHTS', 'adapter', [11.8, 0.0, 0.0], [-90.0, 0.0, -90.0])
  ('CS_EIN_UNTEN', 'adapter', [11.8, 0.0, 0.0], [0.0, -90.0, 0.0])
  ('CS_EIN_OBEN', 'adapter', [11.8, 0.0, 0.0], [0.0, 90.0, 180.0])
  ('CS_EIN', 'adapter', [11.8, 0.0, 1888.0], [90.0, 0.0, 90.0])
  ('CS_EIN_90_180_0', 'adapter', [11.8, 0.0, 1888.0], [180.0, 0.0, -90.0])
  ('CS_EIN_90_0_0', 'adapter', [11.8, 0.0, 1888.0], [180.0, -0.0, 90.0])
  ('CS_EIN_QUER', 'adapter', [11.8, 0.0, 0.0], [90.0, 0.0, 90.0])
  ('CS_EIN_QUER_270_180_90x', 'adapter', [11.8, 0.0, 0.0], [90.0, 90.0, 0.0])
  ('CS_EIN_QUER_90_0_90', 'adapter', [11.8, 0.0, 1888.0], [0.0, -90.0, -90.0])
  ('CS_EIN_QUER_270_180_90', 'adapter', [11.8, 0.0, 1888.0], [90.0, 90.0, 0.0])
  ('CS_SVS', 'adapter', [0.0, 0.0, 0.0], [0.0, -0.0, 0.0])
  ('CS_EIN_LINKS', 'adapter', [11.8, 0.0, 0.0], [90.0, 0.0, 90.0])
  ('CS_EIN_RECHTS', 'adapter', [11.8, 0.0, 0.0], [-90.0, 0.0, -90.0])
  ('CS_EIN_UNTEN', 'adapter', [11.8, 0.0, 0.0], [0.0, -90.0, 0.0])
  ('CS_EIN_OBEN', 'adapter', [11.8, 0.0, 0.0], [0.0, 90.0, 180.0])
  ('CS_EIN', 'adapter', [11.8, 0.0, 1888.0], [90.0, 0.0, 90.0])
  ('CS_EIN_90_180_0', 'adapter', [11.8, 0.0, 1888.0], [180.0, 0.0, -90.0])
  ('CS_EIN_90_0_0', 'adapter', [11.8, 0.0, 1888.0], [180.0, -0.0, 90.0])
  ('CS_EIN_QUER', 'adapter', [11.8, 0.0, 0.0], [90.0, 0.0, 90.0])
  ('CS_EIN_QUER_270_180_90x', 'adapter', [11.8, 0.0, 0.0], [90.0, 90.0, 0.0])
  ('CS_EIN_QUER_90_0_90', 'adapter', [11.8, 0.0, 1888.0], [0.0, -90.0, -90.0])
  ('CS_EIN_QUER_270_180_90', 'adapter', [11.8, 0.0, 1888.0], [90.0, 90.0, 0.0])
  ('CS_SVS', 'adapter', [0.0, 0.0, 0.0], [0.0, -0.0, 0.0])
  ('CS_EIN_LINKS', 'adapter', [11.8, 0.0, 0.0], [90.0, 0.0, 90.0])
  ('CS_EIN_RECHTS', 'adapter', [11.8, 0.0, 0.0], [-90.0, 0.0, -90.0])
  ('CS_EIN_UNTEN', 'adapter', [11.8, 0.0, 0.0], [0.0, -90.0, 0.0])
  ('CS_EIN_OBEN', 'adapter', [11.8, 0.0, 0.0], [0.0, 90.0, 180.0])
  ('CS_EIN', 'adapter', [11.8, 0.0, 41.0], [90.0, 0.0, 90.0])
  ('CS_EIN_90_180_0', 'adapter', [11.8, 0.0, 41.0], [180.0, 0.0, -90.0])
  ('CS_EIN_90_0_0', 'adapter', [11.8, 0.0, 41.0], [180.0, -0.0, 90.0])
  ('CS_EIN_QUER', 'adapter', [11.8, 0.0, 0.0], [90.0, 0.0, 90.0])
  ('CS_EIN_QUER_270_180_90x', 'adapter', [11.8, 0.0, 0.0], [90.0, 90.0, 0.0])
  ('CS_EIN_QUER_90_0_90', 'adapter', [11.8, 0.0, 41.0], [0.0, -90.0, -90.0])
  ('CS_EIN_QUER_270_180_90', 'adapter', [11.8, 0.0, 41.0], [90.0, 90.0, 0.0])
  ('CS_SVS', 'adapter', [0.0, 0.0, 0.0], [0.0, -0.0, 0.0])
  ('CS_EIN_LINKS', 'adapter', [11.8, 0.0, 0.0], [90.0, 0.0, 90.0])
  ('CS_EIN_RECHTS', 'adapter', [11.8, 0.0, 0.0], [-90.0, 0.0, -90.0])
  ('CS_EIN_UNTEN', 'adapter', [11.8, 0.0, 0.0], [0.0, -90.0, 0.0])
  ('CS_EIN_OBEN', 'adapter', [11.8, 0.0, 0.0], [0.0, 90.0, 180.0])
  ('CS_EIN', 'adapter', [11.8, 0.0, 41.0], [90.0, 0.0, 90.0])
  ('CS_EIN_90_180_0', 'adapter', [11.8, 0.0, 41.0], [180.0, 0.0, -90.0])
  ('CS_EIN_90_0_0', 'adapter', [11.8, 0.0, 41.0], [180.0, -0.0, 90.0])
  ('CS_EIN_QUER', 'adapter', [11.8, 0.0, 0.0], [90.0, 0.0, 90.0])
  ('CS_EIN_QUER_270_180_90x', 'adapter', [11.8, 0.0, 0.0], [90.0, 90.0, 0.0])
  ('CS_EIN_QUER_90_0_90', 'adapter', [11.8, 0.0, 41.0], [0.0, -90.0, -90.0])
  ('CS_EIN_QUER_270_180_90', 'adapter', [11.8, 0.0, 41.0], [90.0, 90.0, 0.0])


grep -rn "CS_OUT\|CS_EIN_L\|CS_EIN_R\|CS_SELECT" /Users/marcus.hinz/projects/adesso-cpq/packages/frontend/src --include='*.ts' --include='*.vue' -l | head; echo ---; grep -rn "CS_OUT_L_0\|CS_EIN_START" /Users/marcus.hinz/projects/adesso-cpq/packages/frontend/src -r | head -20

Find code references to left/right PMI names


grep -rln "CS_" /Users/marcus.hinz/projects/adesso-cpq/packages/frontend/src /Users/marcus.hinz/projects/adesso-cpq/packages/core/src 2>/dev/null | head; echo '--- configurator/modules ---'; grep -rln "CS_\|pmi" /Users/marcus.hinz/projects/adesso-cpq/packages/frontend/src --include='*.ts' 2>/dev/null | head -20

Find PMI name references in cpq code


Show PMI name usage in processors


/Users/marcus.hinz/projects/adesso-cpq/packages/frontend/src/configurator/events/eventData.ts:24:        // target group. The drag CS (CS_LINKS/CS_RECHTS) fixes the side; the handle ids fix the
/Users/marcus.hinz/projects/adesso-cpq/packages/frontend/src/configurator/events/DefaultCommandProcessor.ts:289:                            { selector: ".name-CS_EIN_VORNE", dropPoints: [`.name-CS_EIN_HINTEN:not(${subject} .name-CS_EIN_HINTEN)${openOnly}`] },
/Users/marcus.hinz/projects/adesso-cpq/packages/frontend/src/configurator/events/DefaultCommandProcessor.ts:290:                            { selector: ".name-CS_EIN_HINTEN", dropPoints: [`.name-CS_EIN_VORNE:not(${subject} .name-CS_EIN_VORNE)${openOnly}`] },
/Users/marcus.hinz/projects/adesso-cpq/packages/frontend/src/configurator/events/DefaultCommandProcessor.ts:411:                                                selector: `.name-CS_EIN_VORNE${openOnly}`,
/Users/marcus.hinz/projects/adesso-cpq/packages/frontend/src/configurator/events/DefaultCommandProcessor.ts:413:                                                    `.name-CS_EIN_HINTEN:not(${groupSelector} .name-CS_EIN_HINTEN)${openOnly}`,
/Users/marcus.hinz/projects/adesso-cpq/packages/frontend/src/configurator/events/DefaultCommandProcessor.ts:417:                                                selector: `.name-CS_EIN_HINTEN${openOnly}`,
/Users/marcus.hinz/projects/adesso-cpq/packages/frontend/src/configurator/events/DefaultCommandProcessor.ts:419:                                                    `.name-CS_EIN_VORNE:not(${groupSelector} .name-CS_EIN_VORNE)${openOnly}`,
/Users/marcus.hinz/projects/adesso-cpq/packages/frontend/src/configurator/model/GroupProcessor.ts:39:    // the two parts share orientation — the plain left/right case (CS_LINKS/CS_RECHTS carry no rotation).
/Users/marcus.hinz/projects/adesso-cpq/packages/frontend/src/configurator/model/GroupProcessor.ts:623:    // Most points carry no rotation (CS_LINKS/CS_RECHTS = [0,0,0] → identity); the post/branch points
/Users/marcus.hinz/projects/adesso-cpq/packages/frontend/src/configurator/model/GroupProcessor.ts:624:    // (CS_EIN_*) carry the angle that turns a part onto them.


grep -rn "name-CS" /Users/marcus.hinz/projects/adesso-cpq/packages/frontend/src --include='*.ts' | grep -v test | head -30; echo ---; grep -rn "CS_LINKS\|CS_RECHTS" /Users/marcus.hinz/projects/adesso-cpq/packages/frontend/src --include='*.ts' | grep -v "//" | head

List all PMI selectors used by placement code