PluginProbe
OpenStation: Desktop Windows, Dock & Virtual Desktops for WP Admin / 1.1.12
OpenStation: Desktop Windows, Dock & Virtual Desktops for WP Admin v1.1.12
1.1.13 1.1.12 1.1.11 1.1.10 1.1.9 1.1.8 1.1.7 1.1.6 1.1.5 1.1.4 1.1.3 1.1.2 1.1.1 1.1.0 1.0.1 1.0.0 0.9.8 0.9.7 0.9.6 0.9.4 0.9.5 0.9.3 0.9.2 0.9.1 0.9.0 All 37 releases
← All changes | assets/js/game-inkfall.min.js +1 -1 1.0.0 → 1.1.12 View file →
@@ -1,2 +1,2 @@
1 -(function(){"use strict";const Ge="openstation";function ie(){return window.wp?.i18n}function f(e,t=Ge){return ie()?.__(e,t)??e}function K(e,...t){const n=ie()?.sprintf;if(n)return n(e,...t);let r=0;return e.replace(/%(?:(\d+)\$)?[sd]/g,(l,a)=>{const o=a?Number.parseInt(a,10)-1:r++;return String(t[o]??"")})}function ce(){return window.wp?.os??{}}const le="desktop-mode/inkfall-sound",Pe=.16,Fe=.5,j=[0,2,4,5,7,9,11],de=196;function ue(e){const t=e.toLowerCase();if(t.length!==1||t<"a"||t>"z")return 0;const n=t.charCodeAt(0)-97,r=12*Math.floor(n/j.length)+j[n%j.length];return de*Math.pow(2,r/12)}function We(){try{return window.localStorage.getItem(le)!=="0"}catch{return!0}}function De(e){try{window.localStorage.setItem(le,e?"1":"0")}catch{}}function Ke(){let e=null,t=null,n=We(),r=!1;const l=()=>{if(r)return null;if(e)return e.state==="suspended"&&e.resume().catch(()=>{}),e;const o=window.AudioContext??window.webkitAudioContext;if(!o)return null;try{e=new o}catch{return null}return t=e.createGain(),t.gain.value=Pe,t.connect(e.destination),e},a=(o,s={})=>{if(!n||o<=0)return;const c=l();if(!c||!t)return;const{type:w="sine",delay:p=0,duration:d=.22,level:T=Fe}=s,x=c.currentTime+p,E=c.createOscillator(),m=c.createGain();E.type=w,E.frequency.value=o,m.gain.setValueAtTime(1e-4,x),m.gain.exponentialRampToValueAtTime(T,x+.008),m.gain.exponentialRampToValueAtTime(1e-4,x+d),E.connect(m),m.connect(t),E.start(x),E.stop(x+d+.05)};return{letter(o){a(ue(o))},typo(){a(98,{type:"triangle",duration:.15,level:.35}),a(103,{type:"triangle",duration:.12,level:.2})},wordBurst(o){const s=ue(o)||de;a(s,{duration:.3}),a(s*1.25,{delay:.06,duration:.3}),a(s*1.5,{delay:.12,duration:.35}),a(s*2,{delay:.18,duration:.4,level:.4})},miss(){a(165,{type:"triangle",duration:.3,level:.4}),a(123,{type:"triangle",delay:.12,duration:.4,level:.4})},setEnabled(o){n=o,De(o)},isEnabled(){return n},dispose(){r=!0,e&&(e.close().catch(()=>{}),e=null,t=null)}}}const fe="X-WP-Nonce";function ze(e,t){const n=Be();if(!n)return t;const r=He(e);if(!r||!Ue(r))return t;const l=t?.headers??(typeof Request<"u"&&e instanceof Request?e.headers:void 0),a=new Headers(l??{});return a.has(fe)?t:(a.set(fe,n),{...t??{},headers:a})}function Be(){if(typeof window>"u")return;const t=window.openStationConfig?.restNonce;return typeof t=="string"&&t.length>0?t:void 0}function He(e){try{const t=typeof window<"u"&&window.location?window.location.href:void 0;return typeof e=="string"?new URL(e,t):e instanceof URL?e:typeof Request<"u"&&e instanceof Request?new URL(e.url,t):null}catch{return null}}function Ue(e){return typeof window>"u"||!window.location||e.origin!==window.location.origin?!1:!!(e.pathname.includes("/wp-json/")||e.searchParams.has("rest_route"))}function $e(e,t,n={}){const r=window.wp?.os?.fetch;if(typeof r=="function")return r(e,t,n);const l=ze(e,t);return fetch(e,l)}function Xe(e){const t=[];for(const o of e.split(`
1 +(function(){"use strict";const Ge="desktop-mode";function ie(){return window.wp?.i18n}function f(e,t=Ge){return ie()?.__(e,t)??e}function K(e,...t){const n=ie()?.sprintf;if(n)return n(e,...t);let r=0;return e.replace(/%(?:(\d+)\$)?[sd]/g,(l,a)=>{const o=a?Number.parseInt(a,10)-1:r++;return String(t[o]??"")})}function ce(){return window.wp?.os??{}}const le="desktop-mode/inkfall-sound",Pe=.16,Fe=.5,j=[0,2,4,5,7,9,11],de=196;function ue(e){const t=e.toLowerCase();if(t.length!==1||t<"a"||t>"z")return 0;const n=t.charCodeAt(0)-97,r=12*Math.floor(n/j.length)+j[n%j.length];return de*Math.pow(2,r/12)}function We(){try{return window.localStorage.getItem(le)!=="0"}catch{return!0}}function De(e){try{window.localStorage.setItem(le,e?"1":"0")}catch{}}function Ke(){let e=null,t=null,n=We(),r=!1;const l=()=>{if(r)return null;if(e)return e.state==="suspended"&&e.resume().catch(()=>{}),e;const o=window.AudioContext??window.webkitAudioContext;if(!o)return null;try{e=new o}catch{return null}return t=e.createGain(),t.gain.value=Pe,t.connect(e.destination),e},a=(o,s={})=>{if(!n||o<=0)return;const c=l();if(!c||!t)return;const{type:w="sine",delay:p=0,duration:d=.22,level:T=Fe}=s,x=c.currentTime+p,E=c.createOscillator(),m=c.createGain();E.type=w,E.frequency.value=o,m.gain.setValueAtTime(1e-4,x),m.gain.exponentialRampToValueAtTime(T,x+.008),m.gain.exponentialRampToValueAtTime(1e-4,x+d),E.connect(m),m.connect(t),E.start(x),E.stop(x+d+.05)};return{letter(o){a(ue(o))},typo(){a(98,{type:"triangle",duration:.15,level:.35}),a(103,{type:"triangle",duration:.12,level:.2})},wordBurst(o){const s=ue(o)||de;a(s,{duration:.3}),a(s*1.25,{delay:.06,duration:.3}),a(s*1.5,{delay:.12,duration:.35}),a(s*2,{delay:.18,duration:.4,level:.4})},miss(){a(165,{type:"triangle",duration:.3,level:.4}),a(123,{type:"triangle",delay:.12,duration:.4,level:.4})},setEnabled(o){n=o,De(o)},isEnabled(){return n},dispose(){r=!0,e&&(e.close().catch(()=>{}),e=null,t=null)}}}const fe="X-WP-Nonce";function ze(e,t){const n=Be();if(!n)return t;const r=He(e);if(!r||!Ue(r))return t;const l=t?.headers??(typeof Request<"u"&&e instanceof Request?e.headers:void 0),a=new Headers(l??{});return a.has(fe)?t:(a.set(fe,n),{...t??{},headers:a})}function Be(){if(typeof window>"u")return;const t=window.openStationConfig?.restNonce;return typeof t=="string"&&t.length>0?t:void 0}function He(e){try{const t=typeof window<"u"&&window.location?window.location.href:void 0;return typeof e=="string"?new URL(e,t):e instanceof URL?e:typeof Request<"u"&&e instanceof Request?new URL(e.url,t):null}catch{return null}}function Ue(e){return typeof window>"u"||!window.location||e.origin!==window.location.origin?!1:!!(e.pathname.includes("/wp-json/")||e.searchParams.has("rest_route"))}function $e(e,t,n={}){const r=window.wp?.os?.fetch;if(typeof r=="function")return r(e,t,n);const l=ze(e,t);return fetch(e,l)}function Xe(e){const t=[];for(const o of e.split(`
2 2 `)){const s=o.trim();s===""||s.startsWith("#")||t.push(s)}const n=new Map,r=new Map;for(let o=0;o<t.length;o++){const s=t[o].length;n.has(s)||n.set(s,o),r.set(s,o+1)}const l=(o,s)=>{let c=-1,w=-1;for(let p=o;p<=s;p++){const d=n.get(p);d!==void 0&&(c===-1&&(c=d),w=r.get(p))}return c===-1?{start:0,end:t.length}:{start:c,end:w}},a=(o,s,c)=>{const{start:w,end:p}=l(o,s),d=p-w;if(d<=0)return"";const T=Math.floor(d*Math.pow(c(),1.4));return t[w+Math.min(T,d-1)]};return{size:t.length,pick:(o,s,c,w)=>{let p=a(o,s,c);if(w&&w.size>0)for(let d=0;d<3&&p!==""&&w.has(p[0]);d++)p=a(o,s,c);return p}}}async function Ye(e,t={}){const n=await $e(e,{signal:t.signal,credentials:"same-origin"},{windowId:t.windowId,source:t.source??"desktop-mode/games-dictionary"});if(!n.ok)throw new Error(`[openstation] Games dictionary failed to load (${n.status}).`);const r=Xe(await n.text());if(r.size===0)throw new Error("[openstation] Games dictionary is empty.");return r}const X=300,J=3,pe=600,me=["easy","medium","hard"],he={easy:{spawn:[3200,900],speed:[40,170],concurrentStart:1,concurrentSteps:[[20,2],[60,3],[120,4],[200,5]],bandStart:[3,4],bandSteps:[[30,3,5],[75,3,6],[150,4,8],[225,5,10],[300,6,12]]},medium:{spawn:[2400,700],speed:[75,230],concurrentStart:1,concurrentSteps:[[10,2],[40,3],[90,4],[150,5],[240,6]],bandStart:[3,5],bandSteps:[[20,4,6],[60,4,8],[120,5,10],[200,6,12],[300,7,12]]},hard:{spawn:[1700,550],speed:[110,300],concurrentStart:2,concurrentSteps:[[10,3],[30,4],[70,5],[120,6],[200,7]],bandStart:[4,6],bandSteps:[[15,5,8],[45,6,10],[90,7,12],[150,8,12]]}};function z(e){return!Number.isFinite(e)||e<0?0:Math.min(e,X)}function Y(e){return he[e]??he.easy}function Ve(e,t="easy"){const n=z(e),[r,l]=Y(t).spawn;return Math.round(r-(r-l)*n/X)}function qe(e,t="easy"){const n=z(e),[r,l]=Y(t).speed;return r+(l-r)*n/X}function je(e,t="easy"){const n=z(e),{concurrentStart:r,concurrentSteps:l}=Y(t);let a=r;for(const[o,s]of l)n>=o&&(a=s);return a}function Je(e,t="easy"){const n=z(e),{bandStart:r,bandSteps:l}=Y(t);let a={min:r[0],max:r[1]};for(const[o,s,c]of l)n>=o&&(a={min:s,max:c});return a}function Z(e){return Math.min(15,Math.floor(z(e)/20))}function ye(e,t="easy"){const n=Je(e,t);return{spawnIntervalMs:Ve(e,t),fallSpeed:qe(e,t),maxConcurrent:je(e,t),minLength:n.min,maxLength:n.max,level:Z(e)}}const Ze=900,we=.9;function Qe(e,t){const n=[];for(let r=0;r<e;r++){const l=e>1?r/(e-1)*2-1:0;n.push({vx:l*(80+t()*60),vy:-(120+t()*120),spin:(t()*2-1)*6})}return n}function et(e,t){const n=e.vy+Ze*t;return{dx:e.vx*t,dy:(e.vy+n)/2*t,dRotation:e.spin*t,vyNext:n}}function tt(e){return Math.max(0,1-e/we)}const M=2832981,Q=9323693,nt=16249832,ot=12375270,rt=15245729,V='Georgia, "Times New Roman", serif',N=26,ge=32;function ke(e,t,n){e.clear(),e.rect(0,0,t,n).fill({color:nt});for(let l=ge;l<n;l+=ge)e.moveTo(0,l).lineTo(t,l).stroke({color:ot,width:1,alpha:.55});const r=Math.min(64,Math.round(t*.08));e.moveTo(r,0).lineTo(r,n).stroke({color:rt,width:2,alpha:.7}),e.moveTo(0,n-6).lineTo(t,n-6).stroke({color:M,width:2,alpha:.25})}function at(e,t){const n=new e.Container,r={fill:M,fontSize:N,fontFamily:V},l=new e.Text({text:"",style:{...r,fill:Q}}),a=new e.Text({text:t,style:r});return n.addChild(l,a),{container:n,matched:l,rest:a,text:t,width:a.width}}function ve(e,t){const n=Math.max(0,Math.min(t,e.text.length));e.matched.text=e.text.slice(0,n),e.rest.text=e.text.slice(n),e.rest.x=n>0?e.matched.width:0}const ee=["♪","♫","♩","♬"],st=.18,te=1.1;function it(e,t,n=Math.random){const r=[],l=a=>{const o=r.indexOf(a);if(o>=0&&r.splice(o,1),a.kind==="scatter"){for(const s of a.chars)t.removeChild(s.node),s.node.destroy();return}t.removeChild(a.node),a.node.destroy()};return{launchNote(a,o,s,c,w){const p=ee[Math.floor(n()*ee.length)]??ee[0],d=new e.Text({text:p,style:{fill:Q,fontSize:30,fontFamily:V}});d.anchor.set(.5),d.x=a,d.y=o,d.zIndex=30,t.addChild(d),r.push({kind:"note",node:d,fromX:a,fromY:o,toX:s,toY:c,age:0,onArrive:w})},tearWord(a){const o=new e.Text({text:"",style:{fill:M,fontSize:N,fontFamily:V}}),s=[];for(let p=0;p<a.text.length;p++)o.text=a.text.slice(0,p),s.push(o.width);o.destroy();const c=Qe(a.text.length,n),w=[];for(let p=0;p<a.text.length;p++){const d=new e.Text({text:a.text[p],style:{fill:Q,fontSize:N,fontFamily:V}});d.anchor.set(.5),d.x=a.container.x+s[p]+7,d.y=a.container.y+N/2,d.zIndex=20,t.addChild(d),w.push({node:d,particle:c[p]})}t.removeChild(a.container),a.container.destroy({children:!0}),r.push({kind:"scatter",chars:w,age:0})},splashBlot(a,o){const s=new e.Graphics;s.circle(0,0,9).fill({color:M,alpha:.8}),s.ellipse(-12,3,4,2.5).fill({color:M,alpha:.6}),s.ellipse(11,-2,3,2).fill({color:M,alpha:.6}),s.circle(6,7,2.5).fill({color:M,alpha:.5}),s.x=a,s.y=o,s.zIndex=10,t.addChild(s),r.push({kind:"blot",node:s,age:0})},update(a){for(const o of r.slice()){if(o.age+=a,o.kind==="note"){const c=Math.min(1,o.age/st),w=1-(1-c)*(1-c);if(o.node.x=o.fromX+(o.toX-o.fromX)*w,o.node.y=o.fromY+(o.toY-o.fromY)*c*c,o.node.rotation=c*.6,c>=1){const p=o.onArrive;l(o),p()}continue}if(o.kind==="scatter"){for(const c of o.chars){const w=et(c.particle,a);c.node.x+=w.dx,c.node.y+=w.dy,c.node.rotation+=w.dRotation,c.particle.vy=w.vyNext,c.node.alpha=tt(o.age)}o.age>=we&&l(o);continue}const s=te*.4;if(o.age<=s)o.node.alpha=1;else{const c=(o.age-s)/(te-s);o.node.alpha=Math.max(0,1-c)}o.age>=te&&l(o)}},busy(){return r.length>0},clear(){for(const a of r.slice())l(a)}}}function ct(e,t){const n=document.createElement("input");n.type="text",n.autocomplete="off",n.autocapitalize="off",n.spellcheck=!1,n.setAttribute("aria-hidden","true"),n.tabIndex=-1,n.className="inkfall__key-capture",e.appendChild(n);const r=o=>{if(!(o.metaKey||o.ctrlKey||o.altKey)){if(o.key==="Backspace"){o.preventDefault(),t.onBackspace();return}if(o.key==="Escape"){o.preventDefault(),t.onEscape();return}o.key.length===1&&/[a-zA-Z]/.test(o.key)&&(o.preventDefault(),t.onLetter(o.key.toLowerCase()))}},l=()=>{n.value=""};n.addEventListener("keydown",r),n.addEventListener("input",l);const a=()=>{window.setTimeout(()=>n.focus(),0)};return e.addEventListener("pointerdown",a),{focus:()=>n.focus(),dispose:()=>{n.removeEventListener("keydown",r),n.removeEventListener("input",l),e.removeEventListener("pointerdown",a),n.remove()}}}function lt(){let e=null,t=0;const n=()=>{e=null,t=0};return{handleKey(r,l){const a=r.toLowerCase();if(a.length!==1||!/[a-z]/.test(a))return{kind:"ignored"};if(e===null){let s=null;for(const c of l)c.text[0]===a&&(!s||c.y>s.y)&&(s=c);if(!s)return{kind:"ignored"};if(e=s.id,t=1,s.text.length===1){const c=e;return n(),{kind:"completed",targetId:c}}return{kind:"locked",targetId:e,matchedCount:t}}const o=l.find(s=>s.id===e);if(!o)return n(),this.handleKey(a,l);if(o.text[t]!==a)return{kind:"typo",targetId:o.id};if(t++,t>=o.text.length){const s=o.id;return n(),{kind:"completed",targetId:s}}return{kind:"advanced",targetId:o.id,matchedCount:t}},handleBackspace(){e!==null&&(t=Math.max(1,t-1))},release:n,forget(r){e===r&&n()},state(){return{targetId:e,matchedCount:t}}}}function Ee(){return{score:0,wordsCompleted:0,streak:0,correctKeys:0,totalKeys:0,typoInCurrentWord:!1}}function dt(e){return 1+.1*Math.min(Math.max(0,e),10)}function ut(e,t,n){const r=Math.min(1,Math.max(0,t));return Math.round(10*e*(1+.5*r)*dt(n))}function Ce(e){e.correctKeys++,e.totalKeys++}function ft(e){e.totalKeys++,e.typoInCurrentWord=!0,e.streak=0}function pt(e,t,n){const r=ut(t,n,e.streak);return e.score+=r,e.wordsCompleted++,e.typoInCurrentWord?e.streak=0:e.streak++,e.typoInCurrentWord=!1,r}function mt(e){e.streak=0,e.typoInCurrentWord=!1}function _e(e){return e.totalKeys===0?100:Math.round(e.correctKeys/e.totalKeys*100)}function xe(e,t){return t<=0?0:Math.round(e.correctKeys/5*(60/t))}function ht(e,t,n,r){const l={words:e.wordsCompleted,wpm:xe(e,t),accuracy:_e(e),time:Math.round(t),level:n};return r&&(l.mode=r),{score:e.score,meta:l}}function yt(){return window.PIXI??null}const be="desktop-mode/inkfall-mode";function Se(e){switch(e){case"medium":return f("Medium");case"hard":return f("Hard");default:return f("Easy")}}function wt(e){switch(e){case"medium":return f("Brisk from the first word.");case"hard":return f("Fast ink, long words. Good luck.");default:return f("A gentle warm-up that builds.")}}function gt(){try{const e=window.localStorage.getItem(be);if(e&&me.includes(e))return e}catch{}return"easy"}function kt(e){try{window.localStorage.setItem(be,e)}catch{}}const vt=.05,Et=250;function Ct(e){const t=document.createElement("div");t.className="inkfall",e.container.appendChild(t);const n=Ke(),r=document.createElement("div");r.className="inkfall__hud";const l=document.createElement("span");l.className="inkfall__hud-score";const a=document.createElement("span");a.className="inkfall__hud-streak";const o=document.createElement("span");o.className="inkfall__hud-lives";const s=document.createElement("span");s.className="inkfall__hud-level";const c=document.createElement("button");c.type="button",c.className="inkfall__hud-sound";const w=()=>{c.textContent=n.isEnabled()?"🔊":"🔇",c.setAttribute("aria-label",n.isEnabled()?f("Mute sound effects"):f("Unmute sound effects")),c.setAttribute("aria-pressed",n.isEnabled()?"false":"true")};if(w(),c.addEventListener("click",()=>{n.setEnabled(!n.isEnabled()),w()}),r.append(l,a,o,s),e.challenge){const i=document.createElement("span");i.className="inkfall__hud-ribbon",i.textContent=K(f("Beat %1$s: %2$s"),e.challenge.challengerName,String(e.challenge.scoreToBeat)),r.appendChild(i)}r.appendChild(c),t.appendChild(r);const p=document.createElement("div");p.className="inkfall__stage",t.appendChild(p);const d=document.createElement("div");d.className="inkfall__overlay",d.hidden=!0,t.appendChild(d);const T=i=>{d.hidden=!1,d.innerHTML="";const u=document.createElement("p");u.className="inkfall__overlay-message",u.textContent=i,d.appendChild(u)};T(f("Loading the notebook…"));let x=!1,E="loading",m=null,I=null,b=null,P=null,oe=null,B=null,re=null,Ne=null,q=null;const L=lt();let C=Ee(),_=[],H=J,R=0,U=0,Te=0,ae=0,_t=1,A=gt();const F=()=>{l.textContent=K(f("Score %s"),String(C.score)),a.textContent=C.streak>1?`×${C.streak}`:"",o.textContent="●".repeat(H)+"○".repeat(Math.max(0,J-H)),s.textContent=K(f("Level %1$s · %2$s"),String(Z(R)),Se(A))},O=()=>m?.renderer.width??600,W=()=>m?.renderer.height??pe,Ie=()=>W()-10,xt=()=>_.map(i=>({id:i.id,text:i.text,y:i.sprite.container.y})),se=(i,u)=>{_=_.filter(g=>g.id!==i.id),L.forget(i.id),!u&&m&&(m.stage.removeChild(i.sprite.container),i.sprite.container.destroy({children:!0}))},Le=()=>{if(!m||!I||!oe)return;const i=ye(R,A),u=new Set(_.map(v=>v.text[0])),g=oe.pick(i.minLength,i.maxLength,Math.random,u);if(g==="")return;const y=at(I,g),h=Math.min(64,Math.round(O()*.08)),k=Math.max(h+8,O()-y.width-16);y.container.x=h+8+Math.random()*Math.max(1,k-h-8),y.container.y=-N-4,m.stage.addChild(y.container),_.push({id:_t++,text:g,sprite:y,jitter:.9+Math.random()*.2}),Te=ae},D=()=>{const i=L.state();for(const u of _)ve(u.sprite,u.id===i.targetId?i.matchedCount:0)},bt=i=>{const u=_.find(G=>G.id===i);if(!u||!b)return;const g=W(),y=(Ie()-u.sprite.container.y)/Math.max(1,g);pt(C,u.text.length,y);const h=u.sprite;se(u,!0),ve(h,h.text.length);const k=h.text[h.text.length-1],v=h.container.x+h.width/2,S=h.container.y+N/2;b.launchNote(O()/2,W()-12,v,S,()=>{b?.tearWord(h),n.wordBurst(k)}),F()},St=()=>{E="over",L.release(),D();const i=Math.min(R,X),u=ht(C,i,Z(R),A);d.hidden=!1,d.innerHTML="";const g=document.createElement("div");g.className="inkfall__over-panel";const y=document.createElement("p");y.className="inkfall__over-heading",e.challenge?y.textContent=u.score>e.challenge.scoreToBeat?f("Game Over — challenge beaten!"):f("Game Over — challenge missed."):y.textContent=f("Game Over"),g.appendChild(y);const h=document.createElement("p");h.className="inkfall__over-stats",h.textContent=K(f("Score %1$s — %2$s words, %3$s WPM, %4$s%% accuracy."),String(u.score),String(C.wordsCompleted),String(xe(C,Math.max(1,i))),String(_e(C))),g.appendChild(h);const k=document.createElement("p");k.className="inkfall__over-save",k.textContent=f("Saving your score…"),g.appendChild(k),e.submitScore(u).then(()=>{k.textContent=f("Score saved to the scoreboard.")},()=>{k.textContent=f("Your score could not be saved.")});const v=document.createElement("div");v.className="inkfall__over-actions";const S=document.createElement("button");S.type="button",S.className="inkfall__button inkfall__button--primary",S.textContent=f("Play again"),S.addEventListener("click",()=>{Ae(A)}),v.appendChild(S);const G=document.createElement("button");G.type="button",G.className="inkfall__button",G.textContent=f("Change difficulty"),G.addEventListener("click",()=>{Oe()}),v.appendChild(G);const $=document.createElement("button");$.type="button",$.className="inkfall__button",$.textContent=f("Close"),$.addEventListener("click",()=>e.close()),v.appendChild($),g.appendChild(v),d.appendChild(g)},Re=()=>{for(const i of _.slice())se(i,!1);b?.clear(),C=Ee(),H=J,R=0,U=0,L.release()},Ae=i=>{A=i,kt(i),Re(),d.hidden=!0,d.innerHTML="",E="playing",m?.ticker.start(),F(),B?.focus()},Oe=()=>{Re(),E="menu",F(),d.hidden=!1,d.innerHTML="";const i=document.createElement("div");i.className="inkfall__over-panel inkfall__menu";const u=document.createElement("p");if(u.className="inkfall__over-heading",u.textContent=f("Choose your pace"),i.appendChild(u),e.challenge){const y=document.createElement("p");y.className="inkfall__over-stats",y.textContent=K(f("Challenge from %1$s — beat %2$s."),e.challenge.challengerName,String(e.challenge.scoreToBeat)),i.appendChild(y)}const g=document.createElement("div");g.className="inkfall__menu-options";for(const y of me){const h=document.createElement("button");h.type="button",h.className="inkfall__menu-option",y===A&&h.classList.add("inkfall__menu-option--current");const k=document.createElement("span");k.className="inkfall__menu-option-label",k.textContent=Se(y),h.appendChild(k);const v=document.createElement("span");v.className="inkfall__menu-option-hint",v.textContent=wt(y),h.appendChild(v),h.addEventListener("click",S=>{S.stopPropagation(),Ae(y)}),g.appendChild(h)}i.appendChild(g),d.appendChild(i)},Mt=()=>{E==="playing"&&(E="paused",T(f("Paused — click to resume.")),m?.ticker.stop())},Nt=()=>{E==="paused"&&(E="playing",d.hidden=!0,m?.ticker.start(),B?.focus())};d.addEventListener("click",()=>{E==="paused"&&Nt()});const Tt=()=>{if(!m||!b)return;const i=Math.min(vt,m.ticker.deltaMS/1e3);if(ae+=m.ticker.deltaMS,b.update(i),E!=="playing")return;R+=i;const u=ye(R,A),g=W()/pe;U+=i*1e3,(_.length<u.maxConcurrent&&U>=u.spawnIntervalMs||_.length===0&&ae-Te>Et)&&(U=0,Le());const h=Ie();for(const k of _.slice())if(k.sprite.container.y+=u.fallSpeed*g*k.jitter*i,k.sprite.container.y+N>=h){const v=k.sprite.container.x+k.sprite.width/2;if(se(k,!1),b.splashBlot(v,h),n.miss(),mt(C),H--,D(),F(),H<=0){St();return}}},It=i=>{if(E!=="playing")return;const u=L.handleKey(i,xt());switch(u.kind){case"locked":case"advanced":Ce(C),n.letter(i),D();break;case"completed":Ce(C),n.letter(i),bt(u.targetId),D();break;case"typo":{ft(C),n.typo();const g=_.find(y=>y.id===u.targetId);g&&(g.sprite.container.alpha=.4,window.setTimeout(()=>{g.sprite.container.alpha=1},120)),F();break}}};return(async()=>{const i=ce();if(typeof i.loadModules!="function")throw new Error("[openstation] wp.os.loadModules missing.");const u=String(e.config.wordsUrl||"");if(u==="")throw new Error("[openstation] Inkfall config lacks wordsUrl.");const[,g]=await Promise.all([i.loadModules(["pixijs"]),Ye(u,{windowId:e.windowId,source:"desktop-mode/inkfall"})]);if(x)return;if(oe=g,I=yt(),!I)throw new Error("[openstation] PixiJS failed to load.");const y=new I.Application;if(await y.init({resizeTo:p,backgroundAlpha:0,antialias:!0,autoDensity:!0,resolution:Math.min(window.devicePixelRatio||1,2),sharedTicker:!1}),x){y.destroy({removeView:!0},{children:!0,texture:!0});return}m=y,m.canvas.className="inkfall__canvas",p.appendChild(m.canvas),m.stage.sortableChildren=!0,P=new I.Graphics,P.zIndex=0,m.stage.addChild(P),ke(P,O(),W()),b=it(I,m.stage),re=new ResizeObserver(()=>{if(!m||!P)return;m.resize(),ke(P,O(),W());const h=Math.min(64,Math.round(O()*.08));for(const k of _){const v=O()-k.sprite.width-16;k.sprite.container.x>v&&(k.sprite.container.x=Math.max(h+8,v))}}),re.observe(p),B=ct(t,{onLetter:It,onBackspace:()=>{L.handleBackspace(),D()},onEscape:()=>{L.release(),D()}}),Ne=ce().onWindow?.(e.windowId,{blurred:Mt,focused:()=>B?.focus()})??null,q=Tt,m.ticker.add(q),F(),Oe()})().catch(i=>{x||(T(i instanceof Error?i.message:f("Inkfall could not start.")),typeof console<"u"&&console.error("[openstation] Inkfall boot failed:",i))}),()=>{x||(x=!0,n.dispose(),Ne?.(),re?.disconnect(),B?.dispose(),m&&(q&&m.ticker.remove(q),m.ticker.stop(),b?.clear(),m.destroy({removeView:!0},{children:!0,texture:!0}),m=null),t.remove())}}const Me={id:"inkfall",title:f("Inkfall"),icon:"dashicons-edit",scoreColumns:[{key:"score",label:f("Score"),type:"number"},{key:"mode",label:f("Difficulty"),type:"text"},{key:"words",label:f("Words"),type:"number"},{key:"wpm",label:f("WPM"),type:"number"},{key:"accuracy",label:f("Accuracy"),type:"number"},{key:"time",label:f("Time"),type:"time"},{key:"level",label:f("Level"),type:"number"}],window:{width:820,height:620,minWidth:520,minHeight:420},render:e=>Ct(e)},ne=window;ne.openStationGames=ne.openStationGames||{},ne.openStationGames[Me.id]=Me})();