import test from 'node:test';import assert from 'node:assert/strict'; import {portraitFrame,editorialFrame} from '../src/director.ts'; import type {Segment,Cue} from '../src/types.ts'; test('portrait evidence frames fit both complete holograms inside the ship',()=>{ for(const aspect of [320/540,390/569,430/657])for(const side of ['visual','explanation'] as const){ const c=portraitFrame('story',aspect,side);const d=c.position[2]-c.target[2];const height=2*d*Math.tan(c.fov*Math.PI/360);assert(height*aspect>=1.48);assert(height>=1.64);assert(Math.hypot(c.position[0],c.position[2])<4.5); } }); test('portrait gives explanations an insert after images while preserving locked cues',()=>{ const visual={id:'v',at:4,shot:'story',locked:false,visualIndex:0,facts:['First fact'],expression:'neutral'} as Cue; const close={...visual,id:'c',at:10,shot:'close'} as Cue; const s={storyId:'s',facts:['First fact'],cues:[visual,close]} as Segment; assert.deepEqual(editorialFrame(s,close,11,true),{shot:'story',side:'explanation'}); assert.equal(editorialFrame(s,{...close,locked:true},11,true).shot,'close'); assert.equal(editorialFrame(s,close,11,false).shot,'close'); assert.deepEqual(editorialFrame(s,visual,4,true),{shot:'story',side:'visual'}); });