@adatechnology/game-floorplan-structure 0.0.0-stage → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/registry.ts","../src/geometry.ts","../src/presets.ts","../src/construction.ts","../src/locales/en.json","../src/locales/pt-BR.json","../src/types.ts","../src/density.ts","../src/structure/builder.ts","../src/structure/legacy-key.ts","../src/structure/context.ts","../src/structure/balconies.ts","../src/structure/canvas.ts","../src/structure/extras.ts","../src/structure/floor-deck.ts","../src/structure/foundation.ts","../src/structure/plates.ts","../src/structure/porch.ts","../src/structure/porch-roof.ts","../src/structure/roof.ts","../src/structure/stairs.ts","../src/structure/openings.ts","../src/structure/steps.ts","../src/structure/tank-parts.ts","../src/structure/upper-floor.ts","../src/structure/walls.ts","../src/structure/index.ts","../src/utilities/content-tables.ts","../src/utilities/content.ts","../src/utilities/shared.ts","../src/utilities/wall-points.ts","../src/utilities/electrical-outlets.ts","../src/utilities/electrical-entrance.ts","../src/utilities/electrical-circuits.ts","../src/utilities/electrical.ts","../src/utilities/gas.ts","../src/utilities/plumbing.ts","../src/utilities/solar.ts","../src/utilities/index.ts","../src/utilities/outbuildings.ts","../src/water-tank.ts","../src/viewer-layer.ts","../src/register.ts","../src/to-destructible-spec.ts","../src/loads.ts","../src/wall-detail/index.ts","../src/wall-detail/apply.ts","../src/wall-detail/courses.ts","../src/wall-detail/panels.ts","../src/wall-specimen.ts","../src/index.ts"],"sourcesContent":["import type { JointKind } from '@adatechnology/game-contracts'\n\nimport type { Construction, ConstructionSystem, PlanContext, StructureExtras } from './types'\n\n/** What a wall system is made of and how its parts are tied. Timber systems sit on joists, carry the roof on timber plates and have wooden porch posts. */\nexport interface ConstructionSystemDef {\n /** Wall assembly of `game-destruction` (`registerAssembly`) the detailed wall is built from. Empty: no walls (a tent). */\n walls: string\n joints: Record<'wall' | 'slab' | 'beam' | 'column' | 'truss', JointKind>\n /** Thickness of the structural floor under each storey (m). */\n slabThickness: number\n /** Height of the top plate or bond beam (m). */\n plateThickness: number\n timber: boolean\n /** `rules`: bearing when external, under another wall or beside a porch; `bearing`: every wall (logs); `partition`: none (posts carry the roof). */\n wallRole: 'rules' | 'bearing' | 'partition'\n /** Solid fraction of a bearing wall in the structure weight (studs and air). */\n wallFill: number\n studs?: { spacing: number; section: string }\n}\n\nconst uniform = (joint: JointKind): ConstructionSystemDef['joints'] => ({ wall: joint, slab: joint, beam: joint, column: joint, truss: joint })\n\nexport const CONSTRUCTION_SYSTEMS = new Map<string, ConstructionSystemDef>([\n ['masonry', { walls: 'brick_wall_plastered', joints: { wall: 'mortar', slab: 'rebar', beam: 'mortar', column: 'rebar', truss: 'bolt' }, slabThickness: 0.12, plateThickness: 0.2, timber: false, wallRole: 'rules', wallFill: 1 }],\n ['wood_frame', { walls: 'wood_frame_wall', joints: uniform('nail'), slabThickness: 0.28, plateThickness: 0.1, timber: true, wallRole: 'rules', wallFill: 0.35, studs: { spacing: 0.4, section: '38x89' } }],\n ['log', { walls: 'log_wall', joints: { wall: 'bolt', slab: 'nail', beam: 'bolt', column: 'bolt', truss: 'bolt' }, slabThickness: 0.2, plateThickness: 0.1, timber: true, wallRole: 'bearing', wallFill: 1 }],\n ['improvised', { walls: 'sheet_metal_shack', joints: uniform('nail'), slabThickness: 0.2, plateThickness: 0.1, timber: true, wallRole: 'partition', wallFill: 1 }],\n ['canvas', { walls: '', joints: uniform('tie'), slabThickness: 0, plateThickness: 0, timber: false, wallRole: 'partition', wallFill: 1 }],\n])\n\n/** Adds or replaces a construction system (`id` is a `ConstructionSystem` or any name a construction refers to). */\nexport function registerConstructionSystem(id: ConstructionSystem | string, def: ConstructionSystemDef): void {\n CONSTRUCTION_SYSTEMS.set(id, def)\n}\n\nexport interface RoofCoveringDef {\n material: string\n /** How the covering is fixed to the trusses. */\n joint: JointKind\n}\n\nexport const ROOF_COVERINGS = new Map<string, RoofCoveringDef>([\n ['colonial', { material: 'ceramic', joint: 'resting' }],\n ['fiber_cement', { material: 'concrete', joint: 'bolt' }],\n ['slab', { material: 'concrete', joint: 'rebar' }],\n ['asphalt', { material: 'plastic', joint: 'nail' }],\n ['zinc', { material: 'steel', joint: 'nail' }],\n ['wood', { material: 'wood_soft', joint: 'nail' }],\n ['canvas', { material: 'fabric', joint: 'tie' }],\n ['thatch', { material: 'foliage', joint: 'tie' }],\n])\n\nexport function registerRoofCovering(id: string, def: RoofCoveringDef): void {\n ROOF_COVERINGS.set(id, def)\n}\n\nexport interface ConstructionBuild {\n construction: Construction\n extras?: StructureExtras\n}\nexport type ConstructionBuilder = (context: PlanContext) => ConstructionBuild\n\nexport const CONSTRUCTIONS = new Map<string, ConstructionBuilder>()\n\n/** Registers how a template's building is made: `TemplateDef.construction` names it. A template without one gets the masonry default. */\nexport function registerConstruction(id: string, builder: ConstructionBuilder): void {\n CONSTRUCTIONS.set(id, builder)\n}\n","import type { Rect, SourceWall } from './types'\n\nexport const WALL_THICKNESS = 0.15\n\nexport const round2 = (value: number): number => Math.round(value * 100) / 100\n\nexport function touches(a: Rect, b: Rect, tolerance: number): boolean {\n return a[0] < b[2] + tolerance && a[2] > b[0] - tolerance && a[1] < b[3] + tolerance && a[3] > b[1] - tolerance\n}\n\nexport function distanceBetween(a: Rect, b: Rect): number {\n return Math.hypot(Math.max(a[0] - b[2], b[0] - a[2], 0), Math.max(a[1] - b[3], b[1] - a[3], 0))\n}\n\nexport function unionOf(rects: readonly Rect[]): Rect {\n const out: Rect = [1e9, 1e9, -1e9, -1e9]\n for (const rect of rects) {\n out[0] = Math.min(out[0], rect[0])\n out[1] = Math.min(out[1], rect[1])\n out[2] = Math.max(out[2], rect[2])\n out[3] = Math.max(out[3], rect[3])\n }\n return out\n}\n\n/** The wall's centre line thickened to its box in the plan. */\nexport function wallBox(wall: Pick<SourceWall, 'u0' | 'v0' | 'u1' | 'v1' | 'thickness'>): Rect {\n const half = (wall.thickness ?? WALL_THICKNESS) / 2\n return [Math.min(wall.u0, wall.u1) - half, Math.min(wall.v0, wall.v1) - half, Math.max(wall.u0, wall.u1) + half, Math.max(wall.v0, wall.v1) + half]\n}\n\nexport const centreOf = (rect: Rect): [number, number] => [(rect[0] + rect[2]) / 2, (rect[1] + rect[3]) / 2]\n\n/** The nearest `count` of `candidates` to `target`, nearest first. */\nexport function nearestTo<T extends { aabb: Rect }>(target: Rect, candidates: readonly T[], count: number): T[] {\n return candidates.slice().sort((a, b) => distanceBetween(target, a.aabb) - distanceBetween(target, b.aabb)).slice(0, count)\n}\n","import type { Construction, FoundationType, StructureSource } from './types'\nimport { WALL_THICKNESS } from './geometry'\nimport { ROOF_COVERINGS } from './registry'\n\nconst SLAB_COVERING = 'slab'\nconst PLASTERED_FINISHES = ['plaster', 'partial_plaster']\n\n/** Masonry house of the engine's own templates: brick with plaster, concrete frame, tiles by facade; a unit in a building gets a flat slab roof. */\nexport function masonryConstruction(source: StructureSource): Construction {\n const unit = source.floorNumber !== undefined\n const covering = unit ? SLAB_COVERING : (source.facade.roof ?? 'colonial')\n const finish = source.facade.finish ?? 'roughcast'\n const budget = source.style === 'budget'\n const flat = unit || covering === SLAB_COVERING\n return {\n system: 'masonry',\n walls: { material: 'brick', cladding: PLASTERED_FINISHES.includes(finish) ? 'plaster' : null, finish, thickness: WALL_THICKNESS, ...(finish === 'exposed_block' ? { assembly: 'concrete_block_wall' } : {}) },\n floor: { material: budget ? 'concrete' : 'ceramic', finish: budget ? 'burnt_cement' : 'ceramic_tile' },\n roof: { material: ROOF_COVERINGS.get(covering)?.material ?? 'ceramic', covering, shape: flat ? 'slab' : 'gable', pitch: flat ? 0 : covering === 'colonial' ? 30 : 15, timber: 'wood_soft' },\n frame: { material: 'concrete', pillars: 'concrete', beams: 'concrete', slabs: 'concrete', timber: 'wood_soft', rebar: 'steel' },\n foundation: { type: unit ? 'building' : 'strip_footing', material: 'concrete', elevation: 0 },\n }\n}\n\nexport interface WoodFrameOptions {\n foundation?: 'basement' | 'crawl_space' | 'raft'\n covering?: string\n finish?: string\n /** Cladding of the outer face (default soft wood). */\n cladding?: string\n}\n\nconst FOUNDATIONS: Record<NonNullable<WoodFrameOptions['foundation']>, Construction['foundation']> = {\n basement: { type: 'basement', material: 'concrete', elevation: 0.5, depth: 2.4 },\n crawl_space: { type: 'crawl_space', material: 'concrete', elevation: 0.6 },\n raft: { type: 'raft', material: 'concrete', elevation: 0.2 },\n}\n\nconst TIMBER_FRAME: Construction['frame'] = { material: 'wood_soft', pillars: 'wood_soft', beams: 'wood_soft', slabs: 'plywood', timber: 'wood_soft', rebar: null }\n\n/** American wood frame house: 38x89 studs every 40 cm, plaster inside, wood outside, asphalt shingles. */\nexport function woodFrameConstruction(options: WoodFrameOptions = {}): Construction {\n const covering = options.covering ?? 'asphalt'\n return {\n system: 'wood_frame',\n walls: { material: 'wood_soft', interior: 'plaster', cladding: options.cladding ?? 'wood_soft', finish: options.finish ?? 'wood_siding', thickness: WALL_THICKNESS, studs: '38x89 every 40 cm', insulation: 'foam' },\n floor: { material: 'wood_hard', finish: 'wood_boards' },\n roof: { material: ROOF_COVERINGS.get(covering)?.material ?? 'plastic', covering, shape: 'gable', pitch: 28, timber: 'wood_soft', eave: 0.5 },\n frame: { ...TIMBER_FRAME },\n foundation: { ...FOUNDATIONS[options.foundation ?? 'raft'] },\n }\n}\n\nexport interface ChaletOptions {\n covering?: string\n finish?: string\n piles?: boolean\n}\n\n/** Mountain chalet: A-frame roof at 52 degrees with gables front and back, 38x140 studs. */\nexport function chaletConstruction(options: ChaletOptions = {}): Construction {\n const covering = options.covering ?? 'colonial'\n return {\n system: 'wood_frame',\n walls: { material: 'wood_soft', interior: 'wood_soft', cladding: 'wood_hard', finish: options.finish ?? 'vertical_boards', thickness: WALL_THICKNESS, studs: '38x140 every 40 cm' },\n floor: { material: 'wood_hard', finish: 'wood_boards' },\n roof: { material: ROOF_COVERINGS.get(covering)?.material ?? 'wood_soft', covering, shape: 'gable', pitch: 52, timber: 'wood_soft', eave: 0.8, axis: 'v', profile: 'a_frame', gables: ['front', 'back'] },\n frame: { ...TIMBER_FRAME },\n foundation: options.piles ? { type: 'piles', material: 'stone', elevation: 0.9 } : { type: 'raft', material: 'concrete', elevation: 0.2 },\n }\n}\n\n/** Log cabin: every wall is a stack of 26 cm logs, notched at the corners, on stone piles. */\nexport function logCabinConstruction(options: { covering?: string } = {}): Construction {\n const covering = options.covering ?? 'wood'\n return {\n system: 'log',\n walls: { material: 'wood_hard', interior: 'wood_hard', cladding: null, finish: 'log', thickness: WALL_THICKNESS, logDiameter: 0.26, joint: 'notched_corners' },\n floor: { material: 'wood_hard', finish: 'wood_boards' },\n roof: { material: ROOF_COVERINGS.get(covering)?.material ?? 'wood_soft', covering, shape: 'gable', pitch: 32, timber: 'wood_hard', eave: 0.6 },\n frame: { material: 'wood_hard', pillars: 'wood_hard', beams: 'wood_hard', slabs: 'wood_hard', timber: 'wood_hard', rebar: null },\n foundation: { type: 'piles', material: 'stone', elevation: 0.5 },\n }\n}\n\nexport interface ShackOptions {\n material?: 'wood' | 'zinc' | 'mixed'\n floor?: 'soil' | 'concrete'\n}\n\nconst MIXED_SCRAP = ['wood_soft', 'steel', 'plywood', 'steel', 'wood_soft']\n\n/** Shack of scrap boards and zinc sheets: timber posts carry the roof, the walls only close. */\nexport function shackConstruction(options: ShackOptions = {}): Construction {\n const material = options.material === 'zinc' ? 'steel' : 'wood_soft'\n const onSoil = options.floor === 'soil'\n return {\n system: 'improvised',\n walls: { material, interior: options.material === 'zinc' ? 'plywood' : material, cladding: null, finish: 'scrap', thickness: WALL_THICKNESS, ...(options.material === 'mixed' ? { mixed: MIXED_SCRAP } : {}) },\n floor: onSoil ? { material: 'soil', finish: 'packed_earth' } : { material: 'concrete', finish: 'burnt_cement' },\n roof: { material: 'steel', covering: 'zinc', shape: 'gable', pitch: 12, timber: 'wood_soft', eave: 0.3, fastening: 'nails_and_stones' },\n frame: { material: 'wood_soft', pillars: 'wood_soft', beams: 'wood_soft', slabs: 'concrete', timber: 'wood_soft', rebar: null },\n foundation: onSoil ? { type: 'ground', material: 'soil', elevation: 0 } : { type: 'raft', material: 'concrete', elevation: 0.08 },\n }\n}\n\n/** Camping: canvas over aluminium poles on the ground; there are no walls. */\nexport function campConstruction(): Construction {\n return {\n system: 'canvas',\n walls: { material: 'fabric', interior: 'fabric', cladding: null, finish: 'nylon', thickness: 0.002 },\n floor: { material: 'plastic', finish: 'waterproof_mat' },\n roof: { material: 'fabric', covering: 'canvas', shape: 'tent', pitch: 0, timber: 'aluminium', eave: 0 },\n frame: { material: 'aluminium', pillars: 'aluminium', beams: 'aluminium', slabs: 'plastic', timber: 'aluminium', rebar: null },\n foundation: { type: 'ground', material: 'soil', elevation: 0 },\n }\n}\n\n/** The construction a system gets on any plan when the options force it (`options.construction`). */\nexport function constructionOfSystem(system: string, source: StructureSource): Construction | undefined {\n const covering = source.facade.roof\n const keep = covering && covering !== SLAB_COVERING ? { covering } : {}\n switch (system) {\n case 'masonry':\n return masonryConstruction(source)\n case 'wood_frame':\n return woodFrameConstruction(keep)\n case 'log':\n return logCabinConstruction(keep)\n case 'improvised':\n return shackConstruction()\n case 'canvas':\n return campConstruction()\n default:\n return undefined\n }\n}\n\nexport type { FoundationType }\n","import { CONSTRUCTIONS } from './registry'\nimport type { ConstructionBuild } from './registry'\nimport { constructionOfSystem, masonryConstruction } from './presets'\nimport type { PlanContext, StructureSource, Tent } from './types'\n\n/** The construction of a plan: the one it already carries, else the masonry default of the engine's templates. */\nexport function resolveConstruction(source: StructureSource): ConstructionBuild {\n const extras = source.structureExtras ?? {}\n return { construction: source.construction ?? masonryConstruction(source), extras }\n}\n\nconst TENT_LABEL = /^tent_(dome|tunnel)(?:_|$)/\n\n/**\n * Tents of a plan whose template names the `canvas` construction and registers none of its own: one per room of type `tent`, standing on the room's footprint\n * (a label `tent_<kind>_<people>` names the kind, any other is a long tunnel) as high as the room's ceiling.\n */\nexport function tentsOf(source: StructureSource): Tent[] {\n const tents: Tent[] = []\n for (const room of source.rooms) {\n if (room.type !== 'tent' || room.floor !== 0 || !room.parts[0]) continue\n const { label } = room as { label?: unknown }\n tents.push({ id: room.id, kind: TENT_LABEL.exec(typeof label === 'string' ? label : '')?.[1] ?? 'tunnel', height: room.ceiling ?? source.floors[0]?.ceiling ?? 2.4, aabb: room.parts[0] })\n }\n return tents\n}\n\n/**\n * Picks the construction for a plan being generated: `options.construction` (a registered construction or a system name) wins over the template's\n * own (`TemplateDef.construction`), which wins over the masonry default.\n */\nexport function constructionFor(context: PlanContext): ConstructionBuild {\n const forced = context.options?.construction\n const named = typeof forced === 'string' ? forced : (context.template?.construction as string | undefined)\n if (named === undefined) return { construction: masonryConstruction(context.result) }\n const registered = CONSTRUCTIONS.get(named)\n if (registered) return registered(context)\n const preset = constructionOfSystem(named, context.result)\n if (preset) return { construction: preset, ...(named === 'canvas' ? { extras: { tents: tentsOf(context.result) } } : {}) }\n throw new Error(`Unknown construction \"${named}\": register it with registerConstruction`)\n}\n","{\n \"ui\": {\n \"structure_layer\": \"Structure\",\n \"structure_column_concrete\": \"Concrete pillar\",\n \"structure_column_steel\": \"Steel post\",\n \"structure_column_masonry\": \"Masonry pillar\",\n \"structure_column_wood\": \"Wood post\",\n \"structure_beam_concrete\": \"Bond beam / beam (concrete)\",\n \"structure_beam_wood\": \"Plate / beam (wood)\",\n \"structure_roof_frame\": \"Trusses, rafters and ridge (roof view)\"\n }\n}\n","{\n \"ui\": {\n \"structure_layer\": \"Estrutura\",\n \"structure_column_concrete\": \"Pilar de concreto\",\n \"structure_column_steel\": \"Poste de aço\",\n \"structure_column_masonry\": \"Pilar de alvenaria\",\n \"structure_column_wood\": \"Pilar de madeira\",\n \"structure_beam_concrete\": \"Cinta / viga (concreto)\",\n \"structure_beam_wood\": \"Prato / viga (madeira)\",\n \"structure_roof_frame\": \"Tesouras, caibros e cumeeira (vista do telhado)\"\n }\n}\n","import type { JointKind, MaterialId, StructureRole } from '@adatechnology/game-contracts'\n\n/** Axis-aligned rectangle `[u0, v0, u1, v1]` in the plan (metres). */\nexport type Rect = [number, number, number, number]\n\nexport type ConstructionSystem = 'masonry' | 'wood_frame' | 'log' | 'improvised' | 'canvas'\nexport type WallDetail = 'coarse' | 'panels' | 'units'\n/** What a structural part is called in a plan: a column is a pillar, `wall` is a bearing wall, `partition` a wall that only closes. */\nexport type PartRole = Exclude<StructureRole, 'foundation'>\n\nexport const GROUND = 'ground'\n\n/** A piece of the structure with its box in the plan, its height range and the mass it weighs. `y` is absolute: the ground floor sits at `foundation.elevation`. */\nexport interface StructurePart {\n id: string\n role: PartRole\n material: MaterialId\n aabb: Rect\n y0: number\n y1: number\n floor: number\n mass: number\n /** Part this one is cut out of (a pier of a wall in `panels` detail). */\n host?: string\n /** Wall assembly of `game-destruction` the part is built from in the destructible spec (layers, units, rebar, breach). */\n assembly?: string\n /** A brick, block or log: the unit of a wall (`units` detail, log courses), not a piece of it. */\n unit?: true\n /** Distance between repeated members (joists, ceiling joists). */\n spacing?: number\n /** `plate` (timber top plate) or `bond_beam` (masonry bond beam). */\n beamKind?: 'plate' | 'bond_beam'\n steps?: number\n door?: string\n /** Slab that is the roof (flat roof). */\n cover?: boolean\n /** Litres a tank holds. */\n liters?: number\n studs?: { spacing: number; section: string }\n pitch?: number\n tent?: string\n form?: string\n}\n\n/** `part` rests on `on` (`GROUND` or another part) through `joint`. `bears: false` ties the two without carrying load. */\nexport interface Support {\n part: string\n on: string\n joint: JointKind\n bears?: false\n}\n\nexport interface RoofPane {\n id: string\n aabb: Rect\n y0: number\n y1: number\n flat?: true\n}\n\nexport type RoofShape = 'gable' | 'slab' | 'tent'\n\nexport interface Roof {\n shape: RoofShape\n covering: string\n material: MaterialId\n pitch: number\n /** Floor the roof rests on. */\n bearingFloor: number\n panes: (RoofPane | string)[]\n trusses: number\n axis?: 'u' | 'v'\n ridge?: number\n eave?: number\n y0?: number\n aabb?: Rect\n}\n\n/** A window in a wall (the doors are gaps between walls: a lintel part bridges them). Heights are absolute. */\nexport interface Opening {\n id: string\n kind: 'window' | 'door'\n wall: string\n /** Along the wall (u for a wall along u, v for one along v). */\n from: number\n to: number\n y0: number\n y1: number\n}\n\nexport interface Structure {\n parts: StructurePart[]\n supports: Support[]\n openings: Opening[]\n /** Absolute height of the floor level of each storey. */\n levels: number[]\n elevation: number\n roof: Roof\n construction: Construction\n /** A reinforced concrete frame carries the building (apartments, commercial buildings, three storeys or more); the walls are infill. */\n framed: boolean\n}\n\nexport interface WallMaterials {\n material: MaterialId\n interior?: MaterialId\n cladding?: MaterialId | null\n finish?: string\n /** Wall assembly of `game-destruction` (default by system, and by finish in masonry). */\n assembly?: string\n thickness: number\n studs?: string\n /** Materials drawn per wall by a hash of its legacy key (the improvised shack). */\n mixed?: MaterialId[]\n [extra: string]: unknown\n}\n\nexport interface Construction {\n system: ConstructionSystem\n walls: WallMaterials\n floor: { material: MaterialId; finish: string }\n roof: {\n material: MaterialId\n covering: string\n shape: RoofShape\n pitch: number\n timber: MaterialId\n eave?: number\n axis?: 'u' | 'v'\n bearingFloor?: number\n profile?: string\n gables?: string[]\n fastening?: string\n }\n frame: { material: MaterialId; pillars: MaterialId; beams: MaterialId; slabs: MaterialId; timber: MaterialId; rebar: MaterialId | null }\n foundation: { type: FoundationType; material: MaterialId; elevation: number; depth?: number }\n guard?: MaterialId\n stairs?: MaterialId\n}\n\nexport type FoundationType = 'strip_footing' | 'building' | 'raft' | 'crawl_space' | 'piles' | 'basement' | 'ground'\n\nexport interface Chimney {\n kind: 'fireplace' | 'flue'\n material: MaterialId\n aabb: Rect\n flue?: boolean\n top?: number\n height?: number\n}\n\nexport interface Tent {\n id: string\n kind: string\n height: number\n aabb: Rect\n}\n\n/** What a construction needs besides walls and roof, from the template: a chimney, a well, an attic floor, tents. */\nexport interface StructureExtras {\n chimney?: Chimney\n well?: { aabb: Rect; height?: number }\n attic?: boolean\n tents?: Tent[]\n [extra: string]: unknown\n}\n\nexport interface TankPlatform {\n aabb: Rect\n baseY: number\n height: number\n thickness: number\n topY: number\n pillars: { u: number; v: number; side: number }[]\n ladder: boolean\n}\n\nexport interface WaterTank {\n id: 'water_tank'\n kind: 'water_tank'\n itemType: string\n place: 'slab' | 'attic' | 'raised_slab' | 'trestle' | string\n floor: number\n room: string\n u: number\n v: number\n y: number\n w: number\n d: number\n h: number\n capacity: number\n material?: MaterialId\n aabb: Rect\n platform?: TankPlatform\n /** Trestle tank (a stand of its own: rural water). */\n stand?: { pillars: { u: number; v: number; side: number }[]; material: MaterialId; height: number; baseJoint?: JointKind; joint?: JointKind; tie?: JointKind; braces?: boolean }\n}\n\n/** The fields of a generated plan the structure reads. */\nexport interface StructureSource {\n floors: { y0: number; ceiling: number }[]\n rooms: { id: string; type: string; floor: number; parts: Rect[]; ceiling?: number | null }[]\n walls: SourceWall[]\n doors: SourceDoor[]\n windows?: SourceWindow[]\n items: { id?: string; type: string; category?: string; floor: number; aabb?: Rect; link?: { from: number; to: number } | null }[]\n facade: { roof?: string; finish?: string; [extra: string]: unknown }\n style?: string\n template?: string\n lot?: unknown\n w: number\n d: number\n floorNumber?: number\n waterTank?: WaterTank | null\n construction?: Construction\n structureExtras?: StructureExtras\n [extra: string]: unknown\n}\n\nexport interface SourceWall {\n floor: number\n axis: 'u' | 'v'\n u0: number\n v0: number\n u1: number\n v1: number\n thickness?: number\n sides: string[]\n exterior: boolean\n type: string\n h?: number\n /** Gable wall: the plate does not sit on top of it. */\n gable?: boolean\n structureHeight?: number\n}\n\nexport interface SourceWindow {\n id: string\n floor: number\n axis: 'u' | 'v'\n /** Coordinate of the wall line across its axis. */\n pos: number\n /** Centre along the wall. */\n at: number\n width: number\n y0: number\n y1: number\n}\n\nexport interface SourceDoor {\n id: string\n floor: number\n a: string\n b: string\n exterior?: boolean\n model?: string\n type?: string\n u: number\n v: number\n width: number\n side?: string\n axis: 'u' | 'v'\n steps?: number\n}\n\nexport interface StructureOptions {\n construction?: Construction\n extras?: StructureExtras\n tank?: WaterTank | null\n /** The porch roof is carried by its posts alone (the tie to the house wall carries nothing). Default: when the detail is not `coarse`. */\n porchRoofOnPostsOnly?: boolean\n /** Gable roofs as rafters of each side and a ridge beam (a side falls with the wall it rests on) instead of whole trusses. Default: when the detail is not `coarse`. */\n rafterRoof?: boolean\n wallDetail?: WallDetail\n}\n\n/** What a construction builder and the tank get to see: the generated plan, its seed and the template. */\nexport interface PlanContext {\n result: StructureSource\n seed: number | string\n /** The template definition (`TemplateDef`) when known: it may carry `tank` and `tankLocation` hooks. */\n template?: Record<string, unknown>\n options?: { floors?: number; [extra: string]: unknown }\n}\n","import type { MaterialId } from '@adatechnology/game-contracts'\n\n/** kg/m3 the plan structure weighs its parts with (the table of the Visor de casas 3D; a material outside it weighs like soft wood). */\nexport const DENSITY: Readonly<Record<string, number>> = {\n steel: 7850, cast_iron: 7200, aluminium: 2700, copper: 8900, wood_soft: 500, wood_hard: 800, plywood: 600, mdf: 750, glass: 2500,\n tempered_glass: 2500, ceramic: 2000, concrete: 2400, brick: 1800, plaster: 1000, stone: 2600, plastic: 950, rubber: 1100, fabric: 400,\n foam: 30, leather: 900, paper: 800, foliage: 100, green_wood: 900, cactus: 700, flesh_fruit: 900, wax: 900, soil: 1600,\n}\nexport const DEFAULT_DENSITY = 500\n\nexport const densityOf = (material: MaterialId): number => DENSITY[material] ?? DEFAULT_DENSITY\n","import type { JointKind, MaterialId } from '@adatechnology/game-contracts'\n\nimport { densityOf } from '../density'\nimport { round2 } from '../geometry'\nimport { GROUND } from '../types'\nimport type { PartRole, Rect, StructurePart, Support } from '../types'\n\nexport type PartExtras = Partial<Pick<StructurePart, 'host' | 'spacing' | 'beamKind' | 'steps' | 'door' | 'cover' | 'studs' | 'pitch' | 'tent' | 'form' | 'liters' | 'assembly'>>\nexport interface PartOptions extends PartExtras {\n floor?: number\n /** Solid fraction of the box (studs, trusses, tile roofs). */\n fill?: number\n}\n\nexport interface PartDraft {\n id: string\n role: PartRole\n material: MaterialId\n aabb: Rect\n y0: number\n y1: number\n}\n\n/** Collects the parts and what each rests on. A part id is unique: a second one is a bug of the builder. */\nexport class StructureBuilder {\n readonly parts: StructurePart[] = []\n readonly supports: Support[] = []\n private readonly ids = new Set<string>()\n\n add(draft: PartDraft, options: PartOptions = {}): StructurePart {\n const { id, role, material, aabb, y0, y1 } = draft\n if (this.ids.has(id)) throw new Error(`Part repeated in the structure: ${id}`)\n this.ids.add(id)\n const { floor, fill, ...extras } = options\n const volume = Math.max(0, (aabb[2] - aabb[0]) * (aabb[3] - aabb[1]) * (y1 - y0)) * (fill ?? 1)\n const part: StructurePart = {\n id, role, material, aabb: aabb.map(round2) as Rect, y0: round2(y0), y1: round2(y1), floor: floor ?? 0,\n mass: Math.max(1, Math.round(volume * densityOf(material))),\n }\n for (const [key, value] of Object.entries(extras)) if (value !== undefined) (part as unknown as Record<string, unknown>)[key] = value\n this.parts.push(part)\n return part\n }\n\n rest(part: StructurePart | string, on: StructurePart | string, joint: JointKind): void {\n const id = typeof part === 'string' ? part : part.id\n const base = typeof on === 'string' ? on : on.id\n this.supports.push({ part: id, on: base === GROUND ? GROUND : base, joint })\n }\n\n has(id: string): boolean {\n return this.ids.has(id)\n }\n\n find(id: string): StructurePart | undefined {\n return this.parts.find((part) => part.id === id)\n }\n}\n","/** The string hash of the floor plan engine (`engine.hashString`), copied so that this package never imports the engine at run time. */\nexport function hashLegacyKey(key: string): number {\n let hash = 1779033703 ^ key.length\n for (let i = 0; i < key.length; i++) {\n hash = Math.imul(hash ^ key.charCodeAt(i), 3432918353)\n hash = (hash << 13) | (hash >>> 19)\n }\n hash = Math.imul(hash ^ (hash >>> 16), 2246822507)\n hash = Math.imul(hash ^ (hash >>> 13), 3266489909)\n return (hash ^ (hash >>> 16)) >>> 0\n}\n","import type { MaterialId } from '@adatechnology/game-contracts'\n\nimport { unionOf, wallBox, round2 } from '../geometry'\nimport { CONSTRUCTION_SYSTEMS } from '../registry'\nimport type { ConstructionSystemDef } from '../registry'\nimport { GROUND } from '../types'\nimport type { Construction, PartRole, Rect, Roof, StructureExtras, StructurePart, StructureSource, WaterTank, SourceWall } from '../types'\nimport { StructureBuilder } from './builder'\nimport { hashLegacyKey } from './legacy-key'\n\nexport const OPEN_ROOM_TYPES: readonly string[] = ['balcony', 'terrace', 'porch']\nconst GUARD_HEIGHT = 1.1\n\nexport interface BuildWall extends SourceWall {\n id: string\n /** The id the Visor de casas 3D gave the wall (`w<floor>_<index>`); seeded choices hash it so old seeds keep their draws. */\n legacyKey: string\n role: PartRole\n material: MaterialId\n box: Rect\n}\n\nexport interface PorchPosts {\n posts: StructurePart[]\n ceilingY: number\n}\n\ntype Base = StructurePart | typeof GROUND | undefined\n\n/** Everything the steps that build the structure share: the plan, the construction, the parts so far and what each storey rests on. */\nexport interface BuildContext {\n source: StructureSource\n construction: Construction\n system: ConstructionSystemDef\n extras: StructureExtras\n tank: WaterTank | null\n builder: StructureBuilder\n porchRoofOnPostsOnly: boolean\n /** Gable roofs are built as rafters of each side plus a ridge beam, so a side falls with the wall it rests on. */\n rafterRoof: boolean\n floorCount: number\n isUnit: boolean\n elevation: number\n isTimber: boolean\n walls: BuildWall[]\n wallParts: Map<string, StructurePart>\n carriers: Map<number, StructurePart[]>\n plates: Map<number, StructurePart[]>\n pillars: Map<number, StructurePart[]>\n porches: Map<string, PorchPosts>\n base0: Base\n houseBox: Rect\n topBox: Rect\n hasBasement: boolean\n topSlab?: StructurePart\n ceilingJoists?: StructurePart[]\n roof: Roof\n level(floor: number): number\n ceilingOf(floor: number): number\n topOf(floor: number): number\n rectsOf(floor: number, exclude?: readonly string[]): Rect[]\n baseOf(floor: number): Base\n}\n\nexport interface ContextOptions {\n porchRoofOnPostsOnly: boolean\n rafterRoof: boolean\n}\n\nexport function createContext(source: StructureSource, construction: Construction, extras: StructureExtras, tank: WaterTank | null, options: ContextOptions): BuildContext {\n const system = CONSTRUCTION_SYSTEMS.get(construction.system)\n if (!system) throw new Error(`Unknown construction system \"${construction.system}\"`)\n const floorCount = source.floors.length\n const isUnit = source.floorNumber !== undefined\n const elevation = construction.foundation.elevation || 0\n const level = (floor: number): number => round2(elevation + (source.floors[floor]?.y0 ?? 0))\n const ceilingOf = (floor: number): number => source.floors[floor]?.ceiling ?? 0\n const topOf = (floor: number): number => (floor < floorCount - 1 && !isUnit ? level(floor + 1) - system.slabThickness : level(floor) + ceilingOf(floor))\n const rectsOf = (floor: number, exclude: readonly string[] = []): Rect[] =>\n source.rooms.filter((room) => room.floor === floor && !exclude.includes(room.type)).flatMap((room) => room.parts)\n const builder = new StructureBuilder()\n const context: BuildContext = {\n source, construction, system, extras, tank, builder, porchRoofOnPostsOnly: options.porchRoofOnPostsOnly, rafterRoof: options.rafterRoof, floorCount, isUnit, elevation, isTimber: system.timber,\n walls: [], wallParts: new Map(), carriers: new Map(), plates: new Map(), pillars: new Map(), porches: new Map(), base0: GROUND,\n houseBox: [0, 0, 0, 0], topBox: [0, 0, 0, 0], hasBasement: false,\n roof: { shape: 'slab', covering: '', material: '', pitch: 0, bearingFloor: 0, panes: [], trusses: 0 },\n level, ceilingOf, topOf, rectsOf,\n baseOf: (floor) => (floor === 0 ? context.base0 : builder.find(`slab_${floor}`)),\n }\n const closed = rectsOf(0, ['balcony', 'porch'])\n context.houseBox = unionOf(closed.length ? closed : rectsOf(0))\n context.walls = classifyWalls(context)\n return context\n}\n\nconst isBearingOnTop = (wall: BuildWall, walls: readonly BuildWall[]): boolean => {\n const along = (w: SourceWall, pick: (a: number, b: number) => number): number => (w.axis === 'u' ? pick(w.u0, w.u1) : pick(w.v0, w.v1))\n const across = (w: SourceWall): number => (w.axis === 'u' ? w.v0 : w.u0)\n return walls.some(\n (other) =>\n other.floor === wall.floor + 1 && other.type === 'wall' && other.axis === wall.axis && Math.abs(across(other) - across(wall)) < 0.2 &&\n Math.min(along(wall, Math.max), along(other, Math.max)) - Math.max(along(wall, Math.min), along(other, Math.min)) > 0.3,\n )\n}\n\nfunction roleOf(context: BuildContext, wall: BuildWall, walls: readonly BuildWall[], porchIds: ReadonlySet<string>): PartRole {\n if (wall.type === 'railing') return 'partition'\n const { wallRole } = context.system\n if (wallRole === 'bearing') return 'wall'\n if (wallRole === 'partition') return 'partition'\n const bearingFloor = context.construction.roof.bearingFloor ?? context.floorCount - 1\n if (wall.floor > bearingFloor) return 'partition'\n if (wall.exterior || wall.sides.some((id) => porchIds.has(id))) return 'wall'\n return wall.floor < context.floorCount - 1 && isBearingOnTop(wall, walls) ? 'wall' : 'partition'\n}\n\nfunction materialOf(context: BuildContext, wall: BuildWall): MaterialId {\n const { walls, guard } = context.construction\n if (wall.type === 'railing') return guard ?? (context.isTimber ? 'wood_soft' : 'steel')\n if (walls.mixed?.length) return walls.mixed[hashLegacyKey(wall.legacyKey) % walls.mixed.length] as MaterialId\n return wall.exterior ? walls.material : (walls.interior ?? walls.material)\n}\n\nfunction classifyWalls(context: BuildContext): BuildWall[] {\n const countByFloor = new Map<number, number>()\n const all: BuildWall[] = context.source.walls.map((wall) => {\n const index = countByFloor.get(wall.floor) ?? 0\n countByFloor.set(wall.floor, index + 1)\n return { ...wall, id: `wall_${wall.floor}_${index}`, legacyKey: `w${wall.floor}_${index}`, role: 'wall', material: '', box: wallBox(wall) }\n })\n const built = all.filter((wall) => wall.type === 'wall' || wall.type === 'railing')\n const porchIds = new Set(context.source.rooms.filter((room) => room.type === 'porch').map((room) => room.id))\n for (const wall of built) {\n wall.role = roleOf(context, wall, built, porchIds)\n wall.material = materialOf(context, wall)\n }\n return built\n}\n\nexport const guardHeightOf = (wall: BuildWall): number => wall.h || GUARD_HEIGHT\n","import { GROUND } from '../types'\nimport { unionOf } from '../geometry'\nimport type { BuildContext } from './context'\n\n/** Cantilevered balconies: a slab tied to the floor of its storey, or on a pillar of its own when it is at ground level. */\nexport function addBalconies(context: BuildContext): void {\n const { builder, construction, system } = context\n for (const room of context.source.rooms.filter((r) => r.type === 'balcony' && r.floor >= 0)) {\n const floor = room.floor\n const box = unionOf(room.parts)\n const base = floor === 0 ? undefined : context.baseOf(floor)\n const deck = builder.add({ id: `slab_${floor}_${room.id}`, role: 'slab', material: construction.frame.slabs, aabb: box, y0: context.level(floor) - system.slabThickness, y1: context.level(floor) }, { floor })\n if (base) {\n builder.rest(deck, base, system.joints.slab)\n continue\n }\n const pillar = builder.add({ id: `balcony_column_${room.id}`, role: 'column', material: construction.frame.pillars, aabb: [box[0] - 0.08, box[1] - 0.08, box[0] + 0.08, box[1] + 0.08], y0: 0, y1: context.level(floor) - system.slabThickness }, { floor: 0 })\n builder.rest(pillar, GROUND, 'rebar')\n builder.rest(deck, pillar, 'rebar')\n }\n}\n","import { GROUND } from '../types'\nimport type { Construction, Rect, Roof, Structure, StructureExtras } from '../types'\nimport { StructureBuilder } from './builder'\n\nconst GROUNDSHEET = 0.02\n\n/** Camping tents: canvas over aluminium poles, a plastic groundsheet and pegs with guy ropes; no walls. */\nexport function buildCanvasStructure(construction: Construction, extras: StructureExtras): Structure {\n const builder = new StructureBuilder()\n const panes: string[] = []\n for (const tent of extras.tents ?? []) {\n const [u0, v0, u1, v1] = tent.aabb\n const centreU = (u0 + u1) / 2\n const centreV = (v0 + v1) / 2\n const sheet = builder.add({ id: `groundsheet_${tent.id}`, role: 'slab', material: 'plastic', aabb: tent.aabb, y0: 0, y1: GROUNDSHEET }, { floor: 0, tent: tent.id })\n builder.rest(sheet, GROUND, 'resting')\n const canvas = builder.add({ id: `canvas_${tent.id}`, role: 'roof', material: 'fabric', aabb: tent.aabb, y0: GROUNDSHEET, y1: tent.height }, { floor: 0, fill: 0.04, tent: tent.id, form: tent.kind })\n panes.push(canvas.id)\n const poles: [Rect, number][] =\n tent.kind === 'tunnel'\n ? [0.25, 0.75].map((fraction, k): [Rect, number] => [[u0 + (u1 - u0) * fraction - 0.015, v0 + 0.05, u0 + (u1 - u0) * fraction + 0.015, v1 - 0.05], k])\n : [[[u0 + 0.05, centreV - 0.015, u1 - 0.05, centreV + 0.015], 0], [[centreU - 0.015, v0 + 0.05, centreU + 0.015, v1 - 0.05], 1]]\n for (const [aabb, k] of poles) {\n const pole = builder.add({ id: `pole_${tent.id}_${k}`, role: 'column', material: construction.frame.pillars, aabb, y0: GROUNDSHEET, y1: tent.height - GROUNDSHEET }, { floor: 0, fill: 0.05, tent: tent.id })\n builder.rest(pole, GROUND, 'resting')\n builder.rest(canvas, pole, 'tie')\n }\n const corners: [number, number][] = [[u0 - 0.2, v0 - 0.2], [u1 + 0.2, v0 - 0.2], [u0 - 0.2, v1 + 0.2], [u1 + 0.2, v1 + 0.2]]\n corners.forEach(([u, v], k) => {\n const peg = builder.add({ id: `peg_${tent.id}_${k}`, role: 'column', material: 'wood_soft', aabb: [u - 0.02, v - 0.02, u + 0.02, v + 0.02], y0: 0, y1: 0.2 }, { floor: 0 })\n builder.rest(peg, GROUND, 'nail')\n builder.rest(canvas, peg, 'tie')\n })\n }\n const roof: Roof = { shape: 'tent', covering: 'canvas', material: 'fabric', pitch: 0, bearingFloor: 0, panes, trusses: 0 }\n return { parts: builder.parts, supports: builder.supports, levels: [0], elevation: 0, roof, construction, framed: false, openings: [] }\n}\n","import { GROUND } from '../types'\nimport { round2, touches } from '../geometry'\nimport type { BuildContext } from './context'\n\nconst CHIMNEY_CLEARANCE_ABOVE_RIDGE = 0.6\n\n/** A masonry chimney or a stove flue next to the house, tied to the wall it touches, rising above the ridge. */\nexport function addChimney(context: BuildContext): void {\n const chimney = context.extras.chimney\n if (!chimney) return\n const { builder } = context\n const top = context.floorCount - 1\n const ridge = context.roof.ridge || context.level(top) + context.ceilingOf(top)\n const height = Math.max(ridge, chimney.top || 0) + CHIMNEY_CLEARANCE_ABOVE_RIDGE\n const part = builder.add({ id: 'chimney', role: 'column', material: chimney.material || 'brick', aabb: chimney.aabb, y0: chimney.flue ? context.level(0) : 0, y1: height }, { floor: 0, fill: chimney.flue ? 0.15 : 0.7 })\n if (chimney.flue) builder.rest(part, context.base0 ?? GROUND, 'resting')\n else builder.rest(part, GROUND, 'mortar')\n const walls = builder.parts.filter((wall) => wall.role === 'wall' && wall.floor === 0 && !wall.id.startsWith('basement') && touches(wall.aabb, part.aabb, 0.1))\n for (const wall of walls) builder.rest(part, wall, 'bolt')\n chimney.height = round2(height)\n}\n\n/** The stone mouth of a well. */\nexport function addWell(context: BuildContext): void {\n const well = context.extras.well\n if (!well) return\n const part = context.builder.add({ id: 'well', role: 'column', material: 'stone', aabb: well.aabb, y0: -0.5, y1: well.height || 0.9 }, { floor: 0, fill: 0.5 })\n context.builder.rest(part, GROUND, 'mortar')\n}\n","import type { JointKind, MaterialId } from '@adatechnology/game-contracts'\n\nimport { distanceBetween, touches } from '../geometry'\nimport type { Rect, StructurePart } from '../types'\nimport type { BuildContext } from './context'\n\nexport interface JoistOptions {\n floor: number\n box: Rect\n thickness: number\n carriers: readonly StructurePart[]\n material: MaterialId\n joint: JointKind\n suffix?: string\n}\n\nconst JOIST_PITCH = 0.6\n\n/** Joists every 0.6 m under the floor of `floor`, each resting on what touches it from below (or the nearest carrier). */\nexport function addJoists(context: BuildContext, options: JoistOptions): StructurePart[] {\n const { floor, box, thickness, carriers, material, joint, suffix = '' } = options\n const length = box[2] - box[0]\n const depth = box[3] - box[1]\n const alongU = length >= depth\n const span = alongU ? length : depth\n const count = Math.max(2, Math.round(span / JOIST_PITCH) + 1)\n const top = context.level(floor) - thickness * 0.15\n const out: StructurePart[] = []\n for (let k = 0; k < count; k++) {\n const centre = (alongU ? box[0] : box[1]) + 0.05 + (k * (span - 0.1)) / (count - 1)\n const aabb: Rect = alongU ? [centre - 0.025, box[1], centre + 0.025, box[3]] : [box[0], centre - 0.025, box[2], centre + 0.025]\n const joist = context.builder.add({ id: `joist_${floor}${suffix}_${k}`, role: 'beam', material, aabb, y0: context.level(floor) - thickness, y1: top }, { floor, fill: 1, spacing: JOIST_PITCH })\n out.push(joist)\n const below = carriers.filter((carrier) => carrier.y0 <= top + 0.05)\n const touching = below.filter((carrier) => touches(aabb, carrier.aabb, 0.2))\n const pool = below.length ? below : carriers\n const chosen = touching.length ? touching : pool.slice().sort((a, b) => distanceBetween(aabb, a.aabb) - distanceBetween(aabb, b.aabb)).slice(0, 1)\n for (const carrier of chosen) context.builder.rest(joist, carrier, joint)\n }\n return out\n}\n\n/** The deck (floor boards, slab) of `floor` on its joists. */\nexport function addDeck(context: BuildContext, id: string, material: MaterialId, options: Pick<JoistOptions, 'floor' | 'box' | 'thickness' | 'joint'>, joists: readonly StructurePart[]): StructurePart {\n const { floor, box, thickness, joint } = options\n const deck = context.builder.add({ id, role: 'slab', material, aabb: box, y0: context.level(floor) - thickness * 0.15, y1: context.level(floor) }, { floor })\n for (const joist of joists) context.builder.rest(deck, joist, joint)\n return deck\n}\n","import type { StructurePart, Rect } from '../types'\nimport { GROUND } from '../types'\nimport type { BuildContext } from './context'\nimport { addDeck, addJoists } from './floor-deck'\n\nconst raft = (context: BuildContext, thickness: number, material: string): StructurePart => {\n const [u0, v0, u1, v1] = context.houseBox\n const part = context.builder.add({ id: 'foundation_raft', role: 'slab', material, aabb: [u0 - 0.1, v0 - 0.1, u1 + 0.1, v1 + 0.1], y0: 0, y1: thickness }, { floor: 0 })\n context.builder.rest(part, GROUND, 'resting')\n return part\n}\n\n/** A unit in a building: the building's pillars go down to the ground and carry a slab under the unit. */\nfunction addBuildingBase(context: BuildContext): void {\n const { builder, construction, houseBox: box } = context\n const corners: [number, number][] = [[box[0], box[1]], [box[2], box[1]], [box[0], box[3]], [box[2], box[3]]]\n const top = context.level(0) - context.system.slabThickness\n const pillars = corners.map(([u, v], k) => {\n const pillar = builder.add({ id: `building_column_${k}`, role: 'column', material: construction.frame.pillars, aabb: [u - 0.15, v - 0.15, u + 0.15, v + 0.15], y0: 0, y1: top }, { floor: 0 })\n builder.rest(pillar, GROUND, 'rebar')\n return pillar\n })\n const slab = builder.add({ id: 'slab_base', role: 'slab', material: construction.frame.slabs, aabb: box, y0: top, y1: context.level(0) }, { floor: 0 })\n for (const pillar of pillars) builder.rest(slab, pillar, 'rebar')\n context.base0 = slab\n}\n\nfunction addBasement(context: BuildContext): StructurePart[] {\n const { builder, houseBox: box, elevation } = context\n const depth = context.construction.foundation.depth || 2.4\n const floor = builder.add({ id: 'basement_slab', role: 'slab', material: 'concrete', aabb: box, y0: -depth - 0.15, y1: -depth }, { floor: -1 })\n builder.rest(floor, GROUND, 'resting')\n const sides: [string, Rect][] = [\n ['front', [box[0], box[1] - 0.1, box[2], box[1] + 0.1]], ['back', [box[0], box[3] - 0.1, box[2], box[3] + 0.1]],\n ['left', [box[0] - 0.1, box[1], box[0] + 0.1, box[3]]], ['right', [box[2] - 0.1, box[1], box[2] + 0.1, box[3]]],\n ]\n const carried: StructurePart[] = []\n for (const [name, aabb] of sides) {\n const wall = builder.add({ id: `basement_wall_${name}`, role: 'wall', material: 'concrete', aabb, y0: -depth, y1: elevation }, { floor: -1 })\n builder.rest(wall, GROUND, 'rebar')\n builder.rest(wall, floor, 'rebar')\n carried.push(wall)\n }\n const count = Math.max(1, Math.floor((box[2] - box[0]) / 3.0))\n for (let k = 0; k < count; k++) {\n const u = box[0] + ((k + 0.5) * (box[2] - box[0])) / count\n const v = (box[1] + box[3]) / 2\n const column = builder.add({ id: `basement_column_${k}`, role: 'column', material: 'concrete', aabb: [u - 0.15, v - 0.15, u + 0.15, v + 0.15], y0: -depth, y1: elevation - 0.3 }, { floor: -1 })\n builder.rest(column, floor, 'rebar')\n builder.rest(column, GROUND, 'rebar')\n carried.push(column)\n }\n context.hasBasement = true\n return carried\n}\n\n/** Pier footings every ~2 m with a base beam through each line of them (crawl space, piles). */\nfunction addPiers(context: BuildContext): StructurePart[] {\n const { builder, houseBox: box, elevation, construction } = context\n const columns = Math.max(2, Math.ceil((box[2] - box[0]) / 2.0) + 1)\n const rows = Math.max(2, Math.ceil((box[3] - box[1]) / 2.0) + 1)\n const height = Math.max(0.1, elevation - context.system.slabThickness - 0.15)\n const piers: StructurePart[] = []\n for (let j = 0; j < rows; j++) {\n for (let i = 0; i < columns; i++) {\n const u = box[0] + (i * (box[2] - box[0])) / (columns - 1)\n const v = box[1] + (j * (box[3] - box[1])) / (rows - 1)\n const pier = builder.add({ id: `footing_pier_${j}_${i}`, role: 'column', material: construction.foundation.material || 'concrete', aabb: [u - 0.12, v - 0.12, u + 0.12, v + 0.12], y0: 0, y1: height }, { floor: 0 })\n builder.rest(pier, GROUND, 'resting')\n piers.push(pier)\n }\n }\n const alongU = box[2] - box[0] >= box[3] - box[1]\n const beams: StructurePart[] = []\n const lines = alongU ? rows : columns\n for (let line = 0; line < lines; line++) {\n const at = alongU ? box[1] + (line * (box[3] - box[1])) / (rows - 1) : box[0] + (line * (box[2] - box[0])) / (columns - 1)\n const aabb: Rect = alongU ? [box[0], at - 0.07, box[2], at + 0.07] : [at - 0.07, box[1], at + 0.07, box[3]]\n const beam = builder.add({ id: `base_beam_${line}`, role: 'beam', material: construction.frame.timber, aabb, y0: height, y1: elevation - context.system.slabThickness }, { floor: 0 })\n const centre = (q: StructurePart): number => (alongU ? (q.aabb[1] + q.aabb[3]) / 2 : (q.aabb[0] + q.aabb[2]) / 2)\n for (const pier of piers.filter((q) => Math.abs(centre(q) - at) < 0.05)) builder.rest(beam, pier, 'bolt')\n beams.push(beam)\n }\n return beams\n}\n\nfunction addRaisedFloor(context: BuildContext): void {\n const { construction, system, houseBox: box } = context\n const carriers = construction.foundation.type === 'basement' ? addBasement(context) : addPiers(context)\n const thickness = system.slabThickness\n const joists = addJoists(context, { floor: 0, box, thickness, carriers, material: construction.frame.timber, joint: construction.foundation.type === 'basement' ? 'bolt' : 'nail' })\n const deckMaterial = context.isTimber ? (construction.floor.material === 'wood_hard' ? 'wood_hard' : 'plywood') : construction.frame.slabs\n context.base0 = addDeck(context, 'slab_0', deckMaterial, { floor: 0, box, thickness, joint: 'nail' }, joists)\n}\n\n/** Foundation and floor of the ground storey: raft, crawl space, piles, basement, a unit's building base or nothing (strip footing). */\nexport function addFoundation(context: BuildContext): void {\n const { type, material } = context.construction.foundation\n if (context.isUnit) return addBuildingBase(context)\n if (type === 'raft') context.base0 = raft(context, Math.max(0.1, context.elevation), material || 'concrete')\n else if (type === 'crawl_space' || type === 'piles' || type === 'basement') addRaisedFloor(context)\n else if (context.isTimber && type !== 'ground') context.base0 = raft(context, Math.max(0.12, context.elevation), 'concrete')\n}\n","import { GROUND } from '../types'\nimport type { Rect, StructurePart } from '../types'\nimport { round2, touches } from '../geometry'\nimport type { BuildContext, BuildWall } from './context'\n\nconst MAX_GAP_WITHIN_RUN = 3.2\nconst POST_SPACING = 2.4\nconst POST_SIDE = 0.05\n\ninterface Run {\n from: number\n to: number\n walls: BuildWall[]\n}\n\nconst alongOf = (wall: BuildWall, pick: (a: number, b: number) => number): number => (wall.axis === 'u' ? pick(wall.u0, wall.u1) : pick(wall.v0, wall.v1))\nconst acrossOf = (wall: BuildWall): number => (wall.axis === 'u' ? wall.v0 : wall.u0)\n\n/** Continuous runs of exterior wall on one line and height: a plate or bond beam runs along each. */\nfunction runsOf(context: BuildContext, walls: readonly BuildWall[], floor: number): Run[][] {\n const lines = new Map<string, BuildWall[]>()\n for (const wall of walls) {\n if (!wall.exterior || wall.type !== 'wall') continue\n const top = round2(context.wallParts.get(wall.id)!.y1)\n const key = `${floor}|${wall.axis}|${acrossOf(wall).toFixed(2)}|${top.toFixed(2)}`\n lines.set(key, [...(lines.get(key) ?? []), wall])\n }\n return [...lines.values()].map((line) => {\n const sorted = line.slice().sort((a, b) => alongOf(a, Math.min) - alongOf(b, Math.min))\n const runs: Run[] = []\n for (const wall of sorted) {\n const from = alongOf(wall, Math.min)\n const to = alongOf(wall, Math.max)\n const last = runs[runs.length - 1]\n if (last && from - last.to <= MAX_GAP_WITHIN_RUN) {\n last.to = Math.max(last.to, to)\n last.walls.push(wall)\n } else runs.push({ from, to, walls: [wall] })\n }\n return runs\n })\n}\n\n/** Timber posts of a shack: the corner and every ~2.4 m carry the plate; the sheet walls only close. */\nfunction addShackPosts(context: BuildContext, run: Run, plate: StructurePart, floor: number, index: number): StructurePart[] {\n const first = run.walls[0]!\n const across = acrossOf(first)\n const top = context.wallParts.get(first.id)!.y1\n const count = Math.max(1, Math.ceil((run.to - run.from) / POST_SPACING))\n const posts: StructurePart[] = []\n for (let k = 0; k <= count; k++) {\n const along = run.from + ((run.to - run.from) * k) / count\n const [u, v] = first.axis === 'u' ? [along, across] : [across, along]\n const half = 0.05 + POST_SIDE / 2\n const post = context.builder.add({ id: `post_${floor}_${index}_${k}`, role: 'column', material: 'wood_soft', aabb: [u - half, v - half, u + half, v + half], y0: context.level(floor), y1: top }, { floor })\n const base = context.baseOf(floor)\n if (base === GROUND || !base) context.builder.rest(post, GROUND, 'tie')\n else context.builder.rest(post, base, 'nail')\n context.builder.rest(plate, post, 'nail')\n posts.push(post)\n }\n return posts\n}\n\nexport interface PlatesResult {\n plates: StructurePart[]\n pillars: StructurePart[]\n}\n\nfunction addPlates(context: BuildContext, walls: readonly BuildWall[], floor: number): PlatesResult {\n const { builder, system, construction } = context\n const plates: StructurePart[] = []\n const pillars: StructurePart[] = []\n let counter = 0\n for (const runs of runsOf(context, walls, floor)) {\n for (const run of runs) {\n const first = run.walls[0]!\n const half = (first.thickness ?? 0.15) / 2\n const across = acrossOf(first)\n const top = context.wallParts.get(first.id)!.y1\n const aabb: Rect = first.axis === 'u' ? [run.from - half, across - half, run.to + half, across + half] : [across - half, run.from - half, across + half, run.to + half]\n const material = context.isTimber ? construction.frame.timber : construction.frame.beams\n const plate = builder.add({ id: `plate_${floor}_${counter++}`, role: 'beam', material, aabb, y0: top, y1: top + system.plateThickness }, { floor, beamKind: context.isTimber ? 'plate' : 'bond_beam' })\n if (construction.system === 'improvised') pillars.push(...addShackPosts(context, run, plate, floor, counter))\n else for (const wall of run.walls) builder.rest(plate, context.wallParts.get(wall.id)!, system.joints.beam)\n plates.push(plate)\n }\n }\n return { plates, pillars }\n}\n\nfunction cornerPoints(walls: readonly BuildWall[]): [number, number][] {\n const ends = walls\n .filter((wall) => wall.exterior && wall.type === 'wall')\n .flatMap((wall): [number, number, string][] =>\n wall.axis === 'u'\n ? [[Math.min(wall.u0, wall.u1), wall.v0, 'u'], [Math.max(wall.u0, wall.u1), wall.v0, 'u']]\n : [[wall.u0, Math.min(wall.v0, wall.v1), 'v'], [wall.u0, Math.max(wall.v0, wall.v1), 'v']],\n )\n const points: [number, number][] = []\n for (const a of ends) {\n const joinsOtherAxis = ends.some((b) => b[2] !== a[2] && Math.hypot(a[0] - b[0], a[1] - b[1]) < 0.12)\n if (joinsOtherAxis && !points.some((q) => Math.hypot(q[0] - a[0], q[1] - a[1]) < 0.12)) points.push([a[0], a[1]])\n }\n return points\n}\n\n/** Concrete corner pillars of a masonry storey where two exterior walls of different axes meet; they run up to the highest plate they touch. */\nfunction addCornerPillars(context: BuildContext, walls: readonly BuildWall[], floor: number, plates: readonly StructurePart[]): StructurePart[] {\n const { builder } = context\n const topOfFloor = context.topOf(floor)\n return cornerPoints(walls).map(([u, v], k) => {\n const box: Rect = [u - 0.1, v - 0.1, u + 0.1, v + 0.1]\n const top = Math.max(topOfFloor, ...plates.filter((plate) => touches(plate.aabb, box, 0.05)).map((plate) => plate.y0))\n const pillar = builder.add({ id: `column_${floor}_${k}`, role: 'column', material: context.construction.frame.pillars, aabb: box, y0: context.level(floor), y1: top }, { floor })\n const base = context.baseOf(floor)\n builder.rest(pillar, base === GROUND || !base ? GROUND : base, 'rebar')\n for (const plate of plates.filter((p) => touches(p.aabb, pillar.aabb, 0.05))) builder.rest(plate, pillar, 'rebar')\n return pillar\n })\n}\n\n/** Plates (bond beams) over the exterior walls of a storey and, in masonry, the corner pillars; records what carries the storey above. */\nexport function addPlatesAndPillars(context: BuildContext, floor: number): void {\n const walls = context.walls.filter((wall) => wall.floor === floor)\n const { plates, pillars } = addPlates(context, walls, floor)\n if (context.construction.system === 'masonry') pillars.push(...addCornerPillars(context, walls, floor, plates))\n context.pillars.set(floor, pillars)\n context.plates.set(floor, plates)\n const innerBearing = walls.filter((wall) => wall.role === 'wall' && !wall.exterior).map((wall) => context.wallParts.get(wall.id)!)\n context.carriers.set(floor, [...plates, ...pillars, ...innerBearing])\n}\n","import { GROUND } from '../types'\nimport type { Rect, StructurePart } from '../types'\nimport { touches } from '../geometry'\nimport type { BuildContext } from './context'\n\nconst POST_HALF = 0.08\nconst FOOTING_HALF = 0.12\nconst BEAM_DEPTH = 0.2\nconst BEAM_WIDTH = 0.16\n\n/** Footings and posts under the porch roof: two at the front corners and one more in the middle of a wide porch. */\nfunction addPosts(context: BuildContext, porchId: string, rect: Rect, deck: StructurePart, floor: number): StructurePart[] {\n const { builder, construction } = context\n const hasUpperFloor = floor < context.floorCount - 1\n const ceilingY = hasUpperFloor ? context.level(floor + 1) - context.system.slabThickness : context.level(floor) + context.ceilingOf(floor)\n const deckDepth = Math.min(0.2, Math.max(0.06, context.elevation * 0.5))\n const spots: [number, number][] = [[rect[0] + 0.1, rect[1] + 0.1], [rect[2] - 0.1, rect[1] + 0.1]]\n if (rect[2] - rect[0] > 4.5) spots.push([(rect[0] + rect[2]) / 2, rect[1] + 0.1])\n const posts = spots.map(([u, v], k) => {\n const footing = builder.add({ id: `porch_footing_${porchId}_${k}`, role: 'column', material: 'concrete', aabb: [u - FOOTING_HALF, v - FOOTING_HALF, u + FOOTING_HALF, v + FOOTING_HALF], y0: 0, y1: context.level(floor) - deckDepth }, { floor: 0 })\n builder.rest(footing, GROUND, 'resting')\n builder.rest(deck, footing, 'resting')\n const material = context.isTimber ? construction.frame.timber : construction.frame.pillars\n const post = builder.add({ id: `porch_post_${porchId}_${k}`, role: 'column', material, aabb: [u - POST_HALF, v - POST_HALF, u + POST_HALF, v + POST_HALF], y0: context.level(floor), y1: hasUpperFloor ? ceilingY - BEAM_DEPTH : ceilingY }, { floor })\n builder.rest(post, deck, context.isTimber ? 'nail' : 'rebar')\n return post\n })\n context.porches.set(porchId, { posts, ceilingY })\n return posts\n}\n\n/** With a storey above the porch, a head beam over the posts and two side beams carry the floor of that storey. */\nfunction addUpperBeams(context: BuildContext, porchId: string, rect: Rect, posts: StructurePart[], floor: number): void {\n const { builder, construction } = context\n const material = context.isTimber ? construction.frame.timber : construction.frame.beams\n const joint = context.isTimber ? 'nail' : 'rebar'\n const ceilingY = context.porches.get(porchId)!.ceilingY\n const y0 = ceilingY - BEAM_DEPTH\n const carriers = context.carriers.get(floor)!\n const head = builder.add({ id: `porch_beam_${porchId}`, role: 'beam', material, aabb: [rect[0], rect[1], rect[2], rect[1] + BEAM_WIDTH], y0, y1: ceilingY }, { floor })\n for (const post of posts) builder.rest(head, post, joint)\n carriers.push(head)\n const sides: [string, Rect, StructurePart][] = [['e', [rect[0], rect[1], rect[0] + BEAM_WIDTH, rect[3]], posts[0]!], ['d', [rect[2] - BEAM_WIDTH, rect[1], rect[2], rect[3]], posts[1]!]]\n for (const [name, aabb, post] of sides) {\n const side = builder.add({ id: `porch_beam_${porchId}_${name}`, role: 'beam', material, aabb, y0, y1: ceilingY }, { floor })\n builder.rest(side, post, joint)\n builder.rest(side, head, joint)\n for (const wall of context.walls.filter((w) => w.floor === floor && w.role === 'wall' && touches(w.box, side.aabb, 0.3))) builder.rest(side, context.wallParts.get(wall.id)!, joint)\n carriers.push(side)\n }\n}\n\n/** Deck, footings, posts (concrete in masonry, wood in timber houses) and, with a storey above, the beams of every porch of the storey. */\nexport function addPorches(context: BuildContext, floor: number): void {\n const { builder, construction } = context\n for (const room of context.source.rooms.filter((r) => r.type === 'porch' && r.floor === floor)) {\n const rect = room.parts[0]!\n const base = context.baseOf(floor)\n const deckDepth = Math.min(0.2, Math.max(0.06, context.elevation * 0.5))\n const deck = builder.add({ id: `porch_floor_${room.id}`, role: 'slab', material: context.isTimber ? 'wood_soft' : construction.frame.slabs, aabb: rect, y0: context.level(floor) - deckDepth, y1: context.level(floor) }, { floor })\n if (base && base !== GROUND) builder.rest(deck, base, context.isTimber ? 'nail' : context.system.joints.slab)\n const posts = addPosts(context, room.id, rect, deck, floor)\n if (floor < context.floorCount - 1) addUpperBeams(context, room.id, rect, posts, floor)\n }\n}\n","import { ROOF_COVERINGS } from '../registry'\nimport type { BuildContext } from './context'\n\nconst ROOF_RISE = 0.6\n\n/** A porch under the top storey has a roof of its own, resting on its posts and on the wall of the house. */\nexport function addPorchRoofs(context: BuildContext): void {\n const { builder, construction } = context\n for (const room of context.source.rooms.filter((r) => r.type === 'porch')) {\n const floor = room.floor\n const rect = room.parts[0]!\n const posts = context.porches.get(room.id)\n if (floor !== context.floorCount - 1 || !posts) continue\n const material = ROOF_COVERINGS.get(construction.roof.covering)?.material ?? 'ceramic'\n const roof = builder.add({ id: `porch_roof_${room.id}`, role: 'roof', material, aabb: [rect[0] - 0.3, rect[1] - 0.5, rect[2] + 0.3, rect[3]], y0: posts.ceilingY, y1: posts.ceilingY + ROOF_RISE }, { floor })\n for (const post of posts.posts) builder.rest(roof, post, context.isTimber ? 'nail' : 'bolt')\n const housewalls = context.walls.filter((w) => w.floor === floor && !w.exterior && w.sides.includes(room.id) && w.type === 'wall')\n for (const wall of housewalls) {\n if (context.porchRoofOnPostsOnly) builder.supports.push({ part: roof.id, on: wall.id, joint: 'nail', bears: false })\n else builder.rest(roof, context.wallParts.get(wall.id)!, 'nail')\n }\n }\n}\n","import type { JointKind } from '@adatechnology/game-contracts'\n\nimport { distanceBetween, round2, touches, unionOf } from '../geometry'\nimport { ROOF_COVERINGS } from '../registry'\nimport type { Rect, RoofPane, StructurePart } from '../types'\nimport type { BuildContext } from './context'\nimport { OPEN_ROOM_TYPES } from './context'\n\nconst TRUSS_PITCH = 1.2\nconst DEFAULT_PITCH = 20\nconst DEFAULT_EAVE = 0.4\nconst CLOSED_ONLY: readonly string[] = [...OPEN_ROOM_TYPES, 'void']\n\ninterface RoofUnit {\n suffix: string\n box: Rect\n floor: number\n annex: boolean\n}\n\n/** The main roof, plus an own roof for every room of a lower storey that the storey above does not cover (a ground floor wider than the upper one). */\nfunction roofUnits(context: BuildContext, bearing: number): RoofUnit[] {\n const units: RoofUnit[] = [{ suffix: '', box: context.topBox, floor: bearing, annex: false }]\n if (context.floorCount <= 1 || context.isUnit || bearing !== context.floorCount - 1) return units\n for (let floor = 0; floor < context.floorCount - 1; floor++) {\n const above = context.source.rooms.filter((room) => room.floor === floor + 1).flatMap((room) => room.parts)\n const rooms = context.source.rooms.filter((room) => room.floor === floor && !OPEN_ROOM_TYPES.includes(room.type) && room.type !== 'void' && room.type !== 'elevator')\n for (const room of rooms) {\n const area = room.parts.reduce((total, part) => total + (part[2] - part[0]) * (part[3] - part[1]), 0)\n const covered = room.parts.reduce((total, part) => total + above.reduce((sum, other) => sum + Math.max(0, Math.min(part[2], other[2]) - Math.max(part[0], other[0])) * Math.max(0, Math.min(part[3], other[3]) - Math.max(part[1], other[1])), 0), 0)\n if (covered < area * 0.7) units.push({ suffix: `_${room.id}`, box: unionOf(room.parts), floor, annex: true })\n }\n }\n return units\n}\n\n/** Everything that carries the roof of one unit: the plates at its height, the pillars and the inner bearing walls under it. */\nfunction roofCarriers(context: BuildContext, unit: RoofUnit): StructurePart[] {\n const platesHere = context.plates.get(unit.floor) ?? []\n const allPlates = [...context.plates.values()].flat()\n const eaveHeight = platesHere.length ? Math.max(...platesHere.map((plate) => plate.y1)) : 0\n const plates = allPlates.filter((plate) => Math.abs(plate.y1 - eaveHeight) < 0.4 && touches(plate.aabb, unit.box, 0.3))\n const pillars = (context.pillars.get(unit.floor) ?? []).filter((pillar) => touches(pillar.aabb, unit.box, 0.3))\n const walls = context.walls.filter((wall) => wall.floor === unit.floor && wall.role === 'wall' && !wall.exterior && touches(wall.box, unit.box, 0.2)).map((wall) => context.wallParts.get(wall.id)!)\n return [...plates, ...pillars, ...walls]\n}\n\nfunction addFlatRoof(context: BuildContext, unit: RoofUnit, carriers: StructurePart[]): RoofPane {\n const { builder, construction, system } = context\n const top = context.level(unit.floor) + context.ceilingOf(unit.floor)\n const [u0, v0, u1, v1] = unit.box\n const slab = builder.add({ id: `slab_top${unit.suffix}`, role: 'slab', material: construction.frame.slabs, aabb: [u0 - 0.15, v0 - 0.15, u1 + 0.15, v1 + 0.15], y0: top, y1: top + 0.12 }, { floor: unit.floor, cover: true })\n for (const carrier of carriers.length ? carriers : (context.plates.get(unit.floor) ?? [])) builder.rest(slab, carrier, system.joints.slab)\n if (unit.suffix === '') context.topSlab = slab\n return { id: slab.id, aabb: slab.aabb, y0: slab.y0, y1: slab.y1, flat: true }\n}\n\nfunction addTrusses(context: BuildContext, unit: RoofUnit, carriers: StructurePart[], geometry: GableGeometry): StructurePart[] {\n const { builder, construction, system } = context\n const { box } = unit\n const { axis, length, eave, rise, eaveY } = geometry\n const count = Math.max(2, Math.ceil(length / TRUSS_PITCH) + 1)\n const trusses: StructurePart[] = []\n for (let k = 0; k < count; k++) {\n const at = (axis === 'u' ? box[0] : box[1]) + (k * length) / (count - 1)\n const aabb: Rect = axis === 'u' ? [at - 0.04, box[1] - eave * 0.5, at + 0.04, box[3] + eave * 0.5] : [box[0] - eave * 0.5, at - 0.04, box[2] + eave * 0.5, at + 0.04]\n const truss = builder.add({ id: `truss${unit.suffix}_${k}`, role: 'beam', material: construction.frame.timber, aabb, y0: eaveY, y1: eaveY + rise }, { floor: unit.floor, fill: 0.25 })\n const touching = carriers.filter((carrier) => touches(aabb, carrier.aabb, 0.2) && carrier.role !== 'slab')\n const chosen = touching.length ? touching : carriers.slice().sort((a, b) => distanceBetween(aabb, a.aabb) - distanceBetween(aabb, b.aabb)).slice(0, 2)\n for (const carrier of chosen) builder.rest(truss, carrier, system.joints.truss)\n trusses.push(truss)\n }\n return trusses\n}\n\ninterface GableGeometry {\n axis: 'u' | 'v'\n length: number\n eave: number\n rise: number\n eaveY: number\n}\n\nfunction geometryOf(context: BuildContext, unit: RoofUnit): GableGeometry {\n const { box } = unit\n const roof = context.construction.roof\n const platesHere = context.plates.get(unit.floor) ?? []\n const width = box[2] - box[0]\n const depth = box[3] - box[1]\n const axis = roof.axis ?? (width >= depth ? 'u' : 'v')\n const span = axis === 'u' ? depth : width\n const pitch = unit.annex ? Math.min(roof.pitch || DEFAULT_PITCH, 20) : roof.pitch || DEFAULT_PITCH\n const eaveY = platesHere.length ? Math.max(...platesHere.map((plate) => plate.y1)) : context.level(unit.floor) + context.ceilingOf(unit.floor)\n return { axis, length: axis === 'u' ? width : depth, eave: roof.eave ?? DEFAULT_EAVE, rise: round2((span / 2) * Math.tan((pitch * Math.PI) / 180)), eaveY }\n}\n\ninterface Frames {\n all: StructurePart[]\n sideA: StructurePart[]\n sideB: StructurePart[]\n}\n\n/** Rafters of each side at the truss positions, each resting only on what is under its own side, and a ridge beam that rests on all of them. */\nfunction addRafters(context: BuildContext, unit: RoofUnit, carriers: StructurePart[], geometry: GableGeometry): Frames {\n const { builder, construction, system } = context\n const { box } = unit\n const { axis, length, eave, rise, eaveY } = geometry\n const count = Math.max(2, Math.ceil(length / TRUSS_PITCH) + 1)\n const middle = axis === 'u' ? (box[1] + box[3]) / 2 : (box[0] + box[2]) / 2\n const frames: Frames = { all: [], sideA: [], sideB: [] }\n for (let k = 0; k < count; k++) {\n const at = (axis === 'u' ? box[0] : box[1]) + (k * length) / (count - 1)\n const halves: [string, Rect][] =\n axis === 'u'\n ? [['a', [at - 0.04, box[1] - eave * 0.5, at + 0.04, middle]], ['b', [at - 0.04, middle, at + 0.04, box[3] + eave * 0.5]]]\n : [['a', [box[0] - eave * 0.5, at - 0.04, middle, at + 0.04]], ['b', [middle, at - 0.04, box[2] + eave * 0.5, at + 0.04]]]\n for (const [side, aabb] of halves) {\n const rafter = builder.add({ id: `rafter${unit.suffix}_${side}_${k}`, role: 'beam', material: construction.frame.timber, aabb, y0: eaveY, y1: eaveY + rise }, { floor: unit.floor, fill: 0.25 })\n const touching = carriers.filter((carrier) => touches(aabb, carrier.aabb, 0.2) && carrier.role !== 'slab')\n const chosen = touching.length ? touching : carriers.slice().sort((x, y) => distanceBetween(aabb, x.aabb) - distanceBetween(aabb, y.aabb)).slice(0, 2)\n for (const carrier of chosen) builder.rest(rafter, carrier, system.joints.truss)\n frames.all.push(rafter)\n if (side === 'a') frames.sideA.push(rafter)\n else frames.sideB.push(rafter)\n }\n }\n if (!unit.annex) {\n const ridgeBox: Rect = axis === 'u' ? [box[0] - eave, middle - 0.05, box[2] + eave, middle + 0.05] : [middle - 0.05, box[1] - eave, middle + 0.05, box[3] + eave]\n const ridge = builder.add({ id: `ridge${unit.suffix}`, role: 'beam', material: construction.frame.timber, aabb: ridgeBox, y0: eaveY + rise - 0.12, y1: eaveY + rise }, { floor: unit.floor })\n for (const rafter of frames.all) builder.rest(ridge, rafter, system.joints.truss)\n }\n context.roof.trusses += count\n return frames\n}\n\nfunction panesOf(unit: RoofUnit, geometry: GableGeometry): Rect[] {\n const [u0, v0, u1, v1] = unit.box\n const { eave, axis } = geometry\n if (unit.annex) return [[u0 - eave, v0 - eave, u1 + eave, v1 + eave]]\n const midV = (v0 + v1) / 2\n const midU = (u0 + u1) / 2\n return axis === 'u'\n ? [[u0 - eave, v0 - eave, u1 + eave, midV], [u0 - eave, midV, u1 + eave, v1 + eave]]\n : [[u0 - eave, v0 - eave, midU, v1 + eave], [midU, v0 - eave, u1 + eave, v1 + eave]]\n}\n\nfunction coarseFrames(context: BuildContext, unit: RoofUnit, carriers: StructurePart[], geometry: GableGeometry): Frames {\n const trusses = addTrusses(context, unit, carriers, geometry)\n context.roof.trusses += trusses.length\n return { all: trusses, sideA: trusses, sideB: trusses }\n}\n\nfunction addGableRoof(context: BuildContext, unit: RoofUnit, carriers: StructurePart[], covering: JointKind): RoofPane[] {\n const { builder, construction } = context\n const geometry = geometryOf(context, unit)\n const frames: Frames = context.rafterRoof ? addRafters(context, unit, carriers, geometry) : coarseFrames(context, unit, carriers, geometry)\n const panes: RoofPane[] = []\n panesOf(unit, geometry).forEach((aabb, k) => {\n const name = unit.annex ? 'annex' : k === 0 ? 'a' : 'b'\n const options = { floor: unit.floor, fill: construction.roof.covering === 'colonial' ? 0.12 : 0.05, ...(construction.roof.pitch === undefined ? {} : { pitch: construction.roof.pitch }) }\n const pane = builder.add({ id: `roof${unit.suffix}_${name}`, role: 'roof', material: construction.roof.material, aabb, y0: geometry.eaveY, y1: geometry.eaveY + geometry.rise + 0.05 }, options)\n const carried = unit.annex || !context.rafterRoof ? frames.all : k === 0 ? frames.sideA : frames.sideB\n for (const frame of carried) builder.rest(pane, frame, covering)\n panes.push({ id: pane.id, aabb: pane.aabb, y0: pane.y0, y1: pane.y1 })\n })\n if (!unit.annex) {\n const roof = context.roof\n roof.axis = geometry.axis\n roof.ridge = round2(geometry.eaveY + geometry.rise)\n roof.eave = geometry.eave\n roof.y0 = round2(geometry.eaveY)\n roof.aabb = [unit.box[0] - geometry.eave, unit.box[1] - geometry.eave, unit.box[2] + geometry.eave, unit.box[3] + geometry.eave].map(round2) as Rect\n }\n return panes\n}\n\n/** Roof of a timber house: ceiling joists every 0.6 m tie the trusses and carry the attic floor. */\nfunction addCeilingJoists(context: BuildContext): void {\n const { builder, construction } = context\n const bearing = context.roof.bearingFloor\n const rects = context.rectsOf(bearing, CLOSED_ONLY)\n const box = unionOf(rects.length ? rects : [context.topBox])\n const carriers = [...(context.plates.get(bearing) ?? []), ...context.walls.filter((w) => w.floor === bearing && w.role === 'wall' && !w.exterior).map((w) => context.wallParts.get(w.id)!)]\n const length = box[2] - box[0]\n const depth = box[3] - box[1]\n const alongU = length >= depth\n const span = alongU ? length : depth\n const count = Math.max(2, Math.round(span / 0.6) + 1)\n const beamTops = carriers.filter((carrier) => carrier.role === 'beam').map((carrier) => carrier.y0)\n const y0 = carriers.length ? Math.max(...beamTops, context.level(bearing) + 1) : context.topOf(bearing)\n const joists: StructurePart[] = []\n for (let k = 0; k < count; k++) {\n const at = (alongU ? box[0] : box[1]) + 0.05 + (k * (span - 0.1)) / (count - 1)\n const aabb: Rect = alongU ? [at - 0.025, box[1], at + 0.025, box[3]] : [box[0], at - 0.025, box[2], at + 0.025]\n const joist = builder.add({ id: `ceiling_joist_${k}`, role: 'beam', material: construction.frame.timber, aabb, y0: y0 - 0.02, y1: y0 + context.system.plateThickness - 0.02 }, { floor: bearing, spacing: 0.6 })\n const beams = carriers.filter((carrier) => carrier.role === 'beam' && touches(aabb, carrier.aabb, 0.2))\n for (const carrier of beams.length ? beams : carriers.slice(0, 2)) builder.rest(joist, carrier, 'nail')\n joists.push(joist)\n }\n context.ceilingJoists = joists\n}\n\n/** The roof over the top storey: a flat slab or trusses and two panes, and the ceiling joists of a timber house. */\nexport function addRoof(context: BuildContext): void {\n const { construction } = context\n const covering = ROOF_COVERINGS.get(construction.roof.covering)\n const bearing = construction.roof.bearingFloor ?? context.floorCount - 1\n const open = context.rectsOf(context.floorCount - 1, OPEN_ROOM_TYPES)\n const topRects = context.rectsOf(context.floorCount - 1, CLOSED_ONLY)\n const body = unionOf(open.length ? open : topRects)\n context.topBox = context.floorCount - 1 === bearing ? body : unionOf(context.rectsOf(bearing, OPEN_ROOM_TYPES))\n context.roof = { shape: construction.roof.shape, covering: construction.roof.covering, material: construction.roof.material, pitch: construction.roof.pitch || 0, bearingFloor: bearing, panes: [], trusses: 0 }\n for (const unit of roofUnits(context, bearing)) {\n const carriers = roofCarriers(context, unit)\n if (construction.roof.shape === 'slab') context.roof.panes.push(addFlatRoof(context, unit, carriers))\n else context.roof.panes.push(...addGableRoof(context, unit, carriers, covering?.joint ?? 'nail'))\n }\n if (context.isTimber && construction.roof.shape !== 'slab') addCeilingJoists(context)\n}\n","import { GROUND } from '../types'\nimport type { StructureSource } from '../types'\nimport type { BuildContext } from './context'\n\ntype StairItem = StructureSource['items'][number]\n\n/** One flight per pair of linked storeys, taken from the item of the lower storey when both are present. */\nfunction flightsOf(items: readonly StairItem[]): Map<string, StairItem> {\n const flights = new Map<string, StairItem>()\n for (const item of items.filter((it) => it.category === 'stairs' && it.link)) {\n const key = `${item.link!.from}_${item.link!.to}`\n if (!flights.has(key) || item.floor === item.link!.from) flights.set(key, item)\n }\n return flights\n}\n\n/** Interior stairs between storeys, resting on the floor below and tied to the one above, plus the basement stairs. */\nexport function addStairs(context: BuildContext): void {\n const { builder, construction } = context\n const material = context.isTimber ? construction.frame.timber : (construction.stairs ?? 'concrete')\n for (const [key, item] of flightsOf(context.source.items)) {\n const { from, to } = item.link!\n const flight = builder.add({ id: `stairs_${key}`, role: 'stair', material, aabb: item.aabb!, y0: context.level(from), y1: context.level(to) }, { floor: from, steps: Math.round((context.level(to) - context.level(from)) / 0.18) })\n const base = context.baseOf(from)\n builder.rest(flight, !base || base === GROUND ? GROUND : base, !base || base === GROUND ? 'resting' : context.isTimber ? 'nail' : 'mortar')\n const upper = context.baseOf(to)\n if (upper && upper !== GROUND) builder.rest(flight, upper, context.isTimber ? 'nail' : 'bolt')\n }\n if (!context.hasBasement) return\n const item = context.source.items.find((it) => it.type === 'basement_stairs')\n if (!item?.aabb) return\n const depth = construction.foundation.depth || 2.4\n const flight = builder.add({ id: 'basement_stairs', role: 'stair', material: 'wood_soft', aabb: item.aabb, y0: -depth, y1: context.level(0) }, { floor: -1, steps: Math.round((context.level(0) + depth) / 0.18) })\n builder.rest(flight, builder.find('basement_slab')!, 'resting')\n if (context.base0 && context.base0 !== GROUND) builder.rest(flight, context.base0, 'nail')\n}\n","import type { Opening, Rect, StructurePart } from '../types'\nimport type { BuildContext, BuildWall } from './context'\n\nconst TOLERANCE = 0.02\n/** Height of a door leaf, which the plan does not store (m). */\nexport const DOOR_HEIGHT = 2.1\nconst LINTEL_DEPTH = 0.2\nconst LINTEL_BEARING = 0.2\n\nconst crossOf = (wall: BuildWall): number => (wall.axis === 'u' ? wall.v0 : wall.u0)\nconst alongRange = (wall: BuildWall): [number, number] => (wall.axis === 'u' ? [Math.min(wall.u0, wall.u1), Math.max(wall.u0, wall.u1)] : [Math.min(wall.v0, wall.v1), Math.max(wall.v0, wall.v1)])\n\n/** The windows of the plan, each in the wall it sits in. */\nexport function findOpenings(context: BuildContext): Opening[] {\n const openings: Opening[] = []\n for (const window of context.source.windows ?? []) {\n const from = window.at - window.width / 2\n const to = window.at + window.width / 2\n const wall = context.walls.find((w) => {\n if (w.floor !== window.floor || w.axis !== window.axis || w.type !== 'wall' || Math.abs(crossOf(w) - window.pos) > TOLERANCE) return false\n const [low, high] = alongRange(w)\n return from >= low - TOLERANCE && to <= high + TOLERANCE\n })\n if (!wall) continue\n const base = context.level(window.floor)\n openings.push({ id: window.id, kind: 'window', wall: wall.id, from, to, y0: base + window.y0, y1: base + window.y1 })\n }\n return openings\n}\n\n/**\n * A lintel over every door gap, 0.2 m deep, bearing 0.2 m on the wall at each side (a concrete beam in masonry, a header in timber houses). The bond beam or\n * plate over the door rests on it as well as on the walls beside it.\n */\nexport function addDoorLintels(context: BuildContext): void {\n const { builder, construction, system } = context\n for (const door of context.source.doors.filter((d) => d.a !== undefined && d.type !== 'zipper')) {\n const along = door.axis === 'u' ? door.u : door.v\n const cross = door.axis === 'u' ? door.v : door.u\n const from = along - door.width / 2\n const to = along + door.width / 2\n const beside = context.walls.filter((w) => w.floor === door.floor && w.axis === door.axis && w.type === 'wall' && Math.abs(crossOf(w) - cross) <= TOLERANCE && (Math.abs(alongRange(w)[1] - from) <= 0.05 || Math.abs(alongRange(w)[0] - to) <= 0.05))\n if (!beside.length) continue\n const half = (beside[0]!.thickness ?? 0.15) / 2\n const lo = from - LINTEL_BEARING\n const hi = to + LINTEL_BEARING\n const box: Rect = door.axis === 'u' ? [lo, cross - half, hi, cross + half] : [cross - half, lo, cross + half, hi]\n const y0 = context.level(door.floor) + DOOR_HEIGHT\n const lintel = builder.add({ id: `lintel_${door.id}`, role: 'beam', material: system.timber ? construction.frame.timber : 'concrete', aabb: box, y0, y1: y0 + LINTEL_DEPTH }, { floor: door.floor, ...(system.timber ? {} : { assembly: 'reinforced_concrete' }) })\n for (const wall of beside) builder.rest(lintel, context.wallParts.get(wall.id) as StructurePart, system.joints.beam)\n for (const plate of context.plates.get(door.floor) ?? []) if (overlapsInPlan(plate.aabb, box)) builder.rest(plate, lintel, system.joints.beam)\n }\n}\n\nconst overlapsInPlan = (a: Rect, b: Rect): boolean => a[0] < b[2] && a[2] > b[0] && a[1] < b[3] && a[3] > b[1]\n","import { GROUND } from '../types'\nimport type { Rect } from '../types'\nimport type { BuildContext } from './context'\n\nconst RISER = 0.18\nconst TREAD = 0.28\n\nconst stepCount = (elevation: number): number => Math.max(1, Math.ceil(elevation / RISER))\n\n/** Steps from each porch door down to the ground: concrete in masonry, wood otherwise, resting on the porch floor. */\nfunction addPorchSteps(context: BuildContext): void {\n const { builder } = context\n for (const room of context.source.rooms.filter((r) => r.type === 'porch')) {\n const deck = builder.find(`porch_floor_${room.id}`)\n for (const door of context.source.doors.filter((d) => d.floor === room.floor && d.b === 'outside' && d.a === room.id)) {\n const count = stepCount(context.elevation)\n const depth = count * TREAD\n const aabb: Rect = [door.u - door.width / 2, door.v - depth, door.u + door.width / 2, door.v]\n const flight = builder.add({ id: `steps_${door.id}`, role: 'stair', material: context.isTimber ? 'wood_soft' : 'concrete', aabb, y0: 0, y1: context.level(room.floor) }, { floor: 0, steps: count, door: door.id })\n builder.rest(flight, GROUND, 'resting')\n if (deck) builder.rest(flight, deck, context.isTimber ? 'nail' : 'mortar')\n }\n }\n}\n\nfunction boxOfSteps(door: { u: number; v: number; width: number; axis: string; side?: string }, depth: number): Rect {\n const direction = door.axis === 'u' ? (door.side === 'front' ? -1 : 1) : door.side === 'left' ? -1 : 1\n if (door.axis === 'u') return [door.u - door.width / 2, Math.min(door.v, door.v + direction * depth), door.u + door.width / 2, Math.max(door.v, door.v + direction * depth)]\n return [Math.min(door.u, door.u + direction * depth), door.v - door.width / 2, Math.max(door.u, door.u + direction * depth), door.v + door.width / 2]\n}\n\n/** Steps at the other outside doors of the ground storey when the floor sits above the ground. */\nfunction addDoorSteps(context: BuildContext): void {\n if (context.elevation <= 0.1) return\n const { builder } = context\n const doors = context.source.doors.filter((d) => d.floor === 0 && d.exterior && d.model !== 'steel' && d.type !== 'steps' && d.type !== 'zipper')\n for (const door of doors) {\n const count = stepCount(context.elevation)\n const depth = Math.min(TREAD * count, 0.9)\n const flight = builder.add({ id: `steps_${door.id}`, role: 'stair', material: context.isTimber ? 'wood_soft' : 'concrete', aabb: boxOfSteps(door, depth), y0: 0, y1: context.level(0) }, { floor: 0, steps: count, door: door.id })\n builder.rest(flight, GROUND, 'resting')\n const base = context.base0\n if (base && base !== GROUND) builder.rest(flight, base, context.isTimber ? 'nail' : 'mortar')\n }\n}\n\nexport function addExteriorSteps(context: BuildContext): void {\n addPorchSteps(context)\n addDoorSteps(context)\n}\n","import { GROUND } from '../types'\nimport type { Rect, StructurePart, WaterTank } from '../types'\nimport { touches } from '../geometry'\nimport type { BuildContext } from './context'\n\nconst TANK_FILL = 0.08\n\nconst squareAround = (u: number, v: number, side: number): Rect => [u - side / 2, v - side / 2, u + side / 2, v + side / 2]\n\nfunction addTank(context: BuildContext, tank: WaterTank, floor: number, y0: number): StructurePart {\n return context.builder.add({ id: 'water_tank', role: 'none', material: tank.material ?? 'plastic', aabb: tank.aabb, y0, y1: y0 + tank.h }, { floor, fill: TANK_FILL, liters: tank.capacity })\n}\n\n/** The slab under the roof that carries a tank in the attic or on a raised platform: a ceiling slab on the top plates, pillars and bearing walls. */\nfunction ensureCeilingSlab(context: BuildContext, y: number): StructurePart {\n const { builder, construction, system } = context\n const existing = builder.find('slab_ceiling')\n if (existing) return existing\n const top = context.floorCount - 1\n const box = context.topBox\n const carriers = builder.parts.filter(\n (part) =>\n ((part.role === 'beam' && part.id.startsWith(`plate_${top}_`)) || (part.role === 'column' && part.floor === top) || (part.role === 'wall' && part.floor === top && !part.id.startsWith('basement'))) &&\n touches(box, part.aabb, 0.1),\n )\n const slab = builder.add({ id: 'slab_ceiling', role: 'slab', material: construction.frame.slabs, aabb: box, y0: y - 0.12, y1: y }, { floor: top })\n for (const carrier of carriers) builder.rest(slab, carrier, system.joints.slab)\n return slab\n}\n\nfunction addRaisedPlatform(context: BuildContext, tank: WaterTank): void {\n const { builder, construction } = context\n const platform = tank.platform!\n const top = context.floorCount - 1\n const ceiling = ensureCeilingSlab(context, platform.baseY)\n const pillars = platform.pillars.map((q, k) => {\n const pillar = builder.add({ id: `tank_column_${k}`, role: 'column', material: construction.frame.pillars, aabb: squareAround(q.u, q.v, q.side), y0: platform.baseY, y1: platform.topY - platform.thickness }, { floor: top })\n builder.rest(pillar, ceiling, 'rebar')\n return pillar\n })\n const slab = builder.add({ id: 'tank_slab', role: 'slab', material: construction.frame.slabs, aabb: platform.aabb, y0: platform.topY - platform.thickness, y1: platform.topY }, { floor: top })\n for (const pillar of pillars) builder.rest(slab, pillar, 'rebar')\n builder.rest(addTank(context, tank, top, tank.y), slab, 'resting')\n}\n\nfunction addAtticTank(context: BuildContext, tank: WaterTank): void {\n const { builder } = context\n const top = context.floorCount - 1\n if (!context.isTimber) {\n const ceiling = ensureCeilingSlab(context, tank.y)\n builder.rest(addTank(context, tank, top, tank.y), ceiling, 'resting')\n return\n }\n const supports = context.topSlab ? [context.topSlab] : (context.ceilingJoists ?? builder.parts.filter((part) => part.role === 'beam' && part.id.startsWith(`plate_${top}_`)))\n const y0 = supports[0] ? supports[0].y1 : tank.y - 0.03\n const floor = builder.add({ id: 'attic_floor', role: 'slab', material: 'plywood', aabb: context.topBox, y0, y1: y0 + 0.03 }, { floor: top })\n for (const support of supports) if (touches(floor.aabb, support.aabb, 0.1)) builder.rest(floor, support, 'nail')\n builder.rest(addTank(context, tank, top, tank.y), floor, 'resting')\n}\n\nfunction addSlabTank(context: BuildContext, tank: WaterTank): void {\n const { builder } = context\n const supports = builder.parts.filter((part) => part.role === 'slab' && Math.abs(part.y1 - tank.y) < 0.3 && touches(part.aabb, tank.aabb, 0.1))\n const carrier = supports.sort((a, b) => Math.abs(a.y1 - tank.y) - Math.abs(b.y1 - tank.y))[0] ?? context.topSlab\n const part = addTank(context, tank, tank.floor, tank.y)\n builder.rest(part, carrier ?? GROUND, 'resting')\n}\n\nfunction addTrestleTank(context: BuildContext, tank: WaterTank): void {\n const { builder } = context\n const stand = tank.stand!\n const columns = stand.pillars.map((q, k) => {\n const column = builder.add({ id: `trestle_column_${k}`, role: 'column', material: stand.material, aabb: squareAround(q.u, q.v, q.side), y0: 0, y1: stand.height }, { floor: 0 })\n builder.rest(column, GROUND, stand.baseJoint ?? 'resting')\n return column\n })\n const [u0, v0, u1, v1] = tank.aabb\n const beams = ([[u0 - 0.1, v0 - 0.1, u1 + 0.1, v0 + 0.05], [u0 - 0.1, v1 - 0.05, u1 + 0.1, v1 + 0.1]] as Rect[]).map((aabb, k) => {\n const beam = builder.add({ id: `trestle_beam_${k}`, role: 'beam', material: stand.material, aabb, y0: stand.height - 0.12, y1: stand.height }, { floor: 0 })\n for (const column of columns.filter((c) => touches(beam.aabb, c.aabb, 0.15))) builder.rest(beam, column, stand.joint ?? 'nail')\n return beam\n })\n const part = addTank(context, tank, 0, stand.height)\n for (const beam of beams) builder.rest(part, beam, stand.tie ?? 'resting')\n}\n\n/** The water tank as a part (role `none`: it weighs on what holds it and carries nothing) with whatever holds it up. */\nexport function addWaterTank(context: BuildContext): void {\n const tank = context.tank\n if (!tank) return\n switch (tank.place) {\n case 'slab':\n return addSlabTank(context, tank)\n case 'raised_slab':\n return addRaisedPlatform(context, tank)\n case 'attic':\n return addAtticTank(context, tank)\n case 'trestle':\n return addTrestleTank(context, tank)\n }\n}\n","import { touches, unionOf } from '../geometry'\nimport type { BuildContext } from './context'\nimport { addDeck, addJoists } from './floor-deck'\n\n/** The floor of the storey above `floor`: a concrete slab, or joists and boards in timber, resting on what carries `floor`. */\nexport function addUpperFloor(context: BuildContext, floor: number): void {\n if (floor >= context.floorCount - 1 || context.isUnit) return\n const next = floor + 1\n const rects = context.rectsOf(next, ['balcony', 'porch', 'void'])\n const box = rects.length ? unionOf(rects) : context.houseBox\n const carriers = context.carriers.get(floor)!\n const { system, construction, builder } = context\n const thickness = system.slabThickness\n if (context.isTimber) {\n const joists = addJoists(context, { floor: next, box, thickness, carriers, material: construction.frame.timber, joint: system.joints.beam })\n addDeck(context, `slab_${next}`, construction.frame.slabs, { floor: next, box, thickness, joint: system.joints.slab }, joists)\n return\n }\n const slab = builder.add({ id: `slab_${next}`, role: 'slab', material: construction.frame.slabs, aabb: box, y0: context.level(next) - thickness, y1: context.level(next) }, { floor: next })\n const below = carriers.filter((carrier) => carrier.y0 <= slab.y0 + 0.05)\n const touching = below.filter((carrier) => touches(slab.aabb, carrier.aabb, 0.2))\n for (const carrier of touching.length ? touching : below) builder.rest(slab, carrier, system.joints.slab)\n}\n","import { GROUND } from '../types'\nimport type { StructurePart } from '../types'\nimport type { BuildContext, BuildWall } from './context'\nimport { guardHeightOf, OPEN_ROOM_TYPES } from './context'\n\n/** Highest ceiling among the rooms the wall touches (a double-height room lifts its outer wall to the eave). */\nexport function wallCeiling(context: BuildContext, wall: BuildWall): number {\n const rooms = wall.sides.map((id) => context.source.rooms.find((room) => room.id === id && room.floor === wall.floor)).filter((room) => room !== undefined)\n return Math.max(context.ceilingOf(wall.floor), ...rooms.map((room) => room.ceiling || 0))\n}\n\nfunction wallTop(context: BuildContext, wall: BuildWall, floor: number): number {\n const y0 = context.level(floor)\n if (wall.type === 'railing') return y0 + guardHeightOf(wall)\n const ceiling = wallCeiling(context, wall)\n const height = wall.structureHeight || wall.h || context.ceilingOf(floor)\n if (wall.exterior && floor < context.floorCount - 1 && !context.isUnit && ceiling > context.ceilingOf(floor) + 0.01) return y0 + ceiling\n if (floor === context.floorCount - 1 || context.isUnit) return y0 + Math.max(height, ceiling)\n const top = context.topOf(floor)\n return Math.max(y0 + height, y0 + ceiling > top ? top : y0 + ceiling)\n}\n\n/** What a railing rests on: the slab of its own balcony or the floor of its porch. */\nfunction railingBase(context: BuildContext, wall: BuildWall, floor: number): StructurePart | string | undefined {\n const open = wall.sides\n .map((id) => context.source.rooms.find((room) => room.id === id && room.floor === floor))\n .find((room) => room && (room.type === 'balcony' || room.type === 'porch'))\n if (!open) return context.baseOf(floor)\n return open.type === 'porch' ? `porch_floor_${open.id}` : `slab_${floor}_${open.id}`\n}\n\nconst assemblyOf = (context: BuildContext): string | undefined => context.construction.walls.assembly ?? (context.system.walls || undefined)\n\nfunction addWallPart(context: BuildContext, wall: BuildWall, floor: number): void {\n const { system, builder } = context\n const isRailing = wall.type === 'railing'\n const y0 = context.level(floor)\n const top = wallTop(context, wall, floor)\n const y1 = isRailing ? top : wall.exterior && !wall.gable ? top - system.plateThickness : top\n const framed = system.studs !== undefined && !isRailing\n const part = builder.add(\n { id: wall.id, role: wall.role, material: wall.material, aabb: wall.box, y0, y1: Math.max(y1, y0 + 0.2) },\n { floor, fill: context.isTimber && wall.role === 'wall' ? system.wallFill : 1, ...(framed ? { studs: system.studs } : {}), ...(isRailing ? {} : { assembly: assemblyOf(context) }) },\n )\n context.wallParts.set(wall.id, part)\n const base = isRailing ? railingBase(context, wall, floor) : context.baseOf(floor)\n const joint = isRailing ? 'nail' : system.joints.wall\n if (base === GROUND || (floor === 0 && !base)) builder.rest(part, GROUND, joint)\n else if (base) builder.rest(part, base, joint)\n}\n\n/** One part per wall of the storey, resting on the floor below it (or the ground). */\nexport function addWalls(context: BuildContext, floor: number): void {\n for (const wall of context.walls.filter((w) => w.floor === floor)) addWallPart(context, wall, floor)\n}\n\nexport const isOpenRoomType = (type: string): boolean => OPEN_ROOM_TYPES.includes(type)\n","import { createContext } from './context'\nimport type { BuildContext } from './context'\nimport { addBalconies } from './balconies'\nimport { buildCanvasStructure } from './canvas'\nimport { addChimney, addWell } from './extras'\nimport { addFoundation } from './foundation'\nimport { addPlatesAndPillars } from './plates'\nimport { addPorches } from './porch'\nimport { addPorchRoofs } from './porch-roof'\nimport { addRoof } from './roof'\nimport { addStairs } from './stairs'\nimport { addDoorLintels, findOpenings } from './openings'\nimport { addExteriorSteps } from './steps'\nimport { addWaterTank } from './tank-parts'\nimport { addUpperFloor } from './upper-floor'\nimport { addWalls } from './walls'\nimport { resolveConstruction } from '../construction'\nimport type { Structure, StructureOptions, StructureSource } from '../types'\n\nfunction buildFloors(context: BuildContext): void {\n for (let floor = 0; floor < context.floorCount; floor++) {\n addWalls(context, floor)\n addPlatesAndPillars(context, floor)\n addPorches(context, floor)\n addUpperFloor(context, floor)\n }\n}\n\n/**\n * The structure of a generated plan: every part that carries load (foundation, floors, walls, plates and bond beams, pillars, porch posts, trusses,\n * roof, stairs, tank) with what each rests on. The plan itself is not modified.\n */\nexport function buildStructure(source: StructureSource, options: StructureOptions = {}): Structure {\n const refined = options.wallDetail !== 'coarse'\n const built = options.construction ? { construction: options.construction, extras: options.extras ?? {} } : resolveConstruction(source)\n const construction = built.construction\n const extras = options.extras ?? built.extras ?? {}\n if (construction.system === 'canvas') return buildCanvasStructure(construction, extras)\n const tank = options.tank !== undefined ? options.tank : (source.waterTank ?? null)\n const context = createContext(source, construction, extras, tank, { porchRoofOnPostsOnly: options.porchRoofOnPostsOnly ?? refined, rafterRoof: options.rafterRoof ?? refined })\n addFoundation(context)\n buildFloors(context)\n addBalconies(context)\n addPorchRoofs(context)\n addExteriorSteps(context)\n addStairs(context)\n addRoof(context)\n if (refined) addDoorLintels(context)\n addWaterTank(context)\n addChimney(context)\n addWell(context)\n const levels = source.floors.map((_, floor) => context.level(floor))\n const framed = construction.system === 'masonry' && (context.isUnit || source.style === 'commercial' || context.floorCount >= 3)\n return { parts: context.builder.parts, supports: context.builder.supports, levels, elevation: context.elevation, roof: context.roof, construction, framed, openings: findOpenings(context) }\n}\n","export type ContentGroup = 'food' | 'water' | 'medicine' | 'tool' | 'cleaning' | 'improvised_weapon' | 'clothes' | 'document' | 'utensil' | 'trash'\n\nexport interface ContentEntry {\n itemId: string\n min: number\n max: number\n group: ContentGroup\n pickable: boolean\n weight: number\n}\n\nconst entry = (itemId: string, min: number, max: number, group: ContentGroup, pickable: boolean, weight: number): ContentEntry => ({ itemId, min, max, group, pickable, weight })\n\nconst FRIDGE = [\n entry('water_bottle', 1, 3, 'water', true, 3), entry('milk_carton', 1, 2, 'food', true, 2), entry('eggs', 1, 1, 'food', true, 2), entry('packed_meat', 1, 2, 'food', true, 1.5), entry('fruit', 1, 4, 'food', true, 2),\n entry('yogurt', 1, 3, 'food', true, 1), entry('soda', 1, 2, 'water', true, 1), entry('cheese', 1, 1, 'food', true, 1), entry('insulin', 1, 1, 'medicine', true, 0.4), entry('leftovers', 1, 2, 'food', true, 1),\n]\nconst BEDSIDE = [entry('medicine', 1, 2, 'medicine', true, 2), entry('book', 1, 2, 'document', true, 1.5), entry('charger', 1, 1, 'tool', true, 1), entry('flashlight', 1, 1, 'tool', true, 0.7), entry('glasses', 1, 1, 'tool', true, 0.7)]\nconst WARDROBE = [\n entry('shirt', 2, 6, 'clothes', true, 3), entry('trousers', 1, 4, 'clothes', true, 3), entry('coat', 1, 2, 'clothes', true, 1.5), entry('sneakers', 1, 2, 'clothes', true, 1.5),\n entry('shoes', 1, 2, 'clothes', true, 1), entry('blanket', 1, 2, 'clothes', true, 1.5), entry('backpack', 1, 1, 'tool', true, 0.8),\n]\nconst DRESSER = [entry('underwear', 2, 6, 'clothes', true, 3), entry('socks', 2, 6, 'clothes', true, 2), entry('t_shirt', 1, 4, 'clothes', true, 2), entry('documents', 1, 2, 'document', true, 1), entry('flashlight', 1, 1, 'tool', true, 0.7), entry('batteries', 1, 2, 'tool', true, 0.7)]\nconst FILING = [entry('documents', 1, 4, 'document', true, 3), entry('pen', 1, 3, 'tool', true, 1.5), entry('keys', 1, 2, 'tool', true, 1), entry('stapler', 1, 1, 'improvised_weapon', true, 0.5)]\nconst TRASH = [entry('full_trash_bag', 1, 1, 'trash', false, 2), entry('packaging', 1, 4, 'trash', true, 3), entry('empty_can', 1, 3, 'trash', true, 2), entry('crumpled_paper', 1, 3, 'trash', true, 1)]\n\n/** What each kind of container may hold, by category (or by type when a type differs from its category). */\nexport const CONTENT_TABLES: Record<string, ContentEntry[]> = {\n fridge: FRIDGE,\n display_fridge: [entry('soda', 2, 6, 'water', true, 3), entry('water_bottle', 2, 6, 'water', true, 3), entry('yogurt', 2, 5, 'food', true, 2)],\n freezer: [entry('frozen_meat', 2, 5, 'food', true, 3), entry('ice_cream', 1, 2, 'food', true, 1)],\n kitchen_cabinet: [\n entry('pot', 1, 2, 'tool', true, 1.5), entry('kitchen_knife', 1, 2, 'improvised_weapon', true, 1.5), entry('dish_soap', 1, 2, 'cleaning', true, 2), entry('sponge', 1, 2, 'cleaning', true, 1), entry('rice', 1, 2, 'food', true, 1.5),\n entry('beans', 1, 2, 'food', true, 1.5), entry('pasta', 1, 2, 'food', true, 1), entry('cooking_oil', 1, 1, 'food', true, 1), entry('canned_tuna', 1, 3, 'food', true, 1.5), entry('disinfectant', 1, 1, 'cleaning', true, 1), entry('trash_bag', 1, 2, 'trash', true, 0.7),\n ],\n overhead_cabinet: [entry('plates', 4, 8, 'utensil', false, 3), entry('glasses', 3, 6, 'utensil', false, 3), entry('mug', 1, 3, 'utensil', true, 1.5), entry('coffee', 1, 2, 'food', true, 1.5), entry('canned_corn', 1, 3, 'food', true, 1.5), entry('spices', 1, 3, 'food', true, 1)],\n washbasin: [\n entry('painkiller', 1, 2, 'medicine', true, 2), entry('bandages', 1, 2, 'medicine', true, 2), entry('soap', 1, 3, 'cleaning', true, 2), entry('toilet_paper', 1, 4, 'cleaning', true, 2), entry('shampoo', 1, 2, 'cleaning', true, 1),\n entry('toothbrush', 1, 2, 'cleaning', true, 1), entry('scissors', 1, 1, 'improvised_weapon', true, 0.5), entry('rubbing_alcohol', 1, 1, 'medicine', true, 1),\n ],\n wardrobe: WARDROBE,\n wardrobe_large: WARDROBE,\n dresser: DRESSER,\n console_table: DRESSER,\n nightstand: BEDSIDE,\n filing_cabinet: FILING,\n pantry: [\n entry('rice', 2, 4, 'food', true, 2), entry('beans', 2, 4, 'food', true, 2), entry('canned_tuna', 2, 5, 'food', true, 2), entry('water_jug', 1, 2, 'water', true, 2), entry('flour', 1, 2, 'food', true, 1),\n entry('sugar', 1, 2, 'food', true, 1), entry('cooking_oil', 1, 2, 'food', true, 1), entry('biscuits', 1, 4, 'food', true, 1.5),\n ],\n tv_unit: [entry('remote_control', 1, 1, 'tool', true, 2), entry('dvds', 1, 4, 'document', true, 1), entry('cables', 1, 3, 'tool', true, 1.5), entry('batteries', 1, 2, 'tool', true, 1)],\n laundry_cabinet: [entry('washing_powder', 1, 2, 'cleaning', true, 3), entry('bleach', 1, 2, 'cleaning', true, 2), entry('disinfectant', 1, 2, 'cleaning', true, 2), entry('bucket', 1, 1, 'tool', true, 1), entry('broom', 1, 1, 'improvised_weapon', true, 1), entry('rubber_gloves', 1, 2, 'cleaning', true, 1)],\n laundry_shelf: [entry('washing_powder', 1, 1, 'cleaning', true, 2), entry('softener', 1, 2, 'cleaning', true, 2), entry('clothespins', 1, 1, 'tool', true, 1)],\n workbench: [entry('hammer', 1, 1, 'improvised_weapon', true, 2), entry('screwdriver', 1, 2, 'tool', true, 2), entry('pliers', 1, 1, 'tool', true, 1.5), entry('insulating_tape', 1, 2, 'tool', true, 1), entry('screws', 1, 2, 'tool', true, 1)],\n tool_shelf: [entry('hammer', 1, 1, 'improvised_weapon', true, 1.5), entry('hand_saw', 1, 1, 'improvised_weapon', true, 1), entry('paint_can', 1, 3, 'trash', true, 1.5), entry('rope', 1, 1, 'tool', true, 1), entry('nails', 1, 2, 'tool', true, 1.5)],\n mailbox: [entry('letter', 1, 4, 'document', true, 3), entry('bill', 1, 2, 'document', true, 2), entry('flyer', 1, 4, 'trash', true, 2)],\n trash_bin: TRASH,\n outdoor_bin: TRASH,\n china_cabinet: [entry('china_plates', 3, 6, 'utensil', false, 3), entry('wine_glasses', 2, 5, 'utensil', false, 2)],\n}\n\n/** Groups of things somebody who locked themselves in would have stocked up. */\nexport const SUPPLY_GROUPS: readonly ContentGroup[] = ['food', 'water', 'medicine', 'tool']\n","import type { FindStack } from '@adatechnology/game-floorplan'\n\nimport { CONTENT_TABLES, SUPPLY_GROUPS } from './content-tables'\nimport type { ContentEntry } from './content-tables'\nimport type { Rng } from './shared'\n\nexport interface ContentStack extends FindStack {\n group: string\n pickable: boolean\n}\n\nexport interface ContentQuery {\n /** Category or type of the container (`fridge`, `kitchen_cabinet`, `overhead_cabinet`...). */\n container: string\n state: string\n rng: Rng\n /** Footprint of the container in m2. */\n footprint: number\n}\n\n/** How a state changes what a container holds: how many kinds, how likely each is, how many of each, and what is left over. */\nexport interface ContentStateRule {\n kinds(base: number, available: number, rng: Rng): number\n weight(entry: ContentEntry): number\n extraQuantity(entry: ContentEntry): number\n leftovers?(found: ContentStack[], container: string, rng: Rng): void\n}\n\nconst FRIDGES = ['fridge', 'display_fridge', 'freezer']\nconst isSupply = (entry: ContentEntry): boolean => SUPPLY_GROUPS.includes(entry.group)\n\n/** The normal world is the base; `fortified` and `abandoned` are the genre's rules, kept here until the item catalogue and the genre pack own them. */\nexport const CONTENT_STATES: Record<string, ContentStateRule> = {\n normal: { kinds: (base) => base, weight: (entry) => entry.weight, extraQuantity: () => 0 },\n fortified: { kinds: (base, available) => Math.min(available, base + 2), weight: (entry) => (isSupply(entry) ? entry.weight * 2.5 : entry.weight), extraQuantity: (entry) => (isSupply(entry) ? 1 : 0) },\n abandoned: {\n kinds: (_base, _available, rng) => (rng() < 0.4 ? 0 : 1),\n weight: (entry) => entry.weight,\n extraQuantity: () => 0,\n leftovers(found, container, rng) {\n if (found.length === 0 && rng() < 0.5) found.push({ itemId: 'scraps_and_papers', count: 1, pickable: false, group: 'trash' })\n if (FRIDGES.includes(container)) found.push({ itemId: 'spoiled_food', count: 1, pickable: false, group: 'trash' })\n },\n },\n}\n\nexport function registerContentState(state: string, rule: ContentStateRule): void {\n CONTENT_STATES[state] = rule\n}\n\n/** Weighted draw without replacement. */\nfunction weightedOrder<T extends { weight: number }>(candidates: T[], rng: Rng): T[] {\n const pool = candidates.slice()\n const out: T[] = []\n while (pool.length) {\n let x = rng() * pool.reduce((sum, c) => sum + c.weight, 0)\n let i = 0\n for (; i < pool.length - 1; i++) {\n x -= pool[i]!.weight\n if (x < 0) break\n }\n out.push(pool.splice(i, 1)[0]!)\n }\n return out\n}\n\n/** What a container holds in a state: a few kinds of thing from the table of its category, more of the useful ones when fortified, almost nothing when abandoned. */\nexport function contentOf(query: ContentQuery): ContentStack[] {\n const pool = CONTENT_TABLES[query.container]\n if (!pool) return []\n const rule = CONTENT_STATES[query.state] ?? CONTENT_STATES.normal!\n const { rng } = query\n const base = Math.max(2, Math.min(5, Math.round(1.5 + query.footprint * 3 + rng() * 1.5)))\n const kinds = rule.kinds(base, pool.length, rng)\n const found: ContentStack[] = []\n for (const candidate of weightedOrder(pool.map((entry) => ({ entry, weight: rule.weight(entry) })), rng).slice(0, kinds)) {\n const { entry } = candidate\n const count = entry.min + Math.floor(rng() * (entry.max - entry.min + 1)) + rule.extraQuantity(entry)\n found.push({ itemId: entry.itemId, count, pickable: entry.pickable, group: entry.group })\n }\n rule.leftovers?.(found, query.container, rng)\n return found\n}\n\nexport const hasContent = (container: string): boolean => container in CONTENT_TABLES\n\n","import type { Rect } from '../types'\n\n/** Loosely typed plan data: the engine's own plan and its items (`result.items`), which the utilities read and some of them annotate. */\nexport type Json = any\nexport type Rng = () => number\n\nexport const HALF_WALL = 0.075\nexport const round2 = (value: number): number => Math.round(value * 100) / 100\nexport const clamp = (value: number, low: number, high: number): number => Math.max(low, Math.min(high, value))\n\nexport const overlaps = (a: Rect, b: Rect, epsilon = 1e-6): boolean => a[0] < b[2] - epsilon && a[2] > b[0] + epsilon && a[1] < b[3] - epsilon && a[3] > b[1] + epsilon\n\nexport const inner = (rect: Rect): Rect => [rect[0] + HALF_WALL, rect[1] + HALF_WALL, rect[2] - HALF_WALL, rect[3] - HALF_WALL]\n\n/** A solid item: not a rug, not resting on something, and not decoration unless it stands on the floor. */\nexport const isSolid = (item: Json): boolean => !item.flat && !item.on && (!item.decor || item.mount === 'floor')\n\nexport const distanceToRect = (u: number, v: number, rect: Rect): number => Math.hypot(Math.max(rect[0] - u, 0, u - rect[2]), Math.max(rect[1] - v, 0, v - rect[3]))\n\n/** Room types without sockets, switches or circuits. */\nexport const NO_SOCKET_ROOMS: readonly string[] = ['void', 'elevator', 'stairs', 'balcony', 'terrace', 'porch', 'tent']\n\n/** Unit vector pointing out of the house from a wall (`sides[0]` or `sides[1]` is `outside`). */\nexport const outwardOf = (wall: Json): [number, number] => {\n const sign = wall.sides[0] === 'outside' ? -1 : 1\n return wall.axis === 'u' ? [0, sign] : [sign, 0]\n}\n\nexport const sideNameOf = (vector: [number, number]): string => (Math.abs(vector[0]) > Math.abs(vector[1]) ? (vector[0] > 0 ? 'right' : 'left') : vector[1] > 0 ? 'back' : 'front')\n\nexport const alongRange = (wall: Json): [number, number] => (wall.axis === 'u' ? [Math.min(wall.u0, wall.u1), Math.max(wall.u0, wall.u1)] : [Math.min(wall.v0, wall.v1), Math.max(wall.v0, wall.v1)])\n\n/** Exterior ground-floor wall at least 1 m long, the front one first when there is one (a gas meter and an inverter go on them). */\nexport function groundExteriorWalls(plan: Json): Json[] {\n return plan.walls.filter((wall: Json) => wall.exterior && wall.floor === 0 && wall.type === 'wall' && Math.hypot(wall.u1 - wall.u0, wall.v1 - wall.v0) >= 1.0)\n}\n","import type { Json } from './shared'\nimport { HALF_WALL, isSolid, round2 } from './shared'\n\nexport interface WallPoint {\n u: number\n v: number\n /** Position along the wall. */\n c: number\n axis: 'u' | 'v'\n pos: number\n side: number\n nu: number\n nv: number\n a0: number\n a1: number\n exterior: boolean\n windows: Json[]\n /** A solid item within 12 cm of the point reaches higher than `height`. */\n blocked(height: number): boolean\n}\n\nconst STEP = 0.05\nconst SURFACE_OFFSET = 0.012\n\n/** Points on the inner face of the walls of a room, away from corners (`margin`), where sockets, switches and a panel may go. */\nexport function wallPointsOf(plan: Json, room: Json, items: Json[], margin = 0.3): WallPoint[] {\n const points: WallPoint[] = []\n const windows = plan.windows.filter((w: Json) => w.floor === room.floor)\n const solids = items.filter((m) => m.floor === room.floor && !m.outdoor && m.room === room.id && isSolid(m))\n for (const wall of plan.walls) {\n if (wall.floor !== room.floor || wall.type !== 'wall' || !wall.sides.includes(room.id)) continue\n const side = wall.sides[1] === room.id ? 1 : -1\n const a0 = wall.axis === 'u' ? Math.min(wall.u0, wall.u1) : Math.min(wall.v0, wall.v1)\n const a1 = wall.axis === 'u' ? Math.max(wall.u0, wall.u1) : Math.max(wall.v0, wall.v1)\n const pos = wall.axis === 'u' ? wall.v0 : wall.u0\n const nearby = windows.filter((w: Json) => w.axis === wall.axis && Math.abs(w.pos - pos) < 1e-3 && w.at + w.width / 2 > a0 && w.at - w.width / 2 < a1)\n for (let c = a0 + margin; c <= a1 - margin + 1e-9; c += STEP) {\n const u = wall.axis === 'u' ? c : pos + side * (HALF_WALL + SURFACE_OFFSET)\n const v = wall.axis === 'u' ? pos + side * (HALF_WALL + SURFACE_OFFSET) : c\n points.push({\n u: round2(u), v: round2(v), c: round2(c), axis: wall.axis, pos, side, nu: wall.axis === 'u' ? 0 : side, nv: wall.axis === 'u' ? side : 0, a0, a1, exterior: wall.exterior, windows: nearby,\n blocked: (height) => solids.some((m) => m.aabb && Math.hypot(Math.max(m.aabb[0] - u, 0, u - m.aabb[2]), Math.max(m.aabb[1] - v, 0, v - m.aabb[3])) < 0.12 && (m.y || 0) + m.h > height),\n })\n }\n }\n return points\n}\n\nexport const hasWindowAt = (point: WallPoint, y: number, clearance = 0.2): boolean =>\n point.windows.some((w) => y + 0.1 > w.y0 - 0.05 && y - 0.1 < w.y1 + 0.05 && Math.abs(point.c - w.at) < w.width / 2 + clearance)\n\nexport const atDoor = (plan: Json, room: Json, point: WallPoint, clearance: number): boolean =>\n plan.doors.some((d: Json) => d.floor === room.floor && d.axis === point.axis && Math.abs(d.pos - point.pos) < 1e-3 && Math.abs(d.at - point.c) < d.width / 2 + clearance)\n","import type { Layout } from './electrical'\nimport { keyOf } from './electrical'\nimport type { Json } from './shared'\nimport { distanceToRect } from './shared'\nimport { atDoor, hasWindowAt } from './wall-points'\nimport type { WallPoint } from './wall-points'\n\n/** Categories that need a socket of their own. */\nconst APPLIANCES = ['fridge', 'display_fridge', 'freezer', 'tv', 'appliance', 'washing_machine', 'air_conditioner', 'cash_register', 'table_light']\nconst COUNTERS = ['kitchen_cabinet', 'workbench', 'checkout_counter']\nconst LAMPS = ['table_light', 'lamp']\n\nconst needsSocket = (item: Json): boolean => APPLIANCES.includes(item.category) || item.category === 'shower'\n\ninterface Pick {\n point: WallPoint\n y: number\n score: number\n}\n\n/** Sockets: one for each appliance (the shower heater too), then enough for the size of each room, two at counter height in a kitchen with a counter. */\nexport function addOutlets(layout: Layout): void {\n const { plan, items, rooms, electrical, pointsOf } = layout\n let counter = 0\n const outletsOf = (room: Json): Json[] => electrical.outlets.filter((t) => t.room === room.id && t.floor === room.floor)\n const newOutlet = (room: Json, point: WallPoint, y: number): Json => {\n const outlet = { id: `outlet${++counter}`, room: room.id, floor: room.floor, u: point.u, v: point.v, y, c: point.c, axis: point.axis, pos: point.pos, frontU: point.nu, frontV: point.nv, type: '2P+T', voltage: 127 }\n electrical.outlets.push(outlet)\n return outlet\n }\n const counters = items.filter((m) => COUNTERS.includes(m.category) && !m.outdoor)\n const heightFor = (room: Json, point: WallPoint): number =>\n room.type === 'kitchen' && counters.some((m) => m.floor === room.floor && m.room === room.id && distanceToRect(point.u, point.v, m.aabb) < 0.45) ? 1.1 : 0.3\n const valid = (room: Json, point: WallPoint, y: number): boolean =>\n !hasWindowAt(point, y, 0.25) && !atDoor(plan, room, point, 0.45) && !outletsOf(room).some((t) => Math.hypot(t.u - point.u, t.v - point.v) < 0.5 && t.y === y)\n const pick = (room: Json, score: (point: WallPoint) => number, fixedY: number | null, ignoreBlocked?: boolean): Pick | null => {\n let best: Pick | null = null\n for (const point of pointsOf.get(keyOf(room)) ?? []) {\n const y = fixedY ?? heightFor(room, point)\n if (!valid(room, point, y)) continue\n const total = score(point) + (point.blocked(y) && !ignoreBlocked ? 5 : 0)\n if (!best || total < best.score) best = { point, y, score: total }\n }\n return best\n }\n const roomOf = (item: Json): Json | undefined => rooms.find((x) => x.id === item.room && x.floor === item.floor)\n const appliances = items.filter((m) => !m.outdoor && needsSocket(m) && rooms.some((c) => c.id === m.room && c.floor === m.floor) && m.category !== 'table_light')\n for (const item of appliances) connectAppliance(item)\n function connectAppliance(item: Json): void {\n const room = roomOf(item)!\n const target = item.aabb\n const nearest = outletsOf(room).map((t) => ({ t, d: distanceToRect(t.u, t.v, target) })).filter((o) => o.d <= 1.2 && o.t.y <= 1.1).sort((a, b) => a.d - b.d)[0]\n const isShower = item.category === 'shower'\n let outlet: Json | null = nearest && !isShower ? nearest.t : null\n if (!outlet) {\n const height = isShower ? 1.1 : item.y > 0.7 ? 1.1 : null\n const best = pick(room, (p) => { const d = distanceToRect(p.u, p.v, target); return isShower && d < 0.6 ? 50 + d : d }, height)\n let chosen = best\n if (!isShower && (!best || distanceToRect(best.point.u, best.point.v, target) > 1.4)) {\n const behind = pick(room, (p) => distanceToRect(p.u, p.v, target), item.y > 0.7 ? 1.1 : null, true)\n if (behind && (!best || distanceToRect(behind.point.u, behind.point.v, target) < distanceToRect(best.point.u, best.point.v, target))) chosen = behind\n }\n if (chosen) outlet = newOutlet(room, chosen.point, chosen.y)\n }\n if (!outlet) return\n item.outlet = outlet.id\n if (isShower) item.showerHeater = { electric: true, powerW: 5500, outlet: outlet.id }\n }\n for (const room of rooms) {\n const area = room.parts.reduce((sum: number, q: number[]) => sum + (q[2]! - q[0]!) * (q[3]! - q[1]!), 0)\n const wanted = Math.max(room.type === 'kitchen' ? 3 : 2, Math.min(6, Math.round(area / 7)))\n const farthest = (existing: Json[]) => (p: WallPoint) => -Math.min(9, ...existing.map((t) => Math.hypot(t.u - p.u, t.v - p.v)))\n for (let guard = 0; outletsOf(room).length < wanted && guard < 12; guard++) {\n const best = pick(room, farthest(outletsOf(room)), null)\n if (!best) break\n newOutlet(room, best.point, best.y)\n }\n if (room.type !== 'kitchen' || !counters.some((m) => m.room === room.id)) continue\n for (let guard = 0; outletsOf(room).filter((t) => t.y === 1.1).length < 2 && guard < 4; guard++) {\n const existing = outletsOf(room)\n const best = pick(room, (p) => (heightFor(room, p) === 1.1 ? 0 : 20) - Math.min(9, ...existing.map((t) => Math.hypot(t.u - p.u, t.v - p.v))), 1.1)\n if (!best) break\n newOutlet(room, best.point, 1.1)\n }\n }\n for (const item of appliances) {\n if (item.category === 'shower' || !item.outlet) continue\n const room = roomOf(item)!\n const current = outletsOf(room).find((t) => t.id === item.outlet)\n if (!current || distanceToRect(current.u, current.v, item.aabb) <= 1.2) continue\n const other = outletsOf(room).filter((t) => t.y <= 1.1).map((t) => ({ t, d: distanceToRect(t.u, t.v, item.aabb) })).sort((a, b) => a.d - b.d)[0]\n if (other && other.d < distanceToRect(current.u, current.v, item.aabb) && other.d <= 1.2) item.outlet = other.t.id\n }\n for (const item of items.filter((m) => LAMPS.includes(m.category) && !m.outdoor)) {\n const room = roomOf(item)\n if (!room) continue\n const nearest = outletsOf(room).map((t) => ({ t, d: distanceToRect(t.u, t.v, item.aabb) })).sort((a, b) => a.d - b.d)[0]\n if (nearest) item.outlet = nearest.t.id\n }\n}\n\n","import type { Layout } from './electrical'\nimport { heightOf, keyOf } from './electrical'\nimport type { Json } from './shared'\nimport { clamp, round2 } from './shared'\nimport { atDoor, hasWindowAt } from './wall-points'\n\nconst METER_SIZE = { w: 0.35, d: 0.2, h: 0.5 }\n\nexport const mainDoorOf = (plan: Json): Json | undefined => plan.doors.find((p: Json) => p.floor === 0 && p.exterior && p.side === 'front') || plan.doors.find((p: Json) => p.floor === 0 && p.exterior)\n\n/** Pole, drop, meter and descent: the meter on the gate pillar (or the facade without a gate); an apartment or shop has it on the facade. */\nexport function placeEntrance(layout: Layout): void {\n const { plan, electrical } = layout\n const gate = plan.gates.find((g: Json) => g.type === 'pedestrian')\n const door = mainDoorOf(plan)\n const lot = plan.lot\n if (lot && plan.style !== 'commercial') {\n const rect = lot.rect\n const poleU = clamp(gate ? gate.u + 3 : plan.w / 2, rect[0] + 0.5, rect[2] - 0.5)\n const poleV = rect[1] - 0.6\n let meter: Json\n if (gate) {\n const direction = gate.u - gate.width / 2 - 0.4 >= rect[0] + 0.3 ? -1 : 1\n meter = { place: 'gate_pillar', u: round2(gate.u + direction * (gate.width / 2 + 0.25)), v: round2(gate.v), y: 1.4, side: 'front', ...METER_SIZE }\n } else meter = { place: 'facade', u: round2(door ? door.at + 1.2 : plan.w / 2), v: -0.1, y: 1.4, side: 'front', ...METER_SIZE }\n meter.id = 'meter'\n electrical.serviceEntrance = { pole: { u: round2(poleU), v: round2(poleV), h: 7.5 }, drop: [[round2(poleU), round2(poleV), 6.5], [meter.u, meter.v, 2.6]], meter, descent: [[meter.u, meter.v, 2.6], [meter.u, meter.v, 1.65]], internalRun: null }\n } else if (lot === null || plan.style === 'commercial') {\n const front = door ? { u: round2(door.at + 1.0), v: -0.1 } : { u: round2(plan.w / 2), v: -0.1 }\n electrical.serviceEntrance = {\n pole: { u: round2(front.u + 2), v: -3, h: 7.5 }, drop: [[round2(front.u + 2), -3, 6.5], [front.u, front.v, 3.2]],\n meter: { id: 'meter', place: 'facade', u: front.u, v: front.v, y: 1.4, side: 'front', ...METER_SIZE }, descent: [[front.u, front.v, 3.2], [front.u, front.v, 1.65]], internalRun: null,\n }\n }\n}\n\n/** The distribution panel in the room of the main door, on the wall nearest the meter, clear of doors and windows and of tall furniture. */\nexport function placePanel(layout: Layout): void {\n const { plan, rooms, electrical, pointsOf } = layout\n const door = mainDoorOf(plan)\n const room = (door && rooms.find((c) => c.id === door.a && c.floor === 0)) || rooms.find((c) => c.floor === 0) || rooms[0]\n if (!room) return\n const meter = electrical.serviceEntrance?.meter\n const targetU = meter ? meter.u : plan.w / 2\n const targetV = meter ? Math.max(0, meter.v) : 0\n let best: { point: Json; score: number } | null = null\n for (const point of pointsOf.get(keyOf(room)) ?? []) {\n if (point.blocked(1.5) || hasWindowAt(point, 1.5, 0.3) || atDoor(plan, room, point, 0.8)) continue\n const score = Math.hypot(point.u - targetU, point.v - targetV) + (point.exterior ? 0 : 3)\n if (!best || score < best.score) best = { point, score }\n }\n if (!best) best = { point: (pointsOf.get(keyOf(room)) ?? [])[0] as Json, score: 0 }\n if (best.point) {\n const p = best.point\n electrical.panel = { id: 'panel', room: room.id, floor: room.floor, u: p.u, v: p.v, y: 1.5, c: p.c, axis: p.axis, pos: p.pos, frontU: p.nu, frontV: p.nv, w: 0.3, h: 0.4, breakers: 0 }\n }\n if (electrical.serviceEntrance && electrical.panel) {\n const entrance = electrical.serviceEntrance\n entrance.internalRun = [[entrance.meter.u, entrance.meter.v, 0.1], [electrical.panel.u, electrical.panel.v, heightOf(plan, electrical.panel.floor, electrical.panel.y)]]\n }\n}\n","import type { Layout } from './electrical'\nimport { heightOf, keyOf } from './electrical'\nimport { mainDoorOf } from './electrical-entrance'\nimport type { Json } from './shared'\nimport { round2 } from './shared'\nimport { atDoor, hasWindowAt, wallPointsOf } from './wall-points'\n\nconst LAMP_CATEGORIES = ['ceiling_light', 'lamp', 'table_light']\n\nconst lampsOf = (layout: Layout): Json[] => layout.items.filter((m) => !m.outdoor && LAMP_CATEGORIES.includes(m.category))\n\n/** A switch by the latch of the main door of each room that has a lamp (and of the room of the front door, for the outside lamp), at 1.10 m. */\nexport function addSwitches(layout: Layout): void {\n const { plan, items, rooms, electrical, pointsOf } = layout\n const lamps = lampsOf(layout)\n const door = mainDoorOf(plan)\n let counter = 0\n const positionFor = (room: Json): { point: Json; door: Json; latch: boolean } | null => {\n const doors = plan.doors\n .filter((p: Json) => p.floor === room.floor && (p.a === room.id || p.b === room.id))\n .sort((a: Json, b: Json) => (a.opensTo === room.id ? 0 : 1) - (b.opensTo === room.id ? 0 : 1) || (a.width < b.width ? 1 : -1))\n const points = wallPointsOf(plan, room, items, 0.12)\n for (const tolerance of [0.16, 0.3]) {\n for (const d of doors) {\n for (const direction of [1, -1]) {\n const target = d.at + direction * (d.width / 2 + 0.18)\n const point = points.filter((q) => q.axis === d.axis && Math.abs(q.pos - d.pos) < 1e-3 && !hasWindowAt(q, 1.1, 0.2)).sort((a, b) => Math.abs(a.c - target) - Math.abs(b.c - target))[0]\n if (point && Math.abs(point.c - target) <= tolerance && !atDoor(plan, room, point, 0.0) && Math.abs(point.c - d.at) >= d.width / 2 + 0.12) return { point, door: d, latch: direction === 1 }\n }\n }\n }\n return null\n }\n for (const room of rooms.concat(plan.rooms.filter((x: Json) => ['stairs'].includes(x.type)))) {\n const roomLamps = lamps.filter((m) => m.room === room.id && m.floor === room.floor)\n const extra = door && door.a === room.id && room.floor === 0 && plan.lot ? [`outdoor_${door.id}`] : []\n if (!roomLamps.length && !extra.length) continue\n if (!pointsOf.get(keyOf(room))) pointsOf.set(keyOf(room), wallPointsOf(plan, room, items))\n const found = positionFor(room)\n if (!found) continue\n const p = found.point\n electrical.switches.push({ id: `switch${++counter}`, room: room.id, floor: room.floor, u: p.u, v: p.v, y: 1.1, c: p.c, axis: p.axis, pos: p.pos, frontU: p.nu, frontV: p.nv, door: found.door.id, latchSide: found.latch, controls: roomLamps.map((m) => m.id).concat(extra) })\n }\n if (door && plan.lot) {\n const id = `outdoor_${door.id}`\n electrical.outdoorLamps.push({ id, u: round2(door.at + door.width / 2 + 0.32), v: round2(door.pos), y: 2.15, door: door.id, switch: electrical.switches.find((s) => s.controls.includes(id))?.id ?? null })\n }\n}\n\n/** One circuit per room with sockets or switches, and the conduits: from the panel up to the ceiling, along it to the room and down to each point. */\nexport function addConduits(layout: Layout): void {\n const { plan, rooms, electrical } = layout\n const panel = electrical.panel\n const lamps = lampsOf(layout)\n for (const room of rooms) {\n const outlets = electrical.outlets.filter((t) => t.room === room.id && t.floor === room.floor)\n const switches = electrical.switches.filter((i) => i.room === room.id && i.floor === room.floor)\n const roomLamps = lamps.filter((m) => m.room === room.id && m.floor === room.floor)\n if (!outlets.length && !switches.length) continue\n const ceiling = (room.ceiling || plan.floors[room.floor].ceiling) - 0.12\n const part = room.parts[0]\n const centreU = round2((part[0] + part[2]) / 2)\n const centreV = round2((part[1] + part[3]) / 2)\n const circuit = { id: `circuit_${room.id}_${room.floor}`, room: room.id, floor: room.floor, outlets: outlets.map((t) => t.id), switches: switches.map((i) => i.id), lamps: roomLamps.map((m) => m.id), exposed: electrical.exposed, gauge_mm2: outlets.length > 3 ? 2.5 : 1.5 }\n electrical.circuits.push(circuit)\n const base = heightOf(plan, room.floor, 0)\n const riser = panel ? [[panel.u, panel.v, heightOf(plan, panel.floor, panel.y)], [panel.u, panel.v, heightOf(plan, panel.floor, 0) + ceiling]] : []\n if (panel) electrical.conduits.push({ id: `conduit_${circuit.id}`, circuit: circuit.id, from: 'panel', to: room.id, exposed: electrical.exposed, diameter: 0.025, points: riser.concat([[centreU, centreV, base + ceiling]]) })\n for (const point of outlets.concat(switches)) {\n electrical.conduits.push({ id: `conduit_${point.id}`, circuit: circuit.id, from: circuit.id, to: point.id, exposed: electrical.exposed, diameter: 0.02, points: [[centreU, centreV, base + ceiling], [point.u, point.v, base + ceiling], [point.u, point.v, base + point.y]] })\n }\n }\n if (panel) panel.breakers = electrical.circuits.length + 1\n}\n","import type { Json, Rng } from './shared'\nimport { NO_SOCKET_ROOMS } from './shared'\nimport { addOutlets } from './electrical-outlets'\nimport { addConduits, addSwitches } from './electrical-circuits'\nimport { placeEntrance, placePanel } from './electrical-entrance'\nimport { wallPointsOf } from './wall-points'\nimport type { WallPoint } from './wall-points'\n\nexport type EnergyMode = 'grid' | 'tap' | 'offgrid'\n\n/** What a template says about its energy (a shack taps the grid without a meter, a cabin may run off-grid on solar). */\nexport interface EnergyConfig {\n mode: EnergyMode\n solar?: boolean\n}\n\nexport interface Electrical {\n mode: EnergyMode\n serviceEntrance: Json | null\n panel: Json | null\n outlets: Json[]\n switches: Json[]\n circuits: Json[]\n conduits: Json[]\n exposed: boolean\n outdoorLamps: Json[]\n source?: 'solar' | 'lamp'\n}\n\nexport interface ElectricalContext {\n plan: Json\n items: Json[]\n rng: Rng\n energy?: EnergyConfig\n}\n\n/** Shared state of the steps that lay the installation out. */\nexport interface Layout {\n plan: Json\n items: Json[]\n rooms: Json[]\n electrical: Electrical\n pointsOf: Map<string, WallPoint[]>\n}\n\nexport const keyOf = (room: Json): string => `${room.id}@${room.floor}`\n\nconst absolute = (plan: Json, floor: number, y: number): number => (plan.floors[floor] ? plan.floors[floor].y0 : 0) + y\nexport const heightOf = absolute\n\n/**\n * The electrical installation: sockets for the appliances and by room size, the service entrance (pole, drop, meter, descent; a tap without meter for a shack),\n * the panel near the entrance, switches by the door latch, circuits and conduits. Items that plug in are annotated (`outlet`, `showerHeater`).\n */\nexport function planElectrical(context: ElectricalContext): Electrical {\n const { plan, items, rng, energy } = context\n const mode: EnergyMode = energy?.mode ?? 'grid'\n const electrical: Electrical = { mode, serviceEntrance: null, panel: null, outlets: [], switches: [], circuits: [], conduits: [], exposed: false, outdoorLamps: [] }\n electrical.exposed = plan.style === 'budget' ? rng() < 0.65 : plan.style === 'mid' ? rng() < 0.12 : false\n if (mode !== 'grid') electrical.exposed = true\n if (mode === 'offgrid') {\n electrical.source = energy?.solar ? 'solar' : 'lamp'\n return electrical\n }\n const rooms = plan.rooms.filter((room: Json) => !NO_SOCKET_ROOMS.includes(room.type) && !room.outdoor)\n const pointsOf = new Map<string, WallPoint[]>()\n for (const room of rooms) pointsOf.set(keyOf(room), wallPointsOf(plan, room, items))\n const layout: Layout = { plan, items, rooms, electrical, pointsOf }\n addOutlets(layout)\n placeEntrance(layout)\n placePanel(layout)\n addSwitches(layout)\n addConduits(layout)\n if (mode === 'tap' && electrical.serviceEntrance?.meter) {\n const entrance = electrical.serviceEntrance\n const meter = entrance.meter\n entrance.tap = true\n entrance.connection = { u: meter.u, v: meter.v, y: 2.6 }\n entrance.meter = null\n }\n return electrical\n}\n","import type { Rect } from '../types'\nimport type { Json, Rng } from './shared'\nimport { HALF_WALL, clamp, groundExteriorWalls, inner, isSolid, outwardOf, overlaps, round2, sideNameOf } from './shared'\n\nexport const CYLINDER_TYPE = 'cooking_gas_cylinder'\nconst CYLINDER = { w: 0.36, d: 0.36, h: 0.48 }\nconst CYLINDER_KG = 13\n\nexport interface GasMeter {\n id: 'gas.meter'\n u: number\n v: number\n y: number\n side: string\n w: number\n d: number\n h: number\n}\n\nexport interface Gas {\n type: 'piped' | 'cylinder'\n meter: GasMeter | null\n}\n\ninterface Spot {\n mode: 'beside' | 'niche' | 'under'\n x: number\n z: number\n rect: Rect\n outdoor?: boolean\n cabinet?: string\n}\n\n/** Gas meter on the front wall of the ground floor, 1.2 m up. */\nfunction placeMeter(plan: Json): GasMeter | null {\n const segments = groundExteriorWalls(plan).sort((a, b) => (b.sides.includes('outside') ? 1 : 0) - (a.sides.includes('outside') ? 1 : 0) || (a.axis === 'u' && a.v0 === 0 ? -1 : 1))\n const wall = segments.find((w) => w.axis === 'u' && w.v0 === 0) || segments[0]\n if (!wall) return null\n const centre = wall.axis === 'u' ? (wall.u0 + wall.u1) / 2 : (wall.v0 + wall.v1) / 2\n const vector = outwardOf(wall)\n const offset = HALF_WALL + 0.1\n return {\n id: 'gas.meter', u: round2(wall.axis === 'u' ? centre : wall.u0 + vector[0] * offset), v: round2(wall.axis === 'u' ? wall.v0 + vector[1] * offset : centre), y: 1.2, side: sideNameOf(vector), w: 0.3, d: 0.15, h: 0.4,\n }\n}\n\ninterface Context {\n plan: Json\n items: Json[]\n stateItems: Json[]\n rng: Rng\n}\n\nfunction besideStove(context: Context, stove: Json, room: Json, solids: Rect[], doorZones: Rect[]): Spot | undefined {\n const t: [number, number] = [-stove.frontV, stove.frontU]\n const parts = room.parts.map(inner)\n for (const s of context.rng() < 0.5 ? [1, -1] : [-1, 1]) {\n const cx = stove.x + t[0] * s * (stove.w / 2 + CYLINDER.w / 2 + 0.03) - (stove.frontU * (stove.d - CYLINDER.d)) / 2\n const cz = stove.z + t[1] * s * (stove.w / 2 + CYLINDER.w / 2 + 0.03) - (stove.frontV * (stove.d - CYLINDER.d)) / 2\n const rect = [cx - CYLINDER.w / 2, cz - CYLINDER.d / 2, cx + CYLINDER.w / 2, cz + CYLINDER.d / 2].map(round2) as Rect\n const inside = parts.some((q: Rect) => rect[0] >= q[0] - 0.011 && rect[2] <= q[2] + 0.011 && rect[1] >= q[1] - 0.011 && rect[3] <= q[3] + 0.011)\n if (inside && !solids.some((o) => overlaps(rect, o, 0.011)) && !doorZones.some((z) => overlaps(rect, z, 0.011))) return { mode: 'beside', x: cx, z: cz, rect }\n }\n return undefined\n}\n\nfunction inNiche(context: Context, stove: Json, room: Json, doorZones: Rect[]): Spot | undefined {\n const { plan, items, stateItems } = context\n const wall = plan.walls.find(\n (p: Json) =>\n p.exterior && p.floor === stove.floor && p.type === 'wall' && p.sides.includes(room.id) &&\n (p.axis === 'u'\n ? Math.abs(stove.x - clamp(stove.x, p.u0, p.u1)) < 1.6 && Math.abs(stove.z - p.v0) < 1.6\n : Math.abs(stove.z - clamp(stove.z, p.v0, p.v1)) < 1.6 && Math.abs(stove.x - p.u0) < 1.6),\n )\n if (!wall || stove.floor !== 0) return undefined\n const vector = outwardOf(wall)\n const cx = wall.axis === 'u' ? clamp(stove.x, wall.u0 + 0.4, wall.u1 - 0.4) : wall.u0 + vector[0] * (HALF_WALL + CYLINDER.w / 2 + 0.05)\n const cz = wall.axis === 'u' ? wall.v0 + vector[1] * (HALF_WALL + CYLINDER.d / 2 + 0.05) : clamp(stove.z, wall.v0 + 0.4, wall.v1 - 0.4)\n const rect = [cx - CYLINDER.w / 2, cz - CYLINDER.d / 2, cx + CYLINDER.w / 2, cz + CYLINDER.d / 2].map(round2) as Rect\n const blockedByItem = items.some((o) => o.outdoor && isSolid(o) && overlaps(rect, o.aabb, 0.011))\n const blockedByState = stateItems.some((o) => o.outdoor && o.aabb && !o.flat && o.mount !== 'ground' && overlaps(rect, o.aabb, 0.011))\n const blockedByPath = plan.paths.some((c: Json) => c.rects.some((z: Rect) => overlaps(rect, z, 0.011)))\n const blockedByGate = plan.gates.some((g: Json) => g.zones.some((z: Rect) => overlaps(rect, z, 0.011)))\n const blockedByFence = !plan.lot || plan.lot.perimeter.some((q: Json) => overlaps(rect, [Math.min(q.u0, q.u1) - HALF_WALL, Math.min(q.v0, q.v1) - HALF_WALL, Math.max(q.u0, q.u1) + HALF_WALL, Math.max(q.v0, q.v1) + HALF_WALL], 0.011))\n if (blockedByItem || blockedByState || blockedByPath || doorZones.some((z) => overlaps(rect, z, 0.011)) || blockedByGate || blockedByFence) return undefined\n return { mode: 'niche', x: cx, z: cz, rect, outdoor: true }\n}\n\nfunction underCounter(context: Context, stove: Json): Spot | undefined {\n const distance = (m: Json): number => Math.hypot(m.x - stove.x, m.z - stove.z)\n const cabinets = context.items\n .filter(\n (m) => m.floor === stove.floor && m.room === stove.room && !m.outdoor && !m.on && !m.flat && ['kitchen_cabinet', 'workbench'].includes(m.category) && m.aabb && m.id !== stove.id &&\n Math.min(m.aabb[2] - m.aabb[0], m.aabb[3] - m.aabb[1]) >= CYLINDER.d - 0.011 && Math.max(m.aabb[2] - m.aabb[0], m.aabb[3] - m.aabb[1]) >= CYLINDER.w + 0.02,\n )\n .sort((a, b) => (a.category === 'kitchen_cabinet' ? 0 : 1) - (b.category === 'kitchen_cabinet' ? 0 : 1) || distance(a) - distance(b))\n for (const cabinet of cabinets) {\n if (distance(cabinet) > 3) continue\n const box = cabinet.aabb as Rect\n const hw = CYLINDER.w / 2\n const hd = CYLINDER.d / 2\n const cx = clamp(stove.x, box[0] + hw + 0.01, box[2] - hw - 0.01)\n const cz = clamp(stove.z, box[1] + hd + 0.01, box[3] - hd - 0.01)\n const rect = [cx - hw, cz - hd, cx + hw, cz + hd].map(round2) as Rect\n if (rect[0] < box[0] || rect[2] > box[2] || rect[1] < box[1] || rect[3] > box[3] || overlaps(rect, stove.aabb, 0.011)) continue\n return { mode: 'under', x: cx, z: cz, rect, cabinet: cabinet.id }\n }\n return undefined\n}\n\nconst PLACEMENT = { beside: 'beside', niche: 'external_niche', under: 'under_counter' } as const\n\nfunction cylinderItem(stove: Json, spot: Spot): Json {\n const item: Json = {\n id: `${stove.room}.${CYLINDER_TYPE}`, type: CYLINDER_TYPE, category: CYLINDER_TYPE, x: round2(spot.x), z: round2(spot.z), ry: 0, w: CYLINDER.w, d: CYLINDER.d, h: CYLINDER.h, y: 0,\n frontU: -stove.frontU, frontV: -stove.frontV, room: stove.room, floor: stove.floor, outdoor: !!spot.outdoor, slot: 'cylinder', on: null, mode: null, clearance: 0, flat: false, low: false,\n aabb: spot.rect, link: stove.id, placement: PLACEMENT[spot.mode], hose: [[round2(spot.x), round2(spot.z), 0.3], [stove.x, stove.z, 0.5]], capacityKg: CYLINDER_KG,\n }\n if (spot.cabinet) {\n item.on = spot.cabinet\n item.hidden = true\n }\n if (spot.outdoor) item.floor = -1\n item.color = stove.color\n return item\n}\n\n/**\n * Gas for the stoves of the house: a cylinder beside the stove, in an outside niche with a hose or under the counter, or (high-end houses, or when\n * nothing fits) piped gas with a meter on the facade. The cylinders are added to `items`; the stoves are annotated (`gas`, `cylinder`, `gasMeter`).\n */\nexport function planGas(context: Context): Gas | null {\n const { plan, items, stateItems, rng } = context\n const stoves = items.filter((m) => m.category === 'stove' && !m.outdoor)\n if (!stoves.length) return null\n const high = plan.style === 'high'\n const piped = plan.style !== 'commercial' && (high ? rng() < 0.8 : plan.style === 'mid' ? rng() < 0.1 : false)\n const out: Gas = { type: piped ? 'piped' : 'cylinder', meter: null }\n const ensureMeter = (): void => {\n if (!out.meter) out.meter = placeMeter(plan)\n }\n for (const stove of stoves) {\n const room = plan.rooms.find((c: Json) => c.id === stove.room && c.floor === stove.floor)\n if (!room) continue\n stove.gas = piped ? 'piped' : 'cylinder'\n if (piped) {\n ensureMeter()\n stove.gasMeter = 'gas.meter'\n continue\n }\n const solids = items.filter((m) => m.floor === stove.floor && m.room === stove.room && isSolid(m) && m.id !== stove.id).map((m) => m.aabb as Rect)\n .concat(stateItems.filter((m) => m.aabb && m.room === stove.room && m.floor === stove.floor && !m.flat && !m.on && m.mount !== 'window' && m.mount !== 'ground').map((m) => m.aabb as Rect))\n const doorZones = plan.doors.filter((p: Json) => p.floor === stove.floor).flatMap((p: Json) => p.zones as Rect[])\n const order: Spot['mode'][] = rng() < 0.7 ? ['beside', 'niche', 'under'] : ['niche', 'beside', 'under']\n let spot: Spot | undefined\n for (const mode of order) {\n if (spot) break\n spot = mode === 'beside' ? besideStove(context, stove, room, solids, doorZones) : mode === 'niche' ? inNiche(context, stove, room, doorZones) : underCounter(context, stove)\n }\n if (!spot) {\n stove.gas = 'piped'\n out.type = 'piped'\n ensureMeter()\n stove.gasMeter = 'gas.meter'\n continue\n }\n const cylinder = cylinderItem(stove, spot)\n items.push(cylinder)\n stove.cylinder = cylinder.id\n }\n return out\n}\n","import type { Json } from './shared'\nimport { round2 } from './shared'\nimport type { WaterTank } from '../types'\n\nconst FIXTURES: Record<string, string> = { kitchen_cabinet: 'tap', washbasin: 'tap', shower: 'shower', toilet: 'flush', laundry_tub: 'tub', washing_machine: 'machine' }\nconst FLOW_LPM: Record<string, number> = { tap: 6, shower: 9, flush: 6, tub: 8, machine: 12 }\nconst POINT_HEIGHT: Record<string, number> = { shower: 2.1, flush: 0.9, machine: 0.8 }\nconst DEFAULT_CAPACITY = { budget: 500, mid: 1000 }\n\nexport interface PlumbingContext {\n plan: Json\n items: Json[]\n tank: WaterTank | null\n}\n\nconst absolute = (plan: Json, floor: number, y: number): number => (plan.floors[floor] ? plan.floors[floor].y0 : 0) + y\n\n/**\n * Plumbing as logic: a point for every tap, shower, toilet, tub and machine, and the runs you can see: the outlet of the tank, under each sink and in the wall\n * from the tank to every wet room (hidden in the wall, it shows only where the wall breaks).\n */\nexport function planPlumbing(context: PlumbingContext): Json {\n const { plan, items, tank } = context\n const fixtures = items.filter((m) => FIXTURES[m.category] && !m.decor)\n const points: Json[] = []\n const runs: Json[] = []\n const capacity = tank?.capacity ?? (plan.style === 'budget' ? DEFAULT_CAPACITY.budget : plan.style === 'mid' ? DEFAULT_CAPACITY.mid : plan.tpl?.id === 'mansion' ? 3000 : 2000)\n const plumbing: Json = { tank: tank ? 'water_tank' : null, capacityL: tank || !plan.tpl.noWalls ? capacity : 0, points, visibleRuns: runs }\n const top = plan.floors.length - 1\n fixtures.forEach((item, index) => {\n const kind = FIXTURES[item.category]!\n points.push({ id: `pt${index + 1}`, kind, item: item.id, room: item.room, floor: item.outdoor ? -1 : item.floor, u: item.x, v: item.z, y: POINT_HEIGHT[kind] ?? 0.9, flowLpm: FLOW_LPM[kind], run: null })\n })\n if (!tank) return plumbing\n const slabY = absolute(plan, top, plan.floors[top].ceiling)\n const tankY = tank.place === 'raised_slab' ? tank.platform!.topY : tank.place === 'attic' ? slabY + 0.5 : tank.y\n runs.push({ id: 'run_outlet', from: 'water_tank', to: 'ceiling', points: [[tank.u, tank.v, round2(tankY + 0.15)], [tank.u, tank.v, round2(slabY - 0.15)]], diameter: 0.032, exposed: 'tank_outlet' })\n for (const point of points) {\n const item = fixtures.find((x) => x.id === point.item)!\n if (point.kind !== 'tap' || item.outdoor) continue\n const front = [item.frontU || 0, item.frontV || 1]\n const behind = [item.x - front[0]! * (item.d / 2 + 0.02), item.z - front[1]! * (item.d / 2 + 0.02)]\n runs.push({ id: `run_under_${point.id}`, from: 'valve', to: point.id, points: [[round2(behind[0]!), round2(behind[1]!), absolute(plan, item.floor, 0.5)], [item.x, item.z, absolute(plan, item.floor, 0.5)], [item.x, item.z, absolute(plan, item.floor, 0.75)]], diameter: 0.025, exposed: 'under_sink' })\n }\n const wet: { room: string; floor: number; points: Json[] }[] = []\n for (const point of points) {\n if (!wet.some((c) => c.room === point.room && c.floor === point.floor)) wet.push({ room: point.room, floor: point.floor, points: points.filter((q) => q.room === point.room && q.floor === point.floor) })\n }\n for (const room of wet) {\n const found = plan.rooms.find((c: Json) => c.id === room.room && c.floor === room.floor)\n const zone = plan.zones.find((z: Json) => z.id === room.room)\n const parts = (found || zone || { parts: [[tank.u, tank.v, tank.u, tank.v]] }).parts\n const centreU = (parts[0][0] + parts[0][2]) / 2\n const centreV = (parts[0][1] + parts[0][3]) / 2\n const ceiling = found ? found.ceiling || plan.floors[found.floor].ceiling : 2.8\n const y0 = found ? absolute(plan, found.floor, 0) : 0\n const id = `run_wall_${room.room}${room.floor === -1 ? '_outside' : `_${room.floor}`}`\n runs.push({ id, from: 'water_tank', to: room.room, points: [[tank.u, tank.v, round2(slabY - 0.15)], [round2(centreU), round2(centreV), round2(slabY - 0.15)], [round2(centreU), round2(centreV), round2(y0 + ceiling - 0.15)], [round2(centreU), round2(centreV), round2(y0 + 0.6)]], diameter: 0.025, exposed: 'wall' })\n for (const point of room.points) point.run = id\n }\n return plumbing\n}\n","import { outwardOf, groundExteriorWalls, HALF_WALL, round2, sideNameOf } from './shared'\nimport type { Json, Rng } from './shared'\nimport type { EnergyConfig } from './electrical'\n\nconst PANEL_WIDTH = 1.0\nconst PANEL_LENGTH = 1.65\nconst NO_PANELS_UNDER: readonly string[] = ['void', 'elevator', 'stairs', 'balcony', 'terrace', 'porch']\n\nexport interface SolarContext {\n plan: Json\n rng: Rng\n energy?: EnergyConfig\n}\n\n/** Inverter on a side wall of the ground floor, 1.5 m up. */\nfunction placeInverter(plan: Json): Json | null {\n const wall = groundExteriorWalls(plan).filter((q) => q.sides.includes('outside')).sort((a, b) => (a.axis === 'v' ? 0 : 1) - (b.axis === 'v' ? 0 : 1))[0]\n if (!wall) return null\n const vector = outwardOf(wall)\n const centre = wall.axis === 'u' ? (wall.u0 + wall.u1) / 2 : (wall.v0 + wall.v1) / 2\n const offset = HALF_WALL + 0.08\n return { id: 'inverter', u: round2(wall.axis === 'u' ? centre : wall.u0 + vector[0] * offset), v: round2(wall.axis === 'u' ? wall.v0 + vector[1] * offset : centre), y: 1.5, side: sideNameOf(vector), w: 0.4, d: 0.15, h: 0.5, outdoor: true, link: 'panel' }\n}\n\n/**\n * Solar panels: about 6% of budget houses, 25% of mid and 50% of the rest; on the roof slope that faces north or on tilted racks on a flat roof, with the\n * inverter on the wall. A template with its own energy decides (`energy.solar`).\n */\nexport function planSolar(context: SolarContext): Json | null {\n const { plan, rng, energy } = context\n if (!plan.lot || plan.style === 'commercial' || !plan.facade) return null\n const chance = plan.style === 'budget' ? 0.06 : plan.style === 'mid' ? 0.25 : 0.5\n const forced = energy ? (energy.solar ? 1 : 0) : null\n const draw = rng()\n if (forced !== null ? !forced : draw >= chance) return null\n const floor = plan.floors.length - 1\n const level = plan.floors[floor]\n const flat = plan.facade.roof === 'slab'\n const tops = plan.rooms.filter((c: Json) => c.floor === floor && !NO_PANELS_UNDER.includes(c.type))\n if (!tops.length) return null\n const parts: number[][] = tops.flatMap((c: Json) => c.parts)\n const box = [Math.min(...parts.map((q) => q[0]!)), Math.min(...parts.map((q) => q[1]!)), Math.max(...parts.map((q) => q[2]!)), Math.max(...parts.map((q) => q[3]!))] as [number, number, number, number]\n const north = rng() < 0.5 ? 'front' : 'back'\n const angle = flat ? 15 : 25\n const projection = round2(PANEL_LENGTH * Math.cos((angle * Math.PI) / 180))\n const margin = 0.6\n const uStart = box[0] + margin\n const uEnd = box[2] - margin\n const columns = Math.max(1, Math.floor((uEnd - uStart) / (PANEL_WIDTH + 0.05)))\n const vMiddle = (box[1] + box[3]) / 2\n const vArea = flat ? [box[1] + margin, box[3] - margin] : north === 'front' ? [box[1] + 0.4, vMiddle - 0.2] : [vMiddle + 0.2, box[3] - 0.4]\n const step = flat ? projection + 0.5 : projection + 0.05\n const rowsMax = Math.max(1, Math.floor((vArea[1]! - vArea[0]!) / step))\n const wanted = forced !== null ? 1 + Math.floor(rng() * 2) : 3 + Math.floor(rng() * (plan.style === 'high' ? 12 : 8))\n const rows = Math.max(1, Math.min(rowsMax, Math.ceil(wanted / columns)))\n const count = Math.min(wanted, rows * columns)\n const u0 = uStart + (uEnd - uStart - columns * (PANEL_WIDTH + 0.05)) / 2\n const vStart = north === 'front' ? vArea[0]! : vArea[1]! - rows * step\n const panels: Json[] = []\n for (let k = 0; k < count; k++) {\n const row = Math.floor(k / columns)\n const column = k % columns\n panels.push({ id: `pv${k + 1}`, u: round2(u0 + column * (PANEL_WIDTH + 0.05) + PANEL_WIDTH / 2), v: round2(vStart + row * step + (flat ? 0.25 : 0) + projection / 2), w: PANEL_WIDTH, d: projection, length: PANEL_LENGTH })\n }\n const area = [round2(u0), round2(vStart), round2(u0 + columns * (PANEL_WIDTH + 0.05)), round2(vStart + rows * step)]\n return { type: flat ? 'slab_rack' : 'roof', orientation: 'north', north, slopeSide: flat ? null : north, tilt: angle, area, areaM2: round2(count * PANEL_WIDTH * PANEL_LENGTH), count, floor, y: round2(level.y0 + level.ceiling), panels, inverter: placeInverter(plan) }\n}\n","import type { FindsQuery, FindStack } from '@adatechnology/game-floorplan'\n\nimport type { WaterTank } from '../types'\nimport { hasContent } from './content'\nimport type { EnergyConfig, Electrical } from './electrical'\nimport { planElectrical } from './electrical'\nimport { planGas } from './gas'\nimport type { Gas } from './gas'\nimport { planPlumbing } from './plumbing'\nimport type { Json, Rng } from './shared'\nimport { planSolar } from './solar'\n\nexport interface Utilities {\n gas: Gas | null\n electrical: Electrical\n solar: Json | null\n plumbing: Json\n}\n\nexport interface UtilitiesContext {\n plan: Json\n items: Json[]\n stateItems: Json[]\n tank: WaterTank | null\n energy?: EnergyConfig\n /** Seeded stream by name: `gas`, `electrical`, `solar`. */\n rngFor(key: string): Rng\n}\n\n/** Gas, electricity, solar panels and plumbing of a house, in the order that lets the later ones see the cylinders the first adds to `items`. */\nexport function planUtilities(context: UtilitiesContext): Utilities {\n const { plan, items, stateItems, tank, energy, rngFor } = context\n const gas = planGas({ plan, items, stateItems, rng: rngFor('gas') })\n const electrical = planElectrical({ plan, items, rng: rngFor('eletrica'), ...(energy ? { energy } : {}) })\n const solar = planSolar({ plan, rng: rngFor('solar'), ...(energy ? { energy } : {}) })\n const plumbing = planPlumbing({ plan, items, tank })\n return { gas, electrical, solar, plumbing }\n}\n\nconst OVERHEAD = 'overhead_cabinet'\nconst ALWAYS_HOLD: readonly string[] = ['trash_bin', 'outdoor_bin', 'mailbox']\n\nexport interface ContentsContext {\n items: Json[]\n state: string\n place: string\n /** Outbreak days and region of the world, passed to the finds provider. */\n day?: number\n region?: string\n rngFor(key: string): Rng\n findsFor(query: FindsQuery): readonly FindStack[]\n}\n\n/** What every container holds, asked of the registered finds provider: by item id, and `<id>#overhead` for the wall cabinet over a sink. */\nexport function planContents(context: ContentsContext): Record<string, readonly FindStack[]> {\n const out: Record<string, readonly FindStack[]> = {}\n const ask = (item: Json, container: string, key: string): readonly FindStack[] =>\n context.findsFor({ place: context.place, container, state: context.state, rng: context.rngFor(key), footprint: item.w * item.d, key: item.id, ...(context.day === undefined ? {} : { day: context.day }), ...(context.region === undefined ? {} : { region: context.region }) })\n for (const item of context.items) {\n if (item.decor && item.mount !== 'wall_top') continue\n const container = hasContent(item.type) ? item.type : item.category\n if (!hasContent(container)) continue\n if (!ALWAYS_HOLD.includes(container) && item.decor) continue\n out[item.id] = ask(item, container, `content:${item.id}`)\n if (container === 'kitchen_cabinet' && item.overhead !== false) out[`${item.id}#overhead`] = ask(item, OVERHEAD, `content:${item.id}:overhead`)\n }\n return out\n}\n","import type { Rect } from '../types'\nimport type { Json, Rng } from './shared'\nimport { isSolid, overlaps, round2 } from './shared'\n\nconst WALL = 0.15\nconst DOOR_WIDTH = 0.85\nconst DOOR_HEIGHT = 2.1\nconst USES: Record<string, string[]> = { guest_room: ['single_bed', 'nightstand'], office: ['desk', 'shelf_unit_small'], storage: ['tool_shelf', 'crate'], gourmet: ['dining_table_small', 'workbench'] }\nconst USE_WEIGHTS: Record<string, number> = { guest_room: 3, office: 2, storage: 2, gourmet: 2 }\nconst PATH_WIDTH = 1.0\n\nexport interface OutbuildingContext {\n plan: Json\n items: Json[]\n catalog: Record<string, Json>\n rngFor(key: string): Rng\n}\n\n/**\n * Name of the seeded stream of an outbuilding. It is the name the Visor de casas 3D gave it (`edif:<room>.<slot>` in Portuguese: `quintal.edicula`), kept verbatim so that an\n * old seed draws the same use and furniture; it never appears in the output.\n */\nconst LEGACY_ROOMS: Record<string, string> = { backyard: 'quintal' }\nconst LEGACY_SLOTS: Record<string, string> = { outbuilding: 'edicula' }\nexport const streamOf = (itemId: string): string => {\n const [room = '', ...slot] = itemId.split('.')\n return `edif:${LEGACY_ROOMS[room] ?? room}.${slot.map((part) => LEGACY_SLOTS[part] ?? part).join('.')}`\n}\n\nfunction pickWeighted(rng: Rng, weights: Record<string, number>): string {\n const keys = Object.keys(weights)\n let x = rng() * keys.reduce((sum, key) => sum + weights[key]!, 0)\n for (const key of keys) {\n x -= weights[key]!\n if (x < 0) return key\n }\n return keys[keys.length - 1]!\n}\n\nconst sideOf = (x: number, z: number): string => (Math.abs(x) > Math.abs(z) ? (x > 0 ? 'right' : 'left') : z > 0 ? 'back' : 'front')\n\ninterface Frame {\n n: [number, number]\n t: [number, number]\n cx: number\n cz: number\n depth: number\n width: number\n horizontal: boolean\n sideToMiddle: number\n}\n\nconst at = (frame: Frame, a: number, b: number): [number, number] => [frame.cx + frame.n[0] * a + frame.t[0] * b, frame.cz + frame.n[1] * a + frame.t[1] * b]\n\nfunction opening(frame: Frame, id: string, a: number, b: number, vector: [number, number], width: number, extra: Json): Json {\n const [u, v] = at(frame, a, b)\n const alongU = Math.abs(vector[0]) !== 1\n return { id, axis: alongU ? 'u' : 'v', pos: round2(alongU ? v : u), at: round2(alongU ? u : v), u: round2(u), v: round2(v), width: round2(width), side: sideOf(vector[0], vector[1]), ...extra }\n}\n\nfunction wallsOf(box: Rect, door: Json, height: number): Json[] {\n const walls: Json[] = []\n const sides = [\n { axis: 'u', pos: box[1], i0: box[0], i1: box[2], side: 'front' }, { axis: 'u', pos: box[3], i0: box[0], i1: box[2], side: 'back' },\n { axis: 'v', pos: box[0], i0: box[1], i1: box[3], side: 'left' }, { axis: 'v', pos: box[2], i0: box[1], i1: box[3], side: 'right' },\n ]\n for (const w of sides) {\n const cut = w.axis === door.axis && Math.abs(w.pos - door.pos) < 0.02 ? [door.at - door.width / 2, door.at + door.width / 2] : null\n const segments = cut ? [[w.i0, cut[0]!], [cut[1]!, w.i1]] : [[w.i0, w.i1]]\n for (const [x0, x1] of segments) {\n if (x1! - x0! <= 1e-3) continue\n walls.push(w.axis === 'u' ? { axis: 'u', u0: round2(x0!), v0: round2(w.pos), u1: round2(x1!), v1: round2(w.pos), thickness: WALL, h: height, side: w.side } : { axis: 'v', u0: round2(w.pos), v0: round2(x0!), u1: round2(w.pos), v1: round2(x1!), thickness: WALL, h: height, side: w.side })\n }\n }\n return walls\n}\n\nfunction furnish(context: OutbuildingContext, frame: Frame, use: string, interior: Rect, insideDoor: Rect): Json[] {\n const placed: Json[] = []\n USES[use]!.forEach((type, k) => {\n const def = context.catalog[type]!\n const facing: [number, number] = k === 0 ? frame.n : [frame.t[0] * frame.sideToMiddle, frame.t[1] * frame.sideToMiddle]\n const [a, b] = k === 0 ? [-frame.depth / 2 + WALL + def.d / 2, frame.sideToMiddle * -0.4] : [-0.1, -frame.sideToMiddle * (frame.width / 2 - WALL - def.d / 2)]\n const [u, v] = at(frame, a, b)\n const eu = Math.abs(facing[0]) === 1 ? def.d : def.w\n const ev = Math.abs(facing[0]) === 1 ? def.w : def.d\n const box = [u - eu / 2, v - ev / 2, u + eu / 2, v + ev / 2].map(round2) as Rect\n if (box[0] < interior[0] - 0.011 || box[2] > interior[2] + 0.011 || box[1] < interior[1] - 0.011 || box[3] > interior[3] + 0.011 || overlaps(box, insideDoor) || placed.some((o) => overlaps(box, o.aabb))) return\n placed.push({ type, category: def.category, u: round2(u), v: round2(v), w: def.w, d: def.d, h: def.h, ry: Math.atan2(facing[0], facing[1]), frontU: facing[0], frontV: facing[1], aabb: box })\n })\n return placed\n}\n\n/**\n * The outbuilding at the back of the yard is a small building of its own: walls with a gap for the door, a door of 0.85 m facing the yard, two windows and the\n * furniture of a drawn use (guest room, office, storage, gourmet space).\n */\nexport function planOutbuildings(context: OutbuildingContext): Json[] {\n const { plan, items } = context\n const lot = plan.lot\n if (!lot) return []\n const out: Json[] = []\n for (const item of items.filter((m) => m.category === 'outbuilding')) {\n const rng = context.rngFor(streamOf(item.id))\n const [a0, a1, a2, a3] = item.aabb as Rect\n const n: [number, number] = [item.frontU, item.frontV]\n const t: [number, number] = [-item.frontV, item.frontU]\n const horizontal = Math.abs(item.frontU) === 1\n const cx = (a0 + a2) / 2\n const cz = (a1 + a3) / 2\n const depth = horizontal ? a2 - a0 : a3 - a1\n const width = horizontal ? a3 - a1 : a2 - a0\n const sideToMiddle = ((lot.rect[0] + lot.rect[2]) / 2 - cx) * t[0] + ((lot.rect[1] + lot.rect[3]) / 2 - cz) * t[1] >= 0 ? 1 : -1\n const frame: Frame = { n, t, cx, cz, depth, width, horizontal, sideToMiddle }\n const doorOffset = sideToMiddle * (width / 2 - 0.95)\n const door = opening(frame, `${item.id}.d0`, depth / 2, doorOffset, n, DOOR_WIDTH, { height: DOOR_HEIGHT, exterior: true })\n const windowFront = opening(frame, `${item.id}.w0`, depth / 2, -sideToMiddle * (width / 2 - 0.9), n, Math.min(1.0, width / 2 - 0.6), { y0: 1.0, y1: 2.0 })\n const windowSide = opening(frame, `${item.id}.w1`, 0, (sideToMiddle * width) / 2, [t[0] * sideToMiddle, t[1] * sideToMiddle], Math.min(1.0, depth - 0.8), { y0: 1.0, y1: 2.0 })\n const [p, q] = [at(frame, depth / 2, doorOffset), at(frame, depth / 2 - 0.9, doorOffset)]\n door.zone = (horizontal ? [Math.min(p[0], q[0]), p[1] - door.width / 2, Math.max(p[0], q[0]), p[1] + door.width / 2] : [p[0] - door.width / 2, Math.min(p[1], q[1]), p[0] + door.width / 2, Math.max(p[1], q[1])]).map(round2)\n const interior: Rect = [a0 + WALL, a1 + WALL, a2 - WALL, a3 - WALL]\n const use = pickWeighted(rng, USE_WEIGHTS)\n out.push({ id: item.id, type: 'outbuilding', use, floor: 0, aabb: (item.aabb as Rect).slice(), interior: [interior.map(round2)], ceiling: item.h, thickness: WALL, front: n, walls: wallsOf(item.aabb, door, item.h), doors: [door], windows: [windowFront, windowSide], items: furnish(context, frame, use, interior, door.zone) })\n }\n return out\n}\n\n/** A pedestrian path from every door of an outbuilding: a 1 m stub out of the door and an L to the nearest existing path, away from furniture, the building and the fence. */\nexport function addOutbuildingPaths(lot: Json, outbuildings: Json[], items: Json[]): void {\n const half = PATH_WIDTH / 2\n const rect = lot.rect as Rect\n const solids = items.filter((m) => m.outdoor && m.aabb && isSolid(m)).map((m) => m.aabb as Rect)\n const fence = lot.perimeter.map((q: Json) => [Math.min(q.u0, q.u1) - 0.075, Math.min(q.v0, q.v1) - 0.075, Math.max(q.u0, q.u1) + 0.075, Math.max(q.v0, q.v1) + 0.075] as Rect)\n const strip = (p: number[], q: number[]): Rect => [Math.min(p[0]!, q[0]!) - half, Math.min(p[1]!, q[1]!) - half, Math.max(p[0]!, q[0]!) + half, Math.max(p[1]!, q[1]!) + half]\n for (const building of outbuildings) {\n for (const door of building.doors as Json[]) {\n if (lot.paths.some((c: Json) => c.to === door.id)) continue\n const z = door.zone as Rect\n const zc = door.axis === 'v' ? (z[0] + z[2]) / 2 : (z[1] + z[3]) / 2\n const outside = zc > door.pos ? -1 : 1\n const A = door.axis === 'v' ? [door.pos, door.at] : [door.at, door.pos]\n const S = door.axis === 'v' ? [door.pos + outside * PATH_WIDTH, door.at] : [door.at, door.pos + outside * PATH_WIDTH]\n const stub: Rect = door.axis === 'v' ? [Math.min(A[0]!, S[0]!), A[1]! - half, Math.max(A[0]!, S[0]!), A[1]! + half] : [A[0]! - half, Math.min(A[1]!, S[1]!), A[0]! + half, Math.max(A[1]!, S[1]!)]\n const cost = (rs: Rect[]): number => {\n let n = 0\n for (const r of rs) {\n const c: Rect = [r[0] + 0.02, r[1] + 0.02, r[2] - 0.02, r[3] - 0.02]\n for (const q of solids) if (overlaps(c, q, 0.011)) n += 2\n if (overlaps(c, building.aabb, 0.011)) n += 3\n for (const q of fence) if (overlaps(c, q, 0.011)) n += 3\n if (r[0] < rect[0] || r[1] < rect[1] || r[2] > rect[2] || r[3] > rect[3]) n += 3\n }\n return n\n }\n let best: { v: number; k: { rects: Rect[]; points: number[][] }; from: string | null } | null = null\n for (const c of lot.paths.filter((p: Json) => p.type === 'pedestrian' || p.id === 'cargo_path')) {\n for (const r of c.rects as Rect[]) {\n const T = [Math.min(Math.max(S[0]!, r[0] + half), r[2] - half), Math.min(Math.max(S[1]!, r[1] + half), r[3] - half)]\n const candidates: { rects: Rect[]; points: number[][] }[] = []\n if (Math.abs(T[0]! - S[0]!) < 1e-6 && Math.abs(T[1]! - S[1]!) < 1e-6) candidates.push({ rects: [stub], points: [A, S] })\n else for (const via of [[T[0]!, S[1]!], [S[0]!, T[1]!]]) candidates.push({ rects: [stub, strip(S, via), strip(via, T)].filter((q) => q[2] - q[0] > 1e-6), points: [A, S, via, T] })\n for (const k of candidates) {\n const distance = k.points.slice(1).reduce((sum, q, i) => sum + Math.abs(q[0]! - k.points[i]![0]!) + Math.abs(q[1]! - k.points[i]![1]!), 0)\n const value = cost(k.rects.slice(1)) * 100 + distance\n if (!best || value < best.v) best = { v: value, k, from: c.from }\n }\n }\n }\n const chosen = best ? best.k : { rects: [stub], points: [A, S] }\n lot.paths.push({ id: `path_${door.id}`, type: 'pedestrian', from: best ? best.from : null, to: door.id, width: PATH_WIDTH, rects: chosen.rects.map((q) => q.map(round2)), points: chosen.points.map((q) => q.map(round2)) })\n }\n }\n}\n","import { round2 } from './geometry'\nimport type { Rect, StructureSource, WaterTank } from './types'\n\ntype Rng = () => number\n\nconst TANK_SIDE = 1.1\nconst NOT_UNDER_TANK = ['void', 'elevator', 'stairs', 'balcony', 'porch']\nconst WET_ROOMS = ['bathroom', 'kitchen', 'laundry']\nconst ATTIC_CHANCE = 0.12\nconst clamp = (value: number, low: number, high: number): number => Math.max(low, Math.min(high, value))\n\nexport interface TankPlanOptions {\n /** Litres by template id or style id (default: budget 500, mid 1000, mansion 3000, any other 2000). */\n capacities?: Record<string, number>\n /** Where the tank goes; default: on the slab of a flat roof, else on a raised platform (the attic one time in eight). */\n location?: (source: StructureSource, rng: Rng) => WaterTank['place']\n /** A template with its own tank (a trestle for the rural water) answers here instead. */\n custom?: (source: StructureSource, rng: Rng) => WaterTank | null\n}\n\nconst DEFAULT_CAPACITIES: Record<string, number> = { budget: 500, mid: 1000, mansion: 3000 }\n\nfunction capacityOf(source: StructureSource, capacities: Record<string, number>): number {\n return capacities[source.style ?? ''] ?? capacities[source.template ?? ''] ?? 2000\n}\n\n/** Candidate spot: the room part with the least weight (wet rooms first, terraces last, near the reference point or the middle). */\nfunction bestSpot(source: StructureSource, floor: number, reference: { u: number; v: number } | undefined): { roomType: string; roomId: string; rect: Rect } | undefined {\n const centre: [number, number] = reference ? [reference.u, reference.v] : [source.w / 2, source.d / 2]\n let best: { roomType: string; roomId: string; rect: Rect; weight: number } | undefined\n for (const room of source.rooms.filter((r) => r.floor === floor && !NOT_UNDER_TANK.includes(r.type))) {\n for (const part of room.parts) {\n const rect: Rect = [part[0] + 0.4, part[1] + 0.4, part[2] - 0.4, part[3] - 0.4]\n if (rect[2] - rect[0] < TANK_SIDE || rect[3] - rect[1] < TANK_SIDE) continue\n const base = WET_ROOMS.includes(room.type) ? 0 : room.type === 'terrace' ? 500 : 100\n const weight = base + Math.hypot((rect[0] + rect[2]) / 2 - centre[0], (rect[1] + rect[3]) / 2 - centre[1])\n if (!best || weight < best.weight) best = { roomType: room.type, roomId: room.id, rect, weight }\n }\n }\n return best\n}\n\nfunction raisedPlatform(source: StructureSource, u: number, v: number, baseY: number): NonNullable<WaterTank['platform']> {\n const margin = 0.12\n const edge = Math.max(0, Math.min(u, source.w - u, v, source.d - v))\n const rise = round2(clamp(edge * 0.35 + 0.7, 1.1, 2.4))\n const thickness = 0.12\n const reach = TANK_SIDE / 2 + margin - 0.06\n const pillars = ([[-1, -1], [1, -1], [-1, 1], [1, 1]] as const).map(([a, b]) => ({ u: round2(u + a * reach), v: round2(v + b * reach), side: 0.12 }))\n const half = TANK_SIDE / 2 + margin\n return { aabb: [u - half, v - half, u + half, v + half].map(round2) as Rect, baseY, height: rise, thickness, topY: round2(baseY + rise + thickness), pillars, ladder: true }\n}\n\n/**\n * The water tank of a house: on the roof slab, in the attic, or on a platform that rises out of the roof, never in the yard. Null for a plan without\n * a lot (an apartment) or a commercial building, and when no room has space.\n */\nexport function planWaterTank(source: StructureSource, rng: Rng, options: TankPlanOptions = {}): WaterTank | null {\n if (!source.lot || source.style === 'commercial') return null\n if (options.custom) return options.custom(source, rng)\n const floor = source.floors.length - 1\n const level = source.floors[floor]!\n const capacity = capacityOf(source, { ...DEFAULT_CAPACITIES, ...options.capacities })\n const height = capacity >= 2000 ? 1.4 : capacity === 1000 ? 1.0 : 0.85\n const place = options.location ? options.location(source, rng) : source.facade.roof === 'slab' ? 'slab' : rng() < ATTIC_CHANCE ? 'attic' : 'raised_slab'\n const reference = (source.facade.slab as { waterTank?: { u: number; v: number } } | undefined)?.waterTank\n const spot = bestSpot(source, floor, reference)\n if (!spot) return null\n const target = reference ? [reference.u, reference.v] : [(spot.rect[0] + spot.rect[2]) / 2, (spot.rect[1] + spot.rect[3]) / 2]\n const u = clamp(target[0]!, spot.rect[0] + TANK_SIDE / 2, spot.rect[2] - TANK_SIDE / 2)\n const v = clamp(target[1]!, spot.rect[1] + TANK_SIDE / 2, spot.rect[3] - TANK_SIDE / 2)\n const where = spot.roomType === 'terrace' ? 'slab' : place\n const slabY = round2(spot.roomType === 'terrace' ? level.y0 : level.y0 + level.ceiling)\n const tank: WaterTank = {\n id: 'water_tank', kind: 'water_tank', itemType: 'water_tank', place: where, floor, room: spot.roomId, u: round2(u), v: round2(v), y: slabY, w: TANK_SIDE, d: TANK_SIDE, h: height,\n capacity, aabb: [u - TANK_SIDE / 2, v - TANK_SIDE / 2, u + TANK_SIDE / 2, v + TANK_SIDE / 2].map(round2) as Rect,\n }\n if (where === 'raised_slab') {\n tank.platform = raisedPlatform(source, u, v, slabY)\n tank.y = tank.platform.topY\n }\n return tank\n}\n","import type { ViewerLayer, ViewerLayerContext, ViewerLayerLegendEntry } from '@adatechnology/game-floorplan'\n\nimport type { StructurePart } from './types'\n\ntype MaterialGroup = 'concrete' | 'steel' | 'masonry' | 'wood'\n\nconst COLORS: Record<MaterialGroup, string> = { concrete: '#7d8590', steel: '#3d6fb0', masonry: '#b5654b', wood: '#a0693a' }\nconst BEAM_IDS = ['plate_', 'porch_beam', 'base_beam', 'trestle_beam']\n\nexport const LAYER_ID = 'structure'\n\nexport function groupOf(material: string): MaterialGroup {\n if (material === 'concrete') return 'concrete'\n if (material === 'steel' || material === 'aluminium' || material === 'cast_iron') return 'steel'\n if (material === 'brick' || material === 'stone' || material === 'ceramic') return 'masonry'\n return 'wood'\n}\n\nconst isRoofFrame = (part: StructurePart): boolean => ['truss', 'rafter', 'ridge'].some((prefix) => part.id.startsWith(prefix))\nconst isDrawnBeam = (part: StructurePart): boolean => part.role === 'beam' && BEAM_IDS.some((prefix) => part.id.startsWith(prefix))\n\nfunction drawColumns(context: ViewerLayerContext, parts: readonly StructurePart[]): void {\n for (const part of parts.filter((p) => p.role === 'column')) {\n const color = COLORS[groupOf(part.material)]\n if (groupOf(part.material) === 'wood') context.rect(part.aabb, null, color, 2)\n else context.rect(part.aabb, color, null)\n context.hit(part.aabb, `${part.id} · column · ${part.material} · ${part.mass} kg`)\n }\n}\n\nfunction drawBeams(context: ViewerLayerContext, parts: readonly StructurePart[]): void {\n context.g.save()\n context.g.setLineDash([6, 4])\n for (const part of parts.filter(isDrawnBeam)) {\n context.rect(part.aabb, null, COLORS[groupOf(part.material)], 1.5)\n context.hit(part.aabb, `${part.id} · beam · ${part.material} · ${part.mass} kg`)\n }\n context.g.restore()\n}\n\nfunction drawRoofFrames(context: ViewerLayerContext, parts: readonly StructurePart[]): void {\n context.g.save()\n context.g.strokeStyle = COLORS.wood\n context.g.lineWidth = 1\n for (const part of parts.filter(isRoofFrame)) {\n const [u0, v0, u1, v1] = part.aabb\n const alongV = v1 - v0 > u1 - u0\n context.g.beginPath()\n if (alongV) { context.g.moveTo(context.X((u0 + u1) / 2), context.Z(v0)); context.g.lineTo(context.X((u0 + u1) / 2), context.Z(v1)) }\n else { context.g.moveTo(context.X(u0), context.Z((v0 + v1) / 2)); context.g.lineTo(context.X(u1), context.Z((v0 + v1) / 2)) }\n context.g.stroke()\n }\n context.g.restore()\n}\n\nfunction drawPorchRoofs(context: ViewerLayerContext, parts: readonly StructurePart[]): void {\n context.g.save()\n context.g.setLineDash([2, 4])\n for (const part of parts.filter((p) => p.id.startsWith('porch_roof'))) context.rect(part.aabb, null, COLORS.wood, 1)\n context.g.restore()\n}\n\n/** What the viewer draws at one storey: pillars (filled for concrete, steel and masonry, hollow for wood), dashed beams, trusses on the top storey, the porch roof outline. */\nexport function drawStructure(context: ViewerLayerContext): void {\n const structure = context.plan.structure\n if (!structure) return\n const floor = context.all ? 0 : context.floor\n const here = (structure.parts as StructurePart[]).filter((part) => part.floor === floor)\n drawPorchRoofs(context, here)\n if (floor === (context.plan.roof?.bearingFloor ?? 0)) drawRoofFrames(context, structure.parts)\n drawBeams(context, here)\n drawColumns(context, here)\n}\n\nexport function structureLegend(plan: { structure?: { parts: StructurePart[] } }): ViewerLayerLegendEntry[] {\n const parts = plan.structure?.parts ?? []\n const entries: ViewerLayerLegendEntry[] = []\n for (const group of ['concrete', 'steel', 'masonry', 'wood'] as const) {\n const columns = parts.some((p) => p.role === 'column' && groupOf(p.material) === group)\n if (columns) entries.push({ label: `structure_column_${group}`, color: COLORS[group], shape: group === 'wood' ? 'hollow' : 'filled' })\n }\n for (const group of ['concrete', 'wood'] as const) {\n if (parts.some((p) => isDrawnBeam(p) && groupOf(p.material) === group)) entries.push({ label: `structure_beam_${group}`, color: COLORS[group], shape: 'dashed' })\n }\n if (parts.some(isRoofFrame)) entries.push({ label: 'structure_roof_frame', color: COLORS.wood, shape: 'line' })\n return entries\n}\n\nexport const structureLayer: ViewerLayer = {\n id: LAYER_ID,\n label: 'structure_layer',\n defaultOn: false,\n draw: drawStructure,\n legend: structureLegend,\n}\n","import type { FloorplanEngine, ResultExtensionContext } from '@adatechnology/game-floorplan'\n\nimport { constructionFor } from './construction'\nimport enLocale from './locales/en.json'\nimport ptBrLocale from './locales/pt-BR.json'\nimport type { ConstructionBuild } from './registry'\nimport { buildStructure } from './structure'\nimport { contentOf } from './utilities/content'\nimport { planContents, planUtilities } from './utilities'\nimport { addOutbuildingPaths, planOutbuildings } from './utilities/outbuildings'\nimport type { EnergyConfig } from './utilities/electrical'\nimport type { TankPlanOptions } from './water-tank'\nimport { planWaterTank } from './water-tank'\nimport { structureLayer } from './viewer-layer'\nimport type { Roof, StructureOptions, WallDetail } from './types'\n\nexport interface StructurePackOptions {\n /** Litres of the tank by template id or style id. */\n tankCapacities?: Record<string, number>\n}\n\ntype Cache = { build: ConstructionBuild; roof?: Roof }\nconst CACHE = new WeakMap<object, Cache>()\n\nconst cacheOf = (result: object): Cache => {\n const cache = CACHE.get(result)\n if (!cache) throw new Error('The construction extension did not run for this plan')\n return cache\n}\n\nfunction constructionExtension(context: ResultExtensionContext): unknown {\n const build = constructionFor({ result: context.result as never, seed: context.seed, template: context.plan.tpl as never, options: context.options })\n CACHE.set(context.result, { build })\n return build.construction\n}\n\nfunction structureExtension(context: ResultExtensionContext): unknown {\n const cache = cacheOf(context.result)\n const options: StructureOptions = { construction: cache.build.construction, extras: cache.build.extras ?? {}, tank: context.result.waterTank ?? null, wallDetail: (context.options.wallDetail ?? 'panels') as WallDetail }\n const { roof, ...structure } = buildStructure(context.result, options)\n cache.roof = roof\n for (const part of structure.parts) {\n if (part.door === undefined || part.steps === undefined) continue\n const door = context.result.doors.find((d: { id: string }) => d.id === part.door)\n if (door) door.steps = part.steps\n }\n return structure\n}\n\nconst COOKING_CYLINDER = { type: 'cooking_gas_cylinder', category: 'cooking_gas_cylinder', w: 0.36, d: 0.36, h: 0.48 }\n\nfunction energyOf(context: ResultExtensionContext): EnergyConfig | undefined {\n const energy = context.plan.tpl.energy\n return typeof energy === 'function' ? energy(context.options, context.plan.w, context.plan.d) : undefined\n}\n\n/**\n * Registers the structure into the engine: `result.construction`, `result.structureExtras`, `result.waterTank`, `result.structure` and `result.roof` of every plan,\n * and the structure layer of the 2D viewer. Register the content packs first.\n */\nexport function register(engine: FloorplanEngine, options: StructurePackOptions = {}): void {\n engine.registerLocale('en', enLocale)\n engine.registerLocale('pt-BR', ptBrLocale)\n engine.registerResultExtension('construction', constructionExtension)\n engine.registerResultExtension('structureExtras', (context) => cacheOf(context.result).build.extras ?? {}, { after: ['construction'] })\n engine.registerResultExtension(\n 'waterTank',\n (context) => {\n const tank: TankPlanOptions = { capacities: options.tankCapacities, custom: context.plan.tpl.tank, location: context.plan.tpl.tankLocation }\n return planWaterTank(context.result as never, context.rng, tank)\n },\n { after: ['construction'], seedKey: 'caixa' },\n )\n engine.registerResultExtension('structure', structureExtension, { after: ['construction', 'structureExtras', 'waterTank'] })\n engine.registerResultExtension('roof', (context) => cacheOf(context.result).roof ?? null, { after: ['structure'] })\n engine.registerViewerLayer(structureLayer)\n engine.registerItem(COOKING_CYLINDER)\n engine.registerResultExtension('contents', (context) => planContents({ items: context.result.items, state: context.result.state, place: context.plan.tpl.place ?? 'house', ...(typeof context.options.day === 'number' ? { day: context.options.day } : {}), ...(typeof context.options.region === 'string' ? { region: context.options.region } : {}), rngFor: (key) => engine.createRng(context.seed, key), findsFor: (query) => { const answered = engine.findsAnswer(query); return answered ?? contentOf({ container: query.container, state: query.state, rng: query.rng, footprint: query.footprint ?? 0.5 }) } }))\n engine.registerResultExtension('outbuildings', (context) => {\n const outbuildings = planOutbuildings({ plan: context.plan, items: context.result.items, catalog: engine.catalog, rngFor: (key) => engine.createRng(context.seed, key) })\n if (context.result.lot) addOutbuildingPaths(context.result.lot, outbuildings, context.result.items)\n return outbuildings\n }, { after: ['contents'] })\n engine.registerResultExtension('utilities', (context) => planUtilities({ plan: context.plan, items: context.result.items, stateItems: context.result.stateItems, tank: context.result.waterTank ?? null, ...(energyOf(context) ? { energy: energyOf(context) } : {}), rngFor: (key) => engine.createRng(context.seed, key) }), { after: ['outbuildings', 'waterTank'] })\n}\n","import type { DestructibleSpec, JointSpec, PartSpec, StructureRole } from '@adatechnology/game-contracts'\nimport { assemblyPart } from '@adatechnology/game-destruction'\nimport { sizeCapacities } from './loads'\nimport { GROUND } from './types'\nimport { applyPanels, applyUnits } from './wall-detail'\nimport type { PartRole, Structure, StructurePart, WallDetail } from './types'\n\nexport interface DestructibleSpecOptions {\n /** Fraction of its capacity a pillar or bearing wall uses at rest (default 0.65). */\n safety?: number\n /** After losing any other pillar or bearing wall, the most of its capacity one of them uses (default 0.97: the house holds one loss and falls with two). */\n redundancy?: number\n /** Fraction of capacity beams, slabs, roofs, stairs and partitions use at rest (default 0.45). */\n safetyOthers?: number\n /** Bearing walls close but do not carry: a frame of pillars and beams carries the building. Default: for a framed building unless the detail is `coarse`. */\n portico?: boolean\n /** How finely the walls are split (default `panels`; `coarse` is one part per wall as the Visor de casas 3D builds it). */\n wallDetail?: WallDetail\n /** Name of the spec (default `house`). */\n name?: string\n /** Leaves parts out (and what rests on them is dropped from the joints). */\n filter?: (part: StructurePart) => boolean\n /** `false` keeps the capacity of the material instead of sizing it from the load. */\n sized?: boolean\n /** Metres the anchored terrain slab reaches beyond the parts (default 6). */\n terrainMargin?: number\n}\n\nconst CONTRACT_ROLE: Record<PartRole, StructureRole> = { column: 'column', beam: 'beam', slab: 'slab', wall: 'wall', partition: 'partition', roof: 'roof', stair: 'stair', none: 'none' }\n\nconst TERRAIN_MARGIN = 6\nconst TERRAIN_THICKNESS = 0.5\n\nconst boxSpec = (part: StructurePart, capacity: number | undefined): PartSpec => {\n const [u0, v0, u1, v1] = part.aabb\n return {\n id: part.id, material: part.material, shape: { kind: 'box', size: [Math.max(0.01, u1 - u0), Math.max(0.01, part.y1 - part.y0), Math.max(0.01, v1 - v0)] },\n position: [(u0 + u1) / 2, (part.y0 + part.y1) / 2, (v0 + v1) / 2], mass: Math.max(0.1, part.mass || 1),\n structure: capacity === undefined ? { role: CONTRACT_ROLE[part.role] } : { role: CONTRACT_ROLE[part.role], capacity },\n }\n}\n\n/** A wall piece as its assembly builds it (layers, rebar, units, breach), with the mass the structure gave it. A brick or log is the unit itself, so it keeps no units or breach. */\nconst assemblySpec = (part: StructurePart, capacity: number | undefined): PartSpec => {\n const [u0, v0, u1, v1] = part.aabb\n const alongU = u1 - u0 >= v1 - v0\n const spec = assemblyPart(part.assembly!, {\n id: part.id, width: alongU ? u1 - u0 : v1 - v0, height: part.y1 - part.y0, position: [(u0 + u1) / 2, (part.y0 + part.y1) / 2, (v0 + v1) / 2], ...(alongU ? {} : { rotation: [0, Math.PI / 2, 0] }),\n structure: capacity === undefined ? { role: CONTRACT_ROLE[part.role] } : { role: CONTRACT_ROLE[part.role], capacity }, extra: { mass: Math.max(0.1, part.mass || 1) },\n })\n if (part.unit) {\n delete spec.units\n delete spec.breach\n }\n return spec\n}\n\nconst partSpecOf = (part: StructurePart, capacity: number | undefined, detailed: boolean): PartSpec => (detailed && part.assembly ? assemblySpec(part, capacity) : boxSpec(part, capacity))\n\n/**\n * The structure as a `DestructibleSpec` in the space of the house (x = u, y = height, z = v; the ground is y = 0), one box per part and a terrain slab\n * that anchors it. Capacities are sized from the loads at rest, as a designer would: a house stands whole, holds the loss of one pillar or bearing wall\n * and falls with two.\n */\nexport function toDestructibleSpec(structure: Structure, options: DestructibleSpecOptions = {}): DestructibleSpec {\n const { safety = 0.65, redundancy = 0.97, safetyOthers = 0.45 } = options\n const kept = structure.parts.filter((part) => !options.filter || options.filter(part))\n const portico = options.portico ?? (options.wallDetail !== 'coarse' && structure.framed)\n const roled = portico ? kept.map((part): StructurePart => (part.role === 'wall' ? { ...part, role: 'partition' } : part)) : kept\n const ids = new Set(roled.map((part) => part.id))\n const filtered = structure.supports.filter((support) => !options.filter || (ids.has(support.part) && (support.on === GROUND || ids.has(support.on))))\n const detail = options.wallDetail ?? 'panels'\n const panels = applyPanels({ parts: roled, supports: filtered }, structure, detail)\n const sizing = { safety, redundancy, safetyOthers }\n const sized = { ...panels, capacities: options.sized === false ? new Map<string, number>() : sizeCapacities(panels.parts, panels.supports, sizing) }\n const { parts, supports, capacities } = detail === 'units' ? applyUnits(sized, structure) : sized\n const specs = parts.map((part) => partSpecOf(part, capacities.get(part.id), detail !== 'coarse'))\n const margin = options.terrainMargin ?? TERRAIN_MARGIN\n const x0 = Math.min(...parts.map((part) => part.aabb[0]))\n const z0 = Math.min(...parts.map((part) => part.aabb[1]))\n const x1 = Math.max(...parts.map((part) => part.aabb[2]))\n const z1 = Math.max(...parts.map((part) => part.aabb[3]))\n if (parts.length) specs.push({ id: GROUND, material: 'concrete', shape: { kind: 'box', size: [x1 - x0 + margin, TERRAIN_THICKNESS, z1 - z0 + margin] }, position: [(x0 + x1) / 2, -TERRAIN_THICKNESS / 2, (z0 + z1) / 2], hp: 1e12, structure: { role: 'foundation' }, anchored: true, tags: ['terrain'] })\n const present = new Set([...parts.map((part) => part.id), GROUND])\n const joints: JointSpec[] = supports.filter((s) => present.has(s.part) && present.has(s.on)).map((s) => ({ id: `${s.part}~${s.on}`, a: s.part, b: s.on, kind: s.joint, bears: s.bears === false ? false : 'a_on_b' }))\n return { name: options.name ?? 'house', parts: specs, joints, tags: ['structure', 'house'] }\n}\n","import { GROUND } from './types'\nimport type { StructurePart, Support } from './types'\n\n/**\n * Load each part carries at rest, by the rules of the Visor de casas 3D (which the destruction world shares): load only goes down to supports closer to\n * the ground, shared equally, and a partition wall carries nothing, so what rests only on partitions has no load. `without` leaves one part out (as if it\n * had failed). Parts that are not structural (the tank) are not loaded.\n */\nexport function loadsAtRest(parts: readonly StructurePart[], supports: readonly Support[], without?: string): Map<string, number> {\n const byId = new Map(parts.filter((part) => part.id !== without).map((part) => [part.id, part]))\n const resting = new Map<string, string[]>()\n const carrying = new Map<string, string[]>()\n const push = (map: Map<string, string[]>, key: string, value: string): void => {\n const list = map.get(key)\n if (list) list.push(value)\n else map.set(key, [value])\n }\n for (const support of supports) {\n if (support.bears === false) continue\n if (!byId.has(support.part) || (support.on !== GROUND && !byId.has(support.on))) continue\n push(resting, support.part, support.on)\n push(carrying, support.on, support.part)\n }\n const partition = (id: string): boolean => byId.get(id)?.role === 'partition'\n const structural = (id: string): boolean => byId.has(id) && byId.get(id)!.role !== 'none'\n const distance = new Map<string, number>([[GROUND, 0]])\n const queue = [GROUND]\n for (let head = 0; head < queue.length; head++) {\n const current = queue[head]!\n if (current !== GROUND && partition(current)) continue\n for (const above of carrying.get(current) ?? []) {\n if (distance.has(above) || !structural(above)) continue\n distance.set(above, distance.get(current)! + 1)\n queue.push(above)\n }\n }\n const incoming = new Map<string, number>()\n const loads = new Map<string, number>()\n for (let head = queue.length - 1; head >= 1; head--) {\n const id = queue[head]!\n const total = (byId.get(id)!.mass || 1) + (incoming.get(id) ?? 0)\n loads.set(id, total)\n const below = (resting.get(id) ?? []).filter((other) => distance.has(other) && distance.get(other)! < distance.get(id)! && !(other !== GROUND && partition(other)))\n for (const other of below) incoming.set(other, (incoming.get(other) ?? 0) + total / below.length)\n }\n return loads\n}\n\nexport interface SizingOptions {\n /** Fraction of its capacity a pillar or bearing wall uses at rest. */\n safety: number\n /** The most of its capacity a pillar or bearing wall uses after any other pillar or bearing wall is lost. */\n redundancy: number\n /** Fraction of capacity every other structural part uses at rest. */\n safetyOthers: number\n}\n\nconst isBearing = (part: StructurePart): boolean => part.role === 'column' || part.role === 'wall'\n\n/**\n * Capacity of each loaded part, as a designer would size it: a pillar or bearing wall uses `safety` of it at rest and stays under `redundancy` when\n * any other pillar or bearing wall is lost (the house holds one loss and falls with two); every other part uses `safetyOthers`.\n * `sizeStructure` of game-destruction gives the same numbers except for beams of a framed building (it holds them under `redundancy` too).\n */\nexport function sizeCapacities(parts: readonly StructurePart[], supports: readonly Support[], options: SizingOptions): Map<string, number> {\n const loads = loadsAtRest(parts, supports)\n const worst = new Map<string, number>()\n for (const part of parts.filter(isBearing)) {\n for (const [id, load] of loadsAtRest(parts, supports, part.id)) {\n const before = loads.get(id)\n if (before && load / before > (worst.get(id) ?? 1)) worst.set(id, load / before)\n }\n }\n const capacities = new Map<string, number>()\n for (const part of parts) {\n const load = loads.get(part.id)\n if (load === undefined || part.role === 'none') continue\n const factor = isBearing(part) ? Math.max(1 / options.safety, (worst.get(part.id) ?? 1) / options.redundancy) : 1 / options.safetyOthers\n capacities.set(part.id, Math.max(1, load * factor))\n }\n return capacities\n}\n","import { getAssembly } from '@adatechnology/game-destruction'\n\nimport type { Construction, Rect, Structure, StructurePart, WallDetail } from '../types'\nimport { applySplits } from './apply'\nimport type { PartsAndSupports } from './apply'\nimport { splitIntoCourses } from './courses'\nimport type { CourseSpec } from './courses'\nimport { splitIntoPanels } from './panels'\nimport type { WallSplit } from './panels'\nimport { CONSTRUCTION_SYSTEMS } from '../registry'\n\nconst LOG_DIAMETER = 0.26\nconst isWall = (part: StructurePart): boolean => part.id.startsWith('wall_') && part.assembly !== undefined && (part.role === 'wall' || part.role === 'partition')\n\nfunction logSpec(construction: Construction, part: StructurePart): CourseSpec {\n const diameter = (construction.walls.logDiameter as number | undefined) ?? LOG_DIAMETER\n return { rowHeight: diameter, bond: 'stack', joint: CONSTRUCTION_SYSTEMS.get(construction.system)!.joints.wall, assembly: part.assembly! }\n}\n\n/** Walls cut at their windows (piers, sills, lintels, spandrels); the walls of logs as courses of logs. */\nfunction panelSplits(input: PartsAndSupports, structure: Structure): Map<string, WallSplit> {\n const { construction } = structure\n const system = CONSTRUCTION_SYSTEMS.get(construction.system)!\n const splits = new Map<string, WallSplit>()\n for (const part of input.parts.filter(isWall)) {\n if (construction.system === 'log') {\n splits.set(part.id, splitIntoCourses(part, structure.openings, logSpec(construction, part)))\n continue\n }\n const split = splitIntoPanels(part, structure.openings, {\n lintelMaterial: system.timber ? construction.frame.timber : 'concrete', ...(system.timber ? {} : { lintelAssembly: 'reinforced_concrete' }), lintelJoint: system.joints.beam, wallJoint: system.joints.wall,\n })\n if (split.pieces.length > 1) splits.set(part.id, split)\n }\n return splits\n}\n\n/** Splits the walls the way `detail` says: `coarse` keeps one part per wall, `panels` cuts them at the windows, `units` goes on to bricks and blocks. */\nexport function applyPanels(input: PartsAndSupports, structure: Structure, detail: WallDetail): PartsAndSupports {\n if (detail === 'coarse') return input\n return applySplits(input, panelSplits(input, structure))\n}\n\nexport interface Sized extends PartsAndSupports {\n capacities: Map<string, number>\n}\n\n/** Cuts each wall piece that its assembly lays in units (bricks, blocks, concrete panels) into those units; a unit takes the share of the piece's capacity its width has (it carries its column of the wall). */\nexport function applyUnits(input: Sized, structure: Structure): Sized {\n const splits = new Map<string, WallSplit>()\n for (const part of input.parts) {\n if (part.unit || !part.assembly || part.role === 'beam' || part.role === 'none') continue\n const units = getAssembly(part.assembly)?.units\n if (!units) continue\n const joint = CONSTRUCTION_SYSTEMS.get(structure.construction.system)!.joints.wall\n splits.set(part.id, splitIntoCourses(part, [], { rowHeight: units.size[1], unitLength: units.size[0], bond: units.bond, joint: units.mortar === 'concrete' ? 'mortar' : joint, assembly: part.assembly }))\n }\n const next = applySplits(input, splits)\n const capacities = new Map(input.capacities)\n for (const [id, split] of splits) {\n const capacity = input.capacities.get(id)\n capacities.delete(id)\n if (capacity === undefined) continue\n const along = (box: Rect): number => Math.max(box[2] - box[0], box[3] - box[1])\n const length = along(input.parts.find((part) => part.id === id)!.aabb)\n for (const piece of split.pieces) capacities.set(piece.id, Math.max(1, (capacity * along(piece.aabb)) / length))\n }\n return { ...next, capacities }\n}\n","import { touches } from '../geometry'\nimport type { Rect, StructurePart, Support } from '../types'\nimport type { WallSplit } from './panels'\n\nexport interface PartsAndSupports {\n parts: StructurePart[]\n supports: Support[]\n}\n\n/** Replaces each part that has a split by its pieces, and re-points what rested on it or what it rested on (the pieces touching the part resting on it get the load). */\nexport function applySplits(input: PartsAndSupports, splits: ReadonlyMap<string, WallSplit>): PartsAndSupports {\n if (!splits.size) return input\n const boxes = new Map<string, Rect>(input.parts.map((part) => [part.id, part.aabb]))\n const pieceBox = new Map<string, Rect>()\n for (const split of splits.values()) for (const piece of split.pieces) pieceBox.set(piece.id, piece.aabb)\n const parts = input.parts.flatMap((part) => splits.get(part.id)?.pieces ?? [part])\n const supports: Support[] = []\n for (const support of input.supports) {\n const own = splits.get(support.part)\n const host = splits.get(support.on)\n const resting = boxes.get(support.part)\n const targets = host ? host.top.filter((id) => resting && touches(pieceBox.get(id)!, resting, 0.05)) : [support.on]\n const carriers = host ? (targets.length ? targets : host.top) : targets\n for (const part of own ? own.base : [support.part]) for (const on of carriers) supports.push({ ...support, part, on })\n }\n for (const split of splits.values()) supports.push(...split.internal)\n return { parts, supports }\n}\n","import type { JointKind } from '@adatechnology/game-contracts'\n\nimport { round2 } from '../geometry'\nimport type { Opening, Rect, StructurePart, Support } from '../types'\nimport type { WallSplit } from './panels'\n\nexport interface CourseSpec {\n rowHeight: number\n /** Length of a unit along the wall; without it a course is one piece per stretch (a log). */\n unitLength?: number\n bond: 'running' | 'stack'\n /** Joint of a unit on the units under it. */\n joint: JointKind\n assembly: string\n}\n\nconst MIN_UNIT = 0.02\n\ninterface Cell {\n from: number\n to: number\n row: number\n y0: number\n y1: number\n}\n\nfunction cutAt(from: number, to: number, openings: readonly Opening[], y0: number, y1: number): [number, number][] {\n let stretches: [number, number][] = [[from, to]]\n for (const opening of openings.filter((o) => o.y0 < y1 - MIN_UNIT && o.y1 > y0 + MIN_UNIT)) {\n stretches = stretches.flatMap(([a, b]): [number, number][] => {\n if (opening.to <= a || opening.from >= b) return [[a, b]]\n return [[a, Math.min(b, opening.from)], [Math.max(a, opening.to), b]].filter(([x, y]) => (y as number) - (x as number) > MIN_UNIT) as [number, number][]\n })\n }\n return stretches\n}\n\nfunction unitsOf(from: number, to: number, row: number, spec: CourseSpec): [number, number][] {\n const length = spec.unitLength\n if (!length) return [[from, to]]\n const offset = spec.bond === 'running' && row % 2 === 1 ? length / 2 : 0\n const cuts: number[] = [from]\n for (let at = from + (offset || length); at < to - MIN_UNIT; at += length) cuts.push(at)\n cuts.push(to)\n return cuts.slice(0, -1).map((start, k): [number, number] => [start, cuts[k + 1]!]).filter(([a, b]) => b - a > MIN_UNIT)\n}\n\n/**\n * Cuts a wall into courses of units (bricks laid in bond, or logs): each course is cut at the openings it meets, and each unit rests on the units of the course\n * below that it overlaps. A wall whose lowest course goes loses every course above it. The mass of the wall is shared among the units by volume.\n */\nexport function splitIntoCourses(wall: StructurePart, openings: readonly Opening[], spec: CourseSpec): WallSplit {\n const alongU = wall.aabb[2] - wall.aabb[0] >= wall.aabb[3] - wall.aabb[1]\n const from = alongU ? wall.aabb[0] : wall.aabb[1]\n const to = alongU ? wall.aabb[2] : wall.aabb[3]\n const cross: [number, number] = alongU ? [wall.aabb[1], wall.aabb[3]] : [wall.aabb[0], wall.aabb[2]]\n const rows = Math.max(1, Math.round((wall.y1 - wall.y0) / spec.rowHeight))\n const rowHeight = (wall.y1 - wall.y0) / rows\n const cells: Cell[] = []\n for (let row = 0; row < rows; row++) {\n const y0 = wall.y0 + row * rowHeight\n const y1 = wall.y0 + (row + 1) * rowHeight\n for (const [a, b] of cutAt(from, to, openings.filter((o) => o.wall === wall.id), y0, y1)) for (const [x0, x1] of unitsOf(a, b, row, spec)) cells.push({ from: x0, to: x1, row, y0, y1 })\n }\n const total = cells.reduce((sum, cell) => sum + (cell.to - cell.from) * (cell.y1 - cell.y0), 0)\n const box = (cell: Cell): Rect => (alongU ? [cell.from, cross[0], cell.to, cross[1]] : [cross[0], cell.from, cross[1], cell.to])\n const pieces = cells.map((cell, index): StructurePart => ({\n id: `${wall.id}_${spec.unitLength ? 'u' : 'log'}${cell.row}_${index}`, role: wall.role, material: wall.material, aabb: box(cell), y0: cell.y0, y1: cell.y1, floor: wall.floor,\n mass: round2(Math.max(0.1, (wall.mass * (cell.to - cell.from) * (cell.y1 - cell.y0)) / total)), host: wall.id, assembly: spec.assembly, unit: true,\n }))\n const internal: Support[] = []\n cells.forEach((cell, index) => {\n if (cell.row === 0) return\n const below = cells.map((other, k) => ({ other, k })).filter(({ other }) => other.row === cell.row - 1 && Math.min(other.to, cell.to) - Math.max(other.from, cell.from) > MIN_UNIT)\n for (const { k } of below) internal.push({ part: pieces[index]!.id, on: pieces[k]!.id, joint: spec.joint })\n })\n return { pieces, internal, base: pieces.filter((_, i) => cells[i]!.row === 0).map((p) => p.id), top: pieces.filter((_, i) => cells[i]!.row === rows - 1).map((p) => p.id) }\n}\n","import type { JointKind } from '@adatechnology/game-contracts'\n\nimport { round2 } from '../geometry'\nimport type { Opening, Rect, StructurePart, Support } from '../types'\n\nexport interface PanelStyle {\n lintelMaterial: string\n lintelAssembly?: string\n /** Joint of a lintel on its piers and of the wall above it on the lintel. */\n lintelJoint: JointKind\n wallJoint: JointKind\n}\n\nexport interface WallSplit {\n pieces: StructurePart[]\n /** What the pieces rest on among themselves (lintel on piers, spandrel on lintel). */\n internal: Support[]\n /** Pieces that rest on what the wall rests on. */\n base: string[]\n /** Pieces that carry what rests on the wall. */\n top: string[]\n}\n\nexport const LINTEL_DEPTH = 0.2\nexport const LINTEL_BEARING = 0.2\nconst MIN_PIECE = 0.05\n\ninterface Frame {\n alongU: boolean\n from: number\n to: number\n cross: [number, number]\n}\n\nconst frameOf = (wall: StructurePart): Frame => {\n const alongU = wall.aabb[2] - wall.aabb[0] >= wall.aabb[3] - wall.aabb[1]\n return alongU ? { alongU, from: wall.aabb[0], to: wall.aabb[2], cross: [wall.aabb[1], wall.aabb[3]] } : { alongU, from: wall.aabb[1], to: wall.aabb[3], cross: [wall.aabb[0], wall.aabb[2]] }\n}\n\nconst boxOf = (frame: Frame, from: number, to: number): Rect => (frame.alongU ? [from, frame.cross[0], to, frame.cross[1]] : [frame.cross[0], from, frame.cross[1], to])\n\ninterface Draft {\n id: string\n role: StructurePart['role']\n material: string\n assembly?: string\n from: number\n to: number\n y0: number\n y1: number\n /** Volume that counts for the mass share (pieces tile the wall: a lintel keeps the bearing it shares with the piers). */\n volume: number\n}\n\n/**\n * Cuts a wall at its windows: piers between them at full height, a sill wall under each window, a lintel over it that bears 0.2 m on the piers and the wall\n * above the lintel up to the top. The mass of the wall is shared among the pieces by volume, so the total is the wall's.\n */\nexport function splitIntoPanels(wall: StructurePart, openings: readonly Opening[], style: PanelStyle): WallSplit {\n const frame = frameOf(wall)\n const own = openings.filter((o) => o.wall === wall.id && o.to > frame.from + MIN_PIECE && o.from < frame.to - MIN_PIECE).sort((a, b) => a.from - b.from)\n if (!own.length) return { pieces: [wall], internal: [], base: [wall.id], top: [wall.id] }\n const drafts: Draft[] = []\n const piers: Draft[] = []\n const lintels: Draft[] = []\n const spandrels: (Draft | undefined)[] = []\n const height = wall.y1 - wall.y0\n let cursor = frame.from\n const roleOf = wall.role\n const addPier = (to: number): void => {\n if (to - cursor < MIN_PIECE) return\n piers.push({ id: `${wall.id}_pier_${piers.length}`, role: roleOf, material: wall.material, from: cursor, to, y0: wall.y0, y1: wall.y1, volume: (to - cursor) * height })\n }\n own.forEach((opening, k) => {\n addPier(Math.max(cursor, opening.from))\n const lintelTop = Math.min(wall.y1, opening.y1 + LINTEL_DEPTH)\n const lintelFrom = Math.max(frame.from, opening.from - LINTEL_BEARING)\n const lintelTo = Math.min(frame.to, opening.to + LINTEL_BEARING)\n const lintelHeight = lintelTop - opening.y1\n if (opening.y0 - wall.y0 > MIN_PIECE) drafts.push({ id: `${wall.id}_sill_${k}`, role: 'partition', material: wall.material, from: opening.from, to: opening.to, y0: wall.y0, y1: opening.y0, volume: (opening.to - opening.from) * (opening.y0 - wall.y0) })\n lintels.push({ id: `${wall.id}_lintel_${k}`, role: 'beam', material: style.lintelMaterial, from: lintelFrom, to: lintelTo, y0: opening.y1, y1: lintelTop, volume: (lintelTo - lintelFrom) * lintelHeight })\n spandrels.push(wall.y1 - lintelTop > MIN_PIECE ? { id: `${wall.id}_spandrel_${k}`, role: roleOf, material: wall.material, from: opening.from, to: opening.to, y0: lintelTop, y1: wall.y1, volume: (opening.to - opening.from) * (wall.y1 - lintelTop) } : undefined)\n cursor = opening.to\n })\n addPier(frame.to)\n // the piers give the bearing zone of each lintel to it\n for (const pier of piers) {\n for (const lintel of lintels) {\n const overlap = Math.max(0, Math.min(pier.to, lintel.to) - Math.max(pier.from, lintel.from))\n pier.volume -= overlap * (lintel.y1 - lintel.y0)\n }\n }\n const all = [...piers, ...drafts, ...lintels, ...spandrels.filter((d): d is Draft => d !== undefined)]\n const total = all.reduce((sum, d) => sum + d.volume, 0)\n const pieces = all.map((d): StructurePart => ({\n id: d.id, role: d.role, material: d.material, aabb: boxOf(frame, d.from, d.to), y0: d.y0, y1: d.y1, floor: wall.floor, mass: round2(Math.max(0.1, (wall.mass * d.volume) / total)), host: wall.id,\n ...(d.role === 'beam' ? (style.lintelAssembly ? { assembly: style.lintelAssembly } : {}) : wall.assembly ? { assembly: wall.assembly } : {}),\n }))\n const internal: Support[] = []\n lintels.forEach((lintel, k) => {\n for (const pier of piers) if (Math.min(pier.to, lintel.to) - Math.max(pier.from, lintel.from) > 0) internal.push({ part: lintel.id, on: pier.id, joint: style.lintelJoint })\n const spandrel = spandrels[k]\n if (spandrel) internal.push({ part: spandrel.id, on: lintel.id, joint: style.wallJoint })\n })\n const base = [...piers, ...drafts.filter((d) => d.id.includes('_sill_'))].map((d) => d.id)\n const top = [...piers.map((p) => p.id), ...lintels.map((l, k) => spandrels[k]?.id ?? l.id)]\n return { pieces, internal, base, top }\n}\n","import type { DestructibleSpec } from '@adatechnology/game-contracts'\nimport { assemblyDepth, assemblyPart, getAssembly } from '@adatechnology/game-destruction'\n\nimport { GROUND } from './types'\nimport { constructionOfSystem } from './presets'\nimport { CONSTRUCTION_SYSTEMS } from './registry'\nimport { toDestructibleSpec } from './to-destructible-spec'\nimport type { Opening, StructureSource, WallDetail } from './types'\n\nexport interface WallSpecimenOptions {\n /** Wall assembly of `game-destruction` (`brick_wall_plastered`, `concrete_block_wall`, `reinforced_concrete`, `drywall`, `wood_frame_wall`, `log_wall`, `sheet_metal_shack`...). */\n assembly: string\n /** Width and height in metres (the test area uses 2.4 x 2.1). */\n w: number\n h: number\n opening?: 'door' | 'window' | null\n /** Default `panels`: piers, lintel with its 0.2 m bearing, sill, plaster and rebar; `units` also lays the bricks, blocks or concrete panels one by one. */\n detail?: WallDetail\n}\n\nconst SYSTEM_OF_ASSEMBLY: Record<string, string> = { log_wall: 'log', wood_frame_wall: 'wood_frame', sheet_metal_shack: 'improvised' }\nconst DOOR_WIDTH = 0.9\nconst WINDOW_WIDTH = 1.0\n\nfunction openingOf(kind: 'door' | 'window', height: number): Opening {\n return kind === 'door'\n ? { id: 'door', kind, wall: 'wall_specimen', from: -DOOR_WIDTH / 2, to: DOOR_WIDTH / 2, y0: 0, y1: height * 0.8 }\n : { id: 'window', kind, wall: 'wall_specimen', from: -WINDOW_WIDTH / 2, to: WINDOW_WIDTH / 2, y0: height * 0.33, y1: height * 0.8 }\n}\n\n/**\n * A test wall as its assembly builds it, standing on a plinth: in `panels` the piers beside the opening, the lintel over it (reinforced concrete bearing 0.2 m on\n * the piers; a header in timber walls), the sill under a window and the wall above; with the plaster coat and the rebar of the assembly. The mass is the\n * assembly's for the whole w x h, whatever the detail.\n */\nexport function buildWallSpecimen(options: WallSpecimenOptions): DestructibleSpec {\n const { assembly, w, h, opening = null, detail = 'panels' } = options\n const def = getAssembly(assembly)\n if (!def) throw new Error(`unknown assembly \"${assembly}\"`)\n const system = SYSTEM_OF_ASSEMBLY[assembly] ?? 'masonry'\n const depth = assemblyDepth(def)\n const mass = assemblyPart(assembly, { id: 'wall_specimen', width: w, height: h, position: [0, h / 2, 0] }).mass ?? 1\n const construction = constructionOfSystem(system, { facade: {}, floors: [], rooms: [], walls: [], doors: [], items: [], w, d: depth } as StructureSource)!\n const joint = CONSTRUCTION_SYSTEMS.get(system)!.joints.wall\n const structure = {\n parts: [{ id: 'wall_specimen', role: 'wall' as const, material: def.core.material, aabb: [-w / 2, -depth / 2, w / 2, depth / 2] as [number, number, number, number], y0: 0, y1: h, floor: 0, mass, assembly }],\n supports: [{ part: 'wall_specimen', on: GROUND, joint }],\n openings: opening ? [openingOf(opening, h)] : [],\n levels: [0], elevation: 0, construction, framed: false,\n roof: { shape: 'slab' as const, covering: '', material: '', pitch: 0, bearingFloor: 0, panes: [], trusses: 0 },\n }\n return toDestructibleSpec(structure, { wallDetail: detail, sized: false, terrainMargin: 0.6, name: `wall_${assembly}` })\n}\n","export const version = '0.1.0'\n\nexport { register } from './register'\nexport type { StructurePackOptions } from './register'\nexport { buildStructure } from './structure'\nexport { toDestructibleSpec } from './to-destructible-spec'\nexport type { DestructibleSpecOptions } from './to-destructible-spec'\nexport { buildWallSpecimen } from './wall-specimen'\nexport type { WallSpecimenOptions } from './wall-specimen'\nexport { planWaterTank } from './water-tank'\nexport type { TankPlanOptions } from './water-tank'\nexport {\n CONSTRUCTION_SYSTEMS, CONSTRUCTIONS, ROOF_COVERINGS, registerConstruction, registerConstructionSystem, registerRoofCovering,\n} from './registry'\nexport type { ConstructionBuild, ConstructionBuilder, ConstructionSystemDef, RoofCoveringDef } from './registry'\nexport { campConstruction, chaletConstruction, constructionOfSystem, logCabinConstruction, masonryConstruction, shackConstruction, woodFrameConstruction } from './presets'\nexport type { ChaletOptions, ShackOptions, WoodFrameOptions } from './presets'\nexport { structureLayer } from './viewer-layer'\nexport { DENSITY } from './density'\nexport { GROUND } from './types'\nexport type * from './types'\n"],"mappings":"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","names":["at","at","item","flight","part","entry","entry","round2","round2","round2","round2","round2","absolute","round2","round2","DOOR_HEIGHT","round2","clamp","opening","at","LINTEL_DEPTH","LINTEL_BEARING","roleOf","opening","assemblyPart","getAssembly","DOOR_WIDTH","opening","getAssembly","assemblyPart"]}