1/*! © 2011â2026 Georg Luif · georgluif.at · All rights reserved. */ 2export const LORE={hero:{title:"The Meadow",lines:[`The makerâs things lie scattered across the warm fields. 3Some are broken. Some are locked. 4All of them are waiting for a bird.`,`The warm fields again. 5The grass leans toward you, as if it had been waiting.`,`Home, or the nearest thing to it. 6The windmill counts the wind while nobody is looking.`,`The meadow keeps its own hours. 7What broke today will stand again by midnight.`,`Somewhere in the north wall a door was sealed on purpose. 8The stone remembers who did it.`,`Feathers drift where birds have been. 9Some of them were yours.`]},campus:{title:"The Campus",lines:[`The sun never quite sets on the old film school. 10Its classrooms stand empty, its fountain still runs, 11and somebody once called this place the future.`,`Stucco and terracotta, baked pale by a long afternoon. 12The bell tower keeps time for no one.`,`They made films here, once. 13The light still behaves as if a camera were rolling.`,`North, past the gate, lies a lake 14where a man once lived alone to hear what the quiet would say.`,`A statue stands in a ring of flowers. 15It has not moved in years. It is waiting for its cue.`]},dungeon:{title:"The Undercroft",lines:[`Under the gate the maker sealed, the school years were kept in the dark. 16Here the work was never good enough. 17Something made of straw is still waiting to be finished.`,`The air smells of turpentine and old straw. 18The owls are watching. They have opinions.`,`Down here the ideas came slowly, one lamp at a time. 19Light a fire. The dark listens to fire.`,`Not everything that follows you is a friend. 20Some of them only want to look like you.`,`Nothing down here is lost for good. 21It only waits to be carried back.`]},goldcamp:{title:"Gold Creek",lines:[`The rails ran out of luck before they ran out of track. 22Gold Creek: a town that dug for its fortune 23and found mostly dust.`,`The saloon door still swings. 24Nobody pushed it.`,`Wind off the cliffs, dust in every crack. 25The creek remembers where the gold went.`,`The bankâs new safe is full. The town is not. 26Somebody is still counting.`,`Three breaks in the line lead north, past the falls. 27Whatever waits beyond the mine, no train has seen it in years.`]},"treehouse-inside":{title:"The Treehouse",lines:[`It is bigger on the inside. It always was. 28In here a stick is a wand, a broom is a sword, 29and a dragon sleeps on a castle made of cardboard.`,`Leave what you carry by the door. 30In here you play with what the room gives you.`,`Chalk on the wall tells a story: 31a crate falls, a bird flies, a dragon wakes.`,`Everything in here is pretend. 32That has never stopped anything from being real.`,`The dragon is only sleeping. 33Treasure has a way of waking things.`]},"windmill-inside":{title:"The Windmill",lines:[`The sails have stood still a long time. 34High in the cap a brake has bitten down on its wheel, 35and the mill has forgotten how to turn.`,`Flour in the air, light through the boards. 36The mill answers only to its own mallet.`,`Four floors of patient machinery, 37waiting for one good strike in the right place.`,`The miller left a note, his tools and the wind. 38He never came back for any of them.`,`Mend it, and the whole meadow will see the sails turn. 39The wind has been waiting to be useful.`]},"workshop-inside":{title:"The Workshop",lines:[`The makerâs workshop. The door was locked for a reason: 40nothing in here is finished yet.`,`Sawdust, half-built things, a radio left on low. 41Come back later. It will have changed.`,`Every table in here holds something 42that is not ready to be seen.`]}},TITLE_MAX=60,LINE_MAX=320,VARIANTS_MAX=12;function m(e,n){return typeof e!="string"?"":e.replace(/\r\n?/g,` 43`).split(` 44`).map(function(o){return o.replace(/\s+/g," ").trim()}).filter(Boolean).join(` 45`).slice(0,n).trim()}export function loreFor(e,n){const o=Object.prototype.hasOwnProperty.call(LORE,e)?LORE[e]:null,t=n&&n.env&&n.env.lore&&typeof n.env.lore=="object"?n.env.lore:null,i=t&&m(t.title,TITLE_MAX).replace(/\n/g," ")||(o?o.title:"");let a=t&&Array.isArray(t.lines)?t.lines.map(function(r){return m(r,LINE_MAX)}
45).filter(Boolean).slice(0,VARIANTS_MAX):[];return!a.length&&o&&(a=o.lines.slice()),!i&&!a.length?null:{title:i,lines:a}}export function pickVariant(e,n,o){if(!(e>0))return-1;if(n==null||e===1)return 0;const t=typeof o=="function"?o():Math.random(),i=[];for(let a=1;a<e;a++)a!==n&&i.push(a);return i.length?i[Math.min(i.length-1,Math.floor(Math.max(0,t)*i.length))]:0}export function linesOf(e){return String(e||"").split(` 46`).map(function(n){return n.trim()}).filter(Boolean)}export const TITLE_IN_MS=500,LINE_GAP_MS=900;export function readingMs(e,n){const o=Array.isArray(n)?n:linesOf(n);let t=String(e||"").length;for(const a of o)t+=a.length;const i=TITLE_IN_MS+Math.max(0,o.length-1)*LINE_GAP_MS;return Math.round(Math.min(14e3,i+2200+t*45))}export function minHoldMs(e){return TITLE_IN_MS+(Array.isArray(e)&&e.length>1?1e3:700)}export const PACE={first:{beat:450,letter:42,letterIn:850,titleBeat:1300,word:105,wordIn:760,char:55,lineMin:1700,lineBeat:450,readMax:6e3,hold:1500,out:1100},later:{beat:0,letter:26,letterIn:650,titleBeat:260,word:55,wordIn:640,char:24,lineMin:900,lineBeat:0,readMax:2600,hold:0,out:1300}};const M=900;export function wordsTimeline(e,n,o){const t=o&&typeof o=="object"?o:PACE[o]||PACE.later,i=Array.isArray(n)?n.map(String).map(function(s){return s.trim()}).filter(Boolean):linesOf(n),a=String(e||"").trim(),r={title:null,rule:null,lines:[],landed:0,read:0};let l=t.beat;if(a){const s=[];for(let h=0;h<a.length;h++)s.push(Math.round(l+h*t.letter));const d=l+(a.length-1)*t.letter;r.title={at:l,letters:s,end:Math.round(d+t.letterIn)},r.rule={at:Math.round(l+(a.length-1)*t.letter*.5)},r.landed=Math.max(r.title.end,r.rule.at+M),r.read=r.landed,l=d+t.titleBeat}return i.forEach(function(s,d){const h=s.split(/\s+/).filter(Boolean),w=Math.round(l),g=h.map(function(p,y){return{text:p,at:Math.round(l+y*t.word)}}),c=Math.max(0,h.length-1)*t.word+t.wordIn,u=Math.round(l+c),f=Math.min(t.readMax,s.length*t.char);r.lines.push({at:w,words:g,end:u}),r.landed=Math.max(r.landed,u),r.read=Math.max(r.read,Math.round(l+Math.max(c,f))),d<i.length-1&&(l+=Math.max(t.lineMin,f,c*.6)+t.lineBeat)}),r.read=Math.round(Math.max(r.read,r.landed)+t.hold),r}export const FEATHER_SVG='<svg class="hero-area-spin" viewBox="0 0 32 32" aria-hidden="true"><path fill="currentColor" d="M27 4C18 5 11 10 8.5 17.5c-1 3-1.2 6-.8 8.5 2.2-.4 4.6-1.4 6.6-3l-2.6-.4 4.4-1.6c1.4-1.5 2.6-3.3 3.4-5.3l-3 .1 4-2.2C25 10.5 26.6 7.4 27 4z"/><path fill="none" stroke="currentColor" stroke-width="1.4" stroke-linecap="round" d="M5 27l3.6-3.6"/><path fill="none" stroke="#000" stroke-width="0.9" stroke-linecap="round" opacity="0.55" d="M8.6 23.4L21.5 10.5"/></svg>',CINEMA={blackIn:700,liftAfter:550,lift:1600},STAGES={fetch:[0,.18],models:[.18,.62],mount:[.62,.96],live:[1,1]};export function createBar(){return{stage:"fetch",target:0,shown:0}}export function barStage(e,n){const o=STAGES[n];if(!o)return e;const t=["fetch","models","mount","live"];return t.indexOf(n)<t.indexOf(e.stage)||(e.stage=n,e.target=Math.max(e.target,o[0])),e}export function barBytes(e,n){const o=STAGES[e.stage],t=Math.max(0,Math.min(1,Number(n)||0));return e.target=Math.max(e.target,o[0]+(o[1]-o[0])*t),e}const k=1.6,x=.16,T=.05;export function barStep(e,n){const o=STAGES[e.stage],t=Math.max(0,Math.min(.25,Number(n)||0)),i=e.stage==="live",a=o[1];e.target<a&&(e.target+=(a-e.target)*(1-Math.exp(-t/k))),i&&(e.target=1);const r=e.shown+(e.target-e.shown)*(1-Math.exp(-t/(i?T:x)));return e.shown=Math.max(e.shown,Math.min(1,i&&e.target-r<.01?1:r)),e.shown}
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.