diff --git a/index.ef91dd93.js b/index.d796f22d.js similarity index 94% rename from index.ef91dd93.js rename to index.d796f22d.js index 18d7127..ca95ea7 100644 --- a/index.ef91dd93.js +++ b/index.d796f22d.js @@ -4,7 +4,7 @@ function t(t){return t&&t.__esModule?t.default:t}/*! * Copyright (c) 2023 Excalibur.js * Licensed BSD-2-Clause * @preserve - *//******/var e,i,s,r={/***/4662:/***/(t,e,i)=>{i(3430);var s=i(8791);t.exports=s("Array","sort");/***/},/***/8343:/***/(t,e,i)=>{i(4769);var s=i(9276);t.exports=s.Object.keys;/***/},/***/7111:/***/(t,e,i)=>{var s=i(6733),r=i(9821),n=TypeError;// `Assert: IsCallable(argument) is true` + *//******/var e,i,s={/***/4662:/***/(t,e,i)=>{i(3430);var s=i(8791);t.exports=s("Array","sort");/***/},/***/8343:/***/(t,e,i)=>{i(4769);var s=i(9276);t.exports=s.Object.keys;/***/},/***/7111:/***/(t,e,i)=>{var s=i(6733),r=i(9821),n=TypeError;// `Assert: IsCallable(argument) is true` t.exports=function(t){if(s(t))return t;throw n(r(t)+" is not a function")};/***/},/***/1176:/***/(t,e,i)=>{var s=i(5052),r=String,n=TypeError;// `Assert: Type(argument) is Object` t.exports=function(t){if(s(t))return t;throw n(r(t)+" is not an object")};/***/},/***/9540:/***/(t,e,i)=>{var s=i(905),r=i(3231),n=i(9646),o=function(t){return function(e,i,o){var a,h=s(e),l=n(h),d=r(o,l);// Array#includes uses SameValueZero equality algorithm // eslint-disable-next-line no-self-compare -- NaN check @@ -271,25 +271,25 @@ o.push([t.id,` Author Tobias Koppers @sokra */t.exports=function(t){var e=[];return(// return the list of modules as css string e.toString=function(){return this.map(function(e){var i="",s=void 0!==e[5];return e[4]&&(i+="@supports (".concat(e[4],") {")),e[2]&&(i+="@media ".concat(e[2]," {")),s&&(i+="@layer".concat(e[5].length>0?" ".concat(e[5]):""," {")),i+=t(e),s&&(i+="}"),e[2]&&(i+="}"),e[4]&&(i+="}"),i}).join("")},// import a list of modules into the list -e.i=function(t,i,s,r,n){"string"==typeof t&&(t=[[null,t,void 0]]);var o={};if(s)for(var a=0;a0?" ".concat(d[5]):""," {").concat(d[1],"}")),d[5]=n),i&&(d[2]&&(d[1]="@media ".concat(d[2]," {").concat(d[1],"}")),d[2]=i),r&&(d[4]?(d[1]="@supports (".concat(d[4],") {").concat(d[1],"}"),d[4]=r):d[4]="".concat(r)),e.push(d))}},e)};/***/},/***/272:/***/t=>{t.exports=function(t){var e=t[1],i=t[3];if(!i)return e;if("function"==typeof btoa){var s=btoa(unescape(encodeURIComponent(JSON.stringify(i))));return[e].concat(["/*# ".concat("sourceMappingURL=data:application/json;charset=utf-8;base64,".concat(s)," */")]).join("\n")}return[e].join("\n")};/***/}},n={};/******//******/// The require function -/******/function o(t){/******/// Check if module is in cache -/******/var e=n[t];/******/if(void 0!==e)/******/return e.exports;/******/// Create a new module (and put it into the cache) -/******/var i=n[t]={/******/id:t,/******/// no module.loaded needed +e.i=function(t,i,s,r,n){"string"==typeof t&&(t=[[null,t,void 0]]);var o={};if(s)for(var a=0;a0?" ".concat(d[5]):""," {").concat(d[1],"}")),d[5]=n),i&&(d[2]&&(d[1]="@media ".concat(d[2]," {").concat(d[1],"}")),d[2]=i),r&&(d[4]?(d[1]="@supports (".concat(d[4],") {").concat(d[1],"}"),d[4]=r):d[4]="".concat(r)),e.push(d))}},e)};/***/},/***/272:/***/t=>{t.exports=function(t){var e=t[1],i=t[3];if(!i)return e;if("function"==typeof btoa){var s=btoa(unescape(encodeURIComponent(JSON.stringify(i))));return[e].concat(["/*# ".concat("sourceMappingURL=data:application/json;charset=utf-8;base64,".concat(s)," */")]).join("\n")}return[e].join("\n")};/***/}},r={};/******//******/// The require function +/******/function n(t){/******/// Check if module is in cache +/******/var e=r[t];/******/if(void 0!==e)/******/return e.exports;/******/// Create a new module (and put it into the cache) +/******/var i=r[t]={/******/id:t,/******/// no module.loaded needed /******/exports:{}};/******//******/// Return the exports of the module /******/return(/******//******/// Execute the module function -/******/r[t].call(i.exports,i,i.exports,o),i.exports);/******/}/******/// getDefaultExport function for compatibility with non-harmony modules -/******/o.n=t=>{/******/var e=t&&t.__esModule?/******/()=>t.default:/******/()=>t;/******/return /******/o.d(e,{a:e}),e;/******/},/******/// define getter functions for harmony exports -/******/o.d=(t,e)=>{/******/for(var i in e)/******/o.o(e,i)&&!o.o(t,i)&&/******/Object.defineProperty(t,i,{enumerable:!0,get:e[i]});/******/},/******/o.g=function(){/******/if("object"==typeof globalThis)return globalThis;/******/try{/******/return this||Function("return this")();/******/}catch(t){/******/if("object"==typeof window)return window;/******/}/******/}(),/******/o.o=(t,e)=>Object.prototype.hasOwnProperty.call(t,e),/******/// define __esModule on exports -/******/o.r=t=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&/******/Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),/******/Object.defineProperty(t,"__esModule",{value:!0});/******/};/******//************************************************************************/var a={};// This entry need to be wrapped in an IIFE because it need to be isolated against other modules in the chunk. +/******/s[t].call(i.exports,i,i.exports,n),i.exports);/******/}/******/// getDefaultExport function for compatibility with non-harmony modules +/******/n.n=t=>{/******/var e=t&&t.__esModule?/******/()=>t.default:/******/()=>t;/******/return /******/n.d(e,{a:e}),e;/******/},/******/// define getter functions for harmony exports +/******/n.d=(t,e)=>{/******/for(var i in e)/******/n.o(e,i)&&!n.o(t,i)&&/******/Object.defineProperty(t,i,{enumerable:!0,get:e[i]});/******/},/******/n.g=function(){/******/if("object"==typeof globalThis)return globalThis;/******/try{/******/return this||Function("return this")();/******/}catch(t){/******/if("object"==typeof window)return window;/******/}/******/}(),/******/n.o=(t,e)=>Object.prototype.hasOwnProperty.call(t,e),/******/// define __esModule on exports +/******/n.r=t=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&/******/Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),/******/Object.defineProperty(t,"__esModule",{value:!0});/******/};/******//************************************************************************/var o={};// This entry need to be wrapped in an IIFE because it need to be isolated against other modules in the chunk. (()=>{// EXPORTS -o.d(a,{fWn:()=>/* reexport */sR,Ia8:()=>/* reexport */sg,rqv:()=>/* reexport */rY,hLI:()=>/* reexport */sD,yyv:()=>/* reexport */ry,tX5:()=>/* reexport */t1,vtX:()=>/* reexport */sL,r7K:()=>/* reexport */st,lCh:()=>/* reexport */s3,cE4:()=>/* reexport */eP,fwF:()=>/* reexport */Animation,sce:()=>/* reexport */ta,AQ6:()=>/* reexport */rd,_c7:()=>/* reexport */th,KUs:()=>/* reexport */ro,Ajp:()=>/* reexport */io,dkO:()=>/* reexport */H,RDh:()=>/* reexport */tn,_H9:()=>/* reexport */ti,mxs:()=>/* reexport */sT,OmD:()=>/* reexport */i8,kBf:()=>/* reexport */ey,C4F:()=>/* reexport */K,NQt:()=>/* reexport */rR,JjN:()=>/* reexport */rD,EK_:()=>/* reexport */z,V1s:()=>/* reexport */sJ,xHm:()=>/* reexport */sQ,Xz7:()=>/* reexport */i_,Cdc:()=>/* reexport */sc,FKn:()=>/* reexport */i1,SUY:()=>/* reexport */rz,ab2:()=>/* reexport */iJ,GfZ:()=>/* reexport */i0,YMS:()=>/* reexport */iY,oyv:()=>/* reexport */i7,aUb:()=>/* reexport */i2,SdD:()=>/* reexport */tJ,JUv:()=>/* reexport */iG,jEj:()=>/* reexport */rQ,TFq:()=>/* reexport */i3,HDU:()=>/* reexport */tj,R_y:()=>/* reexport */tY,ydN:()=>/* reexport */Z,t50:()=>/* reexport */tQ,s$$:()=>/* reexport */rl,v2G:()=>/* reexport */X,Ilk:()=>/* reexport */ef,s9i:()=>/* reexport */rP,dxL:()=>/* reexport */tc,LLX:()=>/* reexport */rE,wA2:()=>/* reexport */iz,R_p:()=>/* reexport */ij,IQ$:()=>/* reexport */ru,I5F:()=>/* reexport */t8,X8$:()=>/* reexport */ra,FR6:()=>/* reexport */tK,U8o:()=>/* reexport */tZ,kbG:()=>/* reexport */j,iS_:()=>/* reexport */t2,cGG:()=>/* reexport */rM,RPN:()=>/* reexport */sW,skb:()=>/* reexport */rf,SLU:()=>/* reexport */eN,RdJ:()=>/* reexport */Q,cNu:()=>/* reexport */sP,gU7:()=>/* reexport */iP,LSk:()=>/* reexport */sM,Nmp:()=>/* reexport */tr,d1Y:()=>/* reexport */q,xrL:()=>/* reexport */iX,sRW:()=>/* reexport */iK,cmV:()=>/* binding */na,qWz:()=>/* reexport */sS,N0Q:()=>/* reexport */sA,q8b:()=>/* reexport */sp,ynB:()=>/* reexport */i4,jT9:()=>/* reexport */sK,wAz:()=>/* reexport */tl,D4V:()=>/* reexport */rV,NLr:()=>/* reexport */r$,N6H:()=>/* reexport */t4,W1A:()=>/* reexport */t3,JHW:()=>/* reexport */sn,ZZ$:()=>/* reexport */sr,v2K:()=>/* reexport */s7,pBf:()=>/* reexport */rq,vpe:()=>/* reexport */tS,GMl:()=>/* reexport */L,zW2:()=>/* reexport */tf,B0K:()=>/* reexport */im,Nv7:()=>/* reexport */is,C_p:()=>/* reexport */ie,MUA:()=>/* reexport */t9,xqU:()=>/* reexport */t5,pTp:()=>/* reexport */sE,vUK:()=>/* reexport */tC,j9l:()=>/* reexport */sI,Zxw:()=>/* reexport */sU,v51:()=>/* reexport */sF,Hdx:()=>/* reexport */ts,Z$d:()=>/* reexport */tt,iqV:()=>/* reexport */rL,o$7:()=>/* reexport */rI,olM:()=>/* reexport */ex,Zm$:()=>/* reexport */tT,$QH:()=>/* reexport */tI,i78:()=>/* reexport */tk,nJg:()=>/* reexport */Gamepad,h6u:()=>/* reexport */tG,hts:()=>/* reexport */tW,j88:()=>/* reexport */tO,VME:()=>/* reexport */tN,fy2:()=>/* reexport */t6,nt:()=>/* reexport */r6,Ukr:()=>/* reexport */rB,zsu:()=>/* reexport */eF,oA6:()=>/* reexport */sl,TVh:()=>/* reexport */rc,TwZ:()=>/* reexport */sa,GTT:()=>/* reexport */sh,xxj:()=>/* reexport */rm,XdK:()=>/* reexport */tV,Jmb:()=>/* reexport */V,cXo:()=>/* reexport */ez,Dm5:()=>/* reexport */t0,IIB:()=>/* reexport */tx,ebW:()=>/* reexport */rG,zI0:()=>/* reexport */Y,LYD:()=>/* reexport */rx,cEG:()=>/* reexport */rw,SEl:()=>/* reexport */rK,t9V:()=>/* reexport */rZ,ez5:()=>/* reexport */ei,N1d:()=>/* reexport */es,R8U:()=>/* reexport */N,SKZ:()=>/* reexport */tE,__J:()=>/* reexport */rX,RI$:()=>/* reexport */sj,x12:()=>/* reexport */ns,ccz:()=>/* reexport */iQ,aNw:()=>/* reexport */iT,XrL:()=>/* reexport */iS,xwn:()=>/* reexport */sZ,dNK:()=>/* reexport */sX,ini:()=>/* reexport */O,YdH:()=>/* reexport */t7,F5T:()=>/* reexport */e6,y3G:()=>/* reexport */eE,l57:()=>/* reexport */$,xn0:()=>/* reexport */ix,t2V:()=>/* reexport */sk,uxB:()=>/* reexport */iW,cpd:()=>/* reexport */rn,fiy:()=>/* reexport */sf,$XZ:()=>/* reexport */sv,UG6:()=>/* reexport */tp,uqK:()=>/* reexport */iw,STE:()=>/* reexport */ib,y$z:()=>/* reexport */iO,mAD:()=>/* reexport */rb,sOq:()=>/* reexport */i$,hUw:()=>/* reexport */sN,_0G:()=>/* reexport */rj,Sqs:()=>/* reexport */ni,hpZ:()=>/* reexport */rg,Vol:()=>/* reexport */r_,vYX:()=>/* reexport */td,wIZ:()=>/* reexport */iB,cBi:()=>/* reexport */rk,c30:()=>/* reexport */rC,MPV:()=>/* reexport */tg,RFv:()=>/* reexport */su,Ux6:()=>/* reexport */PointerEvent,rxy:()=>/* reexport */rU,I$c:()=>/* reexport */W,kfC:()=>/* reexport */rv,VjY:()=>/* reexport */t_,mgq:()=>/* reexport */nr,YVA:()=>/* reexport */i9,Kgp:()=>/* reexport */e3,HH$:()=>/* reexport */tX,M_d:()=>/* reexport */tF,rgh:()=>/* reexport */tD,Ra6:()=>/* reexport */tH,KhR:()=>/* reexport */tM,BS5:()=>/* reexport */tL,xhz:()=>/* reexport */tq,xOq:()=>/* reexport */tB,a9j:()=>/* reexport */tR,bHk:()=>/* reexport */tz,CgK:()=>/* reexport */tP,cuY:()=>/* reexport */tU,kvE:()=>/* reexport */iV,SBu:()=>/* reexport */e0,AE_:()=>/* reexport */rt,ctO:()=>/* reexport */re,OLH:()=>/* reexport */sY,kky:()=>/* reexport */er,nSF:()=>/* reexport */ig,zHn:()=>/* reexport */iZ,zwx:()=>/* reexport */rh,AeJ:()=>/* reexport */sd,hLz:()=>/* reexport */si,D9g:()=>/* reexport */s9,wA:()=>/* reexport */s_,jhr:()=>/* reexport */sm,GVs:()=>/* reexport */ir,_zO:()=>/* reexport */eR,LXZ:()=>/* reexport */ek,w6$:()=>/* reexport */sx,mhV:()=>/* reexport */sy,MOD:()=>/* reexport */J,kwd:()=>/* reexport */sb,Lmr:()=>/* reexport */sw,xsS:()=>/* reexport */rS,K5l:()=>/* reexport */rA,lLr:()=>/* reexport */Screen,Z$r:()=>/* reexport */et,IXb:()=>/* reexport */sH,SGH:()=>/* reexport */rT,SMj:()=>/* reexport */tm,L34:()=>/* reexport */no,exe:()=>/* reexport */eX,bnF:()=>/* reexport */i6,MFA:()=>/* reexport */G,$uU:()=>/* reexport */iA,Sap:()=>/* reexport */iC,jyi:()=>/* reexport */eU,E03:()=>/* reexport */eO,V6q:()=>/* reexport */eH,rg2:()=>/* reexport */rH,DVW:()=>/* reexport */iv,nVo:()=>/* reexport */sq,F6N:()=>/* reexport */nt,xP7:()=>/* reexport */s5,Odq:()=>/* reexport */ri,Zif:()=>/* reexport */to,ZGJ:()=>/* reexport */iH,MJk:()=>/* reexport */rO,xvT:()=>/* reexport */Text,PHM:()=>/* reexport */te,dpR:()=>/* reexport */eL,n9L:()=>/* reexport */sV,KwO:()=>/* reexport */s$,SxM:()=>/* reexport */sG,B7y:()=>/* reexport */sO,x7r:()=>/* reexport */rW,wx7:()=>/* reexport */iL,Uvn:()=>/* reexport */iN,OFT:()=>/* reexport */iq,xzN:()=>/* reexport */s2,CcZ:()=>/* reexport */s0,M5Z:()=>/* reexport */en,ZrN:()=>/* reexport */tw,OWs:()=>/* reexport */e_,dF9:()=>/* reexport */iF,oZy:()=>/* reexport */eZ,rD2:()=>/* reexport */eK,VHo:()=>/* reexport */t$,ohE:()=>/* reexport */ia,R$E:()=>/* reexport */iy,xQN:()=>/* reexport */tu,AdJ:()=>/* reexport */WheelEvent,q3I:()=>/* reexport */rs,Pab:()=>/* reexport */el,uZ5:()=>/* reexport */eh,McK:()=>/* reexport */tA,F9c:()=>/* reexport */eo,k0b:()=>/* reexport */so,hnT:()=>/* reexport */r0,RSJ:()=>/* reexport */r3,Mku:()=>/* reexport */r2,h90:()=>/* reexport */r9,rms:()=>/* reexport */r4,ErP:()=>/* reexport */rJ,aVg:()=>/* reexport */r5,lPc:()=>/* reexport */r1,Z8E:()=>/* reexport */se,_N2:()=>/* reexport */s4,yFn:()=>/* reexport */s6,lNv:()=>/* reexport */ss,cu9:()=>/* reexport */sz,MZQ:()=>/* reexport */iM,FUM:()=>/* reexport */iD,BxR:()=>/* reexport */e8,vdf:()=>/* reexport */ep,iaL:()=>/* reexport */eg,w6H:()=>/* reexport */eu,Q4c:()=>/* reexport */ik,Xxe:()=>/* reexport */ea,Uxb:()=>/* reexport */ed,Yr5:()=>/* reexport */ec,Bhw:()=>/* reexport */em,yOA:()=>/* reexport */tv});// NAMESPACE OBJECT: ./Events.ts -var t,e,i,s,r,n,h,l,d,c,u,p,g,_,m,f,v,y,x,w,b,C,A,S,T,E,P,M,I,k,R,D,B,F,U,L,z,H,O,N,W,G,$,V,q,X,Z,K,Y,j,Q,J,tt,te,ti,ts,tr,tn,to,ta,th,tl,td,tc,tu,tp,tg,t_,tm,tf={};o.r(tf),o.d(tf,{ActivateEvent:()=>t1,CollisionEndEvent:()=>tJ,CollisionPostSolveEvent:()=>tj,CollisionPreSolveEvent:()=>tY,CollisionStartEvent:()=>tQ,ContactEndEvent:()=>tK,ContactStartEvent:()=>tZ,DeactivateEvent:()=>t2,EnterTriggerEvent:()=>t4,EnterViewPortEvent:()=>t3,EventTypes:()=>L,ExitTriggerEvent:()=>t9,ExitViewPortEvent:()=>t5,GameEvent:()=>tT,GameStartEvent:()=>tI,GameStopEvent:()=>tk,GamepadAxisEvent:()=>tG,GamepadButtonEvent:()=>tW,GamepadConnectEvent:()=>tO,GamepadDisconnectEvent:()=>tN,HiddenEvent:()=>tV,InitializeEvent:()=>t0,KillEvent:()=>tE,PostCollisionEvent:()=>tX,PostDebugDrawEvent:()=>tF,PostDrawEvent:()=>tD,PostFrameEvent:()=>tH,PostKillEvent:()=>tM,PostUpdateEvent:()=>tL,PreCollisionEvent:()=>tq,PreDebugDrawEvent:()=>tB,PreDrawEvent:()=>tR,PreFrameEvent:()=>tz,PreKillEvent:()=>tP,PreUpdateEvent:()=>tU,VisibleEvent:()=>t$});// NAMESPACE OBJECT: ./Graphics/Context/webgl-util.ts -var tv={};o.r(tv),o.d(tv,{getAttributeComponentSize:()=>eV,getAttributePointerType:()=>eq,getGlTypeSizeBytes:()=>e$});// NAMESPACE OBJECT: ./Util/DrawUtil.ts -var ty={};o.r(ty),o.d(ty,{circle:()=>iu,line:()=>ih,point:()=>il,roundRect:()=>ic,vector:()=>id});// NAMESPACE OBJECT: ./Input/Index.ts -var tx={};o.r(tx),o.d(tx,{Axes:()=>H,Buttons:()=>z,Gamepad:()=>Gamepad,Gamepads:()=>t6,KeyEvent:()=>ei,Keyboard:()=>es,Keys:()=>N,NativePointerButton:()=>tp,PointerButton:()=>tg,PointerComponent:()=>su,PointerEvent:()=>PointerEvent,PointerEventReceiver:()=>rU,PointerScope:()=>W,PointerSystem:()=>rv,PointerType:()=>t_,WheelDeltaMode:()=>tu,WheelEvent:()=>WheelEvent});// NAMESPACE OBJECT: ./Util/Index.ts +n.d(o,{fWn:()=>/* reexport */sR,Ia8:()=>/* reexport */sg,rqv:()=>/* reexport */rY,hLI:()=>/* reexport */sD,yyv:()=>/* reexport */ry,tX5:()=>/* reexport */t1,vtX:()=>/* reexport */sL,r7K:()=>/* reexport */st,lCh:()=>/* reexport */s3,cE4:()=>/* reexport */eP,fwF:()=>/* reexport */Animation,sce:()=>/* reexport */ta,AQ6:()=>/* reexport */rd,_c7:()=>/* reexport */th,KUs:()=>/* reexport */ro,Ajp:()=>/* reexport */io,dkO:()=>/* reexport */H,RDh:()=>/* reexport */tn,_H9:()=>/* reexport */ti,mxs:()=>/* reexport */sT,OmD:()=>/* reexport */i8,kBf:()=>/* reexport */ey,C4F:()=>/* reexport */K,NQt:()=>/* reexport */rR,JjN:()=>/* reexport */rD,EK_:()=>/* reexport */z,V1s:()=>/* reexport */sJ,xHm:()=>/* reexport */sQ,Xz7:()=>/* reexport */i_,Cdc:()=>/* reexport */sc,FKn:()=>/* reexport */i1,SUY:()=>/* reexport */rz,ab2:()=>/* reexport */iJ,GfZ:()=>/* reexport */i0,YMS:()=>/* reexport */iY,oyv:()=>/* reexport */i7,aUb:()=>/* reexport */i2,SdD:()=>/* reexport */tJ,JUv:()=>/* reexport */iG,jEj:()=>/* reexport */rQ,TFq:()=>/* reexport */i3,HDU:()=>/* reexport */tj,R_y:()=>/* reexport */tY,ydN:()=>/* reexport */Z,t50:()=>/* reexport */tQ,s$$:()=>/* reexport */rl,v2G:()=>/* reexport */X,Ilk:()=>/* reexport */ef,s9i:()=>/* reexport */rP,dxL:()=>/* reexport */tc,LLX:()=>/* reexport */rE,wA2:()=>/* reexport */iz,R_p:()=>/* reexport */ij,IQ$:()=>/* reexport */ru,I5F:()=>/* reexport */t8,X8$:()=>/* reexport */ra,FR6:()=>/* reexport */tK,U8o:()=>/* reexport */tZ,kbG:()=>/* reexport */j,iS_:()=>/* reexport */t2,cGG:()=>/* reexport */rM,RPN:()=>/* reexport */sW,skb:()=>/* reexport */rf,SLU:()=>/* reexport */eN,RdJ:()=>/* reexport */Q,cNu:()=>/* reexport */sP,gU7:()=>/* reexport */iP,LSk:()=>/* reexport */sM,Nmp:()=>/* reexport */tr,d1Y:()=>/* reexport */q,xrL:()=>/* reexport */iX,sRW:()=>/* reexport */iK,cmV:()=>/* binding */na,qWz:()=>/* reexport */sS,N0Q:()=>/* reexport */sA,q8b:()=>/* reexport */sp,ynB:()=>/* reexport */i4,jT9:()=>/* reexport */sK,wAz:()=>/* reexport */tl,D4V:()=>/* reexport */rV,NLr:()=>/* reexport */r$,N6H:()=>/* reexport */t4,W1A:()=>/* reexport */t3,JHW:()=>/* reexport */sn,ZZ$:()=>/* reexport */sr,v2K:()=>/* reexport */s7,pBf:()=>/* reexport */rq,vpe:()=>/* reexport */tS,GMl:()=>/* reexport */L,zW2:()=>/* reexport */tf,B0K:()=>/* reexport */im,Nv7:()=>/* reexport */is,C_p:()=>/* reexport */ie,MUA:()=>/* reexport */t9,xqU:()=>/* reexport */t5,pTp:()=>/* reexport */sE,vUK:()=>/* reexport */tC,j9l:()=>/* reexport */sI,Zxw:()=>/* reexport */sU,v51:()=>/* reexport */sF,Hdx:()=>/* reexport */ts,Z$d:()=>/* reexport */tt,iqV:()=>/* reexport */rL,o$7:()=>/* reexport */rI,olM:()=>/* reexport */ex,Zm$:()=>/* reexport */tT,$QH:()=>/* reexport */tI,i78:()=>/* reexport */tk,nJg:()=>/* reexport */Gamepad,h6u:()=>/* reexport */tG,hts:()=>/* reexport */tW,j88:()=>/* reexport */tO,VME:()=>/* reexport */tN,fy2:()=>/* reexport */t6,nt:()=>/* reexport */r6,Ukr:()=>/* reexport */rB,zsu:()=>/* reexport */eF,oA6:()=>/* reexport */sl,TVh:()=>/* reexport */rc,TwZ:()=>/* reexport */sa,GTT:()=>/* reexport */sh,xxj:()=>/* reexport */rm,XdK:()=>/* reexport */tV,Jmb:()=>/* reexport */V,cXo:()=>/* reexport */ez,Dm5:()=>/* reexport */t0,IIB:()=>/* reexport */tx,ebW:()=>/* reexport */rG,zI0:()=>/* reexport */Y,LYD:()=>/* reexport */rx,cEG:()=>/* reexport */rw,SEl:()=>/* reexport */rK,t9V:()=>/* reexport */rZ,ez5:()=>/* reexport */ei,N1d:()=>/* reexport */es,R8U:()=>/* reexport */N,SKZ:()=>/* reexport */tE,__J:()=>/* reexport */rX,RI$:()=>/* reexport */sj,x12:()=>/* reexport */ns,ccz:()=>/* reexport */iQ,aNw:()=>/* reexport */iT,XrL:()=>/* reexport */iS,xwn:()=>/* reexport */sZ,dNK:()=>/* reexport */sX,ini:()=>/* reexport */O,YdH:()=>/* reexport */t7,F5T:()=>/* reexport */e6,y3G:()=>/* reexport */eE,l57:()=>/* reexport */$,xn0:()=>/* reexport */ix,t2V:()=>/* reexport */sk,uxB:()=>/* reexport */iW,cpd:()=>/* reexport */rn,fiy:()=>/* reexport */sf,$XZ:()=>/* reexport */sv,UG6:()=>/* reexport */tp,uqK:()=>/* reexport */iw,STE:()=>/* reexport */ib,y$z:()=>/* reexport */iO,mAD:()=>/* reexport */rb,sOq:()=>/* reexport */i$,hUw:()=>/* reexport */sN,_0G:()=>/* reexport */rj,Sqs:()=>/* reexport */ni,hpZ:()=>/* reexport */rg,Vol:()=>/* reexport */r_,vYX:()=>/* reexport */td,wIZ:()=>/* reexport */iB,cBi:()=>/* reexport */rk,c30:()=>/* reexport */rC,MPV:()=>/* reexport */tg,RFv:()=>/* reexport */su,Ux6:()=>/* reexport */PointerEvent,rxy:()=>/* reexport */rU,I$c:()=>/* reexport */W,kfC:()=>/* reexport */rv,VjY:()=>/* reexport */t_,mgq:()=>/* reexport */nr,YVA:()=>/* reexport */i9,Kgp:()=>/* reexport */e3,HH$:()=>/* reexport */tX,M_d:()=>/* reexport */tF,rgh:()=>/* reexport */tD,Ra6:()=>/* reexport */tH,KhR:()=>/* reexport */tM,BS5:()=>/* reexport */tL,xhz:()=>/* reexport */tq,xOq:()=>/* reexport */tB,a9j:()=>/* reexport */tR,bHk:()=>/* reexport */tz,CgK:()=>/* reexport */tP,cuY:()=>/* reexport */tU,kvE:()=>/* reexport */iV,SBu:()=>/* reexport */e0,AE_:()=>/* reexport */rt,ctO:()=>/* reexport */re,OLH:()=>/* reexport */sY,kky:()=>/* reexport */er,nSF:()=>/* reexport */ig,zHn:()=>/* reexport */iZ,zwx:()=>/* reexport */rh,AeJ:()=>/* reexport */sd,hLz:()=>/* reexport */si,D9g:()=>/* reexport */s9,wA:()=>/* reexport */s_,jhr:()=>/* reexport */sm,GVs:()=>/* reexport */ir,_zO:()=>/* reexport */eR,LXZ:()=>/* reexport */ek,w6$:()=>/* reexport */sx,mhV:()=>/* reexport */sy,MOD:()=>/* reexport */J,kwd:()=>/* reexport */sb,Lmr:()=>/* reexport */sw,xsS:()=>/* reexport */rS,K5l:()=>/* reexport */rA,lLr:()=>/* reexport */Screen,Z$r:()=>/* reexport */et,IXb:()=>/* reexport */sH,SGH:()=>/* reexport */rT,SMj:()=>/* reexport */tm,L34:()=>/* reexport */no,exe:()=>/* reexport */eX,bnF:()=>/* reexport */i6,MFA:()=>/* reexport */G,$uU:()=>/* reexport */iA,Sap:()=>/* reexport */iC,jyi:()=>/* reexport */eU,E03:()=>/* reexport */eO,V6q:()=>/* reexport */eH,rg2:()=>/* reexport */rH,DVW:()=>/* reexport */iv,nVo:()=>/* reexport */sq,F6N:()=>/* reexport */nt,xP7:()=>/* reexport */s5,Odq:()=>/* reexport */ri,Zif:()=>/* reexport */to,ZGJ:()=>/* reexport */iH,MJk:()=>/* reexport */rO,xvT:()=>/* reexport */Text,PHM:()=>/* reexport */te,dpR:()=>/* reexport */eL,n9L:()=>/* reexport */sV,KwO:()=>/* reexport */s$,SxM:()=>/* reexport */sG,B7y:()=>/* reexport */sO,x7r:()=>/* reexport */rW,wx7:()=>/* reexport */iL,Uvn:()=>/* reexport */iN,OFT:()=>/* reexport */iq,xzN:()=>/* reexport */s2,CcZ:()=>/* reexport */s0,M5Z:()=>/* reexport */en,ZrN:()=>/* reexport */tw,OWs:()=>/* reexport */e_,dF9:()=>/* reexport */iF,oZy:()=>/* reexport */eZ,rD2:()=>/* reexport */eK,VHo:()=>/* reexport */t$,ohE:()=>/* reexport */ia,R$E:()=>/* reexport */iy,xQN:()=>/* reexport */tu,AdJ:()=>/* reexport */WheelEvent,q3I:()=>/* reexport */rs,Pab:()=>/* reexport */el,uZ5:()=>/* reexport */eh,McK:()=>/* reexport */tA,F9c:()=>/* reexport */eo,k0b:()=>/* reexport */so,hnT:()=>/* reexport */r0,RSJ:()=>/* reexport */r3,Mku:()=>/* reexport */r2,h90:()=>/* reexport */r9,rms:()=>/* reexport */r4,ErP:()=>/* reexport */rJ,aVg:()=>/* reexport */r5,lPc:()=>/* reexport */r1,Z8E:()=>/* reexport */se,_N2:()=>/* reexport */s4,yFn:()=>/* reexport */s6,lNv:()=>/* reexport */ss,cu9:()=>/* reexport */sz,MZQ:()=>/* reexport */iM,FUM:()=>/* reexport */iD,BxR:()=>/* reexport */e8,vdf:()=>/* reexport */ep,iaL:()=>/* reexport */eg,w6H:()=>/* reexport */eu,Q4c:()=>/* reexport */ik,Xxe:()=>/* reexport */ea,Uxb:()=>/* reexport */ed,Yr5:()=>/* reexport */ec,Bhw:()=>/* reexport */em,yOA:()=>/* reexport */tv});// NAMESPACE OBJECT: ./Events.ts +var t,e,i,s,r,a,h,l,d,c,u,p,g,_,m,f,v,y,x,w,b,C,A,S,T,E,P,M,I,k,R,D,B,F,U,L,z,H,O,N,W,G,$,V,q,X,Z,K,Y,j,Q,J,tt,te,ti,ts,tr,tn,to,ta,th,tl,td,tc,tu,tp,tg,t_,tm,tf={};n.r(tf),n.d(tf,{ActivateEvent:()=>t1,CollisionEndEvent:()=>tJ,CollisionPostSolveEvent:()=>tj,CollisionPreSolveEvent:()=>tY,CollisionStartEvent:()=>tQ,ContactEndEvent:()=>tK,ContactStartEvent:()=>tZ,DeactivateEvent:()=>t2,EnterTriggerEvent:()=>t4,EnterViewPortEvent:()=>t3,EventTypes:()=>L,ExitTriggerEvent:()=>t9,ExitViewPortEvent:()=>t5,GameEvent:()=>tT,GameStartEvent:()=>tI,GameStopEvent:()=>tk,GamepadAxisEvent:()=>tG,GamepadButtonEvent:()=>tW,GamepadConnectEvent:()=>tO,GamepadDisconnectEvent:()=>tN,HiddenEvent:()=>tV,InitializeEvent:()=>t0,KillEvent:()=>tE,PostCollisionEvent:()=>tX,PostDebugDrawEvent:()=>tF,PostDrawEvent:()=>tD,PostFrameEvent:()=>tH,PostKillEvent:()=>tM,PostUpdateEvent:()=>tL,PreCollisionEvent:()=>tq,PreDebugDrawEvent:()=>tB,PreDrawEvent:()=>tR,PreFrameEvent:()=>tz,PreKillEvent:()=>tP,PreUpdateEvent:()=>tU,VisibleEvent:()=>t$});// NAMESPACE OBJECT: ./Graphics/Context/webgl-util.ts +var tv={};n.r(tv),n.d(tv,{getAttributeComponentSize:()=>eV,getAttributePointerType:()=>eq,getGlTypeSizeBytes:()=>e$});// NAMESPACE OBJECT: ./Util/DrawUtil.ts +var ty={};n.r(ty),n.d(ty,{circle:()=>iu,line:()=>ih,point:()=>il,roundRect:()=>ic,vector:()=>id});// NAMESPACE OBJECT: ./Input/Index.ts +var tx={};n.r(tx),n.d(tx,{Axes:()=>H,Buttons:()=>z,Gamepad:()=>Gamepad,Gamepads:()=>t6,KeyEvent:()=>ei,Keyboard:()=>es,Keys:()=>N,NativePointerButton:()=>tp,PointerButton:()=>tg,PointerComponent:()=>su,PointerEvent:()=>PointerEvent,PointerEventReceiver:()=>rU,PointerScope:()=>W,PointerSystem:()=>rv,PointerType:()=>t_,WheelDeltaMode:()=>tu,WheelEvent:()=>WheelEvent});// NAMESPACE OBJECT: ./Util/Index.ts var tw={};/** * Polyfill adding function - */function tb(){/* istanbul ignore next */if("undefined"==typeof window&&(window={audioContext:function(){}}),"undefined"==typeof window||window.requestAnimationFrame||(window.requestAnimationFrame=window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||function(t){window.setInterval(t,1e3/60)}),"undefined"==typeof window||window.cancelAnimationFrame||(window.cancelAnimationFrame=window.webkitCancelAnimationFrame||window.mozCancelAnimationFrame||function(){}),"undefined"!=typeof window&&!window.AudioContext){if(window.webkitAudioContext){let t=window.webkitAudioContext,e=t.prototype.decodeAudioData;window.webkitAudioContext.prototype.decodeAudioData=function(t){return new Promise((i,s)=>{e.call(this,t,i,s)})}}window.AudioContext=window.AudioContext||window.webkitAudioContext||window.mozAudioContext||window.msAudioContext||window.oAudioContext}"undefined"==typeof window||window.devicePixelRatio||(window.devicePixelRatio=window.devicePixelRatio||1)}o.r(tw),o.d(tw,{ConsoleAppender:()=>t8,DrawUtil:()=>ty,EasingFunctions:()=>sp,LogLevel:()=>O,Logger:()=>t7,Observable:()=>iO,ScreenAppender:()=>et,addItemToArray:()=>eb,contains:()=>eA,delay:()=>eT,fail:()=>eS,getPosition:()=>ew,removeItemFromArray:()=>eC}),o(4662),o(8343);/** + */function tb(){/* istanbul ignore next */if("undefined"==typeof window&&(window={audioContext:function(){}}),"undefined"==typeof window||window.requestAnimationFrame||(window.requestAnimationFrame=window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||function(t){window.setInterval(t,1e3/60)}),"undefined"==typeof window||window.cancelAnimationFrame||(window.cancelAnimationFrame=window.webkitCancelAnimationFrame||window.mozCancelAnimationFrame||function(){}),"undefined"!=typeof window&&!window.AudioContext){if(window.webkitAudioContext){let t=window.webkitAudioContext,e=t.prototype.decodeAudioData;window.webkitAudioContext.prototype.decodeAudioData=function(t){return new Promise((i,s)=>{e.call(this,t,i,s)})}}window.AudioContext=window.AudioContext||window.webkitAudioContext||window.mozAudioContext||window.msAudioContext||window.oAudioContext}"undefined"==typeof window||window.devicePixelRatio||(window.devicePixelRatio=window.devicePixelRatio||1)}n.r(tw),n.d(tw,{ConsoleAppender:()=>t8,DrawUtil:()=>ty,EasingFunctions:()=>sp,LogLevel:()=>O,Logger:()=>t7,Observable:()=>iO,ScreenAppender:()=>et,addItemToArray:()=>eb,contains:()=>eA,delay:()=>eT,fail:()=>eS,getPosition:()=>ew,removeItemFromArray:()=>eC}),n(4662),n(8343);/** * Flags is a feature flag implementation for Excalibur. They can only be operated **before [[Engine]] construction** * after which they are frozen and are read-only. * @@ -635,9 +635,9 @@ for(let t=0;t{r.playbackState?(r.playbackState===r.PLAYING_STATE||r.playbackSt */function ic(t,e,i,s,r,n=5,o=ef.White,a=null){let h;if("number"==typeof n)h={tl:n,tr:n,br:n,bl:n};else{let t={tl:0,tr:0,br:0,bl:0};for(let e in t)t.hasOwnProperty(e)&&(h[e]=n[e]||t[e])}t.beginPath(),t.moveTo(e+h.tl,i),t.lineTo(e+s-h.tr,i),t.quadraticCurveTo(e+s,i,e+s,i+h.tr),t.lineTo(e+s,i+r-h.br),t.quadraticCurveTo(e+s,i+r,e+s-h.br,i+r),t.lineTo(e+h.bl,i+r),t.quadraticCurveTo(e,i+r,e,i+r-h.bl),t.lineTo(e,i+h.tl),t.quadraticCurveTo(e,i,e+h.tl,i),t.closePath(),a&&(t.fillStyle=a.toString(),t.fill()),o&&(t.strokeStyle=o.toString(),t.stroke())}/** * */function iu(t,e,i,s,r=ef.White,n=null){t.beginPath(),t.arc(e,i,s,0,2*Math.PI),t.closePath(),n&&(t.fillStyle=n.toString(),t.fill()),r&&(t.strokeStyle=r.toString(),t.stroke())}ia._UNLOCKED=!1;// EXTERNAL MODULE: ./Loader.css -var ip=o(1388);/** +var ip=n(1388);/** * A Raster is a Graphic that needs to be first painted to a HTMLCanvasElement before it can be drawn to the * [[ExcaliburGraphicsContext]]. This is useful for generating custom images using the 2D canvas api. * @@ -5050,7 +5050,7 @@ this.update(e),this._currentTime+=e):this._logger.warn("The clock is not running * @param numberOfSteps * @param overrideUpdateMs */run(t,e){for(let i=0;iMath.abs(t.pos.x-e.pos.x)+Math.abs(e.pos.y-e.pos.y),this.query=t.world.queryManager.createQuery([tE.type])}_buildPath(t){let e=[];for(;t.previousNode;)e.unshift(t),t=t.previousNode;return e.unshift(t),e}_getRangeHelper(t,e,i,s){s>=0&&(e.push(t),t.connections.filter(t=>t.isWalkable&&!!(t.walkableMask&i)).forEach(t=>this._getRangeHelper(t,e,i,s-1)))}getRange(t,e,i){let s=[];return this._getRangeHelper(t,s,e,i),s=// dedup results + */getNeighbors(){return[this.board.getCell(this.x,this.y-1),this.board.getCell(this.x,this.y+1),this.board.getCell(this.x+1,this.y),this.board.getCell(this.x-1,this.y)].filter(function(t){return null!==t})}}class tk{constructor(t){this.heuristicWeight=1,this.heuristic=(t,e)=>Math.abs(t.pos.x-e.pos.x)+Math.abs(e.pos.y-e.pos.y),this.query=t.world.queryManager.createQuery([tT.type])}_buildPath(t){let e=[];for(;t.previousNode;)e.unshift(t),t=t.previousNode;return e.unshift(t),e}_getRangeHelper(t,e,i,s){s>=0&&(e.push(t),t.connections.filter(t=>t.isWalkable&&!!(t.walkableMask&i)).forEach(t=>this._getRangeHelper(t,e,i,s-1)))}getRange(t,e,i){let s=[];return this._getRangeHelper(t,s,e,i),s=// dedup results (s=s.filter((t,e,i)=>i.indexOf(t)===e)).filter(t=>t.isWalkable)}/** * * @param start start node for the path @@ -5534,41 +5534,41 @@ this.graphics.hide("range"),this.graphics.hide("path"),this.graphics.hide("attac * @param mask bit mask to test against the node's walkability mask, same bit position means walkable (0b111 & 0b001) = walkable, (0b010 & 0b001) = not walkable * @param range * @returns - */findPath(t,e,i,s){let r=this.query.getEntities().map(t=>t.get(tE));r.forEach(t=>{t.gScore=0,t.hScore=0,t.previousNode=null}),t.gScore=0,t.hScore=t.gScore+this.heuristic(t,e)*this.heuristicWeight,t.direction=F.Down;let n=[t],o=[];for(;n.length>0;){// priority queue, evaluate nodes with the lowest cost + */findPath(t,e,i,s){let r=this.query.getEntities().map(t=>t.get(tT));r.forEach(t=>{t.gScore=0,t.hScore=0,t.previousNode=null}),t.gScore=0,t.hScore=t.gScore+this.heuristic(t,e)*this.heuristicWeight,t.direction=B.Down;let n=[t],o=[];for(;n.length>0;){// priority queue, evaluate nodes with the lowest cost let t=n.sort((t,e)=>t.hScore-e.hScore),r=t[0];// Done! if(r===e)return this._buildPath(r);// Remove current from the open node set let a=n.indexOf(r);n.splice(a,1),o.push(r);// Find the neighbors that haven't been explored let h=r.connections.filter(t=>t.isWalkable&&!!(t.walkableMask&i)).filter(t=>-1===o.indexOf(t));s&&(h=h.filter(t=>s.indexOf(t)>-1));// Current direction! let l=r.direction;h.forEach(t=>{if(-1===n.indexOf(t)){t.previousNode=r,t.gScore=t.weight+r.gScore,t.hScore=t.gScore+this.heuristic(t,e)*this.heuristicWeight;// Turn penalty if direction is not straight let i=t.pos.sub(r.pos).normalize();t.direction=i;let s=l.dot(i);0===s&&(t.hScore+=130),n.push(t)}})}// error case -return[]}}class tD{constructor(t,e,i){this.tileWidth=32,this.tileHeight=32,this.margin=2,this.cells=[],this.rows=t,this.cols=e;for(let t=0;tt.pathNode);this.pathFinder=new tR(i)}getCenter(){return H(this.cols*((this.tileWidth+this.margin)*tS.x),this.rows*((this.tileHeight+this.margin)*tS.y)).scale(.5)}getUnits(){let t=[];for(let e of this.cells)e.unit&&e.unit.active&&t.push(e.unit);return t}getEmptyCells(){return this.cells.filter(t=>!t.unit)}getCellByWorldPos(t){return this.getCell(Math.floor(t.x/*- BOARD_OFFSET.x*//((this.tileWidth+this.margin)*tS.x)),Math.floor(t.y/*- BOARD_OFFSET.y*//((this.tileHeight+this.margin)*tS.y)))}getCell(t,e){return t<0||t>=this.cols||e<0||e>=this.rows?null:this.cells[t+e*this.cols]}}const tB=new E({emitterType:v.Circle,radius:16,minVel:0,maxVel:20,minAngle:0,maxAngle:6.2,isEmitting:!1,emitRate:8,opacity:.75,fadeFlag:!0,particleLife:1500,maxSize:20,minSize:1,startSize:10,endSize:.01,acceleration:H(0,-32),particleSprite:tw,randomRotation:!0,particleRotationalVelocity:Math.PI});class tF extends l{constructor(t,e){super({name:"damage",pos:t,z:10});let i=new x({family:"notjamslab14",size:16*tS.x,unit:w.Px,color:p.Yellow,baseAlign:u.Top,quality:4,shadow:{offset:H(2,2).scale(tS),color:p.Black}}),s=new D({text:e.toFixed(0),font:i});this.graphics.add(s)}}class tU{constructor(t){this.scene=t}spawnDamageNumber(t,e){let i=new tF(t,e);i.actions.easeBy(H(0,-100),1e3,f.EaseOutCubic).die(),this.scene.add(i)}}class tL{constructor(t){this.scene=t}playExplosion(t){let e=new l({name:"explosion",pos:t.add(H(16,16).scale(tS))});tx.reset(),tx.strategy=c.End,tx.scale=tS;let i=tx.events.on("frame",t=>{7===t.frameIndex&&(e.kill(),i.close())});e.graphics.use(tx),this.scene.add(e)}}class tz extends l{constructor(t,e,i,s,r){super({name:i,anchor:H(0,0),z:2}),this.player=r,this.cell=null,this.moved=!1,this.attacked=!1,this.unitConfig={...tT[i]},this.health=this.unitConfig.health,this.anim=this.unitConfig.graphics.idle.clone(),this.anim.scale=tS,this.graphics.use(this.anim),this.graphics.onPostDraw=this.onPostDraw.bind(this);let n=s.getCell(t,e);n&&(this.pos=n.pos.sub(this.unitConfig.graphics.offset),n.addUnit(this))}onInitialize(t){this.damageManager=new tU(t.currentScene),this.animationManger=new tL(t.currentScene)}onPostUpdate(){this.hasActions()?this.anim.tint=p.White:this.anim.tint=p.Gray,this.health<=0&&(this.cell?.removeUnit(this),this.actions.delay(500).callMethod(()=>{this.animationManger.playExplosion(this.pos),to.ExplosionSound.play()}).callMethod(()=>{this.kill()}))}onPostDraw(t){if(this.health>0){let e=tv.getSprite(U(this.health,0,5),0);e&&(e.scale=tS,e.draw(t,10*tS.x+this.unitConfig.graphics.offset.x,10*tS.y+this.unitConfig.graphics.offset.y))}}async move(t){this.cell&&this.cell.removeUnit(this);let e=null;for(let i of t.slice(1,t.length)){e=i.owner;let t=new h(this,t=>{t.delay(200),t.callMethod(()=>{to.MoveSound.play()})}),s=new h(this,t=>{t.easeTo(e.pos.sub(this.unitConfig.graphics.offset),300,f.EaseInOutCubic),t.callMethod(()=>{tB.pos=this.pos.add(tS.scale(16)),tB.emitParticles(5)})}),r=new T([t,s]);await this.actions.runAction(r).toPromise()}e&&e.addUnit(this),this.moved=!0}reset(){this.moved=!1,this.attacked=!1}canAttack(){return this.getPossibleTargets()?.length!==0&&!this.attacked}canMove(){return!this.moved}hasActions(){return this.canMove()||this.canAttack()}availableActions(){let t=[];return this.canMove()&&t.push("move"),this.canAttack()&&t.push("attack"),t}pass(){this.moved=!0,this.attacked=!0}getPossibleTargets(){if(this.cell){let t=this.cell.board.pathFinder.getRange(this.cell.pathNode,~this.player.mask,this.unitConfig.range),e=t.map(t=>t.owner).filter(t=>!!t.unit?.player&&t.unit.player!==this.player);return e}}async attack(t){t.health-=this.unitConfig.attack,to.HitSound.play(),this.damageManager.spawnDamageNumber(t.pos.add(t.unitConfig.graphics.offset).add(H(16*tS.x,0)),this.unitConfig.attack),await t.actions.blink(200,200,5).toPromise(),this.attacked=!0}}class tH{static #t=this._STARTING_BIT=1;static #e=this._CURRENT_GROUP=tH._STARTING_BIT;constructor(t,e){this.name=t,this.board=e,this.active=!1,this.mask=tH._CURRENT_GROUP=tH._CURRENT_GROUP<<1|0}async turnStart(){this.active=!0;let t=this.board.getUnits().filter(t=>t.player===this);t.forEach(t=>t.reset())}hasLost(){let t=this.board.getUnits().filter(t=>t.player===this);return 0===t.length}async turnEnd(){this.active=!1}}class tO extends tH{constructor(t,e,i,s,r){super(t,r),this.engine=e,this.selectionManager=i,this.uiManger=s,this.passed=!1,this.humanMove=new b,e.input.pointers.on("down",this.pointerClick.bind(this)),e.input.pointers.on("move",this.pointerMove.bind(this)),e.input.keyboard.on("press",this.keyboardDown.bind(this)),document.body.oncontextmenu=()=>!1}keyboardDown(t){if(!this.active)return;this.selectionManager.resetHighlight();let e=this.selectionManager.currentCursor;switch(t.key){case A.ArrowRight:case A.D:this.selectionManager.showCursor(e.x+1,e.y);break;case A.Left:case A.A:this.selectionManager.showCursor(e.x-1,e.y);break;case A.Up:case A.W:this.selectionManager.showCursor(e.x,e.y-1);break;case A.Down:case A.D:this.selectionManager.showCursor(e.x,e.y+1);break;case A.Enter:case A.NumpadEnter:let i=this.board.getCell(e.x,e.y);this.maybeSelectUnit(i)}}async pointerClick(t){if(!this.active)return;this.selectionManager.resetHighlight();let e=this.board.getCellByWorldPos(t.worldPos);if(t.button===P.Left){// a unit is currently selected +return[]}}class tR{constructor(t,e,i){this.tileWidth=32,this.tileHeight=32,this.margin=2,this.cells=[],this.rows=t,this.cols=e;for(let t=0;tt.pathNode);this.pathFinder=new tk(i)}getCenter(){return z(this.cols*((this.tileWidth+this.margin)*tA.x),this.rows*((this.tileHeight+this.margin)*tA.y)).scale(.5)}getUnits(){let t=[];for(let e of this.cells)e.unit&&e.unit.active&&t.push(e.unit);return t}getEmptyCells(){return this.cells.filter(t=>!t.unit)}getCellByWorldPos(t){return this.getCell(Math.floor(t.x/*- BOARD_OFFSET.x*//((this.tileWidth+this.margin)*tA.x)),Math.floor(t.y/*- BOARD_OFFSET.y*//((this.tileHeight+this.margin)*tA.y)))}getCell(t,e){return t<0||t>=this.cols||e<0||e>=this.rows?null:this.cells[t+e*this.cols]}}const tD=new T({emitterType:f.Circle,radius:16,minVel:0,maxVel:20,minAngle:0,maxAngle:6.2,isEmitting:!1,emitRate:8,opacity:.75,fadeFlag:!0,particleLife:1500,maxSize:20,minSize:1,startSize:10,endSize:.01,acceleration:z(0,-32),particleSprite:tx,randomRotation:!0,particleRotationalVelocity:Math.PI});class tB extends h{constructor(t,e){super({name:"damage",pos:t,z:10});let i=new y({family:"notjamslab14",size:16*tA.x,unit:x.Px,color:u.Yellow,baseAlign:c.Top,quality:4,shadow:{offset:z(2,2).scale(tA),color:u.Black}}),s=new R({text:e.toFixed(0),font:i});this.graphics.add(s)}}class tF{constructor(t){this.scene=t}spawnDamageNumber(t,e){let i=new tB(t,e);i.actions.easeBy(z(0,-100),1e3,m.EaseOutCubic).die(),this.scene.add(i)}}class tU{constructor(t){this.scene=t}playExplosion(t){let e=new h({name:"explosion",pos:t.add(z(16,16).scale(tA))});ty.reset(),ty.strategy=d.End,ty.scale=tA;let i=ty.events.on("frame",t=>{7===t.frameIndex&&(e.kill(),i.close())});e.graphics.use(ty),this.scene.add(e)}}class tL extends h{constructor(t,e,i,s,r){super({name:i,anchor:z(0,0),z:2}),this.player=r,this.cell=null,this.moved=!1,this.attacked=!1,this.unitConfig={...tS[i]},this.health=this.unitConfig.health,this.anim=this.unitConfig.graphics.idle.clone(),this.anim.scale=tA,this.graphics.use(this.anim),this.graphics.onPostDraw=this.onPostDraw.bind(this);let n=s.getCell(t,e);n&&(this.pos=n.pos.sub(this.unitConfig.graphics.offset),n.addUnit(this))}onInitialize(t){this.damageManager=new tF(t.currentScene),this.animationManger=new tU(t.currentScene)}onPostUpdate(){this.hasActions()?this.anim.tint=u.White:this.anim.tint=u.Gray,this.health<=0&&(this.cell?.removeUnit(this),this.actions.delay(500).callMethod(()=>{this.animationManger.playExplosion(this.pos),tn.ExplosionSound.play()}).callMethod(()=>{this.kill()}))}onPostDraw(t){if(this.health>0){let e=tf.getSprite(F(this.health,0,5),0);e&&(e.scale=tA,e.draw(t,10*tA.x+this.unitConfig.graphics.offset.x,10*tA.y+this.unitConfig.graphics.offset.y))}}async move(t){this.cell&&this.cell.removeUnit(this);let e=null;for(let i of t.slice(1,t.length)){e=i.owner;let t=new a(this,t=>{t.delay(200),t.callMethod(()=>{tn.MoveSound.play()})}),s=new a(this,t=>{t.easeTo(e.pos.sub(this.unitConfig.graphics.offset),300,m.EaseInOutCubic),t.callMethod(()=>{tD.pos=this.pos.add(tA.scale(16)),tD.emitParticles(5)})}),r=new S([t,s]);await this.actions.runAction(r).toPromise()}e&&e.addUnit(this),this.moved=!0}reset(){this.moved=!1,this.attacked=!1}canAttack(){return this.getPossibleTargets()?.length!==0&&!this.attacked}canMove(){return!this.moved}hasActions(){return this.canMove()||this.canAttack()}availableActions(){let t=[];return this.canMove()&&t.push("move"),this.canAttack()&&t.push("attack"),t}pass(){this.moved=!0,this.attacked=!0}getPossibleTargets(){if(this.cell){let t=this.cell.board.pathFinder.getRange(this.cell.pathNode,~this.player.mask,this.unitConfig.range),e=t.map(t=>t.owner).filter(t=>!!t.unit?.player&&t.unit.player!==this.player);return e}}async attack(t){t.health-=this.unitConfig.attack,tn.HitSound.play(),this.damageManager.spawnDamageNumber(t.pos.add(t.unitConfig.graphics.offset).add(z(16*tA.x,0)),this.unitConfig.attack),await t.actions.blink(200,200,5).toPromise(),this.attacked=!0}}class tz{static #t=this._STARTING_BIT=1;static #e=this._CURRENT_GROUP=tz._STARTING_BIT;constructor(t,e){this.name=t,this.board=e,this.active=!1,this.mask=tz._CURRENT_GROUP=tz._CURRENT_GROUP<<1|0}async turnStart(){this.active=!0;let t=this.board.getUnits().filter(t=>t.player===this);t.forEach(t=>t.reset())}hasLost(){let t=this.board.getUnits().filter(t=>t.player===this);return 0===t.length}async turnEnd(){this.active=!1}}class tH extends tz{constructor(t,e,i,s,r){super(t,r),this.engine=e,this.selectionManager=i,this.uiManger=s,this.passed=!1,this.humanMove=new w,e.input.pointers.on("down",this.pointerClick.bind(this)),e.input.pointers.on("move",this.pointerMove.bind(this)),e.input.keyboard.on("press",this.keyboardDown.bind(this)),document.body.oncontextmenu=()=>!1}keyboardDown(t){if(!this.active)return;this.selectionManager.resetHighlight();let e=this.selectionManager.currentCursor;switch(t.key){case C.ArrowRight:case C.D:this.selectionManager.showCursor(e.x+1,e.y);break;case C.Left:case C.A:this.selectionManager.showCursor(e.x-1,e.y);break;case C.Up:case C.W:this.selectionManager.showCursor(e.x,e.y-1);break;case C.Down:case C.D:this.selectionManager.showCursor(e.x,e.y+1);break;case C.Enter:case C.NumpadEnter:let i=this.board.getCell(e.x,e.y);this.maybeSelectUnit(i)}}async pointerClick(t){if(!this.active)return;this.selectionManager.resetHighlight();let e=this.board.getCellByWorldPos(t.worldPos);if(t.button===E.Left){// a unit is currently selected if(this.selectionManager.currentUnitSelection){let t=this.selectionManager.currentUnitSelection;"move"===this.selectionManager.currentSelectionMode?await this.maybeMove(t,e):await this.maybeAttack(t,e),await this.maybeSelectUnit(t.cell);// no unit selected, make a selection -}else this.maybeSelectUnit(e)}t.button===P.Right&&this.highlightUnitRange(e)}pointerMove(t){if(!this.active)return;let e=this.board.getCellByWorldPos(t.worldPos);if(e&&this.selectionManager.showCursor(e.x,e.y),this.selectionManager.currentUnitSelection){// move +}else this.maybeSelectUnit(e)}t.button===E.Right&&this.highlightUnitRange(e)}pointerMove(t){if(!this.active)return;let e=this.board.getCellByWorldPos(t.worldPos);if(e&&this.selectionManager.showCursor(e.x,e.y),this.selectionManager.currentUnitSelection){// move if(this.selectionManager.resetHighlight(),"move"===this.selectionManager.currentSelectionMode){let e=this.selectionManager.findMovementRange(this.selectionManager.currentUnitSelection);this.selectionManager.showHighlight(e,"range");let i=this.board.getCellByWorldPos(t.worldPos);if(i){let t=this.selectionManager.findPath(i,e);this.selectionManager.showHighlight(t,"path")}// attack -}else{let e=this.selectionManager.findAttackRange(this.selectionManager.currentUnitSelection);this.selectionManager.showHighlight(e,"attack");let i=this.board.getCellByWorldPos(t.worldPos);i&&this.hasNonPlayerUnit(i)&&this.selectionManager.showHighlight([i.pathNode],"path")}}}async maybeMove(t,e){e&&t.canMove()?(this.active=!1,to.TargetSelectSound.play(),await this.selectionManager.selectDestinationAndMove(t,e),this.humanMove.resolve()):this.selectionManager.reset()}async maybeAttack(t,e){if(e&&t.canAttack()&&this.hasNonPlayerUnit(e)){this.active=!1;let i=e.unit;this.selectionManager.reset(),await t.attack(i),this.humanMove.resolve()}else this.selectionManager.reset()}/** +}else{let e=this.selectionManager.findAttackRange(this.selectionManager.currentUnitSelection);this.selectionManager.showHighlight(e,"attack");let i=this.board.getCellByWorldPos(t.worldPos);i&&this.hasNonPlayerUnit(i)&&this.selectionManager.showHighlight([i.pathNode],"path")}}}async maybeMove(t,e){e&&t.canMove()?(this.active=!1,tn.TargetSelectSound.play(),await this.selectionManager.selectDestinationAndMove(t,e),this.humanMove.resolve()):this.selectionManager.reset()}async maybeAttack(t,e){if(e&&t.canAttack()&&this.hasNonPlayerUnit(e)){this.active=!1;let i=e.unit;this.selectionManager.reset(),await t.attack(i),this.humanMove.resolve()}else this.selectionManager.reset()}/** * Highlight the range of any unit friendly or not * @param cell */async highlightUnitRange(t){if(t?.unit){let e=t.unit,i=this.board.pathFinder.getRange(t.pathNode,e.player.mask,e.unitConfig.movement+1);this.selectionManager.showHighlight(i,"attack");let s=this.board.pathFinder.getRange(t.pathNode,~e.player.mask,e.unitConfig.range);this.selectionManager.showHighlight(s,"attack");let r=this.selectionManager.findMovementRange(e);this.selectionManager.showHighlight(r,"range")}else this.selectionManager.reset()}async maybeSelectUnit(t){// check if the cell clicked has a unit, then select it -t?.unit&&this.hasPlayerUnitWithActions(t)?(to.SelectSound.play(),this.uiManger.showUnitMenu(t.unit,{move:()=>{this.selectionManager.selectUnit(t.unit,"move")},attack:()=>{this.selectionManager.selectUnit(t.unit,"attack")},pass:()=>{t.unit?.pass(),this.selectionManager.reset(),this.humanMove.resolve()}})):this.selectionManager.reset()}hasNonPlayerUnit(t){return t&&t.unit&&t.unit.player!==this}hasPlayerUnitWithActions(t){return t?.unit&&t?.unit?.hasActions()&&t.unit.player===this}async waitForHumanMove(){this.active=!0,await this.humanMove.promise,this.humanMove=new b}hasMoves(){let t=this.board.getUnits().filter(t=>t.player===this).filter(t=>t.hasActions());return t.length>0&&!this.passed}async makeMove(){for(;this.hasMoves();)await this.waitForHumanMove();return!0}lose(){this.active=!1;let t=this.board.getUnits().filter(t=>t.player instanceof tO);t.forEach(t=>{t.health=0,t.cell?.removeUnit(t)}),this.humanMove.resolve()}}class tN{constructor(t){this.board=t,this.currentPlayer=null,this.currentSelectionMode="move",this.currentUnitSelection=null,this.currentRange=[],this.currentPath=[],this.currentCursor={x:0,y:0}}reset(){this.resetHighlight(),this.currentUnitSelection=null,this.currentPath=[],this.currentRange=[]}showCursor(t,e){let i=this.board.getCell(t,e);i&&(this.board.cells.forEach(t=>t.toggleCursor(!1)),i.toggleCursor(!0),this.currentCursor={x:t,y:e})}selectPlayer(t){this.currentPlayer=t}selectUnit(t,e){t.player===this.currentPlayer&&(this.currentUnitSelection=t,this.currentSelectionMode=e,"move"===e?(this.currentRange=this.findMovementRange(this.currentUnitSelection),this.showHighlight(this.currentRange,"range")):(this.currentRange=this.findAttackRange(this.currentUnitSelection),this.showHighlight(this.currentRange,"attack")))}async selectDestinationAndMove(t,e){if(t.player!==this.currentPlayer)return;let i=this.findMovementRange(t);0===this.currentPath.length&&(this.currentPath=this.findPath(e,i)),this.currentPath.length>1&&await t.move(this.currentPath),this.reset()}findAttackRange(t){return this.currentUnitSelection&&t.cell?this.board.pathFinder.getRange(t.cell.pathNode,~t.player.mask,this.currentUnitSelection.unitConfig.range):[]}findMovementRange(t){return(// if (!this.currentUnitSelection) return []; -t.cell?this.board.pathFinder.getRange(t.cell.pathNode,t.player.mask,t.unitConfig.movement).filter(e=>e.isWalkable&&!!(e.walkableMask&t.player.mask)):[])}resetHighlight(){this.board.cells.forEach(t=>{t.toggleHighlight(!1,"range"),t.toggleHighlight(!1,"path"),t.toggleHighlight(!1,"attack")})}showHighlight(t,e){t.forEach(t=>{let i=t.owner;i.toggleHighlight(!0,e)})}findPath(t,e){if(!this.currentUnitSelection)return[];let i=this.currentUnitSelection.cell?.pathNode;if(t&&!t.unit&&e.includes(t.pathNode)){let s=this.board.pathFinder.findPath(i,t?.pathNode,this.currentUnitSelection.player.mask,e);return s}return[]}}function tW(t,e,i,s){var r,n=arguments.length,o=n<3?e:null===s?s=Object.getOwnPropertyDescriptor(e,i):s;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)o=Reflect.decorate(t,e,i,s);else for(var a=t.length-1;a>=0;a--)(r=t[a])&&(o=(n<3?r(o):n>3?r(e,i,o):r(e,i))||o);return n>3&&o&&Object.defineProperty(e,i,o),o}"function"==typeof SuppressedError&&SuppressedError;/** +t?.unit&&this.hasPlayerUnitWithActions(t)?(tn.SelectSound.play(),this.uiManger.showUnitMenu(t.unit,{move:()=>{this.selectionManager.selectUnit(t.unit,"move")},attack:()=>{this.selectionManager.selectUnit(t.unit,"attack")},pass:()=>{t.unit?.pass(),this.selectionManager.reset(),this.humanMove.resolve()}})):this.selectionManager.reset()}hasNonPlayerUnit(t){return t&&t.unit&&t.unit.player!==this}hasPlayerUnitWithActions(t){return t?.unit&&t?.unit?.hasActions()&&t.unit.player===this}async waitForHumanMove(){this.active=!0,await this.humanMove.promise,this.humanMove=new w}hasMoves(){let t=this.board.getUnits().filter(t=>t.player===this).filter(t=>t.hasActions());return t.length>0&&!this.passed}async makeMove(){for(;this.hasMoves();)await this.waitForHumanMove();return!0}lose(){this.active=!1;let t=this.board.getUnits().filter(t=>t.player instanceof tH);t.forEach(t=>{t.health=0,t.cell?.removeUnit(t)}),this.humanMove.resolve()}}class tO{constructor(t){this.board=t,this.currentPlayer=null,this.currentSelectionMode="move",this.currentUnitSelection=null,this.currentRange=[],this.currentPath=[],this.currentCursor={x:0,y:0}}reset(){this.resetHighlight(),this.currentUnitSelection=null,this.currentPath=[],this.currentRange=[]}showCursor(t,e){let i=this.board.getCell(t,e);i&&(this.board.cells.forEach(t=>t.toggleCursor(!1)),i.toggleCursor(!0),this.currentCursor={x:t,y:e})}selectPlayer(t){this.currentPlayer=t}selectUnit(t,e){t.player===this.currentPlayer&&(this.currentUnitSelection=t,this.currentSelectionMode=e,"move"===e?(this.currentRange=this.findMovementRange(this.currentUnitSelection),this.showHighlight(this.currentRange,"range")):(this.currentRange=this.findAttackRange(this.currentUnitSelection),this.showHighlight(this.currentRange,"attack")))}async selectDestinationAndMove(t,e){if(t.player!==this.currentPlayer)return;let i=this.findMovementRange(t);0===this.currentPath.length&&(this.currentPath=this.findPath(e,i)),this.currentPath.length>1&&await t.move(this.currentPath),this.reset()}findAttackRange(t){return this.currentUnitSelection&&t.cell?this.board.pathFinder.getRange(t.cell.pathNode,~t.player.mask,this.currentUnitSelection.unitConfig.range):[]}findMovementRange(t){return(// if (!this.currentUnitSelection) return []; +t.cell?this.board.pathFinder.getRange(t.cell.pathNode,t.player.mask,t.unitConfig.movement).filter(e=>e.isWalkable&&!!(e.walkableMask&t.player.mask)):[])}resetHighlight(){this.board.cells.forEach(t=>{t.toggleHighlight(!1,"range"),t.toggleHighlight(!1,"path"),t.toggleHighlight(!1,"attack")})}showHighlight(t,e){t.forEach(t=>{let i=t.owner;i.toggleHighlight(!0,e)})}findPath(t,e){if(!this.currentUnitSelection)return[];let i=this.currentUnitSelection.cell?.pathNode;if(t&&!t.unit&&e.includes(t.pathNode)){let s=this.board.pathFinder.findPath(i,t?.pathNode,this.currentUnitSelection.player.mask,e);return s}return[]}}function tN(t,e,i,s){var r,n=arguments.length,o=n<3?e:null===s?s=Object.getOwnPropertyDescriptor(e,i):s;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)o=Reflect.decorate(t,e,i,s);else for(var a=t.length-1;a>=0;a--)(r=t[a])&&(o=(n<3?r(o):n>3?r(e,i,o):r(e,i))||o);return n>3&&o&&Object.defineProperty(e,i,o),o}"function"==typeof SuppressedError&&SuppressedError;/** * @license * Copyright 2019 Google LLC * SPDX-License-Identifier: BSD-3-Clause - */const tG=globalThis,t$=tG.ShadowRoot&&(void 0===tG.ShadyCSS||tG.ShadyCSS.nativeShadow)&&"adoptedStyleSheets"in Document.prototype&&"replace"in CSSStyleSheet.prototype,tV=Symbol(),tq=new WeakMap;class tX{constructor(t,e,i){if(this._$cssResult$=!0,i!==tV)throw Error("CSSResult is not constructable. Use `unsafeCSS` or `css` instead.");this.cssText=t,this.t=e}get styleSheet(){let t=this.o,e=this.t;if(t$&&void 0===t){let i=void 0!==e&&1===e.length;i&&(t=tq.get(e)),void 0===t&&((this.o=t=new CSSStyleSheet).replaceSync(this.cssText),i&&tq.set(e,t))}return t}toString(){return this.cssText}}const tZ=t=>new tX("string"==typeof t?t:t+"",void 0,tV),tK=(t,...e)=>{let i=1===t.length?t[0]:e.reduce((e,i,s)=>e+(t=>{if(!0===t._$cssResult$)return t.cssText;if("number"==typeof t)return t;throw Error("Value passed to 'css' function must be a 'css' function result: "+t+". Use 'unsafeCSS' to pass non-literal values, but take care to ensure page security.")})(i)+t[s+1],t[0]);return new tX(i,t,tV)},tY=(t,e)=>{if(t$)t.adoptedStyleSheets=e.map(t=>t instanceof CSSStyleSheet?t:t.styleSheet);else for(let i of e){let e=document.createElement("style"),s=tG.litNonce;void 0!==s&&e.setAttribute("nonce",s),e.textContent=i.cssText,t.appendChild(e)}},tj=t$?t=>t:t=>t instanceof CSSStyleSheet?(t=>{let e="";for(let i of t.cssRules)e+=i.cssText;return tZ(e)})(t):t,{is:tQ,defineProperty:tJ,getOwnPropertyDescriptor:t0,getOwnPropertyNames:t1,getOwnPropertySymbols:t2,getPrototypeOf:t5}=Object,t3=globalThis,t4=t3.trustedTypes,t9=t4?t4.emptyScript:"",t6=t3.reactiveElementPolyfillSupport,t7=(t,e)=>t,t8={toAttribute(t,e){switch(e){case Boolean:t=t?t9:null;break;case Object:case Array:t=null==t?t:JSON.stringify(t)}return t},fromAttribute(t,e){let i=t;switch(e){case Boolean:i=null!==t;break;case Number:i=null===t?null:Number(t);break;case Object:case Array:try{i=JSON.parse(t)}catch(t){i=null}}return i}},et=(t,e)=>!tQ(t,e),ee={attribute:!0,type:String,converter:t8,reflect:!1,hasChanged:et};Symbol.metadata??=Symbol("metadata"),t3.litPropertyMetadata??=new WeakMap;class ei extends HTMLElement{static addInitializer(t){this._$Ei(),(this.l??=[]).push(t)}static get observedAttributes(){return this.finalize(),this._$Eh&&[...this._$Eh.keys()]}static createProperty(t,e=ee){if(e.state&&(e.attribute=!1),this._$Ei(),this.elementProperties.set(t,e),!e.noAccessor){let i=Symbol(),s=this.getPropertyDescriptor(t,i,e);void 0!==s&&tJ(this.prototype,t,s)}}static getPropertyDescriptor(t,e,i){let{get:s,set:r}=t0(this.prototype,t)??{get(){return this[e]},set(t){this[e]=t}};return{get(){return s?.call(this)},set(e){let n=s?.call(this);r.call(this,e),this.requestUpdate(t,n,i)},configurable:!0,enumerable:!0}}static getPropertyOptions(t){return this.elementProperties.get(t)??ee}static _$Ei(){if(this.hasOwnProperty(t7("elementProperties")))return;let t=t5(this);t.finalize(),void 0!==t.l&&(this.l=[...t.l]),this.elementProperties=new Map(t.elementProperties)}static finalize(){if(this.hasOwnProperty(t7("finalized")))return;if(this.finalized=!0,this._$Ei(),this.hasOwnProperty(t7("properties"))){let t=this.properties,e=[...t1(t),...t2(t)];for(let i of e)this.createProperty(i,t[i])}let t=this[Symbol.metadata];if(null!==t){let e=litPropertyMetadata.get(t);if(void 0!==e)for(let[t,i]of e)this.elementProperties.set(t,i)}for(let[t,e]of(this._$Eh=new Map,this.elementProperties)){let i=this._$Eu(t,e);void 0!==i&&this._$Eh.set(i,t)}this.elementStyles=this.finalizeStyles(this.styles)}static finalizeStyles(t){let e=[];if(Array.isArray(t)){let i=new Set(t.flat(1/0).reverse());for(let t of i)e.unshift(tj(t))}else void 0!==t&&e.push(tj(t));return e}static _$Eu(t,e){let i=e.attribute;return!1===i?void 0:"string"==typeof i?i:"string"==typeof t?t.toLowerCase():void 0}constructor(){super(),this._$Ep=void 0,this.isUpdatePending=!1,this.hasUpdated=!1,this._$Em=null,this._$Ev()}_$Ev(){this._$Eg=new Promise(t=>this.enableUpdating=t),this._$AL=new Map,this._$ES(),this.requestUpdate(),this.constructor.l?.forEach(t=>t(this))}addController(t){(this._$E_??=new Set).add(t),void 0!==this.renderRoot&&this.isConnected&&t.hostConnected?.()}removeController(t){this._$E_?.delete(t)}_$ES(){let t=new Map,e=this.constructor.elementProperties;for(let i of e.keys())this.hasOwnProperty(i)&&(t.set(i,this[i]),delete this[i]);t.size>0&&(this._$Ep=t)}createRenderRoot(){let t=this.shadowRoot??this.attachShadow(this.constructor.shadowRootOptions);return tY(t,this.constructor.elementStyles),t}connectedCallback(){this.renderRoot??=this.createRenderRoot(),this.enableUpdating(!0),this._$E_?.forEach(t=>t.hostConnected?.())}enableUpdating(t){}disconnectedCallback(){this._$E_?.forEach(t=>t.hostDisconnected?.())}attributeChangedCallback(t,e,i){this._$AK(t,i)}_$EO(t,e){let i=this.constructor.elementProperties.get(t),s=this.constructor._$Eu(t,i);if(void 0!==s&&!0===i.reflect){let r=(void 0!==i.converter?.toAttribute?i.converter:t8).toAttribute(e,i.type);this._$Em=t,null==r?this.removeAttribute(s):this.setAttribute(s,r),this._$Em=null}}_$AK(t,e){let i=this.constructor,s=i._$Eh.get(t);if(void 0!==s&&this._$Em!==s){let t=i.getPropertyOptions(s),r="function"==typeof t.converter?{fromAttribute:t.converter}:void 0!==t.converter?.fromAttribute?t.converter:t8;this._$Em=s,this[s]=r.fromAttribute(e,t.type),this._$Em=null}}requestUpdate(t,e,i,s=!1,r){if(void 0!==t){if(!((i??=this.constructor.getPropertyOptions(t)).hasChanged??et)(s?r:this[t],e))return;this.C(t,e,i)}!1===this.isUpdatePending&&(this._$Eg=this._$EP())}C(t,e,i){this._$AL.has(t)||this._$AL.set(t,e),!0===i.reflect&&this._$Em!==t&&(this._$Ej??=new Set).add(t)}async _$EP(){this.isUpdatePending=!0;try{await this._$Eg}catch(t){Promise.reject(t)}let t=this.scheduleUpdate();return null!=t&&await t,!this.isUpdatePending}scheduleUpdate(){return this.performUpdate()}performUpdate(){if(!this.isUpdatePending)return;if(!this.hasUpdated){if(this.renderRoot??=this.createRenderRoot(),this._$Ep){for(let[t,e]of this._$Ep)this[t]=e;this._$Ep=void 0}let t=this.constructor.elementProperties;if(t.size>0)for(let[e,i]of t)!0!==i.wrapped||this._$AL.has(e)||void 0===this[e]||this.C(e,this[e],i)}let t=!1,e=this._$AL;try{(t=this.shouldUpdate(e))?(this.willUpdate(e),this._$E_?.forEach(t=>t.hostUpdate?.()),this.update(e)):this._$ET()}catch(e){throw t=!1,this._$ET(),e}t&&this._$AE(e)}willUpdate(t){}_$AE(t){this._$E_?.forEach(t=>t.hostUpdated?.()),this.hasUpdated||(this.hasUpdated=!0,this.firstUpdated(t)),this.updated(t)}_$ET(){this._$AL=new Map,this.isUpdatePending=!1}get updateComplete(){return this.getUpdateComplete()}getUpdateComplete(){return this._$Eg}shouldUpdate(t){return!0}update(t){this._$Ej&&=this._$Ej.forEach(t=>this._$EO(t,this[t])),this._$ET()}updated(t){}firstUpdated(t){}}ei.elementStyles=[],ei.shadowRootOptions={mode:"open"},ei[t7("elementProperties")]=new Map,ei[t7("finalized")]=new Map,t6?.({ReactiveElement:ei}),(t3.reactiveElementVersions??=[]).push("2.0.2");/** + */const tW=globalThis,tG=tW.ShadowRoot&&(void 0===tW.ShadyCSS||tW.ShadyCSS.nativeShadow)&&"adoptedStyleSheets"in Document.prototype&&"replace"in CSSStyleSheet.prototype,t$=Symbol(),tV=new WeakMap;class tq{constructor(t,e,i){if(this._$cssResult$=!0,i!==t$)throw Error("CSSResult is not constructable. Use `unsafeCSS` or `css` instead.");this.cssText=t,this.t=e}get styleSheet(){let t=this.o,e=this.t;if(tG&&void 0===t){let i=void 0!==e&&1===e.length;i&&(t=tV.get(e)),void 0===t&&((this.o=t=new CSSStyleSheet).replaceSync(this.cssText),i&&tV.set(e,t))}return t}toString(){return this.cssText}}const tX=t=>new tq("string"==typeof t?t:t+"",void 0,t$),tZ=(t,...e)=>{let i=1===t.length?t[0]:e.reduce((e,i,s)=>e+(t=>{if(!0===t._$cssResult$)return t.cssText;if("number"==typeof t)return t;throw Error("Value passed to 'css' function must be a 'css' function result: "+t+". Use 'unsafeCSS' to pass non-literal values, but take care to ensure page security.")})(i)+t[s+1],t[0]);return new tq(i,t,t$)},tK=(t,e)=>{if(tG)t.adoptedStyleSheets=e.map(t=>t instanceof CSSStyleSheet?t:t.styleSheet);else for(let i of e){let e=document.createElement("style"),s=tW.litNonce;void 0!==s&&e.setAttribute("nonce",s),e.textContent=i.cssText,t.appendChild(e)}},tY=tG?t=>t:t=>t instanceof CSSStyleSheet?(t=>{let e="";for(let i of t.cssRules)e+=i.cssText;return tX(e)})(t):t,{is:tj,defineProperty:tQ,getOwnPropertyDescriptor:tJ,getOwnPropertyNames:t0,getOwnPropertySymbols:t1,getPrototypeOf:t2}=Object,t5=globalThis,t3=t5.trustedTypes,t4=t3?t3.emptyScript:"",t9=t5.reactiveElementPolyfillSupport,t6=(t,e)=>t,t7={toAttribute(t,e){switch(e){case Boolean:t=t?t4:null;break;case Object:case Array:t=null==t?t:JSON.stringify(t)}return t},fromAttribute(t,e){let i=t;switch(e){case Boolean:i=null!==t;break;case Number:i=null===t?null:Number(t);break;case Object:case Array:try{i=JSON.parse(t)}catch(t){i=null}}return i}},t8=(t,e)=>!tj(t,e),et={attribute:!0,type:String,converter:t7,reflect:!1,hasChanged:t8};Symbol.metadata??=Symbol("metadata"),t5.litPropertyMetadata??=new WeakMap;class ee extends HTMLElement{static addInitializer(t){this._$Ei(),(this.l??=[]).push(t)}static get observedAttributes(){return this.finalize(),this._$Eh&&[...this._$Eh.keys()]}static createProperty(t,e=et){if(e.state&&(e.attribute=!1),this._$Ei(),this.elementProperties.set(t,e),!e.noAccessor){let i=Symbol(),s=this.getPropertyDescriptor(t,i,e);void 0!==s&&tQ(this.prototype,t,s)}}static getPropertyDescriptor(t,e,i){let{get:s,set:r}=tJ(this.prototype,t)??{get(){return this[e]},set(t){this[e]=t}};return{get(){return s?.call(this)},set(e){let n=s?.call(this);r.call(this,e),this.requestUpdate(t,n,i)},configurable:!0,enumerable:!0}}static getPropertyOptions(t){return this.elementProperties.get(t)??et}static _$Ei(){if(this.hasOwnProperty(t6("elementProperties")))return;let t=t2(this);t.finalize(),void 0!==t.l&&(this.l=[...t.l]),this.elementProperties=new Map(t.elementProperties)}static finalize(){if(this.hasOwnProperty(t6("finalized")))return;if(this.finalized=!0,this._$Ei(),this.hasOwnProperty(t6("properties"))){let t=this.properties,e=[...t0(t),...t1(t)];for(let i of e)this.createProperty(i,t[i])}let t=this[Symbol.metadata];if(null!==t){let e=litPropertyMetadata.get(t);if(void 0!==e)for(let[t,i]of e)this.elementProperties.set(t,i)}for(let[t,e]of(this._$Eh=new Map,this.elementProperties)){let i=this._$Eu(t,e);void 0!==i&&this._$Eh.set(i,t)}this.elementStyles=this.finalizeStyles(this.styles)}static finalizeStyles(t){let e=[];if(Array.isArray(t)){let i=new Set(t.flat(1/0).reverse());for(let t of i)e.unshift(tY(t))}else void 0!==t&&e.push(tY(t));return e}static _$Eu(t,e){let i=e.attribute;return!1===i?void 0:"string"==typeof i?i:"string"==typeof t?t.toLowerCase():void 0}constructor(){super(),this._$Ep=void 0,this.isUpdatePending=!1,this.hasUpdated=!1,this._$Em=null,this._$Ev()}_$Ev(){this._$Eg=new Promise(t=>this.enableUpdating=t),this._$AL=new Map,this._$ES(),this.requestUpdate(),this.constructor.l?.forEach(t=>t(this))}addController(t){(this._$E_??=new Set).add(t),void 0!==this.renderRoot&&this.isConnected&&t.hostConnected?.()}removeController(t){this._$E_?.delete(t)}_$ES(){let t=new Map,e=this.constructor.elementProperties;for(let i of e.keys())this.hasOwnProperty(i)&&(t.set(i,this[i]),delete this[i]);t.size>0&&(this._$Ep=t)}createRenderRoot(){let t=this.shadowRoot??this.attachShadow(this.constructor.shadowRootOptions);return tK(t,this.constructor.elementStyles),t}connectedCallback(){this.renderRoot??=this.createRenderRoot(),this.enableUpdating(!0),this._$E_?.forEach(t=>t.hostConnected?.())}enableUpdating(t){}disconnectedCallback(){this._$E_?.forEach(t=>t.hostDisconnected?.())}attributeChangedCallback(t,e,i){this._$AK(t,i)}_$EO(t,e){let i=this.constructor.elementProperties.get(t),s=this.constructor._$Eu(t,i);if(void 0!==s&&!0===i.reflect){let r=(void 0!==i.converter?.toAttribute?i.converter:t7).toAttribute(e,i.type);this._$Em=t,null==r?this.removeAttribute(s):this.setAttribute(s,r),this._$Em=null}}_$AK(t,e){let i=this.constructor,s=i._$Eh.get(t);if(void 0!==s&&this._$Em!==s){let t=i.getPropertyOptions(s),r="function"==typeof t.converter?{fromAttribute:t.converter}:void 0!==t.converter?.fromAttribute?t.converter:t7;this._$Em=s,this[s]=r.fromAttribute(e,t.type),this._$Em=null}}requestUpdate(t,e,i,s=!1,r){if(void 0!==t){if(!((i??=this.constructor.getPropertyOptions(t)).hasChanged??t8)(s?r:this[t],e))return;this.C(t,e,i)}!1===this.isUpdatePending&&(this._$Eg=this._$EP())}C(t,e,i){this._$AL.has(t)||this._$AL.set(t,e),!0===i.reflect&&this._$Em!==t&&(this._$Ej??=new Set).add(t)}async _$EP(){this.isUpdatePending=!0;try{await this._$Eg}catch(t){Promise.reject(t)}let t=this.scheduleUpdate();return null!=t&&await t,!this.isUpdatePending}scheduleUpdate(){return this.performUpdate()}performUpdate(){if(!this.isUpdatePending)return;if(!this.hasUpdated){if(this.renderRoot??=this.createRenderRoot(),this._$Ep){for(let[t,e]of this._$Ep)this[t]=e;this._$Ep=void 0}let t=this.constructor.elementProperties;if(t.size>0)for(let[e,i]of t)!0!==i.wrapped||this._$AL.has(e)||void 0===this[e]||this.C(e,this[e],i)}let t=!1,e=this._$AL;try{(t=this.shouldUpdate(e))?(this.willUpdate(e),this._$E_?.forEach(t=>t.hostUpdate?.()),this.update(e)):this._$ET()}catch(e){throw t=!1,this._$ET(),e}t&&this._$AE(e)}willUpdate(t){}_$AE(t){this._$E_?.forEach(t=>t.hostUpdated?.()),this.hasUpdated||(this.hasUpdated=!0,this.firstUpdated(t)),this.updated(t)}_$ET(){this._$AL=new Map,this.isUpdatePending=!1}get updateComplete(){return this.getUpdateComplete()}getUpdateComplete(){return this._$Eg}shouldUpdate(t){return!0}update(t){this._$Ej&&=this._$Ej.forEach(t=>this._$EO(t,this[t])),this._$ET()}updated(t){}firstUpdated(t){}}ee.elementStyles=[],ee.shadowRootOptions={mode:"open"},ee[t6("elementProperties")]=new Map,ee[t6("finalized")]=new Map,t9?.({ReactiveElement:ee}),(t5.reactiveElementVersions??=[]).push("2.0.2");/** * @license * Copyright 2017 Google LLC * SPDX-License-Identifier: BSD-3-Clause - */const es=globalThis,er=es.trustedTypes,en=er?er.createPolicy("lit-html",{createHTML:t=>t}):void 0,eo="$lit$",ea=`lit$${(Math.random()+"").slice(9)}$`,eh="?"+ea,el=`<${eh}>`,ed=document,ec=()=>ed.createComment(""),eu=t=>null===t||"object"!=typeof t&&"function"!=typeof t,ep=Array.isArray,eg=t=>ep(t)||"function"==typeof t?.[Symbol.iterator],e_="[ \n\f\r]",em=/<(?:(!--|\/[^a-zA-Z])|(\/?[a-zA-Z][^>\s]*)|(\/?$))/g,ef=/-->/g,ev=/>/g,ey=RegExp(`>|${e_}(?:([^\\s"'>=/]+)(${e_}*=${e_}*(?:[^ -\f\r"'\`<>=]|("|')|))|$)`,"g"),ex=/'/g,ew=/"/g,eb=/^(?:script|style|textarea|title)$/i,eC=t=>(e,...i)=>({_$litType$:t,strings:e,values:i}),eA=eC(1),eS=(eC(2),Symbol.for("lit-noChange")),eT=Symbol.for("lit-nothing"),eE=new WeakMap,eP=ed.createTreeWalker(ed,129);function eM(t,e){if(!Array.isArray(t)||!t.hasOwnProperty("raw"))throw Error("invalid template strings array");return void 0!==en?en.createHTML(e):e}const eI=(t,e)=>{let i=t.length-1,s=[],r,n=2===e?"":"",o=em;for(let e=0;e"===h[0]?(o=r??em,l=-1):void 0===h[1]?l=-2:(l=o.lastIndex-h[2].length,a=h[1],o=void 0===h[3]?ey:'"'===h[3]?ew:ex):o===ew||o===ex?o=ey:o===ef||o===ev?o=em:(o=ey,r=void 0);let c=o===ey&&t[e+1].startsWith("/>")?" ":"";n+=o===em?i+el:l>=0?(s.push(a),i.slice(0,l)+eo+i.slice(l)+ea+c):i+ea+(-2===l?e:c)}return[eM(t,n+(t[i]||"")+(2===e?"":"")),s]};class ek{constructor({strings:t,_$litType$:e},i){let s;this.parts=[];let r=0,n=0,o=t.length-1,a=this.parts,[h,l]=eI(t,e);if(this.el=ek.createElement(h,i),eP.currentNode=this.el.content,2===e){let t=this.el.content.firstChild;t.replaceWith(...t.childNodes)}for(;null!==(s=eP.nextNode())&&a.length0){s.textContent=er?er.emptyScript:"";for(let i=0;i2||""!==i[0]||""!==i[1]?(this._$AH=Array(i.length-1).fill(new String),this.strings=i):this._$AH=eT}_$AI(t,e=this,i,s){let r=this.strings,n=!1;if(void 0===r)(n=!eu(t=eR(this,t,e,0))||t!==this._$AH&&t!==eS)&&(this._$AH=t);else{let s,o;let a=t;for(t=r[0],s=0;s{let s=i?.renderBefore??e,r=s._$litPart$;if(void 0===r){let t=i?.renderBefore??null;s._$litPart$=r=new eB(e.insertBefore(ec(),t),t,void 0,i??{})}return r._$AI(t),r};/** + */const ei=globalThis,es=ei.trustedTypes,er=es?es.createPolicy("lit-html",{createHTML:t=>t}):void 0,en="$lit$",eo=`lit$${(Math.random()+"").slice(9)}$`,ea="?"+eo,eh=`<${ea}>`,el=document,ed=()=>el.createComment(""),ec=t=>null===t||"object"!=typeof t&&"function"!=typeof t,eu=Array.isArray,ep=t=>eu(t)||"function"==typeof t?.[Symbol.iterator],eg="[ \n\f\r]",e_=/<(?:(!--|\/[^a-zA-Z])|(\/?[a-zA-Z][^>\s]*)|(\/?$))/g,em=/-->/g,ef=/>/g,ev=RegExp(`>|${eg}(?:([^\\s"'>=/]+)(${eg}*=${eg}*(?:[^ +\f\r"'\`<>=]|("|')|))|$)`,"g"),ey=/'/g,ex=/"/g,ew=/^(?:script|style|textarea|title)$/i,eb=t=>(e,...i)=>({_$litType$:t,strings:e,values:i}),eC=eb(1),eA=(eb(2),Symbol.for("lit-noChange")),eS=Symbol.for("lit-nothing"),eT=new WeakMap,eE=el.createTreeWalker(el,129);function eP(t,e){if(!Array.isArray(t)||!t.hasOwnProperty("raw"))throw Error("invalid template strings array");return void 0!==er?er.createHTML(e):e}const eM=(t,e)=>{let i=t.length-1,s=[],r,n=2===e?"":"",o=e_;for(let e=0;e"===h[0]?(o=r??e_,l=-1):void 0===h[1]?l=-2:(l=o.lastIndex-h[2].length,a=h[1],o=void 0===h[3]?ev:'"'===h[3]?ex:ey):o===ex||o===ey?o=ev:o===em||o===ef?o=e_:(o=ev,r=void 0);let c=o===ev&&t[e+1].startsWith("/>")?" ":"";n+=o===e_?i+eh:l>=0?(s.push(a),i.slice(0,l)+en+i.slice(l)+eo+c):i+eo+(-2===l?e:c)}return[eP(t,n+(t[i]||"")+(2===e?"":"")),s]};class eI{constructor({strings:t,_$litType$:e},i){let s;this.parts=[];let r=0,n=0,o=t.length-1,a=this.parts,[h,l]=eM(t,e);if(this.el=eI.createElement(h,i),eE.currentNode=this.el.content,2===e){let t=this.el.content.firstChild;t.replaceWith(...t.childNodes)}for(;null!==(s=eE.nextNode())&&a.length0){s.textContent=es?es.emptyScript:"";for(let i=0;i2||""!==i[0]||""!==i[1]?(this._$AH=Array(i.length-1).fill(new String),this.strings=i):this._$AH=eS}_$AI(t,e=this,i,s){let r=this.strings,n=!1;if(void 0===r)(n=!ec(t=ek(this,t,e,0))||t!==this._$AH&&t!==eA)&&(this._$AH=t);else{let s,o;let a=t;for(t=r[0],s=0;s{let s=i?.renderBefore??e,r=s._$litPart$;if(void 0===r){let t=i?.renderBefore??null;s._$litPart$=r=new eD(e.insertBefore(ed(),t),t,void 0,i??{})}return r._$AI(t),r};/** * @license * Copyright 2017 Google LLC * SPDX-License-Identifier: BSD-3-Clause - */class eW extends ei{constructor(){super(...arguments),this.renderOptions={host:this},this._$Do=void 0}createRenderRoot(){let t=super.createRenderRoot();return this.renderOptions.renderBefore??=t.firstChild,t}update(t){let e=this.render();this.hasUpdated||(this.renderOptions.isConnected=this.isConnected),super.update(t),this._$Do=eN(e,this.renderRoot,this.renderOptions)}connectedCallback(){super.connectedCallback(),this._$Do?.setConnected(!0)}disconnectedCallback(){super.disconnectedCallback(),this._$Do?.setConnected(!1)}render(){return eS}}eW._$litElement$=!0,eW.finalized=!0,globalThis.litElementHydrateSupport?.({LitElement:eW});const eG=globalThis.litElementPolyfillSupport;eG?.({LitElement:eW}),(globalThis.litElementVersions??=[]).push("4.0.2");/** + */class eN extends ee{constructor(){super(...arguments),this.renderOptions={host:this},this._$Do=void 0}createRenderRoot(){let t=super.createRenderRoot();return this.renderOptions.renderBefore??=t.firstChild,t}update(t){let e=this.render();this.hasUpdated||(this.renderOptions.isConnected=this.isConnected),super.update(t),this._$Do=eO(e,this.renderRoot,this.renderOptions)}connectedCallback(){super.connectedCallback(),this._$Do?.setConnected(!0)}disconnectedCallback(){super.disconnectedCallback(),this._$Do?.setConnected(!1)}render(){return eA}}eN._$litElement$=!0,eN.finalized=!0,globalThis.litElementHydrateSupport?.({LitElement:eN});const eW=globalThis.litElementPolyfillSupport;eW?.({LitElement:eN}),(globalThis.litElementVersions??=[]).push("4.0.2");/** * @license * Copyright 2017 Google LLC * SPDX-License-Identifier: BSD-3-Clause - */const e$={attribute:!0,type:String,converter:t8,reflect:!1,hasChanged:et},eV=(t=e$,e,i)=>{let{kind:s,metadata:r}=i,n=globalThis.litPropertyMetadata.get(r);if(void 0===n&&globalThis.litPropertyMetadata.set(r,n=new Map),n.set(i.name,t),"accessor"===s){let{name:s}=i;return{set(i){let r=e.get.call(this);e.set.call(this,i),this.requestUpdate(s,r,t)},init(e){return void 0!==e&&this.C(s,void 0,t),e}}}if("setter"===s){let{name:s}=i;return function(i){let r=this[s];e.call(this,i),this.requestUpdate(s,r,t)}}throw Error("Unsupported decorator location: "+s)};function eq(t){return(e,i)=>"object"==typeof i?eV(t,e,i):((t,e,i)=>{let s=e.hasOwnProperty(i);return e.constructor.createProperty(i,s?{...t,wrapped:!0}:t),s?Object.getOwnPropertyDescriptor(e,i):void 0})(t,e,i)}/** + */const eG=t=>(e,i)=>{void 0!==i?i.addInitializer(()=>{customElements.define(t,e)}):customElements.define(t,e)},e$={attribute:!0,type:String,converter:t7,reflect:!1,hasChanged:t8},eV=(t=e$,e,i)=>{let{kind:s,metadata:r}=i,n=globalThis.litPropertyMetadata.get(r);if(void 0===n&&globalThis.litPropertyMetadata.set(r,n=new Map),n.set(i.name,t),"accessor"===s){let{name:s}=i;return{set(i){let r=e.get.call(this);e.set.call(this,i),this.requestUpdate(s,r,t)},init(e){return void 0!==e&&this.C(s,void 0,t),e}}}if("setter"===s){let{name:s}=i;return function(i){let r=this[s];e.call(this,i),this.requestUpdate(s,r,t)}}throw Error("Unsupported decorator location: "+s)};function eq(t){return(e,i)=>"object"==typeof i?eV(t,e,i):((t,e,i)=>{let s=e.hasOwnProperty(i);return e.constructor.createProperty(i,s?{...t,wrapped:!0}:t),s?Object.getOwnPropertyDescriptor(e,i):void 0})(t,e,i)}/** * @license * Copyright 2017 Google LLC * SPDX-License-Identifier: BSD-3-Clause @@ -5576,7 +5576,7 @@ t.cell?this.board.pathFinder.getRange(t.cell.pathNode,t.player.mask,t.unitConfig * @license * Copyright 2018 Google LLC * SPDX-License-Identifier: BSD-3-Clause - */const ej="important",eQ=" !"+ej,eJ=eK(class extends eY{constructor(t){if(super(t),t.type!==eZ.ATTRIBUTE||"style"!==t.name||t.strings?.length>2)throw Error("The `styleMap` directive must be used in the `style` attribute and must be the only part in the attribute.")}render(t){return Object.keys(t).reduce((e,i)=>{let s=t[i];return null==s?e:e+`${i=i.includes("-")?i:i.replace(/(?:^(webkit|moz|ms|o)|)(?=[A-Z])/g,"-$&").toLowerCase()}:${s};`},"")}update(t,[e]){let{style:i}=t.element;if(void 0===this.ut)return this.ut=new Set(Object.keys(e)),this.render(e);for(let t of this.ut)null==e[t]&&(this.ut.delete(t),t.includes("-")?i.removeProperty(t):i[t]=null);for(let t in e){let s=e[t];if(null!=s){this.ut.add(t);let e="string"==typeof s&&s.endsWith(eQ);t.includes("-")||e?i.setProperty(t,e?s.slice(0,-11):s,e?ej:""):i[t]=s}}return eS}}),e0=eK(class extends eY{constructor(t){if(super(t),t.type!==eZ.ATTRIBUTE||"class"!==t.name||t.strings?.length>2)throw Error("`classMap()` can only be used in the `class` attribute and must be the only part in the attribute.")}render(t){return" "+Object.keys(t).filter(e=>t[e]).join(" ")+" "}update(t,[e]){if(void 0===this.it){for(let i in this.it=new Set,void 0!==t.strings&&(this.st=new Set(t.strings.join(" ").split(/\s/).filter(t=>""!==t))),e)e[i]&&!this.st?.has(i)&&this.it.add(i);return this.render(e)}let i=t.element.classList;for(let t of this.it)t in e||(i.remove(t),this.it.delete(t));for(let t in e){let s=!!e[t];s===this.it.has(t)||this.st?.has(t)||(s?(i.add(t),this.it.add(t)):(i.remove(t),this.it.delete(t)))}return eS}});let e1=class extends eW{static #t=this.styles=tK` + */const ej="important",eQ=" !"+ej,eJ=eK(class extends eY{constructor(t){if(super(t),t.type!==eZ.ATTRIBUTE||"style"!==t.name||t.strings?.length>2)throw Error("The `styleMap` directive must be used in the `style` attribute and must be the only part in the attribute.")}render(t){return Object.keys(t).reduce((e,i)=>{let s=t[i];return null==s?e:e+`${i=i.includes("-")?i:i.replace(/(?:^(webkit|moz|ms|o)|)(?=[A-Z])/g,"-$&").toLowerCase()}:${s};`},"")}update(t,[e]){let{style:i}=t.element;if(void 0===this.ut)return this.ut=new Set(Object.keys(e)),this.render(e);for(let t of this.ut)null==e[t]&&(this.ut.delete(t),t.includes("-")?i.removeProperty(t):i[t]=null);for(let t in e){let s=e[t];if(null!=s){this.ut.add(t);let e="string"==typeof s&&s.endsWith(eQ);t.includes("-")||e?i.setProperty(t,e?s.slice(0,-11):s,e?ej:""):i[t]=s}}return eA}}),e0=eK(class extends eY{constructor(t){if(super(t),t.type!==eZ.ATTRIBUTE||"class"!==t.name||t.strings?.length>2)throw Error("`classMap()` can only be used in the `class` attribute and must be the only part in the attribute.")}render(t){return" "+Object.keys(t).filter(e=>t[e]).join(" ")+" "}update(t,[e]){if(void 0===this.it){for(let i in this.it=new Set,void 0!==t.strings&&(this.st=new Set(t.strings.join(" ").split(/\s/).filter(t=>""!==t))),e)e[i]&&!this.st?.has(i)&&this.it.add(i);return this.render(e)}let i=t.element.classList;for(let t of this.it)t in e||(i.remove(t),this.it.delete(t));for(let t in e){let s=!!e[t];s===this.it.has(t)||this.st?.has(t)||(s?(i.add(t),this.it.add(t)):(i.remove(t),this.it.delete(t)))}return eA}});let e1=class extends eN{static #t=this.styles=tZ` @keyframes fadeIn { from { opacity: 0; @@ -5657,7 +5657,7 @@ t.cell?this.board.pathFinder.getRange(t.cell.pathNode,t.player.mask,t.unitConfig button:active, .active { background-color: rgba(250, 240, 240, 1); } - `;firstUpdated(){this.menuHtml?.addEventListener("animationend",t=>{"fadeOut"===t.animationName&&(this._show=!1,this.menuHtml?.classList.remove("hide"),this.requestUpdate())})}sendEvent(t){return()=>{this.dispatchEvent(new Event(t)),this.hide(),this.requestUpdate()}}show(){this._show=!0,this._debounce=Date.now()}hide(){let t=Date.now();t-this._debounce>200&&(this.menuHtml?.classList.add("hide"),this.clearEvents())}render(){let t=this._show?eA`
`:eT;return eA` + `;firstUpdated(){this.menuHtml?.addEventListener("animationend",t=>{"fadeOut"===t.animationName&&(this._show=!1,this.menuHtml?.classList.remove("hide"),this.requestUpdate())})}sendEvent(t){return()=>{this.dispatchEvent(new Event(t)),this.hide(),this.requestUpdate()}}show(){this._show=!0,this._debounce=Date.now()}hide(){let t=Date.now();t-this._debounce>200&&(this.menuHtml?.classList.add("hide"),this.clearEvents())}render(){let t=this._show?eC`
`:eS;return eC` ${t}
@@ -5669,21 +5669,50 @@ t.cell?this.board.pathFinder.getRange(t.cell.pathNode,t.player.mask,t.unitConfig
`}constructor(...t){super(...t),this.left=0,this.top=0,this.fontSize=0,this.width=0,this.unit=null,this.pixelConversion=1,this._show=!1,this.clearEvents=()=>{},// Debounce needed for mobile for some reason // Overlay is also receiving the event -this._debounce=0}};tW([eq({type:Number})],e1.prototype,"left",void 0),tW([eq({type:Number})],e1.prototype,"top",void 0),tW([eq({type:Number})],e1.prototype,"fontSize",void 0),tW([eq({type:Number})],e1.prototype,"width",void 0),tW([eq({attribute:!1})],e1.prototype,"unit",void 0),tW([eq({type:Number})],e1.prototype,"pixelConversion",void 0),tW([eq({state:!0,attribute:!1})],e1.prototype,"_show",void 0),tW([(t,e,i)=>{let s=t=>t.renderRoot?.querySelector(".menu")??null;return eX(t,e,{get(){return s(this)}})}],e1.prototype,"menuHtml",void 0),e1=tW([(i="unit-menu",(t,e)=>{void 0!==e?e.addInitializer(()=>{customElements.define(i,t)}):customElements.define(i,t)})],e1);class e2{constructor(t){this.engine=t,this.uiToWorldPos=new Map,this.unitMenu=new e1,document.body.appendChild(this.unitMenu),document.documentElement.style.setProperty("--pixel-conversion",this.worldDistanceToPage(1).toString()),window.addEventListener("resize",()=>{document.documentElement.style.setProperty("--pixel-conversion",this.worldDistanceToPage(1).toString());let t=this.uiToWorldPos.get(this.unitMenu);if(t){let e=this.engine.screen.worldToPageCoordinates(t);this.unitMenu.left=e.x+this.worldDistanceToPage(32),this.unitMenu.top=e.y}})}worldDistanceToPage(t){let e=this.engine.screen.worldToPageCoordinates(F.Zero),i=this.engine.screen.worldToPageCoordinates(H(t*tS.x,0)).sub(e);return i.x}showUnitMenu(t,e){let i=this.unitMenu,s=this.engine.screen.worldToPageCoordinates(t.pos);i.left=s.x+this.worldDistanceToPage(32),i.top=s.y,i.unit=t;let r=()=>{e.move(),a()},n=()=>{e.attack(),a()},o=()=>{e.pass(),a()};i.addEventListener("move",r),i.addEventListener("attack",n),i.addEventListener("pass",o);let a=()=>{i.removeEventListener("move",r),i.removeEventListener("attack",n),i.removeEventListener("pass",o)};return i.clearEvents=a,i.show(),i.focus(),this.uiToWorldPos.set(i,t.pos),i}showNextMission(t){}}class e5 extends tH{constructor(t,e,i){super(t,i),this.selectionManger=e,this.active=!1}async turnStart(){this.active=!0}async turnEnd(){this.active=!1}findClosestEnemy(t){let e=this.board.getUnits().filter(t=>t.player!==this).map(t=>t.cell).filter(t=>!!t),i=this.findClosestCell(t,e);return i?.unit?i.unit:null}findValidMoveCells(t){// pick a random valid move -let e=[];return t.cell&&(e=this.board.pathFinder.getRange(t.cell.pathNode,this.mask,t.unitConfig.movement).filter(t=>{let e=t.owner;return e.unit?.player!==this})),e.map(t=>t.owner)}findClosestCell(t,e){let i=e[0];if(i){let s=1/0;for(let r of e){let e=r.pos.squareDistance(t.cell?.pos??H(0,0));e{if(t.owner){let e=t.owner;if(e.unit)return e.unit.player!==this}return!1}).map(t=>t.owner)}async maybeAttack(t,e){let i=!1,s=this.findAttackableTargets(t);if(s.length>0){let r=s.map(t=>t.pathNode);this.selectionManger.showHighlight(r,"attack"),await B.delay(200),this.selectionManger.showHighlight([e.cell.pathNode],"path"),await B.delay(200),// attack +this._debounce=0}};tN([eq({type:Number})],e1.prototype,"left",void 0),tN([eq({type:Number})],e1.prototype,"top",void 0),tN([eq({type:Number})],e1.prototype,"fontSize",void 0),tN([eq({type:Number})],e1.prototype,"width",void 0),tN([eq({attribute:!1})],e1.prototype,"unit",void 0),tN([eq({type:Number})],e1.prototype,"pixelConversion",void 0),tN([eq({state:!0,attribute:!1})],e1.prototype,"_show",void 0),tN([(t,e,i)=>{let s=t=>t.renderRoot?.querySelector(".menu")??null;return eX(t,e,{get(){return s(this)}})}],e1.prototype,"menuHtml",void 0),e1=tN([eG("unit-menu")],e1);class e2{constructor(t){this.engine=t,this.uiToWorldPos=new Map,this.unitMenu=new e1,document.body.appendChild(this.unitMenu),document.documentElement.style.setProperty("--pixel-conversion",this.worldDistanceToPage(1).toString()),window.addEventListener("resize",()=>{document.documentElement.style.setProperty("--pixel-conversion",this.worldDistanceToPage(1).toString());let t=this.uiToWorldPos.get(this.unitMenu);if(t){let e=this.engine.screen.worldToPageCoordinates(t);this.unitMenu.left=e.x+this.worldDistanceToPage(32),this.unitMenu.top=e.y}})}worldDistanceToPage(t){let e=this.engine.screen.worldToPageCoordinates(B.Zero),i=this.engine.screen.worldToPageCoordinates(z(t*tA.x,0)).sub(e);return i.x}showUnitMenu(t,e){let i=this.unitMenu,s=this.engine.screen.worldToPageCoordinates(t.pos);i.left=s.x+this.worldDistanceToPage(32),i.top=s.y,i.unit=t;let r=()=>{e.move(),a()},n=()=>{e.attack(),a()},o=()=>{e.pass(),a()};i.addEventListener("move",r),i.addEventListener("attack",n),i.addEventListener("pass",o);let a=()=>{i.removeEventListener("move",r),i.removeEventListener("attack",n),i.removeEventListener("pass",o)};return i.clearEvents=a,i.show(),i.focus(),this.uiToWorldPos.set(i,t.pos),i}showNextMission(t){}}class e5 extends tz{constructor(t,e,i){super(t,i),this.selectionManger=e,this.active=!1}async turnStart(){this.active=!0}async turnEnd(){this.active=!1}findClosestEnemy(t){let e=this.board.getUnits().filter(t=>t.player!==this).map(t=>t.cell).filter(t=>!!t),i=this.findClosestCell(t,e);return i?.unit?i.unit:null}findValidMoveCells(t){// pick a random valid move +let e=[];return t.cell&&(e=this.board.pathFinder.getRange(t.cell.pathNode,this.mask,t.unitConfig.movement).filter(t=>{let e=t.owner;return e.unit?.player!==this})),e.map(t=>t.owner)}findClosestCell(t,e){let i=e[0];if(i){let s=1/0;for(let r of e){let e=r.pos.squareDistance(t.cell?.pos??z(0,0));e{if(t.owner){let e=t.owner;if(e.unit)return e.unit.player!==this}return!1}).map(t=>t.owner)}async maybeAttack(t,e){let i=!1,s=this.findAttackableTargets(t);if(s.length>0){let r=s.map(t=>t.pathNode);this.selectionManger.showHighlight(r,"attack"),await D.delay(200),this.selectionManger.showHighlight([e.cell.pathNode],"path"),await D.delay(200),// attack await t.attack(e),i=!0}return i}async makeMove(){this.board.getUnits().filter(t=>t.player!==this);let t=this.board.getUnits().filter(t=>t.player===this);for(let e of t){// wait before moving each unit -await B.delay(200);let t=[];e.cell&&(t=this.board.pathFinder.getRange(e.cell.pathNode,this.mask,e.unitConfig.movement));// find valid moves +await D.delay(200);let t=[];e.cell&&(t=this.board.pathFinder.getRange(e.cell.pathNode,this.mask,e.unitConfig.movement));// find valid moves let i=this.findValidMoveCells(e),s=this.findClosestEnemy(e);if(s){// attack if right next to enemy let r=await this.maybeAttack(e,s),n=this.findClosestCell(s,i);// move if did not attack -if(!r){this.selectionManger.selectUnit(e,"move"),await B.delay(200);let i=this.selectionManger.findPath(n,t);this.selectionManger.showHighlight(i,"path"),await B.delay(200),await this.selectionManger.selectDestinationAndMove(e,n),await B.delay(200),// try again to attack -await this.maybeAttack(e,s)}this.selectionManger.reset()}}return!0}lose(){this.active=!1;let t=this.board.getUnits().filter(t=>t.player instanceof e5);t.forEach(t=>{t.health=0,t.cell?.removeUnit(t)})}}class e3{constructor(t,e,i,s,r){if(this.engine=t,this.level=e,this.players=i,this.maxTurns=r,this.currentTurn=1,this.currentPlayerIndex=0,this.topScreen=H(400,-2e3),this.centerScreen=H(400,400),this.bottomScreen=H(400,2e3),0===i.length)throw Error("Players should be non-zero in length");this.currentPlayer=i[this.currentPlayerIndex],this.selectionManager=s,this.turnText=new D({text:`Turn ${this.currentTurn}`,font:new x({family:"notjamslab14",size:32*tS.x,unit:w.Px,color:p.White,baseAlign:u.Top,quality:4})});let n=t.screen.resolution.width;this.turnActor=new l({name:"turn text",pos:this.topScreen,coordPlane:_.Screen,color:new p(240,50,50,.4),width:n,height:100,z:10}),this.turnActor.graphics.opacity=0,this.turnActor.graphics.add("text",this.turnText),this.turnActor.graphics.show("text"),t.add(this.turnActor);let o=new D({text:"Victory!",font:new x({family:"notjamslab14",size:32*tS.x,unit:w.Px,color:p.White,baseAlign:u.Top,quality:4})});this.victory=new l({name:"victory text",pos:this.topScreen,coordPlane:_.Screen,color:new p(50,240,50,.4),width:n,height:100,z:10}),this.victory.graphics.opacity=0,this.victory.graphics.add("text",o),this.victory.graphics.show("text"),t.add(this.victory);let a=new D({text:"Failure!",font:new x({family:"notjamslab14",size:32*tS.x,unit:w.Px,color:p.White,baseAlign:u.Top,quality:4})}),h=new D({text:"Click to try again!",font:new x({family:"notjamslab14",size:32*tS.x,unit:w.Px,color:p.White,baseAlign:u.Top,quality:4})});this.failure=new l({name:"failure text",pos:this.topScreen,coordPlane:_.Screen,color:new p(240,50,50,.4),width:n,height:250,z:10}),this.failure.graphics.opacity=0,this.failure.graphics.add("text1",a),this.failure.graphics.add("text2",h),this.failure.graphics.show("text1",{offset:H(0,-50)}),this.failure.graphics.show("text2",{offset:H(0,50)}),t.add(this.failure)}async showTurnDisplay(){0===this.currentPlayerIndex&&(this.turnText.text=`Turn ${this.currentTurn}`,await this.turnActor.actions.runAction(new T([new h(this.turnActor,t=>t.easeTo(this.centerScreen,1200,f.EaseInOutCubic).delay(700).easeTo(this.bottomScreen,1200,f.EaseInOutCubic)),new h(this.turnActor,t=>t.fade(1,1200).delay(700).fade(0,1200))])).toPromise(),this.turnActor.pos=this.topScreen)}async showGameOver(){await this.failure.actions.runAction(new T([new h(this.failure,t=>t.easeTo(this.centerScreen,1200,f.EaseInOutCubic)),new h(this.failure,t=>t.fade(1,1200))])).toPromise()}async showVictory(){await this.victory.actions.runAction(new T([new h(this.victory,t=>t.easeTo(this.centerScreen,1200,f.EaseInOutCubic)),new h(this.victory,t=>t.fade(1,1200))])).toPromise()}async start(){// TODO win condition -for(;this.maxTurns>0;){if(console.log("Current player turn:",this.currentPlayer.name),this.currentPlayer.hasLost()){if(console.log("Player lost!",this.currentPlayer.name),this.currentPlayer instanceof tO){await this.showGameOver(),this.engine.input.pointers.once("down",()=>{to.LevelMusic2.stop(),this.engine.goToScene(this.level.levelData.name)});return}if(this.currentPlayer instanceof e5){await this.showVictory(),this.engine.input.pointers.once("down",()=>{this.engine.goToScene(this.level.levelData.nextLevel)});return}}this.selectionManager.selectPlayer(this.currentPlayer),this.showTurnDisplay(),await this.currentPlayer.turnStart();let t=!0;do t=await this.currentPlayer.makeMove();while(!t)await this.currentPlayer.turnEnd(),this.nextTurn(),this.maxTurns--}}nextTurn(){this.currentPlayerIndex++,this.currentPlayerIndex=this.currentPlayerIndex%this.players.length,this.currentPlayer=this.players[this.currentPlayerIndex],0===this.currentPlayerIndex&&this.currentTurn++}}class e4 extends l{constructor(t){super({name:"cloud",pos:t,vel:H(L(-30,-100),0),width:100,height:100})}onInitialize(t){this.cloudSprite=to.CloudSheet.toSprite(),this.cloudSprite.scale=tS,this.graphics.use(this.cloudSprite)}onPostUpdate(t,e){this.pos.x+this.cloudSprite.width<0&&(this.pos.x=t.screen.contentArea.right+this.cloudSprite.width)}}class e9 extends I{constructor(t,e){super(),this.levelData=t,this.name=e}onInitialize(t){this.engine=t}resetAndLoad(){let t=this.entities;for(let e=t.length-1;e>=0;e--)this.world.remove(t[e],!1);to.LevelMusic2.stop(),this.add(new e4(H(800,0))),this.add(new e4(H(400,300))),this.add(new e4(H(700,700))),this.board=this.parse(this.levelData),this.add(tB),this.camera.pos=this.board.getCenter()}onActivate(){this.resetAndLoad(),this.turnManager.start(),to.LevelMusic2.loop=!0,to.LevelMusic2.volume=.05,to.LevelMusic2.play(),this.engine.input.keyboard.on("press",t=>{t.key===A.W&&this.players[1].lose(),t.key===A.L&&this.players[0].lose()})}onDeactivate(){to.LevelMusic2.instances.forEach(t=>t.stop()),to.LevelMusic2.stop()}parse(t){let e=new tD(t.height,t.width,this);this.selectionManager=new tN(e),this.selectionManager.showCursor(0,0),this.uiManager=new e2(this.engine),// TODO support arbitrary players -this.players=[new tO(t.players[0],this.engine,this.selectionManager,this.uiManager,e),new e5(t.players[1],this.selectionManager,e)],this.turnManager=new e3(this.engine,this,this.players,this.selectionManager,10);for(let i=0;i{t.easeBy(H(0,-30*tS.y),1e3,f.EaseInOutQuad).easeBy(H(0,30*tS.y),1e3,f.EaseInOutQuad)}),this.add(this.title),this.instructions=new l({name:"instructions",pos:H(400,600),coordPlane:_.Screen});let e=new x({family:"notjamslab14",size:32*tS.x,unit:w.Px,color:p.White,baseAlign:u.Top,quality:4,shadow:{offset:H(10,10).scale(tS),color:p.Black}}),i=new D({text:"Click to Play!",font:e});this.instructions.graphics.use(i),this.instructions.actions.repeatForever(t=>{// ctx.blink(300, 300, 2); -t.rotateTo(Math.PI/32,.2),t.rotateTo(-Math.PI/32,.2)}),this.add(this.instructions)}onActivate(){to.TitleMusic.loop=!0,to.TitleMusic.volume=.05,to.TitleMusic.play(),this.engine.input.pointers.primary.once("down",()=>{this.engine.goToScene("tutorial")}),this.engine.input.keyboard.once("press",()=>{this.engine.goToScene("tutorial")})}onDeactivate(){to.TitleMusic.stop()}};e7.addScene("start",e8);const it=new class extends e9{constructor(){super(e6,"tutorial")}onInitialize(t){super.onInitialize(t),this.resetAndLoad();let e=this.board.cells[0].unit;e&&(this.focus=new l({name:"focus",pos:e.pos.add(H(16,16).scale(tS)),width:32,height:32,anchor:H(0,1),z:10}),this.focus.graphics.opacity=0,this.engine.add(this.focus))}async moveToUnit1(){let t=this.board.getCell(0,0).unit.pos.add(H(16,16).scale(tS));await this.focus.actions.easeTo(t,1e3,f.EaseInOutCubic).toPromise()}async selectUnit1(){this.selectionManager.selectPlayer(this.players[0]);let t=this.board.getCell(0,0).unit,e=this.uiManager.showUnitMenu(t,{move:()=>{},attack:()=>{},pass:()=>{}});await B.delay(1e3),e.hide(),this.selectionManager.selectUnit(t,"move");let i=this.selectionManager.findMovementRange(t),s=this.board.getCell(2,0),r=this.selectionManager.findPath(s,i);this.selectionManager.showHighlight(r,"path"),await B.delay(1e3),await this.selectionManager.selectDestinationAndMove(t,s),e.show(),await B.delay(2e3),this.selectionManager.selectUnit(t,"attack");let n=this.selectionManager.findAttackRange(t);this.selectionManager.showHighlight(n,"attack"),await B.delay(1e3);let o=this.board.getCell(2,1);this.selectionManager.showHighlight([o.pathNode],"path"),e.hide(),this.selectionManager.reset();let a=this.board.getCell(2,1).unit;t.attack(a),await B.delay(2e3)}async highlightEnemyRange(){let t=this.players[0],e=this.board.getCell(2,1);await t.highlightUnitRange(e),await B.delay(1e3),this.selectionManager.reset()}async moveToUnit2(){let t=this.board.getCell(0,1).unit.pos.add(H(16,16).scale(tS));await this.focus.actions.easeTo(t,1e3,f.EaseInOutCubic).toPromise()}async showText(t){let e=ta.getSprite(t,0);e.scale=tS,this.focus.graphics.use(e),await this.focus.actions.fade(1,200).toPromise()}async hideText(){await this.focus.actions.fade(0,200).toPromise()}async onActivate(){this.engine.input.keyboard.once("press",t=>{t.key===A.Esc&&this.engine.goToScene("level1")}),to.LevelMusic2.loop=!0,to.LevelMusic2.volume=.05,to.LevelMusic2.play(),this.camera.strategy.lockToActor(this.focus),this.camera.zoomOverTime(1.25,1e3,f.EaseInOutCubic),this.selectionManager.showCursor(0,0),await B.delay(1e3),// hey look at all these spiders! +if(!r){this.selectionManger.selectUnit(e,"move"),await D.delay(200);let i=this.selectionManger.findPath(n,t);this.selectionManger.showHighlight(i,"path"),await D.delay(200),await this.selectionManger.selectDestinationAndMove(e,n),await D.delay(200),// try again to attack +await this.maybeAttack(e,s)}this.selectionManger.reset()}}return!0}lose(){this.active=!1;let t=this.board.getUnits().filter(t=>t.player instanceof e5);t.forEach(t=>{t.health=0,t.cell?.removeUnit(t)})}}class e3{constructor(t,e,i,s,r){if(this.engine=t,this.level=e,this.players=i,this.maxTurns=r,this.currentTurn=1,this.currentPlayerIndex=0,this.topScreen=z(400,-2e3),this.centerScreen=z(400,400),this.bottomScreen=z(400,2e3),0===i.length)throw Error("Players should be non-zero in length");this.currentPlayer=i[this.currentPlayerIndex],this.selectionManager=s,this.turnText=new R({text:`Turn ${this.currentTurn}`,font:new y({family:"notjamslab14",size:32*tA.x,unit:x.Px,color:u.White,baseAlign:c.Top,quality:4})});let n=t.screen.resolution.width;this.turnActor=new h({name:"turn text",pos:this.topScreen,coordPlane:g.Screen,color:new u(240,50,50,.4),width:n,height:100,z:10}),this.turnActor.graphics.opacity=0,this.turnActor.graphics.add("text",this.turnText),this.turnActor.graphics.show("text"),t.add(this.turnActor);let o=new R({text:"Victory!",font:new y({family:"notjamslab14",size:32*tA.x,unit:x.Px,color:u.White,baseAlign:c.Top,quality:4})});this.victory=new h({name:"victory text",pos:this.topScreen,coordPlane:g.Screen,color:new u(50,240,50,.4),width:n,height:100,z:10}),this.victory.graphics.opacity=0,this.victory.graphics.add("text",o),this.victory.graphics.show("text"),t.add(this.victory);let a=new R({text:"Failure!",font:new y({family:"notjamslab14",size:32*tA.x,unit:x.Px,color:u.White,baseAlign:c.Top,quality:4})}),l=new R({text:"Click to try again!",font:new y({family:"notjamslab14",size:32*tA.x,unit:x.Px,color:u.White,baseAlign:c.Top,quality:4})});this.failure=new h({name:"failure text",pos:this.topScreen,coordPlane:g.Screen,color:new u(240,50,50,.4),width:n,height:250,z:10}),this.failure.graphics.opacity=0,this.failure.graphics.add("text1",a),this.failure.graphics.add("text2",l),this.failure.graphics.show("text1",{offset:z(0,-50)}),this.failure.graphics.show("text2",{offset:z(0,50)}),t.add(this.failure)}async showTurnDisplay(){0===this.currentPlayerIndex&&(this.turnText.text=`Turn ${this.currentTurn}`,await this.turnActor.actions.runAction(new S([new a(this.turnActor,t=>t.easeTo(this.centerScreen,1200,m.EaseInOutCubic).delay(700).easeTo(this.bottomScreen,1200,m.EaseInOutCubic)),new a(this.turnActor,t=>t.fade(1,1200).delay(700).fade(0,1200))])).toPromise(),this.turnActor.pos=this.topScreen)}async showGameOver(){await this.failure.actions.runAction(new S([new a(this.failure,t=>t.easeTo(this.centerScreen,1200,m.EaseInOutCubic)),new a(this.failure,t=>t.fade(1,1200))])).toPromise()}async showVictory(){await this.victory.actions.runAction(new S([new a(this.victory,t=>t.easeTo(this.centerScreen,1200,m.EaseInOutCubic)),new a(this.victory,t=>t.fade(1,1200))])).toPromise()}async start(){// TODO win condition +for(;this.maxTurns>0;){if(console.log("Current player turn:",this.currentPlayer.name),this.currentPlayer.hasLost()){if(console.log("Player lost!",this.currentPlayer.name),this.currentPlayer instanceof tH){await this.showGameOver(),this.engine.input.pointers.once("down",()=>{tn.LevelMusic2.stop(),this.engine.goToScene(this.level.levelData.name)});return}if(this.currentPlayer instanceof e5){await this.showVictory(),this.engine.input.pointers.once("down",()=>{this.engine.goToScene(this.level.levelData.nextLevel)});return}}this.selectionManager.selectPlayer(this.currentPlayer),this.showTurnDisplay(),await this.currentPlayer.turnStart();let t=!0;do t=await this.currentPlayer.makeMove();while(!t)await this.currentPlayer.turnEnd(),this.nextTurn(),this.maxTurns--}}nextTurn(){this.currentPlayerIndex++,this.currentPlayerIndex=this.currentPlayerIndex%this.players.length,this.currentPlayer=this.players[this.currentPlayerIndex],0===this.currentPlayerIndex&&this.currentTurn++}}class e4 extends h{constructor(t){super({name:"cloud",pos:t,vel:z(U(-30,-100),0),width:100,height:100})}onInitialize(t){this.cloudSprite=tn.CloudSheet.toSprite(),this.cloudSprite.scale=tA,this.graphics.use(this.cloudSprite)}onPostUpdate(t,e){this.pos.x+this.cloudSprite.width<0&&(this.pos.x=t.screen.contentArea.right+this.cloudSprite.width)}}class e9 extends M{constructor(t,e){super(),this.levelData=t,this.name=e}onInitialize(t){this.engine=t}resetAndLoad(){let t=this.entities;for(let e=t.length-1;e>=0;e--)this.world.remove(t[e],!1);tn.LevelMusic2.stop(),this.add(new e4(z(800,0))),this.add(new e4(z(400,300))),this.add(new e4(z(700,700))),this.board=this.parse(this.levelData),this.add(tD),this.camera.pos=this.board.getCenter()}onActivate(){this.resetAndLoad(),this.turnManager.start(),tn.LevelMusic2.loop=!0,tn.LevelMusic2.play(),this.engine.input.keyboard.on("press",t=>{t.key===C.W&&this.players[1].lose(),t.key===C.L&&this.players[0].lose()})}onDeactivate(){tn.LevelMusic2.instances.forEach(t=>t.stop()),tn.LevelMusic2.stop()}parse(t){let e=new tR(t.height,t.width,this);this.selectionManager=new tO(e),this.selectionManager.showCursor(0,0),this.uiManager=new e2(this.engine),// TODO support arbitrary players +this.players=[new tH(t.players[0],this.engine,this.selectionManager,this.uiManager,e),new e5(t.players[1],this.selectionManager,e)],this.turnManager=new e3(this.engine,this,this.players,this.selectionManager,10);for(let i=0;ivolume_up`:eC``}constructor(...t){super(...t),this.soundOn=!0}};tN([eq()],e8.prototype,"soundOn",void 0),e8=tN([eG("audio-menu")],e8);const it=new v({width:800,height:800,displayMode:_.FitScreenAndFill,antialiasing:!1,suppressHiDPIScaling:!0,configurePerformanceCanvas2DFallback:{allow:!1}});e7.init();const ie=new class extends M{onInitialize(t){this.engine=t,this.add(new e4(z(800,0))),this.add(new e4(z(400,300))),this.add(new e4(z(700,700))),this.title=new h({name:"title",pos:z(400,400),coordPlane:g.Screen}),this.title.scale=tA,this.title.graphics.use(tw),this.title.actions.repeatForever(t=>{t.easeBy(z(0,-30*tA.y),1e3,m.EaseInOutQuad).easeBy(z(0,30*tA.y),1e3,m.EaseInOutQuad)}),this.add(this.title),this.instructions=new h({name:"instructions",pos:z(400,600),coordPlane:g.Screen});let e=new y({family:"notjamslab14",size:32*tA.x,unit:x.Px,color:u.White,baseAlign:c.Top,quality:4,shadow:{offset:z(10,10).scale(tA),color:u.Black}}),i=new R({text:"Click to Play!",font:e});this.instructions.graphics.use(i),this.instructions.actions.repeatForever(t=>{t.rotateTo(Math.PI/32,.2),t.rotateTo(-Math.PI/32,.2)}),this.add(this.instructions)}onActivate(){tn.TitleMusic.loop=!0,tn.TitleMusic.play(),this.engine.input.pointers.primary.once("down",()=>{this.engine.goToScene("tutorial")}),this.engine.input.keyboard.once("press",()=>{this.engine.goToScene("tutorial")})}onDeactivate(){tn.TitleMusic.stop()}};it.addScene("start",ie);const ii=new class extends e9{constructor(){super(e6,"tutorial")}onInitialize(t){super.onInitialize(t),this.resetAndLoad();let e=this.board.cells[0].unit;e&&(this.focus=new h({name:"focus",pos:e.pos.add(z(16,16).scale(tA)),width:32,height:32,anchor:z(0,1),z:10}),this.focus.graphics.opacity=0,this.engine.add(this.focus))}async moveToUnit1(){let t=this.board.getCell(0,0).unit.pos.add(z(16,16).scale(tA));await this.focus.actions.easeTo(t,1e3,m.EaseInOutCubic).toPromise()}async selectUnit1(){this.selectionManager.selectPlayer(this.players[0]);let t=this.board.getCell(0,0).unit,e=this.uiManager.showUnitMenu(t,{move:()=>{},attack:()=>{},pass:()=>{}});await D.delay(1e3),e.hide(),this.selectionManager.selectUnit(t,"move");let i=this.selectionManager.findMovementRange(t),s=this.board.getCell(2,0),r=this.selectionManager.findPath(s,i);this.selectionManager.showHighlight(r,"path"),await D.delay(1e3),await this.selectionManager.selectDestinationAndMove(t,s),e.show(),await D.delay(2e3),this.selectionManager.selectUnit(t,"attack");let n=this.selectionManager.findAttackRange(t);this.selectionManager.showHighlight(n,"attack"),await D.delay(1e3);let o=this.board.getCell(2,1);this.selectionManager.showHighlight([o.pathNode],"path"),e.hide(),this.selectionManager.reset();let a=this.board.getCell(2,1).unit;t.attack(a),await D.delay(2e3)}async highlightEnemyRange(){let t=this.players[0],e=this.board.getCell(2,1);await t.highlightUnitRange(e),await D.delay(1e3),this.selectionManager.reset()}async moveToUnit2(){let t=this.board.getCell(0,1).unit.pos.add(z(16,16).scale(tA));await this.focus.actions.easeTo(t,1e3,m.EaseInOutCubic).toPromise()}async showText(t){let e=to.getSprite(t,0);e.scale=tA,this.focus.graphics.use(e),await this.focus.actions.fade(1,200).toPromise()}async hideText(){await this.focus.actions.fade(0,200).toPromise()}async onActivate(){this.engine.input.keyboard.once("press",t=>{t.key===C.Esc&&this.engine.goToScene("level1")}),tn.LevelMusic2.loop=!0,tn.LevelMusic2.play(),this.camera.strategy.lockToActor(this.focus),this.camera.zoomOverTime(1.25,1e3,m.EaseInOutCubic),this.selectionManager.showCursor(0,0),await D.delay(1e3),// hey look at all these spiders! await this.showText(1),await this.focus.actions.delay(1e3),await this.hideText(),// we need to take them out to get home! await this.moveToUnit2(),await this.showText(2),await this.focus.actions.delay(1e3),await this.hideText(),// how do we do that?!? await this.moveToUnit1(),await this.showText(3),await this.focus.actions.delay(1e3),await this.hideText(),// left click to move/attack, right click to see friendly/enemy range await this.moveToUnit2(),await this.showText(4),await this.focus.actions.delay(4e3),await this.hideText(),await this.selectUnit1(),// we have a limited amount of turns to complete the level! -await this.moveToUnit2(),await this.showText(5),await this.focus.actions.delay(1e3),await this.hideText(),await this.highlightEnemyRange(),await this.showText(6),await this.focus.actions.delay(2e3),await this.hideText(),await this.showText(7),await this.focus.actions.delay(7e3),await this.hideText(),this.camera.zoomOverTime(1,1e3,f.EaseInOutCubic),this.engine.goToScene("level1")}onDeactivate(){to.LevelMusic2.stop()}};e7.addScene(it.name,it);const ie=new e9({displayName:"Gentle Plains",name:"level1",nextLevel:"level2",width:6,height:3,maxTurns:10,players:["human","computer"],data:["GK1","G","G","GS2","G","GS2","GK1","G","GS2","G","G","GS2","G","G","W","W","G","G"]},"level1");e7.addScene(ie.name,ie);const ii=new e9({displayName:"Gentle Plains 2",name:"level2",nextLevel:"start",width:6,height:6,maxTurns:100,players:["human","computer"],data:["GK1","G","GS2","G","G","GS2","GK1","G","G","G","G","GS2","GK1","G","W","W","G","G","G","G","W","W","G","G","G","G","W","W","G","G","G","GS2","W","W","GS2","GS2"]},"level2");e7.addScene(ii.name,ii),e7.start(tC).then(()=>{e7.goToScene("start")});//# sourceMappingURL=index.ef91dd93.js.map +await this.moveToUnit2(),await this.showText(5),await this.focus.actions.delay(1e3),await this.hideText(),await this.highlightEnemyRange(),await this.showText(6),await this.focus.actions.delay(2e3),await this.hideText(),await this.showText(7),await this.focus.actions.delay(7e3),await this.hideText(),this.camera.zoomOverTime(1,1e3,m.EaseInOutCubic),this.engine.goToScene("level1")}onDeactivate(){tn.LevelMusic2.stop()}};it.addScene(ii.name,ii);const is=new e9({displayName:"Gentle Plains",name:"level1",nextLevel:"level2",width:6,height:3,maxTurns:10,players:["human","computer"],data:["GK1","G","G","GS2","G","GS2","GK1","G","GS2","G","G","GS2","G","G","W","W","G","G"]},"level1");it.addScene(is.name,is);const ir=new e9({displayName:"Gentle Plains 2",name:"level2",nextLevel:"start",width:6,height:6,maxTurns:100,players:["human","computer"],data:["GK1","G","GS2","G","G","GS2","GK1","G","G","G","G","GS2","GK1","G","W","W","G","G","G","G","W","W","G","G","G","G","W","W","G","G","G","GS2","W","W","GS2","GS2"]},"level2");it.addScene(ir.name,ir),it.start(tb).then(()=>{it.goToScene("start")});//# sourceMappingURL=index.d796f22d.js.map -//# sourceMappingURL=index.ef91dd93.js.map +//# sourceMappingURL=index.d796f22d.js.map diff --git a/index.d796f22d.js.map b/index.d796f22d.js.map new file mode 100644 index 0000000..bcbd643 --- /dev/null +++ b/index.d796f22d.js.map @@ -0,0 +1 @@ +{"mappings":"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A,EAAA,ICPA,MAAA,EAAA,EAAA,CAAA,CAAA,CAAA,EAAA,IAAA,OAAA,SAAA,CAAA,cAAA,CAAA,IAAA,CAAA,EAAA,GCAA,MAAA,EAAA,+BAAA;AACA,MAAA,EAAA,EAAA,CAAA,CAAA,AAAA,IACA,aAAA,OAAA,QAAA,OAAA,WAAA,EACA,MAAA,EAAA,OAAA,cAAA,CAAA,EAAA,OAAA,WAAA,CAAA,CAAuD,MAAA,QAAA,GAEvD,MAAA,EAAA,OAAA,cAAA,CAAA,EAAA,aAAA,CAAgD,MAAA,CAAA,CAAA,EAChD,OAAA,EAAA,C,O,E,wE,E,I,E,C,E,A,8G;A,C,K,U;A,E,C,C,E,C,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,U,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,E,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,E,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,E,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,E,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,E,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,E,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,E,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,E,I,I,Y,E,G,I,I,Y,E,G,I,I,W,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,E,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,Q,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,G,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,E,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,E,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,E,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,E,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,E,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,a,I,I,Y,E,G,I,I,Y,E,E,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,G,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,E,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,O,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,E,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,K,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,W,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,G,I,I,Y,E,E,E,iC;A,IKUY,EC2YA,EAsEA,EC7dA,EEIA,ECJA,EKCA,EAQE,EITF,EQAA,EuCSA,EeVA,EEUA,EAWA,EAOA,EC5BA,E0BiBA,EYjBA,EgBMA,EA0BA,EA4BA,EAoCA,EASA,EWfA,EErFA,EaQA,EAWA,EGTA,EAmOA,EUnPA,EWDA,ECEA,ECAA,ECAA,EM8EA,EhMjEA,EC2YA,EAsEA,EC7dA,EEIA,ECJA,EKCA,EIDA,EQAA,EuCSA,EeVA,EEUA,EAWA,EAOA,EC5BA,E0BiBA,EYjBA,EgBMA,GA0BA,GA4BA,GAoCA,GASA,GWfA,GErFA,GaQA,GAWA,GGTA,GAmOA,GUnPA,GWDA,GCEA,GCAA,GCAA,GM8EA,G,G,C,E,E,C,C,I,E,C,C,G,C,c,I,G,kB,I,G,wB,I,G,uB,I,G,oB,I,G,gB,I,G,kB,I,G,gB,I,G,kB,I,G,mB,I,G,W,I,E,iB,I,G,kB,I,G,U,I,G,e,I,G,c,I,G,iB,I,G,mB,I,G,oB,I,G,uB,I,G,Y,I,G,gB,I,G,U,I,G,mB,I,G,mB,I,G,c,I,G,e,I,G,c,I,G,gB,I,G,kB,I,G,kB,I,G,a,I,G,c,I,G,a,I,G,e,I,G,a,I,E,E,sD;A,I,G,C,E,E,C,C,I,E,C,C,G,C,0B,I,G,wB,I,G,mB,I,E,E,wC;A,I,G,C,E,E,C,C,I,E,C,C,G,C,O,I,G,K,I,G,M,I,G,U,I,G,O,I,E,E,sC;A,I,G,C,E,E,C,C,I,E,C,C,G,C,K,I,E,Q,I,E,Q,I,Q,S,I,G,S,I,G,S,I,G,K,I,E,oB,I,G,c,I,G,iB,I,G,a,I,a,qB,I,G,a,I,E,c,I,G,Y,I,G,e,I,G,W,I,U,E,qC;A,I,G,C,CpM9EZ;;CAEG,EACI,SAAS,KA2Bd,wBAAA,EACA,GA1BsB,aAAlB,OAAO,QACT,CAAA,OAAc,CACZ,aAAc,WAEd,CACD,CAAA,EAGmB,aAAlB,OAAO,QAA2B,OAAO,qBAAqB,EAC1D,CAAA,OAAQ,qBAAqB,CAC3B,OAAQ,2BAA2B,EACnC,OAAQ,wBAAwB,EACtC,SAAU,CAAkB,EAC1B,OAAO,WAAW,CAAC,EAAU,IAAO,GACtC,CAAA,EAGkB,aAAlB,OAAO,QAA2B,OAAO,oBAAoB,EACzD,CAAA,OAAQ,oBAAoB,CAC1B,OAAQ,0BAA0B,EAClC,OAAQ,uBAAuB,EACrC,WAEA,CAAA,EAGA,AAAkB,aAAlB,OAAO,QAA0B,CAAO,OAAQ,YAAY,CAAE,CAChE,GAAU,OAAQ,kBAAkB,CAAE,CACpC,IAAM,EAAY,OAAQ,kBAAkB,CACtC,EAAY,EAAI,SAAS,CAAC,eAAe,AACzC,CAAA,OAAQ,kBAAkB,CAAC,SAAS,CAAC,eAAe,CAAG,SAAU,CAAwB,EAC7F,OAAO,I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AK,EAAgB,CAAC,CAAtB,CACL,GAAI,AAAU,IAAV,GAGJ,KAAO,AAAU,IAAV,GAAe,AAA2B,IAA3B,IAAI,CAAC,UAAU,CAAC,MAAM,EAC1C,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,MACxB,GAEF,CAAA,IAAI,CAAC,MAAM,EAAI,EACjB,CACD,CC1DD;;;CAGG,EACI,IAAM,GAAa,SAE1B,IAEA,sEAAqE;AACrE,oDAAoD;AAuCpD,sBAAsB;AAItB,qBAAqB;AACrB,gDAAgD;AAkEhD,qBAAqB;AAmBrB,gBAAgB;AAChB,8CAA8C;AAC9C,uCAAuC;AACvC,gCAAgC;A,C,I,E,G,C,E,G,C,I,E,E,G,A,C,E,G,C,E,G,C,E,G,C,I,E,E,G,A,C,E,G,C,E,G,C,E,G,C,I,E,E,G,A,C,E,G,C,E,G,C,I,E,E,G,A,C,E,G,C,E,G,C,E,G,C,E,G,C,I,E,E,G,A,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,I,E,E,G,A,C,E,G,C,E,G,C,E,G,C,I,E,E,G,A,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,I,E,E,G,A,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,I,E,E,G,A,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,I,E,E,G,A,C,E,G,C,E,G,C,I,E,E,G,C,E,E,G,A,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,I,E,E,G,A,C,E,G,C,E,G,C,I,E,E,G,A,C,E,G,C,E,G,C,I,E,E,G,A,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,E,E,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,I,E,E,G,A,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,I,E,E,G,A,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,I,E,E,G,A,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,I,E,E,G,A,C,E,G,C,E,G,C,I,E,E,G,A,C,E,G,C,E,G,C,E,G,C,E,G,C,I,E,E,G,A,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,I,E,E,G,A,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,E,E,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,I,E,E,G,A,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,I,E,E,G,A,C,E,G,C,E,G,C,E,G,C,I,E,E,G,A,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,I,E,E,G,A,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,I,E,E,G,C,E,E,G,A,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,I,E,E,G,A,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,I,E,E,G,C,E,E,G,A,C,E,G,C,E,G,C,E,G,C,E,G,C,E,G,C,I,E,E,G,A,C,E,G,C,I,E,C,EE7IhC,EAAiB,IAAA,IAAoB,sCAAA,YAAA,GAAA,EAAuC,QAAQ,G,I,E,C,ECApF,EAAiB,IAAA,IAAoB,4CAAA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","sources":["","src/main.ts","node_modules/excalibur/build/esm/excalibur.js","node_modules/excalibur/build/node_modules/core-js/es/array/sort.js","node_modules/excalibur/build/node_modules/core-js/es/object/keys.js","node_modules/excalibur/build/node_modules/core-js/internals/a-callable.js","node_modules/excalibur/build/node_modules/core-js/internals/an-object.js","node_modules/excalibur/build/node_modules/core-js/internals/array-includes.js","node_modules/excalibur/build/node_modules/core-js/internals/array-method-is-strict.js","node_modules/excalibur/build/node_modules/core-js/internals/array-slice-simple.js","node_modules/excalibur/build/node_modules/core-js/internals/array-sort.js","node_modules/excalibur/build/node_modules/core-js/internals/classof-raw.js","node_modules/excalibur/build/node_modules/core-js/internals/classof.js","node_modules/excalibur/build/node_modules/core-js/internals/copy-constructor-properties.js","node_modules/excalibur/build/node_modules/core-js/internals/create-non-enumerable-property.js","node_modules/excalibur/build/node_modules/core-js/internals/create-property-descriptor.js","node_modules/excalibur/build/node_modules/core-js/internals/create-property.js","node_modules/excalibur/build/node_modules/core-js/internals/define-built-in.js","node_modules/excalibur/build/node_modules/core-js/internals/define-global-property.js","node_modules/excalibur/build/node_modules/core-js/internals/delete-property-or-throw.js","node_modules/excalibur/build/node_modules/core-js/internals/descriptors.js","node_modules/excalibur/build/node_modules/core-js/internals/document-all.js","node_modules/excalibur/build/node_modules/core-js/internals/document-create-element.js","node_modules/excalibur/build/node_modules/core-js/internals/engine-ff-version.js","node_modules/excalibur/build/node_modules/core-js/internals/engine-is-ie-or-edge.js","node_modules/excalibur/build/node_modules/core-js/internals/engine-user-agent.js","node_modules/excalibur/build/node_modules/core-js/internals/engine-v8-version.js","node_modules/excalibur/build/node_modules/core-js/internals/engine-webkit-version.js","node_modules/excalibur/build/node_modules/core-js/internals/entry-unbind.js","node_modules/excalibur/build/node_modules/core-js/internals/enum-bug-keys.js","node_modules/excalibur/build/node_modules/core-js/internals/export.js","node_modules/excalibur/build/node_modules/core-js/internals/fails.js","node_modules/excalibur/build/node_modules/core-js/internals/function-bind-native.js","node_modules/excalibur/build/node_modules/core-js/internals/function-call.js","node_modules/excalibur/build/node_modules/core-js/internals/function-name.js","node_modules/excalibur/build/node_modules/core-js/internals/function-uncurry-this.js","node_modules/excalibur/build/node_modules/core-js/internals/get-built-in.js","node_modules/excalibur/build/node_modules/core-js/internals/get-method.js","node_modules/excalibur/build/node_modules/core-js/internals/global.js","node_modules/excalibur/build/node_modules/core-js/internals/has-own-property.js","node_modules/excalibur/build/node_modules/core-js/internals/hidden-keys.js","node_modules/excalibur/build/node_modules/core-js/internals/ie8-dom-define.js","node_modules/excalibur/build/node_modules/core-js/internals/indexed-object.js","node_modules/excalibur/build/node_modules/core-js/internals/inspect-source.js","node_modules/excalibur/build/node_modules/core-js/internals/internal-state.js","node_modules/excalibur/build/node_modules/core-js/internals/is-callable.js","node_modules/excalibur/build/node_modules/core-js/internals/is-forced.js","node_modules/excalibur/build/node_modules/core-js/internals/is-null-or-undefined.js","node_modules/excalibur/build/node_modules/core-js/internals/is-object.js","node_modules/excalibur/build/node_modules/core-js/internals/is-pure.js","node_modules/excalibur/build/node_modules/core-js/internals/is-symbol.js","node_modules/excalibur/build/node_modules/core-js/internals/length-of-array-like.js","node_modules/excalibur/build/node_modules/core-js/internals/make-built-in.js","node_modules/excalibur/build/node_modules/core-js/internals/math-trunc.js","node_modules/excalibur/build/node_modules/core-js/internals/object-define-property.js","node_modules/excalibur/build/node_modules/core-js/internals/object-get-own-property-descriptor.js","node_modules/excalibur/build/node_modules/core-js/internals/object-get-own-property-names.js","node_modules/excalibur/build/node_modules/core-js/internals/object-get-own-property-symbols.js","node_modules/excalibur/build/node_modules/core-js/internals/object-is-prototype-of.js","node_modules/excalibur/build/node_modules/core-js/internals/object-keys-internal.js","node_modules/excalibur/build/node_modules/core-js/internals/object-keys.js","node_modules/excalibur/build/node_modules/core-js/internals/object-property-is-enumerable.js","node_modules/excalibur/build/node_modules/core-js/internals/ordinary-to-primitive.js","node_modules/excalibur/build/node_modules/core-js/internals/own-keys.js","node_modules/excalibur/build/node_modules/core-js/internals/path.js","node_modules/excalibur/build/node_modules/core-js/internals/require-object-coercible.js","node_modules/excalibur/build/node_modules/core-js/internals/shared-key.js","node_modules/excalibur/build/node_modules/core-js/internals/shared-store.js","node_modules/excalibur/build/node_modules/core-js/internals/shared.js","node_modules/excalibur/build/node_modules/core-js/internals/symbol-constructor-detection.js","node_modules/excalibur/build/node_modules/core-js/internals/to-absolute-index.js","node_modules/excalibur/build/node_modules/core-js/internals/to-indexed-object.js","node_modules/excalibur/build/node_modules/core-js/internals/to-integer-or-infinity.js","node_modules/excalibur/build/node_modules/core-js/internals/to-length.js","node_modules/excalibur/build/node_modules/core-js/internals/to-object.js","node_modules/excalibur/build/node_modules/core-js/internals/to-primitive.js","node_modules/excalibur/build/node_modules/core-js/internals/to-property-key.js","node_modules/excalibur/build/node_modules/core-js/internals/to-string-tag-support.js","node_modules/excalibur/build/node_modules/core-js/internals/to-string.js","node_modules/excalibur/build/node_modules/core-js/internals/try-to-string.js","node_modules/excalibur/build/node_modules/core-js/internals/uid.js","node_modules/excalibur/build/node_modules/core-js/internals/use-symbol-as-uid.js","node_modules/excalibur/build/node_modules/core-js/internals/v8-prototype-define-bug.js","node_modules/excalibur/build/node_modules/core-js/internals/weak-map-basic-detection.js","node_modules/excalibur/build/node_modules/core-js/internals/well-known-symbol.js","node_modules/excalibur/build/node_modules/core-js/modules/es.array.sort.js","node_modules/excalibur/build/node_modules/core-js/modules/es.object.keys.js","node_modules/excalibur/build/esm/webpack:/Loader.css","node_modules/excalibur/build/esm/webpack:/Util/Toaster.css","node_modules/excalibur/build/node_modules/css-loader/dist/runtime/api.js","node_modules/excalibur/build/node_modules/css-loader/dist/runtime/sourceMaps.js","node_modules/excalibur/build/esm/webpack:/webpack/bootstrap","node_modules/excalibur/build/esm/webpack:/webpack/runtime/compat get default export","node_modules/excalibur/build/esm/webpack:/webpack/runtime/define property getters","node_modules/excalibur/build/esm/webpack:/webpack/runtime/global","node_modules/excalibur/build/esm/webpack:/webpack/runtime/hasOwnProperty shorthand","node_modules/excalibur/build/esm/webpack:/webpack/runtime/make namespace object","node_modules/excalibur/build/esm/webpack:/Polyfill.ts","node_modules/excalibur/build/esm/webpack:/Flags.ts","node_modules/excalibur/build/esm/webpack:/Id.ts","node_modules/excalibur/build/esm/webpack:/EventEmitter.ts","node_modules/excalibur/build/esm/webpack:/Events.ts","node_modules/excalibur/build/esm/webpack:/Input/Gamepad.ts","node_modules/excalibur/build/esm/webpack:/Util/Log.ts","node_modules/excalibur/build/esm/webpack:/Util/IFrame.ts","node_modules/excalibur/build/esm/webpack:/Input/Keyboard.ts","node_modules/excalibur/build/esm/webpack:/Input/PointerScope.ts","node_modules/excalibur/build/esm/webpack:/Math/Random.ts","node_modules/excalibur/build/esm/webpack:/Math/util.ts","node_modules/excalibur/build/esm/webpack:/Math/vector.ts","node_modules/excalibur/build/esm/webpack:/Color.ts","node_modules/excalibur/build/esm/webpack:/Collision/Side.ts","node_modules/excalibur/build/esm/webpack:/Collision/BoundingBox.ts","node_modules/excalibur/build/esm/webpack:/Util/Future.ts","node_modules/excalibur/build/esm/webpack:/Util/Util.ts","node_modules/excalibur/build/esm/webpack:/Math/matrix.ts","node_modules/excalibur/build/esm/webpack:/Math/affine-matrix.ts","node_modules/excalibur/build/esm/webpack:/Graphics/Context/transform-stack.ts","node_modules/excalibur/build/esm/webpack:/Graphics/Context/state-stack.ts","node_modules/excalibur/build/esm/webpack:/Resources/Resource.ts","node_modules/excalibur/build/esm/webpack:/Util/Watch.ts","node_modules/excalibur/build/esm/webpack:/Graphics/Graphic.ts","node_modules/excalibur/build/esm/webpack:/Graphics/Sprite.ts","node_modules/excalibur/build/esm/webpack:/Graphics/Filtering.ts","node_modules/excalibur/build/esm/webpack:/Graphics/Context/texture-loader.ts","node_modules/excalibur/build/esm/webpack:/Graphics/ImageSource.ts","node_modules/excalibur/build/esm/webpack:/Graphics/SpriteSheet.ts","node_modules/excalibur/build/esm/webpack:/Graphics/SpriteFont.ts","node_modules/excalibur/build/esm/webpack:/Graphics/Context/debug-font.png","node_modules/excalibur/build/esm/webpack:/Graphics/Context/debug-text.ts","node_modules/excalibur/build/esm/webpack:/Graphics/Context/render-source.ts","node_modules/excalibur/build/esm/webpack:/Graphics/Context/render-target.ts","node_modules/excalibur/build/esm/webpack:/Graphics/Context/line-renderer/line-vertex.glsl","node_modules/excalibur/build/esm/webpack:/Graphics/Context/line-renderer/line-fragment.glsl","node_modules/excalibur/build/esm/webpack:/Graphics/Context/webgl-util.ts","node_modules/excalibur/build/esm/webpack:/Graphics/Context/shader.ts","node_modules/excalibur/build/esm/webpack:/Graphics/Context/vertex-buffer.ts","node_modules/excalibur/build/esm/webpack:/Graphics/Context/vertex-layout.ts","node_modules/excalibur/build/esm/webpack:/Graphics/GraphicsDiagnostics.ts","node_modules/excalibur/build/esm/webpack:/Graphics/Context/line-renderer/line-renderer.ts","node_modules/excalibur/build/esm/webpack:/Graphics/Context/point-renderer/point-vertex.glsl","node_modules/excalibur/build/esm/webpack:/Graphics/Context/point-renderer/point-fragment.glsl","node_modules/excalibur/build/esm/webpack:/Graphics/Context/point-renderer/point-renderer.ts","node_modules/excalibur/build/esm/webpack:/Graphics/Context/screen-pass-painter/screen-vertex.glsl","node_modules/excalibur/build/esm/webpack:/Graphics/Context/screen-pass-painter/screen-fragment.glsl","node_modules/excalibur/build/esm/webpack:/Graphics/Context/screen-pass-painter/screen-pass-painter.ts","node_modules/excalibur/build/esm/webpack:/Graphics/Context/quad-index-buffer.ts","node_modules/excalibur/build/esm/webpack:/Graphics/Context/image-renderer/image-renderer.frag.glsl","node_modules/excalibur/build/esm/webpack:/Graphics/Context/image-renderer/image-renderer.vert.glsl","node_modules/excalibur/build/esm/webpack:/Graphics/Context/image-renderer/image-renderer.ts","node_modules/excalibur/build/esm/webpack:/Graphics/Context/rectangle-renderer/rectangle-renderer.frag.glsl","node_modules/excalibur/build/esm/webpack:/Graphics/Context/rectangle-renderer/rectangle-renderer.vert.glsl","node_modules/excalibur/build/esm/webpack:/Graphics/Context/rectangle-renderer/rectangle-renderer.ts","node_modules/excalibur/build/esm/webpack:/Graphics/Context/circle-renderer/circle-renderer.frag.glsl","node_modules/excalibur/build/esm/webpack:/Graphics/Context/circle-renderer/circle-renderer.vert.glsl","node_modules/excalibur/build/esm/webpack:/Graphics/Context/circle-renderer/circle-renderer.ts","node_modules/excalibur/build/esm/webpack:/Util/Pool.ts","node_modules/excalibur/build/esm/webpack:/Graphics/Context/draw-call.ts","node_modules/excalibur/build/esm/webpack:/Graphics/Context/material.ts","node_modules/excalibur/build/esm/webpack:/Graphics/Context/material-renderer/material-renderer.ts","node_modules/excalibur/build/esm/webpack:/Graphics/Context/ExcaliburGraphicsContextWebGL.ts","node_modules/excalibur/build/esm/webpack:/Graphics/Context/ExcaliburGraphicsContext2DCanvas.ts","node_modules/excalibur/build/esm/webpack:/Screen.ts","node_modules/excalibur/build/esm/webpack:/Resources/Sound/AudioContext.ts","node_modules/excalibur/build/esm/webpack:/Util/WebAudio.ts","node_modules/excalibur/build/esm/webpack:/Util/DrawUtil.ts","node_modules/excalibur/build/esm/webpack:/Loader.logo.png","node_modules/excalibur/build/esm/webpack:/Graphics/Raster.ts","node_modules/excalibur/build/esm/webpack:/Graphics/Canvas.ts","node_modules/excalibur/build/esm/webpack:/Interfaces/AudioImplementation.ts","node_modules/excalibur/build/esm/webpack:/Util/StateMachine.ts","node_modules/excalibur/build/esm/webpack:/Resources/Sound/WebAudioInstance.ts","node_modules/excalibur/build/esm/webpack:/Events/MediaEvents.ts","node_modules/excalibur/build/esm/webpack:/Util/Sound.ts","node_modules/excalibur/build/esm/webpack:/Resources/Sound/Sound.ts","node_modules/excalibur/build/esm/webpack:/Loader.ts","node_modules/excalibur/build/esm/webpack:/Util/Detector.ts","node_modules/excalibur/build/esm/webpack:/Collision/CollisionType.ts","node_modules/excalibur/build/esm/webpack:/Util/Decorators.ts","node_modules/excalibur/build/esm/webpack:/Collision/Physics.ts","node_modules/excalibur/build/esm/webpack:/Math/coord-plane.ts","node_modules/excalibur/build/esm/webpack:/Math/vector-view.ts","node_modules/excalibur/build/esm/webpack:/Math/watch-vector.ts","node_modules/excalibur/build/esm/webpack:/Math/transform.ts","node_modules/excalibur/build/esm/webpack:/EntityComponentSystem/Component.ts","node_modules/excalibur/build/esm/webpack:/Util/Observable.ts","node_modules/excalibur/build/esm/webpack:/EntityComponentSystem/Components/TransformComponent.ts","node_modules/excalibur/build/esm/webpack:/EntityComponentSystem/Components/MotionComponent.ts","node_modules/excalibur/build/esm/webpack:/Collision/Group/CollisionGroup.ts","node_modules/excalibur/build/esm/webpack:/Collision/Detection/Pair.ts","node_modules/excalibur/build/esm/webpack:/Math/projection.ts","node_modules/excalibur/build/esm/webpack:/Collision/Detection/DynamicTree.ts","node_modules/excalibur/build/esm/webpack:/Math/ray.ts","node_modules/excalibur/build/esm/webpack:/Collision/Detection/DynamicTreeCollisionProcessor.ts","node_modules/excalibur/build/esm/webpack:/Collision/Colliders/Collider.ts","node_modules/excalibur/build/esm/webpack:/Collision/Colliders/CompositeCollider.ts","node_modules/excalibur/build/esm/webpack:/Math/line-segment.ts","node_modules/excalibur/build/esm/webpack:/Collision/Colliders/ClosestLineJumpTable.ts","node_modules/excalibur/build/esm/webpack:/Collision/Colliders/CircleCollider.ts","node_modules/excalibur/build/esm/webpack:/Collision/Detection/CollisionContact.ts","node_modules/excalibur/build/esm/webpack:/Collision/Colliders/SeparatingAxis.ts","node_modules/excalibur/build/esm/webpack:/Collision/Colliders/CollisionJumpTable.ts","node_modules/excalibur/build/esm/webpack:/Collision/Colliders/EdgeCollider.ts","node_modules/excalibur/build/esm/webpack:/Collision/Colliders/PolygonCollider.ts","node_modules/excalibur/build/esm/webpack:/Collision/Colliders/Shape.ts","node_modules/excalibur/build/esm/webpack:/Collision/ColliderComponent.ts","node_modules/excalibur/build/esm/webpack:/Collision/BodyComponent.ts","node_modules/excalibur/build/esm/webpack:/EntityComponentSystem/Entity.ts","node_modules/excalibur/build/esm/webpack:/Graphics/GraphicsComponent.ts","node_modules/excalibur/build/esm/webpack:/Graphics/Rectangle.ts","node_modules/excalibur/build/esm/webpack:/Graphics/Circle.ts","node_modules/excalibur/build/esm/webpack:/Input/PointerComponent.ts","node_modules/excalibur/build/esm/webpack:/Util/EasingFunctions.ts","node_modules/excalibur/build/esm/webpack:/Actions/ActionQueue.ts","node_modules/excalibur/build/esm/webpack:/Actions/Action/Repeat.ts","node_modules/excalibur/build/esm/webpack:/Actions/Action/RepeatForever.ts","node_modules/excalibur/build/esm/webpack:/Actions/Action/MoveBy.ts","node_modules/excalibur/build/esm/webpack:/Actions/Action/MoveTo.ts","node_modules/excalibur/build/esm/webpack:/Actions/RotationType.ts","node_modules/excalibur/build/esm/webpack:/Actions/Action/RotateTo.ts","node_modules/excalibur/build/esm/webpack:/Actions/Action/RotateBy.ts","node_modules/excalibur/build/esm/webpack:/Actions/Action/ScaleTo.ts","node_modules/excalibur/build/esm/webpack:/Actions/Action/ScaleBy.ts","node_modules/excalibur/build/esm/webpack:/Actions/Action/CallMethod.ts","node_modules/excalibur/build/esm/webpack:/Actions/Action/EaseTo.ts","node_modules/excalibur/build/esm/webpack:/Actions/Action/EaseBy.ts","node_modules/excalibur/build/esm/webpack:/Actions/Action/Blink.ts","node_modules/excalibur/build/esm/webpack:/Actions/Action/Fade.ts","node_modules/excalibur/build/esm/webpack:/Actions/Action/Delay.ts","node_modules/excalibur/build/esm/webpack:/Actions/Action/Die.ts","node_modules/excalibur/build/esm/webpack:/Actions/Action/Follow.ts","node_modules/excalibur/build/esm/webpack:/Actions/Action/Meet.ts","node_modules/excalibur/build/esm/webpack:/Actions/ActionContext.ts","node_modules/excalibur/build/esm/webpack:/Actions/ActionsComponent.ts","node_modules/excalibur/build/esm/webpack:/Graphics/FontCommon.ts","node_modules/excalibur/build/esm/webpack:/Graphics/FontTextInstance.ts","node_modules/excalibur/build/esm/webpack:/Graphics/FontCache.ts","node_modules/excalibur/build/esm/webpack:/Graphics/Font.ts","node_modules/excalibur/build/esm/webpack:/Graphics/Text.ts","node_modules/excalibur/build/esm/webpack:/Actor.ts","node_modules/excalibur/build/esm/webpack:/ScreenElement.ts","node_modules/excalibur/build/esm/webpack:/Timer.ts","node_modules/excalibur/build/esm/webpack:/Graphics/ParallaxComponent.ts","node_modules/excalibur/build/esm/webpack:/Graphics/DebugGraphicsComponent.ts","node_modules/excalibur/build/esm/webpack:/TileMap/TileMap.ts","node_modules/excalibur/build/esm/webpack:/Camera.ts","node_modules/excalibur/build/esm/webpack:/Trigger.ts","node_modules/excalibur/build/esm/webpack:/EntityComponentSystem/System.ts","node_modules/excalibur/build/esm/webpack:/EntityComponentSystem/EntityManager.ts","node_modules/excalibur/build/esm/webpack:/EntityComponentSystem/Util.ts","node_modules/excalibur/build/esm/webpack:/EntityComponentSystem/Query.ts","node_modules/excalibur/build/esm/webpack:/EntityComponentSystem/QueryManager.ts","node_modules/excalibur/build/esm/webpack:/EntityComponentSystem/SystemManager.ts","node_modules/excalibur/build/esm/webpack:/EntityComponentSystem/World.ts","node_modules/excalibur/build/esm/webpack:/Collision/Integrator.ts","node_modules/excalibur/build/esm/webpack:/Collision/MotionSystem.ts","node_modules/excalibur/build/esm/webpack:/Collision/Solver/ArcadeSolver.ts","node_modules/excalibur/build/esm/webpack:/Collision/Solver/ContactConstraintPoint.ts","node_modules/excalibur/build/esm/webpack:/Collision/Solver/RealisticSolver.ts","node_modules/excalibur/build/esm/webpack:/Collision/CollisionSystem.ts","node_modules/excalibur/build/esm/webpack:/Graphics/Animation.ts","node_modules/excalibur/build/esm/webpack:/Graphics/GraphicsGroup.ts","node_modules/excalibur/build/esm/webpack:/Configurable.ts","node_modules/excalibur/build/esm/webpack:/Particles.ts","node_modules/excalibur/build/esm/webpack:/Graphics/GraphicsSystem.ts","node_modules/excalibur/build/esm/webpack:/Debug/DebugSystem.ts","node_modules/excalibur/build/esm/webpack:/Input/PointerSystem.ts","node_modules/excalibur/build/esm/webpack:/Actions/ActionsSystem.ts","node_modules/excalibur/build/esm/webpack:/TileMap/IsometricEntityComponent.ts","node_modules/excalibur/build/esm/webpack:/TileMap/IsometricEntitySystem.ts","node_modules/excalibur/build/esm/webpack:/Graphics/OffscreenSystem.ts","node_modules/excalibur/build/esm/webpack:/Collision/PhysicsWorld.ts","node_modules/excalibur/build/esm/webpack:/Scene.ts","node_modules/excalibur/build/esm/webpack:/Graphics/PostProcessor/ColorBlindnessMode.ts","node_modules/excalibur/build/esm/webpack:/Graphics/PostProcessor/color-blind-fragment.glsl","node_modules/excalibur/build/esm/webpack:/Graphics/PostProcessor/ScreenShader.ts","node_modules/excalibur/build/esm/webpack:/Graphics/PostProcessor/ColorBlindnessPostProcessor.ts","node_modules/excalibur/build/esm/webpack:/Debug/DebugFlags.ts","node_modules/excalibur/build/esm/webpack:/Debug/Debug.ts","node_modules/excalibur/build/esm/webpack:/Util/Browser.ts","node_modules/excalibur/build/esm/webpack:/Math/global-coordinates.ts","node_modules/excalibur/build/esm/webpack:/Input/PointerEvent.ts","node_modules/excalibur/build/esm/webpack:/Input/WheelEvent.ts","node_modules/excalibur/build/esm/webpack:/Input/PointerAbstraction.ts","node_modules/excalibur/build/esm/webpack:/Input/WheelDeltaMode.ts","node_modules/excalibur/build/esm/webpack:/Input/NativePointerButton.ts","node_modules/excalibur/build/esm/webpack:/Input/PointerButton.ts","node_modules/excalibur/build/esm/webpack:/Input/PointerType.ts","node_modules/excalibur/build/esm/webpack:/Input/PointerEventReceiver.ts","node_modules/excalibur/build/esm/webpack:/Util/Fps.ts","node_modules/excalibur/build/esm/webpack:/Util/Clock.ts","node_modules/excalibur/build/esm/webpack:/Util/Toaster.ts","node_modules/excalibur/build/esm/webpack:/Input/InputMapper.ts","node_modules/excalibur/build/esm/webpack:/Engine.ts","node_modules/excalibur/build/esm/webpack:/Math/Index.ts","node_modules/excalibur/build/esm/webpack:/Debug/index.ts","node_modules/excalibur/build/esm/webpack:/EventDispatcher.ts","node_modules/excalibur/build/esm/webpack:/Label.ts","node_modules/excalibur/build/esm/webpack:/TileMap/IsometricMap.ts","node_modules/excalibur/build/esm/webpack:/TileMap/index.ts","node_modules/excalibur/build/esm/webpack:/Actions/Action/ActionSequence.ts","node_modules/excalibur/build/esm/webpack:/Actions/Action/ParallelActions.ts","node_modules/excalibur/build/esm/webpack:/Actions/Index.ts","node_modules/excalibur/build/esm/webpack:/Collision/Group/CollisionGroupManager.ts","node_modules/excalibur/build/esm/webpack:/Collision/Index.ts","node_modules/excalibur/build/esm/webpack:/Interfaces/LifecycleEvents.ts","node_modules/excalibur/build/esm/webpack:/Interfaces/Index.ts","node_modules/excalibur/build/esm/webpack:/Resources/Sound/Index.ts","node_modules/excalibur/build/esm/webpack:/Resources/Gif.ts","node_modules/excalibur/build/esm/webpack:/Resources/Index.ts","node_modules/excalibur/build/esm/webpack:/EntityComponentSystem/index.ts","node_modules/excalibur/build/esm/webpack:/Graphics/Line.ts","node_modules/excalibur/build/esm/webpack:/Graphics/Polygon.ts","node_modules/excalibur/build/esm/webpack:/Graphics/index.ts","node_modules/excalibur/build/esm/webpack:/Input/Index.ts","node_modules/excalibur/build/esm/webpack:/Util/Index.ts","node_modules/excalibur/build/esm/webpack:/Util/Semaphore.ts","node_modules/excalibur/build/esm/webpack:/index.ts","src/resources.ts","node_modules/@parcel/runtime-js/lib/runtime-398c9c75c5d4a358.js","node_modules/@parcel/runtime-js/lib/runtime-bfce72378bec8961.js","node_modules/@parcel/runtime-js/lib/runtime-f2af8eacc54ed114.js","node_modules/@parcel/runtime-js/lib/runtime-46377631e4d06a98.js","node_modules/@parcel/runtime-js/lib/runtime-23a957a9edb060ab.js","node_modules/@parcel/runtime-js/lib/runtime-63e2c7023ea3f58e.js","node_modules/@parcel/runtime-js/lib/runtime-670596d4989d6aed.js","node_modules/@parcel/runtime-js/lib/runtime-777e54d247f361a6.js","node_modules/@parcel/runtime-js/lib/runtime-1f46b3b7b93124c5.js","node_modules/@parcel/runtime-js/lib/runtime-e36bd3f65b2d10ba.js","node_modules/@parcel/runtime-js/lib/runtime-fedd81de15167b14.js","node_modules/@parcel/runtime-js/lib/runtime-ec5f6d95c20b101b.js","node_modules/@parcel/runtime-js/lib/runtime-b3360aba47101e22.js","node_modules/@parcel/runtime-js/lib/runtime-7ac1dd5dca35faaa.js","node_modules/@parcel/runtime-js/lib/runtime-0865fc6deccd2e07.js","node_modules/@parcel/runtime-js/lib/runtime-dacf0526456760f1.js","node_modules/@parcel/runtime-js/lib/runtime-4b875ac248be21ad.js","node_modules/@parcel/runtime-js/lib/runtime-efd2308206a20fdc.js","node_modules/@parcel/runtime-js/lib/runtime-e886a9710f52ee14.js","node_modules/@parcel/runtime-js/lib/runtime-b425902a148422eb.js","src/levels/level-base.ts","src/board.ts","src/cell.ts","src/config.ts","src/path-finding/path-node-component.ts","src/path-finding/path-finding-system.ts","src/unit.ts","src/dust-particles.ts","src/damage-manager.ts","src/animation-manager.ts","src/human-player.ts","src/player.ts","src/selection-manager.ts","src/ui-manager.ts","src/ui-components/unit-menu.ts","node_modules/tslib/tslib.es6.js","node_modules/@lit/reactive-element/reactive-element.js","node_modules/@lit/reactive-element/src/reactive-element.ts","node_modules/@lit/reactive-element/css-tag.js","node_modules/@lit/reactive-element/src/css-tag.ts","node_modules/lit-html/lit-html.js","node_modules/lit-html/src/lit-html.ts","node_modules/lit-element/lit-element.js","node_modules/lit-element/src/lit-element.ts","node_modules/lit-html/is-server.js","node_modules/lit-html/src/is-server.ts","node_modules/@lit/reactive-element/decorators/custom-element.js","node_modules/@lit/reactive-element/src/decorators/custom-element.ts","node_modules/@lit/reactive-element/decorators/property.js","node_modules/@lit/reactive-element/src/decorators/property.ts","node_modules/@lit/reactive-element/decorators/state.js","node_modules/@lit/reactive-element/src/decorators/state.ts","node_modules/@lit/reactive-element/decorators/event-options.js","node_modules/@lit/reactive-element/src/decorators/event-options.ts","node_modules/@lit/reactive-element/decorators/query.js","node_modules/@lit/reactive-element/src/decorators/query.ts","node_modules/@lit/reactive-element/decorators/base.js","node_modules/@lit/reactive-element/src/decorators/base.ts","node_modules/@lit/reactive-element/decorators/query-all.js","node_modules/@lit/reactive-element/src/decorators/query-all.ts","node_modules/@lit/reactive-element/decorators/query-async.js","node_modules/@lit/reactive-element/src/decorators/query-async.ts","node_modules/@lit/reactive-element/decorators/query-assigned-elements.js","node_modules/@lit/reactive-element/src/decorators/query-assigned-elements.ts","node_modules/@lit/reactive-element/decorators/query-assigned-nodes.js","node_modules/@lit/reactive-element/src/decorators/query-assigned-nodes.ts","node_modules/lit-html/directives/style-map.js","node_modules/lit-html/src/directives/style-map.ts","node_modules/lit-html/directive.js","node_modules/lit-html/src/directive.ts","node_modules/lit-html/directives/class-map.js","node_modules/lit-html/src/directives/class-map.ts","src/turn-manager.ts","src/computer-player.ts","src/cloud.ts","src/levels/start-screen.ts","src/levels/tutorial.ts","src/ui-components/audio-menu.ts","src/audio-manager.ts"],"sourcesContent":["\nfunction $parcel$interopDefault(a) {\n return a && a.__esModule ? a.default : a;\n}\n/*!\n * excalibur - 0.28.0 - 2023-8-10\n * https://github.com/excaliburjs/Excalibur\n * Copyright (c) 2023 Excalibur.js \n * Licensed BSD-2-Clause\n * @preserve\n */ /******/ var $2c23f148d58cd887$var$__webpack_modules__ = {\n /***/ 4662: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n __webpack_require__(3430);\n var entryUnbind = __webpack_require__(8791);\n module.exports = entryUnbind(\"Array\", \"sort\");\n /***/ },\n /***/ 8343: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n __webpack_require__(4769);\n var path = __webpack_require__(9276);\n module.exports = path.Object.keys;\n /***/ },\n /***/ 7111: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var isCallable = __webpack_require__(6733);\n var tryToString = __webpack_require__(9821);\n var $TypeError = TypeError;\n // `Assert: IsCallable(argument) is true`\n module.exports = function(argument) {\n if (isCallable(argument)) return argument;\n throw $TypeError(tryToString(argument) + \" is not a function\");\n };\n /***/ },\n /***/ 1176: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var isObject = __webpack_require__(5052);\n var $String = String;\n var $TypeError = TypeError;\n // `Assert: Type(argument) is Object`\n module.exports = function(argument) {\n if (isObject(argument)) return argument;\n throw $TypeError($String(argument) + \" is not an object\");\n };\n /***/ },\n /***/ 9540: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var toIndexedObject = __webpack_require__(905);\n var toAbsoluteIndex = __webpack_require__(3231);\n var lengthOfArrayLike = __webpack_require__(9646);\n // `Array.prototype.{ indexOf, includes }` methods implementation\n var createMethod = function(IS_INCLUDES) {\n return function($this, el, fromIndex) {\n var O = toIndexedObject($this);\n var length = lengthOfArrayLike(O);\n var index = toAbsoluteIndex(fromIndex, length);\n var value;\n // Array#includes uses SameValueZero equality algorithm\n // eslint-disable-next-line no-self-compare -- NaN check\n if (IS_INCLUDES && el != el) while(length > index){\n value = O[index++];\n // eslint-disable-next-line no-self-compare -- NaN check\n if (value != value) return true;\n // Array#indexOf ignores holes, Array#includes - not\n }\n else for(; length > index; index++){\n if ((IS_INCLUDES || index in O) && O[index] === el) return IS_INCLUDES || index || 0;\n }\n return !IS_INCLUDES && -1;\n };\n };\n module.exports = {\n // `Array.prototype.includes` method\n // https://tc39.es/ecma262/#sec-array.prototype.includes\n includes: createMethod(true),\n // `Array.prototype.indexOf` method\n // https://tc39.es/ecma262/#sec-array.prototype.indexof\n indexOf: createMethod(false)\n };\n /***/ },\n /***/ 6038: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var fails = __webpack_require__(4229);\n module.exports = function(METHOD_NAME, argument) {\n var method = [][METHOD_NAME];\n return !!method && fails(function() {\n // eslint-disable-next-line no-useless-call -- required for testing\n method.call(null, argument || function() {\n return 1;\n }, 1);\n });\n };\n /***/ },\n /***/ 9794: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var toAbsoluteIndex = __webpack_require__(3231);\n var lengthOfArrayLike = __webpack_require__(9646);\n var createProperty = __webpack_require__(2324);\n var $Array = Array;\n var max = Math.max;\n module.exports = function(O, start, end) {\n var length = lengthOfArrayLike(O);\n var k = toAbsoluteIndex(start, length);\n var fin = toAbsoluteIndex(end === undefined ? length : end, length);\n var result = $Array(max(fin - k, 0));\n for(var n = 0; k < fin; k++, n++)createProperty(result, n, O[k]);\n result.length = n;\n return result;\n };\n /***/ },\n /***/ 3867: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var arraySlice = __webpack_require__(9794);\n var floor = Math.floor;\n var mergeSort = function(array, comparefn) {\n var length = array.length;\n var middle = floor(length / 2);\n return length < 8 ? insertionSort(array, comparefn) : merge(array, mergeSort(arraySlice(array, 0, middle), comparefn), mergeSort(arraySlice(array, middle), comparefn), comparefn);\n };\n var insertionSort = function(array, comparefn) {\n var length = array.length;\n var i = 1;\n var element, j;\n while(i < length){\n j = i;\n element = array[i];\n while(j && comparefn(array[j - 1], element) > 0)array[j] = array[--j];\n if (j !== i++) array[j] = element;\n }\n return array;\n };\n var merge = function(array, left, right, comparefn) {\n var llength = left.length;\n var rlength = right.length;\n var lindex = 0;\n var rindex = 0;\n while(lindex < llength || rindex < rlength)array[lindex + rindex] = lindex < llength && rindex < rlength ? comparefn(left[lindex], right[rindex]) <= 0 ? left[lindex++] : right[rindex++] : lindex < llength ? left[lindex++] : right[rindex++];\n return array;\n };\n module.exports = mergeSort;\n /***/ },\n /***/ 7079: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var uncurryThis = __webpack_require__(5968);\n var toString = uncurryThis({}.toString);\n var stringSlice = uncurryThis(\"\".slice);\n module.exports = function(it) {\n return stringSlice(toString(it), 8, -1);\n };\n /***/ },\n /***/ 1589: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var TO_STRING_TAG_SUPPORT = __webpack_require__(1601);\n var isCallable = __webpack_require__(6733);\n var classofRaw = __webpack_require__(7079);\n var wellKnownSymbol = __webpack_require__(95);\n var TO_STRING_TAG = wellKnownSymbol(\"toStringTag\");\n var $Object = Object;\n // ES3 wrong here\n var CORRECT_ARGUMENTS = classofRaw(function() {\n return arguments;\n }()) == \"Arguments\";\n // fallback for IE11 Script Access Denied error\n var tryGet = function(it, key) {\n try {\n return it[key];\n } catch (error) {}\n };\n // getting tag from ES6+ `Object.prototype.toString`\n module.exports = TO_STRING_TAG_SUPPORT ? classofRaw : function(it) {\n var O, tag, result;\n return it === undefined ? \"Undefined\" : it === null ? \"Null\" : typeof (tag = tryGet(O = $Object(it), TO_STRING_TAG)) == \"string\" ? tag : CORRECT_ARGUMENTS ? classofRaw(O) : (result = classofRaw(O)) == \"Object\" && isCallable(O.callee) ? \"Arguments\" : result;\n };\n /***/ },\n /***/ 7081: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var hasOwn = __webpack_require__(8270);\n var ownKeys = __webpack_require__(4826);\n var getOwnPropertyDescriptorModule = __webpack_require__(7933);\n var definePropertyModule = __webpack_require__(1787);\n module.exports = function(target, source, exceptions) {\n var keys = ownKeys(source);\n var defineProperty = definePropertyModule.f;\n var getOwnPropertyDescriptor = getOwnPropertyDescriptorModule.f;\n for(var i = 0; i < keys.length; i++){\n var key = keys[i];\n if (!hasOwn(target, key) && !(exceptions && hasOwn(exceptions, key))) defineProperty(target, key, getOwnPropertyDescriptor(source, key));\n }\n };\n /***/ },\n /***/ 5762: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var DESCRIPTORS = __webpack_require__(7400);\n var definePropertyModule = __webpack_require__(1787);\n var createPropertyDescriptor = __webpack_require__(5358);\n module.exports = DESCRIPTORS ? function(object, key, value) {\n return definePropertyModule.f(object, key, createPropertyDescriptor(1, value));\n } : function(object, key, value) {\n object[key] = value;\n return object;\n };\n /***/ },\n /***/ 5358: /***/ (module)=>{\n module.exports = function(bitmap, value) {\n return {\n enumerable: !(bitmap & 1),\n configurable: !(bitmap & 2),\n writable: !(bitmap & 4),\n value: value\n };\n };\n /***/ },\n /***/ 2324: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var toPropertyKey = __webpack_require__(9310);\n var definePropertyModule = __webpack_require__(1787);\n var createPropertyDescriptor = __webpack_require__(5358);\n module.exports = function(object, key, value) {\n var propertyKey = toPropertyKey(key);\n if (propertyKey in object) definePropertyModule.f(object, propertyKey, createPropertyDescriptor(0, value));\n else object[propertyKey] = value;\n };\n /***/ },\n /***/ 4768: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var isCallable = __webpack_require__(6733);\n var definePropertyModule = __webpack_require__(1787);\n var makeBuiltIn = __webpack_require__(6039);\n var defineGlobalProperty = __webpack_require__(8400);\n module.exports = function(O, key, value, options) {\n if (!options) options = {};\n var simple = options.enumerable;\n var name = options.name !== undefined ? options.name : key;\n if (isCallable(value)) makeBuiltIn(value, name, options);\n if (options.global) {\n if (simple) O[key] = value;\n else defineGlobalProperty(key, value);\n } else {\n try {\n if (!options.unsafe) delete O[key];\n else if (O[key]) simple = true;\n } catch (error) {}\n if (simple) O[key] = value;\n else definePropertyModule.f(O, key, {\n value: value,\n enumerable: false,\n configurable: !options.nonConfigurable,\n writable: !options.nonWritable\n });\n }\n return O;\n };\n /***/ },\n /***/ 8400: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var global = __webpack_require__(9859);\n // eslint-disable-next-line es/no-object-defineproperty -- safe\n var defineProperty = Object.defineProperty;\n module.exports = function(key, value) {\n try {\n defineProperty(global, key, {\n value: value,\n configurable: true,\n writable: true\n });\n } catch (error) {\n global[key] = value;\n }\n return value;\n };\n /***/ },\n /***/ 9563: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var tryToString = __webpack_require__(9821);\n var $TypeError = TypeError;\n module.exports = function(O, P) {\n if (!delete O[P]) throw $TypeError(\"Cannot delete property \" + tryToString(P) + \" of \" + tryToString(O));\n };\n /***/ },\n /***/ 7400: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var fails = __webpack_require__(4229);\n // Detect IE8's incomplete defineProperty implementation\n module.exports = !fails(function() {\n // eslint-disable-next-line es/no-object-defineproperty -- required for testing\n return Object.defineProperty({}, 1, {\n get: function() {\n return 7;\n }\n })[1] != 7;\n });\n /***/ },\n /***/ 3777: /***/ (module)=>{\n var documentAll = typeof document == \"object\" && document.all;\n // https://tc39.es/ecma262/#sec-IsHTMLDDA-internal-slot\n // eslint-disable-next-line unicorn/no-typeof-undefined -- required for testing\n var IS_HTMLDDA = typeof documentAll == \"undefined\" && documentAll !== undefined;\n module.exports = {\n all: documentAll,\n IS_HTMLDDA: IS_HTMLDDA\n };\n /***/ },\n /***/ 2635: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var global = __webpack_require__(9859);\n var isObject = __webpack_require__(5052);\n var document1 = global.document;\n // typeof document.createElement is 'object' in old IE\n var EXISTS = isObject(document1) && isObject(document1.createElement);\n module.exports = function(it) {\n return EXISTS ? document1.createElement(it) : {};\n };\n /***/ },\n /***/ 2671: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var userAgent = __webpack_require__(598);\n var firefox = userAgent.match(/firefox\\/(\\d+)/i);\n module.exports = !!firefox && +firefox[1];\n /***/ },\n /***/ 8506: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var UA = __webpack_require__(598);\n module.exports = /MSIE|Trident/.test(UA);\n /***/ },\n /***/ 598: /***/ (module)=>{\n module.exports = typeof navigator != \"undefined\" && String(navigator.userAgent) || \"\";\n /***/ },\n /***/ 5884: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var global = __webpack_require__(9859);\n var userAgent = __webpack_require__(598);\n var process = global.process;\n var Deno = global.Deno;\n var versions = process && process.versions || Deno && Deno.version;\n var v8 = versions && versions.v8;\n var match, version;\n if (v8) {\n match = v8.split(\".\");\n // in old Chrome, versions of V8 isn't V8 = Chrome / 10\n // but their correct versions are not interesting for us\n version = match[0] > 0 && match[0] < 4 ? 1 : +(match[0] + match[1]);\n }\n // BrowserFS NodeJS `process` polyfill incorrectly set `.v8` to `0.0`\n // so check `userAgent` even if `.v8` exists, but 0\n if (!version && userAgent) {\n match = userAgent.match(/Edge\\/(\\d+)/);\n if (!match || match[1] >= 74) {\n match = userAgent.match(/Chrome\\/(\\d+)/);\n if (match) version = +match[1];\n }\n }\n module.exports = version;\n /***/ },\n /***/ 9811: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var userAgent = __webpack_require__(598);\n var webkit = userAgent.match(/AppleWebKit\\/(\\d+)\\./);\n module.exports = !!webkit && +webkit[1];\n /***/ },\n /***/ 8791: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var global = __webpack_require__(9859);\n var uncurryThis = __webpack_require__(5968);\n module.exports = function(CONSTRUCTOR, METHOD) {\n return uncurryThis(global[CONSTRUCTOR].prototype[METHOD]);\n };\n /***/ },\n /***/ 3837: /***/ (module)=>{\n // IE8- don't enum bug keys\n module.exports = [\n \"constructor\",\n \"hasOwnProperty\",\n \"isPrototypeOf\",\n \"propertyIsEnumerable\",\n \"toLocaleString\",\n \"toString\",\n \"valueOf\"\n ];\n /***/ },\n /***/ 3103: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var global = __webpack_require__(9859);\n var getOwnPropertyDescriptor = __webpack_require__(7933).f;\n var createNonEnumerableProperty = __webpack_require__(5762);\n var defineBuiltIn = __webpack_require__(4768);\n var defineGlobalProperty = __webpack_require__(8400);\n var copyConstructorProperties = __webpack_require__(7081);\n var isForced = __webpack_require__(6541);\n /*\n options.target - name of the target object\n options.global - target is the global object\n options.stat - export as static methods of target\n options.proto - export as prototype methods of target\n options.real - real prototype method for the `pure` version\n options.forced - export even if the native feature is available\n options.bind - bind methods to the target, required for the `pure` version\n options.wrap - wrap constructors to preventing global pollution, required for the `pure` version\n options.unsafe - use the simple assignment of property instead of delete + defineProperty\n options.sham - add a flag to not completely full polyfills\n options.enumerable - export as enumerable property\n options.dontCallGetSet - prevent calling a getter on target\n options.name - the .name of the function if it does not match the key\n*/ module.exports = function(options, source) {\n var TARGET = options.target;\n var GLOBAL = options.global;\n var STATIC = options.stat;\n var FORCED, target, key, targetProperty, sourceProperty, descriptor;\n if (GLOBAL) target = global;\n else if (STATIC) target = global[TARGET] || defineGlobalProperty(TARGET, {});\n else target = (global[TARGET] || {}).prototype;\n if (target) for(key in source){\n sourceProperty = source[key];\n if (options.dontCallGetSet) {\n descriptor = getOwnPropertyDescriptor(target, key);\n targetProperty = descriptor && descriptor.value;\n } else targetProperty = target[key];\n FORCED = isForced(GLOBAL ? key : TARGET + (STATIC ? \".\" : \"#\") + key, options.forced);\n // contained in target\n if (!FORCED && targetProperty !== undefined) {\n if (typeof sourceProperty == typeof targetProperty) continue;\n copyConstructorProperties(sourceProperty, targetProperty);\n }\n // add a flag to not completely full polyfills\n if (options.sham || targetProperty && targetProperty.sham) createNonEnumerableProperty(sourceProperty, \"sham\", true);\n defineBuiltIn(target, key, sourceProperty, options);\n }\n };\n /***/ },\n /***/ 4229: /***/ (module)=>{\n module.exports = function(exec) {\n try {\n return !!exec();\n } catch (error) {\n return true;\n }\n };\n /***/ },\n /***/ 7188: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var fails = __webpack_require__(4229);\n module.exports = !fails(function() {\n // eslint-disable-next-line es/no-function-prototype-bind -- safe\n var test = (function() {}).bind();\n // eslint-disable-next-line no-prototype-builtins -- safe\n return typeof test != \"function\" || test.hasOwnProperty(\"prototype\");\n });\n /***/ },\n /***/ 266: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var NATIVE_BIND = __webpack_require__(7188);\n var call = Function.prototype.call;\n module.exports = NATIVE_BIND ? call.bind(call) : function() {\n return call.apply(call, arguments);\n };\n /***/ },\n /***/ 1805: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var DESCRIPTORS = __webpack_require__(7400);\n var hasOwn = __webpack_require__(8270);\n var FunctionPrototype = Function.prototype;\n // eslint-disable-next-line es/no-object-getownpropertydescriptor -- safe\n var getDescriptor = DESCRIPTORS && Object.getOwnPropertyDescriptor;\n var EXISTS = hasOwn(FunctionPrototype, \"name\");\n // additional protection from minified / mangled / dropped function names\n var PROPER = EXISTS && (function something() {}).name === \"something\";\n var CONFIGURABLE = EXISTS && (!DESCRIPTORS || DESCRIPTORS && getDescriptor(FunctionPrototype, \"name\").configurable);\n module.exports = {\n EXISTS: EXISTS,\n PROPER: PROPER,\n CONFIGURABLE: CONFIGURABLE\n };\n /***/ },\n /***/ 5968: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var NATIVE_BIND = __webpack_require__(7188);\n var FunctionPrototype = Function.prototype;\n var call = FunctionPrototype.call;\n var uncurryThisWithBind = NATIVE_BIND && FunctionPrototype.bind.bind(call, call);\n module.exports = NATIVE_BIND ? uncurryThisWithBind : function(fn) {\n return function() {\n return call.apply(fn, arguments);\n };\n };\n /***/ },\n /***/ 1333: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var global = __webpack_require__(9859);\n var isCallable = __webpack_require__(6733);\n var aFunction = function(argument) {\n return isCallable(argument) ? argument : undefined;\n };\n module.exports = function(namespace, method) {\n return arguments.length < 2 ? aFunction(global[namespace]) : global[namespace] && global[namespace][method];\n };\n /***/ },\n /***/ 5300: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var aCallable = __webpack_require__(7111);\n var isNullOrUndefined = __webpack_require__(9650);\n // `GetMethod` abstract operation\n // https://tc39.es/ecma262/#sec-getmethod\n module.exports = function(V, P) {\n var func = V[P];\n return isNullOrUndefined(func) ? undefined : aCallable(func);\n };\n /***/ },\n /***/ 9859: /***/ function(module, __unused_webpack_exports, __webpack_require__) {\n var check = function(it) {\n return it && it.Math == Math && it;\n };\n // https://github.com/zloirock/core-js/issues/86#issuecomment-115759028\n module.exports = // eslint-disable-next-line es/no-global-this -- safe\n check(typeof globalThis == \"object\" && globalThis) || check(typeof window == \"object\" && window) || // eslint-disable-next-line no-restricted-globals -- safe\n check(typeof self == \"object\" && self) || check(typeof __webpack_require__.g == \"object\" && __webpack_require__.g) || // eslint-disable-next-line no-new-func -- fallback\n function() {\n return this;\n }() || this || Function(\"return this\")();\n /***/ },\n /***/ 8270: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var uncurryThis = __webpack_require__(5968);\n var toObject = __webpack_require__(2991);\n var hasOwnProperty = uncurryThis({}.hasOwnProperty);\n // `HasOwnProperty` abstract operation\n // https://tc39.es/ecma262/#sec-hasownproperty\n // eslint-disable-next-line es/no-object-hasown -- safe\n module.exports = Object.hasOwn || function hasOwn(it, key) {\n return hasOwnProperty(toObject(it), key);\n };\n /***/ },\n /***/ 5977: /***/ (module)=>{\n module.exports = {};\n /***/ },\n /***/ 4394: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var DESCRIPTORS = __webpack_require__(7400);\n var fails = __webpack_require__(4229);\n var createElement = __webpack_require__(2635);\n // Thanks to IE8 for its funny defineProperty\n module.exports = !DESCRIPTORS && !fails(function() {\n // eslint-disable-next-line es/no-object-defineproperty -- required for testing\n return Object.defineProperty(createElement(\"div\"), \"a\", {\n get: function() {\n return 7;\n }\n }).a != 7;\n });\n /***/ },\n /***/ 9337: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var uncurryThis = __webpack_require__(5968);\n var fails = __webpack_require__(4229);\n var classof = __webpack_require__(7079);\n var $Object = Object;\n var split = uncurryThis(\"\".split);\n // fallback for non-array-like ES3 and non-enumerable old V8 strings\n module.exports = fails(function() {\n // throws an error in rhino, see https://github.com/mozilla/rhino/issues/346\n // eslint-disable-next-line no-prototype-builtins -- safe\n return !$Object(\"z\").propertyIsEnumerable(0);\n }) ? function(it) {\n return classof(it) == \"String\" ? split(it, \"\") : $Object(it);\n } : $Object;\n /***/ },\n /***/ 8511: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var uncurryThis = __webpack_require__(5968);\n var isCallable = __webpack_require__(6733);\n var store = __webpack_require__(5353);\n var functionToString = uncurryThis(Function.toString);\n // this helper broken in `core-js@3.4.1-3.4.4`, so we can't use `shared` helper\n if (!isCallable(store.inspectSource)) store.inspectSource = function(it) {\n return functionToString(it);\n };\n module.exports = store.inspectSource;\n /***/ },\n /***/ 6407: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var NATIVE_WEAK_MAP = __webpack_require__(1180);\n var global = __webpack_require__(9859);\n var isObject = __webpack_require__(5052);\n var createNonEnumerableProperty = __webpack_require__(5762);\n var hasOwn = __webpack_require__(8270);\n var shared = __webpack_require__(5353);\n var sharedKey = __webpack_require__(4399);\n var hiddenKeys = __webpack_require__(5977);\n var OBJECT_ALREADY_INITIALIZED = \"Object already initialized\";\n var TypeError1 = global.TypeError;\n var WeakMap1 = global.WeakMap;\n var set, get, has;\n var enforce = function(it) {\n return has(it) ? get(it) : set(it, {});\n };\n var getterFor = function(TYPE) {\n return function(it) {\n var state;\n if (!isObject(it) || (state = get(it)).type !== TYPE) throw TypeError1(\"Incompatible receiver, \" + TYPE + \" required\");\n return state;\n };\n };\n if (NATIVE_WEAK_MAP || shared.state) {\n var store = shared.state || (shared.state = new WeakMap1());\n /* eslint-disable no-self-assign -- prototype methods protection */ store.get = store.get;\n store.has = store.has;\n store.set = store.set;\n /* eslint-enable no-self-assign -- prototype methods protection */ set = function(it, metadata) {\n if (store.has(it)) throw TypeError1(OBJECT_ALREADY_INITIALIZED);\n metadata.facade = it;\n store.set(it, metadata);\n return metadata;\n };\n get = function(it) {\n return store.get(it) || {};\n };\n has = function(it) {\n return store.has(it);\n };\n } else {\n var STATE = sharedKey(\"state\");\n hiddenKeys[STATE] = true;\n set = function(it, metadata) {\n if (hasOwn(it, STATE)) throw TypeError1(OBJECT_ALREADY_INITIALIZED);\n metadata.facade = it;\n createNonEnumerableProperty(it, STATE, metadata);\n return metadata;\n };\n get = function(it) {\n return hasOwn(it, STATE) ? it[STATE] : {};\n };\n has = function(it) {\n return hasOwn(it, STATE);\n };\n }\n module.exports = {\n set: set,\n get: get,\n has: has,\n enforce: enforce,\n getterFor: getterFor\n };\n /***/ },\n /***/ 6733: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var $documentAll = __webpack_require__(3777);\n var documentAll = $documentAll.all;\n // `IsCallable` abstract operation\n // https://tc39.es/ecma262/#sec-iscallable\n module.exports = $documentAll.IS_HTMLDDA ? function(argument) {\n return typeof argument == \"function\" || argument === documentAll;\n } : function(argument) {\n return typeof argument == \"function\";\n };\n /***/ },\n /***/ 6541: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var fails = __webpack_require__(4229);\n var isCallable = __webpack_require__(6733);\n var replacement = /#|\\.prototype\\./;\n var isForced = function(feature, detection) {\n var value = data[normalize(feature)];\n return value == POLYFILL ? true : value == NATIVE ? false : isCallable(detection) ? fails(detection) : !!detection;\n };\n var normalize = isForced.normalize = function(string) {\n return String(string).replace(replacement, \".\").toLowerCase();\n };\n var data = isForced.data = {};\n var NATIVE = isForced.NATIVE = \"N\";\n var POLYFILL = isForced.POLYFILL = \"P\";\n module.exports = isForced;\n /***/ },\n /***/ 9650: /***/ (module)=>{\n // we can't use just `it == null` since of `document.all` special case\n // https://tc39.es/ecma262/#sec-IsHTMLDDA-internal-slot-aec\n module.exports = function(it) {\n return it === null || it === undefined;\n };\n /***/ },\n /***/ 5052: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var isCallable = __webpack_require__(6733);\n var $documentAll = __webpack_require__(3777);\n var documentAll = $documentAll.all;\n module.exports = $documentAll.IS_HTMLDDA ? function(it) {\n return typeof it == \"object\" ? it !== null : isCallable(it) || it === documentAll;\n } : function(it) {\n return typeof it == \"object\" ? it !== null : isCallable(it);\n };\n /***/ },\n /***/ 4231: /***/ (module)=>{\n module.exports = false;\n /***/ },\n /***/ 9395: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var getBuiltIn = __webpack_require__(1333);\n var isCallable = __webpack_require__(6733);\n var isPrototypeOf = __webpack_require__(1321);\n var USE_SYMBOL_AS_UID = __webpack_require__(6969);\n var $Object = Object;\n module.exports = USE_SYMBOL_AS_UID ? function(it) {\n return typeof it == \"symbol\";\n } : function(it) {\n var $Symbol = getBuiltIn(\"Symbol\");\n return isCallable($Symbol) && isPrototypeOf($Symbol.prototype, $Object(it));\n };\n /***/ },\n /***/ 9646: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var toLength = __webpack_require__(4237);\n // `LengthOfArrayLike` abstract operation\n // https://tc39.es/ecma262/#sec-lengthofarraylike\n module.exports = function(obj) {\n return toLength(obj.length);\n };\n /***/ },\n /***/ 6039: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var uncurryThis = __webpack_require__(5968);\n var fails = __webpack_require__(4229);\n var isCallable = __webpack_require__(6733);\n var hasOwn = __webpack_require__(8270);\n var DESCRIPTORS = __webpack_require__(7400);\n var CONFIGURABLE_FUNCTION_NAME = __webpack_require__(1805).CONFIGURABLE;\n var inspectSource = __webpack_require__(8511);\n var InternalStateModule = __webpack_require__(6407);\n var enforceInternalState = InternalStateModule.enforce;\n var getInternalState = InternalStateModule.get;\n var $String = String;\n // eslint-disable-next-line es/no-object-defineproperty -- safe\n var defineProperty = Object.defineProperty;\n var stringSlice = uncurryThis(\"\".slice);\n var replace = uncurryThis(\"\".replace);\n var join = uncurryThis([].join);\n var CONFIGURABLE_LENGTH = DESCRIPTORS && !fails(function() {\n return defineProperty(function() {}, \"length\", {\n value: 8\n }).length !== 8;\n });\n var TEMPLATE = String(String).split(\"String\");\n var makeBuiltIn = module.exports = function(value, name, options) {\n if (stringSlice($String(name), 0, 7) === \"Symbol(\") name = \"[\" + replace($String(name), /^Symbol\\(([^)]*)\\)/, \"$1\") + \"]\";\n if (options && options.getter) name = \"get \" + name;\n if (options && options.setter) name = \"set \" + name;\n if (!hasOwn(value, \"name\") || CONFIGURABLE_FUNCTION_NAME && value.name !== name) {\n if (DESCRIPTORS) defineProperty(value, \"name\", {\n value: name,\n configurable: true\n });\n else value.name = name;\n }\n if (CONFIGURABLE_LENGTH && options && hasOwn(options, \"arity\") && value.length !== options.arity) defineProperty(value, \"length\", {\n value: options.arity\n });\n try {\n if (options && hasOwn(options, \"constructor\") && options.constructor) {\n if (DESCRIPTORS) defineProperty(value, \"prototype\", {\n writable: false\n });\n } else if (value.prototype) value.prototype = undefined;\n } catch (error) {}\n var state = enforceInternalState(value);\n if (!hasOwn(state, \"source\")) state.source = join(TEMPLATE, typeof name == \"string\" ? name : \"\");\n return value;\n };\n // add fake Function#toString for correct work wrapped methods / constructors with methods like LoDash isNative\n // eslint-disable-next-line no-extend-native -- required\n Function.prototype.toString = makeBuiltIn(function toString() {\n return isCallable(this) && getInternalState(this).source || inspectSource(this);\n }, \"toString\");\n /***/ },\n /***/ 917: /***/ (module)=>{\n var ceil = Math.ceil;\n var floor = Math.floor;\n // `Math.trunc` method\n // https://tc39.es/ecma262/#sec-math.trunc\n // eslint-disable-next-line es/no-math-trunc -- safe\n module.exports = Math.trunc || function trunc(x) {\n var n = +x;\n return (n > 0 ? floor : ceil)(n);\n };\n /***/ },\n /***/ 1787: /***/ (__unused_webpack_module, exports, __webpack_require__)=>{\n var DESCRIPTORS = __webpack_require__(7400);\n var IE8_DOM_DEFINE = __webpack_require__(4394);\n var V8_PROTOTYPE_DEFINE_BUG = __webpack_require__(7137);\n var anObject = __webpack_require__(1176);\n var toPropertyKey = __webpack_require__(9310);\n var $TypeError = TypeError;\n // eslint-disable-next-line es/no-object-defineproperty -- safe\n var $defineProperty = Object.defineProperty;\n // eslint-disable-next-line es/no-object-getownpropertydescriptor -- safe\n var $getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;\n var ENUMERABLE = \"enumerable\";\n var CONFIGURABLE = \"configurable\";\n var WRITABLE = \"writable\";\n // `Object.defineProperty` method\n // https://tc39.es/ecma262/#sec-object.defineproperty\n exports.f = DESCRIPTORS ? V8_PROTOTYPE_DEFINE_BUG ? function defineProperty(O, P, Attributes) {\n anObject(O);\n P = toPropertyKey(P);\n anObject(Attributes);\n if (typeof O === \"function\" && P === \"prototype\" && \"value\" in Attributes && WRITABLE in Attributes && !Attributes[WRITABLE]) {\n var current = $getOwnPropertyDescriptor(O, P);\n if (current && current[WRITABLE]) {\n O[P] = Attributes.value;\n Attributes = {\n configurable: CONFIGURABLE in Attributes ? Attributes[CONFIGURABLE] : current[CONFIGURABLE],\n enumerable: ENUMERABLE in Attributes ? Attributes[ENUMERABLE] : current[ENUMERABLE],\n writable: false\n };\n }\n }\n return $defineProperty(O, P, Attributes);\n } : $defineProperty : function defineProperty(O, P, Attributes) {\n anObject(O);\n P = toPropertyKey(P);\n anObject(Attributes);\n if (IE8_DOM_DEFINE) try {\n return $defineProperty(O, P, Attributes);\n } catch (error) {}\n if (\"get\" in Attributes || \"set\" in Attributes) throw $TypeError(\"Accessors not supported\");\n if (\"value\" in Attributes) O[P] = Attributes.value;\n return O;\n };\n /***/ },\n /***/ 7933: /***/ (__unused_webpack_module, exports, __webpack_require__)=>{\n var DESCRIPTORS = __webpack_require__(7400);\n var call = __webpack_require__(266);\n var propertyIsEnumerableModule = __webpack_require__(9195);\n var createPropertyDescriptor = __webpack_require__(5358);\n var toIndexedObject = __webpack_require__(905);\n var toPropertyKey = __webpack_require__(9310);\n var hasOwn = __webpack_require__(8270);\n var IE8_DOM_DEFINE = __webpack_require__(4394);\n // eslint-disable-next-line es/no-object-getownpropertydescriptor -- safe\n var $getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;\n // `Object.getOwnPropertyDescriptor` method\n // https://tc39.es/ecma262/#sec-object.getownpropertydescriptor\n exports.f = DESCRIPTORS ? $getOwnPropertyDescriptor : function getOwnPropertyDescriptor(O, P) {\n O = toIndexedObject(O);\n P = toPropertyKey(P);\n if (IE8_DOM_DEFINE) try {\n return $getOwnPropertyDescriptor(O, P);\n } catch (error) {}\n if (hasOwn(O, P)) return createPropertyDescriptor(!call(propertyIsEnumerableModule.f, O, P), O[P]);\n };\n /***/ },\n /***/ 8151: /***/ (__unused_webpack_module, exports, __webpack_require__)=>{\n var internalObjectKeys = __webpack_require__(140);\n var enumBugKeys = __webpack_require__(3837);\n var hiddenKeys = enumBugKeys.concat(\"length\", \"prototype\");\n // `Object.getOwnPropertyNames` method\n // https://tc39.es/ecma262/#sec-object.getownpropertynames\n // eslint-disable-next-line es/no-object-getownpropertynames -- safe\n exports.f = Object.getOwnPropertyNames || function getOwnPropertyNames(O) {\n return internalObjectKeys(O, hiddenKeys);\n };\n /***/ },\n /***/ 894: /***/ (__unused_webpack_module, exports)=>{\n // eslint-disable-next-line es/no-object-getownpropertysymbols -- safe\n exports.f = Object.getOwnPropertySymbols;\n /***/ },\n /***/ 1321: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var uncurryThis = __webpack_require__(5968);\n module.exports = uncurryThis({}.isPrototypeOf);\n /***/ },\n /***/ 140: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var uncurryThis = __webpack_require__(5968);\n var hasOwn = __webpack_require__(8270);\n var toIndexedObject = __webpack_require__(905);\n var indexOf = __webpack_require__(9540).indexOf;\n var hiddenKeys = __webpack_require__(5977);\n var push = uncurryThis([].push);\n module.exports = function(object, names) {\n var O = toIndexedObject(object);\n var i = 0;\n var result = [];\n var key;\n for(key in O)!hasOwn(hiddenKeys, key) && hasOwn(O, key) && push(result, key);\n // Don't enum bug & hidden keys\n while(names.length > i)if (hasOwn(O, key = names[i++])) ~indexOf(result, key) || push(result, key);\n return result;\n };\n /***/ },\n /***/ 5632: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var internalObjectKeys = __webpack_require__(140);\n var enumBugKeys = __webpack_require__(3837);\n // `Object.keys` method\n // https://tc39.es/ecma262/#sec-object.keys\n // eslint-disable-next-line es/no-object-keys -- safe\n module.exports = Object.keys || function keys(O) {\n return internalObjectKeys(O, enumBugKeys);\n };\n /***/ },\n /***/ 9195: /***/ (__unused_webpack_module, exports)=>{\n var $propertyIsEnumerable = {}.propertyIsEnumerable;\n // eslint-disable-next-line es/no-object-getownpropertydescriptor -- safe\n var getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;\n // Nashorn ~ JDK8 bug\n var NASHORN_BUG = getOwnPropertyDescriptor && !$propertyIsEnumerable.call({\n 1: 2\n }, 1);\n // `Object.prototype.propertyIsEnumerable` method implementation\n // https://tc39.es/ecma262/#sec-object.prototype.propertyisenumerable\n exports.f = NASHORN_BUG ? function propertyIsEnumerable(V) {\n var descriptor = getOwnPropertyDescriptor(this, V);\n return !!descriptor && descriptor.enumerable;\n } : $propertyIsEnumerable;\n /***/ },\n /***/ 2914: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var call = __webpack_require__(266);\n var isCallable = __webpack_require__(6733);\n var isObject = __webpack_require__(5052);\n var $TypeError = TypeError;\n // `OrdinaryToPrimitive` abstract operation\n // https://tc39.es/ecma262/#sec-ordinarytoprimitive\n module.exports = function(input, pref) {\n var fn, val;\n if (pref === \"string\" && isCallable(fn = input.toString) && !isObject(val = call(fn, input))) return val;\n if (isCallable(fn = input.valueOf) && !isObject(val = call(fn, input))) return val;\n if (pref !== \"string\" && isCallable(fn = input.toString) && !isObject(val = call(fn, input))) return val;\n throw $TypeError(\"Can't convert object to primitive value\");\n };\n /***/ },\n /***/ 4826: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var getBuiltIn = __webpack_require__(1333);\n var uncurryThis = __webpack_require__(5968);\n var getOwnPropertyNamesModule = __webpack_require__(8151);\n var getOwnPropertySymbolsModule = __webpack_require__(894);\n var anObject = __webpack_require__(1176);\n var concat = uncurryThis([].concat);\n // all object keys, includes non-enumerable and symbols\n module.exports = getBuiltIn(\"Reflect\", \"ownKeys\") || function ownKeys(it) {\n var keys = getOwnPropertyNamesModule.f(anObject(it));\n var getOwnPropertySymbols = getOwnPropertySymbolsModule.f;\n return getOwnPropertySymbols ? concat(keys, getOwnPropertySymbols(it)) : keys;\n };\n /***/ },\n /***/ 9276: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var global = __webpack_require__(9859);\n module.exports = global;\n /***/ },\n /***/ 8885: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var isNullOrUndefined = __webpack_require__(9650);\n var $TypeError = TypeError;\n // `RequireObjectCoercible` abstract operation\n // https://tc39.es/ecma262/#sec-requireobjectcoercible\n module.exports = function(it) {\n if (isNullOrUndefined(it)) throw $TypeError(\"Can't call method on \" + it);\n return it;\n };\n /***/ },\n /***/ 4399: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var shared = __webpack_require__(3036);\n var uid = __webpack_require__(1441);\n var keys = shared(\"keys\");\n module.exports = function(key) {\n return keys[key] || (keys[key] = uid(key));\n };\n /***/ },\n /***/ 5353: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var global = __webpack_require__(9859);\n var defineGlobalProperty = __webpack_require__(8400);\n var SHARED = \"__core-js_shared__\";\n var store = global[SHARED] || defineGlobalProperty(SHARED, {});\n module.exports = store;\n /***/ },\n /***/ 3036: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var IS_PURE = __webpack_require__(4231);\n var store = __webpack_require__(5353);\n (module.exports = function(key, value) {\n return store[key] || (store[key] = value !== undefined ? value : {});\n })(\"versions\", []).push({\n version: \"3.32.0\",\n mode: IS_PURE ? \"pure\" : \"global\",\n copyright: \"\\xa9 2014-2023 Denis Pushkarev (zloirock.ru)\",\n license: \"https://github.com/zloirock/core-js/blob/v3.32.0/LICENSE\",\n source: \"https://github.com/zloirock/core-js\"\n });\n /***/ },\n /***/ 4860: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n /* eslint-disable es/no-symbol -- required for testing */ var V8_VERSION = __webpack_require__(5884);\n var fails = __webpack_require__(4229);\n var global = __webpack_require__(9859);\n var $String = global.String;\n // eslint-disable-next-line es/no-object-getownpropertysymbols -- required for testing\n module.exports = !!Object.getOwnPropertySymbols && !fails(function() {\n var symbol = Symbol();\n // Chrome 38 Symbol has incorrect toString conversion\n // `get-own-property-symbols` polyfill symbols converted to object are not Symbol instances\n // nb: Do not call `String` directly to avoid this being optimized out to `symbol+''` which will,\n // of course, fail.\n return !$String(symbol) || !(Object(symbol) instanceof Symbol) || // Chrome 38-40 symbols are not inherited from DOM collections prototypes to instances\n !Symbol.sham && V8_VERSION && V8_VERSION < 41;\n });\n /***/ },\n /***/ 3231: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var toIntegerOrInfinity = __webpack_require__(3329);\n var max = Math.max;\n var min = Math.min;\n // Helper for a popular repeating case of the spec:\n // Let integer be ? ToInteger(index).\n // If integer < 0, let result be max((length + integer), 0); else let result be min(integer, length).\n module.exports = function(index, length) {\n var integer = toIntegerOrInfinity(index);\n return integer < 0 ? max(integer + length, 0) : min(integer, length);\n };\n /***/ },\n /***/ 905: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n // toObject with fallback for non-array-like ES3 strings\n var IndexedObject = __webpack_require__(9337);\n var requireObjectCoercible = __webpack_require__(8885);\n module.exports = function(it) {\n return IndexedObject(requireObjectCoercible(it));\n };\n /***/ },\n /***/ 3329: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var trunc = __webpack_require__(917);\n // `ToIntegerOrInfinity` abstract operation\n // https://tc39.es/ecma262/#sec-tointegerorinfinity\n module.exports = function(argument) {\n var number = +argument;\n // eslint-disable-next-line no-self-compare -- NaN check\n return number !== number || number === 0 ? 0 : trunc(number);\n };\n /***/ },\n /***/ 4237: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var toIntegerOrInfinity = __webpack_require__(3329);\n var min = Math.min;\n // `ToLength` abstract operation\n // https://tc39.es/ecma262/#sec-tolength\n module.exports = function(argument) {\n return argument > 0 ? min(toIntegerOrInfinity(argument), 0x1FFFFFFFFFFFFF) : 0; // 2 ** 53 - 1 == 9007199254740991\n };\n /***/ },\n /***/ 2991: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var requireObjectCoercible = __webpack_require__(8885);\n var $Object = Object;\n // `ToObject` abstract operation\n // https://tc39.es/ecma262/#sec-toobject\n module.exports = function(argument) {\n return $Object(requireObjectCoercible(argument));\n };\n /***/ },\n /***/ 2066: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var call = __webpack_require__(266);\n var isObject = __webpack_require__(5052);\n var isSymbol = __webpack_require__(9395);\n var getMethod = __webpack_require__(5300);\n var ordinaryToPrimitive = __webpack_require__(2914);\n var wellKnownSymbol = __webpack_require__(95);\n var $TypeError = TypeError;\n var TO_PRIMITIVE = wellKnownSymbol(\"toPrimitive\");\n // `ToPrimitive` abstract operation\n // https://tc39.es/ecma262/#sec-toprimitive\n module.exports = function(input, pref) {\n if (!isObject(input) || isSymbol(input)) return input;\n var exoticToPrim = getMethod(input, TO_PRIMITIVE);\n var result;\n if (exoticToPrim) {\n if (pref === undefined) pref = \"default\";\n result = call(exoticToPrim, input, pref);\n if (!isObject(result) || isSymbol(result)) return result;\n throw $TypeError(\"Can't convert object to primitive value\");\n }\n if (pref === undefined) pref = \"number\";\n return ordinaryToPrimitive(input, pref);\n };\n /***/ },\n /***/ 9310: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var toPrimitive = __webpack_require__(2066);\n var isSymbol = __webpack_require__(9395);\n // `ToPropertyKey` abstract operation\n // https://tc39.es/ecma262/#sec-topropertykey\n module.exports = function(argument) {\n var key = toPrimitive(argument, \"string\");\n return isSymbol(key) ? key : key + \"\";\n };\n /***/ },\n /***/ 1601: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var wellKnownSymbol = __webpack_require__(95);\n var TO_STRING_TAG = wellKnownSymbol(\"toStringTag\");\n var test = {};\n test[TO_STRING_TAG] = \"z\";\n module.exports = String(test) === \"[object z]\";\n /***/ },\n /***/ 3326: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var classof = __webpack_require__(1589);\n var $String = String;\n module.exports = function(argument) {\n if (classof(argument) === \"Symbol\") throw TypeError(\"Cannot convert a Symbol value to a string\");\n return $String(argument);\n };\n /***/ },\n /***/ 9821: /***/ (module)=>{\n var $String = String;\n module.exports = function(argument) {\n try {\n return $String(argument);\n } catch (error) {\n return \"Object\";\n }\n };\n /***/ },\n /***/ 1441: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var uncurryThis = __webpack_require__(5968);\n var id = 0;\n var postfix = Math.random();\n var toString = uncurryThis(1.0.toString);\n module.exports = function(key) {\n return \"Symbol(\" + (key === undefined ? \"\" : key) + \")_\" + toString(++id + postfix, 36);\n };\n /***/ },\n /***/ 6969: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n /* eslint-disable es/no-symbol -- required for testing */ var NATIVE_SYMBOL = __webpack_require__(4860);\n module.exports = NATIVE_SYMBOL && !Symbol.sham && typeof Symbol.iterator == \"symbol\";\n /***/ },\n /***/ 7137: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var DESCRIPTORS = __webpack_require__(7400);\n var fails = __webpack_require__(4229);\n // V8 ~ Chrome 36-\n // https://bugs.chromium.org/p/v8/issues/detail?id=3334\n module.exports = DESCRIPTORS && fails(function() {\n // eslint-disable-next-line es/no-object-defineproperty -- required for testing\n return Object.defineProperty(function() {}, \"prototype\", {\n value: 42,\n writable: false\n }).prototype != 42;\n });\n /***/ },\n /***/ 1180: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var global = __webpack_require__(9859);\n var isCallable = __webpack_require__(6733);\n var WeakMap1 = global.WeakMap;\n module.exports = isCallable(WeakMap1) && /native code/.test(String(WeakMap1));\n /***/ },\n /***/ 95: /***/ (module, __unused_webpack_exports, __webpack_require__)=>{\n var global = __webpack_require__(9859);\n var shared = __webpack_require__(3036);\n var hasOwn = __webpack_require__(8270);\n var uid = __webpack_require__(1441);\n var NATIVE_SYMBOL = __webpack_require__(4860);\n var USE_SYMBOL_AS_UID = __webpack_require__(6969);\n var Symbol1 = global.Symbol;\n var WellKnownSymbolsStore = shared(\"wks\");\n var createWellKnownSymbol = USE_SYMBOL_AS_UID ? Symbol1[\"for\"] || Symbol1 : Symbol1 && Symbol1.withoutSetter || uid;\n module.exports = function(name) {\n if (!hasOwn(WellKnownSymbolsStore, name)) WellKnownSymbolsStore[name] = NATIVE_SYMBOL && hasOwn(Symbol1, name) ? Symbol1[name] : createWellKnownSymbol(\"Symbol.\" + name);\n return WellKnownSymbolsStore[name];\n };\n /***/ },\n /***/ 3430: /***/ (__unused_webpack_module, __unused_webpack_exports, __webpack_require__)=>{\n var $ = __webpack_require__(3103);\n var uncurryThis = __webpack_require__(5968);\n var aCallable = __webpack_require__(7111);\n var toObject = __webpack_require__(2991);\n var lengthOfArrayLike = __webpack_require__(9646);\n var deletePropertyOrThrow = __webpack_require__(9563);\n var toString = __webpack_require__(3326);\n var fails = __webpack_require__(4229);\n var internalSort = __webpack_require__(3867);\n var arrayMethodIsStrict = __webpack_require__(6038);\n var FF = __webpack_require__(2671);\n var IE_OR_EDGE = __webpack_require__(8506);\n var V8 = __webpack_require__(5884);\n var WEBKIT = __webpack_require__(9811);\n var test = [];\n var nativeSort = uncurryThis(test.sort);\n var push = uncurryThis(test.push);\n // IE8-\n var FAILS_ON_UNDEFINED = fails(function() {\n test.sort(undefined);\n });\n // V8 bug\n var FAILS_ON_NULL = fails(function() {\n test.sort(null);\n });\n // Old WebKit\n var STRICT_METHOD = arrayMethodIsStrict(\"sort\");\n var STABLE_SORT = !fails(function() {\n // feature detection can be too slow, so check engines versions\n if (V8) return V8 < 70;\n if (FF && FF > 3) return;\n if (IE_OR_EDGE) return true;\n if (WEBKIT) return WEBKIT < 603;\n var result = \"\";\n var code, chr, value, index;\n // generate an array with more 512 elements (Chakra and old V8 fails only in this case)\n for(code = 65; code < 76; code++){\n chr = String.fromCharCode(code);\n switch(code){\n case 66:\n case 69:\n case 70:\n case 72:\n value = 3;\n break;\n case 68:\n case 71:\n value = 4;\n break;\n default:\n value = 2;\n }\n for(index = 0; index < 47; index++)test.push({\n k: chr + index,\n v: value\n });\n }\n test.sort(function(a, b) {\n return b.v - a.v;\n });\n for(index = 0; index < test.length; index++){\n chr = test[index].k.charAt(0);\n if (result.charAt(result.length - 1) !== chr) result += chr;\n }\n return result !== \"DGBEFHACIJK\";\n });\n var FORCED = FAILS_ON_UNDEFINED || !FAILS_ON_NULL || !STRICT_METHOD || !STABLE_SORT;\n var getSortCompare = function(comparefn) {\n return function(x, y) {\n if (y === undefined) return -1;\n if (x === undefined) return 1;\n if (comparefn !== undefined) return +comparefn(x, y) || 0;\n return toString(x) > toString(y) ? 1 : -1;\n };\n };\n // `Array.prototype.sort` method\n // https://tc39.es/ecma262/#sec-array.prototype.sort\n $({\n target: \"Array\",\n proto: true,\n forced: FORCED\n }, {\n sort: function sort(comparefn) {\n if (comparefn !== undefined) aCallable(comparefn);\n var array = toObject(this);\n if (STABLE_SORT) return comparefn === undefined ? nativeSort(array) : nativeSort(array, comparefn);\n var items = [];\n var arrayLength = lengthOfArrayLike(array);\n var itemsLength, index;\n for(index = 0; index < arrayLength; index++)if (index in array) push(items, array[index]);\n internalSort(items, getSortCompare(comparefn));\n itemsLength = lengthOfArrayLike(items);\n index = 0;\n while(index < itemsLength)array[index] = items[index++];\n while(index < arrayLength)deletePropertyOrThrow(array, index++);\n return array;\n }\n });\n /***/ },\n /***/ 4769: /***/ (__unused_webpack_module, __unused_webpack_exports, __webpack_require__)=>{\n var $ = __webpack_require__(3103);\n var toObject = __webpack_require__(2991);\n var nativeKeys = __webpack_require__(5632);\n var fails = __webpack_require__(4229);\n var FAILS_ON_PRIMITIVES = fails(function() {\n nativeKeys(1);\n });\n // `Object.keys` method\n // https://tc39.es/ecma262/#sec-object.keys\n $({\n target: \"Object\",\n stat: true,\n forced: FAILS_ON_PRIMITIVES\n }, {\n keys: function keys(it) {\n return nativeKeys(toObject(it));\n }\n });\n /***/ },\n /***/ 1388: /***/ (module, __webpack_exports__, __webpack_require__)=>{\n /* harmony export */ __webpack_require__.d(__webpack_exports__, {\n /* harmony export */ Z: ()=>__WEBPACK_DEFAULT_EXPORT__\n });\n /* harmony import */ var _node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(272);\n /* harmony import */ var _node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/ __webpack_require__.n(_node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0__);\n /* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(2609);\n /* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/ __webpack_require__.n(_node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__);\n // Imports\n var ___CSS_LOADER_EXPORT___ = _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default()(_node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default());\n // Module\n ___CSS_LOADER_EXPORT___.push([\n module.id,\n `/* Buttons styles start */\r\n\r\nbutton#excalibur-play {\r\n display: inline-block;\r\n position: relative;\r\n z-index: 999;\r\n border-radius: 6px;\r\n border: none;\r\n /*border: 3px solid;\r\n border-color: white;\r\n box-shadow: 0 0 10px #ccc;*/\r\n padding: 1rem 1.5rem 1rem 4rem;\r\n margin: 0;\r\n text-decoration: none;\r\n background: #00b233;\r\n color: #ffffff;\r\n font-family: sans-serif;\r\n font-size: 2rem;\r\n white-space: nowrap;\r\n line-height: 1;\r\n cursor: pointer;\r\n text-align: center;\r\n transition: background 250ms ease-in-out, transform 150ms ease;\r\n -webkit-appearance: none;\r\n -moz-appearance: none;\r\n\r\n -webkit-animation: excalibur-button-fadein 200ms; /* Safari, Chrome and Opera > 12.1 */\r\n -moz-animation: excalibur-button-fadein 200ms; /* Firefox < 16 */\r\n -ms-animation: excalibur-button-fadein 200ms; /* Internet Explorer */\r\n -o-animation: excalibur-button-fadein 200ms; /* Opera < 12.1 */\r\n animation: excalibur-button-fadein 200ms;\r\n}\r\n\r\n/*\r\nbutton#excalibur-play {\r\n display: none;\r\n}*/\r\n\r\nbutton#excalibur-play:after {\r\n position: absolute;\r\n content: '';\r\n border: 8px solid;\r\n border-color: transparent transparent transparent white;\r\n left: 35px;\r\n top: 24px;\r\n width: 0;\r\n height: 0;\r\n}\r\n\r\nbutton#excalibur-play:before {\r\n position: absolute;\r\n content: '';\r\n border: 3px solid;\r\n left: 19px;\r\n top: 14px;\r\n border-radius: 20px;\r\n width: 30px;\r\n height: 30px;\r\n}\r\n\r\nbutton#excalibur-play:hover,\r\nbutton#excalibur-play:focus {\r\n background: #00982c;\r\n}\r\n\r\nbutton#excalibur-play:focus {\r\n outline: 1px solid #fff;\r\n outline-offset: -4px;\r\n}\r\n\r\nbutton#excalibur-play:active {\r\n transform: scale(0.99);\r\n}\r\n\r\n@keyframes excalibur-button-fadein {\r\n from {\r\n opacity: 0;\r\n }\r\n to {\r\n opacity: 1;\r\n }\r\n}\r\n\r\n/* Firefox < 16 */\r\n@-moz-keyframes excalibur-button-fadein {\r\n from {\r\n opacity: 0;\r\n }\r\n to {\r\n opacity: 1;\r\n }\r\n}\r\n\r\n/* Safari, Chrome and Opera > 12.1 */\r\n@-webkit-keyframes excalibur-button-fadein {\r\n from {\r\n opacity: 0;\r\n }\r\n to {\r\n opacity: 1;\r\n }\r\n}\r\n\r\n/* Internet Explorer */\r\n@-ms-keyframes excalibur-button-fadein {\r\n from {\r\n opacity: 0;\r\n }\r\n to {\r\n opacity: 1;\r\n }\r\n}\r\n\r\n/* Opera < 12.1 */\r\n@-o-keyframes excalibur-button-fadein {\r\n from {\r\n opacity: 0;\r\n }\r\n to {\r\n opacity: 1;\r\n }\r\n}\r\n`,\n \"\",\n {\n \"version\": 3,\n \"sources\": [\n \"webpack://./Loader.css\"\n ],\n \"names\": [],\n \"mappings\": \"AAAA,yBAAyB;;AAEzB;EACE,qBAAqB;EACrB,kBAAkB;EAClB,YAAY;EACZ,kBAAkB;EAClB,YAAY;EACZ;;+BAE6B;EAC7B,8BAA8B;EAC9B,SAAS;EACT,qBAAqB;EACrB,mBAAmB;EACnB,cAAc;EACd,uBAAuB;EACvB,eAAe;EACf,mBAAmB;EACnB,cAAc;EACd,eAAe;EACf,kBAAkB;EAClB,8DAA8D;EAC9D,wBAAwB;EACxB,qBAAqB;;EAErB,gDAAgD,EAAE,oCAAoC;EACtF,6CAA6C,EAAE,iBAAiB;EAChE,4CAA4C,EAAE,sBAAsB;EACpE,2CAA2C,EAAE,iBAAiB;EAC9D,wCAAwC;AAC1C;;AAEA;;;EAGE;;AAEF;EACE,kBAAkB;EAClB,WAAW;EACX,iBAAiB;EACjB,uDAAuD;EACvD,UAAU;EACV,SAAS;EACT,QAAQ;EACR,SAAS;AACX;;AAEA;EACE,kBAAkB;EAClB,WAAW;EACX,iBAAiB;EACjB,UAAU;EACV,SAAS;EACT,mBAAmB;EACnB,WAAW;EACX,YAAY;AACd;;AAEA;;EAEE,mBAAmB;AACrB;;AAEA;EACE,uBAAuB;EACvB,oBAAoB;AACtB;;AAEA;EACE,sBAAsB;AACxB;;AAEA;EACE;IACE,UAAU;EACZ;EACA;IACE,UAAU;EACZ;AACF;;AAEA,iBAAiB;AACjB;EACE;IACE,UAAU;EACZ;EACA;IACE,UAAU;EACZ;AACF;;AAEA,oCAAoC;AACpC;EACE;IACE,UAAU;EACZ;EACA;IACE,UAAU;EACZ;AACF;;AAEA,sBAAsB;AACtB;EACE;IACE,UAAU;EACZ;EACA;IACE,UAAU;EACZ;AACF;;AAEA,iBAAiB;AACjB;EACE;IACE,UAAU;EACZ;EACA;IACE,UAAU;EACZ;AACF\",\n \"sourcesContent\": [\n \"/* Buttons styles start */\\r\\n\\r\\nbutton#excalibur-play {\\r\\n display: inline-block;\\r\\n position: relative;\\r\\n z-index: 999;\\r\\n border-radius: 6px;\\r\\n border: none;\\r\\n /*border: 3px solid;\\r\\n border-color: white;\\r\\n box-shadow: 0 0 10px #ccc;*/\\r\\n padding: 1rem 1.5rem 1rem 4rem;\\r\\n margin: 0;\\r\\n text-decoration: none;\\r\\n background: #00b233;\\r\\n color: #ffffff;\\r\\n font-family: sans-serif;\\r\\n font-size: 2rem;\\r\\n white-space: nowrap;\\r\\n line-height: 1;\\r\\n cursor: pointer;\\r\\n text-align: center;\\r\\n transition: background 250ms ease-in-out, transform 150ms ease;\\r\\n -webkit-appearance: none;\\r\\n -moz-appearance: none;\\r\\n\\r\\n -webkit-animation: excalibur-button-fadein 200ms; /* Safari, Chrome and Opera > 12.1 */\\r\\n -moz-animation: excalibur-button-fadein 200ms; /* Firefox < 16 */\\r\\n -ms-animation: excalibur-button-fadein 200ms; /* Internet Explorer */\\r\\n -o-animation: excalibur-button-fadein 200ms; /* Opera < 12.1 */\\r\\n animation: excalibur-button-fadein 200ms;\\r\\n}\\r\\n\\r\\n/*\\r\\nbutton#excalibur-play {\\r\\n display: none;\\r\\n}*/\\r\\n\\r\\nbutton#excalibur-play:after {\\r\\n position: absolute;\\r\\n content: '';\\r\\n border: 8px solid;\\r\\n border-color: transparent transparent transparent white;\\r\\n left: 35px;\\r\\n top: 24px;\\r\\n width: 0;\\r\\n height: 0;\\r\\n}\\r\\n\\r\\nbutton#excalibur-play:before {\\r\\n position: absolute;\\r\\n content: '';\\r\\n border: 3px solid;\\r\\n left: 19px;\\r\\n top: 14px;\\r\\n border-radius: 20px;\\r\\n width: 30px;\\r\\n height: 30px;\\r\\n}\\r\\n\\r\\nbutton#excalibur-play:hover,\\r\\nbutton#excalibur-play:focus {\\r\\n background: #00982c;\\r\\n}\\r\\n\\r\\nbutton#excalibur-play:focus {\\r\\n outline: 1px solid #fff;\\r\\n outline-offset: -4px;\\r\\n}\\r\\n\\r\\nbutton#excalibur-play:active {\\r\\n transform: scale(0.99);\\r\\n}\\r\\n\\r\\n@keyframes excalibur-button-fadein {\\r\\n from {\\r\\n opacity: 0;\\r\\n }\\r\\n to {\\r\\n opacity: 1;\\r\\n }\\r\\n}\\r\\n\\r\\n/* Firefox < 16 */\\r\\n@-moz-keyframes excalibur-button-fadein {\\r\\n from {\\r\\n opacity: 0;\\r\\n }\\r\\n to {\\r\\n opacity: 1;\\r\\n }\\r\\n}\\r\\n\\r\\n/* Safari, Chrome and Opera > 12.1 */\\r\\n@-webkit-keyframes excalibur-button-fadein {\\r\\n from {\\r\\n opacity: 0;\\r\\n }\\r\\n to {\\r\\n opacity: 1;\\r\\n }\\r\\n}\\r\\n\\r\\n/* Internet Explorer */\\r\\n@-ms-keyframes excalibur-button-fadein {\\r\\n from {\\r\\n opacity: 0;\\r\\n }\\r\\n to {\\r\\n opacity: 1;\\r\\n }\\r\\n}\\r\\n\\r\\n/* Opera < 12.1 */\\r\\n@-o-keyframes excalibur-button-fadein {\\r\\n from {\\r\\n opacity: 0;\\r\\n }\\r\\n to {\\r\\n opacity: 1;\\r\\n }\\r\\n}\\r\\n\"\n ],\n \"sourceRoot\": \"\"\n }\n ]);\n // Exports\n /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = ___CSS_LOADER_EXPORT___;\n /***/ },\n /***/ 7379: /***/ (module, __webpack_exports__, __webpack_require__)=>{\n /* harmony export */ __webpack_require__.d(__webpack_exports__, {\n /* harmony export */ Z: ()=>__WEBPACK_DEFAULT_EXPORT__\n });\n /* harmony import */ var _node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(272);\n /* harmony import */ var _node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/ __webpack_require__.n(_node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0__);\n /* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(2609);\n /* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/ __webpack_require__.n(_node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__);\n // Imports\n var ___CSS_LOADER_EXPORT___ = _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default()(_node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default());\n // Module\n ___CSS_LOADER_EXPORT___.push([\n module.id,\n `\r\n#ex-toast-container {\r\n position: absolute;\r\n height: 0;\r\n min-width: 50%;\r\n left: 50%;\r\n top: 0;\r\n}\r\n\r\n.ex-toast-message {\r\n left: -50%;\r\n position: relative;\r\n display: flex;\r\n justify-content: space-between;\r\n\r\n\r\n padding: 10px;\r\n margin-top: 5px;\r\n font-size: 18px;\r\n font-family: sans-serif;\r\n border-radius: 6px;\r\n border: 3px solid #b7b779;\r\n background-color: rgb(253, 253, 192);\r\n}\r\n\r\n\r\n.ex-toast-message button {\r\n align-self: flex-start;\r\n}`,\n \"\",\n {\n \"version\": 3,\n \"sources\": [\n \"webpack://./Util/Toaster.css\"\n ],\n \"names\": [],\n \"mappings\": \";AACA;EACE,kBAAkB;EAClB,SAAS;EACT,cAAc;EACd,SAAS;EACT,MAAM;AACR;;AAEA;EACE,UAAU;EACV,kBAAkB;EAClB,aAAa;EACb,8BAA8B;;;EAG9B,aAAa;EACb,eAAe;EACf,eAAe;EACf,uBAAuB;EACvB,kBAAkB;EAClB,yBAAyB;EACzB,oCAAoC;AACtC;;;AAGA;EACE,sBAAsB;AACxB\",\n \"sourcesContent\": [\n \"\\r\\n#ex-toast-container {\\r\\n position: absolute;\\r\\n height: 0;\\r\\n min-width: 50%;\\r\\n left: 50%;\\r\\n top: 0;\\r\\n}\\r\\n\\r\\n.ex-toast-message {\\r\\n left: -50%;\\r\\n position: relative;\\r\\n display: flex;\\r\\n justify-content: space-between;\\r\\n\\r\\n\\r\\n padding: 10px;\\r\\n margin-top: 5px;\\r\\n font-size: 18px;\\r\\n font-family: sans-serif;\\r\\n border-radius: 6px;\\r\\n border: 3px solid #b7b779;\\r\\n background-color: rgb(253, 253, 192);\\r\\n}\\r\\n\\r\\n\\r\\n.ex-toast-message button {\\r\\n align-self: flex-start;\\r\\n}\"\n ],\n \"sourceRoot\": \"\"\n }\n ]);\n // Exports\n /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = ___CSS_LOADER_EXPORT___;\n /***/ },\n /***/ 2609: /***/ (module)=>{\n /*\n MIT License http://www.opensource.org/licenses/mit-license.php\n Author Tobias Koppers @sokra\n*/ module.exports = function(cssWithMappingToString) {\n var list = [];\n // return the list of modules as css string\n list.toString = function toString() {\n return this.map(function(item) {\n var content = \"\";\n var needLayer = typeof item[5] !== \"undefined\";\n if (item[4]) content += \"@supports (\".concat(item[4], \") {\");\n if (item[2]) content += \"@media \".concat(item[2], \" {\");\n if (needLayer) content += \"@layer\".concat(item[5].length > 0 ? \" \".concat(item[5]) : \"\", \" {\");\n content += cssWithMappingToString(item);\n if (needLayer) content += \"}\";\n if (item[2]) content += \"}\";\n if (item[4]) content += \"}\";\n return content;\n }).join(\"\");\n };\n // import a list of modules into the list\n list.i = function i(modules, media, dedupe, supports, layer) {\n if (typeof modules === \"string\") modules = [\n [\n null,\n modules,\n undefined\n ]\n ];\n var alreadyImportedModules = {};\n if (dedupe) for(var k = 0; k < this.length; k++){\n var id = this[k][0];\n if (id != null) alreadyImportedModules[id] = true;\n }\n for(var _k = 0; _k < modules.length; _k++){\n var item = [].concat(modules[_k]);\n if (dedupe && alreadyImportedModules[item[0]]) continue;\n if (typeof layer !== \"undefined\") {\n if (typeof item[5] === \"undefined\") item[5] = layer;\n else {\n item[1] = \"@layer\".concat(item[5].length > 0 ? \" \".concat(item[5]) : \"\", \" {\").concat(item[1], \"}\");\n item[5] = layer;\n }\n }\n if (media) {\n if (!item[2]) item[2] = media;\n else {\n item[1] = \"@media \".concat(item[2], \" {\").concat(item[1], \"}\");\n item[2] = media;\n }\n }\n if (supports) {\n if (!item[4]) item[4] = \"\".concat(supports);\n else {\n item[1] = \"@supports (\".concat(item[4], \") {\").concat(item[1], \"}\");\n item[4] = supports;\n }\n }\n list.push(item);\n }\n };\n return list;\n };\n /***/ },\n /***/ 272: /***/ (module)=>{\n module.exports = function(item) {\n var content = item[1];\n var cssMapping = item[3];\n if (!cssMapping) return content;\n if (typeof btoa === \"function\") {\n var base64 = btoa(unescape(encodeURIComponent(JSON.stringify(cssMapping))));\n var data = \"sourceMappingURL=data:application/json;charset=utf-8;base64,\".concat(base64);\n var sourceMapping = \"/*# \".concat(data, \" */\");\n return [\n content\n ].concat([\n sourceMapping\n ]).join(\"\\n\");\n }\n return [\n content\n ].join(\"\\n\");\n };\n /***/ }\n};\n/************************************************************************/ /******/ // The module cache\n/******/ var $2c23f148d58cd887$var$__webpack_module_cache__ = {};\n/******/ /******/ // The require function\n/******/ function $2c23f148d58cd887$var$__webpack_require__(moduleId) {\n /******/ // Check if module is in cache\n /******/ var cachedModule = $2c23f148d58cd887$var$__webpack_module_cache__[moduleId];\n /******/ if (cachedModule !== undefined) /******/ return cachedModule.exports;\n /******/ // Create a new module (and put it into the cache)\n /******/ var module = $2c23f148d58cd887$var$__webpack_module_cache__[moduleId] = {\n /******/ id: moduleId,\n /******/ // no module.loaded needed\n /******/ exports: {}\n };\n /******/ /******/ // Execute the module function\n /******/ $2c23f148d58cd887$var$__webpack_modules__[moduleId].call(module.exports, module, module.exports, $2c23f148d58cd887$var$__webpack_require__);\n /******/ /******/ // Return the exports of the module\n /******/ return module.exports;\n/******/ }\n/******/ /************************************************************************/ /******/ /* webpack/runtime/compat get default export */ /******/ (()=>{\n /******/ // getDefaultExport function for compatibility with non-harmony modules\n /******/ $2c23f148d58cd887$var$__webpack_require__.n = (module)=>{\n /******/ var getter = module && module.__esModule ? /******/ ()=>module[\"default\"] : /******/ ()=>module;\n /******/ $2c23f148d58cd887$var$__webpack_require__.d(getter, {\n a: getter\n });\n /******/ return getter;\n /******/ };\n/******/ })();\n/******/ /******/ /* webpack/runtime/define property getters */ /******/ (()=>{\n /******/ // define getter functions for harmony exports\n /******/ $2c23f148d58cd887$var$__webpack_require__.d = (exports, definition)=>{\n /******/ for(var key in definition)/******/ if ($2c23f148d58cd887$var$__webpack_require__.o(definition, key) && !$2c23f148d58cd887$var$__webpack_require__.o(exports, key)) /******/ Object.defineProperty(exports, key, {\n enumerable: true,\n get: definition[key]\n });\n /******/ };\n/******/ })();\n/******/ /******/ /* webpack/runtime/global */ /******/ (()=>{\n /******/ $2c23f148d58cd887$var$__webpack_require__.g = function() {\n /******/ if (typeof globalThis === \"object\") return globalThis;\n /******/ try {\n /******/ return this || new Function(\"return this\")();\n /******/ } catch (e) {\n /******/ if (typeof window === \"object\") return window;\n /******/ }\n /******/ }();\n/******/ })();\n/******/ /******/ /* webpack/runtime/hasOwnProperty shorthand */ /******/ (()=>{\n /******/ $2c23f148d58cd887$var$__webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);\n/******/ })();\n/******/ /******/ /* webpack/runtime/make namespace object */ /******/ (()=>{\n /******/ // define __esModule on exports\n /******/ $2c23f148d58cd887$var$__webpack_require__.r = (exports)=>{\n /******/ if (typeof Symbol !== \"undefined\" && Symbol.toStringTag) /******/ Object.defineProperty(exports, Symbol.toStringTag, {\n value: \"Module\"\n });\n /******/ Object.defineProperty(exports, \"__esModule\", {\n value: true\n });\n /******/ };\n/******/ })();\n/******/ /************************************************************************/ var $2c23f148d58cd887$var$__webpack_exports__ = {};\n// This entry need to be wrapped in an IIFE because it need to be isolated against other modules in the chunk.\n(()=>{\n // EXPORTS\n $2c23f148d58cd887$var$__webpack_require__.d($2c23f148d58cd887$var$__webpack_exports__, {\n fWn: ()=>/* reexport */ ActionContext,\n Ia8: ()=>/* reexport */ ActionQueue,\n rqv: ()=>/* reexport */ ActionSequence,\n hLI: ()=>/* reexport */ ActionsComponent,\n yyv: ()=>/* reexport */ ActionsSystem,\n tX5: ()=>/* reexport */ ActivateEvent,\n vtX: ()=>/* reexport */ Actor,\n r7K: ()=>/* reexport */ AddedComponent,\n lCh: ()=>/* reexport */ AddedEntity,\n cE4: ()=>/* reexport */ AffineMatrix,\n fwF: ()=>/* reexport */ Animation,\n sce: ()=>/* reexport */ AnimationDirection,\n AQ6: ()=>/* reexport */ AnimationEvents,\n _c7: ()=>/* reexport */ AnimationStrategy,\n KUs: ()=>/* reexport */ ArcadeSolver,\n Ajp: ()=>/* reexport */ AudioContextFactory,\n dkO: ()=>/* reexport */ Axes,\n RDh: ()=>/* reexport */ Axis,\n _H9: ()=>/* reexport */ BaseAlign,\n mxs: ()=>/* reexport */ Blink,\n OmD: ()=>/* reexport */ BodyComponent,\n kBf: ()=>/* reexport */ BoundingBox,\n C4F: ()=>/* reexport */ BroadphaseStrategy,\n NQt: ()=>/* reexport */ BrowserComponent,\n JjN: ()=>/* reexport */ BrowserEvents,\n EK_: ()=>/* reexport */ Buttons,\n V1s: ()=>/* reexport */ Camera,\n xHm: ()=>/* reexport */ CameraEvents,\n Xz7: ()=>/* reexport */ Canvas,\n Cdc: ()=>/* reexport */ Circle,\n FKn: ()=>/* reexport */ CircleCollider,\n SUY: ()=>/* reexport */ Clock,\n ab2: ()=>/* reexport */ ClosestLine,\n GfZ: ()=>/* reexport */ ClosestLineJumpTable,\n YMS: ()=>/* reexport */ Collider,\n oyv: ()=>/* reexport */ ColliderComponent,\n aUb: ()=>/* reexport */ CollisionContact,\n SdD: ()=>/* reexport */ CollisionEndEvent,\n JUv: ()=>/* reexport */ CollisionGroup,\n jEj: ()=>/* reexport */ CollisionGroupManager,\n TFq: ()=>/* reexport */ CollisionJumpTable,\n HDU: ()=>/* reexport */ CollisionPostSolveEvent,\n R_y: ()=>/* reexport */ CollisionPreSolveEvent,\n ydN: ()=>/* reexport */ CollisionResolutionStrategy,\n t50: ()=>/* reexport */ CollisionStartEvent,\n s$$: ()=>/* reexport */ CollisionSystem,\n v2G: ()=>/* reexport */ CollisionType,\n Ilk: ()=>/* reexport */ Color,\n s9i: ()=>/* reexport */ ColorBlindFlags,\n dxL: ()=>/* reexport */ ColorBlindnessMode,\n LLX: ()=>/* reexport */ ColorBlindnessPostProcessor,\n wA2: ()=>/* reexport */ Component,\n R_p: ()=>/* reexport */ CompositeCollider,\n IQ$: ()=>/* reexport */ Configurable,\n I5F: ()=>/* reexport */ ConsoleAppender,\n X8$: ()=>/* reexport */ ContactConstraintPoint,\n FR6: ()=>/* reexport */ ContactEndEvent,\n U8o: ()=>/* reexport */ ContactStartEvent,\n kbG: ()=>/* reexport */ CoordPlane,\n iS_: ()=>/* reexport */ DeactivateEvent,\n cGG: ()=>/* reexport */ Debug,\n RPN: ()=>/* reexport */ DebugGraphicsComponent,\n skb: ()=>/* reexport */ DebugSystem,\n SLU: ()=>/* reexport */ DebugText,\n RdJ: ()=>/* reexport */ DegreeOfFreedom,\n cNu: ()=>/* reexport */ Delay,\n gU7: ()=>/* reexport */ Detector,\n LSk: ()=>/* reexport */ Die,\n Nmp: ()=>/* reexport */ Direction,\n d1Y: ()=>/* reexport */ DisplayMode,\n xrL: ()=>/* reexport */ DynamicTree,\n sRW: ()=>/* reexport */ DynamicTreeCollisionProcessor,\n cmV: ()=>/* binding */ EX_VERSION,\n qWz: ()=>/* reexport */ EaseBy,\n N0Q: ()=>/* reexport */ EaseTo,\n q8b: ()=>/* reexport */ EasingFunctions,\n ynB: ()=>/* reexport */ EdgeCollider,\n jT9: ()=>/* reexport */ ElasticToActorStrategy,\n wAz: ()=>/* reexport */ EmitterType,\n D4V: ()=>/* reexport */ Engine,\n NLr: ()=>/* reexport */ EngineEvents,\n N6H: ()=>/* reexport */ EnterTriggerEvent,\n W1A: ()=>/* reexport */ EnterViewPortEvent,\n JHW: ()=>/* reexport */ Entity,\n ZZ$: ()=>/* reexport */ EntityEvents,\n v2K: ()=>/* reexport */ EntityManager,\n pBf: ()=>/* reexport */ EventDispatcher,\n vpe: ()=>/* reexport */ EventEmitter,\n GMl: ()=>/* reexport */ EventTypes,\n zW2: ()=>/* reexport */ Events_namespaceObject,\n B0K: ()=>/* reexport */ ExResponse,\n Nv7: ()=>/* reexport */ ExcaliburGraphicsContext2DCanvas,\n C_p: ()=>/* reexport */ ExcaliburGraphicsContextWebGL,\n MUA: ()=>/* reexport */ ExitTriggerEvent,\n xqU: ()=>/* reexport */ ExitViewPortEvent,\n pTp: ()=>/* reexport */ Fade,\n vUK: ()=>/* reexport */ Flags,\n j9l: ()=>/* reexport */ Follow,\n Zxw: ()=>/* reexport */ Font,\n v51: ()=>/* reexport */ FontCache,\n Hdx: ()=>/* reexport */ FontStyle,\n Z$d: ()=>/* reexport */ FontUnit,\n iqV: ()=>/* reexport */ FpsSampler,\n o$7: ()=>/* reexport */ FrameStats,\n olM: ()=>/* reexport */ Future,\n Zm$: ()=>/* reexport */ GameEvent,\n $QH: ()=>/* reexport */ GameStartEvent,\n i78: ()=>/* reexport */ GameStopEvent,\n nJg: ()=>/* reexport */ Gamepad,\n h6u: ()=>/* reexport */ GamepadAxisEvent,\n hts: ()=>/* reexport */ GamepadButtonEvent,\n j88: ()=>/* reexport */ GamepadConnectEvent,\n VME: ()=>/* reexport */ GamepadDisconnectEvent,\n fy2: ()=>/* reexport */ Gamepads,\n nt: ()=>/* reexport */ Gif,\n Ukr: ()=>/* reexport */ GlobalCoordinates,\n zsu: ()=>/* reexport */ Graphic,\n oA6: ()=>/* reexport */ GraphicsComponent,\n TVh: ()=>/* reexport */ GraphicsGroup,\n TwZ: ()=>/* reexport */ GraphicsLayer,\n GTT: ()=>/* reexport */ GraphicsLayers,\n xxj: ()=>/* reexport */ GraphicsSystem,\n XdK: ()=>/* reexport */ HiddenEvent,\n Jmb: ()=>/* reexport */ ImageFiltering,\n cXo: ()=>/* reexport */ ImageSource,\n Dm5: ()=>/* reexport */ InitializeEvent,\n IIB: ()=>/* reexport */ Input_Index_namespaceObject,\n ebW: ()=>/* reexport */ InputMapper,\n zI0: ()=>/* reexport */ Integrator,\n LYD: ()=>/* reexport */ IsometricEntityComponent,\n cEG: ()=>/* reexport */ IsometricEntitySystem,\n SEl: ()=>/* reexport */ IsometricMap,\n t9V: ()=>/* reexport */ IsometricTile,\n ez5: ()=>/* reexport */ KeyEvent,\n N1d: ()=>/* reexport */ Keyboard,\n R8U: ()=>/* reexport */ Keys,\n SKZ: ()=>/* reexport */ KillEvent,\n __J: ()=>/* reexport */ Label,\n RI$: ()=>/* reexport */ LimitCameraBoundsStrategy,\n x12: ()=>/* reexport */ Line,\n ccz: ()=>/* reexport */ LineSegment,\n aNw: ()=>/* reexport */ Loader,\n XrL: ()=>/* reexport */ LoaderEvents,\n xwn: ()=>/* reexport */ LockCameraToActorAxisStrategy,\n dNK: ()=>/* reexport */ LockCameraToActorStrategy,\n ini: ()=>/* reexport */ LogLevel,\n YdH: ()=>/* reexport */ Logger,\n F5T: ()=>/* reexport */ Material,\n y3G: ()=>/* reexport */ Matrix,\n l57: ()=>/* reexport */ MatrixLocations,\n xn0: ()=>/* reexport */ MediaEvent,\n t2V: ()=>/* reexport */ Meet,\n uxB: ()=>/* reexport */ MotionComponent,\n cpd: ()=>/* reexport */ MotionSystem,\n fiy: ()=>/* reexport */ MoveBy,\n $XZ: ()=>/* reexport */ MoveTo,\n UG6: ()=>/* reexport */ NativePointerButton,\n uqK: ()=>/* reexport */ NativeSoundEvent,\n STE: ()=>/* reexport */ NativeSoundProcessedEvent,\n y$z: ()=>/* reexport */ Observable,\n mAD: ()=>/* reexport */ OffscreenSystem,\n sOq: ()=>/* reexport */ Pair,\n hUw: ()=>/* reexport */ ParallaxComponent,\n _0G: ()=>/* reexport */ ParallelActions,\n Sqs: ()=>/* reexport */ ParseGif,\n hpZ: ()=>/* reexport */ Particle,\n Vol: ()=>/* reexport */ ParticleEmitter,\n vYX: ()=>/* reexport */ ParticleTransform,\n wIZ: ()=>/* reexport */ Physics,\n cBi: ()=>/* reexport */ PhysicsStats,\n c30: ()=>/* reexport */ PhysicsWorld,\n MPV: ()=>/* reexport */ PointerButton,\n RFv: ()=>/* reexport */ PointerComponent,\n Ux6: ()=>/* reexport */ PointerEvent,\n rxy: ()=>/* reexport */ PointerEventReceiver,\n I$c: ()=>/* reexport */ PointerScope,\n kfC: ()=>/* reexport */ PointerSystem,\n VjY: ()=>/* reexport */ PointerType,\n mgq: ()=>/* reexport */ Polygon,\n YVA: ()=>/* reexport */ PolygonCollider,\n Kgp: ()=>/* reexport */ Pool,\n HH$: ()=>/* reexport */ PostCollisionEvent,\n M_d: ()=>/* reexport */ PostDebugDrawEvent,\n rgh: ()=>/* reexport */ PostDrawEvent,\n Ra6: ()=>/* reexport */ PostFrameEvent,\n KhR: ()=>/* reexport */ PostKillEvent,\n BS5: ()=>/* reexport */ PostUpdateEvent,\n xhz: ()=>/* reexport */ PreCollisionEvent,\n xOq: ()=>/* reexport */ PreDebugDrawEvent,\n a9j: ()=>/* reexport */ PreDrawEvent,\n bHk: ()=>/* reexport */ PreFrameEvent,\n CgK: ()=>/* reexport */ PreKillEvent,\n cuY: ()=>/* reexport */ PreUpdateEvent,\n kvE: ()=>/* reexport */ Projection,\n SBu: ()=>/* reexport */ QuadIndexBuffer,\n AE_: ()=>/* reexport */ Query,\n ctO: ()=>/* reexport */ QueryManager,\n OLH: ()=>/* reexport */ RadiusAroundActorStrategy,\n kky: ()=>/* reexport */ Random,\n nSF: ()=>/* reexport */ Raster,\n zHn: ()=>/* reexport */ Ray,\n zwx: ()=>/* reexport */ RealisticSolver,\n AeJ: ()=>/* reexport */ Rectangle,\n hLz: ()=>/* reexport */ RemovedComponent,\n D9g: ()=>/* reexport */ RemovedEntity,\n wA: ()=>/* reexport */ Repeat,\n jhr: ()=>/* reexport */ RepeatForever,\n GVs: ()=>/* reexport */ Resolution,\n _zO: ()=>/* reexport */ Resource,\n LXZ: ()=>/* reexport */ ResourceEvents,\n w6$: ()=>/* reexport */ RotateBy,\n mhV: ()=>/* reexport */ RotateTo,\n MOD: ()=>/* reexport */ RotationType,\n kwd: ()=>/* reexport */ ScaleBy,\n Lmr: ()=>/* reexport */ ScaleTo,\n xsS: ()=>/* reexport */ Scene,\n K5l: ()=>/* reexport */ SceneEvents,\n lLr: ()=>/* reexport */ Screen,\n Z$r: ()=>/* reexport */ ScreenAppender,\n IXb: ()=>/* reexport */ ScreenElement,\n SGH: ()=>/* reexport */ ScreenShader,\n SMj: ()=>/* reexport */ ScrollPreventionMode,\n L34: ()=>/* reexport */ Semaphore,\n exe: ()=>/* reexport */ Shader,\n bnF: ()=>/* reexport */ Shape,\n MFA: ()=>/* reexport */ Side,\n $uU: ()=>/* reexport */ Sound,\n Sap: ()=>/* reexport */ SoundEvents,\n jyi: ()=>/* reexport */ Sprite,\n E03: ()=>/* reexport */ SpriteFont,\n V6q: ()=>/* reexport */ SpriteSheet,\n rg2: ()=>/* reexport */ StandardClock,\n DVW: ()=>/* reexport */ StateMachine,\n nVo: ()=>/* reexport */ StrategyContainer,\n F6N: ()=>/* reexport */ Stream,\n xP7: ()=>/* reexport */ System,\n Odq: ()=>/* reexport */ SystemManager,\n Zif: ()=>/* reexport */ SystemType,\n ZGJ: ()=>/* reexport */ TagComponent,\n MJk: ()=>/* reexport */ TestClock,\n xvT: ()=>/* reexport */ Text,\n PHM: ()=>/* reexport */ TextAlign,\n dpR: ()=>/* reexport */ TextureLoader,\n n9L: ()=>/* reexport */ Tile,\n KwO: ()=>/* reexport */ TileMap,\n SxM: ()=>/* reexport */ TileMapEvents,\n B7y: ()=>/* reexport */ Timer,\n x7r: ()=>/* reexport */ Toaster,\n wx7: ()=>/* reexport */ Transform,\n Uvn: ()=>/* reexport */ TransformComponent,\n OFT: ()=>/* reexport */ TreeNode,\n xzN: ()=>/* reexport */ Trigger,\n CcZ: ()=>/* reexport */ TriggerEvents,\n M5Z: ()=>/* reexport */ TwoPI,\n ZrN: ()=>/* reexport */ Util_Index_namespaceObject,\n OWs: ()=>/* reexport */ Vector,\n dF9: ()=>/* reexport */ VectorView,\n oZy: ()=>/* reexport */ VertexBuffer,\n rD2: ()=>/* reexport */ VertexLayout,\n VHo: ()=>/* reexport */ VisibleEvent,\n ohE: ()=>/* reexport */ WebAudio,\n R$E: ()=>/* reexport */ WebAudioInstance,\n xQN: ()=>/* reexport */ WheelDeltaMode,\n AdJ: ()=>/* reexport */ WheelEvent,\n q3I: ()=>/* reexport */ World,\n Pab: ()=>/* reexport */ canonicalizeAngle,\n uZ5: ()=>/* reexport */ clamp,\n McK: ()=>/* reexport */ createId,\n F9c: ()=>/* reexport */ frac,\n k0b: ()=>/* reexport */ hasGraphicsTick,\n hnT: ()=>/* reexport */ hasOnInitialize,\n RSJ: ()=>/* reexport */ hasOnPostUpdate,\n Mku: ()=>/* reexport */ hasOnPreUpdate,\n h90: ()=>/* reexport */ hasPostDraw,\n rms: ()=>/* reexport */ hasPreDraw,\n ErP: ()=>/* reexport */ has_initialize,\n aVg: ()=>/* reexport */ has_postupdate,\n lPc: ()=>/* reexport */ has_preupdate,\n Z8E: ()=>/* reexport */ isAddedComponent,\n _N2: ()=>/* reexport */ isAddedSystemEntity,\n yFn: ()=>/* reexport */ isRemoveSystemEntity,\n lNv: ()=>/* reexport */ isRemovedComponent,\n cu9: ()=>/* reexport */ isScreenElement,\n MZQ: ()=>/* reexport */ maxMessages,\n FUM: ()=>/* reexport */ obsolete,\n BxR: ()=>/* reexport */ pixelSnapEpsilon,\n vdf: ()=>/* reexport */ randomInRange,\n iaL: ()=>/* reexport */ randomIntInRange,\n w6H: ()=>/* reexport */ range,\n Q4c: ()=>/* reexport */ resetObsoleteCounter,\n Xxe: ()=>/* reexport */ sign,\n Uxb: ()=>/* reexport */ toDegrees,\n Yr5: ()=>/* reexport */ toRadians,\n Bhw: ()=>/* reexport */ vec,\n yOA: ()=>/* reexport */ webgl_util_namespaceObject\n });\n // NAMESPACE OBJECT: ./Events.ts\n var Events_namespaceObject = {};\n $2c23f148d58cd887$var$__webpack_require__.r(Events_namespaceObject);\n $2c23f148d58cd887$var$__webpack_require__.d(Events_namespaceObject, {\n ActivateEvent: ()=>ActivateEvent,\n CollisionEndEvent: ()=>CollisionEndEvent,\n CollisionPostSolveEvent: ()=>CollisionPostSolveEvent,\n CollisionPreSolveEvent: ()=>CollisionPreSolveEvent,\n CollisionStartEvent: ()=>CollisionStartEvent,\n ContactEndEvent: ()=>ContactEndEvent,\n ContactStartEvent: ()=>ContactStartEvent,\n DeactivateEvent: ()=>DeactivateEvent,\n EnterTriggerEvent: ()=>EnterTriggerEvent,\n EnterViewPortEvent: ()=>EnterViewPortEvent,\n EventTypes: ()=>EventTypes,\n ExitTriggerEvent: ()=>ExitTriggerEvent,\n ExitViewPortEvent: ()=>ExitViewPortEvent,\n GameEvent: ()=>GameEvent,\n GameStartEvent: ()=>GameStartEvent,\n GameStopEvent: ()=>GameStopEvent,\n GamepadAxisEvent: ()=>GamepadAxisEvent,\n GamepadButtonEvent: ()=>GamepadButtonEvent,\n GamepadConnectEvent: ()=>GamepadConnectEvent,\n GamepadDisconnectEvent: ()=>GamepadDisconnectEvent,\n HiddenEvent: ()=>HiddenEvent,\n InitializeEvent: ()=>InitializeEvent,\n KillEvent: ()=>KillEvent,\n PostCollisionEvent: ()=>PostCollisionEvent,\n PostDebugDrawEvent: ()=>PostDebugDrawEvent,\n PostDrawEvent: ()=>PostDrawEvent,\n PostFrameEvent: ()=>PostFrameEvent,\n PostKillEvent: ()=>PostKillEvent,\n PostUpdateEvent: ()=>PostUpdateEvent,\n PreCollisionEvent: ()=>PreCollisionEvent,\n PreDebugDrawEvent: ()=>PreDebugDrawEvent,\n PreDrawEvent: ()=>PreDrawEvent,\n PreFrameEvent: ()=>PreFrameEvent,\n PreKillEvent: ()=>PreKillEvent,\n PreUpdateEvent: ()=>PreUpdateEvent,\n VisibleEvent: ()=>VisibleEvent\n });\n // NAMESPACE OBJECT: ./Graphics/Context/webgl-util.ts\n var webgl_util_namespaceObject = {};\n $2c23f148d58cd887$var$__webpack_require__.r(webgl_util_namespaceObject);\n $2c23f148d58cd887$var$__webpack_require__.d(webgl_util_namespaceObject, {\n getAttributeComponentSize: ()=>getAttributeComponentSize,\n getAttributePointerType: ()=>getAttributePointerType,\n getGlTypeSizeBytes: ()=>getGlTypeSizeBytes\n });\n // NAMESPACE OBJECT: ./Util/DrawUtil.ts\n var DrawUtil_namespaceObject = {};\n $2c23f148d58cd887$var$__webpack_require__.r(DrawUtil_namespaceObject);\n $2c23f148d58cd887$var$__webpack_require__.d(DrawUtil_namespaceObject, {\n circle: ()=>circle,\n line: ()=>line,\n point: ()=>point,\n roundRect: ()=>roundRect,\n vector: ()=>vector\n });\n // NAMESPACE OBJECT: ./Input/Index.ts\n var Input_Index_namespaceObject = {};\n $2c23f148d58cd887$var$__webpack_require__.r(Input_Index_namespaceObject);\n $2c23f148d58cd887$var$__webpack_require__.d(Input_Index_namespaceObject, {\n Axes: ()=>Axes,\n Buttons: ()=>Buttons,\n Gamepad: ()=>Gamepad,\n Gamepads: ()=>Gamepads,\n KeyEvent: ()=>KeyEvent,\n Keyboard: ()=>Keyboard,\n Keys: ()=>Keys,\n NativePointerButton: ()=>NativePointerButton,\n PointerButton: ()=>PointerButton,\n PointerComponent: ()=>PointerComponent,\n PointerEvent: ()=>PointerEvent,\n PointerEventReceiver: ()=>PointerEventReceiver,\n PointerScope: ()=>PointerScope,\n PointerSystem: ()=>PointerSystem,\n PointerType: ()=>PointerType,\n WheelDeltaMode: ()=>WheelDeltaMode,\n WheelEvent: ()=>WheelEvent\n });\n // NAMESPACE OBJECT: ./Util/Index.ts\n var Util_Index_namespaceObject = {};\n $2c23f148d58cd887$var$__webpack_require__.r(Util_Index_namespaceObject);\n $2c23f148d58cd887$var$__webpack_require__.d(Util_Index_namespaceObject, {\n ConsoleAppender: ()=>ConsoleAppender,\n DrawUtil: ()=>DrawUtil_namespaceObject,\n EasingFunctions: ()=>EasingFunctions,\n LogLevel: ()=>LogLevel,\n Logger: ()=>Logger,\n Observable: ()=>Observable,\n ScreenAppender: ()=>ScreenAppender,\n addItemToArray: ()=>addItemToArray,\n contains: ()=>contains,\n delay: ()=>delay,\n fail: ()=>fail,\n getPosition: ()=>getPosition,\n removeItemFromArray: ()=>removeItemFromArray\n });\n // EXTERNAL MODULE: ../../node_modules/core-js/es/array/sort.js\n var sort = $2c23f148d58cd887$var$__webpack_require__(4662);\n // EXTERNAL MODULE: ../../node_modules/core-js/es/object/keys.js\n var keys = $2c23f148d58cd887$var$__webpack_require__(8343);\n /**\r\n * Polyfill adding function\r\n */ function polyfill() {\n /* istanbul ignore next */ if (typeof window === \"undefined\") window = {\n audioContext: function() {\n return;\n }\n };\n /* istanbul ignore next */ if (typeof window !== \"undefined\" && !window.requestAnimationFrame) window.requestAnimationFrame = window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || function(callback) {\n window.setInterval(callback, 1000 / 60);\n };\n /* istanbul ignore next */ if (typeof window !== \"undefined\" && !window.cancelAnimationFrame) window.cancelAnimationFrame = window.webkitCancelAnimationFrame || window.mozCancelAnimationFrame || function() {\n return;\n };\n /* istanbul ignore next */ if (typeof window !== \"undefined\" && !window.AudioContext) {\n if (window.webkitAudioContext) {\n const ctx = window.webkitAudioContext;\n const replaceMe = ctx.prototype.decodeAudioData;\n window.webkitAudioContext.prototype.decodeAudioData = function(arrayBuffer) {\n return new Promise((resolve, reject)=>{\n replaceMe.call(this, arrayBuffer, resolve, reject);\n });\n };\n }\n window.AudioContext = window.AudioContext || window.webkitAudioContext || window.mozAudioContext || window.msAudioContext || window.oAudioContext;\n }\n /* istanbul ignore next */ if (typeof window !== \"undefined\" && !window.devicePixelRatio) window.devicePixelRatio = window.devicePixelRatio || 1;\n }\n /**\r\n * Flags is a feature flag implementation for Excalibur. They can only be operated **before [[Engine]] construction**\r\n * after which they are frozen and are read-only.\r\n *\r\n * Flags are used to enable experimental or preview features in Excalibur.\r\n */ class Flags {\n /**\r\n * Force excalibur to load the Canvas 2D graphics context fallback\r\n *\r\n * @warning not all features of excalibur are supported in the Canvas 2D fallback\r\n */ static useCanvasGraphicsContext() {\n Flags.enable(\"use-canvas-context\");\n }\n /**\r\n * Freeze all flag modifications making them readonly\r\n */ static freeze() {\n Flags._FROZEN = true;\n }\n /**\r\n * Resets internal flag state, not meant to be called by users. Only used for testing.\r\n *\r\n * Calling this in your game is UNSUPPORTED\r\n * @internal\r\n */ static _reset() {\n Flags._FROZEN = false;\n Flags._FLAGS = {};\n }\n /**\r\n * Enable a specific feature flag by name. **Note: can only be set before [[Engine]] constructor time**\r\n * @param flagName\r\n */ static enable(flagName) {\n if (this._FROZEN) throw Error(\"Feature flags can only be enabled before Engine constructor time\");\n Flags._FLAGS[flagName] = true;\n }\n /**\r\n * Disable a specific feature flag by name. **Note: can only be set before [[Engine]] constructor time**\r\n * @param flagName\r\n */ static disable(flagName) {\n if (this._FROZEN) throw Error(\"Feature flags can only be disabled before Engine constructor time\");\n Flags._FLAGS[flagName] = false;\n }\n /**\r\n * Check if a flag is enabled. If the flag is disabled or does not exist `false` is returned\r\n * @param flagName\r\n */ static isEnabled(flagName) {\n return !!Flags._FLAGS[flagName];\n }\n /**\r\n * Show a list of currently known flags\r\n */ static show() {\n return Object.keys(Flags._FLAGS);\n }\n }\n Flags._FROZEN = false;\n Flags._FLAGS = {};\n /**\r\n * Create a branded ID type from a number\r\n */ function createId(type, value) {\n return {\n type: type,\n value: value\n };\n }\n /**\r\n * Excalibur's typed event emitter, this allows events to be sent with any string to Type mapping\r\n */ class EventEmitter {\n constructor(){\n this._paused = false;\n this._listeners = {};\n this._listenersOnce = {};\n this._pipes = [];\n }\n clear() {\n this._listeners = {};\n this._listenersOnce = {};\n this._pipes.length = 0;\n }\n on(eventName, handler) {\n var _a;\n this._listeners[eventName] = (_a = this._listeners[eventName]) !== null && _a !== void 0 ? _a : [];\n this._listeners[eventName].push(handler);\n return {\n close: ()=>this.off(eventName, handler)\n };\n }\n once(eventName, handler) {\n var _a;\n this._listenersOnce[eventName] = (_a = this._listenersOnce[eventName]) !== null && _a !== void 0 ? _a : [];\n this._listenersOnce[eventName].push(handler);\n return {\n close: ()=>this.off(eventName, handler)\n };\n }\n off(eventName, handler) {\n var _a, _b, _c, _d;\n if (handler) {\n const listenerIndex = (_a = this._listeners[eventName]) === null || _a === void 0 ? void 0 : _a.indexOf(handler);\n if (listenerIndex > -1) (_b = this._listeners[eventName]) === null || _b === void 0 || _b.splice(listenerIndex, 1);\n const onceIndex = (_c = this._listenersOnce[eventName]) === null || _c === void 0 ? void 0 : _c.indexOf(handler);\n if (onceIndex > -1) (_d = this._listenersOnce[eventName]) === null || _d === void 0 || _d.splice(onceIndex, 1);\n } else delete this._listeners[eventName];\n }\n emit(eventName, event) {\n var _a;\n if (this._paused) return;\n (_a = this._listeners[eventName]) === null || _a === void 0 || _a.forEach((fn)=>fn(event));\n const onces = this._listenersOnce[eventName];\n this._listenersOnce[eventName] = [];\n if (onces) onces.forEach((fn)=>fn(event));\n this._pipes.forEach((pipe)=>{\n pipe.emit(eventName, event);\n });\n }\n pipe(emitter) {\n if (this === emitter) throw Error(\"Cannot pipe to self\");\n this._pipes.push(emitter);\n return {\n close: ()=>{\n const i = this._pipes.indexOf(emitter);\n if (i > -1) this._pipes.splice(i, 1);\n }\n };\n }\n unpipe(emitter) {\n const i = this._pipes.indexOf(emitter);\n if (i > -1) this._pipes.splice(i, 1);\n }\n pause() {\n this._paused = true;\n }\n unpause() {\n this._paused = false;\n }\n }\n var EventTypes;\n (function(EventTypes) {\n EventTypes[\"Kill\"] = \"kill\";\n EventTypes[\"PreKill\"] = \"prekill\";\n EventTypes[\"PostKill\"] = \"postkill\";\n EventTypes[\"PreDraw\"] = \"predraw\";\n EventTypes[\"PostDraw\"] = \"postdraw\";\n EventTypes[\"PreDebugDraw\"] = \"predebugdraw\";\n EventTypes[\"PostDebugDraw\"] = \"postdebugdraw\";\n EventTypes[\"PreUpdate\"] = \"preupdate\";\n EventTypes[\"PostUpdate\"] = \"postupdate\";\n EventTypes[\"PreFrame\"] = \"preframe\";\n EventTypes[\"PostFrame\"] = \"postframe\";\n EventTypes[\"PreCollision\"] = \"precollision\";\n EventTypes[\"CollisionStart\"] = \"collisionstart\";\n EventTypes[\"CollisionEnd\"] = \"collisionend\";\n EventTypes[\"PostCollision\"] = \"postcollision\";\n EventTypes[\"Initialize\"] = \"initialize\";\n EventTypes[\"Activate\"] = \"activate\";\n EventTypes[\"Deactivate\"] = \"deactivate\";\n EventTypes[\"ExitViewport\"] = \"exitviewport\";\n EventTypes[\"EnterViewport\"] = \"enterviewport\";\n EventTypes[\"ExitTrigger\"] = \"exit\";\n EventTypes[\"EnterTrigger\"] = \"enter\";\n EventTypes[\"Connect\"] = \"connect\";\n EventTypes[\"Disconnect\"] = \"disconnect\";\n EventTypes[\"Button\"] = \"button\";\n EventTypes[\"Axis\"] = \"axis\";\n EventTypes[\"Visible\"] = \"visible\";\n EventTypes[\"Hidden\"] = \"hidden\";\n EventTypes[\"Start\"] = \"start\";\n EventTypes[\"Stop\"] = \"stop\";\n EventTypes[\"PointerUp\"] = \"pointerup\";\n EventTypes[\"PointerDown\"] = \"pointerdown\";\n EventTypes[\"PointerMove\"] = \"pointermove\";\n EventTypes[\"PointerEnter\"] = \"pointerenter\";\n EventTypes[\"PointerLeave\"] = \"pointerleave\";\n EventTypes[\"PointerCancel\"] = \"pointercancel\";\n EventTypes[\"PointerWheel\"] = \"pointerwheel\";\n EventTypes[\"Up\"] = \"up\";\n EventTypes[\"Down\"] = \"down\";\n EventTypes[\"Move\"] = \"move\";\n EventTypes[\"Enter\"] = \"enter\";\n EventTypes[\"Leave\"] = \"leave\";\n EventTypes[\"Cancel\"] = \"cancel\";\n EventTypes[\"Wheel\"] = \"wheel\";\n EventTypes[\"Press\"] = \"press\";\n EventTypes[\"Release\"] = \"release\";\n EventTypes[\"Hold\"] = \"hold\";\n EventTypes[\"PointerDragStart\"] = \"pointerdragstart\";\n EventTypes[\"PointerDragEnd\"] = \"pointerdragend\";\n EventTypes[\"PointerDragEnter\"] = \"pointerdragenter\";\n EventTypes[\"PointerDragLeave\"] = \"pointerdragleave\";\n EventTypes[\"PointerDragMove\"] = \"pointerdragmove\";\n })(EventTypes || (EventTypes = {}));\n /**\r\n * Base event type in Excalibur that all other event types derive from. Not all event types are thrown on all Excalibur game objects,\r\n * some events are unique to a type, others are not.\r\n *\r\n */ class GameEvent {\n constructor(){\n this._bubbles = true;\n }\n /**\r\n * If set to false, prevents event from propagating to other actors. If true it will be propagated\r\n * to all actors that apply.\r\n */ get bubbles() {\n return this._bubbles;\n }\n set bubbles(value) {\n this._bubbles = value;\n }\n /**\r\n * Prevents event from bubbling\r\n */ stopPropagation() {\n this.bubbles = false;\n }\n }\n /**\r\n * The 'kill' event is emitted on actors when it is killed. The target is the actor that was killed.\r\n */ class KillEvent extends GameEvent {\n constructor(target){\n super();\n this.target = target;\n }\n }\n /**\r\n * The 'prekill' event is emitted directly before an actor is killed.\r\n */ class PreKillEvent extends GameEvent {\n constructor(target){\n super();\n this.target = target;\n }\n }\n /**\r\n * The 'postkill' event is emitted directly after the actor is killed.\r\n */ class PostKillEvent extends GameEvent {\n constructor(target){\n super();\n this.target = target;\n }\n }\n /**\r\n * The 'start' event is emitted on engine when has started and is ready for interaction.\r\n */ class GameStartEvent extends GameEvent {\n constructor(target){\n super();\n this.target = target;\n }\n }\n /**\r\n * The 'stop' event is emitted on engine when has been stopped and will no longer take input, update or draw.\r\n */ class GameStopEvent extends GameEvent {\n constructor(target){\n super();\n this.target = target;\n }\n }\n /**\r\n * The 'predraw' event is emitted on actors, scenes, and engine before drawing starts. Actors' predraw happens inside their graphics\r\n * transform so that all drawing takes place with the actor as the origin.\r\n *\r\n */ class PreDrawEvent extends GameEvent {\n constructor(ctx, delta, target){\n super();\n this.ctx = ctx;\n this.delta = delta;\n this.target = target;\n }\n }\n /**\r\n * The 'postdraw' event is emitted on actors, scenes, and engine after drawing finishes. Actors' postdraw happens inside their graphics\r\n * transform so that all drawing takes place with the actor as the origin.\r\n *\r\n */ class PostDrawEvent extends GameEvent {\n constructor(ctx, delta, target){\n super();\n this.ctx = ctx;\n this.delta = delta;\n this.target = target;\n }\n }\n /**\r\n * The 'predebugdraw' event is emitted on actors, scenes, and engine before debug drawing starts.\r\n */ class PreDebugDrawEvent extends GameEvent {\n constructor(ctx, target){\n super();\n this.ctx = ctx;\n this.target = target;\n }\n }\n /**\r\n * The 'postdebugdraw' event is emitted on actors, scenes, and engine after debug drawing starts.\r\n */ class PostDebugDrawEvent extends GameEvent {\n constructor(ctx, target){\n super();\n this.ctx = ctx;\n this.target = target;\n }\n }\n /**\r\n * The 'preupdate' event is emitted on actors, scenes, camera, and engine before the update starts.\r\n */ class PreUpdateEvent extends GameEvent {\n constructor(engine, delta, target){\n super();\n this.engine = engine;\n this.delta = delta;\n this.target = target;\n }\n }\n /**\r\n * The 'postupdate' event is emitted on actors, scenes, camera, and engine after the update ends.\r\n */ class PostUpdateEvent extends GameEvent {\n constructor(engine, delta, target){\n super();\n this.engine = engine;\n this.delta = delta;\n this.target = target;\n }\n }\n /**\r\n * The 'preframe' event is emitted on the engine, before the frame begins.\r\n */ class PreFrameEvent extends GameEvent {\n constructor(engine, prevStats){\n super();\n this.engine = engine;\n this.prevStats = prevStats;\n this.target = engine;\n }\n }\n /**\r\n * The 'postframe' event is emitted on the engine, after a frame ends.\r\n */ class PostFrameEvent extends GameEvent {\n constructor(engine, stats){\n super();\n this.engine = engine;\n this.stats = stats;\n this.target = engine;\n }\n }\n /**\r\n * Event received when a gamepad is connected to Excalibur. [[Gamepads]] receives this event.\r\n */ class GamepadConnectEvent extends GameEvent {\n constructor(index, gamepad){\n super();\n this.index = index;\n this.gamepad = gamepad;\n this.target = gamepad;\n }\n }\n /**\r\n * Event received when a gamepad is disconnected from Excalibur. [[Gamepads]] receives this event.\r\n */ class GamepadDisconnectEvent extends GameEvent {\n constructor(index, gamepad){\n super();\n this.index = index;\n this.gamepad = gamepad;\n this.target = gamepad;\n }\n }\n /**\r\n * Gamepad button event. See [[Gamepads]] for information on responding to controller input. [[Gamepad]] instances receive this event;\r\n */ class GamepadButtonEvent extends GameEvent {\n /**\r\n * @param button The Gamepad button\r\n * @param value A numeric value between 0 and 1\r\n */ constructor(button, value, target){\n super();\n this.button = button;\n this.value = value;\n this.target = target;\n }\n }\n /**\r\n * Gamepad axis event. See [[Gamepads]] for information on responding to controller input. [[Gamepad]] instances receive this event;\r\n */ class GamepadAxisEvent extends GameEvent {\n /**\r\n * @param axis The Gamepad axis\r\n * @param value A numeric value between -1 and 1\r\n */ constructor(axis, value, target){\n super();\n this.axis = axis;\n this.value = value;\n this.target = target;\n }\n }\n /**\r\n * Event received by the [[Engine]] when the browser window is visible on a screen.\r\n */ class VisibleEvent extends GameEvent {\n constructor(target){\n super();\n this.target = target;\n }\n }\n /**\r\n * Event received by the [[Engine]] when the browser window is hidden from all screens.\r\n */ class HiddenEvent extends GameEvent {\n constructor(target){\n super();\n this.target = target;\n }\n }\n /**\r\n * Event thrown on an [[Actor|actor]] when a collision will occur this frame if it resolves\r\n */ class PreCollisionEvent extends GameEvent {\n /**\r\n * @param actor The actor the event was thrown on\r\n * @param other The actor that will collided with the current actor\r\n * @param side The side that will be collided with the current actor\r\n * @param intersection Intersection vector\r\n */ constructor(actor, other, side, intersection){\n super();\n this.other = other;\n this.side = side;\n this.intersection = intersection;\n this.target = actor;\n }\n }\n /**\r\n * Event thrown on an [[Actor|actor]] when a collision has been resolved (body reacted) this frame\r\n */ class PostCollisionEvent extends GameEvent {\n /**\r\n * @param actor The actor the event was thrown on\r\n * @param other The actor that did collide with the current actor\r\n * @param side The side that did collide with the current actor\r\n * @param intersection Intersection vector\r\n */ constructor(actor, other, side, intersection){\n super();\n this.other = other;\n this.side = side;\n this.intersection = intersection;\n this.target = actor;\n }\n get actor() {\n return this.target;\n }\n set actor(actor) {\n this.target = actor;\n }\n }\n class ContactStartEvent {\n constructor(target, other, contact){\n this.target = target;\n this.other = other;\n this.contact = contact;\n }\n }\n class ContactEndEvent {\n constructor(target, other){\n this.target = target;\n this.other = other;\n }\n }\n class CollisionPreSolveEvent {\n constructor(target, other, side, intersection, contact){\n this.target = target;\n this.other = other;\n this.side = side;\n this.intersection = intersection;\n this.contact = contact;\n }\n }\n class CollisionPostSolveEvent {\n constructor(target, other, side, intersection, contact){\n this.target = target;\n this.other = other;\n this.side = side;\n this.intersection = intersection;\n this.contact = contact;\n }\n }\n /**\r\n * Event thrown the first time an [[Actor|actor]] collides with another, after an actor is in contact normal collision events are fired.\r\n */ class CollisionStartEvent extends GameEvent {\n /**\r\n *\r\n * @param actor\r\n * @param other\r\n * @param contact\r\n */ constructor(actor, other, contact){\n super();\n this.other = other;\n this.contact = contact;\n this.target = actor;\n }\n get actor() {\n return this.target;\n }\n set actor(actor) {\n this.target = actor;\n }\n }\n /**\r\n * Event thrown when the [[Actor|actor]] is no longer colliding with another\r\n */ class CollisionEndEvent extends GameEvent {\n /**\r\n *\r\n */ constructor(actor, other){\n super();\n this.other = other;\n this.target = actor;\n }\n get actor() {\n return this.target;\n }\n set actor(actor) {\n this.target = actor;\n }\n }\n /**\r\n * Event thrown on an [[Actor]], [[Scene]], and [[Engine]] only once before the first update call\r\n */ class InitializeEvent extends GameEvent {\n /**\r\n * @param engine The reference to the current engine\r\n */ constructor(engine, target){\n super();\n this.engine = engine;\n this.target = target;\n }\n }\n /**\r\n * Event thrown on a [[Scene]] on activation\r\n */ class ActivateEvent extends GameEvent {\n /**\r\n * @param context The context for the scene activation\r\n */ constructor(context, target){\n super();\n this.context = context;\n this.target = target;\n }\n }\n /**\r\n * Event thrown on a [[Scene]] on deactivation\r\n */ class DeactivateEvent extends GameEvent {\n /**\r\n * @param context The context for the scene deactivation\r\n */ constructor(context, target){\n super();\n this.context = context;\n this.target = target;\n }\n }\n /**\r\n * Event thrown on an [[Actor]] when it completely leaves the screen.\r\n */ class ExitViewPortEvent extends GameEvent {\n constructor(target){\n super();\n this.target = target;\n }\n }\n /**\r\n * Event thrown on an [[Actor]] when it completely leaves the screen.\r\n */ class EnterViewPortEvent extends GameEvent {\n constructor(target){\n super();\n this.target = target;\n }\n }\n class EnterTriggerEvent extends GameEvent {\n constructor(target, actor){\n super();\n this.target = target;\n this.actor = actor;\n }\n }\n class ExitTriggerEvent extends GameEvent {\n constructor(target, actor){\n super();\n this.target = target;\n this.actor = actor;\n }\n }\n const GamepadEvents = {\n GamepadConnect: \"connect\",\n GamepadDisconnect: \"disconnect\",\n GamepadButton: \"button\",\n GamepadAxis: \"axis\"\n };\n /**\r\n * Excalibur leverages the HTML5 Gamepad API [where it is supported](http://caniuse.com/#feat=gamepad)\r\n * to provide controller support for your games.\r\n */ class Gamepads {\n constructor(){\n this.events = new EventEmitter();\n /**\r\n * Whether or not to poll for Gamepad input (default: `false`)\r\n */ this.enabled = false;\n /**\r\n * Whether or not Gamepad API is supported\r\n */ this.supported = !!navigator.getGamepads;\n this._gamePadTimeStamps = [\n 0,\n 0,\n 0,\n 0\n ];\n this._oldPads = [];\n this._pads = [];\n this._initSuccess = false;\n this._navigator = navigator;\n this._minimumConfiguration = null;\n }\n init() {\n if (!this.supported) return;\n if (this._initSuccess) return;\n // In Chrome, this will return 4 undefined items until a button is pressed\n // In FF, this will not return any items until a button is pressed\n this._oldPads = this._clonePads(this._navigator.getGamepads());\n if (this._oldPads.length && this._oldPads[0]) this._initSuccess = true;\n }\n /**\r\n * Sets the minimum gamepad configuration, for example {axis: 4, buttons: 4} means\r\n * this game requires at minimum 4 axis inputs and 4 buttons, this is not restrictive\r\n * all other controllers with more axis or buttons are valid as well. If no minimum\r\n * configuration is set all pads are valid.\r\n */ setMinimumGamepadConfiguration(config) {\n this._enableAndUpdate(); // if config is used, implicitly enable\n this._minimumConfiguration = config;\n }\n /**\r\n * When implicitly enabled, set the enabled flag and run an update so information is updated\r\n */ _enableAndUpdate() {\n if (!this.enabled) {\n this.enabled = true;\n this.update();\n }\n }\n /**\r\n * Checks a navigator gamepad against the minimum configuration if present.\r\n */ _isGamepadValid(pad) {\n if (!this._minimumConfiguration) return true;\n if (!pad) return false;\n const axesLength = pad.axes.filter((value)=>{\n return true;\n }).length;\n const buttonLength = pad.buttons.filter((value)=>{\n return true;\n }).length;\n return axesLength >= this._minimumConfiguration.axis && buttonLength >= this._minimumConfiguration.buttons && pad.connected;\n }\n emit(eventName, event) {\n this.events.emit(eventName, event);\n }\n on(eventName, handler) {\n this._enableAndUpdate(); // implicitly enable\n return this.events.on(eventName, handler);\n }\n once(eventName, handler) {\n return this.events.once(eventName, handler);\n }\n off(eventName, handler) {\n this._enableAndUpdate(); // implicitly enable\n this.events.off(eventName, handler);\n }\n /**\r\n * Updates Gamepad state and publishes Gamepad events\r\n */ update() {\n if (!this.enabled || !this.supported) return;\n this.init();\n const gamepads = this._navigator.getGamepads();\n for(let i = 0; i < gamepads.length; i++){\n if (!gamepads[i]) {\n const gamepad = this.at(i);\n // If was connected, but now isn't emit the disconnect event\n if (gamepad.connected) this.events.emit(\"disconnect\", new GamepadDisconnectEvent(i, gamepad));\n // Reset connection status\n gamepad.connected = false;\n continue;\n } else {\n if (!this.at(i).connected && this._isGamepadValid(gamepads[i])) this.events.emit(\"connect\", new GamepadConnectEvent(i, this.at(i)));\n // Set connection status\n this.at(i).connected = true;\n }\n this.at(i).update();\n // Only supported in Chrome\n if (gamepads[i].timestamp && gamepads[i].timestamp === this._gamePadTimeStamps[i]) continue;\n this._gamePadTimeStamps[i] = gamepads[i].timestamp;\n // Add reference to navigator gamepad\n this.at(i).navigatorGamepad = gamepads[i];\n // Buttons\n let b, bi, a, ai, value;\n for(b in Buttons){\n bi = Buttons[b];\n if (typeof bi === \"number\") {\n if (gamepads[i].buttons[bi]) {\n value = gamepads[i].buttons[bi].value;\n if (value !== this._oldPads[i].getButton(bi)) {\n if (gamepads[i].buttons[bi].pressed) {\n this.at(i).updateButton(bi, value);\n this.at(i).events.emit(\"button\", new GamepadButtonEvent(bi, value, this.at(i)));\n } else this.at(i).updateButton(bi, 0);\n }\n }\n }\n }\n // Axes\n for(a in Axes){\n ai = Axes[a];\n if (typeof ai === \"number\") {\n value = gamepads[i].axes[ai];\n if (value !== this._oldPads[i].getAxes(ai)) {\n this.at(i).updateAxes(ai, value);\n this.at(i).events.emit(\"axis\", new GamepadAxisEvent(ai, value, this.at(i)));\n }\n }\n }\n this._oldPads[i] = this._clonePad(gamepads[i]);\n }\n }\n /**\r\n * Safely retrieves a Gamepad at a specific index and creates one if it doesn't yet exist\r\n */ at(index) {\n this._enableAndUpdate(); // implicitly enable gamepads when at() is called\n if (index >= this._pads.length) // Ensure there is a pad to retrieve\n for(let i = this._pads.length - 1, max = index; i < max; i++){\n this._pads.push(new Gamepad());\n this._oldPads.push(new Gamepad());\n }\n return this._pads[index];\n }\n /**\r\n * Returns a list of all valid gamepads that meet the minimum configuration requirement.\r\n */ getValidGamepads() {\n this._enableAndUpdate();\n const result = [];\n for(let i = 0; i < this._pads.length; i++)if (this._isGamepadValid(this.at(i).navigatorGamepad) && this.at(i).connected) result.push(this.at(i));\n return result;\n }\n /**\r\n * Gets the number of connected gamepads\r\n */ count() {\n return this._pads.filter((p)=>p.connected).length;\n }\n _clonePads(pads) {\n const arr = [];\n for(let i = 0, len = pads.length; i < len; i++)arr.push(this._clonePad(pads[i]));\n return arr;\n }\n /**\r\n * Fastest way to clone a known object is to do it yourself\r\n */ _clonePad(pad) {\n let i, len;\n const clonedPad = new Gamepad();\n if (!pad) return clonedPad;\n for(i = 0, len = pad.buttons.length; i < len; i++)if (pad.buttons[i]) clonedPad.updateButton(i, pad.buttons[i].value);\n for(i = 0, len = pad.axes.length; i < len; i++)clonedPad.updateAxes(i, pad.axes[i]);\n return clonedPad;\n }\n }\n /**\r\n * The minimum value an axis has to move before considering it a change\r\n */ Gamepads.MinAxisMoveThreshold = 0.05;\n /**\r\n * Gamepad holds state information for a connected controller. See [[Gamepads]]\r\n * for more information on handling controller input.\r\n */ class Gamepad {\n constructor(){\n this.events = new EventEmitter();\n this.connected = false;\n this._axes = new Array(4);\n this._buttons = new Array(16);\n this._buttonsUp = new Array(16);\n this._buttonsDown = new Array(16);\n for(let i = 0; i < this._buttons.length; i++)this._buttons[i] = 0;\n for(let i = 0; i < this._axes.length; i++)this._axes[i] = 0;\n }\n update() {\n // Reset buttonsDown and buttonsUp after update is complete\n this._buttonsDown = new Array(16);\n this._buttonsUp = new Array(16);\n }\n /**\r\n * Whether or not the given button is pressed\r\n *\r\n * @deprecated will be removed in v0.28.0. Use isButtonHeld instead\r\n * @param button The button to query\r\n * @param threshold The threshold over which the button is considered to be pressed\r\n */ isButtonPressed(button, threshold = 1) {\n return this._buttons[button] >= threshold;\n }\n /**\r\n * Tests if a certain button is held down. This is persisted between frames.\r\n *\r\n * @param button The button to query\r\n * @param threshold The threshold over which the button is considered to be pressed\r\n */ isButtonHeld(button, threshold = 1) {\n return this._buttons[button] >= threshold;\n }\n /**\r\n * Tests if a certain button was just pressed this frame. This is cleared at the end of the update frame.\r\n *\r\n * @param button Test whether a button was just pressed\r\n * @param threshold The threshold over which the button is considered to be pressed\r\n */ wasButtonPressed(button, threshold = 1) {\n return this._buttonsDown[button] >= threshold;\n }\n /**\r\n * Tests if a certain button was just released this frame. This is cleared at the end of the update frame.\r\n *\r\n * @param button Test whether a button was just released\r\n */ wasButtonReleased(button) {\n return Boolean(this._buttonsUp[button]);\n }\n /**\r\n * Gets the given button value between 0 and 1\r\n */ getButton(button) {\n return this._buttons[button];\n }\n /**\r\n * Gets the given axis value between -1 and 1. Values below\r\n * [[MinAxisMoveThreshold]] are considered 0.\r\n */ getAxes(axes) {\n const value = this._axes[axes];\n if (Math.abs(value) < Gamepads.MinAxisMoveThreshold) return 0;\n else return value;\n }\n updateButton(buttonIndex, value) {\n // button was just released\n if (value === 0 && this._buttons[buttonIndex]) this._buttonsUp[buttonIndex] = 1;\n else this._buttonsDown[buttonIndex] = value;\n this._buttons[buttonIndex] = value;\n }\n updateAxes(axesIndex, value) {\n this._axes[axesIndex] = value;\n }\n emit(eventName, event) {\n this.events.emit(eventName, event);\n }\n on(eventName, handler) {\n return this.events.on(eventName, handler);\n }\n once(eventName, handler) {\n return this.events.once(eventName, handler);\n }\n off(eventName, handler) {\n this.events.off(eventName, handler);\n }\n }\n /**\r\n * Gamepad Buttons enumeration\r\n */ var Buttons;\n (function(Buttons) {\n /**\r\n * Face 1 button (e.g. A)\r\n */ Buttons[Buttons[\"Face1\"] = 0] = \"Face1\";\n /**\r\n * Face 2 button (e.g. B)\r\n */ Buttons[Buttons[\"Face2\"] = 1] = \"Face2\";\n /**\r\n * Face 3 button (e.g. X)\r\n */ Buttons[Buttons[\"Face3\"] = 2] = \"Face3\";\n /**\r\n * Face 4 button (e.g. Y)\r\n */ Buttons[Buttons[\"Face4\"] = 3] = \"Face4\";\n /**\r\n * Left bumper button\r\n */ Buttons[Buttons[\"LeftBumper\"] = 4] = \"LeftBumper\";\n /**\r\n * Right bumper button\r\n */ Buttons[Buttons[\"RightBumper\"] = 5] = \"RightBumper\";\n /**\r\n * Left trigger button\r\n */ Buttons[Buttons[\"LeftTrigger\"] = 6] = \"LeftTrigger\";\n /**\r\n * Right trigger button\r\n */ Buttons[Buttons[\"RightTrigger\"] = 7] = \"RightTrigger\";\n /**\r\n * Select button\r\n */ Buttons[Buttons[\"Select\"] = 8] = \"Select\";\n /**\r\n * Start button\r\n */ Buttons[Buttons[\"Start\"] = 9] = \"Start\";\n /**\r\n * Left analog stick press (e.g. L3)\r\n */ Buttons[Buttons[\"LeftStick\"] = 10] = \"LeftStick\";\n /**\r\n * Right analog stick press (e.g. R3)\r\n */ Buttons[Buttons[\"RightStick\"] = 11] = \"RightStick\";\n /**\r\n * D-pad up\r\n */ Buttons[Buttons[\"DpadUp\"] = 12] = \"DpadUp\";\n /**\r\n * D-pad down\r\n */ Buttons[Buttons[\"DpadDown\"] = 13] = \"DpadDown\";\n /**\r\n * D-pad left\r\n */ Buttons[Buttons[\"DpadLeft\"] = 14] = \"DpadLeft\";\n /**\r\n * D-pad right\r\n */ Buttons[Buttons[\"DpadRight\"] = 15] = \"DpadRight\";\n })(Buttons || (Buttons = {}));\n /**\r\n * Gamepad Axes enumeration\r\n */ var Axes;\n (function(Axes) {\n /**\r\n * Left analogue stick X direction\r\n */ Axes[Axes[\"LeftStickX\"] = 0] = \"LeftStickX\";\n /**\r\n * Left analogue stick Y direction\r\n */ Axes[Axes[\"LeftStickY\"] = 1] = \"LeftStickY\";\n /**\r\n * Right analogue stick X direction\r\n */ Axes[Axes[\"RightStickX\"] = 2] = \"RightStickX\";\n /**\r\n * Right analogue stick Y direction\r\n */ Axes[Axes[\"RightStickY\"] = 3] = \"RightStickY\";\n })(Axes || (Axes = {}));\n /* eslint-disable no-console */ /**\r\n * Logging level that Excalibur will tag\r\n */ var LogLevel;\n (function(LogLevel) {\n LogLevel[LogLevel[\"Debug\"] = 0] = \"Debug\";\n LogLevel[LogLevel[\"Info\"] = 1] = \"Info\";\n LogLevel[LogLevel[\"Warn\"] = 2] = \"Warn\";\n LogLevel[LogLevel[\"Error\"] = 3] = \"Error\";\n LogLevel[LogLevel[\"Fatal\"] = 4] = \"Fatal\";\n })(LogLevel || (LogLevel = {}));\n /**\r\n * Static singleton that represents the logging facility for Excalibur.\r\n * Excalibur comes built-in with a [[ConsoleAppender]] and [[ScreenAppender]].\r\n * Derive from [[Appender]] to create your own logging appenders.\r\n */ class Logger {\n constructor(){\n this._appenders = [];\n /**\r\n * Gets or sets the default logging level. Excalibur will only log\r\n * messages if equal to or above this level. Default: [[LogLevel.Info]]\r\n */ this.defaultLevel = LogLevel.Info;\n if (Logger._INSTANCE) throw new Error(\"Logger is a singleton\");\n Logger._INSTANCE = this;\n // Default console appender\n Logger._INSTANCE.addAppender(new ConsoleAppender());\n return Logger._INSTANCE;\n }\n /**\r\n * Gets the current static instance of Logger\r\n */ static getInstance() {\n if (Logger._INSTANCE == null) Logger._INSTANCE = new Logger();\n return Logger._INSTANCE;\n }\n /**\r\n * Adds a new [[Appender]] to the list of appenders to write to\r\n */ addAppender(appender) {\n this._appenders.push(appender);\n }\n /**\r\n * Clears all appenders from the logger\r\n */ clearAppenders() {\n this._appenders.length = 0;\n }\n /**\r\n * Logs a message at a given LogLevel\r\n * @param level The LogLevel`to log the message at\r\n * @param args An array of arguments to write to an appender\r\n */ _log(level, args) {\n if (level == null) level = this.defaultLevel;\n const len = this._appenders.length;\n for(let i = 0; i < len; i++)if (level >= this.defaultLevel) this._appenders[i].log(level, args);\n }\n /**\r\n * Writes a log message at the [[LogLevel.Debug]] level\r\n * @param args Accepts any number of arguments\r\n */ debug(...args) {\n this._log(LogLevel.Debug, args);\n }\n /**\r\n * Writes a log message at the [[LogLevel.Info]] level\r\n * @param args Accepts any number of arguments\r\n */ info(...args) {\n this._log(LogLevel.Info, args);\n }\n /**\r\n * Writes a log message at the [[LogLevel.Warn]] level\r\n * @param args Accepts any number of arguments\r\n */ warn(...args) {\n this._log(LogLevel.Warn, args);\n }\n /**\r\n * Writes a log message at the [[LogLevel.Error]] level\r\n * @param args Accepts any number of arguments\r\n */ error(...args) {\n this._log(LogLevel.Error, args);\n }\n /**\r\n * Writes a log message at the [[LogLevel.Fatal]] level\r\n * @param args Accepts any number of arguments\r\n */ fatal(...args) {\n this._log(LogLevel.Fatal, args);\n }\n }\n Logger._INSTANCE = null;\n /**\r\n * Console appender for browsers (i.e. `console.log`)\r\n */ class ConsoleAppender {\n /**\r\n * Logs a message at the given [[LogLevel]]\r\n * @param level Level to log at\r\n * @param args Arguments to log\r\n */ log(level, args) {\n // Check for console support\n if (!console && !console.log && console.warn && console.error) // todo maybe do something better than nothing\n return;\n // Create a new console args array\n const consoleArgs = [];\n consoleArgs.unshift.apply(consoleArgs, args);\n consoleArgs.unshift(\"[\" + LogLevel[level] + \"] : \");\n if (level < LogLevel.Warn) {\n // Call .log for Debug/Info\n if (console.log.apply) // this is required on some older browsers that don't support apply on console.log :(\n console.log.apply(console, consoleArgs);\n else console.log(consoleArgs.join(\" \"));\n } else if (level < LogLevel.Error) {\n // Call .warn for Warn\n if (console.warn.apply) console.warn.apply(console, consoleArgs);\n else console.warn(consoleArgs.join(\" \"));\n } else // Call .error for Error/Fatal\n if (console.error.apply) console.error.apply(console, consoleArgs);\n else console.error(consoleArgs.join(\" \"));\n }\n }\n /**\r\n * On-screen (canvas) appender\r\n */ class ScreenAppender {\n /**\r\n * @param width Width of the screen appender in pixels\r\n * @param height Height of the screen appender in pixels\r\n */ constructor(width, height){\n // @todo Clean this up\n this._messages = [];\n this._canvas = document.createElement(\"canvas\");\n this._canvas.width = width || window.innerWidth;\n this._canvas.height = height || window.innerHeight;\n this._canvas.style.position = \"absolute\";\n // eslint-disable-next-line\n this._ctx = this._canvas.getContext(\"2d\"); // eslint-disable-line\n document.body.appendChild(this._canvas);\n }\n /**\r\n * Logs a message at the given [[LogLevel]]\r\n * @param level Level to log at\r\n * @param args Arguments to log\r\n */ log(level, args) {\n const message = args.join(\",\");\n this._ctx.clearRect(0, 0, this._canvas.width, this._canvas.height);\n this._messages.unshift(\"[\" + LogLevel[level] + \"] : \" + message);\n let pos = 10;\n let opacity = 1.0;\n for(let i = 0; i < this._messages.length; i++){\n this._ctx.fillStyle = \"rgba(255,255,255,\" + opacity.toFixed(2) + \")\";\n this._ctx.fillText(this._messages[i], 200, pos);\n pos += 10;\n opacity = opacity > 0 ? opacity - 0.05 : 0;\n }\n }\n }\n /**\r\n * Checks if excalibur is in a x-origin iframe\r\n */ function isCrossOriginIframe() {\n try {\n // Try and listen to events on top window frame if within an iframe.\n //\n // See https://github.com/excaliburjs/Excalibur/issues/1294\n //\n // Attempt to add an event listener, which triggers a DOMException on\n // cross-origin iframes\n const noop = ()=>{\n return;\n };\n window.top.addEventListener(\"blur\", noop);\n window.top.removeEventListener(\"blur\", noop);\n } catch (_a) {\n return true;\n }\n return false;\n }\n /**\r\n * Enum representing physical input key codes\r\n */ var Keys;\n (function(Keys) {\n // NUMPAD\n Keys[\"Num0\"] = \"Numpad0\";\n Keys[\"Num1\"] = \"Numpad1\";\n Keys[\"Num2\"] = \"Numpad2\";\n Keys[\"Num3\"] = \"Numpad3\";\n Keys[\"Num4\"] = \"Numpad4\";\n Keys[\"Num5\"] = \"Numpad5\";\n Keys[\"Num6\"] = \"Numpad6\";\n Keys[\"Num7\"] = \"Numpad7\";\n Keys[\"Num8\"] = \"Numpad8\";\n Keys[\"Num9\"] = \"Numpad9\";\n Keys[\"NumAdd\"] = \"NumpadAdd\";\n Keys[\"NumSubtract\"] = \"NumpadSubtract\";\n Keys[\"NumMultiply\"] = \"NumpadMultiply\";\n Keys[\"NumDivide\"] = \"NumpadDivide\";\n // NumComma = 'NumpadComma', // not x-browser\n Keys[\"NumDecimal\"] = \"NumpadDecimal\";\n Keys[\"Numpad0\"] = \"Numpad0\";\n Keys[\"Numpad1\"] = \"Numpad1\";\n Keys[\"Numpad2\"] = \"Numpad2\";\n Keys[\"Numpad3\"] = \"Numpad3\";\n Keys[\"Numpad4\"] = \"Numpad4\";\n Keys[\"Numpad5\"] = \"Numpad5\";\n Keys[\"Numpad6\"] = \"Numpad6\";\n Keys[\"Numpad7\"] = \"Numpad7\";\n Keys[\"Numpad8\"] = \"Numpad8\";\n Keys[\"Numpad9\"] = \"Numpad9\";\n Keys[\"NumpadAdd\"] = \"NumpadAdd\";\n Keys[\"NumpadSubtract\"] = \"NumpadSubtract\";\n Keys[\"NumpadMultiply\"] = \"NumpadMultiply\";\n Keys[\"NumpadDivide\"] = \"NumpadDivide\";\n // NumpadComma = 'NumpadComma', // not x-browser\n Keys[\"NumpadDecimal\"] = \"NumpadDecimal\";\n // MODIFIERS\n Keys[\"NumLock\"] = \"NumLock\";\n Keys[\"ShiftLeft\"] = \"ShiftLeft\";\n Keys[\"ShiftRight\"] = \"ShiftRight\";\n Keys[\"AltLeft\"] = \"AltLeft\";\n Keys[\"AltRight\"] = \"AltRight\";\n Keys[\"ControlLeft\"] = \"ControlLeft\";\n Keys[\"ControlRight\"] = \"ControlRight\";\n Keys[\"MetaLeft\"] = \"MetaLeft\";\n Keys[\"MetaRight\"] = \"MetaRight\";\n // NUMBERS\n Keys[\"Key0\"] = \"Digit0\";\n Keys[\"Key1\"] = \"Digit1\";\n Keys[\"Key2\"] = \"Digit2\";\n Keys[\"Key3\"] = \"Digit3\";\n Keys[\"Key4\"] = \"Digit4\";\n Keys[\"Key5\"] = \"Digit5\";\n Keys[\"Key6\"] = \"Digit6\";\n Keys[\"Key7\"] = \"Digit7\";\n Keys[\"Key8\"] = \"Digit8\";\n Keys[\"Key9\"] = \"Digit9\";\n Keys[\"Digit0\"] = \"Digit0\";\n Keys[\"Digit1\"] = \"Digit1\";\n Keys[\"Digit2\"] = \"Digit2\";\n Keys[\"Digit3\"] = \"Digit3\";\n Keys[\"Digit4\"] = \"Digit4\";\n Keys[\"Digit5\"] = \"Digit5\";\n Keys[\"Digit6\"] = \"Digit6\";\n Keys[\"Digit7\"] = \"Digit7\";\n Keys[\"Digit8\"] = \"Digit8\";\n Keys[\"Digit9\"] = \"Digit9\";\n // FUNCTION KEYS\n Keys[\"F1\"] = \"F1\";\n Keys[\"F2\"] = \"F2\";\n Keys[\"F3\"] = \"F3\";\n Keys[\"F4\"] = \"F4\";\n Keys[\"F5\"] = \"F5\";\n Keys[\"F6\"] = \"F6\";\n Keys[\"F7\"] = \"F7\";\n Keys[\"F8\"] = \"F8\";\n Keys[\"F9\"] = \"F9\";\n Keys[\"F10\"] = \"F10\";\n Keys[\"F11\"] = \"F11\";\n Keys[\"F12\"] = \"F12\";\n // LETTERS\n Keys[\"A\"] = \"KeyA\";\n Keys[\"B\"] = \"KeyB\";\n Keys[\"C\"] = \"KeyC\";\n Keys[\"D\"] = \"KeyD\";\n Keys[\"E\"] = \"KeyE\";\n Keys[\"F\"] = \"KeyF\";\n Keys[\"G\"] = \"KeyG\";\n Keys[\"H\"] = \"KeyH\";\n Keys[\"I\"] = \"KeyI\";\n Keys[\"J\"] = \"KeyJ\";\n Keys[\"K\"] = \"KeyK\";\n Keys[\"L\"] = \"KeyL\";\n Keys[\"M\"] = \"KeyM\";\n Keys[\"N\"] = \"KeyN\";\n Keys[\"O\"] = \"KeyO\";\n Keys[\"P\"] = \"KeyP\";\n Keys[\"Q\"] = \"KeyQ\";\n Keys[\"R\"] = \"KeyR\";\n Keys[\"S\"] = \"KeyS\";\n Keys[\"T\"] = \"KeyT\";\n Keys[\"U\"] = \"KeyU\";\n Keys[\"V\"] = \"KeyV\";\n Keys[\"W\"] = \"KeyW\";\n Keys[\"X\"] = \"KeyX\";\n Keys[\"Y\"] = \"KeyY\";\n Keys[\"Z\"] = \"KeyZ\";\n Keys[\"KeyA\"] = \"KeyA\";\n Keys[\"KeyB\"] = \"KeyB\";\n Keys[\"KeyC\"] = \"KeyC\";\n Keys[\"KeyD\"] = \"KeyD\";\n Keys[\"KeyE\"] = \"KeyE\";\n Keys[\"KeyF\"] = \"KeyF\";\n Keys[\"KeyG\"] = \"KeyG\";\n Keys[\"KeyH\"] = \"KeyH\";\n Keys[\"KeyI\"] = \"KeyI\";\n Keys[\"KeyJ\"] = \"KeyJ\";\n Keys[\"KeyK\"] = \"KeyK\";\n Keys[\"KeyL\"] = \"KeyL\";\n Keys[\"KeyM\"] = \"KeyM\";\n Keys[\"KeyN\"] = \"KeyN\";\n Keys[\"KeyO\"] = \"KeyO\";\n Keys[\"KeyP\"] = \"KeyP\";\n Keys[\"KeyQ\"] = \"KeyQ\";\n Keys[\"KeyR\"] = \"KeyR\";\n Keys[\"KeyS\"] = \"KeyS\";\n Keys[\"KeyT\"] = \"KeyT\";\n Keys[\"KeyU\"] = \"KeyU\";\n Keys[\"KeyV\"] = \"KeyV\";\n Keys[\"KeyW\"] = \"KeyW\";\n Keys[\"KeyX\"] = \"KeyX\";\n Keys[\"KeyY\"] = \"KeyY\";\n Keys[\"KeyZ\"] = \"KeyZ\";\n // SYMBOLS\n Keys[\"Semicolon\"] = \"Semicolon\";\n Keys[\"Quote\"] = \"Quote\";\n Keys[\"Comma\"] = \"Comma\";\n Keys[\"Minus\"] = \"Minus\";\n Keys[\"Period\"] = \"Period\";\n Keys[\"Slash\"] = \"Slash\";\n Keys[\"Equal\"] = \"Equal\";\n Keys[\"BracketLeft\"] = \"BracketLeft\";\n Keys[\"Backslash\"] = \"Backslash\";\n Keys[\"BracketRight\"] = \"BracketRight\";\n Keys[\"Backquote\"] = \"Backquote\";\n // DIRECTIONS\n Keys[\"Up\"] = \"ArrowUp\";\n Keys[\"Down\"] = \"ArrowDown\";\n Keys[\"Left\"] = \"ArrowLeft\";\n Keys[\"Right\"] = \"ArrowRight\";\n Keys[\"ArrowUp\"] = \"ArrowUp\";\n Keys[\"ArrowDown\"] = \"ArrowDown\";\n Keys[\"ArrowLeft\"] = \"ArrowLeft\";\n Keys[\"ArrowRight\"] = \"ArrowRight\";\n // OTHER\n Keys[\"Space\"] = \"Space\";\n Keys[\"Backspace\"] = \"Backspace\";\n Keys[\"Delete\"] = \"Delete\";\n Keys[\"Esc\"] = \"Escape\";\n Keys[\"Escape\"] = \"Escape\";\n Keys[\"Enter\"] = \"Enter\";\n Keys[\"NumpadEnter\"] = \"NumpadEnter\";\n Keys[\"ContextMenu\"] = \"ContextMenu\";\n })(Keys || (Keys = {}));\n /**\r\n * Event thrown on a game object for a key event\r\n */ class KeyEvent extends GameEvent {\n /**\r\n * @param key The key responsible for throwing the event\r\n * @param value The key's typed value the browser detected\r\n * @param originalEvent The original keyboard event that Excalibur handled\r\n */ constructor(key, value, originalEvent){\n super();\n this.key = key;\n this.value = value;\n this.originalEvent = originalEvent;\n }\n }\n const KeyEvents = {\n Press: \"press\",\n Hold: \"hold\",\n Release: \"release\"\n };\n /**\r\n * Provides keyboard support for Excalibur.\r\n */ class Keyboard {\n constructor(){\n this.events = new EventEmitter();\n /**\r\n * Keys that are currently held down\r\n */ this._keys = [];\n /**\r\n * Keys up in the current frame\r\n */ this._keysUp = [];\n /**\r\n * Keys down in the current frame\r\n */ this._keysDown = [];\n this._releaseAllKeys = (ev)=>{\n for (const code of this._keys){\n const keyEvent = new KeyEvent(code, ev.key, ev);\n this.events.emit(\"up\", keyEvent);\n this.events.emit(\"release\", keyEvent);\n }\n this._keysUp = Array.from(new Set(this._keys.concat(this._keysUp)));\n this._keys.length = 0;\n };\n this._handleKeyDown = (ev)=>{\n // handle macos meta key issue\n // https://github.com/excaliburjs/Excalibur/issues/2608\n if (!ev.metaKey && (this._keys.includes(Keys.MetaLeft) || this._keys.includes(Keys.MetaRight))) this._releaseAllKeys(ev);\n const code = ev.code;\n if (this._keys.indexOf(code) === -1) {\n this._keys.push(code);\n this._keysDown.push(code);\n const keyEvent = new KeyEvent(code, ev.key, ev);\n this.events.emit(\"down\", keyEvent);\n this.events.emit(\"press\", keyEvent);\n }\n };\n this._handleKeyUp = (ev)=>{\n const code = ev.code;\n const key = this._keys.indexOf(code);\n this._keys.splice(key, 1);\n this._keysUp.push(code);\n const keyEvent = new KeyEvent(code, ev.key, ev);\n // alias the old api, we may want to deprecate this in the future\n this.events.emit(\"up\", keyEvent);\n this.events.emit(\"release\", keyEvent);\n // handle macos meta key issue\n // https://github.com/excaliburjs/Excalibur/issues/2608\n if (ev.key === \"Meta\") this._releaseAllKeys(ev);\n };\n }\n emit(eventName, event) {\n this.events.emit(eventName, event);\n }\n on(eventName, handler) {\n return this.events.on(eventName, handler);\n }\n once(eventName, handler) {\n return this.events.once(eventName, handler);\n }\n off(eventName, handler) {\n this.events.off(eventName, handler);\n }\n /**\r\n * Initialize Keyboard event listeners\r\n */ init(keyboardOptions) {\n let { global: global } = keyboardOptions;\n const { grabWindowFocus: grabWindowFocus } = keyboardOptions;\n if (!global) {\n if (isCrossOriginIframe()) {\n global = window;\n // Workaround for iframes like for itch.io or codesandbox\n // https://www.reddit.com/r/gamemaker/comments/kfs5cs/keyboard_inputs_no_longer_working_in_html5_game/\n // https://forum.gamemaker.io/index.php?threads/solved-keyboard-issue-on-itch-io.87336/\n if (grabWindowFocus) window.focus();\n Logger.getInstance().warn(\"Excalibur might be in a cross-origin iframe, in order to receive keyboard events it must be in focus\");\n } else global = window.top;\n }\n global.addEventListener(\"blur\", ()=>{\n this._keys.length = 0; // empties array efficiently\n });\n // key up is on window because canvas cannot have focus\n global.addEventListener(\"keyup\", this._handleKeyUp);\n // key down is on window because canvas cannot have focus\n global.addEventListener(\"keydown\", this._handleKeyDown);\n }\n update() {\n // Reset keysDown and keysUp after update is complete\n this._keysDown.length = 0;\n this._keysUp.length = 0;\n // Emit synthetic \"hold\" event\n for(let i = 0; i < this._keys.length; i++)this.events.emit(\"hold\", new KeyEvent(this._keys[i]));\n }\n /**\r\n * Gets list of keys being pressed down\r\n */ getKeys() {\n return this._keys;\n }\n /**\r\n * Tests if a certain key was just pressed this frame. This is cleared at the end of the update frame.\r\n * @param key Test whether a key was just pressed\r\n */ wasPressed(key) {\n return this._keysDown.indexOf(key) > -1;\n }\n /**\r\n * Tests if a certain key is held down. This is persisted between frames.\r\n * @param key Test whether a key is held down\r\n */ isHeld(key) {\n return this._keys.indexOf(key) > -1;\n }\n /**\r\n * Tests if a certain key was just released this frame. This is cleared at the end of the update frame.\r\n * @param key Test whether a key was just released\r\n */ wasReleased(key) {\n return this._keysUp.indexOf(key) > -1;\n }\n /**\r\n * Trigger a manual key event\r\n * @param type\r\n * @param key\r\n * @param character\r\n */ triggerEvent(type, key, character) {\n if (type === \"down\") this._handleKeyDown(new KeyboardEvent(\"keydown\", {\n code: key,\n key: character !== null && character !== void 0 ? character : null\n }));\n if (type === \"up\") this._handleKeyUp(new KeyboardEvent(\"keyup\", {\n code: key,\n key: character !== null && character !== void 0 ? character : null\n }));\n }\n }\n /**\r\n * Determines the scope of handling mouse/touch events.\r\n */ var PointerScope;\n (function(PointerScope) {\n /**\r\n * Handle events on the `canvas` element only. Events originating outside the\r\n * `canvas` will not be handled.\r\n */ PointerScope[\"Canvas\"] = \"Canvas\";\n /**\r\n * Handles events on the entire document. All events will be handled by Excalibur.\r\n */ PointerScope[\"Document\"] = \"Document\";\n })(PointerScope || (PointerScope = {}));\n /**\r\n * @module\r\n * Pseudo-Random Utility\r\n *\r\n * A pseudo-random utility to add seeded random support for help in\r\n * generating things like terrain or reproducible randomness. Uses the\r\n * [Mersenne Twister](https://en.wikipedia.org/wiki/Mersenne_Twister) algorithm.\r\n */ /**\r\n * 32-bit mask\r\n */ const BITMASK32 = 0xffffffff;\n /**\r\n * Pseudo-random number generator following the Mersenne_Twister algorithm. Given a seed this generator will produce the same sequence\r\n * of numbers each time it is called.\r\n * See https://en.wikipedia.org/wiki/Mersenne_Twister for more details.\r\n * Uses the MT19937-32 (2002) implementation documented here http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/MT2002/emt19937ar.html\r\n *\r\n * Api inspired by http://chancejs.com/# https://github.com/chancejs/chancejs\r\n */ class Random {\n /**\r\n * If no seed is specified, the Date.now() is used\r\n */ constructor(seed){\n this.seed = seed;\n // Separation point of one one word, the number of bits in the lower bitmask 0 <= r <= w-1\n this._lowerMask = 0x7fffffff; // 31 bits same as _r\n this._upperMask = 0x80000000; // 34 high bits\n // Word size, 64 bits\n this._w = 32;\n // Degree of recurrence\n this._n = 624;\n // Middle word, an offset used in the recurrence defining the series x, 1<=m>> 0;\n for(let i = 1; i < this._n; i++){\n const s = this._mt[i - 1] ^ this._mt[i - 1] >>> this._w - 2;\n // numbers are bigger than the JS max safe int, add in 16-bit chunks to prevent IEEE rounding errors on high bits\n this._mt[i] = (this._f * ((s & 0xffff0000) >>> 16) << 16) + this._f * (s & 0xffff) + i >>> 0;\n }\n this._index = this._n;\n }\n /**\r\n * Apply the twist\r\n */ _twist() {\n const mag01 = [\n 0x0,\n this._a\n ];\n let y = 0, i = 0;\n for(; i < this._n - this._m; i++){\n y = this._mt[i] & this._upperMask | this._mt[i + 1] & this._lowerMask;\n this._mt[i] = this._mt[i + this._m] ^ y >>> 1 ^ mag01[y & 0x1] & BITMASK32;\n }\n for(; i < this._n - 1; i++){\n y = this._mt[i] & this._upperMask | this._mt[i + 1] & this._lowerMask;\n this._mt[i] = this._mt[i + (this._m - this._n)] ^ y >>> 1 ^ mag01[y & 0x1] & BITMASK32;\n }\n y = this._mt[this._n - 1] & this._upperMask | this._mt[0] & this._lowerMask;\n this._mt[this._n - 1] = this._mt[this._m - 1] ^ y >>> 1 ^ mag01[y & 0x1] & BITMASK32;\n this._index = 0;\n }\n /**\r\n * Return next 32 bit integer number in sequence\r\n */ nextInt() {\n if (this._index >= this._n) this._twist();\n let y = this._mt[this._index++];\n y ^= y >>> this._u;\n y ^= y << this._s & this._b;\n y ^= y << this._t & this._c;\n y ^= y >>> this._l;\n return y >>> 0;\n }\n /**\r\n * Return a random floating point number between [0, 1)\r\n */ next() {\n return this.nextInt() * (1.0 / 4294967296.0); // divided by 2^32\n }\n /**\r\n * Return a random floating point in range [min, max) min is included, max is not included\r\n */ floating(min, max) {\n return (max - min) * this.next() + min;\n }\n /**\r\n * Return a random integer in range [min, max] min is included, max is included.\r\n * Implemented with rejection sampling, see https://medium.com/@betable/tifu-by-using-math-random-f1c308c4fd9d#.i13tdiu5a\r\n */ integer(min, max) {\n return Math.floor((max - min + 1) * this.next() + min);\n }\n /**\r\n * Returns true or false randomly with 50/50 odds by default.\r\n * By default the likelihood of returning a true is .5 (50%).\r\n * @param likelihood takes values between [0, 1]\r\n */ bool(likelihood = 0.5) {\n return this.next() <= likelihood;\n }\n /**\r\n * Returns one element from an array at random\r\n */ pickOne(array) {\n return array[this.integer(0, array.length - 1)];\n }\n /**\r\n * Returns a new array random picking elements from the original\r\n * @param array Original array to pick from\r\n * @param numPicks can be any positive number\r\n * @param allowDuplicates indicates whether the returned set is allowed duplicates (it does not mean there will always be duplicates\r\n * just that it is possible)\r\n */ pickSet(array, numPicks, allowDuplicates = false) {\n if (allowDuplicates) return this._pickSetWithDuplicates(array, numPicks);\n else return this._pickSetWithoutDuplicates(array, numPicks);\n }\n /**\r\n * Returns a new array randomly picking elements in the original (not reused)\r\n * @param array Array to pick elements out of\r\n * @param numPicks must be less than or equal to the number of elements in the array.\r\n */ _pickSetWithoutDuplicates(array, numPicks) {\n if (numPicks > array.length || numPicks < 0) throw new Error(\"Invalid number of elements to pick, must pick a value 0 < n <= length\");\n if (numPicks === array.length) return array;\n const result = new Array(numPicks);\n let currentPick = 0;\n const tempArray = array.slice(0);\n while(currentPick < numPicks){\n const index = this.integer(0, tempArray.length - 1);\n result[currentPick++] = tempArray[index];\n tempArray.splice(index, 1);\n }\n return result;\n }\n /**\r\n * Returns a new array random picking elements from the original allowing duplicates\r\n * @param array Array to pick elements out of\r\n * @param numPicks can be any positive number\r\n */ _pickSetWithDuplicates(array, numPicks) {\n // Typescript numbers are all floating point, so do we add check for int? (or floor the input?)\n if (numPicks < 0) throw new Error(\"Invalid number of elements to pick, must pick a value 0 <= n < MAX_INT\");\n const result = new Array(numPicks);\n for(let i = 0; i < numPicks; i++)result[i] = this.pickOne(array);\n return result;\n }\n /**\r\n * Returns a new array that has its elements shuffled. Using the Fisher/Yates method\r\n * https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle\r\n */ shuffle(array) {\n const tempArray = array.slice(0);\n let swap = null;\n for(let i = 0; i < tempArray.length - 2; i++){\n const randomIndex = this.integer(i, tempArray.length - 1);\n swap = tempArray[i];\n tempArray[i] = tempArray[randomIndex];\n tempArray[randomIndex] = swap;\n }\n return tempArray;\n }\n /**\r\n * Generate a list of random integer numbers\r\n * @param length the length of the final array\r\n * @param min the minimum integer number to generate inclusive\r\n * @param max the maximum integer number to generate inclusive\r\n */ range(length, min, max) {\n const result = new Array(length);\n for(let i = 0; i < length; i++)result[i] = this.integer(min, max);\n return result;\n }\n /**\r\n * Returns the result of a d4 dice roll\r\n */ d4() {\n return this.integer(1, 4);\n }\n /**\r\n * Returns the result of a d6 dice roll\r\n */ d6() {\n return this.integer(1, 6);\n }\n /**\r\n * Returns the result of a d8 dice roll\r\n */ d8() {\n return this.integer(1, 8);\n }\n /**\r\n * Returns the result of a d10 dice roll\r\n */ d10() {\n return this.integer(1, 10);\n }\n /**\r\n * Returns the result of a d12 dice roll\r\n */ d12() {\n return this.integer(1, 12);\n }\n /**\r\n * Returns the result of a d20 dice roll\r\n */ d20() {\n return this.integer(1, 20);\n }\n }\n /**\r\n * Two PI constant\r\n */ const TwoPI = Math.PI * 2;\n /**\r\n * Returns the fractional part of a number\r\n * @param x\r\n */ function frac(x) {\n if (x >= 0) return x - Math.floor(x);\n else return x - Math.ceil(x);\n }\n /**\r\n * Returns the sign of a number, if 0 returns 0\r\n */ function sign(val) {\n if (val === 0) return 0;\n return val < 0 ? -1 : 1;\n }\n /**\r\n * Clamps a value between a min and max inclusive\r\n */ function clamp(val, min, max) {\n return Math.min(Math.max(min, val), max);\n }\n /**\r\n * Convert an angle to be the equivalent in the range [0, 2PI]\r\n */ function canonicalizeAngle(angle) {\n let tmpAngle = angle;\n if (angle > TwoPI) while(tmpAngle > TwoPI)tmpAngle -= TwoPI;\n if (angle < 0) while(tmpAngle < 0)tmpAngle += TwoPI;\n return tmpAngle;\n }\n /**\r\n * Convert radians to degrees\r\n */ function toDegrees(radians) {\n return 180 / Math.PI * radians;\n }\n /**\r\n * Convert degrees to radians\r\n */ function toRadians(degrees) {\n return degrees / 180 * Math.PI;\n }\n /**\r\n * Generate a range of numbers\r\n * For example: range(0, 5) -> [0, 1, 2, 3, 4, 5]\r\n * @param from inclusive\r\n * @param to inclusive\r\n */ const range = (from, to)=>Array.from(new Array(to - from + 1), (_x, i)=>i + from);\n /**\r\n * Find a random floating point number in range\r\n */ function randomInRange(min, max, random = new Random()) {\n return random ? random.floating(min, max) : min + Math.random() * (max - min);\n }\n /**\r\n * Find a random integer in a range\r\n */ function randomIntInRange(min, max, random = new Random()) {\n return random ? random.integer(min, max) : Math.round(randomInRange(min, max));\n }\n /**\r\n * A 2D vector on a plane.\r\n */ class Vector {\n /**\r\n * A (0, 0) vector\r\n */ static get Zero() {\n return new Vector(0, 0);\n }\n /**\r\n * A (1, 1) vector\r\n */ static get One() {\n return new Vector(1, 1);\n }\n /**\r\n * A (0.5, 0.5) vector\r\n */ static get Half() {\n return new Vector(0.5, 0.5);\n }\n /**\r\n * A unit vector pointing up (0, -1)\r\n */ static get Up() {\n return new Vector(0, -1);\n }\n /**\r\n * A unit vector pointing down (0, 1)\r\n */ static get Down() {\n return new Vector(0, 1);\n }\n /**\r\n * A unit vector pointing left (-1, 0)\r\n */ static get Left() {\n return new Vector(-1, 0);\n }\n /**\r\n * A unit vector pointing right (1, 0)\r\n */ static get Right() {\n return new Vector(1, 0);\n }\n /**\r\n * Returns a vector of unit length in the direction of the specified angle in Radians.\r\n * @param angle The angle to generate the vector\r\n */ static fromAngle(angle) {\n return new Vector(Math.cos(angle), Math.sin(angle));\n }\n /**\r\n * Checks if vector is not null, undefined, or if any of its components are NaN or Infinity.\r\n */ static isValid(vec) {\n if (vec === null || vec === undefined) return false;\n if (isNaN(vec.x) || isNaN(vec.y)) return false;\n if (vec.x === Infinity || vec.y === Infinity || vec.x === -Infinity || vec.y === -Infinity) return false;\n return true;\n }\n /**\r\n * Calculates distance between two Vectors\r\n * @param vec1\r\n * @param vec2\r\n */ static distance(vec1, vec2) {\n return Math.sqrt(Math.pow(vec1.x - vec2.x, 2) + Math.pow(vec1.y - vec2.y, 2));\n }\n static min(vec1, vec2) {\n return new Vector(Math.min(vec1.x, vec2.x), Math.min(vec1.y, vec2.y));\n }\n static max(vec1, vec2) {\n return new Vector(Math.max(vec1.x, vec2.x), Math.max(vec1.y, vec2.y));\n }\n /**\r\n * @param x X component of the Vector\r\n * @param y Y component of the Vector\r\n */ constructor(x, y){\n this._x = 0;\n this._y = 0;\n this._x = x;\n this._y = y;\n }\n /**\r\n * Get the x component of the vector\r\n */ get x() {\n return this._x;\n }\n /**\r\n * Set the x component, THIS MUTATES the current vector. It is usually better to create a new vector.\r\n * @warning **Be very careful setting components on shared vectors, mutating shared vectors can cause hard to find bugs**\r\n */ set x(val) {\n this._x = val;\n }\n /**\r\n * Get the y component of the vector\r\n */ get y() {\n return this._y;\n }\n /**\r\n * Set the y component, THIS MUTATES the current vector. It is usually better to create a new vector.\r\n * @warning **Be very careful setting components on shared vectors, mutating shared vectors can cause hard to find bugs**\r\n */ set y(val) {\n this._y = val;\n }\n /**\r\n * Sets the x and y components at once, THIS MUTATES the current vector. It is usually better to create a new vector.\r\n *\r\n * @warning **Be very careful using this, mutating vectors can cause hard to find bugs**\r\n */ setTo(x, y) {\n this.x = x;\n this.y = y;\n }\n /**\r\n * Compares this point against another and tests for equality\r\n * @param vector The other point to compare to\r\n * @param tolerance Amount of euclidean distance off we are willing to tolerate\r\n */ equals(vector, tolerance = 0.001) {\n return Math.abs(this.x - vector.x) <= tolerance && Math.abs(this.y - vector.y) <= tolerance;\n }\n /**\r\n * The distance to another vector. If no other Vector is specified, this will return the [[magnitude]].\r\n * @param v The other vector. Leave blank to use origin vector.\r\n */ distance(v) {\n if (!v) return Math.sqrt(this.x * this.x + this.y * this.y);\n const deltaX = this.x - v.x;\n const deltaY = this.y - v.y;\n return Math.sqrt(deltaX * deltaX + deltaY * deltaY);\n }\n squareDistance(v) {\n if (!v) v = Vector.Zero;\n const deltaX = this.x - v.x;\n const deltaY = this.y - v.y;\n return deltaX * deltaX + deltaY * deltaY;\n }\n /**\r\n * Clamps the current vector's magnitude mutating it\r\n * @param magnitude\r\n */ clampMagnitude(magnitude) {\n const size = this.size;\n const newSize = clamp(size, 0, magnitude);\n this.size = newSize;\n return this;\n }\n /**\r\n * The size (magnitude) of the Vector\r\n */ get size() {\n return this.distance();\n }\n /**\r\n * Setting the size mutates the current vector\r\n *\r\n * @warning Can be used to set the size of the vector, **be very careful using this, mutating vectors can cause hard to find bugs**\r\n */ set size(newLength) {\n const v = this.normalize().scale(newLength);\n this.setTo(v.x, v.y);\n }\n /**\r\n * Normalizes a vector to have a magnitude of 1.\r\n */ normalize() {\n const d = this.distance();\n if (d > 0) return new Vector(this.x / d, this.y / d);\n else return new Vector(0, 1);\n }\n /**\r\n * Returns the average (midpoint) between the current point and the specified\r\n */ average(vec) {\n return this.add(vec).scale(0.5);\n }\n scale(sizeOrScale, dest) {\n const result = dest || new Vector(0, 0);\n if (sizeOrScale instanceof Vector) {\n result.x = this.x * sizeOrScale.x;\n result.y = this.y * sizeOrScale.y;\n } else {\n result.x = this.x * sizeOrScale;\n result.y = this.y * sizeOrScale;\n }\n return result;\n }\n /**\r\n * Adds one vector to another\r\n * @param v The vector to add\r\n * @param dest Optionally copy the result into a provided vector\r\n */ add(v, dest) {\n if (dest) {\n dest.x = this.x + v.x;\n dest.y = this.y + v.y;\n return dest;\n }\n return new Vector(this.x + v.x, this.y + v.y);\n }\n /**\r\n * Subtracts a vector from another, if you subtract vector `B.sub(A)` the resulting vector points from A -> B\r\n * @param v The vector to subtract\r\n */ sub(v) {\n return new Vector(this.x - v.x, this.y - v.y);\n }\n /**\r\n * Adds one vector to this one modifying the original\r\n * @param v The vector to add\r\n * @warning Be very careful using this, mutating vectors can cause hard to find bugs\r\n */ addEqual(v) {\n this.setTo(this.x + v.x, this.y + v.y);\n return this;\n }\n /**\r\n * Subtracts a vector from this one modifying the original\r\n * @param v The vector to subtract\r\n * @warning Be very careful using this, mutating vectors can cause hard to find bugs\r\n */ subEqual(v) {\n this.setTo(this.x - v.x, this.y - v.y);\n return this;\n }\n /**\r\n * Scales this vector by a factor of size and modifies the original\r\n * @warning Be very careful using this, mutating vectors can cause hard to find bugs\r\n */ scaleEqual(size) {\n this.setTo(this.x * size, this.y * size);\n return this;\n }\n /**\r\n * Performs a dot product with another vector\r\n * @param v The vector to dot\r\n */ dot(v) {\n return this.x * v.x + this.y * v.y;\n }\n cross(v) {\n if (v instanceof Vector) return this.x * v.y - this.y * v.x;\n else if (typeof v === \"number\") return new Vector(v * this.y, -v * this.x);\n }\n static cross(num, vec) {\n return new Vector(-num * vec.y, num * vec.x);\n }\n /**\r\n * Returns the perpendicular vector to this one\r\n */ perpendicular() {\n return new Vector(this.y, -this.x);\n }\n /**\r\n * Returns the normal vector to this one, same as the perpendicular of length 1\r\n */ normal() {\n return this.perpendicular().normalize();\n }\n /**\r\n * Negate the current vector\r\n */ negate() {\n return this.scale(-1);\n }\n /**\r\n * Returns the angle of this vector.\r\n */ toAngle() {\n return Math.atan2(this.y, this.x);\n }\n /**\r\n * Rotates the current vector around a point by a certain number of\r\n * degrees in radians\r\n */ rotate(angle, anchor) {\n if (!anchor) anchor = new Vector(0, 0);\n const sinAngle = Math.sin(angle);\n const cosAngle = Math.cos(angle);\n const x = cosAngle * (this.x - anchor.x) - sinAngle * (this.y - anchor.y) + anchor.x;\n const y = sinAngle * (this.x - anchor.x) + cosAngle * (this.y - anchor.y) + anchor.y;\n return new Vector(x, y);\n }\n /**\r\n * Creates new vector that has the same values as the previous.\r\n */ clone(dest) {\n const v = dest !== null && dest !== void 0 ? dest : new Vector(0, 0);\n v.x = this.x;\n v.y = this.y;\n return v;\n }\n /**\r\n * Returns a string representation of the vector.\r\n */ toString(fixed) {\n if (fixed) return `(${this.x.toFixed(fixed)}, ${this.y.toFixed(fixed)})`;\n return `(${this.x}, ${this.y})`;\n }\n }\n /**\r\n * Shorthand for creating new Vectors - returns a new Vector instance with the\r\n * provided X and Y components.\r\n *\r\n * @param x X component of the Vector\r\n * @param y Y component of the Vector\r\n */ function vec(x, y) {\n return new Vector(x, y);\n }\n /**\r\n * Provides standard colors (e.g. [[Color.Black]])\r\n * but you can also create custom colors using RGB, HSL, or Hex. Also provides\r\n * useful color operations like [[Color.lighten]], [[Color.darken]], and more.\r\n */ class Color {\n /**\r\n * Creates a new instance of Color from an r, g, b, a\r\n *\r\n * @param r The red component of color (0-255)\r\n * @param g The green component of color (0-255)\r\n * @param b The blue component of color (0-255)\r\n * @param a The alpha component of color (0-1.0)\r\n */ constructor(r, g, b, a){\n this.r = r;\n this.g = g;\n this.b = b;\n this.a = a != null ? a : 1;\n }\n /**\r\n * Creates a new instance of Color from an r, g, b, a\r\n *\r\n * @param r The red component of color (0-255)\r\n * @param g The green component of color (0-255)\r\n * @param b The blue component of color (0-255)\r\n * @param a The alpha component of color (0-1.0)\r\n */ static fromRGB(r, g, b, a) {\n return new Color(r, g, b, a);\n }\n /**\r\n * Creates a new instance of Color from a rgb string\r\n *\r\n * @param string CSS color string of the form rgba(255, 255, 255, 1) or rgb(255, 255, 255)\r\n */ static fromRGBString(string) {\n const rgbaRegEx = /^rgba?\\((\\d+),\\s*(\\d+),\\s*(\\d+)(?:,\\s*(\\d+(?:\\.\\d+)?))?\\)/i;\n let match = null;\n if (match = string.match(rgbaRegEx)) {\n const r = parseInt(match[1], 10);\n const g = parseInt(match[2], 10);\n const b = parseInt(match[3], 10);\n let a = 1;\n if (match[4]) a = parseFloat(match[4]);\n return new Color(r, g, b, a);\n } else throw new Error(\"Invalid rgb/a string: \" + string);\n }\n /**\r\n * Creates a new instance of Color from a hex string\r\n *\r\n * @param hex CSS color string of the form #ffffff, the alpha component is optional\r\n */ static fromHex(hex) {\n const hexRegEx = /^#?([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})?$/i;\n let match = null;\n if (match = hex.match(hexRegEx)) {\n const r = parseInt(match[1], 16);\n const g = parseInt(match[2], 16);\n const b = parseInt(match[3], 16);\n let a = 1;\n if (match[4]) a = parseInt(match[4], 16) / 255;\n return new Color(r, g, b, a);\n } else throw new Error(\"Invalid hex string: \" + hex);\n }\n /**\r\n * Creates a new instance of Color from hsla values\r\n *\r\n * @param h Hue is represented [0-1]\r\n * @param s Saturation is represented [0-1]\r\n * @param l Luminance is represented [0-1]\r\n * @param a Alpha is represented [0-1]\r\n */ static fromHSL(h, s, l, a = 1.0) {\n const temp = new HSLColor(h, s, l, a);\n return temp.toRGBA();\n }\n /**\r\n * Lightens the current color by a specified amount\r\n *\r\n * @param factor The amount to lighten by [0-1]\r\n */ lighten(factor = 0.1) {\n const temp = HSLColor.fromRGBA(this.r, this.g, this.b, this.a);\n temp.l += (1 - temp.l) * factor;\n return temp.toRGBA();\n }\n /**\r\n * Darkens the current color by a specified amount\r\n *\r\n * @param factor The amount to darken by [0-1]\r\n */ darken(factor = 0.1) {\n const temp = HSLColor.fromRGBA(this.r, this.g, this.b, this.a);\n temp.l -= temp.l * factor;\n return temp.toRGBA();\n }\n /**\r\n * Saturates the current color by a specified amount\r\n *\r\n * @param factor The amount to saturate by [0-1]\r\n */ saturate(factor = 0.1) {\n const temp = HSLColor.fromRGBA(this.r, this.g, this.b, this.a);\n temp.s += temp.s * factor;\n return temp.toRGBA();\n }\n /**\r\n * Desaturates the current color by a specified amount\r\n *\r\n * @param factor The amount to desaturate by [0-1]\r\n */ desaturate(factor = 0.1) {\n const temp = HSLColor.fromRGBA(this.r, this.g, this.b, this.a);\n temp.s -= temp.s * factor;\n return temp.toRGBA();\n }\n /**\r\n * Multiplies a color by another, results in a darker color\r\n *\r\n * @param color The other color\r\n */ multiply(color) {\n const newR = color.r / 255 * this.r / 255 * 255;\n const newG = color.g / 255 * this.g / 255 * 255;\n const newB = color.b / 255 * this.b / 255 * 255;\n const newA = color.a * this.a;\n return new Color(newR, newG, newB, newA);\n }\n /**\r\n * Screens a color by another, results in a lighter color\r\n *\r\n * @param color The other color\r\n */ screen(color) {\n const color1 = color.invert();\n const color2 = color.invert();\n return color1.multiply(color2).invert();\n }\n /**\r\n * Inverts the current color\r\n */ invert() {\n return new Color(255 - this.r, 255 - this.g, 255 - this.b, 1.0 - this.a);\n }\n /**\r\n * Averages the current color with another\r\n *\r\n * @param color The other color\r\n */ average(color) {\n const newR = (color.r + this.r) / 2;\n const newG = (color.g + this.g) / 2;\n const newB = (color.b + this.b) / 2;\n const newA = (color.a + this.a) / 2;\n return new Color(newR, newG, newB, newA);\n }\n equal(color) {\n return this.toString() === color.toString();\n }\n /**\r\n * Returns a CSS string representation of a color.\r\n *\r\n * @param format Color representation, accepts: rgb, hsl, or hex\r\n */ toString(format = \"rgb\") {\n switch(format){\n case \"rgb\":\n return this.toRGBA();\n case \"hsl\":\n return this.toHSLA();\n case \"hex\":\n return this.toHex();\n default:\n throw new Error(\"Invalid Color format\");\n }\n }\n /**\r\n * Returns Hex Value of a color component\r\n * @param c color component\r\n * @see https://stackoverflow.com/questions/5623838/rgb-to-hex-and-hex-to-rgb\r\n */ _componentToHex(c) {\n const hex = c.toString(16);\n return hex.length === 1 ? \"0\" + hex : hex;\n }\n /**\r\n * Return Hex representation of a color.\r\n */ toHex() {\n return \"#\" + this._componentToHex(this.r) + this._componentToHex(this.g) + this._componentToHex(this.b);\n }\n /**\r\n * Return RGBA representation of a color.\r\n */ toRGBA() {\n const result = String(this.r.toFixed(0)) + \", \" + String(this.g.toFixed(0)) + \", \" + String(this.b.toFixed(0));\n if (this.a !== undefined || this.a !== null) return \"rgba(\" + result + \", \" + String(this.a) + \")\";\n return \"rgb(\" + result + \")\";\n }\n /**\r\n * Return HSLA representation of a color.\r\n */ toHSLA() {\n return HSLColor.fromRGBA(this.r, this.g, this.b, this.a).toString();\n }\n /**\r\n * Returns a CSS string representation of a color.\r\n */ fillStyle() {\n return this.toString();\n }\n /**\r\n * Returns a clone of the current color.\r\n */ clone() {\n return new Color(this.r, this.g, this.b, this.a);\n }\n /**\r\n * Black (#000000)\r\n */ static get Black() {\n return Color.fromHex(\"#000000\");\n }\n /**\r\n * White (#FFFFFF)\r\n */ static get White() {\n return Color.fromHex(\"#FFFFFF\");\n }\n /**\r\n * Gray (#808080)\r\n */ static get Gray() {\n return Color.fromHex(\"#808080\");\n }\n /**\r\n * Light gray (#D3D3D3)\r\n */ static get LightGray() {\n return Color.fromHex(\"#D3D3D3\");\n }\n /**\r\n * Dark gray (#A9A9A9)\r\n */ static get DarkGray() {\n return Color.fromHex(\"#A9A9A9\");\n }\n /**\r\n * Yellow (#FFFF00)\r\n */ static get Yellow() {\n return Color.fromHex(\"#FFFF00\");\n }\n /**\r\n * Orange (#FFA500)\r\n */ static get Orange() {\n return Color.fromHex(\"#FFA500\");\n }\n /**\r\n * Red (#FF0000)\r\n */ static get Red() {\n return Color.fromHex(\"#FF0000\");\n }\n /**\r\n * Vermilion (#FF5B31)\r\n */ static get Vermilion() {\n return Color.fromHex(\"#FF5B31\");\n }\n /**\r\n * Rose (#FF007F)\r\n */ static get Rose() {\n return Color.fromHex(\"#FF007F\");\n }\n /**\r\n * Magenta (#FF00FF)\r\n */ static get Magenta() {\n return Color.fromHex(\"#FF00FF\");\n }\n /**\r\n * Violet (#7F00FF)\r\n */ static get Violet() {\n return Color.fromHex(\"#7F00FF\");\n }\n /**\r\n * Blue (#0000FF)\r\n */ static get Blue() {\n return Color.fromHex(\"#0000FF\");\n }\n /**\r\n * Azure (#007FFF)\r\n */ static get Azure() {\n return Color.fromHex(\"#007FFF\");\n }\n /**\r\n * Cyan (#00FFFF)\r\n */ static get Cyan() {\n return Color.fromHex(\"#00FFFF\");\n }\n /**\r\n * Viridian (#59978F)\r\n */ static get Viridian() {\n return Color.fromHex(\"#59978F\");\n }\n /**\r\n * Green (#00FF00)\r\n */ static get Green() {\n return Color.fromHex(\"#00FF00\");\n }\n /**\r\n * Chartreuse (#7FFF00)\r\n */ static get Chartreuse() {\n return Color.fromHex(\"#7FFF00\");\n }\n /**\r\n * Transparent (#FFFFFF00)\r\n */ static get Transparent() {\n return Color.fromHex(\"#FFFFFF00\");\n }\n /**\r\n * ExcaliburBlue (#176BAA)\r\n */ static get ExcaliburBlue() {\n return Color.fromHex(\"#176BAA\");\n }\n }\n /**\r\n * Internal HSL Color representation\r\n *\r\n * http://en.wikipedia.org/wiki/HSL_and_HSV\r\n * http://axonflux.com/handy-rgb-to-hsl-and-rgb-to-hsv-color-model-c\r\n */ class HSLColor {\n constructor(h, s, l, a){\n this.h = h;\n this.s = s;\n this.l = l;\n this.a = a;\n }\n static hue2rgb(p, q, t) {\n if (t < 0) t += 1;\n if (t > 1) t -= 1;\n if (t < 1 / 6) return p + (q - p) * 6 * t;\n if (t < 0.5) return q;\n if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6;\n return p;\n }\n static fromRGBA(r, g, b, a) {\n r /= 255;\n g /= 255;\n b /= 255;\n const max = Math.max(r, g, b), min = Math.min(r, g, b);\n let h, s;\n const l = (max + min) / 2;\n if (max === min) h = s = 0; // achromatic\n else {\n const d = max - min;\n s = l > 0.5 ? d / (2 - max - min) : d / (max + min);\n switch(max){\n case r:\n h = (g - b) / d + (g < b ? 6 : 0);\n break;\n case g:\n h = (b - r) / d + 2;\n break;\n case b:\n h = (r - g) / d + 4;\n break;\n }\n h /= 6;\n }\n return new HSLColor(h, s, l, a);\n }\n toRGBA() {\n let r, g, b;\n if (this.s === 0) r = g = b = this.l; // achromatic\n else {\n const q = this.l < 0.5 ? this.l * (1 + this.s) : this.l + this.s - this.l * this.s;\n const p = 2 * this.l - q;\n r = HSLColor.hue2rgb(p, q, this.h + 1 / 3);\n g = HSLColor.hue2rgb(p, q, this.h);\n b = HSLColor.hue2rgb(p, q, this.h - 1 / 3);\n }\n return new Color(r * 255, g * 255, b * 255, this.a);\n }\n toString() {\n const h = this.h.toFixed(0), s = this.s.toFixed(0), l = this.l.toFixed(0), a = this.a.toFixed(0);\n return `hsla(${h}, ${s}, ${l}, ${a})`;\n }\n }\n /**\r\n * An enum that describes the sides of an axis aligned box for collision\r\n */ var Side;\n (function(Side) {\n Side[\"None\"] = \"None\";\n Side[\"Top\"] = \"Top\";\n Side[\"Bottom\"] = \"Bottom\";\n Side[\"Left\"] = \"Left\";\n Side[\"Right\"] = \"Right\";\n })(Side || (Side = {}));\n (function(Side) {\n /**\r\n * Returns the opposite side from the current\r\n */ function getOpposite(side) {\n if (side === Side.Top) return Side.Bottom;\n if (side === Side.Bottom) return Side.Top;\n if (side === Side.Left) return Side.Right;\n if (side === Side.Right) return Side.Left;\n return Side.None;\n }\n Side.getOpposite = getOpposite;\n /**\r\n * Given a vector, return the Side most in that direction (via dot product)\r\n */ function fromDirection(direction) {\n const directions = [\n Vector.Left,\n Vector.Right,\n Vector.Up,\n Vector.Down\n ];\n const directionEnum = [\n Side.Left,\n Side.Right,\n Side.Top,\n Side.Bottom\n ];\n let max = -Number.MAX_VALUE;\n let maxIndex = -1;\n for(let i = 0; i < directions.length; i++)if (directions[i].dot(direction) > max) {\n max = directions[i].dot(direction);\n maxIndex = i;\n }\n return directionEnum[maxIndex];\n }\n Side.fromDirection = fromDirection;\n })(Side || (Side = {}));\n /**\r\n * Axis Aligned collision primitive for Excalibur.\r\n */ class BoundingBox {\n /**\r\n * Constructor allows passing of either an object with all coordinate components,\r\n * or the coordinate components passed separately.\r\n * @param leftOrOptions Either x coordinate of the left edge or an options object\r\n * containing the four coordinate components.\r\n * @param top y coordinate of the top edge\r\n * @param right x coordinate of the right edge\r\n * @param bottom y coordinate of the bottom edge\r\n */ constructor(leftOrOptions = 0, top = 0, right = 0, bottom = 0){\n if (typeof leftOrOptions === \"object\") {\n this.left = leftOrOptions.left;\n this.top = leftOrOptions.top;\n this.right = leftOrOptions.right;\n this.bottom = leftOrOptions.bottom;\n } else if (typeof leftOrOptions === \"number\") {\n this.left = leftOrOptions;\n this.top = top;\n this.right = right;\n this.bottom = bottom;\n }\n }\n /**\r\n * Returns a new instance of [[BoundingBox]] that is a copy of the current instance\r\n */ clone() {\n return new BoundingBox(this.left, this.top, this.right, this.bottom);\n }\n /**\r\n * Given bounding box A & B, returns the side relative to A when intersection is performed.\r\n * @param intersection Intersection vector between 2 bounding boxes\r\n */ static getSideFromIntersection(intersection) {\n if (!intersection) return Side.None;\n if (intersection) {\n if (Math.abs(intersection.x) > Math.abs(intersection.y)) {\n if (intersection.x < 0) return Side.Right;\n return Side.Left;\n } else {\n if (intersection.y < 0) return Side.Bottom;\n return Side.Top;\n }\n }\n return Side.None;\n }\n static fromPoints(points) {\n let minX = Infinity;\n let minY = Infinity;\n let maxX = -Infinity;\n let maxY = -Infinity;\n for(let i = 0; i < points.length; i++){\n if (points[i].x < minX) minX = points[i].x;\n if (points[i].x > maxX) maxX = points[i].x;\n if (points[i].y < minY) minY = points[i].y;\n if (points[i].y > maxY) maxY = points[i].y;\n }\n return new BoundingBox(minX, minY, maxX, maxY);\n }\n static fromDimension(width, height, anchor = Vector.Half, pos = Vector.Zero) {\n return new BoundingBox(-width * anchor.x + pos.x, -height * anchor.y + pos.y, width - width * anchor.x + pos.x, height - height * anchor.y + pos.y);\n }\n /**\r\n * Returns the calculated width of the bounding box\r\n */ get width() {\n return this.right - this.left;\n }\n /**\r\n * Returns the calculated height of the bounding box\r\n */ get height() {\n return this.bottom - this.top;\n }\n /**\r\n * Return whether the bounding box has zero dimensions in height,width or both\r\n */ hasZeroDimensions() {\n return this.width === 0 || this.height === 0;\n }\n /**\r\n * Returns the center of the bounding box\r\n */ get center() {\n return new Vector((this.left + this.right) / 2, (this.top + this.bottom) / 2);\n }\n translate(pos) {\n return new BoundingBox(this.left + pos.x, this.top + pos.y, this.right + pos.x, this.bottom + pos.y);\n }\n /**\r\n * Rotates a bounding box by and angle and around a point, if no point is specified (0, 0) is used by default. The resulting bounding\r\n * box is also axis-align. This is useful when a new axis-aligned bounding box is needed for rotated geometry.\r\n */ rotate(angle, point = Vector.Zero) {\n const points = this.getPoints().map((p)=>p.rotate(angle, point));\n return BoundingBox.fromPoints(points);\n }\n /**\r\n * Scale a bounding box by a scale factor, optionally provide a point\r\n * @param scale\r\n * @param point\r\n */ scale(scale, point = Vector.Zero) {\n const shifted = this.translate(point);\n return new BoundingBox(shifted.left * scale.x, shifted.top * scale.y, shifted.right * scale.x, shifted.bottom * scale.y);\n }\n /**\r\n * Transform the axis aligned bounding box by a [[Matrix]], producing a new axis aligned bounding box\r\n * @param matrix\r\n */ transform(matrix) {\n // inlined these calculations to not use vectors would speed it up slightly\n // const matFirstColumn = vec(matrix.data[0], matrix.data[1]);\n // const xa = matFirstColumn.scale(this.left);\n const xa1 = matrix.data[0] * this.left;\n const xa2 = matrix.data[1] * this.left;\n // const xb = matFirstColumn.scale(this.right);\n const xb1 = matrix.data[0] * this.right;\n const xb2 = matrix.data[1] * this.right;\n // const matSecondColumn = vec(matrix.data[2], matrix.data[3]);\n // const ya = matSecondColumn.scale(this.top);\n const ya1 = matrix.data[2] * this.top;\n const ya2 = matrix.data[3] * this.top;\n // const yb = matSecondColumn.scale(this.bottom);\n const yb1 = matrix.data[2] * this.bottom;\n const yb2 = matrix.data[3] * this.bottom;\n const matrixPos = matrix.getPosition();\n // const topLeft = Vector.min(xa, xb).add(Vector.min(ya, yb)).add(matrixPos);\n // const bottomRight = Vector.max(xa, xb).add(Vector.max(ya, yb)).add(matrixPos);\n const left = Math.min(xa1, xb1) + Math.min(ya1, yb1) + matrixPos.x;\n const top = Math.min(xa2, xb2) + Math.min(ya2, yb2) + matrixPos.y;\n const right = Math.max(xa1, xb1) + Math.max(ya1, yb1) + matrixPos.x;\n const bottom = Math.max(xa2, xb2) + Math.max(ya2, yb2) + matrixPos.y;\n return new BoundingBox({\n left: left,\n top: top,\n right: right,\n bottom: bottom //: bottomRight.y\n });\n }\n /**\r\n * Returns the perimeter of the bounding box\r\n */ getPerimeter() {\n const wx = this.width;\n const wy = this.height;\n return 2 * (wx + wy);\n }\n getPoints() {\n const results = [];\n results.push(new Vector(this.left, this.top));\n results.push(new Vector(this.right, this.top));\n results.push(new Vector(this.right, this.bottom));\n results.push(new Vector(this.left, this.bottom));\n return results;\n }\n /**\r\n * Determines whether a ray intersects with a bounding box\r\n */ rayCast(ray, farClipDistance = Infinity) {\n // algorithm from https://tavianator.com/fast-branchless-raybounding-box-intersections/\n let tmin = -Infinity;\n let tmax = Infinity;\n const xinv = ray.dir.x === 0 ? Number.MAX_VALUE : 1 / ray.dir.x;\n const yinv = ray.dir.y === 0 ? Number.MAX_VALUE : 1 / ray.dir.y;\n const tx1 = (this.left - ray.pos.x) * xinv;\n const tx2 = (this.right - ray.pos.x) * xinv;\n tmin = Math.min(tx1, tx2);\n tmax = Math.max(tx1, tx2);\n const ty1 = (this.top - ray.pos.y) * yinv;\n const ty2 = (this.bottom - ray.pos.y) * yinv;\n tmin = Math.max(tmin, Math.min(ty1, ty2));\n tmax = Math.min(tmax, Math.max(ty1, ty2));\n return tmax >= Math.max(0, tmin) && tmin < farClipDistance;\n }\n rayCastTime(ray, farClipDistance = Infinity) {\n // algorithm from https://tavianator.com/fast-branchless-raybounding-box-intersections/\n let tmin = -Infinity;\n let tmax = Infinity;\n const xinv = ray.dir.x === 0 ? Number.MAX_VALUE : 1 / ray.dir.x;\n const yinv = ray.dir.y === 0 ? Number.MAX_VALUE : 1 / ray.dir.y;\n const tx1 = (this.left - ray.pos.x) * xinv;\n const tx2 = (this.right - ray.pos.x) * xinv;\n tmin = Math.min(tx1, tx2);\n tmax = Math.max(tx1, tx2);\n const ty1 = (this.top - ray.pos.y) * yinv;\n const ty2 = (this.bottom - ray.pos.y) * yinv;\n tmin = Math.max(tmin, Math.min(ty1, ty2));\n tmax = Math.min(tmax, Math.max(ty1, ty2));\n if (tmax >= Math.max(0, tmin) && tmin < farClipDistance) return tmin;\n return -1;\n }\n contains(val) {\n if (val instanceof Vector) return this.left <= val.x && this.top <= val.y && this.bottom >= val.y && this.right >= val.x;\n else if (val instanceof BoundingBox) {\n if (this.left <= val.left && this.top <= val.top && val.bottom <= this.bottom && val.right <= this.right) return true;\n return false;\n }\n return false;\n }\n /**\r\n * Combines this bounding box and another together returning a new bounding box\r\n * @param other The bounding box to combine\r\n */ combine(other) {\n const compositeBB = new BoundingBox(Math.min(this.left, other.left), Math.min(this.top, other.top), Math.max(this.right, other.right), Math.max(this.bottom, other.bottom));\n return compositeBB;\n }\n get dimensions() {\n return new Vector(this.width, this.height);\n }\n /**\r\n * Returns true if the bounding boxes overlap.\r\n * @param other\r\n * @param epsilon Optionally specify a small epsilon (default 0) as amount of overlap to ignore as overlap.\r\n * This epsilon is useful in stable collision simulations.\r\n */ overlaps(other, epsilon) {\n const e = epsilon || 0;\n if (other.hasZeroDimensions()) return this.contains(other);\n if (this.hasZeroDimensions()) return other.contains(this);\n const totalBoundingBox = this.combine(other);\n return totalBoundingBox.width + e < other.width + this.width && totalBoundingBox.height + e < other.height + this.height;\n }\n /**\r\n * Test wether this bounding box intersects with another returning\r\n * the intersection vector that can be used to resolve the collision. If there\r\n * is no intersection null is returned.\r\n *\r\n * @param other Other [[BoundingBox]] to test intersection with\r\n * @returns A Vector in the direction of the current BoundingBox, this <- other\r\n */ intersect(other) {\n const totalBoundingBox = this.combine(other);\n // If the total bounding box is less than or equal the sum of the 2 bounds then there is collision\n if (totalBoundingBox.width < other.width + this.width && totalBoundingBox.height < other.height + this.height && !totalBoundingBox.dimensions.equals(other.dimensions) && !totalBoundingBox.dimensions.equals(this.dimensions)) {\n // collision\n let overlapX = 0;\n // right edge is between the other's left and right edge\n /**\r\n * +-this-+\r\n * | |\r\n * | +-other-+\r\n * +----|-+ |\r\n * | |\r\n * +-------+\r\n * <---\r\n * ^ overlap\r\n */ if (this.right >= other.left && this.right <= other.right) overlapX = other.left - this.right;\n else overlapX = other.right - this.left;\n let overlapY = 0;\n // top edge is between the other's top and bottom edge\n /**\r\n * +-other-+\r\n * | |\r\n * | +-this-+ | <- overlap\r\n * +----|--+ | |\r\n * | | \\ /\r\n * +------+ '\r\n */ if (this.top <= other.bottom && this.top >= other.top) overlapY = other.bottom - this.top;\n else overlapY = other.top - this.bottom;\n if (Math.abs(overlapX) < Math.abs(overlapY)) return new Vector(overlapX, 0);\n else return new Vector(0, overlapY);\n // Case of total containment of one bounding box by another\n } else if (totalBoundingBox.dimensions.equals(other.dimensions) || totalBoundingBox.dimensions.equals(this.dimensions)) {\n let overlapX = 0;\n // this is wider than the other\n if (this.width - other.width >= 0) {\n // This right edge is closest to the others right edge\n if (this.right - other.right <= other.left - this.left) overlapX = other.left - this.right;\n else overlapX = other.right - this.left;\n } else // This right edge is closest to the others right edge\n if (other.right - this.right <= this.left - other.left) overlapX = this.left - other.right;\n else overlapX = this.right - other.left;\n let overlapY = 0;\n // this is taller than other\n if (this.height - other.height >= 0) {\n // The bottom edge is closest to the others bottom edge\n if (this.bottom - other.bottom <= other.top - this.top) overlapY = other.top - this.bottom;\n else overlapY = other.bottom - this.top;\n } else // The bottom edge is closest to the others bottom edge\n if (other.bottom - this.bottom <= this.top - other.top) overlapY = this.top - other.bottom;\n else overlapY = this.bottom - other.top;\n if (Math.abs(overlapX) < Math.abs(overlapY)) return new Vector(overlapX, 0);\n else return new Vector(0, overlapY);\n } else return null;\n }\n /**\r\n * Test whether the bounding box has intersected with another bounding box, returns the side of the current bb that intersected.\r\n * @param bb The other actor to test\r\n */ intersectWithSide(bb) {\n const intersect = this.intersect(bb);\n return BoundingBox.getSideFromIntersection(intersect);\n }\n /**\r\n * Draw a debug bounding box\r\n * @param ex\r\n * @param color\r\n */ draw(ex, color = Color.Yellow) {\n ex.debug.drawRect(this.left, this.top, this.width, this.height, {\n color: color\n });\n }\n }\n /**\r\n * Future is a wrapper around a native browser Promise to allow resolving/rejecting at any time\r\n */ class Future {\n constructor(){\n this._isCompleted = false;\n this.promise = new Promise((resolve, reject)=>{\n this._resolver = resolve;\n this._rejecter = reject;\n });\n }\n get isCompleted() {\n return this._isCompleted;\n }\n resolve(value) {\n if (this._isCompleted) return;\n this._isCompleted = true;\n this._resolver(value);\n }\n reject(error) {\n if (this._isCompleted) return;\n this._isCompleted = true;\n this._rejecter(error);\n }\n }\n /**\r\n * Find the screen position of an HTML element\r\n */ function getPosition(el) {\n let oLeft = 0, oTop = 0;\n const calcOffsetLeft = (parent)=>{\n oLeft += parent.offsetLeft;\n if (parent.offsetParent) calcOffsetLeft(parent.offsetParent);\n };\n const calcOffsetTop = (parent)=>{\n oTop += parent.offsetTop;\n if (parent.offsetParent) calcOffsetTop(parent.offsetParent);\n };\n calcOffsetLeft(el);\n calcOffsetTop(el);\n return new Vector(oLeft, oTop);\n }\n /**\r\n * Add an item to an array list if it doesn't already exist. Returns true if added, false if not and already exists in the array.\r\n * @deprecated Will be removed in v0.26.0\r\n */ function addItemToArray(item, array) {\n if (array.indexOf(item) === -1) {\n array.push(item);\n return true;\n }\n return false;\n }\n /**\r\n * Remove an item from an list\r\n * @deprecated Will be removed in v0.26.0\r\n */ function removeItemFromArray(item, array) {\n let index = -1;\n if ((index = array.indexOf(item)) > -1) {\n array.splice(index, 1);\n return true;\n }\n return false;\n }\n /**\r\n * See if an array contains something\r\n */ function contains(array, obj) {\n for(let i = 0; i < array.length; i++){\n if (array[i] === obj) return true;\n }\n return false;\n }\n /**\r\n * Used for exhaustive checks at compile time\r\n */ function fail(message) {\n throw new Error(message);\n }\n /**\r\n * Create a promise that resolves after a certain number of milliseconds\r\n *\r\n * It is strongly recommended you pass the excalibur clock so delays are bound to the\r\n * excalibur clock which would be unaffected by stop/pause.\r\n * @param milliseconds\r\n * @param clock\r\n */ function delay(milliseconds, clock) {\n var _a;\n const future = new Future();\n const schedule = (_a = clock === null || clock === void 0 ? void 0 : clock.schedule.bind(clock)) !== null && _a !== void 0 ? _a : setTimeout;\n schedule(()=>{\n future.resolve();\n }, milliseconds);\n return future.promise;\n }\n var MatrixLocations;\n (function(MatrixLocations) {\n MatrixLocations[MatrixLocations[\"X\"] = 12] = \"X\";\n MatrixLocations[MatrixLocations[\"Y\"] = 13] = \"Y\";\n })(MatrixLocations || (MatrixLocations = {}));\n /**\r\n * Excalibur Matrix helper for 4x4 matrices\r\n *\r\n * Useful for webgl 4x4 matrices\r\n */ class Matrix {\n constructor(){\n /**\r\n * 4x4 matrix in column major order\r\n *\r\n * | | | | |\r\n * | ------- | ------- | -------- | -------- |\r\n * | data[0] | data[4] | data[8] | data[12] |\r\n * | data[1] | data[5] | data[9] | data[13] |\r\n * | data[2] | data[6] | data[10] | data[14] |\r\n * | data[3] | data[7] | data[11] | data[15] |\r\n *\r\n */ this.data = new Float32Array(16);\n this._scaleX = 1;\n this._scaleSignX = 1;\n this._scaleY = 1;\n this._scaleSignY = 1;\n }\n /**\r\n * Creates an orthographic (flat non-perspective) projection\r\n * https://en.wikipedia.org/wiki/Orthographic_projection\r\n * @param left\r\n * @param right\r\n * @param bottom\r\n * @param top\r\n * @param near\r\n * @param far\r\n */ static ortho(left, right, bottom, top, near, far) {\n const mat = new Matrix();\n mat.data[0] = 2 / (right - left);\n mat.data[1] = 0;\n mat.data[2] = 0;\n mat.data[3] = 0;\n mat.data[4] = 0;\n mat.data[5] = 2 / (top - bottom);\n mat.data[6] = 0;\n mat.data[7] = 0;\n mat.data[8] = 0;\n mat.data[9] = 0;\n mat.data[10] = -2 / (far - near);\n mat.data[11] = 0;\n mat.data[12] = -(right + left) / (right - left);\n mat.data[13] = -(top + bottom) / (top - bottom);\n mat.data[14] = -(far + near) / (far - near);\n mat.data[15] = 1;\n return mat;\n }\n /**\r\n * Creates a new Matrix with the same data as the current 4x4\r\n */ clone(dest) {\n const mat = dest || new Matrix();\n mat.data[0] = this.data[0];\n mat.data[1] = this.data[1];\n mat.data[2] = this.data[2];\n mat.data[3] = this.data[3];\n mat.data[4] = this.data[4];\n mat.data[5] = this.data[5];\n mat.data[6] = this.data[6];\n mat.data[7] = this.data[7];\n mat.data[8] = this.data[8];\n mat.data[9] = this.data[9];\n mat.data[10] = this.data[10];\n mat.data[11] = this.data[11];\n mat.data[12] = this.data[12];\n mat.data[13] = this.data[13];\n mat.data[14] = this.data[14];\n mat.data[15] = this.data[15];\n return mat;\n }\n /**\r\n * Converts the current matrix into a DOMMatrix\r\n *\r\n * This is useful when working with the browser Canvas context\r\n * @returns {DOMMatrix} DOMMatrix\r\n */ toDOMMatrix() {\n return new DOMMatrix([\n ...this.data\n ]);\n }\n static fromFloat32Array(data) {\n const matrix = new Matrix();\n matrix.data = data;\n return matrix;\n }\n /**\r\n * Creates a new identity matrix (a matrix that when applied does nothing)\r\n */ static identity() {\n const mat = new Matrix();\n mat.data[0] = 1;\n mat.data[1] = 0;\n mat.data[2] = 0;\n mat.data[3] = 0;\n mat.data[4] = 0;\n mat.data[5] = 1;\n mat.data[6] = 0;\n mat.data[7] = 0;\n mat.data[8] = 0;\n mat.data[9] = 0;\n mat.data[10] = 1;\n mat.data[11] = 0;\n mat.data[12] = 0;\n mat.data[13] = 0;\n mat.data[14] = 0;\n mat.data[15] = 1;\n return mat;\n }\n /**\r\n * Resets the current matrix to the identity matrix, mutating it\r\n * @returns {Matrix} Current matrix as identity\r\n */ reset() {\n const mat = this;\n mat.data[0] = 1;\n mat.data[1] = 0;\n mat.data[2] = 0;\n mat.data[3] = 0;\n mat.data[4] = 0;\n mat.data[5] = 1;\n mat.data[6] = 0;\n mat.data[7] = 0;\n mat.data[8] = 0;\n mat.data[9] = 0;\n mat.data[10] = 1;\n mat.data[11] = 0;\n mat.data[12] = 0;\n mat.data[13] = 0;\n mat.data[14] = 0;\n mat.data[15] = 1;\n return mat;\n }\n /**\r\n * Creates a brand new translation matrix at the specified 3d point\r\n * @param x\r\n * @param y\r\n */ static translation(x, y) {\n const mat = Matrix.identity();\n mat.data[12] = x;\n mat.data[13] = y;\n return mat;\n }\n /**\r\n * Creates a brand new scaling matrix with the specified scaling factor\r\n * @param sx\r\n * @param sy\r\n */ static scale(sx, sy) {\n const mat = Matrix.identity();\n mat.data[0] = sx;\n mat.data[5] = sy;\n mat.data[10] = 1;\n mat.data[15] = 1;\n return mat;\n }\n /**\r\n * Creates a brand new rotation matrix with the specified angle\r\n * @param angleRadians\r\n */ static rotation(angleRadians) {\n const mat = Matrix.identity();\n mat.data[0] = Math.cos(angleRadians);\n mat.data[4] = -Math.sin(angleRadians);\n mat.data[1] = Math.sin(angleRadians);\n mat.data[5] = Math.cos(angleRadians);\n return mat;\n }\n multiply(vectorOrMatrix, dest) {\n if (vectorOrMatrix instanceof Vector) {\n const result = dest || new Vector(0, 0);\n const vector = vectorOrMatrix;\n // these shenanigans are to allow dest and vector to be the same instance\n const resultX = vector.x * this.data[0] + vector.y * this.data[4] + this.data[12];\n const resultY = vector.x * this.data[1] + vector.y * this.data[5] + this.data[13];\n result.x = resultX;\n result.y = resultY;\n return result;\n } else {\n const result = dest || new Matrix();\n const other = vectorOrMatrix;\n const a11 = this.data[0];\n const a21 = this.data[1];\n const a31 = this.data[2];\n const a41 = this.data[3];\n const a12 = this.data[4];\n const a22 = this.data[5];\n const a32 = this.data[6];\n const a42 = this.data[7];\n const a13 = this.data[8];\n const a23 = this.data[9];\n const a33 = this.data[10];\n const a43 = this.data[11];\n const a14 = this.data[12];\n const a24 = this.data[13];\n const a34 = this.data[14];\n const a44 = this.data[15];\n const b11 = other.data[0];\n const b21 = other.data[1];\n const b31 = other.data[2];\n const b41 = other.data[3];\n const b12 = other.data[4];\n const b22 = other.data[5];\n const b32 = other.data[6];\n const b42 = other.data[7];\n const b13 = other.data[8];\n const b23 = other.data[9];\n const b33 = other.data[10];\n const b43 = other.data[11];\n const b14 = other.data[12];\n const b24 = other.data[13];\n const b34 = other.data[14];\n const b44 = other.data[15];\n result.data[0] = a11 * b11 + a12 * b21 + a13 * b31 + a14 * b41;\n result.data[1] = a21 * b11 + a22 * b21 + a23 * b31 + a24 * b41;\n result.data[2] = a31 * b11 + a32 * b21 + a33 * b31 + a34 * b41;\n result.data[3] = a41 * b11 + a42 * b21 + a43 * b31 + a44 * b41;\n result.data[4] = a11 * b12 + a12 * b22 + a13 * b32 + a14 * b42;\n result.data[5] = a21 * b12 + a22 * b22 + a23 * b32 + a24 * b42;\n result.data[6] = a31 * b12 + a32 * b22 + a33 * b32 + a34 * b42;\n result.data[7] = a41 * b12 + a42 * b22 + a43 * b32 + a44 * b42;\n result.data[8] = a11 * b13 + a12 * b23 + a13 * b33 + a14 * b43;\n result.data[9] = a21 * b13 + a22 * b23 + a23 * b33 + a24 * b43;\n result.data[10] = a31 * b13 + a32 * b23 + a33 * b33 + a34 * b43;\n result.data[11] = a41 * b13 + a42 * b23 + a43 * b33 + a44 * b43;\n result.data[12] = a11 * b14 + a12 * b24 + a13 * b34 + a14 * b44;\n result.data[13] = a21 * b14 + a22 * b24 + a23 * b34 + a24 * b44;\n result.data[14] = a31 * b14 + a32 * b24 + a33 * b34 + a34 * b44;\n result.data[15] = a41 * b14 + a42 * b24 + a43 * b34 + a44 * b44;\n const s = this.getScale();\n result._scaleSignX = sign(s.x) * sign(result._scaleSignX);\n result._scaleSignY = sign(s.y) * sign(result._scaleSignY);\n return result;\n }\n }\n /**\r\n * Applies translation to the current matrix mutating it\r\n * @param x\r\n * @param y\r\n */ translate(x, y) {\n const a11 = this.data[0];\n const a21 = this.data[1];\n const a31 = this.data[2];\n const a41 = this.data[3];\n const a12 = this.data[4];\n const a22 = this.data[5];\n const a32 = this.data[6];\n const a42 = this.data[7];\n const a13 = this.data[8];\n const a23 = this.data[9];\n const a33 = this.data[10];\n const a43 = this.data[11];\n const a14 = this.data[12];\n const a24 = this.data[13];\n const a34 = this.data[14];\n const a44 = this.data[15];\n // Doesn't change z\n const z = 0;\n const w = 1;\n this.data[12] = a11 * x + a12 * y + a13 * z + a14 * w;\n this.data[13] = a21 * x + a22 * y + a23 * z + a24 * w;\n this.data[14] = a31 * x + a32 * y + a33 * z + a34 * w;\n this.data[15] = a41 * x + a42 * y + a43 * z + a44 * w;\n return this;\n }\n setPosition(x, y) {\n this.data[12] = x;\n this.data[13] = y;\n }\n getPosition() {\n return vec(this.data[12], this.data[13]);\n }\n /**\r\n * Applies rotation to the current matrix mutating it\r\n * @param angle in Radians\r\n */ rotate(angle) {\n const a11 = this.data[0];\n const a21 = this.data[1];\n const a31 = this.data[2];\n const a41 = this.data[3];\n const a12 = this.data[4];\n const a22 = this.data[5];\n const a32 = this.data[6];\n const a42 = this.data[7];\n const sine = Math.sin(angle);\n const cosine = Math.cos(angle);\n this.data[0] = cosine * a11 + sine * a12;\n this.data[1] = cosine * a21 + sine * a22;\n this.data[2] = cosine * a31 + sine * a32;\n this.data[3] = cosine * a41 + sine * a42;\n this.data[4] = cosine * a12 - sine * a11;\n this.data[5] = cosine * a22 - sine * a21;\n this.data[6] = cosine * a32 - sine * a31;\n this.data[7] = cosine * a42 - sine * a41;\n return this;\n }\n /**\r\n * Applies scaling to the current matrix mutating it\r\n * @param x\r\n * @param y\r\n */ scale(x, y) {\n const a11 = this.data[0];\n const a21 = this.data[1];\n const a31 = this.data[2];\n const a41 = this.data[3];\n const a12 = this.data[4];\n const a22 = this.data[5];\n const a32 = this.data[6];\n const a42 = this.data[7];\n this.data[0] = a11 * x;\n this.data[1] = a21 * x;\n this.data[2] = a31 * x;\n this.data[3] = a41 * x;\n this.data[4] = a12 * y;\n this.data[5] = a22 * y;\n this.data[6] = a32 * y;\n this.data[7] = a42 * y;\n return this;\n }\n setRotation(angle) {\n const currentScale = this.getScale();\n const sine = Math.sin(angle);\n const cosine = Math.cos(angle);\n this.data[0] = cosine * currentScale.x;\n this.data[1] = sine * currentScale.y;\n this.data[4] = -sine * currentScale.x;\n this.data[5] = cosine * currentScale.y;\n }\n getRotation() {\n const angle = Math.atan2(this.data[1] / this.getScaleY(), this.data[0] / this.getScaleX());\n return canonicalizeAngle(angle);\n }\n getScaleX() {\n // absolute scale of the matrix (we lose sign so need to add it back)\n const xscale = vec(this.data[0], this.data[4]).size;\n return this._scaleSignX * xscale;\n }\n getScaleY() {\n // absolute scale of the matrix (we lose sign so need to add it back)\n const yscale = vec(this.data[1], this.data[5]).size;\n return this._scaleSignY * yscale;\n }\n /**\r\n * Get the scale of the matrix\r\n */ getScale() {\n return vec(this.getScaleX(), this.getScaleY());\n }\n setScaleX(val) {\n if (this._scaleX === val) return;\n this._scaleSignX = sign(val);\n // negative scale acts like a 180 rotation, so flip\n const xscale = vec(this.data[0] * this._scaleSignX, this.data[4] * this._scaleSignX).normalize();\n this.data[0] = xscale.x * val;\n this.data[4] = xscale.y * val;\n this._scaleX = val;\n }\n setScaleY(val) {\n if (this._scaleY === val) return;\n this._scaleSignY = sign(val);\n // negative scale acts like a 180 rotation, so flip\n const yscale = vec(this.data[1] * this._scaleSignY, this.data[5] * this._scaleSignY).normalize();\n this.data[1] = yscale.x * val;\n this.data[5] = yscale.y * val;\n this._scaleY = val;\n }\n setScale(scale) {\n this.setScaleX(scale.x);\n this.setScaleY(scale.y);\n }\n /**\r\n * Determinant of the upper left 2x2 matrix\r\n */ getBasisDeterminant() {\n return this.data[0] * this.data[5] - this.data[1] * this.data[4];\n }\n /**\r\n * Return the affine inverse, optionally store it in a target matrix.\r\n *\r\n * It's recommended you call .reset() the target unless you know what you're doing\r\n * @param target\r\n */ getAffineInverse(target) {\n // See http://negativeprobability.blogspot.com/2011/11/affine-transformations-and-their.html\n // See https://www.mathsisfun.com/algebra/matrix-inverse.html\n // Since we are actually only doing 2D transformations we can use this hack\n // We don't actually use the 3rd or 4th dimension\n const det = this.getBasisDeterminant();\n const inverseDet = 1 / det; // todo zero check\n const a = this.data[0];\n const b = this.data[4];\n const c = this.data[1];\n const d = this.data[5];\n const m = target || Matrix.identity();\n // inverts rotation and scale\n m.data[0] = d * inverseDet;\n m.data[1] = -c * inverseDet;\n m.data[4] = -b * inverseDet;\n m.data[5] = a * inverseDet;\n const tx = this.data[12];\n const ty = this.data[13];\n // invert translation\n // transform translation into the matrix basis created by rot/scale\n m.data[12] = -(tx * m.data[0] + ty * m.data[4]);\n m.data[13] = -(tx * m.data[1] + ty * m.data[5]);\n return m;\n }\n isIdentity() {\n return this.data[0] === 1 && this.data[1] === 0 && this.data[2] === 0 && this.data[3] === 0 && this.data[4] === 0 && this.data[5] === 1 && this.data[6] === 0 && this.data[7] === 0 && this.data[8] === 0 && this.data[9] === 0 && this.data[10] === 1 && this.data[11] === 0 && this.data[12] === 0 && this.data[13] === 0 && this.data[14] === 0 && this.data[15] === 1;\n }\n toString() {\n return `\r\n[${this.data[0]} ${this.data[4]} ${this.data[8]} ${this.data[12]}]\r\n[${this.data[1]} ${this.data[5]} ${this.data[9]} ${this.data[13]}]\r\n[${this.data[2]} ${this.data[6]} ${this.data[10]} ${this.data[14]}]\r\n[${this.data[3]} ${this.data[7]} ${this.data[11]} ${this.data[15]}]\r\n`;\n }\n }\n class AffineMatrix {\n constructor(){\n /**\r\n * | | | |\r\n * | ------- | ------- | -------- |\r\n * | data[0] | data[2] | data[4] |\r\n * | data[1] | data[3] | data[5] |\r\n * | 0 | 0 | 1 |\r\n */ this.data = new Float64Array(6);\n this._scale = new Float64Array([\n 1,\n 1\n ]);\n this._scaleSignX = 1;\n this._scaleSignY = 1;\n }\n /**\r\n * Converts the current matrix into a DOMMatrix\r\n *\r\n * This is useful when working with the browser Canvas context\r\n * @returns {DOMMatrix} DOMMatrix\r\n */ toDOMMatrix() {\n return new DOMMatrix([\n ...this.data\n ]);\n }\n static identity() {\n const mat = new AffineMatrix();\n mat.data[0] = 1;\n mat.data[1] = 0;\n mat.data[2] = 0;\n mat.data[3] = 1;\n mat.data[4] = 0;\n mat.data[5] = 0;\n return mat;\n }\n /**\r\n * Creates a brand new translation matrix at the specified 3d point\r\n * @param x\r\n * @param y\r\n */ static translation(x, y) {\n const mat = AffineMatrix.identity();\n mat.data[4] = x;\n mat.data[5] = y;\n return mat;\n }\n /**\r\n * Creates a brand new scaling matrix with the specified scaling factor\r\n * @param sx\r\n * @param sy\r\n */ static scale(sx, sy) {\n const mat = AffineMatrix.identity();\n mat.data[0] = sx;\n mat.data[3] = sy;\n mat._scale[0] = sx;\n mat._scale[1] = sy;\n return mat;\n }\n /**\r\n * Creates a brand new rotation matrix with the specified angle\r\n * @param angleRadians\r\n */ static rotation(angleRadians) {\n const mat = AffineMatrix.identity();\n mat.data[0] = Math.cos(angleRadians);\n mat.data[1] = Math.sin(angleRadians);\n mat.data[2] = -Math.sin(angleRadians);\n mat.data[3] = Math.cos(angleRadians);\n return mat;\n }\n setPosition(x, y) {\n this.data[4] = x;\n this.data[5] = y;\n }\n getPosition() {\n return vec(this.data[4], this.data[5]);\n }\n /**\r\n * Applies rotation to the current matrix mutating it\r\n * @param angle in Radians\r\n */ rotate(angle) {\n const a11 = this.data[0];\n const a21 = this.data[1];\n const a12 = this.data[2];\n const a22 = this.data[3];\n const sine = Math.sin(angle);\n const cosine = Math.cos(angle);\n this.data[0] = cosine * a11 + sine * a12;\n this.data[1] = cosine * a21 + sine * a22;\n this.data[2] = cosine * a12 - sine * a11;\n this.data[3] = cosine * a22 - sine * a21;\n return this;\n }\n /**\r\n * Applies translation to the current matrix mutating it\r\n * @param x\r\n * @param y\r\n */ translate(x, y) {\n const a11 = this.data[0];\n const a21 = this.data[1];\n // const a31 = 0;\n const a12 = this.data[2];\n const a22 = this.data[3];\n // const a32 = 0;\n const a13 = this.data[4];\n const a23 = this.data[5];\n // const a33 = 1;\n // Doesn't change z\n this.data[4] = a11 * x + a12 * y + a13;\n this.data[5] = a21 * x + a22 * y + a23;\n return this;\n }\n /**\r\n * Applies scaling to the current matrix mutating it\r\n * @param x\r\n * @param y\r\n */ scale(x, y) {\n const a11 = this.data[0];\n const a21 = this.data[1];\n const a12 = this.data[2];\n const a22 = this.data[3];\n this.data[0] = a11 * x;\n this.data[1] = a21 * x;\n this.data[2] = a12 * y;\n this.data[3] = a22 * y;\n this._scale[0] = x;\n this._scale[1] = y;\n return this;\n }\n determinant() {\n return this.data[0] * this.data[3] - this.data[1] * this.data[2];\n }\n /**\r\n * Return the affine inverse, optionally store it in a target matrix.\r\n *\r\n * It's recommended you call .reset() the target unless you know what you're doing\r\n * @param target\r\n */ inverse(target) {\n // See http://negativeprobability.blogspot.com/2011/11/affine-transformations-and-their.html\n // See https://www.mathsisfun.com/algebra/matrix-inverse.html\n // Since we are actually only doing 2D transformations we can use this hack\n // We don't actually use the 3rd or 4th dimension\n const det = this.determinant();\n const inverseDet = 1 / det; // TODO zero check\n const a = this.data[0];\n const b = this.data[2];\n const c = this.data[1];\n const d = this.data[3];\n const m = target || AffineMatrix.identity();\n // inverts rotation and scale\n m.data[0] = d * inverseDet;\n m.data[1] = -c * inverseDet;\n m.data[2] = -b * inverseDet;\n m.data[3] = a * inverseDet;\n const tx = this.data[4];\n const ty = this.data[5];\n // invert translation\n // transform translation into the matrix basis created by rot/scale\n m.data[4] = -(tx * m.data[0] + ty * m.data[2]);\n m.data[5] = -(tx * m.data[1] + ty * m.data[3]);\n return m;\n }\n multiply(vectorOrMatrix, dest) {\n if (vectorOrMatrix instanceof Vector) {\n const result = dest || new Vector(0, 0);\n const vector = vectorOrMatrix;\n // these shenanigans are to allow dest and vector to be the same instance\n const resultX = vector.x * this.data[0] + vector.y * this.data[2] + this.data[4];\n const resultY = vector.x * this.data[1] + vector.y * this.data[3] + this.data[5];\n result.x = resultX;\n result.y = resultY;\n return result;\n } else {\n const result = dest || new AffineMatrix();\n const other = vectorOrMatrix;\n const a11 = this.data[0];\n const a21 = this.data[1];\n // const a31 = 0;\n const a12 = this.data[2];\n const a22 = this.data[3];\n // const a32 = 0;\n const a13 = this.data[4];\n const a23 = this.data[5];\n // const a33 = 1;\n const b11 = other.data[0];\n const b21 = other.data[1];\n // const b31 = 0;\n const b12 = other.data[2];\n const b22 = other.data[3];\n // const b32 = 0;\n const b13 = other.data[4];\n const b23 = other.data[5];\n // const b33 = 1;\n result.data[0] = a11 * b11 + a12 * b21; // + a13 * b31; // zero\n result.data[1] = a21 * b11 + a22 * b21; // + a23 * b31; // zero\n result.data[2] = a11 * b12 + a12 * b22; // + a13 * b32; // zero\n result.data[3] = a21 * b12 + a22 * b22; // + a23 * b32; // zero\n result.data[4] = a11 * b13 + a12 * b23 + a13; // * b33; // one\n result.data[5] = a21 * b13 + a22 * b23 + a23; // * b33; // one\n const s = this.getScale();\n result._scaleSignX = sign(s.x) * sign(result._scaleSignX);\n result._scaleSignY = sign(s.y) * sign(result._scaleSignY);\n return result;\n }\n }\n to4x4() {\n const mat = new Matrix();\n mat.data[0] = this.data[0];\n mat.data[1] = this.data[1];\n mat.data[2] = 0;\n mat.data[3] = 0;\n mat.data[4] = this.data[2];\n mat.data[5] = this.data[3];\n mat.data[6] = 0;\n mat.data[7] = 0;\n mat.data[8] = 0;\n mat.data[9] = 0;\n mat.data[10] = 1;\n mat.data[11] = 0;\n mat.data[12] = this.data[4];\n mat.data[13] = this.data[5];\n mat.data[14] = 0;\n mat.data[15] = 1;\n return mat;\n }\n setRotation(angle) {\n const currentScale = this.getScale();\n const sine = Math.sin(angle);\n const cosine = Math.cos(angle);\n this.data[0] = cosine * currentScale.x;\n this.data[1] = sine * currentScale.y;\n this.data[2] = -sine * currentScale.x;\n this.data[3] = cosine * currentScale.y;\n }\n getRotation() {\n const angle = Math.atan2(this.data[1] / this.getScaleY(), this.data[0] / this.getScaleX());\n return canonicalizeAngle(angle);\n }\n getScaleX() {\n // absolute scale of the matrix (we lose sign so need to add it back)\n const xscale = vec(this.data[0], this.data[2]).distance();\n return this._scaleSignX * xscale;\n }\n getScaleY() {\n // absolute scale of the matrix (we lose sign so need to add it back)\n const yscale = vec(this.data[1], this.data[3]).distance();\n return this._scaleSignY * yscale;\n }\n /**\r\n * Get the scale of the matrix\r\n */ getScale() {\n return vec(this.getScaleX(), this.getScaleY());\n }\n setScaleX(val) {\n if (val === this._scale[0]) return;\n this._scaleSignX = sign(val);\n // negative scale acts like a 180 rotation, so flip\n const xscale = vec(this.data[0] * this._scaleSignX, this.data[2] * this._scaleSignX).normalize();\n this.data[0] = xscale.x * val;\n this.data[2] = xscale.y * val;\n this._scale[0] = val;\n }\n setScaleY(val) {\n if (val === this._scale[1]) return;\n this._scaleSignY = sign(val);\n // negative scale acts like a 180 rotation, so flip\n const yscale = vec(this.data[1] * this._scaleSignY, this.data[3] * this._scaleSignY).normalize();\n this.data[1] = yscale.x * val;\n this.data[3] = yscale.y * val;\n this._scale[1] = val;\n }\n setScale(scale) {\n this.setScaleX(scale.x);\n this.setScaleY(scale.y);\n }\n isIdentity() {\n return this.data[0] === 1 && this.data[1] === 0 && this.data[2] === 0 && this.data[3] === 1 && this.data[4] === 0 && this.data[5] === 0;\n }\n /**\r\n * Resets the current matrix to the identity matrix, mutating it\r\n * @returns {AffineMatrix} Current matrix as identity\r\n */ reset() {\n const mat = this;\n mat.data[0] = 1;\n mat.data[1] = 0;\n mat.data[2] = 0;\n mat.data[3] = 1;\n mat.data[4] = 0;\n mat.data[5] = 0;\n return mat;\n }\n /**\r\n * Creates a new Matrix with the same data as the current 4x4\r\n */ clone(dest) {\n const mat = dest || new AffineMatrix();\n mat.data[0] = this.data[0];\n mat.data[1] = this.data[1];\n mat.data[2] = this.data[2];\n mat.data[3] = this.data[3];\n mat.data[4] = this.data[4];\n mat.data[5] = this.data[5];\n return mat;\n }\n toString() {\n return `\r\n[${this.data[0]} ${this.data[2]} ${this.data[4]}]\r\n[${this.data[1]} ${this.data[3]} ${this.data[5]}]\r\n[0 0 1]\r\n`;\n }\n }\n class TransformStack {\n constructor(){\n this._transforms = [];\n this._currentTransform = AffineMatrix.identity();\n }\n save() {\n this._transforms.push(this._currentTransform);\n this._currentTransform = this._currentTransform.clone();\n }\n restore() {\n this._currentTransform = this._transforms.pop();\n }\n translate(x, y) {\n return this._currentTransform.translate(x, y);\n }\n rotate(angle) {\n return this._currentTransform.rotate(angle);\n }\n scale(x, y) {\n return this._currentTransform.scale(x, y);\n }\n set current(matrix) {\n this._currentTransform = matrix;\n }\n get current() {\n return this._currentTransform;\n }\n }\n class StateStack {\n constructor(){\n this._states = [];\n this._currentState = this._getDefaultState();\n }\n _getDefaultState() {\n return {\n opacity: 1,\n z: 0,\n tint: Color.White,\n material: null\n };\n }\n _cloneState() {\n return {\n opacity: this._currentState.opacity,\n z: this._currentState.z,\n tint: this._currentState.tint.clone(),\n material: this._currentState.material // TODO is this going to cause problems when cloning\n };\n }\n save() {\n this._states.push(this._currentState);\n this._currentState = this._cloneState();\n }\n restore() {\n this._currentState = this._states.pop();\n }\n get current() {\n return this._currentState;\n }\n set current(val) {\n this._currentState = val;\n }\n }\n const ResourceEvents = {\n Complete: \"complete\",\n Load: \"load\",\n LoadStart: \"loadstart\",\n Progress: \"progress\",\n Error: \"error\"\n };\n /**\r\n * The [[Resource]] type allows games built in Excalibur to load generic resources.\r\n * For any type of remote resource it is recommended to use [[Resource]] for preloading.\r\n */ class Resource {\n /**\r\n * @param path Path to the remote resource\r\n * @param responseType The type to expect as a response: \"\" | \"arraybuffer\" | \"blob\" | \"document\" | \"json\" | \"text\";\r\n * @param bustCache Whether or not to cache-bust requests\r\n */ constructor(path, responseType, bustCache = false){\n this.path = path;\n this.responseType = responseType;\n this.bustCache = bustCache;\n this.data = null;\n this.logger = Logger.getInstance();\n this.events = new EventEmitter();\n }\n /**\r\n * Returns true if the Resource is completely loaded and is ready\r\n * to be drawn.\r\n */ isLoaded() {\n return this.data !== null;\n }\n _cacheBust(uri) {\n const query = /\\?\\w*=\\w*/;\n if (query.test(uri)) uri += \"&__=\" + Date.now();\n else uri += \"?__=\" + Date.now();\n return uri;\n }\n /**\r\n * Begin loading the resource and returns a promise to be resolved on completion\r\n */ load() {\n return new Promise((resolve, reject)=>{\n // Exit early if we already have data\n if (this.data !== null) {\n this.logger.debug(\"Already have data for resource\", this.path);\n this.events.emit(\"complete\", this.data);\n resolve(this.data);\n return;\n }\n const request = new XMLHttpRequest();\n request.open(\"GET\", this.bustCache ? this._cacheBust(this.path) : this.path, true);\n request.responseType = this.responseType;\n request.addEventListener(\"loadstart\", (e)=>this.events.emit(\"loadstart\", e));\n request.addEventListener(\"progress\", (e)=>this.events.emit(\"progress\", e));\n request.addEventListener(\"error\", (e)=>this.events.emit(\"error\", e));\n request.addEventListener(\"load\", (e)=>this.events.emit(\"load\", e));\n request.addEventListener(\"load\", ()=>{\n // XHR on file:// success status is 0, such as with PhantomJS\n if (request.status !== 0 && request.status !== 200) {\n this.logger.error(\"Failed to load resource \", this.path, \" server responded with error code\", request.status);\n this.events.emit(\"error\", request.response);\n reject(new Error(request.statusText));\n return;\n }\n this.data = request.response;\n this.events.emit(\"complete\", this.data);\n this.logger.debug(\"Completed loading resource\", this.path);\n resolve(this.data);\n });\n request.send();\n });\n }\n }\n /**\r\n * Watch an object with a proxy, only fires if property value is different\r\n */ function watch(type, change) {\n if (!type) return type;\n if (type.__isProxy === undefined) // expando hack to mark a proxy\n return new Proxy(type, {\n set: (obj, prop, value)=>{\n // The default behavior to store the value\n if (obj[prop] !== value) {\n obj[prop] = value;\n // Avoid watching private junk\n if (typeof prop === \"string\") {\n if (prop[0] !== \"_\") change(obj);\n }\n }\n // Indicate success\n return true;\n },\n get: (obj, prop)=>{\n if (prop !== \"__isProxy\") return obj[prop];\n return true;\n }\n });\n return type;\n }\n /**\r\n * Watch an object with a proxy, fires change on any property value change\r\n */ function watchAny(type, change) {\n if (!type) return type;\n if (type.__isProxy === undefined) // expando hack to mark a proxy\n return new Proxy(type, {\n set: (obj, prop, value)=>{\n // The default behavior to store the value\n obj[prop] = value;\n // Avoid watching private junk\n if (typeof prop === \"string\") {\n if (prop[0] !== \"_\") change(obj);\n }\n // Indicate success\n return true;\n },\n get: (obj, prop)=>{\n if (prop !== \"__isProxy\") return obj[prop];\n return true;\n }\n });\n return type;\n }\n /**\r\n * A Graphic is the base Excalibur primitive for something that can be drawn to the [[ExcaliburGraphicsContext]].\r\n * [[Sprite]], [[Animation]], [[GraphicsGroup]], [[Canvas]], [[Rectangle]], [[Circle]], and [[Polygon]] all derive from the\r\n * [[Graphic]] abstract class.\r\n *\r\n * Implementors of a Graphic must override the abstract [[Graphic._drawImage]] method to render an image to the graphics context. Graphic\r\n * handles all the position, rotation, and scale transformations in [[Graphic._preDraw]] and [[Graphic._postDraw]]\r\n */ class Graphic {\n isStale() {\n return this._transformStale;\n }\n /**\r\n * Gets or sets the flipHorizontal, which will flip the graphic horizontally (across the y axis)\r\n */ get flipHorizontal() {\n return this._flipHorizontal;\n }\n set flipHorizontal(value) {\n this._flipHorizontal = value;\n this._transformStale = true;\n }\n /**\r\n * Gets or sets the flipVertical, which will flip the graphic vertically (across the x axis)\r\n */ get flipVertical() {\n return this._flipVertical;\n }\n set flipVertical(value) {\n this._flipVertical = value;\n this._transformStale = true;\n }\n /**\r\n * Gets or sets the rotation of the graphic\r\n */ get rotation() {\n return this._rotation;\n }\n set rotation(value) {\n this._rotation = value;\n this._transformStale = true;\n }\n /**\r\n * Gets or sets the scale of the graphic, this affects the width and\r\n */ get scale() {\n return this._scale;\n }\n set scale(value) {\n this._scale = watch(value, ()=>{\n this._transformStale = true;\n });\n this._transformStale = true;\n }\n /**\r\n * Gets or sets the origin of the graphic, if not set the center of the graphic is the origin\r\n */ get origin() {\n return this._origin;\n }\n set origin(value) {\n this._origin = watch(value, ()=>{\n this._transformStale = true;\n });\n this._transformStale = true;\n }\n constructor(options){\n var _a, _b, _c, _d, _e, _f;\n this.id = Graphic._ID++;\n this.transform = AffineMatrix.identity();\n this.tint = null;\n this._transformStale = true;\n /**\r\n * Gets or sets wether to show debug information about the graphic\r\n */ this.showDebug = false;\n this._flipHorizontal = false;\n this._flipVertical = false;\n this._rotation = 0;\n /**\r\n * Gets or sets the opacity of the graphic, 0 is transparent, 1 is solid (opaque).\r\n */ this.opacity = 1;\n this._scale = Vector.One;\n this._origin = null;\n this._width = 0;\n this._height = 0;\n if (options) {\n this.origin = (_a = options.origin) !== null && _a !== void 0 ? _a : this.origin;\n this.flipHorizontal = (_b = options.flipHorizontal) !== null && _b !== void 0 ? _b : this.flipHorizontal;\n this.flipVertical = (_c = options.flipVertical) !== null && _c !== void 0 ? _c : this.flipVertical;\n this.rotation = (_d = options.rotation) !== null && _d !== void 0 ? _d : this.rotation;\n this.opacity = (_e = options.opacity) !== null && _e !== void 0 ? _e : this.opacity;\n this.scale = (_f = options.scale) !== null && _f !== void 0 ? _f : this.scale;\n }\n }\n cloneGraphicOptions() {\n return {\n origin: this.origin ? this.origin.clone() : null,\n flipHorizontal: this.flipHorizontal,\n flipVertical: this.flipVertical,\n rotation: this.rotation,\n opacity: this.opacity,\n scale: this.scale ? this.scale.clone() : null\n };\n }\n /**\r\n * Gets or sets the width of the graphic (always positive)\r\n */ get width() {\n return Math.abs(this._width * this.scale.x);\n }\n /**\r\n * Gets or sets the height of the graphic (always positive)\r\n */ get height() {\n return Math.abs(this._height * this.scale.y);\n }\n set width(value) {\n this._width = value;\n this._transformStale = true;\n }\n set height(value) {\n this._height = value;\n this._transformStale = true;\n }\n /**\r\n * Gets a copy of the bounds in pixels occupied by the graphic on the the screen. This includes scale.\r\n */ get localBounds() {\n return BoundingBox.fromDimension(this.width, this.height, Vector.Zero);\n }\n /**\r\n * Draw the whole graphic to the context including transform\r\n * @param ex The excalibur graphics context\r\n * @param x\r\n * @param y\r\n */ draw(ex, x, y) {\n this._preDraw(ex, x, y);\n this._drawImage(ex, 0, 0);\n this._postDraw(ex);\n }\n /**\r\n * Apply affine transformations to the graphics context to manipulate the graphic before [[Graphic._drawImage]]\r\n * @param ex\r\n * @param x\r\n * @param y\r\n */ _preDraw(ex, x, y) {\n ex.save();\n ex.translate(x, y);\n if (this._transformStale) {\n this.transform.reset();\n this.transform.scale(Math.abs(this.scale.x), Math.abs(this.scale.y));\n this._rotate(this.transform);\n this._flip(this.transform);\n this._transformStale = false;\n }\n ex.multiply(this.transform);\n // it is important to multiply alphas so graphics respect the current context\n ex.opacity = ex.opacity * this.opacity;\n if (this.tint) ex.tint = this.tint;\n }\n _rotate(ex) {\n var _a;\n const scaleDirX = this.scale.x > 0 ? 1 : -1;\n const scaleDirY = this.scale.y > 0 ? 1 : -1;\n const origin = (_a = this.origin) !== null && _a !== void 0 ? _a : vec(this.width / 2, this.height / 2);\n ex.translate(origin.x, origin.y);\n ex.rotate(this.rotation);\n // This is for handling direction changes 1 or -1, that way we don't have mismatched translates()\n ex.scale(scaleDirX, scaleDirY);\n ex.translate(-origin.x, -origin.y);\n }\n _flip(ex) {\n if (this.flipHorizontal) {\n ex.translate(this.width / this.scale.x, 0);\n ex.scale(-1, 1);\n }\n if (this.flipVertical) {\n ex.translate(0, this.height / this.scale.y);\n ex.scale(1, -1);\n }\n }\n /**\r\n * Apply any additional work after [[Graphic._drawImage]] and restore the context state.\r\n * @param ex\r\n */ _postDraw(ex) {\n if (this.showDebug) ex.debug.drawRect(0, 0, this.width, this.height);\n ex.restore();\n }\n }\n Graphic._ID = 0;\n class Sprite extends Graphic {\n static from(image) {\n return new Sprite({\n image: image\n });\n }\n constructor(options){\n var _a, _b;\n super(options);\n this._logger = Logger.getInstance();\n this._dirty = true;\n this._logNotLoadedWarning = false;\n this.image = options.image;\n const { width: width, height: height } = options;\n this.sourceView = (_a = options.sourceView) !== null && _a !== void 0 ? _a : {\n x: 0,\n y: 0,\n width: width !== null && width !== void 0 ? width : 0,\n height: height !== null && height !== void 0 ? height : 0\n };\n this.destSize = (_b = options.destSize) !== null && _b !== void 0 ? _b : {\n width: width !== null && width !== void 0 ? width : 0,\n height: height !== null && height !== void 0 ? height : 0\n };\n this._updateSpriteDimensions();\n this.image.ready.then(()=>{\n this._updateSpriteDimensions();\n });\n }\n get width() {\n return Math.abs(this.destSize.width * this.scale.x);\n }\n get height() {\n return Math.abs(this.destSize.height * this.scale.y);\n }\n set width(newWidth) {\n newWidth /= Math.abs(this.scale.x);\n this.destSize.width = newWidth;\n super.width = Math.ceil(this.destSize.width);\n }\n set height(newHeight) {\n newHeight /= Math.abs(this.scale.y);\n this.destSize.height = newHeight;\n super.height = Math.ceil(this.destSize.height);\n }\n _updateSpriteDimensions() {\n var _a, _b, _c, _d, _e, _f;\n const { width: nativeWidth, height: nativeHeight } = this.image;\n // This code uses || to avoid 0's\n // If the source is not specified, use the native dimension\n this.sourceView.width = ((_a = this.sourceView) === null || _a === void 0 ? void 0 : _a.width) || nativeWidth;\n this.sourceView.height = ((_b = this.sourceView) === null || _b === void 0 ? void 0 : _b.height) || nativeHeight;\n // If the destination is not specified, use the source if specified, then native\n this.destSize.width = ((_c = this.destSize) === null || _c === void 0 ? void 0 : _c.width) || ((_d = this.sourceView) === null || _d === void 0 ? void 0 : _d.width) || nativeWidth;\n this.destSize.height = ((_e = this.destSize) === null || _e === void 0 ? void 0 : _e.height) || ((_f = this.sourceView) === null || _f === void 0 ? void 0 : _f.height) || nativeHeight;\n this.width = Math.ceil(this.destSize.width) * this.scale.x;\n this.height = Math.ceil(this.destSize.height) * this.scale.y;\n }\n _preDraw(ex, x, y) {\n if (this.image.isLoaded() && this._dirty) {\n this._dirty = false;\n this._updateSpriteDimensions();\n }\n super._preDraw(ex, x, y);\n }\n _drawImage(ex, x, y) {\n if (this.image.isLoaded()) ex.drawImage(this.image.image, this.sourceView.x, this.sourceView.y, this.sourceView.width, this.sourceView.height, x, y, this.destSize.width, this.destSize.height);\n else {\n if (!this._logNotLoadedWarning) this._logger.warn(`ImageSource ${this.image.path}` + ` is not yet loaded and won't be drawn. Please call .load() or include in a Loader.\\n\\n` + `Read https://excaliburjs.com/docs/imagesource for more information.`);\n this._logNotLoadedWarning = true;\n }\n }\n clone() {\n return new Sprite({\n image: this.image,\n sourceView: {\n ...this.sourceView\n },\n destSize: {\n ...this.destSize\n },\n ...this.cloneGraphicOptions()\n });\n }\n }\n /**\r\n * Describes the different image filtering modes\r\n */ var ImageFiltering;\n (function(ImageFiltering) {\n /**\r\n * Pixel is useful when you do not want smoothing aka antialiasing applied to your graphics.\r\n *\r\n * Useful for Pixel art aesthetics.\r\n */ ImageFiltering[\"Pixel\"] = \"Pixel\";\n /**\r\n * Blended is useful when you have high resolution artwork and would like it blended and smoothed\r\n */ ImageFiltering[\"Blended\"] = \"Blended\";\n })(ImageFiltering || (ImageFiltering = {}));\n /**\r\n * Manages loading image sources into webgl textures, a unique id is associated with all sources\r\n */ class TextureLoader {\n constructor(gl){\n this._textureMap = new Map();\n this._gl = gl;\n TextureLoader._MAX_TEXTURE_SIZE = gl.getParameter(gl.MAX_TEXTURE_SIZE);\n }\n /**\r\n * Get the WebGL Texture from a source image\r\n * @param image\r\n */ get(image) {\n return this._textureMap.get(image);\n }\n /**\r\n * Returns whether a source image has been loaded as a texture\r\n * @param image\r\n */ has(image) {\n return this._textureMap.has(image);\n }\n /**\r\n * Loads a graphic into webgl and returns it's texture info, a webgl context must be previously registered\r\n * @param image Source graphic\r\n * @param filtering {ImageFiltering} The ImageFiltering mode to apply to the loaded texture\r\n * @param forceUpdate Optionally force a texture to be reloaded, useful if the source graphic has changed\r\n */ load(image, filtering, forceUpdate = false) {\n // Ignore loading if webgl is not registered\n const gl = this._gl;\n if (!gl) return null;\n let tex = null;\n // If reuse the texture if it's from the same source\n if (this.has(image)) tex = this.get(image);\n // Update existing webgl texture and return early\n if (tex) {\n if (forceUpdate) {\n gl.bindTexture(gl.TEXTURE_2D, tex);\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image);\n }\n return tex;\n }\n // No texture exists create a new one\n tex = gl.createTexture();\n TextureLoader.checkImageSizeSupportedAndLog(image);\n gl.bindTexture(gl.TEXTURE_2D, tex);\n gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, true);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\n // NEAREST for pixel art, LINEAR for hi-res\n const filterMode = filtering !== null && filtering !== void 0 ? filtering : TextureLoader.filtering;\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, filterMode === ImageFiltering.Pixel ? gl.NEAREST : gl.LINEAR);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, filterMode === ImageFiltering.Pixel ? gl.NEAREST : gl.LINEAR);\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image);\n this._textureMap.set(image, tex);\n return tex;\n }\n delete(image) {\n // Ignore loading if webgl is not registered\n const gl = this._gl;\n if (!gl) return null;\n let tex = null;\n if (this.has(image)) {\n tex = this.get(image);\n gl.deleteTexture(tex);\n }\n }\n /**\r\n * Takes an image and returns if it meets size criteria for hardware\r\n * @param image\r\n * @returns if the image will be supported at runtime\r\n */ static checkImageSizeSupportedAndLog(image) {\n var _a;\n const originalSrc = (_a = image.dataset.originalSrc) !== null && _a !== void 0 ? _a : \"internal canvas bitmap\";\n if (image.width > TextureLoader._MAX_TEXTURE_SIZE || image.height > TextureLoader._MAX_TEXTURE_SIZE) {\n TextureLoader._LOGGER.error(`The image [${originalSrc}] provided to Excalibur is too large for the device's maximum texture size of ` + `(${TextureLoader._MAX_TEXTURE_SIZE}x${TextureLoader._MAX_TEXTURE_SIZE}) please resize to an image ` + `for excalibur to render properly.\\n\\nImages will likely render as black rectangles.\\n\\n` + `Read more here: https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API/WebGL_best_practices#understand_system_limits`);\n return false;\n } else if (image.width > 4096 || image.height > 4096) // https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API/WebGL_best_practices#understand_system_limits\n TextureLoader._LOGGER.warn(`The image [${originalSrc}] provided to excalibur is too large may not work on all mobile devices, ` + `it is recommended you resize images to a maximum (4096x4096).\\n\\n` + `Images will likely render as black rectangles on some mobile platforms.\\n\\n` + `Read more here: https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API/WebGL_best_practices#understand_system_limits`);\n return true;\n }\n }\n TextureLoader._LOGGER = Logger.getInstance();\n /**\r\n * Sets the default filtering for the Excalibur texture loader, default [[ImageFiltering.Blended]]\r\n */ TextureLoader.filtering = ImageFiltering.Blended;\n TextureLoader._MAX_TEXTURE_SIZE = 4096;\n class ImageSource {\n /**\r\n * The original size of the source image in pixels\r\n */ get width() {\n return this.image.naturalWidth;\n }\n /**\r\n * The original height of the source image in pixels\r\n */ get height() {\n return this.image.naturalHeight;\n }\n /**\r\n * Returns true if the Texture is completely loaded and is ready\r\n * to be drawn.\r\n */ isLoaded() {\n if (!this._src) // this boosts speed of access\n this._src = this.data.src;\n return !!this._src;\n }\n get image() {\n return this.data;\n }\n /**\r\n * The path to the image, can also be a data url like 'data:image/'\r\n * @param path {string} Path to the image resource relative from the HTML document hosting the game, or absolute\r\n * @param bustCache {boolean} Should excalibur add a cache busting querystring?\r\n * @param filtering {ImageFiltering} Optionally override the image filtering set by [[EngineOptions.antialiasing]]\r\n */ constructor(path, bustCache = false, filtering){\n this.path = path;\n this._logger = Logger.getInstance();\n /**\r\n * Access to the underlying html image element\r\n */ this.data = new Image();\n this._readyFuture = new Future();\n /**\r\n * Promise the resolves when the image is loaded and ready for use, does not initiate loading\r\n */ this.ready = this._readyFuture.promise;\n this._resource = new Resource(path, \"blob\", bustCache);\n this.filtering = filtering;\n if (path.endsWith(\".svg\") || path.endsWith(\".gif\")) this._logger.warn(`Image type is not fully supported, you may have mixed results ${path}. Fully supported: jpg, bmp, and png`);\n }\n /**\r\n * Should excalibur add a cache busting querystring? By default false.\r\n * Must be set before loading\r\n */ get bustCache() {\n return this._resource.bustCache;\n }\n set bustCache(val) {\n this._resource.bustCache = val;\n }\n /**\r\n * Begins loading the image and returns a promise that resolves when the image is loaded\r\n */ async load() {\n if (this.isLoaded()) return this.data;\n try {\n // Load base64 or blob if needed\n let url;\n if (!this.path.includes(\"data:image/\")) {\n const blob = await this._resource.load();\n url = URL.createObjectURL(blob);\n } else url = this.path;\n // Decode the image\n const image = new Image();\n // Use Image.onload over Image.decode()\n // https://bugs.chromium.org/p/chromium/issues/detail?id=1055828#c7\n // Otherwise chrome will throw still Image.decode() failures for large textures\n const loadedFuture = new Future();\n image.onload = ()=>loadedFuture.resolve();\n image.src = url;\n image.setAttribute(\"data-original-src\", this.path);\n await loadedFuture.promise;\n // Set results\n // We defer loading the texture into webgl until the first draw that way we avoid a singleton\n // and for the multi-engine case the texture needs to be created in EACH webgl context to work\n // See image-renderer.ts draw()\n this.data = image;\n // emit warning if potentially too big\n TextureLoader.checkImageSizeSupportedAndLog(this.data);\n } catch (error) {\n throw `Error loading ImageSource from path '${this.path}' with error [${error.message}]`;\n }\n // Do a bad thing to pass the filtering as an attribute\n this.data.setAttribute(\"filtering\", this.filtering);\n // todo emit complete\n this._readyFuture.resolve(this.data);\n return this.data;\n }\n /**\r\n * Build a sprite from this ImageSource\r\n */ toSprite() {\n return Sprite.from(this);\n }\n /**\r\n * Unload images from memory\r\n */ unload() {\n this.data = new Image();\n }\n }\n /**\r\n * Represents a collection of sprites from a source image with some organization in a grid\r\n */ class SpriteSheet {\n /**\r\n * Build a new sprite sheet from a list of sprites\r\n *\r\n * Use [[SpriteSheet.fromImageSource]] to create a SpriteSheet from an [[ImageSource]] organized in a grid\r\n * @param options\r\n */ constructor(options){\n this._logger = Logger.getInstance();\n this.sprites = [];\n const { sprites: sprites, rows: rows, columns: columns } = options;\n this.sprites = sprites;\n this.rows = rows !== null && rows !== void 0 ? rows : 1;\n this.columns = columns !== null && columns !== void 0 ? columns : this.sprites.length;\n }\n /**\r\n * Find a sprite by their x/y position in the SpriteSheet, for example `getSprite(0, 0)` is the [[Sprite]] in the top-left\r\n * @param x\r\n * @param y\r\n */ getSprite(x, y) {\n if (x >= this.columns || x < 0) {\n this._logger.warn(`No sprite exists in the SpriteSheet at (${x}, ${y}), x: ${x} should be between 0 and ${this.columns - 1}`);\n return null;\n }\n if (y >= this.rows || y < 0) {\n this._logger.warn(`No sprite exists in the SpriteSheet at (${x}, ${y}), y: ${y} should be between 0 and ${this.rows - 1}`);\n return null;\n }\n const spriteIndex = x + y * this.columns;\n return this.sprites[spriteIndex];\n }\n /**\r\n * Create a sprite sheet from a sparse set of [[SourceView]] rectangles\r\n * @param options\r\n */ static fromImageSourceWithSourceViews(options) {\n const sprites = options.sourceViews.map((sourceView)=>{\n return new Sprite({\n image: options.image,\n sourceView: sourceView\n });\n });\n return new SpriteSheet({\n sprites: sprites\n });\n }\n /**\r\n * Create a SpriteSheet from an [[ImageSource]] organized in a grid\r\n *\r\n * Example:\r\n * ```\r\n * const spriteSheet = SpriteSheet.fromImageSource({\r\n * image: imageSource,\r\n * grid: {\r\n * rows: 5,\r\n * columns: 2,\r\n * spriteWidth: 32, // pixels\r\n * spriteHeight: 32 // pixels\r\n * },\r\n * // Optionally specify spacing\r\n * spacing: {\r\n * // pixels from the top left to start the sprite parsing\r\n * originOffset: {\r\n * x: 5,\r\n * y: 5\r\n * },\r\n * // pixels between each sprite while parsing\r\n * margin: {\r\n * x: 1,\r\n * y: 1\r\n * }\r\n * }\r\n * })\r\n * ```\r\n *\r\n * @param options\r\n */ static fromImageSource(options) {\n var _a;\n const sprites = [];\n options.spacing = (_a = options.spacing) !== null && _a !== void 0 ? _a : {};\n const { image: image, grid: { rows: rows, columns: cols, spriteWidth: spriteWidth, spriteHeight: spriteHeight }, spacing: { originOffset: originOffset, margin: margin } } = options;\n const offsetDefaults = {\n x: 0,\n y: 0,\n ...originOffset\n };\n const marginDefaults = {\n x: 0,\n y: 0,\n ...margin\n };\n for(let x = 0; x < cols; x++)for(let y = 0; y < rows; y++)sprites[x + y * cols] = new Sprite({\n image: image,\n sourceView: {\n x: x * spriteWidth + marginDefaults.x * x + offsetDefaults.x,\n y: y * spriteHeight + marginDefaults.y * y + offsetDefaults.y,\n width: spriteWidth,\n height: spriteHeight\n },\n destSize: {\n height: spriteHeight,\n width: spriteWidth\n }\n });\n return new SpriteSheet({\n sprites: sprites,\n rows: rows,\n columns: cols\n });\n }\n clone() {\n return new SpriteSheet({\n sprites: this.sprites.map((sprite)=>sprite.clone()),\n rows: this.rows,\n columns: this.columns\n });\n }\n }\n class SpriteFont extends Graphic {\n constructor(options){\n super(options);\n this._text = \"\";\n this.alphabet = \"\";\n this.shadow = null;\n this.caseInsensitive = false;\n this.spacing = 0;\n this._logger = Logger.getInstance();\n this._alreadyWarnedAlphabet = false;\n this._alreadyWarnedSpriteSheet = false;\n const { alphabet: alphabet, spriteSheet: spriteSheet, caseInsensitive: caseInsensitive, spacing: spacing, shadow: shadow } = options;\n this.alphabet = alphabet;\n this.spriteSheet = spriteSheet;\n this.caseInsensitive = caseInsensitive !== null && caseInsensitive !== void 0 ? caseInsensitive : this.caseInsensitive;\n this.spacing = spacing !== null && spacing !== void 0 ? spacing : this.spacing;\n this.shadow = shadow !== null && shadow !== void 0 ? shadow : this.shadow;\n }\n _getCharacterSprites(text) {\n const results = [];\n // handle case insensitive\n const textToRender = this.caseInsensitive ? text.toLocaleLowerCase() : text;\n const alphabet = this.caseInsensitive ? this.alphabet.toLocaleLowerCase() : this.alphabet;\n // for each letter in text\n for(let letterIndex = 0; letterIndex < textToRender.length; letterIndex++){\n // find the sprite index in alphabet , if there is an error pick the first\n const letter = textToRender[letterIndex];\n let spriteIndex = alphabet.indexOf(letter);\n if (spriteIndex === -1) {\n spriteIndex = 0;\n if (!this._alreadyWarnedAlphabet) {\n this._logger.warn(`SpriteFont - Cannot find letter '${letter}' in configured alphabet '${alphabet}'.`);\n this._logger.warn(\"There maybe be more issues in the SpriteFont configuration. No additional warnings will be logged.\");\n this._alreadyWarnedAlphabet = true;\n }\n }\n const letterSprite = this.spriteSheet.sprites[spriteIndex];\n if (letterSprite) results.push(letterSprite);\n else if (!this._alreadyWarnedSpriteSheet) {\n this._logger.warn(`SpriteFont - Cannot find sprite for '${letter}' at index '${spriteIndex}' in configured SpriteSheet`);\n this._logger.warn(\"There maybe be more issues in the SpriteFont configuration. No additional warnings will be logged.\");\n this._alreadyWarnedSpriteSheet = true;\n }\n }\n return results;\n }\n measureText(text, maxWidth) {\n const lines = this._getLinesFromText(text, maxWidth);\n const maxWidthLine = lines.reduce((a, b)=>{\n return a.length > b.length ? a : b;\n });\n const sprites = this._getCharacterSprites(maxWidthLine);\n let width = 0;\n let height = 0;\n for (const sprite of sprites){\n width += sprite.width + this.spacing;\n height = Math.max(height, sprite.height);\n }\n return BoundingBox.fromDimension(width, height * lines.length, Vector.Zero);\n }\n _drawImage(ex, x, y, maxWidth) {\n let xCursor = 0;\n let yCursor = 0;\n let height = 0;\n const lines = this._getLinesFromText(this._text, maxWidth);\n for (const line of lines){\n for (const sprite of this._getCharacterSprites(line)){\n // draw it in the right spot and increase the cursor by sprite width\n sprite.draw(ex, x + xCursor, y + yCursor);\n xCursor += sprite.width + this.spacing;\n height = Math.max(height, sprite.height);\n }\n xCursor = 0;\n yCursor += height;\n }\n }\n render(ex, text, _color, x, y, maxWidth) {\n // SpriteFont doesn't support _color, yet...\n this._text = text;\n const bounds = this.measureText(text, maxWidth);\n this.width = bounds.width;\n this.height = bounds.height;\n if (this.shadow) {\n ex.save();\n ex.translate(this.shadow.offset.x, this.shadow.offset.y);\n this._preDraw(ex, x, y);\n this._drawImage(ex, 0, 0, maxWidth);\n this._postDraw(ex);\n ex.restore();\n }\n this._preDraw(ex, x, y);\n this._drawImage(ex, 0, 0, maxWidth);\n this._postDraw(ex);\n }\n clone() {\n return new SpriteFont({\n alphabet: this.alphabet,\n spriteSheet: this.spriteSheet,\n spacing: this.spacing\n });\n }\n _getLinesFromText(text, maxWidth) {\n if (this._cachedText === text && this._cachedRenderWidth === maxWidth) return this._cachedLines;\n const lines = text.split(\"\\n\");\n if (maxWidth == null) return lines;\n // If the current line goes past the maxWidth, append a new line without modifying the underlying text.\n for(let i = 0; i < lines.length; i++){\n let line = lines[i];\n let newLine = \"\";\n // Note: we subtract the spacing to counter the initial padding on the left side.\n if (this.measureText(line).width > maxWidth) {\n while(this.measureText(line).width > maxWidth){\n newLine = line[line.length - 1] + newLine;\n line = line.slice(0, -1); // Remove last character from line\n }\n // Update the array with our new values\n lines[i] = line;\n lines[i + 1] = newLine;\n }\n }\n this._cachedText = text;\n this._cachedLines = lines;\n this._cachedRenderWidth = maxWidth;\n return lines;\n }\n }\n /* harmony default export */ const debug_font = \"data:image/png;base64,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\";\n /**\r\n * Internal debugtext helper\r\n */ class DebugText {\n constructor(){\n /**\r\n * base64 font\r\n */ this.fontSheet = debug_font;\n this.size = 16;\n this.load();\n }\n load() {\n this._imageSource = new ImageSource(this.fontSheet);\n return this._imageSource.load().then(()=>{\n this._spriteSheet = SpriteSheet.fromImageSource({\n image: this._imageSource,\n grid: {\n rows: 3,\n columns: 16,\n spriteWidth: 16,\n spriteHeight: 16\n }\n });\n this._spriteFont = new SpriteFont({\n alphabet: \"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ,!'&.\\\"?-()+ \",\n caseInsensitive: true,\n spriteSheet: this._spriteSheet,\n spacing: -6\n });\n });\n }\n /**\r\n * Writes debug text using the built in sprint font\r\n * @param ctx\r\n * @param text\r\n * @param pos\r\n */ write(ctx, text, pos) {\n if (this._imageSource.isLoaded()) this._spriteFont.render(ctx, text, null, pos.x, pos.y);\n }\n }\n class RenderSource {\n constructor(_gl, _texture){\n this._gl = _gl;\n this._texture = _texture;\n }\n use() {\n const gl = this._gl;\n gl.activeTexture(gl.TEXTURE0);\n gl.bindTexture(gl.TEXTURE_2D, this._texture);\n }\n disable() {\n const gl = this._gl;\n gl.bindTexture(gl.TEXTURE_2D, null);\n }\n }\n class RenderTarget {\n constructor(options){\n this.width = options.width;\n this.height = options.height;\n this._gl = options.gl;\n this._setupFramebuffer();\n }\n setResolution(width, height) {\n const gl = this._gl;\n this.width = width;\n this.height = height;\n gl.bindTexture(gl.TEXTURE_2D, this._frameTexture);\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.width, this.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);\n }\n get frameBuffer() {\n return this._frameBuffer;\n }\n get frameTexture() {\n return this._frameTexture;\n }\n _setupFramebuffer() {\n // Allocates frame buffer\n const gl = this._gl;\n this._frameTexture = gl.createTexture();\n gl.bindTexture(gl.TEXTURE_2D, this._frameTexture);\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.width, this.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);\n // set the filtering so we don't need mips\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\n // attach the texture as the first color attachment\n const attachmentPoint = gl.COLOR_ATTACHMENT0;\n // After this bind all draw calls will draw to this framebuffer texture\n this._frameBuffer = gl.createFramebuffer();\n gl.bindFramebuffer(gl.FRAMEBUFFER, this._frameBuffer);\n gl.framebufferTexture2D(gl.FRAMEBUFFER, attachmentPoint, gl.TEXTURE_2D, this._frameTexture, 0);\n // Reset after initialized\n this.disable();\n }\n toRenderSource() {\n const source = new RenderSource(this._gl, this._frameTexture);\n return source;\n }\n /**\r\n * When called, all drawing gets redirected to this render target\r\n */ use() {\n const gl = this._gl;\n gl.bindFramebuffer(gl.FRAMEBUFFER, this._frameBuffer);\n // very important to set the viewport to the size of the framebuffer texture\n gl.viewport(0, 0, this.width, this.height);\n }\n /**\r\n * When called, all drawing is sent back to the canvas\r\n */ disable() {\n const gl = this._gl;\n // passing null switches rendering back to the canvas\n gl.bindFramebuffer(gl.FRAMEBUFFER, null);\n gl.bindTexture(gl.TEXTURE_2D, null);\n }\n }\n /* harmony default export */ const line_vertex = \"#version 300 es\\r\\nin vec2 a_position;\\r\\nin vec4 a_color;\\r\\n\\r\\nout lowp vec4 v_color;\\r\\n\\r\\nuniform mat4 u_matrix;\\r\\n\\r\\nvoid main() {\\r\\n // Set the vertex position using the ortho transform matrix\\r\\n gl_Position = u_matrix * vec4(a_position, 0.0, 1.0);\\r\\n\\r\\n // Passthrough the color\\r\\n v_color = a_color;\\r\\n}\";\n /* harmony default export */ const line_fragment = \"#version 300 es\\r\\nprecision mediump float;\\r\\n\\r\\n// Color\\r\\nin lowp vec4 v_color;\\r\\n\\r\\nout vec4 fragColor;\\r\\n\\r\\nvoid main() {\\r\\n fragColor = v_color;\\r\\n}\";\n /**\r\n * Return the size of the GlType in bytes\r\n * @param gl\r\n * @param type\r\n */ function getGlTypeSizeBytes(gl, type) {\n switch(type){\n case gl.FLOAT:\n return 4;\n case gl.SHORT:\n return 2;\n case gl.UNSIGNED_SHORT:\n return 2;\n case gl.BYTE:\n return 1;\n case gl.UNSIGNED_BYTE:\n return 1;\n default:\n return 1;\n }\n }\n /**\r\n * Based on the type return the number of attribute components\r\n *\r\n * https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/vertexAttribPointer\r\n * @param gl\r\n * @param type\r\n */ function getAttributeComponentSize(gl, type) {\n switch(type){\n case gl.LOW_FLOAT:\n case gl.HIGH_FLOAT:\n case gl.FLOAT:\n return 1;\n case gl.FLOAT_VEC2:\n return 2;\n case gl.FLOAT_VEC3:\n return 3;\n case gl.FLOAT_VEC4:\n return 4;\n case gl.BYTE:\n return 1;\n case gl.UNSIGNED_BYTE:\n return 1;\n case gl.UNSIGNED_SHORT:\n case gl.SHORT:\n return 1;\n default:\n return 1;\n }\n }\n /**\r\n * Based on the attribute return the corresponding supported attrib pointer type\r\n * https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/vertexAttribPointer\r\n *\r\n * @param gl\r\n * @param type\r\n */ function getAttributePointerType(gl, type) {\n switch(type){\n case gl.LOW_FLOAT:\n case gl.HIGH_FLOAT:\n case gl.FLOAT:\n case gl.FLOAT_VEC2:\n case gl.FLOAT_VEC3:\n case gl.FLOAT_VEC4:\n return gl.FLOAT;\n case gl.BYTE:\n return gl.BYTE;\n case gl.UNSIGNED_BYTE:\n return gl.UNSIGNED_BYTE;\n case gl.SHORT:\n return gl.SHORT;\n case gl.UNSIGNED_SHORT:\n return gl.UNSIGNED_SHORT;\n default:\n return gl.FLOAT;\n }\n }\n class Shader {\n get compiled() {\n return this._compiled;\n }\n /**\r\n * Create a shader program in excalibur\r\n * @param options specify shader vertex and fragment source\r\n */ constructor(options){\n this._logger = Logger.getInstance();\n this.uniforms = {};\n this.attributes = {};\n this._compiled = false;\n const { gl: gl, vertexSource: vertexSource, fragmentSource: fragmentSource } = options;\n this._gl = gl;\n this.vertexSource = vertexSource;\n this.fragmentSource = fragmentSource;\n }\n /**\r\n * Binds the shader program\r\n */ use() {\n const gl = this._gl;\n gl.useProgram(this.program);\n Shader._ACTIVE_SHADER_INSTANCE = this;\n }\n isCurrentlyBound() {\n return Shader._ACTIVE_SHADER_INSTANCE === this;\n }\n /**\r\n * Compile the current shader against a webgl context\r\n */ compile() {\n const gl = this._gl;\n const vertexShader = this._compileShader(gl, this.vertexSource, gl.VERTEX_SHADER);\n const fragmentShader = this._compileShader(gl, this.fragmentSource, gl.FRAGMENT_SHADER);\n this.program = this._createProgram(gl, vertexShader, fragmentShader);\n const attributes = this.getAttributes();\n for (const attribute of attributes)this.attributes[attribute.name] = attribute;\n const uniforms = this.getUniforms();\n for (const uniform of uniforms)this.uniforms[uniform.name] = uniform;\n this._compiled = true;\n return this.program;\n }\n getUniforms() {\n const gl = this._gl;\n const uniformCount = gl.getProgramParameter(this.program, gl.ACTIVE_UNIFORMS);\n const uniforms = [];\n for(let i = 0; i < uniformCount; i++){\n const uniform = gl.getActiveUniform(this.program, i);\n const uniformLocation = gl.getUniformLocation(this.program, uniform.name);\n uniforms.push({\n name: uniform.name,\n glType: uniform.type,\n location: uniformLocation\n });\n }\n return uniforms;\n }\n getAttributes() {\n const gl = this._gl;\n const attributeCount = gl.getProgramParameter(this.program, gl.ACTIVE_ATTRIBUTES);\n const attributes = [];\n for(let i = 0; i < attributeCount; i++){\n const attribute = gl.getActiveAttrib(this.program, i);\n const attributeLocation = gl.getAttribLocation(this.program, attribute.name);\n attributes.push({\n name: attribute.name,\n glType: getAttributePointerType(gl, attribute.type),\n size: getAttributeComponentSize(gl, attribute.type),\n location: attributeLocation,\n normalized: false\n });\n }\n return attributes;\n }\n /**\r\n * Set a texture in a gpu texture slot\r\n * @param slotNumber\r\n * @param texture\r\n */ setTexture(slotNumber, texture) {\n const gl = this._gl;\n gl.activeTexture(gl.TEXTURE0 + slotNumber);\n gl.bindTexture(gl.TEXTURE_2D, texture);\n }\n /**\r\n * Set an integer uniform for the current shader\r\n *\r\n * **Important** Must call ex.Shader.use() before setting a uniform!\r\n *\r\n * @param name\r\n * @param value\r\n */ setUniformInt(name, value) {\n this.setUniform(\"uniform1i\", name, ~~value);\n }\n /**\r\n * Set an integer uniform for the current shader, WILL NOT THROW on error.\r\n *\r\n * **Important** Must call ex.Shader.use() before setting a uniform!\r\n *\r\n * @param name\r\n * @param value\r\n */ trySetUniformInt(name, value) {\n return this.trySetUniform(\"uniform1i\", name, ~~value);\n }\n /**\r\n * Set an integer array uniform for the current shader\r\n *\r\n * **Important** Must call ex.Shader.use() before setting a uniform!\r\n *\r\n * @param name\r\n * @param value\r\n */ setUniformIntArray(name, value) {\n this.setUniform(\"uniform1iv\", name, value);\n }\n /**\r\n * Set an integer array uniform for the current shader, WILL NOT THROW on error.\r\n *\r\n * **Important** Must call ex.Shader.use() before setting a uniform!\r\n *\r\n * @param name\r\n * @param value\r\n */ trySetUniformIntArray(name, value) {\n return this.trySetUniform(\"uniform1iv\", name, value);\n }\n /**\r\n * Set a boolean uniform for the current shader\r\n *\r\n * **Important** Must call ex.Shader.use() before setting a uniform!\r\n *\r\n * @param name\r\n * @param value\r\n */ setUniformBoolean(name, value) {\n this.setUniform(\"uniform1i\", name, value ? 1 : 0);\n }\n /**\r\n * Set a boolean uniform for the current shader, WILL NOT THROW on error.\r\n *\r\n * **Important** Must call ex.Shader.use() before setting a uniform!\r\n *\r\n * @param name\r\n * @param value\r\n */ trySetUniformBoolean(name, value) {\n return this.trySetUniform(\"uniform1i\", name, value ? 1 : 0);\n }\n /**\r\n * Set a float uniform for the current shader\r\n *\r\n * **Important** Must call ex.Shader.use() before setting a uniform!\r\n *\r\n * @param name\r\n * @param value\r\n */ setUniformFloat(name, value) {\n this.setUniform(\"uniform1f\", name, value);\n }\n /**\r\n * Set a float uniform for the current shader, WILL NOT THROW on error.\r\n *\r\n * **Important** Must call ex.Shader.use() before setting a uniform!\r\n *\r\n * @param name\r\n * @param value\r\n */ trySetUniformFloat(name, value) {\n return this.trySetUniform(\"uniform1f\", name, value);\n }\n /**\r\n * Set a float array uniform for the current shader\r\n *\r\n * **Important** Must call ex.Shader.use() before setting a uniform!\r\n *\r\n * @param name\r\n * @param value\r\n */ setUniformFloatArray(name, value) {\n this.setUniform(\"uniform1fv\", name, value);\n }\n /**\r\n * Set a float array uniform for the current shader, WILL NOT THROW on error.\r\n *\r\n * **Important** Must call ex.Shader.use() before setting a uniform!\r\n *\r\n * @param name\r\n * @param value\r\n */ trySetUniformFloatArray(name, value) {\n return this.trySetUniform(\"uniform1fv\", name, value);\n }\n /**\r\n * Set a [[Vector]] uniform for the current shader\r\n *\r\n * **Important** Must call ex.Shader.use() before setting a uniform!\r\n *\r\n * @param name\r\n * @param value\r\n */ setUniformFloatVector(name, value) {\n this.setUniform(\"uniform2f\", name, value.x, value.y);\n }\n /**\r\n * Set a [[Vector]] uniform for the current shader, WILL NOT THROW on error.\r\n *\r\n * **Important** Must call ex.Shader.use() before setting a uniform!\r\n *\r\n * @param name\r\n * @param value\r\n */ trySetUniformFloatVector(name, value) {\n return this.trySetUniform(\"uniform2f\", name, value.x, value.y);\n }\n /**\r\n * Set a [[Color]] uniform for the current shader\r\n *\r\n * **Important** Must call ex.Shader.use() before setting a uniform!\r\n *\r\n * @param name\r\n * @param value\r\n */ setUniformFloatColor(name, value) {\n this.setUniform(\"uniform4f\", name, value.r / 255, value.g / 255, value.b / 255, value.a);\n }\n /**\r\n * Set a [[Color]] uniform for the current shader, WILL NOT THROW on error.\r\n *\r\n * **Important** Must call ex.Shader.use() before setting a uniform!\r\n *\r\n * @param name\r\n * @param value\r\n */ trySetUniformFloatColor(name, value) {\n return this.trySetUniform(\"uniform4f\", name, value.r / 255, value.g / 255, value.b / 255, value.a);\n }\n /**\r\n * Set an [[Matrix]] uniform for the current shader\r\n *\r\n * **Important** Must call ex.Shader.use() before setting a uniform!\r\n *\r\n * @param name\r\n * @param value\r\n */ setUniformMatrix(name, value) {\n this.setUniform(\"uniformMatrix4fv\", name, false, value.data);\n }\n /**\r\n * Set an [[Matrix]] uniform for the current shader, WILL NOT THROW on error.\r\n *\r\n * **Important** Must call ex.Shader.use() before setting a uniform!\r\n *\r\n * @param name\r\n * @param value\r\n */ trySetUniformMatrix(name, value) {\n return this.trySetUniform(\"uniformMatrix4fv\", name, false, value.data);\n }\n /**\r\n * Set any available uniform type in webgl\r\n *\r\n * For example setUniform('uniformMatrix2fv', 'u_my2x2_mat`, ...);\r\n */ setUniform(uniformType, name, ...value) {\n if (!this._compiled) throw Error(`Must compile shader before setting a uniform ${uniformType}:${name}`);\n if (!this.isCurrentlyBound()) throw Error(\"Currently accessed shader instance is not the current active shader in WebGL, must call `shader.use()` before setting uniforms\");\n const gl = this._gl;\n const location = gl.getUniformLocation(this.program, name);\n if (location) {\n const args = [\n location,\n ...value\n ];\n this._gl[uniformType].apply(this._gl, args);\n } else throw Error(`Uniform ${uniformType}:${name} doesn\\'t exist or is not used in the shader source code,` + \" unused uniforms are optimized away by most browsers\");\n }\n /**\r\n * Set any available uniform type in webgl. Will try to set the uniform, will return false if the uniform didn't exist,\r\n * true if it was set.\r\n *\r\n * WILL NOT THROW on error\r\n *\r\n * For example setUniform('uniformMatrix2fv', 'u_my2x2_mat`, ...);\r\n *\r\n */ trySetUniform(uniformType, name, ...value) {\n if (!this._compiled) {\n this._logger.warn(`Must compile shader before setting a uniform ${uniformType}:${name}`);\n return false;\n }\n if (!this.isCurrentlyBound()) {\n this._logger.warn(\"Currently accessed shader instance is not the current active shader in WebGL, must call `shader.use()` before setting uniforms\");\n return false;\n }\n const gl = this._gl;\n const location = gl.getUniformLocation(this.program, name);\n if (location) {\n const args = [\n location,\n ...value\n ];\n this._gl[uniformType].apply(this._gl, args);\n } else return false;\n return true;\n }\n _createProgram(gl, vertexShader, fragmentShader) {\n const program = gl.createProgram();\n if (program === null) throw Error(\"Could not create graphics shader program\");\n // attach the shaders.\n gl.attachShader(program, vertexShader);\n gl.attachShader(program, fragmentShader);\n // link the program.\n gl.linkProgram(program);\n const success = gl.getProgramParameter(program, gl.LINK_STATUS);\n if (!success) throw Error(`Could not link the program: [${gl.getProgramInfoLog(program)}]`);\n return program;\n }\n _compileShader(gl, source, type) {\n const typeName = gl.VERTEX_SHADER === type ? \"vertex\" : \"fragment\";\n const shader = gl.createShader(type);\n if (shader === null) throw Error(`Could not build shader: [${source}]`);\n gl.shaderSource(shader, source);\n gl.compileShader(shader);\n const success = gl.getShaderParameter(shader, gl.COMPILE_STATUS);\n if (!success) {\n const errorInfo = gl.getShaderInfoLog(shader);\n throw Error(`Could not compile ${typeName} shader:\\n\\n${errorInfo}${this._processSourceForError(source, errorInfo)}`);\n }\n return shader;\n }\n _processSourceForError(source, errorInfo) {\n const lines = source.split(\"\\n\");\n const errorLineStart = errorInfo.search(/\\d:\\d/);\n const errorLineEnd = errorInfo.indexOf(\" \", errorLineStart);\n const [_, error2] = errorInfo.slice(errorLineStart, errorLineEnd).split(\":\").map((v)=>Number(v));\n for(let i = 0; i < lines.length; i++)lines[i] = `${i + 1}: ${lines[i]}${error2 === i + 1 ? \" <----- ERROR!\" : \"\"}`;\n return \"\\n\\nSource:\\n\" + lines.join(\"\\n\");\n }\n }\n Shader._ACTIVE_SHADER_INSTANCE = null;\n /**\r\n * Helper around vertex buffer to simplify creating and uploading geometry\r\n *\r\n * Under the hood uses Float32Array\r\n */ class VertexBuffer {\n constructor(options){\n /**\r\n * If the vertices never change switching 'static' can be more efficient on the gpu\r\n *\r\n * Default is 'dynamic'\r\n */ this.type = \"dynamic\";\n const { gl: gl, size: size, type: type, data: data } = options;\n this._gl = gl;\n this.buffer = this._gl.createBuffer();\n if (!data && !size) throw Error(\"Must either provide data or a size to the VertexBuffer\");\n if (!data) this.bufferData = new Float32Array(size);\n else this.bufferData = data;\n this.type = type !== null && type !== void 0 ? type : this.type;\n // Allocate buffer\n gl.bindBuffer(gl.ARRAY_BUFFER, this.buffer);\n gl.bufferData(gl.ARRAY_BUFFER, this.bufferData, this.type === \"static\" ? gl.STATIC_DRAW : gl.DYNAMIC_DRAW);\n }\n /**\r\n * Bind this vertex buffer\r\n */ bind() {\n const gl = this._gl;\n gl.bindBuffer(gl.ARRAY_BUFFER, this.buffer);\n }\n /**\r\n * Upload vertex buffer geometry to the GPU\r\n */ upload(count) {\n const gl = this._gl;\n gl.bindBuffer(gl.ARRAY_BUFFER, this.buffer);\n if (count) gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.bufferData, 0, count);\n else // TODO always use bufferSubData? need to perf test it\n gl.bufferData(gl.ARRAY_BUFFER, this.bufferData, this.type === \"static\" ? gl.STATIC_DRAW : gl.DYNAMIC_DRAW);\n }\n }\n /**\r\n * Helper around creating vertex attributes in a given [[VertexBuffer]], this is useful for describing\r\n * the memory layout for your vertices inside a particular buffer\r\n *\r\n * Note: This helper assumes interleaved attributes in one [[VertexBuffer]], not many.\r\n *\r\n * Working with `gl.vertexAttribPointer` can be tricky, and this attempts to double check you\r\n */ class VertexLayout {\n get vertexBuffer() {\n return this._vertexBuffer;\n }\n get attributes() {\n return this._attributes;\n }\n constructor(options){\n this._logger = Logger.getInstance();\n this._layout = [];\n this._attributes = [];\n this._vertexTotalSizeBytes = 0;\n const { gl: gl, shader: shader, vertexBuffer: vertexBuffer, attributes: attributes } = options;\n this._gl = gl;\n this._vertexBuffer = vertexBuffer;\n this._attributes = attributes;\n this._shader = shader;\n if (shader) this.initialize();\n }\n /**\r\n * Total number of bytes that the vertex will take up\r\n */ get totalVertexSizeBytes() {\n return this._vertexTotalSizeBytes;\n }\n set shader(shader) {\n if (shader && this._shader !== shader) {\n this._shader = shader;\n this.initialize();\n }\n }\n get shader() {\n return this._shader;\n }\n /**\r\n * Layouts need shader locations and must be bound to a shader\r\n */ initialize() {\n if (!this._shader) return;\n if (!this._shader.compiled) throw Error(\"Shader not compiled, shader must be compiled before defining a vertex layout\");\n this._layout.length = 0;\n const shaderAttributes = this._shader.attributes;\n for (const attribute of this._attributes){\n const attrib = shaderAttributes[attribute[0]];\n if (!attrib) throw Error(`The attribute named: ${attribute[0]} size ${attribute[1]}` + ` not found in the shader source code:\\n ${this._shader.vertexSource}`);\n if (attrib.size !== attribute[1]) throw Error(`VertexLayout size definition for attribute: [${attribute[0]}, ${attribute[1]}],` + ` doesnt match shader source size ${attrib.size}:\\n ${this._shader.vertexSource}`);\n this._layout.push(attrib);\n }\n // calc size\n let componentsPerVertex = 0;\n for (const vertAttribute of this._layout){\n const typeSize = getGlTypeSizeBytes(this._gl, vertAttribute.glType);\n this._vertexTotalSizeBytes += typeSize * vertAttribute.size;\n componentsPerVertex += vertAttribute.size;\n }\n if (this._vertexBuffer.bufferData.length % componentsPerVertex !== 0) this._logger.warn(`The vertex component size (${componentsPerVertex}) does divide evenly into the specified vertex buffer` + ` (${this._vertexBuffer.bufferData.length})`);\n }\n /**\r\n * Bind this layout with it's associated vertex buffer\r\n *\r\n * @param uploadBuffer Optionally indicate you wish to upload the buffer to the GPU associated with this layout\r\n */ use(uploadBuffer = false, count) {\n if (!this._shader) throw Error(\"No shader is associated with this vertex layout, a shader must be set\");\n const gl = this._gl;\n if (!this._shader.isCurrentlyBound()) throw Error(\"Shader associated with this vertex layout is not active! Call shader.use() before layout.use()\");\n this._vertexBuffer.bind();\n if (uploadBuffer) this._vertexBuffer.upload(count);\n let offset = 0;\n // TODO switch to VAOs if the extension is\n for (const vert of this._layout){\n gl.vertexAttribPointer(vert.location, vert.size, vert.glType, vert.normalized, this.totalVertexSizeBytes, offset);\n gl.enableVertexAttribArray(vert.location);\n offset += getGlTypeSizeBytes(gl, vert.glType) * vert.size;\n }\n }\n }\n class GraphicsDiagnostics {\n static clear() {\n GraphicsDiagnostics.DrawCallCount = 0;\n GraphicsDiagnostics.DrawnImagesCount = 0;\n }\n }\n GraphicsDiagnostics.DrawCallCount = 0;\n GraphicsDiagnostics.DrawnImagesCount = 0;\n class LineRenderer {\n constructor(){\n this.type = \"ex.line\";\n this.priority = 0;\n this._maxLines = 10922;\n this._vertexIndex = 0;\n this._lineCount = 0;\n }\n initialize(gl, context) {\n this._gl = gl;\n this._context = context;\n this._shader = new Shader({\n gl: gl,\n vertexSource: line_vertex,\n fragmentSource: line_fragment\n });\n this._shader.compile();\n this._shader.use();\n this._shader.setUniformMatrix(\"u_matrix\", this._context.ortho);\n this._vertexBuffer = new VertexBuffer({\n gl: gl,\n size: 12 * this._maxLines,\n type: \"dynamic\"\n });\n this._layout = new VertexLayout({\n gl: gl,\n vertexBuffer: this._vertexBuffer,\n shader: this._shader,\n attributes: [\n [\n \"a_position\",\n 2\n ],\n [\n \"a_color\",\n 4\n ]\n ]\n });\n }\n draw(start, end, color) {\n // Force a render if the batch is full\n if (this._isFull()) this.flush();\n this._lineCount++;\n const transform = this._context.getTransform();\n const finalStart = transform.multiply(start);\n const finalEnd = transform.multiply(end);\n const vertexBuffer = this._vertexBuffer.bufferData;\n // Start\n vertexBuffer[this._vertexIndex++] = finalStart.x;\n vertexBuffer[this._vertexIndex++] = finalStart.y;\n vertexBuffer[this._vertexIndex++] = color.r / 255;\n vertexBuffer[this._vertexIndex++] = color.g / 255;\n vertexBuffer[this._vertexIndex++] = color.b / 255;\n vertexBuffer[this._vertexIndex++] = color.a;\n // End\n vertexBuffer[this._vertexIndex++] = finalEnd.x;\n vertexBuffer[this._vertexIndex++] = finalEnd.y;\n vertexBuffer[this._vertexIndex++] = color.r / 255;\n vertexBuffer[this._vertexIndex++] = color.g / 255;\n vertexBuffer[this._vertexIndex++] = color.b / 255;\n vertexBuffer[this._vertexIndex++] = color.a;\n }\n _isFull() {\n if (this._lineCount >= this._maxLines) return true;\n return false;\n }\n hasPendingDraws() {\n return this._lineCount !== 0;\n }\n flush() {\n // nothing to draw early exit\n if (this._lineCount === 0) return;\n const gl = this._gl;\n this._shader.use();\n this._layout.use(true);\n this._shader.setUniformMatrix(\"u_matrix\", this._context.ortho);\n gl.drawArrays(gl.LINES, 0, this._lineCount * 2); // 2 verts per line\n GraphicsDiagnostics.DrawnImagesCount += this._lineCount;\n GraphicsDiagnostics.DrawCallCount++;\n // reset\n this._vertexIndex = 0;\n this._lineCount = 0;\n }\n }\n /* harmony default export */ const point_vertex = \"#version 300 es\\r\\nin vec2 a_position;\\r\\nin vec4 a_color;\\r\\nin float a_size;\\r\\nout lowp vec4 v_color;\\r\\nuniform mat4 u_matrix;\\r\\n\\r\\nvoid main() {\\r\\n gl_Position = u_matrix * vec4(a_position, 0.0, 1.0);\\r\\n gl_PointSize = a_size * 2.0;\\r\\n v_color = a_color;\\r\\n}\";\n /* harmony default export */ const point_fragment = '#version 300 es\\r\\n\\r\\nprecision mediump float;\\r\\nin lowp vec4 v_color;\\r\\n\\r\\nout vec4 fragColor;\\r\\n\\r\\nvoid main() {\\r\\n float r = 0.0, delta = 0.0, alpha = 1.0;\\r\\n vec2 cxy = 2.0 * gl_PointCoord - 1.0;\\r\\n r = dot(cxy, cxy);\\r\\n\\r\\n delta = fwidth(r);\\r\\n alpha = 1.0 - smoothstep(1.0 - delta, 1.0 + delta, r);\\r\\n // \"premultiply\" the color by alpha\\r\\n vec4 color = v_color;\\r\\n color.a = color.a * alpha;\\r\\n color.rgb = color.rgb * color.a;\\r\\n fragColor = color;\\r\\n}';\n class PointRenderer {\n constructor(){\n this.type = \"ex.point\";\n this.priority = 0;\n this._maxPoints = 10922;\n this._pointCount = 0;\n this._vertexIndex = 0;\n }\n initialize(gl, context) {\n this._gl = gl;\n this._context = context;\n this._shader = new Shader({\n gl: gl,\n vertexSource: point_vertex,\n fragmentSource: point_fragment\n });\n this._shader.compile();\n this._shader.use();\n this._shader.setUniformMatrix(\"u_matrix\", this._context.ortho);\n this._buffer = new VertexBuffer({\n gl: gl,\n size: 7 * this._maxPoints,\n type: \"dynamic\"\n });\n this._layout = new VertexLayout({\n gl: gl,\n shader: this._shader,\n vertexBuffer: this._buffer,\n attributes: [\n [\n \"a_position\",\n 2\n ],\n [\n \"a_color\",\n 4\n ],\n [\n \"a_size\",\n 1\n ]\n ]\n });\n }\n draw(point, color, size) {\n // Force a render if the batch is full\n if (this._isFull()) this.flush();\n this._pointCount++;\n const transform = this._context.getTransform();\n const opacity = this._context.opacity;\n const snapToPixel = this._context.snapToPixel;\n const finalPoint = transform.multiply(point);\n if (snapToPixel) {\n finalPoint.x = ~~(finalPoint.x + pixelSnapEpsilon);\n finalPoint.y = ~~(finalPoint.y + pixelSnapEpsilon);\n }\n const vertexBuffer = this._buffer.bufferData;\n vertexBuffer[this._vertexIndex++] = finalPoint.x;\n vertexBuffer[this._vertexIndex++] = finalPoint.y;\n vertexBuffer[this._vertexIndex++] = color.r / 255;\n vertexBuffer[this._vertexIndex++] = color.g / 255;\n vertexBuffer[this._vertexIndex++] = color.b / 255;\n vertexBuffer[this._vertexIndex++] = color.a * opacity;\n vertexBuffer[this._vertexIndex++] = size * Math.max(transform.getScaleX(), transform.getScaleY());\n }\n _isFull() {\n if (this._pointCount >= this._maxPoints) return true;\n return false;\n }\n hasPendingDraws() {\n return this._pointCount !== 0;\n }\n flush() {\n // nothing to draw early exit\n if (this._pointCount === 0) return;\n const gl = this._gl;\n this._shader.use();\n this._layout.use(true);\n this._shader.setUniformMatrix(\"u_matrix\", this._context.ortho);\n gl.drawArrays(gl.POINTS, 0, this._pointCount);\n GraphicsDiagnostics.DrawnImagesCount += this._pointCount;\n GraphicsDiagnostics.DrawCallCount++;\n this._pointCount = 0;\n this._vertexIndex = 0;\n }\n }\n /* harmony default export */ const screen_vertex = \"#version 300 es\\r\\nin vec2 a_position;\\r\\n\\r\\nin vec2 a_texcoord;\\r\\nout vec2 v_texcoord;\\r\\n\\r\\nvoid main() {\\r\\n gl_Position = vec4(a_position, 0.0, 1.0);\\r\\n\\r\\n // Pass the texcoord to the fragment shader.\\r\\n v_texcoord = a_texcoord;\\r\\n}\";\n /* harmony default export */ const screen_fragment = \"#version 300 es\\r\\nprecision mediump float;\\r\\n\\r\\n// Passed in from the vertex shader.\\r\\nin vec2 v_texcoord;\\r\\n\\r\\n// The texture.\\r\\nuniform sampler2D u_texture;\\r\\n\\r\\nout vec4 fragColor;\\r\\n\\r\\nvoid main() {\\r\\n fragColor = texture(u_texture, v_texcoord);\\r\\n}\";\n /**\r\n * This is responsible for painting the entire screen during the render passes\r\n */ class ScreenPassPainter {\n constructor(gl){\n this._gl = gl;\n this._shader = new Shader({\n gl: gl,\n vertexSource: screen_vertex,\n fragmentSource: screen_fragment\n });\n this._shader.compile();\n // Setup memory layout\n this._buffer = new VertexBuffer({\n gl: gl,\n type: \"static\",\n // clip space quad + uv since we don't need a camera\n data: new Float32Array([\n -1,\n -1,\n 0,\n 0,\n -1,\n 1,\n 0,\n 1,\n 1,\n -1,\n 1,\n 0,\n 1,\n -1,\n 1,\n 0,\n -1,\n 1,\n 0,\n 1,\n 1,\n 1,\n 1,\n 1\n ])\n });\n this._layout = new VertexLayout({\n gl: gl,\n shader: this._shader,\n vertexBuffer: this._buffer,\n attributes: [\n [\n \"a_position\",\n 2\n ],\n [\n \"a_texcoord\",\n 2\n ]\n ]\n });\n this._buffer.upload();\n }\n renderWithPostProcessor(postprocessor) {\n const gl = this._gl;\n postprocessor.getShader().use();\n postprocessor.getLayout().use();\n gl.drawArrays(gl.TRIANGLES, 0, 6);\n }\n renderToScreen() {\n const gl = this._gl;\n this._shader.use();\n this._layout.use();\n gl.drawArrays(gl.TRIANGLES, 0, 6);\n }\n }\n /**\r\n * Helper that defines and index buffer for quad geometry\r\n *\r\n * Index buffers allow you to save space in vertex buffers when you share vertices in geometry\r\n * it is almost always worth it in terms of performance to use an index buffer.\r\n */ class QuadIndexBuffer {\n /**\r\n * @param gl WebGL2RenderingContext this layout will be attached to, these cannot be reused across contexts.\r\n * @param numberOfQuads Specify the max number of quads you want to draw\r\n * @param useUint16 Optionally force a uint16 buffer\r\n */ constructor(gl, numberOfQuads, useUint16){\n this._logger = Logger.getInstance();\n this._gl = gl;\n this.buffer = gl.createBuffer();\n gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.buffer);\n const totalVertices = numberOfQuads * 6;\n if (!useUint16) this.bufferData = new Uint32Array(totalVertices);\n else {\n // fall back to using gl.UNSIGNED_SHORT or tell the user they are out of luck\n const maxUint16 = 65535;\n const maxUint16Index = Math.floor((maxUint16 - 1) / 4); // max quads\n this.bufferGlType = gl.UNSIGNED_SHORT;\n this.bufferData = new Uint16Array(totalVertices);\n // TODO Should we error if this happens?? maybe not might crash mid game\n if (numberOfQuads > maxUint16Index) this._logger.warn(`Total quads exceeds hardware index buffer limit (uint16), max(${maxUint16Index}) requested quads(${numberOfQuads})`);\n }\n let currentQuad = 0;\n for(let i = 0; i < totalVertices; i += 6){\n // first triangle\n this.bufferData[i + 0] = currentQuad + 0;\n this.bufferData[i + 1] = currentQuad + 1;\n this.bufferData[i + 2] = currentQuad + 2;\n // second triangle\n this.bufferData[i + 3] = currentQuad + 2;\n this.bufferData[i + 4] = currentQuad + 1;\n this.bufferData[i + 5] = currentQuad + 3;\n currentQuad += 4;\n }\n gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, this.bufferData, gl.STATIC_DRAW);\n }\n get size() {\n return this.bufferData.length;\n }\n /**\r\n * Upload data to the GPU\r\n */ upload() {\n const gl = this._gl;\n gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.buffer);\n gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, this.bufferData, gl.STATIC_DRAW);\n }\n /**\r\n * Bind this index buffer\r\n */ bind() {\n const gl = this._gl;\n gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.buffer);\n }\n }\n /* harmony default export */ const image_renderer_frag = \"#version 300 es\\r\\nprecision mediump float;\\r\\n\\r\\n// UV coord\\r\\nin vec2 v_texcoord;\\r\\n\\r\\n// Texture index\\r\\nin lowp float v_textureIndex;\\r\\n\\r\\n// Textures in the current draw\\r\\nuniform sampler2D u_textures[%%count%%];\\r\\n\\r\\n// Opacity\\r\\nin float v_opacity;\\r\\n\\r\\nin vec4 v_tint;\\r\\n\\r\\nout vec4 fragColor;\\r\\n\\r\\nvoid main() {\\r\\n // In order to support the most efficient sprite batching, we have multiple\\r\\n // textures loaded into the gpu (usually 8) this picker logic skips over textures\\r\\n // that do not apply to a particular sprite.\\r\\n\\r\\n vec4 color = vec4(1.0, 0, 0, 1.0);\\r\\n\\r\\n // GLSL is templated out to pick the right texture and set the vec4 color\\r\\n %%texture_picker%%\\r\\n\\r\\n color.rgb = color.rgb * v_opacity;\\r\\n color.a = color.a * v_opacity;\\r\\n fragColor = color * v_tint;\\r\\n}\";\n /* harmony default export */ const image_renderer_vert = \"#version 300 es\\r\\nin vec2 a_position;\\r\\n\\r\\n// Opacity \\r\\nin float a_opacity;\\r\\nout float v_opacity;\\r\\n\\r\\n// UV coordinate\\r\\nin vec2 a_texcoord;\\r\\nout vec2 v_texcoord;\\r\\n\\r\\n// Texture number\\r\\nin lowp float a_textureIndex;\\r\\nout lowp float v_textureIndex;\\r\\n\\r\\nin vec4 a_tint;\\r\\nout vec4 v_tint;\\r\\n\\r\\nuniform mat4 u_matrix;\\r\\n\\r\\nvoid main() {\\r\\n // Set the vertex position using the ortho transform matrix\\r\\n gl_Position = u_matrix * vec4(a_position, 0.0, 1.0);\\r\\n\\r\\n // Pass through the Opacity to the fragment shader\\r\\n v_opacity = a_opacity;\\r\\n // Pass through the UV coord to the fragment shader\\r\\n v_texcoord = a_texcoord;\\r\\n // Pass through the texture number to the fragment shader\\r\\n v_textureIndex = a_textureIndex;\\r\\n // Pass through the tint\\r\\n v_tint = a_tint;\\r\\n}\";\n class ImageRenderer {\n constructor(){\n this.type = \"ex.image\";\n this.priority = 0;\n this._maxImages = 10922; // max(uint16) / 6 verts\n this._maxTextures = 0;\n // Per flush vars\n this._imageCount = 0;\n this._textures = [];\n this._vertexIndex = 0;\n }\n initialize(gl, context) {\n this._gl = gl;\n this._context = context;\n // Transform shader source\n // FIXME: PIXEL 6 complains `ERROR: Expression too complex.` if we use it's reported max texture units, 125 seems to work for now...\n this._maxTextures = Math.min(gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS), 125);\n const transformedFrag = this._transformFragmentSource(image_renderer_frag, this._maxTextures);\n // Compile shader\n this._shader = new Shader({\n gl: gl,\n fragmentSource: transformedFrag,\n vertexSource: image_renderer_vert\n });\n this._shader.compile();\n // setup uniforms\n this._shader.use();\n this._shader.setUniformMatrix(\"u_matrix\", context.ortho);\n // Initialize texture slots to [0, 1, 2, 3, 4, .... maxGPUTextures]\n this._shader.setUniformIntArray(\"u_textures\", [\n ...Array(this._maxTextures)\n ].map((_, i)=>i));\n // Setup memory layout\n this._buffer = new VertexBuffer({\n gl: gl,\n size: 40 * this._maxImages,\n type: \"dynamic\"\n });\n this._layout = new VertexLayout({\n gl: gl,\n shader: this._shader,\n vertexBuffer: this._buffer,\n attributes: [\n [\n \"a_position\",\n 2\n ],\n [\n \"a_opacity\",\n 1\n ],\n [\n \"a_texcoord\",\n 2\n ],\n [\n \"a_textureIndex\",\n 1\n ],\n [\n \"a_tint\",\n 4\n ]\n ]\n });\n // Setup index buffer\n this._quads = new QuadIndexBuffer(gl, this._maxImages, true);\n }\n _transformFragmentSource(source, maxTextures) {\n let newSource = source.replace(\"%%count%%\", maxTextures.toString());\n let texturePickerBuilder = \"\";\n for(let i = 0; i < maxTextures; i++){\n if (i === 0) texturePickerBuilder += `if (v_textureIndex <= ${i}.5) {\\n`;\n else texturePickerBuilder += ` else if (v_textureIndex <= ${i}.5) {\\n`;\n texturePickerBuilder += ` color = texture(u_textures[${i}], v_texcoord);\\n`;\n texturePickerBuilder += ` }\\n`;\n }\n newSource = newSource.replace(\"%%texture_picker%%\", texturePickerBuilder);\n return newSource;\n }\n _addImageAsTexture(image) {\n const maybeFiltering = image.getAttribute(\"filtering\");\n let filtering = null;\n if (maybeFiltering === ImageFiltering.Blended || maybeFiltering === ImageFiltering.Pixel) filtering = maybeFiltering;\n const force = image.getAttribute(\"forceUpload\") === \"true\" ? true : false;\n const texture = this._context.textureLoader.load(image, filtering, force);\n // remove force attribute after upload\n image.removeAttribute(\"forceUpload\");\n if (this._textures.indexOf(texture) === -1) this._textures.push(texture);\n }\n _bindTextures(gl) {\n // Bind textures in the correct order\n for(let i = 0; i < this._maxTextures; i++){\n gl.activeTexture(gl.TEXTURE0 + i);\n gl.bindTexture(gl.TEXTURE_2D, this._textures[i] || this._textures[0]);\n }\n }\n _getTextureIdForImage(image) {\n if (image) {\n const maybeTexture = this._context.textureLoader.get(image);\n return this._textures.indexOf(maybeTexture);\n }\n return -1;\n }\n _isFull() {\n if (this._imageCount >= this._maxImages) return true;\n if (this._textures.length >= this._maxTextures) return true;\n return false;\n }\n draw(image, sx, sy, swidth, sheight, dx, dy, dwidth, dheight) {\n var _a, _b, _c, _d;\n // Force a render if the batch is full\n if (this._isFull()) this.flush();\n this._imageCount++;\n // This creates and uploads the texture if not already done\n this._addImageAsTexture(image);\n let width = (image === null || image === void 0 ? void 0 : image.width) || swidth || 0;\n let height = (image === null || image === void 0 ? void 0 : image.height) || sheight || 0;\n let view = [\n 0,\n 0,\n (_a = swidth !== null && swidth !== void 0 ? swidth : image === null || image === void 0 ? void 0 : image.width) !== null && _a !== void 0 ? _a : 0,\n (_b = sheight !== null && sheight !== void 0 ? sheight : image === null || image === void 0 ? void 0 : image.height) !== null && _b !== void 0 ? _b : 0\n ];\n let dest = [\n sx !== null && sx !== void 0 ? sx : 1,\n sy !== null && sy !== void 0 ? sy : 1\n ];\n // If destination is specified, update view and dest\n if (dx !== undefined && dy !== undefined && dwidth !== undefined && dheight !== undefined) {\n view = [\n sx !== null && sx !== void 0 ? sx : 1,\n sy !== null && sy !== void 0 ? sy : 1,\n (_c = swidth !== null && swidth !== void 0 ? swidth : image === null || image === void 0 ? void 0 : image.width) !== null && _c !== void 0 ? _c : 0,\n (_d = sheight !== null && sheight !== void 0 ? sheight : image === null || image === void 0 ? void 0 : image.height) !== null && _d !== void 0 ? _d : 0\n ];\n dest = [\n dx,\n dy\n ];\n width = dwidth;\n height = dheight;\n }\n sx = view[0];\n sy = view[1];\n const sw = view[2];\n const sh = view[3];\n // transform based on current context\n const transform = this._context.getTransform();\n const opacity = this._context.opacity;\n const snapToPixel = this._context.snapToPixel;\n let topLeft = vec(dest[0], dest[1]);\n let topRight = vec(dest[0] + width, dest[1]);\n let bottomLeft = vec(dest[0], dest[1] + height);\n let bottomRight = vec(dest[0] + width, dest[1] + height);\n topLeft = transform.multiply(topLeft);\n topRight = transform.multiply(topRight);\n bottomLeft = transform.multiply(bottomLeft);\n bottomRight = transform.multiply(bottomRight);\n if (snapToPixel) {\n topLeft.x = ~~(topLeft.x + pixelSnapEpsilon);\n topLeft.y = ~~(topLeft.y + pixelSnapEpsilon);\n topRight.x = ~~(topRight.x + pixelSnapEpsilon);\n topRight.y = ~~(topRight.y + pixelSnapEpsilon);\n bottomLeft.x = ~~(bottomLeft.x + pixelSnapEpsilon);\n bottomLeft.y = ~~(bottomLeft.y + pixelSnapEpsilon);\n bottomRight.x = ~~(bottomRight.x + pixelSnapEpsilon);\n bottomRight.y = ~~(bottomRight.y + pixelSnapEpsilon);\n }\n const tint = this._context.tint;\n const textureId = this._getTextureIdForImage(image);\n const imageWidth = image.width || width;\n const imageHeight = image.height || height;\n const uvx0 = sx / imageWidth;\n const uvy0 = sy / imageHeight;\n const uvx1 = (sx + sw - 0.01) / imageWidth;\n const uvy1 = (sy + sh - 0.01) / imageHeight;\n // update data\n const vertexBuffer = this._layout.vertexBuffer.bufferData;\n // (0, 0) - 0\n vertexBuffer[this._vertexIndex++] = topLeft.x;\n vertexBuffer[this._vertexIndex++] = topLeft.y;\n vertexBuffer[this._vertexIndex++] = opacity;\n vertexBuffer[this._vertexIndex++] = uvx0;\n vertexBuffer[this._vertexIndex++] = uvy0;\n vertexBuffer[this._vertexIndex++] = textureId;\n vertexBuffer[this._vertexIndex++] = tint.r / 255;\n vertexBuffer[this._vertexIndex++] = tint.g / 255;\n vertexBuffer[this._vertexIndex++] = tint.b / 255;\n vertexBuffer[this._vertexIndex++] = tint.a;\n // (0, 1) - 1\n vertexBuffer[this._vertexIndex++] = bottomLeft.x;\n vertexBuffer[this._vertexIndex++] = bottomLeft.y;\n vertexBuffer[this._vertexIndex++] = opacity;\n vertexBuffer[this._vertexIndex++] = uvx0;\n vertexBuffer[this._vertexIndex++] = uvy1;\n vertexBuffer[this._vertexIndex++] = textureId;\n vertexBuffer[this._vertexIndex++] = tint.r / 255;\n vertexBuffer[this._vertexIndex++] = tint.g / 255;\n vertexBuffer[this._vertexIndex++] = tint.b / 255;\n vertexBuffer[this._vertexIndex++] = tint.a;\n // (1, 0) - 2\n vertexBuffer[this._vertexIndex++] = topRight.x;\n vertexBuffer[this._vertexIndex++] = topRight.y;\n vertexBuffer[this._vertexIndex++] = opacity;\n vertexBuffer[this._vertexIndex++] = uvx1;\n vertexBuffer[this._vertexIndex++] = uvy0;\n vertexBuffer[this._vertexIndex++] = textureId;\n vertexBuffer[this._vertexIndex++] = tint.r / 255;\n vertexBuffer[this._vertexIndex++] = tint.g / 255;\n vertexBuffer[this._vertexIndex++] = tint.b / 255;\n vertexBuffer[this._vertexIndex++] = tint.a;\n // (1, 1) - 3\n vertexBuffer[this._vertexIndex++] = bottomRight.x;\n vertexBuffer[this._vertexIndex++] = bottomRight.y;\n vertexBuffer[this._vertexIndex++] = opacity;\n vertexBuffer[this._vertexIndex++] = uvx1;\n vertexBuffer[this._vertexIndex++] = uvy1;\n vertexBuffer[this._vertexIndex++] = textureId;\n vertexBuffer[this._vertexIndex++] = tint.r / 255;\n vertexBuffer[this._vertexIndex++] = tint.g / 255;\n vertexBuffer[this._vertexIndex++] = tint.b / 255;\n vertexBuffer[this._vertexIndex++] = tint.a;\n }\n hasPendingDraws() {\n return this._imageCount !== 0;\n }\n flush() {\n // nothing to draw early exit\n if (this._imageCount === 0) return;\n const gl = this._gl;\n // Bind the shader\n this._shader.use();\n // Bind the memory layout and upload data\n this._layout.use(true, 40 * this._imageCount);\n // Update ortho matrix uniform\n this._shader.setUniformMatrix(\"u_matrix\", this._context.ortho);\n // Bind textures to\n this._bindTextures(gl);\n // Bind index buffer\n this._quads.bind();\n // Draw all the quads\n gl.drawElements(gl.TRIANGLES, this._imageCount * 6, this._quads.bufferGlType, 0);\n GraphicsDiagnostics.DrawnImagesCount += this._imageCount;\n GraphicsDiagnostics.DrawCallCount++;\n // Reset\n this._imageCount = 0;\n this._vertexIndex = 0;\n this._textures.length = 0;\n }\n }\n /* harmony default export */ const rectangle_renderer_frag = \"#version 300 es\\r\\n\\r\\nprecision mediump float;\\r\\n\\r\\n// UV coord\\r\\nin vec2 v_uv;\\r\\n\\r\\nin vec2 v_size; // in pixels\\r\\n\\r\\n// Color coord to blend with image\\r\\nin lowp vec4 v_color;\\r\\n\\r\\n// Stroke color if used\\r\\nin lowp vec4 v_strokeColor;\\r\\n\\r\\n// Stroke thickness if used\\r\\nin lowp float v_strokeThickness; // in pixels\\r\\n\\r\\n// Opacity\\r\\nin float v_opacity;\\r\\n\\r\\nout vec4 fragColor;\\r\\n\\r\\nvoid main() {\\r\\n // modified from https://stackoverflow.com/questions/59197671/glsl-rounded-rectangle-with-variable-border\\r\\n vec2 uv = v_uv;\\r\\n vec2 fragCoord = uv * v_size;\\r\\n float maxX = v_size.x - v_strokeThickness;\\r\\n float minX = v_strokeThickness;\\r\\n float maxY = v_size.y - v_strokeThickness;\\r\\n float minY = v_strokeThickness;\\r\\n\\r\\n if (fragCoord.x < maxX && fragCoord.x > minX &&\\r\\n fragCoord.y < maxY && fragCoord.y > minY) {\\r\\n fragColor = v_color;\\r\\n } else {\\r\\n fragColor = v_strokeColor;\\r\\n }\\r\\n fragColor.a *= v_opacity;\\r\\n fragColor.rgb *= fragColor.a;\\r\\n\\r\\n // vec2 v2CenteredPos = abs(fragCoord - v_size.xy / 2.0);\\r\\n // vec2 v2HalfShapeSizePx = v_size.xy/2.0 - v_strokeThickness/2.0;\\r\\n\\r\\n // float fHalfBorderDist = 0.0;\\r\\n // float fHalfBorderThickness = 0.0;\\r\\n\\r\\n // if (fragCoord.x > max(v_radius, v_strokeThickness) && \\r\\n // fragCoord.x < v_size.x - max(v_radius, v_strokeThickness))\\r\\n // {\\r\\n // fHalfBorderDist = v2CenteredPos.y - v2HalfShapeSizePx.y;\\r\\n // fHalfBorderThickness = v_strokeThickness / 2.0;\\r\\n // }\\r\\n // else if (fragCoord.y > max(v_radius, v_strokeThickness) && \\r\\n // fragCoord.y < v_size.y - max(v_radius, v_strokeThickness))\\r\\n // {\\r\\n // fHalfBorderDist = v2CenteredPos.x - v2HalfShapeSizePx.x;\\r\\n // fHalfBorderThickness = v_strokeThickness / 2.0;\\r\\n // }\\r\\n // else\\r\\n // {\\r\\n // vec2 edgeVec = max(vec2(0.0), v_radius - vec2(\\r\\n // uv.x > 0.5 ? v_size.x - fragCoord.x : fragCoord.x,\\r\\n // uv.y > 0.5 ? v_size.y - fragCoord.y : fragCoord.y));\\r\\n \\r\\n // float ellipse_ab = v_radius-v_strokeThickness;\\r\\n // vec2 ellipse_isect = (v_strokeThickness > v_radius || v_strokeThickness > v_radius) ? vec2(0.0) :\\r\\n // edgeVec.xy * ellipse_ab*ellipse_ab / length(ellipse_ab*edgeVec.yx); \\r\\n \\r\\n // fHalfBorderThickness = (v_radius - length(ellipse_isect)) / 2.0;\\r\\n // fHalfBorderDist = length(edgeVec) - (v_radius - fHalfBorderThickness);\\r\\n // }\\r\\n\\r\\n // vec4 v4FromColor = v_strokeColor;\\r\\n // v4FromColor.rgb *= v4FromColor.a;\\r\\n // vec4 v4ToColor = vec4(0.0); // background color is transparent\\r\\n // if (fHalfBorderDist < 0.0) {\\r\\n // v4ToColor = v_color;\\r\\n // v4ToColor.rgb *= v4ToColor.a;\\r\\n // }\\r\\n\\r\\n // float mixPct = abs(fHalfBorderDist) - fHalfBorderThickness;\\r\\n\\r\\n // vec4 finalColor = mix(v4FromColor, v4ToColor, mixPct);\\r\\n // gl_FragColor = finalColor;\\r\\n}\";\n /* harmony default export */ const rectangle_renderer_vert = \"#version 300 es\\r\\nin vec2 a_position;\\r\\n\\r\\n// UV coordinate\\r\\nin vec2 a_uv;\\r\\nout vec2 v_uv;\\r\\n\\r\\nin vec2 a_size;\\r\\nout vec2 v_size;\\r\\n\\r\\n// Opacity \\r\\nin float a_opacity;\\r\\nout float v_opacity;\\r\\n\\r\\nin vec4 a_color;\\r\\nout vec4 v_color;\\r\\n\\r\\nin vec4 a_strokeColor;\\r\\nout vec4 v_strokeColor;\\r\\n\\r\\nin float a_strokeThickness;\\r\\nout float v_strokeThickness;\\r\\n\\r\\nuniform mat4 u_matrix;\\r\\n\\r\\n\\r\\nvoid main() {\\r\\n // Set the vertex position using the ortho transform matrix\\r\\n gl_Position = u_matrix * vec4(a_position, 0.0, 1.0);\\r\\n\\r\\n // Pass through UV coords\\r\\n v_uv = a_uv;\\r\\n // Pass through size\\r\\n v_size = a_size;\\r\\n // Pass through the Opacity to the fragment shader\\r\\n v_opacity = a_opacity;\\r\\n // Pass through the color to the fragment shader\\r\\n v_color = a_color;\\r\\n // Pass through the stroke color to the fragment shader\\r\\n v_strokeColor = a_strokeColor;\\r\\n // Pass through the stroke thickenss to the fragment shader\\r\\n v_strokeThickness = a_strokeThickness;\\r\\n}\";\n class RectangleRenderer {\n constructor(){\n this.type = \"ex.rectangle\";\n this.priority = 0;\n this._maxRectangles = 10922; // max(uint16) / 6 verts\n this._rectangleCount = 0;\n this._vertexIndex = 0;\n }\n initialize(gl, context) {\n this._gl = gl;\n this._context = context;\n // https://stackoverflow.com/questions/59197671/glsl-rounded-rectangle-with-variable-border\n this._shader = new Shader({\n gl: gl,\n fragmentSource: rectangle_renderer_frag,\n vertexSource: rectangle_renderer_vert\n });\n this._shader.compile();\n // setup uniforms\n this._shader.use();\n this._shader.setUniformMatrix(\"u_matrix\", context.ortho);\n this._buffer = new VertexBuffer({\n gl: gl,\n size: 64 * this._maxRectangles,\n type: \"dynamic\"\n });\n this._layout = new VertexLayout({\n gl: gl,\n shader: this._shader,\n vertexBuffer: this._buffer,\n attributes: [\n [\n \"a_position\",\n 2\n ],\n [\n \"a_uv\",\n 2\n ],\n [\n \"a_size\",\n 2\n ],\n [\n \"a_opacity\",\n 1\n ],\n [\n \"a_color\",\n 4\n ],\n [\n \"a_strokeColor\",\n 4\n ],\n [\n \"a_strokeThickness\",\n 1\n ]\n ]\n });\n this._quads = new QuadIndexBuffer(gl, this._maxRectangles, true);\n }\n _isFull() {\n if (this._rectangleCount >= this._maxRectangles) return true;\n return false;\n }\n draw(...args) {\n if (args[0] instanceof Vector && args[1] instanceof Vector) this.drawLine.apply(this, args);\n else this.drawRectangle.apply(this, args);\n }\n drawLine(start, end, color, thickness = 1) {\n if (this._isFull()) this.flush();\n this._rectangleCount++;\n // transform based on current context\n const transform = this._context.getTransform();\n const opacity = this._context.opacity;\n const snapToPixel = this._context.snapToPixel;\n const dir = end.sub(start);\n const length = dir.size;\n const normal = dir.normalize().perpendicular();\n const halfThick = thickness / 2;\n /**\r\n * +---------------------^----------------------+\r\n * | | (normal) |\r\n * (startx, starty)------------------>(endx, endy)\r\n * | |\r\n * + -------------------------------------------+\r\n */ const startTop = transform.multiply(normal.scale(halfThick).add(start));\n const startBottom = transform.multiply(normal.scale(-halfThick).add(start));\n const endTop = transform.multiply(normal.scale(halfThick).add(end));\n const endBottom = transform.multiply(normal.scale(-halfThick).add(end));\n if (snapToPixel) {\n startTop.x = ~~(startTop.x + pixelSnapEpsilon);\n startTop.y = ~~(startTop.y + pixelSnapEpsilon);\n endTop.x = ~~(endTop.x + pixelSnapEpsilon);\n endTop.y = ~~(endTop.y + pixelSnapEpsilon);\n startBottom.x = ~~(startBottom.x + pixelSnapEpsilon);\n startBottom.y = ~~(startBottom.y + pixelSnapEpsilon);\n endBottom.x = ~~(endBottom.x + pixelSnapEpsilon);\n endBottom.y = ~~(endBottom.y + pixelSnapEpsilon);\n }\n // TODO uv could be static vertex buffer\n const uvx0 = 0;\n const uvy0 = 0;\n const uvx1 = 1;\n const uvy1 = 1;\n const stroke = Color.Transparent;\n const strokeThickness = 0;\n const width = 1;\n // update data\n const vertexBuffer = this._layout.vertexBuffer.bufferData;\n // (0, 0) - 0\n vertexBuffer[this._vertexIndex++] = startTop.x;\n vertexBuffer[this._vertexIndex++] = startTop.y;\n vertexBuffer[this._vertexIndex++] = uvx0;\n vertexBuffer[this._vertexIndex++] = uvy0;\n vertexBuffer[this._vertexIndex++] = length;\n vertexBuffer[this._vertexIndex++] = thickness;\n vertexBuffer[this._vertexIndex++] = opacity;\n vertexBuffer[this._vertexIndex++] = color.r / 255;\n vertexBuffer[this._vertexIndex++] = color.g / 255;\n vertexBuffer[this._vertexIndex++] = color.b / 255;\n vertexBuffer[this._vertexIndex++] = color.a;\n vertexBuffer[this._vertexIndex++] = stroke.r / 255;\n vertexBuffer[this._vertexIndex++] = stroke.g / 255;\n vertexBuffer[this._vertexIndex++] = stroke.b / 255;\n vertexBuffer[this._vertexIndex++] = stroke.a;\n vertexBuffer[this._vertexIndex++] = strokeThickness / width;\n // (0, 1) - 1\n vertexBuffer[this._vertexIndex++] = startBottom.x;\n vertexBuffer[this._vertexIndex++] = startBottom.y;\n vertexBuffer[this._vertexIndex++] = uvx0;\n vertexBuffer[this._vertexIndex++] = uvy1;\n vertexBuffer[this._vertexIndex++] = length;\n vertexBuffer[this._vertexIndex++] = thickness;\n vertexBuffer[this._vertexIndex++] = opacity;\n vertexBuffer[this._vertexIndex++] = color.r / 255;\n vertexBuffer[this._vertexIndex++] = color.g / 255;\n vertexBuffer[this._vertexIndex++] = color.b / 255;\n vertexBuffer[this._vertexIndex++] = color.a;\n vertexBuffer[this._vertexIndex++] = stroke.r / 255;\n vertexBuffer[this._vertexIndex++] = stroke.g / 255;\n vertexBuffer[this._vertexIndex++] = stroke.b / 255;\n vertexBuffer[this._vertexIndex++] = stroke.a;\n vertexBuffer[this._vertexIndex++] = strokeThickness / width;\n // (1, 0) - 2\n vertexBuffer[this._vertexIndex++] = endTop.x;\n vertexBuffer[this._vertexIndex++] = endTop.y;\n vertexBuffer[this._vertexIndex++] = uvx1;\n vertexBuffer[this._vertexIndex++] = uvy0;\n vertexBuffer[this._vertexIndex++] = length;\n vertexBuffer[this._vertexIndex++] = thickness;\n vertexBuffer[this._vertexIndex++] = opacity;\n vertexBuffer[this._vertexIndex++] = color.r / 255;\n vertexBuffer[this._vertexIndex++] = color.g / 255;\n vertexBuffer[this._vertexIndex++] = color.b / 255;\n vertexBuffer[this._vertexIndex++] = color.a;\n vertexBuffer[this._vertexIndex++] = stroke.r / 255;\n vertexBuffer[this._vertexIndex++] = stroke.g / 255;\n vertexBuffer[this._vertexIndex++] = stroke.b / 255;\n vertexBuffer[this._vertexIndex++] = stroke.a;\n vertexBuffer[this._vertexIndex++] = strokeThickness / width;\n // (1, 1) - 3\n vertexBuffer[this._vertexIndex++] = endBottom.x;\n vertexBuffer[this._vertexIndex++] = endBottom.y;\n vertexBuffer[this._vertexIndex++] = uvx1;\n vertexBuffer[this._vertexIndex++] = uvy1;\n vertexBuffer[this._vertexIndex++] = length;\n vertexBuffer[this._vertexIndex++] = thickness;\n vertexBuffer[this._vertexIndex++] = opacity;\n vertexBuffer[this._vertexIndex++] = color.r / 255;\n vertexBuffer[this._vertexIndex++] = color.g / 255;\n vertexBuffer[this._vertexIndex++] = color.b / 255;\n vertexBuffer[this._vertexIndex++] = color.a;\n vertexBuffer[this._vertexIndex++] = stroke.r / 255;\n vertexBuffer[this._vertexIndex++] = stroke.g / 255;\n vertexBuffer[this._vertexIndex++] = stroke.b / 255;\n vertexBuffer[this._vertexIndex++] = stroke.a;\n vertexBuffer[this._vertexIndex++] = strokeThickness / width;\n }\n drawRectangle(pos, width, height, color, stroke = Color.Transparent, strokeThickness = 0) {\n if (this._isFull()) this.flush();\n this._rectangleCount++;\n // transform based on current context\n const transform = this._context.getTransform();\n const opacity = this._context.opacity;\n const snapToPixel = this._context.snapToPixel;\n const topLeft = transform.multiply(pos.add(vec(0, 0)));\n const topRight = transform.multiply(pos.add(vec(width, 0)));\n const bottomRight = transform.multiply(pos.add(vec(width, height)));\n const bottomLeft = transform.multiply(pos.add(vec(0, height)));\n if (snapToPixel) {\n topLeft.x = ~~(topLeft.x + pixelSnapEpsilon);\n topLeft.y = ~~(topLeft.y + pixelSnapEpsilon);\n topRight.x = ~~(topRight.x + pixelSnapEpsilon);\n topRight.y = ~~(topRight.y + pixelSnapEpsilon);\n bottomLeft.x = ~~(bottomLeft.x + pixelSnapEpsilon);\n bottomLeft.y = ~~(bottomLeft.y + pixelSnapEpsilon);\n bottomRight.x = ~~(bottomRight.x + pixelSnapEpsilon);\n bottomRight.y = ~~(bottomRight.y + pixelSnapEpsilon);\n }\n // TODO uv could be static vertex buffer\n const uvx0 = 0;\n const uvy0 = 0;\n const uvx1 = 1;\n const uvy1 = 1;\n // update data\n const vertexBuffer = this._layout.vertexBuffer.bufferData;\n // (0, 0) - 0\n vertexBuffer[this._vertexIndex++] = topLeft.x;\n vertexBuffer[this._vertexIndex++] = topLeft.y;\n vertexBuffer[this._vertexIndex++] = uvx0;\n vertexBuffer[this._vertexIndex++] = uvy0;\n vertexBuffer[this._vertexIndex++] = width;\n vertexBuffer[this._vertexIndex++] = height;\n vertexBuffer[this._vertexIndex++] = opacity;\n vertexBuffer[this._vertexIndex++] = color.r / 255;\n vertexBuffer[this._vertexIndex++] = color.g / 255;\n vertexBuffer[this._vertexIndex++] = color.b / 255;\n vertexBuffer[this._vertexIndex++] = color.a;\n vertexBuffer[this._vertexIndex++] = stroke.r / 255;\n vertexBuffer[this._vertexIndex++] = stroke.g / 255;\n vertexBuffer[this._vertexIndex++] = stroke.b / 255;\n vertexBuffer[this._vertexIndex++] = stroke.a;\n vertexBuffer[this._vertexIndex++] = strokeThickness;\n // (0, 1) - 1\n vertexBuffer[this._vertexIndex++] = bottomLeft.x;\n vertexBuffer[this._vertexIndex++] = bottomLeft.y;\n vertexBuffer[this._vertexIndex++] = uvx0;\n vertexBuffer[this._vertexIndex++] = uvy1;\n vertexBuffer[this._vertexIndex++] = width;\n vertexBuffer[this._vertexIndex++] = height;\n vertexBuffer[this._vertexIndex++] = opacity;\n vertexBuffer[this._vertexIndex++] = color.r / 255;\n vertexBuffer[this._vertexIndex++] = color.g / 255;\n vertexBuffer[this._vertexIndex++] = color.b / 255;\n vertexBuffer[this._vertexIndex++] = color.a;\n vertexBuffer[this._vertexIndex++] = stroke.r / 255;\n vertexBuffer[this._vertexIndex++] = stroke.g / 255;\n vertexBuffer[this._vertexIndex++] = stroke.b / 255;\n vertexBuffer[this._vertexIndex++] = stroke.a;\n vertexBuffer[this._vertexIndex++] = strokeThickness;\n // (1, 0) - 2\n vertexBuffer[this._vertexIndex++] = topRight.x;\n vertexBuffer[this._vertexIndex++] = topRight.y;\n vertexBuffer[this._vertexIndex++] = uvx1;\n vertexBuffer[this._vertexIndex++] = uvy0;\n vertexBuffer[this._vertexIndex++] = width;\n vertexBuffer[this._vertexIndex++] = height;\n vertexBuffer[this._vertexIndex++] = opacity;\n vertexBuffer[this._vertexIndex++] = color.r / 255;\n vertexBuffer[this._vertexIndex++] = color.g / 255;\n vertexBuffer[this._vertexIndex++] = color.b / 255;\n vertexBuffer[this._vertexIndex++] = color.a;\n vertexBuffer[this._vertexIndex++] = stroke.r / 255;\n vertexBuffer[this._vertexIndex++] = stroke.g / 255;\n vertexBuffer[this._vertexIndex++] = stroke.b / 255;\n vertexBuffer[this._vertexIndex++] = stroke.a;\n vertexBuffer[this._vertexIndex++] = strokeThickness;\n // (1, 1) - 3\n vertexBuffer[this._vertexIndex++] = bottomRight.x;\n vertexBuffer[this._vertexIndex++] = bottomRight.y;\n vertexBuffer[this._vertexIndex++] = uvx1;\n vertexBuffer[this._vertexIndex++] = uvy1;\n vertexBuffer[this._vertexIndex++] = width;\n vertexBuffer[this._vertexIndex++] = height;\n vertexBuffer[this._vertexIndex++] = opacity;\n vertexBuffer[this._vertexIndex++] = color.r / 255;\n vertexBuffer[this._vertexIndex++] = color.g / 255;\n vertexBuffer[this._vertexIndex++] = color.b / 255;\n vertexBuffer[this._vertexIndex++] = color.a;\n vertexBuffer[this._vertexIndex++] = stroke.r / 255;\n vertexBuffer[this._vertexIndex++] = stroke.g / 255;\n vertexBuffer[this._vertexIndex++] = stroke.b / 255;\n vertexBuffer[this._vertexIndex++] = stroke.a;\n vertexBuffer[this._vertexIndex++] = strokeThickness;\n }\n hasPendingDraws() {\n return this._rectangleCount !== 0;\n }\n flush() {\n // nothing to draw early exit\n if (this._rectangleCount === 0) return;\n const gl = this._gl;\n // Bind the shader\n this._shader.use();\n // Bind the memory layout and upload data\n this._layout.use(true);\n // Update ortho matrix uniform\n this._shader.setUniformMatrix(\"u_matrix\", this._context.ortho);\n // Bind index buffer\n this._quads.bind();\n // Draw all the quads\n gl.drawElements(gl.TRIANGLES, this._rectangleCount * 6, this._quads.bufferGlType, 0);\n GraphicsDiagnostics.DrawnImagesCount += this._rectangleCount;\n GraphicsDiagnostics.DrawCallCount++;\n // Reset\n this._rectangleCount = 0;\n this._vertexIndex = 0;\n }\n }\n /* harmony default export */ const circle_renderer_frag = \"#version 300 es\\r\\nprecision highp float;\\r\\n\\r\\n// UV coord\\r\\nin vec2 v_uv;\\r\\n\\r\\n// Color coord to blend with image\\r\\nin lowp vec4 v_color;\\r\\n\\r\\n// Stroke color if used\\r\\nin lowp vec4 v_strokeColor;\\r\\n\\r\\n// Stroke thickness if used\\r\\nin lowp float v_strokeThickness;\\r\\n\\r\\n// Opacity\\r\\nin float v_opacity;\\r\\n\\r\\nout vec4 fragColor;\\r\\n\\r\\nvoid main() {\\r\\n // make (0, 0) the center the uv \\r\\n vec2 uv = v_uv * 2.0 - 1.0;\\r\\n\\r\\n vec4 color = v_color;\\r\\n vec4 strokeColor = v_strokeColor;\\r\\n\\r\\n // circle border is at radius 1.0 \\r\\n // dist is > 0 when inside the circle \\r\\n float d = length(uv);\\r\\n float dist = 1.0 - length(uv);\\r\\n\\r\\n // Fade based on fwidth\\r\\n float fade = fwidth(dot(uv, uv));\\r\\n\\r\\n // if dist is greater than 0 step to 1;\\r\\n // when we cross this 0 threshold add a smooth fade\\r\\n float fill = smoothstep(-fade/2.0, fade/2.0, dist);\\r\\n\\r\\n // if dist is greater than the stroke thickness step to 1\\r\\n float stroke = 1.0 - smoothstep(v_strokeThickness, v_strokeThickness + fade, dist);\\r\\n\\r\\n strokeColor.a *= fill * stroke;\\r\\n strokeColor.rgb *= strokeColor.a;\\r\\n\\r\\n color.a *= fill * (1.0 - stroke);\\r\\n color.rgb *= color.a;\\r\\n\\r\\n vec4 finalColor = mix(vec4(0.0), (color + strokeColor), fill);\\r\\n finalColor.rgb = finalColor.rgb * v_opacity;\\r\\n finalColor.a = finalColor.a * v_opacity;\\r\\n fragColor = finalColor;\\r\\n}\";\n /* harmony default export */ const circle_renderer_vert = \"#version 300 es\\r\\nin vec2 a_position;\\r\\n\\r\\n// UV coordinate\\r\\nin vec2 a_uv;\\r\\nout vec2 v_uv;\\r\\n\\r\\n// Opacity \\r\\nin float a_opacity;\\r\\nout float v_opacity;\\r\\n\\r\\nin vec4 a_color;\\r\\nout vec4 v_color;\\r\\n\\r\\nin vec4 a_strokeColor;\\r\\nout vec4 v_strokeColor;\\r\\n\\r\\nin float a_strokeThickness;\\r\\nout float v_strokeThickness;\\r\\n\\r\\nuniform mat4 u_matrix;\\r\\n\\r\\n\\r\\nvoid main() {\\r\\n // Set the vertex position using the ortho transform matrix\\r\\n gl_Position = u_matrix * vec4(a_position, 0.0, 1.0);\\r\\n\\r\\n // Pass through UV coords\\r\\n v_uv = a_uv;\\r\\n // Pass through the Opacity to the fragment shader\\r\\n v_opacity = a_opacity;\\r\\n // Pass through the color to the fragment shader\\r\\n v_color = a_color;\\r\\n // Pass through the stroke color to the fragment shader\\r\\n v_strokeColor = a_strokeColor;\\r\\n // Pass through the stroke thickenss to the fragment shader\\r\\n v_strokeThickness = a_strokeThickness;\\r\\n}\";\n class CircleRenderer {\n constructor(){\n this.type = \"ex.circle\";\n this.priority = 0;\n this._maxCircles = 10922; // max(uint16) / 6 verts\n this._circleCount = 0;\n this._vertexIndex = 0;\n }\n initialize(gl, context) {\n this._gl = gl;\n this._context = context;\n this._shader = new Shader({\n gl: gl,\n fragmentSource: circle_renderer_frag,\n vertexSource: circle_renderer_vert\n });\n this._shader.compile();\n // setup uniforms\n this._shader.use();\n this._shader.setUniformMatrix(\"u_matrix\", context.ortho);\n this._buffer = new VertexBuffer({\n gl: gl,\n size: 56 * this._maxCircles,\n type: \"dynamic\"\n });\n this._layout = new VertexLayout({\n gl: gl,\n shader: this._shader,\n vertexBuffer: this._buffer,\n attributes: [\n [\n \"a_position\",\n 2\n ],\n [\n \"a_uv\",\n 2\n ],\n [\n \"a_opacity\",\n 1\n ],\n [\n \"a_color\",\n 4\n ],\n [\n \"a_strokeColor\",\n 4\n ],\n [\n \"a_strokeThickness\",\n 1\n ]\n ]\n });\n this._quads = new QuadIndexBuffer(gl, this._maxCircles, true);\n }\n _isFull() {\n if (this._circleCount >= this._maxCircles) return true;\n return false;\n }\n draw(pos, radius, color, stroke = Color.Transparent, strokeThickness = 0) {\n if (this._isFull()) this.flush();\n this._circleCount++;\n // transform based on current context\n const transform = this._context.getTransform();\n const opacity = this._context.opacity;\n const snapToPixel = this._context.snapToPixel;\n const topLeft = transform.multiply(pos.add(vec(-radius, -radius)));\n const topRight = transform.multiply(pos.add(vec(radius, -radius)));\n const bottomRight = transform.multiply(pos.add(vec(radius, radius)));\n const bottomLeft = transform.multiply(pos.add(vec(-radius, radius)));\n if (snapToPixel) {\n topLeft.x = ~~(topLeft.x + pixelSnapEpsilon);\n topLeft.y = ~~(topLeft.y + pixelSnapEpsilon);\n topRight.x = ~~(topRight.x + pixelSnapEpsilon);\n topRight.y = ~~(topRight.y + pixelSnapEpsilon);\n bottomLeft.x = ~~(bottomLeft.x + pixelSnapEpsilon);\n bottomLeft.y = ~~(bottomLeft.y + pixelSnapEpsilon);\n bottomRight.x = ~~(bottomRight.x + pixelSnapEpsilon);\n bottomRight.y = ~~(bottomRight.y + pixelSnapEpsilon);\n }\n // TODO UV could be static vertex buffer\n const uvx0 = 0;\n const uvy0 = 0;\n const uvx1 = 1;\n const uvy1 = 1;\n // update data\n const vertexBuffer = this._layout.vertexBuffer.bufferData;\n // (0, 0) - 0\n vertexBuffer[this._vertexIndex++] = topLeft.x;\n vertexBuffer[this._vertexIndex++] = topLeft.y;\n vertexBuffer[this._vertexIndex++] = uvx0;\n vertexBuffer[this._vertexIndex++] = uvy0;\n vertexBuffer[this._vertexIndex++] = opacity;\n vertexBuffer[this._vertexIndex++] = color.r / 255;\n vertexBuffer[this._vertexIndex++] = color.g / 255;\n vertexBuffer[this._vertexIndex++] = color.b / 255;\n vertexBuffer[this._vertexIndex++] = color.a;\n vertexBuffer[this._vertexIndex++] = stroke.r / 255;\n vertexBuffer[this._vertexIndex++] = stroke.g / 255;\n vertexBuffer[this._vertexIndex++] = stroke.b / 255;\n vertexBuffer[this._vertexIndex++] = stroke.a;\n vertexBuffer[this._vertexIndex++] = strokeThickness / radius;\n // (0, 1) - 1\n vertexBuffer[this._vertexIndex++] = bottomLeft.x;\n vertexBuffer[this._vertexIndex++] = bottomLeft.y;\n vertexBuffer[this._vertexIndex++] = uvx0;\n vertexBuffer[this._vertexIndex++] = uvy1;\n vertexBuffer[this._vertexIndex++] = opacity;\n vertexBuffer[this._vertexIndex++] = color.r / 255;\n vertexBuffer[this._vertexIndex++] = color.g / 255;\n vertexBuffer[this._vertexIndex++] = color.b / 255;\n vertexBuffer[this._vertexIndex++] = color.a;\n vertexBuffer[this._vertexIndex++] = stroke.r / 255;\n vertexBuffer[this._vertexIndex++] = stroke.g / 255;\n vertexBuffer[this._vertexIndex++] = stroke.b / 255;\n vertexBuffer[this._vertexIndex++] = stroke.a;\n vertexBuffer[this._vertexIndex++] = strokeThickness / radius;\n // (1, 0) - 2\n vertexBuffer[this._vertexIndex++] = topRight.x;\n vertexBuffer[this._vertexIndex++] = topRight.y;\n vertexBuffer[this._vertexIndex++] = uvx1;\n vertexBuffer[this._vertexIndex++] = uvy0;\n vertexBuffer[this._vertexIndex++] = opacity;\n vertexBuffer[this._vertexIndex++] = color.r / 255;\n vertexBuffer[this._vertexIndex++] = color.g / 255;\n vertexBuffer[this._vertexIndex++] = color.b / 255;\n vertexBuffer[this._vertexIndex++] = color.a;\n vertexBuffer[this._vertexIndex++] = stroke.r / 255;\n vertexBuffer[this._vertexIndex++] = stroke.g / 255;\n vertexBuffer[this._vertexIndex++] = stroke.b / 255;\n vertexBuffer[this._vertexIndex++] = stroke.a;\n vertexBuffer[this._vertexIndex++] = strokeThickness / radius;\n // (1, 1) - 3\n vertexBuffer[this._vertexIndex++] = bottomRight.x;\n vertexBuffer[this._vertexIndex++] = bottomRight.y;\n vertexBuffer[this._vertexIndex++] = uvx1;\n vertexBuffer[this._vertexIndex++] = uvy1;\n vertexBuffer[this._vertexIndex++] = opacity;\n vertexBuffer[this._vertexIndex++] = color.r / 255;\n vertexBuffer[this._vertexIndex++] = color.g / 255;\n vertexBuffer[this._vertexIndex++] = color.b / 255;\n vertexBuffer[this._vertexIndex++] = color.a;\n vertexBuffer[this._vertexIndex++] = stroke.r / 255;\n vertexBuffer[this._vertexIndex++] = stroke.g / 255;\n vertexBuffer[this._vertexIndex++] = stroke.b / 255;\n vertexBuffer[this._vertexIndex++] = stroke.a;\n vertexBuffer[this._vertexIndex++] = strokeThickness / radius;\n }\n hasPendingDraws() {\n return this._circleCount !== 0;\n }\n flush() {\n // nothing to draw early exit\n if (this._circleCount === 0) return;\n const gl = this._gl;\n // Bind the shader\n this._shader.use();\n // Bind the memory layout and upload data\n this._layout.use(true);\n // Update ortho matrix uniform\n this._shader.setUniformMatrix(\"u_matrix\", this._context.ortho);\n // Bind index buffer\n this._quads.bind();\n // Draw all the quads\n gl.drawElements(gl.TRIANGLES, this._circleCount * 6, this._quads.bufferGlType, 0);\n GraphicsDiagnostics.DrawnImagesCount += this._circleCount;\n GraphicsDiagnostics.DrawCallCount++;\n // Reset\n this._circleCount = 0;\n this._vertexIndex = 0;\n }\n }\n class Pool {\n constructor(builder, recycler, maxObjects = 100){\n this.builder = builder;\n this.recycler = recycler;\n this.maxObjects = maxObjects;\n this.totalAllocations = 0;\n this.index = 0;\n this.objects = [];\n this.disableWarnings = false;\n this._logger = Logger.getInstance();\n }\n preallocate() {\n for(let i = 0; i < this.maxObjects; i++)this.objects[i] = this.builder();\n }\n /**\r\n * Use many instances out of the in the context and return all to the pool.\r\n *\r\n * By returning values out of the context they will be un-hooked from the pool and are free to be passed to consumers\r\n * @param context\r\n */ using(context) {\n const result = context(this);\n if (result) return this.done(...result);\n return this.done();\n }\n /**\r\n * Use a single instance out of th pool and immediately return it to the pool\r\n * @param context\r\n */ borrow(context) {\n const object = this.get();\n context(object);\n this.index--;\n }\n /**\r\n * Retrieve a value from the pool, will allocate a new instance if necessary or recycle from the pool\r\n * @param args\r\n */ get(...args) {\n if (this.index === this.maxObjects) {\n if (!this.disableWarnings) this._logger.warn(\"Max pooled objects reached, possible memory leak? Doubling\");\n this.maxObjects = this.maxObjects * 2;\n }\n if (this.objects[this.index]) // Pool has an available object already constructed\n return this.recycler(this.objects[this.index++], ...args);\n else {\n // New allocation\n this.totalAllocations++;\n const object = this.objects[this.index++] = this.builder(...args);\n return object;\n }\n }\n done(...objects) {\n // All objects in pool now considered \"free\"\n this.index = 0;\n for (const object of objects){\n const poolIndex = this.objects.indexOf(object);\n // Build a new object to take the pool place\n this.objects[poolIndex] = this.builder(); // TODO problematic 0-arg only support\n this.totalAllocations++;\n }\n return objects;\n }\n }\n class DrawCall {\n constructor(){\n this.z = 0;\n this.priority = 0;\n this.transform = AffineMatrix.identity();\n this.state = {\n z: 0,\n opacity: 1,\n tint: Color.White,\n material: null\n };\n }\n }\n const defaultVertexSource = `#version 300 es\r\nin vec2 a_position;\r\n\r\nin vec2 a_uv;\r\nout vec2 v_uv;\r\n\r\nuniform mat4 u_matrix;\r\nuniform mat4 u_transform;\r\n\r\nvoid main() {\r\n // Set the vertex position using the ortho & transform matrix\r\n gl_Position = u_matrix * u_transform * vec4(a_position, 0.0, 1.0);\r\n\r\n // Pass through the UV coord to the fragment shader\r\n v_uv = a_uv;\r\n}\r\n`;\n class Material {\n constructor(options){\n this._color = Color.Transparent;\n this._initialized = false;\n const { color: color, name: name, vertexSource: vertexSource, fragmentSource: fragmentSource } = options;\n this._name = name;\n this._vertexSource = vertexSource !== null && vertexSource !== void 0 ? vertexSource : defaultVertexSource;\n this._fragmentSource = fragmentSource;\n this._color = color !== null && color !== void 0 ? color : this._color;\n }\n initialize(_gl, _context) {\n if (this._initialized) return;\n this._shader = _context.createShader({\n vertexSource: this._vertexSource,\n fragmentSource: this._fragmentSource\n });\n this._shader.compile();\n this._initialized = true;\n }\n get name() {\n var _a;\n return (_a = this._name) !== null && _a !== void 0 ? _a : \"anonymous material\";\n }\n getShader() {\n return this._shader;\n }\n use() {\n if (this._initialized) {\n // bind the shader\n this._shader.use();\n // Apply standard uniforms\n this._shader.trySetUniformFloatColor(\"u_color\", this._color);\n } else throw Error(`Material ${this.name} not yet initialized, use the ExcaliburGraphicsContext.createMaterial() to work around this.`);\n }\n }\n class MaterialRenderer {\n constructor(){\n this.type = \"ex.material\";\n this.priority = 0;\n this._textures = [];\n }\n initialize(gl, context) {\n this._gl = gl;\n this._context = context;\n // Setup memory layout\n this._buffer = new VertexBuffer({\n gl: gl,\n size: 16,\n type: \"dynamic\"\n });\n // Setup a vertex layout/buffer to the material\n this._layout = new VertexLayout({\n gl: gl,\n vertexBuffer: this._buffer,\n attributes: [\n [\n \"a_position\",\n 2\n ],\n [\n \"a_uv\",\n 2\n ]\n ]\n });\n // Setup index buffer\n this._quads = new QuadIndexBuffer(gl, 1, true);\n }\n draw(image, sx, sy, swidth, sheight, dx, dy, dwidth, dheight) {\n var _a, _b, _c, _d;\n const gl = this._gl;\n // Extract context info\n const material = this._context.material;\n material.initialize(gl, this._context);\n const transform = this._context.getTransform();\n const opacity = this._context.opacity;\n // material shader\n const shader = material.getShader();\n // construct geometry, or hold on to it in the material?\n // geometry primitive for drawing rectangles?\n // update data\n const vertexBuffer = this._layout.vertexBuffer.bufferData;\n let vertexIndex = 0;\n let width = (image === null || image === void 0 ? void 0 : image.width) || swidth || 0;\n let height = (image === null || image === void 0 ? void 0 : image.height) || sheight || 0;\n let view = [\n 0,\n 0,\n (_a = swidth !== null && swidth !== void 0 ? swidth : image === null || image === void 0 ? void 0 : image.width) !== null && _a !== void 0 ? _a : 0,\n (_b = sheight !== null && sheight !== void 0 ? sheight : image === null || image === void 0 ? void 0 : image.height) !== null && _b !== void 0 ? _b : 0\n ];\n let dest = [\n sx !== null && sx !== void 0 ? sx : 1,\n sy !== null && sy !== void 0 ? sy : 1\n ];\n // If destination is specified, update view and dest\n if (dx !== undefined && dy !== undefined && dwidth !== undefined && dheight !== undefined) {\n view = [\n sx !== null && sx !== void 0 ? sx : 1,\n sy !== null && sy !== void 0 ? sy : 1,\n (_c = swidth !== null && swidth !== void 0 ? swidth : image === null || image === void 0 ? void 0 : image.width) !== null && _c !== void 0 ? _c : 0,\n (_d = sheight !== null && sheight !== void 0 ? sheight : image === null || image === void 0 ? void 0 : image.height) !== null && _d !== void 0 ? _d : 0\n ];\n dest = [\n dx,\n dy\n ];\n width = dwidth;\n height = dheight;\n }\n sx = view[0];\n sy = view[1];\n const sw = view[2];\n const sh = view[3];\n const topLeft = vec(dest[0], dest[1]);\n const topRight = vec(dest[0] + width, dest[1]);\n const bottomLeft = vec(dest[0], dest[1] + height);\n const bottomRight = vec(dest[0] + width, dest[1] + height);\n const imageWidth = image.width || width;\n const imageHeight = image.height || height;\n const uvx0 = sx / imageWidth;\n const uvy0 = sy / imageHeight;\n const uvx1 = (sx + sw - 0.01) / imageWidth;\n const uvy1 = (sy + sh - 0.01) / imageHeight;\n // (0, 0) - 0\n vertexBuffer[vertexIndex++] = topLeft.x;\n vertexBuffer[vertexIndex++] = topLeft.y;\n vertexBuffer[vertexIndex++] = uvx0;\n vertexBuffer[vertexIndex++] = uvy0;\n // (0, 1) - 1\n vertexBuffer[vertexIndex++] = bottomLeft.x;\n vertexBuffer[vertexIndex++] = bottomLeft.y;\n vertexBuffer[vertexIndex++] = uvx0;\n vertexBuffer[vertexIndex++] = uvy1;\n // (1, 0) - 2\n vertexBuffer[vertexIndex++] = topRight.x;\n vertexBuffer[vertexIndex++] = topRight.y;\n vertexBuffer[vertexIndex++] = uvx1;\n vertexBuffer[vertexIndex++] = uvy0;\n // (1, 1) - 3\n vertexBuffer[vertexIndex++] = bottomRight.x;\n vertexBuffer[vertexIndex++] = bottomRight.y;\n vertexBuffer[vertexIndex++] = uvx1;\n vertexBuffer[vertexIndex++] = uvy1;\n // This creates and uploads the texture if not already done\n const texture = this._addImageAsTexture(image);\n // apply material\n material.use();\n this._layout.shader = shader;\n // apply layout and geometry\n this._layout.use(true);\n // apply opacity\n shader.trySetUniformFloat(\"u_opacity\", opacity);\n // apply resolution\n shader.trySetUniformFloatVector(\"u_resolution\", vec(this._context.width, this._context.height));\n // apply size\n shader.trySetUniformFloatVector(\"u_size\", vec(sw, sh));\n // apply orthographic projection\n shader.trySetUniformMatrix(\"u_matrix\", this._context.ortho);\n // apply geometry transform\n shader.trySetUniformMatrix(\"u_transform\", transform.to4x4());\n // bind graphic image texture 'uniform sampler2D u_graphic;'\n gl.activeTexture(gl.TEXTURE0 + 0);\n gl.bindTexture(gl.TEXTURE_2D, texture);\n shader.trySetUniformInt(\"u_graphic\", 0);\n // bind quad index buffer\n this._quads.bind();\n // Draw a single quad\n gl.drawElements(gl.TRIANGLES, 6, this._quads.bufferGlType, 0);\n }\n _addImageAsTexture(image) {\n const maybeFiltering = image.getAttribute(\"filtering\");\n let filtering = null;\n if (maybeFiltering === ImageFiltering.Blended || maybeFiltering === ImageFiltering.Pixel) filtering = maybeFiltering;\n const force = image.getAttribute(\"forceUpload\") === \"true\" ? true : false;\n const texture = this._context.textureLoader.load(image, filtering, force);\n // remove force attribute after upload\n image.removeAttribute(\"forceUpload\");\n if (this._textures.indexOf(texture) === -1) this._textures.push(texture);\n return texture;\n }\n hasPendingDraws() {\n return false;\n }\n flush() {\n // flush does not do anything, material renderer renders immediately per draw\n }\n }\n // renderers\n const pixelSnapEpsilon = 0.0001;\n class ExcaliburGraphicsContextWebGLDebug {\n constructor(_webglCtx){\n this._webglCtx = _webglCtx;\n this._debugText = new DebugText();\n }\n /**\r\n * Draw a debugging rectangle to the context\r\n * @param x\r\n * @param y\r\n * @param width\r\n * @param height\r\n */ drawRect(x, y, width, height, rectOptions = {\n color: Color.Black\n }) {\n this.drawLine(vec(x, y), vec(x + width, y), {\n ...rectOptions\n });\n this.drawLine(vec(x + width, y), vec(x + width, y + height), {\n ...rectOptions\n });\n this.drawLine(vec(x + width, y + height), vec(x, y + height), {\n ...rectOptions\n });\n this.drawLine(vec(x, y + height), vec(x, y), {\n ...rectOptions\n });\n }\n /**\r\n * Draw a debugging line to the context\r\n * @param start\r\n * @param end\r\n * @param lineOptions\r\n */ drawLine(start, end, lineOptions = {\n color: Color.Black\n }) {\n this._webglCtx.draw(\"ex.line\", start, end, lineOptions.color);\n }\n /**\r\n * Draw a debugging point to the context\r\n * @param point\r\n * @param pointOptions\r\n */ drawPoint(point, pointOptions = {\n color: Color.Black,\n size: 5\n }) {\n this._webglCtx.draw(\"ex.point\", point, pointOptions.color, pointOptions.size);\n }\n drawText(text, pos) {\n this._debugText.write(this._webglCtx, text, pos);\n }\n }\n class ExcaliburGraphicsContextWebGL {\n get z() {\n return this._state.current.z;\n }\n set z(value) {\n this._state.current.z = value;\n }\n get opacity() {\n return this._state.current.opacity;\n }\n set opacity(value) {\n this._state.current.opacity = value;\n }\n get tint() {\n return this._state.current.tint;\n }\n set tint(color) {\n this._state.current.tint = color;\n }\n get width() {\n return this.__gl.canvas.width;\n }\n get height() {\n return this.__gl.canvas.height;\n }\n get ortho() {\n return this._ortho;\n }\n /**\r\n * Checks the underlying webgl implementation if the requested internal resolution is supported\r\n * @param dim\r\n */ checkIfResolutionSupported(dim) {\n // Slight hack based on this thread https://groups.google.com/g/webgl-dev-list/c/AHONvz3oQTo\n let supported = true;\n if (dim.width > 4096 || dim.height > 4096) supported = false;\n return supported;\n }\n constructor(options){\n this._logger = Logger.getInstance();\n this._renderers = new Map();\n this._isDrawLifecycle = false;\n this.useDrawSorting = true;\n this._drawCallPool = new Pool(()=>new DrawCall(), (instance)=>{\n instance.priority = 0;\n instance.z = 0;\n instance.renderer = undefined;\n instance.args = undefined;\n return instance;\n }, 4000);\n this._drawCalls = [];\n // Postprocessing is a tuple with 2 render targets, these are flip-flopped during the postprocessing process\n this._postProcessTargets = [];\n this._postprocessors = [];\n this._transform = new TransformStack();\n this._state = new StateStack();\n this.snapToPixel = false;\n this.smoothing = false;\n this.backgroundColor = Color.ExcaliburBlue;\n this._alreadyWarnedDrawLifecycle = false;\n this.debug = new ExcaliburGraphicsContextWebGLDebug(this);\n this._totalPostProcessorTime = 0;\n const { canvasElement: canvasElement, enableTransparency: enableTransparency, smoothing: smoothing, snapToPixel: snapToPixel, backgroundColor: backgroundColor, useDrawSorting: useDrawSorting } = options;\n this.__gl = canvasElement.getContext(\"webgl2\", {\n antialias: smoothing !== null && smoothing !== void 0 ? smoothing : this.smoothing,\n premultipliedAlpha: false,\n alpha: enableTransparency !== null && enableTransparency !== void 0 ? enableTransparency : true,\n depth: true,\n powerPreference: \"high-performance\"\n });\n if (!this.__gl) throw Error(\"Failed to retrieve webgl context from browser\");\n this.textureLoader = new TextureLoader(this.__gl);\n this.snapToPixel = snapToPixel !== null && snapToPixel !== void 0 ? snapToPixel : this.snapToPixel;\n this.smoothing = smoothing !== null && smoothing !== void 0 ? smoothing : this.smoothing;\n this.backgroundColor = backgroundColor !== null && backgroundColor !== void 0 ? backgroundColor : this.backgroundColor;\n this.useDrawSorting = useDrawSorting !== null && useDrawSorting !== void 0 ? useDrawSorting : this.useDrawSorting;\n this._drawCallPool.disableWarnings = true;\n this._drawCallPool.preallocate();\n this._init();\n }\n _init() {\n const gl = this.__gl;\n // Setup viewport and view matrix\n this._ortho = Matrix.ortho(0, gl.canvas.width, gl.canvas.height, 0, 400, -400);\n gl.viewport(0, 0, gl.canvas.width, gl.canvas.height);\n // Clear background\n gl.clearColor(this.backgroundColor.r / 255, this.backgroundColor.g / 255, this.backgroundColor.b / 255, this.backgroundColor.a);\n gl.clear(gl.COLOR_BUFFER_BIT);\n // Enable alpha blending\n // https://www.realtimerendering.com/blog/gpus-prefer-premultiplication/\n gl.enable(gl.BLEND);\n gl.blendEquation(gl.FUNC_ADD);\n gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA);\n gl.blendEquationSeparate(gl.FUNC_ADD, gl.FUNC_ADD);\n gl.blendFuncSeparate(gl.ONE, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA);\n // Setup builtin renderers\n this.register(new ImageRenderer());\n this.register(new MaterialRenderer());\n this.register(new RectangleRenderer());\n this.register(new CircleRenderer());\n this.register(new PointRenderer());\n this.register(new LineRenderer());\n this._screenRenderer = new ScreenPassPainter(gl);\n this._renderTarget = new RenderTarget({\n gl: gl,\n width: gl.canvas.width,\n height: gl.canvas.height\n });\n this._postProcessTargets = [\n new RenderTarget({\n gl: gl,\n width: gl.canvas.width,\n height: gl.canvas.height\n }),\n new RenderTarget({\n gl: gl,\n width: gl.canvas.width,\n height: gl.canvas.height\n })\n ];\n }\n register(renderer) {\n this._renderers.set(renderer.type, renderer);\n renderer.initialize(this.__gl, this);\n }\n get(rendererName) {\n return this._renderers.get(rendererName);\n }\n _isCurrentRenderer(renderer) {\n if (!this._currentRenderer || this._currentRenderer === renderer) return true;\n return false;\n }\n beginDrawLifecycle() {\n this._isDrawLifecycle = true;\n }\n endDrawLifecycle() {\n this._isDrawLifecycle = false;\n }\n draw(rendererName, ...args) {\n if (!this._isDrawLifecycle && !this._alreadyWarnedDrawLifecycle) {\n this._logger.warn(`Attempting to draw outside the the drawing lifecycle (preDraw/postDraw) is not supported and is a source of bugs/errors.\\n` + `If you want to do custom drawing, use Actor.graphics, or any onPreDraw or onPostDraw handler.`);\n this._alreadyWarnedDrawLifecycle = true;\n }\n const renderer = this._renderers.get(rendererName);\n if (renderer) {\n if (this.useDrawSorting) {\n const drawCall = this._drawCallPool.get();\n drawCall.z = this._state.current.z;\n drawCall.priority = renderer.priority;\n drawCall.renderer = rendererName;\n this.getTransform().clone(drawCall.transform);\n drawCall.state.z = this._state.current.z;\n drawCall.state.opacity = this._state.current.opacity;\n drawCall.state.tint = this._state.current.tint;\n drawCall.state.material = this._state.current.material;\n drawCall.args = args;\n this._drawCalls.push(drawCall);\n } else {\n // Set the current renderer if not defined\n if (!this._currentRenderer) this._currentRenderer = renderer;\n if (!this._isCurrentRenderer(renderer)) // switching graphics means we must flush the previous\n this._currentRenderer.flush();\n // If we are still using the same renderer we can add to the current batch\n renderer.draw(...args);\n this._currentRenderer = renderer;\n }\n } else throw Error(`No renderer with name ${rendererName} has been registered`);\n }\n resetTransform() {\n this._transform.current = AffineMatrix.identity();\n }\n updateViewport(resolution) {\n const gl = this.__gl;\n this._ortho = this._ortho = Matrix.ortho(0, resolution.width, resolution.height, 0, 400, -400);\n this._renderTarget.setResolution(gl.canvas.width, gl.canvas.height);\n this._postProcessTargets[0].setResolution(gl.canvas.width, gl.canvas.height);\n this._postProcessTargets[1].setResolution(gl.canvas.width, gl.canvas.height);\n }\n drawImage(image, sx, sy, swidth, sheight, dx, dy, dwidth, dheight) {\n if (swidth === 0 || sheight === 0) return; // zero dimension dest exit early\n else if (dwidth === 0 || dheight === 0) return; // zero dimension dest exit early\n else if (image.width === 0 || image.height === 0) return; // zero dimension source exit early\n if (!image) {\n Logger.getInstance().warn(\"Cannot draw a null or undefined image\");\n // tslint:disable-next-line: no-console\n if (console.trace) // tslint:disable-next-line: no-console\n console.trace();\n return;\n }\n if (this._state.current.material) this.draw(\"ex.material\", image, sx, sy, swidth, sheight, dx, dy, dwidth, dheight);\n else this.draw(\"ex.image\", image, sx, sy, swidth, sheight, dx, dy, dwidth, dheight);\n }\n drawLine(start, end, color, thickness = 1) {\n this.draw(\"ex.rectangle\", start, end, color, thickness);\n }\n drawRectangle(pos, width, height, color, stroke, strokeThickness) {\n this.draw(\"ex.rectangle\", pos, width, height, color, stroke, strokeThickness);\n }\n drawCircle(pos, radius, color, stroke, thickness) {\n this.draw(\"ex.circle\", pos, radius, color, stroke, thickness);\n }\n save() {\n this._transform.save();\n this._state.save();\n }\n restore() {\n this._transform.restore();\n this._state.restore();\n }\n translate(x, y) {\n this._transform.translate(this.snapToPixel ? ~~(x + pixelSnapEpsilon) : x, this.snapToPixel ? ~~(y + pixelSnapEpsilon) : y);\n }\n rotate(angle) {\n this._transform.rotate(angle);\n }\n scale(x, y) {\n this._transform.scale(x, y);\n }\n transform(matrix) {\n this._transform.current = matrix;\n }\n getTransform() {\n return this._transform.current;\n }\n multiply(m) {\n this._transform.current.multiply(m, this._transform.current);\n }\n addPostProcessor(postprocessor) {\n this._postprocessors.push(postprocessor);\n postprocessor.initialize(this.__gl);\n }\n removePostProcessor(postprocessor) {\n const index = this._postprocessors.indexOf(postprocessor);\n if (index !== -1) this._postprocessors.splice(index, 1);\n }\n clearPostProcessors() {\n this._postprocessors.length = 0;\n }\n updatePostProcessors(delta) {\n for (const postprocessor of this._postprocessors){\n const shader = postprocessor.getShader();\n shader.use();\n const uniforms = shader.getUniforms();\n this._totalPostProcessorTime += delta;\n if (uniforms.find((u)=>u.name === \"u_time_ms\")) shader.setUniformFloat(\"u_time_ms\", this._totalPostProcessorTime);\n if (uniforms.find((u)=>u.name === \"u_elapsed_ms\")) shader.setUniformFloat(\"u_elapsed_ms\", delta);\n if (uniforms.find((u)=>u.name === \"u_resolution\")) shader.setUniformFloatVector(\"u_resolution\", vec(this.width, this.height));\n if (postprocessor.onUpdate) postprocessor.onUpdate(delta);\n }\n }\n set material(material) {\n this._state.current.material = material;\n }\n get material() {\n return this._state.current.material;\n }\n /**\r\n * Creates and initializes the material which compiles the internal shader\r\n * @param options\r\n * @returns Material\r\n */ createMaterial(options) {\n const material = new Material(options);\n material.initialize(this.__gl, this);\n return material;\n }\n createShader(options) {\n const gl = this.__gl;\n const { vertexSource: vertexSource, fragmentSource: fragmentSource } = options;\n const shader = new Shader({\n gl: gl,\n vertexSource: vertexSource,\n fragmentSource: fragmentSource\n });\n shader.compile();\n return shader;\n }\n clear() {\n const gl = this.__gl;\n this._renderTarget.use();\n gl.clearColor(this.backgroundColor.r / 255, this.backgroundColor.g / 255, this.backgroundColor.b / 255, this.backgroundColor.a);\n // Clear the context with the newly set color. This is\n // the function call that actually does the drawing.\n gl.clear(gl.COLOR_BUFFER_BIT);\n }\n /**\r\n * Flushes all batched rendering to the screen\r\n */ flush() {\n const gl = this.__gl;\n // render target captures all draws and redirects to the render target\n this._renderTarget.use();\n if (this.useDrawSorting) {\n // sort draw calls\n // Find the original order of the first instance of the draw call\n const originalSort = new Map();\n for (const [name] of this._renderers){\n const firstIndex = this._drawCalls.findIndex((dc)=>dc.renderer === name);\n originalSort.set(name, firstIndex);\n }\n this._drawCalls.sort((a, b)=>{\n const zIndex = a.z - b.z;\n const originalSortOrder = originalSort.get(a.renderer) - originalSort.get(b.renderer);\n const priority = a.priority - b.priority;\n if (zIndex === 0) {\n if (priority === 0) return originalSortOrder; // use the original order to inform draw call packing to maximally preserve painter order\n return priority;\n }\n return zIndex;\n });\n const oldTransform = this._transform.current;\n const oldState = this._state.current;\n if (this._drawCalls.length) {\n let currentRendererName = this._drawCalls[0].renderer;\n let currentRenderer = this._renderers.get(currentRendererName);\n for(let i = 0; i < this._drawCalls.length; i++){\n // hydrate the state for renderers\n this._transform.current = this._drawCalls[i].transform;\n this._state.current = this._drawCalls[i].state;\n if (this._drawCalls[i].renderer !== currentRendererName) {\n // switching graphics renderer means we must flush the previous\n currentRenderer.flush();\n currentRendererName = this._drawCalls[i].renderer;\n currentRenderer = this._renderers.get(currentRendererName);\n }\n // If we are still using the same renderer we can add to the current batch\n currentRenderer.draw(...this._drawCalls[i].args);\n }\n if (currentRenderer.hasPendingDraws()) currentRenderer.flush();\n }\n // reset state\n this._transform.current = oldTransform;\n this._state.current = oldState;\n // reclaim draw calls\n this._drawCallPool.done();\n this._drawCalls.length = 0;\n } else {\n // This is the final flush at the moment to draw any leftover pending draw\n for (const renderer of this._renderers.values())if (renderer.hasPendingDraws()) renderer.flush();\n }\n this._renderTarget.disable();\n // post process step\n const source = this._renderTarget.toRenderSource();\n source.use();\n // flip flop render targets\n for(let i = 0; i < this._postprocessors.length; i++){\n this._postProcessTargets[i % 2].use();\n this._screenRenderer.renderWithPostProcessor(this._postprocessors[i]);\n this._postProcessTargets[i % 2].toRenderSource().use();\n }\n // passing null switches rendering back to the canvas\n gl.bindFramebuffer(gl.FRAMEBUFFER, null);\n this._screenRenderer.renderToScreen();\n }\n }\n const ExcaliburGraphicsContext2DCanvas_pixelSnapEpsilon = 0.0001;\n class ExcaliburGraphicsContext2DCanvasDebug {\n constructor(_ex){\n this._ex = _ex;\n this._debugText = new DebugText();\n }\n /**\r\n * Draw a debug rectangle to the context\r\n * @param x\r\n * @param y\r\n * @param width\r\n * @param height\r\n */ drawRect(x, y, width, height) {\n this._ex.__ctx.save();\n this._ex.__ctx.strokeStyle = \"red\";\n this._ex.__ctx.strokeRect(this._ex.snapToPixel ? ~~(x + ExcaliburGraphicsContext2DCanvas_pixelSnapEpsilon) : x, this._ex.snapToPixel ? ~~(y + ExcaliburGraphicsContext2DCanvas_pixelSnapEpsilon) : y, this._ex.snapToPixel ? ~~(width + ExcaliburGraphicsContext2DCanvas_pixelSnapEpsilon) : width, this._ex.snapToPixel ? ~~(height + ExcaliburGraphicsContext2DCanvas_pixelSnapEpsilon) : height);\n this._ex.__ctx.restore();\n }\n drawLine(start, end, lineOptions = {\n color: Color.Black\n }) {\n this._ex.__ctx.save();\n this._ex.__ctx.beginPath();\n this._ex.__ctx.strokeStyle = lineOptions.color.toString();\n this._ex.__ctx.moveTo(this._ex.snapToPixel ? ~~(start.x + ExcaliburGraphicsContext2DCanvas_pixelSnapEpsilon) : start.x, this._ex.snapToPixel ? ~~(start.y + ExcaliburGraphicsContext2DCanvas_pixelSnapEpsilon) : start.y);\n this._ex.__ctx.lineTo(this._ex.snapToPixel ? ~~(end.x + ExcaliburGraphicsContext2DCanvas_pixelSnapEpsilon) : end.x, this._ex.snapToPixel ? ~~(end.y + ExcaliburGraphicsContext2DCanvas_pixelSnapEpsilon) : end.y);\n this._ex.__ctx.lineWidth = 2;\n this._ex.__ctx.stroke();\n this._ex.__ctx.closePath();\n this._ex.__ctx.restore();\n }\n drawPoint(point, pointOptions = {\n color: Color.Black,\n size: 5\n }) {\n this._ex.__ctx.save();\n this._ex.__ctx.beginPath();\n this._ex.__ctx.fillStyle = pointOptions.color.toString();\n this._ex.__ctx.arc(this._ex.snapToPixel ? ~~(point.x + ExcaliburGraphicsContext2DCanvas_pixelSnapEpsilon) : point.x, this._ex.snapToPixel ? ~~(point.y + ExcaliburGraphicsContext2DCanvas_pixelSnapEpsilon) : point.y, pointOptions.size, 0, Math.PI * 2);\n this._ex.__ctx.fill();\n this._ex.__ctx.closePath();\n this._ex.__ctx.restore();\n }\n drawText(text, pos) {\n this._debugText.write(this._ex, text, pos);\n }\n }\n class ExcaliburGraphicsContext2DCanvas {\n get width() {\n return this.__ctx.canvas.width;\n }\n get height() {\n return this.__ctx.canvas.height;\n }\n get opacity() {\n return this._state.current.opacity;\n }\n set opacity(value) {\n this._state.current.opacity = value;\n }\n get tint() {\n return this._state.current.tint;\n }\n set tint(color) {\n this._state.current.tint = color;\n }\n get smoothing() {\n return this.__ctx.imageSmoothingEnabled;\n }\n set smoothing(value) {\n this.__ctx.imageSmoothingEnabled = value;\n }\n constructor(options){\n /**\r\n * Unused in Canvas implementation\r\n */ this.useDrawSorting = false;\n /**\r\n * Unused in Canvas implementation\r\n */ this.z = 0;\n this.backgroundColor = Color.ExcaliburBlue;\n this._state = new StateStack();\n this.snapToPixel = false;\n this.debug = new ExcaliburGraphicsContext2DCanvasDebug(this);\n const { canvasElement: canvasElement, enableTransparency: enableTransparency, snapToPixel: snapToPixel, smoothing: smoothing, backgroundColor: backgroundColor } = options;\n this.__ctx = canvasElement.getContext(\"2d\", {\n alpha: enableTransparency !== null && enableTransparency !== void 0 ? enableTransparency : true\n });\n this.backgroundColor = backgroundColor !== null && backgroundColor !== void 0 ? backgroundColor : this.backgroundColor;\n this.snapToPixel = snapToPixel !== null && snapToPixel !== void 0 ? snapToPixel : this.snapToPixel;\n this.smoothing = smoothing !== null && smoothing !== void 0 ? smoothing : this.smoothing;\n }\n resetTransform() {\n this.__ctx.resetTransform();\n }\n updateViewport(_resolution) {\n // pass\n }\n drawImage(image, sx, sy, swidth, sheight, dx, dy, dwidth, dheight) {\n if (swidth === 0 || sheight === 0) return; // zero dimension dest exit early\n else if (dwidth === 0 || dheight === 0) return; // zero dimension dest exit early\n else if (image.width === 0 || image.height === 0) return; // zero dimension source exit early\n this.__ctx.globalAlpha = this.opacity;\n const args = [\n image,\n sx,\n sy,\n swidth,\n sheight,\n dx,\n dy,\n dwidth,\n dheight\n ].filter((a)=>a !== undefined).map((a)=>typeof a === \"number\" && this.snapToPixel ? ~~a : a);\n this.__ctx.drawImage.apply(this.__ctx, args);\n GraphicsDiagnostics.DrawCallCount++;\n GraphicsDiagnostics.DrawnImagesCount = 1;\n }\n drawLine(start, end, color, thickness = 1) {\n this.__ctx.save();\n this.__ctx.beginPath();\n this.__ctx.strokeStyle = color.toString();\n this.__ctx.moveTo(this.snapToPixel ? ~~(start.x + ExcaliburGraphicsContext2DCanvas_pixelSnapEpsilon) : start.x, this.snapToPixel ? ~~(start.y + ExcaliburGraphicsContext2DCanvas_pixelSnapEpsilon) : start.y);\n this.__ctx.lineTo(this.snapToPixel ? ~~(end.x + ExcaliburGraphicsContext2DCanvas_pixelSnapEpsilon) : end.x, this.snapToPixel ? ~~(end.y + ExcaliburGraphicsContext2DCanvas_pixelSnapEpsilon) : end.y);\n this.__ctx.lineWidth = thickness;\n this.__ctx.stroke();\n this.__ctx.closePath();\n this.__ctx.restore();\n }\n drawRectangle(pos, width, height, color) {\n this.__ctx.save();\n this.__ctx.fillStyle = color.toString();\n this.__ctx.fillRect(this.snapToPixel ? ~~(pos.x + ExcaliburGraphicsContext2DCanvas_pixelSnapEpsilon) : pos.x, this.snapToPixel ? ~~(pos.y + ExcaliburGraphicsContext2DCanvas_pixelSnapEpsilon) : pos.y, this.snapToPixel ? ~~(width + ExcaliburGraphicsContext2DCanvas_pixelSnapEpsilon) : width, this.snapToPixel ? ~~(height + ExcaliburGraphicsContext2DCanvas_pixelSnapEpsilon) : height);\n this.__ctx.restore();\n }\n drawCircle(pos, radius, color, stroke, thickness) {\n this.__ctx.save();\n this.__ctx.beginPath();\n if (stroke) this.__ctx.strokeStyle = stroke.toString();\n if (thickness) this.__ctx.lineWidth = thickness;\n this.__ctx.fillStyle = color.toString();\n this.__ctx.arc(this.snapToPixel ? ~~(pos.x + ExcaliburGraphicsContext2DCanvas_pixelSnapEpsilon) : pos.x, this.snapToPixel ? ~~(pos.y + ExcaliburGraphicsContext2DCanvas_pixelSnapEpsilon) : pos.y, radius, 0, Math.PI * 2);\n this.__ctx.fill();\n if (stroke) this.__ctx.stroke();\n this.__ctx.closePath();\n this.__ctx.restore();\n }\n /**\r\n * Save the current state of the canvas to the stack (transforms and opacity)\r\n */ save() {\n this.__ctx.save();\n }\n /**\r\n * Restore the state of the canvas from the stack\r\n */ restore() {\n this.__ctx.restore();\n }\n /**\r\n * Translate the origin of the context by an x and y\r\n * @param x\r\n * @param y\r\n */ translate(x, y) {\n this.__ctx.translate(this.snapToPixel ? ~~(x + ExcaliburGraphicsContext2DCanvas_pixelSnapEpsilon) : x, this.snapToPixel ? ~~(y + ExcaliburGraphicsContext2DCanvas_pixelSnapEpsilon) : y);\n }\n /**\r\n * Rotate the context about the current origin\r\n */ rotate(angle) {\n this.__ctx.rotate(angle);\n }\n /**\r\n * Scale the context by an x and y factor\r\n * @param x\r\n * @param y\r\n */ scale(x, y) {\n this.__ctx.scale(x, y);\n }\n getTransform() {\n throw new Error(\"Not implemented\");\n }\n multiply(_m) {\n this.__ctx.setTransform(this.__ctx.getTransform().multiply(_m.toDOMMatrix()));\n }\n addPostProcessor(_postprocessor) {\n // pass\n }\n removePostProcessor(_postprocessor) {\n // pass\n }\n clearPostProcessors() {\n // pass\n }\n updatePostProcessors(_delta) {\n // pass\n }\n beginDrawLifecycle() {\n // pass\n }\n endDrawLifecycle() {\n // pass\n }\n set material(material) {\n this._state.current.material = material;\n }\n get material() {\n return this._state.current.material;\n }\n createMaterial(_options) {\n // pass\n return null;\n }\n clear() {\n // Clear frame\n this.__ctx.clearRect(0, 0, this.width, this.height);\n this.__ctx.fillStyle = this.backgroundColor.toString();\n this.__ctx.fillRect(0, 0, this.width, this.height);\n GraphicsDiagnostics.clear();\n }\n /**\r\n * Flushes the batched draw calls to the screen\r\n */ flush() {\n // pass\n }\n }\n /**\r\n * Enum representing the different display modes available to Excalibur.\r\n */ var DisplayMode;\n (function(DisplayMode) {\n /**\r\n * Default, use a specified resolution for the game. Like 800x600 pixels for example.\r\n */ DisplayMode[\"Fixed\"] = \"Fixed\";\n /**\r\n * Fit the aspect ratio given by the game resolution within the container at all times will fill any gaps with canvas.\r\n * The displayed area outside the aspect ratio is not guaranteed to be on the screen, only the [[Screen.contentArea]]\r\n * is guaranteed to be on screen.\r\n */ DisplayMode[\"FitContainerAndFill\"] = \"FitContainerAndFill\";\n /**\r\n * Fit the aspect ratio given by the game resolution the screen at all times will fill the screen.\r\n * This displayed area outside the aspect ratio is not guaranteed to be on the screen, only the [[Screen.contentArea]]\r\n * is guaranteed to be on screen.\r\n */ DisplayMode[\"FitScreenAndFill\"] = \"FitScreenAndFill\";\n /**\r\n * Fit the viewport to the parent element maintaining aspect ratio given by the game resolution, but zooms in to avoid the black bars\r\n * (letterbox) that would otherwise be present in [[FitContainer]].\r\n *\r\n * **warning** This will clip some drawable area from the user because of the zoom,\r\n * use [[Screen.contentArea]] to know the safe to draw area.\r\n */ DisplayMode[\"FitContainerAndZoom\"] = \"FitContainerAndZoom\";\n /**\r\n * Fit the viewport to the device screen maintaining aspect ratio given by the game resolution, but zooms in to avoid the black bars\r\n * (letterbox) that would otherwise be present in [[FitScreen]].\r\n *\r\n * **warning** This will clip some drawable area from the user because of the zoom,\r\n * use [[Screen.contentArea]] to know the safe to draw area.\r\n */ DisplayMode[\"FitScreenAndZoom\"] = \"FitScreenAndZoom\";\n /**\r\n * Fit to screen using as much space as possible while maintaining aspect ratio and resolution.\r\n * This is not the same as [[Screen.goFullScreen]] but behaves in a similar way maintaining aspect ratio.\r\n *\r\n * You may want to center your game here is an example\r\n * ```html\r\n * \r\n * \r\n *
\r\n * \r\n *
\r\n * \r\n * ```\r\n *\r\n * ```css\r\n * // css\r\n * main {\r\n * display: flex;\r\n * align-items: center;\r\n * justify-content: center;\r\n * height: 100%;\r\n * width: 100%;\r\n * }\r\n * ```\r\n */ DisplayMode[\"FitScreen\"] = \"FitScreen\";\n /**\r\n * Fill the entire screen's css width/height for the game resolution dynamically. This means the resolution of the game will\r\n * change dynamically as the window is resized. This is not the same as [[Screen.goFullScreen]]\r\n */ DisplayMode[\"FillScreen\"] = \"FillScreen\";\n /**\r\n * Fit to parent element width/height using as much space as possible while maintaining aspect ratio and resolution.\r\n */ DisplayMode[\"FitContainer\"] = \"FitContainer\";\n /**\r\n * Use the parent DOM container's css width/height for the game resolution dynamically\r\n */ DisplayMode[\"FillContainer\"] = \"FillContainer\";\n })(DisplayMode || (DisplayMode = {}));\n /**\r\n * Convenience class for quick resolutions\r\n * Mostly sourced from https://emulation.gametechwiki.com/index.php/Resolution\r\n */ class Resolution {\n /* istanbul ignore next */ static get SVGA() {\n return {\n width: 800,\n height: 600\n };\n }\n /* istanbul ignore next */ static get Standard() {\n return {\n width: 1920,\n height: 1080\n };\n }\n /* istanbul ignore next */ static get Atari2600() {\n return {\n width: 160,\n height: 192\n };\n }\n /* istanbul ignore next */ static get GameBoy() {\n return {\n width: 160,\n height: 144\n };\n }\n /* istanbul ignore next */ static get GameBoyAdvance() {\n return {\n width: 240,\n height: 160\n };\n }\n /* istanbul ignore next */ static get NintendoDS() {\n return {\n width: 256,\n height: 192\n };\n }\n /* istanbul ignore next */ static get NES() {\n return {\n width: 256,\n height: 224\n };\n }\n /* istanbul ignore next */ static get SNES() {\n return {\n width: 256,\n height: 244\n };\n }\n }\n /**\r\n * The Screen handles all aspects of interacting with the screen for Excalibur.\r\n */ class Screen {\n constructor(options){\n var _a, _b, _c;\n this._antialiasing = true;\n this._resolutionStack = [];\n this._viewportStack = [];\n this._pixelRatioOverride = null;\n this._isFullScreen = false;\n this._isDisposed = false;\n this._logger = Logger.getInstance();\n this._fullscreenChangeHandler = ()=>{\n this._isFullScreen = !this._isFullScreen;\n this._logger.debug(\"Fullscreen Change\", this._isFullScreen);\n };\n this._pixelRatioChangeHandler = ()=>{\n this._logger.debug(\"Pixel Ratio Change\", window.devicePixelRatio);\n this._listenForPixelRatio();\n this._devicePixelRatio = this._calculateDevicePixelRatio();\n this.applyResolutionAndViewport();\n };\n this._resizeHandler = ()=>{\n const parent = this.parent;\n this._logger.debug(\"View port resized\");\n this._setResolutionAndViewportByDisplayMode(parent);\n this.applyResolutionAndViewport();\n };\n // Asking the window.devicePixelRatio is expensive we do it once\n this._devicePixelRatio = this._calculateDevicePixelRatio();\n this._alreadyWarned = false;\n this._contentArea = new BoundingBox();\n this.viewport = options.viewport;\n this.resolution = (_a = options.resolution) !== null && _a !== void 0 ? _a : {\n ...this.viewport\n };\n this._contentResolution = this.resolution;\n this._displayMode = (_b = options.displayMode) !== null && _b !== void 0 ? _b : DisplayMode.Fixed;\n this._canvas = options.canvas;\n this.graphicsContext = options.context;\n this._antialiasing = (_c = options.antialiasing) !== null && _c !== void 0 ? _c : this._antialiasing;\n this._browser = options.browser;\n this._pixelRatioOverride = options.pixelRatio;\n this._applyDisplayMode();\n this._listenForPixelRatio();\n this._canvas.addEventListener(\"fullscreenchange\", this._fullscreenChangeHandler);\n this.applyResolutionAndViewport();\n }\n _listenForPixelRatio() {\n if (this._mediaQueryList && !this._mediaQueryList.addEventListener) // Safari <=13.1 workaround, remove any existing handlers\n this._mediaQueryList.removeListener(this._pixelRatioChangeHandler);\n this._mediaQueryList = this._browser.window.nativeComponent.matchMedia(`(resolution: ${window.devicePixelRatio}dppx)`);\n // Safari <=13.1 workaround\n if (this._mediaQueryList.addEventListener) this._mediaQueryList.addEventListener(\"change\", this._pixelRatioChangeHandler, {\n once: true\n });\n else this._mediaQueryList.addListener(this._pixelRatioChangeHandler);\n }\n dispose() {\n if (!this._isDisposed) {\n // Clean up handlers\n this._isDisposed = true;\n this._browser.window.off(\"resize\", this._resizeHandler);\n if (this._resizeObserver) this._resizeObserver.disconnect();\n this.parent.removeEventListener(\"resize\", this._resizeHandler);\n // Safari <=13.1 workaround\n if (this._mediaQueryList.removeEventListener) this._mediaQueryList.removeEventListener(\"change\", this._pixelRatioChangeHandler);\n else this._mediaQueryList.removeListener(this._pixelRatioChangeHandler);\n this._canvas.removeEventListener(\"fullscreenchange\", this._fullscreenChangeHandler);\n }\n }\n _calculateDevicePixelRatio() {\n if (window.devicePixelRatio < 1) return 1;\n const devicePixelRatio = window.devicePixelRatio || 1;\n return devicePixelRatio;\n }\n get pixelRatio() {\n if (this._pixelRatioOverride) return this._pixelRatioOverride;\n return this._devicePixelRatio;\n }\n get isHiDpi() {\n return this.pixelRatio !== 1;\n }\n get displayMode() {\n return this._displayMode;\n }\n get canvas() {\n return this._canvas;\n }\n get parent() {\n switch(this.displayMode){\n case DisplayMode.FillContainer:\n case DisplayMode.FitContainer:\n case DisplayMode.FitContainerAndFill:\n case DisplayMode.FitContainerAndZoom:\n return this.canvas.parentElement || document.body;\n default:\n return window;\n }\n }\n get resolution() {\n return this._resolution;\n }\n set resolution(resolution) {\n this._resolution = resolution;\n }\n get viewport() {\n if (this._viewport) return this._viewport;\n return this._resolution;\n }\n set viewport(viewport) {\n this._viewport = viewport;\n }\n get aspectRatio() {\n return this._resolution.width / this._resolution.height;\n }\n get scaledWidth() {\n return this._resolution.width * this.pixelRatio;\n }\n get scaledHeight() {\n return this._resolution.height * this.pixelRatio;\n }\n setCurrentCamera(camera) {\n this._camera = camera;\n }\n pushResolutionAndViewport() {\n this._resolutionStack.push(this.resolution);\n this._viewportStack.push(this.viewport);\n this.resolution = {\n ...this.resolution\n };\n this.viewport = {\n ...this.viewport\n };\n }\n peekViewport() {\n return this._viewportStack[this._viewportStack.length - 1];\n }\n peekResolution() {\n return this._resolutionStack[this._resolutionStack.length - 1];\n }\n popResolutionAndViewport() {\n this.resolution = this._resolutionStack.pop();\n this.viewport = this._viewportStack.pop();\n }\n applyResolutionAndViewport() {\n this._canvas.width = this.scaledWidth;\n this._canvas.height = this.scaledHeight;\n if (this.graphicsContext instanceof ExcaliburGraphicsContextWebGL) {\n const supported = this.graphicsContext.checkIfResolutionSupported({\n width: this.scaledWidth,\n height: this.scaledHeight\n });\n if (!supported && !this._alreadyWarned) {\n this._alreadyWarned = true; // warn once\n this._logger.warn(`The currently configured resolution (${this.resolution.width}x${this.resolution.height}) and pixel ratio (${this.pixelRatio})` + \" are too large for the platform WebGL implementation, this may work but cause WebGL rendering to behave oddly.\" + \" Try reducing the resolution or disabling Hi DPI scaling to avoid this\" + \" (read more here https://excaliburjs.com/docs/screens#understanding-viewport--resolution).\");\n }\n }\n if (this._antialiasing) this._canvas.style.imageRendering = \"auto\";\n else {\n this._canvas.style.imageRendering = \"pixelated\";\n // Fall back to 'crisp-edges' if 'pixelated' is not supported\n // Currently for firefox https://developer.mozilla.org/en-US/docs/Web/CSS/image-rendering\n if (this._canvas.style.imageRendering === \"\") this._canvas.style.imageRendering = \"crisp-edges\";\n }\n this._canvas.style.width = this.viewport.width + \"px\";\n this._canvas.style.height = this.viewport.height + \"px\";\n // After messing with the canvas width/height the graphics context is invalidated and needs to have some properties reset\n this.graphicsContext.updateViewport(this.resolution);\n this.graphicsContext.resetTransform();\n this.graphicsContext.smoothing = this._antialiasing;\n if (this.graphicsContext instanceof ExcaliburGraphicsContext2DCanvas) this.graphicsContext.scale(this.pixelRatio, this.pixelRatio);\n }\n get antialiasing() {\n return this._antialiasing;\n }\n set antialiasing(isSmooth) {\n this._antialiasing = isSmooth;\n this.graphicsContext.smoothing = this._antialiasing;\n }\n /**\r\n * Returns true if excalibur is fullscreen using the browser fullscreen api\r\n */ get isFullScreen() {\n return this._isFullScreen;\n }\n /**\r\n * Requests to go fullscreen using the browser fullscreen api, requires user interaction to be successful.\r\n * For example, wire this to a user click handler.\r\n *\r\n * Optionally specify a target element id to go fullscreen, by default the game canvas is used\r\n * @param elementId\r\n */ goFullScreen(elementId) {\n if (elementId) {\n const maybeElement = document.getElementById(elementId);\n if (maybeElement) return maybeElement.requestFullscreen();\n }\n return this._canvas.requestFullscreen();\n }\n /**\r\n * Requests to exit fullscreen using the browser fullscreen api\r\n */ exitFullScreen() {\n return document.exitFullscreen();\n }\n /**\r\n * Takes a coordinate in normal html page space, for example from a pointer move event, and translates it to\r\n * Excalibur screen space.\r\n *\r\n * Excalibur screen space starts at the top left (0, 0) corner of the viewport, and extends to the\r\n * bottom right corner (resolutionX, resolutionY)\r\n * @param point\r\n */ pageToScreenCoordinates(point) {\n let newX = point.x;\n let newY = point.y;\n if (!this._isFullScreen) {\n newX -= getPosition(this._canvas).x;\n newY -= getPosition(this._canvas).y;\n }\n // if fullscreen api on it centers with black bars\n // we need to adjust the screen to world coordinates in this case\n if (this._isFullScreen) {\n if (window.innerWidth / this.aspectRatio < window.innerHeight) {\n const screenHeight = window.innerWidth / this.aspectRatio;\n const screenMarginY = (window.innerHeight - screenHeight) / 2;\n newY = (newY - screenMarginY) / screenHeight * this.viewport.height;\n newX = newX / window.innerWidth * this.viewport.width;\n } else {\n const screenWidth = window.innerHeight * this.aspectRatio;\n const screenMarginX = (window.innerWidth - screenWidth) / 2;\n newX = (newX - screenMarginX) / screenWidth * this.viewport.width;\n newY = newY / window.innerHeight * this.viewport.height;\n }\n }\n newX = newX / this.viewport.width * this.resolution.width;\n newY = newY / this.viewport.height * this.resolution.height;\n return new Vector(newX, newY);\n }\n /**\r\n * Takes a coordinate in Excalibur screen space, and translates it to normal html page space. For example,\r\n * this is where html elements might live if you want to position them relative to Excalibur.\r\n *\r\n * Excalibur screen space starts at the top left (0, 0) corner of the viewport, and extends to the\r\n * bottom right corner (resolutionX, resolutionY)\r\n * @param point\r\n */ screenToPageCoordinates(point) {\n let newX = point.x;\n let newY = point.y;\n newX = newX / this.resolution.width * this.viewport.width;\n newY = newY / this.resolution.height * this.viewport.height;\n if (this._isFullScreen) {\n if (window.innerWidth / this.aspectRatio < window.innerHeight) {\n const screenHeight = window.innerWidth / this.aspectRatio;\n const screenMarginY = (window.innerHeight - screenHeight) / 2;\n newY = newY / this.viewport.height * screenHeight + screenMarginY;\n newX = newX / this.viewport.width * window.innerWidth;\n } else {\n const screenWidth = window.innerHeight * this.aspectRatio;\n const screenMarginX = (window.innerWidth - screenWidth) / 2;\n newX = newX / this.viewport.width * screenWidth + screenMarginX;\n newY = newY / this.viewport.height * window.innerHeight;\n }\n }\n if (!this._isFullScreen) {\n newX += getPosition(this._canvas).x;\n newY += getPosition(this._canvas).y;\n }\n return new Vector(newX, newY);\n }\n /**\r\n * Takes a coordinate in Excalibur screen space, and translates it to Excalibur world space.\r\n *\r\n * World space is where [[Entity|entities]] in Excalibur live by default [[CoordPlane.World]]\r\n * and extends infinitely out relative from the [[Camera]].\r\n * @param point Screen coordinate to convert\r\n */ screenToWorldCoordinates(point) {\n // the only difference between screen & world is the camera transform\n if (this._camera) return this._camera.inverse.multiply(point);\n return point.sub(vec(this.resolution.width / 2, this.resolution.height / 2));\n }\n /**\r\n * Takes a coordinate in Excalibur world space, and translates it to Excalibur screen space.\r\n *\r\n * Screen space is where [[ScreenElement|screen elements]] and [[Entity|entities]] with [[CoordPlane.Screen]] live.\r\n * @param point World coordinate to convert\r\n */ worldToScreenCoordinates(point) {\n if (this._camera) return this._camera.transform.multiply(point);\n return point.add(vec(this.resolution.width / 2, this.resolution.height / 2));\n }\n pageToWorldCoordinates(point) {\n const screen = this.pageToScreenCoordinates(point);\n return this.screenToWorldCoordinates(screen);\n }\n worldToPageCoordinates(point) {\n const screen = this.worldToScreenCoordinates(point);\n return this.screenToPageCoordinates(screen);\n }\n /**\r\n * Returns a BoundingBox of the top left corner of the screen\r\n * and the bottom right corner of the screen.\r\n *\r\n * World bounds are in world coordinates, useful for culling objects offscreen\r\n */ getWorldBounds() {\n const bounds = BoundingBox.fromDimension(this.resolution.width, this.resolution.height, Vector.Half).scale(vec(1 / this._camera.zoom, 1 / this._camera.zoom)).rotate(this._camera.rotation).translate(this._camera.pos);\n return bounds;\n }\n /**\r\n * The width of the game canvas in pixels (physical width component of the\r\n * resolution of the canvas element)\r\n */ get canvasWidth() {\n return this.canvas.width;\n }\n /**\r\n * Returns half width of the game canvas in pixels (half physical width component)\r\n */ get halfCanvasWidth() {\n return this.canvas.width / 2;\n }\n /**\r\n * The height of the game canvas in pixels, (physical height component of\r\n * the resolution of the canvas element)\r\n */ get canvasHeight() {\n return this.canvas.height;\n }\n /**\r\n * Returns half height of the game canvas in pixels (half physical height component)\r\n */ get halfCanvasHeight() {\n return this.canvas.height / 2;\n }\n /**\r\n * Returns the width of the engine's visible drawing surface in pixels including zoom and device pixel ratio.\r\n */ get drawWidth() {\n if (this._camera) return this.resolution.width / this._camera.zoom;\n return this.resolution.width;\n }\n /**\r\n * Returns half the width of the engine's visible drawing surface in pixels including zoom and device pixel ratio.\r\n */ get halfDrawWidth() {\n return this.drawWidth / 2;\n }\n /**\r\n * Returns the height of the engine's visible drawing surface in pixels including zoom and device pixel ratio.\r\n */ get drawHeight() {\n if (this._camera) return this.resolution.height / this._camera.zoom;\n return this.resolution.height;\n }\n /**\r\n * Returns half the height of the engine's visible drawing surface in pixels including zoom and device pixel ratio.\r\n */ get halfDrawHeight() {\n return this.drawHeight / 2;\n }\n /**\r\n * Returns screen center coordinates including zoom and device pixel ratio.\r\n */ get center() {\n return vec(this.halfDrawWidth, this.halfDrawHeight);\n }\n /**\r\n * Returns the content area in screen space where it is safe to place content\r\n */ get contentArea() {\n return this._contentArea;\n }\n _computeFit() {\n document.body.style.margin = \"0px\";\n document.body.style.overflow = \"hidden\";\n const aspect = this.aspectRatio;\n let adjustedWidth = 0;\n let adjustedHeight = 0;\n if (window.innerWidth / aspect < window.innerHeight) {\n adjustedWidth = window.innerWidth;\n adjustedHeight = window.innerWidth / aspect;\n } else {\n adjustedWidth = window.innerHeight * aspect;\n adjustedHeight = window.innerHeight;\n }\n this.viewport = {\n width: adjustedWidth,\n height: adjustedHeight\n };\n this._contentArea = BoundingBox.fromDimension(this.resolution.width, this.resolution.height, Vector.Zero);\n }\n _computeFitScreenAndFill() {\n document.body.style.margin = \"0px\";\n document.body.style.overflow = \"hidden\";\n const vw = window.innerWidth;\n const vh = window.innerHeight;\n this._computeFitAndFill(vw, vh);\n }\n _computeFitContainerAndFill() {\n document.body.style.margin = \"0px\";\n document.body.style.overflow = \"hidden\";\n const parent = this.canvas.parentElement;\n const vw = parent.clientWidth;\n const vh = parent.clientHeight;\n this._computeFitAndFill(vw, vh);\n }\n _computeFitAndFill(vw, vh) {\n this.viewport = {\n width: vw,\n height: vh\n };\n // if the current screen aspectRatio is less than the original aspectRatio\n if (vw / vh <= this._contentResolution.width / this._contentResolution.height) {\n // compute new resolution to match the original aspect ratio\n this.resolution = {\n width: vw * this._contentResolution.width / vw,\n height: vw * this._contentResolution.width / vw * vh / vw\n };\n const clip = (this.resolution.height - this._contentResolution.height) / 2;\n this._contentArea = new BoundingBox({\n top: clip,\n left: 0,\n right: this._contentResolution.width,\n bottom: this.resolution.height - clip\n });\n } else {\n this.resolution = {\n width: vh * this._contentResolution.height / vh * vw / vh,\n height: vh * this._contentResolution.height / vh\n };\n const clip = (this.resolution.width - this._contentResolution.width) / 2;\n this._contentArea = new BoundingBox({\n top: 0,\n left: clip,\n right: this.resolution.width - clip,\n bottom: this._contentResolution.height\n });\n }\n }\n _computeFitScreenAndZoom() {\n document.body.style.margin = \"0px\";\n document.body.style.overflow = \"hidden\";\n this.canvas.style.position = \"absolute\";\n const vw = window.innerWidth;\n const vh = window.innerHeight;\n this._computeFitAndZoom(vw, vh);\n }\n _computeFitContainerAndZoom() {\n document.body.style.margin = \"0px\";\n document.body.style.overflow = \"hidden\";\n this.canvas.style.position = \"absolute\";\n const parent = this.canvas.parentElement;\n parent.style.position = \"relative\";\n parent.style.overflow = \"hidden\";\n const vw = parent.clientWidth;\n const vh = parent.clientHeight;\n this._computeFitAndZoom(vw, vh);\n }\n _computeFitAndZoom(vw, vh) {\n const aspect = this.aspectRatio;\n let adjustedWidth = 0;\n let adjustedHeight = 0;\n if (vw / aspect < vh) {\n adjustedWidth = vw;\n adjustedHeight = vw / aspect;\n } else {\n adjustedWidth = vh * aspect;\n adjustedHeight = vh;\n }\n const scaleX = vw / adjustedWidth;\n const scaleY = vh / adjustedHeight;\n const maxScaleFactor = Math.max(scaleX, scaleY);\n const zoomedWidth = adjustedWidth * maxScaleFactor;\n const zoomedHeight = adjustedHeight * maxScaleFactor;\n // Center zoomed dimension if bigger than the screen\n if (zoomedWidth > vw) this.canvas.style.left = -(zoomedWidth - vw) / 2 + \"px\";\n else this.canvas.style.left = \"\";\n if (zoomedHeight > vh) this.canvas.style.top = -(zoomedHeight - vh) / 2 + \"px\";\n else this.canvas.style.top = \"\";\n this.viewport = {\n width: zoomedWidth,\n height: zoomedHeight\n };\n const bounds = BoundingBox.fromDimension(this.viewport.width, this.viewport.height, Vector.Zero);\n // return safe area\n if (this.viewport.width > vw) {\n const clip = (this.viewport.width - vw) / this.viewport.width * this.resolution.width;\n bounds.top = 0;\n bounds.left = clip / 2;\n bounds.right = this.resolution.width - clip / 2;\n bounds.bottom = this.resolution.height;\n }\n if (this.viewport.height > vh) {\n const clip = (this.viewport.height - vh) / this.viewport.height * this.resolution.height;\n bounds.top = clip / 2;\n bounds.left = 0;\n bounds.bottom = this.resolution.height - clip / 2;\n bounds.right = this.resolution.width;\n }\n this._contentArea = bounds;\n }\n _computeFitContainer() {\n const aspect = this.aspectRatio;\n let adjustedWidth = 0;\n let adjustedHeight = 0;\n const parent = this.canvas.parentElement;\n if (parent.clientWidth / aspect < parent.clientHeight) {\n adjustedWidth = parent.clientWidth;\n adjustedHeight = parent.clientWidth / aspect;\n } else {\n adjustedWidth = parent.clientHeight * aspect;\n adjustedHeight = parent.clientHeight;\n }\n this.viewport = {\n width: adjustedWidth,\n height: adjustedHeight\n };\n this._contentArea = BoundingBox.fromDimension(this.resolution.width, this.resolution.height, Vector.Zero);\n }\n _applyDisplayMode() {\n this._setResolutionAndViewportByDisplayMode(this.parent);\n // watch resizing\n if (this.parent instanceof Window) this._browser.window.on(\"resize\", this._resizeHandler);\n else {\n this._resizeObserver = new ResizeObserver(()=>{\n this._resizeHandler();\n });\n this._resizeObserver.observe(this.parent);\n }\n this.parent.addEventListener(\"resize\", this._resizeHandler);\n }\n /**\r\n * Sets the resolution and viewport based on the selected display mode.\r\n */ _setResolutionAndViewportByDisplayMode(parent) {\n if (this.displayMode === DisplayMode.FillContainer) {\n this.resolution = {\n width: parent.clientWidth,\n height: parent.clientHeight\n };\n this.viewport = this.resolution;\n }\n if (this.displayMode === DisplayMode.FillScreen) {\n document.body.style.margin = \"0px\";\n document.body.style.overflow = \"hidden\";\n this.resolution = {\n width: parent.innerWidth,\n height: parent.innerHeight\n };\n this.viewport = this.resolution;\n }\n this._contentArea = BoundingBox.fromDimension(this.resolution.width, this.resolution.height, Vector.Zero);\n if (this.displayMode === DisplayMode.FitScreen) this._computeFit();\n if (this.displayMode === DisplayMode.FitContainer) this._computeFitContainer();\n if (this.displayMode === DisplayMode.FitScreenAndFill) this._computeFitScreenAndFill();\n if (this.displayMode === DisplayMode.FitContainerAndFill) this._computeFitContainerAndFill();\n if (this.displayMode === DisplayMode.FitScreenAndZoom) this._computeFitScreenAndZoom();\n if (this.displayMode === DisplayMode.FitContainerAndZoom) this._computeFitContainerAndZoom();\n }\n }\n /**\r\n * Internal class used to build instances of AudioContext\r\n */ /* istanbul ignore next */ class AudioContextFactory {\n static create() {\n if (!this._INSTANCE) {\n if (window.AudioContext || window.webkitAudioContext) this._INSTANCE = new AudioContext();\n }\n return this._INSTANCE;\n }\n }\n AudioContextFactory._INSTANCE = null;\n /**\r\n * Patch for detecting legacy web audio in browsers\r\n * @internal\r\n * @param source\r\n */ function isLegacyWebAudioSource(source) {\n return !!source.playbackState;\n }\n class WebAudio {\n /**\r\n * Play an empty sound to unlock Safari WebAudio context. Call this function\r\n * right after a user interaction event.\r\n * @source https://paulbakaus.com/tutorials/html5/web-audio-on-ios/\r\n */ static unlock() {\n const promise = new Promise((resolve, reject)=>{\n if (WebAudio._UNLOCKED || !AudioContextFactory.create()) return resolve(true);\n const unlockTimeoutTimer = setTimeout(()=>{\n Logger.getInstance().warn(\"Excalibur was unable to unlock the audio context, audio probably will not play in this browser.\");\n resolve(false);\n }, 200);\n const audioContext = AudioContextFactory.create();\n audioContext.resume().then(()=>{\n // create empty buffer and play it\n const buffer = audioContext.createBuffer(1, 1, 22050);\n const source = audioContext.createBufferSource();\n let ended = false;\n source.buffer = buffer;\n source.connect(audioContext.destination);\n source.onended = ()=>ended = true;\n source.start(0);\n // by checking the play state after some time, we know if we're really unlocked\n setTimeout(()=>{\n if (isLegacyWebAudioSource(source)) {\n if (source.playbackState === source.PLAYING_STATE || source.playbackState === source.FINISHED_STATE) WebAudio._UNLOCKED = true;\n } else if (audioContext.currentTime > 0 || ended) WebAudio._UNLOCKED = true;\n }, 0);\n clearTimeout(unlockTimeoutTimer);\n resolve(true);\n }, ()=>{\n reject();\n });\n });\n return promise;\n }\n static isUnlocked() {\n return this._UNLOCKED;\n }\n }\n WebAudio._UNLOCKED = false;\n /* istanbul ignore next */ /**\r\n * Draw a line on canvas context\r\n *\r\n * @param ctx The canvas context\r\n * @param color The color of the line\r\n * @param x1 The start x coordinate\r\n * @param y1 The start y coordinate\r\n * @param x2 The ending x coordinate\r\n * @param y2 The ending y coordinate\r\n * @param thickness The line thickness\r\n * @param cap The [[LineCapStyle]] (butt, round, or square)\r\n */ function line(ctx, color = Color.Red, x1, y1, x2, y2, thickness = 1, cap = \"butt\") {\n ctx.save();\n ctx.beginPath();\n ctx.lineWidth = thickness;\n ctx.lineCap = cap;\n ctx.strokeStyle = color.toString();\n ctx.moveTo(x1, y1);\n ctx.lineTo(x2, y2);\n ctx.closePath();\n ctx.stroke();\n ctx.restore();\n }\n /* istanbul ignore next */ /**\r\n * Draw the vector as a point onto the canvas.\r\n */ function point(ctx, color = Color.Red, point) {\n ctx.beginPath();\n ctx.strokeStyle = color.toString();\n ctx.arc(point.x, point.y, 5, 0, Math.PI * 2);\n ctx.closePath();\n ctx.stroke();\n }\n /**\r\n * Draw the vector as a line onto the canvas starting a origin point.\r\n */ /* istanbul ignore next */ /**\r\n *\r\n */ function vector(ctx, color, origin, vector, scale = 1.0) {\n const c = color ? color.toString() : \"blue\";\n const v = vector.scale(scale);\n ctx.beginPath();\n ctx.strokeStyle = c;\n ctx.moveTo(origin.x, origin.y);\n ctx.lineTo(origin.x + v.x, origin.y + v.y);\n ctx.closePath();\n ctx.stroke();\n }\n /**\r\n * Draw a round rectangle on a canvas context\r\n *\r\n * @param ctx The canvas context\r\n * @param x The top-left x coordinate\r\n * @param y The top-left y coordinate\r\n * @param width The width of the rectangle\r\n * @param height The height of the rectangle\r\n * @param radius The border radius of the rectangle\r\n * @param stroke The [[Color]] to stroke rectangle with\r\n * @param fill The [[Color]] to fill rectangle with\r\n */ function roundRect(ctx, x, y, width, height, radius = 5, stroke = Color.White, fill = null) {\n let br;\n if (typeof radius === \"number\") br = {\n tl: radius,\n tr: radius,\n br: radius,\n bl: radius\n };\n else {\n const defaultRadius = {\n tl: 0,\n tr: 0,\n br: 0,\n bl: 0\n };\n for(const prop in defaultRadius)if (defaultRadius.hasOwnProperty(prop)) {\n const side = prop;\n br[side] = radius[side] || defaultRadius[side];\n }\n }\n ctx.beginPath();\n ctx.moveTo(x + br.tl, y);\n ctx.lineTo(x + width - br.tr, y);\n ctx.quadraticCurveTo(x + width, y, x + width, y + br.tr);\n ctx.lineTo(x + width, y + height - br.br);\n ctx.quadraticCurveTo(x + width, y + height, x + width - br.br, y + height);\n ctx.lineTo(x + br.bl, y + height);\n ctx.quadraticCurveTo(x, y + height, x, y + height - br.bl);\n ctx.lineTo(x, y + br.tl);\n ctx.quadraticCurveTo(x, y, x + br.tl, y);\n ctx.closePath();\n if (fill) {\n ctx.fillStyle = fill.toString();\n ctx.fill();\n }\n if (stroke) {\n ctx.strokeStyle = stroke.toString();\n ctx.stroke();\n }\n }\n /**\r\n *\r\n */ function circle(ctx, x, y, radius, stroke = Color.White, fill = null) {\n ctx.beginPath();\n ctx.arc(x, y, radius, 0, Math.PI * 2);\n ctx.closePath();\n if (fill) {\n ctx.fillStyle = fill.toString();\n ctx.fill();\n }\n if (stroke) {\n ctx.strokeStyle = stroke.toString();\n ctx.stroke();\n }\n }\n /* harmony default export */ const Loader_logo = \"data:image/png;base64,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\";\n // EXTERNAL MODULE: ./Loader.css\n var Loader_0 = $2c23f148d58cd887$var$__webpack_require__(1388);\n /**\r\n * A Raster is a Graphic that needs to be first painted to a HTMLCanvasElement before it can be drawn to the\r\n * [[ExcaliburGraphicsContext]]. This is useful for generating custom images using the 2D canvas api.\r\n *\r\n * Implementors must implement the [[Raster.execute]] method to rasterize their drawing.\r\n */ class Raster extends Graphic {\n constructor(options){\n var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;\n super(options);\n this.filtering = null;\n this.lineCap = \"butt\";\n this.quality = 1;\n this._dirty = true;\n this._smoothing = false;\n this._color = watch(Color.Black, ()=>this.flagDirty());\n this._lineWidth = 1;\n this._lineDash = [];\n this._padding = 0;\n if (options) {\n this.quality = (_a = options.quality) !== null && _a !== void 0 ? _a : this.quality;\n this.color = (_b = options.color) !== null && _b !== void 0 ? _b : Color.Black;\n this.strokeColor = options === null || options === void 0 ? void 0 : options.strokeColor;\n this.smoothing = (_c = options.smoothing) !== null && _c !== void 0 ? _c : this.smoothing;\n this.lineWidth = (_d = options.lineWidth) !== null && _d !== void 0 ? _d : this.lineWidth;\n this.lineDash = (_e = options.lineDash) !== null && _e !== void 0 ? _e : this.lineDash;\n this.lineCap = (_f = options.lineCap) !== null && _f !== void 0 ? _f : this.lineCap;\n this.padding = (_g = options.padding) !== null && _g !== void 0 ? _g : this.padding;\n this.filtering = (_h = options.filtering) !== null && _h !== void 0 ? _h : this.filtering;\n }\n this._bitmap = document.createElement(\"canvas\");\n // get the default canvas width/height as a fallback\n const bitmapWidth = (_j = options === null || options === void 0 ? void 0 : options.width) !== null && _j !== void 0 ? _j : this._bitmap.width;\n const bitmapHeight = (_k = options === null || options === void 0 ? void 0 : options.height) !== null && _k !== void 0 ? _k : this._bitmap.height;\n this.width = bitmapWidth;\n this.height = bitmapHeight;\n const maybeCtx = this._bitmap.getContext(\"2d\");\n if (!maybeCtx) /* istanbul ignore next */ throw new Error(\"Browser does not support 2d canvas drawing, cannot create Raster graphic\");\n else this._ctx = maybeCtx;\n }\n cloneRasterOptions() {\n return {\n color: this.color ? this.color.clone() : null,\n strokeColor: this.strokeColor ? this.strokeColor.clone() : null,\n smoothing: this.smoothing,\n lineWidth: this.lineWidth,\n lineDash: this.lineDash,\n lineCap: this.lineCap,\n quality: this.quality,\n padding: this.padding\n };\n }\n /**\r\n * Gets whether the graphic is dirty, this means there are changes that haven't been re-rasterized\r\n */ get dirty() {\n return this._dirty;\n }\n /**\r\n * Flags the graphic as dirty, meaning it must be re-rasterized before draw.\r\n * This should be called any time the graphics state changes such that it affects the outputted drawing\r\n */ flagDirty() {\n this._dirty = true;\n }\n /**\r\n * Gets or sets the current width of the Raster graphic. Setting the width will cause the raster\r\n * to be flagged dirty causing a re-raster on the next draw.\r\n *\r\n * Any `padding`s or `quality` set will be factored into the width\r\n */ get width() {\n return Math.abs(this._getTotalWidth() * this.scale.x);\n }\n set width(value) {\n value /= Math.abs(this.scale.x);\n this._bitmap.width = value;\n this._originalWidth = value;\n this.flagDirty();\n }\n /**\r\n * Gets or sets the current height of the Raster graphic. Setting the height will cause the raster\r\n * to be flagged dirty causing a re-raster on the next draw.\r\n *\r\n * Any `padding` or `quality` set will be factored into the height\r\n */ get height() {\n return Math.abs(this._getTotalHeight() * this.scale.y);\n }\n set height(value) {\n value /= Math.abs(this.scale.y);\n this._bitmap.height = value;\n this._originalHeight = value;\n this.flagDirty();\n }\n _getTotalWidth() {\n var _a;\n return (((_a = this._originalWidth) !== null && _a !== void 0 ? _a : this._bitmap.width) + this.padding * 2) * 1;\n }\n _getTotalHeight() {\n var _a;\n return (((_a = this._originalHeight) !== null && _a !== void 0 ? _a : this._bitmap.height) + this.padding * 2) * 1;\n }\n /**\r\n * Returns the local bounds of the Raster including the padding\r\n */ get localBounds() {\n return BoundingBox.fromDimension(this._getTotalWidth() * this.scale.x, this._getTotalHeight() * this.scale.y, Vector.Zero);\n }\n /**\r\n * Gets or sets the smoothing (anti-aliasing of the graphic). Setting the height will cause the raster\r\n * to be flagged dirty causing a re-raster on the next draw.\r\n */ get smoothing() {\n return this._smoothing;\n }\n set smoothing(value) {\n this._smoothing = value;\n this.flagDirty();\n }\n /**\r\n * Gets or sets the fillStyle of the Raster graphic. Setting the fillStyle will cause the raster to be\r\n * flagged dirty causing a re-raster on the next draw.\r\n */ get color() {\n return this._color;\n }\n set color(value) {\n this.flagDirty();\n this._color = watch(value, ()=>this.flagDirty());\n }\n /**\r\n * Gets or sets the strokeStyle of the Raster graphic. Setting the strokeStyle will cause the raster to be\r\n * flagged dirty causing a re-raster on the next draw.\r\n */ get strokeColor() {\n return this._strokeColor;\n }\n set strokeColor(value) {\n this.flagDirty();\n this._strokeColor = watch(value, ()=>this.flagDirty());\n }\n /**\r\n * Gets or sets the line width of the Raster graphic. Setting the lineWidth will cause the raster to be\r\n * flagged dirty causing a re-raster on the next draw.\r\n */ get lineWidth() {\n return this._lineWidth;\n }\n set lineWidth(value) {\n this._lineWidth = value;\n this.flagDirty();\n }\n get lineDash() {\n return this._lineDash;\n }\n set lineDash(value) {\n this._lineDash = value;\n this.flagDirty();\n }\n get padding() {\n return this._padding;\n }\n set padding(value) {\n this._padding = value;\n this.flagDirty();\n }\n /**\r\n * Rasterize the graphic to a bitmap making it usable as in excalibur. Rasterize is called automatically if\r\n * the graphic is [[Raster.dirty]] on the next [[Graphic.draw]] call\r\n */ rasterize() {\n this._dirty = false;\n this._ctx.clearRect(0, 0, this._getTotalWidth(), this._getTotalHeight());\n this._ctx.save();\n this._applyRasterProperties(this._ctx);\n this.execute(this._ctx);\n this._ctx.restore();\n }\n _applyRasterProperties(ctx) {\n var _a, _b, _c;\n this._bitmap.width = this._getTotalWidth() * this.quality;\n this._bitmap.height = this._getTotalHeight() * this.quality;\n // Do a bad thing to pass the filtering as an attribute\n this._bitmap.setAttribute(\"filtering\", this.filtering);\n this._bitmap.setAttribute(\"forceUpload\", \"true\");\n ctx.scale(this.quality, this.quality);\n ctx.translate(this.padding, this.padding);\n ctx.imageSmoothingEnabled = this.smoothing;\n ctx.lineWidth = this.lineWidth;\n ctx.setLineDash((_a = this.lineDash) !== null && _a !== void 0 ? _a : ctx.getLineDash());\n ctx.lineCap = this.lineCap;\n ctx.strokeStyle = (_b = this.strokeColor) === null || _b === void 0 ? void 0 : _b.toString();\n ctx.fillStyle = (_c = this.color) === null || _c === void 0 ? void 0 : _c.toString();\n }\n _drawImage(ex, x, y) {\n if (this._dirty) this.rasterize();\n ex.scale(1 / this.quality, 1 / this.quality);\n ex.drawImage(this._bitmap, x, y);\n }\n }\n /**\r\n * A canvas [[Graphic]] to provide an adapter between the 2D Canvas API and the [[ExcaliburGraphicsContext]].\r\n *\r\n * The [[Canvas]] works by re-rastering a draw handler to a HTMLCanvasElement for every draw which is then passed\r\n * to the [[ExcaliburGraphicsContext]] implementation as a rendered image.\r\n *\r\n * **Low performance API**\r\n */ class Canvas extends Raster {\n /**\r\n * Return the 2D graphics context of this canvas\r\n */ get ctx() {\n return this._ctx;\n }\n constructor(_options){\n super(_options);\n this._options = _options;\n }\n clone() {\n return new Canvas({\n ...this._options,\n ...this.cloneGraphicOptions(),\n ...this.cloneRasterOptions()\n });\n }\n execute(ctx) {\n var _a, _b;\n if ((_a = this._options) === null || _a === void 0 ? void 0 : _a.draw) (_b = this._options) === null || _b === void 0 || _b.draw(ctx);\n if (!this._options.cache) this.flagDirty();\n }\n }\n class ExResponse {\n }\n ExResponse.type = {\n any: \"\",\n blob: \"blob\",\n json: \"json\",\n text: \"text\",\n document: \"document\",\n arraybuffer: \"arraybuffer\"\n };\n class StateMachine {\n constructor(){\n this.states = new Map();\n }\n get currentState() {\n return this._currentState;\n }\n set currentState(state) {\n this._currentState = state;\n }\n static create(machineDescription, data) {\n const machine = new StateMachine();\n machine.data = data;\n for(const stateName in machineDescription.states)machine.states.set(stateName, {\n name: stateName,\n ...machineDescription.states[stateName]\n });\n // validate transitions are states\n for (const state of machine.states.values())for (const transitionState of state.transitions){\n if (transitionState === \"*\") continue;\n if (!machine.states.has(transitionState)) throw Error(`Invalid state machine, state [${state.name}] has a transition to another state that doesn't exist [${transitionState}]`);\n }\n machine.currentState = machine.startState = machine.states.get(machineDescription.start);\n return machine;\n }\n in(state) {\n return this.currentState.name === state;\n }\n go(stateName, eventData) {\n var _a, _b;\n if (this.currentState.transitions.includes(stateName) || this.currentState.transitions.includes(\"*\")) {\n const potentialNewState = this.states.get(stateName);\n if (this.currentState.onExit) {\n const canExit = (_a = this.currentState) === null || _a === void 0 ? void 0 : _a.onExit({\n to: potentialNewState.name,\n data: this.data\n });\n if (canExit === false) return false;\n }\n if (potentialNewState === null || potentialNewState === void 0 ? void 0 : potentialNewState.onEnter) {\n const canEnter = potentialNewState === null || potentialNewState === void 0 ? void 0 : potentialNewState.onEnter({\n from: this.currentState.name,\n eventData: eventData,\n data: this.data\n });\n if (canEnter === false) return false;\n }\n // console.log(`${this.currentState.name} => ${potentialNewState.name} (${eventData})`);\n this.currentState = potentialNewState;\n if ((_b = this.currentState) === null || _b === void 0 ? void 0 : _b.onState) this.currentState.onState();\n return true;\n }\n return false;\n }\n update(elapsedMs) {\n if (this.currentState.onUpdate) this.currentState.onUpdate(this.data, elapsedMs);\n }\n save(saveKey) {\n localStorage.setItem(saveKey, JSON.stringify({\n currentState: this.currentState.name,\n data: this.data\n }));\n }\n restore(saveKey) {\n const state = JSON.parse(localStorage.getItem(saveKey));\n this.currentState = this.states.get(state.currentState);\n this.data = state.data;\n }\n }\n /**\r\n * Internal class representing a Web Audio AudioBufferSourceNode instance\r\n * @see https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API\r\n */ class WebAudioInstance {\n _createNewBufferSource() {\n this._instance = this._audioContext.createBufferSource();\n this._instance.buffer = this._src;\n this._instance.loop = this.loop;\n this._instance.playbackRate.value = this._playbackRate;\n this._instance.connect(this._volumeNode);\n this._volumeNode.connect(this._audioContext.destination);\n }\n _handleEnd() {\n if (!this.loop) this._instance.onended = ()=>{\n this._playingResolve(true);\n };\n }\n set loop(value) {\n this._loop = value;\n if (this._instance) {\n this._instance.loop = value;\n if (!this.loop) this._instance.onended = ()=>{\n this._playingResolve(true);\n };\n }\n }\n get loop() {\n return this._loop;\n }\n set volume(value) {\n value = clamp(value, 0, 1.0);\n this._volume = value;\n if (this._stateMachine.in(\"PLAYING\") && this._volumeNode.gain.setTargetAtTime) // https://developer.mozilla.org/en-US/docs/Web/API/AudioParam/setTargetAtTime\n // After each .1 seconds timestep, the target value will ~63.2% closer to the target value.\n // This exponential ramp provides a more pleasant transition in gain\n this._volumeNode.gain.setTargetAtTime(value, this._audioContext.currentTime, 0.1);\n else this._volumeNode.gain.value = value;\n }\n get volume() {\n return this._volume;\n }\n /**\r\n * Returns the set duration to play, otherwise returns the total duration if unset\r\n */ get duration() {\n var _a;\n return (_a = this._duration) !== null && _a !== void 0 ? _a : this.getTotalPlaybackDuration();\n }\n /**\r\n * Set the duration that this audio should play.\r\n *\r\n * Note: if you seek to a specific point the duration will start from that point, for example\r\n *\r\n * If you have a 10 second clip, seek to 5 seconds, then set the duration to 2, it will play the clip from 5-7 seconds.\r\n */ set duration(duration) {\n this._duration = duration;\n }\n constructor(_src){\n this._src = _src;\n this._audioContext = AudioContextFactory.create();\n this._volumeNode = this._audioContext.createGain();\n this._playingPromise = new Promise((resolve)=>{\n this._playingResolve = resolve;\n });\n this._stateMachine = StateMachine.create({\n start: \"STOPPED\",\n states: {\n PLAYING: {\n onEnter: ({ data: data })=>{\n // Buffer nodes are single use\n this._createNewBufferSource();\n this._handleEnd();\n if (this.loop) // when looping don't set a duration\n this._instance.start(0, data.pausedAt * this._playbackRate);\n else this._instance.start(0, data.pausedAt * this._playbackRate, this.duration);\n data.startedAt = this._audioContext.currentTime - data.pausedAt;\n data.pausedAt = 0;\n },\n onState: ()=>this._playStarted(),\n onExit: ({ to: to })=>{\n // If you've exited early only resolve if explicitly STOPPED\n if (to === \"STOPPED\") this._playingResolve(true);\n // Whenever you're not playing... you stop!\n this._instance.onended = null; // disconnect the wired on-end handler\n this._instance.disconnect();\n this._instance.stop(0);\n this._instance = null;\n },\n transitions: [\n \"STOPPED\",\n \"PAUSED\",\n \"SEEK\"\n ]\n },\n SEEK: {\n onEnter: ({ eventData: position, data: data })=>{\n data.pausedAt = (position !== null && position !== void 0 ? position : 0) / this._playbackRate;\n data.startedAt = 0;\n },\n transitions: [\n \"*\"\n ]\n },\n STOPPED: {\n onEnter: ({ data: data })=>{\n data.pausedAt = 0;\n data.startedAt = 0;\n this._playingResolve(true);\n },\n transitions: [\n \"PLAYING\",\n \"PAUSED\",\n \"SEEK\"\n ]\n },\n PAUSED: {\n onEnter: ({ data: data })=>{\n // Playback rate will be a scale factor of how fast/slow the audio is being played\n // default is 1.0\n // we need to invert it to get the time scale\n data.pausedAt = this._audioContext.currentTime - data.startedAt;\n },\n transitions: [\n \"PLAYING\",\n \"STOPPED\",\n \"SEEK\"\n ]\n }\n }\n }, {\n startedAt: 0,\n pausedAt: 0\n });\n this._volume = 1;\n this._loop = false;\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n this._playStarted = ()=>{};\n this._playbackRate = 1.0;\n this._createNewBufferSource();\n }\n isPlaying() {\n return this._stateMachine.in(\"PLAYING\");\n }\n isPaused() {\n return this._stateMachine.in(\"PAUSED\") || this._stateMachine.in(\"SEEK\");\n }\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n play(playStarted = ()=>{}) {\n this._playStarted = playStarted;\n this._stateMachine.go(\"PLAYING\");\n return this._playingPromise;\n }\n pause() {\n this._stateMachine.go(\"PAUSED\");\n }\n stop() {\n this._stateMachine.go(\"STOPPED\");\n }\n seek(position) {\n this._stateMachine.go(\"PAUSED\");\n this._stateMachine.go(\"SEEK\", position);\n }\n getTotalPlaybackDuration() {\n return this._src.duration;\n }\n getPlaybackPosition() {\n const { pausedAt: pausedAt, startedAt: startedAt } = this._stateMachine.data;\n if (pausedAt) return pausedAt * this._playbackRate;\n if (startedAt) return (this._audioContext.currentTime - startedAt) * this._playbackRate;\n return 0;\n }\n set playbackRate(playbackRate) {\n this._instance.playbackRate.value = this._playbackRate = playbackRate;\n }\n get playbackRate() {\n return this._instance.playbackRate.value;\n }\n }\n class MediaEvent extends GameEvent {\n /**\r\n * Media event cannot bubble\r\n */ set bubbles(_value) {\n // stubbed\n }\n /**\r\n * Media event cannot bubble\r\n */ get bubbles() {\n return false;\n }\n /**\r\n * Media event cannot bubble, so they have no path\r\n */ get _path() {\n return null;\n }\n /**\r\n * Media event cannot bubble, so they have no path\r\n */ set _path(_val) {\n // stubbed\n }\n constructor(target, _name = \"MediaEvent\"){\n super();\n this.target = target;\n this._name = _name;\n }\n /**\r\n * Prevents event from bubbling\r\n */ stopPropagation() {\n /**\r\n * Stub\r\n */ }\n /**\r\n * Action, that calls when event happens\r\n */ action() {\n /**\r\n * Stub\r\n */ }\n /**\r\n * Propagate event further through event path\r\n */ propagate() {\n /**\r\n * Stub\r\n */ }\n layPath(_actor) {\n /**\r\n * Stub\r\n */ }\n }\n class NativeSoundEvent extends MediaEvent {\n constructor(target, track){\n super(target, \"NativeSoundEvent\");\n this.track = track;\n }\n }\n class NativeSoundProcessedEvent extends MediaEvent {\n constructor(target, _processedData){\n super(target, \"NativeSoundProcessedEvent\");\n this._processedData = _processedData;\n this.data = this._processedData;\n }\n }\n /**\r\n * Whether or not the browser can play this file as HTML5 Audio\r\n */ function canPlayFile(file) {\n try {\n const a = new Audio();\n const filetype = /.*\\.([A-Za-z0-9]+)(?:(?:\\?|\\#).*)*$/;\n const type = file.match(filetype)[1];\n if (a.canPlayType(\"audio/\" + type)) return true;\n else return false;\n } catch (e) {\n Logger.getInstance().warn(\"Cannot determine audio support, assuming no support for the Audio Tag\", e);\n return false;\n }\n }\n const SoundEvents = {\n VolumeChange: \"volumechange\",\n Processed: \"processed\",\n Pause: \"pause\",\n Stop: \"stop\",\n PlaybackEnd: \"playbackend\",\n Resume: \"resume\",\n PlaybackStart: \"playbackstart\"\n };\n /**\r\n * The [[Sound]] object allows games built in Excalibur to load audio\r\n * components, from soundtracks to sound effects. [[Sound]] is an [[Loadable]]\r\n * which means it can be passed to a [[Loader]] to pre-load before a game or level.\r\n */ class Sound {\n /**\r\n * Indicates whether the clip should loop when complete\r\n * @param value Set the looping flag\r\n */ set loop(value) {\n this._loop = value;\n for (const track of this._tracks)track.loop = this._loop;\n this.logger.debug(\"Set loop for all instances of sound\", this.path, \"to\", this._loop);\n }\n get loop() {\n return this._loop;\n }\n set volume(value) {\n this._volume = value;\n for (const track of this._tracks)track.volume = this._volume;\n this.events.emit(\"volumechange\", new NativeSoundEvent(this));\n this.logger.debug(\"Set loop for all instances of sound\", this.path, \"to\", this._volume);\n }\n get volume() {\n return this._volume;\n }\n /**\r\n * Get the duration that this audio should play. If unset the total natural playback duration will be used.\r\n */ get duration() {\n return this._duration;\n }\n /**\r\n * Set the duration that this audio should play. If unset the total natural playback duration will be used.\r\n *\r\n * Note: if you seek to a specific point the duration will start from that point, for example\r\n *\r\n * If you have a 10 second clip, seek to 5 seconds, then set the duration to 2, it will play the clip from 5-7 seconds.\r\n */ set duration(duration) {\n this._duration = duration;\n }\n /**\r\n * Return array of Current AudioInstances playing or being paused\r\n */ get instances() {\n return this._tracks;\n }\n get path() {\n return this._resource.path;\n }\n set path(val) {\n this._resource.path = val;\n }\n /**\r\n * Should excalibur add a cache busting querystring? By default false.\r\n * Must be set before loading\r\n */ get bustCache() {\n return this._resource.bustCache;\n }\n set bustCache(val) {\n this._resource.bustCache = val;\n }\n /**\r\n * @param paths A list of audio sources (clip.wav, clip.mp3, clip.ogg) for this audio clip. This is done for browser compatibility.\r\n */ constructor(...paths){\n this.events = new EventEmitter();\n this.logger = Logger.getInstance();\n this._loop = false;\n this._volume = 1;\n this._isStopped = false;\n // private _isPaused = false;\n this._tracks = [];\n this._wasPlayingOnHidden = false;\n this._playbackRate = 1.0;\n this._audioContext = AudioContextFactory.create();\n this._resource = new Resource(\"\", ExResponse.type.arraybuffer);\n /**\r\n * Chrome : MP3, WAV, Ogg\r\n * Firefox : WAV, Ogg,\r\n * IE : MP3, WAV coming soon\r\n * Safari MP3, WAV, Ogg\r\n */ for (const path of paths)if (canPlayFile(path)) {\n this.path = path;\n break;\n }\n if (!this.path) {\n this.logger.warn(\"This browser does not support any of the audio files specified:\", paths.join(\", \"));\n this.logger.warn(\"Attempting to use\", paths[0]);\n this.path = paths[0]; // select the first specified\n }\n }\n isLoaded() {\n return !!this.data;\n }\n async load() {\n var _a, _b;\n if (this.data) return this.data;\n const arraybuffer = await this._resource.load();\n const audiobuffer = await this.decodeAudio(arraybuffer.slice(0));\n this._duration = (_b = (_a = this._duration) !== null && _a !== void 0 ? _a : audiobuffer === null || audiobuffer === void 0 ? void 0 : audiobuffer.duration) !== null && _b !== void 0 ? _b : undefined;\n this.events.emit(\"processed\", new NativeSoundProcessedEvent(this, audiobuffer));\n return this.data = audiobuffer;\n }\n async decodeAudio(data) {\n try {\n return await this._audioContext.decodeAudioData(data.slice(0));\n } catch (e) {\n this.logger.error(\"Unable to decode this browser may not fully support this format, or the file may be corrupt, if this is an mp3 try removing id3 tags and album art from the file.\");\n return await Promise.reject();\n }\n }\n wireEngine(engine) {\n if (engine) {\n this._engine = engine;\n this._engine.on(\"hidden\", ()=>{\n if (engine.pauseAudioWhenHidden && this.isPlaying()) {\n this._wasPlayingOnHidden = true;\n this.pause();\n }\n });\n this._engine.on(\"visible\", ()=>{\n if (engine.pauseAudioWhenHidden && this._wasPlayingOnHidden) {\n this.play();\n this._wasPlayingOnHidden = false;\n }\n });\n this._engine.on(\"start\", ()=>{\n this._isStopped = false;\n });\n this._engine.on(\"stop\", ()=>{\n this.stop();\n this._isStopped = true;\n });\n }\n }\n /**\r\n * Returns how many instances of the sound are currently playing\r\n */ instanceCount() {\n return this._tracks.length;\n }\n /**\r\n * Whether or not the sound is playing right now\r\n */ isPlaying() {\n return this._tracks.some((t)=>t.isPlaying());\n }\n isPaused() {\n return this._tracks.some((t)=>t.isPaused());\n }\n /**\r\n * Play the sound, returns a promise that resolves when the sound is done playing\r\n * An optional volume argument can be passed in to play the sound. Max volume is 1.0\r\n */ play(volume) {\n if (!this.isLoaded()) {\n this.logger.warn(\"Cannot start playing. Resource\", this.path, \"is not loaded yet\");\n return Promise.resolve(true);\n }\n if (this._isStopped) {\n this.logger.warn(\"Cannot start playing. Engine is in a stopped state.\");\n return Promise.resolve(false);\n }\n this.volume = volume || this.volume;\n if (this.isPaused()) return this._resumePlayback();\n else return this._startPlayback();\n }\n /**\r\n * Stop the sound, and do not rewind\r\n */ pause() {\n if (!this.isPlaying()) return;\n for (const track of this._tracks)track.pause();\n this.events.emit(\"pause\", new NativeSoundEvent(this));\n this.logger.debug(\"Paused all instances of sound\", this.path);\n }\n /**\r\n * Stop the sound if it is currently playing and rewind the track. If the sound is not playing, rewinds the track.\r\n */ stop() {\n for (const track of this._tracks)track.stop();\n this.events.emit(\"stop\", new NativeSoundEvent(this));\n this._tracks.length = 0;\n this.logger.debug(\"Stopped all instances of sound\", this.path);\n }\n get playbackRate() {\n return this._playbackRate;\n }\n set playbackRate(playbackRate) {\n this._playbackRate = playbackRate;\n this._tracks.forEach((t)=>{\n t.playbackRate = this._playbackRate;\n });\n }\n seek(position, trackId = 0) {\n if (this._tracks.length === 0) this._getTrackInstance(this.data);\n this._tracks[trackId].seek(position);\n }\n getTotalPlaybackDuration() {\n return this.data.duration;\n }\n /**\r\n * Return the current playback time of the playing track in seconds from the start.\r\n *\r\n * Optionally specify the track to query if multiple are playing at once.\r\n * @param trackId\r\n */ getPlaybackPosition(trackId = 0) {\n if (this._tracks.length) return this._tracks[trackId].getPlaybackPosition();\n return 0;\n }\n /**\r\n * Get Id of provided AudioInstance in current trackList\r\n * @param track [[Audio]] which Id is to be given\r\n */ getTrackId(track) {\n return this._tracks.indexOf(track);\n }\n async _resumePlayback() {\n if (this.isPaused) {\n const resumed = [];\n // ensure we resume *current* tracks (if paused)\n for (const track of this._tracks)resumed.push(track.play().then(()=>{\n this.events.emit(\"playbackend\", new NativeSoundEvent(this, track));\n this._tracks.splice(this.getTrackId(track), 1);\n return true;\n }));\n this.events.emit(\"resume\", new NativeSoundEvent(this));\n this.logger.debug(\"Resuming paused instances for sound\", this.path, this._tracks);\n // resolve when resumed tracks are done\n await Promise.all(resumed);\n }\n return true;\n }\n /**\r\n * Starts playback, returns a promise that resolves when playback is complete\r\n */ async _startPlayback() {\n const track = await this._getTrackInstance(this.data);\n const complete = await track.play(()=>{\n this.events.emit(\"playbackstart\", new NativeSoundEvent(this, track));\n this.logger.debug(\"Playing new instance for sound\", this.path);\n });\n // when done, remove track\n this.events.emit(\"playbackend\", new NativeSoundEvent(this, track));\n this._tracks.splice(this.getTrackId(track), 1);\n return complete;\n }\n _getTrackInstance(data) {\n const newTrack = new WebAudioInstance(data);\n newTrack.loop = this.loop;\n newTrack.volume = this.volume;\n newTrack.duration = this.duration;\n newTrack.playbackRate = this._playbackRate;\n this._tracks.push(newTrack);\n return newTrack;\n }\n emit(eventName, event) {\n this.events.emit(eventName, event);\n }\n on(eventName, handler) {\n return this.events.on(eventName, handler);\n }\n once(eventName, handler) {\n return this.events.once(eventName, handler);\n }\n off(eventName, handler) {\n this.events.off(eventName, handler);\n }\n }\n const LoaderEvents = {\n };\n /**\r\n * Pre-loading assets\r\n *\r\n * The loader provides a mechanism to preload multiple resources at\r\n * one time. The loader must be passed to the engine in order to\r\n * trigger the loading progress bar.\r\n *\r\n * The [[Loader]] itself implements [[Loadable]] so you can load loaders.\r\n *\r\n * ## Example: Pre-loading resources for a game\r\n *\r\n * ```js\r\n * // create a loader\r\n * var loader = new ex.Loader();\r\n *\r\n * // create a resource dictionary (best practice is to keep a separate file)\r\n * var resources = {\r\n * TextureGround: new ex.Texture(\"/images/textures/ground.png\"),\r\n * SoundDeath: new ex.Sound(\"/sound/death.wav\", \"/sound/death.mp3\")\r\n * };\r\n *\r\n * // loop through dictionary and add to loader\r\n * for (var loadable in resources) {\r\n * if (resources.hasOwnProperty(loadable)) {\r\n * loader.addResource(resources[loadable]);\r\n * }\r\n * }\r\n *\r\n * // start game\r\n * game.start(loader).then(function () {\r\n * console.log(\"Game started!\");\r\n * });\r\n * ```\r\n *\r\n * ## Customize the Loader\r\n *\r\n * The loader can be customized to show different, text, logo, background color, and button.\r\n *\r\n * ```typescript\r\n * const loader = new ex.Loader([playerTexture]);\r\n *\r\n * // The loaders button text can simply modified using this\r\n * loader.playButtonText = 'Start the best game ever';\r\n *\r\n * // The logo can be changed by inserting a base64 image string here\r\n *\r\n * loader.logo = 'data:image/png;base64,iVBORw...';\r\n * loader.logoWidth = 15;\r\n * loader.logoHeight = 14;\r\n *\r\n * // The background color can be changed like so by supplying a valid CSS color string\r\n *\r\n * loader.backgroundColor = 'red'\r\n * loader.backgroundColor = '#176BAA'\r\n *\r\n * // To build a completely new button\r\n * loader.startButtonFactory = () => {\r\n * let myButton = document.createElement('button');\r\n * myButton.textContent = 'The best button';\r\n * return myButton;\r\n * };\r\n *\r\n * engine.start(loader).then(() => {});\r\n * ```\r\n */ class Loader {\n get _image() {\n if (!this._imageElement) {\n this._imageElement = new Image();\n this._imageElement.src = this.logo;\n }\n return this._imageElement;\n }\n get playButtonRootElement() {\n return this._playButtonRootElement;\n }\n get playButtonElement() {\n return this._playButtonElement;\n }\n get _playButton() {\n const existingRoot = document.getElementById(\"excalibur-play-root\");\n if (existingRoot) this._playButtonRootElement = existingRoot;\n if (!this._playButtonRootElement) {\n this._playButtonRootElement = document.createElement(\"div\");\n this._playButtonRootElement.id = \"excalibur-play-root\";\n this._playButtonRootElement.style.position = \"absolute\";\n document.body.appendChild(this._playButtonRootElement);\n }\n if (!this._styleBlock) {\n this._styleBlock = document.createElement(\"style\");\n this._styleBlock.textContent = this._playButtonStyles;\n document.head.appendChild(this._styleBlock);\n }\n if (!this._playButtonElement) {\n this._playButtonElement = this.startButtonFactory();\n this._playButtonRootElement.appendChild(this._playButtonElement);\n }\n return this._playButtonElement;\n }\n /**\r\n * @param loadables Optionally provide the list of resources you want to load at constructor time\r\n */ constructor(loadables){\n this.events = new EventEmitter();\n this.canvas = new Canvas({\n filtering: ImageFiltering.Blended,\n smoothing: true,\n cache: true,\n draw: this.draw.bind(this)\n });\n this._resourceList = [];\n this._index = 0;\n this._playButtonShown = false;\n this._resourceCount = 0;\n this._numLoaded = 0;\n this._progressCounts = {};\n this._totalCounts = {};\n // logo drawing stuff\n // base64 string encoding of the excalibur logo (logo-white.png)\n this.logo = Loader_logo;\n this.logoWidth = 468;\n this.logoHeight = 118;\n /**\r\n * Gets or sets the color of the loading bar, default is [[Color.White]]\r\n */ this.loadingBarColor = Color.White;\n /**\r\n * Gets or sets the background color of the loader as a hex string\r\n */ this.backgroundColor = \"#176BAA\";\n this.suppressPlayButton = false;\n /** Loads the css from Loader.css */ this._playButtonStyles = Loader_0 /* default */ .Z.toString();\n /**\r\n * Get/set play button text\r\n */ this.playButtonText = \"Play game\";\n /**\r\n * Return a html button element for excalibur to use as a play button\r\n */ this.startButtonFactory = ()=>{\n let buttonElement = document.getElementById(\"excalibur-play\");\n if (!buttonElement) buttonElement = document.createElement(\"button\");\n buttonElement.id = \"excalibur-play\";\n buttonElement.textContent = this.playButtonText;\n buttonElement.style.display = \"none\";\n return buttonElement;\n };\n this._loadingFuture = new Future();\n if (loadables) this.addResources(loadables);\n }\n wireEngine(engine) {\n this._engine = engine;\n this.canvas.width = this._engine.canvas.width;\n this.canvas.height = this._engine.canvas.height;\n }\n /**\r\n * Add a resource to the loader to load\r\n * @param loadable Resource to add\r\n */ addResource(loadable) {\n const key = this._index++;\n this._resourceList.push(loadable);\n this._progressCounts[key] = 0;\n this._totalCounts[key] = 1;\n this._resourceCount++;\n }\n /**\r\n * Add a list of resources to the loader to load\r\n * @param loadables The list of resources to load\r\n */ addResources(loadables) {\n let i = 0;\n const len = loadables.length;\n for(i; i < len; i++)this.addResource(loadables[i]);\n }\n /**\r\n * Returns true if the loader has completely loaded all resources\r\n */ isLoaded() {\n return this._numLoaded === this._resourceCount;\n }\n /**\r\n * Shows the play button and returns a promise that resolves when clicked\r\n */ async showPlayButton() {\n var _a, _b;\n if (this.suppressPlayButton) {\n this.hidePlayButton();\n // Delay is to give the logo a chance to show, otherwise don't delay\n await delay(500, (_a = this._engine) === null || _a === void 0 ? void 0 : _a.clock);\n } else {\n const resizeHandler = ()=>{\n this._positionPlayButton();\n };\n if ((_b = this._engine) === null || _b === void 0 ? void 0 : _b.browser) this._engine.browser.window.on(\"resize\", resizeHandler);\n this._playButtonShown = true;\n this._playButton.style.display = \"block\";\n document.body.addEventListener(\"keyup\", (evt)=>{\n if (evt.key === \"Enter\") this._playButton.click();\n });\n this._positionPlayButton();\n const playButtonClicked = new Promise((resolve)=>{\n const startButtonHandler = (e)=>{\n var _a;\n // We want to stop propagation to keep bubbling to the engine pointer handlers\n e.stopPropagation();\n // Hide Button after click\n this.hidePlayButton();\n if ((_a = this._engine) === null || _a === void 0 ? void 0 : _a.browser) this._engine.browser.window.off(\"resize\", resizeHandler);\n resolve();\n };\n this._playButton.addEventListener(\"click\", startButtonHandler);\n this._playButton.addEventListener(\"touchend\", startButtonHandler);\n this._playButton.addEventListener(\"pointerup\", startButtonHandler);\n });\n return await playButtonClicked;\n }\n }\n hidePlayButton() {\n this._playButtonShown = false;\n this._playButton.style.display = \"none\";\n }\n /**\r\n * Clean up generated elements for the loader\r\n */ dispose() {\n if (this._playButtonRootElement.parentElement) {\n this._playButtonRootElement.removeChild(this._playButtonElement);\n document.body.removeChild(this._playButtonRootElement);\n document.head.removeChild(this._styleBlock);\n this._playButtonRootElement = null;\n this._playButtonElement = null;\n this._styleBlock = null;\n }\n }\n update(_engine, _delta) {\n // override me\n }\n areResourcesLoaded() {\n return this._loadingFuture.promise;\n }\n /**\r\n * Begin loading all of the supplied resources, returning a promise\r\n * that resolves when loading of all is complete AND the user has clicked the \"Play button\"\r\n */ async load() {\n var _a, _b;\n await ((_a = this._image) === null || _a === void 0 ? void 0 : _a.decode()); // decode logo if it exists\n this.canvas.flagDirty();\n await Promise.all(this._resourceList.map(async (r)=>{\n await r.load().finally(()=>{\n // capture progress\n this._numLoaded++;\n this.canvas.flagDirty();\n });\n }));\n // Wire all sound to the engine\n for (const resource of this._resourceList)if (resource instanceof Sound) resource.wireEngine(this._engine);\n this._loadingFuture.resolve();\n // short delay in showing the button for aesthetics\n await delay(200, (_b = this._engine) === null || _b === void 0 ? void 0 : _b.clock);\n this.canvas.flagDirty();\n await this.showPlayButton();\n // Unlock browser AudioContext in after user gesture\n // See: https://github.com/excaliburjs/Excalibur/issues/262\n // See: https://github.com/excaliburjs/Excalibur/issues/1031\n await WebAudio.unlock();\n return this.data = this._resourceList;\n }\n markResourceComplete() {\n this._numLoaded++;\n }\n /**\r\n * Returns the progress of the loader as a number between [0, 1] inclusive.\r\n */ get progress() {\n return this._resourceCount > 0 ? clamp(this._numLoaded, 0, this._resourceCount) / this._resourceCount : 1;\n }\n _positionPlayButton() {\n if (this._engine) {\n const screenHeight = this._engine.screen.viewport.height;\n const screenWidth = this._engine.screen.viewport.width;\n if (this._playButtonRootElement) {\n const left = this._engine.canvas.offsetLeft;\n const top = this._engine.canvas.offsetTop;\n const buttonWidth = this._playButton.clientWidth;\n const buttonHeight = this._playButton.clientHeight;\n if (this.playButtonPosition) {\n this._playButtonRootElement.style.left = `${this.playButtonPosition.x}px`;\n this._playButtonRootElement.style.top = `${this.playButtonPosition.y}px`;\n } else {\n this._playButtonRootElement.style.left = `${left + screenWidth / 2 - buttonWidth / 2}px`;\n this._playButtonRootElement.style.top = `${top + screenHeight / 2 - buttonHeight / 2 + 100}px`;\n }\n }\n }\n }\n /**\r\n * Loader draw function. Draws the default Excalibur loading screen.\r\n * Override `logo`, `logoWidth`, `logoHeight` and `backgroundColor` properties\r\n * to customize the drawing, or just override entire method.\r\n */ draw(ctx) {\n const canvasHeight = this._engine.canvasHeight / this._engine.pixelRatio;\n const canvasWidth = this._engine.canvasWidth / this._engine.pixelRatio;\n this._positionPlayButton();\n ctx.fillStyle = this.backgroundColor;\n ctx.fillRect(0, 0, canvasWidth, canvasHeight);\n let logoY = canvasHeight / 2;\n const width = Math.min(this.logoWidth, canvasWidth * 0.75);\n let logoX = canvasWidth / 2 - width / 2;\n if (this.logoPosition) {\n logoX = this.logoPosition.x;\n logoY = this.logoPosition.y;\n }\n const imageHeight = Math.floor(width * (this.logoHeight / this.logoWidth)); // OG height/width factor\n const oldAntialias = this._engine.getAntialiasing();\n this._engine.setAntialiasing(true);\n if (!this.logoPosition) ctx.drawImage(this._image, 0, 0, this.logoWidth, this.logoHeight, logoX, logoY - imageHeight - 20, width, imageHeight);\n else ctx.drawImage(this._image, 0, 0, this.logoWidth, this.logoHeight, logoX, logoY, width, imageHeight);\n // loading box\n if (!this.suppressPlayButton && this._playButtonShown) {\n this._engine.setAntialiasing(oldAntialias);\n return;\n }\n let loadingX = logoX;\n let loadingY = logoY;\n if (this.loadingBarPosition) {\n loadingX = this.loadingBarPosition.x;\n loadingY = this.loadingBarPosition.y;\n }\n ctx.lineWidth = 2;\n roundRect(ctx, loadingX, loadingY, width, 20, 10, this.loadingBarColor);\n const progress = width * this.progress;\n const margin = 5;\n const progressWidth = progress - margin * 2;\n const height = 20 - margin * 2;\n roundRect(ctx, loadingX + margin, loadingY + margin, progressWidth > 10 ? progressWidth : 10, height, 5, null, this.loadingBarColor);\n this._engine.setAntialiasing(oldAntialias);\n }\n emit(eventName, event) {\n this.events.emit(eventName, event);\n }\n on(eventName, handler) {\n return this.events.on(eventName, handler);\n }\n once(eventName, handler) {\n return this.events.once(eventName, handler);\n }\n off(eventName, handler) {\n this.events.off(eventName, handler);\n }\n }\n /**\r\n * This is the list of features that will be used to log the supported\r\n * features to the console when Detector.logBrowserFeatures() is called.\r\n */ const REPORTED_FEATURES = {\n webgl: \"WebGL\",\n webaudio: \"WebAudio\",\n gamepadapi: \"Gamepad API\"\n };\n /**\r\n * Excalibur internal feature detection helper class\r\n */ class Detector {\n constructor(){\n this._features = null;\n this.failedTests = [];\n // critical browser features required for ex to run\n this._criticalTests = {\n // Test canvas/2d context support\n canvasSupport: function() {\n const elem = document.createElement(\"canvas\");\n return !!(elem.getContext && elem.getContext(\"2d\"));\n },\n // Test array buffer support ex uses for downloading binary data\n arrayBufferSupport: function() {\n const xhr = new XMLHttpRequest();\n xhr.open(\"GET\", \"/\");\n try {\n xhr.responseType = \"arraybuffer\";\n } catch (e) {\n return false;\n }\n return xhr.responseType === \"arraybuffer\";\n },\n // Test data urls ex uses for sprites\n dataUrlSupport: function() {\n const canvas = document.createElement(\"canvas\");\n return canvas.toDataURL(\"image/png\").indexOf(\"data:image/png\") === 0;\n },\n // Test object url support for loading\n objectUrlSupport: function() {\n return \"URL\" in window && \"revokeObjectURL\" in URL && \"createObjectURL\" in URL;\n },\n // RGBA support for colors\n rgbaSupport: function() {\n const style = document.createElement(\"a\").style;\n style.cssText = \"background-color:rgba(150,255,150,.5)\";\n return (\"\" + style.backgroundColor).indexOf(\"rgba\") > -1;\n }\n };\n // warnings excalibur performance will be degraded\n this._warningTest = {\n webAudioSupport: function() {\n return !!(window.AudioContext || window.webkitAudioContext || window.mozAudioContext || window.msAudioContext || window.oAudioContext);\n },\n webglSupport: function() {\n const elem = document.createElement(\"canvas\");\n return !!(elem.getContext && elem.getContext(\"webgl\"));\n }\n };\n this._features = this._loadBrowserFeatures();\n }\n /**\r\n * Returns a map of currently supported browser features. This method\r\n * treats the features as a singleton and will only calculate feature\r\n * support if it has not previously been done.\r\n */ getBrowserFeatures() {\n if (this._features === null) this._features = this._loadBrowserFeatures();\n return this._features;\n }\n /**\r\n * Report on non-critical browser support for debugging purposes.\r\n * Use native browser console colors for visibility.\r\n */ logBrowserFeatures() {\n let msg = \"%cSUPPORTED BROWSER FEATURES\\n==========================%c\\n\";\n const args = [\n \"font-weight: bold; color: navy\",\n \"font-weight: normal; color: inherit\"\n ];\n const supported = this.getBrowserFeatures();\n for (const feature of Object.keys(REPORTED_FEATURES)){\n if (supported[feature]) {\n msg += \"(%c\\u2713%c)\"; // (✓)\n args.push(\"font-weight: bold; color: green\");\n args.push(\"font-weight: normal; color: inherit\");\n } else {\n msg += \"(%c\\u2717%c)\"; // (✗)\n args.push(\"font-weight: bold; color: red\");\n args.push(\"font-weight: normal; color: inherit\");\n }\n msg += \" \" + REPORTED_FEATURES[feature] + \"\\n\";\n }\n args.unshift(msg);\n // eslint-disable-next-line no-console\n console.log.apply(console, args);\n }\n /**\r\n * Executes several IIFE's to get a constant reference to supported\r\n * features within the current execution context.\r\n */ _loadBrowserFeatures() {\n return {\n // IIFE to check canvas support\n canvas: (()=>{\n return this._criticalTests.canvasSupport();\n })(),\n // IIFE to check arraybuffer support\n arraybuffer: (()=>{\n return this._criticalTests.arrayBufferSupport();\n })(),\n // IIFE to check dataurl support\n dataurl: (()=>{\n return this._criticalTests.dataUrlSupport();\n })(),\n // IIFE to check objecturl support\n objecturl: (()=>{\n return this._criticalTests.objectUrlSupport();\n })(),\n // IIFE to check rgba support\n rgba: (()=>{\n return this._criticalTests.rgbaSupport();\n })(),\n // IIFE to check webaudio support\n webaudio: (()=>{\n return this._warningTest.webAudioSupport();\n })(),\n // IIFE to check webgl support\n webgl: (()=>{\n return this._warningTest.webglSupport();\n })(),\n // IIFE to check gamepadapi support\n gamepadapi: (()=>{\n return !!navigator.getGamepads;\n })()\n };\n }\n test() {\n // Critical test will for ex not to run\n let failedCritical = false;\n for(const test in this._criticalTests)if (!this._criticalTests[test].call(this)) {\n this.failedTests.push(test);\n Logger.getInstance().error(\"Critical browser feature missing, Excalibur requires:\", test);\n failedCritical = true;\n }\n if (failedCritical) return false;\n // Warning tests do not for ex to return false to compatibility\n for(const warning in this._warningTest)if (!this._warningTest[warning]()) Logger.getInstance().warn(\"Warning browser feature missing, Excalibur will have reduced performance:\", warning);\n return true;\n }\n }\n /**\r\n * An enum that describes the types of collisions bodies can participate in\r\n */ var CollisionType;\n (function(CollisionType) {\n /**\r\n * Bodies with the `PreventCollision` setting do not participate in any\r\n * collisions and do not raise collision events.\r\n */ CollisionType[\"PreventCollision\"] = \"PreventCollision\";\n /**\r\n * Bodies with the `Passive` setting only raise collision events, but are not\r\n * influenced or moved by other bodies and do not influence or move other bodies.\r\n * This is useful for use in trigger type behavior.\r\n */ CollisionType[\"Passive\"] = \"Passive\";\n /**\r\n * Bodies with the `Active` setting raise collision events and participate\r\n * in collisions with other bodies and will be push or moved by bodies sharing\r\n * the `Active` or `Fixed` setting.\r\n */ CollisionType[\"Active\"] = \"Active\";\n /**\r\n * Bodies with the `Fixed` setting raise collision events and participate in\r\n * collisions with other bodies. Actors with the `Fixed` setting will not be\r\n * pushed or moved by other bodies sharing the `Fixed`. Think of Fixed\r\n * bodies as \"immovable/unstoppable\" objects. If two `Fixed` bodies meet they will\r\n * not be pushed or moved by each other, they will not interact except to throw\r\n * collision events.\r\n */ CollisionType[\"Fixed\"] = \"Fixed\";\n })(CollisionType || (CollisionType = {}));\n const maxMessages = 5;\n const obsoleteMessage = {};\n const resetObsoleteCounter = ()=>{\n for(const message in obsoleteMessage)obsoleteMessage[message] = 0;\n };\n const logMessage = (message, options)=>{\n const suppressObsoleteMessages = Flags.isEnabled(\"suppress-obsolete-message\");\n if (obsoleteMessage[message] < maxMessages && !suppressObsoleteMessages) {\n Logger.getInstance().warn(message);\n // tslint:disable-next-line: no-console\n if (console.trace && options.showStackTrace) // tslint:disable-next-line: no-console\n console.trace();\n }\n obsoleteMessage[message]++;\n };\n /**\r\n * Obsolete decorator for marking Excalibur methods obsolete, you can optionally specify a custom message and/or alternate replacement\r\n * method do the deprecated one. Inspired by https://github.com/jayphelps/core-decorators.js\r\n */ function obsolete(options) {\n options = {\n message: \"This feature will be removed in future versions of Excalibur.\",\n alternateMethod: null,\n showStackTrace: false,\n ...options\n };\n return function(target, property, descriptor) {\n if (descriptor && !(typeof descriptor.value === \"function\" || typeof descriptor.get === \"function\" || typeof descriptor.set === \"function\")) throw new SyntaxError(\"Only classes/functions/getters/setters can be marked as obsolete\");\n const methodSignature = `${target.name || \"\"}${target.name && property ? \".\" : \"\"}${property ? property : \"\"}`;\n const message = `${methodSignature} is marked obsolete: ${options.message}` + (options.alternateMethod ? ` Use ${options.alternateMethod} instead` : \"\");\n if (!obsoleteMessage[message]) obsoleteMessage[message] = 0;\n // If descriptor is null it is a class\n const method = descriptor ? {\n ...descriptor\n } : target;\n if (!descriptor) {\n // with es2015 classes we need to change our decoration tactic\n class DecoratedClass extends method {\n constructor(...args){\n logMessage(message, options);\n super(...args);\n }\n }\n return DecoratedClass;\n }\n if (descriptor && descriptor.value) {\n method.value = function() {\n logMessage(message, options);\n return descriptor.value.apply(this, arguments);\n };\n return method;\n }\n if (descriptor && descriptor.get) method.get = function() {\n logMessage(message, options);\n return descriptor.get.apply(this, arguments);\n };\n if (descriptor && descriptor.set) method.set = function() {\n logMessage(message, options);\n return descriptor.set.apply(this, arguments);\n };\n return method;\n };\n }\n var __decorate = function(decorators, target, key, desc) {\n var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;\n if (typeof Reflect === \"object\" && typeof Reflect.decorate === \"function\") r = Reflect.decorate(decorators, target, key, desc);\n else for(var i = decorators.length - 1; i >= 0; i--)if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;\n return c > 3 && r && Object.defineProperty(target, key, r), r;\n };\n /**\r\n * Possible collision resolution strategies\r\n *\r\n * The default is [[CollisionResolutionStrategy.Arcade]] which performs simple axis aligned arcade style physics. This is useful for things\r\n * like platformers or top down games.\r\n *\r\n * More advanced rigid body physics are enabled by setting [[CollisionResolutionStrategy.Realistic]] which allows for complicated\r\n * simulated physical interactions.\r\n */ var CollisionResolutionStrategy;\n (function(CollisionResolutionStrategy) {\n CollisionResolutionStrategy[\"Arcade\"] = \"arcade\";\n CollisionResolutionStrategy[\"Realistic\"] = \"realistic\";\n })(CollisionResolutionStrategy || (CollisionResolutionStrategy = {}));\n /**\r\n * Possible broadphase collision pair identification strategies\r\n *\r\n * The default strategy is [[BroadphaseStrategy.DynamicAABBTree]] which uses a binary tree of axis-aligned bounding boxes to identify\r\n * potential collision pairs which is O(nlog(n)) faster.\r\n */ var BroadphaseStrategy;\n (function(BroadphaseStrategy) {\n BroadphaseStrategy[BroadphaseStrategy[\"DynamicAABBTree\"] = 0] = \"DynamicAABBTree\";\n })(BroadphaseStrategy || (BroadphaseStrategy = {}));\n /**\r\n * Possible numerical integrators for position and velocity\r\n */ var Integrator;\n (function(Integrator) {\n Integrator[Integrator[\"Euler\"] = 0] = \"Euler\";\n })(Integrator || (Integrator = {}));\n /**\r\n * The [[Physics]] object is the global configuration object for all Excalibur physics.\r\n */ /* istanbul ignore next */ class Physics {\n static get gravity() {\n return Physics.acc;\n }\n static set gravity(v) {\n Physics.acc = v;\n }\n /**\r\n * Configures Excalibur to use \"arcade\" physics. Arcade physics which performs simple axis aligned arcade style physics.\r\n */ static useArcadePhysics() {\n Physics.collisionResolutionStrategy = CollisionResolutionStrategy.Arcade;\n }\n /**\r\n * Configures Excalibur to use rigid body physics. Rigid body physics allows for complicated\r\n * simulated physical interactions.\r\n */ static useRealisticPhysics() {\n Physics.collisionResolutionStrategy = CollisionResolutionStrategy.Realistic;\n }\n static get dynamicTreeVelocityMultiplyer() {\n return Physics.dynamicTreeVelocityMultiplier;\n }\n static set dynamicTreeVelocityMultiplyer(value) {\n Physics.dynamicTreeVelocityMultiplier = value;\n }\n }\n /**\r\n * Global acceleration that is applied to all vanilla actors that have a [[CollisionType.Active|active]] collision type.\r\n * Global acceleration won't effect [[Label|labels]], [[ScreenElement|ui actors]], or [[Trigger|triggers]] in Excalibur.\r\n *\r\n * This is a great way to globally simulate effects like gravity.\r\n */ Physics.acc = new Vector(0, 0);\n /**\r\n * Globally switches all Excalibur physics behavior on or off.\r\n */ Physics.enabled = true;\n /**\r\n * Gets or sets the broadphase pair identification strategy.\r\n *\r\n * The default strategy is [[BroadphaseStrategy.DynamicAABBTree]] which uses a binary tree of axis-aligned bounding boxes to identify\r\n * potential collision pairs which is O(nlog(n)) faster.\r\n */ Physics.broadphaseStrategy = BroadphaseStrategy.DynamicAABBTree;\n /**\r\n * Gets or sets the global collision resolution strategy (narrowphase).\r\n *\r\n * The default is [[CollisionResolutionStrategy.Arcade]] which performs simple axis aligned arcade style physics.\r\n *\r\n * More advanced rigid body physics are enabled by setting [[CollisionResolutionStrategy.Realistic]] which allows for complicated\r\n * simulated physical interactions.\r\n */ Physics.collisionResolutionStrategy = CollisionResolutionStrategy.Arcade;\n /**\r\n * The default mass to use if none is specified\r\n */ Physics.defaultMass = 10;\n /**\r\n * Gets or sets the position and velocity positional integrator, currently only Euler is supported.\r\n */ Physics.integrator = Integrator.Euler;\n /**\r\n * Factor to add to the RigidBody BoundingBox, bounding box (dimensions += vel * dynamicTreeVelocityMultiplier);\r\n */ Physics.dynamicTreeVelocityMultiplier = 2;\n /**\r\n * Pad RigidBody BoundingBox by a constant amount\r\n */ Physics.boundsPadding = 5;\n /**\r\n * Number of position iterations (overlap) to run in the solver\r\n */ Physics.positionIterations = 3;\n /**\r\n * Number of velocity iteration (response) to run in the solver\r\n */ Physics.velocityIterations = 8;\n /**\r\n * Amount of overlap to tolerate in pixels\r\n */ Physics.slop = 1;\n /**\r\n * Amount of positional overlap correction to apply each position iteration of the solver\r\n * O - meaning no correction, 1 - meaning correct all overlap\r\n */ Physics.steeringFactor = 0.2;\n /**\r\n * Warm start set to true re-uses impulses from previous frames back in the solver\r\n */ Physics.warmStart = true;\n /**\r\n * By default bodies do not sleep\r\n */ Physics.bodiesCanSleepByDefault = false;\n /**\r\n * Surface epsilon is used to help deal with surface penetration\r\n */ Physics.surfaceEpsilon = 0.1;\n Physics.sleepEpsilon = 0.07;\n Physics.wakeThreshold = Physics.sleepEpsilon * 3;\n Physics.sleepBias = 0.9;\n /**\r\n * Enable fast moving body checking, this enables checking for collision pairs via raycast for fast moving objects to prevent\r\n * bodies from tunneling through one another.\r\n */ Physics.checkForFastBodies = true;\n /**\r\n * Disable minimum fast moving body raycast, by default if ex.Physics.checkForFastBodies = true Excalibur will only check if the\r\n * body is moving at least half of its minimum dimension in an update. If ex.Physics.disableMinimumSpeedForFastBody is set to true,\r\n * Excalibur will always perform the fast body raycast regardless of speed.\r\n */ Physics.disableMinimumSpeedForFastBody = false;\n __decorate([\n obsolete({\n message: \"Alias for incorrect spelling used in older versions, will be removed in v0.25.0\",\n alternateMethod: \"dynamicTreeVelocityMultiplier\"\n })\n ], Physics, \"dynamicTreeVelocityMultiplyer\", null);\n /**\r\n * Enum representing the coordinate plane for the position 2D vector in the [[TransformComponent]]\r\n */ var CoordPlane;\n (function(CoordPlane) {\n /**\r\n * The world coordinate plane (default) represents world space, any entities drawn with world\r\n * space move when the camera moves.\r\n */ CoordPlane[\"World\"] = \"world\";\n /**\r\n * The screen coordinate plane represents screen space, entities drawn in screen space are pinned\r\n * to screen coordinates ignoring the camera.\r\n */ CoordPlane[\"Screen\"] = \"screen\";\n })(CoordPlane || (CoordPlane = {}));\n class VectorView extends Vector {\n constructor(options){\n super(0, 0);\n this._getX = options.getX;\n this._getY = options.getY;\n this._setX = options.setX;\n this._setY = options.setY;\n }\n get x() {\n return this._x = this._getX();\n }\n set x(val) {\n this._setX(val);\n this._x = val;\n }\n get y() {\n return this._y = this._getY();\n }\n set y(val) {\n this._setY(val);\n this._y = val;\n }\n }\n /**\r\n * Wraps a vector and watches for changes in the x/y, modifies the original vector.\r\n */ class WatchVector extends Vector {\n constructor(original, change){\n super(original.x, original.y);\n this.original = original;\n this.change = change;\n }\n get x() {\n return this._x = this.original.x;\n }\n set x(newX) {\n this.change(newX, this._y);\n this._x = this.original.x = newX;\n }\n get y() {\n return this._y = this.original.y;\n }\n set y(newY) {\n this.change(this._x, newY);\n this._y = this.original.y = newY;\n }\n }\n class Transform {\n constructor(){\n this._parent = null;\n this._children = [];\n this._pos = vec(0, 0);\n this._rotation = 0;\n this._scale = vec(1, 1);\n this._isDirty = false;\n this._isInverseDirty = false;\n this._matrix = AffineMatrix.identity();\n this._inverse = AffineMatrix.identity();\n }\n get parent() {\n return this._parent;\n }\n set parent(transform) {\n if (this._parent) {\n const index = this._parent._children.indexOf(this);\n if (index > -1) this._parent._children.splice(index, 1);\n }\n this._parent = transform;\n if (this._parent) this._parent._children.push(this);\n this.flagDirty();\n }\n get children() {\n return this._children;\n }\n set pos(v) {\n if (!v.equals(this._pos)) {\n this._pos.x = v.x;\n this._pos.y = v.y;\n this.flagDirty();\n }\n }\n get pos() {\n return new WatchVector(this._pos, (x, y)=>{\n if (x !== this._pos.x || y !== this._pos.y) this.flagDirty();\n });\n }\n set globalPos(v) {\n let localPos = v.clone();\n if (this.parent) localPos = this.parent.inverse.multiply(v);\n if (!localPos.equals(this._pos)) {\n this._pos = localPos;\n this.flagDirty();\n }\n }\n get globalPos() {\n return new VectorView({\n getX: ()=>this.matrix.data[4],\n getY: ()=>this.matrix.data[5],\n setX: (x)=>{\n if (this.parent) {\n const { x: newX } = this.parent.inverse.multiply(vec(x, this.pos.y));\n this.pos.x = newX;\n } else this.pos.x = x;\n if (x !== this.matrix.data[4]) this.flagDirty();\n },\n setY: (y)=>{\n if (this.parent) {\n const { y: newY } = this.parent.inverse.multiply(vec(this.pos.x, y));\n this.pos.y = newY;\n } else this.pos.y = y;\n if (y !== this.matrix.data[5]) this.flagDirty();\n }\n });\n }\n set rotation(rotation) {\n const canonRotation = canonicalizeAngle(rotation);\n if (canonRotation !== this._rotation) this.flagDirty();\n this._rotation = canonRotation;\n }\n get rotation() {\n return this._rotation;\n }\n set globalRotation(rotation) {\n let inverseRotation = 0;\n if (this.parent) inverseRotation = this.parent.globalRotation;\n const canonRotation = canonicalizeAngle(rotation + inverseRotation);\n if (canonRotation !== this._rotation) this.flagDirty();\n this._rotation = canonRotation;\n }\n get globalRotation() {\n if (this.parent) return this.matrix.getRotation();\n return this.rotation;\n }\n set scale(v) {\n if (!v.equals(this._scale)) {\n this._scale.x = v.x;\n this._scale.y = v.y;\n this.flagDirty();\n }\n }\n get scale() {\n return new WatchVector(this._scale, (x, y)=>{\n if (x !== this._scale.x || y !== this._scale.y) this.flagDirty();\n });\n }\n set globalScale(v) {\n let inverseScale = vec(1, 1);\n if (this.parent) inverseScale = this.parent.globalScale;\n this.scale = v.scale(vec(1 / inverseScale.x, 1 / inverseScale.y));\n }\n get globalScale() {\n return new VectorView({\n getX: ()=>this.parent ? this.matrix.getScaleX() : this.scale.x,\n getY: ()=>this.parent ? this.matrix.getScaleY() : this.scale.y,\n setX: (x)=>{\n if (this.parent) {\n const globalScaleX = this.parent.globalScale.x;\n this.scale.x = x / globalScaleX;\n } else this.scale.x = x;\n },\n setY: (y)=>{\n if (this.parent) {\n const globalScaleY = this.parent.globalScale.y;\n this.scale.y = y / globalScaleY;\n } else this.scale.y = y;\n }\n });\n }\n get matrix() {\n if (this._isDirty) {\n if (this.parent === null) this._matrix = this._calculateMatrix();\n else this._matrix = this.parent.matrix.multiply(this._calculateMatrix());\n this._isDirty = false;\n }\n return this._matrix;\n }\n get inverse() {\n if (this._isInverseDirty) {\n this._inverse = this.matrix.inverse();\n this._isInverseDirty = false;\n }\n return this._inverse;\n }\n _calculateMatrix() {\n const matrix = AffineMatrix.identity().translate(this.pos.x, this.pos.y).rotate(this.rotation).scale(this.scale.x, this.scale.y);\n return matrix;\n }\n flagDirty() {\n this._isDirty = true;\n this._isInverseDirty = true;\n for(let i = 0; i < this._children.length; i++)this._children[i].flagDirty();\n }\n apply(point) {\n return this.matrix.multiply(point);\n }\n applyInverse(point) {\n return this.inverse.multiply(point);\n }\n setTransform(pos, rotation, scale) {\n this._pos.x = pos.x;\n this._pos.y = pos.y;\n this._rotation = canonicalizeAngle(rotation);\n this._scale.x = scale.x;\n this._scale.y = scale.y;\n this.flagDirty();\n }\n clone(dest) {\n const target = dest !== null && dest !== void 0 ? dest : new Transform();\n this._pos.clone(target._pos);\n target._rotation = this._rotation;\n this._scale.clone(target._scale);\n target.flagDirty();\n return target;\n }\n }\n /**\r\n * Type guard to check if a component implements clone\r\n * @param x\r\n */ function hasClone(x) {\n return !!(x === null || x === void 0 ? void 0 : x.clone);\n }\n /**\r\n * Components are containers for state in Excalibur, the are meant to convey capabilities that an Entity possesses\r\n *\r\n * Implementations of Component must have a zero-arg constructor to support dependencies\r\n *\r\n * ```typescript\r\n * class MyComponent extends ex.Component<'my'> {\r\n * public readonly type = 'my';\r\n * // zero arg support required if you want to use component dependencies\r\n * constructor(public optionalPos?: ex.Vector) {}\r\n * }\r\n * ```\r\n */ class Component {\n constructor(){\n /**\r\n * Current owning [[Entity]], if any, of this component. Null if not added to any [[Entity]]\r\n */ this.owner = null;\n }\n /**\r\n * Clones any properties on this component, if that property value has a `clone()` method it will be called\r\n */ clone() {\n const newComponent = new this.constructor();\n for(const prop in this)if (this.hasOwnProperty(prop)) {\n const val = this[prop];\n if (hasClone(val) && prop !== \"owner\" && prop !== \"clone\") newComponent[prop] = val.clone();\n else newComponent[prop] = val;\n }\n return newComponent;\n }\n }\n /**\r\n * Tag components are a way of tagging a component with label and a simple value\r\n *\r\n * For example:\r\n *\r\n * ```typescript\r\n * const isOffscreen = new TagComponent('offscreen');\r\n * entity.addComponent(isOffscreen);\r\n * entity.tags.includes\r\n * ```\r\n */ class TagComponent extends Component {\n constructor(type, value){\n super();\n this.type = type;\n this.value = value;\n }\n }\n /**\r\n * Simple Observable implementation\r\n * @template T is the typescript Type that defines the data being observed\r\n */ class Observable {\n constructor(){\n this.observers = [];\n this.subscriptions = [];\n }\n /**\r\n * Register an observer to listen to this observable\r\n * @param observer\r\n */ register(observer) {\n this.observers.push(observer);\n }\n /**\r\n * Register a callback to listen to this observable\r\n * @param func\r\n */ subscribe(func) {\n this.subscriptions.push(func);\n }\n /**\r\n * Remove an observer from the observable\r\n * @param observer\r\n */ unregister(observer) {\n const i = this.observers.indexOf(observer);\n if (i !== -1) this.observers.splice(i, 1);\n }\n /**\r\n * Remove a callback that is listening to this observable\r\n * @param func\r\n */ unsubscribe(func) {\n const i = this.subscriptions.indexOf(func);\n if (i !== -1) this.subscriptions.splice(i, 1);\n }\n /**\r\n * Broadcasts a message to all observers and callbacks\r\n * @param message\r\n */ notifyAll(message) {\n const observersLength = this.observers.length;\n for(let i = 0; i < observersLength; i++)this.observers[i].notify(message);\n const subscriptionsLength = this.subscriptions.length;\n for(let i = 0; i < subscriptionsLength; i++)this.subscriptions[i](message);\n }\n /**\r\n * Removes all observers and callbacks\r\n */ clear() {\n this.observers.length = 0;\n this.subscriptions.length = 0;\n }\n }\n class TransformComponent extends Component {\n constructor(){\n super(...arguments);\n this.type = \"ex.transform\";\n this._transform = new Transform();\n this._addChildTransform = (child)=>{\n const childTxComponent = child.get(TransformComponent);\n if (childTxComponent) childTxComponent._transform.parent = this._transform;\n };\n /**\r\n * Observable that emits when the z index changes on this component\r\n */ this.zIndexChanged$ = new Observable();\n this._z = 0;\n /**\r\n * The [[CoordPlane|coordinate plane|]] for this transform for the entity.\r\n */ this.coordPlane = CoordPlane.World;\n }\n get() {\n return this._transform;\n }\n onAdd(owner) {\n for (const child of owner.children)this._addChildTransform(child);\n owner.childrenAdded$.subscribe((child)=>this._addChildTransform(child));\n owner.childrenRemoved$.subscribe((child)=>{\n const childTxComponent = child.get(TransformComponent);\n if (childTxComponent) childTxComponent._transform.parent = null;\n });\n }\n onRemove(_previousOwner) {\n this._transform.parent = null;\n }\n /**\r\n * The z-index ordering of the entity, a higher values are drawn on top of lower values.\r\n * For example z=99 would be drawn on top of z=0.\r\n */ get z() {\n return this._z;\n }\n set z(val) {\n const oldz = this._z;\n this._z = val;\n if (oldz !== val) this.zIndexChanged$.notifyAll(val);\n }\n get pos() {\n return this._transform.pos;\n }\n set pos(v) {\n this._transform.pos = v;\n }\n get globalPos() {\n return this._transform.globalPos;\n }\n set globalPos(v) {\n this._transform.globalPos = v;\n }\n get rotation() {\n return this._transform.rotation;\n }\n set rotation(rotation) {\n this._transform.rotation = rotation;\n }\n get globalRotation() {\n return this._transform.globalRotation;\n }\n set globalRotation(rotation) {\n this._transform.globalRotation = rotation;\n }\n get scale() {\n return this._transform.scale;\n }\n set scale(v) {\n this._transform.scale = v;\n }\n get globalScale() {\n return this._transform.globalScale;\n }\n set globalScale(v) {\n this._transform.globalScale = v;\n }\n applyInverse(v) {\n return this._transform.applyInverse(v);\n }\n apply(v) {\n return this._transform.apply(v);\n }\n clone() {\n const component = new TransformComponent();\n component._transform = this._transform.clone();\n component._z = this._z;\n return component;\n }\n }\n class MotionComponent extends Component {\n constructor(){\n super(...arguments);\n this.type = \"ex.motion\";\n /**\r\n * The velocity of an entity in pixels per second\r\n */ this.vel = Vector.Zero;\n /**\r\n * The acceleration of entity in pixels per second^2\r\n */ this.acc = Vector.Zero;\n /**\r\n * The scale rate of change in scale units per second\r\n */ this.scaleFactor = Vector.Zero;\n /**\r\n * The angular velocity which is how quickly the entity is rotating in radians per second\r\n */ this.angularVelocity = 0;\n /**\r\n * The amount of torque applied to the entity, angular acceleration is torque * inertia\r\n */ this.torque = 0;\n /**\r\n * Inertia can be thought of as the resistance to motion\r\n */ this.inertia = 1;\n }\n }\n /**\r\n * CollisionGroups indicate like members that do not collide with each other. Use [[CollisionGroupManager]] to create [[CollisionGroup]]s\r\n *\r\n * For example:\r\n *\r\n * Players have collision group \"player\"\r\n *\r\n * ![Player Collision Group](/assets/images/docs/CollisionGroupsPlayer.png)\r\n *\r\n * Enemies have collision group \"enemy\"\r\n *\r\n * ![Enemy Collision Group](/assets/images/docs/CollisionGroupsEnemy.png)\r\n *\r\n * Blocks have collision group \"ground\"\r\n *\r\n * ![Ground collision group](/assets/images/docs/CollisionGroupsGround.png)\r\n *\r\n * Players don't collide with each other, but enemies and blocks. Likewise, enemies don't collide with each other but collide\r\n * with players and blocks.\r\n *\r\n * This is done with bitmasking, see the following pseudo-code\r\n *\r\n * PlayerGroup = `0b001`\r\n * PlayerGroupMask = `0b110`\r\n *\r\n * EnemyGroup = `0b010`\r\n * EnemyGroupMask = `0b101`\r\n *\r\n * BlockGroup = `0b100`\r\n * BlockGroupMask = `0b011`\r\n *\r\n * Should Players collide? No because the bitwise mask evaluates to 0\r\n * `(player1.group & player2.mask) === 0`\r\n * `(0b001 & 0b110) === 0`\r\n *\r\n * Should Players and Enemies collide? Yes because the bitwise mask is non-zero\r\n * `(player1.group & enemy1.mask) === 1`\r\n * `(0b001 & 0b101) === 1`\r\n *\r\n * Should Players and Blocks collide? Yes because the bitwise mask is non-zero\r\n * `(player1.group & blocks1.mask) === 1`\r\n * `(0b001 & 0b011) === 1`\r\n */ class CollisionGroup {\n /**\r\n * STOP!!** It is preferred that [[CollisionGroupManager.create]] is used to create collision groups\r\n * unless you know how to construct the proper bitmasks. See https://github.com/excaliburjs/Excalibur/issues/1091 for more info.\r\n * @param name Name of the collision group\r\n * @param category 32 bit category for the group, should be a unique power of 2. For example `0b001` or `0b010`\r\n * @param mask 32 bit mask of category, or `~category` generally. For a category of `0b001`, the mask would be `0b110`\r\n */ constructor(name, category, mask){\n this._name = name;\n this._category = category;\n this._mask = mask;\n }\n /**\r\n * Get the name of the collision group\r\n */ get name() {\n return this._name;\n }\n /**\r\n * Get the category of the collision group, a 32 bit number which should be a unique power of 2\r\n */ get category() {\n return this._category;\n }\n /**\r\n * Get the mask for this collision group\r\n */ get mask() {\n return this._mask;\n }\n /**\r\n * Evaluates whether 2 collision groups can collide\r\n * @param other CollisionGroup\r\n */ canCollide(other) {\n return (this.category & other.mask) !== 0 && (other.category & this.mask) !== 0;\n }\n /**\r\n * Inverts the collision group. For example, if before the group specified \"players\",\r\n * inverting would specify all groups except players\r\n * @returns CollisionGroup\r\n */ invert() {\n return new CollisionGroup(\"~(\" + this.name + \")\", ~this.category, ~this.mask);\n }\n /**\r\n * Combine collision groups with each other. The new group includes all of the previous groups.\r\n *\r\n * @param collisionGroups\r\n */ static combine(collisionGroups) {\n const combinedName = collisionGroups.map((c)=>c.name).join(\"+\");\n const combinedCategory = collisionGroups.reduce((current, g)=>g.category | current, 0);\n const combinedMask = ~combinedCategory;\n return new CollisionGroup(combinedName, combinedCategory, combinedMask);\n }\n /**\r\n * Creates a collision group that collides with the listed groups\r\n * @param collisionGroups\r\n */ static collidesWith(collisionGroups) {\n return CollisionGroup.combine(collisionGroups).invert();\n }\n }\n /**\r\n * The `All` [[CollisionGroup]] is a special group that collides with all other groups including itself,\r\n * it is the default collision group on colliders.\r\n */ CollisionGroup.All = new CollisionGroup(\"Collide with all groups\", -1, -1);\n /**\r\n * Models a potential collision between 2 colliders\r\n */ class Pair {\n constructor(colliderA, colliderB){\n this.colliderA = colliderA;\n this.colliderB = colliderB;\n this.id = null;\n this.id = Pair.calculatePairHash(colliderA.id, colliderB.id);\n }\n /**\r\n * Returns whether a it is allowed for 2 colliders in a Pair to collide\r\n * @param colliderA\r\n * @param colliderB\r\n */ static canCollide(colliderA, colliderB) {\n var _a, _b;\n const bodyA = (_a = colliderA === null || colliderA === void 0 ? void 0 : colliderA.owner) === null || _a === void 0 ? void 0 : _a.get(BodyComponent);\n const bodyB = (_b = colliderB === null || colliderB === void 0 ? void 0 : colliderB.owner) === null || _b === void 0 ? void 0 : _b.get(BodyComponent);\n // Prevent self collision\n if (colliderA.id === colliderB.id) return false;\n // Colliders with the same owner do not collide (composite colliders)\n if (colliderA.owner && colliderB.owner && colliderA.owner.id === colliderB.owner.id) return false;\n // if the pair has a member with zero dimension don't collide\n if (colliderA.localBounds.hasZeroDimensions() || colliderB.localBounds.hasZeroDimensions()) return false;\n // Body's needed for collision in the current state\n // TODO can we collide without a body?\n if (!bodyA || !bodyB) return false;\n // If both are in the same collision group short circuit\n if (!bodyA.group.canCollide(bodyB.group)) return false;\n // if both are fixed short circuit\n if (bodyA.collisionType === CollisionType.Fixed && bodyB.collisionType === CollisionType.Fixed) return false;\n // if the either is prevent collision short circuit\n if (bodyB.collisionType === CollisionType.PreventCollision || bodyA.collisionType === CollisionType.PreventCollision) return false;\n // if either is dead short circuit\n if (!bodyA.active || !bodyB.active) return false;\n return true;\n }\n /**\r\n * Returns whether or not it is possible for the pairs to collide\r\n */ get canCollide() {\n const colliderA = this.colliderA;\n const colliderB = this.colliderB;\n return Pair.canCollide(colliderA, colliderB);\n }\n /**\r\n * Runs the collision intersection logic on the members of this pair\r\n */ collide() {\n return this.colliderA.collide(this.colliderB);\n }\n /**\r\n * Check if the collider is part of the pair\r\n * @param collider\r\n */ hasCollider(collider) {\n return collider === this.colliderA || collider === this.colliderB;\n }\n /**\r\n * Calculates the unique pair hash id for this collision pair (owning id)\r\n */ static calculatePairHash(idA, idB) {\n if (idA.value < idB.value) return `#${idA.value}+${idB.value}`;\n else return `#${idB.value}+${idA.value}`;\n }\n }\n /**\r\n * A 1 dimensional projection on an axis, used to test overlaps\r\n */ class Projection {\n constructor(min, max){\n this.min = min;\n this.max = max;\n }\n overlaps(projection) {\n return this.max > projection.min && projection.max > this.min;\n }\n getOverlap(projection) {\n if (this.overlaps(projection)) {\n if (this.max > projection.max) return projection.max - this.min;\n else return this.max - projection.min;\n }\n return 0;\n }\n }\n /**\r\n * Dynamic Tree Node used for tracking bounds within the tree\r\n */ class TreeNode {\n constructor(parent){\n this.parent = parent;\n this.parent = parent || null;\n this.data = null;\n this.bounds = new BoundingBox();\n this.left = null;\n this.right = null;\n this.height = 0;\n }\n isLeaf() {\n return !this.left && !this.right;\n }\n }\n /**\r\n * The DynamicTrees provides a spatial partitioning data structure for quickly querying for overlapping bounding boxes for\r\n * all tracked bodies. The worst case performance of this is O(n*log(n)) where n is the number of bodies in the tree.\r\n *\r\n * Internally the bounding boxes are organized as a balanced binary tree of bounding boxes, where the leaf nodes are tracked bodies.\r\n * Every non-leaf node is a bounding box that contains child bounding boxes.\r\n */ class DynamicTree {\n constructor(worldBounds = new BoundingBox(-Number.MAX_VALUE, -Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE)){\n this.worldBounds = worldBounds;\n this.root = null;\n this.nodes = {};\n }\n /**\r\n * Inserts a node into the dynamic tree\r\n */ _insert(leaf) {\n // If there are no nodes in the tree, make this the root leaf\n if (this.root === null) {\n this.root = leaf;\n this.root.parent = null;\n return;\n }\n // Search the tree for a node that is not a leaf and find the best place to insert\n const leafAABB = leaf.bounds;\n let currentRoot = this.root;\n while(!currentRoot.isLeaf()){\n const left = currentRoot.left;\n const right = currentRoot.right;\n const area = currentRoot.bounds.getPerimeter();\n const combinedAABB = currentRoot.bounds.combine(leafAABB);\n const combinedArea = combinedAABB.getPerimeter();\n // Calculate cost heuristic for creating a new parent and leaf\n const cost = 2 * combinedArea;\n // Minimum cost of pushing the leaf down the tree\n const inheritanceCost = 2 * (combinedArea - area);\n // Cost of descending\n let leftCost = 0;\n const leftCombined = leafAABB.combine(left.bounds);\n let newArea;\n let oldArea;\n if (left.isLeaf()) leftCost = leftCombined.getPerimeter() + inheritanceCost;\n else {\n oldArea = left.bounds.getPerimeter();\n newArea = leftCombined.getPerimeter();\n leftCost = newArea - oldArea + inheritanceCost;\n }\n let rightCost = 0;\n const rightCombined = leafAABB.combine(right.bounds);\n if (right.isLeaf()) rightCost = rightCombined.getPerimeter() + inheritanceCost;\n else {\n oldArea = right.bounds.getPerimeter();\n newArea = rightCombined.getPerimeter();\n rightCost = newArea - oldArea + inheritanceCost;\n }\n // cost is acceptable\n if (cost < leftCost && cost < rightCost) break;\n // Descend to the depths\n if (leftCost < rightCost) currentRoot = left;\n else currentRoot = right;\n }\n // Create the new parent node and insert into the tree\n const oldParent = currentRoot.parent;\n const newParent = new TreeNode(oldParent);\n newParent.bounds = leafAABB.combine(currentRoot.bounds);\n newParent.height = currentRoot.height + 1;\n if (oldParent !== null) {\n // The sibling node was not the root\n if (oldParent.left === currentRoot) oldParent.left = newParent;\n else oldParent.right = newParent;\n newParent.left = currentRoot;\n newParent.right = leaf;\n currentRoot.parent = newParent;\n leaf.parent = newParent;\n } else {\n // The sibling node was the root\n newParent.left = currentRoot;\n newParent.right = leaf;\n currentRoot.parent = newParent;\n leaf.parent = newParent;\n this.root = newParent;\n }\n // Walk up the tree fixing heights and AABBs\n let currentNode = leaf.parent;\n while(currentNode){\n currentNode = this._balance(currentNode);\n if (!currentNode.left) throw new Error(\"Parent of current leaf cannot have a null left child\" + currentNode);\n if (!currentNode.right) throw new Error(\"Parent of current leaf cannot have a null right child\" + currentNode);\n currentNode.height = 1 + Math.max(currentNode.left.height, currentNode.right.height);\n currentNode.bounds = currentNode.left.bounds.combine(currentNode.right.bounds);\n currentNode = currentNode.parent;\n }\n }\n /**\r\n * Removes a node from the dynamic tree\r\n */ _remove(leaf) {\n if (leaf === this.root) {\n this.root = null;\n return;\n }\n const parent = leaf.parent;\n const grandParent = parent.parent;\n let sibling;\n if (parent.left === leaf) sibling = parent.right;\n else sibling = parent.left;\n if (grandParent) {\n if (grandParent.left === parent) grandParent.left = sibling;\n else grandParent.right = sibling;\n sibling.parent = grandParent;\n let currentNode = grandParent;\n while(currentNode){\n currentNode = this._balance(currentNode);\n currentNode.bounds = currentNode.left.bounds.combine(currentNode.right.bounds);\n currentNode.height = 1 + Math.max(currentNode.left.height, currentNode.right.height);\n currentNode = currentNode.parent;\n }\n } else {\n this.root = sibling;\n sibling.parent = null;\n }\n }\n /**\r\n * Tracks a body in the dynamic tree\r\n */ trackCollider(collider) {\n const node = new TreeNode();\n node.data = collider;\n node.bounds = collider.bounds;\n node.bounds.left -= 2;\n node.bounds.top -= 2;\n node.bounds.right += 2;\n node.bounds.bottom += 2;\n this.nodes[collider.id.value] = node;\n this._insert(node);\n }\n /**\r\n * Updates the dynamic tree given the current bounds of each body being tracked\r\n */ updateCollider(collider) {\n var _a;\n const node = this.nodes[collider.id.value];\n if (!node) return false;\n const b = collider.bounds;\n // if the body is outside the world no longer update it\n if (!this.worldBounds.contains(b)) {\n Logger.getInstance().warn(\"Collider with id \" + collider.id.value + \" is outside the world bounds and will no longer be tracked for physics\");\n this.untrackCollider(collider);\n return false;\n }\n if (node.bounds.contains(b)) return false;\n this._remove(node);\n b.left -= Physics.boundsPadding;\n b.top -= Physics.boundsPadding;\n b.right += Physics.boundsPadding;\n b.bottom += Physics.boundsPadding;\n // THIS IS CAUSING UNECESSARY CHECKS\n if (collider.owner) {\n const body = (_a = collider.owner) === null || _a === void 0 ? void 0 : _a.get(BodyComponent);\n if (body) {\n const multdx = body.vel.x * 32 / 1000 * Physics.dynamicTreeVelocityMultiplier;\n const multdy = body.vel.y * 32 / 1000 * Physics.dynamicTreeVelocityMultiplier;\n if (multdx < 0) b.left += multdx;\n else b.right += multdx;\n if (multdy < 0) b.top += multdy;\n else b.bottom += multdy;\n }\n }\n node.bounds = b;\n this._insert(node);\n return true;\n }\n /**\r\n * Untracks a body from the dynamic tree\r\n */ untrackCollider(collider) {\n const node = this.nodes[collider.id.value];\n if (!node) return;\n this._remove(node);\n this.nodes[collider.id.value] = null;\n delete this.nodes[collider.id.value];\n }\n /**\r\n * Balances the tree about a node\r\n */ _balance(node) {\n if (node === null) throw new Error(\"Cannot balance at null node\");\n if (node.isLeaf() || node.height < 2) return node;\n const left = node.left;\n const right = node.right;\n const a = node;\n const b = left;\n const c = right;\n const d = left.left;\n const e = left.right;\n const f = right.left;\n const g = right.right;\n const balance = c.height - b.height;\n // Rotate c node up\n if (balance > 1) {\n // Swap the right node with it's parent\n c.left = a;\n c.parent = a.parent;\n a.parent = c;\n // The original node's old parent should point to the right node\n // this is mega confusing\n if (c.parent) {\n if (c.parent.left === a) c.parent.left = c;\n else c.parent.right = c;\n } else this.root = c;\n // Rotate\n if (f.height > g.height) {\n c.right = f;\n a.right = g;\n g.parent = a;\n a.bounds = b.bounds.combine(g.bounds);\n c.bounds = a.bounds.combine(f.bounds);\n a.height = 1 + Math.max(b.height, g.height);\n c.height = 1 + Math.max(a.height, f.height);\n } else {\n c.right = g;\n a.right = f;\n f.parent = a;\n a.bounds = b.bounds.combine(f.bounds);\n c.bounds = a.bounds.combine(g.bounds);\n a.height = 1 + Math.max(b.height, f.height);\n c.height = 1 + Math.max(a.height, g.height);\n }\n return c;\n }\n // Rotate left node up\n if (balance < -1) {\n // swap\n b.left = a;\n b.parent = a.parent;\n a.parent = b;\n // node's old parent should point to b\n if (b.parent) {\n if (b.parent.left === a) b.parent.left = b;\n else {\n if (b.parent.right !== a) throw \"Error rotating Dynamic Tree\";\n b.parent.right = b;\n }\n } else this.root = b;\n // rotate\n if (d.height > e.height) {\n b.right = d;\n a.left = e;\n e.parent = a;\n a.bounds = c.bounds.combine(e.bounds);\n b.bounds = a.bounds.combine(d.bounds);\n a.height = 1 + Math.max(c.height, e.height);\n b.height = 1 + Math.max(a.height, d.height);\n } else {\n b.right = e;\n a.left = d;\n d.parent = a;\n a.bounds = c.bounds.combine(d.bounds);\n b.bounds = a.bounds.combine(e.bounds);\n a.height = 1 + Math.max(c.height, d.height);\n b.height = 1 + Math.max(a.height, e.height);\n }\n return b;\n }\n return node;\n }\n /**\r\n * Returns the internal height of the tree, shorter trees are better. Performance drops as the tree grows\r\n */ getHeight() {\n if (this.root === null) return 0;\n return this.root.height;\n }\n /**\r\n * Queries the Dynamic Axis Aligned Tree for bodies that could be colliding with the provided body.\r\n *\r\n * In the query callback, it will be passed a potential collider. Returning true from this callback indicates\r\n * that you are complete with your query and you do not want to continue. Returning false will continue searching\r\n * the tree until all possible colliders have been returned.\r\n */ query(collider, callback) {\n const bounds = collider.bounds;\n const helper = (currentNode)=>{\n if (currentNode && currentNode.bounds.overlaps(bounds)) {\n if (currentNode.isLeaf() && currentNode.data !== collider) {\n if (callback.call(collider, currentNode.data)) return true;\n } else return helper(currentNode.left) || helper(currentNode.right);\n }\n return false;\n };\n helper(this.root);\n }\n /**\r\n * Queries the Dynamic Axis Aligned Tree for bodies that could be intersecting. By default the raycast query uses an infinitely\r\n * long ray to test the tree specified by `max`.\r\n *\r\n * In the query callback, it will be passed a potential body that intersects with the raycast. Returning true from this\r\n * callback indicates that your are complete with your query and do not want to continue. Return false will continue searching\r\n * the tree until all possible bodies that would intersect with the ray have been returned.\r\n */ rayCastQuery(ray, max = Infinity, callback) {\n const helper = (currentNode)=>{\n if (currentNode && currentNode.bounds.rayCast(ray, max)) {\n if (currentNode.isLeaf()) {\n if (callback.call(ray, currentNode.data)) // ray hit a leaf! return the body\n return true;\n } else // ray hit but not at a leaf, recurse deeper\n return helper(currentNode.left) || helper(currentNode.right);\n }\n return false; // ray missed\n };\n helper(this.root);\n }\n getNodes() {\n const helper = (currentNode)=>{\n if (currentNode) return [\n currentNode\n ].concat(helper(currentNode.left), helper(currentNode.right));\n else return [];\n };\n return helper(this.root);\n }\n debug(ex) {\n // draw all the nodes in the Dynamic Tree\n const helper = (currentNode)=>{\n if (currentNode) {\n if (currentNode.isLeaf()) currentNode.bounds.draw(ex, Color.Green);\n else currentNode.bounds.draw(ex, Color.White);\n if (currentNode.left) helper(currentNode.left);\n if (currentNode.right) helper(currentNode.right);\n }\n };\n helper(this.root);\n }\n }\n /**\r\n * A 2D ray that can be cast into the scene to do collision detection\r\n */ class Ray {\n /**\r\n * @param pos The starting position for the ray\r\n * @param dir The vector indicating the direction of the ray\r\n */ constructor(pos, dir){\n this.pos = pos;\n this.dir = dir.normalize();\n }\n /**\r\n * Tests a whether this ray intersects with a line segment. Returns a number greater than or equal to 0 on success.\r\n * This number indicates the mathematical intersection time.\r\n * @param line The line to test\r\n */ intersect(line) {\n const numerator = line.begin.sub(this.pos);\n // Test is line and ray are parallel and non intersecting\n if (this.dir.cross(line.getSlope()) === 0 && numerator.cross(this.dir) !== 0) return -1;\n // Lines are parallel\n const divisor = this.dir.cross(line.getSlope());\n if (divisor === 0) return -1;\n const t = numerator.cross(line.getSlope()) / divisor;\n if (t >= 0) {\n const u = numerator.cross(this.dir) / divisor / line.getLength();\n if (u >= 0 && u <= 1) return t;\n }\n return -1;\n }\n intersectPoint(line) {\n const time = this.intersect(line);\n if (time < 0) return null;\n return this.getPoint(time);\n }\n /**\r\n * Returns the point of intersection given the intersection time\r\n */ getPoint(time) {\n return this.pos.add(this.dir.scale(time));\n }\n }\n /**\r\n * Responsible for performing the collision broadphase (locating potential collisions) and\r\n * the narrowphase (actual collision contacts)\r\n */ class DynamicTreeCollisionProcessor {\n constructor(){\n this._dynamicCollisionTree = new DynamicTree();\n this._pairs = new Set();\n this._collisionPairCache = [];\n this._colliders = [];\n }\n getColliders() {\n return this._colliders;\n }\n rayCast(ray, options) {\n var _a, _b, _c;\n const results = [];\n const maxDistance = (_a = options === null || options === void 0 ? void 0 : options.maxDistance) !== null && _a !== void 0 ? _a : Infinity;\n const collisionGroup = (_b = options === null || options === void 0 ? void 0 : options.collisionGroup) !== null && _b !== void 0 ? _b : CollisionGroup.All;\n const searchAllColliders = (_c = options === null || options === void 0 ? void 0 : options.searchAllColliders) !== null && _c !== void 0 ? _c : false;\n this._dynamicCollisionTree.rayCastQuery(ray, maxDistance, (collider)=>{\n var _a;\n const owner = collider.owner;\n const maybeBody = owner.get(BodyComponent);\n // Early exit if not the right group\n if (collisionGroup.mask !== CollisionGroup.All.mask && ((_a = maybeBody === null || maybeBody === void 0 ? void 0 : maybeBody.group) === null || _a === void 0 ? void 0 : _a.mask) !== collisionGroup.mask) return false;\n const hit = collider.rayCast(ray, maxDistance);\n if (hit) {\n results.push({\n distance: hit.sub(ray.pos).distance(),\n point: hit,\n collider: collider,\n body: maybeBody\n });\n if (!searchAllColliders) // returning true exits the search\n return true;\n }\n return false;\n });\n return results;\n }\n /**\r\n * Tracks a physics body for collisions\r\n */ track(target) {\n if (!target) {\n Logger.getInstance().warn(\"Cannot track null collider\");\n return;\n }\n if (target instanceof CompositeCollider) {\n const colliders = target.getColliders();\n for (const c of colliders){\n c.owner = target.owner;\n this._colliders.push(c);\n this._dynamicCollisionTree.trackCollider(c);\n }\n } else {\n this._colliders.push(target);\n this._dynamicCollisionTree.trackCollider(target);\n }\n }\n /**\r\n * Untracks a physics body\r\n */ untrack(target) {\n if (!target) {\n Logger.getInstance().warn(\"Cannot untrack a null collider\");\n return;\n }\n if (target instanceof CompositeCollider) {\n const colliders = target.getColliders();\n for (const c of colliders){\n const index = this._colliders.indexOf(c);\n if (index !== -1) this._colliders.splice(index, 1);\n this._dynamicCollisionTree.untrackCollider(c);\n }\n } else {\n const index = this._colliders.indexOf(target);\n if (index !== -1) this._colliders.splice(index, 1);\n this._dynamicCollisionTree.untrackCollider(target);\n }\n }\n _pairExists(colliderA, colliderB) {\n // if the collision pair has been calculated already short circuit\n const hash = Pair.calculatePairHash(colliderA.id, colliderB.id);\n return this._pairs.has(hash);\n }\n /**\r\n * Detects potential collision pairs in a broadphase approach with the dynamic AABB tree strategy\r\n */ broadphase(targets, delta, stats) {\n const seconds = delta / 1000;\n // Retrieve the list of potential colliders, exclude killed, prevented, and self\n const potentialColliders = targets.filter((other)=>{\n var _a, _b;\n const body = (_a = other.owner) === null || _a === void 0 ? void 0 : _a.get(BodyComponent);\n return ((_b = other.owner) === null || _b === void 0 ? void 0 : _b.active) && body.collisionType !== CollisionType.PreventCollision;\n });\n // clear old list of collision pairs\n this._collisionPairCache = [];\n this._pairs.clear();\n // check for normal collision pairs\n let collider;\n for(let j = 0, l = potentialColliders.length; j < l; j++){\n collider = potentialColliders[j];\n // Query the collision tree for potential colliders\n this._dynamicCollisionTree.query(collider, (other)=>{\n if (!this._pairExists(collider, other) && Pair.canCollide(collider, other)) {\n const pair = new Pair(collider, other);\n this._pairs.add(pair.id);\n this._collisionPairCache.push(pair);\n }\n // Always return false, to query whole tree. Returning true in the query method stops searching\n return false;\n });\n }\n if (stats) stats.physics.pairs = this._collisionPairCache.length;\n // Check dynamic tree for fast moving objects\n // Fast moving objects are those moving at least there smallest bound per frame\n if (Physics.checkForFastBodies) for (const collider of potentialColliders){\n const body = collider.owner.get(BodyComponent);\n // Skip non-active objects. Does not make sense on other collision types\n if (body.collisionType !== CollisionType.Active) continue;\n // Maximum travel distance next frame\n const updateDistance = body.vel.size * seconds + // velocity term\n body.acc.size * 0.5 * seconds * seconds; // acc term\n // Find the minimum dimension\n const minDimension = Math.min(collider.bounds.height, collider.bounds.width);\n if (Physics.disableMinimumSpeedForFastBody || updateDistance > minDimension / 2) {\n if (stats) stats.physics.fastBodies++;\n // start with the oldPos because the integration for actors has already happened\n // objects resting on a surface may be slightly penetrating in the current position\n const updateVec = body.globalPos.sub(body.oldPos);\n const centerPoint = collider.center;\n const furthestPoint = collider.getFurthestPoint(body.vel);\n const origin = furthestPoint.sub(updateVec);\n const ray = new Ray(origin, body.vel);\n // back the ray up by -2x surfaceEpsilon to account for fast moving objects starting on the surface\n ray.pos = ray.pos.add(ray.dir.scale(-2 * Physics.surfaceEpsilon));\n let minCollider;\n let minTranslate = new Vector(Infinity, Infinity);\n this._dynamicCollisionTree.rayCastQuery(ray, updateDistance + Physics.surfaceEpsilon * 2, (other)=>{\n if (!this._pairExists(collider, other) && Pair.canCollide(collider, other)) {\n const hitPoint = other.rayCast(ray, updateDistance + Physics.surfaceEpsilon * 10);\n if (hitPoint) {\n const translate = hitPoint.sub(origin);\n if (translate.size < minTranslate.size) {\n minTranslate = translate;\n minCollider = other;\n }\n }\n }\n return false;\n });\n if (minCollider && Vector.isValid(minTranslate)) {\n const pair = new Pair(collider, minCollider);\n if (!this._pairs.has(pair.id)) {\n this._pairs.add(pair.id);\n this._collisionPairCache.push(pair);\n }\n // move the fast moving object to the other body\n // need to push into the surface by ex.Physics.surfaceEpsilon\n const shift = centerPoint.sub(furthestPoint);\n body.globalPos = origin.add(shift).add(minTranslate).add(ray.dir.scale(10 * Physics.surfaceEpsilon)); // needed to push the shape slightly into contact\n collider.update(body.transform.get());\n if (stats) stats.physics.fastBodyCollisions++;\n }\n }\n }\n // return cache\n return this._collisionPairCache;\n }\n /**\r\n * Applies narrow phase on collision pairs to find actual area intersections\r\n * Adds actual colliding pairs to stats' Frame data\r\n */ narrowphase(pairs, stats) {\n let contacts = [];\n for(let i = 0; i < pairs.length; i++){\n const newContacts = pairs[i].collide();\n contacts = contacts.concat(newContacts);\n if (stats && newContacts.length > 0) for (const c of newContacts)stats.physics.contacts.set(c.id, c);\n }\n if (stats) stats.physics.collisions += contacts.length;\n return contacts;\n }\n /**\r\n * Update the dynamic tree positions\r\n */ update(targets) {\n let updated = 0;\n const len = targets.length;\n for(let i = 0; i < len; i++)if (this._dynamicCollisionTree.updateCollider(targets[i])) updated++;\n return updated;\n }\n debug(ex) {\n this._dynamicCollisionTree.debug(ex);\n }\n }\n /**\r\n * A collision collider specifies the geometry that can detect when other collision colliders intersect\r\n * for the purposes of colliding 2 objects in excalibur.\r\n */ class Collider {\n constructor(){\n this.id = createId(\"collider\", Collider._ID++);\n /**\r\n * Excalibur uses this to signal to the [[CollisionSystem]] this is part of a composite collider\r\n * @internal\r\n * @hidden\r\n */ this.__compositeColliderId = null;\n this.events = new EventEmitter();\n }\n /**\r\n * Returns a boolean indicating whether this body collided with\r\n * or was in stationary contact with\r\n * the body of the other [[Collider]]\r\n */ touching(other) {\n const contact = this.collide(other);\n if (contact) return true;\n return false;\n }\n }\n Collider._ID = 0;\n class CompositeCollider extends Collider {\n constructor(colliders){\n super();\n this._collisionProcessor = new DynamicTreeCollisionProcessor();\n this._dynamicAABBTree = new DynamicTree();\n this._colliders = [];\n for (const c of colliders)this.addCollider(c);\n }\n clearColliders() {\n this._colliders = [];\n }\n addCollider(collider) {\n collider.events.pipe(this.events);\n collider.__compositeColliderId = this.id;\n this._colliders.push(collider);\n this._collisionProcessor.track(collider);\n this._dynamicAABBTree.trackCollider(collider);\n }\n removeCollider(collider) {\n collider.events.pipe(this.events);\n collider.__compositeColliderId = null;\n removeItemFromArray(collider, this._colliders);\n this._collisionProcessor.untrack(collider);\n this._dynamicAABBTree.untrackCollider(collider);\n }\n getColliders() {\n return this._colliders;\n }\n get worldPos() {\n var _a, _b;\n // TODO transform component world pos\n return (_b = (_a = this._transform) === null || _a === void 0 ? void 0 : _a.pos) !== null && _b !== void 0 ? _b : Vector.Zero;\n }\n get center() {\n var _a, _b;\n return (_b = (_a = this._transform) === null || _a === void 0 ? void 0 : _a.pos) !== null && _b !== void 0 ? _b : Vector.Zero;\n }\n get bounds() {\n var _a, _b;\n // TODO cache this\n const colliders = this.getColliders();\n const results = colliders.reduce((acc, collider)=>acc.combine(collider.bounds), (_b = (_a = colliders[0]) === null || _a === void 0 ? void 0 : _a.bounds) !== null && _b !== void 0 ? _b : new BoundingBox().translate(this.worldPos));\n return results;\n }\n get localBounds() {\n var _a, _b;\n // TODO cache this\n const colliders = this.getColliders();\n const results = colliders.reduce((acc, collider)=>acc.combine(collider.localBounds), (_b = (_a = colliders[0]) === null || _a === void 0 ? void 0 : _a.localBounds) !== null && _b !== void 0 ? _b : new BoundingBox());\n return results;\n }\n get axes() {\n // TODO cache this\n const colliders = this.getColliders();\n let axes = [];\n for (const collider of colliders)axes = axes.concat(collider.axes);\n return axes;\n }\n getFurthestPoint(direction) {\n const colliders = this.getColliders();\n const furthestPoints = [];\n for (const collider of colliders)furthestPoints.push(collider.getFurthestPoint(direction));\n // Pick best point from all colliders\n let bestPoint = furthestPoints[0];\n let maxDistance = -Number.MAX_VALUE;\n for (const point of furthestPoints){\n const distance = point.dot(direction);\n if (distance > maxDistance) {\n bestPoint = point;\n maxDistance = distance;\n }\n }\n return bestPoint;\n }\n getInertia(mass) {\n const colliders = this.getColliders();\n let totalInertia = 0;\n for (const collider of colliders)totalInertia += collider.getInertia(mass);\n return totalInertia;\n }\n collide(other) {\n let otherColliders = [\n other\n ];\n if (other instanceof CompositeCollider) otherColliders = other.getColliders();\n const pairs = [];\n for (const c of otherColliders)this._dynamicAABBTree.query(c, (potentialCollider)=>{\n pairs.push(new Pair(c, potentialCollider));\n return false;\n });\n let contacts = [];\n for (const p of pairs)contacts = contacts.concat(p.collide());\n return contacts;\n }\n getClosestLineBetween(other) {\n const colliders = this.getColliders();\n const lines = [];\n if (other instanceof CompositeCollider) {\n const otherColliders = other.getColliders();\n for (const colliderA of colliders)for (const colliderB of otherColliders){\n const maybeLine = colliderA.getClosestLineBetween(colliderB);\n if (maybeLine) lines.push(maybeLine);\n }\n } else for (const collider of colliders){\n const maybeLine = other.getClosestLineBetween(collider);\n if (maybeLine) lines.push(maybeLine);\n }\n if (lines.length) {\n let minLength = lines[0].getLength();\n let minLine = lines[0];\n for (const line of lines){\n const length = line.getLength();\n if (length < minLength) {\n minLength = length;\n minLine = line;\n }\n }\n return minLine;\n }\n return null;\n }\n contains(point) {\n const colliders = this.getColliders();\n for (const collider of colliders){\n if (collider.contains(point)) return true;\n }\n return false;\n }\n rayCast(ray, max) {\n const colliders = this.getColliders();\n const points = [];\n for (const collider of colliders){\n const vec = collider.rayCast(ray, max);\n if (vec) points.push(vec);\n }\n if (points.length) {\n let minPoint = points[0];\n let minDistance = minPoint.dot(ray.dir);\n for (const point of points){\n const distance = ray.dir.dot(point);\n if (distance < minDistance) {\n minPoint = point;\n minDistance = distance;\n }\n }\n return minPoint;\n }\n return null;\n }\n project(axis) {\n const colliders = this.getColliders();\n const projs = [];\n for (const collider of colliders){\n const proj = collider.project(axis);\n if (proj) projs.push(proj);\n }\n // Merge all proj's on the same axis\n if (projs.length) {\n const newProjection = new Projection(projs[0].min, projs[0].max);\n for (const proj of projs){\n newProjection.min = Math.min(proj.min, newProjection.min);\n newProjection.max = Math.max(proj.max, newProjection.max);\n }\n return newProjection;\n }\n return null;\n }\n update(transform) {\n if (transform) {\n const colliders = this.getColliders();\n for (const collider of colliders){\n collider.owner = this.owner;\n collider.update(transform);\n }\n }\n }\n debug(ex, color) {\n const colliders = this.getColliders();\n for (const collider of colliders)collider.debug(ex, color);\n }\n clone() {\n return new CompositeCollider(this._colliders.map((c)=>c.clone()));\n }\n }\n /**\r\n * A 2D line segment\r\n */ class LineSegment {\n /**\r\n * @param begin The starting point of the line segment\r\n * @param end The ending point of the line segment\r\n */ constructor(begin, end){\n this.begin = begin;\n this.end = end;\n }\n /**\r\n * Gets the raw slope (m) of the line. Will return (+/-)Infinity for vertical lines.\r\n */ get slope() {\n return (this.end.y - this.begin.y) / (this.end.x - this.begin.x);\n }\n /**\r\n * Gets the Y-intercept (b) of the line. Will return (+/-)Infinity if there is no intercept.\r\n */ get intercept() {\n return this.begin.y - this.slope * this.begin.x;\n }\n /**\r\n * Gets the normal of the line\r\n */ normal() {\n if (this._normal) return this._normal;\n return this._normal = this.end.sub(this.begin).normal();\n }\n dir() {\n if (this._dir) return this._dir;\n return this._dir = this.end.sub(this.begin);\n }\n getPoints() {\n return [\n this.begin,\n this.end\n ];\n }\n /**\r\n * Returns the slope of the line in the form of a vector of length 1\r\n */ getSlope() {\n if (this._slope) return this._slope;\n const begin = this.begin;\n const end = this.end;\n const distance = begin.distance(end);\n return this._slope = end.sub(begin).scale(1 / distance);\n }\n /**\r\n * Returns the edge of the line as vector, the length of the vector is the length of the edge\r\n */ getEdge() {\n const begin = this.begin;\n const end = this.end;\n return end.sub(begin);\n }\n /**\r\n * Returns the length of the line segment in pixels\r\n */ getLength() {\n if (this._length) return this._length;\n const begin = this.begin;\n const end = this.end;\n const distance = begin.distance(end);\n return this._length = distance;\n }\n /**\r\n * Returns the midpoint of the edge\r\n */ get midpoint() {\n return this.begin.add(this.end).scale(0.5);\n }\n /**\r\n * Flips the direction of the line segment\r\n */ flip() {\n return new LineSegment(this.end, this.begin);\n }\n /**\r\n * Tests if a given point is below the line, points in the normal direction above the line are considered above.\r\n * @param point\r\n */ below(point) {\n const above2 = (this.end.x - this.begin.x) * (point.y - this.begin.y) - (this.end.y - this.begin.y) * (point.x - this.begin.x);\n return above2 >= 0;\n }\n /**\r\n * Returns the clip point\r\n * @param sideVector Vector that traces the line\r\n * @param length Length to clip along side\r\n */ clip(sideVector, length) {\n let dir = sideVector;\n dir = dir.normalize();\n const near = dir.dot(this.begin) - length;\n const far = dir.dot(this.end) - length;\n const results = [];\n if (near <= 0) results.push(this.begin);\n if (far <= 0) results.push(this.end);\n if (near * far < 0) {\n const clipTime = near / (near - far);\n results.push(this.begin.add(this.end.sub(this.begin).scale(clipTime)));\n }\n if (results.length !== 2) return null;\n return new LineSegment(results[0], results[1]);\n }\n /**\r\n * Find the perpendicular distance from the line to a point\r\n * https://en.wikipedia.org/wiki/Distance_from_a_point_to_a_line\r\n * @param point\r\n */ distanceToPoint(point, signed = false) {\n const x0 = point.x;\n const y0 = point.y;\n const l = this.getLength();\n const dy = this.end.y - this.begin.y;\n const dx = this.end.x - this.begin.x;\n const distance = (dy * x0 - dx * y0 + this.end.x * this.begin.y - this.end.y * this.begin.x) / l;\n return signed ? distance : Math.abs(distance);\n }\n /**\r\n * Find the perpendicular line from the line to a point\r\n * https://en.wikipedia.org/wiki/Distance_from_a_point_to_a_line\r\n * (a - p) - ((a - p) * n)n\r\n * a is a point on the line\r\n * p is the arbitrary point above the line\r\n * n is a unit vector in direction of the line\r\n * @param point\r\n */ findVectorToPoint(point) {\n const aMinusP = this.begin.sub(point);\n const n = this.getSlope();\n return aMinusP.sub(n.scale(aMinusP.dot(n)));\n }\n /**\r\n * Finds a point on the line given only an X or a Y value. Given an X value, the function returns\r\n * a new point with the calculated Y value and vice-versa.\r\n *\r\n * @param x The known X value of the target point\r\n * @param y The known Y value of the target point\r\n * @returns A new point with the other calculated axis value\r\n */ findPoint(x = null, y = null) {\n const m = this.slope;\n const b = this.intercept;\n if (x !== null) return new Vector(x, m * x + b);\n else if (y !== null) return new Vector((y - b) / m, y);\n else throw new Error(\"You must provide an X or a Y value\");\n }\n /**\r\n * @see http://stackoverflow.com/a/11908158/109458\r\n */ hasPoint() {\n let currPoint;\n let threshold = 0;\n if (typeof arguments[0] === \"number\" && typeof arguments[1] === \"number\") {\n currPoint = new Vector(arguments[0], arguments[1]);\n threshold = arguments[2] || 0;\n } else if (arguments[0] instanceof Vector) {\n currPoint = arguments[0];\n threshold = arguments[1] || 0;\n } else throw \"Could not determine the arguments for Vector.hasPoint\";\n const dxc = currPoint.x - this.begin.x;\n const dyc = currPoint.y - this.begin.y;\n const dx1 = this.end.x - this.begin.x;\n const dy1 = this.end.y - this.begin.y;\n const cross = dxc * dy1 - dyc * dx1;\n // check whether point lines on the line\n if (Math.abs(cross) > threshold) return false;\n // check whether point lies in-between start and end\n if (Math.abs(dx1) >= Math.abs(dy1)) return dx1 > 0 ? this.begin.x <= currPoint.x && currPoint.x <= this.end.x : this.end.x <= currPoint.x && currPoint.x <= this.begin.x;\n else return dy1 > 0 ? this.begin.y <= currPoint.y && currPoint.y <= this.end.y : this.end.y <= currPoint.y && currPoint.y <= this.begin.y;\n }\n }\n /**\r\n * Finds the closes line between 2 line segments, were the magnitude of u, v are the lengths of each segment\r\n * L1 = P(s) = p0 + s * u, where s is time and p0 is the start of the line\r\n * L2 = Q(t) = q0 + t * v, where t is time and q0 is the start of the line\r\n * @param p0 Point where L1 begins\r\n * @param u Direction and length of L1\r\n * @param q0 Point were L2 begins\r\n * @param v Direction and length of L2\r\n */ function ClosestLine(p0, u, q0, v) {\n // Distance between 2 lines http://geomalgorithms.com/a07-_distance.html\n // w(s, t) = P(s) - Q(t)\n // The w(s, t) that has the minimum distance we will say is w(sClosest, tClosest) = wClosest\n //\n // wClosest is the vector that is uniquely perpendicular to the 2 line directions u & v.\n // wClosest = w0 + sClosest * u - tClosest * v, where w0 is p0 - q0\n //\n // The closest point between 2 lines then satisfies this pair of equations\n // 1: u * wClosest = 0\n // 2: v * wClosest = 0\n //\n // Substituting wClosest into the equations we get\n //\n // 1: (u * u) * sClosest - (u * v) tClosest = -u * w0\n // 2: (v * u) * sClosest - (v * v) tClosest = -v * w0\n // simplify w0\n const w0 = p0.sub(q0);\n // simplify (u * u);\n const a = u.dot(u);\n // simplify (u * v);\n const b = u.dot(v);\n // simplify (v * v)\n const c = v.dot(v);\n // simplify (u * w0)\n const d = u.dot(w0);\n // simplify (v * w0)\n const e = v.dot(w0);\n // denominator ac - b^2\n const denom = a * c - b * b;\n let sDenom = denom;\n let tDenom = denom;\n // if denom is 0 they are parallel, use any point from either as the start in this case p0\n if (denom === 0 || denom <= 0.01) {\n const tClosestParallel = d / b;\n return new LineSegment(p0, q0.add(v.scale(tClosestParallel)));\n }\n // Solve for sClosest for infinite line\n let sClosest = b * e - c * d; // / denom;\n // Solve for tClosest for infinite line\n let tClosest = a * e - b * d; // / denom;\n // Solve for segments candidate edges, if sClosest and tClosest are outside their segments\n if (sClosest < 0) {\n sClosest = 0;\n tClosest = e;\n tDenom = c;\n } else if (sClosest > sDenom) {\n sClosest = sDenom;\n tClosest = e + b;\n tDenom = c;\n }\n if (tClosest < 0) {\n tClosest = 0;\n if (-d < 0) sClosest = 0;\n else if (-d > a) sClosest = sDenom;\n else {\n sClosest = -d;\n sDenom = a;\n }\n } else if (tClosest > tDenom) {\n tClosest = tDenom;\n if (-d + b < 0) sClosest = 0;\n else if (-d + b > a) sClosest = sDenom;\n else {\n sClosest = -d + b;\n sDenom = a;\n }\n }\n sClosest = Math.abs(sClosest) < 0.001 ? 0 : sClosest / sDenom;\n tClosest = Math.abs(tClosest) < 0.001 ? 0 : tClosest / tDenom;\n return new LineSegment(p0.add(u.scale(sClosest)), q0.add(v.scale(tClosest)));\n }\n const ClosestLineJumpTable = {\n PolygonPolygonClosestLine (polygonA, polygonB) {\n // Find the 2 closest faces on each polygon\n const otherWorldPos = polygonB.worldPos;\n const otherDirection = otherWorldPos.sub(polygonA.worldPos);\n const thisDirection = otherDirection.negate();\n const rayTowardsOther = new Ray(polygonA.worldPos, otherDirection);\n const rayTowardsThis = new Ray(otherWorldPos, thisDirection);\n const thisPoint = polygonA.rayCast(rayTowardsOther).add(rayTowardsOther.dir.scale(0.1));\n const otherPoint = polygonB.rayCast(rayTowardsThis).add(rayTowardsThis.dir.scale(0.1));\n const thisFace = polygonA.getClosestFace(thisPoint);\n const otherFace = polygonB.getClosestFace(otherPoint);\n // L1 = P(s) = p0 + s * u, where s is time and p0 is the start of the line\n const p0 = thisFace.face.begin;\n const u = thisFace.face.getEdge();\n // L2 = Q(t) = q0 + t * v, where t is time and q0 is the start of the line\n const q0 = otherFace.face.begin;\n const v = otherFace.face.getEdge();\n return ClosestLine(p0, u, q0, v);\n },\n PolygonEdgeClosestLine (polygon, edge) {\n // Find the 2 closest faces on each polygon\n const otherWorldPos = edge.worldPos;\n const otherDirection = otherWorldPos.sub(polygon.worldPos);\n const rayTowardsOther = new Ray(polygon.worldPos, otherDirection);\n const thisPoint = polygon.rayCast(rayTowardsOther).add(rayTowardsOther.dir.scale(0.1));\n const thisFace = polygon.getClosestFace(thisPoint);\n // L1 = P(s) = p0 + s * u, where s is time and p0 is the start of the line\n const p0 = thisFace.face.begin;\n const u = thisFace.face.getEdge();\n // L2 = Q(t) = q0 + t * v, where t is time and q0 is the start of the line\n const edgeLine = edge.asLine();\n const edgeStart = edgeLine.begin;\n const edgeVector = edgeLine.getEdge();\n const q0 = edgeStart;\n const v = edgeVector;\n return ClosestLine(p0, u, q0, v);\n },\n PolygonCircleClosestLine (polygon, circle) {\n // https://math.stackexchange.com/questions/1919177/how-to-find-point-on-line-closest-to-sphere\n // Find the 2 closest faces on each polygon\n const otherWorldPos = circle.worldPos;\n const otherDirection = otherWorldPos.sub(polygon.worldPos);\n const rayTowardsOther = new Ray(polygon.worldPos, otherDirection.normalize());\n const thisPoint = polygon.rayCast(rayTowardsOther).add(rayTowardsOther.dir.scale(0.1));\n const thisFace = polygon.getClosestFace(thisPoint);\n // L1 = P(s) = p0 + s * u, where s is time and p0 is the start of the line\n const p0 = thisFace.face.begin;\n const u = thisFace.face.getEdge();\n // Time of minimum distance\n let t = (u.x * (otherWorldPos.x - p0.x) + u.y * (otherWorldPos.y - p0.y)) / (u.x * u.x + u.y * u.y);\n // If time of minimum is past the edge clamp\n if (t > 1) t = 1;\n else if (t < 0) t = 0;\n // Minimum distance\n const d = Math.sqrt(Math.pow(p0.x + u.x * t - otherWorldPos.x, 2) + Math.pow(p0.y + u.y * t - otherWorldPos.y, 2)) - circle.radius;\n const circlex = (p0.x + u.x * t - otherWorldPos.x) * circle.radius / (circle.radius + d);\n const circley = (p0.y + u.y * t - otherWorldPos.y) * circle.radius / (circle.radius + d);\n return new LineSegment(u.scale(t).add(p0), new Vector(otherWorldPos.x + circlex, otherWorldPos.y + circley));\n },\n CircleCircleClosestLine (circleA, circleB) {\n // Find the 2 closest faces on each polygon\n const otherWorldPos = circleB.worldPos;\n const otherDirection = otherWorldPos.sub(circleA.worldPos);\n const thisWorldPos = circleA.worldPos;\n const thisDirection = thisWorldPos.sub(circleB.worldPos);\n const rayTowardsOther = new Ray(circleA.worldPos, otherDirection);\n const rayTowardsThis = new Ray(circleB.worldPos, thisDirection);\n const thisPoint = circleA.rayCast(rayTowardsOther);\n const otherPoint = circleB.rayCast(rayTowardsThis);\n return new LineSegment(thisPoint, otherPoint);\n },\n CircleEdgeClosestLine (circle, edge) {\n // https://math.stackexchange.com/questions/1919177/how-to-find-point-on-line-closest-to-sphere\n const circleWorlPos = circle.worldPos;\n // L1 = P(s) = p0 + s * u, where s is time and p0 is the start of the line\n const edgeLine = edge.asLine();\n const edgeStart = edgeLine.begin;\n const edgeVector = edgeLine.getEdge();\n const p0 = edgeStart;\n const u = edgeVector;\n // Time of minimum distance\n let t = (u.x * (circleWorlPos.x - p0.x) + u.y * (circleWorlPos.y - p0.y)) / (u.x * u.x + u.y * u.y);\n // If time of minimum is past the edge clamp to edge\n if (t > 1) t = 1;\n else if (t < 0) t = 0;\n // Minimum distance\n const d = Math.sqrt(Math.pow(p0.x + u.x * t - circleWorlPos.x, 2) + Math.pow(p0.y + u.y * t - circleWorlPos.y, 2)) - circle.radius;\n const circlex = (p0.x + u.x * t - circleWorlPos.x) * circle.radius / (circle.radius + d);\n const circley = (p0.y + u.y * t - circleWorlPos.y) * circle.radius / (circle.radius + d);\n return new LineSegment(u.scale(t).add(p0), new Vector(circleWorlPos.x + circlex, circleWorlPos.y + circley));\n },\n EdgeEdgeClosestLine (edgeA, edgeB) {\n // L1 = P(s) = p0 + s * u, where s is time and p0 is the start of the line\n const edgeLineA = edgeA.asLine();\n const edgeStartA = edgeLineA.begin;\n const edgeVectorA = edgeLineA.getEdge();\n const p0 = edgeStartA;\n const u = edgeVectorA;\n // L2 = Q(t) = q0 + t * v, where t is time and q0 is the start of the line\n const edgeLineB = edgeB.asLine();\n const edgeStartB = edgeLineB.begin;\n const edgeVectorB = edgeLineB.getEdge();\n const q0 = edgeStartB;\n const v = edgeVectorB;\n return ClosestLine(p0, u, q0, v);\n }\n };\n /**\r\n * This is a circle collider for the excalibur rigid body physics simulation\r\n */ class CircleCollider extends Collider {\n get worldPos() {\n return this._globalMatrix.getPosition();\n }\n /**\r\n * Get the radius of the circle\r\n */ get radius() {\n var _a;\n const tx = this._transform;\n const scale = (_a = tx === null || tx === void 0 ? void 0 : tx.globalScale) !== null && _a !== void 0 ? _a : Vector.One;\n // This is a trade off, the alternative is retooling circles to support ellipse collisions\n return this._naturalRadius * Math.min(scale.x, scale.y);\n }\n /**\r\n * Set the radius of the circle\r\n */ set radius(val) {\n var _a;\n const tx = this._transform;\n const scale = (_a = tx === null || tx === void 0 ? void 0 : tx.globalScale) !== null && _a !== void 0 ? _a : Vector.One;\n // This is a trade off, the alternative is retooling circles to support ellipse collisions\n this._naturalRadius = val / Math.min(scale.x, scale.y);\n }\n constructor(options){\n super();\n /**\r\n * Position of the circle relative to the collider, by default (0, 0).\r\n */ this.offset = Vector.Zero;\n this._globalMatrix = AffineMatrix.identity();\n this.offset = options.offset || Vector.Zero;\n this.radius = options.radius || 0;\n this._globalMatrix.translate(this.offset.x, this.offset.y);\n }\n /**\r\n * Returns a clone of this shape, not associated with any collider\r\n */ clone() {\n return new CircleCollider({\n offset: this.offset.clone(),\n radius: this.radius\n });\n }\n /**\r\n * Get the center of the collider in world coordinates\r\n */ get center() {\n return this._globalMatrix.getPosition();\n }\n /**\r\n * Tests if a point is contained in this collider\r\n */ contains(point) {\n var _a, _b;\n const pos = (_b = (_a = this._transform) === null || _a === void 0 ? void 0 : _a.pos) !== null && _b !== void 0 ? _b : this.offset;\n const distance = pos.distance(point);\n if (distance <= this.radius) return true;\n return false;\n }\n /**\r\n * Casts a ray at the Circle collider and returns the nearest point of collision\r\n * @param ray\r\n */ rayCast(ray, max = Infinity) {\n //https://en.wikipedia.org/wiki/Line%E2%80%93sphere_intersection\n const c = this.center;\n const dir = ray.dir;\n const orig = ray.pos;\n const discriminant = Math.sqrt(Math.pow(dir.dot(orig.sub(c)), 2) - Math.pow(orig.sub(c).distance(), 2) + Math.pow(this.radius, 2));\n if (discriminant < 0) // no intersection\n return null;\n else {\n let toi = 0;\n if (discriminant === 0) {\n toi = -dir.dot(orig.sub(c));\n if (toi > 0 && toi < max) return ray.getPoint(toi);\n return null;\n } else {\n const toi1 = -dir.dot(orig.sub(c)) + discriminant;\n const toi2 = -dir.dot(orig.sub(c)) - discriminant;\n const positiveToi = [];\n if (toi1 >= 0) positiveToi.push(toi1);\n if (toi2 >= 0) positiveToi.push(toi2);\n const mintoi = Math.min(...positiveToi);\n if (mintoi <= max) return ray.getPoint(mintoi);\n return null;\n }\n }\n }\n getClosestLineBetween(shape) {\n if (shape instanceof CircleCollider) return ClosestLineJumpTable.CircleCircleClosestLine(this, shape);\n else if (shape instanceof PolygonCollider) return ClosestLineJumpTable.PolygonCircleClosestLine(shape, this).flip();\n else if (shape instanceof EdgeCollider) return ClosestLineJumpTable.CircleEdgeClosestLine(this, shape).flip();\n else throw new Error(`Polygon could not collide with unknown CollisionShape ${typeof shape}`);\n }\n /**\r\n * @inheritdoc\r\n */ collide(collider) {\n if (collider instanceof CircleCollider) return CollisionJumpTable.CollideCircleCircle(this, collider);\n else if (collider instanceof PolygonCollider) return CollisionJumpTable.CollideCirclePolygon(this, collider);\n else if (collider instanceof EdgeCollider) return CollisionJumpTable.CollideCircleEdge(this, collider);\n else throw new Error(`Circle could not collide with unknown CollisionShape ${typeof collider}`);\n }\n /**\r\n * Find the point on the collider furthest in the direction specified\r\n */ getFurthestPoint(direction) {\n return this.center.add(direction.normalize().scale(this.radius));\n }\n /**\r\n * Find the local point on the shape in the direction specified\r\n * @param direction\r\n */ getFurthestLocalPoint(direction) {\n const dir = direction.normalize();\n return dir.scale(this.radius);\n }\n /**\r\n * Get the axis aligned bounding box for the circle collider in world coordinates\r\n */ get bounds() {\n var _a, _b, _c;\n const tx = this._transform;\n const scale = (_a = tx === null || tx === void 0 ? void 0 : tx.globalScale) !== null && _a !== void 0 ? _a : Vector.One;\n const rotation = (_b = tx === null || tx === void 0 ? void 0 : tx.globalRotation) !== null && _b !== void 0 ? _b : 0;\n const pos = (_c = tx === null || tx === void 0 ? void 0 : tx.globalPos) !== null && _c !== void 0 ? _c : Vector.Zero;\n return new BoundingBox(this.offset.x - this._naturalRadius, this.offset.y - this._naturalRadius, this.offset.x + this._naturalRadius, this.offset.y + this._naturalRadius).rotate(rotation).scale(scale).translate(pos);\n }\n /**\r\n * Get the axis aligned bounding box for the circle collider in local coordinates\r\n */ get localBounds() {\n return new BoundingBox(this.offset.x - this._naturalRadius, this.offset.y - this._naturalRadius, this.offset.x + this._naturalRadius, this.offset.y + this._naturalRadius);\n }\n /**\r\n * Get axis not implemented on circles, since there are infinite axis in a circle\r\n */ get axes() {\n return [];\n }\n /**\r\n * Returns the moment of inertia of a circle given it's mass\r\n * https://en.wikipedia.org/wiki/List_of_moments_of_inertia\r\n */ getInertia(mass) {\n return mass * this.radius * this.radius / 2;\n }\n /* istanbul ignore next */ update(transform) {\n var _a;\n this._transform = transform;\n const globalMat = (_a = transform.matrix) !== null && _a !== void 0 ? _a : this._globalMatrix;\n globalMat.clone(this._globalMatrix);\n this._globalMatrix.translate(this.offset.x, this.offset.y);\n }\n /**\r\n * Project the circle along a specified axis\r\n */ project(axis) {\n const scalars = [];\n const point = this.center;\n const dotProduct = point.dot(axis);\n scalars.push(dotProduct);\n scalars.push(dotProduct + this.radius);\n scalars.push(dotProduct - this.radius);\n return new Projection(Math.min.apply(Math, scalars), Math.max.apply(Math, scalars));\n }\n debug(ex, color) {\n var _a, _b, _c, _d;\n const tx = this._transform;\n const scale = (_a = tx === null || tx === void 0 ? void 0 : tx.globalScale) !== null && _a !== void 0 ? _a : Vector.One;\n const rotation = (_b = tx === null || tx === void 0 ? void 0 : tx.globalRotation) !== null && _b !== void 0 ? _b : 0;\n const pos = (_c = tx === null || tx === void 0 ? void 0 : tx.globalPos) !== null && _c !== void 0 ? _c : Vector.Zero;\n ex.save();\n ex.translate(pos.x, pos.y);\n ex.rotate(rotation);\n ex.scale(scale.x, scale.y);\n ex.drawCircle((_d = this.offset) !== null && _d !== void 0 ? _d : Vector.Zero, this._naturalRadius, Color.Transparent, color, 2);\n ex.restore();\n }\n }\n /**\r\n * Collision contacts are used internally by Excalibur to resolve collision between colliders. This\r\n * Pair prevents collisions from being evaluated more than one time\r\n */ class CollisionContact {\n constructor(colliderA, colliderB, mtv, normal, tangent, points, localPoints, info){\n var _a, _b;\n this._canceled = false;\n this.colliderA = colliderA;\n this.colliderB = colliderB;\n this.mtv = mtv;\n this.normal = normal;\n this.tangent = tangent;\n this.points = points;\n this.localPoints = localPoints;\n this.info = info;\n this.id = Pair.calculatePairHash(colliderA.id, colliderB.id);\n if (colliderA.__compositeColliderId || colliderB.__compositeColliderId) // Add on the parent composite pair for start/end contact\n this.id += \"|\" + Pair.calculatePairHash((_a = colliderA.__compositeColliderId) !== null && _a !== void 0 ? _a : colliderA.id, (_b = colliderB.__compositeColliderId) !== null && _b !== void 0 ? _b : colliderB.id);\n }\n /**\r\n * Match contact awake state, except if body's are Fixed\r\n */ matchAwake() {\n const bodyA = this.colliderA.owner.get(BodyComponent);\n const bodyB = this.colliderB.owner.get(BodyComponent);\n if (bodyA && bodyB) {\n if (bodyA.sleeping !== bodyB.sleeping) {\n if (bodyA.sleeping && bodyA.collisionType !== CollisionType.Fixed && bodyB.sleepMotion >= Physics.wakeThreshold) bodyA.setSleeping(false);\n if (bodyB.sleeping && bodyB.collisionType !== CollisionType.Fixed && bodyA.sleepMotion >= Physics.wakeThreshold) bodyB.setSleeping(false);\n }\n }\n }\n isCanceled() {\n return this._canceled;\n }\n cancel() {\n this._canceled = true;\n }\n }\n class SeparatingAxis {\n static findPolygonPolygonSeparation(polyA, polyB) {\n let bestSeparation = -Number.MAX_VALUE;\n let bestSide = null;\n let bestAxis = null;\n let bestSideIndex = -1;\n let bestOtherPoint = null;\n const sides = polyA.getSides();\n const localSides = polyA.getLocalSides();\n for(let i = 0; i < sides.length; i++){\n const side = sides[i];\n const axis = side.normal();\n const vertB = polyB.getFurthestPoint(axis.negate());\n // Separation on side i's axis\n // We are looking for the largest separation between poly A's sides\n const vertSeparation = side.distanceToPoint(vertB, true);\n if (vertSeparation > bestSeparation) {\n bestSeparation = vertSeparation;\n bestSide = side;\n bestAxis = axis;\n bestSideIndex = i;\n bestOtherPoint = vertB;\n }\n }\n return {\n collider: polyA,\n separation: bestAxis ? bestSeparation : 99,\n axis: bestAxis,\n side: bestSide,\n localSide: localSides[bestSideIndex],\n sideId: bestSideIndex,\n point: bestOtherPoint,\n localPoint: bestAxis ? polyB.getFurthestLocalPoint(bestAxis.negate()) : null\n };\n }\n static findCirclePolygonSeparation(circle, polygon) {\n const axes = polygon.axes;\n const pc = polygon.center;\n // Special SAT with circles\n const polyDir = pc.sub(circle.worldPos);\n const closestPointOnPoly = polygon.getFurthestPoint(polyDir.negate());\n axes.push(closestPointOnPoly.sub(circle.worldPos).normalize());\n let minOverlap = Number.MAX_VALUE;\n let minAxis = null;\n let minIndex = -1;\n for(let i = 0; i < axes.length; i++){\n const proj1 = polygon.project(axes[i]);\n const proj2 = circle.project(axes[i]);\n const overlap = proj1.getOverlap(proj2);\n if (overlap <= 0) return null;\n else if (overlap < minOverlap) {\n minOverlap = overlap;\n minAxis = axes[i];\n minIndex = i;\n }\n }\n if (minIndex < 0) return null;\n return minAxis.normalize().scale(minOverlap);\n }\n }\n const CollisionJumpTable = {\n CollideCircleCircle (circleA, circleB) {\n const circleAPos = circleA.worldPos;\n const circleBPos = circleB.worldPos;\n const combinedRadius = circleA.radius + circleB.radius;\n const distance = circleAPos.distance(circleBPos);\n if (distance > combinedRadius) return [];\n // negative means overlap\n const separation = combinedRadius - distance;\n // Normal points from A -> B\n const normal = circleBPos.sub(circleAPos).normalize();\n const tangent = normal.perpendicular();\n const mvt = normal.scale(separation);\n const point = circleA.getFurthestPoint(normal);\n const local = circleA.getFurthestLocalPoint(normal);\n const info = {\n collider: circleA,\n separation: separation,\n axis: normal,\n point: point\n };\n return [\n new CollisionContact(circleA, circleB, mvt, normal, tangent, [\n point\n ], [\n local\n ], info)\n ];\n },\n CollideCirclePolygon (circle, polygon) {\n var _a, _b;\n let minAxis = SeparatingAxis.findCirclePolygonSeparation(circle, polygon);\n if (!minAxis) return [];\n // make sure that the minAxis is pointing away from circle\n const samedir = minAxis.dot(polygon.center.sub(circle.center));\n minAxis = samedir < 0 ? minAxis.negate() : minAxis;\n const point = circle.getFurthestPoint(minAxis);\n const xf = (_b = (_a = circle.owner) === null || _a === void 0 ? void 0 : _a.get(TransformComponent)) !== null && _b !== void 0 ? _b : new TransformComponent();\n const local = xf.applyInverse(point);\n const normal = minAxis.normalize();\n const info = {\n collider: circle,\n separation: -minAxis.size,\n axis: normal,\n point: point,\n localPoint: local,\n side: polygon.findSide(normal.negate()),\n localSide: polygon.findLocalSide(normal.negate())\n };\n return [\n new CollisionContact(circle, polygon, minAxis, normal, normal.perpendicular(), [\n point\n ], [\n local\n ], info)\n ];\n },\n CollideCircleEdge (circle, edge) {\n // TODO not sure this actually abides by local/world collisions\n // Are edge.begin and edge.end local space or world space? I think they should be local\n // center of the circle in world pos\n const cc = circle.center;\n // vector in the direction of the edge\n const edgeWorld = edge.asLine();\n const e = edgeWorld.end.sub(edgeWorld.begin);\n // amount of overlap with the circle's center along the edge direction\n const u = e.dot(edgeWorld.end.sub(cc));\n const v = e.dot(cc.sub(edgeWorld.begin));\n const side = edge.asLine();\n const localSide = edge.asLocalLine();\n // Potential region A collision (circle is on the left side of the edge, before the beginning)\n if (v <= 0) {\n const da = edgeWorld.begin.sub(cc);\n const dda = da.dot(da); // quick and dirty way of calc'n distance in r^2 terms saves some sqrts\n // save some sqrts\n if (dda > circle.radius * circle.radius) return []; // no collision\n const normal = da.normalize();\n const separation = circle.radius - Math.sqrt(dda);\n const info = {\n collider: circle,\n separation: separation,\n axis: normal,\n point: side.begin,\n side: side,\n localSide: localSide\n };\n return [\n new CollisionContact(circle, edge, normal.scale(separation), normal, normal.perpendicular(), [\n side.begin\n ], [\n localSide.begin\n ], info)\n ];\n }\n // Potential region B collision (circle is on the right side of the edge, after the end)\n if (u <= 0) {\n const db = edgeWorld.end.sub(cc);\n const ddb = db.dot(db);\n if (ddb > circle.radius * circle.radius) return [];\n const normal = db.normalize();\n const separation = circle.radius - Math.sqrt(ddb);\n const info = {\n collider: circle,\n separation: separation,\n axis: normal,\n point: side.end,\n side: side,\n localSide: localSide\n };\n return [\n new CollisionContact(circle, edge, normal.scale(separation), normal, normal.perpendicular(), [\n side.end\n ], [\n localSide.end\n ], info)\n ];\n }\n // Otherwise potential region AB collision (circle is in the middle of the edge between the beginning and end)\n const den = e.dot(e);\n const pointOnEdge = edgeWorld.begin.scale(u).add(edgeWorld.end.scale(v)).scale(1 / den);\n const d = cc.sub(pointOnEdge);\n const dd = d.dot(d);\n if (dd > circle.radius * circle.radius) return []; // no collision\n let normal = e.perpendicular();\n // flip correct direction\n if (normal.dot(cc.sub(edgeWorld.begin)) < 0) {\n normal.x = -normal.x;\n normal.y = -normal.y;\n }\n normal = normal.normalize();\n const separation = circle.radius - Math.sqrt(dd);\n const mvt = normal.scale(separation);\n const info = {\n collider: circle,\n separation: separation,\n axis: normal,\n point: pointOnEdge,\n side: side,\n localSide: localSide\n };\n return [\n new CollisionContact(circle, edge, mvt, normal.negate(), normal.negate().perpendicular(), [\n pointOnEdge\n ], [\n pointOnEdge.sub(edge.worldPos)\n ], info)\n ];\n },\n CollideEdgeEdge () {\n // Edge-edge collision doesn't make sense\n return [];\n },\n CollidePolygonEdge (polygon, edge) {\n var _a;\n const pc = polygon.center;\n const ec = edge.center;\n const dir = ec.sub(pc).normalize();\n // build a temporary polygon from the edge to use SAT\n const linePoly = new PolygonCollider({\n points: [\n edge.begin,\n edge.end,\n edge.end.add(dir.scale(100)),\n edge.begin.add(dir.scale(100))\n ],\n offset: edge.offset\n });\n linePoly.owner = edge.owner;\n const tx = (_a = edge.owner) === null || _a === void 0 ? void 0 : _a.get(TransformComponent);\n if (tx) linePoly.update(edge.owner.get(TransformComponent).get());\n // Gross hack but poly-poly works well\n const contact = this.CollidePolygonPolygon(polygon, linePoly);\n if (contact.length) {\n // Fudge the contact back to edge\n contact[0].colliderB = edge;\n contact[0].id = Pair.calculatePairHash(polygon.id, edge.id);\n }\n return contact;\n },\n CollidePolygonPolygon (polyA, polyB) {\n var _a, _b, _c, _d;\n // Multi contact from SAT\n // https://gamedev.stackexchange.com/questions/111390/multiple-contacts-for-sat-collision-detection\n // do a SAT test to find a min axis if it exists\n const separationA = SeparatingAxis.findPolygonPolygonSeparation(polyA, polyB);\n // If there is no overlap from boxA's perspective we can end early\n if (separationA.separation > 0) return [];\n const separationB = SeparatingAxis.findPolygonPolygonSeparation(polyB, polyA);\n // If there is no overlap from boxB's perspective exit now\n if (separationB.separation > 0) return [];\n // Separations are both negative, we want to pick the least negative (minimal movement)\n const separation = separationA.separation > separationB.separation ? separationA : separationB;\n // The incident side is the most opposite from the axes of collision on the other collider\n const other = separation.collider === polyA ? polyB : polyA;\n const incident = other.findSide(separation.axis.negate());\n // Clip incident side by the perpendicular lines at each end of the reference side\n // https://en.wikipedia.org/wiki/Sutherland%E2%80%93Hodgman_algorithm\n const reference = separation.side;\n const refDir = reference.dir().normalize();\n // Find our contact points by clipping the incident by the collision side\n const clipRight = incident.clip(refDir.negate(), -refDir.dot(reference.begin));\n let clipLeft = null;\n if (clipRight) clipLeft = clipRight.clip(refDir, refDir.dot(reference.end));\n // If there is no left there is no collision\n if (clipLeft) {\n // We only want clip points below the reference edge, discard the others\n const points = clipLeft.getPoints().filter((p)=>{\n return reference.below(p);\n });\n let normal = separation.axis;\n let tangent = normal.perpendicular();\n // Point Contact A -> B\n if (polyB.center.sub(polyA.center).dot(normal) < 0) {\n normal = normal.negate();\n tangent = normal.perpendicular();\n }\n // Points are clipped from incident which is the other collider\n // Store those as locals\n let localPoints = [];\n if (separation.collider === polyA) {\n const xf = (_b = (_a = polyB.owner) === null || _a === void 0 ? void 0 : _a.get(TransformComponent)) !== null && _b !== void 0 ? _b : new TransformComponent();\n localPoints = points.map((p)=>xf.applyInverse(p));\n } else {\n const xf = (_d = (_c = polyA.owner) === null || _c === void 0 ? void 0 : _c.get(TransformComponent)) !== null && _d !== void 0 ? _d : new TransformComponent();\n localPoints = points.map((p)=>xf.applyInverse(p));\n }\n return [\n new CollisionContact(polyA, polyB, normal.scale(-separation.separation), normal, tangent, points, localPoints, separation)\n ];\n }\n return [];\n },\n FindContactSeparation (contact, localPoint) {\n var _a, _b, _c, _d;\n const shapeA = contact.colliderA;\n const txA = (_b = (_a = contact.colliderA.owner) === null || _a === void 0 ? void 0 : _a.get(TransformComponent)) !== null && _b !== void 0 ? _b : new TransformComponent();\n const shapeB = contact.colliderB;\n const txB = (_d = (_c = contact.colliderB.owner) === null || _c === void 0 ? void 0 : _c.get(TransformComponent)) !== null && _d !== void 0 ? _d : new TransformComponent();\n // both are circles\n if (shapeA instanceof CircleCollider && shapeB instanceof CircleCollider) {\n const combinedRadius = shapeA.radius + shapeB.radius;\n const distance = txA.pos.distance(txB.pos);\n const separation = combinedRadius - distance;\n return -separation;\n }\n // both are polygons\n if (shapeA instanceof PolygonCollider && shapeB instanceof PolygonCollider) {\n if (contact.info.localSide) {\n let side;\n let worldPoint;\n if (contact.info.collider === shapeA) {\n side = new LineSegment(txA.apply(contact.info.localSide.begin), txA.apply(contact.info.localSide.end));\n worldPoint = txB.apply(localPoint);\n } else {\n side = new LineSegment(txB.apply(contact.info.localSide.begin), txB.apply(contact.info.localSide.end));\n worldPoint = txA.apply(localPoint);\n }\n return side.distanceToPoint(worldPoint, true);\n }\n }\n // polygon v circle\n if (shapeA instanceof PolygonCollider && shapeB instanceof CircleCollider || shapeB instanceof PolygonCollider && shapeA instanceof CircleCollider) {\n const worldPoint = txA.apply(localPoint);\n if (contact.info.side) return contact.info.side.distanceToPoint(worldPoint, true);\n }\n // polygon v edge\n if (shapeA instanceof EdgeCollider && shapeB instanceof PolygonCollider || shapeB instanceof EdgeCollider && shapeA instanceof PolygonCollider) {\n let worldPoint;\n if (contact.info.collider === shapeA) worldPoint = txB.apply(localPoint);\n else worldPoint = txA.apply(localPoint);\n if (contact.info.side) return contact.info.side.distanceToPoint(worldPoint, true);\n }\n // circle v edge\n if (shapeA instanceof CircleCollider && shapeB instanceof EdgeCollider || shapeB instanceof CircleCollider && shapeA instanceof EdgeCollider) {\n // Local point is always on the edge which is always shapeB\n const worldPoint = txB.apply(localPoint);\n let circlePoint;\n if (shapeA instanceof CircleCollider) circlePoint = shapeA.getFurthestPoint(contact.normal);\n const dist = worldPoint.distance(circlePoint);\n if (contact.info.side) return dist > 0 ? -dist : 0;\n }\n return 0;\n }\n };\n /**\r\n * Edge is a single line collider to create collisions with a single line.\r\n */ class EdgeCollider extends Collider {\n constructor(options){\n var _a;\n super();\n this._globalMatrix = AffineMatrix.identity();\n this.begin = options.begin || Vector.Zero;\n this.end = options.end || Vector.Zero;\n this.offset = (_a = options.offset) !== null && _a !== void 0 ? _a : Vector.Zero;\n }\n /**\r\n * Returns a clone of this Edge, not associated with any collider\r\n */ clone() {\n return new EdgeCollider({\n begin: this.begin.clone(),\n end: this.end.clone()\n });\n }\n get worldPos() {\n var _a;\n const tx = this._transform;\n return (_a = tx === null || tx === void 0 ? void 0 : tx.globalPos.add(this.offset)) !== null && _a !== void 0 ? _a : this.offset;\n }\n /**\r\n * Get the center of the collision area in world coordinates\r\n */ get center() {\n const begin = this._getTransformedBegin();\n const end = this._getTransformedEnd();\n const pos = begin.average(end);\n return pos;\n }\n _getTransformedBegin() {\n return this._globalMatrix.multiply(this.begin);\n }\n _getTransformedEnd() {\n return this._globalMatrix.multiply(this.end);\n }\n /**\r\n * Returns the slope of the line in the form of a vector\r\n */ getSlope() {\n const begin = this._getTransformedBegin();\n const end = this._getTransformedEnd();\n const distance = begin.distance(end);\n return end.sub(begin).scale(1 / distance);\n }\n /**\r\n * Returns the length of the line segment in pixels\r\n */ getLength() {\n const begin = this._getTransformedBegin();\n const end = this._getTransformedEnd();\n const distance = begin.distance(end);\n return distance;\n }\n /**\r\n * Tests if a point is contained in this collision area\r\n */ contains() {\n return false;\n }\n /**\r\n * @inheritdoc\r\n */ rayCast(ray, max = Infinity) {\n const numerator = this._getTransformedBegin().sub(ray.pos);\n // Test is line and ray are parallel and non intersecting\n if (ray.dir.cross(this.getSlope()) === 0 && numerator.cross(ray.dir) !== 0) return null;\n // Lines are parallel\n const divisor = ray.dir.cross(this.getSlope());\n if (divisor === 0) return null;\n const t = numerator.cross(this.getSlope()) / divisor;\n if (t >= 0 && t <= max) {\n const u = numerator.cross(ray.dir) / divisor / this.getLength();\n if (u >= 0 && u <= 1) return ray.getPoint(t);\n }\n return null;\n }\n /**\r\n * Returns the closes line between this and another collider, from this -> collider\r\n * @param shape\r\n */ getClosestLineBetween(shape) {\n if (shape instanceof CircleCollider) return ClosestLineJumpTable.CircleEdgeClosestLine(shape, this);\n else if (shape instanceof PolygonCollider) return ClosestLineJumpTable.PolygonEdgeClosestLine(shape, this).flip();\n else if (shape instanceof EdgeCollider) return ClosestLineJumpTable.EdgeEdgeClosestLine(this, shape);\n else throw new Error(`Polygon could not collide with unknown CollisionShape ${typeof shape}`);\n }\n /**\r\n * @inheritdoc\r\n */ collide(shape) {\n if (shape instanceof CircleCollider) return CollisionJumpTable.CollideCircleEdge(shape, this);\n else if (shape instanceof PolygonCollider) return CollisionJumpTable.CollidePolygonEdge(shape, this);\n else if (shape instanceof EdgeCollider) return CollisionJumpTable.CollideEdgeEdge();\n else throw new Error(`Edge could not collide with unknown CollisionShape ${typeof shape}`);\n }\n /**\r\n * Find the point on the collider furthest in the direction specified\r\n */ getFurthestPoint(direction) {\n const transformedBegin = this._getTransformedBegin();\n const transformedEnd = this._getTransformedEnd();\n if (direction.dot(transformedBegin) > 0) return transformedBegin;\n else return transformedEnd;\n }\n _boundsFromBeginEnd(begin, end, padding = 10) {\n // A perfectly vertical or horizontal edge would have a bounds 0 width or height\n // this causes problems for the collision system so we give them some padding\n return new BoundingBox(Math.min(begin.x, end.x) - padding, Math.min(begin.y, end.y) - padding, Math.max(begin.x, end.x) + padding, Math.max(begin.y, end.y) + padding);\n }\n /**\r\n * Get the axis aligned bounding box for the edge collider in world space\r\n */ get bounds() {\n const transformedBegin = this._getTransformedBegin();\n const transformedEnd = this._getTransformedEnd();\n return this._boundsFromBeginEnd(transformedBegin, transformedEnd);\n }\n /**\r\n * Get the axis aligned bounding box for the edge collider in local space\r\n */ get localBounds() {\n return this._boundsFromBeginEnd(this.begin, this.end);\n }\n /**\r\n * Returns this edge represented as a line in world coordinates\r\n */ asLine() {\n return new LineSegment(this._getTransformedBegin(), this._getTransformedEnd());\n }\n /**\r\n * Return this edge as a line in local line coordinates (relative to the position)\r\n */ asLocalLine() {\n return new LineSegment(this.begin, this.end);\n }\n /**\r\n * Get the axis associated with the edge\r\n */ get axes() {\n const e = this._getTransformedEnd().sub(this._getTransformedBegin());\n const edgeNormal = e.normal();\n const axes = [];\n axes.push(edgeNormal);\n axes.push(edgeNormal.negate());\n axes.push(edgeNormal.normal());\n axes.push(edgeNormal.normal().negate());\n return axes;\n }\n /**\r\n * Get the moment of inertia for an edge\r\n * https://en.wikipedia.org/wiki/List_of_moments_of_inertia\r\n */ getInertia(mass) {\n const length = this.end.sub(this.begin).distance() / 2;\n return mass * length * length;\n }\n /**\r\n * @inheritdoc\r\n */ update(transform) {\n var _a;\n this._transform = transform;\n const globalMat = (_a = transform.matrix) !== null && _a !== void 0 ? _a : this._globalMatrix;\n globalMat.clone(this._globalMatrix);\n this._globalMatrix.translate(this.offset.x, this.offset.y);\n }\n /**\r\n * Project the edge along a specified axis\r\n */ project(axis) {\n const scalars = [];\n const points = [\n this._getTransformedBegin(),\n this._getTransformedEnd()\n ];\n const len = points.length;\n for(let i = 0; i < len; i++)scalars.push(points[i].dot(axis));\n return new Projection(Math.min.apply(Math, scalars), Math.max.apply(Math, scalars));\n }\n debug(ex, color) {\n const begin = this._getTransformedBegin();\n const end = this._getTransformedEnd();\n ex.drawLine(begin, end, color, 2);\n ex.drawCircle(begin, 2, color);\n ex.drawCircle(end, 2, color);\n }\n }\n /**\r\n * Polygon collider for detecting collisions\r\n */ class PolygonCollider extends Collider {\n /**\r\n * Points in the polygon in order around the perimeter in local coordinates. These are relative from the body transform position.\r\n * Excalibur stores these in counter-clockwise order\r\n */ set points(points) {\n this._localBoundsDirty = true;\n this._localSidesDirty = true;\n this._sidesDirty = true;\n this._points = points;\n }\n /**\r\n * Points in the polygon in order around the perimeter in local coordinates. These are relative from the body transform position.\r\n * Excalibur stores these in counter-clockwise order\r\n */ get points() {\n return this._points;\n }\n constructor(options){\n var _a, _b;\n super();\n this._logger = Logger.getInstance();\n this._transformedPoints = [];\n this._sides = [];\n this._localSides = [];\n this._globalMatrix = AffineMatrix.identity();\n this._transformedPointsDirty = true;\n this._sidesDirty = true;\n this._localSidesDirty = true;\n this._localBoundsDirty = true;\n this.offset = (_a = options.offset) !== null && _a !== void 0 ? _a : Vector.Zero;\n this._globalMatrix.translate(this.offset.x, this.offset.y);\n this.points = (_b = options.points) !== null && _b !== void 0 ? _b : [];\n const counterClockwise = this._isCounterClockwiseWinding(this.points);\n if (!counterClockwise) this.points.reverse();\n if (!this.isConvex()) this._logger.warn(\"Excalibur only supports convex polygon colliders and will not behave properly.Call PolygonCollider.triangulate() to build a new collider composed of smaller convex triangles\");\n // calculate initial transformation\n this._calculateTransformation();\n }\n _isCounterClockwiseWinding(points) {\n // https://stackoverflow.com/a/1165943\n let sum = 0;\n for(let i = 0; i < points.length; i++)sum += (points[(i + 1) % points.length].x - points[i].x) * (points[(i + 1) % points.length].y + points[i].y);\n return sum < 0;\n }\n /**\r\n * Returns if the polygon collider is convex, Excalibur does not handle non-convex collision shapes.\r\n * Call [[Polygon.triangulate]] to generate a [[CompositeCollider]] from this non-convex shape\r\n */ isConvex() {\n // From SO: https://stackoverflow.com/a/45372025\n if (this.points.length < 3) return false;\n let oldPoint = this.points[this.points.length - 2];\n let newPoint = this.points[this.points.length - 1];\n let direction = Math.atan2(newPoint.y - oldPoint.y, newPoint.x - oldPoint.x);\n let oldDirection = 0;\n let orientation = 0;\n let angleSum = 0;\n for (const [i, point] of this.points.entries()){\n oldPoint = newPoint;\n oldDirection = direction;\n newPoint = point;\n direction = Math.atan2(newPoint.y - oldPoint.y, newPoint.x - oldPoint.x);\n if (oldPoint.equals(newPoint)) return false; // repeat point\n let angle = direction - oldDirection;\n if (angle <= -Math.PI) angle += Math.PI * 2;\n else if (angle > Math.PI) angle -= Math.PI * 2;\n if (i === 0) {\n if (angle === 0.0) return false;\n orientation = angle > 0 ? 1 : -1;\n } else {\n if (orientation * angle <= 0) return false;\n }\n angleSum += angle;\n }\n return Math.abs(Math.round(angleSum / (Math.PI * 2))) === 1;\n }\n /**\r\n * Tessellates the polygon into a triangle fan as a [[CompositeCollider]] of triangle polygons\r\n */ tessellate() {\n const polygons = [];\n for(let i = 1; i < this.points.length - 2; i++)polygons.push([\n this.points[0],\n this.points[i + 1],\n this.points[i + 2]\n ]);\n polygons.push([\n this.points[0],\n this.points[1],\n this.points[2]\n ]);\n return new CompositeCollider(polygons.map((points)=>Shape.Polygon(points)));\n }\n /**\r\n * Triangulate the polygon collider using the \"Ear Clipping\" algorithm.\r\n * Returns a new [[CompositeCollider]] made up of smaller triangles.\r\n */ triangulate() {\n // https://www.youtube.com/watch?v=hTJFcHutls8\n if (this.points.length < 3) throw Error(\"Invalid polygon\");\n /**\r\n * Helper to get a vertex in the list\r\n */ function getItem(index, list) {\n if (index >= list.length) return list[index % list.length];\n else if (index < 0) return list[index % list.length + list.length];\n else return list[index];\n }\n /**\r\n * Quick test for point in triangle\r\n */ function isPointInTriangle(point, a, b, c) {\n const ab = b.sub(a);\n const bc = c.sub(b);\n const ca = a.sub(c);\n const ap = point.sub(a);\n const bp = point.sub(b);\n const cp = point.sub(c);\n const cross1 = ab.cross(ap);\n const cross2 = bc.cross(bp);\n const cross3 = ca.cross(cp);\n if (cross1 > 0 || cross2 > 0 || cross3 > 0) return false;\n return true;\n }\n const triangles = [];\n const vertices = [\n ...this.points\n ];\n const indices = range(0, this.points.length - 1);\n // 1. Loop through vertices clockwise\n // if the vertex is convex (interior angle is < 180) (cross product positive)\n // if the polygon formed by it's edges doesn't contain the points\n // it's an ear add it to our list of triangles, and restart\n while(indices.length > 3)for(let i = 0; i < indices.length; i++){\n const a = indices[i];\n const b = getItem(i - 1, indices);\n const c = getItem(i + 1, indices);\n const va = vertices[a];\n const vb = vertices[b];\n const vc = vertices[c];\n // Check convexity\n const leftArm = vb.sub(va);\n const rightArm = vc.sub(va);\n const isConvex = rightArm.cross(leftArm) > 0; // positive cross means convex\n if (!isConvex) continue;\n let isEar = true;\n // Check that if any vertices are in the triangle a, b, c\n for(let j = 0; j < indices.length; j++){\n const vertIndex = indices[j];\n // We can skip these\n if (vertIndex === a || vertIndex === b || vertIndex === c) continue;\n const point = vertices[vertIndex];\n if (isPointInTriangle(point, vb, va, vc)) {\n isEar = false;\n break;\n }\n }\n // Add ear to polygon list and remove from list\n if (isEar) {\n triangles.push([\n vb,\n va,\n vc\n ]);\n indices.splice(i, 1);\n break;\n }\n }\n triangles.push([\n vertices[indices[0]],\n vertices[indices[1]],\n vertices[indices[2]]\n ]);\n return new CompositeCollider(triangles.map((points)=>Shape.Polygon(points)));\n }\n /**\r\n * Returns a clone of this ConvexPolygon, not associated with any collider\r\n */ clone() {\n return new PolygonCollider({\n offset: this.offset.clone(),\n points: this.points.map((p)=>p.clone())\n });\n }\n /**\r\n * Returns the world position of the collider, which is the current body transform plus any defined offset\r\n */ get worldPos() {\n if (this._transform) return this._transform.pos.add(this.offset);\n return this.offset;\n }\n /**\r\n * Get the center of the collider in world coordinates\r\n */ get center() {\n return this.bounds.center;\n }\n /**\r\n * Calculates the underlying transformation from the body relative space to world space\r\n */ _calculateTransformation() {\n const points = this.points;\n const len = points.length;\n this._transformedPoints.length = 0; // clear out old transform\n for(let i = 0; i < len; i++)this._transformedPoints[i] = this._globalMatrix.multiply(points[i].clone());\n }\n /**\r\n * Gets the points that make up the polygon in world space, from actor relative space (if specified)\r\n */ getTransformedPoints() {\n if (this._transformedPointsDirty) {\n this._calculateTransformation();\n this._transformedPointsDirty = false;\n }\n return this._transformedPoints;\n }\n /**\r\n * Gets the sides of the polygon in world space\r\n */ getSides() {\n if (this._sidesDirty) {\n const lines = [];\n const points = this.getTransformedPoints();\n const len = points.length;\n for(let i = 0; i < len; i++)// This winding is important\n lines.push(new LineSegment(points[i], points[(i + 1) % len]));\n this._sides = lines;\n this._sidesDirty = false;\n }\n return this._sides;\n }\n /**\r\n * Returns the local coordinate space sides\r\n */ getLocalSides() {\n if (this._localSidesDirty) {\n const lines = [];\n const points = this.points;\n const len = points.length;\n for(let i = 0; i < len; i++)// This winding is important\n lines.push(new LineSegment(points[i], points[(i + 1) % len]));\n this._localSides = lines;\n this._localSidesDirty = false;\n }\n return this._localSides;\n }\n /**\r\n * Given a direction vector find the world space side that is most in that direction\r\n * @param direction\r\n */ findSide(direction) {\n const sides = this.getSides();\n let bestSide = sides[0];\n let maxDistance = -Number.MAX_VALUE;\n for(let side = 0; side < sides.length; side++){\n const currentSide = sides[side];\n const sideNormal = currentSide.normal();\n const mostDirection = sideNormal.dot(direction);\n if (mostDirection > maxDistance) {\n bestSide = currentSide;\n maxDistance = mostDirection;\n }\n }\n return bestSide;\n }\n /**\r\n * Given a direction vector find the local space side that is most in that direction\r\n * @param direction\r\n */ findLocalSide(direction) {\n const sides = this.getLocalSides();\n let bestSide = sides[0];\n let maxDistance = -Number.MAX_VALUE;\n for(let side = 0; side < sides.length; side++){\n const currentSide = sides[side];\n const sideNormal = currentSide.normal();\n const mostDirection = sideNormal.dot(direction);\n if (mostDirection > maxDistance) {\n bestSide = currentSide;\n maxDistance = mostDirection;\n }\n }\n return bestSide;\n }\n /**\r\n * Get the axis associated with the convex polygon\r\n */ get axes() {\n const axes = [];\n const sides = this.getSides();\n for(let i = 0; i < sides.length; i++)axes.push(sides[i].normal());\n return axes;\n }\n /**\r\n * Updates the transform for the collision geometry\r\n *\r\n * Collision geometry (points/bounds) will not change until this is called.\r\n * @param transform\r\n */ update(transform) {\n var _a;\n if (transform) {\n this._transform = transform;\n this._transformedPointsDirty = true;\n this._sidesDirty = true;\n // This change means an update must be performed in order for geometry to update\n const globalMat = (_a = transform.matrix) !== null && _a !== void 0 ? _a : this._globalMatrix;\n globalMat.clone(this._globalMatrix);\n this._globalMatrix.translate(this.offset.x, this.offset.y);\n }\n }\n /**\r\n * Tests if a point is contained in this collider in world space\r\n */ contains(point) {\n // Always cast to the right, as long as we cast in a consistent fixed direction we\n // will be fine\n const testRay = new Ray(point, new Vector(1, 0));\n const intersectCount = this.getSides().reduce(function(accum, side) {\n if (testRay.intersect(side) >= 0) return accum + 1;\n return accum;\n }, 0);\n if (intersectCount % 2 === 0) return false;\n return true;\n }\n getClosestLineBetween(collider) {\n if (collider instanceof CircleCollider) return ClosestLineJumpTable.PolygonCircleClosestLine(this, collider);\n else if (collider instanceof PolygonCollider) return ClosestLineJumpTable.PolygonPolygonClosestLine(this, collider);\n else if (collider instanceof EdgeCollider) return ClosestLineJumpTable.PolygonEdgeClosestLine(this, collider);\n else throw new Error(`Polygon could not collide with unknown CollisionShape ${typeof collider}`);\n }\n /**\r\n * Returns a collision contact if the 2 colliders collide, otherwise collide will\r\n * return null.\r\n * @param collider\r\n */ collide(collider) {\n if (collider instanceof CircleCollider) return CollisionJumpTable.CollideCirclePolygon(collider, this);\n else if (collider instanceof PolygonCollider) return CollisionJumpTable.CollidePolygonPolygon(this, collider);\n else if (collider instanceof EdgeCollider) return CollisionJumpTable.CollidePolygonEdge(this, collider);\n else throw new Error(`Polygon could not collide with unknown CollisionShape ${typeof collider}`);\n }\n /**\r\n * Find the point on the collider furthest in the direction specified\r\n */ getFurthestPoint(direction) {\n const pts = this.getTransformedPoints();\n let furthestPoint = null;\n let maxDistance = -Number.MAX_VALUE;\n for(let i = 0; i < pts.length; i++){\n const distance = direction.dot(pts[i]);\n if (distance > maxDistance) {\n maxDistance = distance;\n furthestPoint = pts[i];\n }\n }\n return furthestPoint;\n }\n /**\r\n * Find the local point on the collider furthest in the direction specified\r\n * @param direction\r\n */ getFurthestLocalPoint(direction) {\n const pts = this.points;\n let furthestPoint = pts[0];\n let maxDistance = -Number.MAX_VALUE;\n for(let i = 0; i < pts.length; i++){\n const distance = direction.dot(pts[i]);\n if (distance > maxDistance) {\n maxDistance = distance;\n furthestPoint = pts[i];\n }\n }\n return furthestPoint;\n }\n /**\r\n * Finds the closes face to the point using perpendicular distance\r\n * @param point point to test against polygon\r\n */ getClosestFace(point) {\n const sides = this.getSides();\n let min = Number.POSITIVE_INFINITY;\n let faceIndex = -1;\n let distance = -1;\n for(let i = 0; i < sides.length; i++){\n const dist = sides[i].distanceToPoint(point);\n if (dist < min) {\n min = dist;\n faceIndex = i;\n distance = dist;\n }\n }\n if (faceIndex !== -1) return {\n distance: sides[faceIndex].normal().scale(distance),\n face: sides[faceIndex]\n };\n return null;\n }\n /**\r\n * Get the axis aligned bounding box for the polygon collider in world coordinates\r\n */ get bounds() {\n return this.localBounds.transform(this._globalMatrix);\n }\n /**\r\n * Get the axis aligned bounding box for the polygon collider in local coordinates\r\n */ get localBounds() {\n if (this._localBoundsDirty) {\n this._localBounds = BoundingBox.fromPoints(this.points);\n this._localBoundsDirty = false;\n }\n return this._localBounds;\n }\n /**\r\n * Get the moment of inertia for an arbitrary polygon\r\n * https://en.wikipedia.org/wiki/List_of_moments_of_inertia\r\n */ getInertia(mass) {\n if (this._cachedMass === mass && this._cachedInertia) return this._cachedInertia;\n let numerator = 0;\n let denominator = 0;\n const points = this.points;\n for(let i = 0; i < points.length; i++){\n const iplusone = (i + 1) % points.length;\n const crossTerm = points[iplusone].cross(points[i]);\n numerator += crossTerm * (points[i].dot(points[i]) + points[i].dot(points[iplusone]) + points[iplusone].dot(points[iplusone]));\n denominator += crossTerm;\n }\n this._cachedMass = mass;\n return this._cachedInertia = mass / 6 * (numerator / denominator);\n }\n /**\r\n * Casts a ray into the polygon and returns a vector representing the point of contact (in world space) or null if no collision.\r\n */ rayCast(ray, max = Infinity) {\n // find the minimum contact time greater than 0\n // contact times less than 0 are behind the ray and we don't want those\n const sides = this.getSides();\n const len = sides.length;\n let minContactTime = Number.MAX_VALUE;\n let contactIndex = -1;\n for(let i = 0; i < len; i++){\n const contactTime = ray.intersect(sides[i]);\n if (contactTime >= 0 && contactTime < minContactTime && contactTime <= max) {\n minContactTime = contactTime;\n contactIndex = i;\n }\n }\n // contact was found\n if (contactIndex >= 0) return ray.getPoint(minContactTime);\n // no contact found\n return null;\n }\n /**\r\n * Project the edges of the polygon along a specified axis\r\n */ project(axis) {\n const points = this.getTransformedPoints();\n const len = points.length;\n let min = Number.MAX_VALUE;\n let max = -Number.MAX_VALUE;\n for(let i = 0; i < len; i++){\n const scalar = points[i].dot(axis);\n min = Math.min(min, scalar);\n max = Math.max(max, scalar);\n }\n return new Projection(min, max);\n }\n debug(ex, color) {\n const firstPoint = this.getTransformedPoints()[0];\n const points = [\n firstPoint,\n ...this.getTransformedPoints(),\n firstPoint\n ];\n for(let i = 0; i < points.length - 1; i++){\n ex.drawLine(points[i], points[i + 1], color, 2);\n ex.drawCircle(points[i], 2, color);\n ex.drawCircle(points[i + 1], 2, color);\n }\n }\n }\n /**\r\n * Excalibur helper for defining colliders quickly\r\n */ class Shape {\n /**\r\n * Creates a box collider, under the hood defines a [[PolygonCollider]] collider\r\n * @param width Width of the box\r\n * @param height Height of the box\r\n * @param anchor Anchor of the box (default (.5, .5)) which positions the box relative to the center of the collider's position\r\n * @param offset Optional offset relative to the collider in local coordinates\r\n */ static Box(width, height, anchor = Vector.Half, offset = Vector.Zero) {\n return new PolygonCollider({\n points: new BoundingBox(-width * anchor.x, -height * anchor.y, width - width * anchor.x, height - height * anchor.y).getPoints(),\n offset: offset\n });\n }\n /**\r\n * Creates a new [[PolygonCollider|arbitrary polygon]] collider\r\n *\r\n * PolygonColliders are useful for creating convex polygon shapes\r\n * @param points Points specified in counter clockwise\r\n * @param offset Optional offset relative to the collider in local coordinates\r\n */ static Polygon(points, offset = Vector.Zero) {\n return new PolygonCollider({\n points: points,\n offset: offset\n });\n }\n /**\r\n * Creates a new [[CircleCollider|circle]] collider\r\n *\r\n * Circle colliders are useful for balls, or to make collisions more forgiving on sharp edges\r\n * @param radius Radius of the circle collider\r\n * @param offset Optional offset relative to the collider in local coordinates\r\n */ static Circle(radius, offset = Vector.Zero) {\n return new CircleCollider({\n radius: radius,\n offset: offset\n });\n }\n /**\r\n * Creates a new [[EdgeCollider|edge]] collider\r\n *\r\n * Edge colliders are useful for floors, walls, and other barriers\r\n * @param begin Beginning of the edge in local coordinates to the collider\r\n * @param end Ending of the edge in local coordinates to the collider\r\n */ static Edge(begin, end) {\n return new EdgeCollider({\n begin: begin,\n end: end\n });\n }\n /**\r\n * Creates a new capsule shaped [[CompositeCollider]] using 2 circles and a box\r\n *\r\n * Capsule colliders are useful for platformers with incline or jagged floors to have a smooth\r\n * player experience.\r\n *\r\n * @param width\r\n * @param height\r\n * @param offset Optional offset\r\n */ static Capsule(width, height, offset = Vector.Zero) {\n const logger = Logger.getInstance();\n if (width === height) logger.warn(\"A capsule collider with equal width and height is a circle, consider using a ex.Shape.Circle or ex.CircleCollider\");\n const vertical = height >= width;\n if (vertical) {\n // height > width, if equal maybe use a circle\n const capsule = new CompositeCollider([\n Shape.Circle(width / 2, vec(0, -height / 2 + width / 2).add(offset)),\n Shape.Box(width, height - width, Vector.Half, offset),\n Shape.Circle(width / 2, vec(0, height / 2 - width / 2).add(offset))\n ]);\n return capsule;\n } else {\n // width > height, if equal maybe use a circle\n const capsule = new CompositeCollider([\n Shape.Circle(height / 2, vec(-width / 2 + height / 2, 0).add(offset)),\n Shape.Box(width - height, height, Vector.Half, offset),\n Shape.Circle(height / 2, vec(width / 2 - height / 2, 0).add(offset))\n ]);\n return capsule;\n }\n }\n }\n class ColliderComponent extends Component {\n constructor(collider){\n super();\n this.type = \"ex.collider\";\n this.events = new EventEmitter();\n /**\r\n * Observable that notifies when a collider is added to the body\r\n */ this.$colliderAdded = new Observable();\n /**\r\n * Observable that notifies when a collider is removed from the body\r\n */ this.$colliderRemoved = new Observable();\n this.set(collider);\n }\n /**\r\n * Get the current collider geometry\r\n */ get() {\n return this._collider;\n }\n /**\r\n * Set the collider geometry\r\n * @param collider\r\n * @returns the collider you set\r\n */ set(collider) {\n this.clear();\n if (collider) {\n this._collider = collider;\n this._collider.owner = this.owner;\n collider.events.pipe(this.events);\n this.$colliderAdded.notifyAll(collider);\n this.update();\n }\n return collider;\n }\n /**\r\n * Remove collider geometry from collider component\r\n */ clear() {\n if (this._collider) {\n this._collider.events.unpipe(this.events);\n this.$colliderRemoved.notifyAll(this._collider);\n this._collider.owner = null;\n this._collider = null;\n }\n }\n clone() {\n const clone = new ColliderComponent(this._collider.clone());\n return clone;\n }\n /**\r\n * Return world space bounds\r\n */ get bounds() {\n var _a, _b;\n return (_b = (_a = this._collider) === null || _a === void 0 ? void 0 : _a.bounds) !== null && _b !== void 0 ? _b : new BoundingBox();\n }\n /**\r\n * Return local space bounds\r\n */ get localBounds() {\n var _a, _b;\n return (_b = (_a = this._collider) === null || _a === void 0 ? void 0 : _a.localBounds) !== null && _b !== void 0 ? _b : new BoundingBox();\n }\n /**\r\n * Update the collider's transformed geometry\r\n */ update() {\n var _a;\n const tx = (_a = this.owner) === null || _a === void 0 ? void 0 : _a.get(TransformComponent);\n if (this._collider) {\n this._collider.owner = this.owner;\n if (tx) this._collider.update(tx.get());\n }\n }\n /**\r\n * Collide component with another\r\n * @param other\r\n */ collide(other) {\n let colliderA = this._collider;\n let colliderB = other._collider;\n if (!colliderA || !colliderB) return [];\n // If we have a composite lefthand side :(\n // Might bite us, but to avoid updating all the handlers make composite always left side\n let flipped = false;\n if (colliderB instanceof CompositeCollider) {\n colliderA = colliderB;\n colliderB = this._collider;\n flipped = true;\n }\n if (this._collider) {\n const contacts = colliderA.collide(colliderB);\n if (contacts) {\n if (flipped) contacts.forEach((contact)=>{\n contact.mtv = contact.mtv.negate();\n contact.normal = contact.normal.negate();\n contact.tangent = contact.normal.perpendicular();\n contact.colliderA = this._collider;\n contact.colliderB = other._collider;\n });\n return contacts;\n }\n return [];\n }\n return [];\n }\n onAdd(entity) {\n if (this._collider) this.update();\n // Wire up the collider events to the owning entity\n this.events.on(\"precollision\", (evt)=>{\n const precollision = evt;\n entity.events.emit(\"precollision\", new PreCollisionEvent(precollision.target.owner, precollision.other.owner, precollision.side, precollision.intersection));\n });\n this.events.on(\"postcollision\", (evt)=>{\n const postcollision = evt;\n entity.events.emit(\"postcollision\", new PostCollisionEvent(postcollision.target.owner, postcollision.other.owner, postcollision.side, postcollision.intersection));\n });\n this.events.on(\"collisionstart\", (evt)=>{\n const start = evt;\n entity.events.emit(\"collisionstart\", new CollisionStartEvent(start.target.owner, start.other.owner, start.contact));\n });\n this.events.on(\"collisionend\", (evt)=>{\n const end = evt;\n entity.events.emit(\"collisionend\", new CollisionEndEvent(end.target.owner, end.other.owner));\n });\n }\n onRemove() {\n this.events.clear();\n this.$colliderRemoved.notifyAll(this._collider);\n }\n /**\r\n * Sets up a box geometry based on the current bounds of the associated actor of this physics body.\r\n *\r\n * If no width/height are specified the body will attempt to use the associated actor's width/height.\r\n *\r\n * By default, the box is center is at (0, 0) which means it is centered around the actors anchor.\r\n */ useBoxCollider(width, height, anchor = Vector.Half, center = Vector.Zero) {\n const collider = Shape.Box(width, height, anchor, center);\n return this.set(collider);\n }\n /**\r\n * Sets up a [[PolygonCollider|polygon]] collision geometry based on a list of of points relative\r\n * to the anchor of the associated actor\r\n * of this physics body.\r\n *\r\n * Only [convex polygon](https://en.wikipedia.org/wiki/Convex_polygon) definitions are supported.\r\n *\r\n * By default, the box is center is at (0, 0) which means it is centered around the actors anchor.\r\n */ usePolygonCollider(points, center = Vector.Zero) {\n const poly = Shape.Polygon(points, center);\n return this.set(poly);\n }\n /**\r\n * Sets up a [[Circle|circle collision geometry]] as the only collider with a specified radius in pixels.\r\n *\r\n * By default, the box is center is at (0, 0) which means it is centered around the actors anchor.\r\n */ useCircleCollider(radius, center = Vector.Zero) {\n const collider = Shape.Circle(radius, center);\n return this.set(collider);\n }\n /**\r\n * Sets up an [[Edge|edge collision geometry]] with a start point and an end point relative to the anchor of the associated actor\r\n * of this physics body.\r\n *\r\n * By default, the box is center is at (0, 0) which means it is centered around the actors anchor.\r\n */ useEdgeCollider(begin, end) {\n const collider = Shape.Edge(begin, end);\n return this.set(collider);\n }\n /**\r\n * Setups up a [[CompositeCollider]] which can define any arbitrary set of excalibur colliders\r\n * @param colliders\r\n */ useCompositeCollider(colliders) {\n return this.set(new CompositeCollider(colliders));\n }\n }\n var DegreeOfFreedom;\n (function(DegreeOfFreedom) {\n DegreeOfFreedom[\"Rotation\"] = \"rotation\";\n DegreeOfFreedom[\"X\"] = \"x\";\n DegreeOfFreedom[\"Y\"] = \"y\";\n })(DegreeOfFreedom || (DegreeOfFreedom = {}));\n /**\r\n * Body describes all the physical properties pos, vel, acc, rotation, angular velocity for the purpose of\r\n * of physics simulation.\r\n */ class BodyComponent extends Component {\n constructor(options){\n var _a, _b, _c;\n super();\n this.type = \"ex.body\";\n this.dependencies = [\n TransformComponent,\n MotionComponent\n ];\n this.id = createId(\"body\", BodyComponent._ID++);\n this.events = new EventEmitter();\n this._oldTransform = new Transform();\n /**\r\n * Indicates whether the old transform has been captured at least once for interpolation\r\n * @internal\r\n */ this.__oldTransformCaptured = false;\n /**\r\n * Enable or disabled the fixed update interpolation, by default interpolation is on.\r\n */ this.enableFixedUpdateInterpolate = true;\n /**\r\n * Collision type for the rigidbody physics simulation, by default [[CollisionType.PreventCollision]]\r\n */ this.collisionType = CollisionType.PreventCollision;\n /**\r\n * The collision group for the body's colliders, by default body colliders collide with everything\r\n */ this.group = CollisionGroup.All;\n /**\r\n * The amount of mass the body has\r\n */ this._mass = Physics.defaultMass;\n /**\r\n * Amount of \"motion\" the body has before sleeping. If below [[Physics.sleepEpsilon]] it goes to \"sleep\"\r\n */ this.sleepMotion = Physics.sleepEpsilon * 5;\n /**\r\n * Can this body sleep, by default bodies do not sleep\r\n */ this.canSleep = Physics.bodiesCanSleepByDefault;\n this._sleeping = false;\n /**\r\n * The also known as coefficient of restitution of this actor, represents the amount of energy preserved after collision or the\r\n * bounciness. If 1, it is 100% bouncy, 0 it completely absorbs.\r\n */ this.bounciness = 0.2;\n /**\r\n * The coefficient of friction on this actor\r\n */ this.friction = 0.99;\n /**\r\n * Should use global gravity [[Physics.gravity]] in it's physics simulation, default is true\r\n */ this.useGravity = true;\n /**\r\n * Degrees of freedom to limit\r\n *\r\n * Note: this only limits responses in the realistic solver, if velocity/angularVelocity is set the actor will still respond\r\n */ this.limitDegreeOfFreedom = [];\n /**\r\n * The velocity of the actor last frame (vx, vy) in pixels/second\r\n */ this.oldVel = new Vector(0, 0);\n /**\r\n * Gets/sets the acceleration of the actor from the last frame. This does not include the global acc [[Physics.acc]].\r\n */ this.oldAcc = Vector.Zero;\n if (options) {\n this.collisionType = (_a = options.type) !== null && _a !== void 0 ? _a : this.collisionType;\n this.group = (_b = options.group) !== null && _b !== void 0 ? _b : this.group;\n this.useGravity = (_c = options.useGravity) !== null && _c !== void 0 ? _c : this.useGravity;\n }\n }\n get matrix() {\n return this.transform.get().matrix;\n }\n get mass() {\n return this._mass;\n }\n set mass(newMass) {\n this._mass = newMass;\n this._cachedInertia = undefined;\n this._cachedInverseInertia = undefined;\n }\n /**\r\n * The inverse mass (1/mass) of the body. If [[CollisionType.Fixed]] this is 0, meaning \"infinite\" mass\r\n */ get inverseMass() {\n return this.collisionType === CollisionType.Fixed ? 0 : 1 / this.mass;\n }\n /**\r\n * Whether this body is sleeping or not\r\n */ get sleeping() {\n return this._sleeping;\n }\n /**\r\n * Set the sleep state of the body\r\n * @param sleeping\r\n */ setSleeping(sleeping) {\n this._sleeping = sleeping;\n if (!sleeping) // Give it a kick to keep it from falling asleep immediately\n this.sleepMotion = Physics.sleepEpsilon * 5;\n else {\n this.vel = Vector.Zero;\n this.acc = Vector.Zero;\n this.angularVelocity = 0;\n this.sleepMotion = 0;\n }\n }\n /**\r\n * Update body's [[BodyComponent.sleepMotion]] for the purpose of sleeping\r\n */ updateMotion() {\n if (this._sleeping) this.setSleeping(true);\n const currentMotion = this.vel.size * this.vel.size + Math.abs(this.angularVelocity * this.angularVelocity);\n const bias = Physics.sleepBias;\n this.sleepMotion = bias * this.sleepMotion + (1 - bias) * currentMotion;\n this.sleepMotion = clamp(this.sleepMotion, 0, 10 * Physics.sleepEpsilon);\n if (this.canSleep && this.sleepMotion < Physics.sleepEpsilon) this.setSleeping(true);\n }\n /**\r\n * Get the moment of inertia from the [[ColliderComponent]]\r\n */ get inertia() {\n if (this._cachedInertia) return this._cachedInertia;\n // Inertia is a property of the geometry, so this is a little goofy but seems to be okay?\n const collider = this.owner.get(ColliderComponent);\n if (collider) {\n collider.$colliderAdded.subscribe(()=>{\n this._cachedInertia = null;\n });\n collider.$colliderRemoved.subscribe(()=>{\n this._cachedInertia = null;\n });\n const maybeCollider = collider.get();\n if (maybeCollider) return this._cachedInertia = maybeCollider.getInertia(this.mass);\n }\n return 0;\n }\n /**\r\n * Get the inverse moment of inertial from the [[ColliderComponent]]. If [[CollisionType.Fixed]] this is 0, meaning \"infinite\" mass\r\n */ get inverseInertia() {\n if (this._cachedInverseInertia) return this._cachedInverseInertia;\n return this._cachedInverseInertia = this.collisionType === CollisionType.Fixed ? 0 : 1 / this.inertia;\n }\n /**\r\n * Returns if the owner is active\r\n */ get active() {\n var _a;\n return !!((_a = this.owner) === null || _a === void 0 ? void 0 : _a.active);\n }\n /**\r\n * @deprecated Use globalP0s\r\n */ get center() {\n return this.globalPos;\n }\n get transform() {\n var _a;\n return (_a = this.owner) === null || _a === void 0 ? void 0 : _a.get(TransformComponent);\n }\n get motion() {\n var _a;\n return (_a = this.owner) === null || _a === void 0 ? void 0 : _a.get(MotionComponent);\n }\n get pos() {\n return this.transform.pos;\n }\n set pos(val) {\n this.transform.pos = val;\n }\n /**\r\n * The (x, y) position of the actor this will be in the middle of the actor if the\r\n * [[Actor.anchor]] is set to (0.5, 0.5) which is default.\r\n * If you want the (x, y) position to be the top left of the actor specify an anchor of (0, 0).\r\n */ get globalPos() {\n return this.transform.globalPos;\n }\n set globalPos(val) {\n this.transform.globalPos = val;\n }\n /**\r\n * The position of the actor last frame (x, y) in pixels\r\n */ get oldPos() {\n return this._oldTransform.pos;\n }\n /**\r\n * The current velocity vector (vx, vy) of the actor in pixels/second\r\n */ get vel() {\n return this.motion.vel;\n }\n set vel(val) {\n this.motion.vel = val;\n }\n /**\r\n * The current acceleration vector (ax, ay) of the actor in pixels/second/second. An acceleration pointing down such as (0, 100) may\r\n * be useful to simulate a gravitational effect.\r\n */ get acc() {\n return this.motion.acc;\n }\n set acc(val) {\n this.motion.acc = val;\n }\n /**\r\n * The current torque applied to the actor\r\n */ get torque() {\n return this.motion.torque;\n }\n set torque(val) {\n this.motion.torque = val;\n }\n /**\r\n * Gets/sets the rotation of the body from the last frame.\r\n */ get oldRotation() {\n return this._oldTransform.rotation;\n }\n /**\r\n * The rotation of the body in radians\r\n */ get rotation() {\n return this.transform.globalRotation;\n }\n set rotation(val) {\n this.transform.globalRotation = val;\n }\n /**\r\n * The scale vector of the actor\r\n */ get scale() {\n return this.transform.globalScale;\n }\n set scale(val) {\n this.transform.globalScale = val;\n }\n /**\r\n * The scale of the actor last frame\r\n */ get oldScale() {\n return this._oldTransform.scale;\n }\n /**\r\n * The scale rate of change of the actor in scale/second\r\n */ get scaleFactor() {\n return this.motion.scaleFactor;\n }\n set scaleFactor(scaleFactor) {\n this.motion.scaleFactor = scaleFactor;\n }\n /**\r\n * Get the angular velocity in radians/second\r\n */ get angularVelocity() {\n return this.motion.angularVelocity;\n }\n /**\r\n * Set the angular velocity in radians/second\r\n */ set angularVelocity(value) {\n this.motion.angularVelocity = value;\n }\n /**\r\n * Apply a specific impulse to the body\r\n * @param point\r\n * @param impulse\r\n */ applyImpulse(point, impulse) {\n if (this.collisionType !== CollisionType.Active) return; // only active objects participate in the simulation\n const finalImpulse = impulse.scale(this.inverseMass);\n if (this.limitDegreeOfFreedom.includes(DegreeOfFreedom.X)) finalImpulse.x = 0;\n if (this.limitDegreeOfFreedom.includes(DegreeOfFreedom.Y)) finalImpulse.y = 0;\n this.vel.addEqual(finalImpulse);\n if (!this.limitDegreeOfFreedom.includes(DegreeOfFreedom.Rotation)) {\n const distanceFromCenter = point.sub(this.globalPos);\n this.angularVelocity += this.inverseInertia * distanceFromCenter.cross(impulse);\n }\n }\n /**\r\n * Apply only linear impulse to the body\r\n * @param impulse\r\n */ applyLinearImpulse(impulse) {\n if (this.collisionType !== CollisionType.Active) return; // only active objects participate in the simulation\n const finalImpulse = impulse.scale(this.inverseMass);\n if (this.limitDegreeOfFreedom.includes(DegreeOfFreedom.X)) finalImpulse.x = 0;\n if (this.limitDegreeOfFreedom.includes(DegreeOfFreedom.Y)) finalImpulse.y = 0;\n this.vel = this.vel.add(finalImpulse);\n }\n /**\r\n * Apply only angular impulse to the body\r\n * @param point\r\n * @param impulse\r\n */ applyAngularImpulse(point, impulse) {\n if (this.collisionType !== CollisionType.Active) return; // only active objects participate in the simulation\n if (!this.limitDegreeOfFreedom.includes(DegreeOfFreedom.Rotation)) {\n const distanceFromCenter = point.sub(this.globalPos);\n this.angularVelocity += this.inverseInertia * distanceFromCenter.cross(impulse);\n }\n }\n /**\r\n * Sets the old versions of pos, vel, acc, and scale.\r\n */ captureOldTransform() {\n // Capture old values before integration step updates them\n this.__oldTransformCaptured = true;\n this.transform.get().clone(this._oldTransform);\n this.oldVel.setTo(this.vel.x, this.vel.y);\n this.oldAcc.setTo(this.acc.x, this.acc.y);\n }\n clone() {\n const component = super.clone();\n return component;\n }\n }\n BodyComponent._ID = 0;\n /**\r\n * AddedComponent message\r\n */ class AddedComponent {\n constructor(data){\n this.data = data;\n this.type = \"Component Added\";\n }\n }\n /**\r\n * Type guard to know if message is f an Added Component\r\n */ function isAddedComponent(x) {\n return !!x && x.type === \"Component Added\";\n }\n /**\r\n * RemovedComponent message\r\n */ class RemovedComponent {\n constructor(data){\n this.data = data;\n this.type = \"Component Removed\";\n }\n }\n /**\r\n * Type guard to know if message is for a Removed Component\r\n */ function isRemovedComponent(x) {\n return !!x && x.type === \"Component Removed\";\n }\n const EntityEvents = {\n Initialize: \"initialize\",\n PreUpdate: \"preupdate\",\n PostUpdate: \"postupdate\"\n };\n /**\r\n * An Entity is the base type of anything that can have behavior in Excalibur, they are part of the built in entity component system\r\n *\r\n * Entities can be strongly typed with the components they contain\r\n *\r\n * ```typescript\r\n * const entity = new Entity();\r\n * entity.components.a; // Type ComponentA\r\n * entity.components.b; // Type ComponentB\r\n * ```\r\n */ class Entity {\n constructor(components, name){\n /**\r\n * Listen to or emit events for an entity\r\n */ this.events = new EventEmitter();\n /**\r\n * The unique identifier for the entity\r\n */ this.id = Entity._ID++;\n /**\r\n * The scene that the entity is in, if any\r\n */ this.scene = null;\n this._name = \"anonymous\";\n /**\r\n * Whether this entity is active, if set to false it will be reclaimed\r\n */ this.active = true;\n /**\r\n * Bucket to hold on to deferred removals\r\n */ this._componentsToRemove = [];\n this._componentTypeToInstance = new Map();\n this._componentStringToInstance = new Map();\n this._tagsMemo = [];\n this._typesMemo = [];\n /**\r\n * Observable that keeps track of component add or remove changes on the entity\r\n */ this.componentAdded$ = new Observable();\n this.componentRemoved$ = new Observable();\n this._parent = null;\n this.childrenAdded$ = new Observable();\n this.childrenRemoved$ = new Observable();\n this._children = [];\n this._isInitialized = false;\n this._setName(name);\n if (components) for (const component of components)this.addComponent(component);\n }\n _setName(name) {\n if (name) this._name = name;\n }\n get name() {\n return this._name;\n }\n /**\r\n * Kill the entity, means it will no longer be updated. Kills are deferred to the end of the update.\r\n * If parented it will be removed from the parent when killed.\r\n */ kill() {\n if (this.active) {\n this.active = false;\n this.unparent();\n }\n }\n isKilled() {\n return !this.active;\n }\n /**\r\n * Specifically get the tags on the entity from [[TagComponent]]\r\n */ get tags() {\n return this._tagsMemo;\n }\n /**\r\n * Check if a tag exists on the entity\r\n * @param tag name to check for\r\n */ hasTag(tag) {\n return this.tags.includes(tag);\n }\n /**\r\n * Adds a tag to an entity\r\n * @param tag\r\n * @returns Entity\r\n */ addTag(tag) {\n return this.addComponent(new TagComponent(tag));\n }\n /**\r\n * Removes a tag on the entity\r\n *\r\n * Removals are deferred until the end of update\r\n * @param tag\r\n * @param force Remove component immediately, no deferred\r\n */ removeTag(tag, force = false) {\n return this.removeComponent(tag, force);\n }\n /**\r\n * The types of the components on the Entity\r\n */ get types() {\n return this._typesMemo;\n }\n _rebuildMemos() {\n this._tagsMemo = Array.from(this._componentStringToInstance.values()).filter((c)=>c instanceof TagComponent).map((c)=>c.type);\n this._typesMemo = Array.from(this._componentStringToInstance.keys());\n }\n getComponents() {\n return Array.from(this._componentStringToInstance.values());\n }\n _notifyAddComponent(component) {\n this._rebuildMemos();\n const added = new AddedComponent({\n component: component,\n entity: this\n });\n this.componentAdded$.notifyAll(added);\n }\n _notifyRemoveComponent(component) {\n const removed = new RemovedComponent({\n component: component,\n entity: this\n });\n this.componentRemoved$.notifyAll(removed);\n this._rebuildMemos();\n }\n get parent() {\n return this._parent;\n }\n /**\r\n * Get the direct children of this entity\r\n */ get children() {\n return this._children;\n }\n /**\r\n * Unparents this entity, if there is a parent. Otherwise it does nothing.\r\n */ unparent() {\n if (this._parent) {\n this._parent.removeChild(this);\n this._parent = null;\n }\n }\n /**\r\n * Adds an entity to be a child of this entity\r\n * @param entity\r\n */ addChild(entity) {\n if (entity.parent === null) {\n if (this.getAncestors().includes(entity)) throw new Error(\"Cycle detected, cannot add entity\");\n this._children.push(entity);\n entity._parent = this;\n this.childrenAdded$.notifyAll(entity);\n } else throw new Error(\"Entity already has a parent, cannot add without unparenting\");\n return this;\n }\n /**\r\n * Remove an entity from children if it exists\r\n * @param entity\r\n */ removeChild(entity) {\n if (entity.parent === this) {\n removeItemFromArray(entity, this._children);\n entity._parent = null;\n this.childrenRemoved$.notifyAll(entity);\n }\n return this;\n }\n /**\r\n * Removes all children from this entity\r\n */ removeAllChildren() {\n // Avoid modifying the array issue by walking backwards\n for(let i = this.children.length - 1; i >= 0; i--)this.removeChild(this.children[i]);\n return this;\n }\n /**\r\n * Returns a list of parent entities starting with the topmost parent. Includes the current entity.\r\n */ getAncestors() {\n const result = [\n this\n ];\n let current = this.parent;\n while(current){\n result.push(current);\n current = current.parent;\n }\n return result.reverse();\n }\n /**\r\n * Returns a list of all the entities that descend from this entity. Includes the current entity.\r\n */ getDescendants() {\n let result = [\n this\n ];\n let queue = [\n this\n ];\n while(queue.length > 0){\n const curr = queue.pop();\n queue = queue.concat(curr.children);\n result = result.concat(curr.children);\n }\n return result;\n }\n /**\r\n * Creates a deep copy of the entity and a copy of all its components\r\n */ clone() {\n const newEntity = new Entity();\n for (const c of this.types)newEntity.addComponent(this.get(c).clone());\n for (const child of this.children)newEntity.addChild(child.clone());\n return newEntity;\n }\n /**\r\n * Adds a copy of all the components from another template entity as a \"prefab\"\r\n * @param templateEntity Entity to use as a template\r\n * @param force Force component replacement if it already exists on the target entity\r\n */ addTemplate(templateEntity, force = false) {\n for (const c of templateEntity.getComponents())this.addComponent(c.clone(), force);\n for (const child of templateEntity.children)this.addChild(child.clone().addTemplate(child));\n return this;\n }\n /**\r\n * Adds a component to the entity\r\n * @param component Component or Entity to add copy of components from\r\n * @param force Optionally overwrite any existing components of the same type\r\n */ addComponent(component, force = false) {\n // if component already exists, skip if not forced\n if (this.has(component.type)) {\n if (force) // Remove existing component type if exists when forced\n this.removeComponent(component, true);\n else // early exit component exits\n return this;\n }\n // TODO circular dependencies will be a problem\n if (component.dependencies && component.dependencies.length) for (const ctor of component.dependencies)this.addComponent(new ctor());\n component.owner = this;\n const constuctorType = component.constructor;\n this._componentTypeToInstance.set(constuctorType, component);\n this._componentStringToInstance.set(component.type, component);\n if (component.onAdd) component.onAdd(this);\n this._notifyAddComponent(component);\n return this;\n }\n /**\r\n * Removes a component from the entity, by default removals are deferred to the end of entity update to avoid consistency issues\r\n *\r\n * Components can be force removed with the `force` flag, the removal is not deferred and happens immediately\r\n * @param componentOrType\r\n * @param force\r\n */ removeComponent(componentOrType, force = false) {\n if (force) {\n if (typeof componentOrType === \"string\") this._removeComponentByType(componentOrType);\n else if (componentOrType instanceof Component) this._removeComponentByType(componentOrType.type);\n } else this._componentsToRemove.push(componentOrType);\n return this;\n }\n clearComponents() {\n const components = this.getComponents();\n for (const c of components)this.removeComponent(c);\n }\n _removeComponentByType(type) {\n if (this.has(type)) {\n const component = this.get(type);\n component.owner = null;\n if (component.onRemove) component.onRemove(this);\n const ctor = component.constructor;\n this._componentTypeToInstance.delete(ctor);\n this._componentStringToInstance.delete(component.type);\n this._notifyRemoveComponent(component);\n }\n }\n /**\r\n * @hidden\r\n * @internal\r\n */ processComponentRemoval() {\n for (const componentOrType of this._componentsToRemove){\n const type = typeof componentOrType === \"string\" ? componentOrType : componentOrType.type;\n this._removeComponentByType(type);\n }\n this._componentsToRemove.length = 0;\n }\n has(type) {\n if (typeof type === \"string\") return this._componentStringToInstance.has(type);\n else return this._componentTypeToInstance.has(type);\n }\n get(type) {\n if (typeof type === \"string\") return this._componentStringToInstance.get(type);\n else return this._componentTypeToInstance.get(type);\n }\n /**\r\n * Gets whether the actor is Initialized\r\n */ get isInitialized() {\n return this._isInitialized;\n }\n /**\r\n * Initializes this entity, meant to be called by the Scene before first update not by users of Excalibur.\r\n *\r\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\r\n *\r\n * @internal\r\n */ _initialize(engine) {\n if (!this.isInitialized) {\n this.onInitialize(engine);\n this.events.emit(\"initialize\", new InitializeEvent(engine, this));\n this._isInitialized = true;\n }\n }\n /**\r\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\r\n *\r\n * Internal _preupdate handler for [[onPreUpdate]] lifecycle event\r\n * @internal\r\n */ _preupdate(engine, delta) {\n this.events.emit(\"preupdate\", new PreUpdateEvent(engine, delta, this));\n this.onPreUpdate(engine, delta);\n }\n /**\r\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\r\n *\r\n * Internal _preupdate handler for [[onPostUpdate]] lifecycle event\r\n * @internal\r\n */ _postupdate(engine, delta) {\n this.events.emit(\"postupdate\", new PostUpdateEvent(engine, delta, this));\n this.onPostUpdate(engine, delta);\n }\n /**\r\n * `onInitialize` is called before the first update of the entity. This method is meant to be\r\n * overridden.\r\n *\r\n * Synonymous with the event handler `.on('initialize', (evt) => {...})`\r\n */ onInitialize(_engine) {\n // Override me\n }\n /**\r\n * Safe to override onPreUpdate lifecycle event handler. Synonymous with `.on('preupdate', (evt) =>{...})`\r\n *\r\n * `onPreUpdate` is called directly before an entity is updated.\r\n */ onPreUpdate(_engine, _delta) {\n // Override me\n }\n /**\r\n * Safe to override onPostUpdate lifecycle event handler. Synonymous with `.on('postupdate', (evt) =>{...})`\r\n *\r\n * `onPostUpdate` is called directly after an entity is updated.\r\n */ onPostUpdate(_engine, _delta) {\n // Override me\n }\n /**\r\n *\r\n * Entity update lifecycle, called internally\r\n *\r\n * @internal\r\n * @param engine\r\n * @param delta\r\n */ update(engine, delta) {\n this._initialize(engine);\n this._preupdate(engine, delta);\n for (const child of this.children)child.update(engine, delta);\n this._postupdate(engine, delta);\n }\n emit(eventName, event) {\n this.events.emit(eventName, event);\n }\n on(eventName, handler) {\n return this.events.on(eventName, handler);\n }\n once(eventName, handler) {\n return this.events.once(eventName, handler);\n }\n off(eventName, handler) {\n this.events.off(eventName, handler);\n }\n }\n Entity._ID = 0;\n /**\r\n * Type guard for checking if a Graphic HasTick (used for graphics that change over time like animations)\r\n * @param graphic\r\n */ function hasGraphicsTick(graphic) {\n return !!graphic.tick;\n }\n class GraphicsLayer {\n constructor(_options, _graphics){\n this._options = _options;\n this._graphics = _graphics;\n this.graphics = [];\n }\n get name() {\n return this._options.name;\n }\n hide(nameOrGraphic) {\n if (!nameOrGraphic) this.graphics.length = 0;\n else {\n let gfx = null;\n if (nameOrGraphic instanceof Graphic) gfx = nameOrGraphic;\n else gfx = this._graphics.getGraphic(nameOrGraphic);\n this.graphics = this.graphics.filter((g)=>g.graphic !== gfx);\n this._graphics.recalculateBounds();\n }\n }\n /**\r\n * Show a graphic by name or instance at an offset, graphics are shown in the order in which `show()` is called.\r\n *\r\n * If `show()` is called multiple times for the same graphic it will be shown multiple times.\r\n * @param nameOrGraphic\r\n * @param options\r\n */ show(nameOrGraphic, options) {\n options = {\n ...options\n };\n let gfx;\n if (nameOrGraphic instanceof Graphic) gfx = this._graphics.copyGraphics ? nameOrGraphic.clone() : nameOrGraphic;\n else {\n gfx = this._graphics.getGraphic(nameOrGraphic);\n if (!gfx) Logger.getInstance().error(`No such graphic added to component named ${nameOrGraphic}. These named graphics are available: `, this._graphics.getNames());\n }\n if (gfx) {\n this.graphics.push({\n graphic: gfx,\n options: options\n });\n this._graphics.recalculateBounds();\n return gfx;\n } else return null;\n }\n /**\r\n * Use a specific graphic, swap out any current graphics being shown\r\n * @param nameOrGraphic\r\n * @param options\r\n */ use(nameOrGraphic, options) {\n options = {\n ...options\n };\n this.hide();\n return this.show(nameOrGraphic, options);\n }\n /**\r\n * Current order of the layer, higher numbers are on top, lower numbers are on the bottom.\r\n *\r\n * For example a layer with `order = -1` would be under a layer of `order = 1`\r\n */ get order() {\n return this._options.order;\n }\n /**\r\n * Set the order of the layer, higher numbers are on top, lower numbers are on the bottom.\r\n *\r\n * For example a layer with `order = -1` would be under a layer of `order = 1`\r\n */ set order(order) {\n this._options.order = order;\n }\n /**\r\n * Get or set the pixel offset from the layer anchor for all graphics in the layer\r\n */ get offset() {\n var _a;\n return (_a = this._options.offset) !== null && _a !== void 0 ? _a : Vector.Zero;\n }\n set offset(value) {\n this._options.offset = value;\n }\n get currentKeys() {\n var _a;\n return (_a = this.name) !== null && _a !== void 0 ? _a : \"anonymous\";\n }\n clone(graphicsComponent) {\n const layer = new GraphicsLayer({\n ...this._options\n }, graphicsComponent);\n layer.graphics = [\n ...this.graphics.map((g)=>({\n graphic: g.graphic.clone(),\n options: {\n ...g.options\n }\n }))\n ];\n return layer;\n }\n }\n class GraphicsLayers {\n constructor(_component){\n this._component = _component;\n this._layers = [];\n this._layerMap = {};\n this.default = new GraphicsLayer({\n name: \"default\",\n order: 0\n }, _component);\n this._maybeAddLayer(this.default);\n }\n create(options) {\n const layer = new GraphicsLayer(options, this._component);\n return this._maybeAddLayer(layer);\n }\n get(name) {\n if (name) return this._getLayer(name);\n return this._layers;\n }\n currentKeys() {\n const graphicsLayerKeys = [];\n for (const layer of this._layers)graphicsLayerKeys.push(layer.currentKeys);\n return graphicsLayerKeys;\n }\n has(name) {\n return name in this._layerMap;\n }\n _maybeAddLayer(layer) {\n if (this._layerMap[layer.name]) // todo log warning\n return this._layerMap[layer.name];\n this._layerMap[layer.name] = layer;\n this._layers.push(layer);\n this._layers.sort((a, b)=>a.order - b.order);\n return layer;\n }\n _getLayer(name) {\n return this._layerMap[name];\n }\n clone(graphicsComponent) {\n const layers = new GraphicsLayers(graphicsComponent);\n layers._layerMap = {};\n layers._layers = [];\n layers.default = this.default.clone(graphicsComponent);\n layers._maybeAddLayer(layers.default);\n // Remove the default layer out of the clone\n const clonedLayers = this._layers.filter((l)=>l.name !== \"default\").map((l)=>l.clone(graphicsComponent));\n clonedLayers.forEach((layer)=>layers._maybeAddLayer(layer));\n return layers;\n }\n }\n /**\r\n * Component to manage drawings, using with the position component\r\n */ class GraphicsComponent extends Component {\n getGraphic(name) {\n return this._graphics[name];\n }\n /**\r\n * Get registered graphics names\r\n */ getNames() {\n return Object.keys(this._graphics);\n }\n constructor(options){\n super();\n this.type = \"ex.graphics\";\n this._graphics = {};\n /**\r\n * Sets or gets wether any drawing should be visible in this component\r\n */ this.visible = true;\n /**\r\n * Sets or gets wither all drawings should have an opacity applied\r\n */ this.opacity = 1;\n /**\r\n * Offset to apply to graphics by default\r\n */ this.offset = Vector.Zero;\n /**\r\n * Anchor to apply to graphics by default\r\n */ this.anchor = Vector.Half;\n /**\r\n * Flip all graphics horizontally along the y-axis\r\n */ this.flipHorizontal = false;\n /**\r\n * Flip all graphics vertically along the x-axis\r\n */ this.flipVertical = false;\n /**\r\n * If set to true graphics added to the component will be copied. This can affect performance\r\n */ this.copyGraphics = false;\n this._localBounds = null;\n // Defaults\n options = {\n visible: this.visible,\n ...options\n };\n const { current: current, anchor: anchor, opacity: opacity, visible: visible, graphics: graphics, offset: offset, copyGraphics: copyGraphics, onPreDraw: onPreDraw, onPostDraw: onPostDraw } = options;\n this._graphics = graphics || {};\n this.offset = offset !== null && offset !== void 0 ? offset : this.offset;\n this.opacity = opacity !== null && opacity !== void 0 ? opacity : this.opacity;\n this.anchor = anchor !== null && anchor !== void 0 ? anchor : this.anchor;\n this.copyGraphics = copyGraphics !== null && copyGraphics !== void 0 ? copyGraphics : this.copyGraphics;\n this.onPreDraw = onPreDraw !== null && onPreDraw !== void 0 ? onPreDraw : this.onPreDraw;\n this.onPostDraw = onPostDraw !== null && onPostDraw !== void 0 ? onPostDraw : this.onPostDraw;\n this.visible = !!visible;\n this.layers = new GraphicsLayers(this);\n if (current && this._graphics[current]) this.show(this._graphics[current]);\n }\n /**\r\n * Returns the currently displayed graphics and their offsets, empty array if hidden\r\n */ get current() {\n return this.layers.default.graphics;\n }\n /**\r\n * Returns all graphics associated with this component\r\n */ get graphics() {\n return this._graphics;\n }\n add(nameOrGraphic, graphic) {\n let name = \"default\";\n let graphicToSet = null;\n if (typeof nameOrGraphic === \"string\") {\n name = nameOrGraphic;\n graphicToSet = graphic;\n } else graphicToSet = nameOrGraphic;\n this._graphics[name] = this.copyGraphics ? graphicToSet.clone() : graphicToSet;\n if (name === \"default\") this.show(\"default\");\n return graphicToSet;\n }\n /**\r\n * Show a graphic by name on the **default** layer, returns the new [[Graphic]]\r\n */ show(nameOrGraphic, options) {\n const result = this.layers.default.show(nameOrGraphic, options);\n this.recalculateBounds();\n return result;\n }\n /**\r\n * Use a graphic only, swap out any graphics on the **default** layer, returns the new [[Graphic]]\r\n * @param nameOrGraphic\r\n * @param options\r\n */ use(nameOrGraphic, options) {\n const result = this.layers.default.use(nameOrGraphic, options);\n this.recalculateBounds();\n return result;\n }\n hide(nameOrGraphic) {\n this.layers.default.hide(nameOrGraphic);\n }\n set localBounds(bounds) {\n this._localBounds = bounds;\n }\n recalculateBounds() {\n let bb = new BoundingBox();\n for (const layer of this.layers.get())for (const { graphic: graphic, options: options } of layer.graphics){\n let anchor = this.anchor;\n let offset = this.offset;\n if (options === null || options === void 0 ? void 0 : options.anchor) anchor = options.anchor;\n if (options === null || options === void 0 ? void 0 : options.offset) offset = options.offset;\n const bounds = graphic.localBounds;\n const offsetX = -bounds.width * anchor.x + offset.x;\n const offsetY = -bounds.height * anchor.y + offset.y;\n bb = graphic === null || graphic === void 0 ? void 0 : graphic.localBounds.translate(vec(offsetX + layer.offset.x, offsetY + layer.offset.y)).combine(bb);\n }\n this._localBounds = bb;\n }\n get localBounds() {\n if (!this._localBounds || this._localBounds.hasZeroDimensions()) this.recalculateBounds();\n return this._localBounds;\n }\n /**\r\n * Update underlying graphics if necesary, called internally\r\n * @param elapsed\r\n * @internal\r\n */ update(elapsed, idempotencyToken = 0) {\n for (const layer of this.layers.get()){\n for (const { graphic: graphic } of layer.graphics)if (hasGraphicsTick(graphic)) graphic === null || graphic === void 0 || graphic.tick(elapsed, idempotencyToken);\n }\n }\n clone() {\n const graphics = new GraphicsComponent();\n graphics._graphics = {\n ...this._graphics\n };\n graphics.offset = this.offset.clone();\n graphics.opacity = this.opacity;\n graphics.anchor = this.anchor.clone();\n graphics.copyGraphics = this.copyGraphics;\n graphics.onPreDraw = this.onPreDraw;\n graphics.onPostDraw = this.onPostDraw;\n graphics.visible = this.visible;\n graphics.layers = this.layers.clone(graphics);\n return graphics;\n }\n }\n /**\r\n * A Rectangle [[Graphic]] for drawing rectangles to the [[ExcaliburGraphicsContext]]\r\n */ class Rectangle extends Raster {\n constructor(options){\n super(options);\n this.width = options.width;\n this.height = options.height;\n this.rasterize();\n }\n clone() {\n return new Rectangle({\n width: this.width,\n height: this.height,\n ...this.cloneGraphicOptions(),\n ...this.cloneRasterOptions()\n });\n }\n execute(ctx) {\n if (this.color) ctx.fillRect(0, 0, this.width, this.height);\n if (this.strokeColor) ctx.strokeRect(0, 0, this.width, this.height);\n }\n }\n /**\r\n * A circle [[Graphic]] for drawing circles to the [[ExcaliburGraphicsContext]]\r\n *\r\n * Circles default to [[ImageFiltering.Blended]]\r\n */ class Circle extends Raster {\n get radius() {\n return this._radius;\n }\n set radius(value) {\n this._radius = value;\n this.width = this._radius * 2;\n this.height = this._radius * 2;\n this.flagDirty();\n }\n constructor(options){\n var _a, _b, _c;\n super(options);\n this._radius = 0;\n const lineWidth = (_a = options.lineWidth) !== null && _a !== void 0 ? _a : options.strokeColor ? 1 : 0; // default lineWidth in canvas is 1px\n this.padding = (_b = options.padding) !== null && _b !== void 0 ? _b : 2 + lineWidth / 2; // default 2 padding for circles looks nice\n this.radius = options.radius;\n this.filtering = (_c = options.filtering) !== null && _c !== void 0 ? _c : ImageFiltering.Blended;\n this.rasterize();\n }\n clone() {\n return new Circle({\n radius: this.radius,\n ...this.cloneGraphicOptions(),\n ...this.cloneRasterOptions()\n });\n }\n execute(ctx) {\n if (this.radius > 0) {\n ctx.beginPath();\n ctx.arc(this.radius, this.radius, this.radius, 0, Math.PI * 2);\n if (this.color) ctx.fill();\n if (this.strokeColor) ctx.stroke();\n }\n }\n }\n /**\r\n * Add this component to optionally configure how the pointer\r\n * system detects pointer events.\r\n *\r\n * By default the collider shape is used and graphics bounds is not.\r\n *\r\n * If both collider shape and graphics bounds are enabled it will fire events if either or\r\n * are intersecting the pointer.\r\n */ class PointerComponent extends Component {\n constructor(){\n super(...arguments);\n this.type = \"ex.pointer\";\n /**\r\n * Use any existing Collider component geometry for pointer events. This is useful if you want\r\n * user pointer events only to trigger on the same collision geometry used in the collider component\r\n * for collision resolution. Default is `true`.\r\n */ this.useColliderShape = true;\n /**\r\n * Use any existing Graphics component bounds for pointers. This is useful if you want the axis aligned\r\n * bounds around the graphic to trigger pointer events. Default is `false`.\r\n */ this.useGraphicsBounds = false;\n }\n }\n /**\r\n * Standard easing functions for motion in Excalibur, defined on a domain of [0, duration] and a range from [+startValue,+endValue]\r\n * Given a time, the function will return a value from positive startValue to positive endValue.\r\n *\r\n * ```js\r\n * function Linear (t) {\r\n * return t * t;\r\n * }\r\n *\r\n * // accelerating from zero velocity\r\n * function EaseInQuad (t) {\r\n * return t * t;\r\n * }\r\n *\r\n * // decelerating to zero velocity\r\n * function EaseOutQuad (t) {\r\n * return t * (2 - t);\r\n * }\r\n *\r\n * // acceleration until halfway, then deceleration\r\n * function EaseInOutQuad (t) {\r\n * return t < .5 ? 2 * t * t : -1 + (4 - 2 * t) * t;\r\n * }\r\n *\r\n * // accelerating from zero velocity\r\n * function EaseInCubic (t) {\r\n * return t * t * t;\r\n * }\r\n *\r\n * // decelerating to zero velocity\r\n * function EaseOutCubic (t) {\r\n * return (--t) * t * t + 1;\r\n * }\r\n *\r\n * // acceleration until halfway, then deceleration\r\n * function EaseInOutCubic (t) {\r\n * return t < .5 ? 4 * t * t * t : (t - 1) * (2 * t - 2) * (2 * t - 2) + 1;\r\n * }\r\n * ```\r\n */ class EasingFunctions {\n static CreateReversibleEasingFunction(easing) {\n return (time, start, end, duration)=>{\n if (end < start) return start - (easing(time, end, start, duration) - end);\n else return easing(time, start, end, duration);\n };\n }\n static CreateVectorEasingFunction(easing) {\n return (time, start, end, duration)=>{\n return new Vector(easing(time, start.x, end.x, duration), easing(time, start.y, end.y, duration));\n };\n }\n }\n EasingFunctions.Linear = EasingFunctions.CreateReversibleEasingFunction((currentTime, startValue, endValue, duration)=>{\n endValue = endValue - startValue;\n return endValue * currentTime / duration + startValue;\n });\n EasingFunctions.EaseInQuad = EasingFunctions.CreateReversibleEasingFunction((currentTime, startValue, endValue, duration)=>{\n endValue = endValue - startValue;\n currentTime /= duration;\n return endValue * currentTime * currentTime + startValue;\n });\n EasingFunctions.EaseOutQuad = EasingFunctions.CreateReversibleEasingFunction((currentTime, startValue, endValue, duration)=>{\n endValue = endValue - startValue;\n currentTime /= duration;\n return -endValue * currentTime * (currentTime - 2) + startValue;\n });\n EasingFunctions.EaseInOutQuad = EasingFunctions.CreateReversibleEasingFunction((currentTime, startValue, endValue, duration)=>{\n endValue = endValue - startValue;\n currentTime /= duration / 2;\n if (currentTime < 1) return endValue / 2 * currentTime * currentTime + startValue;\n currentTime--;\n return -endValue / 2 * (currentTime * (currentTime - 2) - 1) + startValue;\n });\n EasingFunctions.EaseInCubic = EasingFunctions.CreateReversibleEasingFunction((currentTime, startValue, endValue, duration)=>{\n endValue = endValue - startValue;\n currentTime /= duration;\n return endValue * currentTime * currentTime * currentTime + startValue;\n });\n EasingFunctions.EaseOutCubic = EasingFunctions.CreateReversibleEasingFunction((currentTime, startValue, endValue, duration)=>{\n endValue = endValue - startValue;\n currentTime /= duration;\n currentTime--;\n return endValue * (currentTime * currentTime * currentTime + 1) + startValue;\n });\n EasingFunctions.EaseInOutCubic = EasingFunctions.CreateReversibleEasingFunction((currentTime, startValue, endValue, duration)=>{\n endValue = endValue - startValue;\n currentTime /= duration / 2;\n if (currentTime < 1) return endValue / 2 * currentTime * currentTime * currentTime + startValue;\n currentTime -= 2;\n return endValue / 2 * (currentTime * currentTime * currentTime + 2) + startValue;\n });\n /**\r\n * Action Queues represent an ordered sequence of actions\r\n *\r\n * Action queues are part of the [[ActionContext|Action API]] and\r\n * store the list of actions to be executed for an [[Actor]].\r\n *\r\n * Actors implement [[Actor.actions]] which can be manipulated by\r\n * advanced users to adjust the actions currently being executed in the\r\n * queue.\r\n */ class ActionQueue {\n constructor(entity){\n this._actions = [];\n this._completedActions = [];\n this._entity = entity;\n }\n /**\r\n * Add an action to the sequence\r\n * @param action\r\n */ add(action) {\n this._actions.push(action);\n }\n /**\r\n * Remove an action by reference from the sequence\r\n * @param action\r\n */ remove(action) {\n const index = this._actions.indexOf(action);\n this._actions.splice(index, 1);\n }\n /**\r\n * Removes all actions from this sequence\r\n */ clearActions() {\n this._actions.length = 0;\n this._completedActions.length = 0;\n if (this._currentAction) this._currentAction.stop();\n }\n /**\r\n *\r\n * @returns The total list of actions in this sequence complete or not\r\n */ getActions() {\n return this._actions.concat(this._completedActions);\n }\n /**\r\n *\r\n * @returns `true` if there are more actions to process in the sequence\r\n */ hasNext() {\n return this._actions.length > 0;\n }\n /**\r\n * @returns `true` if the current sequence of actions is done\r\n */ isComplete() {\n return this._actions.length === 0;\n }\n /**\r\n * Resets the sequence of actions, this is used to restart a sequence from the beginning\r\n */ reset() {\n this._actions = this.getActions();\n const len = this._actions.length;\n for(let i = 0; i < len; i++)this._actions[i].reset();\n this._completedActions = [];\n }\n /**\r\n * Update the queue which updates actions and handles completing actions\r\n * @param elapsedMs\r\n */ update(elapsedMs) {\n if (this._actions.length > 0) {\n this._currentAction = this._actions[0];\n this._currentAction.update(elapsedMs);\n if (this._currentAction.isComplete(this._entity)) this._completedActions.push(this._actions.shift());\n }\n }\n }\n class Repeat {\n constructor(entity, repeatBuilder, repeat){\n this._stopped = false;\n this._repeatBuilder = repeatBuilder;\n this._repeatContext = new ActionContext(entity);\n this._actionQueue = this._repeatContext.getQueue();\n this._repeat = repeat;\n this._originalRepeat = repeat;\n this._repeatBuilder(this._repeatContext);\n this._repeat--; // current execution is the first repeat\n }\n update(delta) {\n if (this._actionQueue.isComplete()) {\n this._actionQueue.clearActions();\n this._repeatBuilder(this._repeatContext);\n this._repeat--;\n }\n this._actionQueue.update(delta);\n }\n isComplete() {\n return this._stopped || this._repeat <= 0 && this._actionQueue.isComplete();\n }\n stop() {\n this._stopped = true;\n }\n reset() {\n this._repeat = this._originalRepeat;\n }\n }\n /**\r\n * RepeatForever Action implementation, it is recommended you use the fluent action\r\n * context API.\r\n *\r\n *\r\n */ class RepeatForever {\n constructor(entity, repeatBuilder){\n this._stopped = false;\n this._repeatBuilder = repeatBuilder;\n this._repeatContext = new ActionContext(entity);\n this._actionQueue = this._repeatContext.getQueue();\n this._repeatBuilder(this._repeatContext);\n }\n update(delta) {\n if (this._stopped) return;\n if (this._actionQueue.isComplete()) {\n this._actionQueue.clearActions();\n this._repeatBuilder(this._repeatContext);\n }\n this._actionQueue.update(delta);\n }\n isComplete() {\n return this._stopped;\n }\n stop() {\n this._stopped = true;\n this._actionQueue.clearActions();\n }\n reset() {\n return;\n }\n }\n class MoveBy {\n constructor(entity, offsetX, offsetY, speed){\n this._started = false;\n this._stopped = false;\n this._entity = entity;\n this._tx = entity.get(TransformComponent);\n this._motion = entity.get(MotionComponent);\n this._speed = speed;\n this._offset = new Vector(offsetX, offsetY);\n if (speed <= 0) {\n Logger.getInstance().error(\"Attempted to moveBy with speed less than or equal to zero : \" + speed);\n throw new Error(\"Speed must be greater than 0 pixels per second\");\n }\n }\n update(_delta) {\n if (!this._started) {\n this._started = true;\n this._start = new Vector(this._tx.pos.x, this._tx.pos.y);\n this._end = this._start.add(this._offset);\n this._distance = this._offset.size;\n this._dir = this._end.sub(this._start).normalize();\n }\n if (this.isComplete(this._entity)) {\n this._tx.pos = vec(this._end.x, this._end.y);\n this._motion.vel = vec(0, 0);\n } else this._motion.vel = this._dir.scale(this._speed);\n }\n isComplete(entity) {\n const tx = entity.get(TransformComponent);\n return this._stopped || tx.pos.distance(this._start) >= this._distance;\n }\n stop() {\n this._motion.vel = vec(0, 0);\n this._stopped = true;\n }\n reset() {\n this._started = false;\n this._stopped = false;\n }\n }\n class MoveTo {\n constructor(entity, destx, desty, speed){\n this.entity = entity;\n this._started = false;\n this._stopped = false;\n this._tx = entity.get(TransformComponent);\n this._motion = entity.get(MotionComponent);\n this._end = new Vector(destx, desty);\n this._speed = speed;\n }\n update(_delta) {\n if (!this._started) {\n this._started = true;\n this._start = new Vector(this._tx.pos.x, this._tx.pos.y);\n this._distance = this._start.distance(this._end);\n this._dir = this._end.sub(this._start).normalize();\n }\n const m = this._dir.scale(this._speed);\n this._motion.vel = vec(m.x, m.y);\n if (this.isComplete(this.entity)) {\n this._tx.pos = vec(this._end.x, this._end.y);\n this._motion.vel = vec(0, 0);\n }\n }\n isComplete(entity) {\n const tx = entity.get(TransformComponent);\n return this._stopped || new Vector(tx.pos.x, tx.pos.y).distance(this._start) >= this._distance;\n }\n stop() {\n this._motion.vel = vec(0, 0);\n this._stopped = true;\n }\n reset() {\n this._started = false;\n this._stopped = false;\n }\n }\n /**\r\n * An enum that describes the strategies that rotation actions can use\r\n */ var RotationType;\n (function(RotationType) {\n /**\r\n * Rotation via `ShortestPath` will use the smallest angle\r\n * between the starting and ending points. This strategy is the default behavior.\r\n */ RotationType[RotationType[\"ShortestPath\"] = 0] = \"ShortestPath\";\n /**\r\n * Rotation via `LongestPath` will use the largest angle\r\n * between the starting and ending points.\r\n */ RotationType[RotationType[\"LongestPath\"] = 1] = \"LongestPath\";\n /**\r\n * Rotation via `Clockwise` will travel in a clockwise direction,\r\n * regardless of the starting and ending points.\r\n */ RotationType[RotationType[\"Clockwise\"] = 2] = \"Clockwise\";\n /**\r\n * Rotation via `CounterClockwise` will travel in a counterclockwise direction,\r\n * regardless of the starting and ending points.\r\n */ RotationType[RotationType[\"CounterClockwise\"] = 3] = \"CounterClockwise\";\n })(RotationType || (RotationType = {}));\n class RotateTo {\n constructor(entity, angleRadians, speed, rotationType){\n this._started = false;\n this._stopped = false;\n this._tx = entity.get(TransformComponent);\n this._motion = entity.get(MotionComponent);\n this._end = angleRadians;\n this._speed = speed;\n this._rotationType = rotationType || RotationType.ShortestPath;\n }\n update(_delta) {\n if (!this._started) {\n this._started = true;\n this._start = this._tx.rotation;\n this._currentNonCannonAngle = this._tx.rotation;\n const distance1 = Math.abs(this._end - this._start);\n const distance2 = TwoPI - distance1;\n if (distance1 > distance2) {\n this._shortDistance = distance2;\n this._longDistance = distance1;\n } else {\n this._shortDistance = distance1;\n this._longDistance = distance2;\n }\n this._shortestPathIsPositive = (this._start - this._end + TwoPI) % TwoPI >= Math.PI;\n switch(this._rotationType){\n case RotationType.ShortestPath:\n this._distance = this._shortDistance;\n if (this._shortestPathIsPositive) this._direction = 1;\n else this._direction = -1;\n break;\n case RotationType.LongestPath:\n this._distance = this._longDistance;\n if (this._shortestPathIsPositive) this._direction = -1;\n else this._direction = 1;\n break;\n case RotationType.Clockwise:\n this._direction = 1;\n if (this._shortestPathIsPositive) this._distance = this._shortDistance;\n else this._distance = this._longDistance;\n break;\n case RotationType.CounterClockwise:\n this._direction = -1;\n if (!this._shortestPathIsPositive) this._distance = this._shortDistance;\n else this._distance = this._longDistance;\n break;\n }\n }\n this._motion.angularVelocity = this._direction * this._speed;\n this._currentNonCannonAngle += this._direction * this._speed * (_delta / 1000);\n if (this.isComplete()) {\n this._tx.rotation = this._end;\n this._motion.angularVelocity = 0;\n this._stopped = true;\n }\n }\n isComplete() {\n const distanceTraveled = Math.abs(this._currentNonCannonAngle - this._start);\n return this._stopped || distanceTraveled >= Math.abs(this._distance);\n }\n stop() {\n this._motion.angularVelocity = 0;\n this._stopped = true;\n }\n reset() {\n this._started = false;\n this._stopped = false;\n }\n }\n class RotateBy {\n constructor(entity, angleRadiansOffset, speed, rotationType){\n this._started = false;\n this._stopped = false;\n this._tx = entity.get(TransformComponent);\n this._motion = entity.get(MotionComponent);\n this._speed = speed;\n this._offset = angleRadiansOffset;\n this._rotationType = rotationType || RotationType.ShortestPath;\n }\n update(_delta) {\n if (!this._started) {\n this._started = true;\n this._start = this._tx.rotation;\n this._currentNonCannonAngle = this._tx.rotation;\n this._end = this._start + this._offset;\n const distance1 = Math.abs(this._end - this._start);\n const distance2 = TwoPI - distance1;\n if (distance1 > distance2) {\n this._shortDistance = distance2;\n this._longDistance = distance1;\n } else {\n this._shortDistance = distance1;\n this._longDistance = distance2;\n }\n this._shortestPathIsPositive = (this._start - this._end + TwoPI) % TwoPI >= Math.PI;\n switch(this._rotationType){\n case RotationType.ShortestPath:\n this._distance = this._shortDistance;\n if (this._shortestPathIsPositive) this._direction = 1;\n else this._direction = -1;\n break;\n case RotationType.LongestPath:\n this._distance = this._longDistance;\n if (this._shortestPathIsPositive) this._direction = -1;\n else this._direction = 1;\n break;\n case RotationType.Clockwise:\n this._direction = 1;\n if (this._shortDistance >= 0) this._distance = this._shortDistance;\n else this._distance = this._longDistance;\n break;\n case RotationType.CounterClockwise:\n this._direction = -1;\n if (this._shortDistance <= 0) this._distance = this._shortDistance;\n else this._distance = this._longDistance;\n break;\n }\n }\n this._motion.angularVelocity = this._direction * this._speed;\n this._currentNonCannonAngle += this._direction * this._speed * (_delta / 1000);\n if (this.isComplete()) {\n this._tx.rotation = this._end;\n this._motion.angularVelocity = 0;\n this._stopped = true;\n }\n }\n isComplete() {\n const distanceTraveled = Math.abs(this._currentNonCannonAngle - this._start);\n return this._stopped || distanceTraveled >= Math.abs(this._distance);\n }\n stop() {\n this._motion.angularVelocity = 0;\n this._stopped = true;\n }\n reset() {\n this._started = false;\n this._stopped = false;\n this._start = undefined;\n this._currentNonCannonAngle = undefined;\n this._distance = undefined;\n }\n }\n class ScaleTo {\n constructor(entity, scaleX, scaleY, speedX, speedY){\n this._started = false;\n this._stopped = false;\n this._tx = entity.get(TransformComponent);\n this._motion = entity.get(MotionComponent);\n this._endX = scaleX;\n this._endY = scaleY;\n this._speedX = speedX;\n this._speedY = speedY;\n }\n update(_delta) {\n if (!this._started) {\n this._started = true;\n this._startX = this._tx.scale.x;\n this._startY = this._tx.scale.y;\n this._distanceX = Math.abs(this._endX - this._startX);\n this._distanceY = Math.abs(this._endY - this._startY);\n }\n if (!(Math.abs(this._tx.scale.x - this._startX) >= this._distanceX)) {\n const directionX = this._endY < this._startY ? -1 : 1;\n this._motion.scaleFactor.x = this._speedX * directionX;\n } else this._motion.scaleFactor.x = 0;\n if (!(Math.abs(this._tx.scale.y - this._startY) >= this._distanceY)) {\n const directionY = this._endY < this._startY ? -1 : 1;\n this._motion.scaleFactor.y = this._speedY * directionY;\n } else this._motion.scaleFactor.y = 0;\n if (this.isComplete()) {\n this._tx.scale = vec(this._endX, this._endY);\n this._motion.scaleFactor.x = 0;\n this._motion.scaleFactor.y = 0;\n }\n }\n isComplete() {\n return this._stopped || Math.abs(this._tx.scale.x - this._startX) >= this._distanceX - 0.01 && Math.abs(this._tx.scale.y - this._startY) >= this._distanceY - 0.01;\n }\n stop() {\n this._motion.scaleFactor.x = 0;\n this._motion.scaleFactor.y = 0;\n this._stopped = true;\n }\n reset() {\n this._started = false;\n this._stopped = false;\n }\n }\n class ScaleBy {\n constructor(entity, scaleOffsetX, scaleOffsetY, speed){\n this._started = false;\n this._stopped = false;\n this._tx = entity.get(TransformComponent);\n this._motion = entity.get(MotionComponent);\n this._offset = new Vector(scaleOffsetX, scaleOffsetY);\n this._speedX = this._speedY = speed;\n }\n update(_delta) {\n if (!this._started) {\n this._started = true;\n this._startScale = this._tx.scale.clone();\n this._endScale = this._startScale.add(this._offset);\n this._distanceX = Math.abs(this._endScale.x - this._startScale.x);\n this._distanceY = Math.abs(this._endScale.y - this._startScale.y);\n this._directionX = this._endScale.x < this._startScale.x ? -1 : 1;\n this._directionY = this._endScale.y < this._startScale.y ? -1 : 1;\n }\n this._motion.scaleFactor.x = this._speedX * this._directionX;\n this._motion.scaleFactor.y = this._speedY * this._directionY;\n if (this.isComplete()) {\n this._tx.scale = this._endScale;\n this._motion.scaleFactor.x = 0;\n this._motion.scaleFactor.y = 0;\n }\n }\n isComplete() {\n return this._stopped || Math.abs(this._tx.scale.x - this._startScale.x) >= this._distanceX - 0.01 && Math.abs(this._tx.scale.y - this._startScale.y) >= this._distanceY - 0.01;\n }\n stop() {\n this._motion.scaleFactor.x = 0;\n this._motion.scaleFactor.y = 0;\n this._stopped = true;\n }\n reset() {\n this._started = false;\n this._stopped = false;\n }\n }\n class CallMethod {\n constructor(method){\n this._method = null;\n this._hasBeenCalled = false;\n this._method = method;\n }\n update(_delta) {\n this._method();\n this._hasBeenCalled = true;\n }\n isComplete() {\n return this._hasBeenCalled;\n }\n reset() {\n this._hasBeenCalled = false;\n }\n stop() {\n this._hasBeenCalled = true;\n }\n }\n class EaseTo {\n constructor(entity, x, y, duration, easingFcn){\n this.easingFcn = easingFcn;\n this._currentLerpTime = 0;\n this._lerpDuration = 1000; // 1 second\n this._lerpStart = new Vector(0, 0);\n this._lerpEnd = new Vector(0, 0);\n this._initialized = false;\n this._stopped = false;\n this._tx = entity.get(TransformComponent);\n this._motion = entity.get(MotionComponent);\n this._lerpDuration = duration;\n this._lerpEnd = new Vector(x, y);\n }\n _initialize() {\n this._lerpStart = new Vector(this._tx.pos.x, this._tx.pos.y);\n this._currentLerpTime = 0;\n }\n update(delta) {\n if (!this._initialized) {\n this._initialize();\n this._initialized = true;\n }\n // Need to update lerp time first, otherwise the first update will always be zero\n this._currentLerpTime += delta;\n let newX = this._tx.pos.x;\n let newY = this._tx.pos.y;\n if (this._currentLerpTime < this._lerpDuration) {\n if (this._lerpEnd.x < this._lerpStart.x) newX = this._lerpStart.x - (this.easingFcn(this._currentLerpTime, this._lerpEnd.x, this._lerpStart.x, this._lerpDuration) - this._lerpEnd.x);\n else newX = this.easingFcn(this._currentLerpTime, this._lerpStart.x, this._lerpEnd.x, this._lerpDuration);\n if (this._lerpEnd.y < this._lerpStart.y) newY = this._lerpStart.y - (this.easingFcn(this._currentLerpTime, this._lerpEnd.y, this._lerpStart.y, this._lerpDuration) - this._lerpEnd.y);\n else newY = this.easingFcn(this._currentLerpTime, this._lerpStart.y, this._lerpEnd.y, this._lerpDuration);\n // Given the lerp position figure out the velocity in pixels per second\n this._motion.vel = vec((newX - this._tx.pos.x) / (delta / 1000), (newY - this._tx.pos.y) / (delta / 1000));\n } else {\n this._tx.pos = vec(this._lerpEnd.x, this._lerpEnd.y);\n this._motion.vel = Vector.Zero;\n }\n }\n isComplete() {\n return this._stopped || this._currentLerpTime >= this._lerpDuration;\n }\n reset() {\n this._initialized = false;\n this._stopped = false;\n this._currentLerpTime = 0;\n }\n stop() {\n this._motion.vel = vec(0, 0);\n this._stopped = true;\n }\n }\n class EaseBy {\n constructor(entity, offsetX, offsetY, duration, easingFcn){\n this.easingFcn = easingFcn;\n this._currentLerpTime = 0;\n this._lerpDuration = 1000; // 1 second\n this._lerpStart = new Vector(0, 0);\n this._lerpEnd = new Vector(0, 0);\n this._initialized = false;\n this._stopped = false;\n this._tx = entity.get(TransformComponent);\n this._motion = entity.get(MotionComponent);\n this._lerpDuration = duration;\n this._offset = new Vector(offsetX, offsetY);\n }\n _initialize() {\n this._lerpStart = new Vector(this._tx.pos.x, this._tx.pos.y);\n this._currentLerpTime = 0;\n this._lerpEnd = this._lerpStart.add(this._offset);\n }\n update(delta) {\n if (!this._initialized) {\n this._initialize();\n this._initialized = true;\n }\n // Need to update lerp time first, otherwise the first update will always be zero\n this._currentLerpTime += delta;\n let newX = this._tx.pos.x;\n let newY = this._tx.pos.y;\n if (this._currentLerpTime < this._lerpDuration) {\n if (this._lerpEnd.x < this._lerpStart.x) newX = this._lerpStart.x - (this.easingFcn(this._currentLerpTime, this._lerpEnd.x, this._lerpStart.x, this._lerpDuration) - this._lerpEnd.x);\n else newX = this.easingFcn(this._currentLerpTime, this._lerpStart.x, this._lerpEnd.x, this._lerpDuration);\n if (this._lerpEnd.y < this._lerpStart.y) newY = this._lerpStart.y - (this.easingFcn(this._currentLerpTime, this._lerpEnd.y, this._lerpStart.y, this._lerpDuration) - this._lerpEnd.y);\n else newY = this.easingFcn(this._currentLerpTime, this._lerpStart.y, this._lerpEnd.y, this._lerpDuration);\n // Given the lerp position figure out the velocity in pixels per second\n this._motion.vel = vec((newX - this._tx.pos.x) / (delta / 1000), (newY - this._tx.pos.y) / (delta / 1000));\n } else {\n this._tx.pos = vec(this._lerpEnd.x, this._lerpEnd.y);\n this._motion.vel = Vector.Zero;\n }\n }\n isComplete() {\n return this._stopped || this._currentLerpTime >= this._lerpDuration;\n }\n reset() {\n this._initialized = false;\n this._stopped = false;\n this._currentLerpTime = 0;\n }\n stop() {\n this._motion.vel = vec(0, 0);\n this._stopped = true;\n }\n }\n class Blink {\n constructor(entity, timeVisible, timeNotVisible, numBlinks = 1){\n this._timeVisible = 0;\n this._timeNotVisible = 0;\n this._elapsedTime = 0;\n this._totalTime = 0;\n this._stopped = false;\n this._started = false;\n this._graphics = entity.get(GraphicsComponent);\n this._timeVisible = timeVisible;\n this._timeNotVisible = timeNotVisible;\n this._duration = (timeVisible + timeNotVisible) * numBlinks;\n }\n update(delta) {\n if (!this._started) {\n this._started = true;\n this._elapsedTime = 0;\n this._totalTime = 0;\n }\n if (!this._graphics) return;\n this._elapsedTime += delta;\n this._totalTime += delta;\n if (this._graphics.visible && this._elapsedTime >= this._timeVisible) {\n this._graphics.visible = false;\n this._elapsedTime = 0;\n }\n if (!this._graphics.visible && this._elapsedTime >= this._timeNotVisible) {\n this._graphics.visible = true;\n this._elapsedTime = 0;\n }\n if (this.isComplete()) this._graphics.visible = true;\n }\n isComplete() {\n return this._stopped || this._totalTime >= this._duration;\n }\n stop() {\n if (this._graphics) this._graphics.visible = true;\n this._stopped = true;\n }\n reset() {\n this._started = false;\n this._stopped = false;\n this._elapsedTime = 0;\n this._totalTime = 0;\n }\n }\n class Fade {\n constructor(entity, endOpacity, speed){\n this._multiplier = 1;\n this._started = false;\n this._stopped = false;\n this._graphics = entity.get(GraphicsComponent);\n this._endOpacity = endOpacity;\n this._speed = this._ogspeed = speed;\n }\n update(delta) {\n if (!this._graphics) return;\n if (!this._started) {\n this._started = true;\n this._speed = this._ogspeed;\n // determine direction when we start\n if (this._endOpacity < this._graphics.opacity) this._multiplier = -1;\n else this._multiplier = 1;\n }\n if (this._speed > 0) this._graphics.opacity += this._multiplier * (Math.abs(this._graphics.opacity - this._endOpacity) * delta) / this._speed;\n this._speed -= delta;\n if (this.isComplete()) this._graphics.opacity = this._endOpacity;\n Logger.getInstance().debug(\"[Action fade] Actor opacity:\", this._graphics.opacity);\n }\n isComplete() {\n return this._stopped || Math.abs(this._graphics.opacity - this._endOpacity) < 0.05;\n }\n stop() {\n this._stopped = true;\n }\n reset() {\n this._started = false;\n this._stopped = false;\n }\n }\n class Delay {\n constructor(delay){\n this._elapsedTime = 0;\n this._started = false;\n this._stopped = false;\n this._delay = delay;\n }\n update(delta) {\n if (!this._started) this._started = true;\n this._elapsedTime += delta;\n }\n isComplete() {\n return this._stopped || this._elapsedTime >= this._delay;\n }\n stop() {\n this._stopped = true;\n }\n reset() {\n this._elapsedTime = 0;\n this._started = false;\n this._stopped = false;\n }\n }\n class Die {\n constructor(entity){\n this._stopped = false;\n this._entity = entity;\n }\n update(_delta) {\n this._entity.get(ActionsComponent).clearActions();\n this._entity.kill();\n this._stopped = true;\n }\n isComplete() {\n return this._stopped;\n }\n stop() {\n return;\n }\n reset() {\n return;\n }\n }\n class Follow {\n constructor(entity, entityToFollow, followDistance){\n this._started = false;\n this._stopped = false;\n this._tx = entity.get(TransformComponent);\n this._motion = entity.get(MotionComponent);\n this._followTx = entityToFollow.get(TransformComponent);\n this._followMotion = entityToFollow.get(MotionComponent);\n this._current = new Vector(this._tx.pos.x, this._tx.pos.y);\n this._end = new Vector(this._followTx.pos.x, this._followTx.pos.y);\n this._maximumDistance = followDistance !== undefined ? followDistance : this._current.distance(this._end);\n this._speed = 0;\n }\n update(_delta) {\n if (!this._started) {\n this._started = true;\n this._distanceBetween = this._current.distance(this._end);\n this._dir = this._end.sub(this._current).normalize();\n }\n const actorToFollowSpeed = Math.sqrt(Math.pow(this._followMotion.vel.x, 2) + Math.pow(this._followMotion.vel.y, 2));\n if (actorToFollowSpeed !== 0) this._speed = actorToFollowSpeed;\n this._current = vec(this._tx.pos.x, this._tx.pos.y);\n this._end = vec(this._followTx.pos.x, this._followTx.pos.y);\n this._distanceBetween = this._current.distance(this._end);\n this._dir = this._end.sub(this._current).normalize();\n if (this._distanceBetween >= this._maximumDistance) {\n const m = this._dir.scale(this._speed);\n this._motion.vel = vec(m.x, m.y);\n } else this._motion.vel = vec(0, 0);\n if (this.isComplete()) {\n this._tx.pos = vec(this._end.x, this._end.y);\n this._motion.vel = vec(0, 0);\n }\n }\n stop() {\n this._motion.vel = vec(0, 0);\n this._stopped = true;\n }\n isComplete() {\n // the actor following should never stop unless specified to do so\n return this._stopped;\n }\n reset() {\n this._started = false;\n this._stopped = false;\n }\n }\n class Meet {\n constructor(actor, actorToMeet, speed){\n this._started = false;\n this._stopped = false;\n this._speedWasSpecified = false;\n this._tx = actor.get(TransformComponent);\n this._motion = actor.get(MotionComponent);\n this._meetTx = actorToMeet.get(TransformComponent);\n this._meetMotion = actorToMeet.get(MotionComponent);\n this._current = new Vector(this._tx.pos.x, this._tx.pos.y);\n this._end = new Vector(this._meetTx.pos.x, this._meetTx.pos.y);\n this._speed = speed || 0;\n if (speed !== undefined) this._speedWasSpecified = true;\n }\n update(_delta) {\n if (!this._started) {\n this._started = true;\n this._distanceBetween = this._current.distance(this._end);\n this._dir = this._end.sub(this._current).normalize();\n }\n const actorToMeetSpeed = Math.sqrt(Math.pow(this._meetMotion.vel.x, 2) + Math.pow(this._meetMotion.vel.y, 2));\n if (actorToMeetSpeed !== 0 && !this._speedWasSpecified) this._speed = actorToMeetSpeed;\n this._current = vec(this._tx.pos.x, this._tx.pos.y);\n this._end = vec(this._meetTx.pos.x, this._meetTx.pos.y);\n this._distanceBetween = this._current.distance(this._end);\n this._dir = this._end.sub(this._current).normalize();\n const m = this._dir.scale(this._speed);\n this._motion.vel = vec(m.x, m.y);\n if (this.isComplete()) {\n this._tx.pos = vec(this._end.x, this._end.y);\n this._motion.vel = vec(0, 0);\n }\n }\n isComplete() {\n return this._stopped || this._distanceBetween <= 1;\n }\n stop() {\n this._motion.vel = vec(0, 0);\n this._stopped = true;\n }\n reset() {\n this._started = false;\n this._stopped = false;\n this._distanceBetween = undefined;\n }\n }\n /**\r\n * The fluent Action API allows you to perform \"actions\" on\r\n * [[Actor|Actors]] such as following, moving, rotating, and\r\n * more. You can implement your own actions by implementing\r\n * the [[Action]] interface.\r\n */ class ActionContext {\n constructor(entity){\n this._entity = entity;\n this._queue = new ActionQueue(entity);\n }\n getQueue() {\n return this._queue;\n }\n update(elapsedMs) {\n this._queue.update(elapsedMs);\n }\n /**\r\n * Clears all queued actions from the Actor\r\n */ clearActions() {\n this._queue.clearActions();\n }\n runAction(action) {\n action.reset();\n this._queue.add(action);\n return this;\n }\n easeTo(...args) {\n var _a, _b;\n let x = 0;\n let y = 0;\n let duration = 0;\n let easingFcn = EasingFunctions.Linear;\n if (args[0] instanceof Vector) {\n x = args[0].x;\n y = args[0].y;\n duration = args[1];\n easingFcn = (_a = args[2]) !== null && _a !== void 0 ? _a : easingFcn;\n } else {\n x = args[0];\n y = args[1];\n duration = args[2];\n easingFcn = (_b = args[3]) !== null && _b !== void 0 ? _b : easingFcn;\n }\n this._queue.add(new EaseTo(this._entity, x, y, duration, easingFcn));\n return this;\n }\n easeBy(...args) {\n var _a, _b;\n let offsetX = 0;\n let offsetY = 0;\n let duration = 0;\n let easingFcn = EasingFunctions.Linear;\n if (args[0] instanceof Vector) {\n offsetX = args[0].x;\n offsetY = args[0].y;\n duration = args[1];\n easingFcn = (_a = args[2]) !== null && _a !== void 0 ? _a : easingFcn;\n } else {\n offsetX = args[0];\n offsetY = args[1];\n duration = args[2];\n easingFcn = (_b = args[3]) !== null && _b !== void 0 ? _b : easingFcn;\n }\n this._queue.add(new EaseBy(this._entity, offsetX, offsetY, duration, easingFcn));\n return this;\n }\n moveTo(xOrPos, yOrSpeed, speedOrUndefined) {\n let x = 0;\n let y = 0;\n let speed = 0;\n if (xOrPos instanceof Vector) {\n x = xOrPos.x;\n y = xOrPos.y;\n speed = yOrSpeed;\n } else {\n x = xOrPos;\n y = yOrSpeed;\n speed = speedOrUndefined;\n }\n this._queue.add(new MoveTo(this._entity, x, y, speed));\n return this;\n }\n moveBy(xOffsetOrVector, yOffsetOrSpeed, speedOrUndefined) {\n let xOffset = 0;\n let yOffset = 0;\n let speed = 0;\n if (xOffsetOrVector instanceof Vector) {\n xOffset = xOffsetOrVector.x;\n yOffset = xOffsetOrVector.y;\n speed = yOffsetOrSpeed;\n } else {\n xOffset = xOffsetOrVector;\n yOffset = yOffsetOrSpeed;\n speed = speedOrUndefined;\n }\n this._queue.add(new MoveBy(this._entity, xOffset, yOffset, speed));\n return this;\n }\n /**\r\n * This method will rotate an actor to the specified angle at the speed\r\n * specified (in radians per second) and return back the actor. This\r\n * method is part of the actor 'Action' fluent API allowing action chaining.\r\n * @param angleRadians The angle to rotate to in radians\r\n * @param speed The angular velocity of the rotation specified in radians per second\r\n * @param rotationType The [[RotationType]] to use for this rotation\r\n */ rotateTo(angleRadians, speed, rotationType) {\n this._queue.add(new RotateTo(this._entity, angleRadians, speed, rotationType));\n return this;\n }\n /**\r\n * This method will rotate an actor by the specified angle offset, from it's current rotation given a certain speed\r\n * in radians/sec and return back the actor. This method is part\r\n * of the actor 'Action' fluent API allowing action chaining.\r\n * @param angleRadiansOffset The angle to rotate to in radians relative to the current rotation\r\n * @param speed The speed in radians/sec the actor should rotate at\r\n * @param rotationType The [[RotationType]] to use for this rotation, default is shortest path\r\n */ rotateBy(angleRadiansOffset, speed, rotationType) {\n this._queue.add(new RotateBy(this._entity, angleRadiansOffset, speed, rotationType));\n return this;\n }\n scaleTo(sizeXOrVector, sizeYOrSpeed, speedXOrUndefined, speedYOrUndefined) {\n let sizeX = 1;\n let sizeY = 1;\n let speedX = 0;\n let speedY = 0;\n if (sizeXOrVector instanceof Vector && sizeYOrSpeed instanceof Vector) {\n sizeX = sizeXOrVector.x;\n sizeY = sizeXOrVector.y;\n speedX = sizeYOrSpeed.x;\n speedY = sizeYOrSpeed.y;\n }\n if (typeof sizeXOrVector === \"number\" && typeof sizeYOrSpeed === \"number\") {\n sizeX = sizeXOrVector;\n sizeY = sizeYOrSpeed;\n speedX = speedXOrUndefined;\n speedY = speedYOrUndefined;\n }\n this._queue.add(new ScaleTo(this._entity, sizeX, sizeY, speedX, speedY));\n return this;\n }\n scaleBy(sizeOffsetXOrVector, sizeOffsetYOrSpeed, speed) {\n let sizeOffsetX = 1;\n let sizeOffsetY = 1;\n if (sizeOffsetXOrVector instanceof Vector) {\n sizeOffsetX = sizeOffsetXOrVector.x;\n sizeOffsetY = sizeOffsetXOrVector.y;\n speed = sizeOffsetYOrSpeed;\n }\n if (typeof sizeOffsetXOrVector === \"number\" && typeof sizeOffsetYOrSpeed === \"number\") {\n sizeOffsetX = sizeOffsetXOrVector;\n sizeOffsetY = sizeOffsetYOrSpeed;\n }\n this._queue.add(new ScaleBy(this._entity, sizeOffsetX, sizeOffsetY, speed));\n return this;\n }\n /**\r\n * This method will cause an actor to blink (become visible and not\r\n * visible). Optionally, you may specify the number of blinks. Specify the amount of time\r\n * the actor should be visible per blink, and the amount of time not visible.\r\n * This method is part of the actor 'Action' fluent API allowing action chaining.\r\n * @param timeVisible The amount of time to stay visible per blink in milliseconds\r\n * @param timeNotVisible The amount of time to stay not visible per blink in milliseconds\r\n * @param numBlinks The number of times to blink\r\n */ blink(timeVisible, timeNotVisible, numBlinks = 1) {\n this._queue.add(new Blink(this._entity, timeVisible, timeNotVisible, numBlinks));\n return this;\n }\n /**\r\n * This method will cause an actor's opacity to change from its current value\r\n * to the provided value by a specified time (in milliseconds). This method is\r\n * part of the actor 'Action' fluent API allowing action chaining.\r\n * @param opacity The ending opacity\r\n * @param time The time it should take to fade the actor (in milliseconds)\r\n */ fade(opacity, time) {\n this._queue.add(new Fade(this._entity, opacity, time));\n return this;\n }\n /**\r\n * This method will delay the next action from executing for a certain\r\n * amount of time (in milliseconds). This method is part of the actor\r\n * 'Action' fluent API allowing action chaining.\r\n * @param time The amount of time to delay the next action in the queue from executing in milliseconds\r\n */ delay(time) {\n this._queue.add(new Delay(time));\n return this;\n }\n /**\r\n * This method will add an action to the queue that will remove the actor from the\r\n * scene once it has completed its previous Any actions on the\r\n * action queue after this action will not be executed.\r\n */ die() {\n this._queue.add(new Die(this._entity));\n return this;\n }\n /**\r\n * This method allows you to call an arbitrary method as the next action in the\r\n * action queue. This is useful if you want to execute code in after a specific\r\n * action, i.e An actor arrives at a destination after traversing a path\r\n */ callMethod(method) {\n this._queue.add(new CallMethod(method));\n return this;\n }\n /**\r\n * This method will cause the actor to repeat all of the actions built in\r\n * the `repeatBuilder` callback. If the number of repeats\r\n * is not specified it will repeat forever. This method is part of\r\n * the actor 'Action' fluent API allowing action chaining\r\n *\r\n * ```typescript\r\n * // Move up in a zig-zag by repeated moveBy's\r\n * actor.actions.repeat(repeatCtx => {\r\n * repeatCtx.moveBy(10, 0, 10);\r\n * repeatCtx.moveBy(0, 10, 10);\r\n * }, 5);\r\n * ```\r\n *\r\n * @param repeatBuilder The builder to specify the repeatable list of actions\r\n * @param times The number of times to repeat all the previous actions in the action queue. If nothing is specified the actions\r\n * will repeat forever\r\n */ repeat(repeatBuilder, times) {\n if (!times) {\n this.repeatForever(repeatBuilder);\n return this;\n }\n this._queue.add(new Repeat(this._entity, repeatBuilder, times));\n return this;\n }\n /**\r\n * This method will cause the actor to repeat all of the actions built in\r\n * the `repeatBuilder` callback. If the number of repeats\r\n * is not specified it will repeat forever. This method is part of\r\n * the actor 'Action' fluent API allowing action chaining\r\n *\r\n * ```typescript\r\n * // Move up in a zig-zag by repeated moveBy's\r\n * actor.actions.repeat(repeatCtx => {\r\n * repeatCtx.moveBy(10, 0, 10);\r\n * repeatCtx.moveBy(0, 10, 10);\r\n * }, 5);\r\n * ```\r\n *\r\n * @param repeatBuilder The builder to specify the repeatable list of actions\r\n */ repeatForever(repeatBuilder) {\n this._queue.add(new RepeatForever(this._entity, repeatBuilder));\n return this;\n }\n /**\r\n * This method will cause the entity to follow another at a specified distance\r\n * @param entity The entity to follow\r\n * @param followDistance The distance to maintain when following, if not specified the actor will follow at the current distance.\r\n */ follow(entity, followDistance) {\n if (followDistance === undefined) this._queue.add(new Follow(this._entity, entity));\n else this._queue.add(new Follow(this._entity, entity, followDistance));\n return this;\n }\n /**\r\n * This method will cause the entity to move towards another until they\r\n * collide \"meet\" at a specified speed.\r\n * @param entity The entity to meet\r\n * @param speed The speed in pixels per second to move, if not specified it will match the speed of the other actor\r\n */ meet(entity, speed) {\n if (speed === undefined) this._queue.add(new Meet(this._entity, entity));\n else this._queue.add(new Meet(this._entity, entity, speed));\n return this;\n }\n /**\r\n * Returns a promise that resolves when the current action queue up to now\r\n * is finished.\r\n */ toPromise() {\n const temp = new Promise((resolve)=>{\n this._queue.add(new CallMethod(()=>{\n resolve();\n }));\n });\n return temp;\n }\n }\n class ActionsComponent extends Component {\n constructor(){\n super(...arguments);\n this.type = \"ex.actions\";\n this.dependencies = [\n TransformComponent,\n MotionComponent\n ];\n }\n onAdd(entity) {\n this._ctx = new ActionContext(entity);\n }\n onRemove() {\n this._ctx = null;\n }\n /**\r\n * Returns the internal action queue\r\n * @returns action queue\r\n */ getQueue() {\n var _a;\n return (_a = this._ctx) === null || _a === void 0 ? void 0 : _a.getQueue();\n }\n runAction(action) {\n var _a;\n return (_a = this._ctx) === null || _a === void 0 ? void 0 : _a.runAction(action);\n }\n /**\r\n * Updates the internal action context, performing action and moving through the internal queue\r\n * @param elapsedMs\r\n */ update(elapsedMs) {\n var _a;\n return (_a = this._ctx) === null || _a === void 0 ? void 0 : _a.update(elapsedMs);\n }\n /**\r\n * Clears all queued actions from the Actor\r\n */ clearActions() {\n var _a;\n (_a = this._ctx) === null || _a === void 0 || _a.clearActions();\n }\n easeTo(...args) {\n return this._ctx.easeTo.apply(this._ctx, args);\n }\n easeBy(...args) {\n return this._ctx.easeBy.apply(this._ctx, args);\n }\n moveTo(xOrPos, yOrSpeed, speedOrUndefined) {\n return this._ctx.moveTo.apply(this._ctx, [\n xOrPos,\n yOrSpeed,\n speedOrUndefined\n ]);\n }\n moveBy(xOffsetOrVector, yOffsetOrSpeed, speedOrUndefined) {\n return this._ctx.moveBy.apply(this._ctx, [\n xOffsetOrVector,\n yOffsetOrSpeed,\n speedOrUndefined\n ]);\n }\n /**\r\n * This method will rotate an actor to the specified angle at the speed\r\n * specified (in radians per second) and return back the actor. This\r\n * method is part of the actor 'Action' fluent API allowing action chaining.\r\n * @param angleRadians The angle to rotate to in radians\r\n * @param speed The angular velocity of the rotation specified in radians per second\r\n * @param rotationType The [[RotationType]] to use for this rotation\r\n */ rotateTo(angleRadians, speed, rotationType) {\n return this._ctx.rotateTo(angleRadians, speed, rotationType);\n }\n /**\r\n * This method will rotate an actor by the specified angle offset, from it's current rotation given a certain speed\r\n * in radians/sec and return back the actor. This method is part\r\n * of the actor 'Action' fluent API allowing action chaining.\r\n * @param angleRadiansOffset The angle to rotate to in radians relative to the current rotation\r\n * @param speed The speed in radians/sec the actor should rotate at\r\n * @param rotationType The [[RotationType]] to use for this rotation, default is shortest path\r\n */ rotateBy(angleRadiansOffset, speed, rotationType) {\n return this._ctx.rotateBy(angleRadiansOffset, speed, rotationType);\n }\n scaleTo(sizeXOrVector, sizeYOrSpeed, speedXOrUndefined, speedYOrUndefined) {\n return this._ctx.scaleTo.apply(this._ctx, [\n sizeXOrVector,\n sizeYOrSpeed,\n speedXOrUndefined,\n speedYOrUndefined\n ]);\n }\n scaleBy(sizeOffsetXOrVector, sizeOffsetYOrSpeed, speed) {\n return this._ctx.scaleBy.apply(this._ctx, [\n sizeOffsetXOrVector,\n sizeOffsetYOrSpeed,\n speed\n ]);\n }\n /**\r\n * This method will cause an actor to blink (become visible and not\r\n * visible). Optionally, you may specify the number of blinks. Specify the amount of time\r\n * the actor should be visible per blink, and the amount of time not visible.\r\n * This method is part of the actor 'Action' fluent API allowing action chaining.\r\n * @param timeVisible The amount of time to stay visible per blink in milliseconds\r\n * @param timeNotVisible The amount of time to stay not visible per blink in milliseconds\r\n * @param numBlinks The number of times to blink\r\n */ blink(timeVisible, timeNotVisible, numBlinks) {\n return this._ctx.blink(timeVisible, timeNotVisible, numBlinks);\n }\n /**\r\n * This method will cause an actor's opacity to change from its current value\r\n * to the provided value by a specified time (in milliseconds). This method is\r\n * part of the actor 'Action' fluent API allowing action chaining.\r\n * @param opacity The ending opacity\r\n * @param time The time it should take to fade the actor (in milliseconds)\r\n */ fade(opacity, time) {\n return this._ctx.fade(opacity, time);\n }\n /**\r\n * This method will delay the next action from executing for a certain\r\n * amount of time (in milliseconds). This method is part of the actor\r\n * 'Action' fluent API allowing action chaining.\r\n * @param time The amount of time to delay the next action in the queue from executing in milliseconds\r\n */ delay(time) {\n return this._ctx.delay(time);\n }\n /**\r\n * This method will add an action to the queue that will remove the actor from the\r\n * scene once it has completed its previous Any actions on the\r\n * action queue after this action will not be executed.\r\n */ die() {\n return this._ctx.die();\n }\n /**\r\n * This method allows you to call an arbitrary method as the next action in the\r\n * action queue. This is useful if you want to execute code in after a specific\r\n * action, i.e An actor arrives at a destination after traversing a path\r\n */ callMethod(method) {\n return this._ctx.callMethod(method);\n }\n /**\r\n * This method will cause the actor to repeat all of the actions built in\r\n * the `repeatBuilder` callback. If the number of repeats\r\n * is not specified it will repeat forever. This method is part of\r\n * the actor 'Action' fluent API allowing action chaining\r\n *\r\n * ```typescript\r\n * // Move up in a zig-zag by repeated moveBy's\r\n * actor.actions.repeat(repeatCtx => {\r\n * repeatCtx.moveBy(10, 0, 10);\r\n * repeatCtx.moveBy(0, 10, 10);\r\n * }, 5);\r\n * ```\r\n *\r\n * @param repeatBuilder The builder to specify the repeatable list of actions\r\n * @param times The number of times to repeat all the previous actions in the action queue. If nothing is specified the actions\r\n * will repeat forever\r\n */ repeat(repeatBuilder, times) {\n return this._ctx.repeat(repeatBuilder, times);\n }\n /**\r\n * This method will cause the actor to repeat all of the actions built in\r\n * the `repeatBuilder` callback. If the number of repeats\r\n * is not specified it will repeat forever. This method is part of\r\n * the actor 'Action' fluent API allowing action chaining\r\n *\r\n * ```typescript\r\n * // Move up in a zig-zag by repeated moveBy's\r\n * actor.actions.repeat(repeatCtx => {\r\n * repeatCtx.moveBy(10, 0, 10);\r\n * repeatCtx.moveBy(0, 10, 10);\r\n * }, 5);\r\n * ```\r\n *\r\n * @param repeatBuilder The builder to specify the repeatable list of actions\r\n */ repeatForever(repeatBuilder) {\n return this._ctx.repeatForever(repeatBuilder);\n }\n /**\r\n * This method will cause the entity to follow another at a specified distance\r\n * @param entity The entity to follow\r\n * @param followDistance The distance to maintain when following, if not specified the actor will follow at the current distance.\r\n */ follow(entity, followDistance) {\n return this._ctx.follow(entity, followDistance);\n }\n /**\r\n * This method will cause the entity to move towards another until they\r\n * collide \"meet\" at a specified speed.\r\n * @param entity The entity to meet\r\n * @param speed The speed in pixels per second to move, if not specified it will match the speed of the other actor\r\n */ meet(entity, speed) {\n return this._ctx.meet(entity, speed);\n }\n /**\r\n * Returns a promise that resolves when the current action queue up to now\r\n * is finished.\r\n */ toPromise() {\n return this._ctx.toPromise();\n }\n }\n /**\r\n * Enum representing the different font size units\r\n * https://developer.mozilla.org/en-US/docs/Web/CSS/font-size\r\n */ var FontUnit;\n (function(FontUnit) {\n /**\r\n * Em is a scalable unit, 1 em is equal to the current font size of the current element, parent elements can effect em values\r\n */ FontUnit[\"Em\"] = \"em\";\n /**\r\n * Rem is similar to the Em, it is a scalable unit. 1 rem is equal to the font size of the root element\r\n */ FontUnit[\"Rem\"] = \"rem\";\n /**\r\n * Pixel is a unit of length in screen pixels\r\n */ FontUnit[\"Px\"] = \"px\";\n /**\r\n * Point is a physical unit length (1/72 of an inch)\r\n */ FontUnit[\"Pt\"] = \"pt\";\n /**\r\n * Percent is a scalable unit similar to Em, the only difference is the Em units scale faster when Text-Size stuff\r\n */ FontUnit[\"Percent\"] = \"%\";\n })(FontUnit || (FontUnit = {}));\n /**\r\n * Enum representing the different horizontal text alignments\r\n */ var TextAlign;\n (function(TextAlign) {\n /**\r\n * The text is left-aligned.\r\n */ TextAlign[\"Left\"] = \"left\";\n /**\r\n * The text is right-aligned.\r\n */ TextAlign[\"Right\"] = \"right\";\n /**\r\n * The text is centered.\r\n */ TextAlign[\"Center\"] = \"center\";\n /**\r\n * The text is aligned at the normal start of the line (left-aligned for left-to-right locales,\r\n * right-aligned for right-to-left locales).\r\n */ TextAlign[\"Start\"] = \"start\";\n /**\r\n * The text is aligned at the normal end of the line (right-aligned for left-to-right locales,\r\n * left-aligned for right-to-left locales).\r\n */ TextAlign[\"End\"] = \"end\";\n })(TextAlign || (TextAlign = {}));\n /**\r\n * Enum representing the different baseline text alignments\r\n */ var BaseAlign;\n (function(BaseAlign) {\n /**\r\n * The text baseline is the top of the em square.\r\n */ BaseAlign[\"Top\"] = \"top\";\n /**\r\n * The text baseline is the hanging baseline. Currently unsupported; this will act like\r\n * alphabetic.\r\n */ BaseAlign[\"Hanging\"] = \"hanging\";\n /**\r\n * The text baseline is the middle of the em square.\r\n */ BaseAlign[\"Middle\"] = \"middle\";\n /**\r\n * The text baseline is the normal alphabetic baseline.\r\n */ BaseAlign[\"Alphabetic\"] = \"alphabetic\";\n /**\r\n * The text baseline is the ideographic baseline; this is the bottom of\r\n * the body of the characters, if the main body of characters protrudes\r\n * beneath the alphabetic baseline. Currently unsupported; this will\r\n * act like alphabetic.\r\n */ BaseAlign[\"Ideographic\"] = \"ideographic\";\n /**\r\n * The text baseline is the bottom of the bounding box. This differs\r\n * from the ideographic baseline in that the ideographic baseline\r\n * doesn't consider descenders.\r\n */ BaseAlign[\"Bottom\"] = \"bottom\";\n })(BaseAlign || (BaseAlign = {}));\n /**\r\n * Enum representing the different possible font styles\r\n */ var FontStyle;\n (function(FontStyle) {\n FontStyle[\"Normal\"] = \"normal\";\n FontStyle[\"Italic\"] = \"italic\";\n FontStyle[\"Oblique\"] = \"oblique\";\n })(FontStyle || (FontStyle = {}));\n /**\r\n * Enum representing the text direction, useful for other languages, or writing text in reverse\r\n */ var Direction;\n (function(Direction) {\n Direction[\"LeftToRight\"] = \"ltr\";\n Direction[\"RightToLeft\"] = \"rtl\";\n })(Direction || (Direction = {}));\n class FontTextInstance {\n constructor(font, text, color, maxWidth){\n this.font = font;\n this.text = text;\n this.color = color;\n this.maxWidth = maxWidth;\n this._textFragments = [];\n this.disposed = false;\n this._dirty = true;\n this.canvas = document.createElement(\"canvas\");\n this.ctx = this.canvas.getContext(\"2d\");\n this.dimensions = this.measureText(text);\n this._setDimension(this.dimensions, this.ctx);\n this._lastHashCode = this.getHashCode();\n }\n measureText(text, maxWidth) {\n if (this.disposed) throw Error(\"Accessing disposed text instance! \" + this.text);\n let lines = null;\n if (maxWidth != null) lines = this._getLinesFromText(text, maxWidth);\n else lines = text.split(\"\\n\");\n const maxWidthLine = lines.reduce((a, b)=>{\n return a.length > b.length ? a : b;\n });\n this._applyFont(this.ctx); // font must be applied to the context to measure it\n const metrics = this.ctx.measureText(maxWidthLine);\n let textHeight = Math.abs(metrics.actualBoundingBoxAscent) + Math.abs(metrics.actualBoundingBoxDescent);\n // TODO lineheight makes the text bounds wonky\n const lineAdjustedHeight = textHeight * lines.length;\n textHeight = lineAdjustedHeight;\n const bottomBounds = lineAdjustedHeight - Math.abs(metrics.actualBoundingBoxAscent);\n const x = 0;\n const y = 0;\n const measurement = new BoundingBox({\n left: x - Math.abs(metrics.actualBoundingBoxLeft) - this.font.padding,\n top: y - Math.abs(metrics.actualBoundingBoxAscent) - this.font.padding,\n bottom: y + bottomBounds + this.font.padding,\n right: x + Math.abs(metrics.actualBoundingBoxRight) + this.font.padding\n });\n return measurement;\n }\n _setDimension(textBounds, bitmap) {\n // Changing the width and height clears the context properties\n // We double the bitmap width to account for all possible alignment\n // We scale by \"quality\" so we render text without jaggies\n bitmap.canvas.width = (textBounds.width + this.font.padding * 2) * 2 * this.font.quality;\n bitmap.canvas.height = (textBounds.height + this.font.padding * 2) * 2 * this.font.quality;\n }\n static getHashCode(font, text, color) {\n var _a;\n const hash = text + \"__hashcode__\" + font.fontString + font.showDebug + font.textAlign + font.baseAlign + font.direction + JSON.stringify(font.shadow) + (font.padding.toString() + font.smoothing.toString() + font.lineWidth.toString() + font.lineDash.toString() + ((_a = font.strokeColor) === null || _a === void 0 ? void 0 : _a.toString()) + (color ? color.toString() : font.color.toString()));\n return hash;\n }\n getHashCode(includeColor = true) {\n return FontTextInstance.getHashCode(this.font, this.text, includeColor ? this.color : undefined);\n }\n _applyRasterProperties(ctx) {\n var _a, _b;\n ctx.translate(this.font.padding, this.font.padding);\n ctx.imageSmoothingEnabled = this.font.smoothing;\n ctx.lineWidth = this.font.lineWidth;\n ctx.setLineDash((_a = this.font.lineDash) !== null && _a !== void 0 ? _a : ctx.getLineDash());\n ctx.strokeStyle = (_b = this.font.strokeColor) === null || _b === void 0 ? void 0 : _b.toString();\n ctx.fillStyle = this.color.toString();\n }\n _applyFont(ctx) {\n ctx.resetTransform();\n ctx.translate(this.font.padding + ctx.canvas.width / 2, this.font.padding + ctx.canvas.height / 2);\n ctx.scale(this.font.quality, this.font.quality);\n ctx.textAlign = this.font.textAlign;\n ctx.textBaseline = this.font.baseAlign;\n ctx.font = this.font.fontString;\n ctx.direction = this.font.direction;\n if (this.font.shadow) {\n ctx.shadowColor = this.font.shadow.color.toString();\n ctx.shadowBlur = this.font.shadow.blur;\n ctx.shadowOffsetX = this.font.shadow.offset.x;\n ctx.shadowOffsetY = this.font.shadow.offset.y;\n }\n }\n _drawText(ctx, lines, lineHeight) {\n this._applyRasterProperties(ctx);\n this._applyFont(ctx);\n for(let i = 0; i < lines.length; i++){\n const line = lines[i];\n if (this.color) ctx.fillText(line, 0, i * lineHeight);\n if (this.font.strokeColor) ctx.strokeText(line, 0, i * lineHeight);\n }\n if (this.font.showDebug) {\n // Horizontal line\n /* istanbul ignore next */ line(ctx, Color.Green, -ctx.canvas.width / 2, 0, ctx.canvas.width / 2, 0, 2);\n // Vertical line\n /* istanbul ignore next */ line(ctx, Color.Red, 0, -ctx.canvas.height / 2, 0, ctx.canvas.height / 2, 2);\n }\n }\n _splitTextBitmap(bitmap) {\n const textImages = [];\n let currentX = 0;\n let currentY = 0;\n // 4k is the max for mobile devices\n const width = Math.min(4096, bitmap.canvas.width);\n const height = Math.min(4096, bitmap.canvas.height);\n // Splits the original bitmap into 4k max chunks\n while(currentX < bitmap.canvas.width){\n while(currentY < bitmap.canvas.height){\n // create new bitmap\n const canvas = document.createElement(\"canvas\");\n canvas.width = width;\n canvas.height = height;\n const ctx = canvas.getContext(\"2d\");\n // draw current slice to new bitmap in < 4k chunks\n ctx.drawImage(bitmap.canvas, currentX, currentY, width, height, 0, 0, width, height);\n textImages.push({\n x: currentX,\n y: currentY,\n canvas: canvas\n });\n currentY += height;\n }\n currentX += width;\n currentY = 0;\n }\n return textImages;\n }\n flagDirty() {\n this._dirty = true;\n }\n render(ex, x, y, maxWidth) {\n if (this.disposed) throw Error(\"Accessing disposed text instance! \" + this.text);\n this._ex = ex;\n const hashCode = this.getHashCode();\n if (this._lastHashCode !== hashCode) this._dirty = true;\n // Calculate image chunks\n if (this._dirty) {\n this.dimensions = this.measureText(this.text, maxWidth);\n this._setDimension(this.dimensions, this.ctx);\n const lines = this._getLinesFromText(this.text, maxWidth);\n const lineHeight = this.dimensions.height / lines.length;\n // draws the text to the main bitmap\n this._drawText(this.ctx, lines, lineHeight);\n // clear any out old fragments\n if (ex instanceof ExcaliburGraphicsContextWebGL) for (const frag of this._textFragments)ex.textureLoader.delete(frag.canvas);\n // splits to < 4k fragments for large text\n this._textFragments = this._splitTextBitmap(this.ctx);\n if (ex instanceof ExcaliburGraphicsContextWebGL) for (const frag of this._textFragments)ex.textureLoader.load(frag.canvas, this.font.filtering, true);\n this._lastHashCode = hashCode;\n this._dirty = false;\n }\n // draws the bitmap fragments to excalibur graphics context\n for (const frag of this._textFragments)ex.drawImage(frag.canvas, 0, 0, frag.canvas.width, frag.canvas.height, frag.x / this.font.quality + x - this.ctx.canvas.width / this.font.quality / 2, frag.y / this.font.quality + y - this.ctx.canvas.height / this.font.quality / 2, frag.canvas.width / this.font.quality, frag.canvas.height / this.font.quality);\n }\n dispose() {\n this.disposed = true;\n this.dimensions = undefined;\n this.canvas = undefined;\n this.ctx = undefined;\n if (this._ex instanceof ExcaliburGraphicsContextWebGL) for (const frag of this._textFragments)this._ex.textureLoader.delete(frag.canvas);\n this._textFragments.length = 0;\n }\n _getLinesFromText(text, maxWidth) {\n if (this._chachedText === text && this._cachedRenderWidth === maxWidth) return this._chachedLines;\n const lines = text.split(\"\\n\");\n if (maxWidth == null) return lines;\n // If the current line goes past the maxWidth, append a new line without modifying the underlying text.\n for(let i = 0; i < lines.length; i++){\n let line = lines[i];\n let newLine = \"\";\n if (this.measureText(line).width > maxWidth) {\n while(this.measureText(line).width > maxWidth){\n newLine = line[line.length - 1] + newLine;\n line = line.slice(0, -1); // Remove last character from line\n }\n // Update the array with our new values\n lines[i] = line;\n lines[i + 1] = newLine;\n }\n }\n this._chachedText = text;\n this._chachedLines = lines;\n this._cachedRenderWidth = maxWidth;\n return lines;\n }\n }\n class FontCache {\n static measureText(text, font, maxWidth) {\n const hash = FontTextInstance.getHashCode(font, text);\n if (FontCache._MEASURE_CACHE.has(hash)) return FontCache._MEASURE_CACHE.get(hash);\n FontCache._LOGGER.debug(\"Font text measurement cache miss\");\n const measurement = font.measureTextWithoutCache(text, maxWidth);\n FontCache._MEASURE_CACHE.set(hash, measurement);\n return measurement;\n }\n static getTextInstance(text, font, color) {\n const hash = FontTextInstance.getHashCode(font, text, color);\n let textInstance = FontCache._TEXT_CACHE.get(hash);\n if (!textInstance) {\n textInstance = new FontTextInstance(font, text, color);\n FontCache._TEXT_CACHE.set(hash, textInstance);\n FontCache._LOGGER.debug(\"Font text instance cache miss\");\n }\n // Cache the bitmap for certain amount of time\n FontCache._TEXT_USAGE.set(textInstance, performance.now());\n return textInstance;\n }\n static checkAndClearCache() {\n const deferred = [];\n const currentHashCodes = new Set();\n for (const [textInstance, time] of FontCache._TEXT_USAGE.entries())// if bitmap hasn't been used in 100 ms clear it\n if (time + 100 < performance.now()) {\n FontCache._LOGGER.debug(`Text cache entry timed out ${textInstance.text}`);\n deferred.push(textInstance);\n textInstance.dispose();\n } else {\n const hash = textInstance.getHashCode(false);\n currentHashCodes.add(hash);\n }\n // Deferred removal of text instances\n deferred.forEach((t)=>{\n FontCache._TEXT_USAGE.delete(t);\n });\n // Regenerate text instance cache\n this._TEXT_CACHE.clear();\n for (const [textInstance] of this._TEXT_USAGE.entries())this._TEXT_CACHE.set(textInstance.getHashCode(), textInstance);\n // Regenerated measurement cache\n const newTextMeasurementCache = new Map();\n for (const current of currentHashCodes)if (FontCache._MEASURE_CACHE.has(current)) newTextMeasurementCache.set(current, FontCache._MEASURE_CACHE.get(current));\n this._MEASURE_CACHE.clear();\n this._MEASURE_CACHE = newTextMeasurementCache;\n }\n static get cacheSize() {\n return FontCache._TEXT_USAGE.size;\n }\n /**\r\n * Force clear all cached text bitmaps\r\n */ static clearCache() {\n for (const [textInstance] of FontCache._TEXT_USAGE.entries())textInstance.dispose();\n FontCache._TEXT_USAGE.clear();\n FontCache._TEXT_CACHE.clear();\n FontCache._MEASURE_CACHE.clear();\n }\n }\n FontCache._LOGGER = Logger.getInstance();\n FontCache._TEXT_USAGE = new Map();\n FontCache._TEXT_CACHE = new Map();\n FontCache._MEASURE_CACHE = new Map();\n /**\r\n * Represents a system or web font in Excalibur\r\n *\r\n * If no options specified, the system sans-serif 10 pixel is used\r\n *\r\n * If loading a custom web font be sure to have the font loaded before you use it https://erikonarheim.com/posts/dont-test-fonts/\r\n */ class Font extends Graphic {\n constructor(options = {}){\n var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u;\n super(options); // <- Graphics properties\n /**\r\n * Set the font filtering mode, by default set to [[ImageFiltering.Blended]] regardless of the engine default smoothing\r\n *\r\n * If you have a pixel style font that may be a reason to switch this to [[ImageFiltering.Pixel]]\r\n */ this.filtering = ImageFiltering.Blended;\n /**\r\n * Font quality determines the size of the underlying raster text, higher quality means less jagged edges.\r\n * If quality is set to 1, then just enough raster bitmap is generated to render the text.\r\n *\r\n * You can think of quality as how zoomed in to the text you can get before seeing jagged edges.\r\n *\r\n * (Default 2)\r\n */ this.quality = 2;\n // Raster properties for fonts\n this.padding = 2;\n this.smoothing = false;\n this.lineWidth = 1;\n this.lineDash = [];\n this.color = Color.Black;\n this.family = \"sans-serif\";\n this.style = FontStyle.Normal;\n this.bold = false;\n this.unit = FontUnit.Px;\n this.textAlign = TextAlign.Left;\n this.baseAlign = BaseAlign.Alphabetic;\n this.direction = Direction.LeftToRight;\n this.size = 10;\n this.shadow = null;\n this._textBounds = new BoundingBox();\n this._textMeasurement = new FontTextInstance(this, \"\", Color.Black);\n // Raster properties\n this.smoothing = (_a = options === null || options === void 0 ? void 0 : options.smoothing) !== null && _a !== void 0 ? _a : this.smoothing;\n this.padding = (_b = options === null || options === void 0 ? void 0 : options.padding) !== null && _b !== void 0 ? _b : this.padding;\n this.color = (_c = options === null || options === void 0 ? void 0 : options.color) !== null && _c !== void 0 ? _c : this.color;\n this.strokeColor = (_d = options === null || options === void 0 ? void 0 : options.strokeColor) !== null && _d !== void 0 ? _d : this.strokeColor;\n this.lineDash = (_e = options === null || options === void 0 ? void 0 : options.lineDash) !== null && _e !== void 0 ? _e : this.lineDash;\n this.lineWidth = (_f = options === null || options === void 0 ? void 0 : options.lineWidth) !== null && _f !== void 0 ? _f : this.lineWidth;\n this.filtering = (_g = options === null || options === void 0 ? void 0 : options.filtering) !== null && _g !== void 0 ? _g : this.filtering;\n // Font specific properties\n this.family = (_h = options === null || options === void 0 ? void 0 : options.family) !== null && _h !== void 0 ? _h : this.family;\n this.style = (_j = options === null || options === void 0 ? void 0 : options.style) !== null && _j !== void 0 ? _j : this.style;\n this.bold = (_k = options === null || options === void 0 ? void 0 : options.bold) !== null && _k !== void 0 ? _k : this.bold;\n this.size = (_l = options === null || options === void 0 ? void 0 : options.size) !== null && _l !== void 0 ? _l : this.size;\n this.unit = (_m = options === null || options === void 0 ? void 0 : options.unit) !== null && _m !== void 0 ? _m : this.unit;\n this.textAlign = (_o = options === null || options === void 0 ? void 0 : options.textAlign) !== null && _o !== void 0 ? _o : this.textAlign;\n this.baseAlign = (_p = options === null || options === void 0 ? void 0 : options.baseAlign) !== null && _p !== void 0 ? _p : this.baseAlign;\n this.direction = (_q = options === null || options === void 0 ? void 0 : options.direction) !== null && _q !== void 0 ? _q : this.direction;\n this.quality = (_r = options === null || options === void 0 ? void 0 : options.quality) !== null && _r !== void 0 ? _r : this.quality;\n if (options === null || options === void 0 ? void 0 : options.shadow) {\n this.shadow = {};\n this.shadow.blur = (_s = options.shadow.blur) !== null && _s !== void 0 ? _s : this.shadow.blur;\n this.shadow.offset = (_t = options.shadow.offset) !== null && _t !== void 0 ? _t : this.shadow.offset;\n this.shadow.color = (_u = options.shadow.color) !== null && _u !== void 0 ? _u : this.shadow.color;\n }\n }\n clone() {\n return new Font({\n ...this.cloneGraphicOptions(),\n size: this.size,\n unit: this.unit,\n family: this.family,\n style: this.style,\n bold: this.bold,\n textAlign: this.textAlign,\n baseAlign: this.baseAlign,\n direction: this.direction,\n shadow: this.shadow ? {\n blur: this.shadow.blur,\n offset: this.shadow.offset,\n color: this.shadow.color\n } : null\n });\n }\n get fontString() {\n return `${this.style} ${this.bold ? \"bold\" : \"\"} ${this.size}${this.unit} ${this.family}`;\n }\n get localBounds() {\n return this._textBounds;\n }\n _drawImage(_ex, _x, _y) {\n // TODO weird vestigial drawimage\n }\n _rotate(ex) {\n var _a;\n // TODO this needs to change depending on the bounding box...\n const origin = (_a = this.origin) !== null && _a !== void 0 ? _a : this._textBounds.center;\n ex.translate(origin.x, origin.y);\n ex.rotate(this.rotation);\n ex.translate(-origin.x, -origin.y);\n }\n _flip(ex) {\n if (this.flipHorizontal) {\n ex.translate(this._textBounds.width / this.scale.x, 0);\n ex.scale(-1, 1);\n }\n if (this.flipVertical) {\n ex.translate(0, -this._textBounds.height / 2 / this.scale.y);\n ex.scale(1, -1);\n }\n }\n measureTextWithoutCache(text, maxWidth) {\n return this._textMeasurement.measureText(text, maxWidth);\n }\n /**\r\n * Returns a BoundingBox that is the total size of the text including multiple lines\r\n *\r\n * Does not include any padding or adjustment\r\n * @param text\r\n * @returns BoundingBox\r\n */ measureText(text, maxWidth) {\n return FontCache.measureText(text, this, maxWidth);\n }\n _postDraw(ex) {\n ex.restore();\n }\n render(ex, text, colorOverride, x, y, maxWidth) {\n const textInstance = FontCache.getTextInstance(text, this, colorOverride);\n // Apply affine transformations\n this._textBounds = textInstance.dimensions;\n this._preDraw(ex, x, y);\n textInstance.render(ex, x, y, maxWidth);\n this._postDraw(ex);\n }\n }\n /**\r\n * Represent Text graphics in excalibur\r\n *\r\n * Useful for in game labels, ui, or overlays\r\n */ class Text extends Graphic {\n constructor(options){\n var _a, _b;\n super(options);\n this._text = \"\";\n this._textWidth = 0;\n this._textHeight = 0;\n // This order is important font, color, then text\n this.font = (_a = options.font) !== null && _a !== void 0 ? _a : new Font();\n this.color = (_b = options.color) !== null && _b !== void 0 ? _b : this.color;\n this.text = options.text;\n this.maxWidth = options.maxWidth;\n }\n clone() {\n var _a, _b;\n return new Text({\n text: this.text.slice(),\n color: (_b = (_a = this.color) === null || _a === void 0 ? void 0 : _a.clone()) !== null && _b !== void 0 ? _b : Color.Black,\n font: this.font.clone(),\n maxWidth: this.maxWidth\n });\n }\n get text() {\n return this._text;\n }\n set text(value) {\n this._text = value;\n this._calculateDimension();\n }\n get font() {\n return this._font;\n }\n set font(font) {\n this._font = font;\n }\n get width() {\n if (this._textWidth === 0) this._calculateDimension();\n return this._textWidth * this.scale.x;\n }\n get height() {\n if (this._textHeight === 0) this._calculateDimension();\n return this._textHeight * this.scale.y;\n }\n _calculateDimension() {\n const { width: width, height: height } = this.font.measureText(this._text, this.maxWidth);\n this._textWidth = width;\n this._textHeight = height;\n }\n get localBounds() {\n return this.font.measureText(this._text, this.maxWidth).scale(this.scale);\n }\n _rotate(_ex) {\n // None this is delegated to font\n // This override erases the default behavior\n }\n _flip(_ex) {\n // None this is delegated to font\n // This override erases the default behavior\n }\n _preDraw(ex, x, y) {\n if (this.isStale() || this.font.isStale()) {\n this.font.flipHorizontal = this.flipHorizontal;\n this.font.flipVertical = this.flipVertical;\n this.font.rotation = this.rotation;\n this.font.origin = this.origin;\n this.font.opacity = this.opacity;\n }\n this.font.tint = this.tint;\n super._preDraw(ex, x, y);\n }\n _drawImage(ex, x, y) {\n var _a;\n let color = Color.Black;\n if (this.font instanceof Font) color = (_a = this.color) !== null && _a !== void 0 ? _a : this.font.color;\n const { width: width, height: height } = this.font.measureText(this._text, this.maxWidth);\n this._textWidth = width;\n this._textHeight = height;\n this.font.render(ex, this._text, color, x, y, this.maxWidth);\n if (this.font.showDebug) {\n ex.debug.drawRect(x - width, y - height, width * 2, height * 2);\n if (this.maxWidth != null) ex.debug.drawRect(x, y, this.maxWidth, this.height, {\n color: Color.Yellow\n });\n }\n }\n }\n /**\r\n * Type guard for checking if something is an Actor\r\n * @param x\r\n */ function isActor(x) {\n return x instanceof Actor;\n }\n const ActorEvents = {\n CollisionStart: \"collisionstart\",\n CollisionEnd: \"collisionend\",\n PreCollision: \"precollision\",\n PostCollision: \"postcollision\",\n Kill: \"kill\",\n PreKill: \"prekill\",\n PostKill: \"postkill\",\n PreDraw: \"predraw\",\n PostDraw: \"postdraw\",\n PreDebugDraw: \"predebugdraw\",\n PostDebugDraw: \"postdebugdraw\",\n PointerUp: \"pointerup\",\n PointerDown: \"pointerdown\",\n PointerEnter: \"pointerenter\",\n PointerLeave: \"pointerleave\",\n PointerMove: \"pointermove\",\n PointerCancel: \"pointercancel\",\n Wheel: \"pointerwheel\",\n PointerDrag: \"pointerdragstart\",\n PointerDragEnd: \"pointerdragend\",\n PointerDragEnter: \"pointerdragenter\",\n PointerDragLeave: \"pointerdragleave\",\n PointerDragMove: \"pointerdragmove\",\n EnterViewPort: \"enterviewport\",\n ExitViewPort: \"exitviewport\"\n };\n /**\r\n * The most important primitive in Excalibur is an `Actor`. Anything that\r\n * can move on the screen, collide with another `Actor`, respond to events,\r\n * or interact with the current scene, must be an actor. An `Actor` **must**\r\n * be part of a [[Scene]] for it to be drawn to the screen.\r\n */ class Actor extends Entity {\n /**\r\n * The physics body the is associated with this actor. The body is the container for all physical properties, like position, velocity,\r\n * acceleration, mass, inertia, etc.\r\n */ get body() {\n return this.get(BodyComponent);\n }\n /**\r\n * Access the Actor's built in [[TransformComponent]]\r\n */ get transform() {\n return this.get(TransformComponent);\n }\n /**\r\n * Access the Actor's built in [[MotionComponent]]\r\n */ get motion() {\n return this.get(MotionComponent);\n }\n /**\r\n * Access to the Actor's built in [[GraphicsComponent]]\r\n */ get graphics() {\n return this.get(GraphicsComponent);\n }\n /**\r\n * Access to the Actor's built in [[ColliderComponent]]\r\n */ get collider() {\n return this.get(ColliderComponent);\n }\n /**\r\n * Access to the Actor's built in [[PointerComponent]] config\r\n */ get pointer() {\n return this.get(PointerComponent);\n }\n /**\r\n * Useful for quickly scripting actor behavior, like moving to a place, patrolling back and forth, blinking, etc.\r\n *\r\n * Access to the Actor's built in [[ActionsComponent]] which forwards to the\r\n * [[ActionContext|Action context]] of the actor.\r\n */ get actions() {\n return this.get(ActionsComponent);\n }\n /**\r\n * Gets the position vector of the actor in pixels\r\n */ get pos() {\n return this.transform.pos;\n }\n /**\r\n * Sets the position vector of the actor in pixels\r\n */ set pos(thePos) {\n this.transform.pos = thePos.clone();\n }\n /**\r\n * Gets the position vector of the actor from the last frame\r\n */ get oldPos() {\n return this.body.oldPos;\n }\n /**\r\n * Sets the position vector of the actor in the last frame\r\n */ set oldPos(thePos) {\n this.body.oldPos.setTo(thePos.x, thePos.y);\n }\n /**\r\n * Gets the velocity vector of the actor in pixels/sec\r\n */ get vel() {\n return this.motion.vel;\n }\n /**\r\n * Sets the velocity vector of the actor in pixels/sec\r\n */ set vel(theVel) {\n this.motion.vel = theVel.clone();\n }\n /**\r\n * Gets the velocity vector of the actor from the last frame\r\n */ get oldVel() {\n return this.body.oldVel;\n }\n /**\r\n * Sets the velocity vector of the actor from the last frame\r\n */ set oldVel(theVel) {\n this.body.oldVel.setTo(theVel.x, theVel.y);\n }\n /**\r\n * Gets the acceleration vector of the actor in pixels/second/second. An acceleration pointing down such as (0, 100) may be\r\n * useful to simulate a gravitational effect.\r\n */ get acc() {\n return this.motion.acc;\n }\n /**\r\n * Sets the acceleration vector of teh actor in pixels/second/second\r\n */ set acc(theAcc) {\n this.motion.acc = theAcc.clone();\n }\n /**\r\n * Sets the acceleration of the actor from the last frame. This does not include the global acc [[Physics.acc]].\r\n */ set oldAcc(theAcc) {\n this.body.oldAcc.setTo(theAcc.x, theAcc.y);\n }\n /**\r\n * Gets the acceleration of the actor from the last frame. This does not include the global acc [[Physics.acc]].\r\n */ get oldAcc() {\n return this.body.oldAcc;\n }\n /**\r\n * Gets the rotation of the actor in radians. 1 radian = 180/PI Degrees.\r\n */ get rotation() {\n return this.transform.rotation;\n }\n /**\r\n * Sets the rotation of the actor in radians. 1 radian = 180/PI Degrees.\r\n */ set rotation(theAngle) {\n this.transform.rotation = theAngle;\n }\n /**\r\n * Gets the rotational velocity of the actor in radians/second\r\n */ get angularVelocity() {\n return this.motion.angularVelocity;\n }\n /**\r\n * Sets the rotational velocity of the actor in radians/sec\r\n */ set angularVelocity(angularVelocity) {\n this.motion.angularVelocity = angularVelocity;\n }\n get scale() {\n return this.get(TransformComponent).scale;\n }\n set scale(scale) {\n this.get(TransformComponent).scale = scale;\n }\n get anchor() {\n return this._anchor;\n }\n set anchor(vec) {\n this._anchor = watch(vec, (v)=>this._handleAnchorChange(v));\n this._handleAnchorChange(vec);\n }\n _handleAnchorChange(v) {\n if (this.graphics) this.graphics.anchor = v;\n }\n /**\r\n * Indicates whether the actor is physically in the viewport\r\n */ get isOffScreen() {\n return this.hasTag(\"ex.offscreen\");\n }\n get draggable() {\n return this._draggable;\n }\n set draggable(isDraggable) {\n if (isDraggable) {\n if (isDraggable && !this._draggable) {\n this.events.on(\"pointerdragstart\", this._pointerDragStartHandler);\n this.events.on(\"pointerdragend\", this._pointerDragEndHandler);\n this.events.on(\"pointerdragmove\", this._pointerDragMoveHandler);\n this.events.on(\"pointerdragleave\", this._pointerDragLeaveHandler);\n } else if (!isDraggable && this._draggable) {\n this.events.off(\"pointerdragstart\", this._pointerDragStartHandler);\n this.events.off(\"pointerdragend\", this._pointerDragEndHandler);\n this.events.off(\"pointerdragmove\", this._pointerDragMoveHandler);\n this.events.off(\"pointerdragleave\", this._pointerDragLeaveHandler);\n }\n this._draggable = isDraggable;\n }\n }\n /**\r\n * Sets the color of the actor's current graphic\r\n */ get color() {\n return this._color;\n }\n set color(v) {\n var _a;\n this._color = v.clone();\n const defaultLayer = this.graphics.layers.default;\n const currentGraphic = (_a = defaultLayer.graphics[0]) === null || _a === void 0 ? void 0 : _a.graphic;\n if (currentGraphic instanceof Raster || currentGraphic instanceof Text) currentGraphic.color = this._color;\n }\n // #endregion\n /**\r\n *\r\n * @param config\r\n */ constructor(config){\n super();\n this.events = new EventEmitter();\n /**\r\n * The anchor to apply all actor related transformations like rotation,\r\n * translation, and scaling. By default the anchor is in the center of\r\n * the actor. By default it is set to the center of the actor (.5, .5)\r\n *\r\n * An anchor of (.5, .5) will ensure that drawings are centered.\r\n *\r\n * Use `anchor.setTo` to set the anchor to a different point using\r\n * values between 0 and 1. For example, anchoring to the top-left would be\r\n * `Actor.anchor.setTo(0, 0)` and top-right would be `Actor.anchor.setTo(0, 1)`.\r\n */ this._anchor = watch(Vector.Half, (v)=>this._handleAnchorChange(v));\n /**\r\n * Convenience reference to the global logger\r\n */ this.logger = Logger.getInstance();\n /**\r\n * Draggable helper\r\n */ this._draggable = false;\n this._dragging = false;\n this._pointerDragStartHandler = ()=>{\n this._dragging = true;\n };\n this._pointerDragEndHandler = ()=>{\n this._dragging = false;\n };\n this._pointerDragMoveHandler = (pe)=>{\n if (this._dragging) this.pos = pe.worldPos;\n };\n this._pointerDragLeaveHandler = (pe)=>{\n if (this._dragging) this.pos = pe.worldPos;\n };\n const { name: name, x: x, y: y, pos: pos, coordPlane: coordPlane, scale: scale, width: width, height: height, radius: radius, collider: collider, vel: vel, acc: acc, rotation: rotation, angularVelocity: angularVelocity, z: z, color: color, visible: visible, anchor: anchor, collisionType: collisionType, collisionGroup: collisionGroup } = {\n ...config\n };\n this._setName(name);\n this.anchor = anchor !== null && anchor !== void 0 ? anchor : Actor.defaults.anchor.clone();\n const tx = new TransformComponent();\n this.addComponent(tx);\n this.pos = pos !== null && pos !== void 0 ? pos : vec(x !== null && x !== void 0 ? x : 0, y !== null && y !== void 0 ? y : 0);\n this.rotation = rotation !== null && rotation !== void 0 ? rotation : 0;\n this.scale = scale !== null && scale !== void 0 ? scale : vec(1, 1);\n this.z = z !== null && z !== void 0 ? z : 0;\n tx.coordPlane = coordPlane !== null && coordPlane !== void 0 ? coordPlane : CoordPlane.World;\n this.addComponent(new PointerComponent);\n this.addComponent(new GraphicsComponent({\n anchor: this.anchor\n }));\n this.addComponent(new MotionComponent());\n this.vel = vel !== null && vel !== void 0 ? vel : Vector.Zero;\n this.acc = acc !== null && acc !== void 0 ? acc : Vector.Zero;\n this.angularVelocity = angularVelocity !== null && angularVelocity !== void 0 ? angularVelocity : 0;\n this.addComponent(new ActionsComponent());\n this.addComponent(new BodyComponent());\n this.body.collisionType = collisionType !== null && collisionType !== void 0 ? collisionType : CollisionType.Passive;\n if (collisionGroup) this.body.group = collisionGroup;\n if (collider) this.addComponent(new ColliderComponent(collider));\n else if (radius) this.addComponent(new ColliderComponent(Shape.Circle(radius)));\n else if (width > 0 && height > 0) this.addComponent(new ColliderComponent(Shape.Box(width, height, this.anchor)));\n else this.addComponent(new ColliderComponent()); // no collider\n this.graphics.visible = visible !== null && visible !== void 0 ? visible : true;\n if (color) {\n this.color = color;\n if (width && height) this.graphics.add(new Rectangle({\n color: color,\n width: width,\n height: height\n }));\n else if (radius) this.graphics.add(new Circle({\n color: color,\n radius: radius\n }));\n }\n }\n clone() {\n const clone = new Actor({\n color: this.color.clone(),\n anchor: this.anchor.clone()\n });\n clone.clearComponents();\n clone.processComponentRemoval();\n // Clone the current actors components\n const components = this.getComponents();\n for (const c of components)clone.addComponent(c.clone(), true);\n return clone;\n }\n /**\r\n * `onInitialize` is called before the first update of the actor. This method is meant to be\r\n * overridden. This is where initialization of child actors should take place.\r\n *\r\n * Synonymous with the event handler `.on('initialize', (evt) => {...})`\r\n */ onInitialize(_engine) {\n // Override me\n }\n /**\r\n * Initializes this actor and all it's child actors, meant to be called by the Scene before first update not by users of Excalibur.\r\n *\r\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\r\n *\r\n * @internal\r\n */ _initialize(engine) {\n super._initialize(engine);\n for (const child of this.children)child._initialize(engine);\n }\n emit(eventName, event) {\n this.events.emit(eventName, event);\n }\n on(eventName, handler) {\n return this.events.on(eventName, handler);\n }\n once(eventName, handler) {\n return this.events.once(eventName, handler);\n }\n off(eventName, handler) {\n this.events.off(eventName, handler);\n }\n // #endregion\n /**\r\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\r\n *\r\n * Internal _prekill handler for [[onPreKill]] lifecycle event\r\n * @internal\r\n */ _prekill(_scene) {\n this.events.emit(\"prekill\", new PreKillEvent(this));\n this.onPreKill(_scene);\n }\n /**\r\n * Safe to override onPreKill lifecycle event handler. Synonymous with `.on('prekill', (evt) =>{...})`\r\n *\r\n * `onPreKill` is called directly before an actor is killed and removed from its current [[Scene]].\r\n */ onPreKill(_scene) {\n // Override me\n }\n /**\r\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\r\n *\r\n * Internal _prekill handler for [[onPostKill]] lifecycle event\r\n * @internal\r\n */ _postkill(_scene) {\n this.events.emit(\"postkill\", new PostKillEvent(this));\n this.onPostKill(_scene);\n }\n /**\r\n * Safe to override onPostKill lifecycle event handler. Synonymous with `.on('postkill', (evt) => {...})`\r\n *\r\n * `onPostKill` is called directly after an actor is killed and remove from its current [[Scene]].\r\n */ onPostKill(_scene) {\n // Override me\n }\n /**\r\n * If the current actor is a member of the scene, this will remove\r\n * it from the scene graph. It will no longer be drawn or updated.\r\n */ kill() {\n if (this.scene) {\n this._prekill(this.scene);\n this.events.emit(\"kill\", new KillEvent(this));\n super.kill();\n this._postkill(this.scene);\n } else this.logger.warn(`Cannot kill actor named \"${this.name}\", it was never added to the Scene`);\n }\n /**\r\n * If the current actor is killed, it will now not be killed.\r\n */ unkill() {\n this.active = true;\n }\n /**\r\n * Indicates wether the actor has been killed.\r\n */ isKilled() {\n return !this.active;\n }\n /**\r\n * Gets the z-index of an actor. The z-index determines the relative order an actor is drawn in.\r\n * Actors with a higher z-index are drawn on top of actors with a lower z-index\r\n */ get z() {\n return this.get(TransformComponent).z;\n }\n /**\r\n * Sets the z-index of an actor and updates it in the drawing list for the scene.\r\n * The z-index determines the relative order an actor is drawn in.\r\n * Actors with a higher z-index are drawn on top of actors with a lower z-index\r\n * @param newZ new z-index to assign\r\n */ set z(newZ) {\n this.get(TransformComponent).z = newZ;\n }\n /**\r\n * Get the center point of an actor (global position)\r\n */ get center() {\n const globalPos = this.getGlobalPos();\n return new Vector(globalPos.x + this.width / 2 - this.anchor.x * this.width, globalPos.y + this.height / 2 - this.anchor.y * this.height);\n }\n /**\r\n * Get the local center point of an actor\r\n */ get localCenter() {\n return new Vector(this.pos.x + this.width / 2 - this.anchor.x * this.width, this.pos.y + this.height / 2 - this.anchor.y * this.height);\n }\n get width() {\n return this.collider.localBounds.width * this.getGlobalScale().x;\n }\n get height() {\n return this.collider.localBounds.height * this.getGlobalScale().y;\n }\n /**\r\n * Gets this actor's rotation taking into account any parent relationships\r\n *\r\n * @returns Rotation angle in radians\r\n */ getGlobalRotation() {\n return this.get(TransformComponent).globalRotation;\n }\n /**\r\n * Gets an actor's world position taking into account parent relationships, scaling, rotation, and translation\r\n *\r\n * @returns Position in world coordinates\r\n */ getGlobalPos() {\n return this.get(TransformComponent).globalPos;\n }\n /**\r\n * Gets the global scale of the Actor\r\n */ getGlobalScale() {\n return this.get(TransformComponent).globalScale;\n }\n // #region Collision\n /**\r\n * Tests whether the x/y specified are contained in the actor\r\n * @param x X coordinate to test (in world coordinates)\r\n * @param y Y coordinate to test (in world coordinates)\r\n * @param recurse checks whether the x/y are contained in any child actors (if they exist).\r\n */ contains(x, y, recurse = false) {\n const point = vec(x, y);\n const collider = this.get(ColliderComponent);\n collider.update();\n const geom = collider.get();\n if (!geom) return false;\n const containment = geom.contains(point);\n if (recurse) return containment || this.children.some((child)=>{\n return child.contains(x, y, true);\n });\n return containment;\n }\n /**\r\n * Returns true if the two actor.collider's surfaces are less than or equal to the distance specified from each other\r\n * @param actor Actor to test\r\n * @param distance Distance in pixels to test\r\n */ within(actor, distance) {\n const collider = this.get(ColliderComponent);\n const otherCollider = actor.get(ColliderComponent);\n const me = collider.get();\n const other = otherCollider.get();\n if (me && other) return me.getClosestLineBetween(other).getLength() <= distance;\n return false;\n }\n // #endregion\n // #region Update\n /**\r\n * Called by the Engine, updates the state of the actor\r\n * @internal\r\n * @param engine The reference to the current game engine\r\n * @param delta The time elapsed since the last update in milliseconds\r\n */ update(engine, delta) {\n this._initialize(engine);\n this._preupdate(engine, delta);\n this._postupdate(engine, delta);\n }\n /**\r\n * Safe to override onPreUpdate lifecycle event handler. Synonymous with `.on('preupdate', (evt) =>{...})`\r\n *\r\n * `onPreUpdate` is called directly before an actor is updated.\r\n */ onPreUpdate(_engine, _delta) {\n // Override me\n }\n /**\r\n * Safe to override onPostUpdate lifecycle event handler. Synonymous with `.on('postupdate', (evt) =>{...})`\r\n *\r\n * `onPostUpdate` is called directly after an actor is updated.\r\n */ onPostUpdate(_engine, _delta) {\n // Override me\n }\n /**\r\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\r\n *\r\n * Internal _preupdate handler for [[onPreUpdate]] lifecycle event\r\n * @internal\r\n */ _preupdate(engine, delta) {\n this.events.emit(\"preupdate\", new PreUpdateEvent(engine, delta, this));\n this.onPreUpdate(engine, delta);\n }\n /**\r\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\r\n *\r\n * Internal _preupdate handler for [[onPostUpdate]] lifecycle event\r\n * @internal\r\n */ _postupdate(engine, delta) {\n this.events.emit(\"postupdate\", new PostUpdateEvent(engine, delta, this));\n this.onPostUpdate(engine, delta);\n }\n }\n // #region Properties\n /**\r\n * Set defaults for all Actors\r\n */ Actor.defaults = {\n anchor: Vector.Half\n };\n /**\r\n * Type guard to detect a screen element\r\n */ function isScreenElement(actor) {\n return actor instanceof ScreenElement;\n }\n /**\r\n * Helper [[Actor]] primitive for drawing UI's, optimized for UI drawing. Does\r\n * not participate in collisions. Drawn on top of all other actors.\r\n */ class ScreenElement extends Actor {\n constructor(config){\n var _a, _b;\n super({\n ...config\n });\n this.get(TransformComponent).coordPlane = CoordPlane.Screen;\n this.anchor = (_a = config === null || config === void 0 ? void 0 : config.anchor) !== null && _a !== void 0 ? _a : vec(0, 0);\n this.body.collisionType = (_b = config === null || config === void 0 ? void 0 : config.collisionType) !== null && _b !== void 0 ? _b : CollisionType.PreventCollision;\n this.pointer.useGraphicsBounds = true;\n this.pointer.useColliderShape = false;\n if (!(config === null || config === void 0 ? void 0 : config.collider) && (config === null || config === void 0 ? void 0 : config.width) > 0 && (config === null || config === void 0 ? void 0 : config.height) > 0) this.collider.useBoxCollider(this.width, this.height, this.anchor);\n }\n _initialize(engine) {\n this._engine = engine;\n super._initialize(engine);\n }\n contains(x, y, useWorld = true) {\n if (useWorld) return super.contains(x, y);\n const coords = this._engine.worldToScreenCoordinates(new Vector(x, y));\n return super.contains(coords.x, coords.y);\n }\n }\n /**\r\n * The Excalibur timer hooks into the internal timer and fires callbacks,\r\n * after a certain interval, optionally repeating.\r\n */ class Timer {\n get complete() {\n return this._complete;\n }\n constructor(fcn, interval, repeats, numberOfRepeats, randomRange, random){\n this._logger = Logger.getInstance();\n this.id = 0;\n this._elapsedTime = 0;\n this._totalTimeAlive = 0;\n this._running = false;\n this._numberOfTicks = 0;\n this.interval = 10;\n this.repeats = false;\n this.maxNumberOfRepeats = -1;\n this.randomRange = [\n 0,\n 0\n ];\n this._baseInterval = 10;\n this._generateRandomInterval = ()=>{\n return this._baseInterval + this.random.integer(this.randomRange[0], this.randomRange[1]);\n };\n this._complete = false;\n this.scene = null;\n if (typeof fcn !== \"function\") {\n const options = fcn;\n fcn = options.fcn;\n interval = options.interval;\n repeats = options.repeats;\n numberOfRepeats = options.numberOfRepeats;\n randomRange = options.randomRange;\n random = options.random;\n }\n if (!!numberOfRepeats && numberOfRepeats >= 0) {\n this.maxNumberOfRepeats = numberOfRepeats;\n if (!repeats) throw new Error(\"repeats must be set to true if numberOfRepeats is set\");\n }\n this.id = Timer._MAX_ID++;\n this._callbacks = [];\n this._baseInterval = this.interval = interval;\n if (!!randomRange) {\n if (randomRange[0] > randomRange[1]) throw new Error(\"min value must be lower than max value for range\");\n //We use the instance of ex.Random to generate the range\n this.random = random !== null && random !== void 0 ? random : new Random();\n this.randomRange = randomRange;\n this.interval = this._generateRandomInterval();\n this.on(()=>{\n this.interval = this._generateRandomInterval();\n });\n }\n this.repeats = repeats || this.repeats;\n if (fcn) this.on(fcn);\n }\n /**\r\n * Adds a new callback to be fired after the interval is complete\r\n * @param fcn The callback to be added to the callback list, to be fired after the interval is complete.\r\n */ on(fcn) {\n this._callbacks.push(fcn);\n }\n /**\r\n * Removes a callback from the callback list to be fired after the interval is complete.\r\n * @param fcn The callback to be removed from the callback list, to be fired after the interval is complete.\r\n */ off(fcn) {\n const index = this._callbacks.indexOf(fcn);\n this._callbacks.splice(index, 1);\n }\n /**\r\n * Updates the timer after a certain number of milliseconds have elapsed. This is used internally by the engine.\r\n * @param delta Number of elapsed milliseconds since the last update.\r\n */ update(delta) {\n if (this._running) {\n this._totalTimeAlive += delta;\n this._elapsedTime += delta;\n if (this.maxNumberOfRepeats > -1 && this._numberOfTicks >= this.maxNumberOfRepeats) {\n this._complete = true;\n this._running = false;\n this._elapsedTime = 0;\n }\n if (!this.complete && this._elapsedTime >= this.interval) {\n this._callbacks.forEach((c)=>{\n c.call(this);\n });\n this._numberOfTicks++;\n if (this.repeats) this._elapsedTime = 0;\n else {\n this._complete = true;\n this._running = false;\n this._elapsedTime = 0;\n }\n }\n }\n }\n /**\r\n * Resets the timer so that it can be reused, and optionally reconfigure the timers interval.\r\n *\r\n * Warning** you may need to call `timer.start()` again if the timer had completed\r\n * @param newInterval If specified, sets a new non-negative interval in milliseconds to refire the callback\r\n * @param newNumberOfRepeats If specified, sets a new non-negative upper limit to the number of time this timer executes\r\n */ reset(newInterval, newNumberOfRepeats) {\n if (!!newInterval && newInterval >= 0) this._baseInterval = this.interval = newInterval;\n if (!!this.maxNumberOfRepeats && this.maxNumberOfRepeats >= 0) {\n this.maxNumberOfRepeats = newNumberOfRepeats;\n if (!this.repeats) throw new Error(\"repeats must be set to true if numberOfRepeats is set\");\n }\n this._complete = false;\n this._elapsedTime = 0;\n this._numberOfTicks = 0;\n }\n get timesRepeated() {\n return this._numberOfTicks;\n }\n getTimeRunning() {\n return this._totalTimeAlive;\n }\n /**\r\n * @returns milliseconds until the next action callback, if complete will return 0\r\n */ get timeToNextAction() {\n if (this.complete) return 0;\n return this.interval - this._elapsedTime;\n }\n /**\r\n * @returns milliseconds elapsed toward the next action\r\n */ get timeElapsedTowardNextAction() {\n return this._elapsedTime;\n }\n get isRunning() {\n return this._running;\n }\n /**\r\n * Pauses the timer, time will no longer increment towards the next call\r\n */ pause() {\n this._running = false;\n return this;\n }\n /**\r\n * Resumes the timer, time will now increment towards the next call.\r\n */ resume() {\n this._running = true;\n return this;\n }\n /**\r\n * Starts the timer, if the timer was complete it will restart the timer and reset the elapsed time counter\r\n */ start() {\n if (!this.scene) this._logger.warn(\"Cannot start a timer not part of a scene, timer wont start until added\");\n this._running = true;\n if (this.complete) {\n this._complete = false;\n this._elapsedTime = 0;\n this._numberOfTicks = 0;\n }\n return this;\n }\n /**\r\n * Stops the timer and resets the elapsed time counter towards the next action invocation\r\n */ stop() {\n this._running = false;\n this._elapsedTime = 0;\n this._numberOfTicks = 0;\n return this;\n }\n /**\r\n * Cancels the timer, preventing any further executions.\r\n */ cancel() {\n this.pause();\n if (this.scene) this.scene.cancelTimer(this);\n }\n }\n Timer._MAX_ID = 0;\n class ParallaxComponent extends Component {\n constructor(parallaxFactor){\n super();\n this.type = \"ex.parallax\";\n this.parallaxFactor = vec(1.0, 1.0);\n this.parallaxFactor = parallaxFactor !== null && parallaxFactor !== void 0 ? parallaxFactor : this.parallaxFactor;\n }\n }\n /**\r\n * Provide arbitrary drawing for the purposes of debugging your game\r\n *\r\n * Will only show when the Engine is set to debug mode [[Engine.showDebug]] or [[Engine.toggleDebug]]\r\n *\r\n */ class DebugGraphicsComponent extends Component {\n constructor(draw, useTransform = true){\n super();\n this.draw = draw;\n this.useTransform = useTransform;\n this.type = \"ex.debuggraphics\";\n }\n }\n const TileMapEvents = {\n PreUpdate: \"preupdate\",\n PostUpdate: \"postupdate\",\n PreDraw: \"predraw\",\n PostDraw: \"postdraw\"\n };\n /**\r\n * The TileMap provides a mechanism for doing flat 2D tiles rendered in a grid.\r\n *\r\n * TileMaps are useful for top down or side scrolling grid oriented games.\r\n */ class TileMap extends Entity {\n flagCollidersDirty() {\n this._collidersDirty = true;\n }\n flagTilesDirty() {\n for(let i = 0; i < this.tiles.length; i++)if (this.tiles[i]) this.tiles[i].flagDirty();\n }\n get x() {\n var _a;\n return (_a = this._transform.pos.x) !== null && _a !== void 0 ? _a : 0;\n }\n set x(val) {\n var _a;\n if ((_a = this._transform) === null || _a === void 0 ? void 0 : _a.pos) this.get(TransformComponent).pos = vec(val, this.y);\n }\n get y() {\n var _a, _b;\n return (_b = (_a = this._transform) === null || _a === void 0 ? void 0 : _a.pos.y) !== null && _b !== void 0 ? _b : 0;\n }\n set y(val) {\n var _a;\n if ((_a = this._transform) === null || _a === void 0 ? void 0 : _a.pos) this._transform.pos = vec(this.x, val);\n }\n get z() {\n var _a;\n return (_a = this._transform.z) !== null && _a !== void 0 ? _a : 0;\n }\n set z(val) {\n if (this._transform) this._transform.z = val;\n }\n get rotation() {\n var _a, _b;\n return (_b = (_a = this._transform) === null || _a === void 0 ? void 0 : _a.rotation) !== null && _b !== void 0 ? _b : 0;\n }\n set rotation(val) {\n var _a;\n if ((_a = this._transform) === null || _a === void 0 ? void 0 : _a.rotation) this._transform.rotation = val;\n }\n get scale() {\n var _a, _b;\n return (_b = (_a = this._transform) === null || _a === void 0 ? void 0 : _a.scale) !== null && _b !== void 0 ? _b : Vector.One;\n }\n set scale(val) {\n var _a;\n if ((_a = this._transform) === null || _a === void 0 ? void 0 : _a.scale) this._transform.scale = val;\n }\n get pos() {\n return this._transform.pos;\n }\n set pos(val) {\n this._transform.pos = val;\n }\n get vel() {\n return this._motion.vel;\n }\n set vel(val) {\n this._motion.vel = val;\n }\n emit(eventName, event) {\n this.events.emit(eventName, event);\n }\n on(eventName, handler) {\n return this.events.on(eventName, handler);\n }\n once(eventName, handler) {\n return this.events.once(eventName, handler);\n }\n off(eventName, handler) {\n this.events.off(eventName, handler);\n }\n /**\r\n * @param options\r\n */ constructor(options){\n var _a, _b;\n super(null, options.name);\n this.events = new EventEmitter();\n this._token = 0;\n this.logger = Logger.getInstance();\n this.tiles = [];\n this._rows = [];\n this._cols = [];\n this.renderFromTopOfGraphic = false;\n this._collidersDirty = true;\n this._originalOffsets = new WeakMap();\n this.addComponent(new TransformComponent());\n this.addComponent(new MotionComponent());\n this.addComponent(new BodyComponent({\n type: CollisionType.Fixed\n }));\n this.addComponent(new GraphicsComponent({\n onPostDraw: (ctx, delta)=>this.draw(ctx, delta)\n }));\n this.addComponent(new DebugGraphicsComponent((ctx)=>this.debug(ctx)));\n this.addComponent(new ColliderComponent());\n this._graphics = this.get(GraphicsComponent);\n this._transform = this.get(TransformComponent);\n this._motion = this.get(MotionComponent);\n this._collider = this.get(ColliderComponent);\n this._composite = this._collider.useCompositeCollider([]);\n this._transform.pos = (_a = options.pos) !== null && _a !== void 0 ? _a : Vector.Zero;\n this._oldPos = this._transform.pos.clone();\n this._oldScale = this._transform.scale.clone();\n this.renderFromTopOfGraphic = (_b = options.renderFromTopOfGraphic) !== null && _b !== void 0 ? _b : this.renderFromTopOfGraphic;\n this.tileWidth = options.tileWidth;\n this.tileHeight = options.tileHeight;\n this.rows = options.rows;\n this.columns = options.columns;\n this.tiles = new Array(this.rows * this.columns);\n this._rows = new Array(this.rows);\n this._cols = new Array(this.columns);\n let currentCol = [];\n for(let i = 0; i < this.columns; i++){\n for(let j = 0; j < this.rows; j++){\n const cd = new Tile({\n x: i,\n y: j,\n map: this\n });\n cd.map = this;\n this.tiles[i + j * this.columns] = cd;\n currentCol.push(cd);\n if (!this._rows[j]) this._rows[j] = [];\n this._rows[j].push(cd);\n }\n this._cols[i] = currentCol;\n currentCol = [];\n }\n this._graphics.localBounds = new BoundingBox({\n left: 0,\n top: 0,\n right: this.columns * this.tileWidth * this.scale.x,\n bottom: this.rows * this.tileHeight * this.scale.y\n });\n }\n _initialize(engine) {\n super._initialize(engine);\n this._engine = engine;\n }\n _getOrSetColliderOriginalOffset(collider) {\n if (!this._originalOffsets.has(collider)) {\n const originalOffset = collider.offset;\n this._originalOffsets.set(collider, originalOffset);\n return originalOffset;\n } else return this._originalOffsets.get(collider);\n }\n /**\r\n * Tiles colliders based on the solid tiles in the tilemap.\r\n */ _updateColliders() {\n this._collider.$colliderRemoved.notifyAll(this._composite);\n this._composite.clearColliders();\n const colliders = [];\n this._composite = this._collider.useCompositeCollider([]);\n let current;\n // Bad square tesselation algo\n for(let i = 0; i < this.columns; i++){\n // Scan column for colliders\n for(let j = 0; j < this.rows; j++){\n // Columns start with a new collider\n if (j === 0) current = null;\n const tile = this.tiles[i + j * this.columns];\n // Current tile in column is solid build up current collider\n if (tile.solid) {\n // Use custom collider otherwise bounding box\n if (tile.getColliders().length > 0) {\n // tile with custom collider interrupting the current run\n for (const collider of tile.getColliders()){\n const originalOffset = this._getOrSetColliderOriginalOffset(collider);\n collider.offset = vec(tile.x * this.tileWidth * this.scale.x, tile.y * this.tileHeight * this.scale.y).add(originalOffset);\n collider.owner = this;\n this._composite.addCollider(collider);\n }\n //we push any current collider before nulling the current run\n if (current) colliders.push(current);\n current = null;\n } else if (!current) // no current run, start one\n current = tile.bounds;\n else // combine with current run\n current = current.combine(tile.bounds);\n } else {\n // Not solid skip and cut off the current collider\n if (current) colliders.push(current);\n current = null;\n }\n }\n // After a column is complete check to see if it can be merged into the last one\n if (current) {\n // if previous is the same combine it\n const prev = colliders[colliders.length - 1];\n if (prev && prev.top === current.top && prev.bottom === current.bottom) colliders[colliders.length - 1] = prev.combine(current);\n else // else new collider\n colliders.push(current);\n }\n }\n for (const c of colliders){\n const collider = Shape.Box(c.width, c.height, Vector.Zero, vec(c.left - this.pos.x, c.top - this.pos.y));\n collider.owner = this;\n this._composite.addCollider(collider);\n }\n this._collider.update();\n // Notify that colliders have been updated\n this._collider.$colliderAdded.notifyAll(this._composite);\n }\n /**\r\n * Returns the [[Tile]] by index (row major order)\r\n */ getTileByIndex(index) {\n return this.tiles[index];\n }\n /**\r\n * Returns the [[Tile]] by its x and y integer coordinates\r\n */ getTile(x, y) {\n if (x < 0 || y < 0 || x >= this.columns || y >= this.rows) return null;\n return this.tiles[x + y * this.columns];\n }\n /**\r\n * Returns the [[Tile]] by testing a point in world coordinates,\r\n * returns `null` if no Tile was found.\r\n */ getTileByPoint(point) {\n const x = Math.floor((point.x - this.pos.x) / (this.tileWidth * this.scale.x));\n const y = Math.floor((point.y - this.pos.y) / (this.tileHeight * this.scale.y));\n const tile = this.getTile(x, y);\n if (x >= 0 && y >= 0 && x < this.columns && y < this.rows && tile) return tile;\n return null;\n }\n getRows() {\n return this._rows;\n }\n getColumns() {\n return this._cols;\n }\n update(engine, delta) {\n this.onPreUpdate(engine, delta);\n this.emit(\"preupdate\", new PreUpdateEvent(engine, delta, this));\n if (!this._oldPos.equals(this.pos) || !this._oldScale.equals(this.scale)) {\n this.flagCollidersDirty();\n this.flagTilesDirty();\n }\n if (this._collidersDirty) {\n this._collidersDirty = false;\n this._updateColliders();\n }\n this._token++;\n this.pos.clone(this._oldPos);\n this.scale.clone(this._oldScale);\n this._transform.pos = this.pos;\n this.onPostUpdate(engine, delta);\n this.emit(\"postupdate\", new PostUpdateEvent(engine, delta, this));\n }\n /**\r\n * Draws the tile map to the screen. Called by the [[Scene]].\r\n * @param ctx ExcaliburGraphicsContext\r\n * @param delta The number of milliseconds since the last draw\r\n */ draw(ctx, delta) {\n this.emit(\"predraw\", new PreDrawEvent(ctx, delta, this)); // TODO fix event\n let worldBounds = this._engine.screen.getWorldBounds();\n // TODO can we trim this down by using world bounds?\n let x = 0;\n const xEnd = this.columns;\n let y = 0;\n const yEnd = this.rows;\n let graphics, graphicsIndex, graphicsLen;\n const maybeParallax = this.get(ParallaxComponent);\n if (maybeParallax) {\n let pos = this.pos;\n const oneMinusFactor = Vector.One.sub(maybeParallax.parallaxFactor);\n const parallaxOffset = this._engine.currentScene.camera.pos.scale(oneMinusFactor);\n pos = pos.sub(parallaxOffset);\n // adjust world bounds by parallax factor\n worldBounds = worldBounds.translate(pos);\n }\n let tile;\n for(x; x < xEnd; x++){\n for(y; y < yEnd; y++){\n tile = this.getTile(x, y);\n // fixme: This has a large perf impact, we iterate over every tile in the tilemap\n // this probably requires a spatial data structure to do more efficiently\n if (!worldBounds.overlaps(tile.bounds)) continue;\n // get non-negative tile sprites\n graphics = this.getTile(x, y).getGraphics();\n for(graphicsIndex = 0, graphicsLen = graphics.length; graphicsIndex < graphicsLen; graphicsIndex++){\n // draw sprite, warning if sprite doesn't exist\n const graphic = graphics[graphicsIndex];\n if (graphic) {\n if (hasGraphicsTick(graphic)) graphic === null || graphic === void 0 || graphic.tick(delta, this._token);\n const offsetY = this.renderFromTopOfGraphic ? 0 : graphic.height - this.tileHeight;\n graphic.draw(ctx, x * this.tileWidth, y * this.tileHeight - offsetY);\n }\n }\n }\n y = 0;\n }\n this.emit(\"postdraw\", new PostDrawEvent(ctx, delta, this));\n }\n debug(gfx) {\n const width = this.tileWidth * this.columns;\n const height = this.tileHeight * this.rows;\n const pos = Vector.Zero;\n for(let r = 0; r < this.rows + 1; r++){\n const yOffset = vec(0, r * this.tileHeight);\n gfx.drawLine(pos.add(yOffset), pos.add(vec(width, yOffset.y)), Color.Red, 2);\n }\n for(let c = 0; c < this.columns + 1; c++){\n const xOffset = vec(c * this.tileWidth, 0);\n gfx.drawLine(pos.add(xOffset), pos.add(vec(xOffset.x, height)), Color.Red, 2);\n }\n const colliders = this._composite.getColliders();\n for (const collider of colliders){\n const grayish = Color.Gray;\n grayish.a = 0.5;\n const bounds = collider.localBounds;\n const pos = collider.worldPos.sub(this.pos);\n gfx.drawRectangle(pos, bounds.width, bounds.height, grayish);\n }\n }\n }\n /**\r\n * TileMap Tile\r\n *\r\n * A light-weight object that occupies a space in a collision map. Generally\r\n * created by a [[TileMap]].\r\n *\r\n * Tiles can draw multiple sprites. Note that the order of drawing is the order\r\n * of the sprites in the array so the last one will be drawn on top. You can\r\n * use transparency to create layers this way.\r\n */ class Tile extends Entity {\n // private _transform: TransformComponent;\n /**\r\n * Return the world position of the top left corner of the tile\r\n */ get pos() {\n if (this._posDirty) {\n this._recalculate();\n this._posDirty = false;\n }\n return this._pos;\n }\n /**\r\n * Width of the tile in pixels\r\n */ get width() {\n return this._width;\n }\n /**\r\n * Height of the tile in pixels\r\n */ get height() {\n return this._height;\n }\n /**\r\n * Wether this tile should be treated as solid by the tilemap\r\n */ get solid() {\n return this._solid;\n }\n /**\r\n * Wether this tile should be treated as solid by the tilemap\r\n */ set solid(val) {\n var _a;\n (_a = this.map) === null || _a === void 0 || _a.flagCollidersDirty();\n this._solid = val;\n }\n /**\r\n * Current list of graphics for this tile\r\n */ getGraphics() {\n return this._graphics;\n }\n /**\r\n * Add another [[Graphic]] to this TileMap tile\r\n * @param graphic\r\n */ addGraphic(graphic) {\n this._graphics.push(graphic);\n }\n /**\r\n * Remove an instance of a [[Graphic]] from this tile\r\n */ removeGraphic(graphic) {\n removeItemFromArray(graphic, this._graphics);\n }\n /**\r\n * Clear all graphics from this tile\r\n */ clearGraphics() {\n this._graphics.length = 0;\n }\n /**\r\n * Returns the list of colliders\r\n */ getColliders() {\n return this._colliders;\n }\n /**\r\n * Adds a custom collider to the [[Tile]] to use instead of it's bounds\r\n *\r\n * If no collider is set but [[Tile.solid]] is set, the tile bounds are used as a collider.\r\n *\r\n * **Note!** the [[Tile.solid]] must be set to true for it to act as a \"fixed\" collider\r\n * @param collider\r\n */ addCollider(collider) {\n this._colliders.push(collider);\n this.map.flagCollidersDirty();\n }\n /**\r\n * Removes a collider from the [[Tile]]\r\n * @param collider\r\n */ removeCollider(collider) {\n const index = this._colliders.indexOf(collider);\n if (index > -1) this._colliders.splice(index, 1);\n this.map.flagCollidersDirty();\n }\n /**\r\n * Clears all colliders from the [[Tile]]\r\n */ clearColliders() {\n this._colliders.length = 0;\n this.map.flagCollidersDirty();\n }\n constructor(options){\n var _a, _b;\n super();\n this._posDirty = false;\n this._solid = false;\n this._graphics = [];\n /**\r\n * Current list of colliders for this tile\r\n */ this._colliders = [];\n /**\r\n * Arbitrary data storage per tile, useful for any game specific data\r\n */ this.data = new Map();\n this.x = options.x;\n this.y = options.y;\n this.map = options.map;\n this._width = options.map.tileWidth * this.map.scale.x;\n this._height = options.map.tileHeight * this.map.scale.y;\n this.solid = (_a = options.solid) !== null && _a !== void 0 ? _a : this.solid;\n this._graphics = (_b = options.graphics) !== null && _b !== void 0 ? _b : [];\n this._recalculate();\n }\n flagDirty() {\n return this._posDirty = true;\n }\n _recalculate() {\n this._width = this.map.tileWidth * this.map.scale.x;\n this._height = this.map.tileHeight * this.map.scale.y;\n this._pos = this.map.pos.add(vec(this.x * this._width, this.y * this._height));\n this._bounds = new BoundingBox(this._pos.x, this._pos.y, this._pos.x + this._width, this._pos.y + this._height);\n this._posDirty = false;\n }\n /**\r\n * Tile bounds in world space\r\n */ get bounds() {\n if (this._posDirty) this._recalculate();\n return this._bounds;\n }\n /**\r\n * Tile position in world space\r\n */ get center() {\n if (this._posDirty) this._recalculate();\n return new Vector(this._pos.x + this._width / 2, this._pos.y + this._height / 2);\n }\n }\n /**\r\n * Container to house convenience strategy methods\r\n * @internal\r\n */ class StrategyContainer {\n constructor(camera){\n this.camera = camera;\n }\n /**\r\n * Creates and adds the [[LockCameraToActorStrategy]] on the current camera.\r\n * @param actor The actor to lock the camera to\r\n */ lockToActor(actor) {\n this.camera.addStrategy(new LockCameraToActorStrategy(actor));\n }\n /**\r\n * Creates and adds the [[LockCameraToActorAxisStrategy]] on the current camera\r\n * @param actor The actor to lock the camera to\r\n * @param axis The axis to follow the actor on\r\n */ lockToActorAxis(actor, axis) {\n this.camera.addStrategy(new LockCameraToActorAxisStrategy(actor, axis));\n }\n /**\r\n * Creates and adds the [[ElasticToActorStrategy]] on the current camera\r\n * If cameraElasticity < cameraFriction < 1.0, the behavior will be a dampened spring that will slowly end at the target without bouncing\r\n * If cameraFriction < cameraElasticity < 1.0, the behavior will be an oscillating spring that will over\r\n * correct and bounce around the target\r\n *\r\n * @param actor Target actor to elastically follow\r\n * @param cameraElasticity [0 - 1.0] The higher the elasticity the more force that will drive the camera towards the target\r\n * @param cameraFriction [0 - 1.0] The higher the friction the more that the camera will resist motion towards the target\r\n */ elasticToActor(actor, cameraElasticity, cameraFriction) {\n this.camera.addStrategy(new ElasticToActorStrategy(actor, cameraElasticity, cameraFriction));\n }\n /**\r\n * Creates and adds the [[RadiusAroundActorStrategy]] on the current camera\r\n * @param actor Target actor to follow when it is \"radius\" pixels away\r\n * @param radius Number of pixels away before the camera will follow\r\n */ radiusAroundActor(actor, radius) {\n this.camera.addStrategy(new RadiusAroundActorStrategy(actor, radius));\n }\n /**\r\n * Creates and adds the [[LimitCameraBoundsStrategy]] on the current camera\r\n * @param box The bounding box to limit the camera to.\r\n */ limitCameraBounds(box) {\n this.camera.addStrategy(new LimitCameraBoundsStrategy(box));\n }\n }\n /**\r\n * Camera axis enum\r\n */ var Axis;\n (function(Axis) {\n Axis[Axis[\"X\"] = 0] = \"X\";\n Axis[Axis[\"Y\"] = 1] = \"Y\";\n })(Axis || (Axis = {}));\n /**\r\n * Lock a camera to the exact x/y position of an actor.\r\n */ class LockCameraToActorStrategy {\n constructor(target){\n this.target = target;\n this.action = (target, _cam, _eng, _delta)=>{\n const center = target.center;\n return center;\n };\n }\n }\n /**\r\n * Lock a camera to a specific axis around an actor.\r\n */ class LockCameraToActorAxisStrategy {\n constructor(target, axis){\n this.target = target;\n this.axis = axis;\n this.action = (target, cam, _eng, _delta)=>{\n const center = target.center;\n const currentFocus = cam.getFocus();\n if (this.axis === Axis.X) return new Vector(center.x, currentFocus.y);\n else return new Vector(currentFocus.x, center.y);\n };\n }\n }\n /**\r\n * Using [Hook's law](https://en.wikipedia.org/wiki/Hooke's_law), elastically move the camera towards the target actor.\r\n */ class ElasticToActorStrategy {\n /**\r\n * If cameraElasticity < cameraFriction < 1.0, the behavior will be a dampened spring that will slowly end at the target without bouncing\r\n * If cameraFriction < cameraElasticity < 1.0, the behavior will be an oscillating spring that will over\r\n * correct and bounce around the target\r\n *\r\n * @param target Target actor to elastically follow\r\n * @param cameraElasticity [0 - 1.0] The higher the elasticity the more force that will drive the camera towards the target\r\n * @param cameraFriction [0 - 1.0] The higher the friction the more that the camera will resist motion towards the target\r\n */ constructor(target, cameraElasticity, cameraFriction){\n this.target = target;\n this.cameraElasticity = cameraElasticity;\n this.cameraFriction = cameraFriction;\n this.action = (target, cam, _eng, _delta)=>{\n const position = target.center;\n let focus = cam.getFocus();\n let cameraVel = cam.vel.clone();\n // Calculate the stretch vector, using the spring equation\n // F = kX\n // https://en.wikipedia.org/wiki/Hooke's_law\n // Apply to the current camera velocity\n const stretch = position.sub(focus).scale(this.cameraElasticity); // stretch is X\n cameraVel = cameraVel.add(stretch);\n // Calculate the friction (-1 to apply a force in the opposition of motion)\n // Apply to the current camera velocity\n const friction = cameraVel.scale(-1).scale(this.cameraFriction);\n cameraVel = cameraVel.add(friction);\n // Update position by velocity deltas\n focus = focus.add(cameraVel);\n return focus;\n };\n }\n }\n class RadiusAroundActorStrategy {\n /**\r\n *\r\n * @param target Target actor to follow when it is \"radius\" pixels away\r\n * @param radius Number of pixels away before the camera will follow\r\n */ constructor(target, radius){\n this.target = target;\n this.radius = radius;\n this.action = (target, cam, _eng, _delta)=>{\n const position = target.center;\n const focus = cam.getFocus();\n const direction = position.sub(focus);\n const distance = direction.size;\n if (distance >= this.radius) {\n const offset = distance - this.radius;\n return focus.add(direction.normalize().scale(offset));\n }\n return focus;\n };\n }\n }\n /**\r\n * Prevent a camera from going beyond the given camera dimensions.\r\n */ class LimitCameraBoundsStrategy {\n constructor(target){\n this.target = target;\n /**\r\n * Useful for limiting the camera to a [[TileMap]]'s dimensions, or a specific area inside the map.\r\n *\r\n * Note that this strategy does not perform any movement by itself.\r\n * It only sets the camera position to within the given bounds when the camera has gone beyond them.\r\n * Thus, it is a good idea to combine it with other camera strategies and set this strategy as the last one.\r\n *\r\n * Make sure that the camera bounds are at least as large as the viewport size.\r\n *\r\n * @param target The bounding box to limit the camera to\r\n */ this.boundSizeChecked = false; // Check and warn only once\n this.action = (target, cam, _eng, _delta)=>{\n const focus = cam.getFocus();\n if (!this.boundSizeChecked) {\n if (target.bottom - target.top < _eng.drawHeight || target.right - target.left < _eng.drawWidth) Logger.getInstance().warn(\"Camera bounds should not be smaller than the engine viewport\");\n this.boundSizeChecked = true;\n }\n let focusX = focus.x;\n let focusY = focus.y;\n if (focus.x < target.left + _eng.halfDrawWidth) focusX = target.left + _eng.halfDrawWidth;\n else if (focus.x > target.right - _eng.halfDrawWidth) focusX = target.right - _eng.halfDrawWidth;\n if (focus.y < target.top + _eng.halfDrawHeight) focusY = target.top + _eng.halfDrawHeight;\n else if (focus.y > target.bottom - _eng.halfDrawHeight) focusY = target.bottom - _eng.halfDrawHeight;\n return vec(focusX, focusY);\n };\n }\n }\n const CameraEvents = {\n Initialize: \"initialize\",\n PreUpdate: \"preupdate\",\n PostUpdate: \"postupdate\"\n };\n /**\r\n * Cameras\r\n *\r\n * [[Camera]] is the base class for all Excalibur cameras. Cameras are used\r\n * to move around your game and set focus. They are used to determine\r\n * what is \"off screen\" and can be used to scale the game.\r\n *\r\n */ class Camera {\n constructor(){\n this.events = new EventEmitter();\n this.transform = AffineMatrix.identity();\n this.inverse = AffineMatrix.identity();\n this._cameraStrategies = [];\n this.strategy = new StrategyContainer(this);\n /**\r\n * Get or set current zoom of the camera, defaults to 1\r\n */ this._z = 1;\n /**\r\n * Get or set rate of change in zoom, defaults to 0\r\n */ this.dz = 0;\n /**\r\n * Get or set zoom acceleration\r\n */ this.az = 0;\n /**\r\n * Current rotation of the camera\r\n */ this.rotation = 0;\n this._angularVelocity = 0;\n /**\r\n * Get or set the camera's position\r\n */ this._posChanged = false;\n this._pos = watchAny(Vector.Zero, ()=>this._posChanged = true);\n /**\r\n * Get or set the camera's velocity\r\n */ this.vel = Vector.Zero;\n /**\r\n * Get or set the camera's acceleration\r\n */ this.acc = Vector.Zero;\n this._cameraMoving = false;\n this._currentLerpTime = 0;\n this._lerpDuration = 1000; // 1 second\n this._lerpStart = null;\n this._lerpEnd = null;\n //camera effects\n this._isShaking = false;\n this._shakeMagnitudeX = 0;\n this._shakeMagnitudeY = 0;\n this._shakeDuration = 0;\n this._elapsedShakeTime = 0;\n this._xShake = 0;\n this._yShake = 0;\n this._isZooming = false;\n this._zoomStart = 1;\n this._zoomEnd = 1;\n this._currentZoomTime = 0;\n this._zoomDuration = 0;\n this._zoomEasing = EasingFunctions.EaseInOutCubic;\n this._easing = EasingFunctions.EaseInOutCubic;\n this._halfWidth = 0;\n this._halfHeight = 0;\n this._viewport = null;\n this._isInitialized = false;\n }\n get zoom() {\n return this._z;\n }\n set zoom(val) {\n this._z = val;\n if (this._engine) {\n this._halfWidth = this._engine.halfDrawWidth;\n this._halfHeight = this._engine.halfDrawHeight;\n }\n }\n /**\r\n * Get or set the camera's angular velocity\r\n */ get angularVelocity() {\n return this._angularVelocity;\n }\n set angularVelocity(value) {\n this._angularVelocity = value;\n }\n get pos() {\n return this._pos;\n }\n set pos(vec) {\n this._pos = watchAny(vec, ()=>this._posChanged = true);\n this._posChanged = true;\n }\n /**\r\n * Get the camera's x position\r\n */ get x() {\n return this.pos.x;\n }\n /**\r\n * Set the camera's x position (cannot be set when following an [[Actor]] or when moving)\r\n */ set x(value) {\n if (!this._follow && !this._cameraMoving) this.pos = vec(value, this.pos.y);\n }\n /**\r\n * Get the camera's y position\r\n */ get y() {\n return this.pos.y;\n }\n /**\r\n * Set the camera's y position (cannot be set when following an [[Actor]] or when moving)\r\n */ set y(value) {\n if (!this._follow && !this._cameraMoving) this.pos = vec(this.pos.x, value);\n }\n /**\r\n * Get or set the camera's x velocity\r\n */ get dx() {\n return this.vel.x;\n }\n set dx(value) {\n this.vel = vec(value, this.vel.y);\n }\n /**\r\n * Get or set the camera's y velocity\r\n */ get dy() {\n return this.vel.y;\n }\n set dy(value) {\n this.vel = vec(this.vel.x, value);\n }\n /**\r\n * Get or set the camera's x acceleration\r\n */ get ax() {\n return this.acc.x;\n }\n set ax(value) {\n this.acc = vec(value, this.acc.y);\n }\n /**\r\n * Get or set the camera's y acceleration\r\n */ get ay() {\n return this.acc.y;\n }\n set ay(value) {\n this.acc = vec(this.acc.x, value);\n }\n /**\r\n * Returns the focal point of the camera, a new point giving the x and y position of the camera\r\n */ getFocus() {\n return this.pos;\n }\n /**\r\n * This moves the camera focal point to the specified position using specified easing function. Cannot move when following an Actor.\r\n *\r\n * @param pos The target position to move to\r\n * @param duration The duration in milliseconds the move should last\r\n * @param [easingFn] An optional easing function ([[ex.EasingFunctions.EaseInOutCubic]] by default)\r\n * @returns A [[Promise]] that resolves when movement is finished, including if it's interrupted.\r\n * The [[Promise]] value is the [[Vector]] of the target position. It will be rejected if a move cannot be made.\r\n */ move(pos, duration, easingFn = EasingFunctions.EaseInOutCubic) {\n if (typeof easingFn !== \"function\") throw \"Please specify an EasingFunction\";\n // cannot move when following an actor\n if (this._follow) return Promise.reject(pos);\n // resolve existing promise, if any\n if (this._lerpPromise && this._lerpResolve) this._lerpResolve(pos);\n this._lerpPromise = new Promise((resolve)=>{\n this._lerpResolve = resolve;\n });\n this._lerpStart = this.getFocus().clone();\n this._lerpDuration = duration;\n this._lerpEnd = pos;\n this._currentLerpTime = 0;\n this._cameraMoving = true;\n this._easing = easingFn;\n return this._lerpPromise;\n }\n /**\r\n * Sets the camera to shake at the specified magnitudes for the specified duration\r\n * @param magnitudeX The x magnitude of the shake\r\n * @param magnitudeY The y magnitude of the shake\r\n * @param duration The duration of the shake in milliseconds\r\n */ shake(magnitudeX, magnitudeY, duration) {\n this._isShaking = true;\n this._shakeMagnitudeX = magnitudeX;\n this._shakeMagnitudeY = magnitudeY;\n this._shakeDuration = duration;\n }\n /**\r\n * Zooms the camera in or out by the specified scale over the specified duration.\r\n * If no duration is specified, it take effect immediately.\r\n * @param scale The scale of the zoom\r\n * @param duration The duration of the zoom in milliseconds\r\n */ zoomOverTime(scale, duration = 0, easingFn = EasingFunctions.EaseInOutCubic) {\n this._zoomPromise = new Promise((resolve)=>{\n this._zoomResolve = resolve;\n });\n if (duration) {\n this._isZooming = true;\n this._zoomEasing = easingFn;\n this._currentZoomTime = 0;\n this._zoomDuration = duration;\n this._zoomStart = this.zoom;\n this._zoomEnd = scale;\n } else {\n this._isZooming = false;\n this.zoom = scale;\n return Promise.resolve(true);\n }\n return this._zoomPromise;\n }\n /**\r\n * Gets the bounding box of the viewport of this camera in world coordinates\r\n */ get viewport() {\n if (this._viewport) return this._viewport;\n return new BoundingBox(0, 0, 0, 0);\n }\n /**\r\n * Adds a new camera strategy to this camera\r\n * @param cameraStrategy Instance of an [[CameraStrategy]]\r\n */ addStrategy(cameraStrategy) {\n this._cameraStrategies.push(cameraStrategy);\n }\n /**\r\n * Removes a camera strategy by reference\r\n * @param cameraStrategy Instance of an [[CameraStrategy]]\r\n */ removeStrategy(cameraStrategy) {\n removeItemFromArray(cameraStrategy, this._cameraStrategies);\n }\n /**\r\n * Clears all camera strategies from the camera\r\n */ clearAllStrategies() {\n this._cameraStrategies.length = 0;\n }\n /**\r\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\r\n *\r\n * Internal _preupdate handler for [[onPreUpdate]] lifecycle event\r\n * @internal\r\n */ _preupdate(engine, delta) {\n this.events.emit(\"preupdate\", new PreUpdateEvent(engine, delta, this));\n this.onPreUpdate(engine, delta);\n }\n /**\r\n * Safe to override onPreUpdate lifecycle event handler. Synonymous with `.on('preupdate', (evt) =>{...})`\r\n *\r\n * `onPreUpdate` is called directly before a scene is updated.\r\n */ onPreUpdate(_engine, _delta) {\n // Overridable\n }\n /**\r\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\r\n *\r\n * Internal _preupdate handler for [[onPostUpdate]] lifecycle event\r\n * @internal\r\n */ _postupdate(engine, delta) {\n this.events.emit(\"postupdate\", new PostUpdateEvent(engine, delta, this));\n this.onPostUpdate(engine, delta);\n }\n /**\r\n * Safe to override onPostUpdate lifecycle event handler. Synonymous with `.on('preupdate', (evt) =>{...})`\r\n *\r\n * `onPostUpdate` is called directly after a scene is updated.\r\n */ onPostUpdate(_engine, _delta) {\n // Overridable\n }\n get isInitialized() {\n return this._isInitialized;\n }\n _initialize(_engine) {\n if (!this.isInitialized) {\n this._engine = _engine;\n this._screen = _engine.screen;\n const currentRes = this._screen.contentArea;\n let center = vec(currentRes.width / 2, currentRes.height / 2);\n if (!this._engine.loadingComplete) {\n // If there was a loading screen, we peek the configured resolution\n const res = this._screen.peekResolution();\n if (res) center = vec(res.width / 2, res.height / 2);\n }\n this._halfWidth = center.x;\n this._halfHeight = center.y;\n // If the user has not set the camera pos, apply default center screen position\n if (!this._posChanged) this.pos = center;\n // First frame bootstrap\n // Ensure camera tx is correct\n // Run update twice to ensure properties are init'd\n this.updateTransform();\n // Run strategies for first frame\n this.runStrategies(_engine, _engine.clock.elapsed());\n // Setup the first frame viewport\n this.updateViewport();\n // It's important to update the camera after strategies\n // This prevents jitter\n this.updateTransform();\n this.onInitialize(_engine);\n this.events.emit(\"initialize\", new InitializeEvent(_engine, this));\n this._isInitialized = true;\n }\n }\n /**\r\n * Safe to override onPostUpdate lifecycle event handler. Synonymous with `.on('preupdate', (evt) =>{...})`\r\n *\r\n * `onPostUpdate` is called directly after a scene is updated.\r\n */ onInitialize(_engine) {\n // Overridable\n }\n emit(eventName, event) {\n this.events.emit(eventName, event);\n }\n on(eventName, handler) {\n return this.events.on(eventName, handler);\n }\n once(eventName, handler) {\n return this.events.once(eventName, handler);\n }\n off(eventName, handler) {\n this.events.off(eventName, handler);\n }\n runStrategies(engine, delta) {\n for (const s of this._cameraStrategies)this.pos = s.action.call(s, s.target, this, engine, delta);\n }\n updateViewport() {\n // recalc viewport\n this._viewport = new BoundingBox(this.x - this._halfWidth, this.y - this._halfHeight, this.x + this._halfWidth, this.y + this._halfHeight);\n }\n update(_engine, delta) {\n this._initialize(_engine);\n this._preupdate(_engine, delta);\n // Update placements based on linear algebra\n this.pos = this.pos.add(this.vel.scale(delta / 1000));\n this.zoom += this.dz * delta / 1000;\n this.vel = this.vel.add(this.acc.scale(delta / 1000));\n this.dz += this.az * delta / 1000;\n this.rotation += this.angularVelocity * delta / 1000;\n if (this._isZooming) {\n if (this._currentZoomTime < this._zoomDuration) {\n const zoomEasing = this._zoomEasing;\n const newZoom = zoomEasing(this._currentZoomTime, this._zoomStart, this._zoomEnd, this._zoomDuration);\n this.zoom = newZoom;\n this._currentZoomTime += delta;\n } else {\n this._isZooming = false;\n this.zoom = this._zoomEnd;\n this._currentZoomTime = 0;\n this._zoomResolve(true);\n }\n }\n if (this._cameraMoving) {\n if (this._currentLerpTime < this._lerpDuration) {\n const moveEasing = EasingFunctions.CreateVectorEasingFunction(this._easing);\n const lerpPoint = moveEasing(this._currentLerpTime, this._lerpStart, this._lerpEnd, this._lerpDuration);\n this.pos = lerpPoint;\n this._currentLerpTime += delta;\n } else {\n this.pos = this._lerpEnd;\n const end = this._lerpEnd.clone();\n this._lerpStart = null;\n this._lerpEnd = null;\n this._currentLerpTime = 0;\n this._cameraMoving = false;\n // Order matters here, resolve should be last so any chain promises have a clean slate\n this._lerpResolve(end);\n }\n }\n if (this._isDoneShaking()) {\n this._isShaking = false;\n this._elapsedShakeTime = 0;\n this._shakeMagnitudeX = 0;\n this._shakeMagnitudeY = 0;\n this._shakeDuration = 0;\n this._xShake = 0;\n this._yShake = 0;\n } else {\n this._elapsedShakeTime += delta;\n this._xShake = (Math.random() * this._shakeMagnitudeX | 0) + 1;\n this._yShake = (Math.random() * this._shakeMagnitudeY | 0) + 1;\n }\n this.runStrategies(_engine, delta);\n this.updateViewport();\n // It's important to update the camera after strategies\n // This prevents jitter\n this.updateTransform();\n this._postupdate(_engine, delta);\n }\n /**\r\n * Applies the relevant transformations to the game canvas to \"move\" or apply effects to the Camera\r\n * @param ctx Canvas context to apply transformations\r\n */ draw(ctx) {\n ctx.multiply(this.transform);\n }\n updateTransform() {\n // center the camera\n const newCanvasWidth = this._screen.resolution.width / this.zoom;\n const newCanvasHeight = this._screen.resolution.height / this.zoom;\n const cameraPos = vec(-this.x + newCanvasWidth / 2 + this._xShake, -this.y + newCanvasHeight / 2 + this._yShake);\n // Calculate camera transform\n this.transform.reset();\n this.transform.scale(this.zoom, this.zoom);\n // rotate about the focus\n this.transform.translate(newCanvasWidth / 2, newCanvasHeight / 2);\n this.transform.rotate(this.rotation);\n this.transform.translate(-newCanvasWidth / 2, -newCanvasHeight / 2);\n this.transform.translate(cameraPos.x, cameraPos.y);\n this.transform.inverse(this.inverse);\n }\n _isDoneShaking() {\n return !this._isShaking || this._elapsedShakeTime >= this._shakeDuration;\n }\n }\n const TriggerEvents = {\n ExitTrigger: \"exittrigger\",\n EnterTrigger: \"entertrigger\"\n };\n const triggerDefaults = {\n pos: Vector.Zero,\n width: 10,\n height: 10,\n visible: false,\n action: ()=>{\n return;\n },\n filter: ()=>true,\n repeat: -1\n };\n /**\r\n * Triggers are a method of firing arbitrary code on collision. These are useful\r\n * as 'buttons', 'switches', or to trigger effects in a game. By default triggers\r\n * are invisible, and can only be seen when [[Trigger.visible]] is set to `true`.\r\n */ class Trigger extends Actor {\n /**\r\n *\r\n * @param opts Trigger options\r\n */ constructor(opts){\n super({\n x: opts.pos.x,\n y: opts.pos.y,\n width: opts.width,\n height: opts.height\n });\n this.events = new EventEmitter();\n /**\r\n * Action to fire when triggered by collision\r\n */ this.action = ()=>{\n return;\n };\n /**\r\n * Filter to add additional granularity to action dispatch, if a filter is specified the action will only fire when\r\n * filter return true for the collided actor.\r\n */ this.filter = ()=>true;\n /**\r\n * Number of times to repeat before killing the trigger,\r\n */ this.repeat = -1;\n opts = {\n ...triggerDefaults,\n ...opts\n };\n this.filter = opts.filter || this.filter;\n this.repeat = opts.repeat || this.repeat;\n this.action = opts.action || this.action;\n if (opts.target) this.target = opts.target;\n this.graphics.visible = opts.visible;\n this.body.collisionType = CollisionType.Passive;\n this.events.on(\"collisionstart\", (evt)=>{\n if (this.filter(evt.other)) {\n this.emit(\"enter\", new EnterTriggerEvent(this, evt.other));\n this._dispatchAction();\n // remove trigger if its done, -1 repeat forever\n if (this.repeat === 0) this.kill();\n }\n });\n this.events.on(\"collisionend\", (evt)=>{\n if (this.filter(evt.other)) this.emit(\"exit\", new ExitTriggerEvent(this, evt.other));\n });\n }\n set target(target) {\n this._target = target;\n this.filter = (actor)=>actor === target;\n }\n get target() {\n return this._target;\n }\n _initialize(engine) {\n super._initialize(engine);\n }\n _dispatchAction() {\n if (this.repeat !== 0) {\n this.action.call(this);\n this.repeat--;\n }\n }\n }\n /**\r\n * Enum that determines whether to run the system in the update or draw phase\r\n */ var SystemType;\n (function(SystemType) {\n SystemType[\"Update\"] = \"update\";\n SystemType[\"Draw\"] = \"draw\";\n })(SystemType || (SystemType = {}));\n /**\r\n * An Excalibur [[System]] that updates entities of certain types.\r\n * Systems are scene specific\r\n *\r\n * Excalibur Systems currently require at least 1 Component type to operated\r\n *\r\n * Multiple types are declared as a type union\r\n * For example:\r\n *\r\n * ```typescript\r\n * class MySystem extends System {\r\n * public readonly types = ['a', 'b'] as const;\r\n * public readonly systemType = SystemType.Update;\r\n * public update(entities: Entity) {\r\n * ...\r\n * }\r\n * }\r\n * ```\r\n */ class System {\n constructor(){\n /**\r\n * System can execute in priority order, by default all systems are priority 0. Lower values indicated higher priority.\r\n * For a system to execute before all other a lower priority value (-1 for example) must be set.\r\n * For a system to execute after all other a higher priority value (10 for example) must be set.\r\n */ this.priority = 0;\n }\n /**\r\n * Systems observe when entities match their types or no longer match their types, override\r\n * @param _entityAddedOrRemoved\r\n */ notify(_entityAddedOrRemoved) {\n // Override me\n }\n }\n /**\r\n * An [[Entity]] with [[Component]] types that matches a [[System]] types exists in the current scene.\r\n */ class AddedEntity {\n constructor(data){\n this.data = data;\n this.type = \"Entity Added\";\n }\n }\n /**\r\n * Type guard to check for AddedEntity messages\r\n * @param x\r\n */ function isAddedSystemEntity(x) {\n return !!x && x.type === \"Entity Added\";\n }\n /**\r\n * An [[Entity]] with [[Component]] types that no longer matches a [[System]] types exists in the current scene.\r\n */ class RemovedEntity {\n constructor(data){\n this.data = data;\n this.type = \"Entity Removed\";\n }\n }\n /**\r\n * type guard to check for the RemovedEntity message\r\n */ function isRemoveSystemEntity(x) {\n return !!x && x.type === \"Entity Removed\";\n }\n // Add/Remove entities and components\n class EntityManager {\n constructor(_world){\n this._world = _world;\n this.entities = [];\n this._entityIndex = {};\n this._entitiesToRemove = [];\n }\n /**\r\n * Runs the entity lifecycle\r\n * @param _context\r\n */ updateEntities(_context, elapsed) {\n for (const entity of this.entities){\n // TODO is this right?\n entity.update(_context.engine, elapsed);\n if (!entity.active) this.removeEntity(entity);\n }\n }\n findEntitiesForRemoval() {\n for (const entity of this.entities)if (!entity.active) this.removeEntity(entity);\n }\n /**\r\n * EntityManager observes changes on entities\r\n * @param message\r\n */ notify(message) {\n if (isAddedComponent(message)) // we don't need the component, it's already on the entity\n this._world.queryManager.addEntity(message.data.entity);\n if (isRemovedComponent(message)) this._world.queryManager.removeComponent(message.data.entity, message.data.component);\n }\n /**\r\n * Adds an entity to be tracked by the EntityManager\r\n * @param entity\r\n */ addEntity(entity) {\n entity.active = true;\n entity.scene = this._world.context;\n if (entity && !this._entityIndex[entity.id]) {\n this._entityIndex[entity.id] = entity;\n this.entities.push(entity);\n this._world.queryManager.addEntity(entity);\n entity.componentAdded$.register(this);\n entity.componentRemoved$.register(this);\n // if entity has children\n entity.children.forEach((c)=>{\n c.scene = entity.scene;\n this.addEntity(c);\n });\n entity.childrenAdded$.register({\n notify: (e)=>{\n this.addEntity(e);\n }\n });\n entity.childrenRemoved$.register({\n notify: (e)=>{\n this.removeEntity(e, false);\n }\n });\n }\n }\n removeEntity(idOrEntity, deferred = true) {\n var _a;\n let id = 0;\n if (idOrEntity instanceof Entity) id = idOrEntity.id;\n else id = idOrEntity;\n const entity = this._entityIndex[id];\n if (entity && entity.active) entity.active = false;\n if (entity && deferred) {\n this._entitiesToRemove.push(entity);\n return;\n }\n delete this._entityIndex[id];\n if (entity) {\n entity.scene = null;\n removeItemFromArray(entity, this.entities);\n this._world.queryManager.removeEntity(entity);\n entity.componentAdded$.unregister(this);\n entity.componentRemoved$.unregister(this);\n // if entity has children\n entity.children.forEach((c)=>{\n c.scene = null;\n this.removeEntity(c, deferred);\n });\n entity.childrenAdded$.clear();\n entity.childrenRemoved$.clear();\n // stats\n if ((_a = this._world.context) === null || _a === void 0 ? void 0 : _a.engine) this._world.context.engine.stats.currFrame.actors.killed++;\n }\n }\n processEntityRemovals() {\n for (const entity of this._entitiesToRemove){\n if (entity.active) continue;\n this.removeEntity(entity, false);\n }\n this._entitiesToRemove.length = 0;\n }\n processComponentRemovals() {\n for (const entity of this.entities)entity.processComponentRemoval();\n }\n getById(id) {\n return this._entityIndex[id];\n }\n getByName(name) {\n return this.entities.filter((e)=>e.name === name);\n }\n clear() {\n for (const entity of this.entities)this.removeEntity(entity);\n }\n }\n const buildTypeKey = (types)=>{\n const key = [\n ...types\n ].sort((a, b)=>a.localeCompare(b)).join(\"+\");\n return key;\n };\n /**\r\n * Represents query for entities that match a list of types that is cached and observable\r\n *\r\n * Queries can be strongly typed by supplying a type union in the optional type parameter\r\n * ```typescript\r\n * const queryAB = new ex.Query(['A', 'B']);\r\n * ```\r\n */ class Query extends Observable {\n get key() {\n if (this._key) return this._key;\n return this._key = buildTypeKey(this.types);\n }\n constructor(types){\n super();\n this._entities = [];\n if (types[0] instanceof Function) this.types = types.map((T)=>(new T).type);\n else this.types = types;\n }\n /**\r\n * Returns a list of entities that match the query\r\n *\r\n * @param sort Optional sorting function to sort entities returned from the query\r\n */ getEntities(sort) {\n if (sort) this._entities.sort(sort);\n return this._entities;\n }\n /**\r\n * Add an entity to the query, will only be added if the entity matches the query types\r\n * @param entity\r\n */ addEntity(entity) {\n if (!contains(this._entities, entity) && this.matches(entity)) {\n this._entities.push(entity);\n this.notifyAll(new AddedEntity(entity));\n }\n }\n /**\r\n * If the entity is part of the query it will be removed regardless of types\r\n * @param entity\r\n */ removeEntity(entity) {\n if (removeItemFromArray(entity, this._entities)) this.notifyAll(new RemovedEntity(entity));\n }\n /**\r\n * Removes all entities and observers from the query\r\n */ clear() {\n this._entities.length = 0;\n for (const observer of this.observers)this.unregister(observer);\n }\n matches(typesOrEntity) {\n let types = [];\n if (typesOrEntity instanceof Entity) types = typesOrEntity.types;\n else types = typesOrEntity;\n let matches = true;\n for (const type of this.types){\n matches = matches && types.indexOf(type) > -1;\n if (!matches) return false;\n }\n return matches;\n }\n contain(type) {\n return this.types.indexOf(type) > -1;\n }\n }\n /**\r\n * The query manager is responsible for updating all queries when entities/components change\r\n */ class QueryManager {\n constructor(_world){\n this._world = _world;\n this._queries = {};\n }\n /**\r\n * Adds a query to the manager and populates with any entities that match\r\n * @param query\r\n */ _addQuery(query) {\n this._queries[buildTypeKey(query.types)] = query;\n for (const entity of this._world.entityManager.entities)query.addEntity(entity);\n }\n /**\r\n * Removes the query if there are no observers left\r\n * @param query\r\n */ maybeRemoveQuery(query) {\n if (query.observers.length === 0) {\n query.clear();\n delete this._queries[buildTypeKey(query.types)];\n }\n }\n /**\r\n * Adds the entity to any matching query in the query manage\r\n * @param entity\r\n */ addEntity(entity) {\n for(const queryType in this._queries)if (this._queries[queryType]) this._queries[queryType].addEntity(entity);\n }\n /**\r\n * Removes an entity from queries if the removed component disqualifies it\r\n * @param entity\r\n * @param component\r\n */ removeComponent(entity, component) {\n for(const queryType in this._queries)// If the component being removed from an entity is a part of a query,\n // it is now disqualified from that query, remove it\n if (this._queries[queryType].contain(component.type)) this._queries[queryType].removeEntity(entity);\n }\n /**\r\n * Removes an entity from all queries it is currently a part of\r\n * @param entity\r\n */ removeEntity(entity) {\n for(const queryType in this._queries)this._queries[queryType].removeEntity(entity);\n }\n /**\r\n * Creates a populated query and returns, if the query already exists that will be returned instead of a new instance\r\n * @param types\r\n */ createQuery(types) {\n const maybeExistingQuery = this.getQuery(types);\n if (maybeExistingQuery) return maybeExistingQuery;\n const query = new Query(types);\n this._addQuery(query);\n return query;\n }\n /**\r\n * Retrieves an existing query by types if it exists otherwise returns null\r\n * @param types\r\n */ getQuery(types) {\n const key = buildTypeKey(types);\n if (this._queries[key]) return this._queries[key];\n return null;\n }\n }\n /**\r\n * The SystemManager is responsible for keeping track of all systems in a scene.\r\n * Systems are scene specific\r\n */ class SystemManager {\n constructor(_world){\n this._world = _world;\n /**\r\n * List of systems, to add a new system call [[SystemManager.addSystem]]\r\n */ this.systems = [];\n this.initialized = false;\n }\n /**\r\n * Get a system registered in the manager by type\r\n * @param systemType\r\n */ get(systemType) {\n return this.systems.find((s)=>s instanceof systemType);\n }\n /**\r\n * Adds a system to the manager, it will now be updated every frame\r\n * @param system\r\n */ addSystem(system) {\n // validate system has types\n if (!system.types || system.types.length === 0) throw new Error(`Attempted to add a System without any types`);\n const query = this._world.queryManager.createQuery(system.types);\n this.systems.push(system);\n this.systems.sort((a, b)=>a.priority - b.priority);\n query.register(system);\n // If systems are added and the manager has already been init'd\n // then immediately init the system\n if (this.initialized && system.initialize) system.initialize(this._world.context);\n }\n /**\r\n * Removes a system from the manager, it will no longer be updated\r\n * @param system\r\n */ removeSystem(system) {\n removeItemFromArray(system, this.systems);\n const query = this._world.queryManager.getQuery(system.types);\n if (query) {\n query.unregister(system);\n this._world.queryManager.maybeRemoveQuery(query);\n }\n }\n /**\r\n * Initialize all systems in the manager\r\n *\r\n * Systems added after initialize() will be initialized on add\r\n */ initialize() {\n if (!this.initialized) {\n this.initialized = true;\n for (const s of this.systems)if (s.initialize) s.initialize(this._world.context);\n }\n }\n /**\r\n * Updates all systems\r\n * @param type whether this is an update or draw system\r\n * @param context context reference\r\n * @param delta time in milliseconds\r\n */ updateSystems(type, context, delta) {\n const systems = this.systems.filter((s)=>s.systemType === type);\n for (const s of systems)if (s.preupdate) s.preupdate(context, delta);\n for (const s of systems){\n // Get entities that match the system types, pre-sort\n const entities = this._world.queryManager.getQuery(s.types).getEntities(s.sort);\n // Initialize entities if needed\n if (context instanceof Scene) for (const entity of entities)entity._initialize(context === null || context === void 0 ? void 0 : context.engine);\n s.update(entities, delta);\n }\n for (const s of systems)if (s.postupdate) s.postupdate(context, delta);\n }\n clear() {\n for (const system of this.systems)this.removeSystem(system);\n }\n }\n /**\r\n * The World is a self-contained entity component system for a particular context.\r\n */ class World {\n /**\r\n * The context type is passed to the system updates\r\n * @param context\r\n */ constructor(context){\n this.context = context;\n this.queryManager = new QueryManager(this);\n this.entityManager = new EntityManager(this);\n this.systemManager = new SystemManager(this);\n }\n /**\r\n * Update systems by type and time elapsed in milliseconds\r\n */ update(type, delta) {\n if (type === SystemType.Update) this.entityManager.updateEntities(this.context, delta);\n this.systemManager.updateSystems(type, this.context, delta);\n this.entityManager.findEntitiesForRemoval();\n this.entityManager.processComponentRemovals();\n this.entityManager.processEntityRemovals();\n }\n add(entityOrSystem) {\n if (entityOrSystem instanceof Entity) this.entityManager.addEntity(entityOrSystem);\n if (entityOrSystem instanceof System) this.systemManager.addSystem(entityOrSystem);\n }\n remove(entityOrSystem, deferred = true) {\n if (entityOrSystem instanceof Entity) this.entityManager.removeEntity(entityOrSystem, deferred);\n if (entityOrSystem instanceof System) this.systemManager.removeSystem(entityOrSystem);\n }\n clearEntities() {\n this.entityManager.clear();\n }\n clearSystems() {\n this.systemManager.clear();\n }\n }\n class EulerIntegrator {\n static integrate(transform, motion, totalAcc, elapsedMs) {\n const seconds = elapsedMs / 1000;\n // This code looks a little wild, but it's to avoid creating any new Vector instances\n // integration is done in a tight loop so this is key to avoid GC'ing\n motion.vel.addEqual(totalAcc.scale(seconds, EulerIntegrator._ACC));\n transform.pos.add(motion.vel.scale(seconds, EulerIntegrator._VEL), EulerIntegrator._POS).addEqual(totalAcc.scale(0.5 * seconds * seconds, EulerIntegrator._VEL_ACC));\n motion.angularVelocity += motion.torque * (1.0 / motion.inertia) * seconds;\n const rotation = transform.rotation + motion.angularVelocity * seconds;\n transform.scale.add(motion.scaleFactor.scale(seconds, this._SCALE_FACTOR), EulerIntegrator._SCALE);\n const tx = transform.get();\n tx.setTransform(EulerIntegrator._POS, rotation, EulerIntegrator._SCALE);\n }\n }\n // Scratch vectors to avoid allocation\n EulerIntegrator._POS = new Vector(0, 0);\n EulerIntegrator._SCALE = new Vector(1, 1);\n EulerIntegrator._ACC = new Vector(0, 0);\n EulerIntegrator._VEL = new Vector(0, 0);\n EulerIntegrator._VEL_ACC = new Vector(0, 0);\n EulerIntegrator._SCALE_FACTOR = new Vector(0, 0);\n class MotionSystem extends System {\n constructor(){\n super(...arguments);\n this.types = [\n \"ex.transform\",\n \"ex.motion\"\n ];\n this.systemType = SystemType.Update;\n this.priority = -1;\n }\n update(entities, elapsedMs) {\n let transform;\n let motion;\n for(let i = 0; i < entities.length; i++){\n transform = entities[i].get(TransformComponent);\n motion = entities[i].get(MotionComponent);\n const optionalBody = entities[i].get(BodyComponent);\n if (optionalBody === null || optionalBody === void 0 ? void 0 : optionalBody.sleeping) continue;\n const totalAcc = motion.acc.clone();\n if ((optionalBody === null || optionalBody === void 0 ? void 0 : optionalBody.collisionType) === CollisionType.Active && (optionalBody === null || optionalBody === void 0 ? void 0 : optionalBody.useGravity)) totalAcc.addEqual(Physics.gravity);\n optionalBody === null || optionalBody === void 0 || optionalBody.captureOldTransform();\n // Update transform and motion based on Euler linear algebra\n EulerIntegrator.integrate(transform, motion, totalAcc, elapsedMs);\n }\n }\n }\n /**\r\n * ArcadeSolver is the default in Excalibur. It solves collisions so that there is no overlap between contacts,\r\n * and negates velocity along the collision normal.\r\n *\r\n * This is usually the type of collisions used for 2D games that don't need a more realistic collision simulation.\r\n *\r\n */ class ArcadeSolver {\n constructor(){\n this.directionMap = new Map();\n this.distanceMap = new Map();\n }\n solve(contacts) {\n // Events and init\n this.preSolve(contacts);\n // Remove any canceled contacts\n contacts = contacts.filter((c)=>!c.isCanceled());\n // Sort contacts by distance to avoid artifacts with seams\n // It's important to solve in a specific order\n contacts.sort((a, b)=>{\n const aDist = this.distanceMap.get(a.id);\n const bDist = this.distanceMap.get(b.id);\n return aDist - bDist;\n });\n for (const contact of contacts){\n // Solve position first in arcade\n this.solvePosition(contact);\n // Solve velocity second in arcade\n this.solveVelocity(contact);\n }\n // Events and any contact house-keeping the solver needs\n this.postSolve(contacts);\n return contacts;\n }\n preSolve(contacts) {\n const epsilon = .0001;\n for (const contact of contacts){\n if (Math.abs(contact.mtv.x) < epsilon && Math.abs(contact.mtv.y) < epsilon) {\n // Cancel near 0 mtv collisions\n contact.cancel();\n continue;\n }\n const side = Side.fromDirection(contact.mtv);\n const mtv = contact.mtv.negate();\n const distance = contact.colliderA.worldPos.squareDistance(contact.colliderB.worldPos);\n this.distanceMap.set(contact.id, distance);\n // Publish collision events on both participants\n contact.colliderA.events.emit(\"precollision\", new PreCollisionEvent(contact.colliderA, contact.colliderB, side, mtv));\n contact.colliderB.events.emit(\"precollision\", new PreCollisionEvent(contact.colliderB, contact.colliderA, Side.getOpposite(side), mtv.negate()));\n }\n }\n postSolve(contacts) {\n var _a, _b;\n for (const contact of contacts){\n if (contact.isCanceled()) continue;\n const colliderA = contact.colliderA;\n const colliderB = contact.colliderB;\n const bodyA = (_a = colliderA.owner) === null || _a === void 0 ? void 0 : _a.get(BodyComponent);\n const bodyB = (_b = colliderB.owner) === null || _b === void 0 ? void 0 : _b.get(BodyComponent);\n if (bodyA && bodyB) {\n if (bodyA.collisionType === CollisionType.Passive || bodyB.collisionType === CollisionType.Passive) continue;\n }\n const side = Side.fromDirection(contact.mtv);\n const mtv = contact.mtv.negate();\n // Publish collision events on both participants\n contact.colliderA.events.emit(\"postcollision\", new PostCollisionEvent(contact.colliderA, contact.colliderB, side, mtv));\n contact.colliderB.events.emit(\"postcollision\", new PostCollisionEvent(contact.colliderB, contact.colliderA, Side.getOpposite(side), mtv.negate()));\n }\n }\n solvePosition(contact) {\n var _a, _b;\n const epsilon = .0001;\n // if bounds no longer intersect skip to the next\n // this removes jitter from overlapping/stacked solid tiles or a wall of solid tiles\n if (!contact.colliderA.bounds.overlaps(contact.colliderB.bounds, epsilon)) {\n // Cancel the contact to prevent and solving\n contact.cancel();\n return;\n }\n if (Math.abs(contact.mtv.x) < epsilon && Math.abs(contact.mtv.y) < epsilon) {\n // Cancel near 0 mtv collisions\n contact.cancel();\n return;\n }\n let mtv = contact.mtv;\n const colliderA = contact.colliderA;\n const colliderB = contact.colliderB;\n const bodyA = (_a = colliderA.owner) === null || _a === void 0 ? void 0 : _a.get(BodyComponent);\n const bodyB = (_b = colliderB.owner) === null || _b === void 0 ? void 0 : _b.get(BodyComponent);\n if (bodyA && bodyB) {\n if (bodyA.collisionType === CollisionType.Passive || bodyB.collisionType === CollisionType.Passive) return;\n if (bodyA.collisionType === CollisionType.Active && bodyB.collisionType === CollisionType.Active) // split overlaps if both are Active\n mtv = mtv.scale(0.5);\n // Resolve overlaps\n if (bodyA.collisionType === CollisionType.Active) {\n bodyA.globalPos.x -= mtv.x;\n bodyA.globalPos.y -= mtv.y;\n colliderA.update(bodyA.transform.get());\n }\n if (bodyB.collisionType === CollisionType.Active) {\n bodyB.globalPos.x += mtv.x;\n bodyB.globalPos.y += mtv.y;\n colliderB.update(bodyB.transform.get());\n }\n }\n }\n solveVelocity(contact) {\n var _a, _b;\n if (contact.isCanceled()) return;\n const colliderA = contact.colliderA;\n const colliderB = contact.colliderB;\n const bodyA = (_a = colliderA.owner) === null || _a === void 0 ? void 0 : _a.get(BodyComponent);\n const bodyB = (_b = colliderB.owner) === null || _b === void 0 ? void 0 : _b.get(BodyComponent);\n if (bodyA && bodyB) {\n if (bodyA.collisionType === CollisionType.Passive || bodyB.collisionType === CollisionType.Passive) return;\n const normal = contact.normal;\n const opposite = normal.negate();\n if (bodyA.collisionType === CollisionType.Active) // only adjust velocity if the contact normal is opposite to the current velocity\n // this avoids catching edges on a platform when sliding off\n {\n if (bodyA.vel.normalize().dot(opposite) < 0) {\n // Cancel out velocity opposite direction of collision normal\n const velAdj = normal.scale(normal.dot(bodyA.vel.negate()));\n bodyA.vel = bodyA.vel.add(velAdj);\n }\n }\n if (bodyB.collisionType === CollisionType.Active) // only adjust velocity if the contact normal is opposite to the current velocity\n // this avoids catching edges on a platform\n {\n if (bodyB.vel.normalize().dot(normal) < 0) {\n const velAdj = opposite.scale(opposite.dot(bodyB.vel.negate()));\n bodyB.vel = bodyB.vel.add(velAdj);\n }\n }\n }\n }\n }\n /**\r\n * Holds information about contact points, meant to be reused over multiple frames of contact\r\n */ class ContactConstraintPoint {\n constructor(point, local, contact){\n this.point = point;\n this.local = local;\n this.contact = contact;\n /**\r\n * Impulse accumulated over time in normal direction\r\n */ this.normalImpulse = 0;\n /**\r\n * Impulse accumulated over time in the tangent direction\r\n */ this.tangentImpulse = 0;\n /**\r\n * Effective mass seen in the normal direction\r\n */ this.normalMass = 0;\n /**\r\n * Effective mass seen in the tangent direction\r\n */ this.tangentMass = 0;\n /**\r\n * Direction from center of mass of bodyA to contact point\r\n */ this.aToContact = new Vector(0, 0);\n /**\r\n * Direction from center of mass of bodyB to contact point\r\n */ this.bToContact = new Vector(0, 0);\n /**\r\n * Original contact velocity combined with bounciness\r\n */ this.originalVelocityAndRestitution = 0;\n this.update();\n }\n /**\r\n * Updates the contact information\r\n */ update() {\n var _a, _b;\n const bodyA = (_a = this.contact.colliderA.owner) === null || _a === void 0 ? void 0 : _a.get(BodyComponent);\n const bodyB = (_b = this.contact.colliderB.owner) === null || _b === void 0 ? void 0 : _b.get(BodyComponent);\n if (bodyA && bodyB) {\n const normal = this.contact.normal;\n const tangent = this.contact.tangent;\n this.aToContact = this.point.sub(bodyA.globalPos);\n this.bToContact = this.point.sub(bodyB.globalPos);\n const aToContactNormal = this.aToContact.cross(normal);\n const bToContactNormal = this.bToContact.cross(normal);\n this.normalMass = bodyA.inverseMass + bodyB.inverseMass + bodyA.inverseInertia * aToContactNormal * aToContactNormal + bodyB.inverseInertia * bToContactNormal * bToContactNormal;\n const aToContactTangent = this.aToContact.cross(tangent);\n const bToContactTangent = this.bToContact.cross(tangent);\n this.tangentMass = bodyA.inverseMass + bodyB.inverseMass + bodyA.inverseInertia * aToContactTangent * aToContactTangent + bodyB.inverseInertia * bToContactTangent * bToContactTangent;\n }\n return this;\n }\n /**\r\n * Returns the relative velocity between bodyA and bodyB\r\n */ getRelativeVelocity() {\n var _a, _b;\n const bodyA = (_a = this.contact.colliderA.owner) === null || _a === void 0 ? void 0 : _a.get(BodyComponent);\n const bodyB = (_b = this.contact.colliderB.owner) === null || _b === void 0 ? void 0 : _b.get(BodyComponent);\n if (bodyA && bodyB) {\n // Relative velocity in linear terms\n // Angular to linear velocity formula -> omega = velocity/radius so omega x radius = velocity\n const velA = bodyA.vel.add(Vector.cross(bodyA.angularVelocity, this.aToContact));\n const velB = bodyB.vel.add(Vector.cross(bodyB.angularVelocity, this.bToContact));\n return velB.sub(velA);\n }\n return Vector.Zero;\n }\n }\n class RealisticSolver {\n constructor(){\n this.lastFrameContacts = new Map();\n // map contact id to contact points\n this.idToContactConstraint = new Map();\n }\n getContactConstraints(id) {\n var _a;\n return (_a = this.idToContactConstraint.get(id)) !== null && _a !== void 0 ? _a : [];\n }\n solve(contacts) {\n // Events and init\n this.preSolve(contacts);\n // Remove any canceled contacts\n contacts = contacts.filter((c)=>!c.isCanceled());\n // Solve velocity first\n this.solveVelocity(contacts);\n // Solve position last because non-overlap is the most important\n this.solvePosition(contacts);\n // Events and any contact house-keeping the solver needs\n this.postSolve(contacts);\n return contacts;\n }\n preSolve(contacts) {\n var _a, _b, _c;\n const epsilon = .0001;\n for (const contact of contacts){\n if (Math.abs(contact.mtv.x) < epsilon && Math.abs(contact.mtv.y) < epsilon) {\n // Cancel near 0 mtv collisions\n contact.cancel();\n continue;\n }\n // Publish collision events on both participants\n const side = Side.fromDirection(contact.mtv);\n contact.colliderA.events.emit(\"precollision\", new PreCollisionEvent(contact.colliderA, contact.colliderB, side, contact.mtv));\n contact.colliderA.events.emit(\"beforecollisionresolve\", new CollisionPreSolveEvent(contact.colliderA, contact.colliderB, side, contact.mtv, contact));\n contact.colliderB.events.emit(\"precollision\", new PreCollisionEvent(contact.colliderB, contact.colliderA, Side.getOpposite(side), contact.mtv.negate()));\n contact.colliderB.events.emit(\"beforecollisionresolve\", new CollisionPreSolveEvent(contact.colliderB, contact.colliderA, Side.getOpposite(side), contact.mtv.negate(), contact));\n // Match awake state for sleeping\n contact.matchAwake();\n }\n // Keep track of contacts that done\n const finishedContactIds = Array.from(this.idToContactConstraint.keys());\n for (const contact of contacts){\n // Remove all current contacts that are not done\n const index = finishedContactIds.indexOf(contact.id);\n if (index > -1) finishedContactIds.splice(index, 1);\n const contactPoints = (_a = this.idToContactConstraint.get(contact.id)) !== null && _a !== void 0 ? _a : [];\n let pointIndex = 0;\n const bodyA = contact.colliderA.owner.get(BodyComponent);\n const bodyB = contact.colliderB.owner.get(BodyComponent);\n if (bodyA && bodyB) for (const point of contact.points){\n const normal = contact.normal;\n const tangent = contact.tangent;\n const aToContact = point.sub(bodyA.globalPos);\n const bToContact = point.sub(bodyB.globalPos);\n const aToContactNormal = aToContact.cross(normal);\n const bToContactNormal = bToContact.cross(normal);\n const normalMass = bodyA.inverseMass + bodyB.inverseMass + bodyA.inverseInertia * aToContactNormal * aToContactNormal + bodyB.inverseInertia * bToContactNormal * bToContactNormal;\n const aToContactTangent = aToContact.cross(tangent);\n const bToContactTangent = bToContact.cross(tangent);\n const tangentMass = bodyA.inverseMass + bodyB.inverseMass + bodyA.inverseInertia * aToContactTangent * aToContactTangent + bodyB.inverseInertia * bToContactTangent * bToContactTangent;\n // Preserve normal/tangent impulse by re-using the contact point if it's close\n if (contactPoints[pointIndex] && ((_c = (_b = contactPoints[pointIndex]) === null || _b === void 0 ? void 0 : _b.point) === null || _c === void 0 ? void 0 : _c.squareDistance(point)) < 4) {\n contactPoints[pointIndex].point = point;\n contactPoints[pointIndex].local = contact.localPoints[pointIndex];\n } else // new contact if it's not close or doesn't exist\n contactPoints[pointIndex] = new ContactConstraintPoint(point, contact.localPoints[pointIndex], contact);\n // Update contact point calculations\n contactPoints[pointIndex].aToContact = aToContact;\n contactPoints[pointIndex].bToContact = bToContact;\n contactPoints[pointIndex].normalMass = 1.0 / normalMass;\n contactPoints[pointIndex].tangentMass = 1.0 / tangentMass;\n // Calculate relative velocity before solving to accurately do restitution\n const restitution = bodyA.bounciness > bodyB.bounciness ? bodyA.bounciness : bodyB.bounciness;\n const relativeVelocity = contact.normal.dot(contactPoints[pointIndex].getRelativeVelocity());\n contactPoints[pointIndex].originalVelocityAndRestitution = 0;\n if (relativeVelocity < -0.1) contactPoints[pointIndex].originalVelocityAndRestitution = -restitution * relativeVelocity;\n pointIndex++;\n }\n this.idToContactConstraint.set(contact.id, contactPoints);\n }\n // Clean up any contacts that did not occur last frame\n for (const id of finishedContactIds)this.idToContactConstraint.delete(id);\n // Warm contacts with accumulated impulse\n // Useful for tall stacks\n if (Physics.warmStart) this.warmStart(contacts);\n else for (const contact of contacts){\n const contactPoints = this.getContactConstraints(contact.id);\n for (const point of contactPoints){\n point.normalImpulse = 0;\n point.tangentImpulse = 0;\n }\n }\n }\n postSolve(contacts) {\n for (const contact of contacts){\n const bodyA = contact.colliderA.owner.get(BodyComponent);\n const bodyB = contact.colliderB.owner.get(BodyComponent);\n if (bodyA && bodyB) {\n // Skip post solve for active+passive collisions\n if (bodyA.collisionType === CollisionType.Passive || bodyB.collisionType === CollisionType.Passive) continue;\n // Update motion values for sleeping\n bodyA.updateMotion();\n bodyB.updateMotion();\n }\n // Publish collision events on both participants\n const side = Side.fromDirection(contact.mtv);\n contact.colliderA.events.emit(\"postcollision\", new PostCollisionEvent(contact.colliderA, contact.colliderB, side, contact.mtv));\n contact.colliderA.events.emit(\"aftercollisionresolve\", new CollisionPostSolveEvent(contact.colliderA, contact.colliderB, side, contact.mtv, contact));\n contact.colliderB.events.emit(\"postcollision\", new PostCollisionEvent(contact.colliderB, contact.colliderA, Side.getOpposite(side), contact.mtv.negate()));\n contact.colliderB.events.emit(\"aftercollisionresolve\", new CollisionPostSolveEvent(contact.colliderB, contact.colliderA, Side.getOpposite(side), contact.mtv.negate(), contact));\n }\n // Store contacts\n this.lastFrameContacts.clear();\n for (const c of contacts)this.lastFrameContacts.set(c.id, c);\n }\n /**\r\n * Warm up body's based on previous frame contact points\r\n * @param contacts\r\n */ warmStart(contacts) {\n var _a, _b, _c;\n for (const contact of contacts){\n const bodyA = (_a = contact.colliderA.owner) === null || _a === void 0 ? void 0 : _a.get(BodyComponent);\n const bodyB = (_b = contact.colliderB.owner) === null || _b === void 0 ? void 0 : _b.get(BodyComponent);\n if (bodyA && bodyB) {\n const contactPoints = (_c = this.idToContactConstraint.get(contact.id)) !== null && _c !== void 0 ? _c : [];\n for (const point of contactPoints)if (Physics.warmStart) {\n const normalImpulse = contact.normal.scale(point.normalImpulse);\n const tangentImpulse = contact.tangent.scale(point.tangentImpulse);\n const impulse = normalImpulse.add(tangentImpulse);\n bodyA.applyImpulse(point.point, impulse.negate());\n bodyB.applyImpulse(point.point, impulse);\n } else {\n point.normalImpulse = 0;\n point.tangentImpulse = 0;\n }\n }\n }\n }\n /**\r\n * Iteratively solve the position overlap constraint\r\n * @param contacts\r\n */ solvePosition(contacts) {\n var _a, _b, _c;\n for(let i = 0; i < Physics.positionIterations; i++)for (const contact of contacts){\n const bodyA = (_a = contact.colliderA.owner) === null || _a === void 0 ? void 0 : _a.get(BodyComponent);\n const bodyB = (_b = contact.colliderB.owner) === null || _b === void 0 ? void 0 : _b.get(BodyComponent);\n if (bodyA && bodyB) {\n // Skip solving active+passive\n if (bodyA.collisionType === CollisionType.Passive || bodyB.collisionType === CollisionType.Passive) continue;\n const constraints = (_c = this.idToContactConstraint.get(contact.id)) !== null && _c !== void 0 ? _c : [];\n for (const point of constraints){\n const normal = contact.normal;\n const separation = CollisionJumpTable.FindContactSeparation(contact, point.local);\n const steeringConstant = Physics.steeringFactor; //0.2;\n const maxCorrection = -5;\n const slop = Physics.slop; //1;\n // Clamp to avoid over-correction\n // Remember that we are shooting for 0 overlap in the end\n const steeringForce = clamp(steeringConstant * (separation + slop), maxCorrection, 0);\n const impulse = normal.scale(-steeringForce * point.normalMass);\n // This is a pseudo impulse, meaning we aren't doing a real impulse calculation\n // We adjust position and rotation instead of doing the velocity\n if (bodyA.collisionType === CollisionType.Active) {\n // TODO make applyPseudoImpulse function?\n const impulseForce = impulse.negate().scale(bodyA.inverseMass);\n if (bodyA.limitDegreeOfFreedom.includes(DegreeOfFreedom.X)) impulseForce.x = 0;\n if (bodyA.limitDegreeOfFreedom.includes(DegreeOfFreedom.Y)) impulseForce.y = 0;\n bodyA.globalPos = bodyA.globalPos.add(impulseForce);\n if (!bodyA.limitDegreeOfFreedom.includes(DegreeOfFreedom.Rotation)) bodyA.rotation -= point.aToContact.cross(impulse) * bodyA.inverseInertia;\n }\n if (bodyB.collisionType === CollisionType.Active) {\n const impulseForce = impulse.scale(bodyB.inverseMass);\n if (bodyB.limitDegreeOfFreedom.includes(DegreeOfFreedom.X)) impulseForce.x = 0;\n if (bodyB.limitDegreeOfFreedom.includes(DegreeOfFreedom.Y)) impulseForce.y = 0;\n bodyB.globalPos = bodyB.globalPos.add(impulseForce);\n if (!bodyB.limitDegreeOfFreedom.includes(DegreeOfFreedom.Rotation)) bodyB.rotation += point.bToContact.cross(impulse) * bodyB.inverseInertia;\n }\n }\n }\n }\n }\n solveVelocity(contacts) {\n var _a, _b, _c;\n for(let i = 0; i < Physics.velocityIterations; i++)for (const contact of contacts){\n const bodyA = (_a = contact.colliderA.owner) === null || _a === void 0 ? void 0 : _a.get(BodyComponent);\n const bodyB = (_b = contact.colliderB.owner) === null || _b === void 0 ? void 0 : _b.get(BodyComponent);\n if (bodyA && bodyB) {\n // Skip solving active+passive\n if (bodyA.collisionType === CollisionType.Passive || bodyB.collisionType === CollisionType.Passive) continue;\n const friction = Math.min(bodyA.friction, bodyB.friction);\n const constraints = (_c = this.idToContactConstraint.get(contact.id)) !== null && _c !== void 0 ? _c : [];\n // Friction constraint\n for (const point of constraints){\n const relativeVelocity = point.getRelativeVelocity();\n // Negate velocity in tangent direction to simulate friction\n const tangentVelocity = -relativeVelocity.dot(contact.tangent);\n let impulseDelta = tangentVelocity * point.tangentMass;\n // Clamping based in Erin Catto's GDC 2006 talk\n // Correct clamping https://github.com/erincatto/box2d-lite/blob/master/docs/GDC2006_Catto_Erin_PhysicsTutorial.pdf\n // Accumulated fiction impulse is always between -uMaxFriction < dT < uMaxFriction\n // But deltas can vary\n const maxFriction = friction * point.normalImpulse;\n const newImpulse = clamp(point.tangentImpulse + impulseDelta, -maxFriction, maxFriction);\n impulseDelta = newImpulse - point.tangentImpulse;\n point.tangentImpulse = newImpulse;\n const impulse = contact.tangent.scale(impulseDelta);\n bodyA.applyImpulse(point.point, impulse.negate());\n bodyB.applyImpulse(point.point, impulse);\n }\n // Bounce constraint\n for (const point of constraints){\n // Need to recalc relative velocity because the previous step could have changed vel\n const relativeVelocity = point.getRelativeVelocity();\n // Compute impulse in normal direction\n const normalVelocity = relativeVelocity.dot(contact.normal);\n // Per Erin it is a mistake to apply the restitution inside the iteration\n // From Erin Catto's Box2D we keep original contact velocity and adjust by small impulses\n let impulseDelta = -point.normalMass * (normalVelocity - point.originalVelocityAndRestitution);\n // Clamping based in Erin Catto's GDC 2014 talk\n // Accumulated impulse stored in the contact is always positive (dV > 0)\n // But deltas can be negative\n const newImpulse = Math.max(point.normalImpulse + impulseDelta, 0);\n impulseDelta = newImpulse - point.normalImpulse;\n point.normalImpulse = newImpulse;\n const impulse = contact.normal.scale(impulseDelta);\n bodyA.applyImpulse(point.point, impulse.negate());\n bodyB.applyImpulse(point.point, impulse);\n }\n }\n }\n }\n }\n class CollisionSystem extends System {\n constructor(physics){\n super();\n this.types = [\n \"ex.transform\",\n \"ex.motion\",\n \"ex.collider\"\n ];\n this.systemType = SystemType.Update;\n this.priority = -1;\n this._realisticSolver = new RealisticSolver();\n this._arcadeSolver = new ArcadeSolver();\n this._lastFrameContacts = new Map();\n this._currentFrameContacts = new Map();\n this._processor = physics.collisionProcessor;\n this._trackCollider = (c)=>this._processor.track(c);\n this._untrackCollider = (c)=>this._processor.untrack(c);\n }\n notify(message) {\n if (isAddedSystemEntity(message)) {\n const colliderComponent = message.data.get(ColliderComponent);\n colliderComponent.$colliderAdded.subscribe(this._trackCollider);\n colliderComponent.$colliderRemoved.subscribe(this._untrackCollider);\n const collider = colliderComponent.get();\n if (collider) this._processor.track(collider);\n } else {\n const colliderComponent = message.data.get(ColliderComponent);\n const collider = colliderComponent.get();\n if (colliderComponent && collider) this._processor.untrack(collider);\n }\n }\n initialize(scene) {\n this._engine = scene.engine;\n }\n update(entities, elapsedMs) {\n var _a, _b, _c, _d;\n if (!Physics.enabled) return;\n // Collect up all the colliders and update them\n let colliders = [];\n for (const entity of entities){\n const colliderComp = entity.get(ColliderComponent);\n const collider = colliderComp === null || colliderComp === void 0 ? void 0 : colliderComp.get();\n if (colliderComp && ((_a = colliderComp.owner) === null || _a === void 0 ? void 0 : _a.active) && collider) {\n colliderComp.update();\n if (collider instanceof CompositeCollider) {\n const compositeColliders = collider.getColliders();\n colliders = colliders.concat(compositeColliders);\n } else colliders.push(collider);\n }\n }\n // Update the spatial partitioning data structures\n // TODO if collider invalid it will break the processor\n // TODO rename \"update\" to something more specific\n this._processor.update(colliders);\n // Run broadphase on all colliders and locates potential collisions\n const pairs = this._processor.broadphase(colliders, elapsedMs);\n this._currentFrameContacts.clear();\n // Given possible pairs find actual contacts\n let contacts = this._processor.narrowphase(pairs, (_d = (_c = (_b = this._engine) === null || _b === void 0 ? void 0 : _b.debug) === null || _c === void 0 ? void 0 : _c.stats) === null || _d === void 0 ? void 0 : _d.currFrame);\n const solver = this.getSolver();\n // Solve, this resolves the position/velocity so entities aren't overlapping\n contacts = solver.solve(contacts);\n // Record contacts for start/end\n for (const contact of contacts){\n // Process composite ids, things with the same composite id are treated as the same collider for start/end\n const index = contact.id.indexOf(\"|\");\n if (index > 0) {\n const compositeId = contact.id.substring(index + 1);\n this._currentFrameContacts.set(compositeId, contact);\n } else this._currentFrameContacts.set(contact.id, contact);\n }\n // Emit contact start/end events\n this.runContactStartEnd();\n // reset the last frame cache\n this._lastFrameContacts.clear();\n // Keep track of collisions contacts that have started or ended\n this._lastFrameContacts = new Map(this._currentFrameContacts);\n }\n getSolver() {\n return Physics.collisionResolutionStrategy === CollisionResolutionStrategy.Realistic ? this._realisticSolver : this._arcadeSolver;\n }\n debug(ex) {\n this._processor.debug(ex);\n }\n runContactStartEnd() {\n // Composite collider collisions may have a duplicate id because we want to treat those as a singular start/end\n for (const [id, c] of this._currentFrameContacts)// find all new contacts\n if (!this._lastFrameContacts.has(id)) {\n const colliderA = c.colliderA;\n const colliderB = c.colliderB;\n colliderA.events.emit(\"collisionstart\", new CollisionStartEvent(colliderA, colliderB, c));\n colliderA.events.emit(\"contactstart\", new ContactStartEvent(colliderA, colliderB, c));\n colliderB.events.emit(\"collisionstart\", new CollisionStartEvent(colliderB, colliderA, c));\n colliderB.events.emit(\"contactstart\", new ContactStartEvent(colliderB, colliderA, c));\n }\n // find all contacts that have ceased\n for (const [id, c] of this._lastFrameContacts)if (!this._currentFrameContacts.has(id)) {\n const colliderA = c.colliderA;\n const colliderB = c.colliderB;\n colliderA.events.emit(\"collisionend\", new CollisionEndEvent(colliderA, colliderB));\n colliderA.events.emit(\"contactend\", new ContactEndEvent(colliderA, colliderB));\n colliderB.events.emit(\"collisionend\", new CollisionEndEvent(colliderB, colliderA));\n colliderB.events.emit(\"contactend\", new ContactEndEvent(colliderB, colliderA));\n }\n }\n }\n var AnimationDirection;\n (function(AnimationDirection) {\n /**\r\n * Animation is playing forwards\r\n */ AnimationDirection[\"Forward\"] = \"forward\";\n /**\r\n * Animation is playing backwards\r\n */ AnimationDirection[\"Backward\"] = \"backward\";\n })(AnimationDirection || (AnimationDirection = {}));\n var AnimationStrategy;\n (function(AnimationStrategy) {\n /**\r\n * Animation ends without displaying anything\r\n */ AnimationStrategy[\"End\"] = \"end\";\n /**\r\n * Animation loops to the first frame after the last frame\r\n */ AnimationStrategy[\"Loop\"] = \"loop\";\n /**\r\n * Animation plays to the last frame, then backwards to the first frame, then repeats\r\n */ AnimationStrategy[\"PingPong\"] = \"pingpong\";\n /**\r\n * Animation ends stopping on the last frame\r\n */ AnimationStrategy[\"Freeze\"] = \"freeze\";\n })(AnimationStrategy || (AnimationStrategy = {}));\n const AnimationEvents = {\n Frame: \"frame\",\n Loop: \"loop\",\n Ended: \"ended\"\n };\n /**\r\n * Create an Animation given a list of [[Frame|frames]] in [[AnimationOptions]]\r\n *\r\n * To create an Animation from a [[SpriteSheet]], use [[Animation.fromSpriteSheet]]\r\n */ class Animation extends Graphic {\n constructor(options){\n var _a, _b;\n super(options);\n this.events = new EventEmitter();\n this.frames = [];\n this.strategy = AnimationStrategy.Loop;\n this.frameDuration = 100;\n this.timeScale = 1;\n this._idempotencyToken = -1;\n this._firstTick = true;\n this._currentFrame = 0;\n this._timeLeftInFrame = 0;\n this._pingPongDirection = 1;\n this._done = false;\n this._playing = true;\n this._reversed = false;\n this.frames = options.frames;\n this.strategy = (_a = options.strategy) !== null && _a !== void 0 ? _a : this.strategy;\n this.frameDuration = options.totalDuration ? options.totalDuration / this.frames.length : (_b = options.frameDuration) !== null && _b !== void 0 ? _b : this.frameDuration;\n if (options.reverse) this.reverse();\n this.goToFrame(0);\n }\n clone() {\n return new Animation({\n frames: this.frames.map((f)=>({\n ...f\n })),\n frameDuration: this.frameDuration,\n reverse: this._reversed,\n strategy: this.strategy,\n ...this.cloneGraphicOptions()\n });\n }\n get width() {\n const maybeFrame = this.currentFrame;\n if (maybeFrame) return Math.abs(maybeFrame.graphic.width * this.scale.x);\n return 0;\n }\n get height() {\n const maybeFrame = this.currentFrame;\n if (maybeFrame) return Math.abs(maybeFrame.graphic.height * this.scale.y);\n return 0;\n }\n /**\r\n * Create an Animation from a [[SpriteSheet]], a list of indices into the sprite sheet, a duration per frame\r\n * and optional [[AnimationStrategy]]\r\n *\r\n * Example:\r\n * ```typescript\r\n * const spriteSheet = SpriteSheet.fromImageSource({...});\r\n *\r\n * const anim = Animation.fromSpriteSheet(spriteSheet, range(0, 5), 200, AnimationStrategy.Loop);\r\n * ```\r\n *\r\n * @param spriteSheet\r\n * @param frameIndices\r\n * @param durationPerFrameMs\r\n * @param strategy\r\n */ static fromSpriteSheet(spriteSheet, frameIndices, durationPerFrameMs, strategy = AnimationStrategy.Loop) {\n const maxIndex = spriteSheet.sprites.length - 1;\n const invalidIndices = frameIndices.filter((index)=>index < 0 || index > maxIndex);\n if (invalidIndices.length) Animation._LOGGER.warn(`Indices into SpriteSheet were provided that don\\'t exist: ${invalidIndices.join(\",\")} no frame will be shown`);\n return new Animation({\n frames: spriteSheet.sprites.filter((_, index)=>frameIndices.indexOf(index) > -1).map((f)=>({\n graphic: f,\n duration: durationPerFrameMs\n })),\n strategy: strategy\n });\n }\n /**\r\n * Create an [[Animation]] from a [[SpriteSheet]] given a list of coordinates\r\n *\r\n * Example:\r\n * ```typescript\r\n * const spriteSheet = SpriteSheet.fromImageSource({...});\r\n *\r\n * const anim = Animation.fromSpriteSheetCoordinates({\r\n * spriteSheet,\r\n * frameCoordinates: [\r\n * {x: 0, y: 5, duration: 100},\r\n * {x: 1, y: 5, duration: 200},\r\n * {x: 2, y: 5, duration: 100},\r\n * {x: 3, y: 5, duration: 500}\r\n * ],\r\n * strategy: AnimationStrategy.PingPong\r\n * });\r\n * ```\r\n *\r\n * @param options\r\n * @returns Animation\r\n */ static fromSpriteSheetCoordinates(options) {\n const { spriteSheet: spriteSheet, frameCoordinates: frameCoordinates, durationPerFrameMs: durationPerFrameMs, strategy: strategy, reverse: reverse } = options;\n const defaultDuration = durationPerFrameMs !== null && durationPerFrameMs !== void 0 ? durationPerFrameMs : 100;\n const frames = [];\n for (const coord of frameCoordinates){\n const { x: x, y: y, duration: duration } = coord;\n const sprite = spriteSheet.getSprite(x, y);\n if (sprite) frames.push({\n graphic: sprite,\n duration: duration !== null && duration !== void 0 ? duration : defaultDuration\n });\n else Animation._LOGGER.warn(`Skipping frame! SpriteSheet does not have coordinate (${x}, ${y}), please check your SpriteSheet to confirm that sprite exists`);\n }\n return new Animation({\n frames: frames,\n strategy: strategy,\n reverse: reverse\n });\n }\n /**\r\n * Returns the current Frame of the animation\r\n *\r\n * Use [[Animation.currentFrameIndex]] to get the frame number and\r\n * [[Animation.goToFrame]] to set the current frame index\r\n */ get currentFrame() {\n if (this._currentFrame >= 0 && this._currentFrame < this.frames.length) return this.frames[this._currentFrame];\n return null;\n }\n /**\r\n * Returns the current frame index of the animation\r\n *\r\n * Use [[Animation.currentFrame]] to grab the current [[Frame]] object\r\n */ get currentFrameIndex() {\n return this._currentFrame;\n }\n /**\r\n * Returns `true` if the animation is playing\r\n */ get isPlaying() {\n return this._playing;\n }\n /**\r\n * Reverses the play direction of the Animation, this preserves the current frame\r\n */ reverse() {\n // Don't mutate with the original frame list, create a copy\n this.frames = this.frames.slice().reverse();\n this._reversed = !this._reversed;\n }\n /**\r\n * Returns the current play direction of the animation\r\n */ get direction() {\n // Keep logically consistent with ping-pong direction\n // If ping-pong is forward = 1 and reversed is true then we are logically reversed\n const reversed = this._reversed && this._pingPongDirection === 1 ? true : false;\n return reversed ? AnimationDirection.Backward : AnimationDirection.Forward;\n }\n /**\r\n * Plays or resumes the animation from the current frame\r\n */ play() {\n this._playing = true;\n }\n /**\r\n * Pauses the animation on the current frame\r\n */ pause() {\n this._playing = false;\n this._firstTick = true; // firstTick must be set to emit the proper frame event\n }\n /**\r\n * Reset the animation back to the beginning, including if the animation were done\r\n */ reset() {\n this._done = false;\n this._firstTick = true;\n this._currentFrame = 0;\n }\n /**\r\n * Returns `true` if the animation can end\r\n */ get canFinish() {\n switch(this.strategy){\n case AnimationStrategy.End:\n case AnimationStrategy.Freeze:\n return true;\n default:\n return false;\n }\n }\n /**\r\n * Returns `true` if the animation is done, for looping type animations\r\n * `ex.AnimationStrategy.PingPong` and `ex.AnimationStrategy.Loop` this will always return `false`\r\n *\r\n * See the `ex.Animation.canFinish()` method to know if an animation type can end\r\n */ get done() {\n return this._done;\n }\n /**\r\n * Jump the animation immediately to a specific frame if it exists\r\n * @param frameNumber\r\n */ goToFrame(frameNumber) {\n this._currentFrame = frameNumber;\n this._timeLeftInFrame = this.frameDuration;\n const maybeFrame = this.frames[this._currentFrame];\n if (maybeFrame && !this._done) {\n this._timeLeftInFrame = (maybeFrame === null || maybeFrame === void 0 ? void 0 : maybeFrame.duration) || this.frameDuration;\n this.events.emit(\"frame\", {\n ...maybeFrame,\n frameIndex: this.currentFrameIndex\n });\n }\n }\n _nextFrame() {\n const currentFrame = this._currentFrame;\n if (this._done) return currentFrame;\n let next = -1;\n switch(this.strategy){\n case AnimationStrategy.Loop:\n next = (currentFrame + 1) % this.frames.length;\n if (next === 0) this.events.emit(\"loop\", this);\n break;\n case AnimationStrategy.End:\n next = currentFrame + 1;\n if (next >= this.frames.length) {\n this._done = true;\n this._currentFrame = this.frames.length;\n this.events.emit(\"end\", this);\n }\n break;\n case AnimationStrategy.Freeze:\n next = clamp(currentFrame + 1, 0, this.frames.length - 1);\n if (next >= this.frames.length - 1) {\n this._done = true;\n this.events.emit(\"end\", this);\n }\n break;\n case AnimationStrategy.PingPong:\n if (currentFrame + this._pingPongDirection >= this.frames.length) {\n this._pingPongDirection = -1;\n this.events.emit(\"loop\", this);\n }\n if (currentFrame + this._pingPongDirection < 0) {\n this._pingPongDirection = 1;\n this.events.emit(\"loop\", this);\n }\n next = currentFrame + this._pingPongDirection % this.frames.length;\n break;\n }\n return next;\n }\n /**\r\n * Called internally by Excalibur to update the state of the animation potential update the current frame\r\n * @param elapsedMilliseconds Milliseconds elapsed\r\n * @param idempotencyToken Prevents double ticking in a frame by passing a unique token to the frame\r\n */ tick(elapsedMilliseconds, idempotencyToken = 0) {\n if (this._idempotencyToken === idempotencyToken) return;\n this._idempotencyToken = idempotencyToken;\n if (!this._playing) return;\n // if it's the first frame emit frame event\n if (this._firstTick) {\n this._firstTick = false;\n this.events.emit(\"frame\", {\n ...this.currentFrame,\n frameIndex: this.currentFrameIndex\n });\n }\n this._timeLeftInFrame -= elapsedMilliseconds * this.timeScale;\n if (this._timeLeftInFrame <= 0) this.goToFrame(this._nextFrame());\n }\n _drawImage(ctx, x, y) {\n if (this.currentFrame) this.currentFrame.graphic.draw(ctx, x, y);\n }\n }\n Animation._LOGGER = Logger.getInstance();\n class GraphicsGroup extends Graphic {\n constructor(options){\n super(options);\n this.members = [];\n this.members = options.members;\n this._updateDimensions();\n }\n clone() {\n return new GraphicsGroup({\n members: [\n ...this.members\n ],\n ...this.cloneGraphicOptions()\n });\n }\n _updateDimensions() {\n let bb = new BoundingBox();\n for (const { graphic: graphic, pos: pos } of this.members)bb = graphic.localBounds.translate(pos).combine(bb);\n this.width = bb.width;\n this.height = bb.height;\n return bb;\n }\n get localBounds() {\n let bb = new BoundingBox();\n for (const { graphic: graphic, pos: pos } of this.members)bb = graphic.localBounds.translate(pos).combine(bb);\n return bb;\n }\n _isAnimationOrGroup(graphic) {\n return graphic instanceof Animation || graphic instanceof GraphicsGroup;\n }\n tick(elapsedMilliseconds, idempotencyToken) {\n for (const member of this.members){\n const maybeAnimation = member.graphic;\n if (this._isAnimationOrGroup(maybeAnimation)) maybeAnimation.tick(elapsedMilliseconds, idempotencyToken);\n }\n }\n reset() {\n for (const member of this.members){\n const maybeAnimation = member.graphic;\n if (this._isAnimationOrGroup(maybeAnimation)) maybeAnimation.reset();\n }\n }\n _preDraw(ex, x, y) {\n this._updateDimensions();\n super._preDraw(ex, x, y);\n }\n _drawImage(ex, x, y) {\n for (const member of this.members){\n ex.save();\n ex.translate(x, y);\n member.graphic.draw(ex, member.pos.x, member.pos.y);\n if (this.showDebug) /* istanbul ignore next */ ex.debug.drawRect(0, 0, this.width, this.height);\n ex.restore();\n }\n }\n }\n /**\r\n * Configurable helper extends base type and makes all properties available as option bag arguments\r\n * @internal\r\n * @param base\r\n */ function Configurable(base) {\n return class extends base {\n assign(props) {\n //set the value of every property that was passed in,\n //if the constructor previously set this value, it will be overridden here\n for(const k in props)// eslint-disable-next-line\n if (typeof this[k] !== \"function\") // eslint-disable-next-line\n this[k] = props[k];\n }\n constructor(...args){\n super(...args);\n //get the number of arguments that aren't undefined. TS passes a value to all parameters\n //of whatever ctor is the implementation, so args.length doesn't work here.\n const size = args.filter(function(value) {\n return value !== undefined;\n }).length;\n if (size === 1 && args[0] && typeof args[0] === \"object\" && !(args[0] instanceof Array)) this.assign(args[0]);\n }\n };\n }\n /**\r\n * An enum that represents the types of emitter nozzles\r\n */ var EmitterType;\n (function(EmitterType) {\n /**\r\n * Constant for the circular emitter type\r\n */ EmitterType[EmitterType[\"Circle\"] = 0] = \"Circle\";\n /**\r\n * Constant for the rectangular emitter type\r\n */ EmitterType[EmitterType[\"Rectangle\"] = 1] = \"Rectangle\";\n })(EmitterType || (EmitterType = {}));\n /**\r\n * @hidden\r\n */ class ParticleImpl extends Entity {\n constructor(emitterOrConfig, life, opacity, beginColor, endColor, position, velocity, acceleration, startSize, endSize){\n super();\n this.position = new Vector(0, 0);\n this.velocity = new Vector(0, 0);\n this.acceleration = new Vector(0, 0);\n this.particleRotationalVelocity = 0;\n this.currentRotation = 0;\n this.focus = null;\n this.focusAccel = 0;\n this.opacity = 1;\n this.beginColor = Color.White;\n this.endColor = Color.White;\n // Life is counted in ms\n this.life = 300;\n this.fadeFlag = false;\n // Color transitions\n this._rRate = 1;\n this._gRate = 1;\n this._bRate = 1;\n this._aRate = 0;\n this._currentColor = Color.White;\n this.emitter = null;\n this.particleSize = 5;\n this.particleSprite = null;\n this.sizeRate = 0;\n this.elapsedMultiplier = 0;\n this.visible = true;\n this.isOffscreen = false;\n let emitter = emitterOrConfig;\n if (emitter && !(emitterOrConfig instanceof ParticleEmitter)) {\n const config = emitterOrConfig;\n emitter = config.emitter;\n life = config.life;\n opacity = config.opacity;\n endColor = config.endColor;\n beginColor = config.beginColor;\n position = config.position;\n velocity = config.velocity;\n acceleration = config.acceleration;\n startSize = config.startSize;\n endSize = config.endSize;\n }\n this.emitter = emitter;\n this.life = life || this.life;\n this.opacity = opacity || this.opacity;\n this.endColor = endColor || this.endColor.clone();\n this.beginColor = beginColor || this.beginColor.clone();\n this._currentColor = this.beginColor.clone();\n if (this.emitter.particleTransform === ParticleTransform.Global) {\n const globalPos = this.emitter.transform.globalPos;\n this.position = (position || this.position).add(globalPos);\n this.velocity = (velocity || this.velocity).rotate(this.emitter.transform.globalRotation);\n } else {\n this.velocity = velocity || this.velocity;\n this.position = position || this.position;\n }\n this.acceleration = acceleration || this.acceleration;\n this._rRate = (this.endColor.r - this.beginColor.r) / this.life;\n this._gRate = (this.endColor.g - this.beginColor.g) / this.life;\n this._bRate = (this.endColor.b - this.beginColor.b) / this.life;\n this._aRate = this.opacity / this.life;\n this.startSize = startSize || 0;\n this.endSize = endSize || 0;\n if (this.endSize > 0 && this.startSize > 0) {\n this.sizeRate = (this.endSize - this.startSize) / this.life;\n this.particleSize = this.startSize;\n }\n this.addComponent(this.transform = new TransformComponent());\n this.addComponent(this.graphics = new GraphicsComponent());\n this.transform.pos = this.position;\n this.transform.rotation = this.currentRotation;\n this.transform.scale = vec(1, 1); // TODO wut\n if (this.particleSprite) {\n this.graphics.opacity = this.opacity;\n this.graphics.use(this.particleSprite);\n } else {\n this.graphics.localBounds = BoundingBox.fromDimension(this.particleSize, this.particleSize, Vector.Half);\n this.graphics.onPostDraw = (ctx)=>{\n ctx.save();\n this.graphics.opacity = this.opacity;\n const tmpColor = this._currentColor.clone();\n tmpColor.a = 1;\n ctx.debug.drawPoint(vec(0, 0), {\n color: tmpColor,\n size: this.particleSize\n });\n ctx.restore();\n };\n }\n }\n kill() {\n this.emitter.removeParticle(this);\n }\n update(_engine, delta) {\n this.life = this.life - delta;\n this.elapsedMultiplier = this.elapsedMultiplier + delta;\n if (this.life < 0) this.kill();\n if (this.fadeFlag) this.opacity = clamp(this._aRate * this.life, 0.0001, 1);\n if (this.startSize > 0 && this.endSize > 0) this.particleSize = clamp(this.sizeRate * delta + this.particleSize, Math.min(this.startSize, this.endSize), Math.max(this.startSize, this.endSize));\n this._currentColor.r = clamp(this._currentColor.r + this._rRate * delta, 0, 255);\n this._currentColor.g = clamp(this._currentColor.g + this._gRate * delta, 0, 255);\n this._currentColor.b = clamp(this._currentColor.b + this._bRate * delta, 0, 255);\n this._currentColor.a = clamp(this.opacity, 0.0001, 1);\n if (this.focus) {\n const accel = this.focus.sub(this.position).normalize().scale(this.focusAccel).scale(delta / 1000);\n this.velocity = this.velocity.add(accel);\n } else this.velocity = this.velocity.add(this.acceleration.scale(delta / 1000));\n this.position = this.position.add(this.velocity.scale(delta / 1000));\n if (this.particleRotationalVelocity) this.currentRotation = (this.currentRotation + this.particleRotationalVelocity * delta / 1000) % (2 * Math.PI);\n this.transform.pos = this.position;\n this.transform.rotation = this.currentRotation;\n this.transform.scale = vec(1, 1); // todo wut\n this.graphics.opacity = this.opacity;\n }\n }\n /**\r\n * Particle is used in a [[ParticleEmitter]]\r\n */ class Particle extends Configurable(ParticleImpl) {\n constructor(emitterOrConfig, life, opacity, beginColor, endColor, position, velocity, acceleration, startSize, endSize){\n super(emitterOrConfig, life, opacity, beginColor, endColor, position, velocity, acceleration, startSize, endSize);\n }\n }\n var ParticleTransform;\n (function(ParticleTransform) {\n /**\r\n * [[ParticleTransform.Global]] is the default and emits particles as if\r\n * they were world space objects, useful for most effects.\r\n */ ParticleTransform[\"Global\"] = \"global\";\n /**\r\n * [[ParticleTransform.Local]] particles are children of the emitter and move relative to the emitter\r\n * as they would in a parent/child actor relationship.\r\n */ ParticleTransform[\"Local\"] = \"local\";\n })(ParticleTransform || (ParticleTransform = {}));\n /**\r\n * Using a particle emitter is a great way to create interesting effects\r\n * in your game, like smoke, fire, water, explosions, etc. `ParticleEmitter`\r\n * extend [[Actor]] allowing you to use all of the features that come with.\r\n */ class ParticleEmitter extends Actor {\n /**\r\n * Gets the opacity of each particle from 0 to 1.0\r\n */ get opacity() {\n return super.graphics.opacity;\n }\n /**\r\n * Gets the opacity of each particle from 0 to 1.0\r\n */ set opacity(opacity) {\n super.graphics.opacity = opacity;\n }\n /**\r\n * Gets or sets the sprite that a particle should use\r\n */ get particleSprite() {\n return this._sprite;\n }\n set particleSprite(val) {\n if (val) this._sprite = val;\n }\n /**\r\n * @param config particle emitter options bag\r\n */ constructor(config){\n var _a, _b;\n super({\n width: (_a = config.width) !== null && _a !== void 0 ? _a : 0,\n height: (_b = config.height) !== null && _b !== void 0 ? _b : 0\n });\n this._particlesToEmit = 0;\n this.numParticles = 0;\n /**\r\n * Gets or sets the isEmitting flag\r\n */ this.isEmitting = true;\n /**\r\n * Gets or sets the backing particle collection\r\n */ this.particles = [];\n /**\r\n * Gets or sets the backing deadParticle collection\r\n */ this.deadParticles = [];\n /**\r\n * Gets or sets the minimum particle velocity\r\n */ this.minVel = 0;\n /**\r\n * Gets or sets the maximum particle velocity\r\n */ this.maxVel = 0;\n /**\r\n * Gets or sets the acceleration vector for all particles\r\n */ this.acceleration = new Vector(0, 0);\n /**\r\n * Gets or sets the minimum angle in radians\r\n */ this.minAngle = 0;\n /**\r\n * Gets or sets the maximum angle in radians\r\n */ this.maxAngle = 0;\n /**\r\n * Gets or sets the emission rate for particles (particles/sec)\r\n */ this.emitRate = 1; //particles/sec\n /**\r\n * Gets or sets the life of each particle in milliseconds\r\n */ this.particleLife = 2000;\n /**\r\n * Gets or sets the fade flag which causes particles to gradually fade out over the course of their life.\r\n */ this.fadeFlag = false;\n /**\r\n * Gets or sets the optional focus where all particles should accelerate towards\r\n */ this.focus = null;\n /**\r\n * Gets or sets the acceleration for focusing particles if a focus has been specified\r\n */ this.focusAccel = null;\n /**\r\n * Gets or sets the optional starting size for the particles\r\n */ this.startSize = null;\n /**\r\n * Gets or sets the optional ending size for the particles\r\n */ this.endSize = null;\n /**\r\n * Gets or sets the minimum size of all particles\r\n */ this.minSize = 5;\n /**\r\n * Gets or sets the maximum size of all particles\r\n */ this.maxSize = 5;\n /**\r\n * Gets or sets the beginning color of all particles\r\n */ this.beginColor = Color.White;\n /**\r\n * Gets or sets the ending color of all particles\r\n */ this.endColor = Color.White;\n this._sprite = null;\n /**\r\n * Gets or sets the emitter type for the particle emitter\r\n */ this.emitterType = EmitterType.Rectangle;\n /**\r\n * Gets or sets the emitter radius, only takes effect when the [[emitterType]] is [[EmitterType.Circle]]\r\n */ this.radius = 0;\n /**\r\n * Gets or sets the particle rotational speed velocity\r\n */ this.particleRotationalVelocity = 0;\n /**\r\n * Indicates whether particles should start with a random rotation\r\n */ this.randomRotation = false;\n /**\r\n * Gets or sets the emitted particle transform style, [[ParticleTransform.Global]] is the default and emits particles as if\r\n * they were world space objects, useful for most effects.\r\n *\r\n * If set to [[ParticleTransform.Local]] particles are children of the emitter and move relative to the emitter\r\n * as they would in a parent/child actor relationship.\r\n */ this.particleTransform = ParticleTransform.Global;\n const { x: x, y: y, pos: pos, isEmitting: isEmitting, minVel: minVel, maxVel: maxVel, acceleration: acceleration, minAngle: minAngle, maxAngle: maxAngle, emitRate: emitRate, particleLife: particleLife, opacity: opacity, fadeFlag: fadeFlag, focus: focus, focusAccel: focusAccel, startSize: startSize, endSize: endSize, minSize: minSize, maxSize: maxSize, beginColor: beginColor, endColor: endColor, particleSprite: particleSprite, emitterType: emitterType, radius: radius, particleRotationalVelocity: particleRotationalVelocity, particleTransform: particleTransform, randomRotation: randomRotation, random: random } = {\n ...config\n };\n this.pos = pos !== null && pos !== void 0 ? pos : vec(x !== null && x !== void 0 ? x : 0, y !== null && y !== void 0 ? y : 0);\n this.isEmitting = isEmitting !== null && isEmitting !== void 0 ? isEmitting : this.isEmitting;\n this.minVel = minVel !== null && minVel !== void 0 ? minVel : this.minVel;\n this.maxVel = maxVel !== null && maxVel !== void 0 ? maxVel : this.maxVel;\n this.acceleration = acceleration !== null && acceleration !== void 0 ? acceleration : this.acceleration;\n this.minAngle = minAngle !== null && minAngle !== void 0 ? minAngle : this.minAngle;\n this.maxAngle = maxAngle !== null && maxAngle !== void 0 ? maxAngle : this.maxAngle;\n this.emitRate = emitRate !== null && emitRate !== void 0 ? emitRate : this.emitRate;\n this.particleLife = particleLife !== null && particleLife !== void 0 ? particleLife : this.particleLife;\n this.opacity = opacity !== null && opacity !== void 0 ? opacity : this.opacity;\n this.fadeFlag = fadeFlag !== null && fadeFlag !== void 0 ? fadeFlag : this.fadeFlag;\n this.focus = focus !== null && focus !== void 0 ? focus : this.focus;\n this.focusAccel = focusAccel !== null && focusAccel !== void 0 ? focusAccel : this.focusAccel;\n this.startSize = startSize !== null && startSize !== void 0 ? startSize : this.startSize;\n this.endSize = endSize !== null && endSize !== void 0 ? endSize : this.endSize;\n this.minSize = minSize !== null && minSize !== void 0 ? minSize : this.minSize;\n this.maxSize = maxSize !== null && maxSize !== void 0 ? maxSize : this.maxSize;\n this.beginColor = beginColor !== null && beginColor !== void 0 ? beginColor : this.beginColor;\n this.endColor = endColor !== null && endColor !== void 0 ? endColor : this.endColor;\n this.particleSprite = particleSprite !== null && particleSprite !== void 0 ? particleSprite : this.particleSprite;\n this.emitterType = emitterType !== null && emitterType !== void 0 ? emitterType : this.emitterType;\n this.radius = radius !== null && radius !== void 0 ? radius : this.radius;\n this.particleRotationalVelocity = particleRotationalVelocity !== null && particleRotationalVelocity !== void 0 ? particleRotationalVelocity : this.particleRotationalVelocity;\n this.randomRotation = randomRotation !== null && randomRotation !== void 0 ? randomRotation : this.randomRotation;\n this.particleTransform = particleTransform !== null && particleTransform !== void 0 ? particleTransform : this.particleTransform;\n this.body.collisionType = CollisionType.PreventCollision;\n this.random = random !== null && random !== void 0 ? random : new Random();\n }\n removeParticle(particle) {\n this.deadParticles.push(particle);\n }\n /**\r\n * Causes the emitter to emit particles\r\n * @param particleCount Number of particles to emit right now\r\n */ emitParticles(particleCount) {\n var _a;\n for(let i = 0; i < particleCount; i++){\n const p = this._createParticle();\n this.particles.push(p);\n if ((_a = this === null || this === void 0 ? void 0 : this.scene) === null || _a === void 0 ? void 0 : _a.world) {\n if (this.particleTransform === ParticleTransform.Global) this.scene.world.add(p);\n else this.addChild(p);\n }\n }\n }\n clearParticles() {\n this.particles.length = 0;\n }\n // Creates a new particle given the constraints of the emitter\n _createParticle() {\n // todo implement emitter constraints;\n let ranX = 0;\n let ranY = 0;\n const angle = randomInRange(this.minAngle, this.maxAngle, this.random);\n const vel = randomInRange(this.minVel, this.maxVel, this.random);\n const size = this.startSize || randomInRange(this.minSize, this.maxSize, this.random);\n const dx = vel * Math.cos(angle);\n const dy = vel * Math.sin(angle);\n if (this.emitterType === EmitterType.Rectangle) {\n ranX = randomInRange(0, this.width, this.random);\n ranY = randomInRange(0, this.height, this.random);\n } else if (this.emitterType === EmitterType.Circle) {\n const radius = randomInRange(0, this.radius, this.random);\n ranX = radius * Math.cos(angle);\n ranY = radius * Math.sin(angle);\n }\n const p = new Particle(this, this.particleLife, this.opacity, this.beginColor, this.endColor, new Vector(ranX, ranY), new Vector(dx, dy), this.acceleration, this.startSize, this.endSize);\n p.fadeFlag = this.fadeFlag;\n p.particleSize = size;\n if (this.particleSprite) {\n p.particleSprite = this.particleSprite;\n p.graphics.opacity = this.opacity;\n p.graphics.use(this._sprite);\n }\n p.particleRotationalVelocity = this.particleRotationalVelocity;\n if (this.randomRotation) p.currentRotation = randomInRange(0, Math.PI * 2, this.random);\n if (this.focus) {\n p.focus = this.focus.add(new Vector(this.pos.x, this.pos.y));\n p.focusAccel = this.focusAccel;\n }\n return p;\n }\n update(engine, delta) {\n var _a;\n super.update(engine, delta);\n if (this.isEmitting) {\n this._particlesToEmit += this.emitRate * (delta / 1000);\n if (this._particlesToEmit > 1.0) {\n this.emitParticles(Math.floor(this._particlesToEmit));\n this._particlesToEmit = this._particlesToEmit - Math.floor(this._particlesToEmit);\n }\n }\n // deferred removal\n for(let i = 0; i < this.deadParticles.length; i++){\n removeItemFromArray(this.deadParticles[i], this.particles);\n if ((_a = this === null || this === void 0 ? void 0 : this.scene) === null || _a === void 0 ? void 0 : _a.world) this.scene.world.remove(this.deadParticles[i], false);\n }\n this.deadParticles.length = 0;\n }\n }\n class GraphicsSystem extends System {\n constructor(){\n super(...arguments);\n this.types = [\n \"ex.transform\",\n \"ex.graphics\"\n ];\n this.systemType = SystemType.Draw;\n this.priority = 0;\n this._token = 0;\n this._sortedTransforms = [];\n this._zHasChanged = false;\n this._zIndexUpdate = ()=>{\n this._zHasChanged = true;\n };\n }\n get sortedTransforms() {\n return this._sortedTransforms;\n }\n initialize(scene) {\n this._camera = scene.camera;\n this._engine = scene.engine;\n }\n preupdate() {\n // Graphics context could be switched to fallback in a new frame\n this._graphicsContext = this._engine.graphicsContext;\n if (this._zHasChanged) {\n this._sortedTransforms.sort((a, b)=>{\n return a.z - b.z;\n });\n this._zHasChanged = false;\n }\n }\n notify(entityAddedOrRemoved) {\n if (isAddedSystemEntity(entityAddedOrRemoved)) {\n const tx = entityAddedOrRemoved.data.get(TransformComponent);\n this._sortedTransforms.push(tx);\n tx.zIndexChanged$.subscribe(this._zIndexUpdate);\n this._zHasChanged = true;\n } else {\n const tx = entityAddedOrRemoved.data.get(TransformComponent);\n tx.zIndexChanged$.unsubscribe(this._zIndexUpdate);\n const index = this._sortedTransforms.indexOf(tx);\n if (index > -1) this._sortedTransforms.splice(index, 1);\n }\n }\n update(_entities, delta) {\n this._token++;\n let graphics;\n FontCache.checkAndClearCache();\n // This is a performance enhancement, most things are in world space\n // so if we can only do this once saves a ton of transform updates\n this._graphicsContext.save();\n if (this._camera) this._camera.draw(this._graphicsContext);\n for (const transform of this._sortedTransforms){\n const entity = transform.owner;\n // If the entity is offscreen skip\n if (entity.hasTag(\"ex.offscreen\")) continue;\n graphics = entity.get(GraphicsComponent);\n // Exit if graphics set to not visible\n if (!graphics.visible) continue;\n // This optionally sets our camera based on the entity coord plan (world vs. screen)\n if (transform.coordPlane === CoordPlane.Screen) this._graphicsContext.restore();\n this._graphicsContext.save();\n if (transform.coordPlane === CoordPlane.Screen) this._graphicsContext.translate(this._engine.screen.contentArea.left, this._engine.screen.contentArea.top);\n // Tick any graphics state (but only once) for animations and graphics groups\n graphics.update(delta, this._token);\n // Apply parallax\n const parallax = entity.get(ParallaxComponent);\n if (parallax) {\n // We use the Tiled formula\n // https://doc.mapeditor.org/en/latest/manual/layers/#parallax-scrolling-factor\n // cameraPos * (1 - parallaxFactor)\n const oneMinusFactor = Vector.One.sub(parallax.parallaxFactor);\n const parallaxOffset = this._camera.pos.scale(oneMinusFactor);\n this._graphicsContext.translate(parallaxOffset.x, parallaxOffset.y);\n }\n // Position the entity + estimate lag\n this._applyTransform(entity);\n // If there is a material enable it on the context\n if (graphics.material) this._graphicsContext.material = graphics.material;\n // Optionally run the onPreDraw graphics lifecycle draw\n if (graphics.onPreDraw) graphics.onPreDraw(this._graphicsContext, delta);\n // TODO remove this hack on the particle redo\n const particleOpacity = entity instanceof Particle ? entity.opacity : 1;\n this._graphicsContext.opacity *= graphics.opacity * particleOpacity;\n // Draw the graphics component\n this._drawGraphicsComponent(graphics);\n // Optionally run the onPostDraw graphics lifecycle draw\n if (graphics.onPostDraw) graphics.onPostDraw(this._graphicsContext, delta);\n this._graphicsContext.restore();\n // Reset the transform back to the original world space\n if (transform.coordPlane === CoordPlane.Screen) {\n this._graphicsContext.save();\n if (this._camera) this._camera.draw(this._graphicsContext);\n }\n }\n this._graphicsContext.restore();\n }\n _drawGraphicsComponent(graphicsComponent) {\n var _a, _b;\n if (graphicsComponent.visible) {\n const flipHorizontal = graphicsComponent.flipHorizontal;\n const flipVertical = graphicsComponent.flipVertical;\n for (const layer of graphicsComponent.layers.get())for (const { graphic: graphic, options: options } of layer.graphics){\n let anchor = graphicsComponent.anchor;\n let offset = graphicsComponent.offset;\n // handle layer specific overrides\n if (options === null || options === void 0 ? void 0 : options.anchor) anchor = options.anchor;\n if (options === null || options === void 0 ? void 0 : options.offset) offset = options.offset;\n // See https://github.com/excaliburjs/Excalibur/pull/619 for discussion on this formula\n const offsetX = -graphic.width * anchor.x + offset.x;\n const offsetY = -graphic.height * anchor.y + offset.y;\n const oldFlipHorizontal = graphic.flipHorizontal;\n const oldFlipVertical = graphic.flipVertical;\n if (flipHorizontal || flipVertical) {\n // flip any currently flipped graphics\n graphic.flipHorizontal = flipHorizontal ? !oldFlipHorizontal : oldFlipHorizontal;\n graphic.flipVertical = flipVertical ? !oldFlipVertical : oldFlipVertical;\n }\n graphic === null || graphic === void 0 || graphic.draw(this._graphicsContext, offsetX + layer.offset.x, offsetY + layer.offset.y);\n if (flipHorizontal || flipVertical) {\n graphic.flipHorizontal = oldFlipHorizontal;\n graphic.flipVertical = oldFlipVertical;\n }\n if (((_a = this._engine) === null || _a === void 0 ? void 0 : _a.isDebug) && this._engine.debug.graphics.showBounds) {\n const offset = vec(offsetX + layer.offset.x, offsetY + layer.offset.y);\n if (graphic instanceof GraphicsGroup) for (const g of graphic.members)(_b = g.graphic) === null || _b === void 0 || _b.localBounds.translate(offset.add(g.pos)).draw(this._graphicsContext, this._engine.debug.graphics.boundsColor);\n else /* istanbul ignore next */ graphic === null || graphic === void 0 || graphic.localBounds.translate(offset).draw(this._graphicsContext, this._engine.debug.graphics.boundsColor);\n }\n }\n }\n }\n /**\r\n * This applies the current entity transform to the graphics context\r\n * @param entity\r\n */ _applyTransform(entity) {\n const ancestors = entity.getAncestors();\n for (const ancestor of ancestors){\n const transform = ancestor === null || ancestor === void 0 ? void 0 : ancestor.get(TransformComponent);\n const optionalBody = ancestor === null || ancestor === void 0 ? void 0 : ancestor.get(BodyComponent);\n let interpolatedPos = transform.pos;\n let interpolatedScale = transform.scale;\n let interpolatedRotation = transform.rotation;\n if (optionalBody) {\n if (this._engine.fixedUpdateFps && optionalBody.__oldTransformCaptured && optionalBody.enableFixedUpdateInterpolate) {\n // Interpolate graphics if needed\n const blend = this._engine.currentFrameLagMs / (1000 / this._engine.fixedUpdateFps);\n interpolatedPos = transform.pos.scale(blend).add(optionalBody.oldPos.scale(1.0 - blend));\n interpolatedScale = transform.scale.scale(blend).add(optionalBody.oldScale.scale(1.0 - blend));\n // Rotational lerp https://stackoverflow.com/a/30129248\n const cosine = (1.0 - blend) * Math.cos(optionalBody.oldRotation) + blend * Math.cos(transform.rotation);\n const sine = (1.0 - blend) * Math.sin(optionalBody.oldRotation) + blend * Math.sin(transform.rotation);\n interpolatedRotation = Math.atan2(sine, cosine);\n }\n }\n if (transform) {\n this._graphicsContext.z = transform.z;\n this._graphicsContext.translate(interpolatedPos.x, interpolatedPos.y);\n this._graphicsContext.scale(interpolatedScale.x, interpolatedScale.y);\n this._graphicsContext.rotate(interpolatedRotation);\n }\n }\n }\n }\n class DebugSystem extends System {\n constructor(){\n super(...arguments);\n this.types = [\n \"ex.transform\"\n ];\n this.systemType = SystemType.Draw;\n this.priority = 999; // lowest priority\n }\n initialize(scene) {\n this._graphicsContext = scene.engine.graphicsContext;\n this._camera = scene.camera;\n this._engine = scene.engine;\n this._collisionSystem = scene.world.systemManager.get(CollisionSystem);\n }\n update(entities, _delta) {\n var _a;\n if (!this._engine.isDebug) return;\n const filterSettings = this._engine.debug.filter;\n let id;\n let name;\n const entitySettings = this._engine.debug.entity;\n let tx;\n const txSettings = this._engine.debug.transform;\n let motion;\n const motionSettings = this._engine.debug.motion;\n let colliderComp;\n const colliderSettings = this._engine.debug.collider;\n const physicsSettings = this._engine.debug.physics;\n let graphics;\n const graphicsSettings = this._engine.debug.graphics;\n let debugDraw;\n let body;\n const bodySettings = this._engine.debug.body;\n const cameraSettings = this._engine.debug.camera;\n for (const entity of entities){\n if (entity.hasTag(\"offscreen\")) continue;\n if (entity instanceof Particle) continue;\n if (filterSettings.useFilter) {\n const allIds = filterSettings.ids.length === 0;\n const idMatch = allIds || filterSettings.ids.includes(entity.id);\n if (!idMatch) continue;\n const allNames = filterSettings.nameQuery === \"\";\n const nameMatch = allNames || entity.name.includes(filterSettings.nameQuery);\n if (!nameMatch) continue;\n }\n let cursor = Vector.Zero;\n const lineHeight = vec(0, 16);\n id = entity.id;\n name = entity.name;\n tx = entity.get(TransformComponent);\n // This optionally sets our camera based on the entity coord plan (world vs. screen)\n this._pushCameraTransform(tx);\n this._graphicsContext.save();\n this._applyTransform(entity);\n if (tx) {\n if (txSettings.showAll || txSettings.showPosition) this._graphicsContext.debug.drawPoint(Vector.Zero, {\n size: 4,\n color: txSettings.positionColor\n });\n if (txSettings.showAll || txSettings.showPositionLabel) {\n this._graphicsContext.debug.drawText(`pos${tx.pos.toString(2)}`, cursor);\n cursor = cursor.add(lineHeight);\n }\n if (txSettings.showAll || txSettings.showZIndex) {\n this._graphicsContext.debug.drawText(`z(${tx.z.toFixed(1)})`, cursor);\n cursor = cursor.add(lineHeight);\n }\n if (entitySettings.showAll || entitySettings.showId) {\n this._graphicsContext.debug.drawText(`id(${id}) ${entity.parent ? \"child of id(\" + ((_a = entity.parent) === null || _a === void 0 ? void 0 : _a.id) + \")\" : \"\"}`, cursor);\n cursor = cursor.add(lineHeight);\n }\n if (entitySettings.showAll || entitySettings.showName) {\n this._graphicsContext.debug.drawText(`name(${name})`, cursor);\n cursor = cursor.add(lineHeight);\n }\n if (txSettings.showAll || txSettings.showRotation) {\n this._graphicsContext.drawLine(Vector.Zero, Vector.fromAngle(tx.rotation).scale(50).add(Vector.Zero), txSettings.rotationColor, 2);\n this._graphicsContext.debug.drawText(`rot deg(${toDegrees(tx.rotation).toFixed(2)})`, cursor);\n cursor = cursor.add(lineHeight);\n }\n if (txSettings.showAll || txSettings.showScale) this._graphicsContext.drawLine(Vector.Zero, tx.scale.add(Vector.Zero), txSettings.scaleColor, 2);\n }\n graphics = entity.get(GraphicsComponent);\n if (graphics) {\n if (graphicsSettings.showAll || graphicsSettings.showBounds) {\n const bounds = graphics.localBounds;\n bounds.draw(this._graphicsContext, graphicsSettings.boundsColor);\n }\n }\n debugDraw = entity.get(DebugGraphicsComponent);\n if (debugDraw) {\n if (!debugDraw.useTransform) this._graphicsContext.restore();\n debugDraw.draw(this._graphicsContext);\n if (!debugDraw.useTransform) {\n this._graphicsContext.save();\n this._applyTransform(entity);\n }\n }\n body = entity.get(BodyComponent);\n if (body) {\n if (bodySettings.showAll || bodySettings.showCollisionGroup) {\n this._graphicsContext.debug.drawText(`collision group(${body.group.name})`, cursor);\n cursor = cursor.add(lineHeight);\n }\n if (bodySettings.showAll || bodySettings.showCollisionType) {\n this._graphicsContext.debug.drawText(`collision type(${body.collisionType})`, cursor);\n cursor = cursor.add(lineHeight);\n }\n if (bodySettings.showAll || bodySettings.showMass) {\n this._graphicsContext.debug.drawText(`mass(${body.mass})`, cursor);\n cursor = cursor.add(lineHeight);\n }\n if (bodySettings.showAll || bodySettings.showMotion) {\n this._graphicsContext.debug.drawText(`motion(${body.sleepMotion})`, cursor);\n cursor = cursor.add(lineHeight);\n }\n if (bodySettings.showAll || bodySettings.showSleeping) {\n this._graphicsContext.debug.drawText(`sleeping(${body.canSleep ? body.sleeping : \"cant sleep\"})`, cursor);\n cursor = cursor.add(lineHeight);\n }\n }\n this._graphicsContext.restore();\n motion = entity.get(MotionComponent);\n if (motion) {\n if (motionSettings.showAll || motionSettings.showVelocity) {\n this._graphicsContext.debug.drawText(`vel${motion.vel.toString(2)}`, cursor.add(tx.globalPos));\n this._graphicsContext.drawLine(tx.globalPos, tx.globalPos.add(motion.vel), motionSettings.velocityColor, 2);\n cursor = cursor.add(lineHeight);\n }\n if (motionSettings.showAll || motionSettings.showAcceleration) this._graphicsContext.drawLine(tx.globalPos, tx.globalPos.add(motion.acc), motionSettings.accelerationColor, 2);\n }\n // Colliders live in world space already so after the restore()\n colliderComp = entity.get(ColliderComponent);\n if (colliderComp) {\n const collider = colliderComp.get();\n if ((colliderSettings.showAll || colliderSettings.showGeometry) && collider) collider.debug(this._graphicsContext, colliderSettings.geometryColor);\n if (colliderSettings.showAll || colliderSettings.showBounds) {\n if (collider instanceof CompositeCollider) {\n const colliders = collider.getColliders();\n for (const collider of colliders){\n const bounds = collider.bounds;\n const pos = vec(bounds.left, bounds.top);\n this._graphicsContext.debug.drawRect(pos.x, pos.y, bounds.width, bounds.height, {\n color: colliderSettings.boundsColor\n });\n if (colliderSettings.showAll || colliderSettings.showOwner) this._graphicsContext.debug.drawText(`owner id(${collider.owner.id})`, pos);\n }\n colliderComp.bounds.draw(this._graphicsContext, colliderSettings.boundsColor);\n } else if (collider) {\n const bounds = colliderComp.bounds;\n const pos = vec(bounds.left, bounds.top);\n this._graphicsContext.debug.drawRect(pos.x, pos.y, bounds.width, bounds.height, {\n color: colliderSettings.boundsColor\n });\n if (colliderSettings.showAll || colliderSettings.showOwner) this._graphicsContext.debug.drawText(`owner id(${colliderComp.owner.id})`, pos);\n }\n }\n }\n this._popCameraTransform(tx);\n }\n this._graphicsContext.save();\n this._camera.draw(this._graphicsContext);\n if (physicsSettings.showAll || physicsSettings.showBroadphaseSpacePartitionDebug) this._collisionSystem.debug(this._graphicsContext);\n if (physicsSettings.showAll || physicsSettings.showCollisionContacts || physicsSettings.showCollisionNormals) for (const [_, contact] of this._engine.debug.stats.currFrame.physics.contacts){\n if (physicsSettings.showAll || physicsSettings.showCollisionContacts) for (const point of contact.points)this._graphicsContext.debug.drawPoint(point, {\n size: 5,\n color: physicsSettings.collisionContactColor\n });\n if (physicsSettings.showAll || physicsSettings.showCollisionNormals) for (const point of contact.points)this._graphicsContext.debug.drawLine(point, contact.normal.scale(30).add(point), {\n color: physicsSettings.collisionNormalColor\n });\n }\n this._graphicsContext.restore();\n if (cameraSettings) {\n this._graphicsContext.save();\n this._camera.draw(this._graphicsContext);\n if (cameraSettings.showAll || cameraSettings.showFocus) this._graphicsContext.drawCircle(this._camera.pos, 4, cameraSettings.focusColor);\n if (cameraSettings.showAll || cameraSettings.showZoom) this._graphicsContext.debug.drawText(`zoom(${this._camera.zoom})`, this._camera.pos);\n this._graphicsContext.restore();\n }\n this._graphicsContext.flush();\n }\n /**\r\n * This applies the current entity transform to the graphics context\r\n * @param entity\r\n */ _applyTransform(entity) {\n const ancestors = entity.getAncestors();\n for (const ancestor of ancestors){\n const transform = ancestor === null || ancestor === void 0 ? void 0 : ancestor.get(TransformComponent);\n if (transform) {\n this._graphicsContext.translate(transform.pos.x, transform.pos.y);\n this._graphicsContext.scale(transform.scale.x, transform.scale.y);\n this._graphicsContext.rotate(transform.rotation);\n }\n }\n }\n /**\r\n * Applies the current camera transform if in world coordinates\r\n * @param transform\r\n */ _pushCameraTransform(transform) {\n // Establish camera offset per entity\n if (transform.coordPlane === CoordPlane.World) {\n this._graphicsContext.save();\n if (this._camera) this._camera.draw(this._graphicsContext);\n }\n }\n /**\r\n * Resets the current camera transform if in world coordinates\r\n * @param transform\r\n */ _popCameraTransform(transform) {\n if (transform.coordPlane === CoordPlane.World) // Apply camera world offset\n this._graphicsContext.restore();\n }\n }\n /**\r\n * The PointerSystem is responsible for dispatching pointer events to entities\r\n * that need them.\r\n *\r\n * The PointerSystem can be optionally configured by the [[PointerComponent]], by default Entities use\r\n * the [[Collider]]'s shape for pointer events.\r\n */ class PointerSystem extends System {\n constructor(){\n super(...arguments);\n this.types = [\n \"ex.transform\",\n \"ex.pointer\"\n ];\n this.systemType = SystemType.Update;\n this.priority = -1;\n /**\r\n * Optionally override component configuration for all entities\r\n */ this.overrideUseColliderShape = false;\n /**\r\n * Optionally override component configuration for all entities\r\n */ this.overrideUseGraphicsBounds = false;\n this.lastFrameEntityToPointers = new Map();\n this.currentFrameEntityToPointers = new Map();\n this._sortedTransforms = [];\n this._sortedEntities = [];\n this._zHasChanged = false;\n this._zIndexUpdate = ()=>{\n this._zHasChanged = true;\n };\n }\n initialize(scene) {\n this._engine = scene.engine;\n }\n preupdate() {\n // event receiver might change per frame\n this._receiver = this._engine.input.pointers;\n if (this._zHasChanged) {\n this._sortedTransforms.sort((a, b)=>{\n return b.z - a.z;\n });\n this._sortedEntities = this._sortedTransforms.map((t)=>t.owner);\n this._zHasChanged = false;\n }\n }\n notify(entityAddedOrRemoved) {\n if (isAddedSystemEntity(entityAddedOrRemoved)) {\n const tx = entityAddedOrRemoved.data.get(TransformComponent);\n this._sortedTransforms.push(tx);\n this._sortedEntities.push(tx.owner);\n tx.zIndexChanged$.subscribe(this._zIndexUpdate);\n this._zHasChanged = true;\n } else {\n const tx = entityAddedOrRemoved.data.get(TransformComponent);\n tx.zIndexChanged$.unsubscribe(this._zIndexUpdate);\n const index = this._sortedTransforms.indexOf(tx);\n if (index > -1) {\n this._sortedTransforms.splice(index, 1);\n this._sortedEntities.splice(index, 1);\n }\n }\n }\n entityCurrentlyUnderPointer(entity, pointerId) {\n return this.currentFrameEntityToPointers.has(entity.id) && this.currentFrameEntityToPointers.get(entity.id).includes(pointerId);\n }\n entityWasUnderPointer(entity, pointerId) {\n return this.lastFrameEntityToPointers.has(entity.id) && this.lastFrameEntityToPointers.get(entity.id).includes(pointerId);\n }\n entered(entity, pointerId) {\n return this.entityCurrentlyUnderPointer(entity, pointerId) && !this.lastFrameEntityToPointers.has(entity.id);\n }\n left(entity, pointerId) {\n return !this.currentFrameEntityToPointers.has(entity.id) && this.entityWasUnderPointer(entity, pointerId);\n }\n addPointerToEntity(entity, pointerId) {\n if (!this.currentFrameEntityToPointers.has(entity.id)) {\n this.currentFrameEntityToPointers.set(entity.id, [\n pointerId\n ]);\n return;\n }\n const pointers = this.currentFrameEntityToPointers.get(entity.id);\n this.currentFrameEntityToPointers.set(entity.id, pointers.concat(pointerId));\n }\n update(_entities) {\n // Locate all the pointer/entity mappings\n this._processPointerToEntity(this._sortedEntities);\n // Dispatch pointer events on entities\n this._dispatchEvents(this._sortedEntities);\n // Clear last frame's events\n this._receiver.update();\n this.lastFrameEntityToPointers.clear();\n this.lastFrameEntityToPointers = new Map(this.currentFrameEntityToPointers);\n this.currentFrameEntityToPointers.clear();\n this._receiver.clear();\n }\n _processPointerToEntity(entities) {\n var _a;\n let transform;\n let collider;\n let graphics;\n let pointer;\n // TODO probably a spatial partition optimization here to quickly query bounds for pointer\n // doesn't seem to cause issues tho for perf\n // Pre-process find entities under pointers\n for (const entity of entities){\n transform = entity.get(TransformComponent);\n pointer = (_a = entity.get(PointerComponent)) !== null && _a !== void 0 ? _a : new PointerComponent;\n // Check collider contains pointer\n collider = entity.get(ColliderComponent);\n if (collider && (pointer.useColliderShape || this.overrideUseColliderShape)) {\n collider.update();\n const geom = collider.get();\n if (geom) {\n for (const [pointerId, pos] of this._receiver.currentFramePointerCoords.entries())if (geom.contains(transform.coordPlane === CoordPlane.World ? pos.worldPos : pos.screenPos)) this.addPointerToEntity(entity, pointerId);\n }\n }\n // Check graphics contains pointer\n graphics = entity.get(GraphicsComponent);\n if (graphics && (pointer.useGraphicsBounds || this.overrideUseGraphicsBounds)) {\n const graphicBounds = graphics.localBounds.transform(transform.get().matrix);\n for (const [pointerId, pos] of this._receiver.currentFramePointerCoords.entries())if (graphicBounds.contains(transform.coordPlane === CoordPlane.World ? pos.worldPos : pos.screenPos)) this.addPointerToEntity(entity, pointerId);\n }\n }\n }\n _processDownAndEmit(entity) {\n const lastDownPerPointer = new Map();\n // Loop through down and dispatch to entities\n for (const event of this._receiver.currentFrameDown){\n if (event.active && entity.active && this.entityCurrentlyUnderPointer(entity, event.pointerId)) {\n entity.events.emit(\"pointerdown\", event);\n if (this._receiver.isDragStart(event.pointerId)) entity.events.emit(\"pointerdragstart\", event);\n }\n lastDownPerPointer.set(event.pointerId, event);\n }\n return lastDownPerPointer;\n }\n _processUpAndEmit(entity) {\n const lastUpPerPointer = new Map();\n // Loop through up and dispatch to entities\n for (const event of this._receiver.currentFrameUp){\n if (event.active && entity.active && this.entityCurrentlyUnderPointer(entity, event.pointerId)) {\n entity.events.emit(\"pointerup\", event);\n if (this._receiver.isDragEnd(event.pointerId)) entity.events.emit(\"pointerdragend\", event);\n }\n lastUpPerPointer.set(event.pointerId, event);\n }\n return lastUpPerPointer;\n }\n _processMoveAndEmit(entity) {\n const lastMovePerPointer = new Map();\n // Loop through move and dispatch to entities\n for (const event of this._receiver.currentFrameMove){\n if (event.active && entity.active && this.entityCurrentlyUnderPointer(entity, event.pointerId)) {\n // move\n entity.events.emit(\"pointermove\", event);\n if (this._receiver.isDragging(event.pointerId)) entity.events.emit(\"pointerdragmove\", event);\n }\n lastMovePerPointer.set(event.pointerId, event);\n }\n return lastMovePerPointer;\n }\n _processEnterLeaveAndEmit(entity, lastUpDownMoveEvents) {\n // up, down, and move are considered for enter and leave\n for (const event of lastUpDownMoveEvents){\n // enter\n if (event.active && entity.active && this.entered(entity, event.pointerId)) {\n entity.events.emit(\"pointerenter\", event);\n if (this._receiver.isDragging(event.pointerId)) entity.events.emit(\"pointerdragenter\", event);\n break;\n }\n if (event.active && entity.active && // leave can happen on move\n (this.left(entity, event.pointerId) || // or leave can happen on pointer up\n this.entityCurrentlyUnderPointer(entity, event.pointerId) && event.type === \"up\")) {\n entity.events.emit(\"pointerleave\", event);\n if (this._receiver.isDragging(event.pointerId)) entity.events.emit(\"pointerdragleave\", event);\n break;\n }\n }\n }\n _processCancelAndEmit(entity) {\n // cancel\n for (const event of this._receiver.currentFrameCancel)if (event.active && entity.active && this.entityCurrentlyUnderPointer(entity, event.pointerId)) entity.events.emit(\"pointercancel\", event);\n }\n _processWheelAndEmit(entity) {\n // wheel\n for (const event of this._receiver.currentFrameWheel)// Currently the wheel only fires under the primary pointer '0'\n if (event.active && entity.active && this.entityCurrentlyUnderPointer(entity, 0)) entity.events.emit(\"pointerwheel\", event);\n }\n _dispatchEvents(entities) {\n const lastFrameEntities = new Set(this.lastFrameEntityToPointers.keys());\n const currentFrameEntities = new Set(this.currentFrameEntityToPointers.keys());\n // Filter preserves z order\n const entitiesWithEvents = entities.filter((e)=>lastFrameEntities.has(e.id) || currentFrameEntities.has(e.id));\n let lastMovePerPointer;\n let lastUpPerPointer;\n let lastDownPerPointer;\n // Dispatch events in entity z order\n for (const entity of entitiesWithEvents){\n lastDownPerPointer = this._processDownAndEmit(entity);\n lastUpPerPointer = this._processUpAndEmit(entity);\n lastMovePerPointer = this._processMoveAndEmit(entity);\n const lastUpDownMoveEvents = [\n ...lastMovePerPointer.values(),\n ...lastDownPerPointer.values(),\n ...lastUpPerPointer.values()\n ];\n this._processEnterLeaveAndEmit(entity, lastUpDownMoveEvents);\n this._processCancelAndEmit(entity);\n this._processWheelAndEmit(entity);\n }\n }\n }\n class ActionsSystem extends System {\n constructor(){\n super(...arguments);\n this.types = [\n \"ex.actions\"\n ];\n this.systemType = SystemType.Update;\n this.priority = -1;\n this._actions = [];\n }\n notify(entityAddedOrRemoved) {\n if (isAddedSystemEntity(entityAddedOrRemoved)) {\n const action = entityAddedOrRemoved.data.get(ActionsComponent);\n this._actions.push(action);\n } else {\n const action = entityAddedOrRemoved.data.get(ActionsComponent);\n const index = this._actions.indexOf(action);\n if (index > -1) this._actions.splice(index, 1);\n }\n }\n update(_entities, delta) {\n for (const actions of this._actions)actions.update(delta);\n }\n }\n class IsometricEntityComponent extends Component {\n /**\r\n * Specify the isometric map to use to position this entity's z-index\r\n * @param map\r\n */ constructor(map){\n super();\n this.type = \"ex.isometricentity\";\n /**\r\n * Vertical \"height\" in the isometric world\r\n */ this.elevation = 0;\n this.map = map;\n }\n }\n class IsometricEntitySystem extends System {\n constructor(){\n super(...arguments);\n this.types = [\n \"ex.transform\",\n \"ex.isometricentity\"\n ];\n this.systemType = SystemType.Update;\n this.priority = 99;\n }\n update(entities, _delta) {\n let transform;\n let iso;\n for (const entity of entities){\n transform = entity.get(TransformComponent);\n iso = entity.get(IsometricEntityComponent);\n const maxZindexPerElevation = Math.max(iso.map.columns * iso.map.tileWidth, iso.map.rows * iso.map.tileHeight);\n const newZ = maxZindexPerElevation * iso.elevation + transform.pos.y;\n transform.z = newZ;\n }\n }\n }\n class OffscreenSystem extends System {\n constructor(){\n super(...arguments);\n this.types = [\n \"ex.transform\",\n \"ex.graphics\"\n ];\n this.systemType = SystemType.Draw;\n this.priority = -1;\n }\n initialize(scene) {\n this._camera = scene.camera;\n this._screen = scene.engine.screen;\n }\n update(entities) {\n this._worldBounds = this._screen.getWorldBounds();\n let transform;\n let graphics;\n let maybeParallax;\n for (const entity of entities){\n graphics = entity.get(GraphicsComponent);\n transform = entity.get(TransformComponent);\n maybeParallax = entity.get(ParallaxComponent);\n let parallaxOffset;\n if (maybeParallax) {\n // We use the Tiled formula\n // https://doc.mapeditor.org/en/latest/manual/layers/#parallax-scrolling-factor\n // cameraPos * (1 - parallaxFactor)\n const oneMinusFactor = Vector.One.sub(maybeParallax.parallaxFactor);\n parallaxOffset = this._camera.pos.scale(oneMinusFactor);\n }\n // Figure out if entities are offscreen\n const entityOffscreen = this._isOffscreen(transform, graphics, parallaxOffset);\n if (entityOffscreen && !entity.hasTag(\"ex.offscreen\")) {\n entity.events.emit(\"exitviewport\", new ExitViewPortEvent(entity));\n entity.addTag(\"ex.offscreen\");\n }\n if (!entityOffscreen && entity.hasTag(\"ex.offscreen\")) {\n entity.events.emit(\"enterviewport\", new EnterViewPortEvent(entity));\n entity.removeTag(\"ex.offscreen\");\n }\n }\n }\n _isOffscreen(transform, graphics, parallaxOffset) {\n if (transform.coordPlane === CoordPlane.World) {\n let bounds = graphics.localBounds;\n if (parallaxOffset) bounds = bounds.translate(parallaxOffset);\n const transformedBounds = bounds.transform(transform.get().matrix);\n const graphicsOffscreen = !this._worldBounds.overlaps(transformedBounds);\n return graphicsOffscreen;\n } else // TODO screen coordinates\n return false;\n }\n }\n class PhysicsWorld {\n constructor(){\n this.collisionProcessor = new DynamicTreeCollisionProcessor();\n }\n rayCast(ray, options) {\n return this.collisionProcessor.rayCast(ray, options);\n }\n }\n const SceneEvents = {\n Initialize: \"initialize\",\n Activate: \"activate\",\n Deactivate: \"deactivate\",\n PreUpdate: \"preupdate\",\n PostUpdate: \"postupdate\",\n PreDraw: \"predraw\",\n PostDraw: \"postdraw\",\n PreDebugDraw: \"predebugdraw\",\n PostDebugDraw: \"postdebugdraw\"\n };\n /**\r\n * [[Actor|Actors]] are composed together into groupings called Scenes in\r\n * Excalibur. The metaphor models the same idea behind real world\r\n * actors in a scene. Only actors in scenes will be updated and drawn.\r\n *\r\n * Typical usages of a scene include: levels, menus, loading screens, etc.\r\n */ class Scene {\n /**\r\n * The actors in the current scene\r\n */ get actors() {\n return this.world.entityManager.entities.filter((e)=>{\n return e instanceof Actor;\n });\n }\n /**\r\n * The entities in the current scene\r\n */ get entities() {\n return this.world.entityManager.entities;\n }\n /**\r\n * The triggers in the current scene\r\n */ get triggers() {\n return this.world.entityManager.entities.filter((e)=>{\n return e instanceof Trigger;\n });\n }\n /**\r\n * The [[TileMap]]s in the scene, if any\r\n */ get tileMaps() {\n return this.world.entityManager.entities.filter((e)=>{\n return e instanceof TileMap;\n });\n }\n get timers() {\n return this._timers;\n }\n constructor(){\n // Initialize systems\n this._logger = Logger.getInstance();\n this.events = new EventEmitter();\n /**\r\n * Gets or sets the current camera for the scene\r\n */ this.camera = new Camera();\n /**\r\n * The ECS world for the scene\r\n */ this.world = new World(this);\n /**\r\n * The Excalibur physics world for the scene. Used to interact\r\n * with colliders included in the scene.\r\n *\r\n * Can be used to perform scene ray casts, track colliders, broadphase, and narrowphase.\r\n */ this.physics = new PhysicsWorld();\n this._isInitialized = false;\n this._timers = [];\n this._cancelQueue = [];\n // Update\n this.world.add(new ActionsSystem());\n this.world.add(new MotionSystem());\n this.world.add(new CollisionSystem(this.physics));\n this.world.add(new PointerSystem());\n this.world.add(new IsometricEntitySystem());\n // Draw\n this.world.add(new OffscreenSystem());\n this.world.add(new GraphicsSystem());\n this.world.add(new DebugSystem());\n }\n emit(eventName, event) {\n this.events.emit(eventName, event);\n }\n on(eventName, handler) {\n return this.events.on(eventName, handler);\n }\n once(eventName, handler) {\n return this.events.once(eventName, handler);\n }\n off(eventName, handler) {\n this.events.off(eventName, handler);\n }\n /**\r\n * This is called before the first update of the [[Scene]]. Initializes scene members like the camera. This method is meant to be\r\n * overridden. This is where initialization of child actors should take place.\r\n */ onInitialize(_engine) {\n // will be overridden\n }\n /**\r\n * This is called when the scene is made active and started. It is meant to be overridden,\r\n * this is where you should setup any DOM UI or event handlers needed for the scene.\r\n */ onActivate(_context) {\n // will be overridden\n }\n /**\r\n * This is called when the scene is made transitioned away from and stopped. It is meant to be overridden,\r\n * this is where you should cleanup any DOM UI or event handlers needed for the scene.\r\n */ onDeactivate(_context) {\n // will be overridden\n }\n /**\r\n * Safe to override onPreUpdate lifecycle event handler. Synonymous with `.on('preupdate', (evt) =>{...})`\r\n *\r\n * `onPreUpdate` is called directly before a scene is updated.\r\n */ onPreUpdate(_engine, _delta) {\n // will be overridden\n }\n /**\r\n * Safe to override onPostUpdate lifecycle event handler. Synonymous with `.on('preupdate', (evt) =>{...})`\r\n *\r\n * `onPostUpdate` is called directly after a scene is updated.\r\n */ onPostUpdate(_engine, _delta) {\n // will be overridden\n }\n /**\r\n * Safe to override onPreDraw lifecycle event handler. Synonymous with `.on('preupdate', (evt) =>{...})`\r\n *\r\n * `onPreDraw` is called directly before a scene is drawn.\r\n *\r\n */ onPreDraw(_ctx, _delta) {\n // will be overridden\n }\n /**\r\n * Safe to override onPostDraw lifecycle event handler. Synonymous with `.on('preupdate', (evt) =>{...})`\r\n *\r\n * `onPostDraw` is called directly after a scene is drawn.\r\n *\r\n */ onPostDraw(_ctx, _delta) {\n // will be overridden\n }\n /**\r\n * Initializes actors in the scene\r\n */ _initializeChildren() {\n for (const child of this.entities)child._initialize(this.engine);\n }\n /**\r\n * Gets whether or not the [[Scene]] has been initialized\r\n */ get isInitialized() {\n return this._isInitialized;\n }\n /**\r\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\r\n *\r\n * Initializes the scene before the first update, meant to be called by engine not by users of\r\n * Excalibur\r\n * @internal\r\n */ _initialize(engine) {\n if (!this.isInitialized) {\n this.engine = engine;\n // Initialize camera first\n this.camera._initialize(engine);\n this.world.systemManager.initialize();\n // This order is important! we want to be sure any custom init that add actors\n // fire before the actor init\n this.onInitialize.call(this, engine);\n this._initializeChildren();\n this._logger.debug(\"Scene.onInitialize\", this, engine);\n this.events.emit(\"initialize\", new InitializeEvent(engine, this));\n this._isInitialized = true;\n }\n }\n /**\r\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\r\n *\r\n * Activates the scene with the base behavior, then calls the overridable `onActivate` implementation.\r\n * @internal\r\n */ _activate(context) {\n this._logger.debug(\"Scene.onActivate\", this);\n this.onActivate(context);\n }\n /**\r\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\r\n *\r\n * Deactivates the scene with the base behavior, then calls the overridable `onDeactivate` implementation.\r\n * @internal\r\n */ _deactivate(context) {\n this._logger.debug(\"Scene.onDeactivate\", this);\n this.onDeactivate(context);\n }\n /**\r\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\r\n *\r\n * Internal _preupdate handler for [[onPreUpdate]] lifecycle event\r\n * @internal\r\n */ _preupdate(_engine, delta) {\n this.emit(\"preupdate\", new PreUpdateEvent(_engine, delta, this));\n this.onPreUpdate(_engine, delta);\n }\n /**\r\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\r\n *\r\n * Internal _preupdate handler for [[onPostUpdate]] lifecycle event\r\n * @internal\r\n */ _postupdate(_engine, delta) {\n this.emit(\"postupdate\", new PostUpdateEvent(_engine, delta, this));\n this.onPostUpdate(_engine, delta);\n }\n /**\r\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\r\n *\r\n * Internal _predraw handler for [[onPreDraw]] lifecycle event\r\n *\r\n * @internal\r\n */ _predraw(_ctx, _delta) {\n this.emit(\"predraw\", new PreDrawEvent(_ctx, _delta, this));\n this.onPreDraw(_ctx, _delta);\n }\n /**\r\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\r\n *\r\n * Internal _postdraw handler for [[onPostDraw]] lifecycle event\r\n *\r\n * @internal\r\n */ _postdraw(_ctx, _delta) {\n this.emit(\"postdraw\", new PostDrawEvent(_ctx, _delta, this));\n this.onPostDraw(_ctx, _delta);\n }\n /**\r\n * Updates all the actors and timers in the scene. Called by the [[Engine]].\r\n * @param engine Reference to the current Engine\r\n * @param delta The number of milliseconds since the last update\r\n */ update(engine, delta) {\n this._preupdate(engine, delta);\n // TODO differed entity removal for timers\n let i, len;\n // Remove timers in the cancel queue before updating them\n for(i = 0, len = this._cancelQueue.length; i < len; i++)this.removeTimer(this._cancelQueue[i]);\n this._cancelQueue.length = 0;\n // Cycle through timers updating timers\n for (const timer of this._timers)timer.update(delta);\n this.world.update(SystemType.Update, delta);\n // Camera last keeps renders smooth that are based on entity/actor\n if (this.camera) this.camera.update(engine, delta);\n this._collectActorStats(engine);\n this._postupdate(engine, delta);\n }\n /**\r\n * Draws all the actors in the Scene. Called by the [[Engine]].\r\n *\r\n * @param ctx The current rendering context\r\n * @param delta The number of milliseconds since the last draw\r\n */ draw(ctx, delta) {\n var _a;\n this._predraw(ctx, delta);\n this.world.update(SystemType.Draw, delta);\n if ((_a = this.engine) === null || _a === void 0 ? void 0 : _a.isDebug) this.debugDraw(ctx);\n this._postdraw(ctx, delta);\n }\n /**\r\n * Draws all the actors' debug information in the Scene. Called by the [[Engine]].\r\n * @param ctx The current rendering context\r\n */ /* istanbul ignore next */ debugDraw(ctx) {\n this.emit(\"predebugdraw\", new PreDebugDrawEvent(ctx, this));\n // pass\n this.emit(\"postdebugdraw\", new PostDebugDrawEvent(ctx, this));\n }\n /**\r\n * Checks whether an actor is contained in this scene or not\r\n */ contains(actor) {\n return this.actors.indexOf(actor) > -1;\n }\n add(entity) {\n this.emit(\"entityadded\", {\n target: entity\n });\n this.world.add(entity);\n entity.scene = this;\n if (entity instanceof Timer) {\n if (!contains(this._timers, entity)) this.addTimer(entity);\n return;\n }\n }\n /**\r\n * Removes an [[Entity]] (Actor, TileMap, Trigger, etc) or [[Timer]] from it's current scene\r\n * and adds it to this scene.\r\n *\r\n * Useful if you want to have an object be present in only 1 scene at a time.\r\n * @param entity\r\n */ transfer(entity) {\n let scene;\n if (entity instanceof Entity && entity.scene && entity.scene !== this) {\n scene = entity.scene;\n entity.scene.world.remove(entity, false);\n }\n if (entity instanceof Timer && entity.scene) {\n scene = entity.scene;\n entity.scene.removeTimer(entity);\n }\n scene === null || scene === void 0 || scene.emit(\"entityremoved\", {\n target: entity\n });\n this.add(entity);\n }\n remove(entity) {\n if (entity instanceof Entity) {\n this.emit(\"entityremoved\", {\n target: entity\n });\n if (entity.active) entity.kill();\n this.world.remove(entity);\n }\n if (entity instanceof Timer) this.removeTimer(entity);\n }\n /**\r\n * Removes all entities and timers from the scene, optionally indicate whether deferred should or shouldn't be used.\r\n *\r\n * By default entities use deferred removal\r\n * @param deferred\r\n */ clear(deferred = true) {\n for (const entity of this.entities)this.world.remove(entity, deferred);\n for (const timer of this.timers)this.removeTimer(timer);\n }\n /**\r\n * Adds a [[Timer]] to the scene\r\n * @param timer The timer to add\r\n */ addTimer(timer) {\n this._timers.push(timer);\n timer.scene = this;\n return timer;\n }\n /**\r\n * Removes a [[Timer]] from the scene.\r\n * @warning Can be dangerous, use [[cancelTimer]] instead\r\n * @param timer The timer to remove\r\n */ removeTimer(timer) {\n const i = this._timers.indexOf(timer);\n if (i !== -1) this._timers.splice(i, 1);\n return timer;\n }\n /**\r\n * Cancels a [[Timer]], removing it from the scene nicely\r\n * @param timer The timer to cancel\r\n */ cancelTimer(timer) {\n this._cancelQueue.push(timer);\n return timer;\n }\n /**\r\n * Tests whether a [[Timer]] is active in the scene\r\n */ isTimerActive(timer) {\n return this._timers.indexOf(timer) > -1 && !timer.complete;\n }\n isCurrentScene() {\n if (this.engine) return this.engine.currentScene === this;\n return false;\n }\n _collectActorStats(engine) {\n const screenElements = this.actors.filter((a)=>a instanceof ScreenElement);\n for (const _ui of screenElements)engine.stats.currFrame.actors.ui++;\n for (const actor of this.actors){\n engine.stats.currFrame.actors.alive++;\n for (const child of actor.children)if (isScreenElement(child)) // TODO not true\n engine.stats.currFrame.actors.ui++;\n else engine.stats.currFrame.actors.alive++;\n }\n }\n }\n var ColorBlindnessMode;\n (function(ColorBlindnessMode) {\n ColorBlindnessMode[\"Protanope\"] = \"Protanope\";\n ColorBlindnessMode[\"Deuteranope\"] = \"Deuteranope\";\n ColorBlindnessMode[\"Tritanope\"] = \"Tritanope\";\n })(ColorBlindnessMode || (ColorBlindnessMode = {}));\n /* harmony default export */ const color_blind_fragment = \"#version 300 es\\r\\nprecision mediump float;\\r\\n// our texture\\r\\nuniform sampler2D u_image;\\r\\n// the texCoords passed in from the vertex shader.\\r\\nin vec2 v_texcoord;\\r\\n\\r\\n// color blind type\\r\\nuniform int u_type;\\r\\n\\r\\n// simulation?\\r\\nuniform bool u_simulate;\\r\\n\\r\\nout vec4 fragColor;\\r\\n\\r\\nvoid main() {\\r\\n vec4 o = texture(u_image, v_texcoord);\\r\\n // RGB to LMS matrix conversion\\r\\n float L = (17.8824 * o.r) + (43.5161 * o.g) + (4.11935 * o.b);\\r\\n float M = (3.45565 * o.r) + (27.1554 * o.g) + (3.86714 * o.b);\\r\\n float S = (0.0299566 * o.r) + (0.184309 * o.g) + (1.46709 * o.b);\\r\\n // Simulate color blindness\\r\\n float l;\\r\\n float m;\\r\\n float s;\\r\\n //MODE CODE//\\r\\n if (u_type == 0) {\\r\\n // Protanope\\r\\n l = 0.0 * L + 2.02344 * M + -2.52581 * S;\\r\\n m = 0.0 * L + 1.0 * M + 0.0 * S;\\r\\n s = 0.0 * L + 0.0 * M + 1.0 * S;;\\r\\n } else if (u_type == 1) {\\r\\n // Deuteranope\\r\\n l = 1.0 * L + 0.0 * M + 0.0 * S;\\r\\n m = 0.494207 * L + 0.0 * M + 1.24827 * S;\\r\\n s = 0.0 * L + 0.0 * M + 1.0 * S;\\r\\n } else if (u_type == 2) {\\r\\n // Tritanope\\r\\n l = 1.0 * L + 0.0 * M + 0.0 * S;\\r\\n m = 0.0 * L + 1.0 * M + 0.0 * S;\\r\\n s = -0.395913 * L + 0.801109 * M + 0.0 * S;\\r\\n }\\r\\n\\r\\n // LMS to RGB matrix conversion\\r\\n vec4 error; // simulate the colors\\r\\n error.r = (0.0809444479 * l) + (-0.130504409 * m) + (0.116721066 * s);\\r\\n error.g = (-0.0102485335 * l) + (0.0540193266 * m) + (-0.113614708 * s);\\r\\n error.b = (-0.000365296938 * l) + (-0.00412161469 * m) + (0.693511405 * s);\\r\\n error.a = 1.0;\\r\\n vec4 diff = o - error;\\r\\n vec4 correction; // correct the colors\\r\\n correction.r = 0.0;\\r\\n correction.g = (diff.r * 0.7) + (diff.g * 1.0);\\r\\n correction.b = (diff.r * 0.7) + (diff.b * 1.0);\\r\\n correction = o + correction;\\r\\n correction.a = o.a;\\r\\n //SIMULATE//\\r\\n\\r\\n // sim \\r\\n if (u_simulate) {\\r\\n fragColor = error.rgba;\\r\\n } else {\\r\\n fragColor = correction.rgba;\\r\\n }\\r\\n}\";\n /**\r\n * Helper that defines a whole screen renderer, just provide a fragment source!\r\n *\r\n * Currently supports 1 varying\r\n * - vec2 a_texcoord between 0-1 which corresponds to screen position\r\n */ class ScreenShader {\n constructor(gl, fragmentSource){\n this._shader = new Shader({\n gl: gl,\n vertexSource: `#version 300 es\r\n in vec2 a_position;\r\n in vec2 a_texcoord;\r\n out vec2 v_texcoord;\r\n\r\n void main() {\r\n gl_Position = vec4(a_position, 0.0, 1.0);\r\n // Pass the texcoord to the fragment shader.\r\n v_texcoord = a_texcoord;\r\n }`,\n fragmentSource: fragmentSource\n });\n this._shader.compile();\n // Setup memory layout\n this._buffer = new VertexBuffer({\n gl: gl,\n type: \"static\",\n // clip space quad + uv since we don't need a camera\n data: new Float32Array([\n -1,\n -1,\n 0,\n 0,\n -1,\n 1,\n 0,\n 1,\n 1,\n -1,\n 1,\n 0,\n 1,\n -1,\n 1,\n 0,\n -1,\n 1,\n 0,\n 1,\n 1,\n 1,\n 1,\n 1\n ])\n });\n this._layout = new VertexLayout({\n gl: gl,\n shader: this._shader,\n vertexBuffer: this._buffer,\n attributes: [\n [\n \"a_position\",\n 2\n ],\n [\n \"a_texcoord\",\n 2\n ]\n ]\n });\n this._buffer.upload();\n }\n getShader() {\n return this._shader;\n }\n getLayout() {\n return this._layout;\n }\n }\n class ColorBlindnessPostProcessor {\n constructor(_colorBlindnessMode, simulate = false){\n this._colorBlindnessMode = _colorBlindnessMode;\n this._simulate = false;\n this._simulate = simulate;\n }\n initialize(gl) {\n this._shader = new ScreenShader(gl, color_blind_fragment);\n this.simulate = this._simulate;\n this.colorBlindnessMode = this._colorBlindnessMode;\n }\n getShader() {\n return this._shader.getShader();\n }\n getLayout() {\n return this._shader.getLayout();\n }\n set colorBlindnessMode(colorBlindMode) {\n this._colorBlindnessMode = colorBlindMode;\n if (this._shader) {\n const shader = this._shader.getShader();\n shader.use();\n if (this._colorBlindnessMode === ColorBlindnessMode.Protanope) shader.setUniformInt(\"u_type\", 0);\n else if (this._colorBlindnessMode === ColorBlindnessMode.Deuteranope) shader.setUniformInt(\"u_type\", 1);\n else if (this._colorBlindnessMode === ColorBlindnessMode.Tritanope) shader.setUniformInt(\"u_type\", 2);\n }\n }\n get colorBlindnessMode() {\n return this._colorBlindnessMode;\n }\n set simulate(value) {\n this._simulate = value;\n if (this._shader) {\n const shader = this._shader.getShader();\n shader.use();\n shader.setUniformBoolean(\"u_simulate\", value);\n }\n }\n get simulate() {\n return this._simulate;\n }\n }\n class ColorBlindFlags {\n constructor(engine){\n this._engine = engine;\n this._colorBlindPostProcessor = new ColorBlindnessPostProcessor(ColorBlindnessMode.Protanope);\n }\n /**\r\n * Correct colors for a specified color blindness\r\n * @param colorBlindness\r\n */ correct(colorBlindness) {\n if (this._engine.graphicsContext instanceof ExcaliburGraphicsContextWebGL) {\n this.clear();\n this._colorBlindPostProcessor.colorBlindnessMode = colorBlindness;\n this._colorBlindPostProcessor.simulate = false;\n this._engine.graphicsContext.addPostProcessor(this._colorBlindPostProcessor);\n }\n }\n /**\r\n * Simulate colors for a specified color blindness\r\n * @param colorBlindness\r\n */ simulate(colorBlindness) {\n if (this._engine.graphicsContext instanceof ExcaliburGraphicsContextWebGL) {\n this.clear();\n this._colorBlindPostProcessor.colorBlindnessMode = colorBlindness;\n this._colorBlindPostProcessor.simulate = true;\n this._engine.graphicsContext.addPostProcessor(this._colorBlindPostProcessor);\n }\n }\n /**\r\n * Remove color blindness post processor\r\n */ clear() {\n this._engine.graphicsContext.removePostProcessor(this._colorBlindPostProcessor);\n }\n }\n /**\r\n * Debug statistics and flags for Excalibur. If polling these values, it would be\r\n * best to do so on the `postupdate` event for [[Engine]], after all values have been\r\n * updated during a frame.\r\n */ class Debug {\n constructor(engine){\n /**\r\n * Performance statistics\r\n */ this.stats = {\n /**\r\n * Current frame statistics. Engine reuses this instance, use [[FrameStats.clone]] to copy frame stats.\r\n * Best accessed on [[postframe]] event. See [[FrameStats]]\r\n */ currFrame: new FrameStats(),\n /**\r\n * Previous frame statistics. Engine reuses this instance, use [[FrameStats.clone]] to copy frame stats.\r\n * Best accessed on [[preframe]] event. Best inspected on engine event `preframe`. See [[FrameStats]]\r\n */ prevFrame: new FrameStats()\n };\n /**\r\n * Filter debug context to named entities or entity ids\r\n */ this.filter = {\n /**\r\n * Toggle filter on or off (default off) must be on for DebugDraw to use filters\r\n */ useFilter: false,\n /**\r\n * Query for entities by name, if the entity name contains `nameQuery` it will be included\r\n */ nameQuery: \"\",\n /**\r\n * Query for Entity ids, if the id matches it will be included\r\n */ ids: []\n };\n /**\r\n * Entity debug settings\r\n */ this.entity = {\n showAll: false,\n showId: true,\n showName: false\n };\n /**\r\n * Transform component debug settings\r\n */ this.transform = {\n showAll: false,\n showPosition: false,\n showPositionLabel: false,\n positionColor: Color.Yellow,\n showZIndex: false,\n showScale: false,\n scaleColor: Color.Green,\n showRotation: false,\n rotationColor: Color.Blue\n };\n /**\r\n * Graphics component debug settings\r\n */ this.graphics = {\n showAll: false,\n showBounds: true,\n boundsColor: Color.Yellow\n };\n /**\r\n * Collider component debug settings\r\n */ this.collider = {\n showAll: false,\n showBounds: true,\n boundsColor: Color.Blue,\n showOwner: false,\n showGeometry: true,\n geometryColor: Color.Green\n };\n /**\r\n * Physics simulation debug settings\r\n */ this.physics = {\n showAll: false,\n showBroadphaseSpacePartitionDebug: false,\n showCollisionNormals: false,\n collisionNormalColor: Color.Cyan,\n showCollisionContacts: true,\n collisionContactColor: Color.Red\n };\n /**\r\n * Motion component debug settings\r\n */ this.motion = {\n showAll: false,\n showVelocity: false,\n velocityColor: Color.Yellow,\n showAcceleration: false,\n accelerationColor: Color.Red\n };\n /**\r\n * Body component debug settings\r\n */ this.body = {\n showAll: false,\n showCollisionGroup: false,\n showCollisionType: false,\n showSleeping: false,\n showMotion: false,\n showMass: false\n };\n /**\r\n * Camera debug settings\r\n */ this.camera = {\n showAll: false,\n showFocus: false,\n focusColor: Color.Red,\n showZoom: false\n };\n this._engine = engine;\n this.colorBlindMode = new ColorBlindFlags(this._engine);\n }\n /**\r\n * Switch the current excalibur clock with the [[TestClock]] and return\r\n * it in the same running state.\r\n *\r\n * This is useful when you need to debug frame by frame.\r\n */ useTestClock() {\n const clock = this._engine.clock;\n const wasRunning = clock.isRunning();\n clock.stop();\n const testClock = clock.toTestClock();\n if (wasRunning) testClock.start();\n this._engine.clock = testClock;\n return testClock;\n }\n /**\r\n * Switch the current excalibur clock with the [[StandardClock]] and\r\n * return it in the same running state.\r\n *\r\n * This is useful when you need to switch back to normal mode after\r\n * debugging.\r\n */ useStandardClock() {\n const currentClock = this._engine.clock;\n const wasRunning = currentClock.isRunning();\n currentClock.stop();\n const standardClock = currentClock.toStandardClock();\n if (wasRunning) standardClock.start();\n this._engine.clock = standardClock;\n return standardClock;\n }\n }\n /**\r\n * Implementation of a frame's stats. Meant to have values copied via [[FrameStats.reset]], avoid\r\n * creating instances of this every frame.\r\n */ class FrameStats {\n constructor(){\n this._id = 0;\n this._delta = 0;\n this._fps = 0;\n this._actorStats = {\n alive: 0,\n killed: 0,\n ui: 0,\n get remaining () {\n return this.alive - this.killed;\n },\n get total () {\n return this.remaining + this.ui;\n }\n };\n this._durationStats = {\n update: 0,\n draw: 0,\n get total () {\n return this.update + this.draw;\n }\n };\n this._physicsStats = new PhysicsStats();\n this._graphicsStats = {\n drawCalls: 0,\n drawnImages: 0\n };\n }\n /**\r\n * Zero out values or clone other IFrameStat stats. Allows instance reuse.\r\n *\r\n * @param [otherStats] Optional stats to clone\r\n */ reset(otherStats) {\n if (otherStats) {\n this.id = otherStats.id;\n this.delta = otherStats.delta;\n this.fps = otherStats.fps;\n this.actors.alive = otherStats.actors.alive;\n this.actors.killed = otherStats.actors.killed;\n this.actors.ui = otherStats.actors.ui;\n this.duration.update = otherStats.duration.update;\n this.duration.draw = otherStats.duration.draw;\n this._physicsStats.reset(otherStats.physics);\n this.graphics.drawCalls = otherStats.graphics.drawCalls;\n this.graphics.drawnImages = otherStats.graphics.drawnImages;\n } else {\n this.id = this.delta = this.fps = 0;\n this.actors.alive = this.actors.killed = this.actors.ui = 0;\n this.duration.update = this.duration.draw = 0;\n this._physicsStats.reset();\n this.graphics.drawnImages = this.graphics.drawCalls = 0;\n }\n }\n /**\r\n * Provides a clone of this instance.\r\n */ clone() {\n const fs = new FrameStats();\n fs.reset(this);\n return fs;\n }\n /**\r\n * Gets the frame's id\r\n */ get id() {\n return this._id;\n }\n /**\r\n * Sets the frame's id\r\n */ set id(value) {\n this._id = value;\n }\n /**\r\n * Gets the frame's delta (time since last frame)\r\n */ get delta() {\n return this._delta;\n }\n /**\r\n * Sets the frame's delta (time since last frame). Internal use only.\r\n * @internal\r\n */ set delta(value) {\n this._delta = value;\n }\n /**\r\n * Gets the frame's frames-per-second (FPS)\r\n */ get fps() {\n return this._fps;\n }\n /**\r\n * Sets the frame's frames-per-second (FPS). Internal use only.\r\n * @internal\r\n */ set fps(value) {\n this._fps = value;\n }\n /**\r\n * Gets the frame's actor statistics\r\n */ get actors() {\n return this._actorStats;\n }\n /**\r\n * Gets the frame's duration statistics\r\n */ get duration() {\n return this._durationStats;\n }\n /**\r\n * Gets the frame's physics statistics\r\n */ get physics() {\n return this._physicsStats;\n }\n /**\r\n * Gets the frame's graphics statistics\r\n */ get graphics() {\n return this._graphicsStats;\n }\n }\n class PhysicsStats {\n constructor(){\n this._pairs = 0;\n this._collisions = 0;\n this._contacts = new Map();\n this._fastBodies = 0;\n this._fastBodyCollisions = 0;\n this._broadphase = 0;\n this._narrowphase = 0;\n }\n /**\r\n * Zero out values or clone other IPhysicsStats stats. Allows instance reuse.\r\n *\r\n * @param [otherStats] Optional stats to clone\r\n */ reset(otherStats) {\n if (otherStats) {\n this.pairs = otherStats.pairs;\n this.collisions = otherStats.collisions;\n this.contacts = otherStats.contacts;\n this.fastBodies = otherStats.fastBodies;\n this.fastBodyCollisions = otherStats.fastBodyCollisions;\n this.broadphase = otherStats.broadphase;\n this.narrowphase = otherStats.narrowphase;\n } else {\n this.pairs = this.collisions = this.fastBodies = 0;\n this.fastBodyCollisions = this.broadphase = this.narrowphase = 0;\n this.contacts.clear();\n }\n }\n /**\r\n * Provides a clone of this instance.\r\n */ clone() {\n const ps = new PhysicsStats();\n ps.reset(this);\n return ps;\n }\n get pairs() {\n return this._pairs;\n }\n set pairs(value) {\n this._pairs = value;\n }\n get collisions() {\n return this._collisions;\n }\n set collisions(value) {\n this._collisions = value;\n }\n get contacts() {\n return this._contacts;\n }\n set contacts(contacts) {\n this._contacts = contacts;\n }\n get fastBodies() {\n return this._fastBodies;\n }\n set fastBodies(value) {\n this._fastBodies = value;\n }\n get fastBodyCollisions() {\n return this._fastBodyCollisions;\n }\n set fastBodyCollisions(value) {\n this._fastBodyCollisions = value;\n }\n get broadphase() {\n return this._broadphase;\n }\n set broadphase(value) {\n this._broadphase = value;\n }\n get narrowphase() {\n return this._narrowphase;\n }\n set narrowphase(value) {\n this._narrowphase = value;\n }\n }\n class BrowserComponent {\n on(eventName, handler) {\n if (this._nativeHandlers[eventName]) this.off(eventName, this._nativeHandlers[eventName]);\n this._nativeHandlers[eventName] = this._decorate(handler);\n this.nativeComponent.addEventListener(eventName, this._nativeHandlers[eventName]);\n }\n off(eventName, handler) {\n if (!handler) handler = this._nativeHandlers[eventName];\n this.nativeComponent.removeEventListener(eventName, handler);\n this._nativeHandlers[eventName] = null;\n }\n _decorate(handler) {\n return (evt)=>{\n if (!this._paused) handler(evt);\n };\n }\n pause() {\n this._paused = true;\n }\n resume() {\n this._paused = false;\n }\n clear() {\n for(const event in this._nativeHandlers)this.off(event);\n }\n constructor(nativeComponent){\n this.nativeComponent = nativeComponent;\n this._paused = false;\n this._nativeHandlers = {};\n }\n }\n class BrowserEvents {\n constructor(_windowGlobal, _documentGlobal){\n this._windowGlobal = _windowGlobal;\n this._documentGlobal = _documentGlobal;\n this._windowComponent = new BrowserComponent(this._windowGlobal);\n this._documentComponent = new BrowserComponent(this._documentGlobal);\n }\n get window() {\n return this._windowComponent;\n }\n get document() {\n return this._documentComponent;\n }\n pause() {\n this.window.pause();\n this.document.pause();\n }\n resume() {\n this.window.resume();\n this.document.resume();\n }\n clear() {\n this.window.clear();\n this.document.clear();\n }\n }\n class GlobalCoordinates {\n static fromPagePosition(xOrPos, yOrEngine, engineOrUndefined) {\n let pageX;\n let pageY;\n let pagePos;\n let engine;\n if (arguments.length === 3) {\n pageX = xOrPos;\n pageY = yOrEngine;\n pagePos = new Vector(pageX, pageY);\n engine = engineOrUndefined;\n } else {\n pagePos = xOrPos;\n pageX = pagePos.x;\n pageY = pagePos.y;\n engine = yOrEngine;\n }\n const screenPos = engine.screen.pageToScreenCoordinates(pagePos);\n const worldPos = engine.screen.screenToWorldCoordinates(screenPos);\n return new GlobalCoordinates(worldPos, pagePos, screenPos);\n }\n constructor(worldPos, pagePos, screenPos){\n this.worldPos = worldPos;\n this.pagePos = pagePos;\n this.screenPos = screenPos;\n }\n }\n class PointerEvent {\n cancel() {\n this.active = false;\n }\n get pagePos() {\n return this.coordinates.pagePos;\n }\n get screenPos() {\n return this.coordinates.screenPos;\n }\n get worldPos() {\n return this.coordinates.worldPos;\n }\n constructor(type, pointerId, button, pointerType, coordinates, nativeEvent){\n this.type = type;\n this.pointerId = pointerId;\n this.button = button;\n this.pointerType = pointerType;\n this.coordinates = coordinates;\n this.nativeEvent = nativeEvent;\n this.active = true;\n }\n }\n class WheelEvent {\n cancel() {\n this.active = false;\n }\n constructor(x, y, pageX, pageY, screenX, screenY, index, deltaX, deltaY, deltaZ, deltaMode, ev){\n this.x = x;\n this.y = y;\n this.pageX = pageX;\n this.pageY = pageY;\n this.screenX = screenX;\n this.screenY = screenY;\n this.index = index;\n this.deltaX = deltaX;\n this.deltaY = deltaY;\n this.deltaZ = deltaZ;\n this.deltaMode = deltaMode;\n this.ev = ev;\n this.active = true;\n }\n }\n class PointerAbstraction {\n constructor(){\n this.events = new EventEmitter();\n /**\r\n * The last position on the document this pointer was at. Can be `null` if pointer was never active.\r\n */ this.lastPagePos = Vector.Zero;\n /**\r\n * The last position on the screen this pointer was at. Can be `null` if pointer was never active.\r\n */ this.lastScreenPos = Vector.Zero;\n /**\r\n * The last position in the game world coordinates this pointer was at. Can be `null` if pointer was never active.\r\n */ this.lastWorldPos = Vector.Zero;\n this._onPointerMove = (ev)=>{\n this.lastPagePos = new Vector(ev.pagePos.x, ev.pagePos.y);\n this.lastScreenPos = new Vector(ev.screenPos.x, ev.screenPos.y);\n this.lastWorldPos = new Vector(ev.worldPos.x, ev.worldPos.y);\n };\n this._onPointerDown = (ev)=>{\n this.lastPagePos = new Vector(ev.pagePos.x, ev.pagePos.y);\n this.lastScreenPos = new Vector(ev.screenPos.x, ev.screenPos.y);\n this.lastWorldPos = new Vector(ev.worldPos.x, ev.worldPos.y);\n };\n this.on(\"move\", this._onPointerMove);\n this.on(\"down\", this._onPointerDown);\n }\n emit(eventName, event) {\n this.events.emit(eventName, event);\n }\n on(eventName, handler) {\n return this.events.on(eventName, handler);\n }\n once(eventName, handler) {\n return this.events.once(eventName, handler);\n }\n off(eventName, handler) {\n this.events.off(eventName, handler);\n }\n }\n var WheelDeltaMode;\n (function(WheelDeltaMode) {\n WheelDeltaMode[\"Pixel\"] = \"Pixel\";\n WheelDeltaMode[\"Line\"] = \"Line\";\n WheelDeltaMode[\"Page\"] = \"Page\";\n })(WheelDeltaMode || (WheelDeltaMode = {}));\n /**\r\n * Native browser button enumeration\r\n */ var NativePointerButton;\n (function(NativePointerButton) {\n NativePointerButton[NativePointerButton[\"NoButton\"] = -1] = \"NoButton\";\n NativePointerButton[NativePointerButton[\"Left\"] = 0] = \"Left\";\n NativePointerButton[NativePointerButton[\"Middle\"] = 1] = \"Middle\";\n NativePointerButton[NativePointerButton[\"Right\"] = 2] = \"Right\";\n NativePointerButton[NativePointerButton[\"Unknown\"] = 3] = \"Unknown\";\n })(NativePointerButton || (NativePointerButton = {}));\n /**\r\n * The mouse button being pressed.\r\n */ var PointerButton;\n (function(PointerButton) {\n PointerButton[\"Left\"] = \"Left\";\n PointerButton[\"Middle\"] = \"Middle\";\n PointerButton[\"Right\"] = \"Right\";\n PointerButton[\"Unknown\"] = \"Unknown\";\n PointerButton[\"NoButton\"] = \"NoButton\";\n })(PointerButton || (PointerButton = {}));\n /**\r\n * The type of pointer for a [[PointerEvent]].\r\n */ var PointerType;\n (function(PointerType) {\n PointerType[\"Touch\"] = \"Touch\";\n PointerType[\"Mouse\"] = \"Mouse\";\n PointerType[\"Pen\"] = \"Pen\";\n PointerType[\"Unknown\"] = \"Unknown\";\n })(PointerType || (PointerType = {}));\n const PointerEvents = {\n Move: \"move\",\n Down: \"down\",\n Up: \"up\",\n Wheel: \"wheel\"\n };\n /**\r\n * Is this event a native touch event?\r\n */ function isTouchEvent(value) {\n // Guard for Safari <= 13.1\n return globalThis.TouchEvent && value instanceof globalThis.TouchEvent;\n }\n /**\r\n * Is this event a native pointer event\r\n */ function isPointerEvent(value) {\n // Guard for Safari <= 13.1\n return globalThis.PointerEvent && value instanceof globalThis.PointerEvent;\n }\n /**\r\n * The PointerEventProcessor is responsible for collecting all the events from the canvas and transforming them into GlobalCoordinates\r\n */ class PointerEventReceiver {\n constructor(target, engine){\n this.target = target;\n this.engine = engine;\n this.events = new EventEmitter();\n this.primary = new PointerAbstraction();\n this._activeNativePointerIdsToNormalized = new Map();\n this.lastFramePointerCoords = new Map();\n this.currentFramePointerCoords = new Map();\n this.currentFramePointerDown = new Map();\n this.lastFramePointerDown = new Map();\n this.currentFrameDown = [];\n this.currentFrameUp = [];\n this.currentFrameMove = [];\n this.currentFrameCancel = [];\n this.currentFrameWheel = [];\n this._pointers = [\n this.primary\n ];\n this._boundHandle = this._handle.bind(this);\n this._boundWheel = this._handleWheel.bind(this);\n }\n /**\r\n * Creates a new PointerEventReceiver with a new target and engine while preserving existing pointer event\r\n * handlers.\r\n * @param target\r\n * @param engine\r\n */ recreate(target, engine) {\n const eventReceiver = new PointerEventReceiver(target, engine);\n eventReceiver.primary = this.primary;\n eventReceiver._pointers = this._pointers;\n return eventReceiver;\n }\n /**\r\n * Locates a specific pointer by id, creates it if it doesn't exist\r\n * @param index\r\n */ at(index) {\n if (index >= this._pointers.length) // Ensure there is a pointer to retrieve\n for(let i = this._pointers.length - 1, max = index; i < max; i++)this._pointers.push(new PointerAbstraction());\n return this._pointers[index];\n }\n /**\r\n * The number of pointers currently being tracked by excalibur\r\n */ count() {\n return this._pointers.length;\n }\n /**\r\n * Is the specified pointer id down this frame\r\n * @param pointerId\r\n */ isDown(pointerId) {\n var _a;\n return (_a = this.currentFramePointerDown.get(pointerId)) !== null && _a !== void 0 ? _a : false;\n }\n /**\r\n * Was the specified pointer id down last frame\r\n * @param pointerId\r\n */ wasDown(pointerId) {\n var _a;\n return (_a = this.lastFramePointerDown.get(pointerId)) !== null && _a !== void 0 ? _a : false;\n }\n /**\r\n * Whether the Pointer is currently dragging.\r\n */ isDragging(pointerId) {\n return this.isDown(pointerId);\n }\n /**\r\n * Whether the Pointer just started dragging.\r\n */ isDragStart(pointerId) {\n return this.isDown(pointerId) && !this.wasDown(pointerId);\n }\n /**\r\n * Whether the Pointer just ended dragging.\r\n */ isDragEnd(pointerId) {\n return !this.isDown(pointerId) && this.wasDown(pointerId);\n }\n emit(eventName, event) {\n this.events.emit(eventName, event);\n }\n on(eventName, handler) {\n return this.events.on(eventName, handler);\n }\n once(eventName, handler) {\n return this.events.once(eventName, handler);\n }\n off(eventName, handler) {\n this.events.off(eventName, handler);\n }\n /**\r\n * Called internally by excalibur\r\n *\r\n * Updates the current frame pointer info and emits raw pointer events\r\n *\r\n * This does not emit events to entities, see PointerSystem\r\n */ update() {\n this.lastFramePointerDown = new Map(this.currentFramePointerDown);\n this.lastFramePointerCoords = new Map(this.currentFramePointerCoords);\n for (const event of this.currentFrameDown){\n this.emit(\"down\", event);\n const pointer = this.at(event.pointerId);\n pointer.emit(\"down\", event);\n this.primary.emit(\"pointerdown\", event);\n }\n for (const event of this.currentFrameUp){\n this.emit(\"up\", event);\n const pointer = this.at(event.pointerId);\n pointer.emit(\"up\", event);\n }\n for (const event of this.currentFrameMove){\n this.emit(\"move\", event);\n const pointer = this.at(event.pointerId);\n pointer.emit(\"move\", event);\n }\n for (const event of this.currentFrameCancel){\n this.emit(\"cancel\", event);\n const pointer = this.at(event.pointerId);\n pointer.emit(\"cancel\", event);\n }\n for (const event of this.currentFrameWheel){\n this.emit(\"wheel\", event);\n this.primary.emit(\"pointerwheel\", event);\n }\n }\n /**\r\n * Clears the current frame event and pointer data\r\n */ clear() {\n for (const event of this.currentFrameUp){\n this.currentFramePointerCoords.delete(event.pointerId);\n const ids = this._activeNativePointerIdsToNormalized.entries();\n for (const [native, normalized] of ids)if (normalized === event.pointerId) this._activeNativePointerIdsToNormalized.delete(native);\n }\n this.currentFrameDown.length = 0;\n this.currentFrameUp.length = 0;\n this.currentFrameMove.length = 0;\n this.currentFrameCancel.length = 0;\n this.currentFrameWheel.length = 0;\n }\n /**\r\n * Initializes the pointer event receiver so that it can start listening to native\r\n * browser events.\r\n */ init(options) {\n var _a;\n // Disabling the touch action avoids browser/platform gestures from firing on the canvas\n // It is important on mobile to have touch action 'none'\n // https://stackoverflow.com/questions/48124372/pointermove-event-not-working-with-touch-why-not\n if (this.target === this.engine.canvas) this.engine.canvas.style.touchAction = \"none\";\n else document.body.style.touchAction = \"none\";\n // Preferred pointer events\n if (window.PointerEvent) {\n this.target.addEventListener(\"pointerdown\", this._boundHandle);\n this.target.addEventListener(\"pointerup\", this._boundHandle);\n this.target.addEventListener(\"pointermove\", this._boundHandle);\n this.target.addEventListener(\"pointercancel\", this._boundHandle);\n } else {\n // Touch Events\n this.target.addEventListener(\"touchstart\", this._boundHandle);\n this.target.addEventListener(\"touchend\", this._boundHandle);\n this.target.addEventListener(\"touchmove\", this._boundHandle);\n this.target.addEventListener(\"touchcancel\", this._boundHandle);\n // Mouse Events\n this.target.addEventListener(\"mousedown\", this._boundHandle);\n this.target.addEventListener(\"mouseup\", this._boundHandle);\n this.target.addEventListener(\"mousemove\", this._boundHandle);\n }\n // MDN MouseWheelEvent\n const wheelOptions = {\n passive: !(this.engine.pageScrollPreventionMode === ScrollPreventionMode.All || this.engine.pageScrollPreventionMode === ScrollPreventionMode.Canvas)\n };\n if (\"onwheel\" in document.createElement(\"div\")) // Modern Browsers\n this.target.addEventListener(\"wheel\", this._boundWheel, wheelOptions);\n else if (document.onmousewheel !== undefined) // Webkit and IE\n this.target.addEventListener(\"mousewheel\", this._boundWheel, wheelOptions);\n else // Remaining browser and older Firefox\n this.target.addEventListener(\"MozMousePixelScroll\", this._boundWheel, wheelOptions);\n const grabWindowFocus = (_a = options === null || options === void 0 ? void 0 : options.grabWindowFocus) !== null && _a !== void 0 ? _a : true;\n // Handle cross origin iframe\n if (grabWindowFocus && isCrossOriginIframe()) {\n const grabFocus = ()=>{\n window.focus();\n };\n // Preferred pointer events\n if (window.PointerEvent) this.target.addEventListener(\"pointerdown\", grabFocus);\n else {\n // Touch Events\n this.target.addEventListener(\"touchstart\", grabFocus);\n // Mouse Events\n this.target.addEventListener(\"mousedown\", grabFocus);\n }\n }\n }\n detach() {\n // Preferred pointer events\n if (window.PointerEvent) {\n this.target.removeEventListener(\"pointerdown\", this._boundHandle);\n this.target.removeEventListener(\"pointerup\", this._boundHandle);\n this.target.removeEventListener(\"pointermove\", this._boundHandle);\n this.target.removeEventListener(\"pointercancel\", this._boundHandle);\n } else {\n // Touch Events\n this.target.removeEventListener(\"touchstart\", this._boundHandle);\n this.target.removeEventListener(\"touchend\", this._boundHandle);\n this.target.removeEventListener(\"touchmove\", this._boundHandle);\n this.target.removeEventListener(\"touchcancel\", this._boundHandle);\n // Mouse Events\n this.target.removeEventListener(\"mousedown\", this._boundHandle);\n this.target.removeEventListener(\"mouseup\", this._boundHandle);\n this.target.removeEventListener(\"mousemove\", this._boundHandle);\n }\n if (\"onwheel\" in document.createElement(\"div\")) // Modern Browsers\n this.target.removeEventListener(\"wheel\", this._boundWheel);\n else if (document.onmousewheel !== undefined) // Webkit and IE\n this.target.addEventListener(\"mousewheel\", this._boundWheel);\n else // Remaining browser and older Firefox\n this.target.addEventListener(\"MozMousePixelScroll\", this._boundWheel);\n }\n /**\r\n * Take native pointer id and map it to index in active pointers\r\n * @param nativePointerId\r\n */ _normalizePointerId(nativePointerId) {\n // Add to the the native pointer set id\n this._activeNativePointerIdsToNormalized.set(nativePointerId, -1);\n // Native pointer ids in ascending order\n const currentPointerIds = Array.from(this._activeNativePointerIdsToNormalized.keys()).sort((a, b)=>a - b);\n // The index into sorted ids will be the new id, will always have an id\n const id = currentPointerIds.findIndex((p)=>p === nativePointerId);\n // Save the mapping so we can reverse it later\n this._activeNativePointerIdsToNormalized.set(nativePointerId, id);\n // ignore pointer because game isn't watching\n return id;\n }\n /**\r\n * Responsible for handling and parsing pointer events\r\n */ _handle(ev) {\n ev.preventDefault();\n const eventCoords = new Map();\n let button;\n let pointerType;\n if (isTouchEvent(ev)) {\n button = PointerButton.Unknown;\n pointerType = PointerType.Touch;\n // https://developer.mozilla.org/en-US/docs/Web/API/TouchEvent\n for(let i = 0; i < ev.changedTouches.length; i++){\n const touch = ev.changedTouches[i];\n const coordinates = GlobalCoordinates.fromPagePosition(touch.pageX, touch.pageY, this.engine);\n const nativePointerId = i + 1;\n const pointerId = this._normalizePointerId(nativePointerId);\n this.currentFramePointerCoords.set(pointerId, coordinates);\n eventCoords.set(pointerId, coordinates);\n }\n } else {\n button = this._nativeButtonToPointerButton(ev.button);\n pointerType = PointerType.Mouse;\n const coordinates = GlobalCoordinates.fromPagePosition(ev.pageX, ev.pageY, this.engine);\n let nativePointerId = 1;\n if (isPointerEvent(ev)) {\n nativePointerId = ev.pointerId;\n pointerType = this._stringToPointerType(ev.pointerType);\n }\n const pointerId = this._normalizePointerId(nativePointerId);\n this.currentFramePointerCoords.set(pointerId, coordinates);\n eventCoords.set(pointerId, coordinates);\n }\n for (const [pointerId, coord] of eventCoords.entries())switch(ev.type){\n case \"mousedown\":\n case \"pointerdown\":\n case \"touchstart\":\n this.currentFrameDown.push(new PointerEvent(\"down\", pointerId, button, pointerType, coord, ev));\n this.currentFramePointerDown.set(pointerId, true);\n break;\n case \"mouseup\":\n case \"pointerup\":\n case \"touchend\":\n this.currentFrameUp.push(new PointerEvent(\"up\", pointerId, button, pointerType, coord, ev));\n this.currentFramePointerDown.set(pointerId, false);\n break;\n case \"mousemove\":\n case \"pointermove\":\n case \"touchmove\":\n this.currentFrameMove.push(new PointerEvent(\"move\", pointerId, button, pointerType, coord, ev));\n break;\n case \"touchcancel\":\n case \"pointercancel\":\n this.currentFrameCancel.push(new PointerEvent(\"cancel\", pointerId, button, pointerType, coord, ev));\n break;\n }\n }\n _handleWheel(ev) {\n // Should we prevent page scroll because of this event\n if (this.engine.pageScrollPreventionMode === ScrollPreventionMode.All || this.engine.pageScrollPreventionMode === ScrollPreventionMode.Canvas && ev.target === this.engine.canvas) ev.preventDefault();\n const screen = this.engine.screen.pageToScreenCoordinates(vec(ev.pageX, ev.pageY));\n const world = this.engine.screen.screenToWorldCoordinates(screen);\n /**\r\n * A constant used to normalize wheel events across different browsers\r\n *\r\n * This normalization factor is pulled from\r\n * https://developer.mozilla.org/en-US/docs/Web/Events/wheel#Listening_to_this_event_across_browser\r\n */ const ScrollWheelNormalizationFactor = -1 / 40;\n const deltaX = ev.deltaX || ev.wheelDeltaX * ScrollWheelNormalizationFactor || 0;\n const deltaY = ev.deltaY || ev.wheelDeltaY * ScrollWheelNormalizationFactor || ev.wheelDelta * ScrollWheelNormalizationFactor || ev.detail || 0;\n const deltaZ = ev.deltaZ || 0;\n let deltaMode = WheelDeltaMode.Pixel;\n if (ev.deltaMode) {\n if (ev.deltaMode === 1) deltaMode = WheelDeltaMode.Line;\n else if (ev.deltaMode === 2) deltaMode = WheelDeltaMode.Page;\n }\n const we = new WheelEvent(world.x, world.y, ev.pageX, ev.pageY, screen.x, screen.y, 0, deltaX, deltaY, deltaZ, deltaMode, ev);\n this.currentFrameWheel.push(we);\n }\n /**\r\n * Triggers an excalibur pointer event in a world space pos\r\n *\r\n * Useful for testing pointers in excalibur\r\n * @param type\r\n * @param pos\r\n */ triggerEvent(type, pos) {\n const page = this.engine.screen.worldToPageCoordinates(pos);\n // Send an event to the event receiver\n if (window.PointerEvent) this._handle(new window.PointerEvent(\"pointer\" + type, {\n pointerId: 0,\n clientX: page.x,\n clientY: page.y\n }));\n else // Safari hack\n this._handle(new window.MouseEvent(\"mouse\" + type, {\n clientX: page.x,\n clientY: page.y\n }));\n // Force update pointer system\n const pointerSystem = this.engine.currentScene.world.systemManager.get(PointerSystem);\n const transformEntities = this.engine.currentScene.world.queryManager.createQuery(pointerSystem.types);\n pointerSystem.preupdate();\n pointerSystem.update(transformEntities.getEntities());\n }\n _nativeButtonToPointerButton(s) {\n switch(s){\n case NativePointerButton.NoButton:\n return PointerButton.NoButton;\n case NativePointerButton.Left:\n return PointerButton.Left;\n case NativePointerButton.Middle:\n return PointerButton.Middle;\n case NativePointerButton.Right:\n return PointerButton.Right;\n case NativePointerButton.Unknown:\n return PointerButton.Unknown;\n default:\n return fail(s);\n }\n }\n _stringToPointerType(s) {\n switch(s){\n case \"touch\":\n return PointerType.Touch;\n case \"mouse\":\n return PointerType.Mouse;\n case \"pen\":\n return PointerType.Pen;\n default:\n return PointerType.Unknown;\n }\n }\n }\n class FpsSampler {\n constructor(options){\n var _a;\n this._samplePeriod = 100;\n this._currentFrameTime = 0;\n this._frames = 0;\n this._previousSampleTime = 0;\n this._beginFrameTime = 0;\n this._fps = options.initialFps;\n this._samplePeriod = (_a = options.samplePeriod) !== null && _a !== void 0 ? _a : this._samplePeriod;\n this._currentFrameTime = 1000 / options.initialFps;\n this._nowFn = options.nowFn;\n this._previousSampleTime = this._nowFn();\n }\n /**\r\n * Start of code block to sample FPS for\r\n */ start() {\n this._beginFrameTime = this._nowFn();\n }\n /**\r\n * End of code block to sample FPS for\r\n */ end() {\n this._frames++;\n const time = this._nowFn();\n this._currentFrameTime = time - this._beginFrameTime;\n if (time >= this._previousSampleTime + this._samplePeriod) {\n this._fps = this._frames * 1000 / (time - this._previousSampleTime);\n this._previousSampleTime = time;\n this._frames = 0;\n }\n }\n /**\r\n * Return the currently sampled fps over the last sample period, by default every 100ms\r\n */ get fps() {\n return this._fps;\n }\n /**\r\n * Return the instantaneous fps, this can be less useful because it will fluctuate given the current frames time\r\n */ get instant() {\n return 1000 / this._currentFrameTime;\n }\n }\n /**\r\n * Abstract Clock is the base type of all Clocks\r\n *\r\n * It has a few opinions\r\n * 1. It manages the calculation of what \"elapsed\" time means and thus maximum fps\r\n * 2. The default timing api is implemented in now()\r\n *\r\n * To implement your own clock, extend Clock and override start/stop to start and stop the clock, then call update() with whatever\r\n * method is unique to your clock implementation.\r\n */ class Clock {\n constructor(options){\n var _a, _b, _c;\n this._onFatalException = ()=>{};\n this._maxFps = Infinity;\n this._lastTime = 0;\n this._elapsed = 1;\n this._scheduledCbs = [];\n this._totalElapsed = 0;\n this._options = options;\n this.tick = options.tick;\n this._lastTime = (_a = this.now()) !== null && _a !== void 0 ? _a : 0;\n this._maxFps = (_b = options.maxFps) !== null && _b !== void 0 ? _b : this._maxFps;\n this._onFatalException = (_c = options.onFatalException) !== null && _c !== void 0 ? _c : this._onFatalException;\n this.fpsSampler = new FpsSampler({\n initialFps: 60,\n nowFn: ()=>this.now()\n });\n }\n /**\r\n * Get the elapsed time for the last completed frame\r\n */ elapsed() {\n return this._elapsed;\n }\n /**\r\n * Get the current time in milliseconds\r\n */ now() {\n return performance.now();\n }\n toTestClock() {\n const testClock = new TestClock({\n ...this._options,\n defaultUpdateMs: 16.6\n });\n return testClock;\n }\n toStandardClock() {\n const clock = new StandardClock({\n ...this._options\n });\n return clock;\n }\n setFatalExceptionHandler(handler) {\n this._onFatalException = handler;\n }\n /**\r\n * Schedule a callback to fire given a timeout in milliseconds using the excalibur [[Clock]]\r\n *\r\n * This is useful to use over the built in browser `setTimeout` because callbacks will be tied to the\r\n * excalibur update clock, instead of browser time, this means that callbacks wont fire if the game is\r\n * stopped or paused.\r\n *\r\n * @param cb callback to fire\r\n * @param timeoutMs Optionally specify a timeout in milliseconds from now, default is 0ms which means the next possible tick\r\n */ schedule(cb, timeoutMs = 0) {\n // Scheduled based on internal elapsed time\n const scheduledTime = this._totalElapsed + timeoutMs;\n this._scheduledCbs.push([\n cb,\n scheduledTime\n ]);\n }\n _runScheduledCbs() {\n // walk backwards to delete items as we loop\n for(let i = this._scheduledCbs.length - 1; i > -1; i--)if (this._scheduledCbs[i][1] <= this._totalElapsed) {\n this._scheduledCbs[i][0]();\n this._scheduledCbs.splice(i, 1);\n }\n }\n update(overrideUpdateMs) {\n try {\n this.fpsSampler.start();\n // Get the time to calculate time-elapsed\n const now = this.now();\n let elapsed = now - this._lastTime || 1; // first frame\n // Constrain fps\n const fpsInterval = 1000 / this._maxFps;\n // only run frame if enough time has elapsed\n if (elapsed >= fpsInterval) {\n let leftover = 0;\n if (fpsInterval !== 0) {\n leftover = elapsed % fpsInterval;\n elapsed = elapsed - leftover; // shift elapsed to be \"in phase\" with the current loop fps\n }\n // Resolves issue #138 if the game has been paused, or blurred for\n // more than a 200 milliseconds, reset elapsed time to 1. This improves reliability\n // and provides more expected behavior when the engine comes back\n // into focus\n if (elapsed > 200) elapsed = 1;\n // tick the mainloop and run scheduled callbacks\n this._elapsed = overrideUpdateMs || elapsed;\n this._totalElapsed += this._elapsed;\n this._runScheduledCbs();\n this.tick(overrideUpdateMs || elapsed);\n if (fpsInterval !== 0) this._lastTime = now - leftover;\n else this._lastTime = now;\n this.fpsSampler.end();\n }\n } catch (e) {\n this._onFatalException(e);\n this.stop();\n }\n }\n }\n /**\r\n * The [[StandardClock]] implements the requestAnimationFrame browser api to run the tick()\r\n */ class StandardClock extends Clock {\n constructor(options){\n super(options);\n this._running = false;\n }\n isRunning() {\n return this._running;\n }\n start() {\n if (this._running) return;\n this._running = true;\n const mainloop = ()=>{\n // stop the loop\n if (!this._running) return;\n try {\n // request next loop\n this._requestId = window.requestAnimationFrame(mainloop);\n this.update();\n } catch (e) {\n window.cancelAnimationFrame(this._requestId);\n throw e;\n }\n };\n // begin the first frame\n mainloop();\n }\n stop() {\n this._running = false;\n }\n }\n /**\r\n * The TestClock is meant for debugging interactions in excalibur that require precise timing to replicate or test\r\n */ class TestClock extends Clock {\n constructor(options){\n super({\n ...options\n });\n this._logger = Logger.getInstance();\n this._running = false;\n this._currentTime = 0;\n this._updateMs = options.defaultUpdateMs;\n }\n /**\r\n * Get the current time in milliseconds\r\n */ now() {\n var _a;\n return (_a = this._currentTime) !== null && _a !== void 0 ? _a : 0;\n }\n isRunning() {\n return this._running;\n }\n start() {\n this._running = true;\n }\n stop() {\n this._running = false;\n }\n /**\r\n * Manually step the clock forward 1 tick, optionally specify an elapsed time in milliseconds\r\n * @param overrideUpdateMs\r\n */ step(overrideUpdateMs) {\n const time = overrideUpdateMs !== null && overrideUpdateMs !== void 0 ? overrideUpdateMs : this._updateMs;\n if (this._running) {\n // to be comparable to RAF this needs to be a full blown Task\n // For example, images cannot decode synchronously in a single step\n this.update(time);\n this._currentTime += time;\n } else this._logger.warn(\"The clock is not running, no step will be performed\");\n }\n /**\r\n * Run a number of steps that tick the clock, optionally specify an elapsed time in milliseconds\r\n * @param numberOfSteps\r\n * @param overrideUpdateMs\r\n */ run(numberOfSteps, overrideUpdateMs) {\n for(let i = 0; i < numberOfSteps; i++)this.step(overrideUpdateMs !== null && overrideUpdateMs !== void 0 ? overrideUpdateMs : this._updateMs);\n }\n }\n // EXTERNAL MODULE: ./Util/Toaster.css\n var Util_Toaster = $2c23f148d58cd887$var$__webpack_require__(7379);\n /**\r\n * The Toaster is only meant to be called from inside Excalibur to display messages to players\r\n */ class Toaster {\n constructor(){\n this._toasterCss = Util_Toaster /* default */ .Z.toString();\n this._isInitialized = false;\n }\n _initialize() {\n if (!this._isInitialized) {\n this._container = document.createElement(\"div\");\n this._container.id = \"ex-toast-container\";\n document.body.appendChild(this._container);\n this._isInitialized = true;\n this._styleBlock = document.createElement(\"style\");\n this._styleBlock.textContent = this._toasterCss;\n document.head.appendChild(this._styleBlock);\n }\n }\n dispose() {\n this._container.parentElement.removeChild(this._container);\n this._styleBlock.parentElement.removeChild(this._styleBlock);\n this._isInitialized = false;\n }\n _createFragment(message) {\n const toastMessage = document.createElement(\"span\");\n toastMessage.innerText = message;\n return toastMessage;\n }\n /**\r\n * Display a toast message to a player\r\n * @param message Text of the message, messages may have a single \"[LINK]\" to influence placement\r\n * @param linkTarget Optionally specify a link location\r\n * @param linkName Optionally specify a name for that link location\r\n */ toast(message, linkTarget, linkName) {\n this._initialize();\n const toast = document.createElement(\"div\");\n toast.className = \"ex-toast-message\";\n const messageFragments = message.split(\"[LINK]\").map((message)=>this._createFragment(message));\n if (linkTarget) {\n const link = document.createElement(\"a\");\n link.href = linkTarget;\n if (linkName) link.innerText = linkName;\n else link.innerText = linkTarget;\n messageFragments.splice(1, 0, link);\n }\n // Assembly message\n const finalMessage = document.createElement(\"div\");\n messageFragments.forEach((message)=>{\n finalMessage.appendChild(message);\n });\n toast.appendChild(finalMessage);\n // Dismiss button\n const dismissBtn = document.createElement(\"button\");\n dismissBtn.innerText = \"x\";\n dismissBtn.addEventListener(\"click\", ()=>{\n this._container.removeChild(toast);\n });\n toast.appendChild(dismissBtn);\n // Escape to dismiss\n const keydownHandler = (evt)=>{\n if (evt.key === \"Escape\") try {\n this._container.removeChild(toast);\n } catch (_a) {\n // pass\n }\n document.removeEventListener(\"keydown\", keydownHandler);\n };\n document.addEventListener(\"keydown\", keydownHandler);\n // Insert into container\n const first = this._container.firstChild;\n this._container.insertBefore(toast, first);\n }\n }\n /**\r\n * This allows you to map multiple inputs to specific commands! This is especially useful when\r\n * you need to allow multiple input sources to control a specific action.\r\n */ class InputMapper {\n constructor(inputs){\n this.inputs = inputs;\n this._handlers = new Map();\n }\n /**\r\n * Executes the input map, called internally by Excalibur\r\n */ execute() {\n for (const [input, command] of this._handlers.entries()){\n const results = input(this.inputs);\n if (results) command(results);\n }\n }\n /**\r\n * This allows you to map multiple inputs to specific commands! This is useful\r\n *\r\n * The inputHandler should return a truthy value if you wish the commandHandler to fire.\r\n *\r\n * Example:\r\n * ```typescript\r\n * const moveRight = (amount: number) => { actor.vel.x = 100 * amount }\r\n * const moveLeft = (amount: number) => { actor.vel.x = -100 * amount }\r\n * const moveUp = (amount: number) => { actor.vel.y = -100 * amount }\r\n * const moveDown = (amount: number) => { actor.vel.y = 100 * amount }\r\n *\r\n * engine.inputMapper.on(({keyboard}) => keyboard.isHeld(ex.Keys.ArrowRight) ? 1 : 0, moveRight);\r\n * engine.inputMapper.on(({gamepads}) => gamepads.at(0).isButtonPressed(ex.Buttons.DpadRight) ? 1 : 0, moveRight);\r\n * engine.inputMapper.on(({gamepads}) => gamepads.at(0).getAxes(ex.Axes.LeftStickX) > 0 ?\r\n * gamepads.at(0).getAxes(ex.Axes.LeftStickX) : 0, moveRight);\r\n * ```\r\n * @param inputHandler\r\n * @param commandHandler\r\n */ on(inputHandler, commandHandler) {\n this._handlers.set(inputHandler, commandHandler);\n }\n }\n polyfill();\n const EngineEvents = {\n FallbackGraphicsContext: \"fallbackgraphicscontext\",\n Initialize: \"initialize\",\n Visible: \"visible\",\n Hidden: \"hidden\",\n Start: \"start\",\n Stop: \"stop\",\n PreUpdate: \"preupdate\",\n PostUpdate: \"postupdate\",\n PreFrame: \"preframe\",\n PostFrame: \"postframe\",\n PreDraw: \"predraw\",\n PostDraw: \"postdraw\"\n };\n /**\r\n * Enum representing the different mousewheel event bubble prevention\r\n */ var ScrollPreventionMode;\n (function(ScrollPreventionMode) {\n /**\r\n * Do not prevent any page scrolling\r\n */ ScrollPreventionMode[ScrollPreventionMode[\"None\"] = 0] = \"None\";\n /**\r\n * Prevent page scroll if mouse is over the game canvas\r\n */ ScrollPreventionMode[ScrollPreventionMode[\"Canvas\"] = 1] = \"Canvas\";\n /**\r\n * Prevent all page scrolling via mouse wheel\r\n */ ScrollPreventionMode[ScrollPreventionMode[\"All\"] = 2] = \"All\";\n })(ScrollPreventionMode || (ScrollPreventionMode = {}));\n /**\r\n * The Excalibur Engine\r\n *\r\n * The [[Engine]] is the main driver for a game. It is responsible for\r\n * starting/stopping the game, maintaining state, transmitting events,\r\n * loading resources, and managing the scene.\r\n */ class Engine {\n /**\r\n * The width of the game canvas in pixels (physical width component of the\r\n * resolution of the canvas element)\r\n */ get canvasWidth() {\n return this.screen.canvasWidth;\n }\n /**\r\n * Returns half width of the game canvas in pixels (half physical width component)\r\n */ get halfCanvasWidth() {\n return this.screen.halfCanvasWidth;\n }\n /**\r\n * The height of the game canvas in pixels, (physical height component of\r\n * the resolution of the canvas element)\r\n */ get canvasHeight() {\n return this.screen.canvasHeight;\n }\n /**\r\n * Returns half height of the game canvas in pixels (half physical height component)\r\n */ get halfCanvasHeight() {\n return this.screen.halfCanvasHeight;\n }\n /**\r\n * Returns the width of the engine's visible drawing surface in pixels including zoom and device pixel ratio.\r\n */ get drawWidth() {\n return this.screen.drawWidth;\n }\n /**\r\n * Returns half the width of the engine's visible drawing surface in pixels including zoom and device pixel ratio.\r\n */ get halfDrawWidth() {\n return this.screen.halfDrawWidth;\n }\n /**\r\n * Returns the height of the engine's visible drawing surface in pixels including zoom and device pixel ratio.\r\n */ get drawHeight() {\n return this.screen.drawHeight;\n }\n /**\r\n * Returns half the height of the engine's visible drawing surface in pixels including zoom and device pixel ratio.\r\n */ get halfDrawHeight() {\n return this.screen.halfDrawHeight;\n }\n /**\r\n * Returns whether excalibur detects the current screen to be HiDPI\r\n */ get isHiDpi() {\n return this.screen.isHiDpi;\n }\n /**\r\n * Access [[stats]] that holds frame statistics.\r\n */ get stats() {\n return this.debug.stats;\n }\n /**\r\n * Indicates whether the engine is set to fullscreen or not\r\n */ get isFullscreen() {\n return this.screen.isFullScreen;\n }\n /**\r\n * Indicates the current [[DisplayMode]] of the engine.\r\n */ get displayMode() {\n return this.screen.displayMode;\n }\n /**\r\n * Returns the calculated pixel ration for use in rendering\r\n */ get pixelRatio() {\n return this.screen.pixelRatio;\n }\n get isDebug() {\n return this._isDebug;\n }\n /**\r\n * Hints the graphics context to truncate fractional world space coordinates\r\n */ get snapToPixel() {\n return this.graphicsContext.snapToPixel;\n }\n set snapToPixel(shouldSnapToPixel) {\n this.graphicsContext.snapToPixel = shouldSnapToPixel;\n }\n emit(eventName, event) {\n this.events.emit(eventName, event);\n }\n on(eventName, handler) {\n return this.events.on(eventName, handler);\n }\n once(eventName, handler) {\n return this.events.once(eventName, handler);\n }\n off(eventName, handler) {\n this.events.off(eventName, handler);\n }\n /**\r\n * Creates a new game using the given [[EngineOptions]]. By default, if no options are provided,\r\n * the game will be rendered full screen (taking up all available browser window space).\r\n * You can customize the game rendering through [[EngineOptions]].\r\n *\r\n * Example:\r\n *\r\n * ```js\r\n * var game = new ex.Engine({\r\n * width: 0, // the width of the canvas\r\n * height: 0, // the height of the canvas\r\n * enableCanvasTransparency: true, // the transparencySection of the canvas\r\n * canvasElementId: '', // the DOM canvas element ID, if you are providing your own\r\n * displayMode: ex.DisplayMode.FullScreen, // the display mode\r\n * pointerScope: ex.PointerScope.Document, // the scope of capturing pointer (mouse/touch) events\r\n * backgroundColor: ex.Color.fromHex('#2185d0') // background color of the engine\r\n * });\r\n *\r\n * // call game.start, which is a Promise\r\n * game.start().then(function () {\r\n * // ready, set, go!\r\n * });\r\n * ```\r\n */ constructor(options){\n var _a, _b, _c, _d, _e, _f;\n /**\r\n * Listen to and emit events on the Engine\r\n */ this.events = new EventEmitter();\n /**\r\n * Optionally set the maximum fps if not set Excalibur will go as fast as the device allows.\r\n *\r\n * You may want to constrain max fps if your game cannot maintain fps consistently, it can look and feel better to have a 30fps game than\r\n * one that bounces between 30fps and 60fps\r\n */ this.maxFps = Number.POSITIVE_INFINITY;\n /**\r\n * Contains all the scenes currently registered with Excalibur\r\n */ this.scenes = {};\n this._suppressPlayButton = false;\n /**\r\n * Indicates whether audio should be paused when the game is no longer visible.\r\n */ this.pauseAudioWhenHidden = true;\n /**\r\n * Indicates whether the engine should draw with debug information\r\n */ this._isDebug = false;\n /**\r\n * Sets the Transparency for the engine.\r\n */ this.enableCanvasTransparency = true;\n /**\r\n * The action to take when a fatal exception is thrown\r\n */ this.onFatalException = (e)=>{\n Logger.getInstance().fatal(e);\n };\n this._toaster = new Toaster();\n this._timescale = 1.0;\n this._isInitialized = false;\n this._deferredGoTo = null;\n this._originalOptions = {};\n this._performanceThresholdTriggered = false;\n this._fpsSamples = [];\n this._loadingComplete = false;\n this._isReady = false;\n this._isReadyPromise = new Promise((resolve)=>{\n this._isReadyResolve = resolve;\n });\n /**\r\n * Returns the current frames elapsed milliseconds\r\n */ this.currentFrameElapsedMs = 0;\n /**\r\n * Returns the current frame lag when in fixed update mode\r\n */ this.currentFrameLagMs = 0;\n this._lagMs = 0;\n this._screenShotRequests = [];\n options = {\n ...Engine._DEFAULT_ENGINE_OPTIONS,\n ...options\n };\n this._originalOptions = options;\n Flags.freeze();\n // Initialize browser events facade\n this.browser = new BrowserEvents(window, document);\n // Check compatibility\n const detector = new Detector();\n if (!options.suppressMinimumBrowserFeatureDetection && !(this._compatible = detector.test())) {\n const message = document.createElement(\"div\");\n message.innerText = \"Sorry, your browser does not support all the features needed for Excalibur\";\n document.body.appendChild(message);\n detector.failedTests.forEach(function(test) {\n const testMessage = document.createElement(\"div\");\n testMessage.innerText = \"Browser feature missing \" + test;\n document.body.appendChild(testMessage);\n });\n if (options.canvasElementId) {\n const canvas = document.getElementById(options.canvasElementId);\n if (canvas) canvas.parentElement.removeChild(canvas);\n }\n return;\n } else this._compatible = true;\n // Use native console API for color fun\n // eslint-disable-next-line no-console\n if (console.log && !options.suppressConsoleBootMessage) {\n // eslint-disable-next-line no-console\n console.log(`%cPowered by Excalibur.js (v${EX_VERSION})`, \"background: #176BAA; color: white; border-radius: 5px; padding: 15px; font-size: 1.5em; line-height: 80px;\");\n // eslint-disable-next-line no-console\n console.log(\"\\n /| ________________\\nO|===|* >________________>\\n \\\\|\");\n // eslint-disable-next-line no-console\n console.log(\"Visit\", \"http://excaliburjs.com\", \"for more information\");\n }\n // Suppress play button\n if (options.suppressPlayButton) this._suppressPlayButton = true;\n this._logger = Logger.getInstance();\n // If debug is enabled, let's log browser features to the console.\n if (this._logger.defaultLevel === LogLevel.Debug) detector.logBrowserFeatures();\n this._logger.debug(\"Building engine...\");\n this.canvasElementId = options.canvasElementId;\n if (options.canvasElementId) {\n this._logger.debug(\"Using Canvas element specified: \" + options.canvasElementId);\n this.canvas = document.getElementById(options.canvasElementId);\n } else if (options.canvasElement) {\n this._logger.debug(\"Using Canvas element specified:\", options.canvasElement);\n this.canvas = options.canvasElement;\n } else {\n this._logger.debug(\"Using generated canvas element\");\n this.canvas = document.createElement(\"canvas\");\n }\n let displayMode = (_a = options.displayMode) !== null && _a !== void 0 ? _a : DisplayMode.Fixed;\n if (options.width && options.height || options.viewport) {\n if (options.displayMode === undefined) displayMode = DisplayMode.Fixed;\n this._logger.debug(\"Engine viewport is size \" + options.width + \" x \" + options.height);\n } else if (!options.displayMode) {\n this._logger.debug(\"Engine viewport is fit\");\n displayMode = DisplayMode.FitScreen;\n }\n this._originalDisplayMode = displayMode;\n // Canvas 2D fallback can be flagged on\n let useCanvasGraphicsContext = Flags.isEnabled(\"use-canvas-context\");\n if (!useCanvasGraphicsContext) // Attempt webgl first\n try {\n this.graphicsContext = new ExcaliburGraphicsContextWebGL({\n canvasElement: this.canvas,\n enableTransparency: this.enableCanvasTransparency,\n smoothing: options.antialiasing,\n backgroundColor: options.backgroundColor,\n snapToPixel: options.snapToPixel,\n useDrawSorting: options.useDrawSorting\n });\n } catch (e) {\n this._logger.warn(`Excalibur could not load webgl for some reason (${e.message}) and loaded a Canvas 2D fallback. ` + `Some features of Excalibur will not work in this mode. \\n\\n` + \"Read more about this issue at https://excaliburjs.com/docs/webgl\");\n // fallback to canvas in case of failure\n useCanvasGraphicsContext = true;\n }\n if (useCanvasGraphicsContext) this.graphicsContext = new ExcaliburGraphicsContext2DCanvas({\n canvasElement: this.canvas,\n enableTransparency: this.enableCanvasTransparency,\n smoothing: options.antialiasing,\n backgroundColor: options.backgroundColor,\n snapToPixel: options.snapToPixel,\n useDrawSorting: options.useDrawSorting\n });\n this.screen = new Screen({\n canvas: this.canvas,\n context: this.graphicsContext,\n antialiasing: (_b = options.antialiasing) !== null && _b !== void 0 ? _b : true,\n browser: this.browser,\n viewport: (_c = options.viewport) !== null && _c !== void 0 ? _c : options.width && options.height ? {\n width: options.width,\n height: options.height\n } : Resolution.SVGA,\n resolution: options.resolution,\n displayMode: displayMode,\n pixelRatio: options.suppressHiDPIScaling ? 1 : (_d = options.pixelRatio) !== null && _d !== void 0 ? _d : null\n });\n // Set default filtering based on antialiasing\n TextureLoader.filtering = options.antialiasing ? ImageFiltering.Blended : ImageFiltering.Pixel;\n if (options.backgroundColor) this.backgroundColor = options.backgroundColor.clone();\n this.maxFps = (_e = options.maxFps) !== null && _e !== void 0 ? _e : this.maxFps;\n this.fixedUpdateFps = (_f = options.fixedUpdateFps) !== null && _f !== void 0 ? _f : this.fixedUpdateFps;\n this.clock = new StandardClock({\n maxFps: this.maxFps,\n tick: this._mainloop.bind(this),\n onFatalException: (e)=>this.onFatalException(e)\n });\n this.enableCanvasTransparency = options.enableCanvasTransparency;\n this._loader = new Loader();\n this._loader.wireEngine(this);\n this.debug = new Debug(this);\n this._initialize(options);\n this.rootScene = this.currentScene = new Scene();\n this.addScene(\"root\", this.rootScene);\n window.___EXCALIBUR_DEVTOOL = this;\n }\n _monitorPerformanceThresholdAndTriggerFallback() {\n const { allow: allow } = this._originalOptions.configurePerformanceCanvas2DFallback;\n let { threshold: threshold, showPlayerMessage: showPlayerMessage } = this._originalOptions.configurePerformanceCanvas2DFallback;\n if (threshold === undefined) threshold = Engine._DEFAULT_ENGINE_OPTIONS.configurePerformanceCanvas2DFallback.threshold;\n if (showPlayerMessage === undefined) showPlayerMessage = Engine._DEFAULT_ENGINE_OPTIONS.configurePerformanceCanvas2DFallback.showPlayerMessage;\n if (!Flags.isEnabled(\"use-canvas-context\") && allow && this.ready && !this._performanceThresholdTriggered) {\n // Calculate Average fps for last X number of frames after start\n if (this._fpsSamples.length === threshold.numberOfFrames) this._fpsSamples.splice(0, 1);\n this._fpsSamples.push(this.clock.fpsSampler.fps);\n let total = 0;\n for(let i = 0; i < this._fpsSamples.length; i++)total += this._fpsSamples[i];\n const average = total / this._fpsSamples.length;\n if (this._fpsSamples.length === threshold.numberOfFrames) {\n if (average <= threshold.fps) {\n this._performanceThresholdTriggered = true;\n this._logger.warn(`Switching to browser 2D Canvas fallback due to performance. Some features of Excalibur will not work in this mode.\\n` + \"this might mean your browser doesn't have webgl enabled or hardware acceleration is unavailable.\\n\\n\" + \"If in Chrome:\\n\" + ' * Visit Settings > Advanced > System, and ensure \"Use Hardware Acceleration\" is checked.\\n' + ' * Visit chrome://flags/#ignore-gpu-blocklist and ensure \"Override software rendering list\" is \"enabled\"\\n' + \"If in Firefox, visit about:config\\n\" + \" * Ensure webgl.disabled = false\\n\" + \" * Ensure webgl.force-enabled = true\\n\" + \" * Ensure layers.acceleration.force-enabled = true\\n\\n\" + \"Read more about this issue at https://excaliburjs.com/docs/performance\");\n if (showPlayerMessage) this._toaster.toast(\"Excalibur is encountering performance issues. It's possible that your browser doesn't have hardware acceleration enabled. Visit [LINK] for more information and potential solutions.\", \"https://excaliburjs.com/docs/performance\");\n this.useCanvas2DFallback();\n this.emit(\"fallbackgraphicscontext\", this.graphicsContext);\n }\n }\n }\n }\n /**\r\n * Switches the engine's graphics context to the 2D Canvas.\r\n * @warning Some features of Excalibur will not work in this mode.\r\n */ useCanvas2DFallback() {\n var _a, _b, _c;\n // Swap out the canvas\n const newCanvas = this.canvas.cloneNode(false);\n this.canvas.parentNode.replaceChild(newCanvas, this.canvas);\n this.canvas = newCanvas;\n const options = this._originalOptions;\n const displayMode = this._originalDisplayMode;\n // New graphics context\n this.graphicsContext = new ExcaliburGraphicsContext2DCanvas({\n canvasElement: this.canvas,\n enableTransparency: this.enableCanvasTransparency,\n smoothing: options.antialiasing,\n backgroundColor: options.backgroundColor,\n snapToPixel: options.snapToPixel,\n useDrawSorting: options.useDrawSorting\n });\n // Reset screen\n if (this.screen) this.screen.dispose();\n this.screen = new Screen({\n canvas: this.canvas,\n context: this.graphicsContext,\n antialiasing: (_a = options.antialiasing) !== null && _a !== void 0 ? _a : true,\n browser: this.browser,\n viewport: (_b = options.viewport) !== null && _b !== void 0 ? _b : options.width && options.height ? {\n width: options.width,\n height: options.height\n } : Resolution.SVGA,\n resolution: options.resolution,\n displayMode: displayMode,\n pixelRatio: options.suppressHiDPIScaling ? 1 : (_c = options.pixelRatio) !== null && _c !== void 0 ? _c : null\n });\n this.screen.setCurrentCamera(this.currentScene.camera);\n // Reset pointers\n this.input.pointers.detach();\n const pointerTarget = options && options.pointerScope === PointerScope.Document ? document : this.canvas;\n this.input.pointers = this.input.pointers.recreate(pointerTarget, this);\n this.input.pointers.init();\n }\n /**\r\n * Returns a BoundingBox of the top left corner of the screen\r\n * and the bottom right corner of the screen.\r\n */ getWorldBounds() {\n return this.screen.getWorldBounds();\n }\n /**\r\n * Gets the current engine timescale factor (default is 1.0 which is 1:1 time)\r\n */ get timescale() {\n return this._timescale;\n }\n /**\r\n * Sets the current engine timescale factor. Useful for creating slow-motion effects or fast-forward effects\r\n * when using time-based movement.\r\n */ set timescale(value) {\n if (value <= 0) {\n Logger.getInstance().error(\"Cannot set engine.timescale to a value of 0 or less than 0.\");\n return;\n }\n this._timescale = value;\n }\n /**\r\n * Adds a [[Timer]] to the [[currentScene]].\r\n * @param timer The timer to add to the [[currentScene]].\r\n */ addTimer(timer) {\n return this.currentScene.addTimer(timer);\n }\n /**\r\n * Removes a [[Timer]] from the [[currentScene]].\r\n * @param timer The timer to remove to the [[currentScene]].\r\n */ removeTimer(timer) {\n return this.currentScene.removeTimer(timer);\n }\n /**\r\n * Adds a [[Scene]] to the engine, think of scenes in Excalibur as you\r\n * would levels or menus.\r\n *\r\n * @param key The name of the scene, must be unique\r\n * @param scene The scene to add to the engine\r\n */ addScene(key, scene) {\n if (this.scenes[key]) this._logger.warn(\"Scene\", key, \"already exists overwriting\");\n this.scenes[key] = scene;\n }\n /**\r\n * @internal\r\n */ removeScene(entity) {\n if (entity instanceof Scene) // remove scene\n for(const key in this.scenes){\n if (this.scenes.hasOwnProperty(key)) {\n if (this.scenes[key] === entity) delete this.scenes[key];\n }\n }\n if (typeof entity === \"string\") // remove scene\n delete this.scenes[entity];\n }\n add(entity) {\n if (arguments.length === 2) {\n this.addScene(arguments[0], arguments[1]);\n return;\n }\n if (this._deferredGoTo && this.scenes[this._deferredGoTo]) this.scenes[this._deferredGoTo].add(entity);\n else this.currentScene.add(entity);\n }\n remove(entity) {\n if (entity instanceof Entity) this.currentScene.remove(entity);\n if (entity instanceof Scene) this.removeScene(entity);\n if (typeof entity === \"string\") this.removeScene(entity);\n }\n /**\r\n * Changes the currently updating and drawing scene to a different,\r\n * named scene. Calls the [[Scene]] lifecycle events.\r\n * @param key The key of the scene to transition to.\r\n * @param data Optional data to send to the scene's onActivate method\r\n */ goToScene(key, data) {\n // if not yet initialized defer goToScene\n if (!this.isInitialized) {\n this._deferredGoTo = key;\n return;\n }\n if (this.scenes[key]) {\n const previousScene = this.currentScene;\n const nextScene = this.scenes[key];\n this._logger.debug(\"Going to scene:\", key);\n // only deactivate when initialized\n if (this.currentScene.isInitialized) {\n const context = {\n engine: this,\n previousScene: previousScene,\n nextScene: nextScene\n };\n this.currentScene._deactivate.apply(this.currentScene, [\n context,\n nextScene\n ]);\n this.currentScene.events.emit(\"deactivate\", new DeactivateEvent(context, this.currentScene));\n }\n // set current scene to new one\n this.currentScene = nextScene;\n this.screen.setCurrentCamera(nextScene.camera);\n // initialize the current scene if has not been already\n this.currentScene._initialize(this);\n const context = {\n engine: this,\n previousScene: previousScene,\n nextScene: nextScene,\n data: data\n };\n this.currentScene._activate.apply(this.currentScene, [\n context,\n nextScene\n ]);\n this.currentScene.events.emit(\"activate\", new ActivateEvent(context, this.currentScene));\n } else this._logger.error(\"Scene\", key, \"does not exist!\");\n }\n /**\r\n * Transforms the current x, y from screen coordinates to world coordinates\r\n * @param point Screen coordinate to convert\r\n */ screenToWorldCoordinates(point) {\n return this.screen.screenToWorldCoordinates(point);\n }\n /**\r\n * Transforms a world coordinate, to a screen coordinate\r\n * @param point World coordinate to convert\r\n */ worldToScreenCoordinates(point) {\n return this.screen.worldToScreenCoordinates(point);\n }\n /**\r\n * Initializes the internal canvas, rendering context, display mode, and native event listeners\r\n */ _initialize(options) {\n var _a, _b, _c, _d;\n this.pageScrollPreventionMode = options.scrollPreventionMode;\n // initialize inputs\n const pointerTarget = options && options.pointerScope === PointerScope.Document ? document : this.canvas;\n this.input = {\n keyboard: new Keyboard(),\n pointers: new PointerEventReceiver(pointerTarget, this),\n gamepads: new Gamepads()\n };\n this.input.keyboard.init({\n grabWindowFocus: (_b = (_a = this._originalOptions) === null || _a === void 0 ? void 0 : _a.grabWindowFocus) !== null && _b !== void 0 ? _b : true\n });\n this.input.pointers.init({\n grabWindowFocus: (_d = (_c = this._originalOptions) === null || _c === void 0 ? void 0 : _c.grabWindowFocus) !== null && _d !== void 0 ? _d : true\n });\n this.input.gamepads.init();\n this.inputMapper = new InputMapper(this.input);\n // Issue #385 make use of the visibility api\n // https://developer.mozilla.org/en-US/docs/Web/Guide/User_experience/Using_the_Page_Visibility_API\n this.browser.document.on(\"visibilitychange\", ()=>{\n if (document.visibilityState === \"hidden\") {\n this.events.emit(\"hidden\", new HiddenEvent(this));\n this._logger.debug(\"Window hidden\");\n } else if (document.visibilityState === \"visible\") {\n this.events.emit(\"visible\", new VisibleEvent(this));\n this._logger.debug(\"Window visible\");\n }\n });\n if (!this.canvasElementId && !options.canvasElement) document.body.appendChild(this.canvas);\n }\n onInitialize(_engine) {\n // Override me\n }\n /**\r\n * If supported by the browser, this will set the antialiasing flag on the\r\n * canvas. Set this to `false` if you want a 'jagged' pixel art look to your\r\n * image resources.\r\n * @param isSmooth Set smoothing to true or false\r\n */ setAntialiasing(isSmooth) {\n this.screen.antialiasing = isSmooth;\n }\n /**\r\n * Return the current smoothing status of the canvas\r\n */ getAntialiasing() {\n return this.screen.antialiasing;\n }\n /**\r\n * Gets whether the actor is Initialized\r\n */ get isInitialized() {\n return this._isInitialized;\n }\n _overrideInitialize(engine) {\n if (!this.isInitialized) {\n this.onInitialize(engine);\n this.events.emit(\"initialize\", new InitializeEvent(engine, this));\n this._isInitialized = true;\n if (this._deferredGoTo) {\n const deferredScene = this._deferredGoTo;\n this._deferredGoTo = null;\n this.goToScene(deferredScene);\n } else this.goToScene(\"root\");\n }\n }\n /**\r\n * Updates the entire state of the game\r\n * @param delta Number of milliseconds elapsed since the last update.\r\n */ _update(delta) {\n if (!this.ready) {\n // suspend updates until loading is finished\n this._loader.update(this, delta);\n // Update input listeners\n this.input.keyboard.update();\n this.input.gamepads.update();\n this.inputMapper.execute();\n return;\n }\n // Publish preupdate events\n this._preupdate(delta);\n // process engine level events\n this.currentScene.update(this, delta);\n // Update graphics postprocessors\n this.graphicsContext.updatePostProcessors(delta);\n // Publish update event\n this._postupdate(delta);\n // Update input listeners\n this.input.keyboard.update();\n this.input.gamepads.update();\n this.inputMapper.execute();\n }\n /**\r\n * @internal\r\n */ _preupdate(delta) {\n this.emit(\"preupdate\", new PreUpdateEvent(this, delta, this));\n this.onPreUpdate(this, delta);\n }\n onPreUpdate(_engine, _delta) {\n // Override me\n }\n /**\r\n * @internal\r\n */ _postupdate(delta) {\n this.emit(\"postupdate\", new PostUpdateEvent(this, delta, this));\n this.onPostUpdate(this, delta);\n }\n onPostUpdate(_engine, _delta) {\n // Override me\n }\n /**\r\n * Draws the entire game\r\n * @param delta Number of milliseconds elapsed since the last draw.\r\n */ _draw(delta) {\n this.graphicsContext.beginDrawLifecycle();\n this.graphicsContext.clear();\n this._predraw(this.graphicsContext, delta);\n // Drawing nothing else while loading\n if (!this._isReady) {\n this._loader.canvas.draw(this.graphicsContext, 0, 0);\n this.graphicsContext.flush();\n return;\n }\n this.graphicsContext.backgroundColor = this.backgroundColor;\n this.currentScene.draw(this.graphicsContext, delta);\n this._postdraw(this.graphicsContext, delta);\n // Flush any pending drawings\n this.graphicsContext.flush();\n this.graphicsContext.endDrawLifecycle();\n this._checkForScreenShots();\n }\n /**\r\n * @internal\r\n */ _predraw(_ctx, delta) {\n this.emit(\"predraw\", new PreDrawEvent(_ctx, delta, this));\n this.onPreDraw(_ctx, delta);\n }\n onPreDraw(_ctx, _delta) {\n // Override me\n }\n /**\r\n * @internal\r\n */ _postdraw(_ctx, delta) {\n this.emit(\"postdraw\", new PostDrawEvent(_ctx, delta, this));\n this.onPostDraw(_ctx, delta);\n }\n onPostDraw(_ctx, _delta) {\n // Override me\n }\n /**\r\n * Enable or disable Excalibur debugging functionality.\r\n * @param toggle a value that debug drawing will be changed to\r\n */ showDebug(toggle) {\n this._isDebug = toggle;\n }\n /**\r\n * Toggle Excalibur debugging functionality.\r\n */ toggleDebug() {\n this._isDebug = !this._isDebug;\n return this._isDebug;\n }\n /**\r\n * Returns true when loading is totally complete and the player has clicked start\r\n */ get loadingComplete() {\n return this._loadingComplete;\n }\n get ready() {\n return this._isReady;\n }\n isReady() {\n return this._isReadyPromise;\n }\n /**\r\n * Starts the internal game loop for Excalibur after loading\r\n * any provided assets.\r\n * @param loader Optional [[Loader]] to use to load resources. The default loader is [[Loader]], override to provide your own\r\n * custom loader.\r\n *\r\n * Note: start() only resolves AFTER the user has clicked the play button\r\n */ async start(loader) {\n if (!this._compatible) throw new Error(\"Excalibur is incompatible with your browser\");\n // Wire loader if we have it\n if (loader) {\n // Push the current user entered resolution/viewport\n this.screen.pushResolutionAndViewport();\n // Configure resolution for loader, it expects resolution === viewport\n this.screen.resolution = this.screen.viewport;\n this.screen.applyResolutionAndViewport();\n this._loader = loader;\n this._loader.suppressPlayButton = this._suppressPlayButton || this._loader.suppressPlayButton;\n this._loader.wireEngine(this);\n }\n // Start the excalibur clock which drives the mainloop\n // has started is a slight misnomer, it's really mainloop started\n this._logger.debug(\"Starting game clock...\");\n this.browser.resume();\n this.clock.start();\n this._logger.debug(\"Game clock started\");\n if (loader) {\n await this.load(this._loader);\n this._loadingComplete = true;\n // reset back to previous user resolution/viewport\n this.screen.popResolutionAndViewport();\n this.screen.applyResolutionAndViewport();\n }\n this._loadingComplete = true;\n // Initialize before ready\n this._overrideInitialize(this);\n this._isReady = true;\n this._isReadyResolve();\n this.emit(\"start\", new GameStartEvent(this));\n return this._isReadyPromise;\n }\n _mainloop(elapsed) {\n this.emit(\"preframe\", new PreFrameEvent(this, this.stats.prevFrame));\n const delta = elapsed * this.timescale;\n this.currentFrameElapsedMs = delta;\n // reset frame stats (reuse existing instances)\n const frameId = this.stats.prevFrame.id + 1;\n this.stats.currFrame.reset();\n this.stats.currFrame.id = frameId;\n this.stats.currFrame.delta = delta;\n this.stats.currFrame.fps = this.clock.fpsSampler.fps;\n GraphicsDiagnostics.clear();\n const beforeUpdate = this.clock.now();\n const fixedTimestepMs = 1000 / this.fixedUpdateFps;\n if (this.fixedUpdateFps) {\n this._lagMs += delta;\n while(this._lagMs >= fixedTimestepMs){\n this._update(fixedTimestepMs);\n this._lagMs -= fixedTimestepMs;\n }\n } else this._update(delta);\n const afterUpdate = this.clock.now();\n this.currentFrameLagMs = this._lagMs;\n this._draw(delta);\n const afterDraw = this.clock.now();\n this.stats.currFrame.duration.update = afterUpdate - beforeUpdate;\n this.stats.currFrame.duration.draw = afterDraw - afterUpdate;\n this.stats.currFrame.graphics.drawnImages = GraphicsDiagnostics.DrawnImagesCount;\n this.stats.currFrame.graphics.drawCalls = GraphicsDiagnostics.DrawCallCount;\n this.emit(\"postframe\", new PostFrameEvent(this, this.stats.currFrame));\n this.stats.prevFrame.reset(this.stats.currFrame);\n this._monitorPerformanceThresholdAndTriggerFallback();\n }\n /**\r\n * Stops Excalibur's main loop, useful for pausing the game.\r\n */ stop() {\n if (this.clock.isRunning()) {\n this.emit(\"stop\", new GameStopEvent(this));\n this.browser.pause();\n this.clock.stop();\n this._logger.debug(\"Game stopped\");\n }\n }\n /**\r\n * Returns the Engine's running status, Useful for checking whether engine is running or paused.\r\n */ isRunning() {\n return this.clock.isRunning();\n }\n /**\r\n * Takes a screen shot of the current viewport and returns it as an\r\n * HTML Image Element.\r\n * @param preserveHiDPIResolution in the case of HiDPI return the full scaled backing image, by default false\r\n */ screenshot(preserveHiDPIResolution = false) {\n const screenShotPromise = new Promise((resolve)=>{\n this._screenShotRequests.push({\n preserveHiDPIResolution: preserveHiDPIResolution,\n resolve: resolve\n });\n });\n return screenShotPromise;\n }\n _checkForScreenShots() {\n // We must grab the draw buffer before we yield to the browser\n // the draw buffer is cleared after compositing\n // the reason for the asynchrony is setting `preserveDrawingBuffer: true`\n // forces the browser to copy buffers which can have a mass perf impact on mobile\n for (const request of this._screenShotRequests){\n const finalWidth = request.preserveHiDPIResolution ? this.canvas.width : this.screen.resolution.width;\n const finalHeight = request.preserveHiDPIResolution ? this.canvas.height : this.screen.resolution.height;\n const screenshot = document.createElement(\"canvas\");\n screenshot.width = finalWidth;\n screenshot.height = finalHeight;\n const ctx = screenshot.getContext(\"2d\");\n ctx.imageSmoothingEnabled = this.screen.antialiasing;\n ctx.drawImage(this.canvas, 0, 0, finalWidth, finalHeight);\n const result = new Image();\n const raw = screenshot.toDataURL(\"image/png\");\n result.src = raw;\n request.resolve(result);\n }\n // Reset state\n this._screenShotRequests.length = 0;\n }\n /**\r\n * Another option available to you to load resources into the game.\r\n * Immediately after calling this the game will pause and the loading screen\r\n * will appear.\r\n * @param loader Some [[Loadable]] such as a [[Loader]] collection, [[Sound]], or [[Texture]].\r\n */ async load(loader) {\n try {\n await loader.load();\n } catch (e) {\n this._logger.error(\"Error loading resources, things may not behave properly\", e);\n await Promise.resolve();\n }\n }\n }\n /**\r\n * Default [[EngineOptions]]\r\n */ Engine._DEFAULT_ENGINE_OPTIONS = {\n width: 0,\n height: 0,\n enableCanvasTransparency: true,\n useDrawSorting: true,\n configurePerformanceCanvas2DFallback: {\n allow: true,\n showPlayerMessage: false,\n threshold: {\n fps: 20,\n numberOfFrames: 100\n }\n },\n canvasElementId: \"\",\n canvasElement: undefined,\n snapToPixel: false,\n pointerScope: PointerScope.Canvas,\n suppressConsoleBootMessage: null,\n suppressMinimumBrowserFeatureDetection: null,\n suppressHiDPIScaling: null,\n suppressPlayButton: null,\n grabWindowFocus: true,\n scrollPreventionMode: ScrollPreventionMode.Canvas,\n backgroundColor: Color.fromHex(\"#2185d0\") // Excalibur blue\n };\n /**\r\n * @deprecated Use [[EventEmitter]] will be removed in v0.29.0\r\n */ class EventDispatcher {\n constructor(){\n this._handlers = {};\n this._wiredEventDispatchers = [];\n this._deferedHandlerRemovals = [];\n }\n /**\r\n * Clears any existing handlers or wired event dispatchers on this event dispatcher\r\n */ clear() {\n this._handlers = {};\n this._wiredEventDispatchers = [];\n }\n _processDeferredHandlerRemovals() {\n for (const eventHandler of this._deferedHandlerRemovals)this._removeHandler(eventHandler.name, eventHandler.handler);\n this._deferedHandlerRemovals.length = 0;\n }\n /**\r\n * Emits an event for target\r\n * @param eventName The name of the event to publish\r\n * @param event Optionally pass an event data object to the handler\r\n */ emit(eventName, event) {\n this._processDeferredHandlerRemovals();\n if (!eventName) // key not mapped\n return;\n eventName = eventName.toLowerCase();\n if (typeof event === \"undefined\" || event === null) event = new GameEvent();\n let i, len;\n if (this._handlers[eventName]) {\n i = 0;\n len = this._handlers[eventName].length;\n for(i; i < len; i++)this._handlers[eventName][i](event);\n }\n i = 0;\n len = this._wiredEventDispatchers.length;\n for(i; i < len; i++)this._wiredEventDispatchers[i].emit(eventName, event);\n }\n /**\r\n * Subscribe an event handler to a particular event name, multiple handlers per event name are allowed.\r\n * @param eventName The name of the event to subscribe to\r\n * @param handler The handler callback to fire on this event\r\n */ on(eventName, handler) {\n this._processDeferredHandlerRemovals();\n eventName = eventName.toLowerCase();\n if (!this._handlers[eventName]) this._handlers[eventName] = [];\n this._handlers[eventName].push(handler);\n }\n /**\r\n * Unsubscribe an event handler(s) from an event. If a specific handler\r\n * is specified for an event, only that handler will be unsubscribed.\r\n * Otherwise all handlers will be unsubscribed for that event.\r\n *\r\n * @param eventName The name of the event to unsubscribe\r\n * @param handler Optionally the specific handler to unsubscribe\r\n */ off(eventName, handler) {\n this._deferedHandlerRemovals.push({\n name: eventName,\n handler: handler\n });\n }\n _removeHandler(eventName, handler) {\n eventName = eventName.toLowerCase();\n const eventHandlers = this._handlers[eventName];\n if (eventHandlers) {\n // if no explicit handler is give with the event name clear all handlers\n if (!handler) this._handlers[eventName].length = 0;\n else {\n const index = eventHandlers.indexOf(handler);\n if (index > -1) this._handlers[eventName].splice(index, 1);\n }\n }\n }\n /**\r\n * Once listens to an event one time, then unsubscribes from that event\r\n *\r\n * @param eventName The name of the event to subscribe to once\r\n * @param handler The handler of the event that will be auto unsubscribed\r\n */ once(eventName, handler) {\n this._processDeferredHandlerRemovals();\n const metaHandler = (event)=>{\n const ev = event || new GameEvent();\n this.off(eventName, metaHandler);\n handler(ev);\n };\n this.on(eventName, metaHandler);\n }\n /**\r\n * Wires this event dispatcher to also receive events from another\r\n */ wire(eventDispatcher) {\n eventDispatcher._wiredEventDispatchers.push(this);\n }\n /**\r\n * Unwires this event dispatcher from another\r\n */ unwire(eventDispatcher) {\n const index = eventDispatcher._wiredEventDispatchers.indexOf(this);\n if (index > -1) eventDispatcher._wiredEventDispatchers.splice(index, 1);\n }\n }\n /**\r\n * Labels are the way to draw small amounts of text to the screen. They are\r\n * actors and inherit all of the benefits and capabilities.\r\n */ class Label extends Actor {\n get font() {\n return this._font;\n }\n set font(newFont) {\n this._font = newFont;\n this._text.font = newFont;\n }\n /**\r\n * The text to draw.\r\n */ get text() {\n return this._text.text;\n }\n set text(text) {\n this._text.text = text;\n }\n get color() {\n return this._text.color;\n }\n set color(color) {\n if (this._text) this._text.color = color;\n }\n get opacity() {\n return this._text.opacity;\n }\n set opacity(opacity) {\n this._text.opacity = opacity;\n }\n /**\r\n * The [[SpriteFont]] to use, if any. Overrides [[Font|font]] if present.\r\n */ get spriteFont() {\n return this._spriteFont;\n }\n set spriteFont(sf) {\n if (sf) {\n this._spriteFont = sf;\n this._text.font = this._spriteFont;\n }\n }\n /**\r\n * Build a new label\r\n * @param options\r\n */ constructor(options){\n super(options);\n this._font = new Font();\n this._text = new Text({\n text: \"\",\n font: this._font\n });\n const { text: text, pos: pos, x: x, y: y, spriteFont: spriteFont, font: font, color: color } = options;\n this.pos = pos !== null && pos !== void 0 ? pos : x && y ? vec(x, y) : this.pos;\n this.text = text !== null && text !== void 0 ? text : this.text;\n this.font = font !== null && font !== void 0 ? font : this.font;\n this.spriteFont = spriteFont !== null && spriteFont !== void 0 ? spriteFont : this.spriteFont;\n this._text.color = color !== null && color !== void 0 ? color : this.color;\n const gfx = this.get(GraphicsComponent);\n gfx.anchor = Vector.Zero;\n gfx.use(this._text);\n }\n _initialize(engine) {\n super._initialize(engine);\n }\n /**\r\n * Returns the width of the text in the label (in pixels);\r\n */ getTextWidth() {\n return this._text.width;\n }\n }\n class IsometricTile extends Entity {\n getGraphics() {\n return this._graphics;\n }\n /**\r\n * Tile graphics\r\n */ addGraphic(graphic) {\n this._graphics.push(graphic);\n this._gfx.visible = true;\n this._gfx.localBounds = this._recalculateBounds();\n }\n _recalculateBounds() {\n let bounds = this._tileBounds.clone();\n for (const graphic of this._graphics){\n const offset = vec(this.map.graphicsOffset.x - this.map.tileWidth / 2, this.map.graphicsOffset.y - (this.map.renderFromTopOfGraphic ? 0 : graphic.height - this.map.tileHeight));\n bounds = bounds.combine(graphic.localBounds.translate(offset));\n }\n return bounds;\n }\n removeGraphic(graphic) {\n const index = this._graphics.indexOf(graphic);\n if (index > -1) this._graphics.splice(index, 1);\n this._gfx.localBounds = this._recalculateBounds();\n }\n clearGraphics() {\n this._graphics.length = 0;\n this._gfx.visible = false;\n this._gfx.localBounds = this._recalculateBounds();\n }\n getColliders() {\n return this._colliders;\n }\n /**\r\n * Adds a collider to the IsometricTile\r\n *\r\n * **Note!** the [[Tile.solid]] must be set to true for it to act as a \"fixed\" collider\r\n * @param collider\r\n */ addCollider(collider) {\n this._colliders.push(collider);\n this.map.flagCollidersDirty();\n }\n /**\r\n * Removes a collider from the IsometricTile\r\n * @param collider\r\n */ removeCollider(collider) {\n const index = this._colliders.indexOf(collider);\n if (index > -1) this._colliders.splice(index, 1);\n this.map.flagCollidersDirty();\n }\n /**\r\n * Clears all colliders from the IsometricTile\r\n */ clearColliders() {\n this._colliders.length = 0;\n this.map.flagCollidersDirty();\n }\n /**\r\n * Returns the top left corner of the [[IsometricTile]] in world space\r\n */ get pos() {\n return this.map.tileToWorld(vec(this.x, this.y));\n }\n /**\r\n * Returns the center of the [[IsometricTile]]\r\n */ get center() {\n return this.pos.add(vec(0, this.map.tileHeight / 2));\n }\n /**\r\n * Construct a new IsometricTile\r\n * @param x tile coordinate in x (not world position)\r\n * @param y tile coordinate in y (not world position)\r\n * @param graphicsOffset offset that tile should be shifted by (default (0, 0))\r\n * @param map reference to owning IsometricMap\r\n */ constructor(x, y, graphicsOffset, map){\n super([\n new TransformComponent(),\n new GraphicsComponent({\n offset: graphicsOffset !== null && graphicsOffset !== void 0 ? graphicsOffset : Vector.Zero,\n onPostDraw: (gfx, elapsed)=>this.draw(gfx, elapsed)\n }),\n new IsometricEntityComponent(map)\n ]);\n /**\r\n * Indicates whether this tile is solid\r\n */ this.solid = false;\n this._tileBounds = new BoundingBox();\n this._graphics = [];\n /**\r\n * Tile colliders\r\n */ this._colliders = [];\n this.x = x;\n this.y = y;\n this.map = map;\n this._transform = this.get(TransformComponent);\n this._isometricEntityComponent = this.get(IsometricEntityComponent);\n const halfTileWidth = this.map.tileWidth / 2;\n const halfTileHeight = this.map.tileHeight / 2;\n // See https://clintbellanger.net/articles/isometric_math/ for formula\n // The x position shifts left with every y step\n const xPos = (this.x - this.y) * halfTileWidth;\n // The y position needs to go down with every x step\n const yPos = (this.x + this.y) * halfTileHeight;\n this._transform.pos = vec(xPos, yPos);\n this._isometricEntityComponent.elevation = 0;\n this._gfx = this.get(GraphicsComponent);\n this._gfx.visible = false; // start not visible\n const totalWidth = this.map.tileWidth;\n const totalHeight = this.map.tileHeight;\n // initial guess at gfx bounds based on the tile\n const offset = vec(0, this.map.renderFromTopOfGraphic ? totalHeight : 0);\n this._gfx.localBounds = this._tileBounds = new BoundingBox({\n left: -totalWidth / 2,\n top: -totalHeight,\n right: totalWidth / 2,\n bottom: totalHeight\n }).translate(offset);\n }\n draw(gfx, _elapsed) {\n const halfTileWidth = this.map.tileWidth / 2;\n gfx.save();\n // shift left origin to corner of map, not the left corner of the first sprite\n gfx.translate(-halfTileWidth, 0);\n for (const graphic of this._graphics)graphic.draw(gfx, this.map.graphicsOffset.x, this.map.graphicsOffset.y - (this.map.renderFromTopOfGraphic ? 0 : graphic.height - this.map.tileHeight));\n gfx.restore();\n }\n }\n /**\r\n * The IsometricMap is a special tile map that provides isometric rendering support to Excalibur\r\n *\r\n * The tileWidth and tileHeight should be the height and width in pixels of the parallelogram of the base of the tile art asset.\r\n * The tileWidth and tileHeight is not necessarily the same as your graphic pixel width and height.\r\n *\r\n * Please refer to the docs https://excaliburjs.com for more details calculating what your tile width and height should be given\r\n * your art assets.\r\n */ class IsometricMap extends Entity {\n constructor(options){\n super([\n new TransformComponent(),\n new BodyComponent({\n type: CollisionType.Fixed\n }),\n new ColliderComponent(),\n new DebugGraphicsComponent((ctx)=>this.debug(ctx), false)\n ], options.name);\n /**\r\n * Render the tile graphic from the top instead of the bottom\r\n *\r\n * default is `false` meaning rendering from the bottom\r\n */ this.renderFromTopOfGraphic = false;\n this.graphicsOffset = vec(0, 0);\n this._collidersDirty = false;\n this._originalOffsets = new WeakMap();\n const { pos: pos, tileWidth: tileWidth, tileHeight: tileHeight, columns: width, rows: height, renderFromTopOfGraphic: renderFromTopOfGraphic, graphicsOffset: graphicsOffset } = options;\n this.transform = this.get(TransformComponent);\n if (pos) this.transform.pos = pos;\n this.collider = this.get(ColliderComponent);\n if (this.collider) this.collider.set(this._composite = new CompositeCollider([]));\n this.renderFromTopOfGraphic = renderFromTopOfGraphic !== null && renderFromTopOfGraphic !== void 0 ? renderFromTopOfGraphic : this.renderFromTopOfGraphic;\n this.graphicsOffset = graphicsOffset !== null && graphicsOffset !== void 0 ? graphicsOffset : this.graphicsOffset;\n this.tileWidth = tileWidth;\n this.tileHeight = tileHeight;\n this.columns = width;\n this.rows = height;\n this.tiles = new Array(width * height);\n // build up tile representation\n for(let y = 0; y < height; y++)for(let x = 0; x < width; x++){\n const tile = new IsometricTile(x, y, this.graphicsOffset, this);\n this.tiles[x + y * width] = tile;\n this.addChild(tile);\n // TODO row/columns helpers\n }\n }\n update() {\n if (this._collidersDirty) {\n this.updateColliders();\n this._collidersDirty = false;\n }\n }\n flagCollidersDirty() {\n this._collidersDirty = true;\n }\n _getOrSetColliderOriginalOffset(collider) {\n if (!this._originalOffsets.has(collider)) {\n const originalOffset = collider.offset;\n this._originalOffsets.set(collider, originalOffset);\n return originalOffset;\n } else return this._originalOffsets.get(collider);\n }\n updateColliders() {\n this._composite.clearColliders();\n const pos = this.get(TransformComponent).pos;\n for (const tile of this.tiles){\n if (tile.solid) for (const collider of tile.getColliders()){\n const originalOffset = this._getOrSetColliderOriginalOffset(collider);\n collider.offset = this.tileToWorld(vec(tile.x, tile.y)).sub(pos).add(originalOffset).sub(vec(this.tileWidth / 2, this.tileHeight)); // We need to unshift height based on drawing\n collider.owner = this;\n this._composite.addCollider(collider);\n }\n }\n this.collider.update();\n }\n /**\r\n * Convert world space coordinates to the tile x, y coordinate\r\n * @param worldCoordinate\r\n */ worldToTile(worldCoordinate) {\n worldCoordinate = worldCoordinate.sub(this.transform.globalPos);\n const halfTileWidth = this.tileWidth / 2;\n const halfTileHeight = this.tileHeight / 2;\n // See https://clintbellanger.net/articles/isometric_math/ for formula\n return vec(~~((worldCoordinate.x / halfTileWidth + worldCoordinate.y / halfTileHeight) / 2), ~~((worldCoordinate.y / halfTileHeight - worldCoordinate.x / halfTileWidth) / 2));\n }\n /**\r\n * Given a tile coordinate, return the top left corner in world space\r\n * @param tileCoordinate\r\n */ tileToWorld(tileCoordinate) {\n const halfTileWidth = this.tileWidth / 2;\n const halfTileHeight = this.tileHeight / 2;\n // The x position shifts left with every y step\n const xPos = (tileCoordinate.x - tileCoordinate.y) * halfTileWidth;\n // The y position needs to go down with every x step\n const yPos = (tileCoordinate.x + tileCoordinate.y) * halfTileHeight;\n return vec(xPos, yPos).add(this.transform.pos);\n }\n /**\r\n * Returns the [[IsometricTile]] by its x and y coordinates\r\n */ getTile(x, y) {\n if (x < 0 || y < 0 || x >= this.columns || y >= this.rows) return null;\n return this.tiles[x + y * this.columns];\n }\n /**\r\n * Returns the [[IsometricTile]] by testing a point in world coordinates,\r\n * returns `null` if no Tile was found.\r\n */ getTileByPoint(point) {\n const tileCoord = this.worldToTile(point);\n const tile = this.getTile(tileCoord.x, tileCoord.y);\n return tile;\n }\n _getMaxZIndex() {\n let maxZ = Number.NEGATIVE_INFINITY;\n for (const tile of this.tiles){\n const currentZ = tile.get(TransformComponent).z;\n if (currentZ > maxZ) maxZ = currentZ;\n }\n return maxZ;\n }\n /**\r\n * Debug draw for IsometricMap, called internally by excalibur when debug mode is toggled on\r\n * @param gfx\r\n */ debug(gfx) {\n gfx.save();\n gfx.z = this._getMaxZIndex() + 0.5;\n for(let y = 0; y < this.rows + 1; y++){\n const left = this.tileToWorld(vec(0, y));\n const right = this.tileToWorld(vec(this.columns, y));\n gfx.drawLine(left, right, Color.Red, 2);\n }\n for(let x = 0; x < this.columns + 1; x++){\n const top = this.tileToWorld(vec(x, 0));\n const bottom = this.tileToWorld(vec(x, this.rows));\n gfx.drawLine(top, bottom, Color.Red, 2);\n }\n for (const tile of this.tiles)gfx.drawCircle(this.tileToWorld(vec(tile.x, tile.y)), 3, Color.Yellow);\n gfx.restore();\n }\n }\n /**\r\n * Action that can represent a sequence of actions, this can be useful in conjunction with\r\n * [[ParallelActions]] to run multiple sequences in parallel.\r\n */ class ActionSequence {\n constructor(entity, actionBuilder){\n this._stopped = false;\n this._sequenceBuilder = actionBuilder;\n this._sequenceContext = new ActionContext(entity);\n this._actionQueue = this._sequenceContext.getQueue();\n this._sequenceBuilder(this._sequenceContext);\n }\n update(delta) {\n this._actionQueue.update(delta);\n }\n isComplete() {\n return this._stopped || this._actionQueue.isComplete();\n }\n stop() {\n this._stopped = true;\n }\n reset() {\n this._stopped = false;\n this._actionQueue.reset();\n }\n clone(entity) {\n return new ActionSequence(entity, this._sequenceBuilder);\n }\n }\n /**\r\n * Action that can run multiple [[Action]]s or [[ActionSequence]]s at the same time\r\n */ class ParallelActions {\n constructor(parallelActions){\n this._actions = parallelActions;\n }\n update(delta) {\n for(let i = 0; i < this._actions.length; i++)this._actions[i].update(delta);\n }\n isComplete(entity) {\n return this._actions.every((a)=>a.isComplete(entity));\n }\n reset() {\n this._actions.forEach((a)=>a.reset());\n }\n stop() {\n this._actions.forEach((a)=>a.stop());\n }\n }\n /**\r\n * Static class for managing collision groups in excalibur, there is a maximum of 32 collision groups possible in excalibur\r\n */ class CollisionGroupManager {\n /**\r\n * Create a new named collision group up to a max of 32.\r\n * @param name Name for the collision group\r\n * @param mask Optionally provide your own 32-bit mask, if none is provide the manager will generate one\r\n */ static create(name, mask) {\n if (this._CURRENT_GROUP > this._MAX_GROUPS) throw new Error(`Cannot have more than ${this._MAX_GROUPS} collision groups`);\n if (this._GROUPS.get(name)) throw new Error(`Collision group ${name} already exists`);\n const group = new CollisionGroup(name, this._CURRENT_BIT, mask !== undefined ? mask : ~this._CURRENT_BIT);\n this._CURRENT_BIT = this._CURRENT_BIT << 1 | 0;\n this._CURRENT_GROUP++;\n this._GROUPS.set(name, group);\n return group;\n }\n /**\r\n * Get all collision groups currently tracked by excalibur\r\n */ static get groups() {\n return Array.from(this._GROUPS.values());\n }\n /**\r\n * Get a collision group by it's name\r\n * @param name\r\n */ static groupByName(name) {\n return this._GROUPS.get(name);\n }\n /**\r\n * Resets the managers internal group management state\r\n */ static reset() {\n this._GROUPS = new Map();\n this._CURRENT_BIT = this._STARTING_BIT;\n this._CURRENT_GROUP = 1;\n }\n }\n // using bitmasking the maximum number of groups is 32, because that is the highest 32bit integer that JS can present.\n CollisionGroupManager._STARTING_BIT = 1;\n CollisionGroupManager._MAX_GROUPS = 32;\n CollisionGroupManager._CURRENT_GROUP = 1;\n CollisionGroupManager._CURRENT_BIT = CollisionGroupManager._STARTING_BIT;\n CollisionGroupManager._GROUPS = new Map();\n /**\r\n * Type guard checking for internal initialize method\r\n * @internal\r\n * @param a\r\n */ function has_initialize(a) {\n return !!a._initialize;\n }\n /**\r\n *\r\n */ function hasOnInitialize(a) {\n return !!a.onInitialize;\n }\n /**\r\n *\r\n */ function has_preupdate(a) {\n return !!a._preupdate;\n }\n /**\r\n *\r\n */ function hasOnPreUpdate(a) {\n return !!a.onPreUpdate;\n }\n /**\r\n *\r\n */ function has_postupdate(a) {\n return !!a.onPostUpdate;\n }\n /**\r\n *\r\n */ function hasOnPostUpdate(a) {\n return !!a.onPostUpdate;\n }\n /**\r\n *\r\n */ function hasPreDraw(a) {\n return !!a.onPreDraw;\n }\n /**\r\n *\r\n */ function hasPostDraw(a) {\n return !!a.onPostDraw;\n }\n /**\r\n * The [[Texture]] object allows games built in Excalibur to load image resources.\r\n * [[Texture]] is an [[Loadable]] which means it can be passed to a [[Loader]]\r\n * to pre-load before starting a level or game.\r\n */ class Gif {\n /**\r\n * @param path Path to the image resource\r\n * @param color Optionally set the color to treat as transparent the gif, by default [[Color.Magenta]]\r\n * @param bustCache Optionally load texture with cache busting\r\n */ constructor(path, color = Color.Magenta, bustCache = false){\n this.path = path;\n this.color = color;\n this._stream = null;\n this._gif = null;\n this._textures = [];\n this._animation = null;\n this._transparentColor = null;\n this._resource = new Resource(path, \"arraybuffer\", bustCache);\n this._transparentColor = color;\n }\n /**\r\n * Should excalibur add a cache busting querystring? By default false.\r\n * Must be set before loading\r\n */ get bustCache() {\n return this._resource.bustCache;\n }\n set bustCache(val) {\n this._resource.bustCache = val;\n }\n /**\r\n * Begins loading the texture and returns a promise to be resolved on completion\r\n */ async load() {\n const arraybuffer = await this._resource.load();\n this._stream = new Stream(arraybuffer);\n this._gif = new ParseGif(this._stream, this._transparentColor);\n const images = this._gif.images.map((i)=>new ImageSource(i.src, false));\n // Load all textures\n await Promise.all(images.map((t)=>t.load()));\n return this.data = this._textures = images;\n }\n isLoaded() {\n return !!this.data;\n }\n /**\r\n * Return a frame of the gif as a sprite by id\r\n * @param id\r\n */ toSprite(id = 0) {\n const sprite = this._textures[id].toSprite();\n return sprite;\n }\n /**\r\n * Return the gif as a spritesheet\r\n */ toSpriteSheet() {\n const sprites = this._textures.map((image)=>{\n return image.toSprite();\n });\n return new SpriteSheet({\n sprites: sprites\n });\n }\n /**\r\n * Transform the GIF into an animation with duration per frame\r\n */ toAnimation(durationPerFrameMs) {\n const spriteSheet = this.toSpriteSheet();\n const length = spriteSheet.sprites.length;\n this._animation = Animation.fromSpriteSheet(spriteSheet, range(0, length), durationPerFrameMs);\n return this._animation;\n }\n get readCheckBytes() {\n return this._gif.checkBytes;\n }\n }\n const bitsToNum = (ba)=>{\n return ba.reduce(function(s, n) {\n return s * 2 + n;\n }, 0);\n };\n const byteToBitArr = (bite)=>{\n const a = [];\n for(let i = 7; i >= 0; i--)a.push(!!(bite & 1 << i));\n return a;\n };\n class Stream {\n constructor(dataArray){\n this.data = null;\n this.len = 0;\n this.position = 0;\n this.readByte = ()=>{\n if (this.position >= this.data.byteLength) throw new Error(\"Attempted to read past end of stream.\");\n return this.data[this.position++];\n };\n this.readBytes = (n)=>{\n const bytes = [];\n for(let i = 0; i < n; i++)bytes.push(this.readByte());\n return bytes;\n };\n this.read = (n)=>{\n let s = \"\";\n for(let i = 0; i < n; i++)s += String.fromCharCode(this.readByte());\n return s;\n };\n this.readUnsigned = ()=>{\n // Little-endian.\n const a = this.readBytes(2);\n return (a[1] << 8) + a[0];\n };\n this.data = new Uint8Array(dataArray);\n this.len = this.data.byteLength;\n if (this.len === 0) throw new Error(\"No data loaded from file\");\n }\n }\n const lzwDecode = function(minCodeSize, data) {\n // TODO: Now that the GIF parser is a bit different, maybe this should get an array of bytes instead of a String?\n let pos = 0; // Maybe this streaming thing should be merged with the Stream?\n const readCode = function(size) {\n let code = 0;\n for(let i = 0; i < size; i++){\n if (data.charCodeAt(pos >> 3) & 1 << (pos & 7)) code |= 1 << i;\n pos++;\n }\n return code;\n };\n const output = [];\n const clearCode = 1 << minCodeSize;\n const eoiCode = clearCode + 1;\n let codeSize = minCodeSize + 1;\n let dict = [];\n const clear = function() {\n dict = [];\n codeSize = minCodeSize + 1;\n for(let i = 0; i < clearCode; i++)dict[i] = [\n i\n ];\n dict[clearCode] = [];\n dict[eoiCode] = null;\n };\n let code;\n let last;\n while(true){\n last = code;\n code = readCode(codeSize);\n if (code === clearCode) {\n clear();\n continue;\n }\n if (code === eoiCode) break;\n if (code < dict.length) {\n if (last !== clearCode) dict.push(dict[last].concat(dict[code][0]));\n } else {\n if (code !== dict.length) throw new Error(\"Invalid LZW code.\");\n dict.push(dict[last].concat(dict[last][0]));\n }\n output.push.apply(output, dict[code]);\n if (dict.length === 1 << codeSize && codeSize < 12) // If we're at the last code and codeSize is 12, the next code will be a clearCode, and it'll be 12 bits long.\n codeSize++;\n }\n // I don't know if this is technically an error, but some GIFs do it.\n //if (Math.ceil(pos / 8) !== data.length) throw new Error('Extraneous LZW bytes.');\n return output;\n };\n // The actual parsing; returns an object with properties.\n class ParseGif {\n constructor(stream, color = Color.Magenta){\n this._st = null;\n this._handler = {};\n this._transparentColor = null;\n this.frames = [];\n this.images = [];\n this.globalColorTable = [];\n this.checkBytes = [];\n // LZW (GIF-specific)\n this.parseColorTable = (entries)=>{\n // Each entry is 3 bytes, for RGB.\n const ct = [];\n for(let i = 0; i < entries; i++){\n const rgb = this._st.readBytes(3);\n const rgba = \"#\" + rgb.map((x)=>{\n const hex = x.toString(16);\n return hex.length === 1 ? \"0\" + hex : hex;\n }).join(\"\");\n ct.push(rgba);\n }\n return ct;\n };\n this.readSubBlocks = ()=>{\n let size, data;\n data = \"\";\n do {\n size = this._st.readByte();\n data += this._st.read(size);\n }while (size !== 0);\n return data;\n };\n this.parseHeader = ()=>{\n const hdr = {\n sig: null,\n ver: null,\n width: null,\n height: null,\n colorRes: null,\n globalColorTableSize: null,\n gctFlag: null,\n sorted: null,\n globalColorTable: [],\n bgColor: null,\n pixelAspectRatio: null // if not 0, aspectRatio = (pixelAspectRatio + 15) / 64\n };\n hdr.sig = this._st.read(3);\n hdr.ver = this._st.read(3);\n if (hdr.sig !== \"GIF\") throw new Error(\"Not a GIF file.\"); // XXX: This should probably be handled more nicely.\n hdr.width = this._st.readUnsigned();\n hdr.height = this._st.readUnsigned();\n const bits = byteToBitArr(this._st.readByte());\n hdr.gctFlag = bits.shift();\n hdr.colorRes = bitsToNum(bits.splice(0, 3));\n hdr.sorted = bits.shift();\n hdr.globalColorTableSize = bitsToNum(bits.splice(0, 3));\n hdr.bgColor = this._st.readByte();\n hdr.pixelAspectRatio = this._st.readByte(); // if not 0, aspectRatio = (pixelAspectRatio + 15) / 64\n if (hdr.gctFlag) {\n hdr.globalColorTable = this.parseColorTable(1 << hdr.globalColorTableSize + 1);\n this.globalColorTable = hdr.globalColorTable;\n }\n if (this._handler.hdr && this._handler.hdr(hdr)) this.checkBytes.push(this._handler.hdr);\n };\n this.parseExt = (block)=>{\n const parseGCExt = (block)=>{\n this.checkBytes.push(this._st.readByte()); // Always 4\n const bits = byteToBitArr(this._st.readByte());\n block.reserved = bits.splice(0, 3); // Reserved; should be 000.\n block.disposalMethod = bitsToNum(bits.splice(0, 3));\n block.userInput = bits.shift();\n block.transparencyGiven = bits.shift();\n block.delayTime = this._st.readUnsigned();\n block.transparencyIndex = this._st.readByte();\n block.terminator = this._st.readByte();\n if (this._handler.gce && this._handler.gce(block)) this.checkBytes.push(this._handler.gce);\n };\n const parseComExt = (block)=>{\n block.comment = this.readSubBlocks();\n if (this._handler.com && this._handler.com(block)) this.checkBytes.push(this._handler.com);\n };\n const parsePTExt = (block)=>{\n this.checkBytes.push(this._st.readByte()); // Always 12\n block.ptHeader = this._st.readBytes(12);\n block.ptData = this.readSubBlocks();\n if (this._handler.pte && this._handler.pte(block)) this.checkBytes.push(this._handler.pte);\n };\n const parseAppExt = (block)=>{\n const parseNetscapeExt = (block)=>{\n this.checkBytes.push(this._st.readByte()); // Always 3\n block.unknown = this._st.readByte(); // Q: Always 1? What is this?\n block.iterations = this._st.readUnsigned();\n block.terminator = this._st.readByte();\n if (this._handler.app && this._handler.app.NETSCAPE && this._handler.app.NETSCAPE(block)) this.checkBytes.push(this._handler.app);\n };\n const parseUnknownAppExt = (block)=>{\n block.appData = this.readSubBlocks();\n // FIXME: This won't work if a handler wants to match on any identifier.\n if (this._handler.app && this._handler.app[block.identifier] && this._handler.app[block.identifier](block)) this.checkBytes.push(this._handler.app[block.identifier]);\n };\n this.checkBytes.push(this._st.readByte()); // Always 11\n block.identifier = this._st.read(8);\n block.authCode = this._st.read(3);\n switch(block.identifier){\n case \"NETSCAPE\":\n parseNetscapeExt(block);\n break;\n default:\n parseUnknownAppExt(block);\n break;\n }\n };\n const parseUnknownExt = (block)=>{\n block.data = this.readSubBlocks();\n if (this._handler.unknown && this._handler.unknown(block)) this.checkBytes.push(this._handler.unknown);\n };\n block.label = this._st.readByte();\n switch(block.label){\n case 0xf9:\n block.extType = \"gce\";\n parseGCExt(block);\n break;\n case 0xfe:\n block.extType = \"com\";\n parseComExt(block);\n break;\n case 0x01:\n block.extType = \"pte\";\n parsePTExt(block);\n break;\n case 0xff:\n block.extType = \"app\";\n parseAppExt(block);\n break;\n default:\n block.extType = \"unknown\";\n parseUnknownExt(block);\n break;\n }\n };\n this.parseImg = (img)=>{\n const deinterlace = (pixels, width)=>{\n // Of course this defeats the purpose of interlacing. And it's *probably*\n // the least efficient way it's ever been implemented. But nevertheless...\n const newPixels = new Array(pixels.length);\n const rows = pixels.length / width;\n const cpRow = (toRow, fromRow)=>{\n const fromPixels = pixels.slice(fromRow * width, (fromRow + 1) * width);\n newPixels.splice.apply(newPixels, [\n toRow * width,\n width\n ].concat(fromPixels));\n };\n const offsets = [\n 0,\n 4,\n 2,\n 1\n ];\n const steps = [\n 8,\n 8,\n 4,\n 2\n ];\n let fromRow = 0;\n for(let pass = 0; pass < 4; pass++)for(let toRow = offsets[pass]; toRow < rows; toRow += steps[pass]){\n cpRow(toRow, fromRow);\n fromRow++;\n }\n return newPixels;\n };\n img.leftPos = this._st.readUnsigned();\n img.topPos = this._st.readUnsigned();\n img.width = this._st.readUnsigned();\n img.height = this._st.readUnsigned();\n const bits = byteToBitArr(this._st.readByte());\n img.lctFlag = bits.shift();\n img.interlaced = bits.shift();\n img.sorted = bits.shift();\n img.reserved = bits.splice(0, 2);\n img.lctSize = bitsToNum(bits.splice(0, 3));\n if (img.lctFlag) img.lct = this.parseColorTable(1 << img.lctSize + 1);\n img.lzwMinCodeSize = this._st.readByte();\n const lzwData = this.readSubBlocks();\n img.pixels = lzwDecode(img.lzwMinCodeSize, lzwData);\n if (img.interlaced) // Move\n img.pixels = deinterlace(img.pixels, img.width);\n this.frames.push(img);\n this.arrayToImage(img);\n if (this._handler.img && this._handler.img(img)) this.checkBytes.push(this._handler);\n };\n this.parseBlock = ()=>{\n const block = {\n sentinel: this._st.readByte(),\n type: \"\"\n };\n const blockChar = String.fromCharCode(block.sentinel);\n switch(blockChar){\n case \"!\":\n block.type = \"ext\";\n this.parseExt(block);\n break;\n case \",\":\n block.type = \"img\";\n this.parseImg(block);\n break;\n case \";\":\n block.type = \"eof\";\n if (this._handler.eof && this._handler.eof(block)) this.checkBytes.push(this._handler.eof);\n break;\n default:\n throw new Error(\"Unknown block: 0x\" + block.sentinel.toString(16));\n }\n if (block.type !== \"eof\") this.parseBlock();\n };\n this.arrayToImage = (frame)=>{\n let count = 0;\n const c = document.createElement(\"canvas\");\n c.id = count.toString();\n c.width = frame.width;\n c.height = frame.height;\n count++;\n const context = c.getContext(\"2d\");\n const pixSize = 1;\n let y = 0;\n let x = 0;\n for(let i = 0; i < frame.pixels.length; i++){\n if (x % frame.width === 0) {\n y++;\n x = 0;\n }\n if (this.globalColorTable[frame.pixels[i]] === this._transparentColor.toHex()) context.fillStyle = `rgba(0, 0, 0, 0)`;\n else context.fillStyle = this.globalColorTable[frame.pixels[i]];\n context.fillRect(x, y, pixSize, pixSize);\n x++;\n }\n const img = new Image();\n img.src = c.toDataURL();\n this.images.push(img);\n };\n this._st = stream;\n this._handler = {};\n this._transparentColor = color;\n this.parseHeader();\n this.parseBlock();\n }\n }\n class Line extends Graphic {\n constructor(options){\n super();\n this.color = Color.Black;\n this.thickness = 1;\n const { start: start, end: end, color: color, thickness: thickness } = options;\n this.start = start;\n this.end = end;\n this.color = color !== null && color !== void 0 ? color : this.color;\n this.thickness = thickness !== null && thickness !== void 0 ? thickness : this.thickness;\n const { width: width, height: height } = BoundingBox.fromPoints([\n start,\n end\n ]);\n this.width = width;\n this.height = height;\n }\n _drawImage(ctx, _x, _y) {\n ctx.drawLine(this.start, this.end, this.color, this.thickness);\n }\n clone() {\n return new Line({\n start: this.start,\n end: this.end,\n color: this.color,\n thickness: this.thickness\n });\n }\n }\n /**\r\n * A polygon [[Graphic]] for drawing arbitrary polygons to the [[ExcaliburGraphicsContext]]\r\n *\r\n * Polygons default to [[ImageFiltering.Blended]]\r\n */ class Polygon extends Raster {\n get points() {\n return this._points;\n }\n set points(points) {\n this._points = points;\n const min = this.minPoint;\n this.width = this._points.reduce((max, p)=>Math.max(p.x, max), 0) - min.x;\n this.height = this._points.reduce((max, p)=>Math.max(p.y, max), 0) - min.y;\n this.flagDirty();\n }\n get minPoint() {\n const minX = this._points.reduce((min, p)=>Math.min(p.x, min), Infinity);\n const minY = this._points.reduce((min, p)=>Math.min(p.y, min), Infinity);\n return vec(minX, minY);\n }\n constructor(options){\n super(options);\n this.points = options.points;\n this.filtering = ImageFiltering.Blended;\n this.rasterize();\n }\n clone() {\n return new Polygon({\n points: this.points.map((p)=>p.clone()),\n ...this.cloneGraphicOptions(),\n ...this.cloneRasterOptions()\n });\n }\n execute(ctx) {\n if (this.points && this.points.length) {\n ctx.beginPath();\n // Iterate through the supplied points and construct a 'polygon'\n const min = this.minPoint.negate();\n const firstPoint = this.points[0].add(min);\n ctx.moveTo(firstPoint.x, firstPoint.y);\n this.points.forEach((point)=>{\n ctx.lineTo(point.x + min.x, point.y + min.y);\n });\n ctx.lineTo(firstPoint.x, firstPoint.y);\n ctx.closePath();\n if (this.color) ctx.fill();\n if (this.strokeColor) ctx.stroke();\n }\n }\n }\n class AsyncWaitQueue {\n constructor(){\n // Code from StephenCleary https://gist.github.com/StephenCleary/ba50b2da419c03b9cba1d20cb4654d5e\n this._queue = [];\n }\n get length() {\n return this._queue.length;\n }\n enqueue() {\n const future = new Future();\n this._queue.push(future);\n return future.promise;\n }\n dequeue(value) {\n const future = this._queue.shift();\n future.resolve(value);\n }\n }\n /**\r\n * Semaphore allows you to limit the amount of async calls happening between `enter()` and `exit()`\r\n *\r\n * This can be useful when limiting the number of http calls, browser api calls, etc either for performance or to work\r\n * around browser limitations like max Image.decode() calls in chromium being 256.\r\n */ class Semaphore {\n constructor(_count){\n this._count = _count;\n this._waitQueue = new AsyncWaitQueue();\n }\n get count() {\n return this._count;\n }\n get waiting() {\n return this._waitQueue.length;\n }\n async enter() {\n if (this._count !== 0) {\n this._count--;\n return Promise.resolve();\n }\n return this._waitQueue.enqueue();\n }\n exit(count = 1) {\n if (count === 0) return;\n while(count !== 0 && this._waitQueue.length !== 0){\n this._waitQueue.dequeue(null);\n count--;\n }\n this._count += count;\n }\n }\n /**\r\n * The current Excalibur version string\r\n * @description `process.env.__EX_VERSION` gets replaced by Webpack on build\r\n */ const EX_VERSION = \"0.28.0\";\n polyfill();\n// This file is used as the bundle entry point and exports everything\n// that will be exposed as the `ex` global variable.\n// ex.Events namespace\n// ex.Input namespace\n// TODO deprecated import site remove in v0.29.0\n// ex.Util namespaces\n// ex.Deprecated\n// import * as deprecated from './Deprecated';\n// export { deprecated as Deprecated };\n// export * from './Deprecated';\n})();\nvar $2c23f148d58cd887$export$e04e17a44f37debc = $2c23f148d58cd887$var$__webpack_exports__.fWn;\nvar $2c23f148d58cd887$export$dfcd1bb88f6d711b = $2c23f148d58cd887$var$__webpack_exports__.Ia8;\nvar $2c23f148d58cd887$export$89f31cec7c284d42 = $2c23f148d58cd887$var$__webpack_exports__.rqv;\nvar $2c23f148d58cd887$export$856e7d6d9d698871 = $2c23f148d58cd887$var$__webpack_exports__.hLI;\nvar $2c23f148d58cd887$export$caffe607ed29fca1 = $2c23f148d58cd887$var$__webpack_exports__.yyv;\nvar $2c23f148d58cd887$export$adc62e83dbcda319 = $2c23f148d58cd887$var$__webpack_exports__.tX5;\nvar $2c23f148d58cd887$export$f73d3eb6fd876d80 = $2c23f148d58cd887$var$__webpack_exports__.vtX;\nvar $2c23f148d58cd887$export$da248c61eea53296 = $2c23f148d58cd887$var$__webpack_exports__.r7K;\nvar $2c23f148d58cd887$export$a314202b9f383ad4 = $2c23f148d58cd887$var$__webpack_exports__.lCh;\nvar $2c23f148d58cd887$export$f0455ab08e3fbd0e = $2c23f148d58cd887$var$__webpack_exports__.cE4;\nvar $2c23f148d58cd887$export$c35d437ae5945fcd = $2c23f148d58cd887$var$__webpack_exports__.fwF;\nvar $2c23f148d58cd887$export$67ee29bab3792d4c = $2c23f148d58cd887$var$__webpack_exports__.sce;\nvar $2c23f148d58cd887$export$d230853e97069d46 = $2c23f148d58cd887$var$__webpack_exports__.AQ6;\nvar $2c23f148d58cd887$export$6cfd78ddb48c90c6 = $2c23f148d58cd887$var$__webpack_exports__._c7;\nvar $2c23f148d58cd887$export$3769e64eb87b5ecc = $2c23f148d58cd887$var$__webpack_exports__.KUs;\nvar $2c23f148d58cd887$export$54dc36bc2fac5425 = $2c23f148d58cd887$var$__webpack_exports__.Ajp;\nvar $2c23f148d58cd887$export$387a78ab20784494 = $2c23f148d58cd887$var$__webpack_exports__.dkO;\nvar $2c23f148d58cd887$export$d06866a9fb0606da = $2c23f148d58cd887$var$__webpack_exports__.RDh;\nvar $2c23f148d58cd887$export$83c931ba0d3bbaf5 = $2c23f148d58cd887$var$__webpack_exports__._H9;\nvar $2c23f148d58cd887$export$1a553341cd0b8415 = $2c23f148d58cd887$var$__webpack_exports__.mxs;\nvar $2c23f148d58cd887$export$43416332cf06b1f = $2c23f148d58cd887$var$__webpack_exports__.OmD;\nvar $2c23f148d58cd887$export$63080c4de6cfc362 = $2c23f148d58cd887$var$__webpack_exports__.kBf;\nvar $2c23f148d58cd887$export$fa45ecb18b97ae89 = $2c23f148d58cd887$var$__webpack_exports__.C4F;\nvar $2c23f148d58cd887$export$c24f8f35353a1e26 = $2c23f148d58cd887$var$__webpack_exports__.NQt;\nvar $2c23f148d58cd887$export$8688def55452cbca = $2c23f148d58cd887$var$__webpack_exports__.JjN;\nvar $2c23f148d58cd887$export$665d5a662b7213f3 = $2c23f148d58cd887$var$__webpack_exports__.EK_;\nvar $2c23f148d58cd887$export$79f141de891a5fed = $2c23f148d58cd887$var$__webpack_exports__.V1s;\nvar $2c23f148d58cd887$export$41606648ac8a293c = $2c23f148d58cd887$var$__webpack_exports__.xHm;\nvar $2c23f148d58cd887$export$8d01c972ee8b14a9 = $2c23f148d58cd887$var$__webpack_exports__.Xz7;\nvar $2c23f148d58cd887$export$c89a927ffc67e6fa = $2c23f148d58cd887$var$__webpack_exports__.Cdc;\nvar $2c23f148d58cd887$export$e2395b697f5a931f = $2c23f148d58cd887$var$__webpack_exports__.FKn;\nvar $2c23f148d58cd887$export$9735c82c4bae3302 = $2c23f148d58cd887$var$__webpack_exports__.SUY;\nvar $2c23f148d58cd887$export$44e6803d1d57f89a = $2c23f148d58cd887$var$__webpack_exports__.ab2;\nvar $2c23f148d58cd887$export$1ed419d47673a225 = $2c23f148d58cd887$var$__webpack_exports__.GfZ;\nvar $2c23f148d58cd887$export$b7c6eef0ebb06133 = $2c23f148d58cd887$var$__webpack_exports__.YMS;\nvar $2c23f148d58cd887$export$3c9e91dc1b611d2e = $2c23f148d58cd887$var$__webpack_exports__.oyv;\nvar $2c23f148d58cd887$export$ce0ca64520c7bfd2 = $2c23f148d58cd887$var$__webpack_exports__.aUb;\nvar $2c23f148d58cd887$export$83caf30c40e9d4b8 = $2c23f148d58cd887$var$__webpack_exports__.SdD;\nvar $2c23f148d58cd887$export$4df0464d8c812c98 = $2c23f148d58cd887$var$__webpack_exports__.JUv;\nvar $2c23f148d58cd887$export$55e924fc640a8405 = $2c23f148d58cd887$var$__webpack_exports__.jEj;\nvar $2c23f148d58cd887$export$fbd6eb86d6a3f08 = $2c23f148d58cd887$var$__webpack_exports__.TFq;\nvar $2c23f148d58cd887$export$7cd2649c3408da6c = $2c23f148d58cd887$var$__webpack_exports__.HDU;\nvar $2c23f148d58cd887$export$897cd666d936ac4c = $2c23f148d58cd887$var$__webpack_exports__.R_y;\nvar $2c23f148d58cd887$export$cd81a0bc3006f9ff = $2c23f148d58cd887$var$__webpack_exports__.ydN;\nvar $2c23f148d58cd887$export$cf976780b3106589 = $2c23f148d58cd887$var$__webpack_exports__.t50;\nvar $2c23f148d58cd887$export$5dcfde0f6b96512b = $2c23f148d58cd887$var$__webpack_exports__.s$$;\nvar $2c23f148d58cd887$export$ddb2ed749236e720 = $2c23f148d58cd887$var$__webpack_exports__.v2G;\nvar $2c23f148d58cd887$export$892596cec99bc70e = $2c23f148d58cd887$var$__webpack_exports__.Ilk;\nvar $2c23f148d58cd887$export$8ed4b5bb5352fe14 = $2c23f148d58cd887$var$__webpack_exports__.s9i;\nvar $2c23f148d58cd887$export$c46090c9df657074 = $2c23f148d58cd887$var$__webpack_exports__.dxL;\nvar $2c23f148d58cd887$export$b3bf2ffaa538264b = $2c23f148d58cd887$var$__webpack_exports__.LLX;\nvar $2c23f148d58cd887$export$16fa2f45be04daa8 = $2c23f148d58cd887$var$__webpack_exports__.wA2;\nvar $2c23f148d58cd887$export$d16a7c95008e315d = $2c23f148d58cd887$var$__webpack_exports__.R_p;\nvar $2c23f148d58cd887$export$abda45806f5adbae = $2c23f148d58cd887$var$__webpack_exports__.IQ$;\nvar $2c23f148d58cd887$export$e5a30aa3d28b26e2 = $2c23f148d58cd887$var$__webpack_exports__.I5F;\nvar $2c23f148d58cd887$export$de7807bd8bd828df = $2c23f148d58cd887$var$__webpack_exports__.X8$;\nvar $2c23f148d58cd887$export$1bdfb0c7c42d632d = $2c23f148d58cd887$var$__webpack_exports__.FR6;\nvar $2c23f148d58cd887$export$71de6146fb6d69d2 = $2c23f148d58cd887$var$__webpack_exports__.U8o;\nvar $2c23f148d58cd887$export$71efaa2be447940c = $2c23f148d58cd887$var$__webpack_exports__.kbG;\nvar $2c23f148d58cd887$export$7d34ad93c25aa8e7 = $2c23f148d58cd887$var$__webpack_exports__.iS_;\nvar $2c23f148d58cd887$export$153e5dc2c098b35c = $2c23f148d58cd887$var$__webpack_exports__.cGG;\nvar $2c23f148d58cd887$export$c3e6e677dda8521a = $2c23f148d58cd887$var$__webpack_exports__.RPN;\nvar $2c23f148d58cd887$export$e52858e61b0ea117 = $2c23f148d58cd887$var$__webpack_exports__.skb;\nvar $2c23f148d58cd887$export$3d1f12550a40f54d = $2c23f148d58cd887$var$__webpack_exports__.SLU;\nvar $2c23f148d58cd887$export$e1545123b54f6785 = $2c23f148d58cd887$var$__webpack_exports__.RdJ;\nvar $2c23f148d58cd887$export$7419ff430885d61c = $2c23f148d58cd887$var$__webpack_exports__.cNu;\nvar $2c23f148d58cd887$export$e695250628cde35 = $2c23f148d58cd887$var$__webpack_exports__.gU7;\nvar $2c23f148d58cd887$export$c5e124f7bab3d492 = $2c23f148d58cd887$var$__webpack_exports__.LSk;\nvar $2c23f148d58cd887$export$cacd6541cfeeb6c1 = $2c23f148d58cd887$var$__webpack_exports__.Nmp;\nvar $2c23f148d58cd887$export$4b7264771109adb6 = $2c23f148d58cd887$var$__webpack_exports__.d1Y;\nvar $2c23f148d58cd887$export$62053d374d83dfb1 = $2c23f148d58cd887$var$__webpack_exports__.xrL;\nvar $2c23f148d58cd887$export$d7078bb1ea3ba3f2 = $2c23f148d58cd887$var$__webpack_exports__.sRW;\nvar $2c23f148d58cd887$export$86ae8da356d53161 = $2c23f148d58cd887$var$__webpack_exports__.cmV;\nvar $2c23f148d58cd887$export$62230588c4867d28 = $2c23f148d58cd887$var$__webpack_exports__.qWz;\nvar $2c23f148d58cd887$export$df007b1d5b86e25a = $2c23f148d58cd887$var$__webpack_exports__.N0Q;\nvar $2c23f148d58cd887$export$6ff391a2049fdf40 = $2c23f148d58cd887$var$__webpack_exports__.q8b;\nvar $2c23f148d58cd887$export$89e5ccdc4c19a8f6 = $2c23f148d58cd887$var$__webpack_exports__.ynB;\nvar $2c23f148d58cd887$export$2cbc8fe61dd10773 = $2c23f148d58cd887$var$__webpack_exports__.jT9;\nvar $2c23f148d58cd887$export$d45269226a4bbdc1 = $2c23f148d58cd887$var$__webpack_exports__.wAz;\nvar $2c23f148d58cd887$export$2c3b404bf3a77a1f = $2c23f148d58cd887$var$__webpack_exports__.D4V;\nvar $2c23f148d58cd887$export$20434e7e042d306a = $2c23f148d58cd887$var$__webpack_exports__.NLr;\nvar $2c23f148d58cd887$export$462adefbb095232e = $2c23f148d58cd887$var$__webpack_exports__.N6H;\nvar $2c23f148d58cd887$export$83f8212621739c1f = $2c23f148d58cd887$var$__webpack_exports__.W1A;\nvar $2c23f148d58cd887$export$bc644a473284d944 = $2c23f148d58cd887$var$__webpack_exports__.JHW;\nvar $2c23f148d58cd887$export$66b8a9cb33a156c = $2c23f148d58cd887$var$__webpack_exports__.ZZ$;\nvar $2c23f148d58cd887$export$c7b7134fd828a5 = $2c23f148d58cd887$var$__webpack_exports__.v2K;\nvar $2c23f148d58cd887$export$ec8b666c5fe2c75a = $2c23f148d58cd887$var$__webpack_exports__.pBf;\nvar $2c23f148d58cd887$export$4fae95256245c8c0 = $2c23f148d58cd887$var$__webpack_exports__.vpe;\nvar $2c23f148d58cd887$export$86d9a347f2bf71d6 = $2c23f148d58cd887$var$__webpack_exports__.GMl;\nvar $2c23f148d58cd887$export$ada873a34909da65 = $2c23f148d58cd887$var$__webpack_exports__.zW2;\nvar $2c23f148d58cd887$export$afee3afd6be961ec = $2c23f148d58cd887$var$__webpack_exports__.B0K;\nvar $2c23f148d58cd887$export$c03216fb3a7a2f87 = $2c23f148d58cd887$var$__webpack_exports__.Nv7;\nvar $2c23f148d58cd887$export$81940238f313e11f = $2c23f148d58cd887$var$__webpack_exports__.C_p;\nvar $2c23f148d58cd887$export$40f8f9a8f94db930 = $2c23f148d58cd887$var$__webpack_exports__.MUA;\nvar $2c23f148d58cd887$export$c579e21b95165414 = $2c23f148d58cd887$var$__webpack_exports__.xqU;\nvar $2c23f148d58cd887$export$c983850c6c9d8b0e = $2c23f148d58cd887$var$__webpack_exports__.pTp;\nvar $2c23f148d58cd887$export$434ba092ed0eee4e = $2c23f148d58cd887$var$__webpack_exports__.vUK;\nvar $2c23f148d58cd887$export$455f05776f1ba8ba = $2c23f148d58cd887$var$__webpack_exports__.j9l;\nvar $2c23f148d58cd887$export$89abf52a030e56ee = $2c23f148d58cd887$var$__webpack_exports__.Zxw;\nvar $2c23f148d58cd887$export$549c899505235621 = $2c23f148d58cd887$var$__webpack_exports__.v51;\nvar $2c23f148d58cd887$export$23b468d4ca3f8c96 = $2c23f148d58cd887$var$__webpack_exports__.Hdx;\nvar $2c23f148d58cd887$export$6976e674e6d5804c = $2c23f148d58cd887$var$__webpack_exports__.Z$d;\nvar $2c23f148d58cd887$export$420acfc1740638d3 = $2c23f148d58cd887$var$__webpack_exports__.iqV;\nvar $2c23f148d58cd887$export$e84927905accfe51 = $2c23f148d58cd887$var$__webpack_exports__.o$7;\nvar $2c23f148d58cd887$export$c9d7bf589772a8ce = $2c23f148d58cd887$var$__webpack_exports__.olM;\nvar $2c23f148d58cd887$export$d5011a4647754c9b = $2c23f148d58cd887$var$__webpack_exports__.Zm$;\nvar $2c23f148d58cd887$export$b8c6aa234afa01bc = $2c23f148d58cd887$var$__webpack_exports__.$QH;\nvar $2c23f148d58cd887$export$6c3776220abeb931 = $2c23f148d58cd887$var$__webpack_exports__.i78;\nvar $2c23f148d58cd887$export$27a9cd7ebdd38262 = $2c23f148d58cd887$var$__webpack_exports__.nJg;\nvar $2c23f148d58cd887$export$fb1b94e06ba8ebc8 = $2c23f148d58cd887$var$__webpack_exports__.h6u;\nvar $2c23f148d58cd887$export$3d953a2d86354b5f = $2c23f148d58cd887$var$__webpack_exports__.hts;\nvar $2c23f148d58cd887$export$88528019d270f582 = $2c23f148d58cd887$var$__webpack_exports__.j88;\nvar $2c23f148d58cd887$export$402da60b1c009e43 = $2c23f148d58cd887$var$__webpack_exports__.VME;\nvar $2c23f148d58cd887$export$757ccd1717b77f48 = $2c23f148d58cd887$var$__webpack_exports__.fy2;\nvar $2c23f148d58cd887$export$48ebf29bc7cb1dd7 = $2c23f148d58cd887$var$__webpack_exports__.nt;\nvar $2c23f148d58cd887$export$3c8c04bde7eed7cb = $2c23f148d58cd887$var$__webpack_exports__.Ukr;\nvar $2c23f148d58cd887$export$adfa9d260876eca5 = $2c23f148d58cd887$var$__webpack_exports__.zsu;\nvar $2c23f148d58cd887$export$6c043ed3a716859a = $2c23f148d58cd887$var$__webpack_exports__.oA6;\nvar $2c23f148d58cd887$export$9f9afb456a8bef30 = $2c23f148d58cd887$var$__webpack_exports__.TVh;\nvar $2c23f148d58cd887$export$46d098cf93b32a72 = $2c23f148d58cd887$var$__webpack_exports__.TwZ;\nvar $2c23f148d58cd887$export$2fcc9871fa09b4ce = $2c23f148d58cd887$var$__webpack_exports__.GTT;\nvar $2c23f148d58cd887$export$1033a6fa0779f4f5 = $2c23f148d58cd887$var$__webpack_exports__.xxj;\nvar $2c23f148d58cd887$export$38f8109d2b8f43ef = $2c23f148d58cd887$var$__webpack_exports__.XdK;\nvar $2c23f148d58cd887$export$5213deb2877a09f2 = $2c23f148d58cd887$var$__webpack_exports__.Jmb;\nvar $2c23f148d58cd887$export$280e9a68c3ffd919 = $2c23f148d58cd887$var$__webpack_exports__.cXo;\nvar $2c23f148d58cd887$export$49a1ecce8d203 = $2c23f148d58cd887$var$__webpack_exports__.Dm5;\nvar $2c23f148d58cd887$export$f5b8910cec6cf069 = $2c23f148d58cd887$var$__webpack_exports__.IIB;\nvar $2c23f148d58cd887$export$2ae6ec0f10d96242 = $2c23f148d58cd887$var$__webpack_exports__.ebW;\nvar $2c23f148d58cd887$export$d379657aa3df1705 = $2c23f148d58cd887$var$__webpack_exports__.zI0;\nvar $2c23f148d58cd887$export$ffed6a4cd9a88787 = $2c23f148d58cd887$var$__webpack_exports__.LYD;\nvar $2c23f148d58cd887$export$7705889256a9371a = $2c23f148d58cd887$var$__webpack_exports__.cEG;\nvar $2c23f148d58cd887$export$539f65e788a82c62 = $2c23f148d58cd887$var$__webpack_exports__.SEl;\nvar $2c23f148d58cd887$export$851e6d93385b6ad2 = $2c23f148d58cd887$var$__webpack_exports__.t9V;\nvar $2c23f148d58cd887$export$4b0c1c390bf9a356 = $2c23f148d58cd887$var$__webpack_exports__.ez5;\nvar $2c23f148d58cd887$export$16e4d70cc375e707 = $2c23f148d58cd887$var$__webpack_exports__.N1d;\nvar $2c23f148d58cd887$export$4b0075e5ea5e1f26 = $2c23f148d58cd887$var$__webpack_exports__.R8U;\nvar $2c23f148d58cd887$export$f3a6c1ca682fd40f = $2c23f148d58cd887$var$__webpack_exports__.SKZ;\nvar $2c23f148d58cd887$export$b04be29aa201d4f5 = $2c23f148d58cd887$var$__webpack_exports__.__J;\nvar $2c23f148d58cd887$export$b3509fba7d85d294 = $2c23f148d58cd887$var$__webpack_exports__.RI$;\nvar $2c23f148d58cd887$export$17d680238e50603e = $2c23f148d58cd887$var$__webpack_exports__.x12;\nvar $2c23f148d58cd887$export$8b98feb4a2766c75 = $2c23f148d58cd887$var$__webpack_exports__.ccz;\nvar $2c23f148d58cd887$export$3b0d6d7590275603 = $2c23f148d58cd887$var$__webpack_exports__.aNw;\nvar $2c23f148d58cd887$export$38d47553764a3d88 = $2c23f148d58cd887$var$__webpack_exports__.XrL;\nvar $2c23f148d58cd887$export$1c4c6d3f8d56581 = $2c23f148d58cd887$var$__webpack_exports__.xwn;\nvar $2c23f148d58cd887$export$fc869739b2177284 = $2c23f148d58cd887$var$__webpack_exports__.dNK;\nvar $2c23f148d58cd887$export$243e62d78d3b544d = $2c23f148d58cd887$var$__webpack_exports__.ini;\nvar $2c23f148d58cd887$export$efa9a398d6368992 = $2c23f148d58cd887$var$__webpack_exports__.YdH;\nvar $2c23f148d58cd887$export$a2d8b23205c25948 = $2c23f148d58cd887$var$__webpack_exports__.F5T;\nvar $2c23f148d58cd887$export$5b12bf1653c0dd85 = $2c23f148d58cd887$var$__webpack_exports__.y3G;\nvar $2c23f148d58cd887$export$9f9b2346169b00c0 = $2c23f148d58cd887$var$__webpack_exports__.l57;\nvar $2c23f148d58cd887$export$8c37b217b84d3f89 = $2c23f148d58cd887$var$__webpack_exports__.xn0;\nvar $2c23f148d58cd887$export$35624b13e79b24a9 = $2c23f148d58cd887$var$__webpack_exports__.t2V;\nvar $2c23f148d58cd887$export$f75e7304717c9cbc = $2c23f148d58cd887$var$__webpack_exports__.uxB;\nvar $2c23f148d58cd887$export$ec1251c88c8bd5c9 = $2c23f148d58cd887$var$__webpack_exports__.cpd;\nvar $2c23f148d58cd887$export$d17844835b0fe8a8 = $2c23f148d58cd887$var$__webpack_exports__.fiy;\nvar $2c23f148d58cd887$export$d1d8cb3d5c2a5671 = $2c23f148d58cd887$var$__webpack_exports__.$XZ;\nvar $2c23f148d58cd887$export$4d607ef791645d6 = $2c23f148d58cd887$var$__webpack_exports__.UG6;\nvar $2c23f148d58cd887$export$f0b55daf9f154b55 = $2c23f148d58cd887$var$__webpack_exports__.uqK;\nvar $2c23f148d58cd887$export$fa9699e41ba6faff = $2c23f148d58cd887$var$__webpack_exports__.STE;\nvar $2c23f148d58cd887$export$77cea355fa80b5f4 = $2c23f148d58cd887$var$__webpack_exports__.y$z;\nvar $2c23f148d58cd887$export$8844adde4348f85c = $2c23f148d58cd887$var$__webpack_exports__.mAD;\nvar $2c23f148d58cd887$export$d63d7cff08fe4dc9 = $2c23f148d58cd887$var$__webpack_exports__.sOq;\nvar $2c23f148d58cd887$export$a960801e47624f4f = $2c23f148d58cd887$var$__webpack_exports__.hUw;\nvar $2c23f148d58cd887$export$ed6a63ee685a4d78 = $2c23f148d58cd887$var$__webpack_exports__._0G;\nvar $2c23f148d58cd887$export$4fe52ae24ae61d51 = $2c23f148d58cd887$var$__webpack_exports__.Sqs;\nvar $2c23f148d58cd887$export$c36c68baa13912a5 = $2c23f148d58cd887$var$__webpack_exports__.hpZ;\nvar $2c23f148d58cd887$export$616c632b282478dd = $2c23f148d58cd887$var$__webpack_exports__.Vol;\nvar $2c23f148d58cd887$export$459b1801e3134a24 = $2c23f148d58cd887$var$__webpack_exports__.vYX;\nvar $2c23f148d58cd887$export$2f09efa5b67124a7 = $2c23f148d58cd887$var$__webpack_exports__.wIZ;\nvar $2c23f148d58cd887$export$618424ba3f30cd41 = $2c23f148d58cd887$var$__webpack_exports__.cBi;\nvar $2c23f148d58cd887$export$4a963ea7a16edf21 = $2c23f148d58cd887$var$__webpack_exports__.c30;\nvar $2c23f148d58cd887$export$982e5de016bedff1 = $2c23f148d58cd887$var$__webpack_exports__.MPV;\nvar $2c23f148d58cd887$export$6860c0696b73f79b = $2c23f148d58cd887$var$__webpack_exports__.RFv;\nvar $2c23f148d58cd887$export$94806efd9890932f = $2c23f148d58cd887$var$__webpack_exports__.Ux6;\nvar $2c23f148d58cd887$export$3bee0b2628b43478 = $2c23f148d58cd887$var$__webpack_exports__.rxy;\nvar $2c23f148d58cd887$export$caed39dbb767d548 = $2c23f148d58cd887$var$__webpack_exports__.I$c;\nvar $2c23f148d58cd887$export$7e5ab4f7f9fd407 = $2c23f148d58cd887$var$__webpack_exports__.kfC;\nvar $2c23f148d58cd887$export$330520496d871ecf = $2c23f148d58cd887$var$__webpack_exports__.VjY;\nvar $2c23f148d58cd887$export$7d31b617c820d435 = $2c23f148d58cd887$var$__webpack_exports__.mgq;\nvar $2c23f148d58cd887$export$f23a2a272a8df60 = $2c23f148d58cd887$var$__webpack_exports__.YVA;\nvar $2c23f148d58cd887$export$14963ee5c8637e11 = $2c23f148d58cd887$var$__webpack_exports__.Kgp;\nvar $2c23f148d58cd887$export$1d2c184034fc4cc2 = $2c23f148d58cd887$var$__webpack_exports__.HH$;\nvar $2c23f148d58cd887$export$fea21a521a6360c1 = $2c23f148d58cd887$var$__webpack_exports__.M_d;\nvar $2c23f148d58cd887$export$8c15bdf7e3727f73 = $2c23f148d58cd887$var$__webpack_exports__.rgh;\nvar $2c23f148d58cd887$export$6eb043bf81d89752 = $2c23f148d58cd887$var$__webpack_exports__.Ra6;\nvar $2c23f148d58cd887$export$e390b859365a3d5b = $2c23f148d58cd887$var$__webpack_exports__.KhR;\nvar $2c23f148d58cd887$export$1ec85152758537e0 = $2c23f148d58cd887$var$__webpack_exports__.BS5;\nvar $2c23f148d58cd887$export$a8584993858a18df = $2c23f148d58cd887$var$__webpack_exports__.xhz;\nvar $2c23f148d58cd887$export$906049a3747337a6 = $2c23f148d58cd887$var$__webpack_exports__.xOq;\nvar $2c23f148d58cd887$export$dbd8a6303ac26a42 = $2c23f148d58cd887$var$__webpack_exports__.a9j;\nvar $2c23f148d58cd887$export$9f68b6f37a444556 = $2c23f148d58cd887$var$__webpack_exports__.bHk;\nvar $2c23f148d58cd887$export$fe2b6ac465da985d = $2c23f148d58cd887$var$__webpack_exports__.CgK;\nvar $2c23f148d58cd887$export$e44279b5c44add28 = $2c23f148d58cd887$var$__webpack_exports__.cuY;\nvar $2c23f148d58cd887$export$dfa3a012bb2ef2e1 = $2c23f148d58cd887$var$__webpack_exports__.kvE;\nvar $2c23f148d58cd887$export$8201b979875baf73 = $2c23f148d58cd887$var$__webpack_exports__.SBu;\nvar $2c23f148d58cd887$export$62297b13309008b2 = $2c23f148d58cd887$var$__webpack_exports__.AE_;\nvar $2c23f148d58cd887$export$b986383a50b53ea4 = $2c23f148d58cd887$var$__webpack_exports__.ctO;\nvar $2c23f148d58cd887$export$ad5b3d166367714c = $2c23f148d58cd887$var$__webpack_exports__.OLH;\nvar $2c23f148d58cd887$export$a92776769f460054 = $2c23f148d58cd887$var$__webpack_exports__.kky;\nvar $2c23f148d58cd887$export$eeb71495ca594706 = $2c23f148d58cd887$var$__webpack_exports__.nSF;\nvar $2c23f148d58cd887$export$a186db52eed6d40e = $2c23f148d58cd887$var$__webpack_exports__.zHn;\nvar $2c23f148d58cd887$export$c07ce6d13c46df49 = $2c23f148d58cd887$var$__webpack_exports__.zwx;\nvar $2c23f148d58cd887$export$4617fb02663045ef = $2c23f148d58cd887$var$__webpack_exports__.AeJ;\nvar $2c23f148d58cd887$export$32437fc39ad02208 = $2c23f148d58cd887$var$__webpack_exports__.hLz;\nvar $2c23f148d58cd887$export$1f63032528469f52 = $2c23f148d58cd887$var$__webpack_exports__.D9g;\nvar $2c23f148d58cd887$export$f9d61a2a6155ab51 = $2c23f148d58cd887$var$__webpack_exports__.wA;\nvar $2c23f148d58cd887$export$9bd81f7d9b69ccb3 = $2c23f148d58cd887$var$__webpack_exports__.jhr;\nvar $2c23f148d58cd887$export$3e4ff2216a90b8a4 = $2c23f148d58cd887$var$__webpack_exports__.GVs;\nvar $2c23f148d58cd887$export$39a853cfb5a94a63 = $2c23f148d58cd887$var$__webpack_exports__._zO;\nvar $2c23f148d58cd887$export$62833702c6700187 = $2c23f148d58cd887$var$__webpack_exports__.LXZ;\nvar $2c23f148d58cd887$export$a43177620e7a9310 = $2c23f148d58cd887$var$__webpack_exports__.w6$;\nvar $2c23f148d58cd887$export$a16b6ef1fd362a19 = $2c23f148d58cd887$var$__webpack_exports__.mhV;\nvar $2c23f148d58cd887$export$91397be43fc980cc = $2c23f148d58cd887$var$__webpack_exports__.MOD;\nvar $2c23f148d58cd887$export$23b9d128e61caefd = $2c23f148d58cd887$var$__webpack_exports__.kwd;\nvar $2c23f148d58cd887$export$ab681471d41eeddc = $2c23f148d58cd887$var$__webpack_exports__.Lmr;\nvar $2c23f148d58cd887$export$38af1803e3442a7f = $2c23f148d58cd887$var$__webpack_exports__.xsS;\nvar $2c23f148d58cd887$export$c1825d965cf69ea3 = $2c23f148d58cd887$var$__webpack_exports__.K5l;\nvar $2c23f148d58cd887$export$a98515d67472a41f = $2c23f148d58cd887$var$__webpack_exports__.lLr;\nvar $2c23f148d58cd887$export$57486627f01aaaf3 = $2c23f148d58cd887$var$__webpack_exports__.Z$r;\nvar $2c23f148d58cd887$export$77630fcd7c3f2eb6 = $2c23f148d58cd887$var$__webpack_exports__.IXb;\nvar $2c23f148d58cd887$export$2f3ac66e390c188b = $2c23f148d58cd887$var$__webpack_exports__.SGH;\nvar $2c23f148d58cd887$export$d160a188872e1e4e = $2c23f148d58cd887$var$__webpack_exports__.SMj;\nvar $2c23f148d58cd887$export$5c7bd08c630c970c = $2c23f148d58cd887$var$__webpack_exports__.L34;\nvar $2c23f148d58cd887$export$462bb059fed9d9e5 = $2c23f148d58cd887$var$__webpack_exports__.exe;\nvar $2c23f148d58cd887$export$6428a7f2611ef1fa = $2c23f148d58cd887$var$__webpack_exports__.bnF;\nvar $2c23f148d58cd887$export$80a00690bda7f17e = $2c23f148d58cd887$var$__webpack_exports__.MFA;\nvar $2c23f148d58cd887$export$85990f0f98a390bb = $2c23f148d58cd887$var$__webpack_exports__.$uU;\nvar $2c23f148d58cd887$export$5bff0d6cc6200d64 = $2c23f148d58cd887$var$__webpack_exports__.Sap;\nvar $2c23f148d58cd887$export$3075603db8e6204c = $2c23f148d58cd887$var$__webpack_exports__.jyi;\nvar $2c23f148d58cd887$export$e1896ac0c4970221 = $2c23f148d58cd887$var$__webpack_exports__.E03;\nvar $2c23f148d58cd887$export$bd73ddfe5f8475d8 = $2c23f148d58cd887$var$__webpack_exports__.V6q;\nvar $2c23f148d58cd887$export$f62bb2892382b3dd = $2c23f148d58cd887$var$__webpack_exports__.rg2;\nvar $2c23f148d58cd887$export$cbf2d83d1eab018a = $2c23f148d58cd887$var$__webpack_exports__.DVW;\nvar $2c23f148d58cd887$export$9ad53eded130cce4 = $2c23f148d58cd887$var$__webpack_exports__.nVo;\nvar $2c23f148d58cd887$export$6a4eb2e7fc9e8903 = $2c23f148d58cd887$var$__webpack_exports__.F6N;\nvar $2c23f148d58cd887$export$e1dae5660003ffa7 = $2c23f148d58cd887$var$__webpack_exports__.xP7;\nvar $2c23f148d58cd887$export$a12e67a4b4590901 = $2c23f148d58cd887$var$__webpack_exports__.Odq;\nvar $2c23f148d58cd887$export$c586aa7b67d94d19 = $2c23f148d58cd887$var$__webpack_exports__.Zif;\nvar $2c23f148d58cd887$export$b06669ac5ed603e = $2c23f148d58cd887$var$__webpack_exports__.ZGJ;\nvar $2c23f148d58cd887$export$9440a22058545f9a = $2c23f148d58cd887$var$__webpack_exports__.MJk;\nvar $2c23f148d58cd887$export$5f1af8db9871e1d6 = $2c23f148d58cd887$var$__webpack_exports__.xvT;\nvar $2c23f148d58cd887$export$3720eb13f948f394 = $2c23f148d58cd887$var$__webpack_exports__.PHM;\nvar $2c23f148d58cd887$export$fd1bfc71f64c538c = $2c23f148d58cd887$var$__webpack_exports__.dpR;\nvar $2c23f148d58cd887$export$235cb65c20ad2b7 = $2c23f148d58cd887$var$__webpack_exports__.n9L;\nvar $2c23f148d58cd887$export$16ec26812de3ce7a = $2c23f148d58cd887$var$__webpack_exports__.KwO;\nvar $2c23f148d58cd887$export$dac3abbdc575ce73 = $2c23f148d58cd887$var$__webpack_exports__.SxM;\nvar $2c23f148d58cd887$export$c57e9b2d8b9e4de = $2c23f148d58cd887$var$__webpack_exports__.B7y;\nvar $2c23f148d58cd887$export$fb98e3a2a4cd92d7 = $2c23f148d58cd887$var$__webpack_exports__.x7r;\nvar $2c23f148d58cd887$export$563a914cafbdc389 = $2c23f148d58cd887$var$__webpack_exports__.wx7;\nvar $2c23f148d58cd887$export$1def2aa75b7c7fe0 = $2c23f148d58cd887$var$__webpack_exports__.Uvn;\nvar $2c23f148d58cd887$export$2eba8ec3a333fdbb = $2c23f148d58cd887$var$__webpack_exports__.OFT;\nvar $2c23f148d58cd887$export$41fb9f06171c75f4 = $2c23f148d58cd887$var$__webpack_exports__.xzN;\nvar $2c23f148d58cd887$export$14963f945d6d59f0 = $2c23f148d58cd887$var$__webpack_exports__.CcZ;\nvar $2c23f148d58cd887$export$ba8651401a8a2b84 = $2c23f148d58cd887$var$__webpack_exports__.M5Z;\nvar $2c23f148d58cd887$export$f8f26dd395d7e1bd = $2c23f148d58cd887$var$__webpack_exports__.ZrN;\nvar $2c23f148d58cd887$export$9b781de7bf37bf48 = $2c23f148d58cd887$var$__webpack_exports__.OWs;\nvar $2c23f148d58cd887$export$ab650c8e5b9b9f2c = $2c23f148d58cd887$var$__webpack_exports__.dF9;\nvar $2c23f148d58cd887$export$41825a1ed6473903 = $2c23f148d58cd887$var$__webpack_exports__.oZy;\nvar $2c23f148d58cd887$export$f5ae2f144b95ebf4 = $2c23f148d58cd887$var$__webpack_exports__.rD2;\nvar $2c23f148d58cd887$export$d5c6f73f7a77b9d = $2c23f148d58cd887$var$__webpack_exports__.VHo;\nvar $2c23f148d58cd887$export$8bfbf00b5dba81f6 = $2c23f148d58cd887$var$__webpack_exports__.ohE;\nvar $2c23f148d58cd887$export$2af5ef044257da25 = $2c23f148d58cd887$var$__webpack_exports__.R$E;\nvar $2c23f148d58cd887$export$8c3375c231593a9d = $2c23f148d58cd887$var$__webpack_exports__.xQN;\nvar $2c23f148d58cd887$export$9a4eae43f302c46e = $2c23f148d58cd887$var$__webpack_exports__.AdJ;\nvar $2c23f148d58cd887$export$812cd9544993280d = $2c23f148d58cd887$var$__webpack_exports__.q3I;\nvar $2c23f148d58cd887$export$a4913eafbb02ceb4 = $2c23f148d58cd887$var$__webpack_exports__.Pab;\nvar $2c23f148d58cd887$export$7d15b64cf5a3a4c4 = $2c23f148d58cd887$var$__webpack_exports__.uZ5;\nvar $2c23f148d58cd887$export$7149c6ffc9994c32 = $2c23f148d58cd887$var$__webpack_exports__.McK;\nvar $2c23f148d58cd887$export$d436988b04cb99a5 = $2c23f148d58cd887$var$__webpack_exports__.F9c;\nvar $2c23f148d58cd887$export$3ba9f2e94585ecc6 = $2c23f148d58cd887$var$__webpack_exports__.k0b;\nvar $2c23f148d58cd887$export$25dac40984956196 = $2c23f148d58cd887$var$__webpack_exports__.hnT;\nvar $2c23f148d58cd887$export$57932b71da6538b7 = $2c23f148d58cd887$var$__webpack_exports__.RSJ;\nvar $2c23f148d58cd887$export$a17402ef5f32064d = $2c23f148d58cd887$var$__webpack_exports__.Mku;\nvar $2c23f148d58cd887$export$d5dea09620a858fd = $2c23f148d58cd887$var$__webpack_exports__.h90;\nvar $2c23f148d58cd887$export$1377812d73ae3cab = $2c23f148d58cd887$var$__webpack_exports__.rms;\nvar $2c23f148d58cd887$export$331f4c7ef74a9752 = $2c23f148d58cd887$var$__webpack_exports__.ErP;\nvar $2c23f148d58cd887$export$5f4e18965661d41f = $2c23f148d58cd887$var$__webpack_exports__.aVg;\nvar $2c23f148d58cd887$export$817667946f51142b = $2c23f148d58cd887$var$__webpack_exports__.lPc;\nvar $2c23f148d58cd887$export$adc479603c39b28 = $2c23f148d58cd887$var$__webpack_exports__.Z8E;\nvar $2c23f148d58cd887$export$af0aa2f45005ee8e = $2c23f148d58cd887$var$__webpack_exports__._N2;\nvar $2c23f148d58cd887$export$6ef10647aef84ad9 = $2c23f148d58cd887$var$__webpack_exports__.yFn;\nvar $2c23f148d58cd887$export$256576ea924e6c90 = $2c23f148d58cd887$var$__webpack_exports__.lNv;\nvar $2c23f148d58cd887$export$e87630d8ef35465d = $2c23f148d58cd887$var$__webpack_exports__.cu9;\nvar $2c23f148d58cd887$export$5a62d8eea226ddc = $2c23f148d58cd887$var$__webpack_exports__.MZQ;\nvar $2c23f148d58cd887$export$640d107500a3202a = $2c23f148d58cd887$var$__webpack_exports__.FUM;\nvar $2c23f148d58cd887$export$506bf22710a79182 = $2c23f148d58cd887$var$__webpack_exports__.BxR;\nvar $2c23f148d58cd887$export$8b958c8ecd94a804 = $2c23f148d58cd887$var$__webpack_exports__.vdf;\nvar $2c23f148d58cd887$export$816343276f749e02 = $2c23f148d58cd887$var$__webpack_exports__.iaL;\nvar $2c23f148d58cd887$export$d02631cccf789723 = $2c23f148d58cd887$var$__webpack_exports__.w6H;\nvar $2c23f148d58cd887$export$5dc5812d8b390c43 = $2c23f148d58cd887$var$__webpack_exports__.Q4c;\nvar $2c23f148d58cd887$export$c5552dfdbc7cec71 = $2c23f148d58cd887$var$__webpack_exports__.Xxe;\nvar $2c23f148d58cd887$export$56cb859c01fa134d = $2c23f148d58cd887$var$__webpack_exports__.Uxb;\nvar $2c23f148d58cd887$export$cba01ba138429a1d = $2c23f148d58cd887$var$__webpack_exports__.Yr5;\nvar $2c23f148d58cd887$export$202e0172ed3c7be0 = $2c23f148d58cd887$var$__webpack_exports__.Bhw;\nvar $2c23f148d58cd887$export$d55298c9efc5ed14 = $2c23f148d58cd887$var$__webpack_exports__.yOA;\n\n\n\nvar $0e59e15bfde09edd$exports = {};\n$0e59e15bfde09edd$exports = new URL(\"title.46943752.png\", import.meta.url).toString();\n\n\nvar $0dc129d04ae81ef3$exports = {};\n$0dc129d04ae81ef3$exports = new URL(\"KnightSheet.2897b254.png\", import.meta.url).toString();\n\n\nvar $e2c126f1741b57c5$exports = {};\n$e2c126f1741b57c5$exports = new URL(\"SpiderSheet.597e1dd4.png\", import.meta.url).toString();\n\n\nvar $fe801e9860db2eda$exports = {};\n$fe801e9860db2eda$exports = new URL(\"HeartSheet.54a99443.png\", import.meta.url).toString();\n\n\nvar $49eab19c842e103d$exports = {};\n$49eab19c842e103d$exports = new URL(\"UISheet.2837e64f.png\", import.meta.url).toString();\n\n\nvar $f960c73d1d02bc54$exports = {};\n$f960c73d1d02bc54$exports = new URL(\"TerrainSheet.e61d651c.png\", import.meta.url).toString();\n\n\nvar $2a43ddce8853d60a$exports = {};\n$2a43ddce8853d60a$exports = new URL(\"HighlightSheet.fff21fa0.png\", import.meta.url).toString();\n\n\nvar $5727a3bc57be5870$exports = {};\n$5727a3bc57be5870$exports = new URL(\"RedHighlightSheet.4a69e4d5.png\", import.meta.url).toString();\n\n\nvar $60ddec0594d58f71$exports = {};\n$60ddec0594d58f71$exports = new URL(\"Cloud.e0b572a9.png\", import.meta.url).toString();\n\n\nvar $0ce3a12f1f5dd845$exports = {};\n$0ce3a12f1f5dd845$exports = new URL(\"Smoke.7bc6cfe7.png\", import.meta.url).toString();\n\n\nvar $6fb18f44ab9c1595$exports = {};\n$6fb18f44ab9c1595$exports = new URL(\"hit.cc332530.wav\", import.meta.url).toString();\n\n\nvar $540b76347fea9b08$exports = {};\n$540b76347fea9b08$exports = new URL(\"move.8e8aee5f.wav\", import.meta.url).toString();\n\n\nvar $149deb400e52312b$exports = {};\n$149deb400e52312b$exports = new URL(\"unitselect.d85b2a99.wav\", import.meta.url).toString();\n\n\nvar $3bf6bc4c70ae7e5f$exports = {};\n$3bf6bc4c70ae7e5f$exports = new URL(\"targetselect.05425c18.wav\", import.meta.url).toString();\n\n\nvar $6329ef07da9769a2$exports = {};\n$6329ef07da9769a2$exports = new URL(\"tutorial-text.d113bd93.png\", import.meta.url).toString();\n\n\nvar $770101c101acbf23$exports = {};\n$770101c101acbf23$exports = new URL(\"Juhani Junkala [Retro Game Music Pack] Level 3.af273cb2.wav\", import.meta.url).toString();\n\n\nvar $9b8ad1dd8b8bdeb1$exports = {};\n$9b8ad1dd8b8bdeb1$exports = new URL(\"gba1complete.c6e75e6f.mp3\", import.meta.url).toString();\n\n\nvar $4120cca26470015b$exports = {};\n$4120cca26470015b$exports = new URL(\"explosion.cd6dbdc9.png\", import.meta.url).toString();\n\n\nvar $6fb9ec456a8e0c26$exports = {};\n$6fb9ec456a8e0c26$exports = new URL(\"explosion.fcafad1f.wav\", import.meta.url).toString();\n\n\nvar $8e99a37004d52dd3$exports = {};\n$8e99a37004d52dd3$exports = new URL(\"two_left_socks.7d2f267c.ogg\", import.meta.url).toString();\n\n\nconst $7c4c300842bd4cf2$export$e9a269813a6315a4 = {\n TitleImage: new $2c23f148d58cd887$export$280e9a68c3ffd919((0, (/*@__PURE__*/$parcel$interopDefault($0e59e15bfde09edd$exports)))),\n KnightSpriteSheet: new $2c23f148d58cd887$export$280e9a68c3ffd919((0, (/*@__PURE__*/$parcel$interopDefault($0dc129d04ae81ef3$exports)))),\n SpiderSheet: new $2c23f148d58cd887$export$280e9a68c3ffd919((0, (/*@__PURE__*/$parcel$interopDefault($e2c126f1741b57c5$exports)))),\n HeartSheet: new $2c23f148d58cd887$export$280e9a68c3ffd919((0, (/*@__PURE__*/$parcel$interopDefault($fe801e9860db2eda$exports)))),\n UISheet: new $2c23f148d58cd887$export$280e9a68c3ffd919((0, (/*@__PURE__*/$parcel$interopDefault($49eab19c842e103d$exports)))),\n TerrainSheet: new $2c23f148d58cd887$export$280e9a68c3ffd919((0, (/*@__PURE__*/$parcel$interopDefault($f960c73d1d02bc54$exports)))),\n HighlightSheet: new $2c23f148d58cd887$export$280e9a68c3ffd919((0, (/*@__PURE__*/$parcel$interopDefault($2a43ddce8853d60a$exports)))),\n RedHighlightSheet: new $2c23f148d58cd887$export$280e9a68c3ffd919((0, (/*@__PURE__*/$parcel$interopDefault($5727a3bc57be5870$exports)))),\n CloudSheet: new $2c23f148d58cd887$export$280e9a68c3ffd919((0, (/*@__PURE__*/$parcel$interopDefault($60ddec0594d58f71$exports)))),\n SmokeSheet: new $2c23f148d58cd887$export$280e9a68c3ffd919((0, (/*@__PURE__*/$parcel$interopDefault($0ce3a12f1f5dd845$exports)))),\n TutorialText: new $2c23f148d58cd887$export$280e9a68c3ffd919((0, (/*@__PURE__*/$parcel$interopDefault($6329ef07da9769a2$exports)))),\n ExplosionSheet: new $2c23f148d58cd887$export$280e9a68c3ffd919((0, (/*@__PURE__*/$parcel$interopDefault($4120cca26470015b$exports)))),\n HitSound: new $2c23f148d58cd887$export$85990f0f98a390bb((0, (/*@__PURE__*/$parcel$interopDefault($6fb18f44ab9c1595$exports)))),\n MoveSound: new $2c23f148d58cd887$export$85990f0f98a390bb((0, (/*@__PURE__*/$parcel$interopDefault($540b76347fea9b08$exports)))),\n SelectSound: new $2c23f148d58cd887$export$85990f0f98a390bb((0, (/*@__PURE__*/$parcel$interopDefault($149deb400e52312b$exports)))),\n TargetSelectSound: new $2c23f148d58cd887$export$85990f0f98a390bb((0, (/*@__PURE__*/$parcel$interopDefault($3bf6bc4c70ae7e5f$exports)))),\n LevelMusic1: new $2c23f148d58cd887$export$85990f0f98a390bb((0, (/*@__PURE__*/$parcel$interopDefault($770101c101acbf23$exports)))),\n LevelMusic2: new $2c23f148d58cd887$export$85990f0f98a390bb((0, (/*@__PURE__*/$parcel$interopDefault($9b8ad1dd8b8bdeb1$exports)))),\n ExplosionSound: new $2c23f148d58cd887$export$85990f0f98a390bb((0, (/*@__PURE__*/$parcel$interopDefault($6fb9ec456a8e0c26$exports)))),\n TitleMusic: new $2c23f148d58cd887$export$85990f0f98a390bb((0, (/*@__PURE__*/$parcel$interopDefault($8e99a37004d52dd3$exports))))\n};\nconst $7c4c300842bd4cf2$export$a3c7706a72a05aed = $2c23f148d58cd887$export$bd73ddfe5f8475d8.fromImageSource({\n image: $7c4c300842bd4cf2$export$e9a269813a6315a4.TutorialText,\n grid: {\n rows: 1,\n columns: 8,\n spriteWidth: 128,\n spriteHeight: 64\n }\n});\nconst $7c4c300842bd4cf2$export$fcaf55e17c4b44d6 = $2c23f148d58cd887$export$bd73ddfe5f8475d8.fromImageSource({\n image: $7c4c300842bd4cf2$export$e9a269813a6315a4.TerrainSheet,\n grid: {\n rows: 5,\n columns: 5,\n spriteHeight: 32,\n spriteWidth: 32\n }\n});\nconst $7c4c300842bd4cf2$export$d1be44e06aeca65e = $2c23f148d58cd887$export$c35d437ae5945fcd.fromSpriteSheetCoordinates({\n spriteSheet: $7c4c300842bd4cf2$export$fcaf55e17c4b44d6,\n frameCoordinates: [\n {\n x: 1,\n y: 1,\n duration: 200\n },\n {\n x: 2,\n y: 1,\n duration: 200\n },\n {\n x: 3,\n y: 1,\n duration: 200\n },\n {\n x: 3,\n y: 1,\n duration: 200\n },\n {\n x: 3,\n y: 1,\n duration: 200\n },\n {\n x: 2,\n y: 1,\n duration: 200\n }\n ]\n});\nconst $7c4c300842bd4cf2$export$e9d873a43611e9a5 = $2c23f148d58cd887$export$bd73ddfe5f8475d8.fromImageSource({\n image: $7c4c300842bd4cf2$export$e9a269813a6315a4.HighlightSheet,\n grid: {\n rows: 1,\n columns: 5,\n spriteHeight: 32,\n spriteWidth: 32\n }\n});\nconst $7c4c300842bd4cf2$export$3c1fac611eb7316d = $2c23f148d58cd887$export$bd73ddfe5f8475d8.fromImageSource({\n image: $7c4c300842bd4cf2$export$e9a269813a6315a4.RedHighlightSheet,\n grid: {\n rows: 1,\n columns: 5,\n spriteHeight: 32,\n spriteWidth: 32\n }\n});\nconst $7c4c300842bd4cf2$export$9360e5c13ef59c04 = $2c23f148d58cd887$export$c35d437ae5945fcd.fromSpriteSheetCoordinates({\n spriteSheet: $7c4c300842bd4cf2$export$e9d873a43611e9a5,\n strategy: $2c23f148d58cd887$export$6cfd78ddb48c90c6.Loop,\n frameCoordinates: [\n {\n x: 0,\n y: 0,\n duration: 100\n },\n {\n x: 1,\n y: 0,\n duration: 100\n },\n {\n x: 2,\n y: 0,\n duration: 100\n },\n {\n x: 3,\n y: 0,\n duration: 100\n },\n {\n x: 4,\n y: 0,\n duration: 100\n }\n ]\n});\nconst $7c4c300842bd4cf2$export$a0fba9298a30ef3d = $2c23f148d58cd887$export$c35d437ae5945fcd.fromSpriteSheetCoordinates({\n spriteSheet: $7c4c300842bd4cf2$export$3c1fac611eb7316d,\n strategy: $2c23f148d58cd887$export$6cfd78ddb48c90c6.Loop,\n frameCoordinates: [\n {\n x: 0,\n y: 0,\n duration: 100\n },\n {\n x: 1,\n y: 0,\n duration: 100\n },\n {\n x: 2,\n y: 0,\n duration: 100\n },\n {\n x: 3,\n y: 0,\n duration: 100\n },\n {\n x: 4,\n y: 0,\n duration: 100\n }\n ]\n});\nconst $7c4c300842bd4cf2$export$41fc288806e4b9da = $2c23f148d58cd887$export$bd73ddfe5f8475d8.fromImageSource({\n image: $7c4c300842bd4cf2$export$e9a269813a6315a4.SpiderSheet,\n grid: {\n rows: 1,\n columns: 4,\n spriteHeight: 32,\n spriteWidth: 32\n }\n});\nconst $7c4c300842bd4cf2$export$7fb2d14e2517651c = $2c23f148d58cd887$export$c35d437ae5945fcd.fromSpriteSheetCoordinates({\n spriteSheet: $7c4c300842bd4cf2$export$41fc288806e4b9da,\n strategy: $2c23f148d58cd887$export$6cfd78ddb48c90c6.Loop,\n frameCoordinates: [\n {\n x: 0,\n y: 0,\n duration: 200\n },\n {\n x: 1,\n y: 0,\n duration: 200\n },\n {\n x: 2,\n y: 0,\n duration: 200\n },\n {\n x: 3,\n y: 0,\n duration: 200\n }\n ]\n});\nconst $7c4c300842bd4cf2$export$4ac5f7ab5408209 = $2c23f148d58cd887$export$bd73ddfe5f8475d8.fromImageSource({\n image: $7c4c300842bd4cf2$export$e9a269813a6315a4.KnightSpriteSheet,\n grid: {\n rows: 1,\n columns: 4,\n spriteHeight: 32,\n spriteWidth: 32\n }\n});\nconst $7c4c300842bd4cf2$export$b0b9df7fc088406f = $2c23f148d58cd887$export$c35d437ae5945fcd.fromSpriteSheetCoordinates({\n spriteSheet: $7c4c300842bd4cf2$export$4ac5f7ab5408209,\n strategy: $2c23f148d58cd887$export$6cfd78ddb48c90c6.Loop,\n frameCoordinates: [\n {\n x: 0,\n y: 0,\n duration: 200\n },\n {\n x: 1,\n y: 0,\n duration: 200\n },\n {\n x: 2,\n y: 0,\n duration: 200\n },\n {\n x: 3,\n y: 0,\n duration: 200\n }\n ]\n});\nconst $7c4c300842bd4cf2$export$88ccdae7a89ba6d3 = $2c23f148d58cd887$export$bd73ddfe5f8475d8.fromImageSource({\n image: $7c4c300842bd4cf2$export$e9a269813a6315a4.HeartSheet,\n grid: {\n rows: 1,\n columns: 6,\n spriteHeight: 32,\n spriteWidth: 32\n }\n});\nconst $7c4c300842bd4cf2$export$4e8cf2e69eec7183 = $2c23f148d58cd887$export$bd73ddfe5f8475d8.fromImageSource({\n image: $7c4c300842bd4cf2$export$e9a269813a6315a4.ExplosionSheet,\n grid: {\n rows: 2,\n columns: 5,\n spriteHeight: 32,\n spriteWidth: 32\n }\n});\nconst $7c4c300842bd4cf2$export$7999860126b75c7 = $2c23f148d58cd887$export$c35d437ae5945fcd.fromSpriteSheetCoordinates({\n spriteSheet: $7c4c300842bd4cf2$export$4e8cf2e69eec7183,\n frameCoordinates: [\n {\n x: 0,\n y: 0,\n duration: 100\n },\n {\n x: 1,\n y: 0,\n duration: 100\n },\n {\n x: 2,\n y: 0,\n duration: 100\n },\n {\n x: 3,\n y: 0,\n duration: 100\n },\n {\n x: 4,\n y: 0,\n duration: 100\n },\n {\n x: 0,\n y: 1,\n duration: 100\n },\n {\n x: 1,\n y: 1,\n duration: 100\n },\n {\n x: 2,\n y: 1,\n duration: 100\n }\n ]\n});\nconst $7c4c300842bd4cf2$export$13e9736c0be16271 = $7c4c300842bd4cf2$export$e9a269813a6315a4.SmokeSheet.toSprite();\nconst $7c4c300842bd4cf2$export$f99233281efd08a0 = $7c4c300842bd4cf2$export$e9a269813a6315a4.TitleImage.toSprite();\nconst $7c4c300842bd4cf2$export$f4c5de44377d2946 = new $2c23f148d58cd887$export$3b0d6d7590275603();\nfor (let res of Object.values($7c4c300842bd4cf2$export$e9a269813a6315a4))$7c4c300842bd4cf2$export$f4c5de44377d2946.addResource(res);\n\n\n\n\n\n\n\n\nconst $9d936a2aecb96285$var$seed = Date.now();\nconsole.log(\"Random seed:\", $9d936a2aecb96285$var$seed);\nconst $9d936a2aecb96285$export$5ada478c8a628231 = new $2c23f148d58cd887$export$a92776769f460054($9d936a2aecb96285$var$seed);\nconst $9d936a2aecb96285$export$fae5d17304677194 = $2c23f148d58cd887$export$202e0172ed3c7be0(3, 3);\nconst $9d936a2aecb96285$export$85771c8f3adc1fb9 = $2c23f148d58cd887$export$202e0172ed3c7be0(96, 128);\nconst $9d936a2aecb96285$export$2811b6d4a003bf2e = 200;\nconst $9d936a2aecb96285$export$e2d6e273e1f58e67 = {\n Knight: {\n graphics: {\n offset: $2c23f148d58cd887$export$202e0172ed3c7be0(0, 12 * $9d936a2aecb96285$export$fae5d17304677194.y),\n idle: (0, $7c4c300842bd4cf2$export$b0b9df7fc088406f)\n },\n health: 5,\n movement: 4,\n attack: 2,\n range: 1\n },\n Spider: {\n graphics: {\n offset: $2c23f148d58cd887$export$202e0172ed3c7be0(0, 8 * $9d936a2aecb96285$export$fae5d17304677194.y),\n idle: (0, $7c4c300842bd4cf2$export$7fb2d14e2517651c)\n },\n health: 3,\n movement: 3,\n attack: 1,\n range: 1\n }\n};\n\n\n\nclass $303d5ab53e6470cf$export$fc967995b0ef7619 extends $2c23f148d58cd887$export$16fa2f45be04daa8 {\n static #_ = this.type = \"path-node\";\n constructor(pos){\n super();\n this.type = \"path-node\";\n this.pos = $2c23f148d58cd887$export$202e0172ed3c7be0(0, 0);\n /**\n * Is this path node traversable by anything at all?\n */ this.isWalkable = true;\n /**\n * Is this path node traversable by certain things\n */ this.walkableMask = -1 // 32-bit mask\n ;\n this.gScore = Infinity;\n this.hScore = Infinity;\n this.weight = 1;\n this.direction = $2c23f148d58cd887$export$9b781de7bf37bf48.Zero;\n this.connections = [];\n this.previousNode = null;\n this.pos = pos;\n }\n}\n\n\nconst $2d5c5a1ac765e3b2$var$RangeHighlightAnimation = (0, $7c4c300842bd4cf2$export$9360e5c13ef59c04).clone();\nconst $2d5c5a1ac765e3b2$var$PathHighlightAnimation = (0, $7c4c300842bd4cf2$export$9360e5c13ef59c04).clone();\nconst $2d5c5a1ac765e3b2$var$AttackHighlightAnimation = (0, $7c4c300842bd4cf2$export$a0fba9298a30ef3d).clone();\nvar $2d5c5a1ac765e3b2$export$efddd1472b012ba0;\n(function(Terrain) {\n Terrain[\"Grass\"] = \"G\";\n Terrain[\"Water\"] = \"W\";\n Terrain[\"Sand\"] = \"S\";\n Terrain[\"Stone\"] = \"T\";\n})($2d5c5a1ac765e3b2$export$efddd1472b012ba0 || ($2d5c5a1ac765e3b2$export$efddd1472b012ba0 = {}));\nclass $2d5c5a1ac765e3b2$export$f6f0c3fe4ec306ea extends $2c23f148d58cd887$export$f73d3eb6fd876d80 {\n /**\n * Individual cells on the board\n * \n * @param x integer coordinate\n * @param y integer coordinate\n * @param board \n */ constructor(x, y, board){\n super({\n name: `cell(${x}, ${y})`,\n pos: $2c23f148d58cd887$export$202e0172ed3c7be0(x * (board.tileWidth + board.margin) * (0, $9d936a2aecb96285$export$fae5d17304677194).x, y * (board.tileHeight + board.margin) * (0, $9d936a2aecb96285$export$fae5d17304677194).y),\n anchor: $2c23f148d58cd887$export$9b781de7bf37bf48.Zero\n });\n this.x = x;\n this.y = y;\n this.board = board;\n this.unit = null;\n this._terrain = \"G\";\n this.pathNode = new (0, $303d5ab53e6470cf$export$fc967995b0ef7619)(this.pos);\n this.addComponent(this.pathNode);\n this.terrain = \"G\";\n $2d5c5a1ac765e3b2$var$RangeHighlightAnimation.scale = (0, $9d936a2aecb96285$export$fae5d17304677194);\n $2d5c5a1ac765e3b2$var$RangeHighlightAnimation.opacity = 0.75;\n $2d5c5a1ac765e3b2$var$PathHighlightAnimation.scale = (0, $9d936a2aecb96285$export$fae5d17304677194);\n $2d5c5a1ac765e3b2$var$PathHighlightAnimation.opacity = 0.75;\n $2d5c5a1ac765e3b2$var$PathHighlightAnimation.tint = $2c23f148d58cd887$export$892596cec99bc70e.Green;\n $2d5c5a1ac765e3b2$var$AttackHighlightAnimation.scale = (0, $9d936a2aecb96285$export$fae5d17304677194);\n $2d5c5a1ac765e3b2$var$AttackHighlightAnimation.opacity = 0.75;\n (0, $7c4c300842bd4cf2$export$d1be44e06aeca65e).scale = (0, $9d936a2aecb96285$export$fae5d17304677194);\n this.graphics.add(\"range\", $2d5c5a1ac765e3b2$var$RangeHighlightAnimation);\n this.graphics.add(\"path\", $2d5c5a1ac765e3b2$var$PathHighlightAnimation);\n this.graphics.add(\"attack\", $2d5c5a1ac765e3b2$var$AttackHighlightAnimation);\n this.graphics.add(\"cursor\", (0, $7c4c300842bd4cf2$export$d1be44e06aeca65e));\n }\n get terrain() {\n return this._terrain;\n }\n set terrain(terrain) {\n this._terrain = terrain;\n switch(this.terrain){\n case \"G\":\n this.sprite = (0, $7c4c300842bd4cf2$export$fcaf55e17c4b44d6).sprites[$2c23f148d58cd887$export$816343276f749e02(0, 1)];\n break;\n case \"S\":\n this.sprite = (0, $7c4c300842bd4cf2$export$fcaf55e17c4b44d6).sprites[$2c23f148d58cd887$export$816343276f749e02(2, 3)];\n break;\n case \"W\":\n this.sprite = (0, $7c4c300842bd4cf2$export$fcaf55e17c4b44d6).sprites[4];\n this.pathNode.isWalkable = false;\n break;\n case \"T\":\n this.sprite = (0, $7c4c300842bd4cf2$export$fcaf55e17c4b44d6).sprites[5];\n break;\n }\n this.sprite.scale = (0, $9d936a2aecb96285$export$fae5d17304677194);\n this.graphics.use(this.sprite.clone());\n }\n addUnit(unit) {\n this.unit = unit;\n this.unit.cell = this;\n this.pathNode.walkableMask = unit.player.mask;\n }\n removeUnit(unit) {\n this.pathNode.walkableMask = -1;\n this.unit = null;\n unit.cell = null;\n }\n toggleHighlight(show, type) {\n // reset highlight\n this.graphics.hide(\"range\");\n this.graphics.hide(\"path\");\n this.graphics.hide(\"attack\");\n if (show) this.graphics.show(type);\n else this.graphics.hide(type);\n }\n toggleCursor(show) {\n if (show) this.graphics.show(\"cursor\");\n else this.graphics.hide(\"cursor\");\n }\n getDistance(other) {\n return Math.abs(this.pos.x - other.pos.x) + Math.abs(this.pos.y - other.pos.y);\n }\n /**\n * Returns the orthogonal neighbors (up, down, left, right)\n * @returns \n */ getNeighbors() {\n return [\n this.board.getCell(this.x, this.y - 1),\n this.board.getCell(this.x, this.y + 1),\n this.board.getCell(this.x + 1, this.y),\n this.board.getCell(this.x - 1, this.y)\n ].filter(function(cell) {\n return cell !== null;\n });\n }\n}\n\n\n\n\n\nclass $0a6d04c785e34eb3$export$29b501f29c340548 {\n constructor(scene){\n this.heuristicWeight = 1;\n this.heuristic = (start, end)=>{\n // manhattan distance\n return Math.abs(start.pos.x - end.pos.x) + Math.abs(end.pos.y - end.pos.y);\n // euclidean distance\n // return start.pos.distance(end.pos);\n };\n this.query = scene.world.queryManager.createQuery([\n (0, $303d5ab53e6470cf$export$fc967995b0ef7619).type\n ]);\n }\n _buildPath(currentNode) {\n const path = [];\n while(currentNode.previousNode){\n path.unshift(currentNode);\n currentNode = currentNode.previousNode;\n }\n path.unshift(currentNode);\n return path;\n }\n _getRangeHelper(cell, accum, mask, range) {\n if (range >= 0) {\n accum.push(cell);\n cell.connections.filter((node)=>node.isWalkable && !!(node.walkableMask & mask)).forEach((cell)=>this._getRangeHelper(cell, accum, mask, range - 1));\n }\n }\n getRange(start, mask, range) {\n let result = [];\n this._getRangeHelper(start, result, mask, range);\n // dedup results\n result = result.filter((node, index, nodeArray)=>nodeArray.indexOf(node) === index);\n result = result.filter((node)=>node.isWalkable);\n return result;\n }\n /**\n * \n * @param start start node for the path\n * @param end end node for the path\n * @param mask bit mask to test against the node's walkability mask, same bit position means walkable (0b111 & 0b001) = walkable, (0b010 & 0b001) = not walkable\n * @param range \n * @returns \n */ findPath(start, end, mask, range) {\n const nodes = this.query.getEntities().map((n)=>n.get((0, $303d5ab53e6470cf$export$fc967995b0ef7619)));\n nodes.forEach((node)=>{\n node.gScore = 0;\n node.hScore = 0;\n node.previousNode = null;\n });\n start.gScore = 0;\n start.hScore = start.gScore + this.heuristic(start, end) * this.heuristicWeight;\n start.direction = $2c23f148d58cd887$export$9b781de7bf37bf48.Down;\n const openNodes = [\n start\n ];\n const closedNodes = [];\n while(openNodes.length > 0){\n // priority queue, evaluate nodes with the lowest cost\n const priorityNodes = openNodes.sort((a, b)=>{\n // tie breaking for aesthetics\n // if (a.hScore === b.hScore) {\n // // console.log(b.direction.normalize());\n // // console.log(a.direction.normalize());\n // console.log(b.direction.dot(ex.Vector.Down) - a.direction.dot(ex.Vector.Down));\n // return b.direction.dot(ex.Vector.Down) - a.direction.dot(ex.Vector.Down);\n // // return b.pos.y - a.pos.y;\n // }\n return a.hScore - b.hScore;\n });\n // tie breaking for aesthetics\n const current = priorityNodes[0];\n // Done!\n if (current === end) return this._buildPath(current);\n // Remove current from the open node set\n const index = openNodes.indexOf(current);\n openNodes.splice(index, 1);\n closedNodes.push(current);\n // Find the neighbors that haven't been explored\n let neighbors = current.connections.filter((node)=>{\n return node.isWalkable && !!(node.walkableMask & mask);\n }).filter((node)=>{\n return closedNodes.indexOf(node) === -1;\n });\n // If a range is supplied only look for nodes in there\n if (range) neighbors = neighbors.filter((node)=>range.indexOf(node) > -1);\n // Current direction!\n let currentDirection = current.direction;\n neighbors.forEach((node)=>{\n if (openNodes.indexOf(node) === -1) {\n node.previousNode = current;\n node.gScore = node.weight + current.gScore;\n node.hScore = node.gScore + this.heuristic(node, end) * this.heuristicWeight;\n // Turn penalty if direction is not straight\n const newDirection = node.pos.sub(current.pos).normalize();\n node.direction = newDirection;\n const inline = currentDirection.dot(newDirection);\n if (inline === 0.0) node.hScore += 130.0;\n openNodes.push(node);\n }\n });\n }\n // error case\n return [];\n }\n}\n\n\nclass $b2ebc7535321c5c8$export$dc537a3a3893548e {\n constructor(rows, cols, scene){\n this.tileWidth = 32;\n this.tileHeight = 32;\n this.margin = 2;\n this.cells = [];\n this.rows = rows;\n this.cols = cols;\n for(let i = 0; i < this.rows * this.cols; i++){\n const cell = new (0, $2d5c5a1ac765e3b2$export$f6f0c3fe4ec306ea)(i % this.cols, Math.floor(i / this.cols), this);\n this.cells.push(cell);\n scene.add(cell);\n }\n // setup neighbors connections\n for (let cell of this.cells)cell.pathNode.connections = cell.getNeighbors().map((c)=>c.pathNode);\n this.pathFinder = new (0, $0a6d04c785e34eb3$export$29b501f29c340548)(scene);\n }\n getCenter() {\n return $2c23f148d58cd887$export$202e0172ed3c7be0(this.cols * ((this.tileWidth + this.margin) * (0, $9d936a2aecb96285$export$fae5d17304677194).x), this.rows * ((this.tileHeight + this.margin) * (0, $9d936a2aecb96285$export$fae5d17304677194).y)).scale(.5);\n }\n getUnits() {\n let result = [];\n for (let cell of this.cells)if (cell.unit && cell.unit.active) result.push(cell.unit);\n return result;\n }\n getEmptyCells() {\n return this.cells.filter((cell)=>!cell.unit);\n }\n getCellByWorldPos(pos) {\n return this.getCell(Math.floor(pos.x /*- BOARD_OFFSET.x*/ / ((this.tileWidth + this.margin) * (0, $9d936a2aecb96285$export$fae5d17304677194).x)), Math.floor(pos.y /*- BOARD_OFFSET.y*/ / ((this.tileHeight + this.margin) * (0, $9d936a2aecb96285$export$fae5d17304677194).y)));\n }\n getCell(x, y) {\n if (x < 0 || x >= this.cols) return null;\n if (y < 0 || y >= this.rows) return null;\n return this.cells[x + y * this.cols];\n }\n}\n\n\n\n\n\n\n\nconst $715aef12944b79e3$export$4e2634e353696b95 = new $2c23f148d58cd887$export$616c632b282478dd({\n emitterType: $2c23f148d58cd887$export$d45269226a4bbdc1.Circle,\n radius: 16,\n minVel: 0,\n maxVel: 20,\n minAngle: 0,\n maxAngle: 6.2,\n isEmitting: false,\n emitRate: 8,\n opacity: 0.75,\n fadeFlag: true,\n particleLife: 1500,\n maxSize: 20,\n minSize: 1,\n startSize: 10,\n endSize: .01,\n acceleration: $2c23f148d58cd887$export$202e0172ed3c7be0(0, -32),\n particleSprite: (0, $7c4c300842bd4cf2$export$13e9736c0be16271),\n randomRotation: true,\n particleRotationalVelocity: Math.PI\n});\n\n\n\n\nclass $7bd1984434415a26$export$5dabcd2da5d381a3 extends $2c23f148d58cd887$export$f73d3eb6fd876d80 {\n constructor(pos, damage){\n super({\n name: \"damage\",\n pos: pos,\n z: 10\n });\n const font = new $2c23f148d58cd887$export$89abf52a030e56ee({\n family: \"notjamslab14\",\n size: 16 * (0, $9d936a2aecb96285$export$fae5d17304677194).x,\n unit: $2c23f148d58cd887$export$6976e674e6d5804c.Px,\n color: $2c23f148d58cd887$export$892596cec99bc70e.Yellow,\n baseAlign: $2c23f148d58cd887$export$83c931ba0d3bbaf5.Top,\n quality: 4,\n shadow: {\n offset: $2c23f148d58cd887$export$202e0172ed3c7be0(2, 2).scale((0, $9d936a2aecb96285$export$fae5d17304677194)),\n color: $2c23f148d58cd887$export$892596cec99bc70e.Black\n }\n });\n const text = new $2c23f148d58cd887$export$5f1af8db9871e1d6({\n text: damage.toFixed(0),\n font: font\n });\n this.graphics.add(text);\n }\n}\nclass $7bd1984434415a26$export$c76affe69a87ef28 {\n constructor(scene){\n this.scene = scene;\n }\n spawnDamageNumber(pos, damage) {\n const damageNumber = new $7bd1984434415a26$export$5dabcd2da5d381a3(pos, damage);\n damageNumber.actions.easeBy($2c23f148d58cd887$export$202e0172ed3c7be0(0, -100), 1000, $2c23f148d58cd887$export$6ff391a2049fdf40.EaseOutCubic).die();\n this.scene.add(damageNumber);\n }\n}\n\n\n\n\n\nclass $16f37671958ba436$export$42d239a7180b47de {\n constructor(scene){\n this.scene = scene;\n }\n playExplosion(pos) {\n const explosionActor = new $2c23f148d58cd887$export$f73d3eb6fd876d80({\n name: \"explosion\",\n pos: pos.add($2c23f148d58cd887$export$202e0172ed3c7be0(16, 16).scale((0, $9d936a2aecb96285$export$fae5d17304677194)))\n });\n (0, $7c4c300842bd4cf2$export$7999860126b75c7).reset();\n (0, $7c4c300842bd4cf2$export$7999860126b75c7).strategy = $2c23f148d58cd887$export$6cfd78ddb48c90c6.End;\n (0, $7c4c300842bd4cf2$export$7999860126b75c7).scale = (0, $9d936a2aecb96285$export$fae5d17304677194);\n const sub = (0, $7c4c300842bd4cf2$export$7999860126b75c7).events.on(\"frame\", (data)=>{\n if (data.frameIndex === 7) {\n explosionActor.kill();\n sub.close();\n }\n });\n explosionActor.graphics.use((0, $7c4c300842bd4cf2$export$7999860126b75c7));\n this.scene.add(explosionActor);\n }\n}\n\n\nclass $6baa46b5146e0ebc$export$1d8b9ae22d404866 extends $2c23f148d58cd887$export$f73d3eb6fd876d80 {\n constructor(x, y, unitType, board, player){\n super({\n name: unitType,\n anchor: $2c23f148d58cd887$export$202e0172ed3c7be0(0, 0),\n z: 2\n });\n this.player = player;\n this.cell = null;\n this.moved = false;\n this.attacked = false;\n this.unitConfig = {\n ...(0, $9d936a2aecb96285$export$e2d6e273e1f58e67)[unitType]\n };\n this.health = this.unitConfig.health;\n this.anim = this.unitConfig.graphics.idle.clone();\n this.anim.scale = (0, $9d936a2aecb96285$export$fae5d17304677194);\n this.graphics.use(this.anim);\n this.graphics.onPostDraw = this.onPostDraw.bind(this);\n const cell = board.getCell(x, y);\n if (cell) {\n this.pos = cell.pos.sub(this.unitConfig.graphics.offset);\n cell.addUnit(this);\n }\n }\n onInitialize(engine) {\n this.damageManager = new (0, $7bd1984434415a26$export$c76affe69a87ef28)(engine.currentScene);\n this.animationManger = new (0, $16f37671958ba436$export$42d239a7180b47de)(engine.currentScene);\n }\n onPostUpdate() {\n if (!this.hasActions()) this.anim.tint = $2c23f148d58cd887$export$892596cec99bc70e.Gray;\n else this.anim.tint = $2c23f148d58cd887$export$892596cec99bc70e.White;\n if (this.health <= 0) {\n this.cell?.removeUnit(this);\n this.actions.delay(500).callMethod(()=>{\n this.animationManger.playExplosion(this.pos);\n (0, $7c4c300842bd4cf2$export$e9a269813a6315a4).ExplosionSound.play();\n }).callMethod(()=>{\n this.kill();\n });\n }\n }\n onPostDraw(ctx) {\n if (this.health > 0) {\n const heart = (0, $7c4c300842bd4cf2$export$88ccdae7a89ba6d3).getSprite($2c23f148d58cd887$export$7d15b64cf5a3a4c4(this.health, 0, 5), 0);\n if (heart) {\n heart.scale = (0, $9d936a2aecb96285$export$fae5d17304677194);\n heart.draw(ctx, 10 * (0, $9d936a2aecb96285$export$fae5d17304677194).x + this.unitConfig.graphics.offset.x, 10 * (0, $9d936a2aecb96285$export$fae5d17304677194).y + this.unitConfig.graphics.offset.y);\n }\n }\n }\n async move(path) {\n if (this.cell) this.cell.removeUnit(this);\n let currentCell = null;\n let pathMinusFirst = path.slice(1, path.length);\n for (let node of pathMinusFirst){\n currentCell = node.owner;\n const sound = new $2c23f148d58cd887$export$89f31cec7c284d42(this, (ctx)=>{\n ctx.delay(200);\n ctx.callMethod(()=>{\n (0, $7c4c300842bd4cf2$export$e9a269813a6315a4).MoveSound.play();\n });\n });\n const move = new $2c23f148d58cd887$export$89f31cec7c284d42(this, (ctx)=>{\n ctx.easeTo(currentCell.pos.sub(this.unitConfig.graphics.offset), 300, $2c23f148d58cd887$export$6ff391a2049fdf40.EaseInOutCubic);\n ctx.callMethod(()=>{\n (0, $715aef12944b79e3$export$4e2634e353696b95).pos = this.pos.add((0, $9d936a2aecb96285$export$fae5d17304677194).scale(16));\n (0, $715aef12944b79e3$export$4e2634e353696b95).emitParticles(5);\n });\n });\n const parallel = new $2c23f148d58cd887$export$ed6a63ee685a4d78([\n sound,\n move\n ]);\n await this.actions.runAction(parallel).toPromise();\n }\n if (currentCell) currentCell.addUnit(this);\n this.moved = true;\n }\n reset() {\n this.moved = false;\n this.attacked = false;\n }\n canAttack() {\n return this.getPossibleTargets()?.length !== 0 && !this.attacked;\n }\n canMove() {\n return !this.moved;\n }\n hasActions() {\n return this.canMove() || this.canAttack();\n }\n availableActions() {\n let available = [];\n if (this.canMove()) available.push(\"move\");\n if (this.canAttack()) available.push(\"attack\");\n return available;\n }\n pass() {\n this.moved = true;\n this.attacked = true;\n }\n getPossibleTargets() {\n if (this.cell) {\n const range = this.cell.board.pathFinder.getRange(this.cell.pathNode, ~this.player.mask, this.unitConfig.range);\n const cellsWithEnemies = range.map((node)=>node.owner).filter((cell)=>{\n if (cell.unit?.player) return cell.unit.player !== this.player;\n return false;\n });\n return cellsWithEnemies;\n }\n }\n async attack(other) {\n other.health -= this.unitConfig.attack;\n (0, $7c4c300842bd4cf2$export$e9a269813a6315a4).HitSound.play();\n this.damageManager.spawnDamageNumber(other.pos.add(other.unitConfig.graphics.offset).add($2c23f148d58cd887$export$202e0172ed3c7be0(16 * (0, $9d936a2aecb96285$export$fae5d17304677194).x, 0)), this.unitConfig.attack);\n await other.actions.blink(200, 200, 5).toPromise();\n this.attacked = true;\n }\n}\n\n\n\nclass $51d548b0596e1d08$export$2616165974278734 {\n static #_ = this._STARTING_BIT = 1;\n static #_1 = this._CURRENT_GROUP = $51d548b0596e1d08$export$2616165974278734._STARTING_BIT;\n constructor(name, board){\n this.name = name;\n this.board = board;\n this.active = false;\n this.mask = $51d548b0596e1d08$export$2616165974278734._CURRENT_GROUP = $51d548b0596e1d08$export$2616165974278734._CURRENT_GROUP << 1 | 0;\n }\n async turnStart() {\n this.active = true;\n const units = this.board.getUnits().filter((u)=>u.player === this);\n units.forEach((u)=>u.reset());\n }\n hasLost() {\n const units = this.board.getUnits().filter((u)=>u.player === this);\n return units.length === 0;\n }\n async turnEnd() {\n this.active = false;\n }\n}\n\n\n\nclass $8f27ec21febf6fa6$export$b4ba4c460e535077 extends (0, $51d548b0596e1d08$export$2616165974278734) {\n constructor(name, engine, selectionManager, uiManger, board){\n super(name, board);\n this.engine = engine;\n this.selectionManager = selectionManager;\n this.uiManger = uiManger;\n this.passed = false;\n this.humanMove = new $2c23f148d58cd887$export$c9d7bf589772a8ce();\n engine.input.pointers.on(\"down\", this.pointerClick.bind(this));\n engine.input.pointers.on(\"move\", this.pointerMove.bind(this));\n engine.input.keyboard.on(\"press\", this.keyboardDown.bind(this));\n document.body.oncontextmenu = ()=>false;\n }\n keyboardDown(event) {\n if (!this.active) return;\n this.selectionManager.resetHighlight();\n const currentCursor = this.selectionManager.currentCursor;\n switch(event.key){\n case $2c23f148d58cd887$export$4b0075e5ea5e1f26.ArrowRight:\n case $2c23f148d58cd887$export$4b0075e5ea5e1f26.D:\n this.selectionManager.showCursor(currentCursor.x + 1, currentCursor.y);\n break;\n case $2c23f148d58cd887$export$4b0075e5ea5e1f26.Left:\n case $2c23f148d58cd887$export$4b0075e5ea5e1f26.A:\n this.selectionManager.showCursor(currentCursor.x - 1, currentCursor.y);\n break;\n case $2c23f148d58cd887$export$4b0075e5ea5e1f26.Up:\n case $2c23f148d58cd887$export$4b0075e5ea5e1f26.W:\n this.selectionManager.showCursor(currentCursor.x, currentCursor.y - 1);\n break;\n case $2c23f148d58cd887$export$4b0075e5ea5e1f26.Down:\n case $2c23f148d58cd887$export$4b0075e5ea5e1f26.D:\n this.selectionManager.showCursor(currentCursor.x, currentCursor.y + 1);\n break;\n case $2c23f148d58cd887$export$4b0075e5ea5e1f26.Enter:\n case $2c23f148d58cd887$export$4b0075e5ea5e1f26.NumpadEnter:\n const cell = this.board.getCell(currentCursor.x, currentCursor.y);\n this.maybeSelectUnit(cell);\n }\n }\n async pointerClick(pointer) {\n if (!this.active) return;\n this.selectionManager.resetHighlight();\n const maybeClickedCell = this.board.getCellByWorldPos(pointer.worldPos);\n if (pointer.button === $2c23f148d58cd887$export$982e5de016bedff1.Left) {\n // a unit is currently selected\n if (this.selectionManager.currentUnitSelection) {\n const unit = this.selectionManager.currentUnitSelection;\n if (this.selectionManager.currentSelectionMode === \"move\") {\n await this.maybeMove(unit, maybeClickedCell);\n await this.maybeSelectUnit(unit.cell);\n } else {\n await this.maybeAttack(unit, maybeClickedCell);\n await this.maybeSelectUnit(unit.cell);\n }\n // no unit selected, make a selection\n } else this.maybeSelectUnit(maybeClickedCell);\n }\n if (pointer.button === $2c23f148d58cd887$export$982e5de016bedff1.Right) this.highlightUnitRange(maybeClickedCell);\n }\n pointerMove(pointer) {\n if (!this.active) return;\n const cellBelowPointer = this.board.getCellByWorldPos(pointer.worldPos);\n if (cellBelowPointer) this.selectionManager.showCursor(cellBelowPointer.x, cellBelowPointer.y);\n if (!this.selectionManager.currentUnitSelection) return;\n this.selectionManager.resetHighlight();\n // move\n if (this.selectionManager.currentSelectionMode === \"move\") {\n const currentRange = this.selectionManager.findMovementRange(this.selectionManager.currentUnitSelection);\n this.selectionManager.showHighlight(currentRange, \"range\");\n const destination = this.board.getCellByWorldPos(pointer.worldPos);\n if (destination) {\n const currentPath = this.selectionManager.findPath(destination, currentRange);\n this.selectionManager.showHighlight(currentPath, \"path\");\n }\n // attack\n } else {\n const currentRange = this.selectionManager.findAttackRange(this.selectionManager.currentUnitSelection);\n this.selectionManager.showHighlight(currentRange, \"attack\");\n const destination = this.board.getCellByWorldPos(pointer.worldPos);\n if (destination && this.hasNonPlayerUnit(destination)) this.selectionManager.showHighlight([\n destination.pathNode\n ], \"path\");\n }\n }\n async maybeMove(unit, destination) {\n if (destination && unit.canMove()) {\n this.active = false;\n (0, $7c4c300842bd4cf2$export$e9a269813a6315a4).TargetSelectSound.play();\n await this.selectionManager.selectDestinationAndMove(unit, destination);\n this.humanMove.resolve();\n } else this.selectionManager.reset();\n }\n async maybeAttack(attacker, destination) {\n if (destination && attacker.canAttack() && this.hasNonPlayerUnit(destination)) {\n this.active = false;\n const enemyUnit = destination.unit;\n this.selectionManager.reset();\n await attacker.attack(enemyUnit);\n this.humanMove.resolve();\n } else this.selectionManager.reset();\n }\n /**\n * Highlight the range of any unit friendly or not\n * @param cell \n */ async highlightUnitRange(cell) {\n if (cell?.unit) {\n const unit = cell.unit;\n const rangePlusAttack = this.board.pathFinder.getRange(cell.pathNode, unit.player.mask, unit.unitConfig.movement + 1);\n this.selectionManager.showHighlight(rangePlusAttack, \"attack\");\n const attack = this.board.pathFinder.getRange(cell.pathNode, ~unit.player.mask, unit.unitConfig.range);\n this.selectionManager.showHighlight(attack, \"attack\");\n const currentRange = this.selectionManager.findMovementRange(unit);\n this.selectionManager.showHighlight(currentRange, \"range\");\n } else this.selectionManager.reset();\n }\n async maybeSelectUnit(cell) {\n // check if the cell clicked has a unit, then select it\n if (cell?.unit && this.hasPlayerUnitWithActions(cell)) {\n (0, $7c4c300842bd4cf2$export$e9a269813a6315a4).SelectSound.play();\n this.uiManger.showUnitMenu(cell.unit, {\n move: ()=>{\n this.selectionManager.selectUnit(cell.unit, \"move\");\n },\n attack: ()=>{\n this.selectionManager.selectUnit(cell.unit, \"attack\");\n },\n pass: ()=>{\n cell.unit?.pass();\n this.selectionManager.reset();\n this.humanMove.resolve();\n }\n });\n // otherwise clear selection\n } else this.selectionManager.reset();\n }\n hasNonPlayerUnit(maybeClickedCell) {\n return maybeClickedCell && maybeClickedCell.unit && maybeClickedCell.unit.player !== this;\n }\n hasPlayerUnitWithActions(maybeClickedCell) {\n return maybeClickedCell?.unit && maybeClickedCell?.unit?.hasActions() && maybeClickedCell.unit.player === this;\n }\n async waitForHumanMove() {\n this.active = true;\n await this.humanMove.promise;\n this.humanMove = new $2c23f148d58cd887$export$c9d7bf589772a8ce();\n }\n hasMoves() {\n const units = this.board.getUnits().filter((u)=>u.player === this).filter((u)=>u.hasActions());\n return units.length > 0 && !this.passed;\n }\n async makeMove() {\n while(this.hasMoves())await this.waitForHumanMove();\n return true;\n }\n lose() {\n this.active = false;\n const playerUnits = this.board.getUnits().filter((u)=>u.player instanceof $8f27ec21febf6fa6$export$b4ba4c460e535077);\n playerUnits.forEach((u)=>{\n u.health = 0;\n u.cell?.removeUnit(u);\n });\n this.humanMove.resolve();\n }\n}\n\n\nclass $56541b8f9a5aaec4$export$6c8a5aaad13c9852 {\n constructor(board){\n this.board = board;\n this.currentPlayer = null;\n this.currentSelectionMode = \"move\";\n this.currentUnitSelection = null;\n this.currentRange = [];\n this.currentPath = [];\n this.currentCursor = {\n x: 0,\n y: 0\n };\n }\n reset() {\n this.resetHighlight();\n this.currentUnitSelection = null;\n this.currentPath = [];\n this.currentRange = [];\n }\n showCursor(x, y) {\n const cell = this.board.getCell(x, y);\n if (cell) {\n this.board.cells.forEach((c)=>c.toggleCursor(false));\n cell.toggleCursor(true);\n this.currentCursor = {\n x: x,\n y: y\n };\n }\n }\n selectPlayer(player) {\n this.currentPlayer = player;\n }\n selectUnit(unit, type) {\n if (unit.player !== this.currentPlayer) return;\n this.currentUnitSelection = unit;\n this.currentSelectionMode = type;\n if (type === \"move\") {\n this.currentRange = this.findMovementRange(this.currentUnitSelection);\n this.showHighlight(this.currentRange, \"range\");\n } else {\n this.currentRange = this.findAttackRange(this.currentUnitSelection);\n this.showHighlight(this.currentRange, \"attack\");\n }\n }\n async selectDestinationAndMove(unit, destination) {\n if (unit.player !== this.currentPlayer) return;\n const range = this.findMovementRange(unit);\n // select a destination if there is no path\n if (this.currentPath.length === 0) this.currentPath = this.findPath(destination, range);\n // if a valid path was found move!\n if (this.currentPath.length > 1) await unit.move(this.currentPath);\n this.reset();\n }\n findAttackRange(unit) {\n if (!this.currentUnitSelection) return [];\n if (!unit.cell) return [];\n let range = this.board.pathFinder.getRange(unit.cell.pathNode, ~unit.player.mask, this.currentUnitSelection.unitConfig.range);\n return range;\n }\n findMovementRange(unit) {\n // if (!this.currentUnitSelection) return [];\n if (!unit.cell) return [];\n let range = this.board.pathFinder.getRange(unit.cell.pathNode, unit.player.mask, unit.unitConfig.movement);\n range = range.filter((node)=>node.isWalkable && !!(node.walkableMask & unit.player.mask));\n return range;\n }\n resetHighlight() {\n this.board.cells.forEach((cell)=>{\n cell.toggleHighlight(false, \"range\");\n cell.toggleHighlight(false, \"path\");\n cell.toggleHighlight(false, \"attack\");\n });\n }\n showHighlight(path, type) {\n path.forEach((node)=>{\n const cell = node.owner;\n cell.toggleHighlight(true, type);\n });\n }\n findPath(destination, currentRange) {\n if (!this.currentUnitSelection) return [];\n const start = this.currentUnitSelection.cell?.pathNode;\n if (destination && !destination.unit && currentRange.includes(destination.pathNode)) {\n const path = this.board.pathFinder.findPath(start, destination?.pathNode, this.currentUnitSelection.player.mask, currentRange);\n return path;\n }\n return [];\n }\n}\n\n\n\n/******************************************************************************\r\nCopyright (c) Microsoft Corporation.\r\n\r\nPermission to use, copy, modify, and/or distribute this software for any\r\npurpose with or without fee is hereby granted.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH\r\nREGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY\r\nAND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,\r\nINDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM\r\nLOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR\r\nOTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR\r\nPERFORMANCE OF THIS SOFTWARE.\r\n***************************************************************************** */ /* global Reflect, Promise, SuppressedError, Symbol */ var $5c96a02c592fcff1$var$extendStatics = function(d, b) {\n $5c96a02c592fcff1$var$extendStatics = Object.setPrototypeOf || ({\n __proto__: []\n }) instanceof Array && function(d, b) {\n d.__proto__ = b;\n } || function(d, b) {\n for(var p in b)if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n };\n return $5c96a02c592fcff1$var$extendStatics(d, b);\n};\nfunction $5c96a02c592fcff1$export$a8ba968b8961cb8a(d, b) {\n if (typeof b !== \"function\" && b !== null) throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\n $5c96a02c592fcff1$var$extendStatics(d, b);\n function __() {\n this.constructor = d;\n }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n}\nvar $5c96a02c592fcff1$export$18ce0697a983be9b = function() {\n $5c96a02c592fcff1$export$18ce0697a983be9b = Object.assign || function __assign(t) {\n for(var s, i = 1, n = arguments.length; i < n; i++){\n s = arguments[i];\n for(var p in s)if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];\n }\n return t;\n };\n return $5c96a02c592fcff1$export$18ce0697a983be9b.apply(this, arguments);\n};\nfunction $5c96a02c592fcff1$export$3c9a16f847548506(s, e) {\n var t = {};\n for(var p in s)if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p];\n if (s != null && typeof Object.getOwnPropertySymbols === \"function\") {\n for(var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++)if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]];\n }\n return t;\n}\nfunction $5c96a02c592fcff1$export$29e00dfd3077644b(decorators, target, key, desc) {\n var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;\n if (typeof Reflect === \"object\" && typeof Reflect.decorate === \"function\") r = Reflect.decorate(decorators, target, key, desc);\n else for(var i = decorators.length - 1; i >= 0; i--)if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;\n return c > 3 && r && Object.defineProperty(target, key, r), r;\n}\nfunction $5c96a02c592fcff1$export$d5ad3fd78186038f(paramIndex, decorator) {\n return function(target, key) {\n decorator(target, key, paramIndex);\n };\n}\nfunction $5c96a02c592fcff1$export$3a84e1ae4e97e9b0(ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {\n function accept(f) {\n if (f !== void 0 && typeof f !== \"function\") throw new TypeError(\"Function expected\");\n return f;\n }\n var kind = contextIn.kind, key = kind === \"getter\" ? \"get\" : kind === \"setter\" ? \"set\" : \"value\";\n var target = !descriptorIn && ctor ? contextIn[\"static\"] ? ctor : ctor.prototype : null;\n var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});\n var _, done = false;\n for(var i = decorators.length - 1; i >= 0; i--){\n var context = {};\n for(var p in contextIn)context[p] = p === \"access\" ? {} : contextIn[p];\n for(var p in contextIn.access)context.access[p] = contextIn.access[p];\n context.addInitializer = function(f) {\n if (done) throw new TypeError(\"Cannot add initializers after decoration has completed\");\n extraInitializers.push(accept(f || null));\n };\n var result = (0, decorators[i])(kind === \"accessor\" ? {\n get: descriptor.get,\n set: descriptor.set\n } : descriptor[key], context);\n if (kind === \"accessor\") {\n if (result === void 0) continue;\n if (result === null || typeof result !== \"object\") throw new TypeError(\"Object expected\");\n if (_ = accept(result.get)) descriptor.get = _;\n if (_ = accept(result.set)) descriptor.set = _;\n if (_ = accept(result.init)) initializers.unshift(_);\n } else if (_ = accept(result)) {\n if (kind === \"field\") initializers.unshift(_);\n else descriptor[key] = _;\n }\n }\n if (target) Object.defineProperty(target, contextIn.name, descriptor);\n done = true;\n}\nfunction $5c96a02c592fcff1$export$d831c04e792af3d(thisArg, initializers, value) {\n var useValue = arguments.length > 2;\n for(var i = 0; i < initializers.length; i++)value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);\n return useValue ? value : void 0;\n}\nfunction $5c96a02c592fcff1$export$6a2a36740a146cb8(x) {\n return typeof x === \"symbol\" ? x : \"\".concat(x);\n}\nfunction $5c96a02c592fcff1$export$d1a06452d3489bc7(f, name, prefix) {\n if (typeof name === \"symbol\") name = name.description ? \"[\".concat(name.description, \"]\") : \"\";\n return Object.defineProperty(f, \"name\", {\n configurable: true,\n value: prefix ? \"\".concat(prefix, \" \", name) : name\n });\n}\nfunction $5c96a02c592fcff1$export$f1db080c865becb9(metadataKey, metadataValue) {\n if (typeof Reflect === \"object\" && typeof Reflect.metadata === \"function\") return Reflect.metadata(metadataKey, metadataValue);\n}\nfunction $5c96a02c592fcff1$export$1050f835b63b671e(thisArg, _arguments, P, generator) {\n function adopt(value) {\n return value instanceof P ? value : new P(function(resolve) {\n resolve(value);\n });\n }\n return new (P || (P = Promise))(function(resolve, reject) {\n function fulfilled(value) {\n try {\n step(generator.next(value));\n } catch (e) {\n reject(e);\n }\n }\n function rejected(value) {\n try {\n step(generator[\"throw\"](value));\n } catch (e) {\n reject(e);\n }\n }\n function step(result) {\n result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected);\n }\n step((generator = generator.apply(thisArg, _arguments || [])).next());\n });\n}\nfunction $5c96a02c592fcff1$export$67ebef60e6f28a6(thisArg, body) {\n var _ = {\n label: 0,\n sent: function() {\n if (t[0] & 1) throw t[1];\n return t[1];\n },\n trys: [],\n ops: []\n }, f, y, t, g;\n return g = {\n next: verb(0),\n \"throw\": verb(1),\n \"return\": verb(2)\n }, typeof Symbol === \"function\" && (g[Symbol.iterator] = function() {\n return this;\n }), g;\n function verb(n) {\n return function(v) {\n return step([\n n,\n v\n ]);\n };\n }\n function step(op) {\n if (f) throw new TypeError(\"Generator is already executing.\");\n while(g && (g = 0, op[0] && (_ = 0)), _)try {\n if (f = 1, y && (t = op[0] & 2 ? y[\"return\"] : op[0] ? y[\"throw\"] || ((t = y[\"return\"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;\n if (y = 0, t) op = [\n op[0] & 2,\n t.value\n ];\n switch(op[0]){\n case 0:\n case 1:\n t = op;\n break;\n case 4:\n _.label++;\n return {\n value: op[1],\n done: false\n };\n case 5:\n _.label++;\n y = op[1];\n op = [\n 0\n ];\n continue;\n case 7:\n op = _.ops.pop();\n _.trys.pop();\n continue;\n default:\n if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) {\n _ = 0;\n continue;\n }\n if (op[0] === 3 && (!t || op[1] > t[0] && op[1] < t[3])) {\n _.label = op[1];\n break;\n }\n if (op[0] === 6 && _.label < t[1]) {\n _.label = t[1];\n t = op;\n break;\n }\n if (t && _.label < t[2]) {\n _.label = t[2];\n _.ops.push(op);\n break;\n }\n if (t[2]) _.ops.pop();\n _.trys.pop();\n continue;\n }\n op = body.call(thisArg, _);\n } catch (e) {\n op = [\n 6,\n e\n ];\n y = 0;\n } finally{\n f = t = 0;\n }\n if (op[0] & 5) throw op[1];\n return {\n value: op[0] ? op[1] : void 0,\n done: true\n };\n }\n}\nvar $5c96a02c592fcff1$export$45d3717a4c69092e = Object.create ? function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n var desc = Object.getOwnPropertyDescriptor(m, k);\n if (!desc || (\"get\" in desc ? !m.__esModule : desc.writable || desc.configurable)) desc = {\n enumerable: true,\n get: function() {\n return m[k];\n }\n };\n Object.defineProperty(o, k2, desc);\n} : function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n o[k2] = m[k];\n};\nfunction $5c96a02c592fcff1$export$f33643c0debef087(m, o) {\n for(var p in m)if (p !== \"default\" && !Object.prototype.hasOwnProperty.call(o, p)) $5c96a02c592fcff1$export$45d3717a4c69092e(o, m, p);\n}\nfunction $5c96a02c592fcff1$export$19a8beecd37a4c45(o) {\n var s = typeof Symbol === \"function\" && Symbol.iterator, m = s && o[s], i = 0;\n if (m) return m.call(o);\n if (o && typeof o.length === \"number\") return {\n next: function() {\n if (o && i >= o.length) o = void 0;\n return {\n value: o && o[i++],\n done: !o\n };\n }\n };\n throw new TypeError(s ? \"Object is not iterable.\" : \"Symbol.iterator is not defined.\");\n}\nfunction $5c96a02c592fcff1$export$8d051b38c9118094(o, n) {\n var m = typeof Symbol === \"function\" && o[Symbol.iterator];\n if (!m) return o;\n var i = m.call(o), r, ar = [], e;\n try {\n while((n === void 0 || n-- > 0) && !(r = i.next()).done)ar.push(r.value);\n } catch (error) {\n e = {\n error: error\n };\n } finally{\n try {\n if (r && !r.done && (m = i[\"return\"])) m.call(i);\n } finally{\n if (e) throw e.error;\n }\n }\n return ar;\n}\nfunction $5c96a02c592fcff1$export$afc72e2116322959() {\n for(var ar = [], i = 0; i < arguments.length; i++)ar = ar.concat($5c96a02c592fcff1$export$8d051b38c9118094(arguments[i]));\n return ar;\n}\nfunction $5c96a02c592fcff1$export$6388937ca91ccae8() {\n for(var s = 0, i = 0, il = arguments.length; i < il; i++)s += arguments[i].length;\n for(var r = Array(s), k = 0, i = 0; i < il; i++)for(var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)r[k] = a[j];\n return r;\n}\nfunction $5c96a02c592fcff1$export$1216008129fb82ed(to, from, pack) {\n if (pack || arguments.length === 2) {\n for(var i = 0, l = from.length, ar; i < l; i++)if (ar || !(i in from)) {\n if (!ar) ar = Array.prototype.slice.call(from, 0, i);\n ar[i] = from[i];\n }\n }\n return to.concat(ar || Array.prototype.slice.call(from));\n}\nfunction $5c96a02c592fcff1$export$10c90e4f7922046c(v) {\n return this instanceof $5c96a02c592fcff1$export$10c90e4f7922046c ? (this.v = v, this) : new $5c96a02c592fcff1$export$10c90e4f7922046c(v);\n}\nfunction $5c96a02c592fcff1$export$e427f37a30a4de9b(thisArg, _arguments, generator) {\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\n var g = generator.apply(thisArg, _arguments || []), i, q = [];\n return i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function() {\n return this;\n }, i;\n function verb(n) {\n if (g[n]) i[n] = function(v) {\n return new Promise(function(a, b) {\n q.push([\n n,\n v,\n a,\n b\n ]) > 1 || resume(n, v);\n });\n };\n }\n function resume(n, v) {\n try {\n step(g[n](v));\n } catch (e) {\n settle(q[0][3], e);\n }\n }\n function step(r) {\n r.value instanceof $5c96a02c592fcff1$export$10c90e4f7922046c ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r);\n }\n function fulfill(value) {\n resume(\"next\", value);\n }\n function reject(value) {\n resume(\"throw\", value);\n }\n function settle(f, v) {\n if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]);\n }\n}\nfunction $5c96a02c592fcff1$export$bbd80228419bb833(o) {\n var i, p;\n return i = {}, verb(\"next\"), verb(\"throw\", function(e) {\n throw e;\n }), verb(\"return\"), i[Symbol.iterator] = function() {\n return this;\n }, i;\n function verb(n, f) {\n i[n] = o[n] ? function(v) {\n return (p = !p) ? {\n value: $5c96a02c592fcff1$export$10c90e4f7922046c(o[n](v)),\n done: false\n } : f ? f(v) : v;\n } : f;\n }\n}\nfunction $5c96a02c592fcff1$export$e3b29a3d6162315f(o) {\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\n var m = o[Symbol.asyncIterator], i;\n return m ? m.call(o) : (o = typeof $5c96a02c592fcff1$export$19a8beecd37a4c45 === \"function\" ? $5c96a02c592fcff1$export$19a8beecd37a4c45(o) : o[Symbol.iterator](), i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function() {\n return this;\n }, i);\n function verb(n) {\n i[n] = o[n] && function(v) {\n return new Promise(function(resolve, reject) {\n v = o[n](v), settle(resolve, reject, v.done, v.value);\n });\n };\n }\n function settle(resolve, reject, d, v) {\n Promise.resolve(v).then(function(v) {\n resolve({\n value: v,\n done: d\n });\n }, reject);\n }\n}\nfunction $5c96a02c592fcff1$export$4fb47efe1390b86f(cooked, raw) {\n if (Object.defineProperty) Object.defineProperty(cooked, \"raw\", {\n value: raw\n });\n else cooked.raw = raw;\n return cooked;\n}\nvar $5c96a02c592fcff1$var$__setModuleDefault = Object.create ? function(o, v) {\n Object.defineProperty(o, \"default\", {\n enumerable: true,\n value: v\n });\n} : function(o, v) {\n o[\"default\"] = v;\n};\nfunction $5c96a02c592fcff1$export$c21735bcef00d192(mod) {\n if (mod && mod.__esModule) return mod;\n var result = {};\n if (mod != null) {\n for(var k in mod)if (k !== \"default\" && Object.prototype.hasOwnProperty.call(mod, k)) $5c96a02c592fcff1$export$45d3717a4c69092e(result, mod, k);\n }\n $5c96a02c592fcff1$var$__setModuleDefault(result, mod);\n return result;\n}\nfunction $5c96a02c592fcff1$export$da59b14a69baef04(mod) {\n return mod && mod.__esModule ? mod : {\n default: mod\n };\n}\nfunction $5c96a02c592fcff1$export$d5dcaf168c640c35(receiver, state, kind, f) {\n if (kind === \"a\" && !f) throw new TypeError(\"Private accessor was defined without a getter\");\n if (typeof state === \"function\" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError(\"Cannot read private member from an object whose class did not declare it\");\n return kind === \"m\" ? f : kind === \"a\" ? f.call(receiver) : f ? f.value : state.get(receiver);\n}\nfunction $5c96a02c592fcff1$export$d40a35129aaff81f(receiver, state, value, kind, f) {\n if (kind === \"m\") throw new TypeError(\"Private method is not writable\");\n if (kind === \"a\" && !f) throw new TypeError(\"Private accessor was defined without a setter\");\n if (typeof state === \"function\" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError(\"Cannot write private member to an object whose class did not declare it\");\n return kind === \"a\" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value), value;\n}\nfunction $5c96a02c592fcff1$export$81fdc39f203e4e04(state, receiver) {\n if (receiver === null || typeof receiver !== \"object\" && typeof receiver !== \"function\") throw new TypeError(\"Cannot use 'in' operator on non-object\");\n return typeof state === \"function\" ? receiver === state : state.has(receiver);\n}\nfunction $5c96a02c592fcff1$export$88ac25d8e944e405(env, value, async) {\n if (value !== null && value !== void 0) {\n if (typeof value !== \"object\" && typeof value !== \"function\") throw new TypeError(\"Object expected.\");\n var dispose;\n if (async) {\n if (!Symbol.asyncDispose) throw new TypeError(\"Symbol.asyncDispose is not defined.\");\n dispose = value[Symbol.asyncDispose];\n }\n if (dispose === void 0) {\n if (!Symbol.dispose) throw new TypeError(\"Symbol.dispose is not defined.\");\n dispose = value[Symbol.dispose];\n }\n if (typeof dispose !== \"function\") throw new TypeError(\"Object not disposable.\");\n env.stack.push({\n value: value,\n dispose: dispose,\n async: async\n });\n } else if (async) env.stack.push({\n async: true\n });\n return value;\n}\nvar $5c96a02c592fcff1$var$_SuppressedError = typeof SuppressedError === \"function\" ? SuppressedError : function(error, suppressed, message) {\n var e = new Error(message);\n return e.name = \"SuppressedError\", e.error = error, e.suppressed = suppressed, e;\n};\nfunction $5c96a02c592fcff1$export$8f076105dc360e92(env) {\n function fail(e) {\n env.error = env.hasError ? new $5c96a02c592fcff1$var$_SuppressedError(e, env.error, \"An error was suppressed during disposal.\") : e;\n env.hasError = true;\n }\n function next() {\n while(env.stack.length){\n var rec = env.stack.pop();\n try {\n var result = rec.dispose && rec.dispose.call(rec.value);\n if (rec.async) return Promise.resolve(result).then(next, function(e) {\n fail(e);\n return next();\n });\n } catch (e) {\n fail(e);\n }\n }\n if (env.hasError) throw env.error;\n }\n return next();\n}\nvar $5c96a02c592fcff1$export$2e2bcd8739ae039 = {\n __extends: $5c96a02c592fcff1$export$a8ba968b8961cb8a,\n __assign: $5c96a02c592fcff1$export$18ce0697a983be9b,\n __rest: $5c96a02c592fcff1$export$3c9a16f847548506,\n __decorate: $5c96a02c592fcff1$export$29e00dfd3077644b,\n __param: $5c96a02c592fcff1$export$d5ad3fd78186038f,\n __metadata: $5c96a02c592fcff1$export$f1db080c865becb9,\n __awaiter: $5c96a02c592fcff1$export$1050f835b63b671e,\n __generator: $5c96a02c592fcff1$export$67ebef60e6f28a6,\n __createBinding: $5c96a02c592fcff1$export$45d3717a4c69092e,\n __exportStar: $5c96a02c592fcff1$export$f33643c0debef087,\n __values: $5c96a02c592fcff1$export$19a8beecd37a4c45,\n __read: $5c96a02c592fcff1$export$8d051b38c9118094,\n __spread: $5c96a02c592fcff1$export$afc72e2116322959,\n __spreadArrays: $5c96a02c592fcff1$export$6388937ca91ccae8,\n __spreadArray: $5c96a02c592fcff1$export$1216008129fb82ed,\n __await: $5c96a02c592fcff1$export$10c90e4f7922046c,\n __asyncGenerator: $5c96a02c592fcff1$export$e427f37a30a4de9b,\n __asyncDelegator: $5c96a02c592fcff1$export$bbd80228419bb833,\n __asyncValues: $5c96a02c592fcff1$export$e3b29a3d6162315f,\n __makeTemplateObject: $5c96a02c592fcff1$export$4fb47efe1390b86f,\n __importStar: $5c96a02c592fcff1$export$c21735bcef00d192,\n __importDefault: $5c96a02c592fcff1$export$da59b14a69baef04,\n __classPrivateFieldGet: $5c96a02c592fcff1$export$d5dcaf168c640c35,\n __classPrivateFieldSet: $5c96a02c592fcff1$export$d40a35129aaff81f,\n __classPrivateFieldIn: $5c96a02c592fcff1$export$81fdc39f203e4e04,\n __addDisposableResource: $5c96a02c592fcff1$export$88ac25d8e944e405,\n __disposeResources: $5c96a02c592fcff1$export$8f076105dc360e92\n};\n\n\n/**\n * @license\n * Copyright 2019 Google LLC\n * SPDX-License-Identifier: BSD-3-Clause\n */ const $3233927aa82734f9$var$t = globalThis, $3233927aa82734f9$export$b4d10f6001c083c2 = $3233927aa82734f9$var$t.ShadowRoot && (void 0 === $3233927aa82734f9$var$t.ShadyCSS || $3233927aa82734f9$var$t.ShadyCSS.nativeShadow) && \"adoptedStyleSheets\" in Document.prototype && \"replace\" in CSSStyleSheet.prototype, $3233927aa82734f9$var$s = Symbol(), $3233927aa82734f9$var$o = new WeakMap;\nclass $3233927aa82734f9$export$505d1e8739bad805 {\n constructor(t, e, o){\n if (this._$cssResult$ = !0, o !== $3233927aa82734f9$var$s) throw Error(\"CSSResult is not constructable. Use `unsafeCSS` or `css` instead.\");\n this.cssText = t, this.t = e;\n }\n get styleSheet() {\n let t = this.o;\n const s = this.t;\n if ($3233927aa82734f9$export$b4d10f6001c083c2 && void 0 === t) {\n const e = void 0 !== s && 1 === s.length;\n e && (t = $3233927aa82734f9$var$o.get(s)), void 0 === t && ((this.o = t = new CSSStyleSheet).replaceSync(this.cssText), e && $3233927aa82734f9$var$o.set(s, t));\n }\n return t;\n }\n toString() {\n return this.cssText;\n }\n}\nconst $3233927aa82734f9$export$8d80f9cac07cdb3 = (t)=>new $3233927aa82734f9$export$505d1e8739bad805(\"string\" == typeof t ? t : t + \"\", void 0, $3233927aa82734f9$var$s), $3233927aa82734f9$export$dbf350e5966cf602 = (t, ...e)=>{\n const o = 1 === t.length ? t[0] : e.reduce((e, s, o)=>e + ((t)=>{\n if (!0 === t._$cssResult$) return t.cssText;\n if (\"number\" == typeof t) return t;\n throw Error(\"Value passed to 'css' function must be a 'css' function result: \" + t + \". Use 'unsafeCSS' to pass non-literal values, but take care to ensure page security.\");\n })(s) + t[o + 1], t[0]);\n return new $3233927aa82734f9$export$505d1e8739bad805(o, t, $3233927aa82734f9$var$s);\n}, $3233927aa82734f9$export$2ca4a66ec4cecb90 = (s, o)=>{\n if ($3233927aa82734f9$export$b4d10f6001c083c2) s.adoptedStyleSheets = o.map((t)=>t instanceof CSSStyleSheet ? t : t.styleSheet);\n else for (const e of o){\n const o = document.createElement(\"style\"), n = $3233927aa82734f9$var$t.litNonce;\n void 0 !== n && o.setAttribute(\"nonce\", n), o.textContent = e.cssText, s.appendChild(o);\n }\n}, $3233927aa82734f9$export$ee69dfd951e24778 = $3233927aa82734f9$export$b4d10f6001c083c2 ? (t)=>t : (t)=>t instanceof CSSStyleSheet ? ((t)=>{\n let e = \"\";\n for (const s of t.cssRules)e += s.cssText;\n return $3233927aa82734f9$export$8d80f9cac07cdb3(e);\n })(t) : t;\n\n\n/**\n * @license\n * Copyright 2017 Google LLC\n * SPDX-License-Identifier: BSD-3-Clause\n */ const { is: $27fcf98b67c2a783$var$i, defineProperty: $27fcf98b67c2a783$var$e, getOwnPropertyDescriptor: $27fcf98b67c2a783$var$r, getOwnPropertyNames: $27fcf98b67c2a783$var$h, getOwnPropertySymbols: $27fcf98b67c2a783$var$o, getPrototypeOf: $27fcf98b67c2a783$var$n } = Object, $27fcf98b67c2a783$var$a = globalThis, $27fcf98b67c2a783$var$c = $27fcf98b67c2a783$var$a.trustedTypes, $27fcf98b67c2a783$var$l = $27fcf98b67c2a783$var$c ? $27fcf98b67c2a783$var$c.emptyScript : \"\", $27fcf98b67c2a783$var$p = $27fcf98b67c2a783$var$a.reactiveElementPolyfillSupport, $27fcf98b67c2a783$var$d = (t, s)=>t, $27fcf98b67c2a783$export$7312b35fbf521afb = {\n toAttribute (t, s) {\n switch(s){\n case Boolean:\n t = t ? $27fcf98b67c2a783$var$l : null;\n break;\n case Object:\n case Array:\n t = null == t ? t : JSON.stringify(t);\n }\n return t;\n },\n fromAttribute (t, s) {\n let i = t;\n switch(s){\n case Boolean:\n i = null !== t;\n break;\n case Number:\n i = null === t ? null : Number(t);\n break;\n case Object:\n case Array:\n try {\n i = JSON.parse(t);\n } catch (t) {\n i = null;\n }\n }\n return i;\n }\n}, $27fcf98b67c2a783$export$53a6892c50694894 = (t, s)=>!$27fcf98b67c2a783$var$i(t, s), $27fcf98b67c2a783$var$y = {\n attribute: !0,\n type: String,\n converter: $27fcf98b67c2a783$export$7312b35fbf521afb,\n reflect: !1,\n hasChanged: $27fcf98b67c2a783$export$53a6892c50694894\n};\nSymbol.metadata ??= Symbol(\"metadata\"), $27fcf98b67c2a783$var$a.litPropertyMetadata ??= new WeakMap;\nclass $27fcf98b67c2a783$export$c7c07a37856565d extends HTMLElement {\n static addInitializer(t) {\n this._$Ei(), (this.l ??= []).push(t);\n }\n static get observedAttributes() {\n return this.finalize(), this._$Eh && [\n ...this._$Eh.keys()\n ];\n }\n static createProperty(t, s = $27fcf98b67c2a783$var$y) {\n if (s.state && (s.attribute = !1), this._$Ei(), this.elementProperties.set(t, s), !s.noAccessor) {\n const i = Symbol(), r = this.getPropertyDescriptor(t, i, s);\n void 0 !== r && $27fcf98b67c2a783$var$e(this.prototype, t, r);\n }\n }\n static getPropertyDescriptor(t, s, i) {\n const { get: e, set: h } = $27fcf98b67c2a783$var$r(this.prototype, t) ?? {\n get () {\n return this[s];\n },\n set (t) {\n this[s] = t;\n }\n };\n return {\n get () {\n return e?.call(this);\n },\n set (s) {\n const r = e?.call(this);\n h.call(this, s), this.requestUpdate(t, r, i);\n },\n configurable: !0,\n enumerable: !0\n };\n }\n static getPropertyOptions(t) {\n return this.elementProperties.get(t) ?? $27fcf98b67c2a783$var$y;\n }\n static _$Ei() {\n if (this.hasOwnProperty($27fcf98b67c2a783$var$d(\"elementProperties\"))) return;\n const t = $27fcf98b67c2a783$var$n(this);\n t.finalize(), void 0 !== t.l && (this.l = [\n ...t.l\n ]), this.elementProperties = new Map(t.elementProperties);\n }\n static finalize() {\n if (this.hasOwnProperty($27fcf98b67c2a783$var$d(\"finalized\"))) return;\n if (this.finalized = !0, this._$Ei(), this.hasOwnProperty($27fcf98b67c2a783$var$d(\"properties\"))) {\n const t = this.properties, s = [\n ...$27fcf98b67c2a783$var$h(t),\n ...$27fcf98b67c2a783$var$o(t)\n ];\n for (const i of s)this.createProperty(i, t[i]);\n }\n const t = this[Symbol.metadata];\n if (null !== t) {\n const s = litPropertyMetadata.get(t);\n if (void 0 !== s) for (const [t, i] of s)this.elementProperties.set(t, i);\n }\n this._$Eh = new Map;\n for (const [t, s] of this.elementProperties){\n const i = this._$Eu(t, s);\n void 0 !== i && this._$Eh.set(i, t);\n }\n this.elementStyles = this.finalizeStyles(this.styles);\n }\n static finalizeStyles(s) {\n const i = [];\n if (Array.isArray(s)) {\n const e = new Set(s.flat(1 / 0).reverse());\n for (const s of e)i.unshift((0, $3233927aa82734f9$export$ee69dfd951e24778)(s));\n } else void 0 !== s && i.push((0, $3233927aa82734f9$export$ee69dfd951e24778)(s));\n return i;\n }\n static _$Eu(t, s) {\n const i = s.attribute;\n return !1 === i ? void 0 : \"string\" == typeof i ? i : \"string\" == typeof t ? t.toLowerCase() : void 0;\n }\n constructor(){\n super(), this._$Ep = void 0, this.isUpdatePending = !1, this.hasUpdated = !1, this._$Em = null, this._$Ev();\n }\n _$Ev() {\n this._$Eg = new Promise((t)=>this.enableUpdating = t), this._$AL = new Map, this._$ES(), this.requestUpdate(), this.constructor.l?.forEach((t)=>t(this));\n }\n addController(t) {\n (this._$E_ ??= new Set).add(t), void 0 !== this.renderRoot && this.isConnected && t.hostConnected?.();\n }\n removeController(t) {\n this._$E_?.delete(t);\n }\n _$ES() {\n const t = new Map, s = this.constructor.elementProperties;\n for (const i of s.keys())this.hasOwnProperty(i) && (t.set(i, this[i]), delete this[i]);\n t.size > 0 && (this._$Ep = t);\n }\n createRenderRoot() {\n const t = this.shadowRoot ?? this.attachShadow(this.constructor.shadowRootOptions);\n return (0, $3233927aa82734f9$export$2ca4a66ec4cecb90)(t, this.constructor.elementStyles), t;\n }\n connectedCallback() {\n this.renderRoot ??= this.createRenderRoot(), this.enableUpdating(!0), this._$E_?.forEach((t)=>t.hostConnected?.());\n }\n enableUpdating(t) {}\n disconnectedCallback() {\n this._$E_?.forEach((t)=>t.hostDisconnected?.());\n }\n attributeChangedCallback(t, s, i) {\n this._$AK(t, i);\n }\n _$EO(t, s) {\n const i = this.constructor.elementProperties.get(t), e = this.constructor._$Eu(t, i);\n if (void 0 !== e && !0 === i.reflect) {\n const r = (void 0 !== i.converter?.toAttribute ? i.converter : $27fcf98b67c2a783$export$7312b35fbf521afb).toAttribute(s, i.type);\n this._$Em = t, null == r ? this.removeAttribute(e) : this.setAttribute(e, r), this._$Em = null;\n }\n }\n _$AK(t, s) {\n const i = this.constructor, e = i._$Eh.get(t);\n if (void 0 !== e && this._$Em !== e) {\n const t = i.getPropertyOptions(e), r = \"function\" == typeof t.converter ? {\n fromAttribute: t.converter\n } : void 0 !== t.converter?.fromAttribute ? t.converter : $27fcf98b67c2a783$export$7312b35fbf521afb;\n this._$Em = e, this[e] = r.fromAttribute(s, t.type), this._$Em = null;\n }\n }\n requestUpdate(t, s, i, e = !1, r) {\n if (void 0 !== t) {\n if (i ??= this.constructor.getPropertyOptions(t), !(i.hasChanged ?? $27fcf98b67c2a783$export$53a6892c50694894)(e ? r : this[t], s)) return;\n this.C(t, s, i);\n }\n !1 === this.isUpdatePending && (this._$Eg = this._$EP());\n }\n C(t, s, i) {\n this._$AL.has(t) || this._$AL.set(t, s), !0 === i.reflect && this._$Em !== t && (this._$Ej ??= new Set).add(t);\n }\n async _$EP() {\n this.isUpdatePending = !0;\n try {\n await this._$Eg;\n } catch (t) {\n Promise.reject(t);\n }\n const t = this.scheduleUpdate();\n return null != t && await t, !this.isUpdatePending;\n }\n scheduleUpdate() {\n return this.performUpdate();\n }\n performUpdate() {\n if (!this.isUpdatePending) return;\n if (!this.hasUpdated) {\n if (this.renderRoot ??= this.createRenderRoot(), this._$Ep) {\n for (const [t, s] of this._$Ep)this[t] = s;\n this._$Ep = void 0;\n }\n const t = this.constructor.elementProperties;\n if (t.size > 0) for (const [s, i] of t)!0 !== i.wrapped || this._$AL.has(s) || void 0 === this[s] || this.C(s, this[s], i);\n }\n let t = !1;\n const s = this._$AL;\n try {\n t = this.shouldUpdate(s), t ? (this.willUpdate(s), this._$E_?.forEach((t)=>t.hostUpdate?.()), this.update(s)) : this._$ET();\n } catch (s) {\n throw t = !1, this._$ET(), s;\n }\n t && this._$AE(s);\n }\n willUpdate(t) {}\n _$AE(t) {\n this._$E_?.forEach((t)=>t.hostUpdated?.()), this.hasUpdated || (this.hasUpdated = !0, this.firstUpdated(t)), this.updated(t);\n }\n _$ET() {\n this._$AL = new Map, this.isUpdatePending = !1;\n }\n get updateComplete() {\n return this.getUpdateComplete();\n }\n getUpdateComplete() {\n return this._$Eg;\n }\n shouldUpdate(t) {\n return !0;\n }\n update(t) {\n this._$Ej &&= this._$Ej.forEach((t)=>this._$EO(t, this[t])), this._$ET();\n }\n updated(t) {}\n firstUpdated(t) {}\n}\n$27fcf98b67c2a783$export$c7c07a37856565d.elementStyles = [], $27fcf98b67c2a783$export$c7c07a37856565d.shadowRootOptions = {\n mode: \"open\"\n}, $27fcf98b67c2a783$export$c7c07a37856565d[$27fcf98b67c2a783$var$d(\"elementProperties\")] = new Map, $27fcf98b67c2a783$export$c7c07a37856565d[$27fcf98b67c2a783$var$d(\"finalized\")] = new Map, $27fcf98b67c2a783$var$p?.({\n ReactiveElement: $27fcf98b67c2a783$export$c7c07a37856565d\n}), ($27fcf98b67c2a783$var$a.reactiveElementVersions ??= []).push(\"2.0.2\");\n\n\n/**\n * @license\n * Copyright 2017 Google LLC\n * SPDX-License-Identifier: BSD-3-Clause\n */ const $e5ed8027d647799b$var$t = globalThis, $e5ed8027d647799b$var$i = $e5ed8027d647799b$var$t.trustedTypes, $e5ed8027d647799b$var$s = $e5ed8027d647799b$var$i ? $e5ed8027d647799b$var$i.createPolicy(\"lit-html\", {\n createHTML: (t)=>t\n}) : void 0, $e5ed8027d647799b$var$e = \"$lit$\", $e5ed8027d647799b$var$h = `lit$${(Math.random() + \"\").slice(9)}$`, $e5ed8027d647799b$var$o = \"?\" + $e5ed8027d647799b$var$h, $e5ed8027d647799b$var$n = `<${$e5ed8027d647799b$var$o}>`, $e5ed8027d647799b$var$r = document, $e5ed8027d647799b$var$l = ()=>$e5ed8027d647799b$var$r.createComment(\"\"), $e5ed8027d647799b$var$c = (t)=>null === t || \"object\" != typeof t && \"function\" != typeof t, $e5ed8027d647799b$var$a = Array.isArray, $e5ed8027d647799b$var$u = (t)=>$e5ed8027d647799b$var$a(t) || \"function\" == typeof t?.[Symbol.iterator], $e5ed8027d647799b$var$d = \"[ \t\\n\\f\\r]\", $e5ed8027d647799b$var$f = /<(?:(!--|\\/[^a-zA-Z])|(\\/?[a-zA-Z][^>\\s]*)|(\\/?$))/g, $e5ed8027d647799b$var$v = /-->/g, $e5ed8027d647799b$var$_ = />/g, $e5ed8027d647799b$var$m = RegExp(`>|${$e5ed8027d647799b$var$d}(?:([^\\\\s\"'>=/]+)(${$e5ed8027d647799b$var$d}*=${$e5ed8027d647799b$var$d}*(?:[^ \\t\\n\\f\\r\"'\\`<>=]|(\"|')|))|$)`, \"g\"), $e5ed8027d647799b$var$p = /'/g, $e5ed8027d647799b$var$g = /\"/g, $e5ed8027d647799b$var$$ = /^(?:script|style|textarea|title)$/i, $e5ed8027d647799b$var$y = (t)=>(i, ...s)=>({\n _$litType$: t,\n strings: i,\n values: s\n }), $e5ed8027d647799b$export$c0bb0b647f701bb5 = $e5ed8027d647799b$var$y(1), $e5ed8027d647799b$export$7ed1367e7fa1ad68 = $e5ed8027d647799b$var$y(2), $e5ed8027d647799b$export$9c068ae9cc5db4e8 = Symbol.for(\"lit-noChange\"), $e5ed8027d647799b$export$45b790e32b2810ee = Symbol.for(\"lit-nothing\"), $e5ed8027d647799b$var$A = new WeakMap, $e5ed8027d647799b$var$E = $e5ed8027d647799b$var$r.createTreeWalker($e5ed8027d647799b$var$r, 129);\nfunction $e5ed8027d647799b$var$C(t, i) {\n if (!Array.isArray(t) || !t.hasOwnProperty(\"raw\")) throw Error(\"invalid template strings array\");\n return void 0 !== $e5ed8027d647799b$var$s ? $e5ed8027d647799b$var$s.createHTML(i) : i;\n}\nconst $e5ed8027d647799b$var$P = (t, i)=>{\n const s = t.length - 1, o = [];\n let r, l = 2 === i ? \"\" : \"\", c = $e5ed8027d647799b$var$f;\n for(let i = 0; i < s; i++){\n const s = t[i];\n let a, u, d = -1, y = 0;\n for(; y < s.length && (c.lastIndex = y, u = c.exec(s), null !== u);)y = c.lastIndex, c === $e5ed8027d647799b$var$f ? \"!--\" === u[1] ? c = $e5ed8027d647799b$var$v : void 0 !== u[1] ? c = $e5ed8027d647799b$var$_ : void 0 !== u[2] ? ($e5ed8027d647799b$var$$.test(u[2]) && (r = RegExp(\"\" === u[0] ? (c = r ?? $e5ed8027d647799b$var$f, d = -1) : void 0 === u[1] ? d = -2 : (d = c.lastIndex - u[2].length, a = u[1], c = void 0 === u[3] ? $e5ed8027d647799b$var$m : '\"' === u[3] ? $e5ed8027d647799b$var$g : $e5ed8027d647799b$var$p) : c === $e5ed8027d647799b$var$g || c === $e5ed8027d647799b$var$p ? c = $e5ed8027d647799b$var$m : c === $e5ed8027d647799b$var$v || c === $e5ed8027d647799b$var$_ ? c = $e5ed8027d647799b$var$f : (c = $e5ed8027d647799b$var$m, r = void 0);\n const x = c === $e5ed8027d647799b$var$m && t[i + 1].startsWith(\"/>\") ? \" \" : \"\";\n l += c === $e5ed8027d647799b$var$f ? s + $e5ed8027d647799b$var$n : d >= 0 ? (o.push(a), s.slice(0, d) + $e5ed8027d647799b$var$e + s.slice(d) + $e5ed8027d647799b$var$h + x) : s + $e5ed8027d647799b$var$h + (-2 === d ? i : x);\n }\n return [\n $e5ed8027d647799b$var$C(t, l + (t[s] || \"\") + (2 === i ? \"\" : \"\")),\n o\n ];\n};\nclass $e5ed8027d647799b$var$V {\n constructor({ strings: t, _$litType$: s }, n){\n let r;\n this.parts = [];\n let c = 0, a = 0;\n const u = t.length - 1, d = this.parts, [f, v] = $e5ed8027d647799b$var$P(t, s);\n if (this.el = $e5ed8027d647799b$var$V.createElement(f, n), $e5ed8027d647799b$var$E.currentNode = this.el.content, 2 === s) {\n const t = this.el.content.firstChild;\n t.replaceWith(...t.childNodes);\n }\n for(; null !== (r = $e5ed8027d647799b$var$E.nextNode()) && d.length < u;){\n if (1 === r.nodeType) {\n if (r.hasAttributes()) for (const t of r.getAttributeNames())if (t.endsWith($e5ed8027d647799b$var$e)) {\n const i = v[a++], s = r.getAttribute(t).split($e5ed8027d647799b$var$h), e = /([.?@])?(.*)/.exec(i);\n d.push({\n type: 1,\n index: c,\n name: e[2],\n strings: s,\n ctor: \".\" === e[1] ? $e5ed8027d647799b$var$k : \"?\" === e[1] ? $e5ed8027d647799b$var$H : \"@\" === e[1] ? $e5ed8027d647799b$var$I : $e5ed8027d647799b$var$R\n }), r.removeAttribute(t);\n } else t.startsWith($e5ed8027d647799b$var$h) && (d.push({\n type: 6,\n index: c\n }), r.removeAttribute(t));\n if ($e5ed8027d647799b$var$$.test(r.tagName)) {\n const t = r.textContent.split($e5ed8027d647799b$var$h), s = t.length - 1;\n if (s > 0) {\n r.textContent = $e5ed8027d647799b$var$i ? $e5ed8027d647799b$var$i.emptyScript : \"\";\n for(let i = 0; i < s; i++)r.append(t[i], $e5ed8027d647799b$var$l()), $e5ed8027d647799b$var$E.nextNode(), d.push({\n type: 2,\n index: ++c\n });\n r.append(t[s], $e5ed8027d647799b$var$l());\n }\n }\n } else if (8 === r.nodeType) {\n if (r.data === $e5ed8027d647799b$var$o) d.push({\n type: 2,\n index: c\n });\n else {\n let t = -1;\n for(; -1 !== (t = r.data.indexOf($e5ed8027d647799b$var$h, t + 1));)d.push({\n type: 7,\n index: c\n }), t += $e5ed8027d647799b$var$h.length - 1;\n }\n }\n c++;\n }\n }\n static createElement(t, i) {\n const s = $e5ed8027d647799b$var$r.createElement(\"template\");\n return s.innerHTML = t, s;\n }\n}\nfunction $e5ed8027d647799b$var$N(t, i, s = t, e) {\n if (i === $e5ed8027d647799b$export$9c068ae9cc5db4e8) return i;\n let h = void 0 !== e ? s._$Co?.[e] : s._$Cl;\n const o = $e5ed8027d647799b$var$c(i) ? void 0 : i._$litDirective$;\n return h?.constructor !== o && (h?._$AO?.(!1), void 0 === o ? h = void 0 : (h = new o(t), h._$AT(t, s, e)), void 0 !== e ? (s._$Co ??= [])[e] = h : s._$Cl = h), void 0 !== h && (i = $e5ed8027d647799b$var$N(t, h._$AS(t, i.values), h, e)), i;\n}\nclass $e5ed8027d647799b$var$S {\n constructor(t, i){\n this._$AV = [], this._$AN = void 0, this._$AD = t, this._$AM = i;\n }\n get parentNode() {\n return this._$AM.parentNode;\n }\n get _$AU() {\n return this._$AM._$AU;\n }\n u(t) {\n const { el: { content: i }, parts: s } = this._$AD, e = (t?.creationScope ?? $e5ed8027d647799b$var$r).importNode(i, !0);\n $e5ed8027d647799b$var$E.currentNode = e;\n let h = $e5ed8027d647799b$var$E.nextNode(), o = 0, n = 0, l = s[0];\n for(; void 0 !== l;){\n if (o === l.index) {\n let i;\n 2 === l.type ? i = new $e5ed8027d647799b$var$M(h, h.nextSibling, this, t) : 1 === l.type ? i = new l.ctor(h, l.name, l.strings, this, t) : 6 === l.type && (i = new $e5ed8027d647799b$var$L(h, this, t)), this._$AV.push(i), l = s[++n];\n }\n o !== l?.index && (h = $e5ed8027d647799b$var$E.nextNode(), o++);\n }\n return $e5ed8027d647799b$var$E.currentNode = $e5ed8027d647799b$var$r, e;\n }\n p(t) {\n let i = 0;\n for (const s of this._$AV)void 0 !== s && (void 0 !== s.strings ? (s._$AI(t, s, i), i += s.strings.length - 2) : s._$AI(t[i])), i++;\n }\n}\nclass $e5ed8027d647799b$var$M {\n get _$AU() {\n return this._$AM?._$AU ?? this._$Cv;\n }\n constructor(t, i, s, e){\n this.type = 2, this._$AH = $e5ed8027d647799b$export$45b790e32b2810ee, this._$AN = void 0, this._$AA = t, this._$AB = i, this._$AM = s, this.options = e, this._$Cv = e?.isConnected ?? !0;\n }\n get parentNode() {\n let t = this._$AA.parentNode;\n const i = this._$AM;\n return void 0 !== i && 11 === t?.nodeType && (t = i.parentNode), t;\n }\n get startNode() {\n return this._$AA;\n }\n get endNode() {\n return this._$AB;\n }\n _$AI(t, i = this) {\n t = $e5ed8027d647799b$var$N(this, t, i), $e5ed8027d647799b$var$c(t) ? t === $e5ed8027d647799b$export$45b790e32b2810ee || null == t || \"\" === t ? (this._$AH !== $e5ed8027d647799b$export$45b790e32b2810ee && this._$AR(), this._$AH = $e5ed8027d647799b$export$45b790e32b2810ee) : t !== this._$AH && t !== $e5ed8027d647799b$export$9c068ae9cc5db4e8 && this._(t) : void 0 !== t._$litType$ ? this.g(t) : void 0 !== t.nodeType ? this.$(t) : $e5ed8027d647799b$var$u(t) ? this.T(t) : this._(t);\n }\n k(t) {\n return this._$AA.parentNode.insertBefore(t, this._$AB);\n }\n $(t) {\n this._$AH !== t && (this._$AR(), this._$AH = this.k(t));\n }\n _(t) {\n this._$AH !== $e5ed8027d647799b$export$45b790e32b2810ee && $e5ed8027d647799b$var$c(this._$AH) ? this._$AA.nextSibling.data = t : this.$($e5ed8027d647799b$var$r.createTextNode(t)), this._$AH = t;\n }\n g(t) {\n const { values: i, _$litType$: s } = t, e = \"number\" == typeof s ? this._$AC(t) : (void 0 === s.el && (s.el = $e5ed8027d647799b$var$V.createElement($e5ed8027d647799b$var$C(s.h, s.h[0]), this.options)), s);\n if (this._$AH?._$AD === e) this._$AH.p(i);\n else {\n const t = new $e5ed8027d647799b$var$S(e, this), s = t.u(this.options);\n t.p(i), this.$(s), this._$AH = t;\n }\n }\n _$AC(t) {\n let i = $e5ed8027d647799b$var$A.get(t.strings);\n return void 0 === i && $e5ed8027d647799b$var$A.set(t.strings, i = new $e5ed8027d647799b$var$V(t)), i;\n }\n T(t) {\n $e5ed8027d647799b$var$a(this._$AH) || (this._$AH = [], this._$AR());\n const i = this._$AH;\n let s, e = 0;\n for (const h of t)e === i.length ? i.push(s = new $e5ed8027d647799b$var$M(this.k($e5ed8027d647799b$var$l()), this.k($e5ed8027d647799b$var$l()), this, this.options)) : s = i[e], s._$AI(h), e++;\n e < i.length && (this._$AR(s && s._$AB.nextSibling, e), i.length = e);\n }\n _$AR(t = this._$AA.nextSibling, i) {\n for(this._$AP?.(!1, !0, i); t && t !== this._$AB;){\n const i = t.nextSibling;\n t.remove(), t = i;\n }\n }\n setConnected(t) {\n void 0 === this._$AM && (this._$Cv = t, this._$AP?.(t));\n }\n}\nclass $e5ed8027d647799b$var$R {\n get tagName() {\n return this.element.tagName;\n }\n get _$AU() {\n return this._$AM._$AU;\n }\n constructor(t, i, s, e, h){\n this.type = 1, this._$AH = $e5ed8027d647799b$export$45b790e32b2810ee, this._$AN = void 0, this.element = t, this.name = i, this._$AM = e, this.options = h, s.length > 2 || \"\" !== s[0] || \"\" !== s[1] ? (this._$AH = Array(s.length - 1).fill(new String), this.strings = s) : this._$AH = $e5ed8027d647799b$export$45b790e32b2810ee;\n }\n _$AI(t, i = this, s, e) {\n const h = this.strings;\n let o = !1;\n if (void 0 === h) t = $e5ed8027d647799b$var$N(this, t, i, 0), o = !$e5ed8027d647799b$var$c(t) || t !== this._$AH && t !== $e5ed8027d647799b$export$9c068ae9cc5db4e8, o && (this._$AH = t);\n else {\n const e = t;\n let n, r;\n for(t = h[0], n = 0; n < h.length - 1; n++)r = $e5ed8027d647799b$var$N(this, e[s + n], i, n), r === $e5ed8027d647799b$export$9c068ae9cc5db4e8 && (r = this._$AH[n]), o ||= !$e5ed8027d647799b$var$c(r) || r !== this._$AH[n], r === $e5ed8027d647799b$export$45b790e32b2810ee ? t = $e5ed8027d647799b$export$45b790e32b2810ee : t !== $e5ed8027d647799b$export$45b790e32b2810ee && (t += (r ?? \"\") + h[n + 1]), this._$AH[n] = r;\n }\n o && !e && this.O(t);\n }\n O(t) {\n t === $e5ed8027d647799b$export$45b790e32b2810ee ? this.element.removeAttribute(this.name) : this.element.setAttribute(this.name, t ?? \"\");\n }\n}\nclass $e5ed8027d647799b$var$k extends $e5ed8027d647799b$var$R {\n constructor(){\n super(...arguments), this.type = 3;\n }\n O(t) {\n this.element[this.name] = t === $e5ed8027d647799b$export$45b790e32b2810ee ? void 0 : t;\n }\n}\nclass $e5ed8027d647799b$var$H extends $e5ed8027d647799b$var$R {\n constructor(){\n super(...arguments), this.type = 4;\n }\n O(t) {\n this.element.toggleAttribute(this.name, !!t && t !== $e5ed8027d647799b$export$45b790e32b2810ee);\n }\n}\nclass $e5ed8027d647799b$var$I extends $e5ed8027d647799b$var$R {\n constructor(t, i, s, e, h){\n super(t, i, s, e, h), this.type = 5;\n }\n _$AI(t, i = this) {\n if ((t = $e5ed8027d647799b$var$N(this, t, i, 0) ?? $e5ed8027d647799b$export$45b790e32b2810ee) === $e5ed8027d647799b$export$9c068ae9cc5db4e8) return;\n const s = this._$AH, e = t === $e5ed8027d647799b$export$45b790e32b2810ee && s !== $e5ed8027d647799b$export$45b790e32b2810ee || t.capture !== s.capture || t.once !== s.once || t.passive !== s.passive, h = t !== $e5ed8027d647799b$export$45b790e32b2810ee && (s === $e5ed8027d647799b$export$45b790e32b2810ee || e);\n e && this.element.removeEventListener(this.name, this, s), h && this.element.addEventListener(this.name, this, t), this._$AH = t;\n }\n handleEvent(t) {\n \"function\" == typeof this._$AH ? this._$AH.call(this.options?.host ?? this.element, t) : this._$AH.handleEvent(t);\n }\n}\nclass $e5ed8027d647799b$var$L {\n constructor(t, i, s){\n this.element = t, this.type = 6, this._$AN = void 0, this._$AM = i, this.options = s;\n }\n get _$AU() {\n return this._$AM._$AU;\n }\n _$AI(t) {\n $e5ed8027d647799b$var$N(this, t);\n }\n}\nconst $e5ed8027d647799b$export$8613d1ca9052b22e = {\n j: $e5ed8027d647799b$var$e,\n P: $e5ed8027d647799b$var$h,\n A: $e5ed8027d647799b$var$o,\n C: 1,\n M: $e5ed8027d647799b$var$P,\n L: $e5ed8027d647799b$var$S,\n R: $e5ed8027d647799b$var$u,\n V: $e5ed8027d647799b$var$N,\n D: $e5ed8027d647799b$var$M,\n I: $e5ed8027d647799b$var$R,\n H: $e5ed8027d647799b$var$H,\n N: $e5ed8027d647799b$var$I,\n U: $e5ed8027d647799b$var$k,\n B: $e5ed8027d647799b$var$L\n}, $e5ed8027d647799b$var$Z = $e5ed8027d647799b$var$t.litHtmlPolyfillSupport;\n$e5ed8027d647799b$var$Z?.($e5ed8027d647799b$var$V, $e5ed8027d647799b$var$M), ($e5ed8027d647799b$var$t.litHtmlVersions ??= []).push(\"3.1.0\");\nconst $e5ed8027d647799b$export$b3890eb0ae9dca99 = (t, i, s)=>{\n const e = s?.renderBefore ?? i;\n let h = e._$litPart$;\n if (void 0 === h) {\n const t = s?.renderBefore ?? null;\n e._$litPart$ = h = new $e5ed8027d647799b$var$M(i.insertBefore($e5ed8027d647799b$var$l(), t), t, void 0, s ?? {});\n }\n return h._$AI(t), h;\n};\n\n\n\n\n/**\n * @license\n * Copyright 2017 Google LLC\n * SPDX-License-Identifier: BSD-3-Clause\n */ class $fe586ba0757c37f7$export$3f2f9f5909897157 extends (0, $27fcf98b67c2a783$export$c7c07a37856565d) {\n constructor(){\n super(...arguments), this.renderOptions = {\n host: this\n }, this._$Do = void 0;\n }\n createRenderRoot() {\n const t = super.createRenderRoot();\n return this.renderOptions.renderBefore ??= t.firstChild, t;\n }\n update(t) {\n const i = this.render();\n this.hasUpdated || (this.renderOptions.isConnected = this.isConnected), super.update(t), this._$Do = (0, $e5ed8027d647799b$export$b3890eb0ae9dca99)(i, this.renderRoot, this.renderOptions);\n }\n connectedCallback() {\n super.connectedCallback(), this._$Do?.setConnected(!0);\n }\n disconnectedCallback() {\n super.disconnectedCallback(), this._$Do?.setConnected(!1);\n }\n render() {\n return 0, $e5ed8027d647799b$export$9c068ae9cc5db4e8;\n }\n}\n$fe586ba0757c37f7$export$3f2f9f5909897157._$litElement$ = !0, $fe586ba0757c37f7$export$3f2f9f5909897157[\"finalized\"] = !0, globalThis.litElementHydrateSupport?.({\n LitElement: $fe586ba0757c37f7$export$3f2f9f5909897157\n});\nconst $fe586ba0757c37f7$var$r = globalThis.litElementPolyfillSupport;\n$fe586ba0757c37f7$var$r?.({\n LitElement: $fe586ba0757c37f7$export$3f2f9f5909897157\n});\nconst $fe586ba0757c37f7$export$f5c524615a7708d6 = {\n _$AK: (t, e, i)=>{\n t._$AK(e, i);\n },\n _$AL: (t)=>t._$AL\n};\n(globalThis.litElementVersions ??= []).push(\"4.0.2\");\n\n\n/**\n * @license\n * Copyright 2022 Google LLC\n * SPDX-License-Identifier: BSD-3-Clause\n */ const $650ed036964a13b8$export$6acf61af03e62db = !1;\n\n\n\n\n/**\n * @license\n * Copyright 2017 Google LLC\n * SPDX-License-Identifier: BSD-3-Clause\n */ const $07706bf0c990b886$export$da64fc29f17f9d0e = (t)=>(e, o)=>{\n void 0 !== o ? o.addInitializer(()=>{\n customElements.define(t, e);\n }) : customElements.define(t, e);\n };\n\n\n\n/**\n * @license\n * Copyright 2017 Google LLC\n * SPDX-License-Identifier: BSD-3-Clause\n */ const $b2fdcbe153c88f81$var$o = {\n attribute: !0,\n type: String,\n converter: (0, $27fcf98b67c2a783$export$7312b35fbf521afb),\n reflect: !1,\n hasChanged: (0, $27fcf98b67c2a783$export$53a6892c50694894)\n}, $b2fdcbe153c88f81$export$8d623b1670eb40f4 = (t = $b2fdcbe153c88f81$var$o, e, r)=>{\n const { kind: n, metadata: i } = r;\n let s = globalThis.litPropertyMetadata.get(i);\n if (void 0 === s && globalThis.litPropertyMetadata.set(i, s = new Map), s.set(r.name, t), \"accessor\" === n) {\n const { name: o } = r;\n return {\n set (r) {\n const n = e.get.call(this);\n e.set.call(this, r), this.requestUpdate(o, n, t);\n },\n init (e) {\n return void 0 !== e && this.C(o, void 0, t), e;\n }\n };\n }\n if (\"setter\" === n) {\n const { name: o } = r;\n return function(r) {\n const n = this[o];\n e.call(this, r), this.requestUpdate(o, n, t);\n };\n }\n throw Error(\"Unsupported decorator location: \" + n);\n};\nfunction $b2fdcbe153c88f81$export$d541bacb2bda4494(t) {\n return (e, o)=>\"object\" == typeof o ? $b2fdcbe153c88f81$export$8d623b1670eb40f4(t, e, o) : ((t, e, o)=>{\n const r = e.hasOwnProperty(o);\n return e.constructor.createProperty(o, r ? {\n ...t,\n wrapped: !0\n } : t), r ? Object.getOwnPropertyDescriptor(e, o) : void 0;\n })(t, e, o);\n}\n\n\n\n/**\n * @license\n * Copyright 2017 Google LLC\n * SPDX-License-Identifier: BSD-3-Clause\n */ function $7162e77b40ffab5c$export$ca000e230c0caa3e(r) {\n return (0, $b2fdcbe153c88f81$export$d541bacb2bda4494)({\n ...r,\n state: !0,\n attribute: !1\n });\n}\n\n\n/**\n * @license\n * Copyright 2017 Google LLC\n * SPDX-License-Identifier: BSD-3-Clause\n */ function $e5c3d47edfef3b02$export$b2b799818fbabcf3(t) {\n return (n, o)=>{\n const c = \"function\" == typeof n ? n : n[o];\n Object.assign(c, t);\n };\n}\n\n\n/**\n * @license\n * Copyright 2017 Google LLC\n * SPDX-License-Identifier: BSD-3-Clause\n */ const $15c76e2f7983b497$export$51987bb50e1f6752 = (e, t, c)=>(c.configurable = !0, c.enumerable = !0, Reflect.decorate && \"object\" != typeof t && Object.defineProperty(e, t, c), c);\n\n\n/**\n * @license\n * Copyright 2017 Google LLC\n * SPDX-License-Identifier: BSD-3-Clause\n */ function $10a410638b7df95b$export$2fa187e846a241c4(e, r) {\n return (n, s, i)=>{\n const o = (t)=>t.renderRoot?.querySelector(e) ?? null;\n if (r) {\n const { get: e, set: r } = \"object\" == typeof s ? n : i ?? (()=>{\n const t = Symbol();\n return {\n get () {\n return this[t];\n },\n set (e) {\n this[t] = e;\n }\n };\n })();\n return (0, $15c76e2f7983b497$export$51987bb50e1f6752)(n, s, {\n get () {\n let t = e.call(this);\n return void 0 === t && (t = o(this), (null !== t || this.hasUpdated) && r.call(this, t)), t;\n }\n });\n }\n return (0, $15c76e2f7983b497$export$51987bb50e1f6752)(n, s, {\n get () {\n return o(this);\n }\n });\n };\n}\n\n\n\n/**\n * @license\n * Copyright 2017 Google LLC\n * SPDX-License-Identifier: BSD-3-Clause\n */ let $24ba95ebfbdcf6b8$var$e;\nfunction $24ba95ebfbdcf6b8$export$dcd0d083aa86c355(r) {\n return (n, o)=>(0, $15c76e2f7983b497$export$51987bb50e1f6752)(n, o, {\n get () {\n return (this.renderRoot ?? ($24ba95ebfbdcf6b8$var$e ??= document.createDocumentFragment())).querySelectorAll(r);\n }\n });\n}\n\n\n\n/**\n * @license\n * Copyright 2017 Google LLC\n * SPDX-License-Identifier: BSD-3-Clause\n */ function $1f45ba04a1effcd1$export$163dfc35cc43f240(r) {\n return (n, e)=>(0, $15c76e2f7983b497$export$51987bb50e1f6752)(n, e, {\n async get () {\n return await this.updateComplete, this.renderRoot?.querySelector(r) ?? null;\n }\n });\n}\n\n\n\n/**\n * @license\n * Copyright 2021 Google LLC\n * SPDX-License-Identifier: BSD-3-Clause\n */ function $43ca3aec390b0561$export$4682af2d9ee91415(o) {\n return (e, n)=>{\n const { slot: r, selector: s } = o ?? {}, c = \"slot\" + (r ? `[name=${r}]` : \":not([name])\");\n return (0, $15c76e2f7983b497$export$51987bb50e1f6752)(e, n, {\n get () {\n const t = this.renderRoot?.querySelector(c), e = t?.assignedElements(o) ?? [];\n return void 0 === s ? e : e.filter((t)=>t.matches(s));\n }\n });\n };\n}\n\n\n\n/**\n * @license\n * Copyright 2017 Google LLC\n * SPDX-License-Identifier: BSD-3-Clause\n */ function $965e44d5bf066bc5$export$1bdbe53f9df1b8(n) {\n return (o, r)=>{\n const { slot: e } = n ?? {}, s = \"slot\" + (e ? `[name=${e}]` : \":not([name])\");\n return (0, $15c76e2f7983b497$export$51987bb50e1f6752)(o, r, {\n get () {\n const t = this.renderRoot?.querySelector(s);\n return t?.assignedNodes(n) ?? [];\n }\n });\n };\n}\n\n\n\n\n\n/**\n * @license\n * Copyright 2017 Google LLC\n * SPDX-License-Identifier: BSD-3-Clause\n */ const $3baabda811939da5$export$9ba3b3f20a85bfa = {\n ATTRIBUTE: 1,\n CHILD: 2,\n PROPERTY: 3,\n BOOLEAN_ATTRIBUTE: 4,\n EVENT: 5,\n ELEMENT: 6\n}, $3baabda811939da5$export$99b43ad1ed32e735 = (t)=>(...e)=>({\n _$litDirective$: t,\n values: e\n });\nclass $3baabda811939da5$export$befdefbdce210f91 {\n constructor(t){}\n get _$AU() {\n return this._$AM._$AU;\n }\n _$AT(t, e, i) {\n this._$Ct = t, this._$AM = e, this._$Ci = i;\n }\n _$AS(t, e) {\n return this.update(t, e);\n }\n update(t, e) {\n return this.render(...e);\n }\n}\n\n\n/**\n * @license\n * Copyright 2018 Google LLC\n * SPDX-License-Identifier: BSD-3-Clause\n */ const $74d80410d825d70d$var$n = \"important\", $74d80410d825d70d$var$i = \" !\" + $74d80410d825d70d$var$n, $74d80410d825d70d$export$1e5b4ce2fa884e6a = (0, $3baabda811939da5$export$99b43ad1ed32e735)(class extends (0, $3baabda811939da5$export$befdefbdce210f91) {\n constructor(t){\n if (super(t), t.type !== (0, $3baabda811939da5$export$9ba3b3f20a85bfa).ATTRIBUTE || \"style\" !== t.name || t.strings?.length > 2) throw Error(\"The `styleMap` directive must be used in the `style` attribute and must be the only part in the attribute.\");\n }\n render(t) {\n return Object.keys(t).reduce((e, r)=>{\n const s = t[r];\n return null == s ? e : e + `${r = r.includes(\"-\") ? r : r.replace(/(?:^(webkit|moz|ms|o)|)(?=[A-Z])/g, \"-$&\").toLowerCase()}:${s};`;\n }, \"\");\n }\n update(e, [r]) {\n const { style: s } = e.element;\n if (void 0 === this.ut) return this.ut = new Set(Object.keys(r)), this.render(r);\n for (const t of this.ut)null == r[t] && (this.ut.delete(t), t.includes(\"-\") ? s.removeProperty(t) : s[t] = null);\n for(const t in r){\n const e = r[t];\n if (null != e) {\n this.ut.add(t);\n const r = \"string\" == typeof e && e.endsWith($74d80410d825d70d$var$i);\n t.includes(\"-\") || r ? s.setProperty(t, r ? e.slice(0, -11) : e, r ? $74d80410d825d70d$var$n : \"\") : s[t] = e;\n }\n }\n return 0, $e5ed8027d647799b$export$9c068ae9cc5db4e8;\n }\n});\n\n\n\n\n\n\n/**\n * @license\n * Copyright 2018 Google LLC\n * SPDX-License-Identifier: BSD-3-Clause\n */ const $0e5c059fc79abe53$export$56cc687933817664 = (0, $3baabda811939da5$export$99b43ad1ed32e735)(class extends (0, $3baabda811939da5$export$befdefbdce210f91) {\n constructor(t){\n if (super(t), t.type !== (0, $3baabda811939da5$export$9ba3b3f20a85bfa).ATTRIBUTE || \"class\" !== t.name || t.strings?.length > 2) throw Error(\"`classMap()` can only be used in the `class` attribute and must be the only part in the attribute.\");\n }\n render(t) {\n return \" \" + Object.keys(t).filter((s)=>t[s]).join(\" \") + \" \";\n }\n update(s, [i]) {\n if (void 0 === this.it) {\n this.it = new Set, void 0 !== s.strings && (this.st = new Set(s.strings.join(\" \").split(/\\s/).filter((t)=>\"\" !== t)));\n for(const t in i)i[t] && !this.st?.has(t) && this.it.add(t);\n return this.render(i);\n }\n const r = s.element.classList;\n for (const t of this.it)t in i || (r.remove(t), this.it.delete(t));\n for(const t in i){\n const s = !!i[t];\n s === this.it.has(t) || this.st?.has(t) || (s ? (r.add(t), this.it.add(t)) : (r.remove(t), this.it.delete(t)));\n }\n return 0, $e5ed8027d647799b$export$9c068ae9cc5db4e8;\n }\n});\n\n\n\n\nlet $787720610257fa2e$export$3c5e3062706796ad = class UnitMenu extends (0, $fe586ba0757c37f7$export$3f2f9f5909897157) {\n static #_ = this.styles = (0, $3233927aa82734f9$export$dbf350e5966cf602)`\n @keyframes fadeIn {\n from {\n opacity: 0;\n transform: translateY(50%);\n }\n to {\n opacity: 1;\n transform: translateY(0%);\n }\n }\n\n @keyframes fadeOut {\n from {\n opacity: 1;\n transform: translateY(0%);\n }\n to {\n opacity: 0;\n transform: translateY(50%);\n }\n }\n\n .menu {\n position: absolute;\n top: 0;\n left: 0;\n width: calc(64px * var(--pixel-conversion));\n display: none;\n opacity: 0;\n flex-direction: column;\n font-size: calc(8px * var(--pixel-conversion));\n background-color: rgba(240, 220, 220, 1);\n\n border: black calc(1px * var(--pixel-conversion)) solid;\n z-index: 1;\n }\n\n .overlay {\n position: fixed;\n left: 0;\n top: 0;\n right: 0;\n bottom: 0;\n }\n\n .show {\n display: flex;\n opacity: 1;\n animation: fadeIn 140ms ease normal;\n }\n\n .hide {\n animation: fadeOut 140ms ease normal;\n }\n\n .options {\n display: flex;\n flex-direction: column;\n }\n\n .title-bar {\n background-color: red;\n width: 100%;\n height: calc(7px * var(--pixel-conversion));\n }\n\n button {\n all: unset;\n padding: calc(2px * var(--pixel-conversion));\n padding-left: calc(4px * var(--pixel-conversion));\n cursor: pointer;\n }\n\n button:focus, button:hover, .focus {\n background-color: rgba(220, 200, 200, 1);\n }\n\n button:active, .active {\n background-color: rgba(250, 240, 240, 1);\n }\n `;\n firstUpdated() {\n this.menuHtml?.addEventListener(\"animationend\", (evt)=>{\n if (evt.animationName === \"fadeOut\") {\n this._show = false;\n this.menuHtml?.classList.remove(\"hide\");\n this.requestUpdate();\n }\n });\n }\n sendEvent(type) {\n return ()=>{\n this.dispatchEvent(new Event(type));\n this.hide();\n this.requestUpdate();\n };\n }\n show() {\n this._show = true;\n this._debounce = Date.now();\n }\n hide() {\n const now = Date.now();\n if (now - this._debounce > 200) {\n this.menuHtml?.classList.add(\"hide\");\n this.clearEvents();\n }\n }\n render() {\n const dismissOverlayHtml = this._show ? (0, $e5ed8027d647799b$export$c0bb0b647f701bb5)`
` : (0, $e5ed8027d647799b$export$45b790e32b2810ee);\n return (0, $e5ed8027d647799b$export$c0bb0b647f701bb5)`\n ${dismissOverlayHtml}\n
\n
\n
\n \n \n \n
\n
\n `;\n }\n constructor(...args){\n super(...args);\n this.left = 0;\n this.top = 0;\n this.fontSize = 0;\n this.width = 0;\n this.unit = null;\n this.pixelConversion = 1;\n this._show = false;\n this.clearEvents = ()=>{};\n // Debounce needed for mobile for some reason\n // Overlay is also receiving the event\n this._debounce = 0;\n }\n};\n(0, $5c96a02c592fcff1$export$29e00dfd3077644b)([\n (0, $b2fdcbe153c88f81$export$d541bacb2bda4494)({\n type: Number\n })\n], $787720610257fa2e$export$3c5e3062706796ad.prototype, \"left\", void 0);\n(0, $5c96a02c592fcff1$export$29e00dfd3077644b)([\n (0, $b2fdcbe153c88f81$export$d541bacb2bda4494)({\n type: Number\n })\n], $787720610257fa2e$export$3c5e3062706796ad.prototype, \"top\", void 0);\n(0, $5c96a02c592fcff1$export$29e00dfd3077644b)([\n (0, $b2fdcbe153c88f81$export$d541bacb2bda4494)({\n type: Number\n })\n], $787720610257fa2e$export$3c5e3062706796ad.prototype, \"fontSize\", void 0);\n(0, $5c96a02c592fcff1$export$29e00dfd3077644b)([\n (0, $b2fdcbe153c88f81$export$d541bacb2bda4494)({\n type: Number\n })\n], $787720610257fa2e$export$3c5e3062706796ad.prototype, \"width\", void 0);\n(0, $5c96a02c592fcff1$export$29e00dfd3077644b)([\n (0, $b2fdcbe153c88f81$export$d541bacb2bda4494)({\n attribute: false\n })\n], $787720610257fa2e$export$3c5e3062706796ad.prototype, \"unit\", void 0);\n(0, $5c96a02c592fcff1$export$29e00dfd3077644b)([\n (0, $b2fdcbe153c88f81$export$d541bacb2bda4494)({\n type: Number\n })\n], $787720610257fa2e$export$3c5e3062706796ad.prototype, \"pixelConversion\", void 0);\n(0, $5c96a02c592fcff1$export$29e00dfd3077644b)([\n (0, $7162e77b40ffab5c$export$ca000e230c0caa3e)()\n], $787720610257fa2e$export$3c5e3062706796ad.prototype, \"_show\", void 0);\n(0, $5c96a02c592fcff1$export$29e00dfd3077644b)([\n (0, $10a410638b7df95b$export$2fa187e846a241c4)(\".menu\")\n], $787720610257fa2e$export$3c5e3062706796ad.prototype, \"menuHtml\", void 0);\n$787720610257fa2e$export$3c5e3062706796ad = (0, $5c96a02c592fcff1$export$29e00dfd3077644b)([\n (0, $07706bf0c990b886$export$da64fc29f17f9d0e)(\"unit-menu\")\n], $787720610257fa2e$export$3c5e3062706796ad);\n\n\n\nclass $08d6772c516efcf0$export$2524c4960ed9dff2 {\n constructor(engine){\n this.engine = engine;\n this.uiToWorldPos = new Map();\n this.unitMenu = new (0, $787720610257fa2e$export$3c5e3062706796ad)();\n document.body.appendChild(this.unitMenu);\n document.documentElement.style.setProperty(\"--pixel-conversion\", this.worldDistanceToPage(1).toString());\n window.addEventListener(\"resize\", ()=>{\n document.documentElement.style.setProperty(\"--pixel-conversion\", this.worldDistanceToPage(1).toString());\n const menuPos = this.uiToWorldPos.get(this.unitMenu);\n if (menuPos) {\n const pagePos = this.engine.screen.worldToPageCoordinates(menuPos);\n this.unitMenu.left = pagePos.x + this.worldDistanceToPage(32);\n this.unitMenu.top = pagePos.y;\n }\n });\n }\n worldDistanceToPage(distance) {\n const pageOrigin = this.engine.screen.worldToPageCoordinates($2c23f148d58cd887$export$9b781de7bf37bf48.Zero);\n const pageDistance = this.engine.screen.worldToPageCoordinates($2c23f148d58cd887$export$202e0172ed3c7be0(distance * (0, $9d936a2aecb96285$export$fae5d17304677194).x, 0)).sub(pageOrigin);\n return pageDistance.x;\n }\n showUnitMenu(unit, options) {\n const menu = this.unitMenu;\n const pagePos = this.engine.screen.worldToPageCoordinates(unit.pos);\n menu.left = pagePos.x + this.worldDistanceToPage(32);\n menu.top = pagePos.y;\n menu.unit = unit;\n const move = ()=>{\n options.move();\n clearEvents();\n };\n const attack = ()=>{\n options.attack();\n clearEvents();\n };\n const pass = ()=>{\n options.pass();\n clearEvents();\n };\n menu.addEventListener(\"move\", move);\n menu.addEventListener(\"attack\", attack);\n menu.addEventListener(\"pass\", pass);\n const clearEvents = ()=>{\n menu.removeEventListener(\"move\", move);\n menu.removeEventListener(\"attack\", attack);\n menu.removeEventListener(\"pass\", pass);\n };\n menu.clearEvents = clearEvents;\n menu.show();\n menu.focus();\n this.uiToWorldPos.set(menu, unit.pos);\n return menu;\n }\n showNextMission(pos) {}\n}\n\n\n\n\n\n\n\n\nclass $5bb1f3979eaf16cf$export$9e9f75da6ccd8cee extends (0, $51d548b0596e1d08$export$2616165974278734) {\n constructor(name, selectionManger, board){\n super(name, board);\n this.selectionManger = selectionManger;\n this.active = false;\n }\n async turnStart() {\n this.active = true;\n }\n async turnEnd() {\n this.active = false;\n }\n findClosestEnemy(unit) {\n const enemyCells = this.board.getUnits().filter((u)=>u.player !== this).map((u)=>u.cell).filter((c)=>!!c);\n const closestCell = this.findClosestCell(unit, enemyCells);\n if (closestCell?.unit) return closestCell.unit;\n return null;\n }\n findValidMoveCells(unit) {\n // pick a random valid move\n let range = [];\n if (unit.cell) // find empty or enemy occupied cells\n range = this.board.pathFinder.getRange(unit.cell.pathNode, this.mask, unit.unitConfig.movement).filter((node)=>{\n const cell = node.owner;\n return cell.unit?.player !== this;\n });\n return range.map((node)=>node.owner);\n }\n findClosestCell(unit, cells) {\n let closest = cells[0];\n if (closest) {\n let distance = Infinity;\n for (let cell of cells){\n const cellDistance = cell.pos.squareDistance(unit.cell?.pos ?? $2c23f148d58cd887$export$202e0172ed3c7be0(0, 0));\n if (cellDistance < distance) {\n closest = cell;\n distance = cellDistance;\n }\n }\n return closest;\n }\n return null;\n }\n findAttackableTargets(unit) {\n this.selectionManger.selectUnit(unit, \"attack\");\n const attackRange = this.selectionManger.findAttackRange(unit);\n return attackRange.filter((node)=>{\n if (node.owner) {\n const cell = node.owner;\n if (cell.unit) return cell.unit.player !== this;\n }\n return false;\n }).map((node)=>node.owner);\n }\n async maybeAttack(unit, closestEnemy) {\n let attacked = false;\n // possible targets\n const possibleTargets = this.findAttackableTargets(unit);\n if (possibleTargets.length > 0) {\n const currentRange = possibleTargets.map((c)=>c.pathNode);\n this.selectionManger.showHighlight(currentRange, \"attack\");\n await $2c23f148d58cd887$export$f8f26dd395d7e1bd.delay((0, $9d936a2aecb96285$export$2811b6d4a003bf2e));\n this.selectionManger.showHighlight([\n closestEnemy.cell.pathNode\n ], \"path\");\n await $2c23f148d58cd887$export$f8f26dd395d7e1bd.delay((0, $9d936a2aecb96285$export$2811b6d4a003bf2e));\n // attack\n await unit.attack(closestEnemy);\n attacked = true;\n }\n return attacked;\n }\n async makeMove() {\n const enemyUnits = this.board.getUnits().filter((u)=>u.player !== this);\n const units = this.board.getUnits().filter((u)=>u.player === this);\n for (let unit of units){\n // wait before moving each unit\n await $2c23f148d58cd887$export$f8f26dd395d7e1bd.delay((0, $9d936a2aecb96285$export$2811b6d4a003bf2e));\n let range = [];\n if (unit.cell) range = this.board.pathFinder.getRange(unit.cell.pathNode, this.mask, unit.unitConfig.movement);\n // find valid moves\n let validCells = this.findValidMoveCells(unit);\n // find the closest enemy\n const closestEnemy = this.findClosestEnemy(unit);\n if (closestEnemy) {\n // attack if right next to enemy\n const attacked = await this.maybeAttack(unit, closestEnemy);\n // find the closest valid move to an enemy\n const closestCell = this.findClosestCell(closestEnemy, validCells);\n // move if did not attack\n if (!attacked) {\n this.selectionManger.selectUnit(unit, \"move\");\n await $2c23f148d58cd887$export$f8f26dd395d7e1bd.delay((0, $9d936a2aecb96285$export$2811b6d4a003bf2e));\n const currentPath = this.selectionManger.findPath(closestCell, range);\n this.selectionManger.showHighlight(currentPath, \"path\");\n await $2c23f148d58cd887$export$f8f26dd395d7e1bd.delay((0, $9d936a2aecb96285$export$2811b6d4a003bf2e));\n await this.selectionManger.selectDestinationAndMove(unit, closestCell);\n await $2c23f148d58cd887$export$f8f26dd395d7e1bd.delay((0, $9d936a2aecb96285$export$2811b6d4a003bf2e));\n // try again to attack\n await this.maybeAttack(unit, closestEnemy);\n }\n this.selectionManger.reset();\n }\n }\n return true;\n }\n lose() {\n this.active = false;\n const computerUnits = this.board.getUnits().filter((u)=>u.player instanceof $5bb1f3979eaf16cf$export$9e9f75da6ccd8cee);\n computerUnits.forEach((u)=>{\n u.health = 0;\n u.cell?.removeUnit(u);\n });\n }\n}\n\n\n\nclass $ea9d612b63edc7d8$export$a4f31f7df8777f2a {\n constructor(engine, level, players, selectionManager, maxTurns){\n this.engine = engine;\n this.level = level;\n this.players = players;\n this.maxTurns = maxTurns;\n this.currentTurn = 1;\n this.currentPlayerIndex = 0;\n this.topScreen = $2c23f148d58cd887$export$202e0172ed3c7be0(400, -2000);\n this.centerScreen = $2c23f148d58cd887$export$202e0172ed3c7be0(400, 400);\n this.bottomScreen = $2c23f148d58cd887$export$202e0172ed3c7be0(400, 2000);\n if (players.length === 0) throw Error(\"Players should be non-zero in length\");\n this.currentPlayer = players[this.currentPlayerIndex];\n this.selectionManager = selectionManager;\n this.turnText = new $2c23f148d58cd887$export$5f1af8db9871e1d6({\n text: `Turn ${this.currentTurn}`,\n font: new $2c23f148d58cd887$export$89abf52a030e56ee({\n family: \"notjamslab14\",\n size: 32 * (0, $9d936a2aecb96285$export$fae5d17304677194).x,\n unit: $2c23f148d58cd887$export$6976e674e6d5804c.Px,\n color: $2c23f148d58cd887$export$892596cec99bc70e.White,\n baseAlign: $2c23f148d58cd887$export$83c931ba0d3bbaf5.Top,\n quality: 4\n })\n });\n const screenWidth = engine.screen.resolution.width;\n this.turnActor = new $2c23f148d58cd887$export$f73d3eb6fd876d80({\n name: \"turn text\",\n pos: this.topScreen,\n coordPlane: $2c23f148d58cd887$export$71efaa2be447940c.Screen,\n color: new $2c23f148d58cd887$export$892596cec99bc70e(240, 50, 50, .4),\n width: screenWidth,\n height: 100,\n z: 10\n });\n this.turnActor.graphics.opacity = 0;\n this.turnActor.graphics.add(\"text\", this.turnText);\n this.turnActor.graphics.show(\"text\");\n engine.add(this.turnActor);\n const victory = new $2c23f148d58cd887$export$5f1af8db9871e1d6({\n text: `Victory!`,\n font: new $2c23f148d58cd887$export$89abf52a030e56ee({\n family: \"notjamslab14\",\n size: 32 * (0, $9d936a2aecb96285$export$fae5d17304677194).x,\n unit: $2c23f148d58cd887$export$6976e674e6d5804c.Px,\n color: $2c23f148d58cd887$export$892596cec99bc70e.White,\n baseAlign: $2c23f148d58cd887$export$83c931ba0d3bbaf5.Top,\n quality: 4\n })\n });\n this.victory = new $2c23f148d58cd887$export$f73d3eb6fd876d80({\n name: \"victory text\",\n pos: this.topScreen,\n coordPlane: $2c23f148d58cd887$export$71efaa2be447940c.Screen,\n color: new $2c23f148d58cd887$export$892596cec99bc70e(50, 240, 50, .4),\n width: screenWidth,\n height: 100,\n z: 10\n });\n this.victory.graphics.opacity = 0;\n this.victory.graphics.add(\"text\", victory);\n this.victory.graphics.show(\"text\");\n engine.add(this.victory);\n const failureText1 = new $2c23f148d58cd887$export$5f1af8db9871e1d6({\n text: `Failure!`,\n font: new $2c23f148d58cd887$export$89abf52a030e56ee({\n family: \"notjamslab14\",\n size: 32 * (0, $9d936a2aecb96285$export$fae5d17304677194).x,\n unit: $2c23f148d58cd887$export$6976e674e6d5804c.Px,\n color: $2c23f148d58cd887$export$892596cec99bc70e.White,\n baseAlign: $2c23f148d58cd887$export$83c931ba0d3bbaf5.Top,\n quality: 4\n })\n });\n const failureText2 = new $2c23f148d58cd887$export$5f1af8db9871e1d6({\n text: `Click to try again!`,\n font: new $2c23f148d58cd887$export$89abf52a030e56ee({\n family: \"notjamslab14\",\n size: 32 * (0, $9d936a2aecb96285$export$fae5d17304677194).x,\n unit: $2c23f148d58cd887$export$6976e674e6d5804c.Px,\n color: $2c23f148d58cd887$export$892596cec99bc70e.White,\n baseAlign: $2c23f148d58cd887$export$83c931ba0d3bbaf5.Top,\n quality: 4\n })\n });\n this.failure = new $2c23f148d58cd887$export$f73d3eb6fd876d80({\n name: \"failure text\",\n pos: this.topScreen,\n coordPlane: $2c23f148d58cd887$export$71efaa2be447940c.Screen,\n color: new $2c23f148d58cd887$export$892596cec99bc70e(240, 50, 50, .4),\n width: screenWidth,\n height: 250,\n z: 10\n });\n this.failure.graphics.opacity = 0;\n this.failure.graphics.add(\"text1\", failureText1);\n this.failure.graphics.add(\"text2\", failureText2);\n this.failure.graphics.show(\"text1\", {\n offset: $2c23f148d58cd887$export$202e0172ed3c7be0(0, -50)\n });\n this.failure.graphics.show(\"text2\", {\n offset: $2c23f148d58cd887$export$202e0172ed3c7be0(0, 50)\n });\n engine.add(this.failure);\n }\n async showTurnDisplay() {\n if (this.currentPlayerIndex !== 0) return;\n this.turnText.text = `Turn ${this.currentTurn}`;\n const transitionTime = 1200;\n const waitTime = 700;\n await this.turnActor.actions.runAction(new $2c23f148d58cd887$export$ed6a63ee685a4d78([\n new $2c23f148d58cd887$export$89f31cec7c284d42(this.turnActor, (ctx)=>ctx.easeTo(this.centerScreen, transitionTime, $2c23f148d58cd887$export$6ff391a2049fdf40.EaseInOutCubic).delay(waitTime).easeTo(this.bottomScreen, transitionTime, $2c23f148d58cd887$export$6ff391a2049fdf40.EaseInOutCubic)),\n new $2c23f148d58cd887$export$89f31cec7c284d42(this.turnActor, (ctx)=>ctx.fade(1, transitionTime).delay(waitTime).fade(0, transitionTime))\n ])).toPromise();\n this.turnActor.pos = this.topScreen;\n }\n async showGameOver() {\n const transitionTime = 1200;\n await this.failure.actions.runAction(new $2c23f148d58cd887$export$ed6a63ee685a4d78([\n new $2c23f148d58cd887$export$89f31cec7c284d42(this.failure, (ctx)=>ctx.easeTo(this.centerScreen, transitionTime, $2c23f148d58cd887$export$6ff391a2049fdf40.EaseInOutCubic)),\n new $2c23f148d58cd887$export$89f31cec7c284d42(this.failure, (ctx)=>ctx.fade(1, transitionTime))\n ])).toPromise();\n }\n async showVictory() {\n const transitionTime = 1200;\n await this.victory.actions.runAction(new $2c23f148d58cd887$export$ed6a63ee685a4d78([\n new $2c23f148d58cd887$export$89f31cec7c284d42(this.victory, (ctx)=>ctx.easeTo(this.centerScreen, transitionTime, $2c23f148d58cd887$export$6ff391a2049fdf40.EaseInOutCubic)),\n new $2c23f148d58cd887$export$89f31cec7c284d42(this.victory, (ctx)=>ctx.fade(1, transitionTime))\n ])).toPromise();\n }\n async start() {\n // TODO win condition\n while(this.maxTurns > 0){\n console.log(\"Current player turn:\", this.currentPlayer.name);\n if (this.currentPlayer.hasLost()) {\n console.log(\"Player lost!\", this.currentPlayer.name);\n if (this.currentPlayer instanceof (0, $8f27ec21febf6fa6$export$b4ba4c460e535077)) {\n await this.showGameOver();\n this.engine.input.pointers.once(\"down\", ()=>{\n (0, $7c4c300842bd4cf2$export$e9a269813a6315a4).LevelMusic2.stop();\n this.engine.goToScene(this.level.levelData.name);\n });\n return;\n }\n if (this.currentPlayer instanceof (0, $5bb1f3979eaf16cf$export$9e9f75da6ccd8cee)) {\n await this.showVictory();\n this.engine.input.pointers.once(\"down\", ()=>{\n this.engine.goToScene(this.level.levelData.nextLevel);\n });\n return;\n }\n }\n this.selectionManager.selectPlayer(this.currentPlayer);\n this.showTurnDisplay();\n await this.currentPlayer.turnStart();\n let move = true;\n do move = await this.currentPlayer.makeMove();\n while (!move);\n await this.currentPlayer.turnEnd();\n this.nextTurn();\n this.maxTurns--;\n }\n }\n nextTurn() {\n this.currentPlayerIndex++;\n this.currentPlayerIndex = this.currentPlayerIndex % this.players.length;\n this.currentPlayer = this.players[this.currentPlayerIndex];\n if (this.currentPlayerIndex === 0) this.currentTurn++;\n }\n}\n\n\n\n\n\n\nclass $49cd3ddcf46f2e40$export$e2767e27b246eae1 extends $2c23f148d58cd887$export$f73d3eb6fd876d80 {\n constructor(pos){\n super({\n name: \"cloud\",\n pos: pos,\n vel: $2c23f148d58cd887$export$202e0172ed3c7be0($2c23f148d58cd887$export$8b958c8ecd94a804(-30, -100), 0),\n width: 100,\n height: 100\n });\n }\n onInitialize(_engine) {\n this.cloudSprite = (0, $7c4c300842bd4cf2$export$e9a269813a6315a4).CloudSheet.toSprite();\n this.cloudSprite.scale = (0, $9d936a2aecb96285$export$fae5d17304677194);\n this.graphics.use(this.cloudSprite);\n }\n onPostUpdate(engine, _delta) {\n if (this.pos.x + this.cloudSprite.width < 0) this.pos.x = engine.screen.contentArea.right + this.cloudSprite.width;\n }\n}\n\n\n\n\nclass $20d8c361c0c6eb68$export$91f8da61a0e8158c extends $2c23f148d58cd887$export$38af1803e3442a7f {\n constructor(levelData, name){\n super();\n this.levelData = levelData;\n this.name = name;\n }\n onInitialize(engine) {\n this.engine = engine;\n }\n resetAndLoad() {\n const entities = this.entities;\n for(let i = entities.length - 1; i >= 0; i--)this.world.remove(entities[i], false);\n (0, $7c4c300842bd4cf2$export$e9a269813a6315a4).LevelMusic2.stop();\n this.add(new (0, $49cd3ddcf46f2e40$export$e2767e27b246eae1)($2c23f148d58cd887$export$202e0172ed3c7be0(800, 0)));\n this.add(new (0, $49cd3ddcf46f2e40$export$e2767e27b246eae1)($2c23f148d58cd887$export$202e0172ed3c7be0(400, 300)));\n this.add(new (0, $49cd3ddcf46f2e40$export$e2767e27b246eae1)($2c23f148d58cd887$export$202e0172ed3c7be0(700, 700)));\n this.board = this.parse(this.levelData);\n this.add((0, $715aef12944b79e3$export$4e2634e353696b95));\n this.camera.pos = this.board.getCenter();\n }\n onActivate() {\n this.resetAndLoad();\n this.turnManager.start();\n (0, $7c4c300842bd4cf2$export$e9a269813a6315a4).LevelMusic2.loop = true;\n (0, $7c4c300842bd4cf2$export$e9a269813a6315a4).LevelMusic2.play();\n this.engine.input.keyboard.on(\"press\", (evt)=>{\n // DELETEME for debugging\n if (evt.key === $2c23f148d58cd887$export$4b0075e5ea5e1f26.W) this.players[1].lose();\n if (evt.key === $2c23f148d58cd887$export$4b0075e5ea5e1f26.L) this.players[0].lose();\n });\n }\n onDeactivate() {\n // TODO deactivate event handlers on types that have them!!\n (0, $7c4c300842bd4cf2$export$e9a269813a6315a4).LevelMusic2.instances.forEach((i)=>i.stop());\n (0, $7c4c300842bd4cf2$export$e9a269813a6315a4).LevelMusic2.stop();\n }\n parse(levelData) {\n const board = new (0, $b2ebc7535321c5c8$export$dc537a3a3893548e)(levelData.height, levelData.width, this);\n this.selectionManager = new (0, $56541b8f9a5aaec4$export$6c8a5aaad13c9852)(board);\n this.selectionManager.showCursor(0, 0);\n this.uiManager = new (0, $08d6772c516efcf0$export$2524c4960ed9dff2)(this.engine);\n // TODO support arbitrary players\n this.players = [\n new (0, $8f27ec21febf6fa6$export$b4ba4c460e535077)(levelData.players[0], this.engine, this.selectionManager, this.uiManager, board),\n new (0, $5bb1f3979eaf16cf$export$9e9f75da6ccd8cee)(levelData.players[1], this.selectionManager, board)\n ];\n this.turnManager = new (0, $ea9d612b63edc7d8$export$a4f31f7df8777f2a)(this.engine, this, this.players, this.selectionManager, 10);\n for(let y = 0; y < levelData.height; y++)for(let x = 0; x < levelData.width; x++){\n const data = levelData.data[x + y * levelData.width];\n const terrain = data.charAt(0);\n let unit = null;\n if (data.length === 3) {\n const unitType = data.charAt(1) === \"K\" ? \"Knight\" : \"Spider\";\n const playerIndex = +data.charAt(2) - 1;\n unit = new (0, $6baa46b5146e0ebc$export$1d8b9ae22d404866)(x, y, unitType, board, this.players[playerIndex]);\n this.add(unit);\n }\n const cell = board.getCell(x, y);\n if (cell) {\n cell.terrain = terrain;\n if (unit) cell.addUnit(unit);\n }\n }\n return board;\n }\n}\n\n\n\n\n\n\nclass $59eb2793a39f1e42$export$a1909b6cc88e74a extends $2c23f148d58cd887$export$38af1803e3442a7f {\n onInitialize(engine) {\n this.engine = engine;\n this.add(new (0, $49cd3ddcf46f2e40$export$e2767e27b246eae1)($2c23f148d58cd887$export$202e0172ed3c7be0(800, 0)));\n this.add(new (0, $49cd3ddcf46f2e40$export$e2767e27b246eae1)($2c23f148d58cd887$export$202e0172ed3c7be0(400, 300)));\n this.add(new (0, $49cd3ddcf46f2e40$export$e2767e27b246eae1)($2c23f148d58cd887$export$202e0172ed3c7be0(700, 700)));\n this.title = new $2c23f148d58cd887$export$f73d3eb6fd876d80({\n name: \"title\",\n pos: $2c23f148d58cd887$export$202e0172ed3c7be0(400, 400),\n coordPlane: $2c23f148d58cd887$export$71efaa2be447940c.Screen\n });\n this.title.scale = (0, $9d936a2aecb96285$export$fae5d17304677194);\n this.title.graphics.use((0, $7c4c300842bd4cf2$export$f99233281efd08a0));\n this.title.actions.repeatForever((ctx)=>{\n ctx.easeBy($2c23f148d58cd887$export$202e0172ed3c7be0(0, -30 * (0, $9d936a2aecb96285$export$fae5d17304677194).y), 1000, $2c23f148d58cd887$export$6ff391a2049fdf40.EaseInOutQuad).easeBy($2c23f148d58cd887$export$202e0172ed3c7be0(0, 30 * (0, $9d936a2aecb96285$export$fae5d17304677194).y), 1000, $2c23f148d58cd887$export$6ff391a2049fdf40.EaseInOutQuad);\n });\n this.add(this.title);\n this.instructions = new $2c23f148d58cd887$export$f73d3eb6fd876d80({\n name: \"instructions\",\n pos: $2c23f148d58cd887$export$202e0172ed3c7be0(400, 600),\n coordPlane: $2c23f148d58cd887$export$71efaa2be447940c.Screen\n });\n const font = new $2c23f148d58cd887$export$89abf52a030e56ee({\n family: \"notjamslab14\",\n size: 32 * (0, $9d936a2aecb96285$export$fae5d17304677194).x,\n unit: $2c23f148d58cd887$export$6976e674e6d5804c.Px,\n color: $2c23f148d58cd887$export$892596cec99bc70e.White,\n baseAlign: $2c23f148d58cd887$export$83c931ba0d3bbaf5.Top,\n quality: 4,\n shadow: {\n offset: $2c23f148d58cd887$export$202e0172ed3c7be0(10, 10).scale((0, $9d936a2aecb96285$export$fae5d17304677194)),\n color: $2c23f148d58cd887$export$892596cec99bc70e.Black\n }\n });\n const text = new $2c23f148d58cd887$export$5f1af8db9871e1d6({\n text: \"Click to Play!\",\n font: font\n });\n this.instructions.graphics.use(text);\n this.instructions.actions.repeatForever((ctx)=>{\n ctx.rotateTo(Math.PI / 32, .2);\n ctx.rotateTo(-Math.PI / 32, .2);\n });\n this.add(this.instructions);\n }\n onActivate() {\n (0, $7c4c300842bd4cf2$export$e9a269813a6315a4).TitleMusic.loop = true;\n (0, $7c4c300842bd4cf2$export$e9a269813a6315a4).TitleMusic.play();\n this.engine.input.pointers.primary.once(\"down\", ()=>{\n this.engine.goToScene(\"tutorial\");\n });\n this.engine.input.keyboard.once(\"press\", ()=>{\n this.engine.goToScene(\"tutorial\");\n });\n }\n onDeactivate() {\n (0, $7c4c300842bd4cf2$export$e9a269813a6315a4).TitleMusic.stop();\n }\n}\n\n\n\n\n\n\nconst $e554be45dd7d77e1$export$cbd80808721120f2 = {\n name: \"tutorial\",\n displayName: \"Gentle Plains\",\n nextLevel: \"level\",\n width: 6,\n height: 3,\n maxTurns: 10,\n players: [\n \"human\",\n \"computer\"\n ],\n data: [\n \"GK1\",\n \"G\",\n \"G\",\n \"GS2\",\n \"G\",\n \"GS2\",\n \"GK1\",\n \"G\",\n \"GS2\",\n \"G\",\n \"G\",\n \"GS2\",\n \"G\",\n \"G\",\n \"W\",\n \"W\",\n \"G\",\n \"G\"\n ]\n};\nclass $e554be45dd7d77e1$export$825b76de5f2b0345 extends (0, $20d8c361c0c6eb68$export$91f8da61a0e8158c) {\n constructor(){\n super($e554be45dd7d77e1$export$cbd80808721120f2, \"tutorial\");\n }\n onInitialize(engine) {\n super.onInitialize(engine);\n this.resetAndLoad();\n const unit = this.board.cells[0].unit;\n if (unit) {\n this.focus = new $2c23f148d58cd887$export$f73d3eb6fd876d80({\n name: \"focus\",\n pos: unit.pos.add($2c23f148d58cd887$export$202e0172ed3c7be0(16, 16).scale((0, $9d936a2aecb96285$export$fae5d17304677194))),\n width: 32,\n height: 32,\n anchor: $2c23f148d58cd887$export$202e0172ed3c7be0(0, 1),\n z: 10\n });\n this.focus.graphics.opacity = 0;\n this.engine.add(this.focus);\n }\n }\n async moveToUnit1() {\n const pos = this.board.getCell(0, 0).unit.pos.add($2c23f148d58cd887$export$202e0172ed3c7be0(16, 16).scale((0, $9d936a2aecb96285$export$fae5d17304677194)));\n await this.focus.actions.easeTo(pos, 1000, $2c23f148d58cd887$export$6ff391a2049fdf40.EaseInOutCubic).toPromise();\n }\n async selectUnit1() {\n this.selectionManager.selectPlayer(this.players[0]);\n const unit1 = this.board.getCell(0, 0).unit;\n const menu = this.uiManager.showUnitMenu(unit1, {\n move: ()=>{},\n attack: ()=>{},\n pass: ()=>{}\n });\n await $2c23f148d58cd887$export$f8f26dd395d7e1bd.delay(1000);\n menu.hide();\n this.selectionManager.selectUnit(unit1, \"move\");\n const currentRange = this.selectionManager.findMovementRange(unit1);\n const cell = this.board.getCell(2, 0);\n const currentPath = this.selectionManager.findPath(cell, currentRange);\n this.selectionManager.showHighlight(currentPath, \"path\");\n await $2c23f148d58cd887$export$f8f26dd395d7e1bd.delay(1000);\n await this.selectionManager.selectDestinationAndMove(unit1, cell);\n menu.show();\n await $2c23f148d58cd887$export$f8f26dd395d7e1bd.delay(2000);\n this.selectionManager.selectUnit(unit1, \"attack\");\n const currentAttackRange = this.selectionManager.findAttackRange(unit1);\n this.selectionManager.showHighlight(currentAttackRange, \"attack\");\n await $2c23f148d58cd887$export$f8f26dd395d7e1bd.delay(1000);\n const attackCell = this.board.getCell(2, 1);\n this.selectionManager.showHighlight([\n attackCell.pathNode\n ], \"path\");\n menu.hide();\n this.selectionManager.reset();\n const enemy = this.board.getCell(2, 1).unit;\n unit1.attack(enemy);\n await $2c23f148d58cd887$export$f8f26dd395d7e1bd.delay(2000);\n }\n async highlightEnemyRange() {\n const humanPlayer = this.players[0];\n const enemyCell = this.board.getCell(2, 1);\n await humanPlayer.highlightUnitRange(enemyCell);\n await $2c23f148d58cd887$export$f8f26dd395d7e1bd.delay(1000);\n this.selectionManager.reset();\n }\n async moveToUnit2() {\n const pos = this.board.getCell(0, 1).unit.pos.add($2c23f148d58cd887$export$202e0172ed3c7be0(16, 16).scale((0, $9d936a2aecb96285$export$fae5d17304677194)));\n await this.focus.actions.easeTo(pos, 1000, $2c23f148d58cd887$export$6ff391a2049fdf40.EaseInOutCubic).toPromise();\n }\n async showText(index) {\n const text = (0, $7c4c300842bd4cf2$export$a3c7706a72a05aed).getSprite(index, 0);\n text.scale = (0, $9d936a2aecb96285$export$fae5d17304677194);\n this.focus.graphics.use(text);\n await this.focus.actions.fade(1, 200).toPromise();\n }\n async hideText() {\n await this.focus.actions.fade(0, 200).toPromise();\n }\n async onActivate() {\n this.engine.input.keyboard.once(\"press\", (evt)=>{\n if (evt.key === $2c23f148d58cd887$export$4b0075e5ea5e1f26.Esc) this.engine.goToScene(\"level1\");\n });\n (0, $7c4c300842bd4cf2$export$e9a269813a6315a4).LevelMusic2.loop = true;\n (0, $7c4c300842bd4cf2$export$e9a269813a6315a4).LevelMusic2.play();\n this.camera.strategy.lockToActor(this.focus);\n this.camera.zoomOverTime(1.25, 1000, $2c23f148d58cd887$export$6ff391a2049fdf40.EaseInOutCubic);\n this.selectionManager.showCursor(0, 0);\n await $2c23f148d58cd887$export$f8f26dd395d7e1bd.delay(1000);\n // hey look at all these spiders!\n await this.showText(1);\n await this.focus.actions.delay(1000);\n await this.hideText();\n // we need to take them out to get home!\n await this.moveToUnit2();\n await this.showText(2);\n await this.focus.actions.delay(1000);\n await this.hideText();\n // how do we do that?!?\n await this.moveToUnit1();\n await this.showText(3);\n await this.focus.actions.delay(1000);\n await this.hideText();\n // left click to move/attack, right click to see friendly/enemy range\n await this.moveToUnit2();\n await this.showText(4);\n await this.focus.actions.delay(4000);\n await this.hideText();\n await this.selectUnit1();\n // we have a limited amount of turns to complete the level!\n await this.moveToUnit2();\n await this.showText(5);\n await this.focus.actions.delay(1000);\n await this.hideText();\n await this.highlightEnemyRange();\n await this.showText(6);\n await this.focus.actions.delay(2000);\n await this.hideText();\n await this.showText(7);\n await this.focus.actions.delay(7000);\n await this.hideText();\n this.camera.zoomOverTime(1, 1000, $2c23f148d58cd887$export$6ff391a2049fdf40.EaseInOutCubic);\n this.engine.goToScene(\"level1\");\n }\n onDeactivate() {\n (0, $7c4c300842bd4cf2$export$e9a269813a6315a4).LevelMusic2.stop();\n }\n}\n\n\n\n\n\n\n\nclass $c8edba33324a483c$export$557a8016f4e0c1ba {\n static #_ = this.levels = new Map([\n [\n (0, $7c4c300842bd4cf2$export$e9a269813a6315a4).HitSound,\n 1.0\n ],\n [\n (0, $7c4c300842bd4cf2$export$e9a269813a6315a4).MoveSound,\n 1.0\n ],\n [\n (0, $7c4c300842bd4cf2$export$e9a269813a6315a4).SelectSound,\n 1.0\n ],\n [\n (0, $7c4c300842bd4cf2$export$e9a269813a6315a4).TargetSelectSound,\n 1.0\n ],\n [\n (0, $7c4c300842bd4cf2$export$e9a269813a6315a4).LevelMusic1,\n .05\n ],\n [\n (0, $7c4c300842bd4cf2$export$e9a269813a6315a4).LevelMusic2,\n .05\n ],\n [\n (0, $7c4c300842bd4cf2$export$e9a269813a6315a4).ExplosionSound,\n 1.0\n ],\n [\n (0, $7c4c300842bd4cf2$export$e9a269813a6315a4).TitleMusic,\n .05\n ]\n ]);\n static init() {\n for (let resource of Object.values((0, $7c4c300842bd4cf2$export$e9a269813a6315a4)))if (resource instanceof $2c23f148d58cd887$export$85990f0f98a390bb) resource.volume = $c8edba33324a483c$export$557a8016f4e0c1ba.levels.get(resource) ?? 1.0;\n }\n static toggleMute(shouldMute) {\n for (let resource of Object.values((0, $7c4c300842bd4cf2$export$e9a269813a6315a4)))if (resource instanceof $2c23f148d58cd887$export$85990f0f98a390bb) resource.volume = shouldMute ? 0 : $c8edba33324a483c$export$557a8016f4e0c1ba.levels.get(resource) ?? 1.0;\n }\n}\n\n\nlet $2208178db6097809$export$6fc3d951b68e69bd = class AudioMenu extends (0, $fe586ba0757c37f7$export$3f2f9f5909897157) {\n static #_ = this.styles = (0, $3233927aa82734f9$export$dbf350e5966cf602)`\n :host {\n position: absolute;\n left: 0;\n bottom: 0;\n margin: 16px;\n }\n button {\n all: unset;\n cursor: pointer;\n color: white;\n font-size: 32px;\n }\n .material-symbols-outlined {\n font-family: 'Material Symbols Outlined';\n font-weight: normal;\n font-style: normal;\n font-size: 24px;\n line-height: 1;\n letter-spacing: normal;\n text-transform: none;\n display: inline-block;\n white-space: nowrap;\n word-wrap: normal;\n direction: ltr;\n -moz-font-feature-settings: 'liga';\n -moz-osx-font-smoothing: grayscale;\n }\n `;\n toggleSound() {\n this.soundOn = !this.soundOn;\n (0, $c8edba33324a483c$export$557a8016f4e0c1ba).toggleMute(!this.soundOn);\n }\n render() {\n // material symbols\n // https://fonts.google.com/icons?selected=Material+Symbols+Outlined:volume_off:FILL@0;wght@400;GRAD@0;opsz@24&icon.query=speaker\n return this.soundOn ? (0, $e5ed8027d647799b$export$c0bb0b647f701bb5)`` : (0, $e5ed8027d647799b$export$c0bb0b647f701bb5)``;\n }\n constructor(...args){\n super(...args);\n this.soundOn = true;\n }\n};\n(0, $5c96a02c592fcff1$export$29e00dfd3077644b)([\n (0, $b2fdcbe153c88f81$export$d541bacb2bda4494)()\n], $2208178db6097809$export$6fc3d951b68e69bd.prototype, \"soundOn\", void 0);\n$2208178db6097809$export$6fc3d951b68e69bd = (0, $5c96a02c592fcff1$export$29e00dfd3077644b)([\n (0, $07706bf0c990b886$export$da64fc29f17f9d0e)(\"audio-menu\")\n], $2208178db6097809$export$6fc3d951b68e69bd);\n\n\n\nconst $ad2bcec7a0192558$var$game = new $2c23f148d58cd887$export$2c3b404bf3a77a1f({\n width: 800,\n height: 800,\n displayMode: $2c23f148d58cd887$export$4b7264771109adb6.FitScreenAndFill,\n antialiasing: false,\n suppressHiDPIScaling: true,\n configurePerformanceCanvas2DFallback: {\n allow: false\n }\n});\n(0, $c8edba33324a483c$export$557a8016f4e0c1ba).init();\nconst $ad2bcec7a0192558$var$startScreen = new (0, $59eb2793a39f1e42$export$a1909b6cc88e74a)();\n$ad2bcec7a0192558$var$game.addScene(\"start\", $ad2bcec7a0192558$var$startScreen);\nconst $ad2bcec7a0192558$var$tutorial = new (0, $e554be45dd7d77e1$export$825b76de5f2b0345)();\n$ad2bcec7a0192558$var$game.addScene($ad2bcec7a0192558$var$tutorial.name, $ad2bcec7a0192558$var$tutorial);\nconst $ad2bcec7a0192558$var$Level1Data = {\n displayName: \"Gentle Plains\",\n name: \"level1\",\n nextLevel: \"level2\",\n width: 6,\n height: 3,\n maxTurns: 10,\n players: [\n \"human\",\n \"computer\"\n ],\n data: [\n \"GK1\",\n \"G\",\n \"G\",\n \"GS2\",\n \"G\",\n \"GS2\",\n \"GK1\",\n \"G\",\n \"GS2\",\n \"G\",\n \"G\",\n \"GS2\",\n \"G\",\n \"G\",\n \"W\",\n \"W\",\n \"G\",\n \"G\"\n ]\n};\nconst $ad2bcec7a0192558$var$level1 = new (0, $20d8c361c0c6eb68$export$91f8da61a0e8158c)($ad2bcec7a0192558$var$Level1Data, \"level1\");\n$ad2bcec7a0192558$var$game.addScene($ad2bcec7a0192558$var$level1.name, $ad2bcec7a0192558$var$level1);\nconst $ad2bcec7a0192558$export$9cdd43c553b4a90f = {\n displayName: \"Gentle Plains 2\",\n name: \"level2\",\n nextLevel: \"start\",\n width: 6,\n height: 6,\n maxTurns: 100,\n players: [\n \"human\",\n \"computer\"\n ],\n data: [\n \"GK1\",\n \"G\",\n \"GS2\",\n \"G\",\n \"G\",\n \"GS2\",\n \"GK1\",\n \"G\",\n \"G\",\n \"G\",\n \"G\",\n \"GS2\",\n \"GK1\",\n \"G\",\n \"W\",\n \"W\",\n \"G\",\n \"G\",\n \"G\",\n \"G\",\n \"W\",\n \"W\",\n \"G\",\n \"G\",\n \"G\",\n \"G\",\n \"W\",\n \"W\",\n \"G\",\n \"G\",\n \"G\",\n \"GS2\",\n \"W\",\n \"W\",\n \"GS2\",\n \"GS2\"\n ]\n};\nconst $ad2bcec7a0192558$var$level2 = new (0, $20d8c361c0c6eb68$export$91f8da61a0e8158c)($ad2bcec7a0192558$export$9cdd43c553b4a90f, \"level2\");\n$ad2bcec7a0192558$var$game.addScene($ad2bcec7a0192558$var$level2.name, $ad2bcec7a0192558$var$level2);\n$ad2bcec7a0192558$var$game.start((0, $7c4c300842bd4cf2$export$f4c5de44377d2946)).then(()=>{\n $ad2bcec7a0192558$var$game.goToScene(\"start\");\n});\n\n\n//# sourceMappingURL=index.d796f22d.js.map\n","import * as ex from 'excalibur';\nimport { loader } from './resources';\nimport { LevelBase, LevelData } from './levels/level-base';\nimport { StartScreen } from './levels/start-screen';\nimport { Tutorial } from './levels/tutorial';\nimport './ui-components/audio-menu';\nimport { AudioManager } from './audio-manager';\n\nconst game = new ex.Engine({\n width: 800,\n height: 800,\n displayMode: ex.DisplayMode.FitScreenAndFill,\n antialiasing: false,\n suppressHiDPIScaling: true,\n configurePerformanceCanvas2DFallback: {\n allow: false\n }\n});\n\nAudioManager.init();\n\nconst startScreen = new StartScreen();\ngame.addScene('start', startScreen);\n\nconst tutorial = new Tutorial();\ngame.addScene(tutorial.name, tutorial);\n\n\nconst Level1Data: LevelData = {\n displayName: 'Gentle Plains',\n name: 'level1',\n nextLevel: 'level2',\n width: 6,\n height: 3,\n maxTurns: 10,\n players: ['human', 'computer'],\n data: [\n 'GK1', 'G', 'G', 'GS2', 'G', 'GS2',\n 'GK1', 'G', 'GS2', 'G', 'G', 'GS2',\n 'G', 'G', 'W', 'W', 'G', 'G',\n ]\n}\n\nconst level1 = new LevelBase(Level1Data, 'level1')\ngame.addScene(level1.name, level1);\n\nexport const Level2Data: LevelData = {\n displayName: 'Gentle Plains 2',\n name: 'level2',\n nextLevel: 'start',\n width: 6,\n height: 6,\n maxTurns: 100,\n players: ['human', 'computer'],\n data: [\n 'GK1', 'G', 'GS2', 'G', 'G', 'GS2',\n 'GK1', 'G', 'G', 'G', 'G', 'GS2',\n 'GK1', 'G', 'W', 'W', 'G', 'G',\n 'G', 'G', 'W', 'W', 'G', 'G',\n 'G', 'G', 'W', 'W', 'G', 'G',\n 'G', 'GS2', 'W', 'W', 'GS2', 'GS2',\n ]\n}\n\nconst level2 = new LevelBase(Level2Data, 'level2')\ngame.addScene(level2.name, level2);\n\ngame.start(loader).then(() => {\n game.goToScene('start');\n});","/*!\n * excalibur - 0.28.0 - 2023-8-10\n * https://github.com/excaliburjs/Excalibur\n * Copyright (c) 2023 Excalibur.js \n * Licensed BSD-2-Clause\n * @preserve\n */\n/******/ var __webpack_modules__ = ({\n\n/***/ 4662:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\n__webpack_require__(3430);\nvar entryUnbind = __webpack_require__(8791);\n\nmodule.exports = entryUnbind('Array', 'sort');\n\n\n/***/ }),\n\n/***/ 8343:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\n__webpack_require__(4769);\nvar path = __webpack_require__(9276);\n\nmodule.exports = path.Object.keys;\n\n\n/***/ }),\n\n/***/ 7111:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar isCallable = __webpack_require__(6733);\nvar tryToString = __webpack_require__(9821);\n\nvar $TypeError = TypeError;\n\n// `Assert: IsCallable(argument) is true`\nmodule.exports = function (argument) {\n if (isCallable(argument)) return argument;\n throw $TypeError(tryToString(argument) + ' is not a function');\n};\n\n\n/***/ }),\n\n/***/ 1176:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar isObject = __webpack_require__(5052);\n\nvar $String = String;\nvar $TypeError = TypeError;\n\n// `Assert: Type(argument) is Object`\nmodule.exports = function (argument) {\n if (isObject(argument)) return argument;\n throw $TypeError($String(argument) + ' is not an object');\n};\n\n\n/***/ }),\n\n/***/ 9540:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar toIndexedObject = __webpack_require__(905);\nvar toAbsoluteIndex = __webpack_require__(3231);\nvar lengthOfArrayLike = __webpack_require__(9646);\n\n// `Array.prototype.{ indexOf, includes }` methods implementation\nvar createMethod = function (IS_INCLUDES) {\n return function ($this, el, fromIndex) {\n var O = toIndexedObject($this);\n var length = lengthOfArrayLike(O);\n var index = toAbsoluteIndex(fromIndex, length);\n var value;\n // Array#includes uses SameValueZero equality algorithm\n // eslint-disable-next-line no-self-compare -- NaN check\n if (IS_INCLUDES && el != el) while (length > index) {\n value = O[index++];\n // eslint-disable-next-line no-self-compare -- NaN check\n if (value != value) return true;\n // Array#indexOf ignores holes, Array#includes - not\n } else for (;length > index; index++) {\n if ((IS_INCLUDES || index in O) && O[index] === el) return IS_INCLUDES || index || 0;\n } return !IS_INCLUDES && -1;\n };\n};\n\nmodule.exports = {\n // `Array.prototype.includes` method\n // https://tc39.es/ecma262/#sec-array.prototype.includes\n includes: createMethod(true),\n // `Array.prototype.indexOf` method\n // https://tc39.es/ecma262/#sec-array.prototype.indexof\n indexOf: createMethod(false)\n};\n\n\n/***/ }),\n\n/***/ 6038:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar fails = __webpack_require__(4229);\n\nmodule.exports = function (METHOD_NAME, argument) {\n var method = [][METHOD_NAME];\n return !!method && fails(function () {\n // eslint-disable-next-line no-useless-call -- required for testing\n method.call(null, argument || function () { return 1; }, 1);\n });\n};\n\n\n/***/ }),\n\n/***/ 9794:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar toAbsoluteIndex = __webpack_require__(3231);\nvar lengthOfArrayLike = __webpack_require__(9646);\nvar createProperty = __webpack_require__(2324);\n\nvar $Array = Array;\nvar max = Math.max;\n\nmodule.exports = function (O, start, end) {\n var length = lengthOfArrayLike(O);\n var k = toAbsoluteIndex(start, length);\n var fin = toAbsoluteIndex(end === undefined ? length : end, length);\n var result = $Array(max(fin - k, 0));\n for (var n = 0; k < fin; k++, n++) createProperty(result, n, O[k]);\n result.length = n;\n return result;\n};\n\n\n/***/ }),\n\n/***/ 3867:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar arraySlice = __webpack_require__(9794);\n\nvar floor = Math.floor;\n\nvar mergeSort = function (array, comparefn) {\n var length = array.length;\n var middle = floor(length / 2);\n return length < 8 ? insertionSort(array, comparefn) : merge(\n array,\n mergeSort(arraySlice(array, 0, middle), comparefn),\n mergeSort(arraySlice(array, middle), comparefn),\n comparefn\n );\n};\n\nvar insertionSort = function (array, comparefn) {\n var length = array.length;\n var i = 1;\n var element, j;\n\n while (i < length) {\n j = i;\n element = array[i];\n while (j && comparefn(array[j - 1], element) > 0) {\n array[j] = array[--j];\n }\n if (j !== i++) array[j] = element;\n } return array;\n};\n\nvar merge = function (array, left, right, comparefn) {\n var llength = left.length;\n var rlength = right.length;\n var lindex = 0;\n var rindex = 0;\n\n while (lindex < llength || rindex < rlength) {\n array[lindex + rindex] = (lindex < llength && rindex < rlength)\n ? comparefn(left[lindex], right[rindex]) <= 0 ? left[lindex++] : right[rindex++]\n : lindex < llength ? left[lindex++] : right[rindex++];\n } return array;\n};\n\nmodule.exports = mergeSort;\n\n\n/***/ }),\n\n/***/ 7079:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar uncurryThis = __webpack_require__(5968);\n\nvar toString = uncurryThis({}.toString);\nvar stringSlice = uncurryThis(''.slice);\n\nmodule.exports = function (it) {\n return stringSlice(toString(it), 8, -1);\n};\n\n\n/***/ }),\n\n/***/ 1589:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar TO_STRING_TAG_SUPPORT = __webpack_require__(1601);\nvar isCallable = __webpack_require__(6733);\nvar classofRaw = __webpack_require__(7079);\nvar wellKnownSymbol = __webpack_require__(95);\n\nvar TO_STRING_TAG = wellKnownSymbol('toStringTag');\nvar $Object = Object;\n\n// ES3 wrong here\nvar CORRECT_ARGUMENTS = classofRaw(function () { return arguments; }()) == 'Arguments';\n\n// fallback for IE11 Script Access Denied error\nvar tryGet = function (it, key) {\n try {\n return it[key];\n } catch (error) { /* empty */ }\n};\n\n// getting tag from ES6+ `Object.prototype.toString`\nmodule.exports = TO_STRING_TAG_SUPPORT ? classofRaw : function (it) {\n var O, tag, result;\n return it === undefined ? 'Undefined' : it === null ? 'Null'\n // @@toStringTag case\n : typeof (tag = tryGet(O = $Object(it), TO_STRING_TAG)) == 'string' ? tag\n // builtinTag case\n : CORRECT_ARGUMENTS ? classofRaw(O)\n // ES3 arguments fallback\n : (result = classofRaw(O)) == 'Object' && isCallable(O.callee) ? 'Arguments' : result;\n};\n\n\n/***/ }),\n\n/***/ 7081:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar hasOwn = __webpack_require__(8270);\nvar ownKeys = __webpack_require__(4826);\nvar getOwnPropertyDescriptorModule = __webpack_require__(7933);\nvar definePropertyModule = __webpack_require__(1787);\n\nmodule.exports = function (target, source, exceptions) {\n var keys = ownKeys(source);\n var defineProperty = definePropertyModule.f;\n var getOwnPropertyDescriptor = getOwnPropertyDescriptorModule.f;\n for (var i = 0; i < keys.length; i++) {\n var key = keys[i];\n if (!hasOwn(target, key) && !(exceptions && hasOwn(exceptions, key))) {\n defineProperty(target, key, getOwnPropertyDescriptor(source, key));\n }\n }\n};\n\n\n/***/ }),\n\n/***/ 5762:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar DESCRIPTORS = __webpack_require__(7400);\nvar definePropertyModule = __webpack_require__(1787);\nvar createPropertyDescriptor = __webpack_require__(5358);\n\nmodule.exports = DESCRIPTORS ? function (object, key, value) {\n return definePropertyModule.f(object, key, createPropertyDescriptor(1, value));\n} : function (object, key, value) {\n object[key] = value;\n return object;\n};\n\n\n/***/ }),\n\n/***/ 5358:\n/***/ ((module) => {\n\n\nmodule.exports = function (bitmap, value) {\n return {\n enumerable: !(bitmap & 1),\n configurable: !(bitmap & 2),\n writable: !(bitmap & 4),\n value: value\n };\n};\n\n\n/***/ }),\n\n/***/ 2324:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar toPropertyKey = __webpack_require__(9310);\nvar definePropertyModule = __webpack_require__(1787);\nvar createPropertyDescriptor = __webpack_require__(5358);\n\nmodule.exports = function (object, key, value) {\n var propertyKey = toPropertyKey(key);\n if (propertyKey in object) definePropertyModule.f(object, propertyKey, createPropertyDescriptor(0, value));\n else object[propertyKey] = value;\n};\n\n\n/***/ }),\n\n/***/ 4768:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar isCallable = __webpack_require__(6733);\nvar definePropertyModule = __webpack_require__(1787);\nvar makeBuiltIn = __webpack_require__(6039);\nvar defineGlobalProperty = __webpack_require__(8400);\n\nmodule.exports = function (O, key, value, options) {\n if (!options) options = {};\n var simple = options.enumerable;\n var name = options.name !== undefined ? options.name : key;\n if (isCallable(value)) makeBuiltIn(value, name, options);\n if (options.global) {\n if (simple) O[key] = value;\n else defineGlobalProperty(key, value);\n } else {\n try {\n if (!options.unsafe) delete O[key];\n else if (O[key]) simple = true;\n } catch (error) { /* empty */ }\n if (simple) O[key] = value;\n else definePropertyModule.f(O, key, {\n value: value,\n enumerable: false,\n configurable: !options.nonConfigurable,\n writable: !options.nonWritable\n });\n } return O;\n};\n\n\n/***/ }),\n\n/***/ 8400:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar global = __webpack_require__(9859);\n\n// eslint-disable-next-line es/no-object-defineproperty -- safe\nvar defineProperty = Object.defineProperty;\n\nmodule.exports = function (key, value) {\n try {\n defineProperty(global, key, { value: value, configurable: true, writable: true });\n } catch (error) {\n global[key] = value;\n } return value;\n};\n\n\n/***/ }),\n\n/***/ 9563:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar tryToString = __webpack_require__(9821);\n\nvar $TypeError = TypeError;\n\nmodule.exports = function (O, P) {\n if (!delete O[P]) throw $TypeError('Cannot delete property ' + tryToString(P) + ' of ' + tryToString(O));\n};\n\n\n/***/ }),\n\n/***/ 7400:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar fails = __webpack_require__(4229);\n\n// Detect IE8's incomplete defineProperty implementation\nmodule.exports = !fails(function () {\n // eslint-disable-next-line es/no-object-defineproperty -- required for testing\n return Object.defineProperty({}, 1, { get: function () { return 7; } })[1] != 7;\n});\n\n\n/***/ }),\n\n/***/ 3777:\n/***/ ((module) => {\n\n\nvar documentAll = typeof document == 'object' && document.all;\n\n// https://tc39.es/ecma262/#sec-IsHTMLDDA-internal-slot\n// eslint-disable-next-line unicorn/no-typeof-undefined -- required for testing\nvar IS_HTMLDDA = typeof documentAll == 'undefined' && documentAll !== undefined;\n\nmodule.exports = {\n all: documentAll,\n IS_HTMLDDA: IS_HTMLDDA\n};\n\n\n/***/ }),\n\n/***/ 2635:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar global = __webpack_require__(9859);\nvar isObject = __webpack_require__(5052);\n\nvar document = global.document;\n// typeof document.createElement is 'object' in old IE\nvar EXISTS = isObject(document) && isObject(document.createElement);\n\nmodule.exports = function (it) {\n return EXISTS ? document.createElement(it) : {};\n};\n\n\n/***/ }),\n\n/***/ 2671:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar userAgent = __webpack_require__(598);\n\nvar firefox = userAgent.match(/firefox\\/(\\d+)/i);\n\nmodule.exports = !!firefox && +firefox[1];\n\n\n/***/ }),\n\n/***/ 8506:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar UA = __webpack_require__(598);\n\nmodule.exports = /MSIE|Trident/.test(UA);\n\n\n/***/ }),\n\n/***/ 598:\n/***/ ((module) => {\n\n\nmodule.exports = typeof navigator != 'undefined' && String(navigator.userAgent) || '';\n\n\n/***/ }),\n\n/***/ 5884:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar global = __webpack_require__(9859);\nvar userAgent = __webpack_require__(598);\n\nvar process = global.process;\nvar Deno = global.Deno;\nvar versions = process && process.versions || Deno && Deno.version;\nvar v8 = versions && versions.v8;\nvar match, version;\n\nif (v8) {\n match = v8.split('.');\n // in old Chrome, versions of V8 isn't V8 = Chrome / 10\n // but their correct versions are not interesting for us\n version = match[0] > 0 && match[0] < 4 ? 1 : +(match[0] + match[1]);\n}\n\n// BrowserFS NodeJS `process` polyfill incorrectly set `.v8` to `0.0`\n// so check `userAgent` even if `.v8` exists, but 0\nif (!version && userAgent) {\n match = userAgent.match(/Edge\\/(\\d+)/);\n if (!match || match[1] >= 74) {\n match = userAgent.match(/Chrome\\/(\\d+)/);\n if (match) version = +match[1];\n }\n}\n\nmodule.exports = version;\n\n\n/***/ }),\n\n/***/ 9811:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar userAgent = __webpack_require__(598);\n\nvar webkit = userAgent.match(/AppleWebKit\\/(\\d+)\\./);\n\nmodule.exports = !!webkit && +webkit[1];\n\n\n/***/ }),\n\n/***/ 8791:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar global = __webpack_require__(9859);\nvar uncurryThis = __webpack_require__(5968);\n\nmodule.exports = function (CONSTRUCTOR, METHOD) {\n return uncurryThis(global[CONSTRUCTOR].prototype[METHOD]);\n};\n\n\n/***/ }),\n\n/***/ 3837:\n/***/ ((module) => {\n\n\n// IE8- don't enum bug keys\nmodule.exports = [\n 'constructor',\n 'hasOwnProperty',\n 'isPrototypeOf',\n 'propertyIsEnumerable',\n 'toLocaleString',\n 'toString',\n 'valueOf'\n];\n\n\n/***/ }),\n\n/***/ 3103:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar global = __webpack_require__(9859);\nvar getOwnPropertyDescriptor = (__webpack_require__(7933).f);\nvar createNonEnumerableProperty = __webpack_require__(5762);\nvar defineBuiltIn = __webpack_require__(4768);\nvar defineGlobalProperty = __webpack_require__(8400);\nvar copyConstructorProperties = __webpack_require__(7081);\nvar isForced = __webpack_require__(6541);\n\n/*\n options.target - name of the target object\n options.global - target is the global object\n options.stat - export as static methods of target\n options.proto - export as prototype methods of target\n options.real - real prototype method for the `pure` version\n options.forced - export even if the native feature is available\n options.bind - bind methods to the target, required for the `pure` version\n options.wrap - wrap constructors to preventing global pollution, required for the `pure` version\n options.unsafe - use the simple assignment of property instead of delete + defineProperty\n options.sham - add a flag to not completely full polyfills\n options.enumerable - export as enumerable property\n options.dontCallGetSet - prevent calling a getter on target\n options.name - the .name of the function if it does not match the key\n*/\nmodule.exports = function (options, source) {\n var TARGET = options.target;\n var GLOBAL = options.global;\n var STATIC = options.stat;\n var FORCED, target, key, targetProperty, sourceProperty, descriptor;\n if (GLOBAL) {\n target = global;\n } else if (STATIC) {\n target = global[TARGET] || defineGlobalProperty(TARGET, {});\n } else {\n target = (global[TARGET] || {}).prototype;\n }\n if (target) for (key in source) {\n sourceProperty = source[key];\n if (options.dontCallGetSet) {\n descriptor = getOwnPropertyDescriptor(target, key);\n targetProperty = descriptor && descriptor.value;\n } else targetProperty = target[key];\n FORCED = isForced(GLOBAL ? key : TARGET + (STATIC ? '.' : '#') + key, options.forced);\n // contained in target\n if (!FORCED && targetProperty !== undefined) {\n if (typeof sourceProperty == typeof targetProperty) continue;\n copyConstructorProperties(sourceProperty, targetProperty);\n }\n // add a flag to not completely full polyfills\n if (options.sham || (targetProperty && targetProperty.sham)) {\n createNonEnumerableProperty(sourceProperty, 'sham', true);\n }\n defineBuiltIn(target, key, sourceProperty, options);\n }\n};\n\n\n/***/ }),\n\n/***/ 4229:\n/***/ ((module) => {\n\n\nmodule.exports = function (exec) {\n try {\n return !!exec();\n } catch (error) {\n return true;\n }\n};\n\n\n/***/ }),\n\n/***/ 7188:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar fails = __webpack_require__(4229);\n\nmodule.exports = !fails(function () {\n // eslint-disable-next-line es/no-function-prototype-bind -- safe\n var test = (function () { /* empty */ }).bind();\n // eslint-disable-next-line no-prototype-builtins -- safe\n return typeof test != 'function' || test.hasOwnProperty('prototype');\n});\n\n\n/***/ }),\n\n/***/ 266:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar NATIVE_BIND = __webpack_require__(7188);\n\nvar call = Function.prototype.call;\n\nmodule.exports = NATIVE_BIND ? call.bind(call) : function () {\n return call.apply(call, arguments);\n};\n\n\n/***/ }),\n\n/***/ 1805:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar DESCRIPTORS = __webpack_require__(7400);\nvar hasOwn = __webpack_require__(8270);\n\nvar FunctionPrototype = Function.prototype;\n// eslint-disable-next-line es/no-object-getownpropertydescriptor -- safe\nvar getDescriptor = DESCRIPTORS && Object.getOwnPropertyDescriptor;\n\nvar EXISTS = hasOwn(FunctionPrototype, 'name');\n// additional protection from minified / mangled / dropped function names\nvar PROPER = EXISTS && (function something() { /* empty */ }).name === 'something';\nvar CONFIGURABLE = EXISTS && (!DESCRIPTORS || (DESCRIPTORS && getDescriptor(FunctionPrototype, 'name').configurable));\n\nmodule.exports = {\n EXISTS: EXISTS,\n PROPER: PROPER,\n CONFIGURABLE: CONFIGURABLE\n};\n\n\n/***/ }),\n\n/***/ 5968:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar NATIVE_BIND = __webpack_require__(7188);\n\nvar FunctionPrototype = Function.prototype;\nvar call = FunctionPrototype.call;\nvar uncurryThisWithBind = NATIVE_BIND && FunctionPrototype.bind.bind(call, call);\n\nmodule.exports = NATIVE_BIND ? uncurryThisWithBind : function (fn) {\n return function () {\n return call.apply(fn, arguments);\n };\n};\n\n\n/***/ }),\n\n/***/ 1333:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar global = __webpack_require__(9859);\nvar isCallable = __webpack_require__(6733);\n\nvar aFunction = function (argument) {\n return isCallable(argument) ? argument : undefined;\n};\n\nmodule.exports = function (namespace, method) {\n return arguments.length < 2 ? aFunction(global[namespace]) : global[namespace] && global[namespace][method];\n};\n\n\n/***/ }),\n\n/***/ 5300:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar aCallable = __webpack_require__(7111);\nvar isNullOrUndefined = __webpack_require__(9650);\n\n// `GetMethod` abstract operation\n// https://tc39.es/ecma262/#sec-getmethod\nmodule.exports = function (V, P) {\n var func = V[P];\n return isNullOrUndefined(func) ? undefined : aCallable(func);\n};\n\n\n/***/ }),\n\n/***/ 9859:\n/***/ (function(module, __unused_webpack_exports, __webpack_require__) {\n\n\nvar check = function (it) {\n return it && it.Math == Math && it;\n};\n\n// https://github.com/zloirock/core-js/issues/86#issuecomment-115759028\nmodule.exports =\n // eslint-disable-next-line es/no-global-this -- safe\n check(typeof globalThis == 'object' && globalThis) ||\n check(typeof window == 'object' && window) ||\n // eslint-disable-next-line no-restricted-globals -- safe\n check(typeof self == 'object' && self) ||\n check(typeof __webpack_require__.g == 'object' && __webpack_require__.g) ||\n // eslint-disable-next-line no-new-func -- fallback\n (function () { return this; })() || this || Function('return this')();\n\n\n/***/ }),\n\n/***/ 8270:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar uncurryThis = __webpack_require__(5968);\nvar toObject = __webpack_require__(2991);\n\nvar hasOwnProperty = uncurryThis({}.hasOwnProperty);\n\n// `HasOwnProperty` abstract operation\n// https://tc39.es/ecma262/#sec-hasownproperty\n// eslint-disable-next-line es/no-object-hasown -- safe\nmodule.exports = Object.hasOwn || function hasOwn(it, key) {\n return hasOwnProperty(toObject(it), key);\n};\n\n\n/***/ }),\n\n/***/ 5977:\n/***/ ((module) => {\n\n\nmodule.exports = {};\n\n\n/***/ }),\n\n/***/ 4394:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar DESCRIPTORS = __webpack_require__(7400);\nvar fails = __webpack_require__(4229);\nvar createElement = __webpack_require__(2635);\n\n// Thanks to IE8 for its funny defineProperty\nmodule.exports = !DESCRIPTORS && !fails(function () {\n // eslint-disable-next-line es/no-object-defineproperty -- required for testing\n return Object.defineProperty(createElement('div'), 'a', {\n get: function () { return 7; }\n }).a != 7;\n});\n\n\n/***/ }),\n\n/***/ 9337:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar uncurryThis = __webpack_require__(5968);\nvar fails = __webpack_require__(4229);\nvar classof = __webpack_require__(7079);\n\nvar $Object = Object;\nvar split = uncurryThis(''.split);\n\n// fallback for non-array-like ES3 and non-enumerable old V8 strings\nmodule.exports = fails(function () {\n // throws an error in rhino, see https://github.com/mozilla/rhino/issues/346\n // eslint-disable-next-line no-prototype-builtins -- safe\n return !$Object('z').propertyIsEnumerable(0);\n}) ? function (it) {\n return classof(it) == 'String' ? split(it, '') : $Object(it);\n} : $Object;\n\n\n/***/ }),\n\n/***/ 8511:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar uncurryThis = __webpack_require__(5968);\nvar isCallable = __webpack_require__(6733);\nvar store = __webpack_require__(5353);\n\nvar functionToString = uncurryThis(Function.toString);\n\n// this helper broken in `core-js@3.4.1-3.4.4`, so we can't use `shared` helper\nif (!isCallable(store.inspectSource)) {\n store.inspectSource = function (it) {\n return functionToString(it);\n };\n}\n\nmodule.exports = store.inspectSource;\n\n\n/***/ }),\n\n/***/ 6407:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar NATIVE_WEAK_MAP = __webpack_require__(1180);\nvar global = __webpack_require__(9859);\nvar isObject = __webpack_require__(5052);\nvar createNonEnumerableProperty = __webpack_require__(5762);\nvar hasOwn = __webpack_require__(8270);\nvar shared = __webpack_require__(5353);\nvar sharedKey = __webpack_require__(4399);\nvar hiddenKeys = __webpack_require__(5977);\n\nvar OBJECT_ALREADY_INITIALIZED = 'Object already initialized';\nvar TypeError = global.TypeError;\nvar WeakMap = global.WeakMap;\nvar set, get, has;\n\nvar enforce = function (it) {\n return has(it) ? get(it) : set(it, {});\n};\n\nvar getterFor = function (TYPE) {\n return function (it) {\n var state;\n if (!isObject(it) || (state = get(it)).type !== TYPE) {\n throw TypeError('Incompatible receiver, ' + TYPE + ' required');\n } return state;\n };\n};\n\nif (NATIVE_WEAK_MAP || shared.state) {\n var store = shared.state || (shared.state = new WeakMap());\n /* eslint-disable no-self-assign -- prototype methods protection */\n store.get = store.get;\n store.has = store.has;\n store.set = store.set;\n /* eslint-enable no-self-assign -- prototype methods protection */\n set = function (it, metadata) {\n if (store.has(it)) throw TypeError(OBJECT_ALREADY_INITIALIZED);\n metadata.facade = it;\n store.set(it, metadata);\n return metadata;\n };\n get = function (it) {\n return store.get(it) || {};\n };\n has = function (it) {\n return store.has(it);\n };\n} else {\n var STATE = sharedKey('state');\n hiddenKeys[STATE] = true;\n set = function (it, metadata) {\n if (hasOwn(it, STATE)) throw TypeError(OBJECT_ALREADY_INITIALIZED);\n metadata.facade = it;\n createNonEnumerableProperty(it, STATE, metadata);\n return metadata;\n };\n get = function (it) {\n return hasOwn(it, STATE) ? it[STATE] : {};\n };\n has = function (it) {\n return hasOwn(it, STATE);\n };\n}\n\nmodule.exports = {\n set: set,\n get: get,\n has: has,\n enforce: enforce,\n getterFor: getterFor\n};\n\n\n/***/ }),\n\n/***/ 6733:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar $documentAll = __webpack_require__(3777);\n\nvar documentAll = $documentAll.all;\n\n// `IsCallable` abstract operation\n// https://tc39.es/ecma262/#sec-iscallable\nmodule.exports = $documentAll.IS_HTMLDDA ? function (argument) {\n return typeof argument == 'function' || argument === documentAll;\n} : function (argument) {\n return typeof argument == 'function';\n};\n\n\n/***/ }),\n\n/***/ 6541:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar fails = __webpack_require__(4229);\nvar isCallable = __webpack_require__(6733);\n\nvar replacement = /#|\\.prototype\\./;\n\nvar isForced = function (feature, detection) {\n var value = data[normalize(feature)];\n return value == POLYFILL ? true\n : value == NATIVE ? false\n : isCallable(detection) ? fails(detection)\n : !!detection;\n};\n\nvar normalize = isForced.normalize = function (string) {\n return String(string).replace(replacement, '.').toLowerCase();\n};\n\nvar data = isForced.data = {};\nvar NATIVE = isForced.NATIVE = 'N';\nvar POLYFILL = isForced.POLYFILL = 'P';\n\nmodule.exports = isForced;\n\n\n/***/ }),\n\n/***/ 9650:\n/***/ ((module) => {\n\n\n// we can't use just `it == null` since of `document.all` special case\n// https://tc39.es/ecma262/#sec-IsHTMLDDA-internal-slot-aec\nmodule.exports = function (it) {\n return it === null || it === undefined;\n};\n\n\n/***/ }),\n\n/***/ 5052:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar isCallable = __webpack_require__(6733);\nvar $documentAll = __webpack_require__(3777);\n\nvar documentAll = $documentAll.all;\n\nmodule.exports = $documentAll.IS_HTMLDDA ? function (it) {\n return typeof it == 'object' ? it !== null : isCallable(it) || it === documentAll;\n} : function (it) {\n return typeof it == 'object' ? it !== null : isCallable(it);\n};\n\n\n/***/ }),\n\n/***/ 4231:\n/***/ ((module) => {\n\n\nmodule.exports = false;\n\n\n/***/ }),\n\n/***/ 9395:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar getBuiltIn = __webpack_require__(1333);\nvar isCallable = __webpack_require__(6733);\nvar isPrototypeOf = __webpack_require__(1321);\nvar USE_SYMBOL_AS_UID = __webpack_require__(6969);\n\nvar $Object = Object;\n\nmodule.exports = USE_SYMBOL_AS_UID ? function (it) {\n return typeof it == 'symbol';\n} : function (it) {\n var $Symbol = getBuiltIn('Symbol');\n return isCallable($Symbol) && isPrototypeOf($Symbol.prototype, $Object(it));\n};\n\n\n/***/ }),\n\n/***/ 9646:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar toLength = __webpack_require__(4237);\n\n// `LengthOfArrayLike` abstract operation\n// https://tc39.es/ecma262/#sec-lengthofarraylike\nmodule.exports = function (obj) {\n return toLength(obj.length);\n};\n\n\n/***/ }),\n\n/***/ 6039:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar uncurryThis = __webpack_require__(5968);\nvar fails = __webpack_require__(4229);\nvar isCallable = __webpack_require__(6733);\nvar hasOwn = __webpack_require__(8270);\nvar DESCRIPTORS = __webpack_require__(7400);\nvar CONFIGURABLE_FUNCTION_NAME = (__webpack_require__(1805).CONFIGURABLE);\nvar inspectSource = __webpack_require__(8511);\nvar InternalStateModule = __webpack_require__(6407);\n\nvar enforceInternalState = InternalStateModule.enforce;\nvar getInternalState = InternalStateModule.get;\nvar $String = String;\n// eslint-disable-next-line es/no-object-defineproperty -- safe\nvar defineProperty = Object.defineProperty;\nvar stringSlice = uncurryThis(''.slice);\nvar replace = uncurryThis(''.replace);\nvar join = uncurryThis([].join);\n\nvar CONFIGURABLE_LENGTH = DESCRIPTORS && !fails(function () {\n return defineProperty(function () { /* empty */ }, 'length', { value: 8 }).length !== 8;\n});\n\nvar TEMPLATE = String(String).split('String');\n\nvar makeBuiltIn = module.exports = function (value, name, options) {\n if (stringSlice($String(name), 0, 7) === 'Symbol(') {\n name = '[' + replace($String(name), /^Symbol\\(([^)]*)\\)/, '$1') + ']';\n }\n if (options && options.getter) name = 'get ' + name;\n if (options && options.setter) name = 'set ' + name;\n if (!hasOwn(value, 'name') || (CONFIGURABLE_FUNCTION_NAME && value.name !== name)) {\n if (DESCRIPTORS) defineProperty(value, 'name', { value: name, configurable: true });\n else value.name = name;\n }\n if (CONFIGURABLE_LENGTH && options && hasOwn(options, 'arity') && value.length !== options.arity) {\n defineProperty(value, 'length', { value: options.arity });\n }\n try {\n if (options && hasOwn(options, 'constructor') && options.constructor) {\n if (DESCRIPTORS) defineProperty(value, 'prototype', { writable: false });\n // in V8 ~ Chrome 53, prototypes of some methods, like `Array.prototype.values`, are non-writable\n } else if (value.prototype) value.prototype = undefined;\n } catch (error) { /* empty */ }\n var state = enforceInternalState(value);\n if (!hasOwn(state, 'source')) {\n state.source = join(TEMPLATE, typeof name == 'string' ? name : '');\n } return value;\n};\n\n// add fake Function#toString for correct work wrapped methods / constructors with methods like LoDash isNative\n// eslint-disable-next-line no-extend-native -- required\nFunction.prototype.toString = makeBuiltIn(function toString() {\n return isCallable(this) && getInternalState(this).source || inspectSource(this);\n}, 'toString');\n\n\n/***/ }),\n\n/***/ 917:\n/***/ ((module) => {\n\n\nvar ceil = Math.ceil;\nvar floor = Math.floor;\n\n// `Math.trunc` method\n// https://tc39.es/ecma262/#sec-math.trunc\n// eslint-disable-next-line es/no-math-trunc -- safe\nmodule.exports = Math.trunc || function trunc(x) {\n var n = +x;\n return (n > 0 ? floor : ceil)(n);\n};\n\n\n/***/ }),\n\n/***/ 1787:\n/***/ ((__unused_webpack_module, exports, __webpack_require__) => {\n\n\nvar DESCRIPTORS = __webpack_require__(7400);\nvar IE8_DOM_DEFINE = __webpack_require__(4394);\nvar V8_PROTOTYPE_DEFINE_BUG = __webpack_require__(7137);\nvar anObject = __webpack_require__(1176);\nvar toPropertyKey = __webpack_require__(9310);\n\nvar $TypeError = TypeError;\n// eslint-disable-next-line es/no-object-defineproperty -- safe\nvar $defineProperty = Object.defineProperty;\n// eslint-disable-next-line es/no-object-getownpropertydescriptor -- safe\nvar $getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;\nvar ENUMERABLE = 'enumerable';\nvar CONFIGURABLE = 'configurable';\nvar WRITABLE = 'writable';\n\n// `Object.defineProperty` method\n// https://tc39.es/ecma262/#sec-object.defineproperty\nexports.f = DESCRIPTORS ? V8_PROTOTYPE_DEFINE_BUG ? function defineProperty(O, P, Attributes) {\n anObject(O);\n P = toPropertyKey(P);\n anObject(Attributes);\n if (typeof O === 'function' && P === 'prototype' && 'value' in Attributes && WRITABLE in Attributes && !Attributes[WRITABLE]) {\n var current = $getOwnPropertyDescriptor(O, P);\n if (current && current[WRITABLE]) {\n O[P] = Attributes.value;\n Attributes = {\n configurable: CONFIGURABLE in Attributes ? Attributes[CONFIGURABLE] : current[CONFIGURABLE],\n enumerable: ENUMERABLE in Attributes ? Attributes[ENUMERABLE] : current[ENUMERABLE],\n writable: false\n };\n }\n } return $defineProperty(O, P, Attributes);\n} : $defineProperty : function defineProperty(O, P, Attributes) {\n anObject(O);\n P = toPropertyKey(P);\n anObject(Attributes);\n if (IE8_DOM_DEFINE) try {\n return $defineProperty(O, P, Attributes);\n } catch (error) { /* empty */ }\n if ('get' in Attributes || 'set' in Attributes) throw $TypeError('Accessors not supported');\n if ('value' in Attributes) O[P] = Attributes.value;\n return O;\n};\n\n\n/***/ }),\n\n/***/ 7933:\n/***/ ((__unused_webpack_module, exports, __webpack_require__) => {\n\n\nvar DESCRIPTORS = __webpack_require__(7400);\nvar call = __webpack_require__(266);\nvar propertyIsEnumerableModule = __webpack_require__(9195);\nvar createPropertyDescriptor = __webpack_require__(5358);\nvar toIndexedObject = __webpack_require__(905);\nvar toPropertyKey = __webpack_require__(9310);\nvar hasOwn = __webpack_require__(8270);\nvar IE8_DOM_DEFINE = __webpack_require__(4394);\n\n// eslint-disable-next-line es/no-object-getownpropertydescriptor -- safe\nvar $getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;\n\n// `Object.getOwnPropertyDescriptor` method\n// https://tc39.es/ecma262/#sec-object.getownpropertydescriptor\nexports.f = DESCRIPTORS ? $getOwnPropertyDescriptor : function getOwnPropertyDescriptor(O, P) {\n O = toIndexedObject(O);\n P = toPropertyKey(P);\n if (IE8_DOM_DEFINE) try {\n return $getOwnPropertyDescriptor(O, P);\n } catch (error) { /* empty */ }\n if (hasOwn(O, P)) return createPropertyDescriptor(!call(propertyIsEnumerableModule.f, O, P), O[P]);\n};\n\n\n/***/ }),\n\n/***/ 8151:\n/***/ ((__unused_webpack_module, exports, __webpack_require__) => {\n\n\nvar internalObjectKeys = __webpack_require__(140);\nvar enumBugKeys = __webpack_require__(3837);\n\nvar hiddenKeys = enumBugKeys.concat('length', 'prototype');\n\n// `Object.getOwnPropertyNames` method\n// https://tc39.es/ecma262/#sec-object.getownpropertynames\n// eslint-disable-next-line es/no-object-getownpropertynames -- safe\nexports.f = Object.getOwnPropertyNames || function getOwnPropertyNames(O) {\n return internalObjectKeys(O, hiddenKeys);\n};\n\n\n/***/ }),\n\n/***/ 894:\n/***/ ((__unused_webpack_module, exports) => {\n\n\n// eslint-disable-next-line es/no-object-getownpropertysymbols -- safe\nexports.f = Object.getOwnPropertySymbols;\n\n\n/***/ }),\n\n/***/ 1321:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar uncurryThis = __webpack_require__(5968);\n\nmodule.exports = uncurryThis({}.isPrototypeOf);\n\n\n/***/ }),\n\n/***/ 140:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar uncurryThis = __webpack_require__(5968);\nvar hasOwn = __webpack_require__(8270);\nvar toIndexedObject = __webpack_require__(905);\nvar indexOf = (__webpack_require__(9540).indexOf);\nvar hiddenKeys = __webpack_require__(5977);\n\nvar push = uncurryThis([].push);\n\nmodule.exports = function (object, names) {\n var O = toIndexedObject(object);\n var i = 0;\n var result = [];\n var key;\n for (key in O) !hasOwn(hiddenKeys, key) && hasOwn(O, key) && push(result, key);\n // Don't enum bug & hidden keys\n while (names.length > i) if (hasOwn(O, key = names[i++])) {\n ~indexOf(result, key) || push(result, key);\n }\n return result;\n};\n\n\n/***/ }),\n\n/***/ 5632:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar internalObjectKeys = __webpack_require__(140);\nvar enumBugKeys = __webpack_require__(3837);\n\n// `Object.keys` method\n// https://tc39.es/ecma262/#sec-object.keys\n// eslint-disable-next-line es/no-object-keys -- safe\nmodule.exports = Object.keys || function keys(O) {\n return internalObjectKeys(O, enumBugKeys);\n};\n\n\n/***/ }),\n\n/***/ 9195:\n/***/ ((__unused_webpack_module, exports) => {\n\n\nvar $propertyIsEnumerable = {}.propertyIsEnumerable;\n// eslint-disable-next-line es/no-object-getownpropertydescriptor -- safe\nvar getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;\n\n// Nashorn ~ JDK8 bug\nvar NASHORN_BUG = getOwnPropertyDescriptor && !$propertyIsEnumerable.call({ 1: 2 }, 1);\n\n// `Object.prototype.propertyIsEnumerable` method implementation\n// https://tc39.es/ecma262/#sec-object.prototype.propertyisenumerable\nexports.f = NASHORN_BUG ? function propertyIsEnumerable(V) {\n var descriptor = getOwnPropertyDescriptor(this, V);\n return !!descriptor && descriptor.enumerable;\n} : $propertyIsEnumerable;\n\n\n/***/ }),\n\n/***/ 2914:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar call = __webpack_require__(266);\nvar isCallable = __webpack_require__(6733);\nvar isObject = __webpack_require__(5052);\n\nvar $TypeError = TypeError;\n\n// `OrdinaryToPrimitive` abstract operation\n// https://tc39.es/ecma262/#sec-ordinarytoprimitive\nmodule.exports = function (input, pref) {\n var fn, val;\n if (pref === 'string' && isCallable(fn = input.toString) && !isObject(val = call(fn, input))) return val;\n if (isCallable(fn = input.valueOf) && !isObject(val = call(fn, input))) return val;\n if (pref !== 'string' && isCallable(fn = input.toString) && !isObject(val = call(fn, input))) return val;\n throw $TypeError(\"Can't convert object to primitive value\");\n};\n\n\n/***/ }),\n\n/***/ 4826:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar getBuiltIn = __webpack_require__(1333);\nvar uncurryThis = __webpack_require__(5968);\nvar getOwnPropertyNamesModule = __webpack_require__(8151);\nvar getOwnPropertySymbolsModule = __webpack_require__(894);\nvar anObject = __webpack_require__(1176);\n\nvar concat = uncurryThis([].concat);\n\n// all object keys, includes non-enumerable and symbols\nmodule.exports = getBuiltIn('Reflect', 'ownKeys') || function ownKeys(it) {\n var keys = getOwnPropertyNamesModule.f(anObject(it));\n var getOwnPropertySymbols = getOwnPropertySymbolsModule.f;\n return getOwnPropertySymbols ? concat(keys, getOwnPropertySymbols(it)) : keys;\n};\n\n\n/***/ }),\n\n/***/ 9276:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar global = __webpack_require__(9859);\n\nmodule.exports = global;\n\n\n/***/ }),\n\n/***/ 8885:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar isNullOrUndefined = __webpack_require__(9650);\n\nvar $TypeError = TypeError;\n\n// `RequireObjectCoercible` abstract operation\n// https://tc39.es/ecma262/#sec-requireobjectcoercible\nmodule.exports = function (it) {\n if (isNullOrUndefined(it)) throw $TypeError(\"Can't call method on \" + it);\n return it;\n};\n\n\n/***/ }),\n\n/***/ 4399:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar shared = __webpack_require__(3036);\nvar uid = __webpack_require__(1441);\n\nvar keys = shared('keys');\n\nmodule.exports = function (key) {\n return keys[key] || (keys[key] = uid(key));\n};\n\n\n/***/ }),\n\n/***/ 5353:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar global = __webpack_require__(9859);\nvar defineGlobalProperty = __webpack_require__(8400);\n\nvar SHARED = '__core-js_shared__';\nvar store = global[SHARED] || defineGlobalProperty(SHARED, {});\n\nmodule.exports = store;\n\n\n/***/ }),\n\n/***/ 3036:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar IS_PURE = __webpack_require__(4231);\nvar store = __webpack_require__(5353);\n\n(module.exports = function (key, value) {\n return store[key] || (store[key] = value !== undefined ? value : {});\n})('versions', []).push({\n version: '3.32.0',\n mode: IS_PURE ? 'pure' : 'global',\n copyright: '© 2014-2023 Denis Pushkarev (zloirock.ru)',\n license: 'https://github.com/zloirock/core-js/blob/v3.32.0/LICENSE',\n source: 'https://github.com/zloirock/core-js'\n});\n\n\n/***/ }),\n\n/***/ 4860:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\n/* eslint-disable es/no-symbol -- required for testing */\nvar V8_VERSION = __webpack_require__(5884);\nvar fails = __webpack_require__(4229);\nvar global = __webpack_require__(9859);\n\nvar $String = global.String;\n\n// eslint-disable-next-line es/no-object-getownpropertysymbols -- required for testing\nmodule.exports = !!Object.getOwnPropertySymbols && !fails(function () {\n var symbol = Symbol();\n // Chrome 38 Symbol has incorrect toString conversion\n // `get-own-property-symbols` polyfill symbols converted to object are not Symbol instances\n // nb: Do not call `String` directly to avoid this being optimized out to `symbol+''` which will,\n // of course, fail.\n return !$String(symbol) || !(Object(symbol) instanceof Symbol) ||\n // Chrome 38-40 symbols are not inherited from DOM collections prototypes to instances\n !Symbol.sham && V8_VERSION && V8_VERSION < 41;\n});\n\n\n/***/ }),\n\n/***/ 3231:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar toIntegerOrInfinity = __webpack_require__(3329);\n\nvar max = Math.max;\nvar min = Math.min;\n\n// Helper for a popular repeating case of the spec:\n// Let integer be ? ToInteger(index).\n// If integer < 0, let result be max((length + integer), 0); else let result be min(integer, length).\nmodule.exports = function (index, length) {\n var integer = toIntegerOrInfinity(index);\n return integer < 0 ? max(integer + length, 0) : min(integer, length);\n};\n\n\n/***/ }),\n\n/***/ 905:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\n// toObject with fallback for non-array-like ES3 strings\nvar IndexedObject = __webpack_require__(9337);\nvar requireObjectCoercible = __webpack_require__(8885);\n\nmodule.exports = function (it) {\n return IndexedObject(requireObjectCoercible(it));\n};\n\n\n/***/ }),\n\n/***/ 3329:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar trunc = __webpack_require__(917);\n\n// `ToIntegerOrInfinity` abstract operation\n// https://tc39.es/ecma262/#sec-tointegerorinfinity\nmodule.exports = function (argument) {\n var number = +argument;\n // eslint-disable-next-line no-self-compare -- NaN check\n return number !== number || number === 0 ? 0 : trunc(number);\n};\n\n\n/***/ }),\n\n/***/ 4237:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar toIntegerOrInfinity = __webpack_require__(3329);\n\nvar min = Math.min;\n\n// `ToLength` abstract operation\n// https://tc39.es/ecma262/#sec-tolength\nmodule.exports = function (argument) {\n return argument > 0 ? min(toIntegerOrInfinity(argument), 0x1FFFFFFFFFFFFF) : 0; // 2 ** 53 - 1 == 9007199254740991\n};\n\n\n/***/ }),\n\n/***/ 2991:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar requireObjectCoercible = __webpack_require__(8885);\n\nvar $Object = Object;\n\n// `ToObject` abstract operation\n// https://tc39.es/ecma262/#sec-toobject\nmodule.exports = function (argument) {\n return $Object(requireObjectCoercible(argument));\n};\n\n\n/***/ }),\n\n/***/ 2066:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar call = __webpack_require__(266);\nvar isObject = __webpack_require__(5052);\nvar isSymbol = __webpack_require__(9395);\nvar getMethod = __webpack_require__(5300);\nvar ordinaryToPrimitive = __webpack_require__(2914);\nvar wellKnownSymbol = __webpack_require__(95);\n\nvar $TypeError = TypeError;\nvar TO_PRIMITIVE = wellKnownSymbol('toPrimitive');\n\n// `ToPrimitive` abstract operation\n// https://tc39.es/ecma262/#sec-toprimitive\nmodule.exports = function (input, pref) {\n if (!isObject(input) || isSymbol(input)) return input;\n var exoticToPrim = getMethod(input, TO_PRIMITIVE);\n var result;\n if (exoticToPrim) {\n if (pref === undefined) pref = 'default';\n result = call(exoticToPrim, input, pref);\n if (!isObject(result) || isSymbol(result)) return result;\n throw $TypeError(\"Can't convert object to primitive value\");\n }\n if (pref === undefined) pref = 'number';\n return ordinaryToPrimitive(input, pref);\n};\n\n\n/***/ }),\n\n/***/ 9310:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar toPrimitive = __webpack_require__(2066);\nvar isSymbol = __webpack_require__(9395);\n\n// `ToPropertyKey` abstract operation\n// https://tc39.es/ecma262/#sec-topropertykey\nmodule.exports = function (argument) {\n var key = toPrimitive(argument, 'string');\n return isSymbol(key) ? key : key + '';\n};\n\n\n/***/ }),\n\n/***/ 1601:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar wellKnownSymbol = __webpack_require__(95);\n\nvar TO_STRING_TAG = wellKnownSymbol('toStringTag');\nvar test = {};\n\ntest[TO_STRING_TAG] = 'z';\n\nmodule.exports = String(test) === '[object z]';\n\n\n/***/ }),\n\n/***/ 3326:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar classof = __webpack_require__(1589);\n\nvar $String = String;\n\nmodule.exports = function (argument) {\n if (classof(argument) === 'Symbol') throw TypeError('Cannot convert a Symbol value to a string');\n return $String(argument);\n};\n\n\n/***/ }),\n\n/***/ 9821:\n/***/ ((module) => {\n\n\nvar $String = String;\n\nmodule.exports = function (argument) {\n try {\n return $String(argument);\n } catch (error) {\n return 'Object';\n }\n};\n\n\n/***/ }),\n\n/***/ 1441:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar uncurryThis = __webpack_require__(5968);\n\nvar id = 0;\nvar postfix = Math.random();\nvar toString = uncurryThis(1.0.toString);\n\nmodule.exports = function (key) {\n return 'Symbol(' + (key === undefined ? '' : key) + ')_' + toString(++id + postfix, 36);\n};\n\n\n/***/ }),\n\n/***/ 6969:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\n/* eslint-disable es/no-symbol -- required for testing */\nvar NATIVE_SYMBOL = __webpack_require__(4860);\n\nmodule.exports = NATIVE_SYMBOL\n && !Symbol.sham\n && typeof Symbol.iterator == 'symbol';\n\n\n/***/ }),\n\n/***/ 7137:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar DESCRIPTORS = __webpack_require__(7400);\nvar fails = __webpack_require__(4229);\n\n// V8 ~ Chrome 36-\n// https://bugs.chromium.org/p/v8/issues/detail?id=3334\nmodule.exports = DESCRIPTORS && fails(function () {\n // eslint-disable-next-line es/no-object-defineproperty -- required for testing\n return Object.defineProperty(function () { /* empty */ }, 'prototype', {\n value: 42,\n writable: false\n }).prototype != 42;\n});\n\n\n/***/ }),\n\n/***/ 1180:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar global = __webpack_require__(9859);\nvar isCallable = __webpack_require__(6733);\n\nvar WeakMap = global.WeakMap;\n\nmodule.exports = isCallable(WeakMap) && /native code/.test(String(WeakMap));\n\n\n/***/ }),\n\n/***/ 95:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar global = __webpack_require__(9859);\nvar shared = __webpack_require__(3036);\nvar hasOwn = __webpack_require__(8270);\nvar uid = __webpack_require__(1441);\nvar NATIVE_SYMBOL = __webpack_require__(4860);\nvar USE_SYMBOL_AS_UID = __webpack_require__(6969);\n\nvar Symbol = global.Symbol;\nvar WellKnownSymbolsStore = shared('wks');\nvar createWellKnownSymbol = USE_SYMBOL_AS_UID ? Symbol['for'] || Symbol : Symbol && Symbol.withoutSetter || uid;\n\nmodule.exports = function (name) {\n if (!hasOwn(WellKnownSymbolsStore, name)) {\n WellKnownSymbolsStore[name] = NATIVE_SYMBOL && hasOwn(Symbol, name)\n ? Symbol[name]\n : createWellKnownSymbol('Symbol.' + name);\n } return WellKnownSymbolsStore[name];\n};\n\n\n/***/ }),\n\n/***/ 3430:\n/***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar $ = __webpack_require__(3103);\nvar uncurryThis = __webpack_require__(5968);\nvar aCallable = __webpack_require__(7111);\nvar toObject = __webpack_require__(2991);\nvar lengthOfArrayLike = __webpack_require__(9646);\nvar deletePropertyOrThrow = __webpack_require__(9563);\nvar toString = __webpack_require__(3326);\nvar fails = __webpack_require__(4229);\nvar internalSort = __webpack_require__(3867);\nvar arrayMethodIsStrict = __webpack_require__(6038);\nvar FF = __webpack_require__(2671);\nvar IE_OR_EDGE = __webpack_require__(8506);\nvar V8 = __webpack_require__(5884);\nvar WEBKIT = __webpack_require__(9811);\n\nvar test = [];\nvar nativeSort = uncurryThis(test.sort);\nvar push = uncurryThis(test.push);\n\n// IE8-\nvar FAILS_ON_UNDEFINED = fails(function () {\n test.sort(undefined);\n});\n// V8 bug\nvar FAILS_ON_NULL = fails(function () {\n test.sort(null);\n});\n// Old WebKit\nvar STRICT_METHOD = arrayMethodIsStrict('sort');\n\nvar STABLE_SORT = !fails(function () {\n // feature detection can be too slow, so check engines versions\n if (V8) return V8 < 70;\n if (FF && FF > 3) return;\n if (IE_OR_EDGE) return true;\n if (WEBKIT) return WEBKIT < 603;\n\n var result = '';\n var code, chr, value, index;\n\n // generate an array with more 512 elements (Chakra and old V8 fails only in this case)\n for (code = 65; code < 76; code++) {\n chr = String.fromCharCode(code);\n\n switch (code) {\n case 66: case 69: case 70: case 72: value = 3; break;\n case 68: case 71: value = 4; break;\n default: value = 2;\n }\n\n for (index = 0; index < 47; index++) {\n test.push({ k: chr + index, v: value });\n }\n }\n\n test.sort(function (a, b) { return b.v - a.v; });\n\n for (index = 0; index < test.length; index++) {\n chr = test[index].k.charAt(0);\n if (result.charAt(result.length - 1) !== chr) result += chr;\n }\n\n return result !== 'DGBEFHACIJK';\n});\n\nvar FORCED = FAILS_ON_UNDEFINED || !FAILS_ON_NULL || !STRICT_METHOD || !STABLE_SORT;\n\nvar getSortCompare = function (comparefn) {\n return function (x, y) {\n if (y === undefined) return -1;\n if (x === undefined) return 1;\n if (comparefn !== undefined) return +comparefn(x, y) || 0;\n return toString(x) > toString(y) ? 1 : -1;\n };\n};\n\n// `Array.prototype.sort` method\n// https://tc39.es/ecma262/#sec-array.prototype.sort\n$({ target: 'Array', proto: true, forced: FORCED }, {\n sort: function sort(comparefn) {\n if (comparefn !== undefined) aCallable(comparefn);\n\n var array = toObject(this);\n\n if (STABLE_SORT) return comparefn === undefined ? nativeSort(array) : nativeSort(array, comparefn);\n\n var items = [];\n var arrayLength = lengthOfArrayLike(array);\n var itemsLength, index;\n\n for (index = 0; index < arrayLength; index++) {\n if (index in array) push(items, array[index]);\n }\n\n internalSort(items, getSortCompare(comparefn));\n\n itemsLength = lengthOfArrayLike(items);\n index = 0;\n\n while (index < itemsLength) array[index] = items[index++];\n while (index < arrayLength) deletePropertyOrThrow(array, index++);\n\n return array;\n }\n});\n\n\n/***/ }),\n\n/***/ 4769:\n/***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => {\n\n\nvar $ = __webpack_require__(3103);\nvar toObject = __webpack_require__(2991);\nvar nativeKeys = __webpack_require__(5632);\nvar fails = __webpack_require__(4229);\n\nvar FAILS_ON_PRIMITIVES = fails(function () { nativeKeys(1); });\n\n// `Object.keys` method\n// https://tc39.es/ecma262/#sec-object.keys\n$({ target: 'Object', stat: true, forced: FAILS_ON_PRIMITIVES }, {\n keys: function keys(it) {\n return nativeKeys(toObject(it));\n }\n});\n\n\n/***/ }),\n\n/***/ 1388:\n/***/ ((module, __webpack_exports__, __webpack_require__) => {\n\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n/* harmony import */ var _node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(272);\n/* harmony import */ var _node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(2609);\n/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__);\n// Imports\n\n\nvar ___CSS_LOADER_EXPORT___ = _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default()((_node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default()));\n// Module\n___CSS_LOADER_EXPORT___.push([module.id, `/* Buttons styles start */\r\n\r\nbutton#excalibur-play {\r\n display: inline-block;\r\n position: relative;\r\n z-index: 999;\r\n border-radius: 6px;\r\n border: none;\r\n /*border: 3px solid;\r\n border-color: white;\r\n box-shadow: 0 0 10px #ccc;*/\r\n padding: 1rem 1.5rem 1rem 4rem;\r\n margin: 0;\r\n text-decoration: none;\r\n background: #00b233;\r\n color: #ffffff;\r\n font-family: sans-serif;\r\n font-size: 2rem;\r\n white-space: nowrap;\r\n line-height: 1;\r\n cursor: pointer;\r\n text-align: center;\r\n transition: background 250ms ease-in-out, transform 150ms ease;\r\n -webkit-appearance: none;\r\n -moz-appearance: none;\r\n\r\n -webkit-animation: excalibur-button-fadein 200ms; /* Safari, Chrome and Opera > 12.1 */\r\n -moz-animation: excalibur-button-fadein 200ms; /* Firefox < 16 */\r\n -ms-animation: excalibur-button-fadein 200ms; /* Internet Explorer */\r\n -o-animation: excalibur-button-fadein 200ms; /* Opera < 12.1 */\r\n animation: excalibur-button-fadein 200ms;\r\n}\r\n\r\n/*\r\nbutton#excalibur-play {\r\n display: none;\r\n}*/\r\n\r\nbutton#excalibur-play:after {\r\n position: absolute;\r\n content: '';\r\n border: 8px solid;\r\n border-color: transparent transparent transparent white;\r\n left: 35px;\r\n top: 24px;\r\n width: 0;\r\n height: 0;\r\n}\r\n\r\nbutton#excalibur-play:before {\r\n position: absolute;\r\n content: '';\r\n border: 3px solid;\r\n left: 19px;\r\n top: 14px;\r\n border-radius: 20px;\r\n width: 30px;\r\n height: 30px;\r\n}\r\n\r\nbutton#excalibur-play:hover,\r\nbutton#excalibur-play:focus {\r\n background: #00982c;\r\n}\r\n\r\nbutton#excalibur-play:focus {\r\n outline: 1px solid #fff;\r\n outline-offset: -4px;\r\n}\r\n\r\nbutton#excalibur-play:active {\r\n transform: scale(0.99);\r\n}\r\n\r\n@keyframes excalibur-button-fadein {\r\n from {\r\n opacity: 0;\r\n }\r\n to {\r\n opacity: 1;\r\n }\r\n}\r\n\r\n/* Firefox < 16 */\r\n@-moz-keyframes excalibur-button-fadein {\r\n from {\r\n opacity: 0;\r\n }\r\n to {\r\n opacity: 1;\r\n }\r\n}\r\n\r\n/* Safari, Chrome and Opera > 12.1 */\r\n@-webkit-keyframes excalibur-button-fadein {\r\n from {\r\n opacity: 0;\r\n }\r\n to {\r\n opacity: 1;\r\n }\r\n}\r\n\r\n/* Internet Explorer */\r\n@-ms-keyframes excalibur-button-fadein {\r\n from {\r\n opacity: 0;\r\n }\r\n to {\r\n opacity: 1;\r\n }\r\n}\r\n\r\n/* Opera < 12.1 */\r\n@-o-keyframes excalibur-button-fadein {\r\n from {\r\n opacity: 0;\r\n }\r\n to {\r\n opacity: 1;\r\n }\r\n}\r\n`, \"\",{\"version\":3,\"sources\":[\"webpack://./Loader.css\"],\"names\":[],\"mappings\":\"AAAA,yBAAyB;;AAEzB;EACE,qBAAqB;EACrB,kBAAkB;EAClB,YAAY;EACZ,kBAAkB;EAClB,YAAY;EACZ;;+BAE6B;EAC7B,8BAA8B;EAC9B,SAAS;EACT,qBAAqB;EACrB,mBAAmB;EACnB,cAAc;EACd,uBAAuB;EACvB,eAAe;EACf,mBAAmB;EACnB,cAAc;EACd,eAAe;EACf,kBAAkB;EAClB,8DAA8D;EAC9D,wBAAwB;EACxB,qBAAqB;;EAErB,gDAAgD,EAAE,oCAAoC;EACtF,6CAA6C,EAAE,iBAAiB;EAChE,4CAA4C,EAAE,sBAAsB;EACpE,2CAA2C,EAAE,iBAAiB;EAC9D,wCAAwC;AAC1C;;AAEA;;;EAGE;;AAEF;EACE,kBAAkB;EAClB,WAAW;EACX,iBAAiB;EACjB,uDAAuD;EACvD,UAAU;EACV,SAAS;EACT,QAAQ;EACR,SAAS;AACX;;AAEA;EACE,kBAAkB;EAClB,WAAW;EACX,iBAAiB;EACjB,UAAU;EACV,SAAS;EACT,mBAAmB;EACnB,WAAW;EACX,YAAY;AACd;;AAEA;;EAEE,mBAAmB;AACrB;;AAEA;EACE,uBAAuB;EACvB,oBAAoB;AACtB;;AAEA;EACE,sBAAsB;AACxB;;AAEA;EACE;IACE,UAAU;EACZ;EACA;IACE,UAAU;EACZ;AACF;;AAEA,iBAAiB;AACjB;EACE;IACE,UAAU;EACZ;EACA;IACE,UAAU;EACZ;AACF;;AAEA,oCAAoC;AACpC;EACE;IACE,UAAU;EACZ;EACA;IACE,UAAU;EACZ;AACF;;AAEA,sBAAsB;AACtB;EACE;IACE,UAAU;EACZ;EACA;IACE,UAAU;EACZ;AACF;;AAEA,iBAAiB;AACjB;EACE;IACE,UAAU;EACZ;EACA;IACE,UAAU;EACZ;AACF\",\"sourcesContent\":[\"/* Buttons styles start */\\r\\n\\r\\nbutton#excalibur-play {\\r\\n display: inline-block;\\r\\n position: relative;\\r\\n z-index: 999;\\r\\n border-radius: 6px;\\r\\n border: none;\\r\\n /*border: 3px solid;\\r\\n border-color: white;\\r\\n box-shadow: 0 0 10px #ccc;*/\\r\\n padding: 1rem 1.5rem 1rem 4rem;\\r\\n margin: 0;\\r\\n text-decoration: none;\\r\\n background: #00b233;\\r\\n color: #ffffff;\\r\\n font-family: sans-serif;\\r\\n font-size: 2rem;\\r\\n white-space: nowrap;\\r\\n line-height: 1;\\r\\n cursor: pointer;\\r\\n text-align: center;\\r\\n transition: background 250ms ease-in-out, transform 150ms ease;\\r\\n -webkit-appearance: none;\\r\\n -moz-appearance: none;\\r\\n\\r\\n -webkit-animation: excalibur-button-fadein 200ms; /* Safari, Chrome and Opera > 12.1 */\\r\\n -moz-animation: excalibur-button-fadein 200ms; /* Firefox < 16 */\\r\\n -ms-animation: excalibur-button-fadein 200ms; /* Internet Explorer */\\r\\n -o-animation: excalibur-button-fadein 200ms; /* Opera < 12.1 */\\r\\n animation: excalibur-button-fadein 200ms;\\r\\n}\\r\\n\\r\\n/*\\r\\nbutton#excalibur-play {\\r\\n display: none;\\r\\n}*/\\r\\n\\r\\nbutton#excalibur-play:after {\\r\\n position: absolute;\\r\\n content: '';\\r\\n border: 8px solid;\\r\\n border-color: transparent transparent transparent white;\\r\\n left: 35px;\\r\\n top: 24px;\\r\\n width: 0;\\r\\n height: 0;\\r\\n}\\r\\n\\r\\nbutton#excalibur-play:before {\\r\\n position: absolute;\\r\\n content: '';\\r\\n border: 3px solid;\\r\\n left: 19px;\\r\\n top: 14px;\\r\\n border-radius: 20px;\\r\\n width: 30px;\\r\\n height: 30px;\\r\\n}\\r\\n\\r\\nbutton#excalibur-play:hover,\\r\\nbutton#excalibur-play:focus {\\r\\n background: #00982c;\\r\\n}\\r\\n\\r\\nbutton#excalibur-play:focus {\\r\\n outline: 1px solid #fff;\\r\\n outline-offset: -4px;\\r\\n}\\r\\n\\r\\nbutton#excalibur-play:active {\\r\\n transform: scale(0.99);\\r\\n}\\r\\n\\r\\n@keyframes excalibur-button-fadein {\\r\\n from {\\r\\n opacity: 0;\\r\\n }\\r\\n to {\\r\\n opacity: 1;\\r\\n }\\r\\n}\\r\\n\\r\\n/* Firefox < 16 */\\r\\n@-moz-keyframes excalibur-button-fadein {\\r\\n from {\\r\\n opacity: 0;\\r\\n }\\r\\n to {\\r\\n opacity: 1;\\r\\n }\\r\\n}\\r\\n\\r\\n/* Safari, Chrome and Opera > 12.1 */\\r\\n@-webkit-keyframes excalibur-button-fadein {\\r\\n from {\\r\\n opacity: 0;\\r\\n }\\r\\n to {\\r\\n opacity: 1;\\r\\n }\\r\\n}\\r\\n\\r\\n/* Internet Explorer */\\r\\n@-ms-keyframes excalibur-button-fadein {\\r\\n from {\\r\\n opacity: 0;\\r\\n }\\r\\n to {\\r\\n opacity: 1;\\r\\n }\\r\\n}\\r\\n\\r\\n/* Opera < 12.1 */\\r\\n@-o-keyframes excalibur-button-fadein {\\r\\n from {\\r\\n opacity: 0;\\r\\n }\\r\\n to {\\r\\n opacity: 1;\\r\\n }\\r\\n}\\r\\n\"],\"sourceRoot\":\"\"}]);\n// Exports\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___);\n\n\n/***/ }),\n\n/***/ 7379:\n/***/ ((module, __webpack_exports__, __webpack_require__) => {\n\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n/* harmony import */ var _node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(272);\n/* harmony import */ var _node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(2609);\n/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__);\n// Imports\n\n\nvar ___CSS_LOADER_EXPORT___ = _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default()((_node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default()));\n// Module\n___CSS_LOADER_EXPORT___.push([module.id, `\r\n#ex-toast-container {\r\n position: absolute;\r\n height: 0;\r\n min-width: 50%;\r\n left: 50%;\r\n top: 0;\r\n}\r\n\r\n.ex-toast-message {\r\n left: -50%;\r\n position: relative;\r\n display: flex;\r\n justify-content: space-between;\r\n\r\n\r\n padding: 10px;\r\n margin-top: 5px;\r\n font-size: 18px;\r\n font-family: sans-serif;\r\n border-radius: 6px;\r\n border: 3px solid #b7b779;\r\n background-color: rgb(253, 253, 192);\r\n}\r\n\r\n\r\n.ex-toast-message button {\r\n align-self: flex-start;\r\n}`, \"\",{\"version\":3,\"sources\":[\"webpack://./Util/Toaster.css\"],\"names\":[],\"mappings\":\";AACA;EACE,kBAAkB;EAClB,SAAS;EACT,cAAc;EACd,SAAS;EACT,MAAM;AACR;;AAEA;EACE,UAAU;EACV,kBAAkB;EAClB,aAAa;EACb,8BAA8B;;;EAG9B,aAAa;EACb,eAAe;EACf,eAAe;EACf,uBAAuB;EACvB,kBAAkB;EAClB,yBAAyB;EACzB,oCAAoC;AACtC;;;AAGA;EACE,sBAAsB;AACxB\",\"sourcesContent\":[\"\\r\\n#ex-toast-container {\\r\\n position: absolute;\\r\\n height: 0;\\r\\n min-width: 50%;\\r\\n left: 50%;\\r\\n top: 0;\\r\\n}\\r\\n\\r\\n.ex-toast-message {\\r\\n left: -50%;\\r\\n position: relative;\\r\\n display: flex;\\r\\n justify-content: space-between;\\r\\n\\r\\n\\r\\n padding: 10px;\\r\\n margin-top: 5px;\\r\\n font-size: 18px;\\r\\n font-family: sans-serif;\\r\\n border-radius: 6px;\\r\\n border: 3px solid #b7b779;\\r\\n background-color: rgb(253, 253, 192);\\r\\n}\\r\\n\\r\\n\\r\\n.ex-toast-message button {\\r\\n align-self: flex-start;\\r\\n}\"],\"sourceRoot\":\"\"}]);\n// Exports\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___);\n\n\n/***/ }),\n\n/***/ 2609:\n/***/ ((module) => {\n\n\n\n/*\n MIT License http://www.opensource.org/licenses/mit-license.php\n Author Tobias Koppers @sokra\n*/\nmodule.exports = function (cssWithMappingToString) {\n var list = [];\n\n // return the list of modules as css string\n list.toString = function toString() {\n return this.map(function (item) {\n var content = \"\";\n var needLayer = typeof item[5] !== \"undefined\";\n if (item[4]) {\n content += \"@supports (\".concat(item[4], \") {\");\n }\n if (item[2]) {\n content += \"@media \".concat(item[2], \" {\");\n }\n if (needLayer) {\n content += \"@layer\".concat(item[5].length > 0 ? \" \".concat(item[5]) : \"\", \" {\");\n }\n content += cssWithMappingToString(item);\n if (needLayer) {\n content += \"}\";\n }\n if (item[2]) {\n content += \"}\";\n }\n if (item[4]) {\n content += \"}\";\n }\n return content;\n }).join(\"\");\n };\n\n // import a list of modules into the list\n list.i = function i(modules, media, dedupe, supports, layer) {\n if (typeof modules === \"string\") {\n modules = [[null, modules, undefined]];\n }\n var alreadyImportedModules = {};\n if (dedupe) {\n for (var k = 0; k < this.length; k++) {\n var id = this[k][0];\n if (id != null) {\n alreadyImportedModules[id] = true;\n }\n }\n }\n for (var _k = 0; _k < modules.length; _k++) {\n var item = [].concat(modules[_k]);\n if (dedupe && alreadyImportedModules[item[0]]) {\n continue;\n }\n if (typeof layer !== \"undefined\") {\n if (typeof item[5] === \"undefined\") {\n item[5] = layer;\n } else {\n item[1] = \"@layer\".concat(item[5].length > 0 ? \" \".concat(item[5]) : \"\", \" {\").concat(item[1], \"}\");\n item[5] = layer;\n }\n }\n if (media) {\n if (!item[2]) {\n item[2] = media;\n } else {\n item[1] = \"@media \".concat(item[2], \" {\").concat(item[1], \"}\");\n item[2] = media;\n }\n }\n if (supports) {\n if (!item[4]) {\n item[4] = \"\".concat(supports);\n } else {\n item[1] = \"@supports (\".concat(item[4], \") {\").concat(item[1], \"}\");\n item[4] = supports;\n }\n }\n list.push(item);\n }\n };\n return list;\n};\n\n/***/ }),\n\n/***/ 272:\n/***/ ((module) => {\n\n\n\nmodule.exports = function (item) {\n var content = item[1];\n var cssMapping = item[3];\n if (!cssMapping) {\n return content;\n }\n if (typeof btoa === \"function\") {\n var base64 = btoa(unescape(encodeURIComponent(JSON.stringify(cssMapping))));\n var data = \"sourceMappingURL=data:application/json;charset=utf-8;base64,\".concat(base64);\n var sourceMapping = \"/*# \".concat(data, \" */\");\n return [content].concat([sourceMapping]).join(\"\\n\");\n }\n return [content].join(\"\\n\");\n};\n\n/***/ })\n\n/******/ });\n/************************************************************************/\n/******/ // The module cache\n/******/ var __webpack_module_cache__ = {};\n/******/ \n/******/ // The require function\n/******/ function __webpack_require__(moduleId) {\n/******/ \t// Check if module is in cache\n/******/ \tvar cachedModule = __webpack_module_cache__[moduleId];\n/******/ \tif (cachedModule !== undefined) {\n/******/ \t\treturn cachedModule.exports;\n/******/ \t}\n/******/ \t// Create a new module (and put it into the cache)\n/******/ \tvar module = __webpack_module_cache__[moduleId] = {\n/******/ \t\tid: moduleId,\n/******/ \t\t// no module.loaded needed\n/******/ \t\texports: {}\n/******/ \t};\n/******/ \n/******/ \t// Execute the module function\n/******/ \t__webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n/******/ \n/******/ \t// Return the exports of the module\n/******/ \treturn module.exports;\n/******/ }\n/******/ \n/************************************************************************/\n/******/ /* webpack/runtime/compat get default export */\n/******/ (() => {\n/******/ \t// getDefaultExport function for compatibility with non-harmony modules\n/******/ \t__webpack_require__.n = (module) => {\n/******/ \t\tvar getter = module && module.__esModule ?\n/******/ \t\t\t() => (module['default']) :\n/******/ \t\t\t() => (module);\n/******/ \t\t__webpack_require__.d(getter, { a: getter });\n/******/ \t\treturn getter;\n/******/ \t};\n/******/ })();\n/******/ \n/******/ /* webpack/runtime/define property getters */\n/******/ (() => {\n/******/ \t// define getter functions for harmony exports\n/******/ \t__webpack_require__.d = (exports, definition) => {\n/******/ \t\tfor(var key in definition) {\n/******/ \t\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n/******/ \t\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n/******/ \t\t\t}\n/******/ \t\t}\n/******/ \t};\n/******/ })();\n/******/ \n/******/ /* webpack/runtime/global */\n/******/ (() => {\n/******/ \t__webpack_require__.g = (function() {\n/******/ \t\tif (typeof globalThis === 'object') return globalThis;\n/******/ \t\ttry {\n/******/ \t\t\treturn this || new Function('return this')();\n/******/ \t\t} catch (e) {\n/******/ \t\t\tif (typeof window === 'object') return window;\n/******/ \t\t}\n/******/ \t})();\n/******/ })();\n/******/ \n/******/ /* webpack/runtime/hasOwnProperty shorthand */\n/******/ (() => {\n/******/ \t__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))\n/******/ })();\n/******/ \n/******/ /* webpack/runtime/make namespace object */\n/******/ (() => {\n/******/ \t// define __esModule on exports\n/******/ \t__webpack_require__.r = (exports) => {\n/******/ \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n/******/ \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n/******/ \t\t}\n/******/ \t\tObject.defineProperty(exports, '__esModule', { value: true });\n/******/ \t};\n/******/ })();\n/******/ \n/************************************************************************/\nvar __webpack_exports__ = {};\n// This entry need to be wrapped in an IIFE because it need to be isolated against other modules in the chunk.\n(() => {\n\n// EXPORTS\n__webpack_require__.d(__webpack_exports__, {\n fWn: () => (/* reexport */ ActionContext),\n Ia8: () => (/* reexport */ ActionQueue),\n rqv: () => (/* reexport */ ActionSequence),\n hLI: () => (/* reexport */ ActionsComponent),\n yyv: () => (/* reexport */ ActionsSystem),\n tX5: () => (/* reexport */ ActivateEvent),\n vtX: () => (/* reexport */ Actor),\n r7K: () => (/* reexport */ AddedComponent),\n lCh: () => (/* reexport */ AddedEntity),\n cE4: () => (/* reexport */ AffineMatrix),\n fwF: () => (/* reexport */ Animation),\n sce: () => (/* reexport */ AnimationDirection),\n AQ6: () => (/* reexport */ AnimationEvents),\n _c7: () => (/* reexport */ AnimationStrategy),\n KUs: () => (/* reexport */ ArcadeSolver),\n Ajp: () => (/* reexport */ AudioContextFactory),\n dkO: () => (/* reexport */ Axes),\n RDh: () => (/* reexport */ Axis),\n _H9: () => (/* reexport */ BaseAlign),\n mxs: () => (/* reexport */ Blink),\n OmD: () => (/* reexport */ BodyComponent),\n kBf: () => (/* reexport */ BoundingBox),\n C4F: () => (/* reexport */ BroadphaseStrategy),\n NQt: () => (/* reexport */ BrowserComponent),\n JjN: () => (/* reexport */ BrowserEvents),\n EK_: () => (/* reexport */ Buttons),\n V1s: () => (/* reexport */ Camera),\n xHm: () => (/* reexport */ CameraEvents),\n Xz7: () => (/* reexport */ Canvas),\n Cdc: () => (/* reexport */ Circle),\n FKn: () => (/* reexport */ CircleCollider),\n SUY: () => (/* reexport */ Clock),\n ab2: () => (/* reexport */ ClosestLine),\n GfZ: () => (/* reexport */ ClosestLineJumpTable),\n YMS: () => (/* reexport */ Collider),\n oyv: () => (/* reexport */ ColliderComponent),\n aUb: () => (/* reexport */ CollisionContact),\n SdD: () => (/* reexport */ CollisionEndEvent),\n JUv: () => (/* reexport */ CollisionGroup),\n jEj: () => (/* reexport */ CollisionGroupManager),\n TFq: () => (/* reexport */ CollisionJumpTable),\n HDU: () => (/* reexport */ CollisionPostSolveEvent),\n R_y: () => (/* reexport */ CollisionPreSolveEvent),\n ydN: () => (/* reexport */ CollisionResolutionStrategy),\n t50: () => (/* reexport */ CollisionStartEvent),\n s$$: () => (/* reexport */ CollisionSystem),\n v2G: () => (/* reexport */ CollisionType),\n Ilk: () => (/* reexport */ Color),\n s9i: () => (/* reexport */ ColorBlindFlags),\n dxL: () => (/* reexport */ ColorBlindnessMode),\n LLX: () => (/* reexport */ ColorBlindnessPostProcessor),\n wA2: () => (/* reexport */ Component),\n R_p: () => (/* reexport */ CompositeCollider),\n IQ$: () => (/* reexport */ Configurable),\n I5F: () => (/* reexport */ ConsoleAppender),\n X8$: () => (/* reexport */ ContactConstraintPoint),\n FR6: () => (/* reexport */ ContactEndEvent),\n U8o: () => (/* reexport */ ContactStartEvent),\n kbG: () => (/* reexport */ CoordPlane),\n iS_: () => (/* reexport */ DeactivateEvent),\n cGG: () => (/* reexport */ Debug),\n RPN: () => (/* reexport */ DebugGraphicsComponent),\n skb: () => (/* reexport */ DebugSystem),\n SLU: () => (/* reexport */ DebugText),\n RdJ: () => (/* reexport */ DegreeOfFreedom),\n cNu: () => (/* reexport */ Delay),\n gU7: () => (/* reexport */ Detector),\n LSk: () => (/* reexport */ Die),\n Nmp: () => (/* reexport */ Direction),\n d1Y: () => (/* reexport */ DisplayMode),\n xrL: () => (/* reexport */ DynamicTree),\n sRW: () => (/* reexport */ DynamicTreeCollisionProcessor),\n cmV: () => (/* binding */ EX_VERSION),\n qWz: () => (/* reexport */ EaseBy),\n N0Q: () => (/* reexport */ EaseTo),\n q8b: () => (/* reexport */ EasingFunctions),\n ynB: () => (/* reexport */ EdgeCollider),\n jT9: () => (/* reexport */ ElasticToActorStrategy),\n wAz: () => (/* reexport */ EmitterType),\n D4V: () => (/* reexport */ Engine),\n NLr: () => (/* reexport */ EngineEvents),\n N6H: () => (/* reexport */ EnterTriggerEvent),\n W1A: () => (/* reexport */ EnterViewPortEvent),\n JHW: () => (/* reexport */ Entity),\n ZZ$: () => (/* reexport */ EntityEvents),\n v2K: () => (/* reexport */ EntityManager),\n pBf: () => (/* reexport */ EventDispatcher),\n vpe: () => (/* reexport */ EventEmitter),\n GMl: () => (/* reexport */ EventTypes),\n zW2: () => (/* reexport */ Events_namespaceObject),\n B0K: () => (/* reexport */ ExResponse),\n Nv7: () => (/* reexport */ ExcaliburGraphicsContext2DCanvas),\n C_p: () => (/* reexport */ ExcaliburGraphicsContextWebGL),\n MUA: () => (/* reexport */ ExitTriggerEvent),\n xqU: () => (/* reexport */ ExitViewPortEvent),\n pTp: () => (/* reexport */ Fade),\n vUK: () => (/* reexport */ Flags),\n j9l: () => (/* reexport */ Follow),\n Zxw: () => (/* reexport */ Font),\n v51: () => (/* reexport */ FontCache),\n Hdx: () => (/* reexport */ FontStyle),\n Z$d: () => (/* reexport */ FontUnit),\n iqV: () => (/* reexport */ FpsSampler),\n o$7: () => (/* reexport */ FrameStats),\n olM: () => (/* reexport */ Future),\n Zm$: () => (/* reexport */ GameEvent),\n $QH: () => (/* reexport */ GameStartEvent),\n i78: () => (/* reexport */ GameStopEvent),\n nJg: () => (/* reexport */ Gamepad),\n h6u: () => (/* reexport */ GamepadAxisEvent),\n hts: () => (/* reexport */ GamepadButtonEvent),\n j88: () => (/* reexport */ GamepadConnectEvent),\n VME: () => (/* reexport */ GamepadDisconnectEvent),\n fy2: () => (/* reexport */ Gamepads),\n nt: () => (/* reexport */ Gif),\n Ukr: () => (/* reexport */ GlobalCoordinates),\n zsu: () => (/* reexport */ Graphic),\n oA6: () => (/* reexport */ GraphicsComponent),\n TVh: () => (/* reexport */ GraphicsGroup),\n TwZ: () => (/* reexport */ GraphicsLayer),\n GTT: () => (/* reexport */ GraphicsLayers),\n xxj: () => (/* reexport */ GraphicsSystem),\n XdK: () => (/* reexport */ HiddenEvent),\n Jmb: () => (/* reexport */ ImageFiltering),\n cXo: () => (/* reexport */ ImageSource),\n Dm5: () => (/* reexport */ InitializeEvent),\n IIB: () => (/* reexport */ Input_Index_namespaceObject),\n ebW: () => (/* reexport */ InputMapper),\n zI0: () => (/* reexport */ Integrator),\n LYD: () => (/* reexport */ IsometricEntityComponent),\n cEG: () => (/* reexport */ IsometricEntitySystem),\n SEl: () => (/* reexport */ IsometricMap),\n t9V: () => (/* reexport */ IsometricTile),\n ez5: () => (/* reexport */ KeyEvent),\n N1d: () => (/* reexport */ Keyboard),\n R8U: () => (/* reexport */ Keys),\n SKZ: () => (/* reexport */ KillEvent),\n __J: () => (/* reexport */ Label),\n RI$: () => (/* reexport */ LimitCameraBoundsStrategy),\n x12: () => (/* reexport */ Line),\n ccz: () => (/* reexport */ LineSegment),\n aNw: () => (/* reexport */ Loader),\n XrL: () => (/* reexport */ LoaderEvents),\n xwn: () => (/* reexport */ LockCameraToActorAxisStrategy),\n dNK: () => (/* reexport */ LockCameraToActorStrategy),\n ini: () => (/* reexport */ LogLevel),\n YdH: () => (/* reexport */ Logger),\n F5T: () => (/* reexport */ Material),\n y3G: () => (/* reexport */ Matrix),\n l57: () => (/* reexport */ MatrixLocations),\n xn0: () => (/* reexport */ MediaEvent),\n t2V: () => (/* reexport */ Meet),\n uxB: () => (/* reexport */ MotionComponent),\n cpd: () => (/* reexport */ MotionSystem),\n fiy: () => (/* reexport */ MoveBy),\n $XZ: () => (/* reexport */ MoveTo),\n UG6: () => (/* reexport */ NativePointerButton),\n uqK: () => (/* reexport */ NativeSoundEvent),\n STE: () => (/* reexport */ NativeSoundProcessedEvent),\n y$z: () => (/* reexport */ Observable),\n mAD: () => (/* reexport */ OffscreenSystem),\n sOq: () => (/* reexport */ Pair),\n hUw: () => (/* reexport */ ParallaxComponent),\n _0G: () => (/* reexport */ ParallelActions),\n Sqs: () => (/* reexport */ ParseGif),\n hpZ: () => (/* reexport */ Particle),\n Vol: () => (/* reexport */ ParticleEmitter),\n vYX: () => (/* reexport */ ParticleTransform),\n wIZ: () => (/* reexport */ Physics),\n cBi: () => (/* reexport */ PhysicsStats),\n c30: () => (/* reexport */ PhysicsWorld),\n MPV: () => (/* reexport */ PointerButton),\n RFv: () => (/* reexport */ PointerComponent),\n Ux6: () => (/* reexport */ PointerEvent),\n rxy: () => (/* reexport */ PointerEventReceiver),\n I$c: () => (/* reexport */ PointerScope),\n kfC: () => (/* reexport */ PointerSystem),\n VjY: () => (/* reexport */ PointerType),\n mgq: () => (/* reexport */ Polygon),\n YVA: () => (/* reexport */ PolygonCollider),\n Kgp: () => (/* reexport */ Pool),\n HH$: () => (/* reexport */ PostCollisionEvent),\n M_d: () => (/* reexport */ PostDebugDrawEvent),\n rgh: () => (/* reexport */ PostDrawEvent),\n Ra6: () => (/* reexport */ PostFrameEvent),\n KhR: () => (/* reexport */ PostKillEvent),\n BS5: () => (/* reexport */ PostUpdateEvent),\n xhz: () => (/* reexport */ PreCollisionEvent),\n xOq: () => (/* reexport */ PreDebugDrawEvent),\n a9j: () => (/* reexport */ PreDrawEvent),\n bHk: () => (/* reexport */ PreFrameEvent),\n CgK: () => (/* reexport */ PreKillEvent),\n cuY: () => (/* reexport */ PreUpdateEvent),\n kvE: () => (/* reexport */ Projection),\n SBu: () => (/* reexport */ QuadIndexBuffer),\n AE_: () => (/* reexport */ Query),\n ctO: () => (/* reexport */ QueryManager),\n OLH: () => (/* reexport */ RadiusAroundActorStrategy),\n kky: () => (/* reexport */ Random),\n nSF: () => (/* reexport */ Raster),\n zHn: () => (/* reexport */ Ray),\n zwx: () => (/* reexport */ RealisticSolver),\n AeJ: () => (/* reexport */ Rectangle),\n hLz: () => (/* reexport */ RemovedComponent),\n D9g: () => (/* reexport */ RemovedEntity),\n wA: () => (/* reexport */ Repeat),\n jhr: () => (/* reexport */ RepeatForever),\n GVs: () => (/* reexport */ Resolution),\n _zO: () => (/* reexport */ Resource),\n LXZ: () => (/* reexport */ ResourceEvents),\n w6$: () => (/* reexport */ RotateBy),\n mhV: () => (/* reexport */ RotateTo),\n MOD: () => (/* reexport */ RotationType),\n kwd: () => (/* reexport */ ScaleBy),\n Lmr: () => (/* reexport */ ScaleTo),\n xsS: () => (/* reexport */ Scene),\n K5l: () => (/* reexport */ SceneEvents),\n lLr: () => (/* reexport */ Screen),\n Z$r: () => (/* reexport */ ScreenAppender),\n IXb: () => (/* reexport */ ScreenElement),\n SGH: () => (/* reexport */ ScreenShader),\n SMj: () => (/* reexport */ ScrollPreventionMode),\n L34: () => (/* reexport */ Semaphore),\n exe: () => (/* reexport */ Shader),\n bnF: () => (/* reexport */ Shape),\n MFA: () => (/* reexport */ Side),\n $uU: () => (/* reexport */ Sound),\n Sap: () => (/* reexport */ SoundEvents),\n jyi: () => (/* reexport */ Sprite),\n E03: () => (/* reexport */ SpriteFont),\n V6q: () => (/* reexport */ SpriteSheet),\n rg2: () => (/* reexport */ StandardClock),\n DVW: () => (/* reexport */ StateMachine),\n nVo: () => (/* reexport */ StrategyContainer),\n F6N: () => (/* reexport */ Stream),\n xP7: () => (/* reexport */ System),\n Odq: () => (/* reexport */ SystemManager),\n Zif: () => (/* reexport */ SystemType),\n ZGJ: () => (/* reexport */ TagComponent),\n MJk: () => (/* reexport */ TestClock),\n xvT: () => (/* reexport */ Text),\n PHM: () => (/* reexport */ TextAlign),\n dpR: () => (/* reexport */ TextureLoader),\n n9L: () => (/* reexport */ Tile),\n KwO: () => (/* reexport */ TileMap),\n SxM: () => (/* reexport */ TileMapEvents),\n B7y: () => (/* reexport */ Timer),\n x7r: () => (/* reexport */ Toaster),\n wx7: () => (/* reexport */ Transform),\n Uvn: () => (/* reexport */ TransformComponent),\n OFT: () => (/* reexport */ TreeNode),\n xzN: () => (/* reexport */ Trigger),\n CcZ: () => (/* reexport */ TriggerEvents),\n M5Z: () => (/* reexport */ TwoPI),\n ZrN: () => (/* reexport */ Util_Index_namespaceObject),\n OWs: () => (/* reexport */ Vector),\n dF9: () => (/* reexport */ VectorView),\n oZy: () => (/* reexport */ VertexBuffer),\n rD2: () => (/* reexport */ VertexLayout),\n VHo: () => (/* reexport */ VisibleEvent),\n ohE: () => (/* reexport */ WebAudio),\n R$E: () => (/* reexport */ WebAudioInstance),\n xQN: () => (/* reexport */ WheelDeltaMode),\n AdJ: () => (/* reexport */ WheelEvent),\n q3I: () => (/* reexport */ World),\n Pab: () => (/* reexport */ canonicalizeAngle),\n uZ5: () => (/* reexport */ clamp),\n McK: () => (/* reexport */ createId),\n F9c: () => (/* reexport */ frac),\n k0b: () => (/* reexport */ hasGraphicsTick),\n hnT: () => (/* reexport */ hasOnInitialize),\n RSJ: () => (/* reexport */ hasOnPostUpdate),\n Mku: () => (/* reexport */ hasOnPreUpdate),\n h90: () => (/* reexport */ hasPostDraw),\n rms: () => (/* reexport */ hasPreDraw),\n ErP: () => (/* reexport */ has_initialize),\n aVg: () => (/* reexport */ has_postupdate),\n lPc: () => (/* reexport */ has_preupdate),\n Z8E: () => (/* reexport */ isAddedComponent),\n _N2: () => (/* reexport */ isAddedSystemEntity),\n yFn: () => (/* reexport */ isRemoveSystemEntity),\n lNv: () => (/* reexport */ isRemovedComponent),\n cu9: () => (/* reexport */ isScreenElement),\n MZQ: () => (/* reexport */ maxMessages),\n FUM: () => (/* reexport */ obsolete),\n BxR: () => (/* reexport */ pixelSnapEpsilon),\n vdf: () => (/* reexport */ randomInRange),\n iaL: () => (/* reexport */ randomIntInRange),\n w6H: () => (/* reexport */ range),\n Q4c: () => (/* reexport */ resetObsoleteCounter),\n Xxe: () => (/* reexport */ sign),\n Uxb: () => (/* reexport */ toDegrees),\n Yr5: () => (/* reexport */ toRadians),\n Bhw: () => (/* reexport */ vec),\n yOA: () => (/* reexport */ webgl_util_namespaceObject)\n});\n\n// NAMESPACE OBJECT: ./Events.ts\nvar Events_namespaceObject = {};\n__webpack_require__.r(Events_namespaceObject);\n__webpack_require__.d(Events_namespaceObject, {\n ActivateEvent: () => (ActivateEvent),\n CollisionEndEvent: () => (CollisionEndEvent),\n CollisionPostSolveEvent: () => (CollisionPostSolveEvent),\n CollisionPreSolveEvent: () => (CollisionPreSolveEvent),\n CollisionStartEvent: () => (CollisionStartEvent),\n ContactEndEvent: () => (ContactEndEvent),\n ContactStartEvent: () => (ContactStartEvent),\n DeactivateEvent: () => (DeactivateEvent),\n EnterTriggerEvent: () => (EnterTriggerEvent),\n EnterViewPortEvent: () => (EnterViewPortEvent),\n EventTypes: () => (EventTypes),\n ExitTriggerEvent: () => (ExitTriggerEvent),\n ExitViewPortEvent: () => (ExitViewPortEvent),\n GameEvent: () => (GameEvent),\n GameStartEvent: () => (GameStartEvent),\n GameStopEvent: () => (GameStopEvent),\n GamepadAxisEvent: () => (GamepadAxisEvent),\n GamepadButtonEvent: () => (GamepadButtonEvent),\n GamepadConnectEvent: () => (GamepadConnectEvent),\n GamepadDisconnectEvent: () => (GamepadDisconnectEvent),\n HiddenEvent: () => (HiddenEvent),\n InitializeEvent: () => (InitializeEvent),\n KillEvent: () => (KillEvent),\n PostCollisionEvent: () => (PostCollisionEvent),\n PostDebugDrawEvent: () => (PostDebugDrawEvent),\n PostDrawEvent: () => (PostDrawEvent),\n PostFrameEvent: () => (PostFrameEvent),\n PostKillEvent: () => (PostKillEvent),\n PostUpdateEvent: () => (PostUpdateEvent),\n PreCollisionEvent: () => (PreCollisionEvent),\n PreDebugDrawEvent: () => (PreDebugDrawEvent),\n PreDrawEvent: () => (PreDrawEvent),\n PreFrameEvent: () => (PreFrameEvent),\n PreKillEvent: () => (PreKillEvent),\n PreUpdateEvent: () => (PreUpdateEvent),\n VisibleEvent: () => (VisibleEvent)\n});\n\n// NAMESPACE OBJECT: ./Graphics/Context/webgl-util.ts\nvar webgl_util_namespaceObject = {};\n__webpack_require__.r(webgl_util_namespaceObject);\n__webpack_require__.d(webgl_util_namespaceObject, {\n getAttributeComponentSize: () => (getAttributeComponentSize),\n getAttributePointerType: () => (getAttributePointerType),\n getGlTypeSizeBytes: () => (getGlTypeSizeBytes)\n});\n\n// NAMESPACE OBJECT: ./Util/DrawUtil.ts\nvar DrawUtil_namespaceObject = {};\n__webpack_require__.r(DrawUtil_namespaceObject);\n__webpack_require__.d(DrawUtil_namespaceObject, {\n circle: () => (circle),\n line: () => (line),\n point: () => (point),\n roundRect: () => (roundRect),\n vector: () => (vector)\n});\n\n// NAMESPACE OBJECT: ./Input/Index.ts\nvar Input_Index_namespaceObject = {};\n__webpack_require__.r(Input_Index_namespaceObject);\n__webpack_require__.d(Input_Index_namespaceObject, {\n Axes: () => (Axes),\n Buttons: () => (Buttons),\n Gamepad: () => (Gamepad),\n Gamepads: () => (Gamepads),\n KeyEvent: () => (KeyEvent),\n Keyboard: () => (Keyboard),\n Keys: () => (Keys),\n NativePointerButton: () => (NativePointerButton),\n PointerButton: () => (PointerButton),\n PointerComponent: () => (PointerComponent),\n PointerEvent: () => (PointerEvent),\n PointerEventReceiver: () => (PointerEventReceiver),\n PointerScope: () => (PointerScope),\n PointerSystem: () => (PointerSystem),\n PointerType: () => (PointerType),\n WheelDeltaMode: () => (WheelDeltaMode),\n WheelEvent: () => (WheelEvent)\n});\n\n// NAMESPACE OBJECT: ./Util/Index.ts\nvar Util_Index_namespaceObject = {};\n__webpack_require__.r(Util_Index_namespaceObject);\n__webpack_require__.d(Util_Index_namespaceObject, {\n ConsoleAppender: () => (ConsoleAppender),\n DrawUtil: () => (DrawUtil_namespaceObject),\n EasingFunctions: () => (EasingFunctions),\n LogLevel: () => (LogLevel),\n Logger: () => (Logger),\n Observable: () => (Observable),\n ScreenAppender: () => (ScreenAppender),\n addItemToArray: () => (addItemToArray),\n contains: () => (contains),\n delay: () => (delay),\n fail: () => (fail),\n getPosition: () => (getPosition),\n removeItemFromArray: () => (removeItemFromArray)\n});\n\n// EXTERNAL MODULE: ../../node_modules/core-js/es/array/sort.js\nvar sort = __webpack_require__(4662);\n// EXTERNAL MODULE: ../../node_modules/core-js/es/object/keys.js\nvar keys = __webpack_require__(8343);\n;// CONCATENATED MODULE: ./Polyfill.ts\n\r\n\r\n/**\r\n * Polyfill adding function\r\n */\r\nfunction polyfill() {\r\n /* istanbul ignore next */\r\n if (typeof window === 'undefined') {\r\n window = {\r\n audioContext: function () {\r\n return;\r\n }\r\n };\r\n }\r\n /* istanbul ignore next */\r\n if (typeof window !== 'undefined' && !window.requestAnimationFrame) {\r\n window.requestAnimationFrame =\r\n window.webkitRequestAnimationFrame ||\r\n window.mozRequestAnimationFrame ||\r\n function (callback) {\r\n window.setInterval(callback, 1000 / 60);\r\n };\r\n }\r\n /* istanbul ignore next */\r\n if (typeof window !== 'undefined' && !window.cancelAnimationFrame) {\r\n window.cancelAnimationFrame =\r\n window.webkitCancelAnimationFrame ||\r\n window.mozCancelAnimationFrame ||\r\n function () {\r\n return;\r\n };\r\n }\r\n /* istanbul ignore next */\r\n if (typeof window !== 'undefined' && !window.AudioContext) {\r\n if (window.webkitAudioContext) {\r\n const ctx = window.webkitAudioContext;\r\n const replaceMe = ctx.prototype.decodeAudioData;\r\n window.webkitAudioContext.prototype.decodeAudioData = function (arrayBuffer) {\r\n return new Promise((resolve, reject) => {\r\n replaceMe.call(this, arrayBuffer, resolve, reject);\r\n });\r\n };\r\n }\r\n window.AudioContext =\r\n window.AudioContext ||\r\n window.webkitAudioContext ||\r\n window.mozAudioContext ||\r\n window.msAudioContext ||\r\n window.oAudioContext;\r\n }\r\n /* istanbul ignore next */\r\n if (typeof window !== 'undefined' && !window.devicePixelRatio) {\r\n window.devicePixelRatio = window.devicePixelRatio || 1;\r\n }\r\n}\r\n\n;// CONCATENATED MODULE: ./Flags.ts\n/**\r\n * Flags is a feature flag implementation for Excalibur. They can only be operated **before [[Engine]] construction**\r\n * after which they are frozen and are read-only.\r\n *\r\n * Flags are used to enable experimental or preview features in Excalibur.\r\n */\r\nclass Flags {\r\n /**\r\n * Force excalibur to load the Canvas 2D graphics context fallback\r\n *\r\n * @warning not all features of excalibur are supported in the Canvas 2D fallback\r\n */\r\n static useCanvasGraphicsContext() {\r\n Flags.enable('use-canvas-context');\r\n }\r\n /**\r\n * Freeze all flag modifications making them readonly\r\n */\r\n static freeze() {\r\n Flags._FROZEN = true;\r\n }\r\n /**\r\n * Resets internal flag state, not meant to be called by users. Only used for testing.\r\n *\r\n * Calling this in your game is UNSUPPORTED\r\n * @internal\r\n */\r\n static _reset() {\r\n Flags._FROZEN = false;\r\n Flags._FLAGS = {};\r\n }\r\n /**\r\n * Enable a specific feature flag by name. **Note: can only be set before [[Engine]] constructor time**\r\n * @param flagName\r\n */\r\n static enable(flagName) {\r\n if (this._FROZEN) {\r\n throw Error('Feature flags can only be enabled before Engine constructor time');\r\n }\r\n Flags._FLAGS[flagName] = true;\r\n }\r\n /**\r\n * Disable a specific feature flag by name. **Note: can only be set before [[Engine]] constructor time**\r\n * @param flagName\r\n */\r\n static disable(flagName) {\r\n if (this._FROZEN) {\r\n throw Error('Feature flags can only be disabled before Engine constructor time');\r\n }\r\n Flags._FLAGS[flagName] = false;\r\n }\r\n /**\r\n * Check if a flag is enabled. If the flag is disabled or does not exist `false` is returned\r\n * @param flagName\r\n */\r\n static isEnabled(flagName) {\r\n return !!Flags._FLAGS[flagName];\r\n }\r\n /**\r\n * Show a list of currently known flags\r\n */\r\n static show() {\r\n return Object.keys(Flags._FLAGS);\r\n }\r\n}\r\nFlags._FROZEN = false;\r\nFlags._FLAGS = {};\r\n\n;// CONCATENATED MODULE: ./Id.ts\n/**\r\n * Create a branded ID type from a number\r\n */\r\nfunction createId(type, value) {\r\n return { type, value };\r\n}\r\n;\r\n\n;// CONCATENATED MODULE: ./EventEmitter.ts\n/**\r\n * Excalibur's typed event emitter, this allows events to be sent with any string to Type mapping\r\n */\r\nclass EventEmitter {\r\n constructor() {\r\n this._paused = false;\r\n this._listeners = {};\r\n this._listenersOnce = {};\r\n this._pipes = [];\r\n }\r\n clear() {\r\n this._listeners = {};\r\n this._listenersOnce = {};\r\n this._pipes.length = 0;\r\n }\r\n on(eventName, handler) {\r\n var _a;\r\n this._listeners[eventName] = (_a = this._listeners[eventName]) !== null && _a !== void 0 ? _a : [];\r\n this._listeners[eventName].push(handler);\r\n return {\r\n close: () => this.off(eventName, handler)\r\n };\r\n }\r\n once(eventName, handler) {\r\n var _a;\r\n this._listenersOnce[eventName] = (_a = this._listenersOnce[eventName]) !== null && _a !== void 0 ? _a : [];\r\n this._listenersOnce[eventName].push(handler);\r\n return {\r\n close: () => this.off(eventName, handler)\r\n };\r\n }\r\n off(eventName, handler) {\r\n var _a, _b, _c, _d;\r\n if (handler) {\r\n const listenerIndex = (_a = this._listeners[eventName]) === null || _a === void 0 ? void 0 : _a.indexOf(handler);\r\n if (listenerIndex > -1) {\r\n (_b = this._listeners[eventName]) === null || _b === void 0 ? void 0 : _b.splice(listenerIndex, 1);\r\n }\r\n const onceIndex = (_c = this._listenersOnce[eventName]) === null || _c === void 0 ? void 0 : _c.indexOf(handler);\r\n if (onceIndex > -1) {\r\n (_d = this._listenersOnce[eventName]) === null || _d === void 0 ? void 0 : _d.splice(onceIndex, 1);\r\n }\r\n }\r\n else {\r\n delete this._listeners[eventName];\r\n }\r\n }\r\n emit(eventName, event) {\r\n var _a;\r\n if (this._paused) {\r\n return;\r\n }\r\n (_a = this._listeners[eventName]) === null || _a === void 0 ? void 0 : _a.forEach((fn) => fn(event));\r\n const onces = this._listenersOnce[eventName];\r\n this._listenersOnce[eventName] = [];\r\n if (onces) {\r\n onces.forEach((fn) => fn(event));\r\n }\r\n this._pipes.forEach((pipe) => {\r\n pipe.emit(eventName, event);\r\n });\r\n }\r\n pipe(emitter) {\r\n if (this === emitter) {\r\n throw Error('Cannot pipe to self');\r\n }\r\n this._pipes.push(emitter);\r\n return {\r\n close: () => {\r\n const i = this._pipes.indexOf(emitter);\r\n if (i > -1) {\r\n this._pipes.splice(i, 1);\r\n }\r\n }\r\n };\r\n }\r\n unpipe(emitter) {\r\n const i = this._pipes.indexOf(emitter);\r\n if (i > -1) {\r\n this._pipes.splice(i, 1);\r\n }\r\n }\r\n pause() {\r\n this._paused = true;\r\n }\r\n unpause() {\r\n this._paused = false;\r\n }\r\n}\r\n\n;// CONCATENATED MODULE: ./Events.ts\nvar EventTypes;\r\n(function (EventTypes) {\r\n EventTypes[\"Kill\"] = \"kill\";\r\n EventTypes[\"PreKill\"] = \"prekill\";\r\n EventTypes[\"PostKill\"] = \"postkill\";\r\n EventTypes[\"PreDraw\"] = \"predraw\";\r\n EventTypes[\"PostDraw\"] = \"postdraw\";\r\n EventTypes[\"PreDebugDraw\"] = \"predebugdraw\";\r\n EventTypes[\"PostDebugDraw\"] = \"postdebugdraw\";\r\n EventTypes[\"PreUpdate\"] = \"preupdate\";\r\n EventTypes[\"PostUpdate\"] = \"postupdate\";\r\n EventTypes[\"PreFrame\"] = \"preframe\";\r\n EventTypes[\"PostFrame\"] = \"postframe\";\r\n EventTypes[\"PreCollision\"] = \"precollision\";\r\n EventTypes[\"CollisionStart\"] = \"collisionstart\";\r\n EventTypes[\"CollisionEnd\"] = \"collisionend\";\r\n EventTypes[\"PostCollision\"] = \"postcollision\";\r\n EventTypes[\"Initialize\"] = \"initialize\";\r\n EventTypes[\"Activate\"] = \"activate\";\r\n EventTypes[\"Deactivate\"] = \"deactivate\";\r\n EventTypes[\"ExitViewport\"] = \"exitviewport\";\r\n EventTypes[\"EnterViewport\"] = \"enterviewport\";\r\n EventTypes[\"ExitTrigger\"] = \"exit\";\r\n EventTypes[\"EnterTrigger\"] = \"enter\";\r\n EventTypes[\"Connect\"] = \"connect\";\r\n EventTypes[\"Disconnect\"] = \"disconnect\";\r\n EventTypes[\"Button\"] = \"button\";\r\n EventTypes[\"Axis\"] = \"axis\";\r\n EventTypes[\"Visible\"] = \"visible\";\r\n EventTypes[\"Hidden\"] = \"hidden\";\r\n EventTypes[\"Start\"] = \"start\";\r\n EventTypes[\"Stop\"] = \"stop\";\r\n EventTypes[\"PointerUp\"] = \"pointerup\";\r\n EventTypes[\"PointerDown\"] = \"pointerdown\";\r\n EventTypes[\"PointerMove\"] = \"pointermove\";\r\n EventTypes[\"PointerEnter\"] = \"pointerenter\";\r\n EventTypes[\"PointerLeave\"] = \"pointerleave\";\r\n EventTypes[\"PointerCancel\"] = \"pointercancel\";\r\n EventTypes[\"PointerWheel\"] = \"pointerwheel\";\r\n EventTypes[\"Up\"] = \"up\";\r\n EventTypes[\"Down\"] = \"down\";\r\n EventTypes[\"Move\"] = \"move\";\r\n EventTypes[\"Enter\"] = \"enter\";\r\n EventTypes[\"Leave\"] = \"leave\";\r\n EventTypes[\"Cancel\"] = \"cancel\";\r\n EventTypes[\"Wheel\"] = \"wheel\";\r\n EventTypes[\"Press\"] = \"press\";\r\n EventTypes[\"Release\"] = \"release\";\r\n EventTypes[\"Hold\"] = \"hold\";\r\n EventTypes[\"PointerDragStart\"] = \"pointerdragstart\";\r\n EventTypes[\"PointerDragEnd\"] = \"pointerdragend\";\r\n EventTypes[\"PointerDragEnter\"] = \"pointerdragenter\";\r\n EventTypes[\"PointerDragLeave\"] = \"pointerdragleave\";\r\n EventTypes[\"PointerDragMove\"] = \"pointerdragmove\";\r\n})(EventTypes || (EventTypes = {}));\r\n/**\r\n * Base event type in Excalibur that all other event types derive from. Not all event types are thrown on all Excalibur game objects,\r\n * some events are unique to a type, others are not.\r\n *\r\n */\r\nclass GameEvent {\r\n constructor() {\r\n this._bubbles = true;\r\n }\r\n /**\r\n * If set to false, prevents event from propagating to other actors. If true it will be propagated\r\n * to all actors that apply.\r\n */\r\n get bubbles() {\r\n return this._bubbles;\r\n }\r\n set bubbles(value) {\r\n this._bubbles = value;\r\n }\r\n /**\r\n * Prevents event from bubbling\r\n */\r\n stopPropagation() {\r\n this.bubbles = false;\r\n }\r\n}\r\n/**\r\n * The 'kill' event is emitted on actors when it is killed. The target is the actor that was killed.\r\n */\r\nclass KillEvent extends GameEvent {\r\n constructor(target) {\r\n super();\r\n this.target = target;\r\n }\r\n}\r\n/**\r\n * The 'prekill' event is emitted directly before an actor is killed.\r\n */\r\nclass PreKillEvent extends GameEvent {\r\n constructor(target) {\r\n super();\r\n this.target = target;\r\n }\r\n}\r\n/**\r\n * The 'postkill' event is emitted directly after the actor is killed.\r\n */\r\nclass PostKillEvent extends GameEvent {\r\n constructor(target) {\r\n super();\r\n this.target = target;\r\n }\r\n}\r\n/**\r\n * The 'start' event is emitted on engine when has started and is ready for interaction.\r\n */\r\nclass GameStartEvent extends GameEvent {\r\n constructor(target) {\r\n super();\r\n this.target = target;\r\n }\r\n}\r\n/**\r\n * The 'stop' event is emitted on engine when has been stopped and will no longer take input, update or draw.\r\n */\r\nclass GameStopEvent extends GameEvent {\r\n constructor(target) {\r\n super();\r\n this.target = target;\r\n }\r\n}\r\n/**\r\n * The 'predraw' event is emitted on actors, scenes, and engine before drawing starts. Actors' predraw happens inside their graphics\r\n * transform so that all drawing takes place with the actor as the origin.\r\n *\r\n */\r\nclass PreDrawEvent extends GameEvent {\r\n constructor(ctx, delta, target) {\r\n super();\r\n this.ctx = ctx;\r\n this.delta = delta;\r\n this.target = target;\r\n }\r\n}\r\n/**\r\n * The 'postdraw' event is emitted on actors, scenes, and engine after drawing finishes. Actors' postdraw happens inside their graphics\r\n * transform so that all drawing takes place with the actor as the origin.\r\n *\r\n */\r\nclass PostDrawEvent extends GameEvent {\r\n constructor(ctx, delta, target) {\r\n super();\r\n this.ctx = ctx;\r\n this.delta = delta;\r\n this.target = target;\r\n }\r\n}\r\n/**\r\n * The 'predebugdraw' event is emitted on actors, scenes, and engine before debug drawing starts.\r\n */\r\nclass PreDebugDrawEvent extends GameEvent {\r\n constructor(ctx, target) {\r\n super();\r\n this.ctx = ctx;\r\n this.target = target;\r\n }\r\n}\r\n/**\r\n * The 'postdebugdraw' event is emitted on actors, scenes, and engine after debug drawing starts.\r\n */\r\nclass PostDebugDrawEvent extends GameEvent {\r\n constructor(ctx, target) {\r\n super();\r\n this.ctx = ctx;\r\n this.target = target;\r\n }\r\n}\r\n/**\r\n * The 'preupdate' event is emitted on actors, scenes, camera, and engine before the update starts.\r\n */\r\nclass PreUpdateEvent extends GameEvent {\r\n constructor(engine, delta, target) {\r\n super();\r\n this.engine = engine;\r\n this.delta = delta;\r\n this.target = target;\r\n }\r\n}\r\n/**\r\n * The 'postupdate' event is emitted on actors, scenes, camera, and engine after the update ends.\r\n */\r\nclass PostUpdateEvent extends GameEvent {\r\n constructor(engine, delta, target) {\r\n super();\r\n this.engine = engine;\r\n this.delta = delta;\r\n this.target = target;\r\n }\r\n}\r\n/**\r\n * The 'preframe' event is emitted on the engine, before the frame begins.\r\n */\r\nclass PreFrameEvent extends GameEvent {\r\n constructor(engine, prevStats) {\r\n super();\r\n this.engine = engine;\r\n this.prevStats = prevStats;\r\n this.target = engine;\r\n }\r\n}\r\n/**\r\n * The 'postframe' event is emitted on the engine, after a frame ends.\r\n */\r\nclass PostFrameEvent extends GameEvent {\r\n constructor(engine, stats) {\r\n super();\r\n this.engine = engine;\r\n this.stats = stats;\r\n this.target = engine;\r\n }\r\n}\r\n/**\r\n * Event received when a gamepad is connected to Excalibur. [[Gamepads]] receives this event.\r\n */\r\nclass GamepadConnectEvent extends GameEvent {\r\n constructor(index, gamepad) {\r\n super();\r\n this.index = index;\r\n this.gamepad = gamepad;\r\n this.target = gamepad;\r\n }\r\n}\r\n/**\r\n * Event received when a gamepad is disconnected from Excalibur. [[Gamepads]] receives this event.\r\n */\r\nclass GamepadDisconnectEvent extends GameEvent {\r\n constructor(index, gamepad) {\r\n super();\r\n this.index = index;\r\n this.gamepad = gamepad;\r\n this.target = gamepad;\r\n }\r\n}\r\n/**\r\n * Gamepad button event. See [[Gamepads]] for information on responding to controller input. [[Gamepad]] instances receive this event;\r\n */\r\nclass GamepadButtonEvent extends GameEvent {\r\n /**\r\n * @param button The Gamepad button\r\n * @param value A numeric value between 0 and 1\r\n */\r\n constructor(button, value, target) {\r\n super();\r\n this.button = button;\r\n this.value = value;\r\n this.target = target;\r\n }\r\n}\r\n/**\r\n * Gamepad axis event. See [[Gamepads]] for information on responding to controller input. [[Gamepad]] instances receive this event;\r\n */\r\nclass GamepadAxisEvent extends GameEvent {\r\n /**\r\n * @param axis The Gamepad axis\r\n * @param value A numeric value between -1 and 1\r\n */\r\n constructor(axis, value, target) {\r\n super();\r\n this.axis = axis;\r\n this.value = value;\r\n this.target = target;\r\n }\r\n}\r\n/**\r\n * Event received by the [[Engine]] when the browser window is visible on a screen.\r\n */\r\nclass VisibleEvent extends GameEvent {\r\n constructor(target) {\r\n super();\r\n this.target = target;\r\n }\r\n}\r\n/**\r\n * Event received by the [[Engine]] when the browser window is hidden from all screens.\r\n */\r\nclass HiddenEvent extends GameEvent {\r\n constructor(target) {\r\n super();\r\n this.target = target;\r\n }\r\n}\r\n/**\r\n * Event thrown on an [[Actor|actor]] when a collision will occur this frame if it resolves\r\n */\r\nclass PreCollisionEvent extends GameEvent {\r\n /**\r\n * @param actor The actor the event was thrown on\r\n * @param other The actor that will collided with the current actor\r\n * @param side The side that will be collided with the current actor\r\n * @param intersection Intersection vector\r\n */\r\n constructor(actor, other, side, intersection) {\r\n super();\r\n this.other = other;\r\n this.side = side;\r\n this.intersection = intersection;\r\n this.target = actor;\r\n }\r\n}\r\n/**\r\n * Event thrown on an [[Actor|actor]] when a collision has been resolved (body reacted) this frame\r\n */\r\nclass PostCollisionEvent extends GameEvent {\r\n /**\r\n * @param actor The actor the event was thrown on\r\n * @param other The actor that did collide with the current actor\r\n * @param side The side that did collide with the current actor\r\n * @param intersection Intersection vector\r\n */\r\n constructor(actor, other, side, intersection) {\r\n super();\r\n this.other = other;\r\n this.side = side;\r\n this.intersection = intersection;\r\n this.target = actor;\r\n }\r\n get actor() {\r\n return this.target;\r\n }\r\n set actor(actor) {\r\n this.target = actor;\r\n }\r\n}\r\nclass ContactStartEvent {\r\n constructor(target, other, contact) {\r\n this.target = target;\r\n this.other = other;\r\n this.contact = contact;\r\n }\r\n}\r\nclass ContactEndEvent {\r\n constructor(target, other) {\r\n this.target = target;\r\n this.other = other;\r\n }\r\n}\r\nclass CollisionPreSolveEvent {\r\n constructor(target, other, side, intersection, contact) {\r\n this.target = target;\r\n this.other = other;\r\n this.side = side;\r\n this.intersection = intersection;\r\n this.contact = contact;\r\n }\r\n}\r\nclass CollisionPostSolveEvent {\r\n constructor(target, other, side, intersection, contact) {\r\n this.target = target;\r\n this.other = other;\r\n this.side = side;\r\n this.intersection = intersection;\r\n this.contact = contact;\r\n }\r\n}\r\n/**\r\n * Event thrown the first time an [[Actor|actor]] collides with another, after an actor is in contact normal collision events are fired.\r\n */\r\nclass CollisionStartEvent extends GameEvent {\r\n /**\r\n *\r\n * @param actor\r\n * @param other\r\n * @param contact\r\n */\r\n constructor(actor, other, contact) {\r\n super();\r\n this.other = other;\r\n this.contact = contact;\r\n this.target = actor;\r\n }\r\n get actor() {\r\n return this.target;\r\n }\r\n set actor(actor) {\r\n this.target = actor;\r\n }\r\n}\r\n/**\r\n * Event thrown when the [[Actor|actor]] is no longer colliding with another\r\n */\r\nclass CollisionEndEvent extends GameEvent {\r\n /**\r\n *\r\n */\r\n constructor(actor, other) {\r\n super();\r\n this.other = other;\r\n this.target = actor;\r\n }\r\n get actor() {\r\n return this.target;\r\n }\r\n set actor(actor) {\r\n this.target = actor;\r\n }\r\n}\r\n/**\r\n * Event thrown on an [[Actor]], [[Scene]], and [[Engine]] only once before the first update call\r\n */\r\nclass InitializeEvent extends GameEvent {\r\n /**\r\n * @param engine The reference to the current engine\r\n */\r\n constructor(engine, target) {\r\n super();\r\n this.engine = engine;\r\n this.target = target;\r\n }\r\n}\r\n/**\r\n * Event thrown on a [[Scene]] on activation\r\n */\r\nclass ActivateEvent extends GameEvent {\r\n /**\r\n * @param context The context for the scene activation\r\n */\r\n constructor(context, target) {\r\n super();\r\n this.context = context;\r\n this.target = target;\r\n }\r\n}\r\n/**\r\n * Event thrown on a [[Scene]] on deactivation\r\n */\r\nclass DeactivateEvent extends GameEvent {\r\n /**\r\n * @param context The context for the scene deactivation\r\n */\r\n constructor(context, target) {\r\n super();\r\n this.context = context;\r\n this.target = target;\r\n }\r\n}\r\n/**\r\n * Event thrown on an [[Actor]] when it completely leaves the screen.\r\n */\r\nclass ExitViewPortEvent extends GameEvent {\r\n constructor(target) {\r\n super();\r\n this.target = target;\r\n }\r\n}\r\n/**\r\n * Event thrown on an [[Actor]] when it completely leaves the screen.\r\n */\r\nclass EnterViewPortEvent extends GameEvent {\r\n constructor(target) {\r\n super();\r\n this.target = target;\r\n }\r\n}\r\nclass EnterTriggerEvent extends GameEvent {\r\n constructor(target, actor) {\r\n super();\r\n this.target = target;\r\n this.actor = actor;\r\n }\r\n}\r\nclass ExitTriggerEvent extends GameEvent {\r\n constructor(target, actor) {\r\n super();\r\n this.target = target;\r\n this.actor = actor;\r\n }\r\n}\r\n\n;// CONCATENATED MODULE: ./Input/Gamepad.ts\n\r\n\r\nconst GamepadEvents = {\r\n GamepadConnect: 'connect',\r\n GamepadDisconnect: 'disconnect',\r\n GamepadButton: 'button',\r\n GamepadAxis: 'axis'\r\n};\r\n/**\r\n * Excalibur leverages the HTML5 Gamepad API [where it is supported](http://caniuse.com/#feat=gamepad)\r\n * to provide controller support for your games.\r\n */\r\nclass Gamepads {\r\n constructor() {\r\n this.events = new EventEmitter();\r\n /**\r\n * Whether or not to poll for Gamepad input (default: `false`)\r\n */\r\n this.enabled = false;\r\n /**\r\n * Whether or not Gamepad API is supported\r\n */\r\n this.supported = !!navigator.getGamepads;\r\n this._gamePadTimeStamps = [0, 0, 0, 0];\r\n this._oldPads = [];\r\n this._pads = [];\r\n this._initSuccess = false;\r\n this._navigator = navigator;\r\n this._minimumConfiguration = null;\r\n }\r\n init() {\r\n if (!this.supported) {\r\n return;\r\n }\r\n if (this._initSuccess) {\r\n return;\r\n }\r\n // In Chrome, this will return 4 undefined items until a button is pressed\r\n // In FF, this will not return any items until a button is pressed\r\n this._oldPads = this._clonePads(this._navigator.getGamepads());\r\n if (this._oldPads.length && this._oldPads[0]) {\r\n this._initSuccess = true;\r\n }\r\n }\r\n /**\r\n * Sets the minimum gamepad configuration, for example {axis: 4, buttons: 4} means\r\n * this game requires at minimum 4 axis inputs and 4 buttons, this is not restrictive\r\n * all other controllers with more axis or buttons are valid as well. If no minimum\r\n * configuration is set all pads are valid.\r\n */\r\n setMinimumGamepadConfiguration(config) {\r\n this._enableAndUpdate(); // if config is used, implicitly enable\r\n this._minimumConfiguration = config;\r\n }\r\n /**\r\n * When implicitly enabled, set the enabled flag and run an update so information is updated\r\n */\r\n _enableAndUpdate() {\r\n if (!this.enabled) {\r\n this.enabled = true;\r\n this.update();\r\n }\r\n }\r\n /**\r\n * Checks a navigator gamepad against the minimum configuration if present.\r\n */\r\n _isGamepadValid(pad) {\r\n if (!this._minimumConfiguration) {\r\n return true;\r\n }\r\n if (!pad) {\r\n return false;\r\n }\r\n const axesLength = pad.axes.filter((value) => {\r\n return typeof value !== undefined;\r\n }).length;\r\n const buttonLength = pad.buttons.filter((value) => {\r\n return typeof value !== undefined;\r\n }).length;\r\n return axesLength >= this._minimumConfiguration.axis && buttonLength >= this._minimumConfiguration.buttons && pad.connected;\r\n }\r\n emit(eventName, event) {\r\n this.events.emit(eventName, event);\r\n }\r\n on(eventName, handler) {\r\n this._enableAndUpdate(); // implicitly enable\r\n return this.events.on(eventName, handler);\r\n }\r\n once(eventName, handler) {\r\n return this.events.once(eventName, handler);\r\n }\r\n off(eventName, handler) {\r\n this._enableAndUpdate(); // implicitly enable\r\n this.events.off(eventName, handler);\r\n }\r\n /**\r\n * Updates Gamepad state and publishes Gamepad events\r\n */\r\n update() {\r\n if (!this.enabled || !this.supported) {\r\n return;\r\n }\r\n this.init();\r\n const gamepads = this._navigator.getGamepads();\r\n for (let i = 0; i < gamepads.length; i++) {\r\n if (!gamepads[i]) {\r\n const gamepad = this.at(i);\r\n // If was connected, but now isn't emit the disconnect event\r\n if (gamepad.connected) {\r\n this.events.emit('disconnect', new GamepadDisconnectEvent(i, gamepad));\r\n }\r\n // Reset connection status\r\n gamepad.connected = false;\r\n continue;\r\n }\r\n else {\r\n if (!this.at(i).connected && this._isGamepadValid(gamepads[i])) {\r\n this.events.emit('connect', new GamepadConnectEvent(i, this.at(i)));\r\n }\r\n // Set connection status\r\n this.at(i).connected = true;\r\n }\r\n this.at(i).update();\r\n // Only supported in Chrome\r\n if (gamepads[i].timestamp && gamepads[i].timestamp === this._gamePadTimeStamps[i]) {\r\n continue;\r\n }\r\n this._gamePadTimeStamps[i] = gamepads[i].timestamp;\r\n // Add reference to navigator gamepad\r\n this.at(i).navigatorGamepad = gamepads[i];\r\n // Buttons\r\n let b, bi, a, ai, value;\r\n for (b in Buttons) {\r\n bi = Buttons[b];\r\n if (typeof bi === 'number') {\r\n if (gamepads[i].buttons[bi]) {\r\n value = gamepads[i].buttons[bi].value;\r\n if (value !== this._oldPads[i].getButton(bi)) {\r\n if (gamepads[i].buttons[bi].pressed) {\r\n this.at(i).updateButton(bi, value);\r\n this.at(i).events.emit('button', new GamepadButtonEvent(bi, value, this.at(i)));\r\n }\r\n else {\r\n this.at(i).updateButton(bi, 0);\r\n }\r\n }\r\n }\r\n }\r\n }\r\n // Axes\r\n for (a in Axes) {\r\n ai = Axes[a];\r\n if (typeof ai === 'number') {\r\n value = gamepads[i].axes[ai];\r\n if (value !== this._oldPads[i].getAxes(ai)) {\r\n this.at(i).updateAxes(ai, value);\r\n this.at(i).events.emit('axis', new GamepadAxisEvent(ai, value, this.at(i)));\r\n }\r\n }\r\n }\r\n this._oldPads[i] = this._clonePad(gamepads[i]);\r\n }\r\n }\r\n /**\r\n * Safely retrieves a Gamepad at a specific index and creates one if it doesn't yet exist\r\n */\r\n at(index) {\r\n this._enableAndUpdate(); // implicitly enable gamepads when at() is called\r\n if (index >= this._pads.length) {\r\n // Ensure there is a pad to retrieve\r\n for (let i = this._pads.length - 1, max = index; i < max; i++) {\r\n this._pads.push(new Gamepad());\r\n this._oldPads.push(new Gamepad());\r\n }\r\n }\r\n return this._pads[index];\r\n }\r\n /**\r\n * Returns a list of all valid gamepads that meet the minimum configuration requirement.\r\n */\r\n getValidGamepads() {\r\n this._enableAndUpdate();\r\n const result = [];\r\n for (let i = 0; i < this._pads.length; i++) {\r\n if (this._isGamepadValid(this.at(i).navigatorGamepad) && this.at(i).connected) {\r\n result.push(this.at(i));\r\n }\r\n }\r\n return result;\r\n }\r\n /**\r\n * Gets the number of connected gamepads\r\n */\r\n count() {\r\n return this._pads.filter((p) => p.connected).length;\r\n }\r\n _clonePads(pads) {\r\n const arr = [];\r\n for (let i = 0, len = pads.length; i < len; i++) {\r\n arr.push(this._clonePad(pads[i]));\r\n }\r\n return arr;\r\n }\r\n /**\r\n * Fastest way to clone a known object is to do it yourself\r\n */\r\n _clonePad(pad) {\r\n let i, len;\r\n const clonedPad = new Gamepad();\r\n if (!pad) {\r\n return clonedPad;\r\n }\r\n for (i = 0, len = pad.buttons.length; i < len; i++) {\r\n if (pad.buttons[i]) {\r\n clonedPad.updateButton(i, pad.buttons[i].value);\r\n }\r\n }\r\n for (i = 0, len = pad.axes.length; i < len; i++) {\r\n clonedPad.updateAxes(i, pad.axes[i]);\r\n }\r\n return clonedPad;\r\n }\r\n}\r\n/**\r\n * The minimum value an axis has to move before considering it a change\r\n */\r\nGamepads.MinAxisMoveThreshold = 0.05;\r\n/**\r\n * Gamepad holds state information for a connected controller. See [[Gamepads]]\r\n * for more information on handling controller input.\r\n */\r\nclass Gamepad {\r\n constructor() {\r\n this.events = new EventEmitter();\r\n this.connected = false;\r\n this._axes = new Array(4);\r\n this._buttons = new Array(16);\r\n this._buttonsUp = new Array(16);\r\n this._buttonsDown = new Array(16);\r\n for (let i = 0; i < this._buttons.length; i++) {\r\n this._buttons[i] = 0;\r\n }\r\n for (let i = 0; i < this._axes.length; i++) {\r\n this._axes[i] = 0;\r\n }\r\n }\r\n update() {\r\n // Reset buttonsDown and buttonsUp after update is complete\r\n this._buttonsDown = new Array(16);\r\n this._buttonsUp = new Array(16);\r\n }\r\n /**\r\n * Whether or not the given button is pressed\r\n *\r\n * @deprecated will be removed in v0.28.0. Use isButtonHeld instead\r\n * @param button The button to query\r\n * @param threshold The threshold over which the button is considered to be pressed\r\n */\r\n isButtonPressed(button, threshold = 1) {\r\n return this._buttons[button] >= threshold;\r\n }\r\n /**\r\n * Tests if a certain button is held down. This is persisted between frames.\r\n *\r\n * @param button The button to query\r\n * @param threshold The threshold over which the button is considered to be pressed\r\n */\r\n isButtonHeld(button, threshold = 1) {\r\n return this._buttons[button] >= threshold;\r\n }\r\n /**\r\n * Tests if a certain button was just pressed this frame. This is cleared at the end of the update frame.\r\n *\r\n * @param button Test whether a button was just pressed\r\n * @param threshold The threshold over which the button is considered to be pressed\r\n */\r\n wasButtonPressed(button, threshold = 1) {\r\n return this._buttonsDown[button] >= threshold;\r\n }\r\n /**\r\n * Tests if a certain button was just released this frame. This is cleared at the end of the update frame.\r\n *\r\n * @param button Test whether a button was just released\r\n */\r\n wasButtonReleased(button) {\r\n return Boolean(this._buttonsUp[button]);\r\n }\r\n /**\r\n * Gets the given button value between 0 and 1\r\n */\r\n getButton(button) {\r\n return this._buttons[button];\r\n }\r\n /**\r\n * Gets the given axis value between -1 and 1. Values below\r\n * [[MinAxisMoveThreshold]] are considered 0.\r\n */\r\n getAxes(axes) {\r\n const value = this._axes[axes];\r\n if (Math.abs(value) < Gamepads.MinAxisMoveThreshold) {\r\n return 0;\r\n }\r\n else {\r\n return value;\r\n }\r\n }\r\n updateButton(buttonIndex, value) {\r\n // button was just released\r\n if (value === 0 && this._buttons[buttonIndex]) {\r\n this._buttonsUp[buttonIndex] = 1;\r\n // button was just pressed\r\n }\r\n else {\r\n this._buttonsDown[buttonIndex] = value;\r\n }\r\n this._buttons[buttonIndex] = value;\r\n }\r\n updateAxes(axesIndex, value) {\r\n this._axes[axesIndex] = value;\r\n }\r\n emit(eventName, event) {\r\n this.events.emit(eventName, event);\r\n }\r\n on(eventName, handler) {\r\n return this.events.on(eventName, handler);\r\n }\r\n once(eventName, handler) {\r\n return this.events.once(eventName, handler);\r\n }\r\n off(eventName, handler) {\r\n this.events.off(eventName, handler);\r\n }\r\n}\r\n/**\r\n * Gamepad Buttons enumeration\r\n */\r\nvar Buttons;\r\n(function (Buttons) {\r\n /**\r\n * Face 1 button (e.g. A)\r\n */\r\n Buttons[Buttons[\"Face1\"] = 0] = \"Face1\";\r\n /**\r\n * Face 2 button (e.g. B)\r\n */\r\n Buttons[Buttons[\"Face2\"] = 1] = \"Face2\";\r\n /**\r\n * Face 3 button (e.g. X)\r\n */\r\n Buttons[Buttons[\"Face3\"] = 2] = \"Face3\";\r\n /**\r\n * Face 4 button (e.g. Y)\r\n */\r\n Buttons[Buttons[\"Face4\"] = 3] = \"Face4\";\r\n /**\r\n * Left bumper button\r\n */\r\n Buttons[Buttons[\"LeftBumper\"] = 4] = \"LeftBumper\";\r\n /**\r\n * Right bumper button\r\n */\r\n Buttons[Buttons[\"RightBumper\"] = 5] = \"RightBumper\";\r\n /**\r\n * Left trigger button\r\n */\r\n Buttons[Buttons[\"LeftTrigger\"] = 6] = \"LeftTrigger\";\r\n /**\r\n * Right trigger button\r\n */\r\n Buttons[Buttons[\"RightTrigger\"] = 7] = \"RightTrigger\";\r\n /**\r\n * Select button\r\n */\r\n Buttons[Buttons[\"Select\"] = 8] = \"Select\";\r\n /**\r\n * Start button\r\n */\r\n Buttons[Buttons[\"Start\"] = 9] = \"Start\";\r\n /**\r\n * Left analog stick press (e.g. L3)\r\n */\r\n Buttons[Buttons[\"LeftStick\"] = 10] = \"LeftStick\";\r\n /**\r\n * Right analog stick press (e.g. R3)\r\n */\r\n Buttons[Buttons[\"RightStick\"] = 11] = \"RightStick\";\r\n /**\r\n * D-pad up\r\n */\r\n Buttons[Buttons[\"DpadUp\"] = 12] = \"DpadUp\";\r\n /**\r\n * D-pad down\r\n */\r\n Buttons[Buttons[\"DpadDown\"] = 13] = \"DpadDown\";\r\n /**\r\n * D-pad left\r\n */\r\n Buttons[Buttons[\"DpadLeft\"] = 14] = \"DpadLeft\";\r\n /**\r\n * D-pad right\r\n */\r\n Buttons[Buttons[\"DpadRight\"] = 15] = \"DpadRight\";\r\n})(Buttons || (Buttons = {}));\r\n/**\r\n * Gamepad Axes enumeration\r\n */\r\nvar Axes;\r\n(function (Axes) {\r\n /**\r\n * Left analogue stick X direction\r\n */\r\n Axes[Axes[\"LeftStickX\"] = 0] = \"LeftStickX\";\r\n /**\r\n * Left analogue stick Y direction\r\n */\r\n Axes[Axes[\"LeftStickY\"] = 1] = \"LeftStickY\";\r\n /**\r\n * Right analogue stick X direction\r\n */\r\n Axes[Axes[\"RightStickX\"] = 2] = \"RightStickX\";\r\n /**\r\n * Right analogue stick Y direction\r\n */\r\n Axes[Axes[\"RightStickY\"] = 3] = \"RightStickY\";\r\n})(Axes || (Axes = {}));\r\n\n;// CONCATENATED MODULE: ./Util/Log.ts\n/* eslint-disable no-console */\r\n/**\r\n * Logging level that Excalibur will tag\r\n */\r\nvar LogLevel;\r\n(function (LogLevel) {\r\n LogLevel[LogLevel[\"Debug\"] = 0] = \"Debug\";\r\n LogLevel[LogLevel[\"Info\"] = 1] = \"Info\";\r\n LogLevel[LogLevel[\"Warn\"] = 2] = \"Warn\";\r\n LogLevel[LogLevel[\"Error\"] = 3] = \"Error\";\r\n LogLevel[LogLevel[\"Fatal\"] = 4] = \"Fatal\";\r\n})(LogLevel || (LogLevel = {}));\r\n/**\r\n * Static singleton that represents the logging facility for Excalibur.\r\n * Excalibur comes built-in with a [[ConsoleAppender]] and [[ScreenAppender]].\r\n * Derive from [[Appender]] to create your own logging appenders.\r\n */\r\nclass Logger {\r\n constructor() {\r\n this._appenders = [];\r\n /**\r\n * Gets or sets the default logging level. Excalibur will only log\r\n * messages if equal to or above this level. Default: [[LogLevel.Info]]\r\n */\r\n this.defaultLevel = LogLevel.Info;\r\n if (Logger._INSTANCE) {\r\n throw new Error('Logger is a singleton');\r\n }\r\n Logger._INSTANCE = this;\r\n // Default console appender\r\n Logger._INSTANCE.addAppender(new ConsoleAppender());\r\n return Logger._INSTANCE;\r\n }\r\n /**\r\n * Gets the current static instance of Logger\r\n */\r\n static getInstance() {\r\n if (Logger._INSTANCE == null) {\r\n Logger._INSTANCE = new Logger();\r\n }\r\n return Logger._INSTANCE;\r\n }\r\n /**\r\n * Adds a new [[Appender]] to the list of appenders to write to\r\n */\r\n addAppender(appender) {\r\n this._appenders.push(appender);\r\n }\r\n /**\r\n * Clears all appenders from the logger\r\n */\r\n clearAppenders() {\r\n this._appenders.length = 0;\r\n }\r\n /**\r\n * Logs a message at a given LogLevel\r\n * @param level The LogLevel`to log the message at\r\n * @param args An array of arguments to write to an appender\r\n */\r\n _log(level, args) {\r\n if (level == null) {\r\n level = this.defaultLevel;\r\n }\r\n const len = this._appenders.length;\r\n for (let i = 0; i < len; i++) {\r\n if (level >= this.defaultLevel) {\r\n this._appenders[i].log(level, args);\r\n }\r\n }\r\n }\r\n /**\r\n * Writes a log message at the [[LogLevel.Debug]] level\r\n * @param args Accepts any number of arguments\r\n */\r\n debug(...args) {\r\n this._log(LogLevel.Debug, args);\r\n }\r\n /**\r\n * Writes a log message at the [[LogLevel.Info]] level\r\n * @param args Accepts any number of arguments\r\n */\r\n info(...args) {\r\n this._log(LogLevel.Info, args);\r\n }\r\n /**\r\n * Writes a log message at the [[LogLevel.Warn]] level\r\n * @param args Accepts any number of arguments\r\n */\r\n warn(...args) {\r\n this._log(LogLevel.Warn, args);\r\n }\r\n /**\r\n * Writes a log message at the [[LogLevel.Error]] level\r\n * @param args Accepts any number of arguments\r\n */\r\n error(...args) {\r\n this._log(LogLevel.Error, args);\r\n }\r\n /**\r\n * Writes a log message at the [[LogLevel.Fatal]] level\r\n * @param args Accepts any number of arguments\r\n */\r\n fatal(...args) {\r\n this._log(LogLevel.Fatal, args);\r\n }\r\n}\r\nLogger._INSTANCE = null;\r\n/**\r\n * Console appender for browsers (i.e. `console.log`)\r\n */\r\nclass ConsoleAppender {\r\n /**\r\n * Logs a message at the given [[LogLevel]]\r\n * @param level Level to log at\r\n * @param args Arguments to log\r\n */\r\n log(level, args) {\r\n // Check for console support\r\n if (!console && !console.log && console.warn && console.error) {\r\n // todo maybe do something better than nothing\r\n return;\r\n }\r\n // Create a new console args array\r\n const consoleArgs = [];\r\n consoleArgs.unshift.apply(consoleArgs, args);\r\n consoleArgs.unshift('[' + LogLevel[level] + '] : ');\r\n if (level < LogLevel.Warn) {\r\n // Call .log for Debug/Info\r\n if (console.log.apply) {\r\n // this is required on some older browsers that don't support apply on console.log :(\r\n console.log.apply(console, consoleArgs);\r\n }\r\n else {\r\n console.log(consoleArgs.join(' '));\r\n }\r\n }\r\n else if (level < LogLevel.Error) {\r\n // Call .warn for Warn\r\n if (console.warn.apply) {\r\n console.warn.apply(console, consoleArgs);\r\n }\r\n else {\r\n console.warn(consoleArgs.join(' '));\r\n }\r\n }\r\n else {\r\n // Call .error for Error/Fatal\r\n if (console.error.apply) {\r\n console.error.apply(console, consoleArgs);\r\n }\r\n else {\r\n console.error(consoleArgs.join(' '));\r\n }\r\n }\r\n }\r\n}\r\n/**\r\n * On-screen (canvas) appender\r\n */\r\nclass ScreenAppender {\r\n /**\r\n * @param width Width of the screen appender in pixels\r\n * @param height Height of the screen appender in pixels\r\n */\r\n constructor(width, height) {\r\n // @todo Clean this up\r\n this._messages = [];\r\n this._canvas = document.createElement('canvas');\r\n this._canvas.width = width || window.innerWidth;\r\n this._canvas.height = height || window.innerHeight;\r\n this._canvas.style.position = 'absolute';\r\n // eslint-disable-next-line\r\n this._ctx = this._canvas.getContext('2d'); // eslint-disable-line\r\n document.body.appendChild(this._canvas);\r\n }\r\n /**\r\n * Logs a message at the given [[LogLevel]]\r\n * @param level Level to log at\r\n * @param args Arguments to log\r\n */\r\n log(level, args) {\r\n const message = args.join(',');\r\n this._ctx.clearRect(0, 0, this._canvas.width, this._canvas.height);\r\n this._messages.unshift('[' + LogLevel[level] + '] : ' + message);\r\n let pos = 10;\r\n let opacity = 1.0;\r\n for (let i = 0; i < this._messages.length; i++) {\r\n this._ctx.fillStyle = 'rgba(255,255,255,' + opacity.toFixed(2) + ')';\r\n this._ctx.fillText(this._messages[i], 200, pos);\r\n pos += 10;\r\n opacity = opacity > 0 ? opacity - 0.05 : 0;\r\n }\r\n }\r\n}\r\n\n;// CONCATENATED MODULE: ./Util/IFrame.ts\n/**\r\n * Checks if excalibur is in a x-origin iframe\r\n */\r\nfunction isCrossOriginIframe() {\r\n try {\r\n // Try and listen to events on top window frame if within an iframe.\r\n //\r\n // See https://github.com/excaliburjs/Excalibur/issues/1294\r\n //\r\n // Attempt to add an event listener, which triggers a DOMException on\r\n // cross-origin iframes\r\n const noop = () => {\r\n return;\r\n };\r\n window.top.addEventListener('blur', noop);\r\n window.top.removeEventListener('blur', noop);\r\n }\r\n catch (_a) {\r\n return true;\r\n }\r\n return false;\r\n}\r\n\n;// CONCATENATED MODULE: ./Input/Keyboard.ts\n\r\n\r\n\r\n\r\n/**\r\n * Enum representing physical input key codes\r\n */\r\nvar Keys;\r\n(function (Keys) {\r\n // NUMPAD\r\n Keys[\"Num0\"] = \"Numpad0\";\r\n Keys[\"Num1\"] = \"Numpad1\";\r\n Keys[\"Num2\"] = \"Numpad2\";\r\n Keys[\"Num3\"] = \"Numpad3\";\r\n Keys[\"Num4\"] = \"Numpad4\";\r\n Keys[\"Num5\"] = \"Numpad5\";\r\n Keys[\"Num6\"] = \"Numpad6\";\r\n Keys[\"Num7\"] = \"Numpad7\";\r\n Keys[\"Num8\"] = \"Numpad8\";\r\n Keys[\"Num9\"] = \"Numpad9\";\r\n Keys[\"NumAdd\"] = \"NumpadAdd\";\r\n Keys[\"NumSubtract\"] = \"NumpadSubtract\";\r\n Keys[\"NumMultiply\"] = \"NumpadMultiply\";\r\n Keys[\"NumDivide\"] = \"NumpadDivide\";\r\n // NumComma = 'NumpadComma', // not x-browser\r\n Keys[\"NumDecimal\"] = \"NumpadDecimal\";\r\n Keys[\"Numpad0\"] = \"Numpad0\";\r\n Keys[\"Numpad1\"] = \"Numpad1\";\r\n Keys[\"Numpad2\"] = \"Numpad2\";\r\n Keys[\"Numpad3\"] = \"Numpad3\";\r\n Keys[\"Numpad4\"] = \"Numpad4\";\r\n Keys[\"Numpad5\"] = \"Numpad5\";\r\n Keys[\"Numpad6\"] = \"Numpad6\";\r\n Keys[\"Numpad7\"] = \"Numpad7\";\r\n Keys[\"Numpad8\"] = \"Numpad8\";\r\n Keys[\"Numpad9\"] = \"Numpad9\";\r\n Keys[\"NumpadAdd\"] = \"NumpadAdd\";\r\n Keys[\"NumpadSubtract\"] = \"NumpadSubtract\";\r\n Keys[\"NumpadMultiply\"] = \"NumpadMultiply\";\r\n Keys[\"NumpadDivide\"] = \"NumpadDivide\";\r\n // NumpadComma = 'NumpadComma', // not x-browser\r\n Keys[\"NumpadDecimal\"] = \"NumpadDecimal\";\r\n // MODIFIERS\r\n Keys[\"NumLock\"] = \"NumLock\";\r\n Keys[\"ShiftLeft\"] = \"ShiftLeft\";\r\n Keys[\"ShiftRight\"] = \"ShiftRight\";\r\n Keys[\"AltLeft\"] = \"AltLeft\";\r\n Keys[\"AltRight\"] = \"AltRight\";\r\n Keys[\"ControlLeft\"] = \"ControlLeft\";\r\n Keys[\"ControlRight\"] = \"ControlRight\";\r\n Keys[\"MetaLeft\"] = \"MetaLeft\";\r\n Keys[\"MetaRight\"] = \"MetaRight\";\r\n // NUMBERS\r\n Keys[\"Key0\"] = \"Digit0\";\r\n Keys[\"Key1\"] = \"Digit1\";\r\n Keys[\"Key2\"] = \"Digit2\";\r\n Keys[\"Key3\"] = \"Digit3\";\r\n Keys[\"Key4\"] = \"Digit4\";\r\n Keys[\"Key5\"] = \"Digit5\";\r\n Keys[\"Key6\"] = \"Digit6\";\r\n Keys[\"Key7\"] = \"Digit7\";\r\n Keys[\"Key8\"] = \"Digit8\";\r\n Keys[\"Key9\"] = \"Digit9\";\r\n Keys[\"Digit0\"] = \"Digit0\";\r\n Keys[\"Digit1\"] = \"Digit1\";\r\n Keys[\"Digit2\"] = \"Digit2\";\r\n Keys[\"Digit3\"] = \"Digit3\";\r\n Keys[\"Digit4\"] = \"Digit4\";\r\n Keys[\"Digit5\"] = \"Digit5\";\r\n Keys[\"Digit6\"] = \"Digit6\";\r\n Keys[\"Digit7\"] = \"Digit7\";\r\n Keys[\"Digit8\"] = \"Digit8\";\r\n Keys[\"Digit9\"] = \"Digit9\";\r\n // FUNCTION KEYS\r\n Keys[\"F1\"] = \"F1\";\r\n Keys[\"F2\"] = \"F2\";\r\n Keys[\"F3\"] = \"F3\";\r\n Keys[\"F4\"] = \"F4\";\r\n Keys[\"F5\"] = \"F5\";\r\n Keys[\"F6\"] = \"F6\";\r\n Keys[\"F7\"] = \"F7\";\r\n Keys[\"F8\"] = \"F8\";\r\n Keys[\"F9\"] = \"F9\";\r\n Keys[\"F10\"] = \"F10\";\r\n Keys[\"F11\"] = \"F11\";\r\n Keys[\"F12\"] = \"F12\";\r\n // LETTERS\r\n Keys[\"A\"] = \"KeyA\";\r\n Keys[\"B\"] = \"KeyB\";\r\n Keys[\"C\"] = \"KeyC\";\r\n Keys[\"D\"] = \"KeyD\";\r\n Keys[\"E\"] = \"KeyE\";\r\n Keys[\"F\"] = \"KeyF\";\r\n Keys[\"G\"] = \"KeyG\";\r\n Keys[\"H\"] = \"KeyH\";\r\n Keys[\"I\"] = \"KeyI\";\r\n Keys[\"J\"] = \"KeyJ\";\r\n Keys[\"K\"] = \"KeyK\";\r\n Keys[\"L\"] = \"KeyL\";\r\n Keys[\"M\"] = \"KeyM\";\r\n Keys[\"N\"] = \"KeyN\";\r\n Keys[\"O\"] = \"KeyO\";\r\n Keys[\"P\"] = \"KeyP\";\r\n Keys[\"Q\"] = \"KeyQ\";\r\n Keys[\"R\"] = \"KeyR\";\r\n Keys[\"S\"] = \"KeyS\";\r\n Keys[\"T\"] = \"KeyT\";\r\n Keys[\"U\"] = \"KeyU\";\r\n Keys[\"V\"] = \"KeyV\";\r\n Keys[\"W\"] = \"KeyW\";\r\n Keys[\"X\"] = \"KeyX\";\r\n Keys[\"Y\"] = \"KeyY\";\r\n Keys[\"Z\"] = \"KeyZ\";\r\n Keys[\"KeyA\"] = \"KeyA\";\r\n Keys[\"KeyB\"] = \"KeyB\";\r\n Keys[\"KeyC\"] = \"KeyC\";\r\n Keys[\"KeyD\"] = \"KeyD\";\r\n Keys[\"KeyE\"] = \"KeyE\";\r\n Keys[\"KeyF\"] = \"KeyF\";\r\n Keys[\"KeyG\"] = \"KeyG\";\r\n Keys[\"KeyH\"] = \"KeyH\";\r\n Keys[\"KeyI\"] = \"KeyI\";\r\n Keys[\"KeyJ\"] = \"KeyJ\";\r\n Keys[\"KeyK\"] = \"KeyK\";\r\n Keys[\"KeyL\"] = \"KeyL\";\r\n Keys[\"KeyM\"] = \"KeyM\";\r\n Keys[\"KeyN\"] = \"KeyN\";\r\n Keys[\"KeyO\"] = \"KeyO\";\r\n Keys[\"KeyP\"] = \"KeyP\";\r\n Keys[\"KeyQ\"] = \"KeyQ\";\r\n Keys[\"KeyR\"] = \"KeyR\";\r\n Keys[\"KeyS\"] = \"KeyS\";\r\n Keys[\"KeyT\"] = \"KeyT\";\r\n Keys[\"KeyU\"] = \"KeyU\";\r\n Keys[\"KeyV\"] = \"KeyV\";\r\n Keys[\"KeyW\"] = \"KeyW\";\r\n Keys[\"KeyX\"] = \"KeyX\";\r\n Keys[\"KeyY\"] = \"KeyY\";\r\n Keys[\"KeyZ\"] = \"KeyZ\";\r\n // SYMBOLS\r\n Keys[\"Semicolon\"] = \"Semicolon\";\r\n Keys[\"Quote\"] = \"Quote\";\r\n Keys[\"Comma\"] = \"Comma\";\r\n Keys[\"Minus\"] = \"Minus\";\r\n Keys[\"Period\"] = \"Period\";\r\n Keys[\"Slash\"] = \"Slash\";\r\n Keys[\"Equal\"] = \"Equal\";\r\n Keys[\"BracketLeft\"] = \"BracketLeft\";\r\n Keys[\"Backslash\"] = \"Backslash\";\r\n Keys[\"BracketRight\"] = \"BracketRight\";\r\n Keys[\"Backquote\"] = \"Backquote\";\r\n // DIRECTIONS\r\n Keys[\"Up\"] = \"ArrowUp\";\r\n Keys[\"Down\"] = \"ArrowDown\";\r\n Keys[\"Left\"] = \"ArrowLeft\";\r\n Keys[\"Right\"] = \"ArrowRight\";\r\n Keys[\"ArrowUp\"] = \"ArrowUp\";\r\n Keys[\"ArrowDown\"] = \"ArrowDown\";\r\n Keys[\"ArrowLeft\"] = \"ArrowLeft\";\r\n Keys[\"ArrowRight\"] = \"ArrowRight\";\r\n // OTHER\r\n Keys[\"Space\"] = \"Space\";\r\n Keys[\"Backspace\"] = \"Backspace\";\r\n Keys[\"Delete\"] = \"Delete\";\r\n Keys[\"Esc\"] = \"Escape\";\r\n Keys[\"Escape\"] = \"Escape\";\r\n Keys[\"Enter\"] = \"Enter\";\r\n Keys[\"NumpadEnter\"] = \"NumpadEnter\";\r\n Keys[\"ContextMenu\"] = \"ContextMenu\";\r\n})(Keys || (Keys = {}));\r\n/**\r\n * Event thrown on a game object for a key event\r\n */\r\nclass KeyEvent extends GameEvent {\r\n /**\r\n * @param key The key responsible for throwing the event\r\n * @param value The key's typed value the browser detected\r\n * @param originalEvent The original keyboard event that Excalibur handled\r\n */\r\n constructor(key, value, originalEvent) {\r\n super();\r\n this.key = key;\r\n this.value = value;\r\n this.originalEvent = originalEvent;\r\n }\r\n}\r\nconst KeyEvents = {\r\n Press: 'press',\r\n Hold: 'hold',\r\n Release: 'release'\r\n};\r\n/**\r\n * Provides keyboard support for Excalibur.\r\n */\r\nclass Keyboard {\r\n constructor() {\r\n this.events = new EventEmitter();\r\n /**\r\n * Keys that are currently held down\r\n */\r\n this._keys = [];\r\n /**\r\n * Keys up in the current frame\r\n */\r\n this._keysUp = [];\r\n /**\r\n * Keys down in the current frame\r\n */\r\n this._keysDown = [];\r\n this._releaseAllKeys = (ev) => {\r\n for (const code of this._keys) {\r\n const keyEvent = new KeyEvent(code, ev.key, ev);\r\n this.events.emit('up', keyEvent);\r\n this.events.emit('release', keyEvent);\r\n }\r\n this._keysUp = Array.from((new Set(this._keys.concat(this._keysUp))));\r\n this._keys.length = 0;\r\n };\r\n this._handleKeyDown = (ev) => {\r\n // handle macos meta key issue\r\n // https://github.com/excaliburjs/Excalibur/issues/2608\r\n if (!ev.metaKey && (this._keys.includes(Keys.MetaLeft) || this._keys.includes(Keys.MetaRight))) {\r\n this._releaseAllKeys(ev);\r\n }\r\n const code = ev.code;\r\n if (this._keys.indexOf(code) === -1) {\r\n this._keys.push(code);\r\n this._keysDown.push(code);\r\n const keyEvent = new KeyEvent(code, ev.key, ev);\r\n this.events.emit('down', keyEvent);\r\n this.events.emit('press', keyEvent);\r\n }\r\n };\r\n this._handleKeyUp = (ev) => {\r\n const code = ev.code;\r\n const key = this._keys.indexOf(code);\r\n this._keys.splice(key, 1);\r\n this._keysUp.push(code);\r\n const keyEvent = new KeyEvent(code, ev.key, ev);\r\n // alias the old api, we may want to deprecate this in the future\r\n this.events.emit('up', keyEvent);\r\n this.events.emit('release', keyEvent);\r\n // handle macos meta key issue\r\n // https://github.com/excaliburjs/Excalibur/issues/2608\r\n if (ev.key === 'Meta') {\r\n this._releaseAllKeys(ev);\r\n }\r\n };\r\n }\r\n emit(eventName, event) {\r\n this.events.emit(eventName, event);\r\n }\r\n on(eventName, handler) {\r\n return this.events.on(eventName, handler);\r\n }\r\n once(eventName, handler) {\r\n return this.events.once(eventName, handler);\r\n }\r\n off(eventName, handler) {\r\n this.events.off(eventName, handler);\r\n }\r\n /**\r\n * Initialize Keyboard event listeners\r\n */\r\n init(keyboardOptions) {\r\n let { global } = keyboardOptions;\r\n const { grabWindowFocus } = keyboardOptions;\r\n if (!global) {\r\n if (isCrossOriginIframe()) {\r\n global = window;\r\n // Workaround for iframes like for itch.io or codesandbox\r\n // https://www.reddit.com/r/gamemaker/comments/kfs5cs/keyboard_inputs_no_longer_working_in_html5_game/\r\n // https://forum.gamemaker.io/index.php?threads/solved-keyboard-issue-on-itch-io.87336/\r\n if (grabWindowFocus) {\r\n window.focus();\r\n }\r\n Logger.getInstance().warn('Excalibur might be in a cross-origin iframe, in order to receive keyboard events it must be in focus');\r\n }\r\n else {\r\n global = window.top;\r\n }\r\n }\r\n global.addEventListener('blur', () => {\r\n this._keys.length = 0; // empties array efficiently\r\n });\r\n // key up is on window because canvas cannot have focus\r\n global.addEventListener('keyup', this._handleKeyUp);\r\n // key down is on window because canvas cannot have focus\r\n global.addEventListener('keydown', this._handleKeyDown);\r\n }\r\n update() {\r\n // Reset keysDown and keysUp after update is complete\r\n this._keysDown.length = 0;\r\n this._keysUp.length = 0;\r\n // Emit synthetic \"hold\" event\r\n for (let i = 0; i < this._keys.length; i++) {\r\n this.events.emit('hold', new KeyEvent(this._keys[i]));\r\n }\r\n }\r\n /**\r\n * Gets list of keys being pressed down\r\n */\r\n getKeys() {\r\n return this._keys;\r\n }\r\n /**\r\n * Tests if a certain key was just pressed this frame. This is cleared at the end of the update frame.\r\n * @param key Test whether a key was just pressed\r\n */\r\n wasPressed(key) {\r\n return this._keysDown.indexOf(key) > -1;\r\n }\r\n /**\r\n * Tests if a certain key is held down. This is persisted between frames.\r\n * @param key Test whether a key is held down\r\n */\r\n isHeld(key) {\r\n return this._keys.indexOf(key) > -1;\r\n }\r\n /**\r\n * Tests if a certain key was just released this frame. This is cleared at the end of the update frame.\r\n * @param key Test whether a key was just released\r\n */\r\n wasReleased(key) {\r\n return this._keysUp.indexOf(key) > -1;\r\n }\r\n /**\r\n * Trigger a manual key event\r\n * @param type\r\n * @param key\r\n * @param character\r\n */\r\n triggerEvent(type, key, character) {\r\n if (type === 'down') {\r\n this._handleKeyDown(new KeyboardEvent('keydown', {\r\n code: key,\r\n key: character !== null && character !== void 0 ? character : null\r\n }));\r\n }\r\n if (type === 'up') {\r\n this._handleKeyUp(new KeyboardEvent('keyup', {\r\n code: key,\r\n key: character !== null && character !== void 0 ? character : null\r\n }));\r\n }\r\n }\r\n}\r\n\n;// CONCATENATED MODULE: ./Input/PointerScope.ts\n/**\r\n * Determines the scope of handling mouse/touch events.\r\n */\r\nvar PointerScope;\r\n(function (PointerScope) {\r\n /**\r\n * Handle events on the `canvas` element only. Events originating outside the\r\n * `canvas` will not be handled.\r\n */\r\n PointerScope[\"Canvas\"] = \"Canvas\";\r\n /**\r\n * Handles events on the entire document. All events will be handled by Excalibur.\r\n */\r\n PointerScope[\"Document\"] = \"Document\";\r\n})(PointerScope || (PointerScope = {}));\r\n\n;// CONCATENATED MODULE: ./Math/Random.ts\n/**\r\n * @module\r\n * Pseudo-Random Utility\r\n *\r\n * A pseudo-random utility to add seeded random support for help in\r\n * generating things like terrain or reproducible randomness. Uses the\r\n * [Mersenne Twister](https://en.wikipedia.org/wiki/Mersenne_Twister) algorithm.\r\n */\r\n/**\r\n * 32-bit mask\r\n */\r\nconst BITMASK32 = 0xffffffff;\r\n/**\r\n * Pseudo-random number generator following the Mersenne_Twister algorithm. Given a seed this generator will produce the same sequence\r\n * of numbers each time it is called.\r\n * See https://en.wikipedia.org/wiki/Mersenne_Twister for more details.\r\n * Uses the MT19937-32 (2002) implementation documented here http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/MT2002/emt19937ar.html\r\n *\r\n * Api inspired by http://chancejs.com/# https://github.com/chancejs/chancejs\r\n */\r\nclass Random {\r\n /**\r\n * If no seed is specified, the Date.now() is used\r\n */\r\n constructor(seed) {\r\n this.seed = seed;\r\n // Separation point of one one word, the number of bits in the lower bitmask 0 <= r <= w-1\r\n this._lowerMask = 0x7fffffff; // 31 bits same as _r\r\n this._upperMask = 0x80000000; // 34 high bits\r\n // Word size, 64 bits\r\n this._w = 32;\r\n // Degree of recurrence\r\n this._n = 624;\r\n // Middle word, an offset used in the recurrence defining the series x, 1<=m>> 0;\r\n for (let i = 1; i < this._n; i++) {\r\n const s = this._mt[i - 1] ^ (this._mt[i - 1] >>> (this._w - 2));\r\n // numbers are bigger than the JS max safe int, add in 16-bit chunks to prevent IEEE rounding errors on high bits\r\n this._mt[i] = (((this._f * ((s & 0xffff0000) >>> 16)) << 16) + this._f * (s & 0xffff) + i) >>> 0;\r\n }\r\n this._index = this._n;\r\n }\r\n /**\r\n * Apply the twist\r\n */\r\n _twist() {\r\n const mag01 = [0x0, this._a];\r\n let y = 0, i = 0;\r\n for (; i < this._n - this._m; i++) {\r\n y = (this._mt[i] & this._upperMask) | (this._mt[i + 1] & this._lowerMask);\r\n this._mt[i] = this._mt[i + this._m] ^ (y >>> 1) ^ (mag01[y & 0x1] & BITMASK32);\r\n }\r\n for (; i < this._n - 1; i++) {\r\n y = (this._mt[i] & this._upperMask) | (this._mt[i + 1] & this._lowerMask);\r\n this._mt[i] = this._mt[i + (this._m - this._n)] ^ (y >>> 1) ^ (mag01[y & 0x1] & BITMASK32);\r\n }\r\n y = (this._mt[this._n - 1] & this._upperMask) | (this._mt[0] & this._lowerMask);\r\n this._mt[this._n - 1] = this._mt[this._m - 1] ^ (y >>> 1) ^ (mag01[y & 0x1] & BITMASK32);\r\n this._index = 0;\r\n }\r\n /**\r\n * Return next 32 bit integer number in sequence\r\n */\r\n nextInt() {\r\n if (this._index >= this._n) {\r\n this._twist();\r\n }\r\n let y = this._mt[this._index++];\r\n y ^= y >>> this._u;\r\n y ^= (y << this._s) & this._b;\r\n y ^= (y << this._t) & this._c;\r\n y ^= y >>> this._l;\r\n return y >>> 0;\r\n }\r\n /**\r\n * Return a random floating point number between [0, 1)\r\n */\r\n next() {\r\n return this.nextInt() * (1.0 / 4294967296.0); // divided by 2^32\r\n }\r\n /**\r\n * Return a random floating point in range [min, max) min is included, max is not included\r\n */\r\n floating(min, max) {\r\n return (max - min) * this.next() + min;\r\n }\r\n /**\r\n * Return a random integer in range [min, max] min is included, max is included.\r\n * Implemented with rejection sampling, see https://medium.com/@betable/tifu-by-using-math-random-f1c308c4fd9d#.i13tdiu5a\r\n */\r\n integer(min, max) {\r\n return Math.floor((max - min + 1) * this.next() + min);\r\n }\r\n /**\r\n * Returns true or false randomly with 50/50 odds by default.\r\n * By default the likelihood of returning a true is .5 (50%).\r\n * @param likelihood takes values between [0, 1]\r\n */\r\n bool(likelihood = 0.5) {\r\n return this.next() <= likelihood;\r\n }\r\n /**\r\n * Returns one element from an array at random\r\n */\r\n pickOne(array) {\r\n return array[this.integer(0, array.length - 1)];\r\n }\r\n /**\r\n * Returns a new array random picking elements from the original\r\n * @param array Original array to pick from\r\n * @param numPicks can be any positive number\r\n * @param allowDuplicates indicates whether the returned set is allowed duplicates (it does not mean there will always be duplicates\r\n * just that it is possible)\r\n */\r\n pickSet(array, numPicks, allowDuplicates = false) {\r\n if (allowDuplicates) {\r\n return this._pickSetWithDuplicates(array, numPicks);\r\n }\r\n else {\r\n return this._pickSetWithoutDuplicates(array, numPicks);\r\n }\r\n }\r\n /**\r\n * Returns a new array randomly picking elements in the original (not reused)\r\n * @param array Array to pick elements out of\r\n * @param numPicks must be less than or equal to the number of elements in the array.\r\n */\r\n _pickSetWithoutDuplicates(array, numPicks) {\r\n if (numPicks > array.length || numPicks < 0) {\r\n throw new Error('Invalid number of elements to pick, must pick a value 0 < n <= length');\r\n }\r\n if (numPicks === array.length) {\r\n return array;\r\n }\r\n const result = new Array(numPicks);\r\n let currentPick = 0;\r\n const tempArray = array.slice(0);\r\n while (currentPick < numPicks) {\r\n const index = this.integer(0, tempArray.length - 1);\r\n result[currentPick++] = tempArray[index];\r\n tempArray.splice(index, 1);\r\n }\r\n return result;\r\n }\r\n /**\r\n * Returns a new array random picking elements from the original allowing duplicates\r\n * @param array Array to pick elements out of\r\n * @param numPicks can be any positive number\r\n */\r\n _pickSetWithDuplicates(array, numPicks) {\r\n // Typescript numbers are all floating point, so do we add check for int? (or floor the input?)\r\n if (numPicks < 0) {\r\n throw new Error('Invalid number of elements to pick, must pick a value 0 <= n < MAX_INT');\r\n }\r\n const result = new Array(numPicks);\r\n for (let i = 0; i < numPicks; i++) {\r\n result[i] = this.pickOne(array);\r\n }\r\n return result;\r\n }\r\n /**\r\n * Returns a new array that has its elements shuffled. Using the Fisher/Yates method\r\n * https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle\r\n */\r\n shuffle(array) {\r\n const tempArray = array.slice(0);\r\n let swap = null;\r\n for (let i = 0; i < tempArray.length - 2; i++) {\r\n const randomIndex = this.integer(i, tempArray.length - 1);\r\n swap = tempArray[i];\r\n tempArray[i] = tempArray[randomIndex];\r\n tempArray[randomIndex] = swap;\r\n }\r\n return tempArray;\r\n }\r\n /**\r\n * Generate a list of random integer numbers\r\n * @param length the length of the final array\r\n * @param min the minimum integer number to generate inclusive\r\n * @param max the maximum integer number to generate inclusive\r\n */\r\n range(length, min, max) {\r\n const result = new Array(length);\r\n for (let i = 0; i < length; i++) {\r\n result[i] = this.integer(min, max);\r\n }\r\n return result;\r\n }\r\n /**\r\n * Returns the result of a d4 dice roll\r\n */\r\n d4() {\r\n return this.integer(1, 4);\r\n }\r\n /**\r\n * Returns the result of a d6 dice roll\r\n */\r\n d6() {\r\n return this.integer(1, 6);\r\n }\r\n /**\r\n * Returns the result of a d8 dice roll\r\n */\r\n d8() {\r\n return this.integer(1, 8);\r\n }\r\n /**\r\n * Returns the result of a d10 dice roll\r\n */\r\n d10() {\r\n return this.integer(1, 10);\r\n }\r\n /**\r\n * Returns the result of a d12 dice roll\r\n */\r\n d12() {\r\n return this.integer(1, 12);\r\n }\r\n /**\r\n * Returns the result of a d20 dice roll\r\n */\r\n d20() {\r\n return this.integer(1, 20);\r\n }\r\n}\r\n\n;// CONCATENATED MODULE: ./Math/util.ts\n\r\n/**\r\n * Two PI constant\r\n */\r\nconst TwoPI = Math.PI * 2;\r\n/**\r\n * Returns the fractional part of a number\r\n * @param x\r\n */\r\nfunction frac(x) {\r\n if (x >= 0) {\r\n return x - Math.floor(x);\r\n }\r\n else {\r\n return x - Math.ceil(x);\r\n }\r\n}\r\n/**\r\n * Returns the sign of a number, if 0 returns 0\r\n */\r\nfunction sign(val) {\r\n if (val === 0) {\r\n return 0;\r\n }\r\n return val < 0 ? -1 : 1;\r\n}\r\n;\r\n/**\r\n * Clamps a value between a min and max inclusive\r\n */\r\nfunction clamp(val, min, max) {\r\n return Math.min(Math.max(min, val), max);\r\n}\r\n/**\r\n * Convert an angle to be the equivalent in the range [0, 2PI]\r\n */\r\nfunction canonicalizeAngle(angle) {\r\n let tmpAngle = angle;\r\n if (angle > TwoPI) {\r\n while (tmpAngle > TwoPI) {\r\n tmpAngle -= TwoPI;\r\n }\r\n }\r\n if (angle < 0) {\r\n while (tmpAngle < 0) {\r\n tmpAngle += TwoPI;\r\n }\r\n }\r\n return tmpAngle;\r\n}\r\n/**\r\n * Convert radians to degrees\r\n */\r\nfunction toDegrees(radians) {\r\n return (180 / Math.PI) * radians;\r\n}\r\n/**\r\n * Convert degrees to radians\r\n */\r\nfunction toRadians(degrees) {\r\n return (degrees / 180) * Math.PI;\r\n}\r\n/**\r\n * Generate a range of numbers\r\n * For example: range(0, 5) -> [0, 1, 2, 3, 4, 5]\r\n * @param from inclusive\r\n * @param to inclusive\r\n */\r\nconst range = (from, to) => Array.from(new Array(to - from + 1), (_x, i) => i + from);\r\n/**\r\n * Find a random floating point number in range\r\n */\r\nfunction randomInRange(min, max, random = new Random()) {\r\n return random ? random.floating(min, max) : min + Math.random() * (max - min);\r\n}\r\n/**\r\n * Find a random integer in a range\r\n */\r\nfunction randomIntInRange(min, max, random = new Random()) {\r\n return random ? random.integer(min, max) : Math.round(randomInRange(min, max));\r\n}\r\n\n;// CONCATENATED MODULE: ./Math/vector.ts\n\r\n/**\r\n * A 2D vector on a plane.\r\n */\r\nclass Vector {\r\n /**\r\n * A (0, 0) vector\r\n */\r\n static get Zero() {\r\n return new Vector(0, 0);\r\n }\r\n /**\r\n * A (1, 1) vector\r\n */\r\n static get One() {\r\n return new Vector(1, 1);\r\n }\r\n /**\r\n * A (0.5, 0.5) vector\r\n */\r\n static get Half() {\r\n return new Vector(0.5, 0.5);\r\n }\r\n /**\r\n * A unit vector pointing up (0, -1)\r\n */\r\n static get Up() {\r\n return new Vector(0, -1);\r\n }\r\n /**\r\n * A unit vector pointing down (0, 1)\r\n */\r\n static get Down() {\r\n return new Vector(0, 1);\r\n }\r\n /**\r\n * A unit vector pointing left (-1, 0)\r\n */\r\n static get Left() {\r\n return new Vector(-1, 0);\r\n }\r\n /**\r\n * A unit vector pointing right (1, 0)\r\n */\r\n static get Right() {\r\n return new Vector(1, 0);\r\n }\r\n /**\r\n * Returns a vector of unit length in the direction of the specified angle in Radians.\r\n * @param angle The angle to generate the vector\r\n */\r\n static fromAngle(angle) {\r\n return new Vector(Math.cos(angle), Math.sin(angle));\r\n }\r\n /**\r\n * Checks if vector is not null, undefined, or if any of its components are NaN or Infinity.\r\n */\r\n static isValid(vec) {\r\n if (vec === null || vec === undefined) {\r\n return false;\r\n }\r\n if (isNaN(vec.x) || isNaN(vec.y)) {\r\n return false;\r\n }\r\n if (vec.x === Infinity || vec.y === Infinity || vec.x === -Infinity || vec.y === -Infinity) {\r\n return false;\r\n }\r\n return true;\r\n }\r\n /**\r\n * Calculates distance between two Vectors\r\n * @param vec1\r\n * @param vec2\r\n */\r\n static distance(vec1, vec2) {\r\n return Math.sqrt(Math.pow(vec1.x - vec2.x, 2) + Math.pow(vec1.y - vec2.y, 2));\r\n }\r\n static min(vec1, vec2) {\r\n return new Vector(Math.min(vec1.x, vec2.x), Math.min(vec1.y, vec2.y));\r\n }\r\n static max(vec1, vec2) {\r\n return new Vector(Math.max(vec1.x, vec2.x), Math.max(vec1.y, vec2.y));\r\n }\r\n /**\r\n * @param x X component of the Vector\r\n * @param y Y component of the Vector\r\n */\r\n constructor(x, y) {\r\n this._x = 0;\r\n this._y = 0;\r\n this._x = x;\r\n this._y = y;\r\n }\r\n /**\r\n * Get the x component of the vector\r\n */\r\n get x() {\r\n return this._x;\r\n }\r\n /**\r\n * Set the x component, THIS MUTATES the current vector. It is usually better to create a new vector.\r\n * @warning **Be very careful setting components on shared vectors, mutating shared vectors can cause hard to find bugs**\r\n */\r\n set x(val) {\r\n this._x = val;\r\n }\r\n /**\r\n * Get the y component of the vector\r\n */\r\n get y() {\r\n return this._y;\r\n }\r\n /**\r\n * Set the y component, THIS MUTATES the current vector. It is usually better to create a new vector.\r\n * @warning **Be very careful setting components on shared vectors, mutating shared vectors can cause hard to find bugs**\r\n */\r\n set y(val) {\r\n this._y = val;\r\n }\r\n /**\r\n * Sets the x and y components at once, THIS MUTATES the current vector. It is usually better to create a new vector.\r\n *\r\n * @warning **Be very careful using this, mutating vectors can cause hard to find bugs**\r\n */\r\n setTo(x, y) {\r\n this.x = x;\r\n this.y = y;\r\n }\r\n /**\r\n * Compares this point against another and tests for equality\r\n * @param vector The other point to compare to\r\n * @param tolerance Amount of euclidean distance off we are willing to tolerate\r\n */\r\n equals(vector, tolerance = 0.001) {\r\n return Math.abs(this.x - vector.x) <= tolerance && Math.abs(this.y - vector.y) <= tolerance;\r\n }\r\n /**\r\n * The distance to another vector. If no other Vector is specified, this will return the [[magnitude]].\r\n * @param v The other vector. Leave blank to use origin vector.\r\n */\r\n distance(v) {\r\n if (!v) {\r\n return Math.sqrt(this.x * this.x + this.y * this.y);\r\n }\r\n const deltaX = this.x - v.x;\r\n const deltaY = this.y - v.y;\r\n return Math.sqrt(deltaX * deltaX + deltaY * deltaY);\r\n }\r\n squareDistance(v) {\r\n if (!v) {\r\n v = Vector.Zero;\r\n }\r\n const deltaX = this.x - v.x;\r\n const deltaY = this.y - v.y;\r\n return deltaX * deltaX + deltaY * deltaY;\r\n }\r\n /**\r\n * Clamps the current vector's magnitude mutating it\r\n * @param magnitude\r\n */\r\n clampMagnitude(magnitude) {\r\n const size = this.size;\r\n const newSize = clamp(size, 0, magnitude);\r\n this.size = newSize;\r\n return this;\r\n }\r\n /**\r\n * The size (magnitude) of the Vector\r\n */\r\n get size() {\r\n return this.distance();\r\n }\r\n /**\r\n * Setting the size mutates the current vector\r\n *\r\n * @warning Can be used to set the size of the vector, **be very careful using this, mutating vectors can cause hard to find bugs**\r\n */\r\n set size(newLength) {\r\n const v = this.normalize().scale(newLength);\r\n this.setTo(v.x, v.y);\r\n }\r\n /**\r\n * Normalizes a vector to have a magnitude of 1.\r\n */\r\n normalize() {\r\n const d = this.distance();\r\n if (d > 0) {\r\n return new Vector(this.x / d, this.y / d);\r\n }\r\n else {\r\n return new Vector(0, 1);\r\n }\r\n }\r\n /**\r\n * Returns the average (midpoint) between the current point and the specified\r\n */\r\n average(vec) {\r\n return this.add(vec).scale(0.5);\r\n }\r\n scale(sizeOrScale, dest) {\r\n const result = dest || new Vector(0, 0);\r\n if (sizeOrScale instanceof Vector) {\r\n result.x = this.x * sizeOrScale.x;\r\n result.y = this.y * sizeOrScale.y;\r\n }\r\n else {\r\n result.x = this.x * sizeOrScale;\r\n result.y = this.y * sizeOrScale;\r\n }\r\n return result;\r\n }\r\n /**\r\n * Adds one vector to another\r\n * @param v The vector to add\r\n * @param dest Optionally copy the result into a provided vector\r\n */\r\n add(v, dest) {\r\n if (dest) {\r\n dest.x = this.x + v.x;\r\n dest.y = this.y + v.y;\r\n return dest;\r\n }\r\n return new Vector(this.x + v.x, this.y + v.y);\r\n }\r\n /**\r\n * Subtracts a vector from another, if you subtract vector `B.sub(A)` the resulting vector points from A -> B\r\n * @param v The vector to subtract\r\n */\r\n sub(v) {\r\n return new Vector(this.x - v.x, this.y - v.y);\r\n }\r\n /**\r\n * Adds one vector to this one modifying the original\r\n * @param v The vector to add\r\n * @warning Be very careful using this, mutating vectors can cause hard to find bugs\r\n */\r\n addEqual(v) {\r\n this.setTo(this.x + v.x, this.y + v.y);\r\n return this;\r\n }\r\n /**\r\n * Subtracts a vector from this one modifying the original\r\n * @param v The vector to subtract\r\n * @warning Be very careful using this, mutating vectors can cause hard to find bugs\r\n */\r\n subEqual(v) {\r\n this.setTo(this.x - v.x, this.y - v.y);\r\n return this;\r\n }\r\n /**\r\n * Scales this vector by a factor of size and modifies the original\r\n * @warning Be very careful using this, mutating vectors can cause hard to find bugs\r\n */\r\n scaleEqual(size) {\r\n this.setTo(this.x * size, this.y * size);\r\n return this;\r\n }\r\n /**\r\n * Performs a dot product with another vector\r\n * @param v The vector to dot\r\n */\r\n dot(v) {\r\n return this.x * v.x + this.y * v.y;\r\n }\r\n cross(v) {\r\n if (v instanceof Vector) {\r\n return this.x * v.y - this.y * v.x;\r\n }\r\n else if (typeof v === 'number') {\r\n return new Vector(v * this.y, -v * this.x);\r\n }\r\n }\r\n static cross(num, vec) {\r\n return new Vector(-num * vec.y, num * vec.x);\r\n }\r\n /**\r\n * Returns the perpendicular vector to this one\r\n */\r\n perpendicular() {\r\n return new Vector(this.y, -this.x);\r\n }\r\n /**\r\n * Returns the normal vector to this one, same as the perpendicular of length 1\r\n */\r\n normal() {\r\n return this.perpendicular().normalize();\r\n }\r\n /**\r\n * Negate the current vector\r\n */\r\n negate() {\r\n return this.scale(-1);\r\n }\r\n /**\r\n * Returns the angle of this vector.\r\n */\r\n toAngle() {\r\n return Math.atan2(this.y, this.x);\r\n }\r\n /**\r\n * Rotates the current vector around a point by a certain number of\r\n * degrees in radians\r\n */\r\n rotate(angle, anchor) {\r\n if (!anchor) {\r\n anchor = new Vector(0, 0);\r\n }\r\n const sinAngle = Math.sin(angle);\r\n const cosAngle = Math.cos(angle);\r\n const x = cosAngle * (this.x - anchor.x) - sinAngle * (this.y - anchor.y) + anchor.x;\r\n const y = sinAngle * (this.x - anchor.x) + cosAngle * (this.y - anchor.y) + anchor.y;\r\n return new Vector(x, y);\r\n }\r\n /**\r\n * Creates new vector that has the same values as the previous.\r\n */\r\n clone(dest) {\r\n const v = dest !== null && dest !== void 0 ? dest : new Vector(0, 0);\r\n v.x = this.x;\r\n v.y = this.y;\r\n return v;\r\n }\r\n /**\r\n * Returns a string representation of the vector.\r\n */\r\n toString(fixed) {\r\n if (fixed) {\r\n return `(${this.x.toFixed(fixed)}, ${this.y.toFixed(fixed)})`;\r\n }\r\n return `(${this.x}, ${this.y})`;\r\n }\r\n}\r\n/**\r\n * Shorthand for creating new Vectors - returns a new Vector instance with the\r\n * provided X and Y components.\r\n *\r\n * @param x X component of the Vector\r\n * @param y Y component of the Vector\r\n */\r\nfunction vec(x, y) {\r\n return new Vector(x, y);\r\n}\r\n\n;// CONCATENATED MODULE: ./Color.ts\n/**\r\n * Provides standard colors (e.g. [[Color.Black]])\r\n * but you can also create custom colors using RGB, HSL, or Hex. Also provides\r\n * useful color operations like [[Color.lighten]], [[Color.darken]], and more.\r\n */\r\nclass Color {\r\n /**\r\n * Creates a new instance of Color from an r, g, b, a\r\n *\r\n * @param r The red component of color (0-255)\r\n * @param g The green component of color (0-255)\r\n * @param b The blue component of color (0-255)\r\n * @param a The alpha component of color (0-1.0)\r\n */\r\n constructor(r, g, b, a) {\r\n this.r = r;\r\n this.g = g;\r\n this.b = b;\r\n this.a = a != null ? a : 1;\r\n }\r\n /**\r\n * Creates a new instance of Color from an r, g, b, a\r\n *\r\n * @param r The red component of color (0-255)\r\n * @param g The green component of color (0-255)\r\n * @param b The blue component of color (0-255)\r\n * @param a The alpha component of color (0-1.0)\r\n */\r\n static fromRGB(r, g, b, a) {\r\n return new Color(r, g, b, a);\r\n }\r\n /**\r\n * Creates a new instance of Color from a rgb string\r\n *\r\n * @param string CSS color string of the form rgba(255, 255, 255, 1) or rgb(255, 255, 255)\r\n */\r\n static fromRGBString(string) {\r\n const rgbaRegEx = /^rgba?\\((\\d+),\\s*(\\d+),\\s*(\\d+)(?:,\\s*(\\d+(?:\\.\\d+)?))?\\)/i;\r\n let match = null;\r\n if ((match = string.match(rgbaRegEx))) {\r\n const r = parseInt(match[1], 10);\r\n const g = parseInt(match[2], 10);\r\n const b = parseInt(match[3], 10);\r\n let a = 1;\r\n if (match[4]) {\r\n a = parseFloat(match[4]);\r\n }\r\n return new Color(r, g, b, a);\r\n }\r\n else {\r\n throw new Error('Invalid rgb/a string: ' + string);\r\n }\r\n }\r\n /**\r\n * Creates a new instance of Color from a hex string\r\n *\r\n * @param hex CSS color string of the form #ffffff, the alpha component is optional\r\n */\r\n static fromHex(hex) {\r\n const hexRegEx = /^#?([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})?$/i;\r\n let match = null;\r\n if ((match = hex.match(hexRegEx))) {\r\n const r = parseInt(match[1], 16);\r\n const g = parseInt(match[2], 16);\r\n const b = parseInt(match[3], 16);\r\n let a = 1;\r\n if (match[4]) {\r\n a = parseInt(match[4], 16) / 255;\r\n }\r\n return new Color(r, g, b, a);\r\n }\r\n else {\r\n throw new Error('Invalid hex string: ' + hex);\r\n }\r\n }\r\n /**\r\n * Creates a new instance of Color from hsla values\r\n *\r\n * @param h Hue is represented [0-1]\r\n * @param s Saturation is represented [0-1]\r\n * @param l Luminance is represented [0-1]\r\n * @param a Alpha is represented [0-1]\r\n */\r\n static fromHSL(h, s, l, a = 1.0) {\r\n const temp = new HSLColor(h, s, l, a);\r\n return temp.toRGBA();\r\n }\r\n /**\r\n * Lightens the current color by a specified amount\r\n *\r\n * @param factor The amount to lighten by [0-1]\r\n */\r\n lighten(factor = 0.1) {\r\n const temp = HSLColor.fromRGBA(this.r, this.g, this.b, this.a);\r\n temp.l += (1 - temp.l) * factor;\r\n return temp.toRGBA();\r\n }\r\n /**\r\n * Darkens the current color by a specified amount\r\n *\r\n * @param factor The amount to darken by [0-1]\r\n */\r\n darken(factor = 0.1) {\r\n const temp = HSLColor.fromRGBA(this.r, this.g, this.b, this.a);\r\n temp.l -= temp.l * factor;\r\n return temp.toRGBA();\r\n }\r\n /**\r\n * Saturates the current color by a specified amount\r\n *\r\n * @param factor The amount to saturate by [0-1]\r\n */\r\n saturate(factor = 0.1) {\r\n const temp = HSLColor.fromRGBA(this.r, this.g, this.b, this.a);\r\n temp.s += temp.s * factor;\r\n return temp.toRGBA();\r\n }\r\n /**\r\n * Desaturates the current color by a specified amount\r\n *\r\n * @param factor The amount to desaturate by [0-1]\r\n */\r\n desaturate(factor = 0.1) {\r\n const temp = HSLColor.fromRGBA(this.r, this.g, this.b, this.a);\r\n temp.s -= temp.s * factor;\r\n return temp.toRGBA();\r\n }\r\n /**\r\n * Multiplies a color by another, results in a darker color\r\n *\r\n * @param color The other color\r\n */\r\n multiply(color) {\r\n const newR = (((color.r / 255) * this.r) / 255) * 255;\r\n const newG = (((color.g / 255) * this.g) / 255) * 255;\r\n const newB = (((color.b / 255) * this.b) / 255) * 255;\r\n const newA = color.a * this.a;\r\n return new Color(newR, newG, newB, newA);\r\n }\r\n /**\r\n * Screens a color by another, results in a lighter color\r\n *\r\n * @param color The other color\r\n */\r\n screen(color) {\r\n const color1 = color.invert();\r\n const color2 = color.invert();\r\n return color1.multiply(color2).invert();\r\n }\r\n /**\r\n * Inverts the current color\r\n */\r\n invert() {\r\n return new Color(255 - this.r, 255 - this.g, 255 - this.b, 1.0 - this.a);\r\n }\r\n /**\r\n * Averages the current color with another\r\n *\r\n * @param color The other color\r\n */\r\n average(color) {\r\n const newR = (color.r + this.r) / 2;\r\n const newG = (color.g + this.g) / 2;\r\n const newB = (color.b + this.b) / 2;\r\n const newA = (color.a + this.a) / 2;\r\n return new Color(newR, newG, newB, newA);\r\n }\r\n equal(color) {\r\n return this.toString() === color.toString();\r\n }\r\n /**\r\n * Returns a CSS string representation of a color.\r\n *\r\n * @param format Color representation, accepts: rgb, hsl, or hex\r\n */\r\n toString(format = 'rgb') {\r\n switch (format) {\r\n case 'rgb':\r\n return this.toRGBA();\r\n case 'hsl':\r\n return this.toHSLA();\r\n case 'hex':\r\n return this.toHex();\r\n default:\r\n throw new Error('Invalid Color format');\r\n }\r\n }\r\n /**\r\n * Returns Hex Value of a color component\r\n * @param c color component\r\n * @see https://stackoverflow.com/questions/5623838/rgb-to-hex-and-hex-to-rgb\r\n */\r\n _componentToHex(c) {\r\n const hex = c.toString(16);\r\n return hex.length === 1 ? '0' + hex : hex;\r\n }\r\n /**\r\n * Return Hex representation of a color.\r\n */\r\n toHex() {\r\n return '#' + this._componentToHex(this.r) + this._componentToHex(this.g) + this._componentToHex(this.b);\r\n }\r\n /**\r\n * Return RGBA representation of a color.\r\n */\r\n toRGBA() {\r\n const result = String(this.r.toFixed(0)) + ', ' + String(this.g.toFixed(0)) + ', ' + String(this.b.toFixed(0));\r\n if (this.a !== undefined || this.a !== null) {\r\n return 'rgba(' + result + ', ' + String(this.a) + ')';\r\n }\r\n return 'rgb(' + result + ')';\r\n }\r\n /**\r\n * Return HSLA representation of a color.\r\n */\r\n toHSLA() {\r\n return HSLColor.fromRGBA(this.r, this.g, this.b, this.a).toString();\r\n }\r\n /**\r\n * Returns a CSS string representation of a color.\r\n */\r\n fillStyle() {\r\n return this.toString();\r\n }\r\n /**\r\n * Returns a clone of the current color.\r\n */\r\n clone() {\r\n return new Color(this.r, this.g, this.b, this.a);\r\n }\r\n /**\r\n * Black (#000000)\r\n */\r\n static get Black() {\r\n return Color.fromHex('#000000');\r\n }\r\n /**\r\n * White (#FFFFFF)\r\n */\r\n static get White() {\r\n return Color.fromHex('#FFFFFF');\r\n }\r\n /**\r\n * Gray (#808080)\r\n */\r\n static get Gray() {\r\n return Color.fromHex('#808080');\r\n }\r\n /**\r\n * Light gray (#D3D3D3)\r\n */\r\n static get LightGray() {\r\n return Color.fromHex('#D3D3D3');\r\n }\r\n /**\r\n * Dark gray (#A9A9A9)\r\n */\r\n static get DarkGray() {\r\n return Color.fromHex('#A9A9A9');\r\n }\r\n /**\r\n * Yellow (#FFFF00)\r\n */\r\n static get Yellow() {\r\n return Color.fromHex('#FFFF00');\r\n }\r\n /**\r\n * Orange (#FFA500)\r\n */\r\n static get Orange() {\r\n return Color.fromHex('#FFA500');\r\n }\r\n /**\r\n * Red (#FF0000)\r\n */\r\n static get Red() {\r\n return Color.fromHex('#FF0000');\r\n }\r\n /**\r\n * Vermilion (#FF5B31)\r\n */\r\n static get Vermilion() {\r\n return Color.fromHex('#FF5B31');\r\n }\r\n /**\r\n * Rose (#FF007F)\r\n */\r\n static get Rose() {\r\n return Color.fromHex('#FF007F');\r\n }\r\n /**\r\n * Magenta (#FF00FF)\r\n */\r\n static get Magenta() {\r\n return Color.fromHex('#FF00FF');\r\n }\r\n /**\r\n * Violet (#7F00FF)\r\n */\r\n static get Violet() {\r\n return Color.fromHex('#7F00FF');\r\n }\r\n /**\r\n * Blue (#0000FF)\r\n */\r\n static get Blue() {\r\n return Color.fromHex('#0000FF');\r\n }\r\n /**\r\n * Azure (#007FFF)\r\n */\r\n static get Azure() {\r\n return Color.fromHex('#007FFF');\r\n }\r\n /**\r\n * Cyan (#00FFFF)\r\n */\r\n static get Cyan() {\r\n return Color.fromHex('#00FFFF');\r\n }\r\n /**\r\n * Viridian (#59978F)\r\n */\r\n static get Viridian() {\r\n return Color.fromHex('#59978F');\r\n }\r\n /**\r\n * Green (#00FF00)\r\n */\r\n static get Green() {\r\n return Color.fromHex('#00FF00');\r\n }\r\n /**\r\n * Chartreuse (#7FFF00)\r\n */\r\n static get Chartreuse() {\r\n return Color.fromHex('#7FFF00');\r\n }\r\n /**\r\n * Transparent (#FFFFFF00)\r\n */\r\n static get Transparent() {\r\n return Color.fromHex('#FFFFFF00');\r\n }\r\n /**\r\n * ExcaliburBlue (#176BAA)\r\n */\r\n static get ExcaliburBlue() {\r\n return Color.fromHex('#176BAA');\r\n }\r\n}\r\n/**\r\n * Internal HSL Color representation\r\n *\r\n * http://en.wikipedia.org/wiki/HSL_and_HSV\r\n * http://axonflux.com/handy-rgb-to-hsl-and-rgb-to-hsv-color-model-c\r\n */\r\nclass HSLColor {\r\n constructor(h, s, l, a) {\r\n this.h = h;\r\n this.s = s;\r\n this.l = l;\r\n this.a = a;\r\n }\r\n static hue2rgb(p, q, t) {\r\n if (t < 0) {\r\n t += 1;\r\n }\r\n if (t > 1) {\r\n t -= 1;\r\n }\r\n if (t < 1 / 6) {\r\n return p + (q - p) * 6 * t;\r\n }\r\n if (t < 1 / 2) {\r\n return q;\r\n }\r\n if (t < 2 / 3) {\r\n return p + (q - p) * (2 / 3 - t) * 6;\r\n }\r\n return p;\r\n }\r\n static fromRGBA(r, g, b, a) {\r\n r /= 255;\r\n g /= 255;\r\n b /= 255;\r\n const max = Math.max(r, g, b), min = Math.min(r, g, b);\r\n let h, s;\r\n const l = (max + min) / 2;\r\n if (max === min) {\r\n h = s = 0; // achromatic\r\n }\r\n else {\r\n const d = max - min;\r\n s = l > 0.5 ? d / (2 - max - min) : d / (max + min);\r\n switch (max) {\r\n case r:\r\n h = (g - b) / d + (g < b ? 6 : 0);\r\n break;\r\n case g:\r\n h = (b - r) / d + 2;\r\n break;\r\n case b:\r\n h = (r - g) / d + 4;\r\n break;\r\n }\r\n h /= 6;\r\n }\r\n return new HSLColor(h, s, l, a);\r\n }\r\n toRGBA() {\r\n let r, g, b;\r\n if (this.s === 0) {\r\n r = g = b = this.l; // achromatic\r\n }\r\n else {\r\n const q = this.l < 0.5 ? this.l * (1 + this.s) : this.l + this.s - this.l * this.s;\r\n const p = 2 * this.l - q;\r\n r = HSLColor.hue2rgb(p, q, this.h + 1 / 3);\r\n g = HSLColor.hue2rgb(p, q, this.h);\r\n b = HSLColor.hue2rgb(p, q, this.h - 1 / 3);\r\n }\r\n return new Color(r * 255, g * 255, b * 255, this.a);\r\n }\r\n toString() {\r\n const h = this.h.toFixed(0), s = this.s.toFixed(0), l = this.l.toFixed(0), a = this.a.toFixed(0);\r\n return `hsla(${h}, ${s}, ${l}, ${a})`;\r\n }\r\n}\r\n\n;// CONCATENATED MODULE: ./Collision/Side.ts\n\r\n/**\r\n * An enum that describes the sides of an axis aligned box for collision\r\n */\r\nvar Side;\r\n(function (Side) {\r\n Side[\"None\"] = \"None\";\r\n Side[\"Top\"] = \"Top\";\r\n Side[\"Bottom\"] = \"Bottom\";\r\n Side[\"Left\"] = \"Left\";\r\n Side[\"Right\"] = \"Right\";\r\n})(Side || (Side = {}));\r\n(function (Side) {\r\n /**\r\n * Returns the opposite side from the current\r\n */\r\n function getOpposite(side) {\r\n if (side === Side.Top) {\r\n return Side.Bottom;\r\n }\r\n if (side === Side.Bottom) {\r\n return Side.Top;\r\n }\r\n if (side === Side.Left) {\r\n return Side.Right;\r\n }\r\n if (side === Side.Right) {\r\n return Side.Left;\r\n }\r\n return Side.None;\r\n }\r\n Side.getOpposite = getOpposite;\r\n /**\r\n * Given a vector, return the Side most in that direction (via dot product)\r\n */\r\n function fromDirection(direction) {\r\n const directions = [Vector.Left, Vector.Right, Vector.Up, Vector.Down];\r\n const directionEnum = [Side.Left, Side.Right, Side.Top, Side.Bottom];\r\n let max = -Number.MAX_VALUE;\r\n let maxIndex = -1;\r\n for (let i = 0; i < directions.length; i++) {\r\n if (directions[i].dot(direction) > max) {\r\n max = directions[i].dot(direction);\r\n maxIndex = i;\r\n }\r\n }\r\n return directionEnum[maxIndex];\r\n }\r\n Side.fromDirection = fromDirection;\r\n})(Side || (Side = {}));\r\n\n;// CONCATENATED MODULE: ./Collision/BoundingBox.ts\n\r\n\r\n\r\n/**\r\n * Axis Aligned collision primitive for Excalibur.\r\n */\r\nclass BoundingBox {\r\n /**\r\n * Constructor allows passing of either an object with all coordinate components,\r\n * or the coordinate components passed separately.\r\n * @param leftOrOptions Either x coordinate of the left edge or an options object\r\n * containing the four coordinate components.\r\n * @param top y coordinate of the top edge\r\n * @param right x coordinate of the right edge\r\n * @param bottom y coordinate of the bottom edge\r\n */\r\n constructor(leftOrOptions = 0, top = 0, right = 0, bottom = 0) {\r\n if (typeof leftOrOptions === 'object') {\r\n this.left = leftOrOptions.left;\r\n this.top = leftOrOptions.top;\r\n this.right = leftOrOptions.right;\r\n this.bottom = leftOrOptions.bottom;\r\n }\r\n else if (typeof leftOrOptions === 'number') {\r\n this.left = leftOrOptions;\r\n this.top = top;\r\n this.right = right;\r\n this.bottom = bottom;\r\n }\r\n }\r\n /**\r\n * Returns a new instance of [[BoundingBox]] that is a copy of the current instance\r\n */\r\n clone() {\r\n return new BoundingBox(this.left, this.top, this.right, this.bottom);\r\n }\r\n /**\r\n * Given bounding box A & B, returns the side relative to A when intersection is performed.\r\n * @param intersection Intersection vector between 2 bounding boxes\r\n */\r\n static getSideFromIntersection(intersection) {\r\n if (!intersection) {\r\n return Side.None;\r\n }\r\n if (intersection) {\r\n if (Math.abs(intersection.x) > Math.abs(intersection.y)) {\r\n if (intersection.x < 0) {\r\n return Side.Right;\r\n }\r\n return Side.Left;\r\n }\r\n else {\r\n if (intersection.y < 0) {\r\n return Side.Bottom;\r\n }\r\n return Side.Top;\r\n }\r\n }\r\n return Side.None;\r\n }\r\n static fromPoints(points) {\r\n let minX = Infinity;\r\n let minY = Infinity;\r\n let maxX = -Infinity;\r\n let maxY = -Infinity;\r\n for (let i = 0; i < points.length; i++) {\r\n if (points[i].x < minX) {\r\n minX = points[i].x;\r\n }\r\n if (points[i].x > maxX) {\r\n maxX = points[i].x;\r\n }\r\n if (points[i].y < minY) {\r\n minY = points[i].y;\r\n }\r\n if (points[i].y > maxY) {\r\n maxY = points[i].y;\r\n }\r\n }\r\n return new BoundingBox(minX, minY, maxX, maxY);\r\n }\r\n static fromDimension(width, height, anchor = Vector.Half, pos = Vector.Zero) {\r\n return new BoundingBox(-width * anchor.x + pos.x, -height * anchor.y + pos.y, width - width * anchor.x + pos.x, height - height * anchor.y + pos.y);\r\n }\r\n /**\r\n * Returns the calculated width of the bounding box\r\n */\r\n get width() {\r\n return this.right - this.left;\r\n }\r\n /**\r\n * Returns the calculated height of the bounding box\r\n */\r\n get height() {\r\n return this.bottom - this.top;\r\n }\r\n /**\r\n * Return whether the bounding box has zero dimensions in height,width or both\r\n */\r\n hasZeroDimensions() {\r\n return this.width === 0 || this.height === 0;\r\n }\r\n /**\r\n * Returns the center of the bounding box\r\n */\r\n get center() {\r\n return new Vector((this.left + this.right) / 2, (this.top + this.bottom) / 2);\r\n }\r\n translate(pos) {\r\n return new BoundingBox(this.left + pos.x, this.top + pos.y, this.right + pos.x, this.bottom + pos.y);\r\n }\r\n /**\r\n * Rotates a bounding box by and angle and around a point, if no point is specified (0, 0) is used by default. The resulting bounding\r\n * box is also axis-align. This is useful when a new axis-aligned bounding box is needed for rotated geometry.\r\n */\r\n rotate(angle, point = Vector.Zero) {\r\n const points = this.getPoints().map((p) => p.rotate(angle, point));\r\n return BoundingBox.fromPoints(points);\r\n }\r\n /**\r\n * Scale a bounding box by a scale factor, optionally provide a point\r\n * @param scale\r\n * @param point\r\n */\r\n scale(scale, point = Vector.Zero) {\r\n const shifted = this.translate(point);\r\n return new BoundingBox(shifted.left * scale.x, shifted.top * scale.y, shifted.right * scale.x, shifted.bottom * scale.y);\r\n }\r\n /**\r\n * Transform the axis aligned bounding box by a [[Matrix]], producing a new axis aligned bounding box\r\n * @param matrix\r\n */\r\n transform(matrix) {\r\n // inlined these calculations to not use vectors would speed it up slightly\r\n // const matFirstColumn = vec(matrix.data[0], matrix.data[1]);\r\n // const xa = matFirstColumn.scale(this.left);\r\n const xa1 = matrix.data[0] * this.left;\r\n const xa2 = matrix.data[1] * this.left;\r\n // const xb = matFirstColumn.scale(this.right);\r\n const xb1 = matrix.data[0] * this.right;\r\n const xb2 = matrix.data[1] * this.right;\r\n // const matSecondColumn = vec(matrix.data[2], matrix.data[3]);\r\n // const ya = matSecondColumn.scale(this.top);\r\n const ya1 = matrix.data[2] * this.top;\r\n const ya2 = matrix.data[3] * this.top;\r\n // const yb = matSecondColumn.scale(this.bottom);\r\n const yb1 = matrix.data[2] * this.bottom;\r\n const yb2 = matrix.data[3] * this.bottom;\r\n const matrixPos = matrix.getPosition();\r\n // const topLeft = Vector.min(xa, xb).add(Vector.min(ya, yb)).add(matrixPos);\r\n // const bottomRight = Vector.max(xa, xb).add(Vector.max(ya, yb)).add(matrixPos);\r\n const left = Math.min(xa1, xb1) + Math.min(ya1, yb1) + matrixPos.x;\r\n const top = Math.min(xa2, xb2) + Math.min(ya2, yb2) + matrixPos.y;\r\n const right = Math.max(xa1, xb1) + Math.max(ya1, yb1) + matrixPos.x;\r\n const bottom = Math.max(xa2, xb2) + Math.max(ya2, yb2) + matrixPos.y;\r\n return new BoundingBox({\r\n left,\r\n top,\r\n right,\r\n bottom //: bottomRight.y\r\n });\r\n }\r\n /**\r\n * Returns the perimeter of the bounding box\r\n */\r\n getPerimeter() {\r\n const wx = this.width;\r\n const wy = this.height;\r\n return 2 * (wx + wy);\r\n }\r\n getPoints() {\r\n const results = [];\r\n results.push(new Vector(this.left, this.top));\r\n results.push(new Vector(this.right, this.top));\r\n results.push(new Vector(this.right, this.bottom));\r\n results.push(new Vector(this.left, this.bottom));\r\n return results;\r\n }\r\n /**\r\n * Determines whether a ray intersects with a bounding box\r\n */\r\n rayCast(ray, farClipDistance = Infinity) {\r\n // algorithm from https://tavianator.com/fast-branchless-raybounding-box-intersections/\r\n let tmin = -Infinity;\r\n let tmax = +Infinity;\r\n const xinv = ray.dir.x === 0 ? Number.MAX_VALUE : 1 / ray.dir.x;\r\n const yinv = ray.dir.y === 0 ? Number.MAX_VALUE : 1 / ray.dir.y;\r\n const tx1 = (this.left - ray.pos.x) * xinv;\r\n const tx2 = (this.right - ray.pos.x) * xinv;\r\n tmin = Math.min(tx1, tx2);\r\n tmax = Math.max(tx1, tx2);\r\n const ty1 = (this.top - ray.pos.y) * yinv;\r\n const ty2 = (this.bottom - ray.pos.y) * yinv;\r\n tmin = Math.max(tmin, Math.min(ty1, ty2));\r\n tmax = Math.min(tmax, Math.max(ty1, ty2));\r\n return tmax >= Math.max(0, tmin) && tmin < farClipDistance;\r\n }\r\n rayCastTime(ray, farClipDistance = Infinity) {\r\n // algorithm from https://tavianator.com/fast-branchless-raybounding-box-intersections/\r\n let tmin = -Infinity;\r\n let tmax = +Infinity;\r\n const xinv = ray.dir.x === 0 ? Number.MAX_VALUE : 1 / ray.dir.x;\r\n const yinv = ray.dir.y === 0 ? Number.MAX_VALUE : 1 / ray.dir.y;\r\n const tx1 = (this.left - ray.pos.x) * xinv;\r\n const tx2 = (this.right - ray.pos.x) * xinv;\r\n tmin = Math.min(tx1, tx2);\r\n tmax = Math.max(tx1, tx2);\r\n const ty1 = (this.top - ray.pos.y) * yinv;\r\n const ty2 = (this.bottom - ray.pos.y) * yinv;\r\n tmin = Math.max(tmin, Math.min(ty1, ty2));\r\n tmax = Math.min(tmax, Math.max(ty1, ty2));\r\n if (tmax >= Math.max(0, tmin) && tmin < farClipDistance) {\r\n return tmin;\r\n }\r\n return -1;\r\n }\r\n contains(val) {\r\n if (val instanceof Vector) {\r\n return this.left <= val.x && this.top <= val.y && this.bottom >= val.y && this.right >= val.x;\r\n }\r\n else if (val instanceof BoundingBox) {\r\n if (this.left <= val.left && this.top <= val.top && val.bottom <= this.bottom && val.right <= this.right) {\r\n return true;\r\n }\r\n return false;\r\n }\r\n return false;\r\n }\r\n /**\r\n * Combines this bounding box and another together returning a new bounding box\r\n * @param other The bounding box to combine\r\n */\r\n combine(other) {\r\n const compositeBB = new BoundingBox(Math.min(this.left, other.left), Math.min(this.top, other.top), Math.max(this.right, other.right), Math.max(this.bottom, other.bottom));\r\n return compositeBB;\r\n }\r\n get dimensions() {\r\n return new Vector(this.width, this.height);\r\n }\r\n /**\r\n * Returns true if the bounding boxes overlap.\r\n * @param other\r\n * @param epsilon Optionally specify a small epsilon (default 0) as amount of overlap to ignore as overlap.\r\n * This epsilon is useful in stable collision simulations.\r\n */\r\n overlaps(other, epsilon) {\r\n const e = epsilon || 0;\r\n if (other.hasZeroDimensions()) {\r\n return this.contains(other);\r\n }\r\n if (this.hasZeroDimensions()) {\r\n return other.contains(this);\r\n }\r\n const totalBoundingBox = this.combine(other);\r\n return totalBoundingBox.width + e < other.width + this.width &&\r\n totalBoundingBox.height + e < other.height + this.height;\r\n }\r\n /**\r\n * Test wether this bounding box intersects with another returning\r\n * the intersection vector that can be used to resolve the collision. If there\r\n * is no intersection null is returned.\r\n *\r\n * @param other Other [[BoundingBox]] to test intersection with\r\n * @returns A Vector in the direction of the current BoundingBox, this <- other\r\n */\r\n intersect(other) {\r\n const totalBoundingBox = this.combine(other);\r\n // If the total bounding box is less than or equal the sum of the 2 bounds then there is collision\r\n if (totalBoundingBox.width < other.width + this.width &&\r\n totalBoundingBox.height < other.height + this.height &&\r\n !totalBoundingBox.dimensions.equals(other.dimensions) &&\r\n !totalBoundingBox.dimensions.equals(this.dimensions)) {\r\n // collision\r\n let overlapX = 0;\r\n // right edge is between the other's left and right edge\r\n /**\r\n * +-this-+\r\n * | |\r\n * | +-other-+\r\n * +----|-+ |\r\n * | |\r\n * +-------+\r\n * <---\r\n * ^ overlap\r\n */\r\n if (this.right >= other.left && this.right <= other.right) {\r\n overlapX = other.left - this.right;\r\n // right edge is past the other's right edge\r\n /**\r\n * +-other-+\r\n * | |\r\n * | +-this-+\r\n * +----|--+ |\r\n * | |\r\n * +------+\r\n * --->\r\n * ^ overlap\r\n */\r\n }\r\n else {\r\n overlapX = other.right - this.left;\r\n }\r\n let overlapY = 0;\r\n // top edge is between the other's top and bottom edge\r\n /**\r\n * +-other-+\r\n * | |\r\n * | +-this-+ | <- overlap\r\n * +----|--+ | |\r\n * | | \\ /\r\n * +------+ '\r\n */\r\n if (this.top <= other.bottom && this.top >= other.top) {\r\n overlapY = other.bottom - this.top;\r\n // top edge is above the other top edge\r\n /**\r\n * +-this-+ .\r\n * | | / \\\r\n * | +-other-+ | <- overlap\r\n * +----|-+ | |\r\n * | |\r\n * +-------+\r\n */\r\n }\r\n else {\r\n overlapY = other.top - this.bottom;\r\n }\r\n if (Math.abs(overlapX) < Math.abs(overlapY)) {\r\n return new Vector(overlapX, 0);\r\n }\r\n else {\r\n return new Vector(0, overlapY);\r\n }\r\n // Case of total containment of one bounding box by another\r\n }\r\n else if (totalBoundingBox.dimensions.equals(other.dimensions) || totalBoundingBox.dimensions.equals(this.dimensions)) {\r\n let overlapX = 0;\r\n // this is wider than the other\r\n if (this.width - other.width >= 0) {\r\n // This right edge is closest to the others right edge\r\n if (this.right - other.right <= other.left - this.left) {\r\n overlapX = other.left - this.right;\r\n // This left edge is closest to the others left edge\r\n }\r\n else {\r\n overlapX = other.right - this.left;\r\n }\r\n // other is wider than this\r\n }\r\n else {\r\n // This right edge is closest to the others right edge\r\n if (other.right - this.right <= this.left - other.left) {\r\n overlapX = this.left - other.right;\r\n // This left edge is closest to the others left edge\r\n }\r\n else {\r\n overlapX = this.right - other.left;\r\n }\r\n }\r\n let overlapY = 0;\r\n // this is taller than other\r\n if (this.height - other.height >= 0) {\r\n // The bottom edge is closest to the others bottom edge\r\n if (this.bottom - other.bottom <= other.top - this.top) {\r\n overlapY = other.top - this.bottom;\r\n }\r\n else {\r\n overlapY = other.bottom - this.top;\r\n }\r\n // other is taller than this\r\n }\r\n else {\r\n // The bottom edge is closest to the others bottom edge\r\n if (other.bottom - this.bottom <= this.top - other.top) {\r\n overlapY = this.top - other.bottom;\r\n }\r\n else {\r\n overlapY = this.bottom - other.top;\r\n }\r\n }\r\n if (Math.abs(overlapX) < Math.abs(overlapY)) {\r\n return new Vector(overlapX, 0);\r\n }\r\n else {\r\n return new Vector(0, overlapY);\r\n }\r\n }\r\n else {\r\n return null;\r\n }\r\n }\r\n /**\r\n * Test whether the bounding box has intersected with another bounding box, returns the side of the current bb that intersected.\r\n * @param bb The other actor to test\r\n */\r\n intersectWithSide(bb) {\r\n const intersect = this.intersect(bb);\r\n return BoundingBox.getSideFromIntersection(intersect);\r\n }\r\n /**\r\n * Draw a debug bounding box\r\n * @param ex\r\n * @param color\r\n */\r\n draw(ex, color = Color.Yellow) {\r\n ex.debug.drawRect(this.left, this.top, this.width, this.height, { color });\r\n }\r\n}\r\n\n;// CONCATENATED MODULE: ./Util/Future.ts\n/**\r\n * Future is a wrapper around a native browser Promise to allow resolving/rejecting at any time\r\n */\r\nclass Future {\r\n constructor() {\r\n this._isCompleted = false;\r\n this.promise = new Promise((resolve, reject) => {\r\n this._resolver = resolve;\r\n this._rejecter = reject;\r\n });\r\n }\r\n get isCompleted() {\r\n return this._isCompleted;\r\n }\r\n resolve(value) {\r\n if (this._isCompleted) {\r\n return;\r\n }\r\n this._isCompleted = true;\r\n this._resolver(value);\r\n }\r\n reject(error) {\r\n if (this._isCompleted) {\r\n return;\r\n }\r\n this._isCompleted = true;\r\n this._rejecter(error);\r\n }\r\n}\r\n\n;// CONCATENATED MODULE: ./Util/Util.ts\n\r\n\r\n/**\r\n * Find the screen position of an HTML element\r\n */\r\nfunction getPosition(el) {\r\n let oLeft = 0, oTop = 0;\r\n const calcOffsetLeft = (parent) => {\r\n oLeft += parent.offsetLeft;\r\n if (parent.offsetParent) {\r\n calcOffsetLeft(parent.offsetParent);\r\n }\r\n };\r\n const calcOffsetTop = (parent) => {\r\n oTop += parent.offsetTop;\r\n if (parent.offsetParent) {\r\n calcOffsetTop(parent.offsetParent);\r\n }\r\n };\r\n calcOffsetLeft(el);\r\n calcOffsetTop(el);\r\n return new Vector(oLeft, oTop);\r\n}\r\n/**\r\n * Add an item to an array list if it doesn't already exist. Returns true if added, false if not and already exists in the array.\r\n * @deprecated Will be removed in v0.26.0\r\n */\r\nfunction addItemToArray(item, array) {\r\n if (array.indexOf(item) === -1) {\r\n array.push(item);\r\n return true;\r\n }\r\n return false;\r\n}\r\n/**\r\n * Remove an item from an list\r\n * @deprecated Will be removed in v0.26.0\r\n */\r\nfunction removeItemFromArray(item, array) {\r\n let index = -1;\r\n if ((index = array.indexOf(item)) > -1) {\r\n array.splice(index, 1);\r\n return true;\r\n }\r\n return false;\r\n}\r\n/**\r\n * See if an array contains something\r\n */\r\nfunction contains(array, obj) {\r\n for (let i = 0; i < array.length; i++) {\r\n if (array[i] === obj) {\r\n return true;\r\n }\r\n }\r\n return false;\r\n}\r\n/**\r\n * Used for exhaustive checks at compile time\r\n */\r\nfunction fail(message) {\r\n throw new Error(message);\r\n}\r\n/**\r\n * Create a promise that resolves after a certain number of milliseconds\r\n *\r\n * It is strongly recommended you pass the excalibur clock so delays are bound to the\r\n * excalibur clock which would be unaffected by stop/pause.\r\n * @param milliseconds\r\n * @param clock\r\n */\r\nfunction delay(milliseconds, clock) {\r\n var _a;\r\n const future = new Future();\r\n const schedule = (_a = clock === null || clock === void 0 ? void 0 : clock.schedule.bind(clock)) !== null && _a !== void 0 ? _a : setTimeout;\r\n schedule(() => {\r\n future.resolve();\r\n }, milliseconds);\r\n return future.promise;\r\n}\r\n\n;// CONCATENATED MODULE: ./Math/matrix.ts\n\r\n\r\n\r\nvar MatrixLocations;\r\n(function (MatrixLocations) {\r\n MatrixLocations[MatrixLocations[\"X\"] = 12] = \"X\";\r\n MatrixLocations[MatrixLocations[\"Y\"] = 13] = \"Y\";\r\n})(MatrixLocations || (MatrixLocations = {}));\r\n/**\r\n * Excalibur Matrix helper for 4x4 matrices\r\n *\r\n * Useful for webgl 4x4 matrices\r\n */\r\nclass Matrix {\r\n constructor() {\r\n /**\r\n * 4x4 matrix in column major order\r\n *\r\n * | | | | |\r\n * | ------- | ------- | -------- | -------- |\r\n * | data[0] | data[4] | data[8] | data[12] |\r\n * | data[1] | data[5] | data[9] | data[13] |\r\n * | data[2] | data[6] | data[10] | data[14] |\r\n * | data[3] | data[7] | data[11] | data[15] |\r\n *\r\n */\r\n this.data = new Float32Array(16);\r\n this._scaleX = 1;\r\n this._scaleSignX = 1;\r\n this._scaleY = 1;\r\n this._scaleSignY = 1;\r\n }\r\n /**\r\n * Creates an orthographic (flat non-perspective) projection\r\n * https://en.wikipedia.org/wiki/Orthographic_projection\r\n * @param left\r\n * @param right\r\n * @param bottom\r\n * @param top\r\n * @param near\r\n * @param far\r\n */\r\n static ortho(left, right, bottom, top, near, far) {\r\n const mat = new Matrix();\r\n mat.data[0] = 2 / (right - left);\r\n mat.data[1] = 0;\r\n mat.data[2] = 0;\r\n mat.data[3] = 0;\r\n mat.data[4] = 0;\r\n mat.data[5] = 2 / (top - bottom);\r\n mat.data[6] = 0;\r\n mat.data[7] = 0;\r\n mat.data[8] = 0;\r\n mat.data[9] = 0;\r\n mat.data[10] = -2 / (far - near);\r\n mat.data[11] = 0;\r\n mat.data[12] = -(right + left) / (right - left);\r\n mat.data[13] = -(top + bottom) / (top - bottom);\r\n mat.data[14] = -(far + near) / (far - near);\r\n mat.data[15] = 1;\r\n return mat;\r\n }\r\n /**\r\n * Creates a new Matrix with the same data as the current 4x4\r\n */\r\n clone(dest) {\r\n const mat = dest || new Matrix();\r\n mat.data[0] = this.data[0];\r\n mat.data[1] = this.data[1];\r\n mat.data[2] = this.data[2];\r\n mat.data[3] = this.data[3];\r\n mat.data[4] = this.data[4];\r\n mat.data[5] = this.data[5];\r\n mat.data[6] = this.data[6];\r\n mat.data[7] = this.data[7];\r\n mat.data[8] = this.data[8];\r\n mat.data[9] = this.data[9];\r\n mat.data[10] = this.data[10];\r\n mat.data[11] = this.data[11];\r\n mat.data[12] = this.data[12];\r\n mat.data[13] = this.data[13];\r\n mat.data[14] = this.data[14];\r\n mat.data[15] = this.data[15];\r\n return mat;\r\n }\r\n /**\r\n * Converts the current matrix into a DOMMatrix\r\n *\r\n * This is useful when working with the browser Canvas context\r\n * @returns {DOMMatrix} DOMMatrix\r\n */\r\n toDOMMatrix() {\r\n return new DOMMatrix([...this.data]);\r\n }\r\n static fromFloat32Array(data) {\r\n const matrix = new Matrix();\r\n matrix.data = data;\r\n return matrix;\r\n }\r\n /**\r\n * Creates a new identity matrix (a matrix that when applied does nothing)\r\n */\r\n static identity() {\r\n const mat = new Matrix();\r\n mat.data[0] = 1;\r\n mat.data[1] = 0;\r\n mat.data[2] = 0;\r\n mat.data[3] = 0;\r\n mat.data[4] = 0;\r\n mat.data[5] = 1;\r\n mat.data[6] = 0;\r\n mat.data[7] = 0;\r\n mat.data[8] = 0;\r\n mat.data[9] = 0;\r\n mat.data[10] = 1;\r\n mat.data[11] = 0;\r\n mat.data[12] = 0;\r\n mat.data[13] = 0;\r\n mat.data[14] = 0;\r\n mat.data[15] = 1;\r\n return mat;\r\n }\r\n /**\r\n * Resets the current matrix to the identity matrix, mutating it\r\n * @returns {Matrix} Current matrix as identity\r\n */\r\n reset() {\r\n const mat = this;\r\n mat.data[0] = 1;\r\n mat.data[1] = 0;\r\n mat.data[2] = 0;\r\n mat.data[3] = 0;\r\n mat.data[4] = 0;\r\n mat.data[5] = 1;\r\n mat.data[6] = 0;\r\n mat.data[7] = 0;\r\n mat.data[8] = 0;\r\n mat.data[9] = 0;\r\n mat.data[10] = 1;\r\n mat.data[11] = 0;\r\n mat.data[12] = 0;\r\n mat.data[13] = 0;\r\n mat.data[14] = 0;\r\n mat.data[15] = 1;\r\n return mat;\r\n }\r\n /**\r\n * Creates a brand new translation matrix at the specified 3d point\r\n * @param x\r\n * @param y\r\n */\r\n static translation(x, y) {\r\n const mat = Matrix.identity();\r\n mat.data[12] = x;\r\n mat.data[13] = y;\r\n return mat;\r\n }\r\n /**\r\n * Creates a brand new scaling matrix with the specified scaling factor\r\n * @param sx\r\n * @param sy\r\n */\r\n static scale(sx, sy) {\r\n const mat = Matrix.identity();\r\n mat.data[0] = sx;\r\n mat.data[5] = sy;\r\n mat.data[10] = 1;\r\n mat.data[15] = 1;\r\n return mat;\r\n }\r\n /**\r\n * Creates a brand new rotation matrix with the specified angle\r\n * @param angleRadians\r\n */\r\n static rotation(angleRadians) {\r\n const mat = Matrix.identity();\r\n mat.data[0] = Math.cos(angleRadians);\r\n mat.data[4] = -Math.sin(angleRadians);\r\n mat.data[1] = Math.sin(angleRadians);\r\n mat.data[5] = Math.cos(angleRadians);\r\n return mat;\r\n }\r\n multiply(vectorOrMatrix, dest) {\r\n if (vectorOrMatrix instanceof Vector) {\r\n const result = dest || new Vector(0, 0);\r\n const vector = vectorOrMatrix;\r\n // these shenanigans are to allow dest and vector to be the same instance\r\n const resultX = vector.x * this.data[0] + vector.y * this.data[4] + this.data[12];\r\n const resultY = vector.x * this.data[1] + vector.y * this.data[5] + this.data[13];\r\n result.x = resultX;\r\n result.y = resultY;\r\n return result;\r\n }\r\n else {\r\n const result = dest || new Matrix();\r\n const other = vectorOrMatrix;\r\n const a11 = this.data[0];\r\n const a21 = this.data[1];\r\n const a31 = this.data[2];\r\n const a41 = this.data[3];\r\n const a12 = this.data[4];\r\n const a22 = this.data[5];\r\n const a32 = this.data[6];\r\n const a42 = this.data[7];\r\n const a13 = this.data[8];\r\n const a23 = this.data[9];\r\n const a33 = this.data[10];\r\n const a43 = this.data[11];\r\n const a14 = this.data[12];\r\n const a24 = this.data[13];\r\n const a34 = this.data[14];\r\n const a44 = this.data[15];\r\n const b11 = other.data[0];\r\n const b21 = other.data[1];\r\n const b31 = other.data[2];\r\n const b41 = other.data[3];\r\n const b12 = other.data[4];\r\n const b22 = other.data[5];\r\n const b32 = other.data[6];\r\n const b42 = other.data[7];\r\n const b13 = other.data[8];\r\n const b23 = other.data[9];\r\n const b33 = other.data[10];\r\n const b43 = other.data[11];\r\n const b14 = other.data[12];\r\n const b24 = other.data[13];\r\n const b34 = other.data[14];\r\n const b44 = other.data[15];\r\n result.data[0] = a11 * b11 + a12 * b21 + a13 * b31 + a14 * b41;\r\n result.data[1] = a21 * b11 + a22 * b21 + a23 * b31 + a24 * b41;\r\n result.data[2] = a31 * b11 + a32 * b21 + a33 * b31 + a34 * b41;\r\n result.data[3] = a41 * b11 + a42 * b21 + a43 * b31 + a44 * b41;\r\n result.data[4] = a11 * b12 + a12 * b22 + a13 * b32 + a14 * b42;\r\n result.data[5] = a21 * b12 + a22 * b22 + a23 * b32 + a24 * b42;\r\n result.data[6] = a31 * b12 + a32 * b22 + a33 * b32 + a34 * b42;\r\n result.data[7] = a41 * b12 + a42 * b22 + a43 * b32 + a44 * b42;\r\n result.data[8] = a11 * b13 + a12 * b23 + a13 * b33 + a14 * b43;\r\n result.data[9] = a21 * b13 + a22 * b23 + a23 * b33 + a24 * b43;\r\n result.data[10] = a31 * b13 + a32 * b23 + a33 * b33 + a34 * b43;\r\n result.data[11] = a41 * b13 + a42 * b23 + a43 * b33 + a44 * b43;\r\n result.data[12] = a11 * b14 + a12 * b24 + a13 * b34 + a14 * b44;\r\n result.data[13] = a21 * b14 + a22 * b24 + a23 * b34 + a24 * b44;\r\n result.data[14] = a31 * b14 + a32 * b24 + a33 * b34 + a34 * b44;\r\n result.data[15] = a41 * b14 + a42 * b24 + a43 * b34 + a44 * b44;\r\n const s = this.getScale();\r\n result._scaleSignX = sign(s.x) * sign(result._scaleSignX);\r\n result._scaleSignY = sign(s.y) * sign(result._scaleSignY);\r\n return result;\r\n }\r\n }\r\n /**\r\n * Applies translation to the current matrix mutating it\r\n * @param x\r\n * @param y\r\n */\r\n translate(x, y) {\r\n const a11 = this.data[0];\r\n const a21 = this.data[1];\r\n const a31 = this.data[2];\r\n const a41 = this.data[3];\r\n const a12 = this.data[4];\r\n const a22 = this.data[5];\r\n const a32 = this.data[6];\r\n const a42 = this.data[7];\r\n const a13 = this.data[8];\r\n const a23 = this.data[9];\r\n const a33 = this.data[10];\r\n const a43 = this.data[11];\r\n const a14 = this.data[12];\r\n const a24 = this.data[13];\r\n const a34 = this.data[14];\r\n const a44 = this.data[15];\r\n // Doesn't change z\r\n const z = 0;\r\n const w = 1;\r\n this.data[12] = a11 * x + a12 * y + a13 * z + a14 * w;\r\n this.data[13] = a21 * x + a22 * y + a23 * z + a24 * w;\r\n this.data[14] = a31 * x + a32 * y + a33 * z + a34 * w;\r\n this.data[15] = a41 * x + a42 * y + a43 * z + a44 * w;\r\n return this;\r\n }\r\n setPosition(x, y) {\r\n this.data[12] = x;\r\n this.data[13] = y;\r\n }\r\n getPosition() {\r\n return vec(this.data[12], this.data[13]);\r\n }\r\n /**\r\n * Applies rotation to the current matrix mutating it\r\n * @param angle in Radians\r\n */\r\n rotate(angle) {\r\n const a11 = this.data[0];\r\n const a21 = this.data[1];\r\n const a31 = this.data[2];\r\n const a41 = this.data[3];\r\n const a12 = this.data[4];\r\n const a22 = this.data[5];\r\n const a32 = this.data[6];\r\n const a42 = this.data[7];\r\n const sine = Math.sin(angle);\r\n const cosine = Math.cos(angle);\r\n this.data[0] = cosine * a11 + sine * a12;\r\n this.data[1] = cosine * a21 + sine * a22;\r\n this.data[2] = cosine * a31 + sine * a32;\r\n this.data[3] = cosine * a41 + sine * a42;\r\n this.data[4] = cosine * a12 - sine * a11;\r\n this.data[5] = cosine * a22 - sine * a21;\r\n this.data[6] = cosine * a32 - sine * a31;\r\n this.data[7] = cosine * a42 - sine * a41;\r\n return this;\r\n }\r\n /**\r\n * Applies scaling to the current matrix mutating it\r\n * @param x\r\n * @param y\r\n */\r\n scale(x, y) {\r\n const a11 = this.data[0];\r\n const a21 = this.data[1];\r\n const a31 = this.data[2];\r\n const a41 = this.data[3];\r\n const a12 = this.data[4];\r\n const a22 = this.data[5];\r\n const a32 = this.data[6];\r\n const a42 = this.data[7];\r\n this.data[0] = a11 * x;\r\n this.data[1] = a21 * x;\r\n this.data[2] = a31 * x;\r\n this.data[3] = a41 * x;\r\n this.data[4] = a12 * y;\r\n this.data[5] = a22 * y;\r\n this.data[6] = a32 * y;\r\n this.data[7] = a42 * y;\r\n return this;\r\n }\r\n setRotation(angle) {\r\n const currentScale = this.getScale();\r\n const sine = Math.sin(angle);\r\n const cosine = Math.cos(angle);\r\n this.data[0] = cosine * currentScale.x;\r\n this.data[1] = sine * currentScale.y;\r\n this.data[4] = -sine * currentScale.x;\r\n this.data[5] = cosine * currentScale.y;\r\n }\r\n getRotation() {\r\n const angle = Math.atan2(this.data[1] / this.getScaleY(), this.data[0] / this.getScaleX());\r\n return canonicalizeAngle(angle);\r\n }\r\n getScaleX() {\r\n // absolute scale of the matrix (we lose sign so need to add it back)\r\n const xscale = vec(this.data[0], this.data[4]).size;\r\n return this._scaleSignX * xscale;\r\n }\r\n getScaleY() {\r\n // absolute scale of the matrix (we lose sign so need to add it back)\r\n const yscale = vec(this.data[1], this.data[5]).size;\r\n return this._scaleSignY * yscale;\r\n }\r\n /**\r\n * Get the scale of the matrix\r\n */\r\n getScale() {\r\n return vec(this.getScaleX(), this.getScaleY());\r\n }\r\n setScaleX(val) {\r\n if (this._scaleX === val) {\r\n return;\r\n }\r\n this._scaleSignX = sign(val);\r\n // negative scale acts like a 180 rotation, so flip\r\n const xscale = vec(this.data[0] * this._scaleSignX, this.data[4] * this._scaleSignX).normalize();\r\n this.data[0] = xscale.x * val;\r\n this.data[4] = xscale.y * val;\r\n this._scaleX = val;\r\n }\r\n setScaleY(val) {\r\n if (this._scaleY === val) {\r\n return;\r\n }\r\n this._scaleSignY = sign(val);\r\n // negative scale acts like a 180 rotation, so flip\r\n const yscale = vec(this.data[1] * this._scaleSignY, this.data[5] * this._scaleSignY).normalize();\r\n this.data[1] = yscale.x * val;\r\n this.data[5] = yscale.y * val;\r\n this._scaleY = val;\r\n }\r\n setScale(scale) {\r\n this.setScaleX(scale.x);\r\n this.setScaleY(scale.y);\r\n }\r\n /**\r\n * Determinant of the upper left 2x2 matrix\r\n */\r\n getBasisDeterminant() {\r\n return this.data[0] * this.data[5] - this.data[1] * this.data[4];\r\n }\r\n /**\r\n * Return the affine inverse, optionally store it in a target matrix.\r\n *\r\n * It's recommended you call .reset() the target unless you know what you're doing\r\n * @param target\r\n */\r\n getAffineInverse(target) {\r\n // See http://negativeprobability.blogspot.com/2011/11/affine-transformations-and-their.html\r\n // See https://www.mathsisfun.com/algebra/matrix-inverse.html\r\n // Since we are actually only doing 2D transformations we can use this hack\r\n // We don't actually use the 3rd or 4th dimension\r\n const det = this.getBasisDeterminant();\r\n const inverseDet = 1 / det; // todo zero check\r\n const a = this.data[0];\r\n const b = this.data[4];\r\n const c = this.data[1];\r\n const d = this.data[5];\r\n const m = target || Matrix.identity();\r\n // inverts rotation and scale\r\n m.data[0] = d * inverseDet;\r\n m.data[1] = -c * inverseDet;\r\n m.data[4] = -b * inverseDet;\r\n m.data[5] = a * inverseDet;\r\n const tx = this.data[12];\r\n const ty = this.data[13];\r\n // invert translation\r\n // transform translation into the matrix basis created by rot/scale\r\n m.data[12] = -(tx * m.data[0] + ty * m.data[4]);\r\n m.data[13] = -(tx * m.data[1] + ty * m.data[5]);\r\n return m;\r\n }\r\n isIdentity() {\r\n return (this.data[0] === 1 &&\r\n this.data[1] === 0 &&\r\n this.data[2] === 0 &&\r\n this.data[3] === 0 &&\r\n this.data[4] === 0 &&\r\n this.data[5] === 1 &&\r\n this.data[6] === 0 &&\r\n this.data[7] === 0 &&\r\n this.data[8] === 0 &&\r\n this.data[9] === 0 &&\r\n this.data[10] === 1 &&\r\n this.data[11] === 0 &&\r\n this.data[12] === 0 &&\r\n this.data[13] === 0 &&\r\n this.data[14] === 0 &&\r\n this.data[15] === 1);\r\n }\r\n toString() {\r\n return `\r\n[${this.data[0]} ${this.data[4]} ${this.data[8]} ${this.data[12]}]\r\n[${this.data[1]} ${this.data[5]} ${this.data[9]} ${this.data[13]}]\r\n[${this.data[2]} ${this.data[6]} ${this.data[10]} ${this.data[14]}]\r\n[${this.data[3]} ${this.data[7]} ${this.data[11]} ${this.data[15]}]\r\n`;\r\n }\r\n}\r\n\n;// CONCATENATED MODULE: ./Math/affine-matrix.ts\n\r\n\r\n\r\nclass AffineMatrix {\r\n constructor() {\r\n /**\r\n * | | | |\r\n * | ------- | ------- | -------- |\r\n * | data[0] | data[2] | data[4] |\r\n * | data[1] | data[3] | data[5] |\r\n * | 0 | 0 | 1 |\r\n */\r\n this.data = new Float64Array(6);\r\n this._scale = new Float64Array([1, 1]);\r\n this._scaleSignX = 1;\r\n this._scaleSignY = 1;\r\n }\r\n /**\r\n * Converts the current matrix into a DOMMatrix\r\n *\r\n * This is useful when working with the browser Canvas context\r\n * @returns {DOMMatrix} DOMMatrix\r\n */\r\n toDOMMatrix() {\r\n return new DOMMatrix([...this.data]);\r\n }\r\n static identity() {\r\n const mat = new AffineMatrix();\r\n mat.data[0] = 1;\r\n mat.data[1] = 0;\r\n mat.data[2] = 0;\r\n mat.data[3] = 1;\r\n mat.data[4] = 0;\r\n mat.data[5] = 0;\r\n return mat;\r\n }\r\n /**\r\n * Creates a brand new translation matrix at the specified 3d point\r\n * @param x\r\n * @param y\r\n */\r\n static translation(x, y) {\r\n const mat = AffineMatrix.identity();\r\n mat.data[4] = x;\r\n mat.data[5] = y;\r\n return mat;\r\n }\r\n /**\r\n * Creates a brand new scaling matrix with the specified scaling factor\r\n * @param sx\r\n * @param sy\r\n */\r\n static scale(sx, sy) {\r\n const mat = AffineMatrix.identity();\r\n mat.data[0] = sx;\r\n mat.data[3] = sy;\r\n mat._scale[0] = sx;\r\n mat._scale[1] = sy;\r\n return mat;\r\n }\r\n /**\r\n * Creates a brand new rotation matrix with the specified angle\r\n * @param angleRadians\r\n */\r\n static rotation(angleRadians) {\r\n const mat = AffineMatrix.identity();\r\n mat.data[0] = Math.cos(angleRadians);\r\n mat.data[1] = Math.sin(angleRadians);\r\n mat.data[2] = -Math.sin(angleRadians);\r\n mat.data[3] = Math.cos(angleRadians);\r\n return mat;\r\n }\r\n setPosition(x, y) {\r\n this.data[4] = x;\r\n this.data[5] = y;\r\n }\r\n getPosition() {\r\n return vec(this.data[4], this.data[5]);\r\n }\r\n /**\r\n * Applies rotation to the current matrix mutating it\r\n * @param angle in Radians\r\n */\r\n rotate(angle) {\r\n const a11 = this.data[0];\r\n const a21 = this.data[1];\r\n const a12 = this.data[2];\r\n const a22 = this.data[3];\r\n const sine = Math.sin(angle);\r\n const cosine = Math.cos(angle);\r\n this.data[0] = cosine * a11 + sine * a12;\r\n this.data[1] = cosine * a21 + sine * a22;\r\n this.data[2] = cosine * a12 - sine * a11;\r\n this.data[3] = cosine * a22 - sine * a21;\r\n return this;\r\n }\r\n /**\r\n * Applies translation to the current matrix mutating it\r\n * @param x\r\n * @param y\r\n */\r\n translate(x, y) {\r\n const a11 = this.data[0];\r\n const a21 = this.data[1];\r\n // const a31 = 0;\r\n const a12 = this.data[2];\r\n const a22 = this.data[3];\r\n // const a32 = 0;\r\n const a13 = this.data[4];\r\n const a23 = this.data[5];\r\n // const a33 = 1;\r\n // Doesn't change z\r\n this.data[4] = a11 * x + a12 * y + a13;\r\n this.data[5] = a21 * x + a22 * y + a23;\r\n return this;\r\n }\r\n /**\r\n * Applies scaling to the current matrix mutating it\r\n * @param x\r\n * @param y\r\n */\r\n scale(x, y) {\r\n const a11 = this.data[0];\r\n const a21 = this.data[1];\r\n const a12 = this.data[2];\r\n const a22 = this.data[3];\r\n this.data[0] = a11 * x;\r\n this.data[1] = a21 * x;\r\n this.data[2] = a12 * y;\r\n this.data[3] = a22 * y;\r\n this._scale[0] = x;\r\n this._scale[1] = y;\r\n return this;\r\n }\r\n determinant() {\r\n return this.data[0] * this.data[3] - this.data[1] * this.data[2];\r\n }\r\n /**\r\n * Return the affine inverse, optionally store it in a target matrix.\r\n *\r\n * It's recommended you call .reset() the target unless you know what you're doing\r\n * @param target\r\n */\r\n inverse(target) {\r\n // See http://negativeprobability.blogspot.com/2011/11/affine-transformations-and-their.html\r\n // See https://www.mathsisfun.com/algebra/matrix-inverse.html\r\n // Since we are actually only doing 2D transformations we can use this hack\r\n // We don't actually use the 3rd or 4th dimension\r\n const det = this.determinant();\r\n const inverseDet = 1 / det; // TODO zero check\r\n const a = this.data[0];\r\n const b = this.data[2];\r\n const c = this.data[1];\r\n const d = this.data[3];\r\n const m = target || AffineMatrix.identity();\r\n // inverts rotation and scale\r\n m.data[0] = d * inverseDet;\r\n m.data[1] = -c * inverseDet;\r\n m.data[2] = -b * inverseDet;\r\n m.data[3] = a * inverseDet;\r\n const tx = this.data[4];\r\n const ty = this.data[5];\r\n // invert translation\r\n // transform translation into the matrix basis created by rot/scale\r\n m.data[4] = -(tx * m.data[0] + ty * m.data[2]);\r\n m.data[5] = -(tx * m.data[1] + ty * m.data[3]);\r\n return m;\r\n }\r\n multiply(vectorOrMatrix, dest) {\r\n if (vectorOrMatrix instanceof Vector) {\r\n const result = dest || new Vector(0, 0);\r\n const vector = vectorOrMatrix;\r\n // these shenanigans are to allow dest and vector to be the same instance\r\n const resultX = vector.x * this.data[0] + vector.y * this.data[2] + this.data[4];\r\n const resultY = vector.x * this.data[1] + vector.y * this.data[3] + this.data[5];\r\n result.x = resultX;\r\n result.y = resultY;\r\n return result;\r\n }\r\n else {\r\n const result = dest || new AffineMatrix();\r\n const other = vectorOrMatrix;\r\n const a11 = this.data[0];\r\n const a21 = this.data[1];\r\n // const a31 = 0;\r\n const a12 = this.data[2];\r\n const a22 = this.data[3];\r\n // const a32 = 0;\r\n const a13 = this.data[4];\r\n const a23 = this.data[5];\r\n // const a33 = 1;\r\n const b11 = other.data[0];\r\n const b21 = other.data[1];\r\n // const b31 = 0;\r\n const b12 = other.data[2];\r\n const b22 = other.data[3];\r\n // const b32 = 0;\r\n const b13 = other.data[4];\r\n const b23 = other.data[5];\r\n // const b33 = 1;\r\n result.data[0] = a11 * b11 + a12 * b21; // + a13 * b31; // zero\r\n result.data[1] = a21 * b11 + a22 * b21; // + a23 * b31; // zero\r\n result.data[2] = a11 * b12 + a12 * b22; // + a13 * b32; // zero\r\n result.data[3] = a21 * b12 + a22 * b22; // + a23 * b32; // zero\r\n result.data[4] = a11 * b13 + a12 * b23 + a13; // * b33; // one\r\n result.data[5] = a21 * b13 + a22 * b23 + a23; // * b33; // one\r\n const s = this.getScale();\r\n result._scaleSignX = sign(s.x) * sign(result._scaleSignX);\r\n result._scaleSignY = sign(s.y) * sign(result._scaleSignY);\r\n return result;\r\n }\r\n }\r\n to4x4() {\r\n const mat = new Matrix();\r\n mat.data[0] = this.data[0];\r\n mat.data[1] = this.data[1];\r\n mat.data[2] = 0;\r\n mat.data[3] = 0;\r\n mat.data[4] = this.data[2];\r\n mat.data[5] = this.data[3];\r\n mat.data[6] = 0;\r\n mat.data[7] = 0;\r\n mat.data[8] = 0;\r\n mat.data[9] = 0;\r\n mat.data[10] = 1;\r\n mat.data[11] = 0;\r\n mat.data[12] = this.data[4];\r\n mat.data[13] = this.data[5];\r\n mat.data[14] = 0;\r\n mat.data[15] = 1;\r\n return mat;\r\n }\r\n setRotation(angle) {\r\n const currentScale = this.getScale();\r\n const sine = Math.sin(angle);\r\n const cosine = Math.cos(angle);\r\n this.data[0] = cosine * currentScale.x;\r\n this.data[1] = sine * currentScale.y;\r\n this.data[2] = -sine * currentScale.x;\r\n this.data[3] = cosine * currentScale.y;\r\n }\r\n getRotation() {\r\n const angle = Math.atan2(this.data[1] / this.getScaleY(), this.data[0] / this.getScaleX());\r\n return canonicalizeAngle(angle);\r\n }\r\n getScaleX() {\r\n // absolute scale of the matrix (we lose sign so need to add it back)\r\n const xscale = vec(this.data[0], this.data[2]).distance();\r\n return this._scaleSignX * xscale;\r\n }\r\n getScaleY() {\r\n // absolute scale of the matrix (we lose sign so need to add it back)\r\n const yscale = vec(this.data[1], this.data[3]).distance();\r\n return this._scaleSignY * yscale;\r\n }\r\n /**\r\n * Get the scale of the matrix\r\n */\r\n getScale() {\r\n return vec(this.getScaleX(), this.getScaleY());\r\n }\r\n setScaleX(val) {\r\n if (val === this._scale[0]) {\r\n return;\r\n }\r\n this._scaleSignX = sign(val);\r\n // negative scale acts like a 180 rotation, so flip\r\n const xscale = vec(this.data[0] * this._scaleSignX, this.data[2] * this._scaleSignX).normalize();\r\n this.data[0] = xscale.x * val;\r\n this.data[2] = xscale.y * val;\r\n this._scale[0] = val;\r\n }\r\n setScaleY(val) {\r\n if (val === this._scale[1]) {\r\n return;\r\n }\r\n this._scaleSignY = sign(val);\r\n // negative scale acts like a 180 rotation, so flip\r\n const yscale = vec(this.data[1] * this._scaleSignY, this.data[3] * this._scaleSignY).normalize();\r\n this.data[1] = yscale.x * val;\r\n this.data[3] = yscale.y * val;\r\n this._scale[1] = val;\r\n }\r\n setScale(scale) {\r\n this.setScaleX(scale.x);\r\n this.setScaleY(scale.y);\r\n }\r\n isIdentity() {\r\n return (this.data[0] === 1 &&\r\n this.data[1] === 0 &&\r\n this.data[2] === 0 &&\r\n this.data[3] === 1 &&\r\n this.data[4] === 0 &&\r\n this.data[5] === 0);\r\n }\r\n /**\r\n * Resets the current matrix to the identity matrix, mutating it\r\n * @returns {AffineMatrix} Current matrix as identity\r\n */\r\n reset() {\r\n const mat = this;\r\n mat.data[0] = 1;\r\n mat.data[1] = 0;\r\n mat.data[2] = 0;\r\n mat.data[3] = 1;\r\n mat.data[4] = 0;\r\n mat.data[5] = 0;\r\n return mat;\r\n }\r\n /**\r\n * Creates a new Matrix with the same data as the current 4x4\r\n */\r\n clone(dest) {\r\n const mat = dest || new AffineMatrix();\r\n mat.data[0] = this.data[0];\r\n mat.data[1] = this.data[1];\r\n mat.data[2] = this.data[2];\r\n mat.data[3] = this.data[3];\r\n mat.data[4] = this.data[4];\r\n mat.data[5] = this.data[5];\r\n return mat;\r\n }\r\n toString() {\r\n return `\r\n[${this.data[0]} ${this.data[2]} ${this.data[4]}]\r\n[${this.data[1]} ${this.data[3]} ${this.data[5]}]\r\n[0 0 1]\r\n`;\r\n }\r\n}\r\n\n;// CONCATENATED MODULE: ./Graphics/Context/transform-stack.ts\n\r\nclass TransformStack {\r\n constructor() {\r\n this._transforms = [];\r\n this._currentTransform = AffineMatrix.identity();\r\n }\r\n save() {\r\n this._transforms.push(this._currentTransform);\r\n this._currentTransform = this._currentTransform.clone();\r\n }\r\n restore() {\r\n this._currentTransform = this._transforms.pop();\r\n }\r\n translate(x, y) {\r\n return this._currentTransform.translate(x, y);\r\n }\r\n rotate(angle) {\r\n return this._currentTransform.rotate(angle);\r\n }\r\n scale(x, y) {\r\n return this._currentTransform.scale(x, y);\r\n }\r\n set current(matrix) {\r\n this._currentTransform = matrix;\r\n }\r\n get current() {\r\n return this._currentTransform;\r\n }\r\n}\r\n\n;// CONCATENATED MODULE: ./Graphics/Context/state-stack.ts\n\r\nclass StateStack {\r\n constructor() {\r\n this._states = [];\r\n this._currentState = this._getDefaultState();\r\n }\r\n _getDefaultState() {\r\n return {\r\n opacity: 1,\r\n z: 0,\r\n tint: Color.White,\r\n material: null\r\n };\r\n }\r\n _cloneState() {\r\n return {\r\n opacity: this._currentState.opacity,\r\n z: this._currentState.z,\r\n tint: this._currentState.tint.clone(),\r\n material: this._currentState.material // TODO is this going to cause problems when cloning\r\n };\r\n }\r\n save() {\r\n this._states.push(this._currentState);\r\n this._currentState = this._cloneState();\r\n }\r\n restore() {\r\n this._currentState = this._states.pop();\r\n }\r\n get current() {\r\n return this._currentState;\r\n }\r\n set current(val) {\r\n this._currentState = val;\r\n }\r\n}\r\n\n;// CONCATENATED MODULE: ./Resources/Resource.ts\n\r\n\r\nconst ResourceEvents = {\r\n Complete: 'complete',\r\n Load: 'load',\r\n LoadStart: 'loadstart',\r\n Progress: 'progress',\r\n Error: 'error'\r\n};\r\n/**\r\n * The [[Resource]] type allows games built in Excalibur to load generic resources.\r\n * For any type of remote resource it is recommended to use [[Resource]] for preloading.\r\n */\r\nclass Resource {\r\n /**\r\n * @param path Path to the remote resource\r\n * @param responseType The type to expect as a response: \"\" | \"arraybuffer\" | \"blob\" | \"document\" | \"json\" | \"text\";\r\n * @param bustCache Whether or not to cache-bust requests\r\n */\r\n constructor(path, responseType, bustCache = false) {\r\n this.path = path;\r\n this.responseType = responseType;\r\n this.bustCache = bustCache;\r\n this.data = null;\r\n this.logger = Logger.getInstance();\r\n this.events = new EventEmitter();\r\n }\r\n /**\r\n * Returns true if the Resource is completely loaded and is ready\r\n * to be drawn.\r\n */\r\n isLoaded() {\r\n return this.data !== null;\r\n }\r\n _cacheBust(uri) {\r\n const query = /\\?\\w*=\\w*/;\r\n if (query.test(uri)) {\r\n uri += '&__=' + Date.now();\r\n }\r\n else {\r\n uri += '?__=' + Date.now();\r\n }\r\n return uri;\r\n }\r\n /**\r\n * Begin loading the resource and returns a promise to be resolved on completion\r\n */\r\n load() {\r\n return new Promise((resolve, reject) => {\r\n // Exit early if we already have data\r\n if (this.data !== null) {\r\n this.logger.debug('Already have data for resource', this.path);\r\n this.events.emit('complete', this.data);\r\n resolve(this.data);\r\n return;\r\n }\r\n const request = new XMLHttpRequest();\r\n request.open('GET', this.bustCache ? this._cacheBust(this.path) : this.path, true);\r\n request.responseType = this.responseType;\r\n request.addEventListener('loadstart', (e) => this.events.emit('loadstart', e));\r\n request.addEventListener('progress', (e) => this.events.emit('progress', e));\r\n request.addEventListener('error', (e) => this.events.emit('error', e));\r\n request.addEventListener('load', (e) => this.events.emit('load', e));\r\n request.addEventListener('load', () => {\r\n // XHR on file:// success status is 0, such as with PhantomJS\r\n if (request.status !== 0 && request.status !== 200) {\r\n this.logger.error('Failed to load resource ', this.path, ' server responded with error code', request.status);\r\n this.events.emit('error', request.response);\r\n reject(new Error(request.statusText));\r\n return;\r\n }\r\n this.data = request.response;\r\n this.events.emit('complete', this.data);\r\n this.logger.debug('Completed loading resource', this.path);\r\n resolve(this.data);\r\n });\r\n request.send();\r\n });\r\n }\r\n}\r\n\n;// CONCATENATED MODULE: ./Util/Watch.ts\n/**\r\n * Watch an object with a proxy, only fires if property value is different\r\n */\r\nfunction watch(type, change) {\r\n if (!type) {\r\n return type;\r\n }\r\n if (type.__isProxy === undefined) {\r\n // expando hack to mark a proxy\r\n return new Proxy(type, {\r\n set: (obj, prop, value) => {\r\n // The default behavior to store the value\r\n if (obj[prop] !== value) {\r\n obj[prop] = value;\r\n // Avoid watching private junk\r\n if (typeof prop === 'string') {\r\n if (prop[0] !== '_') {\r\n change(obj);\r\n }\r\n }\r\n }\r\n // Indicate success\r\n return true;\r\n },\r\n get: (obj, prop) => {\r\n if (prop !== '__isProxy') {\r\n return obj[prop];\r\n }\r\n return true;\r\n }\r\n });\r\n }\r\n return type;\r\n}\r\n/**\r\n * Watch an object with a proxy, fires change on any property value change\r\n */\r\nfunction watchAny(type, change) {\r\n if (!type) {\r\n return type;\r\n }\r\n if (type.__isProxy === undefined) {\r\n // expando hack to mark a proxy\r\n return new Proxy(type, {\r\n set: (obj, prop, value) => {\r\n // The default behavior to store the value\r\n obj[prop] = value;\r\n // Avoid watching private junk\r\n if (typeof prop === 'string') {\r\n if (prop[0] !== '_') {\r\n change(obj);\r\n }\r\n }\r\n // Indicate success\r\n return true;\r\n },\r\n get: (obj, prop) => {\r\n if (prop !== '__isProxy') {\r\n return obj[prop];\r\n }\r\n return true;\r\n }\r\n });\r\n }\r\n return type;\r\n}\r\n\n;// CONCATENATED MODULE: ./Graphics/Graphic.ts\n\r\n\r\n\r\n\r\n/**\r\n * A Graphic is the base Excalibur primitive for something that can be drawn to the [[ExcaliburGraphicsContext]].\r\n * [[Sprite]], [[Animation]], [[GraphicsGroup]], [[Canvas]], [[Rectangle]], [[Circle]], and [[Polygon]] all derive from the\r\n * [[Graphic]] abstract class.\r\n *\r\n * Implementors of a Graphic must override the abstract [[Graphic._drawImage]] method to render an image to the graphics context. Graphic\r\n * handles all the position, rotation, and scale transformations in [[Graphic._preDraw]] and [[Graphic._postDraw]]\r\n */\r\nclass Graphic {\r\n isStale() {\r\n return this._transformStale;\r\n }\r\n /**\r\n * Gets or sets the flipHorizontal, which will flip the graphic horizontally (across the y axis)\r\n */\r\n get flipHorizontal() {\r\n return this._flipHorizontal;\r\n }\r\n set flipHorizontal(value) {\r\n this._flipHorizontal = value;\r\n this._transformStale = true;\r\n }\r\n /**\r\n * Gets or sets the flipVertical, which will flip the graphic vertically (across the x axis)\r\n */\r\n get flipVertical() {\r\n return this._flipVertical;\r\n }\r\n set flipVertical(value) {\r\n this._flipVertical = value;\r\n this._transformStale = true;\r\n }\r\n /**\r\n * Gets or sets the rotation of the graphic\r\n */\r\n get rotation() {\r\n return this._rotation;\r\n }\r\n set rotation(value) {\r\n this._rotation = value;\r\n this._transformStale = true;\r\n }\r\n /**\r\n * Gets or sets the scale of the graphic, this affects the width and\r\n */\r\n get scale() {\r\n return this._scale;\r\n }\r\n set scale(value) {\r\n this._scale = watch(value, () => {\r\n this._transformStale = true;\r\n });\r\n this._transformStale = true;\r\n }\r\n /**\r\n * Gets or sets the origin of the graphic, if not set the center of the graphic is the origin\r\n */\r\n get origin() {\r\n return this._origin;\r\n }\r\n set origin(value) {\r\n this._origin = watch(value, () => {\r\n this._transformStale = true;\r\n });\r\n this._transformStale = true;\r\n }\r\n constructor(options) {\r\n var _a, _b, _c, _d, _e, _f;\r\n this.id = Graphic._ID++;\r\n this.transform = AffineMatrix.identity();\r\n this.tint = null;\r\n this._transformStale = true;\r\n /**\r\n * Gets or sets wether to show debug information about the graphic\r\n */\r\n this.showDebug = false;\r\n this._flipHorizontal = false;\r\n this._flipVertical = false;\r\n this._rotation = 0;\r\n /**\r\n * Gets or sets the opacity of the graphic, 0 is transparent, 1 is solid (opaque).\r\n */\r\n this.opacity = 1;\r\n this._scale = Vector.One;\r\n this._origin = null;\r\n this._width = 0;\r\n this._height = 0;\r\n if (options) {\r\n this.origin = (_a = options.origin) !== null && _a !== void 0 ? _a : this.origin;\r\n this.flipHorizontal = (_b = options.flipHorizontal) !== null && _b !== void 0 ? _b : this.flipHorizontal;\r\n this.flipVertical = (_c = options.flipVertical) !== null && _c !== void 0 ? _c : this.flipVertical;\r\n this.rotation = (_d = options.rotation) !== null && _d !== void 0 ? _d : this.rotation;\r\n this.opacity = (_e = options.opacity) !== null && _e !== void 0 ? _e : this.opacity;\r\n this.scale = (_f = options.scale) !== null && _f !== void 0 ? _f : this.scale;\r\n }\r\n }\r\n cloneGraphicOptions() {\r\n return {\r\n origin: this.origin ? this.origin.clone() : null,\r\n flipHorizontal: this.flipHorizontal,\r\n flipVertical: this.flipVertical,\r\n rotation: this.rotation,\r\n opacity: this.opacity,\r\n scale: this.scale ? this.scale.clone() : null\r\n };\r\n }\r\n /**\r\n * Gets or sets the width of the graphic (always positive)\r\n */\r\n get width() {\r\n return Math.abs(this._width * this.scale.x);\r\n }\r\n /**\r\n * Gets or sets the height of the graphic (always positive)\r\n */\r\n get height() {\r\n return Math.abs(this._height * this.scale.y);\r\n }\r\n set width(value) {\r\n this._width = value;\r\n this._transformStale = true;\r\n }\r\n set height(value) {\r\n this._height = value;\r\n this._transformStale = true;\r\n }\r\n /**\r\n * Gets a copy of the bounds in pixels occupied by the graphic on the the screen. This includes scale.\r\n */\r\n get localBounds() {\r\n return BoundingBox.fromDimension(this.width, this.height, Vector.Zero);\r\n }\r\n /**\r\n * Draw the whole graphic to the context including transform\r\n * @param ex The excalibur graphics context\r\n * @param x\r\n * @param y\r\n */\r\n draw(ex, x, y) {\r\n this._preDraw(ex, x, y);\r\n this._drawImage(ex, 0, 0);\r\n this._postDraw(ex);\r\n }\r\n /**\r\n * Apply affine transformations to the graphics context to manipulate the graphic before [[Graphic._drawImage]]\r\n * @param ex\r\n * @param x\r\n * @param y\r\n */\r\n _preDraw(ex, x, y) {\r\n ex.save();\r\n ex.translate(x, y);\r\n if (this._transformStale) {\r\n this.transform.reset();\r\n this.transform.scale(Math.abs(this.scale.x), Math.abs(this.scale.y));\r\n this._rotate(this.transform);\r\n this._flip(this.transform);\r\n this._transformStale = false;\r\n }\r\n ex.multiply(this.transform);\r\n // it is important to multiply alphas so graphics respect the current context\r\n ex.opacity = ex.opacity * this.opacity;\r\n if (this.tint) {\r\n ex.tint = this.tint;\r\n }\r\n }\r\n _rotate(ex) {\r\n var _a;\r\n const scaleDirX = this.scale.x > 0 ? 1 : -1;\r\n const scaleDirY = this.scale.y > 0 ? 1 : -1;\r\n const origin = (_a = this.origin) !== null && _a !== void 0 ? _a : vec(this.width / 2, this.height / 2);\r\n ex.translate(origin.x, origin.y);\r\n ex.rotate(this.rotation);\r\n // This is for handling direction changes 1 or -1, that way we don't have mismatched translates()\r\n ex.scale(scaleDirX, scaleDirY);\r\n ex.translate(-origin.x, -origin.y);\r\n }\r\n _flip(ex) {\r\n if (this.flipHorizontal) {\r\n ex.translate(this.width / this.scale.x, 0);\r\n ex.scale(-1, 1);\r\n }\r\n if (this.flipVertical) {\r\n ex.translate(0, this.height / this.scale.y);\r\n ex.scale(1, -1);\r\n }\r\n }\r\n /**\r\n * Apply any additional work after [[Graphic._drawImage]] and restore the context state.\r\n * @param ex\r\n */\r\n _postDraw(ex) {\r\n if (this.showDebug) {\r\n ex.debug.drawRect(0, 0, this.width, this.height);\r\n }\r\n ex.restore();\r\n }\r\n}\r\nGraphic._ID = 0;\r\n\n;// CONCATENATED MODULE: ./Graphics/Sprite.ts\n\r\n\r\nclass Sprite extends Graphic {\r\n static from(image) {\r\n return new Sprite({\r\n image: image\r\n });\r\n }\r\n constructor(options) {\r\n var _a, _b;\r\n super(options);\r\n this._logger = Logger.getInstance();\r\n this._dirty = true;\r\n this._logNotLoadedWarning = false;\r\n this.image = options.image;\r\n const { width, height } = options;\r\n this.sourceView = (_a = options.sourceView) !== null && _a !== void 0 ? _a : { x: 0, y: 0, width: width !== null && width !== void 0 ? width : 0, height: height !== null && height !== void 0 ? height : 0 };\r\n this.destSize = (_b = options.destSize) !== null && _b !== void 0 ? _b : { width: width !== null && width !== void 0 ? width : 0, height: height !== null && height !== void 0 ? height : 0 };\r\n this._updateSpriteDimensions();\r\n this.image.ready.then(() => {\r\n this._updateSpriteDimensions();\r\n });\r\n }\r\n get width() {\r\n return Math.abs(this.destSize.width * this.scale.x);\r\n }\r\n get height() {\r\n return Math.abs(this.destSize.height * this.scale.y);\r\n }\r\n set width(newWidth) {\r\n newWidth /= Math.abs(this.scale.x);\r\n this.destSize.width = newWidth;\r\n super.width = Math.ceil(this.destSize.width);\r\n }\r\n set height(newHeight) {\r\n newHeight /= Math.abs(this.scale.y);\r\n this.destSize.height = newHeight;\r\n super.height = Math.ceil(this.destSize.height);\r\n }\r\n _updateSpriteDimensions() {\r\n var _a, _b, _c, _d, _e, _f;\r\n const { width: nativeWidth, height: nativeHeight } = this.image;\r\n // This code uses || to avoid 0's\r\n // If the source is not specified, use the native dimension\r\n this.sourceView.width = ((_a = this.sourceView) === null || _a === void 0 ? void 0 : _a.width) || nativeWidth;\r\n this.sourceView.height = ((_b = this.sourceView) === null || _b === void 0 ? void 0 : _b.height) || nativeHeight;\r\n // If the destination is not specified, use the source if specified, then native\r\n this.destSize.width = ((_c = this.destSize) === null || _c === void 0 ? void 0 : _c.width) || ((_d = this.sourceView) === null || _d === void 0 ? void 0 : _d.width) || nativeWidth;\r\n this.destSize.height = ((_e = this.destSize) === null || _e === void 0 ? void 0 : _e.height) || ((_f = this.sourceView) === null || _f === void 0 ? void 0 : _f.height) || nativeHeight;\r\n this.width = Math.ceil(this.destSize.width) * this.scale.x;\r\n this.height = Math.ceil(this.destSize.height) * this.scale.y;\r\n }\r\n _preDraw(ex, x, y) {\r\n if (this.image.isLoaded() && this._dirty) {\r\n this._dirty = false;\r\n this._updateSpriteDimensions();\r\n }\r\n super._preDraw(ex, x, y);\r\n }\r\n _drawImage(ex, x, y) {\r\n if (this.image.isLoaded()) {\r\n ex.drawImage(this.image.image, this.sourceView.x, this.sourceView.y, this.sourceView.width, this.sourceView.height, x, y, this.destSize.width, this.destSize.height);\r\n }\r\n else {\r\n if (!this._logNotLoadedWarning) {\r\n this._logger.warn(`ImageSource ${this.image.path}` +\r\n ` is not yet loaded and won't be drawn. Please call .load() or include in a Loader.\\n\\n` +\r\n `Read https://excaliburjs.com/docs/imagesource for more information.`);\r\n }\r\n this._logNotLoadedWarning = true;\r\n }\r\n }\r\n clone() {\r\n return new Sprite({\r\n image: this.image,\r\n sourceView: { ...this.sourceView },\r\n destSize: { ...this.destSize },\r\n ...this.cloneGraphicOptions()\r\n });\r\n }\r\n}\r\n\n;// CONCATENATED MODULE: ./Graphics/Filtering.ts\n/**\r\n * Describes the different image filtering modes\r\n */\r\nvar ImageFiltering;\r\n(function (ImageFiltering) {\r\n /**\r\n * Pixel is useful when you do not want smoothing aka antialiasing applied to your graphics.\r\n *\r\n * Useful for Pixel art aesthetics.\r\n */\r\n ImageFiltering[\"Pixel\"] = \"Pixel\";\r\n /**\r\n * Blended is useful when you have high resolution artwork and would like it blended and smoothed\r\n */\r\n ImageFiltering[\"Blended\"] = \"Blended\";\r\n})(ImageFiltering || (ImageFiltering = {}));\r\n\n;// CONCATENATED MODULE: ./Graphics/Context/texture-loader.ts\n\r\n\r\n/**\r\n * Manages loading image sources into webgl textures, a unique id is associated with all sources\r\n */\r\nclass TextureLoader {\r\n constructor(gl) {\r\n this._textureMap = new Map();\r\n this._gl = gl;\r\n TextureLoader._MAX_TEXTURE_SIZE = gl.getParameter(gl.MAX_TEXTURE_SIZE);\r\n }\r\n /**\r\n * Get the WebGL Texture from a source image\r\n * @param image\r\n */\r\n get(image) {\r\n return this._textureMap.get(image);\r\n }\r\n /**\r\n * Returns whether a source image has been loaded as a texture\r\n * @param image\r\n */\r\n has(image) {\r\n return this._textureMap.has(image);\r\n }\r\n /**\r\n * Loads a graphic into webgl and returns it's texture info, a webgl context must be previously registered\r\n * @param image Source graphic\r\n * @param filtering {ImageFiltering} The ImageFiltering mode to apply to the loaded texture\r\n * @param forceUpdate Optionally force a texture to be reloaded, useful if the source graphic has changed\r\n */\r\n load(image, filtering, forceUpdate = false) {\r\n // Ignore loading if webgl is not registered\r\n const gl = this._gl;\r\n if (!gl) {\r\n return null;\r\n }\r\n let tex = null;\r\n // If reuse the texture if it's from the same source\r\n if (this.has(image)) {\r\n tex = this.get(image);\r\n }\r\n // Update existing webgl texture and return early\r\n if (tex) {\r\n if (forceUpdate) {\r\n gl.bindTexture(gl.TEXTURE_2D, tex);\r\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image);\r\n }\r\n return tex;\r\n }\r\n // No texture exists create a new one\r\n tex = gl.createTexture();\r\n TextureLoader.checkImageSizeSupportedAndLog(image);\r\n gl.bindTexture(gl.TEXTURE_2D, tex);\r\n gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, true);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\r\n // NEAREST for pixel art, LINEAR for hi-res\r\n const filterMode = filtering !== null && filtering !== void 0 ? filtering : TextureLoader.filtering;\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, filterMode === ImageFiltering.Pixel ? gl.NEAREST : gl.LINEAR);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, filterMode === ImageFiltering.Pixel ? gl.NEAREST : gl.LINEAR);\r\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image);\r\n this._textureMap.set(image, tex);\r\n return tex;\r\n }\r\n delete(image) {\r\n // Ignore loading if webgl is not registered\r\n const gl = this._gl;\r\n if (!gl) {\r\n return null;\r\n }\r\n let tex = null;\r\n if (this.has(image)) {\r\n tex = this.get(image);\r\n gl.deleteTexture(tex);\r\n }\r\n }\r\n /**\r\n * Takes an image and returns if it meets size criteria for hardware\r\n * @param image\r\n * @returns if the image will be supported at runtime\r\n */\r\n static checkImageSizeSupportedAndLog(image) {\r\n var _a;\r\n const originalSrc = (_a = image.dataset.originalSrc) !== null && _a !== void 0 ? _a : 'internal canvas bitmap';\r\n if (image.width > TextureLoader._MAX_TEXTURE_SIZE || image.height > TextureLoader._MAX_TEXTURE_SIZE) {\r\n TextureLoader._LOGGER.error(`The image [${originalSrc}] provided to Excalibur is too large for the device's maximum texture size of ` +\r\n `(${TextureLoader._MAX_TEXTURE_SIZE}x${TextureLoader._MAX_TEXTURE_SIZE}) please resize to an image `\r\n + `for excalibur to render properly.\\n\\nImages will likely render as black rectangles.\\n\\n` +\r\n `Read more here: https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API/WebGL_best_practices#understand_system_limits`);\r\n return false;\r\n }\r\n else if (image.width > 4096 || image.height > 4096) {\r\n // https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API/WebGL_best_practices#understand_system_limits\r\n TextureLoader._LOGGER.warn(`The image [${originalSrc}] provided to excalibur is too large may not work on all mobile devices, ` +\r\n `it is recommended you resize images to a maximum (4096x4096).\\n\\n` +\r\n `Images will likely render as black rectangles on some mobile platforms.\\n\\n` +\r\n `Read more here: https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API/WebGL_best_practices#understand_system_limits`);\r\n }\r\n return true;\r\n }\r\n}\r\nTextureLoader._LOGGER = Logger.getInstance();\r\n/**\r\n * Sets the default filtering for the Excalibur texture loader, default [[ImageFiltering.Blended]]\r\n */\r\nTextureLoader.filtering = ImageFiltering.Blended;\r\nTextureLoader._MAX_TEXTURE_SIZE = 4096;\r\n\n;// CONCATENATED MODULE: ./Graphics/ImageSource.ts\n\r\n\r\n\r\n\r\n\r\nclass ImageSource {\r\n /**\r\n * The original size of the source image in pixels\r\n */\r\n get width() {\r\n return this.image.naturalWidth;\r\n }\r\n /**\r\n * The original height of the source image in pixels\r\n */\r\n get height() {\r\n return this.image.naturalHeight;\r\n }\r\n /**\r\n * Returns true if the Texture is completely loaded and is ready\r\n * to be drawn.\r\n */\r\n isLoaded() {\r\n if (!this._src) {\r\n // this boosts speed of access\r\n this._src = this.data.src;\r\n }\r\n return !!this._src;\r\n }\r\n get image() {\r\n return this.data;\r\n }\r\n /**\r\n * The path to the image, can also be a data url like 'data:image/'\r\n * @param path {string} Path to the image resource relative from the HTML document hosting the game, or absolute\r\n * @param bustCache {boolean} Should excalibur add a cache busting querystring?\r\n * @param filtering {ImageFiltering} Optionally override the image filtering set by [[EngineOptions.antialiasing]]\r\n */\r\n constructor(path, bustCache = false, filtering) {\r\n this.path = path;\r\n this._logger = Logger.getInstance();\r\n /**\r\n * Access to the underlying html image element\r\n */\r\n this.data = new Image();\r\n this._readyFuture = new Future();\r\n /**\r\n * Promise the resolves when the image is loaded and ready for use, does not initiate loading\r\n */\r\n this.ready = this._readyFuture.promise;\r\n this._resource = new Resource(path, 'blob', bustCache);\r\n this.filtering = filtering;\r\n if (path.endsWith('.svg') || path.endsWith('.gif')) {\r\n this._logger.warn(`Image type is not fully supported, you may have mixed results ${path}. Fully supported: jpg, bmp, and png`);\r\n }\r\n }\r\n /**\r\n * Should excalibur add a cache busting querystring? By default false.\r\n * Must be set before loading\r\n */\r\n get bustCache() {\r\n return this._resource.bustCache;\r\n }\r\n set bustCache(val) {\r\n this._resource.bustCache = val;\r\n }\r\n /**\r\n * Begins loading the image and returns a promise that resolves when the image is loaded\r\n */\r\n async load() {\r\n if (this.isLoaded()) {\r\n return this.data;\r\n }\r\n try {\r\n // Load base64 or blob if needed\r\n let url;\r\n if (!this.path.includes('data:image/')) {\r\n const blob = await this._resource.load();\r\n url = URL.createObjectURL(blob);\r\n }\r\n else {\r\n url = this.path;\r\n }\r\n // Decode the image\r\n const image = new Image();\r\n // Use Image.onload over Image.decode()\r\n // https://bugs.chromium.org/p/chromium/issues/detail?id=1055828#c7\r\n // Otherwise chrome will throw still Image.decode() failures for large textures\r\n const loadedFuture = new Future();\r\n image.onload = () => loadedFuture.resolve();\r\n image.src = url;\r\n image.setAttribute('data-original-src', this.path);\r\n await loadedFuture.promise;\r\n // Set results\r\n // We defer loading the texture into webgl until the first draw that way we avoid a singleton\r\n // and for the multi-engine case the texture needs to be created in EACH webgl context to work\r\n // See image-renderer.ts draw()\r\n this.data = image;\r\n // emit warning if potentially too big\r\n TextureLoader.checkImageSizeSupportedAndLog(this.data);\r\n }\r\n catch (error) {\r\n throw `Error loading ImageSource from path '${this.path}' with error [${error.message}]`;\r\n }\r\n // Do a bad thing to pass the filtering as an attribute\r\n this.data.setAttribute('filtering', this.filtering);\r\n // todo emit complete\r\n this._readyFuture.resolve(this.data);\r\n return this.data;\r\n }\r\n /**\r\n * Build a sprite from this ImageSource\r\n */\r\n toSprite() {\r\n return Sprite.from(this);\r\n }\r\n /**\r\n * Unload images from memory\r\n */\r\n unload() {\r\n this.data = new Image();\r\n }\r\n}\r\n\n;// CONCATENATED MODULE: ./Graphics/SpriteSheet.ts\n\r\n\r\n/**\r\n * Represents a collection of sprites from a source image with some organization in a grid\r\n */\r\nclass SpriteSheet {\r\n /**\r\n * Build a new sprite sheet from a list of sprites\r\n *\r\n * Use [[SpriteSheet.fromImageSource]] to create a SpriteSheet from an [[ImageSource]] organized in a grid\r\n * @param options\r\n */\r\n constructor(options) {\r\n this._logger = Logger.getInstance();\r\n this.sprites = [];\r\n const { sprites, rows, columns } = options;\r\n this.sprites = sprites;\r\n this.rows = rows !== null && rows !== void 0 ? rows : 1;\r\n this.columns = columns !== null && columns !== void 0 ? columns : this.sprites.length;\r\n }\r\n /**\r\n * Find a sprite by their x/y position in the SpriteSheet, for example `getSprite(0, 0)` is the [[Sprite]] in the top-left\r\n * @param x\r\n * @param y\r\n */\r\n getSprite(x, y) {\r\n if (x >= this.columns || x < 0) {\r\n this._logger.warn(`No sprite exists in the SpriteSheet at (${x}, ${y}), x: ${x} should be between 0 and ${this.columns - 1}`);\r\n return null;\r\n }\r\n if (y >= this.rows || y < 0) {\r\n this._logger.warn(`No sprite exists in the SpriteSheet at (${x}, ${y}), y: ${y} should be between 0 and ${this.rows - 1}`);\r\n return null;\r\n }\r\n const spriteIndex = x + y * this.columns;\r\n return this.sprites[spriteIndex];\r\n }\r\n /**\r\n * Create a sprite sheet from a sparse set of [[SourceView]] rectangles\r\n * @param options\r\n */\r\n static fromImageSourceWithSourceViews(options) {\r\n const sprites = options.sourceViews.map(sourceView => {\r\n return new Sprite({\r\n image: options.image,\r\n sourceView\r\n });\r\n });\r\n return new SpriteSheet({ sprites });\r\n }\r\n /**\r\n * Create a SpriteSheet from an [[ImageSource]] organized in a grid\r\n *\r\n * Example:\r\n * ```\r\n * const spriteSheet = SpriteSheet.fromImageSource({\r\n * image: imageSource,\r\n * grid: {\r\n * rows: 5,\r\n * columns: 2,\r\n * spriteWidth: 32, // pixels\r\n * spriteHeight: 32 // pixels\r\n * },\r\n * // Optionally specify spacing\r\n * spacing: {\r\n * // pixels from the top left to start the sprite parsing\r\n * originOffset: {\r\n * x: 5,\r\n * y: 5\r\n * },\r\n * // pixels between each sprite while parsing\r\n * margin: {\r\n * x: 1,\r\n * y: 1\r\n * }\r\n * }\r\n * })\r\n * ```\r\n *\r\n * @param options\r\n */\r\n static fromImageSource(options) {\r\n var _a;\r\n const sprites = [];\r\n options.spacing = (_a = options.spacing) !== null && _a !== void 0 ? _a : {};\r\n const { image, grid: { rows, columns: cols, spriteWidth, spriteHeight }, spacing: { originOffset, margin } } = options;\r\n const offsetDefaults = { x: 0, y: 0, ...originOffset };\r\n const marginDefaults = { x: 0, y: 0, ...margin };\r\n for (let x = 0; x < cols; x++) {\r\n for (let y = 0; y < rows; y++) {\r\n sprites[x + y * cols] = new Sprite({\r\n image: image,\r\n sourceView: {\r\n x: x * spriteWidth + marginDefaults.x * x + offsetDefaults.x,\r\n y: y * spriteHeight + marginDefaults.y * y + offsetDefaults.y,\r\n width: spriteWidth,\r\n height: spriteHeight\r\n },\r\n destSize: { height: spriteHeight, width: spriteWidth }\r\n });\r\n }\r\n }\r\n return new SpriteSheet({\r\n sprites: sprites,\r\n rows: rows,\r\n columns: cols\r\n });\r\n }\r\n clone() {\r\n return new SpriteSheet({\r\n sprites: this.sprites.map(sprite => sprite.clone()),\r\n rows: this.rows,\r\n columns: this.columns\r\n });\r\n }\r\n}\r\n\n;// CONCATENATED MODULE: ./Graphics/SpriteFont.ts\n\r\n\r\n\r\n\r\nclass SpriteFont extends Graphic {\r\n constructor(options) {\r\n super(options);\r\n this._text = '';\r\n this.alphabet = '';\r\n this.shadow = null;\r\n this.caseInsensitive = false;\r\n this.spacing = 0;\r\n this._logger = Logger.getInstance();\r\n this._alreadyWarnedAlphabet = false;\r\n this._alreadyWarnedSpriteSheet = false;\r\n const { alphabet, spriteSheet, caseInsensitive, spacing, shadow } = options;\r\n this.alphabet = alphabet;\r\n this.spriteSheet = spriteSheet;\r\n this.caseInsensitive = caseInsensitive !== null && caseInsensitive !== void 0 ? caseInsensitive : this.caseInsensitive;\r\n this.spacing = spacing !== null && spacing !== void 0 ? spacing : this.spacing;\r\n this.shadow = shadow !== null && shadow !== void 0 ? shadow : this.shadow;\r\n }\r\n _getCharacterSprites(text) {\r\n const results = [];\r\n // handle case insensitive\r\n const textToRender = this.caseInsensitive ? text.toLocaleLowerCase() : text;\r\n const alphabet = this.caseInsensitive ? this.alphabet.toLocaleLowerCase() : this.alphabet;\r\n // for each letter in text\r\n for (let letterIndex = 0; letterIndex < textToRender.length; letterIndex++) {\r\n // find the sprite index in alphabet , if there is an error pick the first\r\n const letter = textToRender[letterIndex];\r\n let spriteIndex = alphabet.indexOf(letter);\r\n if (spriteIndex === -1) {\r\n spriteIndex = 0;\r\n if (!this._alreadyWarnedAlphabet) {\r\n this._logger.warn(`SpriteFont - Cannot find letter '${letter}' in configured alphabet '${alphabet}'.`);\r\n this._logger.warn('There maybe be more issues in the SpriteFont configuration. No additional warnings will be logged.');\r\n this._alreadyWarnedAlphabet = true;\r\n }\r\n }\r\n const letterSprite = this.spriteSheet.sprites[spriteIndex];\r\n if (letterSprite) {\r\n results.push(letterSprite);\r\n }\r\n else {\r\n if (!this._alreadyWarnedSpriteSheet) {\r\n this._logger.warn(`SpriteFont - Cannot find sprite for '${letter}' at index '${spriteIndex}' in configured SpriteSheet`);\r\n this._logger.warn('There maybe be more issues in the SpriteFont configuration. No additional warnings will be logged.');\r\n this._alreadyWarnedSpriteSheet = true;\r\n }\r\n }\r\n }\r\n return results;\r\n }\r\n measureText(text, maxWidth) {\r\n const lines = this._getLinesFromText(text, maxWidth);\r\n const maxWidthLine = lines.reduce((a, b) => {\r\n return a.length > b.length ? a : b;\r\n });\r\n const sprites = this._getCharacterSprites(maxWidthLine);\r\n let width = 0;\r\n let height = 0;\r\n for (const sprite of sprites) {\r\n width += sprite.width + this.spacing;\r\n height = Math.max(height, sprite.height);\r\n }\r\n return BoundingBox.fromDimension(width, height * lines.length, Vector.Zero);\r\n }\r\n _drawImage(ex, x, y, maxWidth) {\r\n let xCursor = 0;\r\n let yCursor = 0;\r\n let height = 0;\r\n const lines = this._getLinesFromText(this._text, maxWidth);\r\n for (const line of lines) {\r\n for (const sprite of this._getCharacterSprites(line)) {\r\n // draw it in the right spot and increase the cursor by sprite width\r\n sprite.draw(ex, x + xCursor, y + yCursor);\r\n xCursor += sprite.width + this.spacing;\r\n height = Math.max(height, sprite.height);\r\n }\r\n xCursor = 0;\r\n yCursor += height;\r\n }\r\n }\r\n render(ex, text, _color, x, y, maxWidth) {\r\n // SpriteFont doesn't support _color, yet...\r\n this._text = text;\r\n const bounds = this.measureText(text, maxWidth);\r\n this.width = bounds.width;\r\n this.height = bounds.height;\r\n if (this.shadow) {\r\n ex.save();\r\n ex.translate(this.shadow.offset.x, this.shadow.offset.y);\r\n this._preDraw(ex, x, y);\r\n this._drawImage(ex, 0, 0, maxWidth);\r\n this._postDraw(ex);\r\n ex.restore();\r\n }\r\n this._preDraw(ex, x, y);\r\n this._drawImage(ex, 0, 0, maxWidth);\r\n this._postDraw(ex);\r\n }\r\n clone() {\r\n return new SpriteFont({\r\n alphabet: this.alphabet,\r\n spriteSheet: this.spriteSheet,\r\n spacing: this.spacing\r\n });\r\n }\r\n _getLinesFromText(text, maxWidth) {\r\n if (this._cachedText === text && this._cachedRenderWidth === maxWidth) {\r\n return this._cachedLines;\r\n }\r\n const lines = text.split('\\n');\r\n if (maxWidth == null) {\r\n return lines;\r\n }\r\n // If the current line goes past the maxWidth, append a new line without modifying the underlying text.\r\n for (let i = 0; i < lines.length; i++) {\r\n let line = lines[i];\r\n let newLine = '';\r\n // Note: we subtract the spacing to counter the initial padding on the left side.\r\n if (this.measureText(line).width > maxWidth) {\r\n while (this.measureText(line).width > maxWidth) {\r\n newLine = line[line.length - 1] + newLine;\r\n line = line.slice(0, -1); // Remove last character from line\r\n }\r\n // Update the array with our new values\r\n lines[i] = line;\r\n lines[i + 1] = newLine;\r\n }\r\n }\r\n this._cachedText = text;\r\n this._cachedLines = lines;\r\n this._cachedRenderWidth = maxWidth;\r\n return lines;\r\n }\r\n}\r\n\n;// CONCATENATED MODULE: ./Graphics/Context/debug-font.png\n/* harmony default export */ const debug_font = (\"data:image/png;base64,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\");\n;// CONCATENATED MODULE: ./Graphics/Context/debug-text.ts\n\r\n\r\n/**\r\n * Internal debugtext helper\r\n */\r\nclass DebugText {\r\n constructor() {\r\n /**\r\n * base64 font\r\n */\r\n this.fontSheet = debug_font;\r\n this.size = 16;\r\n this.load();\r\n }\r\n load() {\r\n this._imageSource = new ImageSource(this.fontSheet);\r\n return this._imageSource.load().then(() => {\r\n this._spriteSheet = SpriteSheet.fromImageSource({\r\n image: this._imageSource,\r\n grid: {\r\n rows: 3,\r\n columns: 16,\r\n spriteWidth: 16,\r\n spriteHeight: 16\r\n }\r\n });\r\n this._spriteFont = new SpriteFont({\r\n alphabet: '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ,!\\'&.\"?-()+ ',\r\n caseInsensitive: true,\r\n spriteSheet: this._spriteSheet,\r\n spacing: -6\r\n });\r\n });\r\n }\r\n /**\r\n * Writes debug text using the built in sprint font\r\n * @param ctx\r\n * @param text\r\n * @param pos\r\n */\r\n write(ctx, text, pos) {\r\n if (this._imageSource.isLoaded()) {\r\n this._spriteFont.render(ctx, text, null, pos.x, pos.y);\r\n }\r\n }\r\n}\r\n\n;// CONCATENATED MODULE: ./Graphics/Context/render-source.ts\nclass RenderSource {\r\n constructor(_gl, _texture) {\r\n this._gl = _gl;\r\n this._texture = _texture;\r\n }\r\n use() {\r\n const gl = this._gl;\r\n gl.activeTexture(gl.TEXTURE0);\r\n gl.bindTexture(gl.TEXTURE_2D, this._texture);\r\n }\r\n disable() {\r\n const gl = this._gl;\r\n gl.bindTexture(gl.TEXTURE_2D, null);\r\n }\r\n}\r\n\n;// CONCATENATED MODULE: ./Graphics/Context/render-target.ts\n\r\nclass RenderTarget {\r\n constructor(options) {\r\n this.width = options.width;\r\n this.height = options.height;\r\n this._gl = options.gl;\r\n this._setupFramebuffer();\r\n }\r\n setResolution(width, height) {\r\n const gl = this._gl;\r\n this.width = width;\r\n this.height = height;\r\n gl.bindTexture(gl.TEXTURE_2D, this._frameTexture);\r\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.width, this.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);\r\n }\r\n get frameBuffer() {\r\n return this._frameBuffer;\r\n }\r\n get frameTexture() {\r\n return this._frameTexture;\r\n }\r\n _setupFramebuffer() {\r\n // Allocates frame buffer\r\n const gl = this._gl;\r\n this._frameTexture = gl.createTexture();\r\n gl.bindTexture(gl.TEXTURE_2D, this._frameTexture);\r\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.width, this.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);\r\n // set the filtering so we don't need mips\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\r\n // attach the texture as the first color attachment\r\n const attachmentPoint = gl.COLOR_ATTACHMENT0;\r\n // After this bind all draw calls will draw to this framebuffer texture\r\n this._frameBuffer = gl.createFramebuffer();\r\n gl.bindFramebuffer(gl.FRAMEBUFFER, this._frameBuffer);\r\n gl.framebufferTexture2D(gl.FRAMEBUFFER, attachmentPoint, gl.TEXTURE_2D, this._frameTexture, 0);\r\n // Reset after initialized\r\n this.disable();\r\n }\r\n toRenderSource() {\r\n const source = new RenderSource(this._gl, this._frameTexture);\r\n return source;\r\n }\r\n /**\r\n * When called, all drawing gets redirected to this render target\r\n */\r\n use() {\r\n const gl = this._gl;\r\n gl.bindFramebuffer(gl.FRAMEBUFFER, this._frameBuffer);\r\n // very important to set the viewport to the size of the framebuffer texture\r\n gl.viewport(0, 0, this.width, this.height);\r\n }\r\n /**\r\n * When called, all drawing is sent back to the canvas\r\n */\r\n disable() {\r\n const gl = this._gl;\r\n // passing null switches rendering back to the canvas\r\n gl.bindFramebuffer(gl.FRAMEBUFFER, null);\r\n gl.bindTexture(gl.TEXTURE_2D, null);\r\n }\r\n}\r\n\n;// CONCATENATED MODULE: ./Graphics/Context/line-renderer/line-vertex.glsl\n/* harmony default export */ const line_vertex = (\"#version 300 es\\r\\nin vec2 a_position;\\r\\nin vec4 a_color;\\r\\n\\r\\nout lowp vec4 v_color;\\r\\n\\r\\nuniform mat4 u_matrix;\\r\\n\\r\\nvoid main() {\\r\\n // Set the vertex position using the ortho transform matrix\\r\\n gl_Position = u_matrix * vec4(a_position, 0.0, 1.0);\\r\\n\\r\\n // Passthrough the color\\r\\n v_color = a_color;\\r\\n}\");\n;// CONCATENATED MODULE: ./Graphics/Context/line-renderer/line-fragment.glsl\n/* harmony default export */ const line_fragment = (\"#version 300 es\\r\\nprecision mediump float;\\r\\n\\r\\n// Color\\r\\nin lowp vec4 v_color;\\r\\n\\r\\nout vec4 fragColor;\\r\\n\\r\\nvoid main() {\\r\\n fragColor = v_color;\\r\\n}\");\n;// CONCATENATED MODULE: ./Graphics/Context/webgl-util.ts\n/**\r\n * Return the size of the GlType in bytes\r\n * @param gl\r\n * @param type\r\n */\r\nfunction getGlTypeSizeBytes(gl, type) {\r\n switch (type) {\r\n case gl.FLOAT:\r\n return 4;\r\n case gl.SHORT:\r\n return 2;\r\n case gl.UNSIGNED_SHORT:\r\n return 2;\r\n case gl.BYTE:\r\n return 1;\r\n case gl.UNSIGNED_BYTE:\r\n return 1;\r\n default:\r\n return 1;\r\n }\r\n}\r\n/**\r\n * Based on the type return the number of attribute components\r\n *\r\n * https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/vertexAttribPointer\r\n * @param gl\r\n * @param type\r\n */\r\nfunction getAttributeComponentSize(gl, type) {\r\n switch (type) {\r\n case gl.LOW_FLOAT:\r\n case gl.HIGH_FLOAT:\r\n case gl.FLOAT:\r\n return 1;\r\n case gl.FLOAT_VEC2:\r\n return 2;\r\n case gl.FLOAT_VEC3:\r\n return 3;\r\n case gl.FLOAT_VEC4:\r\n return 4;\r\n case gl.BYTE:\r\n return 1;\r\n case gl.UNSIGNED_BYTE:\r\n return 1;\r\n case gl.UNSIGNED_SHORT:\r\n case gl.SHORT:\r\n return 1;\r\n default:\r\n return 1;\r\n }\r\n}\r\n/**\r\n * Based on the attribute return the corresponding supported attrib pointer type\r\n * https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/vertexAttribPointer\r\n *\r\n * @param gl\r\n * @param type\r\n */\r\nfunction getAttributePointerType(gl, type) {\r\n switch (type) {\r\n case gl.LOW_FLOAT:\r\n case gl.HIGH_FLOAT:\r\n case gl.FLOAT:\r\n case gl.FLOAT_VEC2:\r\n case gl.FLOAT_VEC3:\r\n case gl.FLOAT_VEC4:\r\n return gl.FLOAT;\r\n case gl.BYTE:\r\n return gl.BYTE;\r\n case gl.UNSIGNED_BYTE:\r\n return gl.UNSIGNED_BYTE;\r\n case gl.SHORT:\r\n return gl.SHORT;\r\n case gl.UNSIGNED_SHORT:\r\n return gl.UNSIGNED_SHORT;\r\n default:\r\n return gl.FLOAT;\r\n }\r\n}\r\n\n;// CONCATENATED MODULE: ./Graphics/Context/shader.ts\n\r\n\r\nclass Shader {\r\n get compiled() {\r\n return this._compiled;\r\n }\r\n /**\r\n * Create a shader program in excalibur\r\n * @param options specify shader vertex and fragment source\r\n */\r\n constructor(options) {\r\n this._logger = Logger.getInstance();\r\n this.uniforms = {};\r\n this.attributes = {};\r\n this._compiled = false;\r\n const { gl, vertexSource, fragmentSource } = options;\r\n this._gl = gl;\r\n this.vertexSource = vertexSource;\r\n this.fragmentSource = fragmentSource;\r\n }\r\n /**\r\n * Binds the shader program\r\n */\r\n use() {\r\n const gl = this._gl;\r\n gl.useProgram(this.program);\r\n Shader._ACTIVE_SHADER_INSTANCE = this;\r\n }\r\n isCurrentlyBound() {\r\n return Shader._ACTIVE_SHADER_INSTANCE === this;\r\n }\r\n /**\r\n * Compile the current shader against a webgl context\r\n */\r\n compile() {\r\n const gl = this._gl;\r\n const vertexShader = this._compileShader(gl, this.vertexSource, gl.VERTEX_SHADER);\r\n const fragmentShader = this._compileShader(gl, this.fragmentSource, gl.FRAGMENT_SHADER);\r\n this.program = this._createProgram(gl, vertexShader, fragmentShader);\r\n const attributes = this.getAttributes();\r\n for (const attribute of attributes) {\r\n this.attributes[attribute.name] = attribute;\r\n }\r\n const uniforms = this.getUniforms();\r\n for (const uniform of uniforms) {\r\n this.uniforms[uniform.name] = uniform;\r\n }\r\n this._compiled = true;\r\n return this.program;\r\n }\r\n getUniforms() {\r\n const gl = this._gl;\r\n const uniformCount = gl.getProgramParameter(this.program, gl.ACTIVE_UNIFORMS);\r\n const uniforms = [];\r\n for (let i = 0; i < uniformCount; i++) {\r\n const uniform = gl.getActiveUniform(this.program, i);\r\n const uniformLocation = gl.getUniformLocation(this.program, uniform.name);\r\n uniforms.push({\r\n name: uniform.name,\r\n glType: uniform.type,\r\n location: uniformLocation\r\n });\r\n }\r\n return uniforms;\r\n }\r\n getAttributes() {\r\n const gl = this._gl;\r\n const attributeCount = gl.getProgramParameter(this.program, gl.ACTIVE_ATTRIBUTES);\r\n const attributes = [];\r\n for (let i = 0; i < attributeCount; i++) {\r\n const attribute = gl.getActiveAttrib(this.program, i);\r\n const attributeLocation = gl.getAttribLocation(this.program, attribute.name);\r\n attributes.push({\r\n name: attribute.name,\r\n glType: getAttributePointerType(gl, attribute.type),\r\n size: getAttributeComponentSize(gl, attribute.type),\r\n location: attributeLocation,\r\n normalized: false\r\n });\r\n }\r\n return attributes;\r\n }\r\n /**\r\n * Set a texture in a gpu texture slot\r\n * @param slotNumber\r\n * @param texture\r\n */\r\n setTexture(slotNumber, texture) {\r\n const gl = this._gl;\r\n gl.activeTexture(gl.TEXTURE0 + slotNumber);\r\n gl.bindTexture(gl.TEXTURE_2D, texture);\r\n }\r\n /**\r\n * Set an integer uniform for the current shader\r\n *\r\n * **Important** Must call ex.Shader.use() before setting a uniform!\r\n *\r\n * @param name\r\n * @param value\r\n */\r\n setUniformInt(name, value) {\r\n this.setUniform('uniform1i', name, ~~value);\r\n }\r\n /**\r\n * Set an integer uniform for the current shader, WILL NOT THROW on error.\r\n *\r\n * **Important** Must call ex.Shader.use() before setting a uniform!\r\n *\r\n * @param name\r\n * @param value\r\n */\r\n trySetUniformInt(name, value) {\r\n return this.trySetUniform('uniform1i', name, ~~value);\r\n }\r\n /**\r\n * Set an integer array uniform for the current shader\r\n *\r\n * **Important** Must call ex.Shader.use() before setting a uniform!\r\n *\r\n * @param name\r\n * @param value\r\n */\r\n setUniformIntArray(name, value) {\r\n this.setUniform('uniform1iv', name, value);\r\n }\r\n /**\r\n * Set an integer array uniform for the current shader, WILL NOT THROW on error.\r\n *\r\n * **Important** Must call ex.Shader.use() before setting a uniform!\r\n *\r\n * @param name\r\n * @param value\r\n */\r\n trySetUniformIntArray(name, value) {\r\n return this.trySetUniform('uniform1iv', name, value);\r\n }\r\n /**\r\n * Set a boolean uniform for the current shader\r\n *\r\n * **Important** Must call ex.Shader.use() before setting a uniform!\r\n *\r\n * @param name\r\n * @param value\r\n */\r\n setUniformBoolean(name, value) {\r\n this.setUniform('uniform1i', name, value ? 1 : 0);\r\n }\r\n /**\r\n * Set a boolean uniform for the current shader, WILL NOT THROW on error.\r\n *\r\n * **Important** Must call ex.Shader.use() before setting a uniform!\r\n *\r\n * @param name\r\n * @param value\r\n */\r\n trySetUniformBoolean(name, value) {\r\n return this.trySetUniform('uniform1i', name, value ? 1 : 0);\r\n }\r\n /**\r\n * Set a float uniform for the current shader\r\n *\r\n * **Important** Must call ex.Shader.use() before setting a uniform!\r\n *\r\n * @param name\r\n * @param value\r\n */\r\n setUniformFloat(name, value) {\r\n this.setUniform('uniform1f', name, value);\r\n }\r\n /**\r\n * Set a float uniform for the current shader, WILL NOT THROW on error.\r\n *\r\n * **Important** Must call ex.Shader.use() before setting a uniform!\r\n *\r\n * @param name\r\n * @param value\r\n */\r\n trySetUniformFloat(name, value) {\r\n return this.trySetUniform('uniform1f', name, value);\r\n }\r\n /**\r\n * Set a float array uniform for the current shader\r\n *\r\n * **Important** Must call ex.Shader.use() before setting a uniform!\r\n *\r\n * @param name\r\n * @param value\r\n */\r\n setUniformFloatArray(name, value) {\r\n this.setUniform('uniform1fv', name, value);\r\n }\r\n /**\r\n * Set a float array uniform for the current shader, WILL NOT THROW on error.\r\n *\r\n * **Important** Must call ex.Shader.use() before setting a uniform!\r\n *\r\n * @param name\r\n * @param value\r\n */\r\n trySetUniformFloatArray(name, value) {\r\n return this.trySetUniform('uniform1fv', name, value);\r\n }\r\n /**\r\n * Set a [[Vector]] uniform for the current shader\r\n *\r\n * **Important** Must call ex.Shader.use() before setting a uniform!\r\n *\r\n * @param name\r\n * @param value\r\n */\r\n setUniformFloatVector(name, value) {\r\n this.setUniform('uniform2f', name, value.x, value.y);\r\n }\r\n /**\r\n * Set a [[Vector]] uniform for the current shader, WILL NOT THROW on error.\r\n *\r\n * **Important** Must call ex.Shader.use() before setting a uniform!\r\n *\r\n * @param name\r\n * @param value\r\n */\r\n trySetUniformFloatVector(name, value) {\r\n return this.trySetUniform('uniform2f', name, value.x, value.y);\r\n }\r\n /**\r\n * Set a [[Color]] uniform for the current shader\r\n *\r\n * **Important** Must call ex.Shader.use() before setting a uniform!\r\n *\r\n * @param name\r\n * @param value\r\n */\r\n setUniformFloatColor(name, value) {\r\n this.setUniform('uniform4f', name, value.r / 255, value.g / 255, value.b / 255, value.a);\r\n }\r\n /**\r\n * Set a [[Color]] uniform for the current shader, WILL NOT THROW on error.\r\n *\r\n * **Important** Must call ex.Shader.use() before setting a uniform!\r\n *\r\n * @param name\r\n * @param value\r\n */\r\n trySetUniformFloatColor(name, value) {\r\n return this.trySetUniform('uniform4f', name, value.r / 255, value.g / 255, value.b / 255, value.a);\r\n }\r\n /**\r\n * Set an [[Matrix]] uniform for the current shader\r\n *\r\n * **Important** Must call ex.Shader.use() before setting a uniform!\r\n *\r\n * @param name\r\n * @param value\r\n */\r\n setUniformMatrix(name, value) {\r\n this.setUniform('uniformMatrix4fv', name, false, value.data);\r\n }\r\n /**\r\n * Set an [[Matrix]] uniform for the current shader, WILL NOT THROW on error.\r\n *\r\n * **Important** Must call ex.Shader.use() before setting a uniform!\r\n *\r\n * @param name\r\n * @param value\r\n */\r\n trySetUniformMatrix(name, value) {\r\n return this.trySetUniform('uniformMatrix4fv', name, false, value.data);\r\n }\r\n /**\r\n * Set any available uniform type in webgl\r\n *\r\n * For example setUniform('uniformMatrix2fv', 'u_my2x2_mat`, ...);\r\n */\r\n setUniform(uniformType, name, ...value) {\r\n if (!this._compiled) {\r\n throw Error(`Must compile shader before setting a uniform ${uniformType}:${name}`);\r\n }\r\n if (!this.isCurrentlyBound()) {\r\n throw Error('Currently accessed shader instance is not the current active shader in WebGL,' +\r\n ' must call `shader.use()` before setting uniforms');\r\n }\r\n const gl = this._gl;\r\n const location = gl.getUniformLocation(this.program, name);\r\n if (location) {\r\n const args = [location, ...value];\r\n this._gl[uniformType].apply(this._gl, args);\r\n }\r\n else {\r\n throw Error(`Uniform ${uniformType}:${name} doesn\\'t exist or is not used in the shader source code,` +\r\n ' unused uniforms are optimized away by most browsers');\r\n }\r\n }\r\n /**\r\n * Set any available uniform type in webgl. Will try to set the uniform, will return false if the uniform didn't exist,\r\n * true if it was set.\r\n *\r\n * WILL NOT THROW on error\r\n *\r\n * For example setUniform('uniformMatrix2fv', 'u_my2x2_mat`, ...);\r\n *\r\n */\r\n trySetUniform(uniformType, name, ...value) {\r\n if (!this._compiled) {\r\n this._logger.warn(`Must compile shader before setting a uniform ${uniformType}:${name}`);\r\n return false;\r\n }\r\n if (!this.isCurrentlyBound()) {\r\n this._logger.warn('Currently accessed shader instance is not the current active shader in WebGL,' +\r\n ' must call `shader.use()` before setting uniforms');\r\n return false;\r\n }\r\n const gl = this._gl;\r\n const location = gl.getUniformLocation(this.program, name);\r\n if (location) {\r\n const args = [location, ...value];\r\n this._gl[uniformType].apply(this._gl, args);\r\n }\r\n else {\r\n return false;\r\n }\r\n return true;\r\n }\r\n _createProgram(gl, vertexShader, fragmentShader) {\r\n const program = gl.createProgram();\r\n if (program === null) {\r\n throw Error('Could not create graphics shader program');\r\n }\r\n // attach the shaders.\r\n gl.attachShader(program, vertexShader);\r\n gl.attachShader(program, fragmentShader);\r\n // link the program.\r\n gl.linkProgram(program);\r\n const success = gl.getProgramParameter(program, gl.LINK_STATUS);\r\n if (!success) {\r\n throw Error(`Could not link the program: [${gl.getProgramInfoLog(program)}]`);\r\n }\r\n return program;\r\n }\r\n _compileShader(gl, source, type) {\r\n const typeName = gl.VERTEX_SHADER === type ? 'vertex' : 'fragment';\r\n const shader = gl.createShader(type);\r\n if (shader === null) {\r\n throw Error(`Could not build shader: [${source}]`);\r\n }\r\n gl.shaderSource(shader, source);\r\n gl.compileShader(shader);\r\n const success = gl.getShaderParameter(shader, gl.COMPILE_STATUS);\r\n if (!success) {\r\n const errorInfo = gl.getShaderInfoLog(shader);\r\n throw Error(`Could not compile ${typeName} shader:\\n\\n${errorInfo}${this._processSourceForError(source, errorInfo)}`);\r\n }\r\n return shader;\r\n }\r\n _processSourceForError(source, errorInfo) {\r\n const lines = source.split('\\n');\r\n const errorLineStart = errorInfo.search(/\\d:\\d/);\r\n const errorLineEnd = errorInfo.indexOf(' ', errorLineStart);\r\n const [_, error2] = errorInfo.slice(errorLineStart, errorLineEnd).split(':').map(v => Number(v));\r\n for (let i = 0; i < lines.length; i++) {\r\n lines[i] = `${i + 1}: ${lines[i]}${error2 === (i + 1) ? ' <----- ERROR!' : ''}`;\r\n }\r\n return '\\n\\nSource:\\n' + lines.join('\\n');\r\n }\r\n}\r\nShader._ACTIVE_SHADER_INSTANCE = null;\r\n\n;// CONCATENATED MODULE: ./Graphics/Context/vertex-buffer.ts\n/**\r\n * Helper around vertex buffer to simplify creating and uploading geometry\r\n *\r\n * Under the hood uses Float32Array\r\n */\r\nclass VertexBuffer {\r\n constructor(options) {\r\n /**\r\n * If the vertices never change switching 'static' can be more efficient on the gpu\r\n *\r\n * Default is 'dynamic'\r\n */\r\n this.type = 'dynamic';\r\n const { gl, size, type, data } = options;\r\n this._gl = gl;\r\n this.buffer = this._gl.createBuffer();\r\n if (!data && !size) {\r\n throw Error('Must either provide data or a size to the VertexBuffer');\r\n }\r\n if (!data) {\r\n this.bufferData = new Float32Array(size);\r\n }\r\n else {\r\n this.bufferData = data;\r\n }\r\n this.type = type !== null && type !== void 0 ? type : this.type;\r\n // Allocate buffer\r\n gl.bindBuffer(gl.ARRAY_BUFFER, this.buffer);\r\n gl.bufferData(gl.ARRAY_BUFFER, this.bufferData, this.type === 'static' ? gl.STATIC_DRAW : gl.DYNAMIC_DRAW);\r\n }\r\n /**\r\n * Bind this vertex buffer\r\n */\r\n bind() {\r\n const gl = this._gl;\r\n gl.bindBuffer(gl.ARRAY_BUFFER, this.buffer);\r\n }\r\n /**\r\n * Upload vertex buffer geometry to the GPU\r\n */\r\n upload(count) {\r\n const gl = this._gl;\r\n gl.bindBuffer(gl.ARRAY_BUFFER, this.buffer);\r\n if (count) {\r\n gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.bufferData, 0, count);\r\n }\r\n else {\r\n // TODO always use bufferSubData? need to perf test it\r\n gl.bufferData(gl.ARRAY_BUFFER, this.bufferData, this.type === 'static' ? gl.STATIC_DRAW : gl.DYNAMIC_DRAW);\r\n }\r\n }\r\n}\r\n\n;// CONCATENATED MODULE: ./Graphics/Context/vertex-layout.ts\n\r\n\r\n/**\r\n * Helper around creating vertex attributes in a given [[VertexBuffer]], this is useful for describing\r\n * the memory layout for your vertices inside a particular buffer\r\n *\r\n * Note: This helper assumes interleaved attributes in one [[VertexBuffer]], not many.\r\n *\r\n * Working with `gl.vertexAttribPointer` can be tricky, and this attempts to double check you\r\n */\r\nclass VertexLayout {\r\n get vertexBuffer() {\r\n return this._vertexBuffer;\r\n }\r\n get attributes() {\r\n return this._attributes;\r\n }\r\n constructor(options) {\r\n this._logger = Logger.getInstance();\r\n this._layout = [];\r\n this._attributes = [];\r\n this._vertexTotalSizeBytes = 0;\r\n const { gl, shader, vertexBuffer, attributes } = options;\r\n this._gl = gl;\r\n this._vertexBuffer = vertexBuffer;\r\n this._attributes = attributes;\r\n this._shader = shader;\r\n if (shader) {\r\n this.initialize();\r\n }\r\n }\r\n /**\r\n * Total number of bytes that the vertex will take up\r\n */\r\n get totalVertexSizeBytes() {\r\n return this._vertexTotalSizeBytes;\r\n }\r\n set shader(shader) {\r\n if (shader && this._shader !== shader) {\r\n this._shader = shader;\r\n this.initialize();\r\n }\r\n }\r\n get shader() {\r\n return this._shader;\r\n }\r\n /**\r\n * Layouts need shader locations and must be bound to a shader\r\n */\r\n initialize() {\r\n if (!this._shader) {\r\n return;\r\n }\r\n if (!this._shader.compiled) {\r\n throw Error('Shader not compiled, shader must be compiled before defining a vertex layout');\r\n }\r\n this._layout.length = 0;\r\n const shaderAttributes = this._shader.attributes;\r\n for (const attribute of this._attributes) {\r\n const attrib = shaderAttributes[attribute[0]];\r\n if (!attrib) {\r\n throw Error(`The attribute named: ${attribute[0]} size ${attribute[1]}` +\r\n ` not found in the shader source code:\\n ${this._shader.vertexSource}`);\r\n }\r\n if (attrib.size !== attribute[1]) {\r\n throw Error(`VertexLayout size definition for attribute: [${attribute[0]}, ${attribute[1]}],`\r\n + ` doesnt match shader source size ${attrib.size}:\\n ${this._shader.vertexSource}`);\r\n }\r\n this._layout.push(attrib);\r\n }\r\n // calc size\r\n let componentsPerVertex = 0;\r\n for (const vertAttribute of this._layout) {\r\n const typeSize = getGlTypeSizeBytes(this._gl, vertAttribute.glType);\r\n this._vertexTotalSizeBytes += typeSize * vertAttribute.size;\r\n componentsPerVertex += vertAttribute.size;\r\n }\r\n if (this._vertexBuffer.bufferData.length % componentsPerVertex !== 0) {\r\n this._logger.warn(`The vertex component size (${componentsPerVertex}) does divide evenly into the specified vertex buffer`\r\n + ` (${this._vertexBuffer.bufferData.length})`);\r\n }\r\n }\r\n /**\r\n * Bind this layout with it's associated vertex buffer\r\n *\r\n * @param uploadBuffer Optionally indicate you wish to upload the buffer to the GPU associated with this layout\r\n */\r\n use(uploadBuffer = false, count) {\r\n if (!this._shader) {\r\n throw Error('No shader is associated with this vertex layout, a shader must be set');\r\n }\r\n const gl = this._gl;\r\n if (!this._shader.isCurrentlyBound()) {\r\n throw Error('Shader associated with this vertex layout is not active! Call shader.use() before layout.use()');\r\n }\r\n this._vertexBuffer.bind();\r\n if (uploadBuffer) {\r\n this._vertexBuffer.upload(count);\r\n }\r\n let offset = 0;\r\n // TODO switch to VAOs if the extension is\r\n for (const vert of this._layout) {\r\n gl.vertexAttribPointer(vert.location, vert.size, vert.glType, vert.normalized, this.totalVertexSizeBytes, offset);\r\n gl.enableVertexAttribArray(vert.location);\r\n offset += getGlTypeSizeBytes(gl, vert.glType) * vert.size;\r\n }\r\n }\r\n}\r\n\n;// CONCATENATED MODULE: ./Graphics/GraphicsDiagnostics.ts\nclass GraphicsDiagnostics {\r\n static clear() {\r\n GraphicsDiagnostics.DrawCallCount = 0;\r\n GraphicsDiagnostics.DrawnImagesCount = 0;\r\n }\r\n}\r\nGraphicsDiagnostics.DrawCallCount = 0;\r\nGraphicsDiagnostics.DrawnImagesCount = 0;\r\n\n;// CONCATENATED MODULE: ./Graphics/Context/line-renderer/line-renderer.ts\n\r\n\r\n\r\n\r\nclass LineRenderer {\r\n constructor() {\r\n this.type = 'ex.line';\r\n this.priority = 0;\r\n this._maxLines = 10922;\r\n this._vertexIndex = 0;\r\n this._lineCount = 0;\r\n }\r\n initialize(gl, context) {\r\n this._gl = gl;\r\n this._context = context;\r\n this._shader = new Shader({\r\n gl,\r\n vertexSource: line_vertex,\r\n fragmentSource: line_fragment\r\n });\r\n this._shader.compile();\r\n this._shader.use();\r\n this._shader.setUniformMatrix('u_matrix', this._context.ortho);\r\n this._vertexBuffer = new VertexBuffer({\r\n gl,\r\n size: 6 * 2 * this._maxLines,\r\n type: 'dynamic'\r\n });\r\n this._layout = new VertexLayout({\r\n gl,\r\n vertexBuffer: this._vertexBuffer,\r\n shader: this._shader,\r\n attributes: [\r\n ['a_position', 2],\r\n ['a_color', 4]\r\n ]\r\n });\r\n }\r\n draw(start, end, color) {\r\n // Force a render if the batch is full\r\n if (this._isFull()) {\r\n this.flush();\r\n }\r\n this._lineCount++;\r\n const transform = this._context.getTransform();\r\n const finalStart = transform.multiply(start);\r\n const finalEnd = transform.multiply(end);\r\n const vertexBuffer = this._vertexBuffer.bufferData;\r\n // Start\r\n vertexBuffer[this._vertexIndex++] = finalStart.x;\r\n vertexBuffer[this._vertexIndex++] = finalStart.y;\r\n vertexBuffer[this._vertexIndex++] = color.r / 255;\r\n vertexBuffer[this._vertexIndex++] = color.g / 255;\r\n vertexBuffer[this._vertexIndex++] = color.b / 255;\r\n vertexBuffer[this._vertexIndex++] = color.a;\r\n // End\r\n vertexBuffer[this._vertexIndex++] = finalEnd.x;\r\n vertexBuffer[this._vertexIndex++] = finalEnd.y;\r\n vertexBuffer[this._vertexIndex++] = color.r / 255;\r\n vertexBuffer[this._vertexIndex++] = color.g / 255;\r\n vertexBuffer[this._vertexIndex++] = color.b / 255;\r\n vertexBuffer[this._vertexIndex++] = color.a;\r\n }\r\n _isFull() {\r\n if (this._lineCount >= this._maxLines) {\r\n return true;\r\n }\r\n return false;\r\n }\r\n hasPendingDraws() {\r\n return this._lineCount !== 0;\r\n }\r\n flush() {\r\n // nothing to draw early exit\r\n if (this._lineCount === 0) {\r\n return;\r\n }\r\n const gl = this._gl;\r\n this._shader.use();\r\n this._layout.use(true);\r\n this._shader.setUniformMatrix('u_matrix', this._context.ortho);\r\n gl.drawArrays(gl.LINES, 0, this._lineCount * 2); // 2 verts per line\r\n GraphicsDiagnostics.DrawnImagesCount += this._lineCount;\r\n GraphicsDiagnostics.DrawCallCount++;\r\n // reset\r\n this._vertexIndex = 0;\r\n this._lineCount = 0;\r\n }\r\n}\r\n\n;// CONCATENATED MODULE: ./Graphics/Context/point-renderer/point-vertex.glsl\n/* harmony default export */ const point_vertex = (\"#version 300 es\\r\\nin vec2 a_position;\\r\\nin vec4 a_color;\\r\\nin float a_size;\\r\\nout lowp vec4 v_color;\\r\\nuniform mat4 u_matrix;\\r\\n\\r\\nvoid main() {\\r\\n gl_Position = u_matrix * vec4(a_position, 0.0, 1.0);\\r\\n gl_PointSize = a_size * 2.0;\\r\\n v_color = a_color;\\r\\n}\");\n;// CONCATENATED MODULE: ./Graphics/Context/point-renderer/point-fragment.glsl\n/* harmony default export */ const point_fragment = (\"#version 300 es\\r\\n\\r\\nprecision mediump float;\\r\\nin lowp vec4 v_color;\\r\\n\\r\\nout vec4 fragColor;\\r\\n\\r\\nvoid main() {\\r\\n float r = 0.0, delta = 0.0, alpha = 1.0;\\r\\n vec2 cxy = 2.0 * gl_PointCoord - 1.0;\\r\\n r = dot(cxy, cxy);\\r\\n\\r\\n delta = fwidth(r);\\r\\n alpha = 1.0 - smoothstep(1.0 - delta, 1.0 + delta, r);\\r\\n // \\\"premultiply\\\" the color by alpha\\r\\n vec4 color = v_color;\\r\\n color.a = color.a * alpha;\\r\\n color.rgb = color.rgb * color.a;\\r\\n fragColor = color;\\r\\n}\");\n;// CONCATENATED MODULE: ./Graphics/Context/point-renderer/point-renderer.ts\n\r\n\r\n\r\n\r\n\r\n\r\n\r\nclass PointRenderer {\r\n constructor() {\r\n this.type = 'ex.point';\r\n this.priority = 0;\r\n this._maxPoints = 10922;\r\n this._pointCount = 0;\r\n this._vertexIndex = 0;\r\n }\r\n initialize(gl, context) {\r\n this._gl = gl;\r\n this._context = context;\r\n this._shader = new Shader({\r\n gl,\r\n vertexSource: point_vertex,\r\n fragmentSource: point_fragment\r\n });\r\n this._shader.compile();\r\n this._shader.use();\r\n this._shader.setUniformMatrix('u_matrix', this._context.ortho);\r\n this._buffer = new VertexBuffer({\r\n gl,\r\n size: 7 * this._maxPoints,\r\n type: 'dynamic'\r\n });\r\n this._layout = new VertexLayout({\r\n gl,\r\n shader: this._shader,\r\n vertexBuffer: this._buffer,\r\n attributes: [\r\n ['a_position', 2],\r\n ['a_color', 4],\r\n ['a_size', 1]\r\n ]\r\n });\r\n }\r\n draw(point, color, size) {\r\n // Force a render if the batch is full\r\n if (this._isFull()) {\r\n this.flush();\r\n }\r\n this._pointCount++;\r\n const transform = this._context.getTransform();\r\n const opacity = this._context.opacity;\r\n const snapToPixel = this._context.snapToPixel;\r\n const finalPoint = transform.multiply(point);\r\n if (snapToPixel) {\r\n finalPoint.x = ~~(finalPoint.x + pixelSnapEpsilon);\r\n finalPoint.y = ~~(finalPoint.y + pixelSnapEpsilon);\r\n }\r\n const vertexBuffer = this._buffer.bufferData;\r\n vertexBuffer[this._vertexIndex++] = finalPoint.x;\r\n vertexBuffer[this._vertexIndex++] = finalPoint.y;\r\n vertexBuffer[this._vertexIndex++] = color.r / 255;\r\n vertexBuffer[this._vertexIndex++] = color.g / 255;\r\n vertexBuffer[this._vertexIndex++] = color.b / 255;\r\n vertexBuffer[this._vertexIndex++] = color.a * opacity;\r\n vertexBuffer[this._vertexIndex++] = size * Math.max(transform.getScaleX(), transform.getScaleY());\r\n }\r\n _isFull() {\r\n if (this._pointCount >= this._maxPoints) {\r\n return true;\r\n }\r\n return false;\r\n }\r\n hasPendingDraws() {\r\n return this._pointCount !== 0;\r\n }\r\n flush() {\r\n // nothing to draw early exit\r\n if (this._pointCount === 0) {\r\n return;\r\n }\r\n const gl = this._gl;\r\n this._shader.use();\r\n this._layout.use(true);\r\n this._shader.setUniformMatrix('u_matrix', this._context.ortho);\r\n gl.drawArrays(gl.POINTS, 0, this._pointCount);\r\n GraphicsDiagnostics.DrawnImagesCount += this._pointCount;\r\n GraphicsDiagnostics.DrawCallCount++;\r\n this._pointCount = 0;\r\n this._vertexIndex = 0;\r\n }\r\n}\r\n\n;// CONCATENATED MODULE: ./Graphics/Context/screen-pass-painter/screen-vertex.glsl\n/* harmony default export */ const screen_vertex = (\"#version 300 es\\r\\nin vec2 a_position;\\r\\n\\r\\nin vec2 a_texcoord;\\r\\nout vec2 v_texcoord;\\r\\n\\r\\nvoid main() {\\r\\n gl_Position = vec4(a_position, 0.0, 1.0);\\r\\n\\r\\n // Pass the texcoord to the fragment shader.\\r\\n v_texcoord = a_texcoord;\\r\\n}\");\n;// CONCATENATED MODULE: ./Graphics/Context/screen-pass-painter/screen-fragment.glsl\n/* harmony default export */ const screen_fragment = (\"#version 300 es\\r\\nprecision mediump float;\\r\\n\\r\\n// Passed in from the vertex shader.\\r\\nin vec2 v_texcoord;\\r\\n\\r\\n// The texture.\\r\\nuniform sampler2D u_texture;\\r\\n\\r\\nout vec4 fragColor;\\r\\n\\r\\nvoid main() {\\r\\n fragColor = texture(u_texture, v_texcoord);\\r\\n}\");\n;// CONCATENATED MODULE: ./Graphics/Context/screen-pass-painter/screen-pass-painter.ts\n\r\n\r\n\r\n\r\n\r\n/**\r\n * This is responsible for painting the entire screen during the render passes\r\n */\r\nclass ScreenPassPainter {\r\n constructor(gl) {\r\n this._gl = gl;\r\n this._shader = new Shader({\r\n gl,\r\n vertexSource: screen_vertex,\r\n fragmentSource: screen_fragment\r\n });\r\n this._shader.compile();\r\n // Setup memory layout\r\n this._buffer = new VertexBuffer({\r\n gl,\r\n type: 'static',\r\n // clip space quad + uv since we don't need a camera\r\n data: new Float32Array([\r\n -1, -1, 0, 0,\r\n -1, 1, 0, 1,\r\n 1, -1, 1, 0,\r\n 1, -1, 1, 0,\r\n -1, 1, 0, 1,\r\n 1, 1, 1, 1\r\n ])\r\n });\r\n this._layout = new VertexLayout({\r\n gl,\r\n shader: this._shader,\r\n vertexBuffer: this._buffer,\r\n attributes: [\r\n ['a_position', 2],\r\n ['a_texcoord', 2]\r\n ]\r\n });\r\n this._buffer.upload();\r\n }\r\n renderWithPostProcessor(postprocessor) {\r\n const gl = this._gl;\r\n postprocessor.getShader().use();\r\n postprocessor.getLayout().use();\r\n gl.drawArrays(gl.TRIANGLES, 0, 6);\r\n }\r\n renderToScreen() {\r\n const gl = this._gl;\r\n this._shader.use();\r\n this._layout.use();\r\n gl.drawArrays(gl.TRIANGLES, 0, 6);\r\n }\r\n}\r\n\n;// CONCATENATED MODULE: ./Graphics/Context/quad-index-buffer.ts\n\r\n/**\r\n * Helper that defines and index buffer for quad geometry\r\n *\r\n * Index buffers allow you to save space in vertex buffers when you share vertices in geometry\r\n * it is almost always worth it in terms of performance to use an index buffer.\r\n */\r\nclass QuadIndexBuffer {\r\n /**\r\n * @param gl WebGL2RenderingContext this layout will be attached to, these cannot be reused across contexts.\r\n * @param numberOfQuads Specify the max number of quads you want to draw\r\n * @param useUint16 Optionally force a uint16 buffer\r\n */\r\n constructor(gl, numberOfQuads, useUint16) {\r\n this._logger = Logger.getInstance();\r\n this._gl = gl;\r\n this.buffer = gl.createBuffer();\r\n gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.buffer);\r\n const totalVertices = numberOfQuads * 6;\r\n if (!useUint16) {\r\n this.bufferData = new Uint32Array(totalVertices);\r\n }\r\n else {\r\n // fall back to using gl.UNSIGNED_SHORT or tell the user they are out of luck\r\n const maxUint16 = 65535;\r\n const maxUint16Index = Math.floor((maxUint16 - 1) / 4); // max quads\r\n this.bufferGlType = gl.UNSIGNED_SHORT;\r\n this.bufferData = new Uint16Array(totalVertices);\r\n // TODO Should we error if this happens?? maybe not might crash mid game\r\n if (numberOfQuads > maxUint16Index) {\r\n this._logger.warn(`Total quads exceeds hardware index buffer limit (uint16), max(${maxUint16Index}) requested quads(${numberOfQuads})`);\r\n }\r\n }\r\n let currentQuad = 0;\r\n for (let i = 0; i < totalVertices; i += 6) {\r\n // first triangle\r\n this.bufferData[i + 0] = currentQuad + 0;\r\n this.bufferData[i + 1] = currentQuad + 1;\r\n this.bufferData[i + 2] = currentQuad + 2;\r\n // second triangle\r\n this.bufferData[i + 3] = currentQuad + 2;\r\n this.bufferData[i + 4] = currentQuad + 1;\r\n this.bufferData[i + 5] = currentQuad + 3;\r\n currentQuad += 4;\r\n }\r\n gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, this.bufferData, gl.STATIC_DRAW);\r\n }\r\n get size() {\r\n return this.bufferData.length;\r\n }\r\n /**\r\n * Upload data to the GPU\r\n */\r\n upload() {\r\n const gl = this._gl;\r\n gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.buffer);\r\n gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, this.bufferData, gl.STATIC_DRAW);\r\n }\r\n /**\r\n * Bind this index buffer\r\n */\r\n bind() {\r\n const gl = this._gl;\r\n gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.buffer);\r\n }\r\n}\r\n\n;// CONCATENATED MODULE: ./Graphics/Context/image-renderer/image-renderer.frag.glsl\n/* harmony default export */ const image_renderer_frag = (\"#version 300 es\\r\\nprecision mediump float;\\r\\n\\r\\n// UV coord\\r\\nin vec2 v_texcoord;\\r\\n\\r\\n// Texture index\\r\\nin lowp float v_textureIndex;\\r\\n\\r\\n// Textures in the current draw\\r\\nuniform sampler2D u_textures[%%count%%];\\r\\n\\r\\n// Opacity\\r\\nin float v_opacity;\\r\\n\\r\\nin vec4 v_tint;\\r\\n\\r\\nout vec4 fragColor;\\r\\n\\r\\nvoid main() {\\r\\n // In order to support the most efficient sprite batching, we have multiple\\r\\n // textures loaded into the gpu (usually 8) this picker logic skips over textures\\r\\n // that do not apply to a particular sprite.\\r\\n\\r\\n vec4 color = vec4(1.0, 0, 0, 1.0);\\r\\n\\r\\n // GLSL is templated out to pick the right texture and set the vec4 color\\r\\n %%texture_picker%%\\r\\n\\r\\n color.rgb = color.rgb * v_opacity;\\r\\n color.a = color.a * v_opacity;\\r\\n fragColor = color * v_tint;\\r\\n}\");\n;// CONCATENATED MODULE: ./Graphics/Context/image-renderer/image-renderer.vert.glsl\n/* harmony default export */ const image_renderer_vert = (\"#version 300 es\\r\\nin vec2 a_position;\\r\\n\\r\\n// Opacity \\r\\nin float a_opacity;\\r\\nout float v_opacity;\\r\\n\\r\\n// UV coordinate\\r\\nin vec2 a_texcoord;\\r\\nout vec2 v_texcoord;\\r\\n\\r\\n// Texture number\\r\\nin lowp float a_textureIndex;\\r\\nout lowp float v_textureIndex;\\r\\n\\r\\nin vec4 a_tint;\\r\\nout vec4 v_tint;\\r\\n\\r\\nuniform mat4 u_matrix;\\r\\n\\r\\nvoid main() {\\r\\n // Set the vertex position using the ortho transform matrix\\r\\n gl_Position = u_matrix * vec4(a_position, 0.0, 1.0);\\r\\n\\r\\n // Pass through the Opacity to the fragment shader\\r\\n v_opacity = a_opacity;\\r\\n // Pass through the UV coord to the fragment shader\\r\\n v_texcoord = a_texcoord;\\r\\n // Pass through the texture number to the fragment shader\\r\\n v_textureIndex = a_textureIndex;\\r\\n // Pass through the tint\\r\\n v_tint = a_tint;\\r\\n}\");\n;// CONCATENATED MODULE: ./Graphics/Context/image-renderer/image-renderer.ts\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\nclass ImageRenderer {\r\n constructor() {\r\n this.type = 'ex.image';\r\n this.priority = 0;\r\n this._maxImages = 10922; // max(uint16) / 6 verts\r\n this._maxTextures = 0;\r\n // Per flush vars\r\n this._imageCount = 0;\r\n this._textures = [];\r\n this._vertexIndex = 0;\r\n }\r\n initialize(gl, context) {\r\n this._gl = gl;\r\n this._context = context;\r\n // Transform shader source\r\n // FIXME: PIXEL 6 complains `ERROR: Expression too complex.` if we use it's reported max texture units, 125 seems to work for now...\r\n this._maxTextures = Math.min(gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS), 125);\r\n const transformedFrag = this._transformFragmentSource(image_renderer_frag, this._maxTextures);\r\n // Compile shader\r\n this._shader = new Shader({\r\n gl,\r\n fragmentSource: transformedFrag,\r\n vertexSource: image_renderer_vert\r\n });\r\n this._shader.compile();\r\n // setup uniforms\r\n this._shader.use();\r\n this._shader.setUniformMatrix('u_matrix', context.ortho);\r\n // Initialize texture slots to [0, 1, 2, 3, 4, .... maxGPUTextures]\r\n this._shader.setUniformIntArray('u_textures', [...Array(this._maxTextures)].map((_, i) => i));\r\n // Setup memory layout\r\n this._buffer = new VertexBuffer({\r\n gl,\r\n size: 10 * 4 * this._maxImages,\r\n type: 'dynamic'\r\n });\r\n this._layout = new VertexLayout({\r\n gl,\r\n shader: this._shader,\r\n vertexBuffer: this._buffer,\r\n attributes: [\r\n ['a_position', 2],\r\n ['a_opacity', 1],\r\n ['a_texcoord', 2],\r\n ['a_textureIndex', 1],\r\n ['a_tint', 4]\r\n ]\r\n });\r\n // Setup index buffer\r\n this._quads = new QuadIndexBuffer(gl, this._maxImages, true);\r\n }\r\n _transformFragmentSource(source, maxTextures) {\r\n let newSource = source.replace('%%count%%', maxTextures.toString());\r\n let texturePickerBuilder = '';\r\n for (let i = 0; i < maxTextures; i++) {\r\n if (i === 0) {\r\n texturePickerBuilder += `if (v_textureIndex <= ${i}.5) {\\n`;\r\n }\r\n else {\r\n texturePickerBuilder += ` else if (v_textureIndex <= ${i}.5) {\\n`;\r\n }\r\n texturePickerBuilder += ` color = texture(u_textures[${i}], v_texcoord);\\n`;\r\n texturePickerBuilder += ` }\\n`;\r\n }\r\n newSource = newSource.replace('%%texture_picker%%', texturePickerBuilder);\r\n return newSource;\r\n }\r\n _addImageAsTexture(image) {\r\n const maybeFiltering = image.getAttribute('filtering');\r\n let filtering = null;\r\n if (maybeFiltering === ImageFiltering.Blended ||\r\n maybeFiltering === ImageFiltering.Pixel) {\r\n filtering = maybeFiltering;\r\n }\r\n const force = image.getAttribute('forceUpload') === 'true' ? true : false;\r\n const texture = this._context.textureLoader.load(image, filtering, force);\r\n // remove force attribute after upload\r\n image.removeAttribute('forceUpload');\r\n if (this._textures.indexOf(texture) === -1) {\r\n this._textures.push(texture);\r\n }\r\n }\r\n _bindTextures(gl) {\r\n // Bind textures in the correct order\r\n for (let i = 0; i < this._maxTextures; i++) {\r\n gl.activeTexture(gl.TEXTURE0 + i);\r\n gl.bindTexture(gl.TEXTURE_2D, this._textures[i] || this._textures[0]);\r\n }\r\n }\r\n _getTextureIdForImage(image) {\r\n if (image) {\r\n const maybeTexture = this._context.textureLoader.get(image);\r\n return this._textures.indexOf(maybeTexture);\r\n }\r\n return -1;\r\n }\r\n _isFull() {\r\n if (this._imageCount >= this._maxImages) {\r\n return true;\r\n }\r\n if (this._textures.length >= this._maxTextures) {\r\n return true;\r\n }\r\n return false;\r\n }\r\n draw(image, sx, sy, swidth, sheight, dx, dy, dwidth, dheight) {\r\n var _a, _b, _c, _d;\r\n // Force a render if the batch is full\r\n if (this._isFull()) {\r\n this.flush();\r\n }\r\n this._imageCount++;\r\n // This creates and uploads the texture if not already done\r\n this._addImageAsTexture(image);\r\n let width = (image === null || image === void 0 ? void 0 : image.width) || swidth || 0;\r\n let height = (image === null || image === void 0 ? void 0 : image.height) || sheight || 0;\r\n let view = [0, 0, (_a = swidth !== null && swidth !== void 0 ? swidth : image === null || image === void 0 ? void 0 : image.width) !== null && _a !== void 0 ? _a : 0, (_b = sheight !== null && sheight !== void 0 ? sheight : image === null || image === void 0 ? void 0 : image.height) !== null && _b !== void 0 ? _b : 0];\r\n let dest = [sx !== null && sx !== void 0 ? sx : 1, sy !== null && sy !== void 0 ? sy : 1];\r\n // If destination is specified, update view and dest\r\n if (dx !== undefined && dy !== undefined && dwidth !== undefined && dheight !== undefined) {\r\n view = [sx !== null && sx !== void 0 ? sx : 1, sy !== null && sy !== void 0 ? sy : 1, (_c = swidth !== null && swidth !== void 0 ? swidth : image === null || image === void 0 ? void 0 : image.width) !== null && _c !== void 0 ? _c : 0, (_d = sheight !== null && sheight !== void 0 ? sheight : image === null || image === void 0 ? void 0 : image.height) !== null && _d !== void 0 ? _d : 0];\r\n dest = [dx, dy];\r\n width = dwidth;\r\n height = dheight;\r\n }\r\n sx = view[0];\r\n sy = view[1];\r\n const sw = view[2];\r\n const sh = view[3];\r\n // transform based on current context\r\n const transform = this._context.getTransform();\r\n const opacity = this._context.opacity;\r\n const snapToPixel = this._context.snapToPixel;\r\n let topLeft = vec(dest[0], dest[1]);\r\n let topRight = vec(dest[0] + width, dest[1]);\r\n let bottomLeft = vec(dest[0], dest[1] + height);\r\n let bottomRight = vec(dest[0] + width, dest[1] + height);\r\n topLeft = transform.multiply(topLeft);\r\n topRight = transform.multiply(topRight);\r\n bottomLeft = transform.multiply(bottomLeft);\r\n bottomRight = transform.multiply(bottomRight);\r\n if (snapToPixel) {\r\n topLeft.x = ~~(topLeft.x + pixelSnapEpsilon);\r\n topLeft.y = ~~(topLeft.y + pixelSnapEpsilon);\r\n topRight.x = ~~(topRight.x + pixelSnapEpsilon);\r\n topRight.y = ~~(topRight.y + pixelSnapEpsilon);\r\n bottomLeft.x = ~~(bottomLeft.x + pixelSnapEpsilon);\r\n bottomLeft.y = ~~(bottomLeft.y + pixelSnapEpsilon);\r\n bottomRight.x = ~~(bottomRight.x + pixelSnapEpsilon);\r\n bottomRight.y = ~~(bottomRight.y + pixelSnapEpsilon);\r\n }\r\n const tint = this._context.tint;\r\n const textureId = this._getTextureIdForImage(image);\r\n const imageWidth = image.width || width;\r\n const imageHeight = image.height || height;\r\n const uvx0 = (sx) / imageWidth;\r\n const uvy0 = (sy) / imageHeight;\r\n const uvx1 = (sx + sw - 0.01) / imageWidth;\r\n const uvy1 = (sy + sh - 0.01) / imageHeight;\r\n // update data\r\n const vertexBuffer = this._layout.vertexBuffer.bufferData;\r\n // (0, 0) - 0\r\n vertexBuffer[this._vertexIndex++] = topLeft.x;\r\n vertexBuffer[this._vertexIndex++] = topLeft.y;\r\n vertexBuffer[this._vertexIndex++] = opacity;\r\n vertexBuffer[this._vertexIndex++] = uvx0;\r\n vertexBuffer[this._vertexIndex++] = uvy0;\r\n vertexBuffer[this._vertexIndex++] = textureId;\r\n vertexBuffer[this._vertexIndex++] = tint.r / 255;\r\n vertexBuffer[this._vertexIndex++] = tint.g / 255;\r\n vertexBuffer[this._vertexIndex++] = tint.b / 255;\r\n vertexBuffer[this._vertexIndex++] = tint.a;\r\n // (0, 1) - 1\r\n vertexBuffer[this._vertexIndex++] = bottomLeft.x;\r\n vertexBuffer[this._vertexIndex++] = bottomLeft.y;\r\n vertexBuffer[this._vertexIndex++] = opacity;\r\n vertexBuffer[this._vertexIndex++] = uvx0;\r\n vertexBuffer[this._vertexIndex++] = uvy1;\r\n vertexBuffer[this._vertexIndex++] = textureId;\r\n vertexBuffer[this._vertexIndex++] = tint.r / 255;\r\n vertexBuffer[this._vertexIndex++] = tint.g / 255;\r\n vertexBuffer[this._vertexIndex++] = tint.b / 255;\r\n vertexBuffer[this._vertexIndex++] = tint.a;\r\n // (1, 0) - 2\r\n vertexBuffer[this._vertexIndex++] = topRight.x;\r\n vertexBuffer[this._vertexIndex++] = topRight.y;\r\n vertexBuffer[this._vertexIndex++] = opacity;\r\n vertexBuffer[this._vertexIndex++] = uvx1;\r\n vertexBuffer[this._vertexIndex++] = uvy0;\r\n vertexBuffer[this._vertexIndex++] = textureId;\r\n vertexBuffer[this._vertexIndex++] = tint.r / 255;\r\n vertexBuffer[this._vertexIndex++] = tint.g / 255;\r\n vertexBuffer[this._vertexIndex++] = tint.b / 255;\r\n vertexBuffer[this._vertexIndex++] = tint.a;\r\n // (1, 1) - 3\r\n vertexBuffer[this._vertexIndex++] = bottomRight.x;\r\n vertexBuffer[this._vertexIndex++] = bottomRight.y;\r\n vertexBuffer[this._vertexIndex++] = opacity;\r\n vertexBuffer[this._vertexIndex++] = uvx1;\r\n vertexBuffer[this._vertexIndex++] = uvy1;\r\n vertexBuffer[this._vertexIndex++] = textureId;\r\n vertexBuffer[this._vertexIndex++] = tint.r / 255;\r\n vertexBuffer[this._vertexIndex++] = tint.g / 255;\r\n vertexBuffer[this._vertexIndex++] = tint.b / 255;\r\n vertexBuffer[this._vertexIndex++] = tint.a;\r\n }\r\n hasPendingDraws() {\r\n return this._imageCount !== 0;\r\n }\r\n flush() {\r\n // nothing to draw early exit\r\n if (this._imageCount === 0) {\r\n return;\r\n }\r\n const gl = this._gl;\r\n // Bind the shader\r\n this._shader.use();\r\n // Bind the memory layout and upload data\r\n this._layout.use(true, 4 * 10 * this._imageCount);\r\n // Update ortho matrix uniform\r\n this._shader.setUniformMatrix('u_matrix', this._context.ortho);\r\n // Bind textures to\r\n this._bindTextures(gl);\r\n // Bind index buffer\r\n this._quads.bind();\r\n // Draw all the quads\r\n gl.drawElements(gl.TRIANGLES, this._imageCount * 6, this._quads.bufferGlType, 0);\r\n GraphicsDiagnostics.DrawnImagesCount += this._imageCount;\r\n GraphicsDiagnostics.DrawCallCount++;\r\n // Reset\r\n this._imageCount = 0;\r\n this._vertexIndex = 0;\r\n this._textures.length = 0;\r\n }\r\n}\r\n\n;// CONCATENATED MODULE: ./Graphics/Context/rectangle-renderer/rectangle-renderer.frag.glsl\n/* harmony default export */ const rectangle_renderer_frag = (\"#version 300 es\\r\\n\\r\\nprecision mediump float;\\r\\n\\r\\n// UV coord\\r\\nin vec2 v_uv;\\r\\n\\r\\nin vec2 v_size; // in pixels\\r\\n\\r\\n// Color coord to blend with image\\r\\nin lowp vec4 v_color;\\r\\n\\r\\n// Stroke color if used\\r\\nin lowp vec4 v_strokeColor;\\r\\n\\r\\n// Stroke thickness if used\\r\\nin lowp float v_strokeThickness; // in pixels\\r\\n\\r\\n// Opacity\\r\\nin float v_opacity;\\r\\n\\r\\nout vec4 fragColor;\\r\\n\\r\\nvoid main() {\\r\\n // modified from https://stackoverflow.com/questions/59197671/glsl-rounded-rectangle-with-variable-border\\r\\n vec2 uv = v_uv;\\r\\n vec2 fragCoord = uv * v_size;\\r\\n float maxX = v_size.x - v_strokeThickness;\\r\\n float minX = v_strokeThickness;\\r\\n float maxY = v_size.y - v_strokeThickness;\\r\\n float minY = v_strokeThickness;\\r\\n\\r\\n if (fragCoord.x < maxX && fragCoord.x > minX &&\\r\\n fragCoord.y < maxY && fragCoord.y > minY) {\\r\\n fragColor = v_color;\\r\\n } else {\\r\\n fragColor = v_strokeColor;\\r\\n }\\r\\n fragColor.a *= v_opacity;\\r\\n fragColor.rgb *= fragColor.a;\\r\\n\\r\\n // vec2 v2CenteredPos = abs(fragCoord - v_size.xy / 2.0);\\r\\n // vec2 v2HalfShapeSizePx = v_size.xy/2.0 - v_strokeThickness/2.0;\\r\\n\\r\\n // float fHalfBorderDist = 0.0;\\r\\n // float fHalfBorderThickness = 0.0;\\r\\n\\r\\n // if (fragCoord.x > max(v_radius, v_strokeThickness) && \\r\\n // fragCoord.x < v_size.x - max(v_radius, v_strokeThickness))\\r\\n // {\\r\\n // fHalfBorderDist = v2CenteredPos.y - v2HalfShapeSizePx.y;\\r\\n // fHalfBorderThickness = v_strokeThickness / 2.0;\\r\\n // }\\r\\n // else if (fragCoord.y > max(v_radius, v_strokeThickness) && \\r\\n // fragCoord.y < v_size.y - max(v_radius, v_strokeThickness))\\r\\n // {\\r\\n // fHalfBorderDist = v2CenteredPos.x - v2HalfShapeSizePx.x;\\r\\n // fHalfBorderThickness = v_strokeThickness / 2.0;\\r\\n // }\\r\\n // else\\r\\n // {\\r\\n // vec2 edgeVec = max(vec2(0.0), v_radius - vec2(\\r\\n // uv.x > 0.5 ? v_size.x - fragCoord.x : fragCoord.x,\\r\\n // uv.y > 0.5 ? v_size.y - fragCoord.y : fragCoord.y));\\r\\n \\r\\n // float ellipse_ab = v_radius-v_strokeThickness;\\r\\n // vec2 ellipse_isect = (v_strokeThickness > v_radius || v_strokeThickness > v_radius) ? vec2(0.0) :\\r\\n // edgeVec.xy * ellipse_ab*ellipse_ab / length(ellipse_ab*edgeVec.yx); \\r\\n \\r\\n // fHalfBorderThickness = (v_radius - length(ellipse_isect)) / 2.0;\\r\\n // fHalfBorderDist = length(edgeVec) - (v_radius - fHalfBorderThickness);\\r\\n // }\\r\\n\\r\\n // vec4 v4FromColor = v_strokeColor;\\r\\n // v4FromColor.rgb *= v4FromColor.a;\\r\\n // vec4 v4ToColor = vec4(0.0); // background color is transparent\\r\\n // if (fHalfBorderDist < 0.0) {\\r\\n // v4ToColor = v_color;\\r\\n // v4ToColor.rgb *= v4ToColor.a;\\r\\n // }\\r\\n\\r\\n // float mixPct = abs(fHalfBorderDist) - fHalfBorderThickness;\\r\\n\\r\\n // vec4 finalColor = mix(v4FromColor, v4ToColor, mixPct);\\r\\n // gl_FragColor = finalColor;\\r\\n}\");\n;// CONCATENATED MODULE: ./Graphics/Context/rectangle-renderer/rectangle-renderer.vert.glsl\n/* harmony default export */ const rectangle_renderer_vert = (\"#version 300 es\\r\\nin vec2 a_position;\\r\\n\\r\\n// UV coordinate\\r\\nin vec2 a_uv;\\r\\nout vec2 v_uv;\\r\\n\\r\\nin vec2 a_size;\\r\\nout vec2 v_size;\\r\\n\\r\\n// Opacity \\r\\nin float a_opacity;\\r\\nout float v_opacity;\\r\\n\\r\\nin vec4 a_color;\\r\\nout vec4 v_color;\\r\\n\\r\\nin vec4 a_strokeColor;\\r\\nout vec4 v_strokeColor;\\r\\n\\r\\nin float a_strokeThickness;\\r\\nout float v_strokeThickness;\\r\\n\\r\\nuniform mat4 u_matrix;\\r\\n\\r\\n\\r\\nvoid main() {\\r\\n // Set the vertex position using the ortho transform matrix\\r\\n gl_Position = u_matrix * vec4(a_position, 0.0, 1.0);\\r\\n\\r\\n // Pass through UV coords\\r\\n v_uv = a_uv;\\r\\n // Pass through size\\r\\n v_size = a_size;\\r\\n // Pass through the Opacity to the fragment shader\\r\\n v_opacity = a_opacity;\\r\\n // Pass through the color to the fragment shader\\r\\n v_color = a_color;\\r\\n // Pass through the stroke color to the fragment shader\\r\\n v_strokeColor = a_strokeColor;\\r\\n // Pass through the stroke thickenss to the fragment shader\\r\\n v_strokeThickness = a_strokeThickness;\\r\\n}\");\n;// CONCATENATED MODULE: ./Graphics/Context/rectangle-renderer/rectangle-renderer.ts\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\nclass RectangleRenderer {\r\n constructor() {\r\n this.type = 'ex.rectangle';\r\n this.priority = 0;\r\n this._maxRectangles = 10922; // max(uint16) / 6 verts\r\n this._rectangleCount = 0;\r\n this._vertexIndex = 0;\r\n }\r\n initialize(gl, context) {\r\n this._gl = gl;\r\n this._context = context;\r\n // https://stackoverflow.com/questions/59197671/glsl-rounded-rectangle-with-variable-border\r\n this._shader = new Shader({\r\n gl,\r\n fragmentSource: rectangle_renderer_frag,\r\n vertexSource: rectangle_renderer_vert\r\n });\r\n this._shader.compile();\r\n // setup uniforms\r\n this._shader.use();\r\n this._shader.setUniformMatrix('u_matrix', context.ortho);\r\n this._buffer = new VertexBuffer({\r\n gl,\r\n size: 16 * 4 * this._maxRectangles,\r\n type: 'dynamic'\r\n });\r\n this._layout = new VertexLayout({\r\n gl,\r\n shader: this._shader,\r\n vertexBuffer: this._buffer,\r\n attributes: [\r\n ['a_position', 2],\r\n ['a_uv', 2],\r\n ['a_size', 2],\r\n ['a_opacity', 1],\r\n ['a_color', 4],\r\n ['a_strokeColor', 4],\r\n ['a_strokeThickness', 1]\r\n ]\r\n });\r\n this._quads = new QuadIndexBuffer(gl, this._maxRectangles, true);\r\n }\r\n _isFull() {\r\n if (this._rectangleCount >= this._maxRectangles) {\r\n return true;\r\n }\r\n return false;\r\n }\r\n draw(...args) {\r\n if (args[0] instanceof Vector && args[1] instanceof Vector) {\r\n this.drawLine.apply(this, args);\r\n }\r\n else {\r\n this.drawRectangle.apply(this, args);\r\n }\r\n }\r\n drawLine(start, end, color, thickness = 1) {\r\n if (this._isFull()) {\r\n this.flush();\r\n }\r\n this._rectangleCount++;\r\n // transform based on current context\r\n const transform = this._context.getTransform();\r\n const opacity = this._context.opacity;\r\n const snapToPixel = this._context.snapToPixel;\r\n const dir = end.sub(start);\r\n const length = dir.size;\r\n const normal = dir.normalize().perpendicular();\r\n const halfThick = thickness / 2;\r\n /**\r\n * +---------------------^----------------------+\r\n * | | (normal) |\r\n * (startx, starty)------------------>(endx, endy)\r\n * | |\r\n * + -------------------------------------------+\r\n */\r\n const startTop = transform.multiply(normal.scale(halfThick).add(start));\r\n const startBottom = transform.multiply(normal.scale(-halfThick).add(start));\r\n const endTop = transform.multiply(normal.scale(halfThick).add(end));\r\n const endBottom = transform.multiply(normal.scale(-halfThick).add(end));\r\n if (snapToPixel) {\r\n startTop.x = ~~(startTop.x + pixelSnapEpsilon);\r\n startTop.y = ~~(startTop.y + pixelSnapEpsilon);\r\n endTop.x = ~~(endTop.x + pixelSnapEpsilon);\r\n endTop.y = ~~(endTop.y + pixelSnapEpsilon);\r\n startBottom.x = ~~(startBottom.x + pixelSnapEpsilon);\r\n startBottom.y = ~~(startBottom.y + pixelSnapEpsilon);\r\n endBottom.x = ~~(endBottom.x + pixelSnapEpsilon);\r\n endBottom.y = ~~(endBottom.y + pixelSnapEpsilon);\r\n }\r\n // TODO uv could be static vertex buffer\r\n const uvx0 = 0;\r\n const uvy0 = 0;\r\n const uvx1 = 1;\r\n const uvy1 = 1;\r\n const stroke = Color.Transparent;\r\n const strokeThickness = 0;\r\n const width = 1;\r\n // update data\r\n const vertexBuffer = this._layout.vertexBuffer.bufferData;\r\n // (0, 0) - 0\r\n vertexBuffer[this._vertexIndex++] = startTop.x;\r\n vertexBuffer[this._vertexIndex++] = startTop.y;\r\n vertexBuffer[this._vertexIndex++] = uvx0;\r\n vertexBuffer[this._vertexIndex++] = uvy0;\r\n vertexBuffer[this._vertexIndex++] = length;\r\n vertexBuffer[this._vertexIndex++] = thickness;\r\n vertexBuffer[this._vertexIndex++] = opacity;\r\n vertexBuffer[this._vertexIndex++] = color.r / 255;\r\n vertexBuffer[this._vertexIndex++] = color.g / 255;\r\n vertexBuffer[this._vertexIndex++] = color.b / 255;\r\n vertexBuffer[this._vertexIndex++] = color.a;\r\n vertexBuffer[this._vertexIndex++] = stroke.r / 255;\r\n vertexBuffer[this._vertexIndex++] = stroke.g / 255;\r\n vertexBuffer[this._vertexIndex++] = stroke.b / 255;\r\n vertexBuffer[this._vertexIndex++] = stroke.a;\r\n vertexBuffer[this._vertexIndex++] = strokeThickness / width;\r\n // (0, 1) - 1\r\n vertexBuffer[this._vertexIndex++] = startBottom.x;\r\n vertexBuffer[this._vertexIndex++] = startBottom.y;\r\n vertexBuffer[this._vertexIndex++] = uvx0;\r\n vertexBuffer[this._vertexIndex++] = uvy1;\r\n vertexBuffer[this._vertexIndex++] = length;\r\n vertexBuffer[this._vertexIndex++] = thickness;\r\n vertexBuffer[this._vertexIndex++] = opacity;\r\n vertexBuffer[this._vertexIndex++] = color.r / 255;\r\n vertexBuffer[this._vertexIndex++] = color.g / 255;\r\n vertexBuffer[this._vertexIndex++] = color.b / 255;\r\n vertexBuffer[this._vertexIndex++] = color.a;\r\n vertexBuffer[this._vertexIndex++] = stroke.r / 255;\r\n vertexBuffer[this._vertexIndex++] = stroke.g / 255;\r\n vertexBuffer[this._vertexIndex++] = stroke.b / 255;\r\n vertexBuffer[this._vertexIndex++] = stroke.a;\r\n vertexBuffer[this._vertexIndex++] = strokeThickness / width;\r\n // (1, 0) - 2\r\n vertexBuffer[this._vertexIndex++] = endTop.x;\r\n vertexBuffer[this._vertexIndex++] = endTop.y;\r\n vertexBuffer[this._vertexIndex++] = uvx1;\r\n vertexBuffer[this._vertexIndex++] = uvy0;\r\n vertexBuffer[this._vertexIndex++] = length;\r\n vertexBuffer[this._vertexIndex++] = thickness;\r\n vertexBuffer[this._vertexIndex++] = opacity;\r\n vertexBuffer[this._vertexIndex++] = color.r / 255;\r\n vertexBuffer[this._vertexIndex++] = color.g / 255;\r\n vertexBuffer[this._vertexIndex++] = color.b / 255;\r\n vertexBuffer[this._vertexIndex++] = color.a;\r\n vertexBuffer[this._vertexIndex++] = stroke.r / 255;\r\n vertexBuffer[this._vertexIndex++] = stroke.g / 255;\r\n vertexBuffer[this._vertexIndex++] = stroke.b / 255;\r\n vertexBuffer[this._vertexIndex++] = stroke.a;\r\n vertexBuffer[this._vertexIndex++] = strokeThickness / width;\r\n // (1, 1) - 3\r\n vertexBuffer[this._vertexIndex++] = endBottom.x;\r\n vertexBuffer[this._vertexIndex++] = endBottom.y;\r\n vertexBuffer[this._vertexIndex++] = uvx1;\r\n vertexBuffer[this._vertexIndex++] = uvy1;\r\n vertexBuffer[this._vertexIndex++] = length;\r\n vertexBuffer[this._vertexIndex++] = thickness;\r\n vertexBuffer[this._vertexIndex++] = opacity;\r\n vertexBuffer[this._vertexIndex++] = color.r / 255;\r\n vertexBuffer[this._vertexIndex++] = color.g / 255;\r\n vertexBuffer[this._vertexIndex++] = color.b / 255;\r\n vertexBuffer[this._vertexIndex++] = color.a;\r\n vertexBuffer[this._vertexIndex++] = stroke.r / 255;\r\n vertexBuffer[this._vertexIndex++] = stroke.g / 255;\r\n vertexBuffer[this._vertexIndex++] = stroke.b / 255;\r\n vertexBuffer[this._vertexIndex++] = stroke.a;\r\n vertexBuffer[this._vertexIndex++] = strokeThickness / width;\r\n }\r\n drawRectangle(pos, width, height, color, stroke = Color.Transparent, strokeThickness = 0) {\r\n if (this._isFull()) {\r\n this.flush();\r\n }\r\n this._rectangleCount++;\r\n // transform based on current context\r\n const transform = this._context.getTransform();\r\n const opacity = this._context.opacity;\r\n const snapToPixel = this._context.snapToPixel;\r\n const topLeft = transform.multiply(pos.add(vec(0, 0)));\r\n const topRight = transform.multiply(pos.add(vec(width, 0)));\r\n const bottomRight = transform.multiply(pos.add(vec(width, height)));\r\n const bottomLeft = transform.multiply(pos.add(vec(0, height)));\r\n if (snapToPixel) {\r\n topLeft.x = ~~(topLeft.x + pixelSnapEpsilon);\r\n topLeft.y = ~~(topLeft.y + pixelSnapEpsilon);\r\n topRight.x = ~~(topRight.x + pixelSnapEpsilon);\r\n topRight.y = ~~(topRight.y + pixelSnapEpsilon);\r\n bottomLeft.x = ~~(bottomLeft.x + pixelSnapEpsilon);\r\n bottomLeft.y = ~~(bottomLeft.y + pixelSnapEpsilon);\r\n bottomRight.x = ~~(bottomRight.x + pixelSnapEpsilon);\r\n bottomRight.y = ~~(bottomRight.y + pixelSnapEpsilon);\r\n }\r\n // TODO uv could be static vertex buffer\r\n const uvx0 = 0;\r\n const uvy0 = 0;\r\n const uvx1 = 1;\r\n const uvy1 = 1;\r\n // update data\r\n const vertexBuffer = this._layout.vertexBuffer.bufferData;\r\n // (0, 0) - 0\r\n vertexBuffer[this._vertexIndex++] = topLeft.x;\r\n vertexBuffer[this._vertexIndex++] = topLeft.y;\r\n vertexBuffer[this._vertexIndex++] = uvx0;\r\n vertexBuffer[this._vertexIndex++] = uvy0;\r\n vertexBuffer[this._vertexIndex++] = width;\r\n vertexBuffer[this._vertexIndex++] = height;\r\n vertexBuffer[this._vertexIndex++] = opacity;\r\n vertexBuffer[this._vertexIndex++] = color.r / 255;\r\n vertexBuffer[this._vertexIndex++] = color.g / 255;\r\n vertexBuffer[this._vertexIndex++] = color.b / 255;\r\n vertexBuffer[this._vertexIndex++] = color.a;\r\n vertexBuffer[this._vertexIndex++] = stroke.r / 255;\r\n vertexBuffer[this._vertexIndex++] = stroke.g / 255;\r\n vertexBuffer[this._vertexIndex++] = stroke.b / 255;\r\n vertexBuffer[this._vertexIndex++] = stroke.a;\r\n vertexBuffer[this._vertexIndex++] = strokeThickness;\r\n // (0, 1) - 1\r\n vertexBuffer[this._vertexIndex++] = bottomLeft.x;\r\n vertexBuffer[this._vertexIndex++] = bottomLeft.y;\r\n vertexBuffer[this._vertexIndex++] = uvx0;\r\n vertexBuffer[this._vertexIndex++] = uvy1;\r\n vertexBuffer[this._vertexIndex++] = width;\r\n vertexBuffer[this._vertexIndex++] = height;\r\n vertexBuffer[this._vertexIndex++] = opacity;\r\n vertexBuffer[this._vertexIndex++] = color.r / 255;\r\n vertexBuffer[this._vertexIndex++] = color.g / 255;\r\n vertexBuffer[this._vertexIndex++] = color.b / 255;\r\n vertexBuffer[this._vertexIndex++] = color.a;\r\n vertexBuffer[this._vertexIndex++] = stroke.r / 255;\r\n vertexBuffer[this._vertexIndex++] = stroke.g / 255;\r\n vertexBuffer[this._vertexIndex++] = stroke.b / 255;\r\n vertexBuffer[this._vertexIndex++] = stroke.a;\r\n vertexBuffer[this._vertexIndex++] = strokeThickness;\r\n // (1, 0) - 2\r\n vertexBuffer[this._vertexIndex++] = topRight.x;\r\n vertexBuffer[this._vertexIndex++] = topRight.y;\r\n vertexBuffer[this._vertexIndex++] = uvx1;\r\n vertexBuffer[this._vertexIndex++] = uvy0;\r\n vertexBuffer[this._vertexIndex++] = width;\r\n vertexBuffer[this._vertexIndex++] = height;\r\n vertexBuffer[this._vertexIndex++] = opacity;\r\n vertexBuffer[this._vertexIndex++] = color.r / 255;\r\n vertexBuffer[this._vertexIndex++] = color.g / 255;\r\n vertexBuffer[this._vertexIndex++] = color.b / 255;\r\n vertexBuffer[this._vertexIndex++] = color.a;\r\n vertexBuffer[this._vertexIndex++] = stroke.r / 255;\r\n vertexBuffer[this._vertexIndex++] = stroke.g / 255;\r\n vertexBuffer[this._vertexIndex++] = stroke.b / 255;\r\n vertexBuffer[this._vertexIndex++] = stroke.a;\r\n vertexBuffer[this._vertexIndex++] = strokeThickness;\r\n // (1, 1) - 3\r\n vertexBuffer[this._vertexIndex++] = bottomRight.x;\r\n vertexBuffer[this._vertexIndex++] = bottomRight.y;\r\n vertexBuffer[this._vertexIndex++] = uvx1;\r\n vertexBuffer[this._vertexIndex++] = uvy1;\r\n vertexBuffer[this._vertexIndex++] = width;\r\n vertexBuffer[this._vertexIndex++] = height;\r\n vertexBuffer[this._vertexIndex++] = opacity;\r\n vertexBuffer[this._vertexIndex++] = color.r / 255;\r\n vertexBuffer[this._vertexIndex++] = color.g / 255;\r\n vertexBuffer[this._vertexIndex++] = color.b / 255;\r\n vertexBuffer[this._vertexIndex++] = color.a;\r\n vertexBuffer[this._vertexIndex++] = stroke.r / 255;\r\n vertexBuffer[this._vertexIndex++] = stroke.g / 255;\r\n vertexBuffer[this._vertexIndex++] = stroke.b / 255;\r\n vertexBuffer[this._vertexIndex++] = stroke.a;\r\n vertexBuffer[this._vertexIndex++] = strokeThickness;\r\n }\r\n hasPendingDraws() {\r\n return this._rectangleCount !== 0;\r\n }\r\n flush() {\r\n // nothing to draw early exit\r\n if (this._rectangleCount === 0) {\r\n return;\r\n }\r\n const gl = this._gl;\r\n // Bind the shader\r\n this._shader.use();\r\n // Bind the memory layout and upload data\r\n this._layout.use(true);\r\n // Update ortho matrix uniform\r\n this._shader.setUniformMatrix('u_matrix', this._context.ortho);\r\n // Bind index buffer\r\n this._quads.bind();\r\n // Draw all the quads\r\n gl.drawElements(gl.TRIANGLES, this._rectangleCount * 6, this._quads.bufferGlType, 0);\r\n GraphicsDiagnostics.DrawnImagesCount += this._rectangleCount;\r\n GraphicsDiagnostics.DrawCallCount++;\r\n // Reset\r\n this._rectangleCount = 0;\r\n this._vertexIndex = 0;\r\n }\r\n}\r\n\n;// CONCATENATED MODULE: ./Graphics/Context/circle-renderer/circle-renderer.frag.glsl\n/* harmony default export */ const circle_renderer_frag = (\"#version 300 es\\r\\nprecision highp float;\\r\\n\\r\\n// UV coord\\r\\nin vec2 v_uv;\\r\\n\\r\\n// Color coord to blend with image\\r\\nin lowp vec4 v_color;\\r\\n\\r\\n// Stroke color if used\\r\\nin lowp vec4 v_strokeColor;\\r\\n\\r\\n// Stroke thickness if used\\r\\nin lowp float v_strokeThickness;\\r\\n\\r\\n// Opacity\\r\\nin float v_opacity;\\r\\n\\r\\nout vec4 fragColor;\\r\\n\\r\\nvoid main() {\\r\\n // make (0, 0) the center the uv \\r\\n vec2 uv = v_uv * 2.0 - 1.0;\\r\\n\\r\\n vec4 color = v_color;\\r\\n vec4 strokeColor = v_strokeColor;\\r\\n\\r\\n // circle border is at radius 1.0 \\r\\n // dist is > 0 when inside the circle \\r\\n float d = length(uv);\\r\\n float dist = 1.0 - length(uv);\\r\\n\\r\\n // Fade based on fwidth\\r\\n float fade = fwidth(dot(uv, uv));\\r\\n\\r\\n // if dist is greater than 0 step to 1;\\r\\n // when we cross this 0 threshold add a smooth fade\\r\\n float fill = smoothstep(-fade/2.0, fade/2.0, dist);\\r\\n\\r\\n // if dist is greater than the stroke thickness step to 1\\r\\n float stroke = 1.0 - smoothstep(v_strokeThickness, v_strokeThickness + fade, dist);\\r\\n\\r\\n strokeColor.a *= fill * stroke;\\r\\n strokeColor.rgb *= strokeColor.a;\\r\\n\\r\\n color.a *= fill * (1.0 - stroke);\\r\\n color.rgb *= color.a;\\r\\n\\r\\n vec4 finalColor = mix(vec4(0.0), (color + strokeColor), fill);\\r\\n finalColor.rgb = finalColor.rgb * v_opacity;\\r\\n finalColor.a = finalColor.a * v_opacity;\\r\\n fragColor = finalColor;\\r\\n}\");\n;// CONCATENATED MODULE: ./Graphics/Context/circle-renderer/circle-renderer.vert.glsl\n/* harmony default export */ const circle_renderer_vert = (\"#version 300 es\\r\\nin vec2 a_position;\\r\\n\\r\\n// UV coordinate\\r\\nin vec2 a_uv;\\r\\nout vec2 v_uv;\\r\\n\\r\\n// Opacity \\r\\nin float a_opacity;\\r\\nout float v_opacity;\\r\\n\\r\\nin vec4 a_color;\\r\\nout vec4 v_color;\\r\\n\\r\\nin vec4 a_strokeColor;\\r\\nout vec4 v_strokeColor;\\r\\n\\r\\nin float a_strokeThickness;\\r\\nout float v_strokeThickness;\\r\\n\\r\\nuniform mat4 u_matrix;\\r\\n\\r\\n\\r\\nvoid main() {\\r\\n // Set the vertex position using the ortho transform matrix\\r\\n gl_Position = u_matrix * vec4(a_position, 0.0, 1.0);\\r\\n\\r\\n // Pass through UV coords\\r\\n v_uv = a_uv;\\r\\n // Pass through the Opacity to the fragment shader\\r\\n v_opacity = a_opacity;\\r\\n // Pass through the color to the fragment shader\\r\\n v_color = a_color;\\r\\n // Pass through the stroke color to the fragment shader\\r\\n v_strokeColor = a_strokeColor;\\r\\n // Pass through the stroke thickenss to the fragment shader\\r\\n v_strokeThickness = a_strokeThickness;\\r\\n}\");\n;// CONCATENATED MODULE: ./Graphics/Context/circle-renderer/circle-renderer.ts\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\nclass CircleRenderer {\r\n constructor() {\r\n this.type = 'ex.circle';\r\n this.priority = 0;\r\n this._maxCircles = 10922; // max(uint16) / 6 verts\r\n this._circleCount = 0;\r\n this._vertexIndex = 0;\r\n }\r\n initialize(gl, context) {\r\n this._gl = gl;\r\n this._context = context;\r\n this._shader = new Shader({\r\n gl,\r\n fragmentSource: circle_renderer_frag,\r\n vertexSource: circle_renderer_vert\r\n });\r\n this._shader.compile();\r\n // setup uniforms\r\n this._shader.use();\r\n this._shader.setUniformMatrix('u_matrix', context.ortho);\r\n this._buffer = new VertexBuffer({\r\n gl,\r\n size: 14 * 4 * this._maxCircles,\r\n type: 'dynamic'\r\n });\r\n this._layout = new VertexLayout({\r\n gl,\r\n shader: this._shader,\r\n vertexBuffer: this._buffer,\r\n attributes: [\r\n ['a_position', 2],\r\n ['a_uv', 2],\r\n ['a_opacity', 1],\r\n ['a_color', 4],\r\n ['a_strokeColor', 4],\r\n ['a_strokeThickness', 1]\r\n ]\r\n });\r\n this._quads = new QuadIndexBuffer(gl, this._maxCircles, true);\r\n }\r\n _isFull() {\r\n if (this._circleCount >= this._maxCircles) {\r\n return true;\r\n }\r\n return false;\r\n }\r\n draw(pos, radius, color, stroke = Color.Transparent, strokeThickness = 0) {\r\n if (this._isFull()) {\r\n this.flush();\r\n }\r\n this._circleCount++;\r\n // transform based on current context\r\n const transform = this._context.getTransform();\r\n const opacity = this._context.opacity;\r\n const snapToPixel = this._context.snapToPixel;\r\n const topLeft = transform.multiply(pos.add(vec(-radius, -radius)));\r\n const topRight = transform.multiply(pos.add(vec(radius, -radius)));\r\n const bottomRight = transform.multiply(pos.add(vec(radius, radius)));\r\n const bottomLeft = transform.multiply(pos.add(vec(-radius, radius)));\r\n if (snapToPixel) {\r\n topLeft.x = ~~(topLeft.x + pixelSnapEpsilon);\r\n topLeft.y = ~~(topLeft.y + pixelSnapEpsilon);\r\n topRight.x = ~~(topRight.x + pixelSnapEpsilon);\r\n topRight.y = ~~(topRight.y + pixelSnapEpsilon);\r\n bottomLeft.x = ~~(bottomLeft.x + pixelSnapEpsilon);\r\n bottomLeft.y = ~~(bottomLeft.y + pixelSnapEpsilon);\r\n bottomRight.x = ~~(bottomRight.x + pixelSnapEpsilon);\r\n bottomRight.y = ~~(bottomRight.y + pixelSnapEpsilon);\r\n }\r\n // TODO UV could be static vertex buffer\r\n const uvx0 = 0;\r\n const uvy0 = 0;\r\n const uvx1 = 1;\r\n const uvy1 = 1;\r\n // update data\r\n const vertexBuffer = this._layout.vertexBuffer.bufferData;\r\n // (0, 0) - 0\r\n vertexBuffer[this._vertexIndex++] = topLeft.x;\r\n vertexBuffer[this._vertexIndex++] = topLeft.y;\r\n vertexBuffer[this._vertexIndex++] = uvx0;\r\n vertexBuffer[this._vertexIndex++] = uvy0;\r\n vertexBuffer[this._vertexIndex++] = opacity;\r\n vertexBuffer[this._vertexIndex++] = color.r / 255;\r\n vertexBuffer[this._vertexIndex++] = color.g / 255;\r\n vertexBuffer[this._vertexIndex++] = color.b / 255;\r\n vertexBuffer[this._vertexIndex++] = color.a;\r\n vertexBuffer[this._vertexIndex++] = stroke.r / 255;\r\n vertexBuffer[this._vertexIndex++] = stroke.g / 255;\r\n vertexBuffer[this._vertexIndex++] = stroke.b / 255;\r\n vertexBuffer[this._vertexIndex++] = stroke.a;\r\n vertexBuffer[this._vertexIndex++] = strokeThickness / radius;\r\n // (0, 1) - 1\r\n vertexBuffer[this._vertexIndex++] = bottomLeft.x;\r\n vertexBuffer[this._vertexIndex++] = bottomLeft.y;\r\n vertexBuffer[this._vertexIndex++] = uvx0;\r\n vertexBuffer[this._vertexIndex++] = uvy1;\r\n vertexBuffer[this._vertexIndex++] = opacity;\r\n vertexBuffer[this._vertexIndex++] = color.r / 255;\r\n vertexBuffer[this._vertexIndex++] = color.g / 255;\r\n vertexBuffer[this._vertexIndex++] = color.b / 255;\r\n vertexBuffer[this._vertexIndex++] = color.a;\r\n vertexBuffer[this._vertexIndex++] = stroke.r / 255;\r\n vertexBuffer[this._vertexIndex++] = stroke.g / 255;\r\n vertexBuffer[this._vertexIndex++] = stroke.b / 255;\r\n vertexBuffer[this._vertexIndex++] = stroke.a;\r\n vertexBuffer[this._vertexIndex++] = strokeThickness / radius;\r\n // (1, 0) - 2\r\n vertexBuffer[this._vertexIndex++] = topRight.x;\r\n vertexBuffer[this._vertexIndex++] = topRight.y;\r\n vertexBuffer[this._vertexIndex++] = uvx1;\r\n vertexBuffer[this._vertexIndex++] = uvy0;\r\n vertexBuffer[this._vertexIndex++] = opacity;\r\n vertexBuffer[this._vertexIndex++] = color.r / 255;\r\n vertexBuffer[this._vertexIndex++] = color.g / 255;\r\n vertexBuffer[this._vertexIndex++] = color.b / 255;\r\n vertexBuffer[this._vertexIndex++] = color.a;\r\n vertexBuffer[this._vertexIndex++] = stroke.r / 255;\r\n vertexBuffer[this._vertexIndex++] = stroke.g / 255;\r\n vertexBuffer[this._vertexIndex++] = stroke.b / 255;\r\n vertexBuffer[this._vertexIndex++] = stroke.a;\r\n vertexBuffer[this._vertexIndex++] = strokeThickness / radius;\r\n // (1, 1) - 3\r\n vertexBuffer[this._vertexIndex++] = bottomRight.x;\r\n vertexBuffer[this._vertexIndex++] = bottomRight.y;\r\n vertexBuffer[this._vertexIndex++] = uvx1;\r\n vertexBuffer[this._vertexIndex++] = uvy1;\r\n vertexBuffer[this._vertexIndex++] = opacity;\r\n vertexBuffer[this._vertexIndex++] = color.r / 255;\r\n vertexBuffer[this._vertexIndex++] = color.g / 255;\r\n vertexBuffer[this._vertexIndex++] = color.b / 255;\r\n vertexBuffer[this._vertexIndex++] = color.a;\r\n vertexBuffer[this._vertexIndex++] = stroke.r / 255;\r\n vertexBuffer[this._vertexIndex++] = stroke.g / 255;\r\n vertexBuffer[this._vertexIndex++] = stroke.b / 255;\r\n vertexBuffer[this._vertexIndex++] = stroke.a;\r\n vertexBuffer[this._vertexIndex++] = strokeThickness / radius;\r\n }\r\n hasPendingDraws() {\r\n return this._circleCount !== 0;\r\n }\r\n flush() {\r\n // nothing to draw early exit\r\n if (this._circleCount === 0) {\r\n return;\r\n }\r\n const gl = this._gl;\r\n // Bind the shader\r\n this._shader.use();\r\n // Bind the memory layout and upload data\r\n this._layout.use(true);\r\n // Update ortho matrix uniform\r\n this._shader.setUniformMatrix('u_matrix', this._context.ortho);\r\n // Bind index buffer\r\n this._quads.bind();\r\n // Draw all the quads\r\n gl.drawElements(gl.TRIANGLES, this._circleCount * 6, this._quads.bufferGlType, 0);\r\n GraphicsDiagnostics.DrawnImagesCount += this._circleCount;\r\n GraphicsDiagnostics.DrawCallCount++;\r\n // Reset\r\n this._circleCount = 0;\r\n this._vertexIndex = 0;\r\n }\r\n}\r\n\n;// CONCATENATED MODULE: ./Util/Pool.ts\n\r\nclass Pool {\r\n constructor(builder, recycler, maxObjects = 100) {\r\n this.builder = builder;\r\n this.recycler = recycler;\r\n this.maxObjects = maxObjects;\r\n this.totalAllocations = 0;\r\n this.index = 0;\r\n this.objects = [];\r\n this.disableWarnings = false;\r\n this._logger = Logger.getInstance();\r\n }\r\n preallocate() {\r\n for (let i = 0; i < this.maxObjects; i++) {\r\n this.objects[i] = this.builder();\r\n }\r\n }\r\n /**\r\n * Use many instances out of the in the context and return all to the pool.\r\n *\r\n * By returning values out of the context they will be un-hooked from the pool and are free to be passed to consumers\r\n * @param context\r\n */\r\n using(context) {\r\n const result = context(this);\r\n if (result) {\r\n return this.done(...result);\r\n }\r\n return this.done();\r\n }\r\n /**\r\n * Use a single instance out of th pool and immediately return it to the pool\r\n * @param context\r\n */\r\n borrow(context) {\r\n const object = this.get();\r\n context(object);\r\n this.index--;\r\n }\r\n /**\r\n * Retrieve a value from the pool, will allocate a new instance if necessary or recycle from the pool\r\n * @param args\r\n */\r\n get(...args) {\r\n if (this.index === this.maxObjects) {\r\n if (!this.disableWarnings) {\r\n this._logger.warn('Max pooled objects reached, possible memory leak? Doubling');\r\n }\r\n this.maxObjects = this.maxObjects * 2;\r\n }\r\n if (this.objects[this.index]) {\r\n // Pool has an available object already constructed\r\n return this.recycler(this.objects[this.index++], ...args);\r\n }\r\n else {\r\n // New allocation\r\n this.totalAllocations++;\r\n const object = (this.objects[this.index++] = this.builder(...args));\r\n return object;\r\n }\r\n }\r\n done(...objects) {\r\n // All objects in pool now considered \"free\"\r\n this.index = 0;\r\n for (const object of objects) {\r\n const poolIndex = this.objects.indexOf(object);\r\n // Build a new object to take the pool place\r\n this.objects[poolIndex] = this.builder(); // TODO problematic 0-arg only support\r\n this.totalAllocations++;\r\n }\r\n return objects;\r\n }\r\n}\r\n\n;// CONCATENATED MODULE: ./Graphics/Context/draw-call.ts\n\r\n\r\nclass DrawCall {\r\n constructor() {\r\n this.z = 0;\r\n this.priority = 0;\r\n this.transform = AffineMatrix.identity();\r\n this.state = {\r\n z: 0,\r\n opacity: 1,\r\n tint: Color.White,\r\n material: null\r\n };\r\n }\r\n}\r\n\n;// CONCATENATED MODULE: ./Graphics/Context/material.ts\n\r\nconst defaultVertexSource = `#version 300 es\r\nin vec2 a_position;\r\n\r\nin vec2 a_uv;\r\nout vec2 v_uv;\r\n\r\nuniform mat4 u_matrix;\r\nuniform mat4 u_transform;\r\n\r\nvoid main() {\r\n // Set the vertex position using the ortho & transform matrix\r\n gl_Position = u_matrix * u_transform * vec4(a_position, 0.0, 1.0);\r\n\r\n // Pass through the UV coord to the fragment shader\r\n v_uv = a_uv;\r\n}\r\n`;\r\nclass Material {\r\n constructor(options) {\r\n this._color = Color.Transparent;\r\n this._initialized = false;\r\n const { color, name, vertexSource, fragmentSource } = options;\r\n this._name = name;\r\n this._vertexSource = vertexSource !== null && vertexSource !== void 0 ? vertexSource : defaultVertexSource;\r\n this._fragmentSource = fragmentSource;\r\n this._color = color !== null && color !== void 0 ? color : this._color;\r\n }\r\n initialize(_gl, _context) {\r\n if (this._initialized) {\r\n return;\r\n }\r\n this._shader = _context.createShader({\r\n vertexSource: this._vertexSource,\r\n fragmentSource: this._fragmentSource\r\n });\r\n this._shader.compile();\r\n this._initialized = true;\r\n }\r\n get name() {\r\n var _a;\r\n return (_a = this._name) !== null && _a !== void 0 ? _a : 'anonymous material';\r\n }\r\n getShader() {\r\n return this._shader;\r\n }\r\n use() {\r\n if (this._initialized) {\r\n // bind the shader\r\n this._shader.use();\r\n // Apply standard uniforms\r\n this._shader.trySetUniformFloatColor('u_color', this._color);\r\n }\r\n else {\r\n throw Error(`Material ${this.name} not yet initialized, use the ExcaliburGraphicsContext.createMaterial() to work around this.`);\r\n }\r\n }\r\n}\r\n\n;// CONCATENATED MODULE: ./Graphics/Context/material-renderer/material-renderer.ts\n\r\n\r\n\r\n\r\n\r\nclass MaterialRenderer {\r\n constructor() {\r\n this.type = 'ex.material';\r\n this.priority = 0;\r\n this._textures = [];\r\n }\r\n initialize(gl, context) {\r\n this._gl = gl;\r\n this._context = context;\r\n // Setup memory layout\r\n this._buffer = new VertexBuffer({\r\n gl,\r\n size: 4 * 4,\r\n type: 'dynamic'\r\n });\r\n // Setup a vertex layout/buffer to the material\r\n this._layout = new VertexLayout({\r\n gl,\r\n vertexBuffer: this._buffer,\r\n attributes: [\r\n ['a_position', 2],\r\n ['a_uv', 2]\r\n ]\r\n });\r\n // Setup index buffer\r\n this._quads = new QuadIndexBuffer(gl, 1, true);\r\n }\r\n draw(image, sx, sy, swidth, sheight, dx, dy, dwidth, dheight) {\r\n var _a, _b, _c, _d;\r\n const gl = this._gl;\r\n // Extract context info\r\n const material = this._context.material;\r\n material.initialize(gl, this._context);\r\n const transform = this._context.getTransform();\r\n const opacity = this._context.opacity;\r\n // material shader\r\n const shader = material.getShader();\r\n // construct geometry, or hold on to it in the material?\r\n // geometry primitive for drawing rectangles?\r\n // update data\r\n const vertexBuffer = this._layout.vertexBuffer.bufferData;\r\n let vertexIndex = 0;\r\n let width = (image === null || image === void 0 ? void 0 : image.width) || swidth || 0;\r\n let height = (image === null || image === void 0 ? void 0 : image.height) || sheight || 0;\r\n let view = [0, 0, (_a = swidth !== null && swidth !== void 0 ? swidth : image === null || image === void 0 ? void 0 : image.width) !== null && _a !== void 0 ? _a : 0, (_b = sheight !== null && sheight !== void 0 ? sheight : image === null || image === void 0 ? void 0 : image.height) !== null && _b !== void 0 ? _b : 0];\r\n let dest = [sx !== null && sx !== void 0 ? sx : 1, sy !== null && sy !== void 0 ? sy : 1];\r\n // If destination is specified, update view and dest\r\n if (dx !== undefined && dy !== undefined && dwidth !== undefined && dheight !== undefined) {\r\n view = [sx !== null && sx !== void 0 ? sx : 1, sy !== null && sy !== void 0 ? sy : 1, (_c = swidth !== null && swidth !== void 0 ? swidth : image === null || image === void 0 ? void 0 : image.width) !== null && _c !== void 0 ? _c : 0, (_d = sheight !== null && sheight !== void 0 ? sheight : image === null || image === void 0 ? void 0 : image.height) !== null && _d !== void 0 ? _d : 0];\r\n dest = [dx, dy];\r\n width = dwidth;\r\n height = dheight;\r\n }\r\n sx = view[0];\r\n sy = view[1];\r\n const sw = view[2];\r\n const sh = view[3];\r\n const topLeft = vec(dest[0], dest[1]);\r\n const topRight = vec(dest[0] + width, dest[1]);\r\n const bottomLeft = vec(dest[0], dest[1] + height);\r\n const bottomRight = vec(dest[0] + width, dest[1] + height);\r\n const imageWidth = image.width || width;\r\n const imageHeight = image.height || height;\r\n const uvx0 = (sx) / imageWidth;\r\n const uvy0 = (sy) / imageHeight;\r\n const uvx1 = (sx + sw - 0.01) / imageWidth;\r\n const uvy1 = (sy + sh - 0.01) / imageHeight;\r\n // (0, 0) - 0\r\n vertexBuffer[vertexIndex++] = topLeft.x;\r\n vertexBuffer[vertexIndex++] = topLeft.y;\r\n vertexBuffer[vertexIndex++] = uvx0;\r\n vertexBuffer[vertexIndex++] = uvy0;\r\n // (0, 1) - 1\r\n vertexBuffer[vertexIndex++] = bottomLeft.x;\r\n vertexBuffer[vertexIndex++] = bottomLeft.y;\r\n vertexBuffer[vertexIndex++] = uvx0;\r\n vertexBuffer[vertexIndex++] = uvy1;\r\n // (1, 0) - 2\r\n vertexBuffer[vertexIndex++] = topRight.x;\r\n vertexBuffer[vertexIndex++] = topRight.y;\r\n vertexBuffer[vertexIndex++] = uvx1;\r\n vertexBuffer[vertexIndex++] = uvy0;\r\n // (1, 1) - 3\r\n vertexBuffer[vertexIndex++] = bottomRight.x;\r\n vertexBuffer[vertexIndex++] = bottomRight.y;\r\n vertexBuffer[vertexIndex++] = uvx1;\r\n vertexBuffer[vertexIndex++] = uvy1;\r\n // This creates and uploads the texture if not already done\r\n const texture = this._addImageAsTexture(image);\r\n // apply material\r\n material.use();\r\n this._layout.shader = shader;\r\n // apply layout and geometry\r\n this._layout.use(true);\r\n // apply opacity\r\n shader.trySetUniformFloat('u_opacity', opacity);\r\n // apply resolution\r\n shader.trySetUniformFloatVector('u_resolution', vec(this._context.width, this._context.height));\r\n // apply size\r\n shader.trySetUniformFloatVector('u_size', vec(sw, sh));\r\n // apply orthographic projection\r\n shader.trySetUniformMatrix('u_matrix', this._context.ortho);\r\n // apply geometry transform\r\n shader.trySetUniformMatrix('u_transform', transform.to4x4());\r\n // bind graphic image texture 'uniform sampler2D u_graphic;'\r\n gl.activeTexture(gl.TEXTURE0 + 0);\r\n gl.bindTexture(gl.TEXTURE_2D, texture);\r\n shader.trySetUniformInt('u_graphic', 0);\r\n // bind quad index buffer\r\n this._quads.bind();\r\n // Draw a single quad\r\n gl.drawElements(gl.TRIANGLES, 6, this._quads.bufferGlType, 0);\r\n }\r\n _addImageAsTexture(image) {\r\n const maybeFiltering = image.getAttribute('filtering');\r\n let filtering = null;\r\n if (maybeFiltering === ImageFiltering.Blended ||\r\n maybeFiltering === ImageFiltering.Pixel) {\r\n filtering = maybeFiltering;\r\n }\r\n const force = image.getAttribute('forceUpload') === 'true' ? true : false;\r\n const texture = this._context.textureLoader.load(image, filtering, force);\r\n // remove force attribute after upload\r\n image.removeAttribute('forceUpload');\r\n if (this._textures.indexOf(texture) === -1) {\r\n this._textures.push(texture);\r\n }\r\n return texture;\r\n }\r\n hasPendingDraws() {\r\n return false;\r\n }\r\n flush() {\r\n // flush does not do anything, material renderer renders immediately per draw\r\n }\r\n}\r\n\n;// CONCATENATED MODULE: ./Graphics/Context/ExcaliburGraphicsContextWebGL.ts\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n// renderers\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\nconst pixelSnapEpsilon = 0.0001;\r\nclass ExcaliburGraphicsContextWebGLDebug {\r\n constructor(_webglCtx) {\r\n this._webglCtx = _webglCtx;\r\n this._debugText = new DebugText();\r\n }\r\n /**\r\n * Draw a debugging rectangle to the context\r\n * @param x\r\n * @param y\r\n * @param width\r\n * @param height\r\n */\r\n drawRect(x, y, width, height, rectOptions = { color: Color.Black }) {\r\n this.drawLine(vec(x, y), vec(x + width, y), { ...rectOptions });\r\n this.drawLine(vec(x + width, y), vec(x + width, y + height), { ...rectOptions });\r\n this.drawLine(vec(x + width, y + height), vec(x, y + height), { ...rectOptions });\r\n this.drawLine(vec(x, y + height), vec(x, y), { ...rectOptions });\r\n }\r\n /**\r\n * Draw a debugging line to the context\r\n * @param start\r\n * @param end\r\n * @param lineOptions\r\n */\r\n drawLine(start, end, lineOptions = { color: Color.Black }) {\r\n this._webglCtx.draw('ex.line', start, end, lineOptions.color);\r\n }\r\n /**\r\n * Draw a debugging point to the context\r\n * @param point\r\n * @param pointOptions\r\n */\r\n drawPoint(point, pointOptions = { color: Color.Black, size: 5 }) {\r\n this._webglCtx.draw('ex.point', point, pointOptions.color, pointOptions.size);\r\n }\r\n drawText(text, pos) {\r\n this._debugText.write(this._webglCtx, text, pos);\r\n }\r\n}\r\nclass ExcaliburGraphicsContextWebGL {\r\n get z() {\r\n return this._state.current.z;\r\n }\r\n set z(value) {\r\n this._state.current.z = value;\r\n }\r\n get opacity() {\r\n return this._state.current.opacity;\r\n }\r\n set opacity(value) {\r\n this._state.current.opacity = value;\r\n }\r\n get tint() {\r\n return this._state.current.tint;\r\n }\r\n set tint(color) {\r\n this._state.current.tint = color;\r\n }\r\n get width() {\r\n return this.__gl.canvas.width;\r\n }\r\n get height() {\r\n return this.__gl.canvas.height;\r\n }\r\n get ortho() {\r\n return this._ortho;\r\n }\r\n /**\r\n * Checks the underlying webgl implementation if the requested internal resolution is supported\r\n * @param dim\r\n */\r\n checkIfResolutionSupported(dim) {\r\n // Slight hack based on this thread https://groups.google.com/g/webgl-dev-list/c/AHONvz3oQTo\r\n let supported = true;\r\n if (dim.width > 4096 || dim.height > 4096) {\r\n supported = false;\r\n }\r\n return supported;\r\n }\r\n constructor(options) {\r\n this._logger = Logger.getInstance();\r\n this._renderers = new Map();\r\n this._isDrawLifecycle = false;\r\n this.useDrawSorting = true;\r\n this._drawCallPool = new Pool(() => new DrawCall(), (instance) => {\r\n instance.priority = 0;\r\n instance.z = 0;\r\n instance.renderer = undefined;\r\n instance.args = undefined;\r\n return instance;\r\n }, 4000);\r\n this._drawCalls = [];\r\n // Postprocessing is a tuple with 2 render targets, these are flip-flopped during the postprocessing process\r\n this._postProcessTargets = [];\r\n this._postprocessors = [];\r\n this._transform = new TransformStack();\r\n this._state = new StateStack();\r\n this.snapToPixel = false;\r\n this.smoothing = false;\r\n this.backgroundColor = Color.ExcaliburBlue;\r\n this._alreadyWarnedDrawLifecycle = false;\r\n this.debug = new ExcaliburGraphicsContextWebGLDebug(this);\r\n this._totalPostProcessorTime = 0;\r\n const { canvasElement, enableTransparency, smoothing, snapToPixel, backgroundColor, useDrawSorting } = options;\r\n this.__gl = canvasElement.getContext('webgl2', {\r\n antialias: smoothing !== null && smoothing !== void 0 ? smoothing : this.smoothing,\r\n premultipliedAlpha: false,\r\n alpha: enableTransparency !== null && enableTransparency !== void 0 ? enableTransparency : true,\r\n depth: true,\r\n powerPreference: 'high-performance'\r\n // TODO Chromium fixed the bug where this didn't work now it breaks CI :(\r\n // failIfMajorPerformanceCaveat: true\r\n });\r\n if (!this.__gl) {\r\n throw Error('Failed to retrieve webgl context from browser');\r\n }\r\n this.textureLoader = new TextureLoader(this.__gl);\r\n this.snapToPixel = snapToPixel !== null && snapToPixel !== void 0 ? snapToPixel : this.snapToPixel;\r\n this.smoothing = smoothing !== null && smoothing !== void 0 ? smoothing : this.smoothing;\r\n this.backgroundColor = backgroundColor !== null && backgroundColor !== void 0 ? backgroundColor : this.backgroundColor;\r\n this.useDrawSorting = useDrawSorting !== null && useDrawSorting !== void 0 ? useDrawSorting : this.useDrawSorting;\r\n this._drawCallPool.disableWarnings = true;\r\n this._drawCallPool.preallocate();\r\n this._init();\r\n }\r\n _init() {\r\n const gl = this.__gl;\r\n // Setup viewport and view matrix\r\n this._ortho = Matrix.ortho(0, gl.canvas.width, gl.canvas.height, 0, 400, -400);\r\n gl.viewport(0, 0, gl.canvas.width, gl.canvas.height);\r\n // Clear background\r\n gl.clearColor(this.backgroundColor.r / 255, this.backgroundColor.g / 255, this.backgroundColor.b / 255, this.backgroundColor.a);\r\n gl.clear(gl.COLOR_BUFFER_BIT);\r\n // Enable alpha blending\r\n // https://www.realtimerendering.com/blog/gpus-prefer-premultiplication/\r\n gl.enable(gl.BLEND);\r\n gl.blendEquation(gl.FUNC_ADD);\r\n gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA);\r\n gl.blendEquationSeparate(gl.FUNC_ADD, gl.FUNC_ADD);\r\n gl.blendFuncSeparate(gl.ONE, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA);\r\n // Setup builtin renderers\r\n this.register(new ImageRenderer());\r\n this.register(new MaterialRenderer());\r\n this.register(new RectangleRenderer());\r\n this.register(new CircleRenderer());\r\n this.register(new PointRenderer());\r\n this.register(new LineRenderer());\r\n this._screenRenderer = new ScreenPassPainter(gl);\r\n this._renderTarget = new RenderTarget({\r\n gl,\r\n width: gl.canvas.width,\r\n height: gl.canvas.height\r\n });\r\n this._postProcessTargets = [\r\n new RenderTarget({\r\n gl,\r\n width: gl.canvas.width,\r\n height: gl.canvas.height\r\n }),\r\n new RenderTarget({\r\n gl,\r\n width: gl.canvas.width,\r\n height: gl.canvas.height\r\n })\r\n ];\r\n }\r\n register(renderer) {\r\n this._renderers.set(renderer.type, renderer);\r\n renderer.initialize(this.__gl, this);\r\n }\r\n get(rendererName) {\r\n return this._renderers.get(rendererName);\r\n }\r\n _isCurrentRenderer(renderer) {\r\n if (!this._currentRenderer || this._currentRenderer === renderer) {\r\n return true;\r\n }\r\n return false;\r\n }\r\n beginDrawLifecycle() {\r\n this._isDrawLifecycle = true;\r\n }\r\n endDrawLifecycle() {\r\n this._isDrawLifecycle = false;\r\n }\r\n draw(rendererName, ...args) {\r\n if (!this._isDrawLifecycle && !this._alreadyWarnedDrawLifecycle) {\r\n this._logger.warn(`Attempting to draw outside the the drawing lifecycle (preDraw/postDraw) is not supported and is a source of bugs/errors.\\n` +\r\n `If you want to do custom drawing, use Actor.graphics, or any onPreDraw or onPostDraw handler.`);\r\n this._alreadyWarnedDrawLifecycle = true;\r\n }\r\n const renderer = this._renderers.get(rendererName);\r\n if (renderer) {\r\n if (this.useDrawSorting) {\r\n const drawCall = this._drawCallPool.get();\r\n drawCall.z = this._state.current.z;\r\n drawCall.priority = renderer.priority;\r\n drawCall.renderer = rendererName;\r\n this.getTransform().clone(drawCall.transform);\r\n drawCall.state.z = this._state.current.z;\r\n drawCall.state.opacity = this._state.current.opacity;\r\n drawCall.state.tint = this._state.current.tint;\r\n drawCall.state.material = this._state.current.material;\r\n drawCall.args = args;\r\n this._drawCalls.push(drawCall);\r\n }\r\n else {\r\n // Set the current renderer if not defined\r\n if (!this._currentRenderer) {\r\n this._currentRenderer = renderer;\r\n }\r\n if (!this._isCurrentRenderer(renderer)) {\r\n // switching graphics means we must flush the previous\r\n this._currentRenderer.flush();\r\n }\r\n // If we are still using the same renderer we can add to the current batch\r\n renderer.draw(...args);\r\n this._currentRenderer = renderer;\r\n }\r\n }\r\n else {\r\n throw Error(`No renderer with name ${rendererName} has been registered`);\r\n }\r\n }\r\n resetTransform() {\r\n this._transform.current = AffineMatrix.identity();\r\n }\r\n updateViewport(resolution) {\r\n const gl = this.__gl;\r\n this._ortho = this._ortho = Matrix.ortho(0, resolution.width, resolution.height, 0, 400, -400);\r\n this._renderTarget.setResolution(gl.canvas.width, gl.canvas.height);\r\n this._postProcessTargets[0].setResolution(gl.canvas.width, gl.canvas.height);\r\n this._postProcessTargets[1].setResolution(gl.canvas.width, gl.canvas.height);\r\n }\r\n drawImage(image, sx, sy, swidth, sheight, dx, dy, dwidth, dheight) {\r\n if (swidth === 0 || sheight === 0) {\r\n return; // zero dimension dest exit early\r\n }\r\n else if (dwidth === 0 || dheight === 0) {\r\n return; // zero dimension dest exit early\r\n }\r\n else if (image.width === 0 || image.height === 0) {\r\n return; // zero dimension source exit early\r\n }\r\n if (!image) {\r\n Logger.getInstance().warn('Cannot draw a null or undefined image');\r\n // tslint:disable-next-line: no-console\r\n if (console.trace) {\r\n // tslint:disable-next-line: no-console\r\n console.trace();\r\n }\r\n return;\r\n }\r\n if (this._state.current.material) {\r\n this.draw('ex.material', image, sx, sy, swidth, sheight, dx, dy, dwidth, dheight);\r\n }\r\n else {\r\n this.draw('ex.image', image, sx, sy, swidth, sheight, dx, dy, dwidth, dheight);\r\n }\r\n }\r\n drawLine(start, end, color, thickness = 1) {\r\n this.draw('ex.rectangle', start, end, color, thickness);\r\n }\r\n drawRectangle(pos, width, height, color, stroke, strokeThickness) {\r\n this.draw('ex.rectangle', pos, width, height, color, stroke, strokeThickness);\r\n }\r\n drawCircle(pos, radius, color, stroke, thickness) {\r\n this.draw('ex.circle', pos, radius, color, stroke, thickness);\r\n }\r\n save() {\r\n this._transform.save();\r\n this._state.save();\r\n }\r\n restore() {\r\n this._transform.restore();\r\n this._state.restore();\r\n }\r\n translate(x, y) {\r\n this._transform.translate(this.snapToPixel ? ~~(x + pixelSnapEpsilon) : x, this.snapToPixel ? ~~(y + pixelSnapEpsilon) : y);\r\n }\r\n rotate(angle) {\r\n this._transform.rotate(angle);\r\n }\r\n scale(x, y) {\r\n this._transform.scale(x, y);\r\n }\r\n transform(matrix) {\r\n this._transform.current = matrix;\r\n }\r\n getTransform() {\r\n return this._transform.current;\r\n }\r\n multiply(m) {\r\n this._transform.current.multiply(m, this._transform.current);\r\n }\r\n addPostProcessor(postprocessor) {\r\n this._postprocessors.push(postprocessor);\r\n postprocessor.initialize(this.__gl);\r\n }\r\n removePostProcessor(postprocessor) {\r\n const index = this._postprocessors.indexOf(postprocessor);\r\n if (index !== -1) {\r\n this._postprocessors.splice(index, 1);\r\n }\r\n }\r\n clearPostProcessors() {\r\n this._postprocessors.length = 0;\r\n }\r\n updatePostProcessors(delta) {\r\n for (const postprocessor of this._postprocessors) {\r\n const shader = postprocessor.getShader();\r\n shader.use();\r\n const uniforms = shader.getUniforms();\r\n this._totalPostProcessorTime += delta;\r\n if (uniforms.find(u => u.name === 'u_time_ms')) {\r\n shader.setUniformFloat('u_time_ms', this._totalPostProcessorTime);\r\n }\r\n if (uniforms.find(u => u.name === 'u_elapsed_ms')) {\r\n shader.setUniformFloat('u_elapsed_ms', delta);\r\n }\r\n if (uniforms.find(u => u.name === 'u_resolution')) {\r\n shader.setUniformFloatVector('u_resolution', vec(this.width, this.height));\r\n }\r\n if (postprocessor.onUpdate) {\r\n postprocessor.onUpdate(delta);\r\n }\r\n }\r\n }\r\n set material(material) {\r\n this._state.current.material = material;\r\n }\r\n get material() {\r\n return this._state.current.material;\r\n }\r\n /**\r\n * Creates and initializes the material which compiles the internal shader\r\n * @param options\r\n * @returns Material\r\n */\r\n createMaterial(options) {\r\n const material = new Material(options);\r\n material.initialize(this.__gl, this);\r\n return material;\r\n }\r\n createShader(options) {\r\n const gl = this.__gl;\r\n const { vertexSource, fragmentSource } = options;\r\n const shader = new Shader({\r\n gl,\r\n vertexSource,\r\n fragmentSource\r\n });\r\n shader.compile();\r\n return shader;\r\n }\r\n clear() {\r\n const gl = this.__gl;\r\n this._renderTarget.use();\r\n gl.clearColor(this.backgroundColor.r / 255, this.backgroundColor.g / 255, this.backgroundColor.b / 255, this.backgroundColor.a);\r\n // Clear the context with the newly set color. This is\r\n // the function call that actually does the drawing.\r\n gl.clear(gl.COLOR_BUFFER_BIT);\r\n }\r\n /**\r\n * Flushes all batched rendering to the screen\r\n */\r\n flush() {\r\n const gl = this.__gl;\r\n // render target captures all draws and redirects to the render target\r\n this._renderTarget.use();\r\n if (this.useDrawSorting) {\r\n // sort draw calls\r\n // Find the original order of the first instance of the draw call\r\n const originalSort = new Map();\r\n for (const [name] of this._renderers) {\r\n const firstIndex = this._drawCalls.findIndex(dc => dc.renderer === name);\r\n originalSort.set(name, firstIndex);\r\n }\r\n this._drawCalls.sort((a, b) => {\r\n const zIndex = a.z - b.z;\r\n const originalSortOrder = originalSort.get(a.renderer) - originalSort.get(b.renderer);\r\n const priority = a.priority - b.priority;\r\n if (zIndex === 0) { // sort by z first\r\n if (priority === 0) { // sort by priority\r\n return originalSortOrder; // use the original order to inform draw call packing to maximally preserve painter order\r\n }\r\n return priority;\r\n }\r\n return zIndex;\r\n });\r\n const oldTransform = this._transform.current;\r\n const oldState = this._state.current;\r\n if (this._drawCalls.length) {\r\n let currentRendererName = this._drawCalls[0].renderer;\r\n let currentRenderer = this._renderers.get(currentRendererName);\r\n for (let i = 0; i < this._drawCalls.length; i++) {\r\n // hydrate the state for renderers\r\n this._transform.current = this._drawCalls[i].transform;\r\n this._state.current = this._drawCalls[i].state;\r\n if (this._drawCalls[i].renderer !== currentRendererName) {\r\n // switching graphics renderer means we must flush the previous\r\n currentRenderer.flush();\r\n currentRendererName = this._drawCalls[i].renderer;\r\n currentRenderer = this._renderers.get(currentRendererName);\r\n }\r\n // If we are still using the same renderer we can add to the current batch\r\n currentRenderer.draw(...this._drawCalls[i].args);\r\n }\r\n if (currentRenderer.hasPendingDraws()) {\r\n currentRenderer.flush();\r\n }\r\n }\r\n // reset state\r\n this._transform.current = oldTransform;\r\n this._state.current = oldState;\r\n // reclaim draw calls\r\n this._drawCallPool.done();\r\n this._drawCalls.length = 0;\r\n }\r\n else {\r\n // This is the final flush at the moment to draw any leftover pending draw\r\n for (const renderer of this._renderers.values()) {\r\n if (renderer.hasPendingDraws()) {\r\n renderer.flush();\r\n }\r\n }\r\n }\r\n this._renderTarget.disable();\r\n // post process step\r\n const source = this._renderTarget.toRenderSource();\r\n source.use();\r\n // flip flop render targets\r\n for (let i = 0; i < this._postprocessors.length; i++) {\r\n this._postProcessTargets[i % 2].use();\r\n this._screenRenderer.renderWithPostProcessor(this._postprocessors[i]);\r\n this._postProcessTargets[i % 2].toRenderSource().use();\r\n }\r\n // passing null switches rendering back to the canvas\r\n gl.bindFramebuffer(gl.FRAMEBUFFER, null);\r\n this._screenRenderer.renderToScreen();\r\n }\r\n}\r\n\n;// CONCATENATED MODULE: ./Graphics/Context/ExcaliburGraphicsContext2DCanvas.ts\n\r\n\r\n\r\n\r\nconst ExcaliburGraphicsContext2DCanvas_pixelSnapEpsilon = 0.0001;\r\nclass ExcaliburGraphicsContext2DCanvasDebug {\r\n constructor(_ex) {\r\n this._ex = _ex;\r\n this._debugText = new DebugText();\r\n }\r\n /**\r\n * Draw a debug rectangle to the context\r\n * @param x\r\n * @param y\r\n * @param width\r\n * @param height\r\n */\r\n drawRect(x, y, width, height) {\r\n this._ex.__ctx.save();\r\n this._ex.__ctx.strokeStyle = 'red';\r\n this._ex.__ctx.strokeRect(this._ex.snapToPixel ? ~~(x + ExcaliburGraphicsContext2DCanvas_pixelSnapEpsilon) : x, this._ex.snapToPixel ? ~~(y + ExcaliburGraphicsContext2DCanvas_pixelSnapEpsilon) : y, this._ex.snapToPixel ? ~~(width + ExcaliburGraphicsContext2DCanvas_pixelSnapEpsilon) : width, this._ex.snapToPixel ? ~~(height + ExcaliburGraphicsContext2DCanvas_pixelSnapEpsilon) : height);\r\n this._ex.__ctx.restore();\r\n }\r\n drawLine(start, end, lineOptions = { color: Color.Black }) {\r\n this._ex.__ctx.save();\r\n this._ex.__ctx.beginPath();\r\n this._ex.__ctx.strokeStyle = lineOptions.color.toString();\r\n this._ex.__ctx.moveTo(this._ex.snapToPixel ? ~~(start.x + ExcaliburGraphicsContext2DCanvas_pixelSnapEpsilon) : start.x, this._ex.snapToPixel ? ~~(start.y + ExcaliburGraphicsContext2DCanvas_pixelSnapEpsilon) : start.y);\r\n this._ex.__ctx.lineTo(this._ex.snapToPixel ? ~~(end.x + ExcaliburGraphicsContext2DCanvas_pixelSnapEpsilon) : end.x, this._ex.snapToPixel ? ~~(end.y + ExcaliburGraphicsContext2DCanvas_pixelSnapEpsilon) : end.y);\r\n this._ex.__ctx.lineWidth = 2;\r\n this._ex.__ctx.stroke();\r\n this._ex.__ctx.closePath();\r\n this._ex.__ctx.restore();\r\n }\r\n drawPoint(point, pointOptions = { color: Color.Black, size: 5 }) {\r\n this._ex.__ctx.save();\r\n this._ex.__ctx.beginPath();\r\n this._ex.__ctx.fillStyle = pointOptions.color.toString();\r\n this._ex.__ctx.arc(this._ex.snapToPixel ? ~~(point.x + ExcaliburGraphicsContext2DCanvas_pixelSnapEpsilon) : point.x, this._ex.snapToPixel ? ~~(point.y + ExcaliburGraphicsContext2DCanvas_pixelSnapEpsilon) : point.y, pointOptions.size, 0, Math.PI * 2);\r\n this._ex.__ctx.fill();\r\n this._ex.__ctx.closePath();\r\n this._ex.__ctx.restore();\r\n }\r\n drawText(text, pos) {\r\n this._debugText.write(this._ex, text, pos);\r\n }\r\n}\r\nclass ExcaliburGraphicsContext2DCanvas {\r\n get width() {\r\n return this.__ctx.canvas.width;\r\n }\r\n get height() {\r\n return this.__ctx.canvas.height;\r\n }\r\n get opacity() {\r\n return this._state.current.opacity;\r\n }\r\n set opacity(value) {\r\n this._state.current.opacity = value;\r\n }\r\n get tint() {\r\n return this._state.current.tint;\r\n }\r\n set tint(color) {\r\n this._state.current.tint = color;\r\n }\r\n get smoothing() {\r\n return this.__ctx.imageSmoothingEnabled;\r\n }\r\n set smoothing(value) {\r\n this.__ctx.imageSmoothingEnabled = value;\r\n }\r\n constructor(options) {\r\n /**\r\n * Unused in Canvas implementation\r\n */\r\n this.useDrawSorting = false;\r\n /**\r\n * Unused in Canvas implementation\r\n */\r\n this.z = 0;\r\n this.backgroundColor = Color.ExcaliburBlue;\r\n this._state = new StateStack();\r\n this.snapToPixel = false;\r\n this.debug = new ExcaliburGraphicsContext2DCanvasDebug(this);\r\n const { canvasElement, enableTransparency, snapToPixel, smoothing, backgroundColor } = options;\r\n this.__ctx = canvasElement.getContext('2d', {\r\n alpha: enableTransparency !== null && enableTransparency !== void 0 ? enableTransparency : true\r\n });\r\n this.backgroundColor = backgroundColor !== null && backgroundColor !== void 0 ? backgroundColor : this.backgroundColor;\r\n this.snapToPixel = snapToPixel !== null && snapToPixel !== void 0 ? snapToPixel : this.snapToPixel;\r\n this.smoothing = smoothing !== null && smoothing !== void 0 ? smoothing : this.smoothing;\r\n }\r\n resetTransform() {\r\n this.__ctx.resetTransform();\r\n }\r\n updateViewport(_resolution) {\r\n // pass\r\n }\r\n drawImage(image, sx, sy, swidth, sheight, dx, dy, dwidth, dheight) {\r\n if (swidth === 0 || sheight === 0) {\r\n return; // zero dimension dest exit early\r\n }\r\n else if (dwidth === 0 || dheight === 0) {\r\n return; // zero dimension dest exit early\r\n }\r\n else if (image.width === 0 || image.height === 0) {\r\n return; // zero dimension source exit early\r\n }\r\n this.__ctx.globalAlpha = this.opacity;\r\n const args = [image, sx, sy, swidth, sheight, dx, dy, dwidth, dheight]\r\n .filter((a) => a !== undefined)\r\n .map((a) => (typeof a === 'number' && this.snapToPixel ? ~~a : a));\r\n this.__ctx.drawImage.apply(this.__ctx, args);\r\n GraphicsDiagnostics.DrawCallCount++;\r\n GraphicsDiagnostics.DrawnImagesCount = 1;\r\n }\r\n drawLine(start, end, color, thickness = 1) {\r\n this.__ctx.save();\r\n this.__ctx.beginPath();\r\n this.__ctx.strokeStyle = color.toString();\r\n this.__ctx.moveTo(this.snapToPixel ? ~~(start.x + ExcaliburGraphicsContext2DCanvas_pixelSnapEpsilon) : start.x, this.snapToPixel ? ~~(start.y + ExcaliburGraphicsContext2DCanvas_pixelSnapEpsilon) : start.y);\r\n this.__ctx.lineTo(this.snapToPixel ? ~~(end.x + ExcaliburGraphicsContext2DCanvas_pixelSnapEpsilon) : end.x, this.snapToPixel ? ~~(end.y + ExcaliburGraphicsContext2DCanvas_pixelSnapEpsilon) : end.y);\r\n this.__ctx.lineWidth = thickness;\r\n this.__ctx.stroke();\r\n this.__ctx.closePath();\r\n this.__ctx.restore();\r\n }\r\n drawRectangle(pos, width, height, color) {\r\n this.__ctx.save();\r\n this.__ctx.fillStyle = color.toString();\r\n this.__ctx.fillRect(this.snapToPixel ? ~~(pos.x + ExcaliburGraphicsContext2DCanvas_pixelSnapEpsilon) : pos.x, this.snapToPixel ? ~~(pos.y + ExcaliburGraphicsContext2DCanvas_pixelSnapEpsilon) : pos.y, this.snapToPixel ? ~~(width + ExcaliburGraphicsContext2DCanvas_pixelSnapEpsilon) : width, this.snapToPixel ? ~~(height + ExcaliburGraphicsContext2DCanvas_pixelSnapEpsilon) : height);\r\n this.__ctx.restore();\r\n }\r\n drawCircle(pos, radius, color, stroke, thickness) {\r\n this.__ctx.save();\r\n this.__ctx.beginPath();\r\n if (stroke) {\r\n this.__ctx.strokeStyle = stroke.toString();\r\n }\r\n if (thickness) {\r\n this.__ctx.lineWidth = thickness;\r\n }\r\n this.__ctx.fillStyle = color.toString();\r\n this.__ctx.arc(this.snapToPixel ? ~~(pos.x + ExcaliburGraphicsContext2DCanvas_pixelSnapEpsilon) : pos.x, this.snapToPixel ? ~~(pos.y + ExcaliburGraphicsContext2DCanvas_pixelSnapEpsilon) : pos.y, radius, 0, Math.PI * 2);\r\n this.__ctx.fill();\r\n if (stroke) {\r\n this.__ctx.stroke();\r\n }\r\n this.__ctx.closePath();\r\n this.__ctx.restore();\r\n }\r\n /**\r\n * Save the current state of the canvas to the stack (transforms and opacity)\r\n */\r\n save() {\r\n this.__ctx.save();\r\n }\r\n /**\r\n * Restore the state of the canvas from the stack\r\n */\r\n restore() {\r\n this.__ctx.restore();\r\n }\r\n /**\r\n * Translate the origin of the context by an x and y\r\n * @param x\r\n * @param y\r\n */\r\n translate(x, y) {\r\n this.__ctx.translate(this.snapToPixel ? ~~(x + ExcaliburGraphicsContext2DCanvas_pixelSnapEpsilon) : x, this.snapToPixel ? ~~(y + ExcaliburGraphicsContext2DCanvas_pixelSnapEpsilon) : y);\r\n }\r\n /**\r\n * Rotate the context about the current origin\r\n */\r\n rotate(angle) {\r\n this.__ctx.rotate(angle);\r\n }\r\n /**\r\n * Scale the context by an x and y factor\r\n * @param x\r\n * @param y\r\n */\r\n scale(x, y) {\r\n this.__ctx.scale(x, y);\r\n }\r\n getTransform() {\r\n throw new Error('Not implemented');\r\n }\r\n multiply(_m) {\r\n this.__ctx.setTransform(this.__ctx.getTransform().multiply(_m.toDOMMatrix()));\r\n }\r\n addPostProcessor(_postprocessor) {\r\n // pass\r\n }\r\n removePostProcessor(_postprocessor) {\r\n // pass\r\n }\r\n clearPostProcessors() {\r\n // pass\r\n }\r\n updatePostProcessors(_delta) {\r\n // pass\r\n }\r\n beginDrawLifecycle() {\r\n // pass\r\n }\r\n endDrawLifecycle() {\r\n // pass\r\n }\r\n set material(material) {\r\n this._state.current.material = material;\r\n }\r\n get material() {\r\n return this._state.current.material;\r\n }\r\n createMaterial(_options) {\r\n // pass\r\n return null;\r\n }\r\n clear() {\r\n // Clear frame\r\n this.__ctx.clearRect(0, 0, this.width, this.height);\r\n this.__ctx.fillStyle = this.backgroundColor.toString();\r\n this.__ctx.fillRect(0, 0, this.width, this.height);\r\n GraphicsDiagnostics.clear();\r\n }\r\n /**\r\n * Flushes the batched draw calls to the screen\r\n */\r\n flush() {\r\n // pass\r\n }\r\n}\r\n\n;// CONCATENATED MODULE: ./Screen.ts\n\r\n\r\n\r\n\r\n\r\n\r\n/**\r\n * Enum representing the different display modes available to Excalibur.\r\n */\r\nvar DisplayMode;\r\n(function (DisplayMode) {\r\n /**\r\n * Default, use a specified resolution for the game. Like 800x600 pixels for example.\r\n */\r\n DisplayMode[\"Fixed\"] = \"Fixed\";\r\n /**\r\n * Fit the aspect ratio given by the game resolution within the container at all times will fill any gaps with canvas.\r\n * The displayed area outside the aspect ratio is not guaranteed to be on the screen, only the [[Screen.contentArea]]\r\n * is guaranteed to be on screen.\r\n */\r\n DisplayMode[\"FitContainerAndFill\"] = \"FitContainerAndFill\";\r\n /**\r\n * Fit the aspect ratio given by the game resolution the screen at all times will fill the screen.\r\n * This displayed area outside the aspect ratio is not guaranteed to be on the screen, only the [[Screen.contentArea]]\r\n * is guaranteed to be on screen.\r\n */\r\n DisplayMode[\"FitScreenAndFill\"] = \"FitScreenAndFill\";\r\n /**\r\n * Fit the viewport to the parent element maintaining aspect ratio given by the game resolution, but zooms in to avoid the black bars\r\n * (letterbox) that would otherwise be present in [[FitContainer]].\r\n *\r\n * **warning** This will clip some drawable area from the user because of the zoom,\r\n * use [[Screen.contentArea]] to know the safe to draw area.\r\n */\r\n DisplayMode[\"FitContainerAndZoom\"] = \"FitContainerAndZoom\";\r\n /**\r\n * Fit the viewport to the device screen maintaining aspect ratio given by the game resolution, but zooms in to avoid the black bars\r\n * (letterbox) that would otherwise be present in [[FitScreen]].\r\n *\r\n * **warning** This will clip some drawable area from the user because of the zoom,\r\n * use [[Screen.contentArea]] to know the safe to draw area.\r\n */\r\n DisplayMode[\"FitScreenAndZoom\"] = \"FitScreenAndZoom\";\r\n /**\r\n * Fit to screen using as much space as possible while maintaining aspect ratio and resolution.\r\n * This is not the same as [[Screen.goFullScreen]] but behaves in a similar way maintaining aspect ratio.\r\n *\r\n * You may want to center your game here is an example\r\n * ```html\r\n * \r\n * \r\n *
\r\n * \r\n *
\r\n * \r\n * ```\r\n *\r\n * ```css\r\n * // css\r\n * main {\r\n * display: flex;\r\n * align-items: center;\r\n * justify-content: center;\r\n * height: 100%;\r\n * width: 100%;\r\n * }\r\n * ```\r\n */\r\n DisplayMode[\"FitScreen\"] = \"FitScreen\";\r\n /**\r\n * Fill the entire screen's css width/height for the game resolution dynamically. This means the resolution of the game will\r\n * change dynamically as the window is resized. This is not the same as [[Screen.goFullScreen]]\r\n */\r\n DisplayMode[\"FillScreen\"] = \"FillScreen\";\r\n /**\r\n * Fit to parent element width/height using as much space as possible while maintaining aspect ratio and resolution.\r\n */\r\n DisplayMode[\"FitContainer\"] = \"FitContainer\";\r\n /**\r\n * Use the parent DOM container's css width/height for the game resolution dynamically\r\n */\r\n DisplayMode[\"FillContainer\"] = \"FillContainer\";\r\n})(DisplayMode || (DisplayMode = {}));\r\n/**\r\n * Convenience class for quick resolutions\r\n * Mostly sourced from https://emulation.gametechwiki.com/index.php/Resolution\r\n */\r\nclass Resolution {\r\n /* istanbul ignore next */\r\n static get SVGA() {\r\n return { width: 800, height: 600 };\r\n }\r\n /* istanbul ignore next */\r\n static get Standard() {\r\n return { width: 1920, height: 1080 };\r\n }\r\n /* istanbul ignore next */\r\n static get Atari2600() {\r\n return { width: 160, height: 192 };\r\n }\r\n /* istanbul ignore next */\r\n static get GameBoy() {\r\n return { width: 160, height: 144 };\r\n }\r\n /* istanbul ignore next */\r\n static get GameBoyAdvance() {\r\n return { width: 240, height: 160 };\r\n }\r\n /* istanbul ignore next */\r\n static get NintendoDS() {\r\n return { width: 256, height: 192 };\r\n }\r\n /* istanbul ignore next */\r\n static get NES() {\r\n return { width: 256, height: 224 };\r\n }\r\n /* istanbul ignore next */\r\n static get SNES() {\r\n return { width: 256, height: 244 };\r\n }\r\n}\r\n/**\r\n * The Screen handles all aspects of interacting with the screen for Excalibur.\r\n */\r\nclass Screen {\r\n constructor(options) {\r\n var _a, _b, _c;\r\n this._antialiasing = true;\r\n this._resolutionStack = [];\r\n this._viewportStack = [];\r\n this._pixelRatioOverride = null;\r\n this._isFullScreen = false;\r\n this._isDisposed = false;\r\n this._logger = Logger.getInstance();\r\n this._fullscreenChangeHandler = () => {\r\n this._isFullScreen = !this._isFullScreen;\r\n this._logger.debug('Fullscreen Change', this._isFullScreen);\r\n };\r\n this._pixelRatioChangeHandler = () => {\r\n this._logger.debug('Pixel Ratio Change', window.devicePixelRatio);\r\n this._listenForPixelRatio();\r\n this._devicePixelRatio = this._calculateDevicePixelRatio();\r\n this.applyResolutionAndViewport();\r\n };\r\n this._resizeHandler = () => {\r\n const parent = this.parent;\r\n this._logger.debug('View port resized');\r\n this._setResolutionAndViewportByDisplayMode(parent);\r\n this.applyResolutionAndViewport();\r\n };\r\n // Asking the window.devicePixelRatio is expensive we do it once\r\n this._devicePixelRatio = this._calculateDevicePixelRatio();\r\n this._alreadyWarned = false;\r\n this._contentArea = new BoundingBox();\r\n this.viewport = options.viewport;\r\n this.resolution = (_a = options.resolution) !== null && _a !== void 0 ? _a : { ...this.viewport };\r\n this._contentResolution = this.resolution;\r\n this._displayMode = (_b = options.displayMode) !== null && _b !== void 0 ? _b : DisplayMode.Fixed;\r\n this._canvas = options.canvas;\r\n this.graphicsContext = options.context;\r\n this._antialiasing = (_c = options.antialiasing) !== null && _c !== void 0 ? _c : this._antialiasing;\r\n this._browser = options.browser;\r\n this._pixelRatioOverride = options.pixelRatio;\r\n this._applyDisplayMode();\r\n this._listenForPixelRatio();\r\n this._canvas.addEventListener('fullscreenchange', this._fullscreenChangeHandler);\r\n this.applyResolutionAndViewport();\r\n }\r\n _listenForPixelRatio() {\r\n if (this._mediaQueryList && !this._mediaQueryList.addEventListener) {\r\n // Safari <=13.1 workaround, remove any existing handlers\r\n this._mediaQueryList.removeListener(this._pixelRatioChangeHandler);\r\n }\r\n this._mediaQueryList = this._browser.window.nativeComponent.matchMedia(`(resolution: ${window.devicePixelRatio}dppx)`);\r\n // Safari <=13.1 workaround\r\n if (this._mediaQueryList.addEventListener) {\r\n this._mediaQueryList.addEventListener('change', this._pixelRatioChangeHandler, { once: true });\r\n }\r\n else {\r\n this._mediaQueryList.addListener(this._pixelRatioChangeHandler);\r\n }\r\n }\r\n dispose() {\r\n if (!this._isDisposed) {\r\n // Clean up handlers\r\n this._isDisposed = true;\r\n this._browser.window.off('resize', this._resizeHandler);\r\n if (this._resizeObserver) {\r\n this._resizeObserver.disconnect();\r\n }\r\n this.parent.removeEventListener('resize', this._resizeHandler);\r\n // Safari <=13.1 workaround\r\n if (this._mediaQueryList.removeEventListener) {\r\n this._mediaQueryList.removeEventListener('change', this._pixelRatioChangeHandler);\r\n }\r\n else {\r\n this._mediaQueryList.removeListener(this._pixelRatioChangeHandler);\r\n }\r\n this._canvas.removeEventListener('fullscreenchange', this._fullscreenChangeHandler);\r\n }\r\n }\r\n _calculateDevicePixelRatio() {\r\n if (window.devicePixelRatio < 1) {\r\n return 1;\r\n }\r\n const devicePixelRatio = window.devicePixelRatio || 1;\r\n return devicePixelRatio;\r\n }\r\n get pixelRatio() {\r\n if (this._pixelRatioOverride) {\r\n return this._pixelRatioOverride;\r\n }\r\n return this._devicePixelRatio;\r\n }\r\n get isHiDpi() {\r\n return this.pixelRatio !== 1;\r\n }\r\n get displayMode() {\r\n return this._displayMode;\r\n }\r\n get canvas() {\r\n return this._canvas;\r\n }\r\n get parent() {\r\n switch (this.displayMode) {\r\n case DisplayMode.FillContainer:\r\n case DisplayMode.FitContainer:\r\n case DisplayMode.FitContainerAndFill:\r\n case DisplayMode.FitContainerAndZoom:\r\n return this.canvas.parentElement || document.body;\r\n default:\r\n return window;\r\n }\r\n }\r\n get resolution() {\r\n return this._resolution;\r\n }\r\n set resolution(resolution) {\r\n this._resolution = resolution;\r\n }\r\n get viewport() {\r\n if (this._viewport) {\r\n return this._viewport;\r\n }\r\n return this._resolution;\r\n }\r\n set viewport(viewport) {\r\n this._viewport = viewport;\r\n }\r\n get aspectRatio() {\r\n return this._resolution.width / this._resolution.height;\r\n }\r\n get scaledWidth() {\r\n return this._resolution.width * this.pixelRatio;\r\n }\r\n get scaledHeight() {\r\n return this._resolution.height * this.pixelRatio;\r\n }\r\n setCurrentCamera(camera) {\r\n this._camera = camera;\r\n }\r\n pushResolutionAndViewport() {\r\n this._resolutionStack.push(this.resolution);\r\n this._viewportStack.push(this.viewport);\r\n this.resolution = { ...this.resolution };\r\n this.viewport = { ...this.viewport };\r\n }\r\n peekViewport() {\r\n return this._viewportStack[this._viewportStack.length - 1];\r\n }\r\n peekResolution() {\r\n return this._resolutionStack[this._resolutionStack.length - 1];\r\n }\r\n popResolutionAndViewport() {\r\n this.resolution = this._resolutionStack.pop();\r\n this.viewport = this._viewportStack.pop();\r\n }\r\n applyResolutionAndViewport() {\r\n this._canvas.width = this.scaledWidth;\r\n this._canvas.height = this.scaledHeight;\r\n if (this.graphicsContext instanceof ExcaliburGraphicsContextWebGL) {\r\n const supported = this.graphicsContext.checkIfResolutionSupported({\r\n width: this.scaledWidth,\r\n height: this.scaledHeight\r\n });\r\n if (!supported && !this._alreadyWarned) {\r\n this._alreadyWarned = true; // warn once\r\n this._logger.warn(`The currently configured resolution (${this.resolution.width}x${this.resolution.height}) and pixel ratio (${this.pixelRatio})` +\r\n ' are too large for the platform WebGL implementation, this may work but cause WebGL rendering to behave oddly.' +\r\n ' Try reducing the resolution or disabling Hi DPI scaling to avoid this' +\r\n ' (read more here https://excaliburjs.com/docs/screens#understanding-viewport--resolution).');\r\n }\r\n }\r\n if (this._antialiasing) {\r\n this._canvas.style.imageRendering = 'auto';\r\n }\r\n else {\r\n this._canvas.style.imageRendering = 'pixelated';\r\n // Fall back to 'crisp-edges' if 'pixelated' is not supported\r\n // Currently for firefox https://developer.mozilla.org/en-US/docs/Web/CSS/image-rendering\r\n if (this._canvas.style.imageRendering === '') {\r\n this._canvas.style.imageRendering = 'crisp-edges';\r\n }\r\n }\r\n this._canvas.style.width = this.viewport.width + 'px';\r\n this._canvas.style.height = this.viewport.height + 'px';\r\n // After messing with the canvas width/height the graphics context is invalidated and needs to have some properties reset\r\n this.graphicsContext.updateViewport(this.resolution);\r\n this.graphicsContext.resetTransform();\r\n this.graphicsContext.smoothing = this._antialiasing;\r\n if (this.graphicsContext instanceof ExcaliburGraphicsContext2DCanvas) {\r\n this.graphicsContext.scale(this.pixelRatio, this.pixelRatio);\r\n }\r\n }\r\n get antialiasing() {\r\n return this._antialiasing;\r\n }\r\n set antialiasing(isSmooth) {\r\n this._antialiasing = isSmooth;\r\n this.graphicsContext.smoothing = this._antialiasing;\r\n }\r\n /**\r\n * Returns true if excalibur is fullscreen using the browser fullscreen api\r\n */\r\n get isFullScreen() {\r\n return this._isFullScreen;\r\n }\r\n /**\r\n * Requests to go fullscreen using the browser fullscreen api, requires user interaction to be successful.\r\n * For example, wire this to a user click handler.\r\n *\r\n * Optionally specify a target element id to go fullscreen, by default the game canvas is used\r\n * @param elementId\r\n */\r\n goFullScreen(elementId) {\r\n if (elementId) {\r\n const maybeElement = document.getElementById(elementId);\r\n if (maybeElement) {\r\n return maybeElement.requestFullscreen();\r\n }\r\n }\r\n return this._canvas.requestFullscreen();\r\n }\r\n /**\r\n * Requests to exit fullscreen using the browser fullscreen api\r\n */\r\n exitFullScreen() {\r\n return document.exitFullscreen();\r\n }\r\n /**\r\n * Takes a coordinate in normal html page space, for example from a pointer move event, and translates it to\r\n * Excalibur screen space.\r\n *\r\n * Excalibur screen space starts at the top left (0, 0) corner of the viewport, and extends to the\r\n * bottom right corner (resolutionX, resolutionY)\r\n * @param point\r\n */\r\n pageToScreenCoordinates(point) {\r\n let newX = point.x;\r\n let newY = point.y;\r\n if (!this._isFullScreen) {\r\n newX -= getPosition(this._canvas).x;\r\n newY -= getPosition(this._canvas).y;\r\n }\r\n // if fullscreen api on it centers with black bars\r\n // we need to adjust the screen to world coordinates in this case\r\n if (this._isFullScreen) {\r\n if (window.innerWidth / this.aspectRatio < window.innerHeight) {\r\n const screenHeight = window.innerWidth / this.aspectRatio;\r\n const screenMarginY = (window.innerHeight - screenHeight) / 2;\r\n newY = ((newY - screenMarginY) / screenHeight) * this.viewport.height;\r\n newX = (newX / window.innerWidth) * this.viewport.width;\r\n }\r\n else {\r\n const screenWidth = window.innerHeight * this.aspectRatio;\r\n const screenMarginX = (window.innerWidth - screenWidth) / 2;\r\n newX = ((newX - screenMarginX) / screenWidth) * this.viewport.width;\r\n newY = (newY / window.innerHeight) * this.viewport.height;\r\n }\r\n }\r\n newX = (newX / this.viewport.width) * this.resolution.width;\r\n newY = (newY / this.viewport.height) * this.resolution.height;\r\n return new Vector(newX, newY);\r\n }\r\n /**\r\n * Takes a coordinate in Excalibur screen space, and translates it to normal html page space. For example,\r\n * this is where html elements might live if you want to position them relative to Excalibur.\r\n *\r\n * Excalibur screen space starts at the top left (0, 0) corner of the viewport, and extends to the\r\n * bottom right corner (resolutionX, resolutionY)\r\n * @param point\r\n */\r\n screenToPageCoordinates(point) {\r\n let newX = point.x;\r\n let newY = point.y;\r\n newX = (newX / this.resolution.width) * this.viewport.width;\r\n newY = (newY / this.resolution.height) * this.viewport.height;\r\n if (this._isFullScreen) {\r\n if (window.innerWidth / this.aspectRatio < window.innerHeight) {\r\n const screenHeight = window.innerWidth / this.aspectRatio;\r\n const screenMarginY = (window.innerHeight - screenHeight) / 2;\r\n newY = (newY / this.viewport.height) * screenHeight + screenMarginY;\r\n newX = (newX / this.viewport.width) * window.innerWidth;\r\n }\r\n else {\r\n const screenWidth = window.innerHeight * this.aspectRatio;\r\n const screenMarginX = (window.innerWidth - screenWidth) / 2;\r\n newX = (newX / this.viewport.width) * screenWidth + screenMarginX;\r\n newY = (newY / this.viewport.height) * window.innerHeight;\r\n }\r\n }\r\n if (!this._isFullScreen) {\r\n newX += getPosition(this._canvas).x;\r\n newY += getPosition(this._canvas).y;\r\n }\r\n return new Vector(newX, newY);\r\n }\r\n /**\r\n * Takes a coordinate in Excalibur screen space, and translates it to Excalibur world space.\r\n *\r\n * World space is where [[Entity|entities]] in Excalibur live by default [[CoordPlane.World]]\r\n * and extends infinitely out relative from the [[Camera]].\r\n * @param point Screen coordinate to convert\r\n */\r\n screenToWorldCoordinates(point) {\r\n // the only difference between screen & world is the camera transform\r\n if (this._camera) {\r\n return this._camera.inverse.multiply(point);\r\n }\r\n return point.sub(vec(this.resolution.width / 2, this.resolution.height / 2));\r\n }\r\n /**\r\n * Takes a coordinate in Excalibur world space, and translates it to Excalibur screen space.\r\n *\r\n * Screen space is where [[ScreenElement|screen elements]] and [[Entity|entities]] with [[CoordPlane.Screen]] live.\r\n * @param point World coordinate to convert\r\n */\r\n worldToScreenCoordinates(point) {\r\n if (this._camera) {\r\n return this._camera.transform.multiply(point);\r\n }\r\n return point.add(vec(this.resolution.width / 2, this.resolution.height / 2));\r\n }\r\n pageToWorldCoordinates(point) {\r\n const screen = this.pageToScreenCoordinates(point);\r\n return this.screenToWorldCoordinates(screen);\r\n }\r\n worldToPageCoordinates(point) {\r\n const screen = this.worldToScreenCoordinates(point);\r\n return this.screenToPageCoordinates(screen);\r\n }\r\n /**\r\n * Returns a BoundingBox of the top left corner of the screen\r\n * and the bottom right corner of the screen.\r\n *\r\n * World bounds are in world coordinates, useful for culling objects offscreen\r\n */\r\n getWorldBounds() {\r\n const bounds = BoundingBox.fromDimension(this.resolution.width, this.resolution.height, Vector.Half)\r\n .scale(vec(1 / this._camera.zoom, 1 / this._camera.zoom))\r\n .rotate(this._camera.rotation)\r\n .translate(this._camera.pos);\r\n return bounds;\r\n }\r\n /**\r\n * The width of the game canvas in pixels (physical width component of the\r\n * resolution of the canvas element)\r\n */\r\n get canvasWidth() {\r\n return this.canvas.width;\r\n }\r\n /**\r\n * Returns half width of the game canvas in pixels (half physical width component)\r\n */\r\n get halfCanvasWidth() {\r\n return this.canvas.width / 2;\r\n }\r\n /**\r\n * The height of the game canvas in pixels, (physical height component of\r\n * the resolution of the canvas element)\r\n */\r\n get canvasHeight() {\r\n return this.canvas.height;\r\n }\r\n /**\r\n * Returns half height of the game canvas in pixels (half physical height component)\r\n */\r\n get halfCanvasHeight() {\r\n return this.canvas.height / 2;\r\n }\r\n /**\r\n * Returns the width of the engine's visible drawing surface in pixels including zoom and device pixel ratio.\r\n */\r\n get drawWidth() {\r\n if (this._camera) {\r\n return this.resolution.width / this._camera.zoom;\r\n }\r\n return this.resolution.width;\r\n }\r\n /**\r\n * Returns half the width of the engine's visible drawing surface in pixels including zoom and device pixel ratio.\r\n */\r\n get halfDrawWidth() {\r\n return this.drawWidth / 2;\r\n }\r\n /**\r\n * Returns the height of the engine's visible drawing surface in pixels including zoom and device pixel ratio.\r\n */\r\n get drawHeight() {\r\n if (this._camera) {\r\n return this.resolution.height / this._camera.zoom;\r\n }\r\n return this.resolution.height;\r\n }\r\n /**\r\n * Returns half the height of the engine's visible drawing surface in pixels including zoom and device pixel ratio.\r\n */\r\n get halfDrawHeight() {\r\n return this.drawHeight / 2;\r\n }\r\n /**\r\n * Returns screen center coordinates including zoom and device pixel ratio.\r\n */\r\n get center() {\r\n return vec(this.halfDrawWidth, this.halfDrawHeight);\r\n }\r\n /**\r\n * Returns the content area in screen space where it is safe to place content\r\n */\r\n get contentArea() {\r\n return this._contentArea;\r\n }\r\n _computeFit() {\r\n document.body.style.margin = '0px';\r\n document.body.style.overflow = 'hidden';\r\n const aspect = this.aspectRatio;\r\n let adjustedWidth = 0;\r\n let adjustedHeight = 0;\r\n if (window.innerWidth / aspect < window.innerHeight) {\r\n adjustedWidth = window.innerWidth;\r\n adjustedHeight = window.innerWidth / aspect;\r\n }\r\n else {\r\n adjustedWidth = window.innerHeight * aspect;\r\n adjustedHeight = window.innerHeight;\r\n }\r\n this.viewport = {\r\n width: adjustedWidth,\r\n height: adjustedHeight\r\n };\r\n this._contentArea = BoundingBox.fromDimension(this.resolution.width, this.resolution.height, Vector.Zero);\r\n }\r\n _computeFitScreenAndFill() {\r\n document.body.style.margin = '0px';\r\n document.body.style.overflow = 'hidden';\r\n const vw = window.innerWidth;\r\n const vh = window.innerHeight;\r\n this._computeFitAndFill(vw, vh);\r\n }\r\n _computeFitContainerAndFill() {\r\n document.body.style.margin = '0px';\r\n document.body.style.overflow = 'hidden';\r\n const parent = this.canvas.parentElement;\r\n const vw = parent.clientWidth;\r\n const vh = parent.clientHeight;\r\n this._computeFitAndFill(vw, vh);\r\n }\r\n _computeFitAndFill(vw, vh) {\r\n this.viewport = {\r\n width: vw,\r\n height: vh\r\n };\r\n // if the current screen aspectRatio is less than the original aspectRatio\r\n if (vw / vh <= this._contentResolution.width / this._contentResolution.height) {\r\n // compute new resolution to match the original aspect ratio\r\n this.resolution = {\r\n width: vw * this._contentResolution.width / vw,\r\n height: vw * this._contentResolution.width / vw * vh / vw\r\n };\r\n const clip = (this.resolution.height - this._contentResolution.height) / 2;\r\n this._contentArea = new BoundingBox({\r\n top: clip,\r\n left: 0,\r\n right: this._contentResolution.width,\r\n bottom: this.resolution.height - clip\r\n });\r\n }\r\n else {\r\n this.resolution = {\r\n width: vh * this._contentResolution.height / vh * vw / vh,\r\n height: vh * this._contentResolution.height / vh\r\n };\r\n const clip = (this.resolution.width - this._contentResolution.width) / 2;\r\n this._contentArea = new BoundingBox({\r\n top: 0,\r\n left: clip,\r\n right: this.resolution.width - clip,\r\n bottom: this._contentResolution.height\r\n });\r\n }\r\n }\r\n _computeFitScreenAndZoom() {\r\n document.body.style.margin = '0px';\r\n document.body.style.overflow = 'hidden';\r\n this.canvas.style.position = 'absolute';\r\n const vw = window.innerWidth;\r\n const vh = window.innerHeight;\r\n this._computeFitAndZoom(vw, vh);\r\n }\r\n _computeFitContainerAndZoom() {\r\n document.body.style.margin = '0px';\r\n document.body.style.overflow = 'hidden';\r\n this.canvas.style.position = 'absolute';\r\n const parent = this.canvas.parentElement;\r\n parent.style.position = 'relative';\r\n parent.style.overflow = 'hidden';\r\n const vw = parent.clientWidth;\r\n const vh = parent.clientHeight;\r\n this._computeFitAndZoom(vw, vh);\r\n }\r\n _computeFitAndZoom(vw, vh) {\r\n const aspect = this.aspectRatio;\r\n let adjustedWidth = 0;\r\n let adjustedHeight = 0;\r\n if (vw / aspect < vh) {\r\n adjustedWidth = vw;\r\n adjustedHeight = vw / aspect;\r\n }\r\n else {\r\n adjustedWidth = vh * aspect;\r\n adjustedHeight = vh;\r\n }\r\n const scaleX = vw / adjustedWidth;\r\n const scaleY = vh / adjustedHeight;\r\n const maxScaleFactor = Math.max(scaleX, scaleY);\r\n const zoomedWidth = adjustedWidth * maxScaleFactor;\r\n const zoomedHeight = adjustedHeight * maxScaleFactor;\r\n // Center zoomed dimension if bigger than the screen\r\n if (zoomedWidth > vw) {\r\n this.canvas.style.left = -(zoomedWidth - vw) / 2 + 'px';\r\n }\r\n else {\r\n this.canvas.style.left = '';\r\n }\r\n if (zoomedHeight > vh) {\r\n this.canvas.style.top = -(zoomedHeight - vh) / 2 + 'px';\r\n }\r\n else {\r\n this.canvas.style.top = '';\r\n }\r\n this.viewport = {\r\n width: zoomedWidth,\r\n height: zoomedHeight\r\n };\r\n const bounds = BoundingBox.fromDimension(this.viewport.width, this.viewport.height, Vector.Zero);\r\n // return safe area\r\n if (this.viewport.width > vw) {\r\n const clip = (this.viewport.width - vw) / this.viewport.width * this.resolution.width;\r\n bounds.top = 0;\r\n bounds.left = clip / 2;\r\n bounds.right = this.resolution.width - clip / 2;\r\n bounds.bottom = this.resolution.height;\r\n }\r\n if (this.viewport.height > vh) {\r\n const clip = (this.viewport.height - vh) / this.viewport.height * this.resolution.height;\r\n bounds.top = clip / 2;\r\n bounds.left = 0;\r\n bounds.bottom = this.resolution.height - clip / 2;\r\n bounds.right = this.resolution.width;\r\n }\r\n this._contentArea = bounds;\r\n }\r\n _computeFitContainer() {\r\n const aspect = this.aspectRatio;\r\n let adjustedWidth = 0;\r\n let adjustedHeight = 0;\r\n const parent = this.canvas.parentElement;\r\n if (parent.clientWidth / aspect < parent.clientHeight) {\r\n adjustedWidth = parent.clientWidth;\r\n adjustedHeight = parent.clientWidth / aspect;\r\n }\r\n else {\r\n adjustedWidth = parent.clientHeight * aspect;\r\n adjustedHeight = parent.clientHeight;\r\n }\r\n this.viewport = {\r\n width: adjustedWidth,\r\n height: adjustedHeight\r\n };\r\n this._contentArea = BoundingBox.fromDimension(this.resolution.width, this.resolution.height, Vector.Zero);\r\n }\r\n _applyDisplayMode() {\r\n this._setResolutionAndViewportByDisplayMode(this.parent);\r\n // watch resizing\r\n if (this.parent instanceof Window) {\r\n this._browser.window.on('resize', this._resizeHandler);\r\n }\r\n else {\r\n this._resizeObserver = new ResizeObserver(() => {\r\n this._resizeHandler();\r\n });\r\n this._resizeObserver.observe(this.parent);\r\n }\r\n this.parent.addEventListener('resize', this._resizeHandler);\r\n }\r\n /**\r\n * Sets the resolution and viewport based on the selected display mode.\r\n */\r\n _setResolutionAndViewportByDisplayMode(parent) {\r\n if (this.displayMode === DisplayMode.FillContainer) {\r\n this.resolution = {\r\n width: parent.clientWidth,\r\n height: parent.clientHeight\r\n };\r\n this.viewport = this.resolution;\r\n }\r\n if (this.displayMode === DisplayMode.FillScreen) {\r\n document.body.style.margin = '0px';\r\n document.body.style.overflow = 'hidden';\r\n this.resolution = {\r\n width: parent.innerWidth,\r\n height: parent.innerHeight\r\n };\r\n this.viewport = this.resolution;\r\n }\r\n this._contentArea = BoundingBox.fromDimension(this.resolution.width, this.resolution.height, Vector.Zero);\r\n if (this.displayMode === DisplayMode.FitScreen) {\r\n this._computeFit();\r\n }\r\n if (this.displayMode === DisplayMode.FitContainer) {\r\n this._computeFitContainer();\r\n }\r\n if (this.displayMode === DisplayMode.FitScreenAndFill) {\r\n this._computeFitScreenAndFill();\r\n }\r\n if (this.displayMode === DisplayMode.FitContainerAndFill) {\r\n this._computeFitContainerAndFill();\r\n }\r\n if (this.displayMode === DisplayMode.FitScreenAndZoom) {\r\n this._computeFitScreenAndZoom();\r\n }\r\n if (this.displayMode === DisplayMode.FitContainerAndZoom) {\r\n this._computeFitContainerAndZoom();\r\n }\r\n }\r\n}\r\n\n;// CONCATENATED MODULE: ./Resources/Sound/AudioContext.ts\n/**\r\n * Internal class used to build instances of AudioContext\r\n */\r\n/* istanbul ignore next */\r\nclass AudioContextFactory {\r\n static create() {\r\n if (!this._INSTANCE) {\r\n if (window.AudioContext || window.webkitAudioContext) {\r\n this._INSTANCE = new AudioContext();\r\n }\r\n }\r\n return this._INSTANCE;\r\n }\r\n}\r\nAudioContextFactory._INSTANCE = null;\r\n\n;// CONCATENATED MODULE: ./Util/WebAudio.ts\n\r\n\r\n/**\r\n * Patch for detecting legacy web audio in browsers\r\n * @internal\r\n * @param source\r\n */\r\nfunction isLegacyWebAudioSource(source) {\r\n return !!source.playbackState;\r\n}\r\nclass WebAudio {\r\n /**\r\n * Play an empty sound to unlock Safari WebAudio context. Call this function\r\n * right after a user interaction event.\r\n * @source https://paulbakaus.com/tutorials/html5/web-audio-on-ios/\r\n */\r\n static unlock() {\r\n const promise = new Promise((resolve, reject) => {\r\n if (WebAudio._UNLOCKED || !AudioContextFactory.create()) {\r\n return resolve(true);\r\n }\r\n const unlockTimeoutTimer = setTimeout(() => {\r\n Logger.getInstance().warn('Excalibur was unable to unlock the audio context, audio probably will not play in this browser.');\r\n resolve(false);\r\n }, 200);\r\n const audioContext = AudioContextFactory.create();\r\n audioContext.resume().then(() => {\r\n // create empty buffer and play it\r\n const buffer = audioContext.createBuffer(1, 1, 22050);\r\n const source = audioContext.createBufferSource();\r\n let ended = false;\r\n source.buffer = buffer;\r\n source.connect(audioContext.destination);\r\n source.onended = () => (ended = true);\r\n source.start(0);\r\n // by checking the play state after some time, we know if we're really unlocked\r\n setTimeout(() => {\r\n if (isLegacyWebAudioSource(source)) {\r\n if (source.playbackState === source.PLAYING_STATE || source.playbackState === source.FINISHED_STATE) {\r\n WebAudio._UNLOCKED = true;\r\n }\r\n }\r\n else {\r\n if (audioContext.currentTime > 0 || ended) {\r\n WebAudio._UNLOCKED = true;\r\n }\r\n }\r\n }, 0);\r\n clearTimeout(unlockTimeoutTimer);\r\n resolve(true);\r\n }, () => {\r\n reject();\r\n });\r\n });\r\n return promise;\r\n }\r\n static isUnlocked() {\r\n return this._UNLOCKED;\r\n }\r\n}\r\nWebAudio._UNLOCKED = false;\r\n\n;// CONCATENATED MODULE: ./Util/DrawUtil.ts\n\r\n/* istanbul ignore next */\r\n/**\r\n * Draw a line on canvas context\r\n *\r\n * @param ctx The canvas context\r\n * @param color The color of the line\r\n * @param x1 The start x coordinate\r\n * @param y1 The start y coordinate\r\n * @param x2 The ending x coordinate\r\n * @param y2 The ending y coordinate\r\n * @param thickness The line thickness\r\n * @param cap The [[LineCapStyle]] (butt, round, or square)\r\n */\r\nfunction line(ctx, color = Color.Red, x1, y1, x2, y2, thickness = 1, cap = 'butt') {\r\n ctx.save();\r\n ctx.beginPath();\r\n ctx.lineWidth = thickness;\r\n ctx.lineCap = cap;\r\n ctx.strokeStyle = color.toString();\r\n ctx.moveTo(x1, y1);\r\n ctx.lineTo(x2, y2);\r\n ctx.closePath();\r\n ctx.stroke();\r\n ctx.restore();\r\n}\r\n/* istanbul ignore next */\r\n/**\r\n * Draw the vector as a point onto the canvas.\r\n */\r\nfunction point(ctx, color = Color.Red, point) {\r\n ctx.beginPath();\r\n ctx.strokeStyle = color.toString();\r\n ctx.arc(point.x, point.y, 5, 0, Math.PI * 2);\r\n ctx.closePath();\r\n ctx.stroke();\r\n}\r\n/**\r\n * Draw the vector as a line onto the canvas starting a origin point.\r\n */\r\n/* istanbul ignore next */\r\n/**\r\n *\r\n */\r\nfunction vector(ctx, color, origin, vector, scale = 1.0) {\r\n const c = color ? color.toString() : 'blue';\r\n const v = vector.scale(scale);\r\n ctx.beginPath();\r\n ctx.strokeStyle = c;\r\n ctx.moveTo(origin.x, origin.y);\r\n ctx.lineTo(origin.x + v.x, origin.y + v.y);\r\n ctx.closePath();\r\n ctx.stroke();\r\n}\r\n/**\r\n * Draw a round rectangle on a canvas context\r\n *\r\n * @param ctx The canvas context\r\n * @param x The top-left x coordinate\r\n * @param y The top-left y coordinate\r\n * @param width The width of the rectangle\r\n * @param height The height of the rectangle\r\n * @param radius The border radius of the rectangle\r\n * @param stroke The [[Color]] to stroke rectangle with\r\n * @param fill The [[Color]] to fill rectangle with\r\n */\r\nfunction roundRect(ctx, x, y, width, height, radius = 5, stroke = Color.White, fill = null) {\r\n let br;\r\n if (typeof radius === 'number') {\r\n br = { tl: radius, tr: radius, br: radius, bl: radius };\r\n }\r\n else {\r\n const defaultRadius = { tl: 0, tr: 0, br: 0, bl: 0 };\r\n for (const prop in defaultRadius) {\r\n if (defaultRadius.hasOwnProperty(prop)) {\r\n const side = prop;\r\n br[side] = radius[side] || defaultRadius[side];\r\n }\r\n }\r\n }\r\n ctx.beginPath();\r\n ctx.moveTo(x + br.tl, y);\r\n ctx.lineTo(x + width - br.tr, y);\r\n ctx.quadraticCurveTo(x + width, y, x + width, y + br.tr);\r\n ctx.lineTo(x + width, y + height - br.br);\r\n ctx.quadraticCurveTo(x + width, y + height, x + width - br.br, y + height);\r\n ctx.lineTo(x + br.bl, y + height);\r\n ctx.quadraticCurveTo(x, y + height, x, y + height - br.bl);\r\n ctx.lineTo(x, y + br.tl);\r\n ctx.quadraticCurveTo(x, y, x + br.tl, y);\r\n ctx.closePath();\r\n if (fill) {\r\n ctx.fillStyle = fill.toString();\r\n ctx.fill();\r\n }\r\n if (stroke) {\r\n ctx.strokeStyle = stroke.toString();\r\n ctx.stroke();\r\n }\r\n}\r\n/**\r\n *\r\n */\r\nfunction circle(ctx, x, y, radius, stroke = Color.White, fill = null) {\r\n ctx.beginPath();\r\n ctx.arc(x, y, radius, 0, Math.PI * 2);\r\n ctx.closePath();\r\n if (fill) {\r\n ctx.fillStyle = fill.toString();\r\n ctx.fill();\r\n }\r\n if (stroke) {\r\n ctx.strokeStyle = stroke.toString();\r\n ctx.stroke();\r\n }\r\n}\r\n\n;// CONCATENATED MODULE: ./Loader.logo.png\n/* harmony default export */ const Loader_logo = (\"data:image/png;base64,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\");\n// EXTERNAL MODULE: ./Loader.css\nvar Loader_0 = __webpack_require__(1388);\n;// CONCATENATED MODULE: ./Graphics/Raster.ts\n\r\n\r\n\r\n\r\n\r\n/**\r\n * A Raster is a Graphic that needs to be first painted to a HTMLCanvasElement before it can be drawn to the\r\n * [[ExcaliburGraphicsContext]]. This is useful for generating custom images using the 2D canvas api.\r\n *\r\n * Implementors must implement the [[Raster.execute]] method to rasterize their drawing.\r\n */\r\nclass Raster extends Graphic {\r\n constructor(options) {\r\n var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;\r\n super(options);\r\n this.filtering = null;\r\n this.lineCap = 'butt';\r\n this.quality = 1;\r\n this._dirty = true;\r\n this._smoothing = false;\r\n this._color = watch(Color.Black, () => this.flagDirty());\r\n this._lineWidth = 1;\r\n this._lineDash = [];\r\n this._padding = 0;\r\n if (options) {\r\n this.quality = (_a = options.quality) !== null && _a !== void 0 ? _a : this.quality;\r\n this.color = (_b = options.color) !== null && _b !== void 0 ? _b : Color.Black;\r\n this.strokeColor = options === null || options === void 0 ? void 0 : options.strokeColor;\r\n this.smoothing = (_c = options.smoothing) !== null && _c !== void 0 ? _c : this.smoothing;\r\n this.lineWidth = (_d = options.lineWidth) !== null && _d !== void 0 ? _d : this.lineWidth;\r\n this.lineDash = (_e = options.lineDash) !== null && _e !== void 0 ? _e : this.lineDash;\r\n this.lineCap = (_f = options.lineCap) !== null && _f !== void 0 ? _f : this.lineCap;\r\n this.padding = (_g = options.padding) !== null && _g !== void 0 ? _g : this.padding;\r\n this.filtering = (_h = options.filtering) !== null && _h !== void 0 ? _h : this.filtering;\r\n }\r\n this._bitmap = document.createElement('canvas');\r\n // get the default canvas width/height as a fallback\r\n const bitmapWidth = (_j = options === null || options === void 0 ? void 0 : options.width) !== null && _j !== void 0 ? _j : this._bitmap.width;\r\n const bitmapHeight = (_k = options === null || options === void 0 ? void 0 : options.height) !== null && _k !== void 0 ? _k : this._bitmap.height;\r\n this.width = bitmapWidth;\r\n this.height = bitmapHeight;\r\n const maybeCtx = this._bitmap.getContext('2d');\r\n if (!maybeCtx) {\r\n /* istanbul ignore next */\r\n throw new Error('Browser does not support 2d canvas drawing, cannot create Raster graphic');\r\n }\r\n else {\r\n this._ctx = maybeCtx;\r\n }\r\n }\r\n cloneRasterOptions() {\r\n return {\r\n color: this.color ? this.color.clone() : null,\r\n strokeColor: this.strokeColor ? this.strokeColor.clone() : null,\r\n smoothing: this.smoothing,\r\n lineWidth: this.lineWidth,\r\n lineDash: this.lineDash,\r\n lineCap: this.lineCap,\r\n quality: this.quality,\r\n padding: this.padding\r\n };\r\n }\r\n /**\r\n * Gets whether the graphic is dirty, this means there are changes that haven't been re-rasterized\r\n */\r\n get dirty() {\r\n return this._dirty;\r\n }\r\n /**\r\n * Flags the graphic as dirty, meaning it must be re-rasterized before draw.\r\n * This should be called any time the graphics state changes such that it affects the outputted drawing\r\n */\r\n flagDirty() {\r\n this._dirty = true;\r\n }\r\n /**\r\n * Gets or sets the current width of the Raster graphic. Setting the width will cause the raster\r\n * to be flagged dirty causing a re-raster on the next draw.\r\n *\r\n * Any `padding`s or `quality` set will be factored into the width\r\n */\r\n get width() {\r\n return Math.abs(this._getTotalWidth() * this.scale.x);\r\n }\r\n set width(value) {\r\n value /= Math.abs(this.scale.x);\r\n this._bitmap.width = value;\r\n this._originalWidth = value;\r\n this.flagDirty();\r\n }\r\n /**\r\n * Gets or sets the current height of the Raster graphic. Setting the height will cause the raster\r\n * to be flagged dirty causing a re-raster on the next draw.\r\n *\r\n * Any `padding` or `quality` set will be factored into the height\r\n */\r\n get height() {\r\n return Math.abs(this._getTotalHeight() * this.scale.y);\r\n }\r\n set height(value) {\r\n value /= Math.abs(this.scale.y);\r\n this._bitmap.height = value;\r\n this._originalHeight = value;\r\n this.flagDirty();\r\n }\r\n _getTotalWidth() {\r\n var _a;\r\n return (((_a = this._originalWidth) !== null && _a !== void 0 ? _a : this._bitmap.width) + this.padding * 2) * 1;\r\n }\r\n _getTotalHeight() {\r\n var _a;\r\n return (((_a = this._originalHeight) !== null && _a !== void 0 ? _a : this._bitmap.height) + this.padding * 2) * 1;\r\n }\r\n /**\r\n * Returns the local bounds of the Raster including the padding\r\n */\r\n get localBounds() {\r\n return BoundingBox.fromDimension(this._getTotalWidth() * this.scale.x, this._getTotalHeight() * this.scale.y, Vector.Zero);\r\n }\r\n /**\r\n * Gets or sets the smoothing (anti-aliasing of the graphic). Setting the height will cause the raster\r\n * to be flagged dirty causing a re-raster on the next draw.\r\n */\r\n get smoothing() {\r\n return this._smoothing;\r\n }\r\n set smoothing(value) {\r\n this._smoothing = value;\r\n this.flagDirty();\r\n }\r\n /**\r\n * Gets or sets the fillStyle of the Raster graphic. Setting the fillStyle will cause the raster to be\r\n * flagged dirty causing a re-raster on the next draw.\r\n */\r\n get color() {\r\n return this._color;\r\n }\r\n set color(value) {\r\n this.flagDirty();\r\n this._color = watch(value, () => this.flagDirty());\r\n }\r\n /**\r\n * Gets or sets the strokeStyle of the Raster graphic. Setting the strokeStyle will cause the raster to be\r\n * flagged dirty causing a re-raster on the next draw.\r\n */\r\n get strokeColor() {\r\n return this._strokeColor;\r\n }\r\n set strokeColor(value) {\r\n this.flagDirty();\r\n this._strokeColor = watch(value, () => this.flagDirty());\r\n }\r\n /**\r\n * Gets or sets the line width of the Raster graphic. Setting the lineWidth will cause the raster to be\r\n * flagged dirty causing a re-raster on the next draw.\r\n */\r\n get lineWidth() {\r\n return this._lineWidth;\r\n }\r\n set lineWidth(value) {\r\n this._lineWidth = value;\r\n this.flagDirty();\r\n }\r\n get lineDash() {\r\n return this._lineDash;\r\n }\r\n set lineDash(value) {\r\n this._lineDash = value;\r\n this.flagDirty();\r\n }\r\n get padding() {\r\n return this._padding;\r\n }\r\n set padding(value) {\r\n this._padding = value;\r\n this.flagDirty();\r\n }\r\n /**\r\n * Rasterize the graphic to a bitmap making it usable as in excalibur. Rasterize is called automatically if\r\n * the graphic is [[Raster.dirty]] on the next [[Graphic.draw]] call\r\n */\r\n rasterize() {\r\n this._dirty = false;\r\n this._ctx.clearRect(0, 0, this._getTotalWidth(), this._getTotalHeight());\r\n this._ctx.save();\r\n this._applyRasterProperties(this._ctx);\r\n this.execute(this._ctx);\r\n this._ctx.restore();\r\n }\r\n _applyRasterProperties(ctx) {\r\n var _a, _b, _c;\r\n this._bitmap.width = this._getTotalWidth() * this.quality;\r\n this._bitmap.height = this._getTotalHeight() * this.quality;\r\n // Do a bad thing to pass the filtering as an attribute\r\n this._bitmap.setAttribute('filtering', this.filtering);\r\n this._bitmap.setAttribute('forceUpload', 'true');\r\n ctx.scale(this.quality, this.quality);\r\n ctx.translate(this.padding, this.padding);\r\n ctx.imageSmoothingEnabled = this.smoothing;\r\n ctx.lineWidth = this.lineWidth;\r\n ctx.setLineDash((_a = this.lineDash) !== null && _a !== void 0 ? _a : ctx.getLineDash());\r\n ctx.lineCap = this.lineCap;\r\n ctx.strokeStyle = (_b = this.strokeColor) === null || _b === void 0 ? void 0 : _b.toString();\r\n ctx.fillStyle = (_c = this.color) === null || _c === void 0 ? void 0 : _c.toString();\r\n }\r\n _drawImage(ex, x, y) {\r\n if (this._dirty) {\r\n this.rasterize();\r\n }\r\n ex.scale(1 / this.quality, 1 / this.quality);\r\n ex.drawImage(this._bitmap, x, y);\r\n }\r\n}\r\n\n;// CONCATENATED MODULE: ./Graphics/Canvas.ts\n\r\n/**\r\n * A canvas [[Graphic]] to provide an adapter between the 2D Canvas API and the [[ExcaliburGraphicsContext]].\r\n *\r\n * The [[Canvas]] works by re-rastering a draw handler to a HTMLCanvasElement for every draw which is then passed\r\n * to the [[ExcaliburGraphicsContext]] implementation as a rendered image.\r\n *\r\n * **Low performance API**\r\n */\r\nclass Canvas extends Raster {\r\n /**\r\n * Return the 2D graphics context of this canvas\r\n */\r\n get ctx() {\r\n return this._ctx;\r\n }\r\n constructor(_options) {\r\n super(_options);\r\n this._options = _options;\r\n }\r\n clone() {\r\n return new Canvas({\r\n ...this._options,\r\n ...this.cloneGraphicOptions(),\r\n ...this.cloneRasterOptions()\r\n });\r\n }\r\n execute(ctx) {\r\n var _a, _b;\r\n if ((_a = this._options) === null || _a === void 0 ? void 0 : _a.draw) {\r\n (_b = this._options) === null || _b === void 0 ? void 0 : _b.draw(ctx);\r\n }\r\n if (!this._options.cache) {\r\n this.flagDirty();\r\n }\r\n }\r\n}\r\n\n;// CONCATENATED MODULE: ./Interfaces/AudioImplementation.ts\nclass ExResponse {\r\n}\r\nExResponse.type = {\r\n any: '',\r\n blob: 'blob',\r\n json: 'json',\r\n text: 'text',\r\n document: 'document',\r\n arraybuffer: 'arraybuffer'\r\n};\r\n\n;// CONCATENATED MODULE: ./Util/StateMachine.ts\nclass StateMachine {\r\n constructor() {\r\n this.states = new Map();\r\n }\r\n get currentState() {\r\n return this._currentState;\r\n }\r\n set currentState(state) {\r\n this._currentState = state;\r\n }\r\n static create(machineDescription, data) {\r\n const machine = new StateMachine();\r\n machine.data = data;\r\n for (const stateName in machineDescription.states) {\r\n machine.states.set(stateName, {\r\n name: stateName,\r\n ...machineDescription.states[stateName]\r\n });\r\n }\r\n // validate transitions are states\r\n for (const state of machine.states.values()) {\r\n for (const transitionState of state.transitions) {\r\n if (transitionState === '*') {\r\n continue;\r\n }\r\n if (!machine.states.has(transitionState)) {\r\n throw Error(`Invalid state machine, state [${state.name}] has a transition to another state that doesn't exist [${transitionState}]`);\r\n }\r\n }\r\n }\r\n machine.currentState = machine.startState = machine.states.get(machineDescription.start);\r\n return machine;\r\n }\r\n in(state) {\r\n return this.currentState.name === state;\r\n }\r\n go(stateName, eventData) {\r\n var _a, _b;\r\n if (this.currentState.transitions.includes(stateName) || this.currentState.transitions.includes('*')) {\r\n const potentialNewState = this.states.get(stateName);\r\n if (this.currentState.onExit) {\r\n const canExit = (_a = this.currentState) === null || _a === void 0 ? void 0 : _a.onExit({ to: potentialNewState.name, data: this.data });\r\n if (canExit === false) {\r\n return false;\r\n }\r\n }\r\n if (potentialNewState === null || potentialNewState === void 0 ? void 0 : potentialNewState.onEnter) {\r\n const canEnter = potentialNewState === null || potentialNewState === void 0 ? void 0 : potentialNewState.onEnter({ from: this.currentState.name, eventData, data: this.data });\r\n if (canEnter === false) {\r\n return false;\r\n }\r\n }\r\n // console.log(`${this.currentState.name} => ${potentialNewState.name} (${eventData})`);\r\n this.currentState = potentialNewState;\r\n if ((_b = this.currentState) === null || _b === void 0 ? void 0 : _b.onState) {\r\n this.currentState.onState();\r\n }\r\n return true;\r\n }\r\n return false;\r\n }\r\n update(elapsedMs) {\r\n if (this.currentState.onUpdate) {\r\n this.currentState.onUpdate(this.data, elapsedMs);\r\n }\r\n }\r\n save(saveKey) {\r\n localStorage.setItem(saveKey, JSON.stringify({\r\n currentState: this.currentState.name,\r\n data: this.data\r\n }));\r\n }\r\n restore(saveKey) {\r\n const state = JSON.parse(localStorage.getItem(saveKey));\r\n this.currentState = this.states.get(state.currentState);\r\n this.data = state.data;\r\n }\r\n}\r\n\n;// CONCATENATED MODULE: ./Resources/Sound/WebAudioInstance.ts\n\r\n\r\n\r\n/**\r\n * Internal class representing a Web Audio AudioBufferSourceNode instance\r\n * @see https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API\r\n */\r\nclass WebAudioInstance {\r\n _createNewBufferSource() {\r\n this._instance = this._audioContext.createBufferSource();\r\n this._instance.buffer = this._src;\r\n this._instance.loop = this.loop;\r\n this._instance.playbackRate.value = this._playbackRate;\r\n this._instance.connect(this._volumeNode);\r\n this._volumeNode.connect(this._audioContext.destination);\r\n }\r\n _handleEnd() {\r\n if (!this.loop) {\r\n this._instance.onended = () => {\r\n this._playingResolve(true);\r\n };\r\n }\r\n }\r\n set loop(value) {\r\n this._loop = value;\r\n if (this._instance) {\r\n this._instance.loop = value;\r\n if (!this.loop) {\r\n this._instance.onended = () => {\r\n this._playingResolve(true);\r\n };\r\n }\r\n }\r\n }\r\n get loop() {\r\n return this._loop;\r\n }\r\n set volume(value) {\r\n value = clamp(value, 0, 1.0);\r\n this._volume = value;\r\n if (this._stateMachine.in('PLAYING') && this._volumeNode.gain.setTargetAtTime) {\r\n // https://developer.mozilla.org/en-US/docs/Web/API/AudioParam/setTargetAtTime\r\n // After each .1 seconds timestep, the target value will ~63.2% closer to the target value.\r\n // This exponential ramp provides a more pleasant transition in gain\r\n this._volumeNode.gain.setTargetAtTime(value, this._audioContext.currentTime, 0.1);\r\n }\r\n else {\r\n this._volumeNode.gain.value = value;\r\n }\r\n }\r\n get volume() {\r\n return this._volume;\r\n }\r\n /**\r\n * Returns the set duration to play, otherwise returns the total duration if unset\r\n */\r\n get duration() {\r\n var _a;\r\n return (_a = this._duration) !== null && _a !== void 0 ? _a : this.getTotalPlaybackDuration();\r\n }\r\n /**\r\n * Set the duration that this audio should play.\r\n *\r\n * Note: if you seek to a specific point the duration will start from that point, for example\r\n *\r\n * If you have a 10 second clip, seek to 5 seconds, then set the duration to 2, it will play the clip from 5-7 seconds.\r\n */\r\n set duration(duration) {\r\n this._duration = duration;\r\n }\r\n constructor(_src) {\r\n this._src = _src;\r\n this._audioContext = AudioContextFactory.create();\r\n this._volumeNode = this._audioContext.createGain();\r\n this._playingPromise = new Promise((resolve) => {\r\n this._playingResolve = resolve;\r\n });\r\n this._stateMachine = StateMachine.create({\r\n start: 'STOPPED',\r\n states: {\r\n PLAYING: {\r\n onEnter: ({ data }) => {\r\n // Buffer nodes are single use\r\n this._createNewBufferSource();\r\n this._handleEnd();\r\n if (this.loop) {\r\n // when looping don't set a duration\r\n this._instance.start(0, data.pausedAt * this._playbackRate);\r\n }\r\n else {\r\n this._instance.start(0, data.pausedAt * this._playbackRate, this.duration);\r\n }\r\n data.startedAt = (this._audioContext.currentTime - data.pausedAt);\r\n data.pausedAt = 0;\r\n },\r\n onState: () => this._playStarted(),\r\n onExit: ({ to }) => {\r\n // If you've exited early only resolve if explicitly STOPPED\r\n if (to === 'STOPPED') {\r\n this._playingResolve(true);\r\n }\r\n // Whenever you're not playing... you stop!\r\n this._instance.onended = null; // disconnect the wired on-end handler\r\n this._instance.disconnect();\r\n this._instance.stop(0);\r\n this._instance = null;\r\n },\r\n transitions: ['STOPPED', 'PAUSED', 'SEEK']\r\n },\r\n SEEK: {\r\n onEnter: ({ eventData: position, data }) => {\r\n data.pausedAt = (position !== null && position !== void 0 ? position : 0) / this._playbackRate;\r\n data.startedAt = 0;\r\n },\r\n transitions: ['*']\r\n },\r\n STOPPED: {\r\n onEnter: ({ data }) => {\r\n data.pausedAt = 0;\r\n data.startedAt = 0;\r\n this._playingResolve(true);\r\n },\r\n transitions: ['PLAYING', 'PAUSED', 'SEEK']\r\n },\r\n PAUSED: {\r\n onEnter: ({ data }) => {\r\n // Playback rate will be a scale factor of how fast/slow the audio is being played\r\n // default is 1.0\r\n // we need to invert it to get the time scale\r\n data.pausedAt = (this._audioContext.currentTime - data.startedAt);\r\n },\r\n transitions: ['PLAYING', 'STOPPED', 'SEEK']\r\n }\r\n }\r\n }, {\r\n startedAt: 0,\r\n pausedAt: 0\r\n });\r\n this._volume = 1;\r\n this._loop = false;\r\n // eslint-disable-next-line @typescript-eslint/no-empty-function\r\n this._playStarted = () => { };\r\n this._playbackRate = 1.0;\r\n this._createNewBufferSource();\r\n }\r\n isPlaying() {\r\n return this._stateMachine.in('PLAYING');\r\n }\r\n isPaused() {\r\n return this._stateMachine.in('PAUSED') || this._stateMachine.in('SEEK');\r\n }\r\n // eslint-disable-next-line @typescript-eslint/no-empty-function\r\n play(playStarted = () => { }) {\r\n this._playStarted = playStarted;\r\n this._stateMachine.go('PLAYING');\r\n return this._playingPromise;\r\n }\r\n pause() {\r\n this._stateMachine.go('PAUSED');\r\n }\r\n stop() {\r\n this._stateMachine.go('STOPPED');\r\n }\r\n seek(position) {\r\n this._stateMachine.go('PAUSED');\r\n this._stateMachine.go('SEEK', position);\r\n }\r\n getTotalPlaybackDuration() {\r\n return this._src.duration;\r\n }\r\n getPlaybackPosition() {\r\n const { pausedAt, startedAt } = this._stateMachine.data;\r\n if (pausedAt) {\r\n return pausedAt * this._playbackRate;\r\n }\r\n if (startedAt) {\r\n return (this._audioContext.currentTime - startedAt) * this._playbackRate;\r\n }\r\n return 0;\r\n }\r\n set playbackRate(playbackRate) {\r\n this._instance.playbackRate.value = this._playbackRate = playbackRate;\r\n }\r\n get playbackRate() {\r\n return this._instance.playbackRate.value;\r\n }\r\n}\r\n\n;// CONCATENATED MODULE: ./Events/MediaEvents.ts\n\r\nclass MediaEvent extends GameEvent {\r\n /**\r\n * Media event cannot bubble\r\n */\r\n set bubbles(_value) {\r\n // stubbed\r\n }\r\n /**\r\n * Media event cannot bubble\r\n */\r\n get bubbles() {\r\n return false;\r\n }\r\n /**\r\n * Media event cannot bubble, so they have no path\r\n */\r\n get _path() {\r\n return null;\r\n }\r\n /**\r\n * Media event cannot bubble, so they have no path\r\n */\r\n set _path(_val) {\r\n // stubbed\r\n }\r\n constructor(target, _name = 'MediaEvent') {\r\n super();\r\n this.target = target;\r\n this._name = _name;\r\n }\r\n /**\r\n * Prevents event from bubbling\r\n */\r\n stopPropagation() {\r\n /**\r\n * Stub\r\n */\r\n }\r\n /**\r\n * Action, that calls when event happens\r\n */\r\n action() {\r\n /**\r\n * Stub\r\n */\r\n }\r\n /**\r\n * Propagate event further through event path\r\n */\r\n propagate() {\r\n /**\r\n * Stub\r\n */\r\n }\r\n layPath(_actor) {\r\n /**\r\n * Stub\r\n */\r\n }\r\n}\r\nclass NativeSoundEvent extends MediaEvent {\r\n constructor(target, track) {\r\n super(target, 'NativeSoundEvent');\r\n this.track = track;\r\n }\r\n}\r\nclass NativeSoundProcessedEvent extends MediaEvent {\r\n constructor(target, _processedData) {\r\n super(target, 'NativeSoundProcessedEvent');\r\n this._processedData = _processedData;\r\n this.data = this._processedData;\r\n }\r\n}\r\n\n;// CONCATENATED MODULE: ./Util/Sound.ts\n\r\n/**\r\n * Whether or not the browser can play this file as HTML5 Audio\r\n */\r\nfunction canPlayFile(file) {\r\n try {\r\n const a = new Audio();\r\n const filetype = /.*\\.([A-Za-z0-9]+)(?:(?:\\?|\\#).*)*$/;\r\n const type = file.match(filetype)[1];\r\n if (a.canPlayType('audio/' + type)) {\r\n return true;\r\n }\r\n else {\r\n return false;\r\n }\r\n }\r\n catch (e) {\r\n Logger.getInstance().warn('Cannot determine audio support, assuming no support for the Audio Tag', e);\r\n return false;\r\n }\r\n}\r\n\n;// CONCATENATED MODULE: ./Resources/Sound/Sound.ts\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\nconst SoundEvents = {\r\n VolumeChange: 'volumechange',\r\n Processed: 'processed',\r\n Pause: 'pause',\r\n Stop: 'stop',\r\n PlaybackEnd: 'playbackend',\r\n Resume: 'resume',\r\n PlaybackStart: 'playbackstart'\r\n};\r\n/**\r\n * The [[Sound]] object allows games built in Excalibur to load audio\r\n * components, from soundtracks to sound effects. [[Sound]] is an [[Loadable]]\r\n * which means it can be passed to a [[Loader]] to pre-load before a game or level.\r\n */\r\nclass Sound {\r\n /**\r\n * Indicates whether the clip should loop when complete\r\n * @param value Set the looping flag\r\n */\r\n set loop(value) {\r\n this._loop = value;\r\n for (const track of this._tracks) {\r\n track.loop = this._loop;\r\n }\r\n this.logger.debug('Set loop for all instances of sound', this.path, 'to', this._loop);\r\n }\r\n get loop() {\r\n return this._loop;\r\n }\r\n set volume(value) {\r\n this._volume = value;\r\n for (const track of this._tracks) {\r\n track.volume = this._volume;\r\n }\r\n this.events.emit('volumechange', new NativeSoundEvent(this));\r\n this.logger.debug('Set loop for all instances of sound', this.path, 'to', this._volume);\r\n }\r\n get volume() {\r\n return this._volume;\r\n }\r\n /**\r\n * Get the duration that this audio should play. If unset the total natural playback duration will be used.\r\n */\r\n get duration() {\r\n return this._duration;\r\n }\r\n /**\r\n * Set the duration that this audio should play. If unset the total natural playback duration will be used.\r\n *\r\n * Note: if you seek to a specific point the duration will start from that point, for example\r\n *\r\n * If you have a 10 second clip, seek to 5 seconds, then set the duration to 2, it will play the clip from 5-7 seconds.\r\n */\r\n set duration(duration) {\r\n this._duration = duration;\r\n }\r\n /**\r\n * Return array of Current AudioInstances playing or being paused\r\n */\r\n get instances() {\r\n return this._tracks;\r\n }\r\n get path() {\r\n return this._resource.path;\r\n }\r\n set path(val) {\r\n this._resource.path = val;\r\n }\r\n /**\r\n * Should excalibur add a cache busting querystring? By default false.\r\n * Must be set before loading\r\n */\r\n get bustCache() {\r\n return this._resource.bustCache;\r\n }\r\n set bustCache(val) {\r\n this._resource.bustCache = val;\r\n }\r\n /**\r\n * @param paths A list of audio sources (clip.wav, clip.mp3, clip.ogg) for this audio clip. This is done for browser compatibility.\r\n */\r\n constructor(...paths) {\r\n this.events = new EventEmitter();\r\n this.logger = Logger.getInstance();\r\n this._loop = false;\r\n this._volume = 1;\r\n this._isStopped = false;\r\n // private _isPaused = false;\r\n this._tracks = [];\r\n this._wasPlayingOnHidden = false;\r\n this._playbackRate = 1.0;\r\n this._audioContext = AudioContextFactory.create();\r\n this._resource = new Resource('', ExResponse.type.arraybuffer);\r\n /**\r\n * Chrome : MP3, WAV, Ogg\r\n * Firefox : WAV, Ogg,\r\n * IE : MP3, WAV coming soon\r\n * Safari MP3, WAV, Ogg\r\n */\r\n for (const path of paths) {\r\n if (canPlayFile(path)) {\r\n this.path = path;\r\n break;\r\n }\r\n }\r\n if (!this.path) {\r\n this.logger.warn('This browser does not support any of the audio files specified:', paths.join(', '));\r\n this.logger.warn('Attempting to use', paths[0]);\r\n this.path = paths[0]; // select the first specified\r\n }\r\n }\r\n isLoaded() {\r\n return !!this.data;\r\n }\r\n async load() {\r\n var _a, _b;\r\n if (this.data) {\r\n return this.data;\r\n }\r\n const arraybuffer = await this._resource.load();\r\n const audiobuffer = await this.decodeAudio(arraybuffer.slice(0));\r\n this._duration = (_b = (_a = this._duration) !== null && _a !== void 0 ? _a : audiobuffer === null || audiobuffer === void 0 ? void 0 : audiobuffer.duration) !== null && _b !== void 0 ? _b : undefined;\r\n this.events.emit('processed', new NativeSoundProcessedEvent(this, audiobuffer));\r\n return this.data = audiobuffer;\r\n }\r\n async decodeAudio(data) {\r\n try {\r\n return await this._audioContext.decodeAudioData(data.slice(0));\r\n }\r\n catch (e) {\r\n this.logger.error('Unable to decode ' +\r\n ' this browser may not fully support this format, or the file may be corrupt, ' +\r\n 'if this is an mp3 try removing id3 tags and album art from the file.');\r\n return await Promise.reject();\r\n }\r\n }\r\n wireEngine(engine) {\r\n if (engine) {\r\n this._engine = engine;\r\n this._engine.on('hidden', () => {\r\n if (engine.pauseAudioWhenHidden && this.isPlaying()) {\r\n this._wasPlayingOnHidden = true;\r\n this.pause();\r\n }\r\n });\r\n this._engine.on('visible', () => {\r\n if (engine.pauseAudioWhenHidden && this._wasPlayingOnHidden) {\r\n this.play();\r\n this._wasPlayingOnHidden = false;\r\n }\r\n });\r\n this._engine.on('start', () => {\r\n this._isStopped = false;\r\n });\r\n this._engine.on('stop', () => {\r\n this.stop();\r\n this._isStopped = true;\r\n });\r\n }\r\n }\r\n /**\r\n * Returns how many instances of the sound are currently playing\r\n */\r\n instanceCount() {\r\n return this._tracks.length;\r\n }\r\n /**\r\n * Whether or not the sound is playing right now\r\n */\r\n isPlaying() {\r\n return this._tracks.some((t) => t.isPlaying());\r\n }\r\n isPaused() {\r\n return this._tracks.some(t => t.isPaused());\r\n }\r\n /**\r\n * Play the sound, returns a promise that resolves when the sound is done playing\r\n * An optional volume argument can be passed in to play the sound. Max volume is 1.0\r\n */\r\n play(volume) {\r\n if (!this.isLoaded()) {\r\n this.logger.warn('Cannot start playing. Resource', this.path, 'is not loaded yet');\r\n return Promise.resolve(true);\r\n }\r\n if (this._isStopped) {\r\n this.logger.warn('Cannot start playing. Engine is in a stopped state.');\r\n return Promise.resolve(false);\r\n }\r\n this.volume = volume || this.volume;\r\n if (this.isPaused()) {\r\n return this._resumePlayback();\r\n }\r\n else {\r\n return this._startPlayback();\r\n }\r\n }\r\n /**\r\n * Stop the sound, and do not rewind\r\n */\r\n pause() {\r\n if (!this.isPlaying()) {\r\n return;\r\n }\r\n for (const track of this._tracks) {\r\n track.pause();\r\n }\r\n this.events.emit('pause', new NativeSoundEvent(this));\r\n this.logger.debug('Paused all instances of sound', this.path);\r\n }\r\n /**\r\n * Stop the sound if it is currently playing and rewind the track. If the sound is not playing, rewinds the track.\r\n */\r\n stop() {\r\n for (const track of this._tracks) {\r\n track.stop();\r\n }\r\n this.events.emit('stop', new NativeSoundEvent(this));\r\n this._tracks.length = 0;\r\n this.logger.debug('Stopped all instances of sound', this.path);\r\n }\r\n get playbackRate() {\r\n return this._playbackRate;\r\n }\r\n set playbackRate(playbackRate) {\r\n this._playbackRate = playbackRate;\r\n this._tracks.forEach(t => {\r\n t.playbackRate = this._playbackRate;\r\n });\r\n }\r\n seek(position, trackId = 0) {\r\n if (this._tracks.length === 0) {\r\n this._getTrackInstance(this.data);\r\n }\r\n this._tracks[trackId].seek(position);\r\n }\r\n getTotalPlaybackDuration() {\r\n return this.data.duration;\r\n }\r\n /**\r\n * Return the current playback time of the playing track in seconds from the start.\r\n *\r\n * Optionally specify the track to query if multiple are playing at once.\r\n * @param trackId\r\n */\r\n getPlaybackPosition(trackId = 0) {\r\n if (this._tracks.length) {\r\n return this._tracks[trackId].getPlaybackPosition();\r\n }\r\n return 0;\r\n }\r\n /**\r\n * Get Id of provided AudioInstance in current trackList\r\n * @param track [[Audio]] which Id is to be given\r\n */\r\n getTrackId(track) {\r\n return this._tracks.indexOf(track);\r\n }\r\n async _resumePlayback() {\r\n if (this.isPaused) {\r\n const resumed = [];\r\n // ensure we resume *current* tracks (if paused)\r\n for (const track of this._tracks) {\r\n resumed.push(track.play().then(() => {\r\n this.events.emit('playbackend', new NativeSoundEvent(this, track));\r\n this._tracks.splice(this.getTrackId(track), 1);\r\n return true;\r\n }));\r\n }\r\n this.events.emit('resume', new NativeSoundEvent(this));\r\n this.logger.debug('Resuming paused instances for sound', this.path, this._tracks);\r\n // resolve when resumed tracks are done\r\n await Promise.all(resumed);\r\n }\r\n return true;\r\n }\r\n /**\r\n * Starts playback, returns a promise that resolves when playback is complete\r\n */\r\n async _startPlayback() {\r\n const track = await this._getTrackInstance(this.data);\r\n const complete = await track.play(() => {\r\n this.events.emit('playbackstart', new NativeSoundEvent(this, track));\r\n this.logger.debug('Playing new instance for sound', this.path);\r\n });\r\n // when done, remove track\r\n this.events.emit('playbackend', new NativeSoundEvent(this, track));\r\n this._tracks.splice(this.getTrackId(track), 1);\r\n return complete;\r\n }\r\n _getTrackInstance(data) {\r\n const newTrack = new WebAudioInstance(data);\r\n newTrack.loop = this.loop;\r\n newTrack.volume = this.volume;\r\n newTrack.duration = this.duration;\r\n newTrack.playbackRate = this._playbackRate;\r\n this._tracks.push(newTrack);\r\n return newTrack;\r\n }\r\n emit(eventName, event) {\r\n this.events.emit(eventName, event);\r\n }\r\n on(eventName, handler) {\r\n return this.events.on(eventName, handler);\r\n }\r\n once(eventName, handler) {\r\n return this.events.once(eventName, handler);\r\n }\r\n off(eventName, handler) {\r\n this.events.off(eventName, handler);\r\n }\r\n}\r\n\n;// CONCATENATED MODULE: ./Loader.ts\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\nconst LoaderEvents = {\r\n// Add event types here\r\n};\r\n/**\r\n * Pre-loading assets\r\n *\r\n * The loader provides a mechanism to preload multiple resources at\r\n * one time. The loader must be passed to the engine in order to\r\n * trigger the loading progress bar.\r\n *\r\n * The [[Loader]] itself implements [[Loadable]] so you can load loaders.\r\n *\r\n * ## Example: Pre-loading resources for a game\r\n *\r\n * ```js\r\n * // create a loader\r\n * var loader = new ex.Loader();\r\n *\r\n * // create a resource dictionary (best practice is to keep a separate file)\r\n * var resources = {\r\n * TextureGround: new ex.Texture(\"/images/textures/ground.png\"),\r\n * SoundDeath: new ex.Sound(\"/sound/death.wav\", \"/sound/death.mp3\")\r\n * };\r\n *\r\n * // loop through dictionary and add to loader\r\n * for (var loadable in resources) {\r\n * if (resources.hasOwnProperty(loadable)) {\r\n * loader.addResource(resources[loadable]);\r\n * }\r\n * }\r\n *\r\n * // start game\r\n * game.start(loader).then(function () {\r\n * console.log(\"Game started!\");\r\n * });\r\n * ```\r\n *\r\n * ## Customize the Loader\r\n *\r\n * The loader can be customized to show different, text, logo, background color, and button.\r\n *\r\n * ```typescript\r\n * const loader = new ex.Loader([playerTexture]);\r\n *\r\n * // The loaders button text can simply modified using this\r\n * loader.playButtonText = 'Start the best game ever';\r\n *\r\n * // The logo can be changed by inserting a base64 image string here\r\n *\r\n * loader.logo = 'data:image/png;base64,iVBORw...';\r\n * loader.logoWidth = 15;\r\n * loader.logoHeight = 14;\r\n *\r\n * // The background color can be changed like so by supplying a valid CSS color string\r\n *\r\n * loader.backgroundColor = 'red'\r\n * loader.backgroundColor = '#176BAA'\r\n *\r\n * // To build a completely new button\r\n * loader.startButtonFactory = () => {\r\n * let myButton = document.createElement('button');\r\n * myButton.textContent = 'The best button';\r\n * return myButton;\r\n * };\r\n *\r\n * engine.start(loader).then(() => {});\r\n * ```\r\n */\r\nclass Loader {\r\n get _image() {\r\n if (!this._imageElement) {\r\n this._imageElement = new Image();\r\n this._imageElement.src = this.logo;\r\n }\r\n return this._imageElement;\r\n }\r\n get playButtonRootElement() {\r\n return this._playButtonRootElement;\r\n }\r\n get playButtonElement() {\r\n return this._playButtonElement;\r\n }\r\n get _playButton() {\r\n const existingRoot = document.getElementById('excalibur-play-root');\r\n if (existingRoot) {\r\n this._playButtonRootElement = existingRoot;\r\n }\r\n if (!this._playButtonRootElement) {\r\n this._playButtonRootElement = document.createElement('div');\r\n this._playButtonRootElement.id = 'excalibur-play-root';\r\n this._playButtonRootElement.style.position = 'absolute';\r\n document.body.appendChild(this._playButtonRootElement);\r\n }\r\n if (!this._styleBlock) {\r\n this._styleBlock = document.createElement('style');\r\n this._styleBlock.textContent = this._playButtonStyles;\r\n document.head.appendChild(this._styleBlock);\r\n }\r\n if (!this._playButtonElement) {\r\n this._playButtonElement = this.startButtonFactory();\r\n this._playButtonRootElement.appendChild(this._playButtonElement);\r\n }\r\n return this._playButtonElement;\r\n }\r\n /**\r\n * @param loadables Optionally provide the list of resources you want to load at constructor time\r\n */\r\n constructor(loadables) {\r\n this.events = new EventEmitter();\r\n this.canvas = new Canvas({\r\n filtering: ImageFiltering.Blended,\r\n smoothing: true,\r\n cache: true,\r\n draw: this.draw.bind(this)\r\n });\r\n this._resourceList = [];\r\n this._index = 0;\r\n this._playButtonShown = false;\r\n this._resourceCount = 0;\r\n this._numLoaded = 0;\r\n this._progressCounts = {};\r\n this._totalCounts = {};\r\n // logo drawing stuff\r\n // base64 string encoding of the excalibur logo (logo-white.png)\r\n this.logo = Loader_logo;\r\n this.logoWidth = 468;\r\n this.logoHeight = 118;\r\n /**\r\n * Gets or sets the color of the loading bar, default is [[Color.White]]\r\n */\r\n this.loadingBarColor = Color.White;\r\n /**\r\n * Gets or sets the background color of the loader as a hex string\r\n */\r\n this.backgroundColor = '#176BAA';\r\n this.suppressPlayButton = false;\r\n /** Loads the css from Loader.css */\r\n this._playButtonStyles = Loader_0/* default */.Z.toString();\r\n /**\r\n * Get/set play button text\r\n */\r\n this.playButtonText = 'Play game';\r\n /**\r\n * Return a html button element for excalibur to use as a play button\r\n */\r\n this.startButtonFactory = () => {\r\n let buttonElement = document.getElementById('excalibur-play');\r\n if (!buttonElement) {\r\n buttonElement = document.createElement('button');\r\n }\r\n buttonElement.id = 'excalibur-play';\r\n buttonElement.textContent = this.playButtonText;\r\n buttonElement.style.display = 'none';\r\n return buttonElement;\r\n };\r\n this._loadingFuture = new Future();\r\n if (loadables) {\r\n this.addResources(loadables);\r\n }\r\n }\r\n wireEngine(engine) {\r\n this._engine = engine;\r\n this.canvas.width = this._engine.canvas.width;\r\n this.canvas.height = this._engine.canvas.height;\r\n }\r\n /**\r\n * Add a resource to the loader to load\r\n * @param loadable Resource to add\r\n */\r\n addResource(loadable) {\r\n const key = this._index++;\r\n this._resourceList.push(loadable);\r\n this._progressCounts[key] = 0;\r\n this._totalCounts[key] = 1;\r\n this._resourceCount++;\r\n }\r\n /**\r\n * Add a list of resources to the loader to load\r\n * @param loadables The list of resources to load\r\n */\r\n addResources(loadables) {\r\n let i = 0;\r\n const len = loadables.length;\r\n for (i; i < len; i++) {\r\n this.addResource(loadables[i]);\r\n }\r\n }\r\n /**\r\n * Returns true if the loader has completely loaded all resources\r\n */\r\n isLoaded() {\r\n return this._numLoaded === this._resourceCount;\r\n }\r\n /**\r\n * Shows the play button and returns a promise that resolves when clicked\r\n */\r\n async showPlayButton() {\r\n var _a, _b;\r\n if (this.suppressPlayButton) {\r\n this.hidePlayButton();\r\n // Delay is to give the logo a chance to show, otherwise don't delay\r\n await delay(500, (_a = this._engine) === null || _a === void 0 ? void 0 : _a.clock);\r\n }\r\n else {\r\n const resizeHandler = () => {\r\n this._positionPlayButton();\r\n };\r\n if ((_b = this._engine) === null || _b === void 0 ? void 0 : _b.browser) {\r\n this._engine.browser.window.on('resize', resizeHandler);\r\n }\r\n this._playButtonShown = true;\r\n this._playButton.style.display = 'block';\r\n document.body.addEventListener('keyup', (evt) => {\r\n if (evt.key === 'Enter') {\r\n this._playButton.click();\r\n }\r\n });\r\n this._positionPlayButton();\r\n const playButtonClicked = new Promise((resolve) => {\r\n const startButtonHandler = (e) => {\r\n var _a;\r\n // We want to stop propagation to keep bubbling to the engine pointer handlers\r\n e.stopPropagation();\r\n // Hide Button after click\r\n this.hidePlayButton();\r\n if ((_a = this._engine) === null || _a === void 0 ? void 0 : _a.browser) {\r\n this._engine.browser.window.off('resize', resizeHandler);\r\n }\r\n resolve();\r\n };\r\n this._playButton.addEventListener('click', startButtonHandler);\r\n this._playButton.addEventListener('touchend', startButtonHandler);\r\n this._playButton.addEventListener('pointerup', startButtonHandler);\r\n });\r\n return await playButtonClicked;\r\n }\r\n }\r\n hidePlayButton() {\r\n this._playButtonShown = false;\r\n this._playButton.style.display = 'none';\r\n }\r\n /**\r\n * Clean up generated elements for the loader\r\n */\r\n dispose() {\r\n if (this._playButtonRootElement.parentElement) {\r\n this._playButtonRootElement.removeChild(this._playButtonElement);\r\n document.body.removeChild(this._playButtonRootElement);\r\n document.head.removeChild(this._styleBlock);\r\n this._playButtonRootElement = null;\r\n this._playButtonElement = null;\r\n this._styleBlock = null;\r\n }\r\n }\r\n update(_engine, _delta) {\r\n // override me\r\n }\r\n areResourcesLoaded() {\r\n return this._loadingFuture.promise;\r\n }\r\n /**\r\n * Begin loading all of the supplied resources, returning a promise\r\n * that resolves when loading of all is complete AND the user has clicked the \"Play button\"\r\n */\r\n async load() {\r\n var _a, _b;\r\n await ((_a = this._image) === null || _a === void 0 ? void 0 : _a.decode()); // decode logo if it exists\r\n this.canvas.flagDirty();\r\n await Promise.all(this._resourceList.map(async (r) => {\r\n await r.load().finally(() => {\r\n // capture progress\r\n this._numLoaded++;\r\n this.canvas.flagDirty();\r\n });\r\n }));\r\n // Wire all sound to the engine\r\n for (const resource of this._resourceList) {\r\n if (resource instanceof Sound) {\r\n resource.wireEngine(this._engine);\r\n }\r\n }\r\n this._loadingFuture.resolve();\r\n // short delay in showing the button for aesthetics\r\n await delay(200, (_b = this._engine) === null || _b === void 0 ? void 0 : _b.clock);\r\n this.canvas.flagDirty();\r\n await this.showPlayButton();\r\n // Unlock browser AudioContext in after user gesture\r\n // See: https://github.com/excaliburjs/Excalibur/issues/262\r\n // See: https://github.com/excaliburjs/Excalibur/issues/1031\r\n await WebAudio.unlock();\r\n return (this.data = this._resourceList);\r\n }\r\n markResourceComplete() {\r\n this._numLoaded++;\r\n }\r\n /**\r\n * Returns the progress of the loader as a number between [0, 1] inclusive.\r\n */\r\n get progress() {\r\n return this._resourceCount > 0 ? clamp(this._numLoaded, 0, this._resourceCount) / this._resourceCount : 1;\r\n }\r\n _positionPlayButton() {\r\n if (this._engine) {\r\n const screenHeight = this._engine.screen.viewport.height;\r\n const screenWidth = this._engine.screen.viewport.width;\r\n if (this._playButtonRootElement) {\r\n const left = this._engine.canvas.offsetLeft;\r\n const top = this._engine.canvas.offsetTop;\r\n const buttonWidth = this._playButton.clientWidth;\r\n const buttonHeight = this._playButton.clientHeight;\r\n if (this.playButtonPosition) {\r\n this._playButtonRootElement.style.left = `${this.playButtonPosition.x}px`;\r\n this._playButtonRootElement.style.top = `${this.playButtonPosition.y}px`;\r\n }\r\n else {\r\n this._playButtonRootElement.style.left = `${left + screenWidth / 2 - buttonWidth / 2}px`;\r\n this._playButtonRootElement.style.top = `${top + screenHeight / 2 - buttonHeight / 2 + 100}px`;\r\n }\r\n }\r\n }\r\n }\r\n /**\r\n * Loader draw function. Draws the default Excalibur loading screen.\r\n * Override `logo`, `logoWidth`, `logoHeight` and `backgroundColor` properties\r\n * to customize the drawing, or just override entire method.\r\n */\r\n draw(ctx) {\r\n const canvasHeight = this._engine.canvasHeight / this._engine.pixelRatio;\r\n const canvasWidth = this._engine.canvasWidth / this._engine.pixelRatio;\r\n this._positionPlayButton();\r\n ctx.fillStyle = this.backgroundColor;\r\n ctx.fillRect(0, 0, canvasWidth, canvasHeight);\r\n let logoY = canvasHeight / 2;\r\n const width = Math.min(this.logoWidth, canvasWidth * 0.75);\r\n let logoX = canvasWidth / 2 - width / 2;\r\n if (this.logoPosition) {\r\n logoX = this.logoPosition.x;\r\n logoY = this.logoPosition.y;\r\n }\r\n const imageHeight = Math.floor(width * (this.logoHeight / this.logoWidth)); // OG height/width factor\r\n const oldAntialias = this._engine.getAntialiasing();\r\n this._engine.setAntialiasing(true);\r\n if (!this.logoPosition) {\r\n ctx.drawImage(this._image, 0, 0, this.logoWidth, this.logoHeight, logoX, logoY - imageHeight - 20, width, imageHeight);\r\n }\r\n else {\r\n ctx.drawImage(this._image, 0, 0, this.logoWidth, this.logoHeight, logoX, logoY, width, imageHeight);\r\n }\r\n // loading box\r\n if (!this.suppressPlayButton && this._playButtonShown) {\r\n this._engine.setAntialiasing(oldAntialias);\r\n return;\r\n }\r\n let loadingX = logoX;\r\n let loadingY = logoY;\r\n if (this.loadingBarPosition) {\r\n loadingX = this.loadingBarPosition.x;\r\n loadingY = this.loadingBarPosition.y;\r\n }\r\n ctx.lineWidth = 2;\r\n roundRect(ctx, loadingX, loadingY, width, 20, 10, this.loadingBarColor);\r\n const progress = width * this.progress;\r\n const margin = 5;\r\n const progressWidth = progress - margin * 2;\r\n const height = 20 - margin * 2;\r\n roundRect(ctx, loadingX + margin, loadingY + margin, progressWidth > 10 ? progressWidth : 10, height, 5, null, this.loadingBarColor);\r\n this._engine.setAntialiasing(oldAntialias);\r\n }\r\n emit(eventName, event) {\r\n this.events.emit(eventName, event);\r\n }\r\n on(eventName, handler) {\r\n return this.events.on(eventName, handler);\r\n }\r\n once(eventName, handler) {\r\n return this.events.once(eventName, handler);\r\n }\r\n off(eventName, handler) {\r\n this.events.off(eventName, handler);\r\n }\r\n}\r\n\n;// CONCATENATED MODULE: ./Util/Detector.ts\n\r\n/**\r\n * This is the list of features that will be used to log the supported\r\n * features to the console when Detector.logBrowserFeatures() is called.\r\n */\r\nconst REPORTED_FEATURES = {\r\n webgl: 'WebGL',\r\n webaudio: 'WebAudio',\r\n gamepadapi: 'Gamepad API'\r\n};\r\n/**\r\n * Excalibur internal feature detection helper class\r\n */\r\nclass Detector {\r\n constructor() {\r\n this._features = null;\r\n this.failedTests = [];\r\n // critical browser features required for ex to run\r\n this._criticalTests = {\r\n // Test canvas/2d context support\r\n canvasSupport: function () {\r\n const elem = document.createElement('canvas');\r\n return !!(elem.getContext && elem.getContext('2d'));\r\n },\r\n // Test array buffer support ex uses for downloading binary data\r\n arrayBufferSupport: function () {\r\n const xhr = new XMLHttpRequest();\r\n xhr.open('GET', '/');\r\n try {\r\n xhr.responseType = 'arraybuffer';\r\n }\r\n catch (e) {\r\n return false;\r\n }\r\n return xhr.responseType === 'arraybuffer';\r\n },\r\n // Test data urls ex uses for sprites\r\n dataUrlSupport: function () {\r\n const canvas = document.createElement('canvas');\r\n return canvas.toDataURL('image/png').indexOf('data:image/png') === 0;\r\n },\r\n // Test object url support for loading\r\n objectUrlSupport: function () {\r\n return 'URL' in window && 'revokeObjectURL' in URL && 'createObjectURL' in URL;\r\n },\r\n // RGBA support for colors\r\n rgbaSupport: function () {\r\n const style = document.createElement('a').style;\r\n style.cssText = 'background-color:rgba(150,255,150,.5)';\r\n return ('' + style.backgroundColor).indexOf('rgba') > -1;\r\n }\r\n };\r\n // warnings excalibur performance will be degraded\r\n this._warningTest = {\r\n webAudioSupport: function () {\r\n return !!(window.AudioContext ||\r\n window.webkitAudioContext ||\r\n window.mozAudioContext ||\r\n window.msAudioContext ||\r\n window.oAudioContext);\r\n },\r\n webglSupport: function () {\r\n const elem = document.createElement('canvas');\r\n return !!(elem.getContext && elem.getContext('webgl'));\r\n }\r\n };\r\n this._features = this._loadBrowserFeatures();\r\n }\r\n /**\r\n * Returns a map of currently supported browser features. This method\r\n * treats the features as a singleton and will only calculate feature\r\n * support if it has not previously been done.\r\n */\r\n getBrowserFeatures() {\r\n if (this._features === null) {\r\n this._features = this._loadBrowserFeatures();\r\n }\r\n return this._features;\r\n }\r\n /**\r\n * Report on non-critical browser support for debugging purposes.\r\n * Use native browser console colors for visibility.\r\n */\r\n logBrowserFeatures() {\r\n let msg = '%cSUPPORTED BROWSER FEATURES\\n==========================%c\\n';\r\n const args = ['font-weight: bold; color: navy', 'font-weight: normal; color: inherit'];\r\n const supported = this.getBrowserFeatures();\r\n for (const feature of Object.keys(REPORTED_FEATURES)) {\r\n if (supported[feature]) {\r\n msg += '(%c\\u2713%c)'; // (✓)\r\n args.push('font-weight: bold; color: green');\r\n args.push('font-weight: normal; color: inherit');\r\n }\r\n else {\r\n msg += '(%c\\u2717%c)'; // (✗)\r\n args.push('font-weight: bold; color: red');\r\n args.push('font-weight: normal; color: inherit');\r\n }\r\n msg += ' ' + REPORTED_FEATURES[feature] + '\\n';\r\n }\r\n args.unshift(msg);\r\n // eslint-disable-next-line no-console\r\n console.log.apply(console, args);\r\n }\r\n /**\r\n * Executes several IIFE's to get a constant reference to supported\r\n * features within the current execution context.\r\n */\r\n _loadBrowserFeatures() {\r\n return {\r\n // IIFE to check canvas support\r\n canvas: (() => {\r\n return this._criticalTests.canvasSupport();\r\n })(),\r\n // IIFE to check arraybuffer support\r\n arraybuffer: (() => {\r\n return this._criticalTests.arrayBufferSupport();\r\n })(),\r\n // IIFE to check dataurl support\r\n dataurl: (() => {\r\n return this._criticalTests.dataUrlSupport();\r\n })(),\r\n // IIFE to check objecturl support\r\n objecturl: (() => {\r\n return this._criticalTests.objectUrlSupport();\r\n })(),\r\n // IIFE to check rgba support\r\n rgba: (() => {\r\n return this._criticalTests.rgbaSupport();\r\n })(),\r\n // IIFE to check webaudio support\r\n webaudio: (() => {\r\n return this._warningTest.webAudioSupport();\r\n })(),\r\n // IIFE to check webgl support\r\n webgl: (() => {\r\n return this._warningTest.webglSupport();\r\n })(),\r\n // IIFE to check gamepadapi support\r\n gamepadapi: (() => {\r\n return !!navigator.getGamepads;\r\n })()\r\n };\r\n }\r\n test() {\r\n // Critical test will for ex not to run\r\n let failedCritical = false;\r\n for (const test in this._criticalTests) {\r\n if (!this._criticalTests[test].call(this)) {\r\n this.failedTests.push(test);\r\n Logger.getInstance().error('Critical browser feature missing, Excalibur requires:', test);\r\n failedCritical = true;\r\n }\r\n }\r\n if (failedCritical) {\r\n return false;\r\n }\r\n // Warning tests do not for ex to return false to compatibility\r\n for (const warning in this._warningTest) {\r\n if (!this._warningTest[warning]()) {\r\n Logger.getInstance().warn('Warning browser feature missing, Excalibur will have reduced performance:', warning);\r\n }\r\n }\r\n return true;\r\n }\r\n}\r\n\n;// CONCATENATED MODULE: ./Collision/CollisionType.ts\n/**\r\n * An enum that describes the types of collisions bodies can participate in\r\n */\r\nvar CollisionType;\r\n(function (CollisionType) {\r\n /**\r\n * Bodies with the `PreventCollision` setting do not participate in any\r\n * collisions and do not raise collision events.\r\n */\r\n CollisionType[\"PreventCollision\"] = \"PreventCollision\";\r\n /**\r\n * Bodies with the `Passive` setting only raise collision events, but are not\r\n * influenced or moved by other bodies and do not influence or move other bodies.\r\n * This is useful for use in trigger type behavior.\r\n */\r\n CollisionType[\"Passive\"] = \"Passive\";\r\n /**\r\n * Bodies with the `Active` setting raise collision events and participate\r\n * in collisions with other bodies and will be push or moved by bodies sharing\r\n * the `Active` or `Fixed` setting.\r\n */\r\n CollisionType[\"Active\"] = \"Active\";\r\n /**\r\n * Bodies with the `Fixed` setting raise collision events and participate in\r\n * collisions with other bodies. Actors with the `Fixed` setting will not be\r\n * pushed or moved by other bodies sharing the `Fixed`. Think of Fixed\r\n * bodies as \"immovable/unstoppable\" objects. If two `Fixed` bodies meet they will\r\n * not be pushed or moved by each other, they will not interact except to throw\r\n * collision events.\r\n */\r\n CollisionType[\"Fixed\"] = \"Fixed\";\r\n})(CollisionType || (CollisionType = {}));\r\n\n;// CONCATENATED MODULE: ./Util/Decorators.ts\n\r\n\r\nconst maxMessages = 5;\r\nconst obsoleteMessage = {};\r\nconst resetObsoleteCounter = () => {\r\n for (const message in obsoleteMessage) {\r\n obsoleteMessage[message] = 0;\r\n }\r\n};\r\nconst logMessage = (message, options) => {\r\n const suppressObsoleteMessages = Flags.isEnabled('suppress-obsolete-message');\r\n if (obsoleteMessage[message] < maxMessages && !suppressObsoleteMessages) {\r\n Logger.getInstance().warn(message);\r\n // tslint:disable-next-line: no-console\r\n if (console.trace && options.showStackTrace) {\r\n // tslint:disable-next-line: no-console\r\n console.trace();\r\n }\r\n }\r\n obsoleteMessage[message]++;\r\n};\r\n/**\r\n * Obsolete decorator for marking Excalibur methods obsolete, you can optionally specify a custom message and/or alternate replacement\r\n * method do the deprecated one. Inspired by https://github.com/jayphelps/core-decorators.js\r\n */\r\nfunction obsolete(options) {\r\n options = {\r\n message: 'This feature will be removed in future versions of Excalibur.',\r\n alternateMethod: null,\r\n showStackTrace: false,\r\n ...options\r\n };\r\n return function (target, property, descriptor) {\r\n if (descriptor &&\r\n !(typeof descriptor.value === 'function' || typeof descriptor.get === 'function' || typeof descriptor.set === 'function')) {\r\n throw new SyntaxError('Only classes/functions/getters/setters can be marked as obsolete');\r\n }\r\n const methodSignature = `${target.name || ''}${target.name && property ? '.' : ''}${property ? property : ''}`;\r\n const message = `${methodSignature} is marked obsolete: ${options.message}` +\r\n (options.alternateMethod ? ` Use ${options.alternateMethod} instead` : '');\r\n if (!obsoleteMessage[message]) {\r\n obsoleteMessage[message] = 0;\r\n }\r\n // If descriptor is null it is a class\r\n const method = descriptor ? { ...descriptor } : target;\r\n if (!descriptor) {\r\n // with es2015 classes we need to change our decoration tactic\r\n class DecoratedClass extends method {\r\n constructor(...args) {\r\n logMessage(message, options);\r\n super(...args);\r\n }\r\n }\r\n return DecoratedClass;\r\n }\r\n if (descriptor && descriptor.value) {\r\n method.value = function () {\r\n logMessage(message, options);\r\n return descriptor.value.apply(this, arguments);\r\n };\r\n return method;\r\n }\r\n if (descriptor && descriptor.get) {\r\n method.get = function () {\r\n logMessage(message, options);\r\n return descriptor.get.apply(this, arguments);\r\n };\r\n }\r\n if (descriptor && descriptor.set) {\r\n method.set = function () {\r\n logMessage(message, options);\r\n return descriptor.set.apply(this, arguments);\r\n };\r\n }\r\n return method;\r\n };\r\n}\r\n\n;// CONCATENATED MODULE: ./Collision/Physics.ts\nvar __decorate = (undefined && undefined.__decorate) || function (decorators, target, key, desc) {\r\n var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;\r\n if (typeof Reflect === \"object\" && typeof Reflect.decorate === \"function\") r = Reflect.decorate(decorators, target, key, desc);\r\n else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;\r\n return c > 3 && r && Object.defineProperty(target, key, r), r;\r\n};\r\n\r\n\r\n/**\r\n * Possible collision resolution strategies\r\n *\r\n * The default is [[CollisionResolutionStrategy.Arcade]] which performs simple axis aligned arcade style physics. This is useful for things\r\n * like platformers or top down games.\r\n *\r\n * More advanced rigid body physics are enabled by setting [[CollisionResolutionStrategy.Realistic]] which allows for complicated\r\n * simulated physical interactions.\r\n */\r\nvar CollisionResolutionStrategy;\r\n(function (CollisionResolutionStrategy) {\r\n CollisionResolutionStrategy[\"Arcade\"] = \"arcade\";\r\n CollisionResolutionStrategy[\"Realistic\"] = \"realistic\";\r\n})(CollisionResolutionStrategy || (CollisionResolutionStrategy = {}));\r\n/**\r\n * Possible broadphase collision pair identification strategies\r\n *\r\n * The default strategy is [[BroadphaseStrategy.DynamicAABBTree]] which uses a binary tree of axis-aligned bounding boxes to identify\r\n * potential collision pairs which is O(nlog(n)) faster.\r\n */\r\nvar BroadphaseStrategy;\r\n(function (BroadphaseStrategy) {\r\n BroadphaseStrategy[BroadphaseStrategy[\"DynamicAABBTree\"] = 0] = \"DynamicAABBTree\";\r\n})(BroadphaseStrategy || (BroadphaseStrategy = {}));\r\n/**\r\n * Possible numerical integrators for position and velocity\r\n */\r\nvar Integrator;\r\n(function (Integrator) {\r\n Integrator[Integrator[\"Euler\"] = 0] = \"Euler\";\r\n})(Integrator || (Integrator = {}));\r\n/**\r\n * The [[Physics]] object is the global configuration object for all Excalibur physics.\r\n */\r\n/* istanbul ignore next */\r\nclass Physics {\r\n static get gravity() {\r\n return Physics.acc;\r\n }\r\n static set gravity(v) {\r\n Physics.acc = v;\r\n }\r\n /**\r\n * Configures Excalibur to use \"arcade\" physics. Arcade physics which performs simple axis aligned arcade style physics.\r\n */\r\n static useArcadePhysics() {\r\n Physics.collisionResolutionStrategy = CollisionResolutionStrategy.Arcade;\r\n }\r\n /**\r\n * Configures Excalibur to use rigid body physics. Rigid body physics allows for complicated\r\n * simulated physical interactions.\r\n */\r\n static useRealisticPhysics() {\r\n Physics.collisionResolutionStrategy = CollisionResolutionStrategy.Realistic;\r\n }\r\n static get dynamicTreeVelocityMultiplyer() {\r\n return Physics.dynamicTreeVelocityMultiplier;\r\n }\r\n static set dynamicTreeVelocityMultiplyer(value) {\r\n Physics.dynamicTreeVelocityMultiplier = value;\r\n }\r\n}\r\n/**\r\n * Global acceleration that is applied to all vanilla actors that have a [[CollisionType.Active|active]] collision type.\r\n * Global acceleration won't effect [[Label|labels]], [[ScreenElement|ui actors]], or [[Trigger|triggers]] in Excalibur.\r\n *\r\n * This is a great way to globally simulate effects like gravity.\r\n */\r\nPhysics.acc = new Vector(0, 0);\r\n/**\r\n * Globally switches all Excalibur physics behavior on or off.\r\n */\r\nPhysics.enabled = true;\r\n/**\r\n * Gets or sets the broadphase pair identification strategy.\r\n *\r\n * The default strategy is [[BroadphaseStrategy.DynamicAABBTree]] which uses a binary tree of axis-aligned bounding boxes to identify\r\n * potential collision pairs which is O(nlog(n)) faster.\r\n */\r\nPhysics.broadphaseStrategy = BroadphaseStrategy.DynamicAABBTree;\r\n/**\r\n * Gets or sets the global collision resolution strategy (narrowphase).\r\n *\r\n * The default is [[CollisionResolutionStrategy.Arcade]] which performs simple axis aligned arcade style physics.\r\n *\r\n * More advanced rigid body physics are enabled by setting [[CollisionResolutionStrategy.Realistic]] which allows for complicated\r\n * simulated physical interactions.\r\n */\r\nPhysics.collisionResolutionStrategy = CollisionResolutionStrategy.Arcade;\r\n/**\r\n * The default mass to use if none is specified\r\n */\r\nPhysics.defaultMass = 10;\r\n/**\r\n * Gets or sets the position and velocity positional integrator, currently only Euler is supported.\r\n */\r\nPhysics.integrator = Integrator.Euler;\r\n/**\r\n * Factor to add to the RigidBody BoundingBox, bounding box (dimensions += vel * dynamicTreeVelocityMultiplier);\r\n */\r\nPhysics.dynamicTreeVelocityMultiplier = 2;\r\n/**\r\n * Pad RigidBody BoundingBox by a constant amount\r\n */\r\nPhysics.boundsPadding = 5;\r\n/**\r\n * Number of position iterations (overlap) to run in the solver\r\n */\r\nPhysics.positionIterations = 3;\r\n/**\r\n * Number of velocity iteration (response) to run in the solver\r\n */\r\nPhysics.velocityIterations = 8;\r\n/**\r\n * Amount of overlap to tolerate in pixels\r\n */\r\nPhysics.slop = 1;\r\n/**\r\n * Amount of positional overlap correction to apply each position iteration of the solver\r\n * O - meaning no correction, 1 - meaning correct all overlap\r\n */\r\nPhysics.steeringFactor = 0.2;\r\n/**\r\n * Warm start set to true re-uses impulses from previous frames back in the solver\r\n */\r\nPhysics.warmStart = true;\r\n/**\r\n * By default bodies do not sleep\r\n */\r\nPhysics.bodiesCanSleepByDefault = false;\r\n/**\r\n * Surface epsilon is used to help deal with surface penetration\r\n */\r\nPhysics.surfaceEpsilon = 0.1;\r\nPhysics.sleepEpsilon = 0.07;\r\nPhysics.wakeThreshold = Physics.sleepEpsilon * 3;\r\nPhysics.sleepBias = 0.9;\r\n/**\r\n * Enable fast moving body checking, this enables checking for collision pairs via raycast for fast moving objects to prevent\r\n * bodies from tunneling through one another.\r\n */\r\nPhysics.checkForFastBodies = true;\r\n/**\r\n * Disable minimum fast moving body raycast, by default if ex.Physics.checkForFastBodies = true Excalibur will only check if the\r\n * body is moving at least half of its minimum dimension in an update. If ex.Physics.disableMinimumSpeedForFastBody is set to true,\r\n * Excalibur will always perform the fast body raycast regardless of speed.\r\n */\r\nPhysics.disableMinimumSpeedForFastBody = false;\r\n__decorate([\r\n obsolete({\r\n message: 'Alias for incorrect spelling used in older versions, will be removed in v0.25.0',\r\n alternateMethod: 'dynamicTreeVelocityMultiplier'\r\n })\r\n], Physics, \"dynamicTreeVelocityMultiplyer\", null);\r\n\n;// CONCATENATED MODULE: ./Math/coord-plane.ts\n/**\r\n * Enum representing the coordinate plane for the position 2D vector in the [[TransformComponent]]\r\n */\r\nvar CoordPlane;\r\n(function (CoordPlane) {\r\n /**\r\n * The world coordinate plane (default) represents world space, any entities drawn with world\r\n * space move when the camera moves.\r\n */\r\n CoordPlane[\"World\"] = \"world\";\r\n /**\r\n * The screen coordinate plane represents screen space, entities drawn in screen space are pinned\r\n * to screen coordinates ignoring the camera.\r\n */\r\n CoordPlane[\"Screen\"] = \"screen\";\r\n})(CoordPlane || (CoordPlane = {}));\r\n\n;// CONCATENATED MODULE: ./Math/vector-view.ts\n\r\nclass VectorView extends Vector {\r\n constructor(options) {\r\n super(0, 0);\r\n this._getX = options.getX;\r\n this._getY = options.getY;\r\n this._setX = options.setX;\r\n this._setY = options.setY;\r\n }\r\n get x() {\r\n return (this._x = this._getX());\r\n }\r\n set x(val) {\r\n this._setX(val);\r\n this._x = val;\r\n }\r\n get y() {\r\n return (this._y = this._getY());\r\n }\r\n set y(val) {\r\n this._setY(val);\r\n this._y = val;\r\n }\r\n}\r\n\n;// CONCATENATED MODULE: ./Math/watch-vector.ts\n\r\n/**\r\n * Wraps a vector and watches for changes in the x/y, modifies the original vector.\r\n */\r\nclass WatchVector extends Vector {\r\n constructor(original, change) {\r\n super(original.x, original.y);\r\n this.original = original;\r\n this.change = change;\r\n }\r\n get x() {\r\n return this._x = this.original.x;\r\n }\r\n set x(newX) {\r\n this.change(newX, this._y);\r\n this._x = this.original.x = newX;\r\n }\r\n get y() {\r\n return this._y = this.original.y;\r\n }\r\n set y(newY) {\r\n this.change(this._x, newY);\r\n this._y = this.original.y = newY;\r\n }\r\n}\r\n\n;// CONCATENATED MODULE: ./Math/transform.ts\n\r\n\r\n\r\n\r\n\r\nclass Transform {\r\n constructor() {\r\n this._parent = null;\r\n this._children = [];\r\n this._pos = vec(0, 0);\r\n this._rotation = 0;\r\n this._scale = vec(1, 1);\r\n this._isDirty = false;\r\n this._isInverseDirty = false;\r\n this._matrix = AffineMatrix.identity();\r\n this._inverse = AffineMatrix.identity();\r\n }\r\n get parent() {\r\n return this._parent;\r\n }\r\n set parent(transform) {\r\n if (this._parent) {\r\n const index = this._parent._children.indexOf(this);\r\n if (index > -1) {\r\n this._parent._children.splice(index, 1);\r\n }\r\n }\r\n this._parent = transform;\r\n if (this._parent) {\r\n this._parent._children.push(this);\r\n }\r\n this.flagDirty();\r\n }\r\n get children() {\r\n return this._children;\r\n }\r\n set pos(v) {\r\n if (!v.equals(this._pos)) {\r\n this._pos.x = v.x;\r\n this._pos.y = v.y;\r\n this.flagDirty();\r\n }\r\n }\r\n get pos() {\r\n return new WatchVector(this._pos, (x, y) => {\r\n if (x !== this._pos.x || y !== this._pos.y) {\r\n this.flagDirty();\r\n }\r\n });\r\n }\r\n set globalPos(v) {\r\n let localPos = v.clone();\r\n if (this.parent) {\r\n localPos = this.parent.inverse.multiply(v);\r\n }\r\n if (!localPos.equals(this._pos)) {\r\n this._pos = localPos;\r\n this.flagDirty();\r\n }\r\n }\r\n get globalPos() {\r\n return new VectorView({\r\n getX: () => this.matrix.data[4],\r\n getY: () => this.matrix.data[5],\r\n setX: (x) => {\r\n if (this.parent) {\r\n const { x: newX } = this.parent.inverse.multiply(vec(x, this.pos.y));\r\n this.pos.x = newX;\r\n }\r\n else {\r\n this.pos.x = x;\r\n }\r\n if (x !== this.matrix.data[4]) {\r\n this.flagDirty();\r\n }\r\n },\r\n setY: (y) => {\r\n if (this.parent) {\r\n const { y: newY } = this.parent.inverse.multiply(vec(this.pos.x, y));\r\n this.pos.y = newY;\r\n }\r\n else {\r\n this.pos.y = y;\r\n }\r\n if (y !== this.matrix.data[5]) {\r\n this.flagDirty();\r\n }\r\n }\r\n });\r\n }\r\n set rotation(rotation) {\r\n const canonRotation = canonicalizeAngle(rotation);\r\n if (canonRotation !== this._rotation) {\r\n this.flagDirty();\r\n }\r\n this._rotation = canonRotation;\r\n }\r\n get rotation() {\r\n return this._rotation;\r\n }\r\n set globalRotation(rotation) {\r\n let inverseRotation = 0;\r\n if (this.parent) {\r\n inverseRotation = this.parent.globalRotation;\r\n }\r\n const canonRotation = canonicalizeAngle(rotation + inverseRotation);\r\n if (canonRotation !== this._rotation) {\r\n this.flagDirty();\r\n }\r\n this._rotation = canonRotation;\r\n }\r\n get globalRotation() {\r\n if (this.parent) {\r\n return this.matrix.getRotation();\r\n }\r\n return this.rotation;\r\n }\r\n set scale(v) {\r\n if (!v.equals(this._scale)) {\r\n this._scale.x = v.x;\r\n this._scale.y = v.y;\r\n this.flagDirty();\r\n }\r\n }\r\n get scale() {\r\n return new WatchVector(this._scale, (x, y) => {\r\n if (x !== this._scale.x || y !== this._scale.y) {\r\n this.flagDirty();\r\n }\r\n });\r\n }\r\n set globalScale(v) {\r\n let inverseScale = vec(1, 1);\r\n if (this.parent) {\r\n inverseScale = this.parent.globalScale;\r\n }\r\n this.scale = v.scale(vec(1 / inverseScale.x, 1 / inverseScale.y));\r\n }\r\n get globalScale() {\r\n return new VectorView({\r\n getX: () => this.parent ? this.matrix.getScaleX() : this.scale.x,\r\n getY: () => this.parent ? this.matrix.getScaleY() : this.scale.y,\r\n setX: (x) => {\r\n if (this.parent) {\r\n const globalScaleX = this.parent.globalScale.x;\r\n this.scale.x = x / globalScaleX;\r\n }\r\n else {\r\n this.scale.x = x;\r\n }\r\n },\r\n setY: (y) => {\r\n if (this.parent) {\r\n const globalScaleY = this.parent.globalScale.y;\r\n this.scale.y = y / globalScaleY;\r\n }\r\n else {\r\n this.scale.y = y;\r\n }\r\n }\r\n });\r\n }\r\n get matrix() {\r\n if (this._isDirty) {\r\n if (this.parent === null) {\r\n this._matrix = this._calculateMatrix();\r\n }\r\n else {\r\n this._matrix = this.parent.matrix.multiply(this._calculateMatrix());\r\n }\r\n this._isDirty = false;\r\n }\r\n return this._matrix;\r\n }\r\n get inverse() {\r\n if (this._isInverseDirty) {\r\n this._inverse = this.matrix.inverse();\r\n this._isInverseDirty = false;\r\n }\r\n return this._inverse;\r\n }\r\n _calculateMatrix() {\r\n const matrix = AffineMatrix.identity()\r\n .translate(this.pos.x, this.pos.y)\r\n .rotate(this.rotation)\r\n .scale(this.scale.x, this.scale.y);\r\n return matrix;\r\n }\r\n flagDirty() {\r\n this._isDirty = true;\r\n this._isInverseDirty = true;\r\n for (let i = 0; i < this._children.length; i++) {\r\n this._children[i].flagDirty();\r\n }\r\n }\r\n apply(point) {\r\n return this.matrix.multiply(point);\r\n }\r\n applyInverse(point) {\r\n return this.inverse.multiply(point);\r\n }\r\n setTransform(pos, rotation, scale) {\r\n this._pos.x = pos.x;\r\n this._pos.y = pos.y;\r\n this._rotation = canonicalizeAngle(rotation);\r\n this._scale.x = scale.x;\r\n this._scale.y = scale.y;\r\n this.flagDirty();\r\n }\r\n clone(dest) {\r\n const target = dest !== null && dest !== void 0 ? dest : new Transform();\r\n this._pos.clone(target._pos);\r\n target._rotation = this._rotation;\r\n this._scale.clone(target._scale);\r\n target.flagDirty();\r\n return target;\r\n }\r\n}\r\n\n;// CONCATENATED MODULE: ./EntityComponentSystem/Component.ts\n/**\r\n * Type guard to check if a component implements clone\r\n * @param x\r\n */\r\nfunction hasClone(x) {\r\n return !!(x === null || x === void 0 ? void 0 : x.clone);\r\n}\r\n/**\r\n * Components are containers for state in Excalibur, the are meant to convey capabilities that an Entity possesses\r\n *\r\n * Implementations of Component must have a zero-arg constructor to support dependencies\r\n *\r\n * ```typescript\r\n * class MyComponent extends ex.Component<'my'> {\r\n * public readonly type = 'my';\r\n * // zero arg support required if you want to use component dependencies\r\n * constructor(public optionalPos?: ex.Vector) {}\r\n * }\r\n * ```\r\n */\r\nclass Component {\r\n constructor() {\r\n /**\r\n * Current owning [[Entity]], if any, of this component. Null if not added to any [[Entity]]\r\n */\r\n this.owner = null;\r\n }\r\n /**\r\n * Clones any properties on this component, if that property value has a `clone()` method it will be called\r\n */\r\n clone() {\r\n const newComponent = new this.constructor();\r\n for (const prop in this) {\r\n if (this.hasOwnProperty(prop)) {\r\n const val = this[prop];\r\n if (hasClone(val) && prop !== 'owner' && prop !== 'clone') {\r\n newComponent[prop] = val.clone();\r\n }\r\n else {\r\n newComponent[prop] = val;\r\n }\r\n }\r\n }\r\n return newComponent;\r\n }\r\n}\r\n/**\r\n * Tag components are a way of tagging a component with label and a simple value\r\n *\r\n * For example:\r\n *\r\n * ```typescript\r\n * const isOffscreen = new TagComponent('offscreen');\r\n * entity.addComponent(isOffscreen);\r\n * entity.tags.includes\r\n * ```\r\n */\r\nclass TagComponent extends Component {\r\n constructor(type, value) {\r\n super();\r\n this.type = type;\r\n this.value = value;\r\n }\r\n}\r\n\n;// CONCATENATED MODULE: ./Util/Observable.ts\n/**\r\n * Simple Observable implementation\r\n * @template T is the typescript Type that defines the data being observed\r\n */\r\nclass Observable {\r\n constructor() {\r\n this.observers = [];\r\n this.subscriptions = [];\r\n }\r\n /**\r\n * Register an observer to listen to this observable\r\n * @param observer\r\n */\r\n register(observer) {\r\n this.observers.push(observer);\r\n }\r\n /**\r\n * Register a callback to listen to this observable\r\n * @param func\r\n */\r\n subscribe(func) {\r\n this.subscriptions.push(func);\r\n }\r\n /**\r\n * Remove an observer from the observable\r\n * @param observer\r\n */\r\n unregister(observer) {\r\n const i = this.observers.indexOf(observer);\r\n if (i !== -1) {\r\n this.observers.splice(i, 1);\r\n }\r\n }\r\n /**\r\n * Remove a callback that is listening to this observable\r\n * @param func\r\n */\r\n unsubscribe(func) {\r\n const i = this.subscriptions.indexOf(func);\r\n if (i !== -1) {\r\n this.subscriptions.splice(i, 1);\r\n }\r\n }\r\n /**\r\n * Broadcasts a message to all observers and callbacks\r\n * @param message\r\n */\r\n notifyAll(message) {\r\n const observersLength = this.observers.length;\r\n for (let i = 0; i < observersLength; i++) {\r\n this.observers[i].notify(message);\r\n }\r\n const subscriptionsLength = this.subscriptions.length;\r\n for (let i = 0; i < subscriptionsLength; i++) {\r\n this.subscriptions[i](message);\r\n }\r\n }\r\n /**\r\n * Removes all observers and callbacks\r\n */\r\n clear() {\r\n this.observers.length = 0;\r\n this.subscriptions.length = 0;\r\n }\r\n}\r\n\n;// CONCATENATED MODULE: ./EntityComponentSystem/Components/TransformComponent.ts\n\r\n\r\n\r\n\r\nclass TransformComponent extends Component {\r\n constructor() {\r\n super(...arguments);\r\n this.type = 'ex.transform';\r\n this._transform = new Transform();\r\n this._addChildTransform = (child) => {\r\n const childTxComponent = child.get(TransformComponent);\r\n if (childTxComponent) {\r\n childTxComponent._transform.parent = this._transform;\r\n }\r\n };\r\n /**\r\n * Observable that emits when the z index changes on this component\r\n */\r\n this.zIndexChanged$ = new Observable();\r\n this._z = 0;\r\n /**\r\n * The [[CoordPlane|coordinate plane|]] for this transform for the entity.\r\n */\r\n this.coordPlane = CoordPlane.World;\r\n }\r\n get() {\r\n return this._transform;\r\n }\r\n onAdd(owner) {\r\n for (const child of owner.children) {\r\n this._addChildTransform(child);\r\n }\r\n owner.childrenAdded$.subscribe(child => this._addChildTransform(child));\r\n owner.childrenRemoved$.subscribe(child => {\r\n const childTxComponent = child.get(TransformComponent);\r\n if (childTxComponent) {\r\n childTxComponent._transform.parent = null;\r\n }\r\n });\r\n }\r\n onRemove(_previousOwner) {\r\n this._transform.parent = null;\r\n }\r\n /**\r\n * The z-index ordering of the entity, a higher values are drawn on top of lower values.\r\n * For example z=99 would be drawn on top of z=0.\r\n */\r\n get z() {\r\n return this._z;\r\n }\r\n set z(val) {\r\n const oldz = this._z;\r\n this._z = val;\r\n if (oldz !== val) {\r\n this.zIndexChanged$.notifyAll(val);\r\n }\r\n }\r\n get pos() {\r\n return this._transform.pos;\r\n }\r\n set pos(v) {\r\n this._transform.pos = v;\r\n }\r\n get globalPos() {\r\n return this._transform.globalPos;\r\n }\r\n set globalPos(v) {\r\n this._transform.globalPos = v;\r\n }\r\n get rotation() {\r\n return this._transform.rotation;\r\n }\r\n set rotation(rotation) {\r\n this._transform.rotation = rotation;\r\n }\r\n get globalRotation() {\r\n return this._transform.globalRotation;\r\n }\r\n set globalRotation(rotation) {\r\n this._transform.globalRotation = rotation;\r\n }\r\n get scale() {\r\n return this._transform.scale;\r\n }\r\n set scale(v) {\r\n this._transform.scale = v;\r\n }\r\n get globalScale() {\r\n return this._transform.globalScale;\r\n }\r\n set globalScale(v) {\r\n this._transform.globalScale = v;\r\n }\r\n applyInverse(v) {\r\n return this._transform.applyInverse(v);\r\n }\r\n apply(v) {\r\n return this._transform.apply(v);\r\n }\r\n clone() {\r\n const component = new TransformComponent();\r\n component._transform = this._transform.clone();\r\n component._z = this._z;\r\n return component;\r\n }\r\n}\r\n\n;// CONCATENATED MODULE: ./EntityComponentSystem/Components/MotionComponent.ts\n\r\n\r\nclass MotionComponent extends Component {\r\n constructor() {\r\n super(...arguments);\r\n this.type = 'ex.motion';\r\n /**\r\n * The velocity of an entity in pixels per second\r\n */\r\n this.vel = Vector.Zero;\r\n /**\r\n * The acceleration of entity in pixels per second^2\r\n */\r\n this.acc = Vector.Zero;\r\n /**\r\n * The scale rate of change in scale units per second\r\n */\r\n this.scaleFactor = Vector.Zero;\r\n /**\r\n * The angular velocity which is how quickly the entity is rotating in radians per second\r\n */\r\n this.angularVelocity = 0;\r\n /**\r\n * The amount of torque applied to the entity, angular acceleration is torque * inertia\r\n */\r\n this.torque = 0;\r\n /**\r\n * Inertia can be thought of as the resistance to motion\r\n */\r\n this.inertia = 1;\r\n }\r\n}\r\n\n;// CONCATENATED MODULE: ./Collision/Group/CollisionGroup.ts\n/**\r\n * CollisionGroups indicate like members that do not collide with each other. Use [[CollisionGroupManager]] to create [[CollisionGroup]]s\r\n *\r\n * For example:\r\n *\r\n * Players have collision group \"player\"\r\n *\r\n * ![Player Collision Group](/assets/images/docs/CollisionGroupsPlayer.png)\r\n *\r\n * Enemies have collision group \"enemy\"\r\n *\r\n * ![Enemy Collision Group](/assets/images/docs/CollisionGroupsEnemy.png)\r\n *\r\n * Blocks have collision group \"ground\"\r\n *\r\n * ![Ground collision group](/assets/images/docs/CollisionGroupsGround.png)\r\n *\r\n * Players don't collide with each other, but enemies and blocks. Likewise, enemies don't collide with each other but collide\r\n * with players and blocks.\r\n *\r\n * This is done with bitmasking, see the following pseudo-code\r\n *\r\n * PlayerGroup = `0b001`\r\n * PlayerGroupMask = `0b110`\r\n *\r\n * EnemyGroup = `0b010`\r\n * EnemyGroupMask = `0b101`\r\n *\r\n * BlockGroup = `0b100`\r\n * BlockGroupMask = `0b011`\r\n *\r\n * Should Players collide? No because the bitwise mask evaluates to 0\r\n * `(player1.group & player2.mask) === 0`\r\n * `(0b001 & 0b110) === 0`\r\n *\r\n * Should Players and Enemies collide? Yes because the bitwise mask is non-zero\r\n * `(player1.group & enemy1.mask) === 1`\r\n * `(0b001 & 0b101) === 1`\r\n *\r\n * Should Players and Blocks collide? Yes because the bitwise mask is non-zero\r\n * `(player1.group & blocks1.mask) === 1`\r\n * `(0b001 & 0b011) === 1`\r\n */\r\nclass CollisionGroup {\r\n /**\r\n * STOP!!** It is preferred that [[CollisionGroupManager.create]] is used to create collision groups\r\n * unless you know how to construct the proper bitmasks. See https://github.com/excaliburjs/Excalibur/issues/1091 for more info.\r\n * @param name Name of the collision group\r\n * @param category 32 bit category for the group, should be a unique power of 2. For example `0b001` or `0b010`\r\n * @param mask 32 bit mask of category, or `~category` generally. For a category of `0b001`, the mask would be `0b110`\r\n */\r\n constructor(name, category, mask) {\r\n this._name = name;\r\n this._category = category;\r\n this._mask = mask;\r\n }\r\n /**\r\n * Get the name of the collision group\r\n */\r\n get name() {\r\n return this._name;\r\n }\r\n /**\r\n * Get the category of the collision group, a 32 bit number which should be a unique power of 2\r\n */\r\n get category() {\r\n return this._category;\r\n }\r\n /**\r\n * Get the mask for this collision group\r\n */\r\n get mask() {\r\n return this._mask;\r\n }\r\n /**\r\n * Evaluates whether 2 collision groups can collide\r\n * @param other CollisionGroup\r\n */\r\n canCollide(other) {\r\n return (this.category & other.mask) !== 0 && (other.category & this.mask) !== 0;\r\n }\r\n /**\r\n * Inverts the collision group. For example, if before the group specified \"players\",\r\n * inverting would specify all groups except players\r\n * @returns CollisionGroup\r\n */\r\n invert() {\r\n return new CollisionGroup('~(' + this.name + ')', ~this.category, ~this.mask);\r\n }\r\n /**\r\n * Combine collision groups with each other. The new group includes all of the previous groups.\r\n *\r\n * @param collisionGroups\r\n */\r\n static combine(collisionGroups) {\r\n const combinedName = collisionGroups.map((c) => c.name).join('+');\r\n const combinedCategory = collisionGroups.reduce((current, g) => g.category | current, 0b0);\r\n const combinedMask = ~combinedCategory;\r\n return new CollisionGroup(combinedName, combinedCategory, combinedMask);\r\n }\r\n /**\r\n * Creates a collision group that collides with the listed groups\r\n * @param collisionGroups\r\n */\r\n static collidesWith(collisionGroups) {\r\n return CollisionGroup.combine(collisionGroups).invert();\r\n }\r\n}\r\n/**\r\n * The `All` [[CollisionGroup]] is a special group that collides with all other groups including itself,\r\n * it is the default collision group on colliders.\r\n */\r\nCollisionGroup.All = new CollisionGroup('Collide with all groups', -1, -1);\r\n\n;// CONCATENATED MODULE: ./Collision/Detection/Pair.ts\n\r\n\r\n/**\r\n * Models a potential collision between 2 colliders\r\n */\r\nclass Pair {\r\n constructor(colliderA, colliderB) {\r\n this.colliderA = colliderA;\r\n this.colliderB = colliderB;\r\n this.id = null;\r\n this.id = Pair.calculatePairHash(colliderA.id, colliderB.id);\r\n }\r\n /**\r\n * Returns whether a it is allowed for 2 colliders in a Pair to collide\r\n * @param colliderA\r\n * @param colliderB\r\n */\r\n static canCollide(colliderA, colliderB) {\r\n var _a, _b;\r\n const bodyA = (_a = colliderA === null || colliderA === void 0 ? void 0 : colliderA.owner) === null || _a === void 0 ? void 0 : _a.get(BodyComponent);\r\n const bodyB = (_b = colliderB === null || colliderB === void 0 ? void 0 : colliderB.owner) === null || _b === void 0 ? void 0 : _b.get(BodyComponent);\r\n // Prevent self collision\r\n if (colliderA.id === colliderB.id) {\r\n return false;\r\n }\r\n // Colliders with the same owner do not collide (composite colliders)\r\n if (colliderA.owner &&\r\n colliderB.owner &&\r\n colliderA.owner.id === colliderB.owner.id) {\r\n return false;\r\n }\r\n // if the pair has a member with zero dimension don't collide\r\n if (colliderA.localBounds.hasZeroDimensions() || colliderB.localBounds.hasZeroDimensions()) {\r\n return false;\r\n }\r\n // Body's needed for collision in the current state\r\n // TODO can we collide without a body?\r\n if (!bodyA || !bodyB) {\r\n return false;\r\n }\r\n // If both are in the same collision group short circuit\r\n if (!bodyA.group.canCollide(bodyB.group)) {\r\n return false;\r\n }\r\n // if both are fixed short circuit\r\n if (bodyA.collisionType === CollisionType.Fixed && bodyB.collisionType === CollisionType.Fixed) {\r\n return false;\r\n }\r\n // if the either is prevent collision short circuit\r\n if (bodyB.collisionType === CollisionType.PreventCollision || bodyA.collisionType === CollisionType.PreventCollision) {\r\n return false;\r\n }\r\n // if either is dead short circuit\r\n if (!bodyA.active || !bodyB.active) {\r\n return false;\r\n }\r\n return true;\r\n }\r\n /**\r\n * Returns whether or not it is possible for the pairs to collide\r\n */\r\n get canCollide() {\r\n const colliderA = this.colliderA;\r\n const colliderB = this.colliderB;\r\n return Pair.canCollide(colliderA, colliderB);\r\n }\r\n /**\r\n * Runs the collision intersection logic on the members of this pair\r\n */\r\n collide() {\r\n return this.colliderA.collide(this.colliderB);\r\n }\r\n /**\r\n * Check if the collider is part of the pair\r\n * @param collider\r\n */\r\n hasCollider(collider) {\r\n return collider === this.colliderA || collider === this.colliderB;\r\n }\r\n /**\r\n * Calculates the unique pair hash id for this collision pair (owning id)\r\n */\r\n static calculatePairHash(idA, idB) {\r\n if (idA.value < idB.value) {\r\n return `#${idA.value}+${idB.value}`;\r\n }\r\n else {\r\n return `#${idB.value}+${idA.value}`;\r\n }\r\n }\r\n}\r\n\n;// CONCATENATED MODULE: ./Math/projection.ts\n/**\r\n * A 1 dimensional projection on an axis, used to test overlaps\r\n */\r\nclass Projection {\r\n constructor(min, max) {\r\n this.min = min;\r\n this.max = max;\r\n }\r\n overlaps(projection) {\r\n return this.max > projection.min && projection.max > this.min;\r\n }\r\n getOverlap(projection) {\r\n if (this.overlaps(projection)) {\r\n if (this.max > projection.max) {\r\n return projection.max - this.min;\r\n }\r\n else {\r\n return this.max - projection.min;\r\n }\r\n }\r\n return 0;\r\n }\r\n}\r\n\n;// CONCATENATED MODULE: ./Collision/Detection/DynamicTree.ts\n\r\n\r\n\r\n\r\n\r\n/**\r\n * Dynamic Tree Node used for tracking bounds within the tree\r\n */\r\nclass TreeNode {\r\n constructor(parent) {\r\n this.parent = parent;\r\n this.parent = parent || null;\r\n this.data = null;\r\n this.bounds = new BoundingBox();\r\n this.left = null;\r\n this.right = null;\r\n this.height = 0;\r\n }\r\n isLeaf() {\r\n return !this.left && !this.right;\r\n }\r\n}\r\n/**\r\n * The DynamicTrees provides a spatial partitioning data structure for quickly querying for overlapping bounding boxes for\r\n * all tracked bodies. The worst case performance of this is O(n*log(n)) where n is the number of bodies in the tree.\r\n *\r\n * Internally the bounding boxes are organized as a balanced binary tree of bounding boxes, where the leaf nodes are tracked bodies.\r\n * Every non-leaf node is a bounding box that contains child bounding boxes.\r\n */\r\nclass DynamicTree {\r\n constructor(worldBounds = new BoundingBox(-Number.MAX_VALUE, -Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE)) {\r\n this.worldBounds = worldBounds;\r\n this.root = null;\r\n this.nodes = {};\r\n }\r\n /**\r\n * Inserts a node into the dynamic tree\r\n */\r\n _insert(leaf) {\r\n // If there are no nodes in the tree, make this the root leaf\r\n if (this.root === null) {\r\n this.root = leaf;\r\n this.root.parent = null;\r\n return;\r\n }\r\n // Search the tree for a node that is not a leaf and find the best place to insert\r\n const leafAABB = leaf.bounds;\r\n let currentRoot = this.root;\r\n while (!currentRoot.isLeaf()) {\r\n const left = currentRoot.left;\r\n const right = currentRoot.right;\r\n const area = currentRoot.bounds.getPerimeter();\r\n const combinedAABB = currentRoot.bounds.combine(leafAABB);\r\n const combinedArea = combinedAABB.getPerimeter();\r\n // Calculate cost heuristic for creating a new parent and leaf\r\n const cost = 2 * combinedArea;\r\n // Minimum cost of pushing the leaf down the tree\r\n const inheritanceCost = 2 * (combinedArea - area);\r\n // Cost of descending\r\n let leftCost = 0;\r\n const leftCombined = leafAABB.combine(left.bounds);\r\n let newArea;\r\n let oldArea;\r\n if (left.isLeaf()) {\r\n leftCost = leftCombined.getPerimeter() + inheritanceCost;\r\n }\r\n else {\r\n oldArea = left.bounds.getPerimeter();\r\n newArea = leftCombined.getPerimeter();\r\n leftCost = newArea - oldArea + inheritanceCost;\r\n }\r\n let rightCost = 0;\r\n const rightCombined = leafAABB.combine(right.bounds);\r\n if (right.isLeaf()) {\r\n rightCost = rightCombined.getPerimeter() + inheritanceCost;\r\n }\r\n else {\r\n oldArea = right.bounds.getPerimeter();\r\n newArea = rightCombined.getPerimeter();\r\n rightCost = newArea - oldArea + inheritanceCost;\r\n }\r\n // cost is acceptable\r\n if (cost < leftCost && cost < rightCost) {\r\n break;\r\n }\r\n // Descend to the depths\r\n if (leftCost < rightCost) {\r\n currentRoot = left;\r\n }\r\n else {\r\n currentRoot = right;\r\n }\r\n }\r\n // Create the new parent node and insert into the tree\r\n const oldParent = currentRoot.parent;\r\n const newParent = new TreeNode(oldParent);\r\n newParent.bounds = leafAABB.combine(currentRoot.bounds);\r\n newParent.height = currentRoot.height + 1;\r\n if (oldParent !== null) {\r\n // The sibling node was not the root\r\n if (oldParent.left === currentRoot) {\r\n oldParent.left = newParent;\r\n }\r\n else {\r\n oldParent.right = newParent;\r\n }\r\n newParent.left = currentRoot;\r\n newParent.right = leaf;\r\n currentRoot.parent = newParent;\r\n leaf.parent = newParent;\r\n }\r\n else {\r\n // The sibling node was the root\r\n newParent.left = currentRoot;\r\n newParent.right = leaf;\r\n currentRoot.parent = newParent;\r\n leaf.parent = newParent;\r\n this.root = newParent;\r\n }\r\n // Walk up the tree fixing heights and AABBs\r\n let currentNode = leaf.parent;\r\n while (currentNode) {\r\n currentNode = this._balance(currentNode);\r\n if (!currentNode.left) {\r\n throw new Error('Parent of current leaf cannot have a null left child' + currentNode);\r\n }\r\n if (!currentNode.right) {\r\n throw new Error('Parent of current leaf cannot have a null right child' + currentNode);\r\n }\r\n currentNode.height = 1 + Math.max(currentNode.left.height, currentNode.right.height);\r\n currentNode.bounds = currentNode.left.bounds.combine(currentNode.right.bounds);\r\n currentNode = currentNode.parent;\r\n }\r\n }\r\n /**\r\n * Removes a node from the dynamic tree\r\n */\r\n _remove(leaf) {\r\n if (leaf === this.root) {\r\n this.root = null;\r\n return;\r\n }\r\n const parent = leaf.parent;\r\n const grandParent = parent.parent;\r\n let sibling;\r\n if (parent.left === leaf) {\r\n sibling = parent.right;\r\n }\r\n else {\r\n sibling = parent.left;\r\n }\r\n if (grandParent) {\r\n if (grandParent.left === parent) {\r\n grandParent.left = sibling;\r\n }\r\n else {\r\n grandParent.right = sibling;\r\n }\r\n sibling.parent = grandParent;\r\n let currentNode = grandParent;\r\n while (currentNode) {\r\n currentNode = this._balance(currentNode);\r\n currentNode.bounds = currentNode.left.bounds.combine(currentNode.right.bounds);\r\n currentNode.height = 1 + Math.max(currentNode.left.height, currentNode.right.height);\r\n currentNode = currentNode.parent;\r\n }\r\n }\r\n else {\r\n this.root = sibling;\r\n sibling.parent = null;\r\n }\r\n }\r\n /**\r\n * Tracks a body in the dynamic tree\r\n */\r\n trackCollider(collider) {\r\n const node = new TreeNode();\r\n node.data = collider;\r\n node.bounds = collider.bounds;\r\n node.bounds.left -= 2;\r\n node.bounds.top -= 2;\r\n node.bounds.right += 2;\r\n node.bounds.bottom += 2;\r\n this.nodes[collider.id.value] = node;\r\n this._insert(node);\r\n }\r\n /**\r\n * Updates the dynamic tree given the current bounds of each body being tracked\r\n */\r\n updateCollider(collider) {\r\n var _a;\r\n const node = this.nodes[collider.id.value];\r\n if (!node) {\r\n return false;\r\n }\r\n const b = collider.bounds;\r\n // if the body is outside the world no longer update it\r\n if (!this.worldBounds.contains(b)) {\r\n Logger.getInstance().warn('Collider with id ' + collider.id.value + ' is outside the world bounds and will no longer be tracked for physics');\r\n this.untrackCollider(collider);\r\n return false;\r\n }\r\n if (node.bounds.contains(b)) {\r\n return false;\r\n }\r\n this._remove(node);\r\n b.left -= Physics.boundsPadding;\r\n b.top -= Physics.boundsPadding;\r\n b.right += Physics.boundsPadding;\r\n b.bottom += Physics.boundsPadding;\r\n // THIS IS CAUSING UNECESSARY CHECKS\r\n if (collider.owner) {\r\n const body = (_a = collider.owner) === null || _a === void 0 ? void 0 : _a.get(BodyComponent);\r\n if (body) {\r\n const multdx = ((body.vel.x * 32) / 1000) * Physics.dynamicTreeVelocityMultiplier;\r\n const multdy = ((body.vel.y * 32) / 1000) * Physics.dynamicTreeVelocityMultiplier;\r\n if (multdx < 0) {\r\n b.left += multdx;\r\n }\r\n else {\r\n b.right += multdx;\r\n }\r\n if (multdy < 0) {\r\n b.top += multdy;\r\n }\r\n else {\r\n b.bottom += multdy;\r\n }\r\n }\r\n }\r\n node.bounds = b;\r\n this._insert(node);\r\n return true;\r\n }\r\n /**\r\n * Untracks a body from the dynamic tree\r\n */\r\n untrackCollider(collider) {\r\n const node = this.nodes[collider.id.value];\r\n if (!node) {\r\n return;\r\n }\r\n this._remove(node);\r\n this.nodes[collider.id.value] = null;\r\n delete this.nodes[collider.id.value];\r\n }\r\n /**\r\n * Balances the tree about a node\r\n */\r\n _balance(node) {\r\n if (node === null) {\r\n throw new Error('Cannot balance at null node');\r\n }\r\n if (node.isLeaf() || node.height < 2) {\r\n return node;\r\n }\r\n const left = node.left;\r\n const right = node.right;\r\n const a = node;\r\n const b = left;\r\n const c = right;\r\n const d = left.left;\r\n const e = left.right;\r\n const f = right.left;\r\n const g = right.right;\r\n const balance = c.height - b.height;\r\n // Rotate c node up\r\n if (balance > 1) {\r\n // Swap the right node with it's parent\r\n c.left = a;\r\n c.parent = a.parent;\r\n a.parent = c;\r\n // The original node's old parent should point to the right node\r\n // this is mega confusing\r\n if (c.parent) {\r\n if (c.parent.left === a) {\r\n c.parent.left = c;\r\n }\r\n else {\r\n c.parent.right = c;\r\n }\r\n }\r\n else {\r\n this.root = c;\r\n }\r\n // Rotate\r\n if (f.height > g.height) {\r\n c.right = f;\r\n a.right = g;\r\n g.parent = a;\r\n a.bounds = b.bounds.combine(g.bounds);\r\n c.bounds = a.bounds.combine(f.bounds);\r\n a.height = 1 + Math.max(b.height, g.height);\r\n c.height = 1 + Math.max(a.height, f.height);\r\n }\r\n else {\r\n c.right = g;\r\n a.right = f;\r\n f.parent = a;\r\n a.bounds = b.bounds.combine(f.bounds);\r\n c.bounds = a.bounds.combine(g.bounds);\r\n a.height = 1 + Math.max(b.height, f.height);\r\n c.height = 1 + Math.max(a.height, g.height);\r\n }\r\n return c;\r\n }\r\n // Rotate left node up\r\n if (balance < -1) {\r\n // swap\r\n b.left = a;\r\n b.parent = a.parent;\r\n a.parent = b;\r\n // node's old parent should point to b\r\n if (b.parent) {\r\n if (b.parent.left === a) {\r\n b.parent.left = b;\r\n }\r\n else {\r\n if (b.parent.right !== a) {\r\n throw 'Error rotating Dynamic Tree';\r\n }\r\n b.parent.right = b;\r\n }\r\n }\r\n else {\r\n this.root = b;\r\n }\r\n // rotate\r\n if (d.height > e.height) {\r\n b.right = d;\r\n a.left = e;\r\n e.parent = a;\r\n a.bounds = c.bounds.combine(e.bounds);\r\n b.bounds = a.bounds.combine(d.bounds);\r\n a.height = 1 + Math.max(c.height, e.height);\r\n b.height = 1 + Math.max(a.height, d.height);\r\n }\r\n else {\r\n b.right = e;\r\n a.left = d;\r\n d.parent = a;\r\n a.bounds = c.bounds.combine(d.bounds);\r\n b.bounds = a.bounds.combine(e.bounds);\r\n a.height = 1 + Math.max(c.height, d.height);\r\n b.height = 1 + Math.max(a.height, e.height);\r\n }\r\n return b;\r\n }\r\n return node;\r\n }\r\n /**\r\n * Returns the internal height of the tree, shorter trees are better. Performance drops as the tree grows\r\n */\r\n getHeight() {\r\n if (this.root === null) {\r\n return 0;\r\n }\r\n return this.root.height;\r\n }\r\n /**\r\n * Queries the Dynamic Axis Aligned Tree for bodies that could be colliding with the provided body.\r\n *\r\n * In the query callback, it will be passed a potential collider. Returning true from this callback indicates\r\n * that you are complete with your query and you do not want to continue. Returning false will continue searching\r\n * the tree until all possible colliders have been returned.\r\n */\r\n query(collider, callback) {\r\n const bounds = collider.bounds;\r\n const helper = (currentNode) => {\r\n if (currentNode && currentNode.bounds.overlaps(bounds)) {\r\n if (currentNode.isLeaf() && currentNode.data !== collider) {\r\n if (callback.call(collider, currentNode.data)) {\r\n return true;\r\n }\r\n }\r\n else {\r\n return helper(currentNode.left) || helper(currentNode.right);\r\n }\r\n }\r\n return false;\r\n };\r\n helper(this.root);\r\n }\r\n /**\r\n * Queries the Dynamic Axis Aligned Tree for bodies that could be intersecting. By default the raycast query uses an infinitely\r\n * long ray to test the tree specified by `max`.\r\n *\r\n * In the query callback, it will be passed a potential body that intersects with the raycast. Returning true from this\r\n * callback indicates that your are complete with your query and do not want to continue. Return false will continue searching\r\n * the tree until all possible bodies that would intersect with the ray have been returned.\r\n */\r\n rayCastQuery(ray, max = Infinity, callback) {\r\n const helper = (currentNode) => {\r\n if (currentNode && currentNode.bounds.rayCast(ray, max)) {\r\n if (currentNode.isLeaf()) {\r\n if (callback.call(ray, currentNode.data)) {\r\n // ray hit a leaf! return the body\r\n return true;\r\n }\r\n }\r\n else {\r\n // ray hit but not at a leaf, recurse deeper\r\n return helper(currentNode.left) || helper(currentNode.right);\r\n }\r\n }\r\n return false; // ray missed\r\n };\r\n helper(this.root);\r\n }\r\n getNodes() {\r\n const helper = (currentNode) => {\r\n if (currentNode) {\r\n return [currentNode].concat(helper(currentNode.left), helper(currentNode.right));\r\n }\r\n else {\r\n return [];\r\n }\r\n };\r\n return helper(this.root);\r\n }\r\n debug(ex) {\r\n // draw all the nodes in the Dynamic Tree\r\n const helper = (currentNode) => {\r\n if (currentNode) {\r\n if (currentNode.isLeaf()) {\r\n currentNode.bounds.draw(ex, Color.Green);\r\n }\r\n else {\r\n currentNode.bounds.draw(ex, Color.White);\r\n }\r\n if (currentNode.left) {\r\n helper(currentNode.left);\r\n }\r\n if (currentNode.right) {\r\n helper(currentNode.right);\r\n }\r\n }\r\n };\r\n helper(this.root);\r\n }\r\n}\r\n\n;// CONCATENATED MODULE: ./Math/ray.ts\n/**\r\n * A 2D ray that can be cast into the scene to do collision detection\r\n */\r\nclass Ray {\r\n /**\r\n * @param pos The starting position for the ray\r\n * @param dir The vector indicating the direction of the ray\r\n */\r\n constructor(pos, dir) {\r\n this.pos = pos;\r\n this.dir = dir.normalize();\r\n }\r\n /**\r\n * Tests a whether this ray intersects with a line segment. Returns a number greater than or equal to 0 on success.\r\n * This number indicates the mathematical intersection time.\r\n * @param line The line to test\r\n */\r\n intersect(line) {\r\n const numerator = line.begin.sub(this.pos);\r\n // Test is line and ray are parallel and non intersecting\r\n if (this.dir.cross(line.getSlope()) === 0 && numerator.cross(this.dir) !== 0) {\r\n return -1;\r\n }\r\n // Lines are parallel\r\n const divisor = this.dir.cross(line.getSlope());\r\n if (divisor === 0) {\r\n return -1;\r\n }\r\n const t = numerator.cross(line.getSlope()) / divisor;\r\n if (t >= 0) {\r\n const u = numerator.cross(this.dir) / divisor / line.getLength();\r\n if (u >= 0 && u <= 1) {\r\n return t;\r\n }\r\n }\r\n return -1;\r\n }\r\n intersectPoint(line) {\r\n const time = this.intersect(line);\r\n if (time < 0) {\r\n return null;\r\n }\r\n return this.getPoint(time);\r\n }\r\n /**\r\n * Returns the point of intersection given the intersection time\r\n */\r\n getPoint(time) {\r\n return this.pos.add(this.dir.scale(time));\r\n }\r\n}\r\n\n;// CONCATENATED MODULE: ./Collision/Detection/DynamicTreeCollisionProcessor.ts\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n/**\r\n * Responsible for performing the collision broadphase (locating potential collisions) and\r\n * the narrowphase (actual collision contacts)\r\n */\r\nclass DynamicTreeCollisionProcessor {\r\n constructor() {\r\n this._dynamicCollisionTree = new DynamicTree();\r\n this._pairs = new Set();\r\n this._collisionPairCache = [];\r\n this._colliders = [];\r\n }\r\n getColliders() {\r\n return this._colliders;\r\n }\r\n rayCast(ray, options) {\r\n var _a, _b, _c;\r\n const results = [];\r\n const maxDistance = (_a = options === null || options === void 0 ? void 0 : options.maxDistance) !== null && _a !== void 0 ? _a : Infinity;\r\n const collisionGroup = (_b = options === null || options === void 0 ? void 0 : options.collisionGroup) !== null && _b !== void 0 ? _b : CollisionGroup.All;\r\n const searchAllColliders = (_c = options === null || options === void 0 ? void 0 : options.searchAllColliders) !== null && _c !== void 0 ? _c : false;\r\n this._dynamicCollisionTree.rayCastQuery(ray, maxDistance, (collider) => {\r\n var _a;\r\n const owner = collider.owner;\r\n const maybeBody = owner.get(BodyComponent);\r\n // Early exit if not the right group\r\n if (collisionGroup.mask !== CollisionGroup.All.mask && ((_a = maybeBody === null || maybeBody === void 0 ? void 0 : maybeBody.group) === null || _a === void 0 ? void 0 : _a.mask) !== collisionGroup.mask) {\r\n return false;\r\n }\r\n const hit = collider.rayCast(ray, maxDistance);\r\n if (hit) {\r\n results.push({\r\n distance: hit.sub(ray.pos).distance(),\r\n point: hit,\r\n collider: collider,\r\n body: maybeBody\r\n });\r\n if (!searchAllColliders) {\r\n // returning true exits the search\r\n return true;\r\n }\r\n }\r\n return false;\r\n });\r\n return results;\r\n }\r\n /**\r\n * Tracks a physics body for collisions\r\n */\r\n track(target) {\r\n if (!target) {\r\n Logger.getInstance().warn('Cannot track null collider');\r\n return;\r\n }\r\n if (target instanceof CompositeCollider) {\r\n const colliders = target.getColliders();\r\n for (const c of colliders) {\r\n c.owner = target.owner;\r\n this._colliders.push(c);\r\n this._dynamicCollisionTree.trackCollider(c);\r\n }\r\n }\r\n else {\r\n this._colliders.push(target);\r\n this._dynamicCollisionTree.trackCollider(target);\r\n }\r\n }\r\n /**\r\n * Untracks a physics body\r\n */\r\n untrack(target) {\r\n if (!target) {\r\n Logger.getInstance().warn('Cannot untrack a null collider');\r\n return;\r\n }\r\n if (target instanceof CompositeCollider) {\r\n const colliders = target.getColliders();\r\n for (const c of colliders) {\r\n const index = this._colliders.indexOf(c);\r\n if (index !== -1) {\r\n this._colliders.splice(index, 1);\r\n }\r\n this._dynamicCollisionTree.untrackCollider(c);\r\n }\r\n }\r\n else {\r\n const index = this._colliders.indexOf(target);\r\n if (index !== -1) {\r\n this._colliders.splice(index, 1);\r\n }\r\n this._dynamicCollisionTree.untrackCollider(target);\r\n }\r\n }\r\n _pairExists(colliderA, colliderB) {\r\n // if the collision pair has been calculated already short circuit\r\n const hash = Pair.calculatePairHash(colliderA.id, colliderB.id);\r\n return this._pairs.has(hash);\r\n }\r\n /**\r\n * Detects potential collision pairs in a broadphase approach with the dynamic AABB tree strategy\r\n */\r\n broadphase(targets, delta, stats) {\r\n const seconds = delta / 1000;\r\n // Retrieve the list of potential colliders, exclude killed, prevented, and self\r\n const potentialColliders = targets.filter((other) => {\r\n var _a, _b;\r\n const body = (_a = other.owner) === null || _a === void 0 ? void 0 : _a.get(BodyComponent);\r\n return ((_b = other.owner) === null || _b === void 0 ? void 0 : _b.active) && body.collisionType !== CollisionType.PreventCollision;\r\n });\r\n // clear old list of collision pairs\r\n this._collisionPairCache = [];\r\n this._pairs.clear();\r\n // check for normal collision pairs\r\n let collider;\r\n for (let j = 0, l = potentialColliders.length; j < l; j++) {\r\n collider = potentialColliders[j];\r\n // Query the collision tree for potential colliders\r\n this._dynamicCollisionTree.query(collider, (other) => {\r\n if (!this._pairExists(collider, other) && Pair.canCollide(collider, other)) {\r\n const pair = new Pair(collider, other);\r\n this._pairs.add(pair.id);\r\n this._collisionPairCache.push(pair);\r\n }\r\n // Always return false, to query whole tree. Returning true in the query method stops searching\r\n return false;\r\n });\r\n }\r\n if (stats) {\r\n stats.physics.pairs = this._collisionPairCache.length;\r\n }\r\n // Check dynamic tree for fast moving objects\r\n // Fast moving objects are those moving at least there smallest bound per frame\r\n if (Physics.checkForFastBodies) {\r\n for (const collider of potentialColliders) {\r\n const body = collider.owner.get(BodyComponent);\r\n // Skip non-active objects. Does not make sense on other collision types\r\n if (body.collisionType !== CollisionType.Active) {\r\n continue;\r\n }\r\n // Maximum travel distance next frame\r\n const updateDistance = body.vel.size * seconds + // velocity term\r\n body.acc.size * 0.5 * seconds * seconds; // acc term\r\n // Find the minimum dimension\r\n const minDimension = Math.min(collider.bounds.height, collider.bounds.width);\r\n if (Physics.disableMinimumSpeedForFastBody || updateDistance > minDimension / 2) {\r\n if (stats) {\r\n stats.physics.fastBodies++;\r\n }\r\n // start with the oldPos because the integration for actors has already happened\r\n // objects resting on a surface may be slightly penetrating in the current position\r\n const updateVec = body.globalPos.sub(body.oldPos);\r\n const centerPoint = collider.center;\r\n const furthestPoint = collider.getFurthestPoint(body.vel);\r\n const origin = furthestPoint.sub(updateVec);\r\n const ray = new Ray(origin, body.vel);\r\n // back the ray up by -2x surfaceEpsilon to account for fast moving objects starting on the surface\r\n ray.pos = ray.pos.add(ray.dir.scale(-2 * Physics.surfaceEpsilon));\r\n let minCollider;\r\n let minTranslate = new Vector(Infinity, Infinity);\r\n this._dynamicCollisionTree.rayCastQuery(ray, updateDistance + Physics.surfaceEpsilon * 2, (other) => {\r\n if (!this._pairExists(collider, other) && Pair.canCollide(collider, other)) {\r\n const hitPoint = other.rayCast(ray, updateDistance + Physics.surfaceEpsilon * 10);\r\n if (hitPoint) {\r\n const translate = hitPoint.sub(origin);\r\n if (translate.size < minTranslate.size) {\r\n minTranslate = translate;\r\n minCollider = other;\r\n }\r\n }\r\n }\r\n return false;\r\n });\r\n if (minCollider && Vector.isValid(minTranslate)) {\r\n const pair = new Pair(collider, minCollider);\r\n if (!this._pairs.has(pair.id)) {\r\n this._pairs.add(pair.id);\r\n this._collisionPairCache.push(pair);\r\n }\r\n // move the fast moving object to the other body\r\n // need to push into the surface by ex.Physics.surfaceEpsilon\r\n const shift = centerPoint.sub(furthestPoint);\r\n body.globalPos = origin\r\n .add(shift)\r\n .add(minTranslate)\r\n .add(ray.dir.scale(10 * Physics.surfaceEpsilon)); // needed to push the shape slightly into contact\r\n collider.update(body.transform.get());\r\n if (stats) {\r\n stats.physics.fastBodyCollisions++;\r\n }\r\n }\r\n }\r\n }\r\n }\r\n // return cache\r\n return this._collisionPairCache;\r\n }\r\n /**\r\n * Applies narrow phase on collision pairs to find actual area intersections\r\n * Adds actual colliding pairs to stats' Frame data\r\n */\r\n narrowphase(pairs, stats) {\r\n let contacts = [];\r\n for (let i = 0; i < pairs.length; i++) {\r\n const newContacts = pairs[i].collide();\r\n contacts = contacts.concat(newContacts);\r\n if (stats && newContacts.length > 0) {\r\n for (const c of newContacts) {\r\n stats.physics.contacts.set(c.id, c);\r\n }\r\n }\r\n }\r\n if (stats) {\r\n stats.physics.collisions += contacts.length;\r\n }\r\n return contacts;\r\n }\r\n /**\r\n * Update the dynamic tree positions\r\n */\r\n update(targets) {\r\n let updated = 0;\r\n const len = targets.length;\r\n for (let i = 0; i < len; i++) {\r\n if (this._dynamicCollisionTree.updateCollider(targets[i])) {\r\n updated++;\r\n }\r\n }\r\n return updated;\r\n }\r\n debug(ex) {\r\n this._dynamicCollisionTree.debug(ex);\r\n }\r\n}\r\n\n;// CONCATENATED MODULE: ./Collision/Colliders/Collider.ts\n\r\n\r\n/**\r\n * A collision collider specifies the geometry that can detect when other collision colliders intersect\r\n * for the purposes of colliding 2 objects in excalibur.\r\n */\r\nclass Collider {\r\n constructor() {\r\n this.id = createId('collider', Collider._ID++);\r\n /**\r\n * Excalibur uses this to signal to the [[CollisionSystem]] this is part of a composite collider\r\n * @internal\r\n * @hidden\r\n */\r\n this.__compositeColliderId = null;\r\n this.events = new EventEmitter();\r\n }\r\n /**\r\n * Returns a boolean indicating whether this body collided with\r\n * or was in stationary contact with\r\n * the body of the other [[Collider]]\r\n */\r\n touching(other) {\r\n const contact = this.collide(other);\r\n if (contact) {\r\n return true;\r\n }\r\n return false;\r\n }\r\n}\r\nCollider._ID = 0;\r\n\n;// CONCATENATED MODULE: ./Collision/Colliders/CompositeCollider.ts\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\nclass CompositeCollider extends Collider {\r\n constructor(colliders) {\r\n super();\r\n this._collisionProcessor = new DynamicTreeCollisionProcessor();\r\n this._dynamicAABBTree = new DynamicTree();\r\n this._colliders = [];\r\n for (const c of colliders) {\r\n this.addCollider(c);\r\n }\r\n }\r\n clearColliders() {\r\n this._colliders = [];\r\n }\r\n addCollider(collider) {\r\n collider.events.pipe(this.events);\r\n collider.__compositeColliderId = this.id;\r\n this._colliders.push(collider);\r\n this._collisionProcessor.track(collider);\r\n this._dynamicAABBTree.trackCollider(collider);\r\n }\r\n removeCollider(collider) {\r\n collider.events.pipe(this.events);\r\n collider.__compositeColliderId = null;\r\n removeItemFromArray(collider, this._colliders);\r\n this._collisionProcessor.untrack(collider);\r\n this._dynamicAABBTree.untrackCollider(collider);\r\n }\r\n getColliders() {\r\n return this._colliders;\r\n }\r\n get worldPos() {\r\n var _a, _b;\r\n // TODO transform component world pos\r\n return (_b = (_a = this._transform) === null || _a === void 0 ? void 0 : _a.pos) !== null && _b !== void 0 ? _b : Vector.Zero;\r\n }\r\n get center() {\r\n var _a, _b;\r\n return (_b = (_a = this._transform) === null || _a === void 0 ? void 0 : _a.pos) !== null && _b !== void 0 ? _b : Vector.Zero;\r\n }\r\n get bounds() {\r\n var _a, _b;\r\n // TODO cache this\r\n const colliders = this.getColliders();\r\n const results = colliders.reduce((acc, collider) => acc.combine(collider.bounds), (_b = (_a = colliders[0]) === null || _a === void 0 ? void 0 : _a.bounds) !== null && _b !== void 0 ? _b : new BoundingBox().translate(this.worldPos));\r\n return results;\r\n }\r\n get localBounds() {\r\n var _a, _b;\r\n // TODO cache this\r\n const colliders = this.getColliders();\r\n const results = colliders.reduce((acc, collider) => acc.combine(collider.localBounds), (_b = (_a = colliders[0]) === null || _a === void 0 ? void 0 : _a.localBounds) !== null && _b !== void 0 ? _b : new BoundingBox());\r\n return results;\r\n }\r\n get axes() {\r\n // TODO cache this\r\n const colliders = this.getColliders();\r\n let axes = [];\r\n for (const collider of colliders) {\r\n axes = axes.concat(collider.axes);\r\n }\r\n return axes;\r\n }\r\n getFurthestPoint(direction) {\r\n const colliders = this.getColliders();\r\n const furthestPoints = [];\r\n for (const collider of colliders) {\r\n furthestPoints.push(collider.getFurthestPoint(direction));\r\n }\r\n // Pick best point from all colliders\r\n let bestPoint = furthestPoints[0];\r\n let maxDistance = -Number.MAX_VALUE;\r\n for (const point of furthestPoints) {\r\n const distance = point.dot(direction);\r\n if (distance > maxDistance) {\r\n bestPoint = point;\r\n maxDistance = distance;\r\n }\r\n }\r\n return bestPoint;\r\n }\r\n getInertia(mass) {\r\n const colliders = this.getColliders();\r\n let totalInertia = 0;\r\n for (const collider of colliders) {\r\n totalInertia += collider.getInertia(mass);\r\n }\r\n return totalInertia;\r\n }\r\n collide(other) {\r\n let otherColliders = [other];\r\n if (other instanceof CompositeCollider) {\r\n otherColliders = other.getColliders();\r\n }\r\n const pairs = [];\r\n for (const c of otherColliders) {\r\n this._dynamicAABBTree.query(c, (potentialCollider) => {\r\n pairs.push(new Pair(c, potentialCollider));\r\n return false;\r\n });\r\n }\r\n let contacts = [];\r\n for (const p of pairs) {\r\n contacts = contacts.concat(p.collide());\r\n }\r\n return contacts;\r\n }\r\n getClosestLineBetween(other) {\r\n const colliders = this.getColliders();\r\n const lines = [];\r\n if (other instanceof CompositeCollider) {\r\n const otherColliders = other.getColliders();\r\n for (const colliderA of colliders) {\r\n for (const colliderB of otherColliders) {\r\n const maybeLine = colliderA.getClosestLineBetween(colliderB);\r\n if (maybeLine) {\r\n lines.push(maybeLine);\r\n }\r\n }\r\n }\r\n }\r\n else {\r\n for (const collider of colliders) {\r\n const maybeLine = other.getClosestLineBetween(collider);\r\n if (maybeLine) {\r\n lines.push(maybeLine);\r\n }\r\n }\r\n }\r\n if (lines.length) {\r\n let minLength = lines[0].getLength();\r\n let minLine = lines[0];\r\n for (const line of lines) {\r\n const length = line.getLength();\r\n if (length < minLength) {\r\n minLength = length;\r\n minLine = line;\r\n }\r\n }\r\n return minLine;\r\n }\r\n return null;\r\n }\r\n contains(point) {\r\n const colliders = this.getColliders();\r\n for (const collider of colliders) {\r\n if (collider.contains(point)) {\r\n return true;\r\n }\r\n }\r\n return false;\r\n }\r\n rayCast(ray, max) {\r\n const colliders = this.getColliders();\r\n const points = [];\r\n for (const collider of colliders) {\r\n const vec = collider.rayCast(ray, max);\r\n if (vec) {\r\n points.push(vec);\r\n }\r\n }\r\n if (points.length) {\r\n let minPoint = points[0];\r\n let minDistance = minPoint.dot(ray.dir);\r\n for (const point of points) {\r\n const distance = ray.dir.dot(point);\r\n if (distance < minDistance) {\r\n minPoint = point;\r\n minDistance = distance;\r\n }\r\n }\r\n return minPoint;\r\n }\r\n return null;\r\n }\r\n project(axis) {\r\n const colliders = this.getColliders();\r\n const projs = [];\r\n for (const collider of colliders) {\r\n const proj = collider.project(axis);\r\n if (proj) {\r\n projs.push(proj);\r\n }\r\n }\r\n // Merge all proj's on the same axis\r\n if (projs.length) {\r\n const newProjection = new Projection(projs[0].min, projs[0].max);\r\n for (const proj of projs) {\r\n newProjection.min = Math.min(proj.min, newProjection.min);\r\n newProjection.max = Math.max(proj.max, newProjection.max);\r\n }\r\n return newProjection;\r\n }\r\n return null;\r\n }\r\n update(transform) {\r\n if (transform) {\r\n const colliders = this.getColliders();\r\n for (const collider of colliders) {\r\n collider.owner = this.owner;\r\n collider.update(transform);\r\n }\r\n }\r\n }\r\n debug(ex, color) {\r\n const colliders = this.getColliders();\r\n for (const collider of colliders) {\r\n collider.debug(ex, color);\r\n }\r\n }\r\n clone() {\r\n return new CompositeCollider(this._colliders.map((c) => c.clone()));\r\n }\r\n}\r\n\n;// CONCATENATED MODULE: ./Math/line-segment.ts\n\r\n/**\r\n * A 2D line segment\r\n */\r\nclass LineSegment {\r\n /**\r\n * @param begin The starting point of the line segment\r\n * @param end The ending point of the line segment\r\n */\r\n constructor(begin, end) {\r\n this.begin = begin;\r\n this.end = end;\r\n }\r\n /**\r\n * Gets the raw slope (m) of the line. Will return (+/-)Infinity for vertical lines.\r\n */\r\n get slope() {\r\n return (this.end.y - this.begin.y) / (this.end.x - this.begin.x);\r\n }\r\n /**\r\n * Gets the Y-intercept (b) of the line. Will return (+/-)Infinity if there is no intercept.\r\n */\r\n get intercept() {\r\n return this.begin.y - this.slope * this.begin.x;\r\n }\r\n /**\r\n * Gets the normal of the line\r\n */\r\n normal() {\r\n if (this._normal) {\r\n return this._normal;\r\n }\r\n return this._normal = this.end.sub(this.begin).normal();\r\n }\r\n dir() {\r\n if (this._dir) {\r\n return this._dir;\r\n }\r\n return this._dir = this.end.sub(this.begin);\r\n }\r\n getPoints() {\r\n return [this.begin, this.end];\r\n }\r\n /**\r\n * Returns the slope of the line in the form of a vector of length 1\r\n */\r\n getSlope() {\r\n if (this._slope) {\r\n return this._slope;\r\n }\r\n const begin = this.begin;\r\n const end = this.end;\r\n const distance = begin.distance(end);\r\n return this._slope = end.sub(begin).scale(1 / distance);\r\n }\r\n /**\r\n * Returns the edge of the line as vector, the length of the vector is the length of the edge\r\n */\r\n getEdge() {\r\n const begin = this.begin;\r\n const end = this.end;\r\n return end.sub(begin);\r\n }\r\n /**\r\n * Returns the length of the line segment in pixels\r\n */\r\n getLength() {\r\n if (this._length) {\r\n return this._length;\r\n }\r\n const begin = this.begin;\r\n const end = this.end;\r\n const distance = begin.distance(end);\r\n return this._length = distance;\r\n }\r\n /**\r\n * Returns the midpoint of the edge\r\n */\r\n get midpoint() {\r\n return this.begin.add(this.end).scale(0.5);\r\n }\r\n /**\r\n * Flips the direction of the line segment\r\n */\r\n flip() {\r\n return new LineSegment(this.end, this.begin);\r\n }\r\n /**\r\n * Tests if a given point is below the line, points in the normal direction above the line are considered above.\r\n * @param point\r\n */\r\n below(point) {\r\n const above2 = (this.end.x - this.begin.x) * (point.y - this.begin.y) - (this.end.y - this.begin.y) * (point.x - this.begin.x);\r\n return above2 >= 0;\r\n }\r\n /**\r\n * Returns the clip point\r\n * @param sideVector Vector that traces the line\r\n * @param length Length to clip along side\r\n */\r\n clip(sideVector, length) {\r\n let dir = sideVector;\r\n dir = dir.normalize();\r\n const near = dir.dot(this.begin) - length;\r\n const far = dir.dot(this.end) - length;\r\n const results = [];\r\n if (near <= 0) {\r\n results.push(this.begin);\r\n }\r\n if (far <= 0) {\r\n results.push(this.end);\r\n }\r\n if (near * far < 0) {\r\n const clipTime = near / (near - far);\r\n results.push(this.begin.add(this.end.sub(this.begin).scale(clipTime)));\r\n }\r\n if (results.length !== 2) {\r\n return null;\r\n }\r\n return new LineSegment(results[0], results[1]);\r\n }\r\n /**\r\n * Find the perpendicular distance from the line to a point\r\n * https://en.wikipedia.org/wiki/Distance_from_a_point_to_a_line\r\n * @param point\r\n */\r\n distanceToPoint(point, signed = false) {\r\n const x0 = point.x;\r\n const y0 = point.y;\r\n const l = this.getLength();\r\n const dy = this.end.y - this.begin.y;\r\n const dx = this.end.x - this.begin.x;\r\n const distance = (dy * x0 - dx * y0 + this.end.x * this.begin.y - this.end.y * this.begin.x) / l;\r\n return signed ? distance : Math.abs(distance);\r\n }\r\n /**\r\n * Find the perpendicular line from the line to a point\r\n * https://en.wikipedia.org/wiki/Distance_from_a_point_to_a_line\r\n * (a - p) - ((a - p) * n)n\r\n * a is a point on the line\r\n * p is the arbitrary point above the line\r\n * n is a unit vector in direction of the line\r\n * @param point\r\n */\r\n findVectorToPoint(point) {\r\n const aMinusP = this.begin.sub(point);\r\n const n = this.getSlope();\r\n return aMinusP.sub(n.scale(aMinusP.dot(n)));\r\n }\r\n /**\r\n * Finds a point on the line given only an X or a Y value. Given an X value, the function returns\r\n * a new point with the calculated Y value and vice-versa.\r\n *\r\n * @param x The known X value of the target point\r\n * @param y The known Y value of the target point\r\n * @returns A new point with the other calculated axis value\r\n */\r\n findPoint(x = null, y = null) {\r\n const m = this.slope;\r\n const b = this.intercept;\r\n if (x !== null) {\r\n return new Vector(x, m * x + b);\r\n }\r\n else if (y !== null) {\r\n return new Vector((y - b) / m, y);\r\n }\r\n else {\r\n throw new Error('You must provide an X or a Y value');\r\n }\r\n }\r\n /**\r\n * @see http://stackoverflow.com/a/11908158/109458\r\n */\r\n hasPoint() {\r\n let currPoint;\r\n let threshold = 0;\r\n if (typeof arguments[0] === 'number' && typeof arguments[1] === 'number') {\r\n currPoint = new Vector(arguments[0], arguments[1]);\r\n threshold = arguments[2] || 0;\r\n }\r\n else if (arguments[0] instanceof Vector) {\r\n currPoint = arguments[0];\r\n threshold = arguments[1] || 0;\r\n }\r\n else {\r\n throw 'Could not determine the arguments for Vector.hasPoint';\r\n }\r\n const dxc = currPoint.x - this.begin.x;\r\n const dyc = currPoint.y - this.begin.y;\r\n const dx1 = this.end.x - this.begin.x;\r\n const dy1 = this.end.y - this.begin.y;\r\n const cross = dxc * dy1 - dyc * dx1;\r\n // check whether point lines on the line\r\n if (Math.abs(cross) > threshold) {\r\n return false;\r\n }\r\n // check whether point lies in-between start and end\r\n if (Math.abs(dx1) >= Math.abs(dy1)) {\r\n return dx1 > 0 ? this.begin.x <= currPoint.x && currPoint.x <= this.end.x : this.end.x <= currPoint.x && currPoint.x <= this.begin.x;\r\n }\r\n else {\r\n return dy1 > 0 ? this.begin.y <= currPoint.y && currPoint.y <= this.end.y : this.end.y <= currPoint.y && currPoint.y <= this.begin.y;\r\n }\r\n }\r\n}\r\n\n;// CONCATENATED MODULE: ./Collision/Colliders/ClosestLineJumpTable.ts\n\r\n\r\n\r\n/**\r\n * Finds the closes line between 2 line segments, were the magnitude of u, v are the lengths of each segment\r\n * L1 = P(s) = p0 + s * u, where s is time and p0 is the start of the line\r\n * L2 = Q(t) = q0 + t * v, where t is time and q0 is the start of the line\r\n * @param p0 Point where L1 begins\r\n * @param u Direction and length of L1\r\n * @param q0 Point were L2 begins\r\n * @param v Direction and length of L2\r\n */\r\nfunction ClosestLine(p0, u, q0, v) {\r\n // Distance between 2 lines http://geomalgorithms.com/a07-_distance.html\r\n // w(s, t) = P(s) - Q(t)\r\n // The w(s, t) that has the minimum distance we will say is w(sClosest, tClosest) = wClosest\r\n //\r\n // wClosest is the vector that is uniquely perpendicular to the 2 line directions u & v.\r\n // wClosest = w0 + sClosest * u - tClosest * v, where w0 is p0 - q0\r\n //\r\n // The closest point between 2 lines then satisfies this pair of equations\r\n // 1: u * wClosest = 0\r\n // 2: v * wClosest = 0\r\n //\r\n // Substituting wClosest into the equations we get\r\n //\r\n // 1: (u * u) * sClosest - (u * v) tClosest = -u * w0\r\n // 2: (v * u) * sClosest - (v * v) tClosest = -v * w0\r\n // simplify w0\r\n const w0 = p0.sub(q0);\r\n // simplify (u * u);\r\n const a = u.dot(u);\r\n // simplify (u * v);\r\n const b = u.dot(v);\r\n // simplify (v * v)\r\n const c = v.dot(v);\r\n // simplify (u * w0)\r\n const d = u.dot(w0);\r\n // simplify (v * w0)\r\n const e = v.dot(w0);\r\n // denominator ac - b^2\r\n const denom = a * c - b * b;\r\n let sDenom = denom;\r\n let tDenom = denom;\r\n // if denom is 0 they are parallel, use any point from either as the start in this case p0\r\n if (denom === 0 || denom <= 0.01) {\r\n const tClosestParallel = d / b;\r\n return new LineSegment(p0, q0.add(v.scale(tClosestParallel)));\r\n }\r\n // Solve for sClosest for infinite line\r\n let sClosest = b * e - c * d; // / denom;\r\n // Solve for tClosest for infinite line\r\n let tClosest = a * e - b * d; // / denom;\r\n // Solve for segments candidate edges, if sClosest and tClosest are outside their segments\r\n if (sClosest < 0) {\r\n sClosest = 0;\r\n tClosest = e;\r\n tDenom = c;\r\n }\r\n else if (sClosest > sDenom) {\r\n sClosest = sDenom;\r\n tClosest = e + b;\r\n tDenom = c;\r\n }\r\n if (tClosest < 0) {\r\n tClosest = 0;\r\n if (-d < 0) {\r\n sClosest = 0;\r\n }\r\n else if (-d > a) {\r\n sClosest = sDenom;\r\n }\r\n else {\r\n sClosest = -d;\r\n sDenom = a;\r\n }\r\n }\r\n else if (tClosest > tDenom) {\r\n tClosest = tDenom;\r\n if (-d + b < 0) {\r\n sClosest = 0;\r\n }\r\n else if (-d + b > a) {\r\n sClosest = sDenom;\r\n }\r\n else {\r\n sClosest = -d + b;\r\n sDenom = a;\r\n }\r\n }\r\n sClosest = Math.abs(sClosest) < 0.001 ? 0 : sClosest / sDenom;\r\n tClosest = Math.abs(tClosest) < 0.001 ? 0 : tClosest / tDenom;\r\n return new LineSegment(p0.add(u.scale(sClosest)), q0.add(v.scale(tClosest)));\r\n}\r\nconst ClosestLineJumpTable = {\r\n PolygonPolygonClosestLine(polygonA, polygonB) {\r\n // Find the 2 closest faces on each polygon\r\n const otherWorldPos = polygonB.worldPos;\r\n const otherDirection = otherWorldPos.sub(polygonA.worldPos);\r\n const thisDirection = otherDirection.negate();\r\n const rayTowardsOther = new Ray(polygonA.worldPos, otherDirection);\r\n const rayTowardsThis = new Ray(otherWorldPos, thisDirection);\r\n const thisPoint = polygonA.rayCast(rayTowardsOther).add(rayTowardsOther.dir.scale(0.1));\r\n const otherPoint = polygonB.rayCast(rayTowardsThis).add(rayTowardsThis.dir.scale(0.1));\r\n const thisFace = polygonA.getClosestFace(thisPoint);\r\n const otherFace = polygonB.getClosestFace(otherPoint);\r\n // L1 = P(s) = p0 + s * u, where s is time and p0 is the start of the line\r\n const p0 = thisFace.face.begin;\r\n const u = thisFace.face.getEdge();\r\n // L2 = Q(t) = q0 + t * v, where t is time and q0 is the start of the line\r\n const q0 = otherFace.face.begin;\r\n const v = otherFace.face.getEdge();\r\n return ClosestLine(p0, u, q0, v);\r\n },\r\n PolygonEdgeClosestLine(polygon, edge) {\r\n // Find the 2 closest faces on each polygon\r\n const otherWorldPos = edge.worldPos;\r\n const otherDirection = otherWorldPos.sub(polygon.worldPos);\r\n const rayTowardsOther = new Ray(polygon.worldPos, otherDirection);\r\n const thisPoint = polygon.rayCast(rayTowardsOther).add(rayTowardsOther.dir.scale(0.1));\r\n const thisFace = polygon.getClosestFace(thisPoint);\r\n // L1 = P(s) = p0 + s * u, where s is time and p0 is the start of the line\r\n const p0 = thisFace.face.begin;\r\n const u = thisFace.face.getEdge();\r\n // L2 = Q(t) = q0 + t * v, where t is time and q0 is the start of the line\r\n const edgeLine = edge.asLine();\r\n const edgeStart = edgeLine.begin;\r\n const edgeVector = edgeLine.getEdge();\r\n const q0 = edgeStart;\r\n const v = edgeVector;\r\n return ClosestLine(p0, u, q0, v);\r\n },\r\n PolygonCircleClosestLine(polygon, circle) {\r\n // https://math.stackexchange.com/questions/1919177/how-to-find-point-on-line-closest-to-sphere\r\n // Find the 2 closest faces on each polygon\r\n const otherWorldPos = circle.worldPos;\r\n const otherDirection = otherWorldPos.sub(polygon.worldPos);\r\n const rayTowardsOther = new Ray(polygon.worldPos, otherDirection.normalize());\r\n const thisPoint = polygon.rayCast(rayTowardsOther).add(rayTowardsOther.dir.scale(0.1));\r\n const thisFace = polygon.getClosestFace(thisPoint);\r\n // L1 = P(s) = p0 + s * u, where s is time and p0 is the start of the line\r\n const p0 = thisFace.face.begin;\r\n const u = thisFace.face.getEdge();\r\n // Time of minimum distance\r\n let t = (u.x * (otherWorldPos.x - p0.x) + u.y * (otherWorldPos.y - p0.y)) / (u.x * u.x + u.y * u.y);\r\n // If time of minimum is past the edge clamp\r\n if (t > 1) {\r\n t = 1;\r\n }\r\n else if (t < 0) {\r\n t = 0;\r\n }\r\n // Minimum distance\r\n const d = Math.sqrt(Math.pow(p0.x + u.x * t - otherWorldPos.x, 2) + Math.pow(p0.y + u.y * t - otherWorldPos.y, 2)) - circle.radius;\r\n const circlex = ((p0.x + u.x * t - otherWorldPos.x) * circle.radius) / (circle.radius + d);\r\n const circley = ((p0.y + u.y * t - otherWorldPos.y) * circle.radius) / (circle.radius + d);\r\n return new LineSegment(u.scale(t).add(p0), new Vector(otherWorldPos.x + circlex, otherWorldPos.y + circley));\r\n },\r\n CircleCircleClosestLine(circleA, circleB) {\r\n // Find the 2 closest faces on each polygon\r\n const otherWorldPos = circleB.worldPos;\r\n const otherDirection = otherWorldPos.sub(circleA.worldPos);\r\n const thisWorldPos = circleA.worldPos;\r\n const thisDirection = thisWorldPos.sub(circleB.worldPos);\r\n const rayTowardsOther = new Ray(circleA.worldPos, otherDirection);\r\n const rayTowardsThis = new Ray(circleB.worldPos, thisDirection);\r\n const thisPoint = circleA.rayCast(rayTowardsOther);\r\n const otherPoint = circleB.rayCast(rayTowardsThis);\r\n return new LineSegment(thisPoint, otherPoint);\r\n },\r\n CircleEdgeClosestLine(circle, edge) {\r\n // https://math.stackexchange.com/questions/1919177/how-to-find-point-on-line-closest-to-sphere\r\n const circleWorlPos = circle.worldPos;\r\n // L1 = P(s) = p0 + s * u, where s is time and p0 is the start of the line\r\n const edgeLine = edge.asLine();\r\n const edgeStart = edgeLine.begin;\r\n const edgeVector = edgeLine.getEdge();\r\n const p0 = edgeStart;\r\n const u = edgeVector;\r\n // Time of minimum distance\r\n let t = (u.x * (circleWorlPos.x - p0.x) + u.y * (circleWorlPos.y - p0.y)) / (u.x * u.x + u.y * u.y);\r\n // If time of minimum is past the edge clamp to edge\r\n if (t > 1) {\r\n t = 1;\r\n }\r\n else if (t < 0) {\r\n t = 0;\r\n }\r\n // Minimum distance\r\n const d = Math.sqrt(Math.pow(p0.x + u.x * t - circleWorlPos.x, 2) + Math.pow(p0.y + u.y * t - circleWorlPos.y, 2)) - circle.radius;\r\n const circlex = ((p0.x + u.x * t - circleWorlPos.x) * circle.radius) / (circle.radius + d);\r\n const circley = ((p0.y + u.y * t - circleWorlPos.y) * circle.radius) / (circle.radius + d);\r\n return new LineSegment(u.scale(t).add(p0), new Vector(circleWorlPos.x + circlex, circleWorlPos.y + circley));\r\n },\r\n EdgeEdgeClosestLine(edgeA, edgeB) {\r\n // L1 = P(s) = p0 + s * u, where s is time and p0 is the start of the line\r\n const edgeLineA = edgeA.asLine();\r\n const edgeStartA = edgeLineA.begin;\r\n const edgeVectorA = edgeLineA.getEdge();\r\n const p0 = edgeStartA;\r\n const u = edgeVectorA;\r\n // L2 = Q(t) = q0 + t * v, where t is time and q0 is the start of the line\r\n const edgeLineB = edgeB.asLine();\r\n const edgeStartB = edgeLineB.begin;\r\n const edgeVectorB = edgeLineB.getEdge();\r\n const q0 = edgeStartB;\r\n const v = edgeVectorB;\r\n return ClosestLine(p0, u, q0, v);\r\n }\r\n};\r\n\n;// CONCATENATED MODULE: ./Collision/Colliders/CircleCollider.ts\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n/**\r\n * This is a circle collider for the excalibur rigid body physics simulation\r\n */\r\nclass CircleCollider extends Collider {\r\n get worldPos() {\r\n return this._globalMatrix.getPosition();\r\n }\r\n /**\r\n * Get the radius of the circle\r\n */\r\n get radius() {\r\n var _a;\r\n const tx = this._transform;\r\n const scale = (_a = tx === null || tx === void 0 ? void 0 : tx.globalScale) !== null && _a !== void 0 ? _a : Vector.One;\r\n // This is a trade off, the alternative is retooling circles to support ellipse collisions\r\n return this._naturalRadius * Math.min(scale.x, scale.y);\r\n }\r\n /**\r\n * Set the radius of the circle\r\n */\r\n set radius(val) {\r\n var _a;\r\n const tx = this._transform;\r\n const scale = (_a = tx === null || tx === void 0 ? void 0 : tx.globalScale) !== null && _a !== void 0 ? _a : Vector.One;\r\n // This is a trade off, the alternative is retooling circles to support ellipse collisions\r\n this._naturalRadius = val / Math.min(scale.x, scale.y);\r\n }\r\n constructor(options) {\r\n super();\r\n /**\r\n * Position of the circle relative to the collider, by default (0, 0).\r\n */\r\n this.offset = Vector.Zero;\r\n this._globalMatrix = AffineMatrix.identity();\r\n this.offset = options.offset || Vector.Zero;\r\n this.radius = options.radius || 0;\r\n this._globalMatrix.translate(this.offset.x, this.offset.y);\r\n }\r\n /**\r\n * Returns a clone of this shape, not associated with any collider\r\n */\r\n clone() {\r\n return new CircleCollider({\r\n offset: this.offset.clone(),\r\n radius: this.radius\r\n });\r\n }\r\n /**\r\n * Get the center of the collider in world coordinates\r\n */\r\n get center() {\r\n return this._globalMatrix.getPosition();\r\n }\r\n /**\r\n * Tests if a point is contained in this collider\r\n */\r\n contains(point) {\r\n var _a, _b;\r\n const pos = (_b = (_a = this._transform) === null || _a === void 0 ? void 0 : _a.pos) !== null && _b !== void 0 ? _b : this.offset;\r\n const distance = pos.distance(point);\r\n if (distance <= this.radius) {\r\n return true;\r\n }\r\n return false;\r\n }\r\n /**\r\n * Casts a ray at the Circle collider and returns the nearest point of collision\r\n * @param ray\r\n */\r\n rayCast(ray, max = Infinity) {\r\n //https://en.wikipedia.org/wiki/Line%E2%80%93sphere_intersection\r\n const c = this.center;\r\n const dir = ray.dir;\r\n const orig = ray.pos;\r\n const discriminant = Math.sqrt(Math.pow(dir.dot(orig.sub(c)), 2) - Math.pow(orig.sub(c).distance(), 2) + Math.pow(this.radius, 2));\r\n if (discriminant < 0) {\r\n // no intersection\r\n return null;\r\n }\r\n else {\r\n let toi = 0;\r\n if (discriminant === 0) {\r\n toi = -dir.dot(orig.sub(c));\r\n if (toi > 0 && toi < max) {\r\n return ray.getPoint(toi);\r\n }\r\n return null;\r\n }\r\n else {\r\n const toi1 = -dir.dot(orig.sub(c)) + discriminant;\r\n const toi2 = -dir.dot(orig.sub(c)) - discriminant;\r\n const positiveToi = [];\r\n if (toi1 >= 0) {\r\n positiveToi.push(toi1);\r\n }\r\n if (toi2 >= 0) {\r\n positiveToi.push(toi2);\r\n }\r\n const mintoi = Math.min(...positiveToi);\r\n if (mintoi <= max) {\r\n return ray.getPoint(mintoi);\r\n }\r\n return null;\r\n }\r\n }\r\n }\r\n getClosestLineBetween(shape) {\r\n if (shape instanceof CircleCollider) {\r\n return ClosestLineJumpTable.CircleCircleClosestLine(this, shape);\r\n }\r\n else if (shape instanceof PolygonCollider) {\r\n return ClosestLineJumpTable.PolygonCircleClosestLine(shape, this).flip();\r\n }\r\n else if (shape instanceof EdgeCollider) {\r\n return ClosestLineJumpTable.CircleEdgeClosestLine(this, shape).flip();\r\n }\r\n else {\r\n throw new Error(`Polygon could not collide with unknown CollisionShape ${typeof shape}`);\r\n }\r\n }\r\n /**\r\n * @inheritdoc\r\n */\r\n collide(collider) {\r\n if (collider instanceof CircleCollider) {\r\n return CollisionJumpTable.CollideCircleCircle(this, collider);\r\n }\r\n else if (collider instanceof PolygonCollider) {\r\n return CollisionJumpTable.CollideCirclePolygon(this, collider);\r\n }\r\n else if (collider instanceof EdgeCollider) {\r\n return CollisionJumpTable.CollideCircleEdge(this, collider);\r\n }\r\n else {\r\n throw new Error(`Circle could not collide with unknown CollisionShape ${typeof collider}`);\r\n }\r\n }\r\n /**\r\n * Find the point on the collider furthest in the direction specified\r\n */\r\n getFurthestPoint(direction) {\r\n return this.center.add(direction.normalize().scale(this.radius));\r\n }\r\n /**\r\n * Find the local point on the shape in the direction specified\r\n * @param direction\r\n */\r\n getFurthestLocalPoint(direction) {\r\n const dir = direction.normalize();\r\n return dir.scale(this.radius);\r\n }\r\n /**\r\n * Get the axis aligned bounding box for the circle collider in world coordinates\r\n */\r\n get bounds() {\r\n var _a, _b, _c;\r\n const tx = this._transform;\r\n const scale = (_a = tx === null || tx === void 0 ? void 0 : tx.globalScale) !== null && _a !== void 0 ? _a : Vector.One;\r\n const rotation = (_b = tx === null || tx === void 0 ? void 0 : tx.globalRotation) !== null && _b !== void 0 ? _b : 0;\r\n const pos = ((_c = tx === null || tx === void 0 ? void 0 : tx.globalPos) !== null && _c !== void 0 ? _c : Vector.Zero);\r\n return new BoundingBox(this.offset.x - this._naturalRadius, this.offset.y - this._naturalRadius, this.offset.x + this._naturalRadius, this.offset.y + this._naturalRadius).rotate(rotation).scale(scale).translate(pos);\r\n }\r\n /**\r\n * Get the axis aligned bounding box for the circle collider in local coordinates\r\n */\r\n get localBounds() {\r\n return new BoundingBox(this.offset.x - this._naturalRadius, this.offset.y - this._naturalRadius, this.offset.x + this._naturalRadius, this.offset.y + this._naturalRadius);\r\n }\r\n /**\r\n * Get axis not implemented on circles, since there are infinite axis in a circle\r\n */\r\n get axes() {\r\n return [];\r\n }\r\n /**\r\n * Returns the moment of inertia of a circle given it's mass\r\n * https://en.wikipedia.org/wiki/List_of_moments_of_inertia\r\n */\r\n getInertia(mass) {\r\n return (mass * this.radius * this.radius) / 2;\r\n }\r\n /* istanbul ignore next */\r\n update(transform) {\r\n var _a;\r\n this._transform = transform;\r\n const globalMat = (_a = transform.matrix) !== null && _a !== void 0 ? _a : this._globalMatrix;\r\n globalMat.clone(this._globalMatrix);\r\n this._globalMatrix.translate(this.offset.x, this.offset.y);\r\n }\r\n /**\r\n * Project the circle along a specified axis\r\n */\r\n project(axis) {\r\n const scalars = [];\r\n const point = this.center;\r\n const dotProduct = point.dot(axis);\r\n scalars.push(dotProduct);\r\n scalars.push(dotProduct + this.radius);\r\n scalars.push(dotProduct - this.radius);\r\n return new Projection(Math.min.apply(Math, scalars), Math.max.apply(Math, scalars));\r\n }\r\n debug(ex, color) {\r\n var _a, _b, _c, _d;\r\n const tx = this._transform;\r\n const scale = (_a = tx === null || tx === void 0 ? void 0 : tx.globalScale) !== null && _a !== void 0 ? _a : Vector.One;\r\n const rotation = (_b = tx === null || tx === void 0 ? void 0 : tx.globalRotation) !== null && _b !== void 0 ? _b : 0;\r\n const pos = ((_c = tx === null || tx === void 0 ? void 0 : tx.globalPos) !== null && _c !== void 0 ? _c : Vector.Zero);\r\n ex.save();\r\n ex.translate(pos.x, pos.y);\r\n ex.rotate(rotation);\r\n ex.scale(scale.x, scale.y);\r\n ex.drawCircle(((_d = this.offset) !== null && _d !== void 0 ? _d : Vector.Zero), this._naturalRadius, Color.Transparent, color, 2);\r\n ex.restore();\r\n }\r\n}\r\n\n;// CONCATENATED MODULE: ./Collision/Detection/CollisionContact.ts\n\r\n\r\n\r\n\r\n/**\r\n * Collision contacts are used internally by Excalibur to resolve collision between colliders. This\r\n * Pair prevents collisions from being evaluated more than one time\r\n */\r\nclass CollisionContact {\r\n constructor(colliderA, colliderB, mtv, normal, tangent, points, localPoints, info) {\r\n var _a, _b;\r\n this._canceled = false;\r\n this.colliderA = colliderA;\r\n this.colliderB = colliderB;\r\n this.mtv = mtv;\r\n this.normal = normal;\r\n this.tangent = tangent;\r\n this.points = points;\r\n this.localPoints = localPoints;\r\n this.info = info;\r\n this.id = Pair.calculatePairHash(colliderA.id, colliderB.id);\r\n if (colliderA.__compositeColliderId || colliderB.__compositeColliderId) {\r\n // Add on the parent composite pair for start/end contact\r\n this.id += '|' + Pair.calculatePairHash((_a = colliderA.__compositeColliderId) !== null && _a !== void 0 ? _a : colliderA.id, (_b = colliderB.__compositeColliderId) !== null && _b !== void 0 ? _b : colliderB.id);\r\n }\r\n }\r\n /**\r\n * Match contact awake state, except if body's are Fixed\r\n */\r\n matchAwake() {\r\n const bodyA = this.colliderA.owner.get(BodyComponent);\r\n const bodyB = this.colliderB.owner.get(BodyComponent);\r\n if (bodyA && bodyB) {\r\n if (bodyA.sleeping !== bodyB.sleeping) {\r\n if (bodyA.sleeping && bodyA.collisionType !== CollisionType.Fixed && bodyB.sleepMotion >= Physics.wakeThreshold) {\r\n bodyA.setSleeping(false);\r\n }\r\n if (bodyB.sleeping && bodyB.collisionType !== CollisionType.Fixed && bodyA.sleepMotion >= Physics.wakeThreshold) {\r\n bodyB.setSleeping(false);\r\n }\r\n }\r\n }\r\n }\r\n isCanceled() {\r\n return this._canceled;\r\n }\r\n cancel() {\r\n this._canceled = true;\r\n }\r\n}\r\n\n;// CONCATENATED MODULE: ./Collision/Colliders/SeparatingAxis.ts\nclass SeparatingAxis {\r\n static findPolygonPolygonSeparation(polyA, polyB) {\r\n let bestSeparation = -Number.MAX_VALUE;\r\n let bestSide = null;\r\n let bestAxis = null;\r\n let bestSideIndex = -1;\r\n let bestOtherPoint = null;\r\n const sides = polyA.getSides();\r\n const localSides = polyA.getLocalSides();\r\n for (let i = 0; i < sides.length; i++) {\r\n const side = sides[i];\r\n const axis = side.normal();\r\n const vertB = polyB.getFurthestPoint(axis.negate());\r\n // Separation on side i's axis\r\n // We are looking for the largest separation between poly A's sides\r\n const vertSeparation = side.distanceToPoint(vertB, true);\r\n if (vertSeparation > bestSeparation) {\r\n bestSeparation = vertSeparation;\r\n bestSide = side;\r\n bestAxis = axis;\r\n bestSideIndex = i;\r\n bestOtherPoint = vertB;\r\n }\r\n }\r\n return {\r\n collider: polyA,\r\n separation: bestAxis ? bestSeparation : 99,\r\n axis: bestAxis,\r\n side: bestSide,\r\n localSide: localSides[bestSideIndex],\r\n sideId: bestSideIndex,\r\n point: bestOtherPoint,\r\n localPoint: bestAxis ? polyB.getFurthestLocalPoint(bestAxis.negate()) : null\r\n };\r\n }\r\n static findCirclePolygonSeparation(circle, polygon) {\r\n const axes = polygon.axes;\r\n const pc = polygon.center;\r\n // Special SAT with circles\r\n const polyDir = pc.sub(circle.worldPos);\r\n const closestPointOnPoly = polygon.getFurthestPoint(polyDir.negate());\r\n axes.push(closestPointOnPoly.sub(circle.worldPos).normalize());\r\n let minOverlap = Number.MAX_VALUE;\r\n let minAxis = null;\r\n let minIndex = -1;\r\n for (let i = 0; i < axes.length; i++) {\r\n const proj1 = polygon.project(axes[i]);\r\n const proj2 = circle.project(axes[i]);\r\n const overlap = proj1.getOverlap(proj2);\r\n if (overlap <= 0) {\r\n return null;\r\n }\r\n else {\r\n if (overlap < minOverlap) {\r\n minOverlap = overlap;\r\n minAxis = axes[i];\r\n minIndex = i;\r\n }\r\n }\r\n }\r\n if (minIndex < 0) {\r\n return null;\r\n }\r\n return minAxis.normalize().scale(minOverlap);\r\n }\r\n}\r\n\n;// CONCATENATED MODULE: ./Collision/Colliders/CollisionJumpTable.ts\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\nconst CollisionJumpTable = {\r\n CollideCircleCircle(circleA, circleB) {\r\n const circleAPos = circleA.worldPos;\r\n const circleBPos = circleB.worldPos;\r\n const combinedRadius = circleA.radius + circleB.radius;\r\n const distance = circleAPos.distance(circleBPos);\r\n if (distance > combinedRadius) {\r\n return [];\r\n }\r\n // negative means overlap\r\n const separation = combinedRadius - distance;\r\n // Normal points from A -> B\r\n const normal = circleBPos.sub(circleAPos).normalize();\r\n const tangent = normal.perpendicular();\r\n const mvt = normal.scale(separation);\r\n const point = circleA.getFurthestPoint(normal);\r\n const local = circleA.getFurthestLocalPoint(normal);\r\n const info = {\r\n collider: circleA,\r\n separation,\r\n axis: normal,\r\n point: point\r\n };\r\n return [new CollisionContact(circleA, circleB, mvt, normal, tangent, [point], [local], info)];\r\n },\r\n CollideCirclePolygon(circle, polygon) {\r\n var _a, _b;\r\n let minAxis = SeparatingAxis.findCirclePolygonSeparation(circle, polygon);\r\n if (!minAxis) {\r\n return [];\r\n }\r\n // make sure that the minAxis is pointing away from circle\r\n const samedir = minAxis.dot(polygon.center.sub(circle.center));\r\n minAxis = samedir < 0 ? minAxis.negate() : minAxis;\r\n const point = circle.getFurthestPoint(minAxis);\r\n const xf = (_b = (_a = circle.owner) === null || _a === void 0 ? void 0 : _a.get(TransformComponent)) !== null && _b !== void 0 ? _b : new TransformComponent();\r\n const local = xf.applyInverse(point);\r\n const normal = minAxis.normalize();\r\n const info = {\r\n collider: circle,\r\n separation: -minAxis.size,\r\n axis: normal,\r\n point: point,\r\n localPoint: local,\r\n side: polygon.findSide(normal.negate()),\r\n localSide: polygon.findLocalSide(normal.negate())\r\n };\r\n return [new CollisionContact(circle, polygon, minAxis, normal, normal.perpendicular(), [point], [local], info)];\r\n },\r\n CollideCircleEdge(circle, edge) {\r\n // TODO not sure this actually abides by local/world collisions\r\n // Are edge.begin and edge.end local space or world space? I think they should be local\r\n // center of the circle in world pos\r\n const cc = circle.center;\r\n // vector in the direction of the edge\r\n const edgeWorld = edge.asLine();\r\n const e = edgeWorld.end.sub(edgeWorld.begin);\r\n // amount of overlap with the circle's center along the edge direction\r\n const u = e.dot(edgeWorld.end.sub(cc));\r\n const v = e.dot(cc.sub(edgeWorld.begin));\r\n const side = edge.asLine();\r\n const localSide = edge.asLocalLine();\r\n // Potential region A collision (circle is on the left side of the edge, before the beginning)\r\n if (v <= 0) {\r\n const da = edgeWorld.begin.sub(cc);\r\n const dda = da.dot(da); // quick and dirty way of calc'n distance in r^2 terms saves some sqrts\r\n // save some sqrts\r\n if (dda > circle.radius * circle.radius) {\r\n return []; // no collision\r\n }\r\n const normal = da.normalize();\r\n const separation = circle.radius - Math.sqrt(dda);\r\n const info = {\r\n collider: circle,\r\n separation: separation,\r\n axis: normal,\r\n point: side.begin,\r\n side: side,\r\n localSide: localSide\r\n };\r\n return [\r\n new CollisionContact(circle, edge, normal.scale(separation), normal, normal.perpendicular(), [side.begin], [localSide.begin], info)\r\n ];\r\n }\r\n // Potential region B collision (circle is on the right side of the edge, after the end)\r\n if (u <= 0) {\r\n const db = edgeWorld.end.sub(cc);\r\n const ddb = db.dot(db);\r\n if (ddb > circle.radius * circle.radius) {\r\n return [];\r\n }\r\n const normal = db.normalize();\r\n const separation = circle.radius - Math.sqrt(ddb);\r\n const info = {\r\n collider: circle,\r\n separation: separation,\r\n axis: normal,\r\n point: side.end,\r\n side: side,\r\n localSide: localSide\r\n };\r\n return [\r\n new CollisionContact(circle, edge, normal.scale(separation), normal, normal.perpendicular(), [side.end], [localSide.end], info)\r\n ];\r\n }\r\n // Otherwise potential region AB collision (circle is in the middle of the edge between the beginning and end)\r\n const den = e.dot(e);\r\n const pointOnEdge = edgeWorld.begin\r\n .scale(u)\r\n .add(edgeWorld.end.scale(v))\r\n .scale(1 / den);\r\n const d = cc.sub(pointOnEdge);\r\n const dd = d.dot(d);\r\n if (dd > circle.radius * circle.radius) {\r\n return []; // no collision\r\n }\r\n let normal = e.perpendicular();\r\n // flip correct direction\r\n if (normal.dot(cc.sub(edgeWorld.begin)) < 0) {\r\n normal.x = -normal.x;\r\n normal.y = -normal.y;\r\n }\r\n normal = normal.normalize();\r\n const separation = circle.radius - Math.sqrt(dd);\r\n const mvt = normal.scale(separation);\r\n const info = {\r\n collider: circle,\r\n separation: separation,\r\n axis: normal,\r\n point: pointOnEdge,\r\n side: side,\r\n localSide: localSide\r\n };\r\n return [\r\n new CollisionContact(circle, edge, mvt, normal.negate(), normal.negate().perpendicular(), [pointOnEdge], [pointOnEdge.sub(edge.worldPos)], info)\r\n ];\r\n },\r\n CollideEdgeEdge() {\r\n // Edge-edge collision doesn't make sense\r\n return [];\r\n },\r\n CollidePolygonEdge(polygon, edge) {\r\n var _a;\r\n const pc = polygon.center;\r\n const ec = edge.center;\r\n const dir = ec.sub(pc).normalize();\r\n // build a temporary polygon from the edge to use SAT\r\n const linePoly = new PolygonCollider({\r\n points: [edge.begin, edge.end, edge.end.add(dir.scale(100)), edge.begin.add(dir.scale(100))],\r\n offset: edge.offset\r\n });\r\n linePoly.owner = edge.owner;\r\n const tx = (_a = edge.owner) === null || _a === void 0 ? void 0 : _a.get(TransformComponent);\r\n if (tx) {\r\n linePoly.update(edge.owner.get(TransformComponent).get());\r\n }\r\n // Gross hack but poly-poly works well\r\n const contact = this.CollidePolygonPolygon(polygon, linePoly);\r\n if (contact.length) {\r\n // Fudge the contact back to edge\r\n contact[0].colliderB = edge;\r\n contact[0].id = Pair.calculatePairHash(polygon.id, edge.id);\r\n }\r\n return contact;\r\n },\r\n CollidePolygonPolygon(polyA, polyB) {\r\n var _a, _b, _c, _d;\r\n // Multi contact from SAT\r\n // https://gamedev.stackexchange.com/questions/111390/multiple-contacts-for-sat-collision-detection\r\n // do a SAT test to find a min axis if it exists\r\n const separationA = SeparatingAxis.findPolygonPolygonSeparation(polyA, polyB);\r\n // If there is no overlap from boxA's perspective we can end early\r\n if (separationA.separation > 0) {\r\n return [];\r\n }\r\n const separationB = SeparatingAxis.findPolygonPolygonSeparation(polyB, polyA);\r\n // If there is no overlap from boxB's perspective exit now\r\n if (separationB.separation > 0) {\r\n return [];\r\n }\r\n // Separations are both negative, we want to pick the least negative (minimal movement)\r\n const separation = separationA.separation > separationB.separation ? separationA : separationB;\r\n // The incident side is the most opposite from the axes of collision on the other collider\r\n const other = separation.collider === polyA ? polyB : polyA;\r\n const incident = other.findSide(separation.axis.negate());\r\n // Clip incident side by the perpendicular lines at each end of the reference side\r\n // https://en.wikipedia.org/wiki/Sutherland%E2%80%93Hodgman_algorithm\r\n const reference = separation.side;\r\n const refDir = reference.dir().normalize();\r\n // Find our contact points by clipping the incident by the collision side\r\n const clipRight = incident.clip(refDir.negate(), -refDir.dot(reference.begin));\r\n let clipLeft = null;\r\n if (clipRight) {\r\n clipLeft = clipRight.clip(refDir, refDir.dot(reference.end));\r\n }\r\n // If there is no left there is no collision\r\n if (clipLeft) {\r\n // We only want clip points below the reference edge, discard the others\r\n const points = clipLeft.getPoints().filter((p) => {\r\n return reference.below(p);\r\n });\r\n let normal = separation.axis;\r\n let tangent = normal.perpendicular();\r\n // Point Contact A -> B\r\n if (polyB.center.sub(polyA.center).dot(normal) < 0) {\r\n normal = normal.negate();\r\n tangent = normal.perpendicular();\r\n }\r\n // Points are clipped from incident which is the other collider\r\n // Store those as locals\r\n let localPoints = [];\r\n if (separation.collider === polyA) {\r\n const xf = (_b = (_a = polyB.owner) === null || _a === void 0 ? void 0 : _a.get(TransformComponent)) !== null && _b !== void 0 ? _b : new TransformComponent();\r\n localPoints = points.map((p) => xf.applyInverse(p));\r\n }\r\n else {\r\n const xf = (_d = (_c = polyA.owner) === null || _c === void 0 ? void 0 : _c.get(TransformComponent)) !== null && _d !== void 0 ? _d : new TransformComponent();\r\n localPoints = points.map((p) => xf.applyInverse(p));\r\n }\r\n return [new CollisionContact(polyA, polyB, normal.scale(-separation.separation), normal, tangent, points, localPoints, separation)];\r\n }\r\n return [];\r\n },\r\n FindContactSeparation(contact, localPoint) {\r\n var _a, _b, _c, _d;\r\n const shapeA = contact.colliderA;\r\n const txA = (_b = (_a = contact.colliderA.owner) === null || _a === void 0 ? void 0 : _a.get(TransformComponent)) !== null && _b !== void 0 ? _b : new TransformComponent();\r\n const shapeB = contact.colliderB;\r\n const txB = (_d = (_c = contact.colliderB.owner) === null || _c === void 0 ? void 0 : _c.get(TransformComponent)) !== null && _d !== void 0 ? _d : new TransformComponent();\r\n // both are circles\r\n if (shapeA instanceof CircleCollider && shapeB instanceof CircleCollider) {\r\n const combinedRadius = shapeA.radius + shapeB.radius;\r\n const distance = txA.pos.distance(txB.pos);\r\n const separation = combinedRadius - distance;\r\n return -separation;\r\n }\r\n // both are polygons\r\n if (shapeA instanceof PolygonCollider && shapeB instanceof PolygonCollider) {\r\n if (contact.info.localSide) {\r\n let side;\r\n let worldPoint;\r\n if (contact.info.collider === shapeA) {\r\n side = new LineSegment(txA.apply(contact.info.localSide.begin), txA.apply(contact.info.localSide.end));\r\n worldPoint = txB.apply(localPoint);\r\n }\r\n else {\r\n side = new LineSegment(txB.apply(contact.info.localSide.begin), txB.apply(contact.info.localSide.end));\r\n worldPoint = txA.apply(localPoint);\r\n }\r\n return side.distanceToPoint(worldPoint, true);\r\n }\r\n }\r\n // polygon v circle\r\n if ((shapeA instanceof PolygonCollider && shapeB instanceof CircleCollider) ||\r\n (shapeB instanceof PolygonCollider && shapeA instanceof CircleCollider)) {\r\n const worldPoint = txA.apply(localPoint);\r\n if (contact.info.side) {\r\n return contact.info.side.distanceToPoint(worldPoint, true);\r\n }\r\n }\r\n // polygon v edge\r\n if ((shapeA instanceof EdgeCollider && shapeB instanceof PolygonCollider) ||\r\n (shapeB instanceof EdgeCollider && shapeA instanceof PolygonCollider)) {\r\n let worldPoint;\r\n if (contact.info.collider === shapeA) {\r\n worldPoint = txB.apply(localPoint);\r\n }\r\n else {\r\n worldPoint = txA.apply(localPoint);\r\n }\r\n if (contact.info.side) {\r\n return contact.info.side.distanceToPoint(worldPoint, true);\r\n }\r\n }\r\n // circle v edge\r\n if ((shapeA instanceof CircleCollider && shapeB instanceof EdgeCollider) ||\r\n (shapeB instanceof CircleCollider && shapeA instanceof EdgeCollider)) {\r\n // Local point is always on the edge which is always shapeB\r\n const worldPoint = txB.apply(localPoint);\r\n let circlePoint;\r\n if (shapeA instanceof CircleCollider) {\r\n circlePoint = shapeA.getFurthestPoint(contact.normal);\r\n }\r\n const dist = worldPoint.distance(circlePoint);\r\n if (contact.info.side) {\r\n return dist > 0 ? -dist : 0;\r\n }\r\n }\r\n return 0;\r\n }\r\n};\r\n\n;// CONCATENATED MODULE: ./Collision/Colliders/EdgeCollider.ts\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n/**\r\n * Edge is a single line collider to create collisions with a single line.\r\n */\r\nclass EdgeCollider extends Collider {\r\n constructor(options) {\r\n var _a;\r\n super();\r\n this._globalMatrix = AffineMatrix.identity();\r\n this.begin = options.begin || Vector.Zero;\r\n this.end = options.end || Vector.Zero;\r\n this.offset = (_a = options.offset) !== null && _a !== void 0 ? _a : Vector.Zero;\r\n }\r\n /**\r\n * Returns a clone of this Edge, not associated with any collider\r\n */\r\n clone() {\r\n return new EdgeCollider({\r\n begin: this.begin.clone(),\r\n end: this.end.clone()\r\n });\r\n }\r\n get worldPos() {\r\n var _a;\r\n const tx = this._transform;\r\n return (_a = tx === null || tx === void 0 ? void 0 : tx.globalPos.add(this.offset)) !== null && _a !== void 0 ? _a : this.offset;\r\n }\r\n /**\r\n * Get the center of the collision area in world coordinates\r\n */\r\n get center() {\r\n const begin = this._getTransformedBegin();\r\n const end = this._getTransformedEnd();\r\n const pos = begin.average(end);\r\n return pos;\r\n }\r\n _getTransformedBegin() {\r\n return this._globalMatrix.multiply(this.begin);\r\n }\r\n _getTransformedEnd() {\r\n return this._globalMatrix.multiply(this.end);\r\n }\r\n /**\r\n * Returns the slope of the line in the form of a vector\r\n */\r\n getSlope() {\r\n const begin = this._getTransformedBegin();\r\n const end = this._getTransformedEnd();\r\n const distance = begin.distance(end);\r\n return end.sub(begin).scale(1 / distance);\r\n }\r\n /**\r\n * Returns the length of the line segment in pixels\r\n */\r\n getLength() {\r\n const begin = this._getTransformedBegin();\r\n const end = this._getTransformedEnd();\r\n const distance = begin.distance(end);\r\n return distance;\r\n }\r\n /**\r\n * Tests if a point is contained in this collision area\r\n */\r\n contains() {\r\n return false;\r\n }\r\n /**\r\n * @inheritdoc\r\n */\r\n rayCast(ray, max = Infinity) {\r\n const numerator = this._getTransformedBegin().sub(ray.pos);\r\n // Test is line and ray are parallel and non intersecting\r\n if (ray.dir.cross(this.getSlope()) === 0 && numerator.cross(ray.dir) !== 0) {\r\n return null;\r\n }\r\n // Lines are parallel\r\n const divisor = ray.dir.cross(this.getSlope());\r\n if (divisor === 0) {\r\n return null;\r\n }\r\n const t = numerator.cross(this.getSlope()) / divisor;\r\n if (t >= 0 && t <= max) {\r\n const u = numerator.cross(ray.dir) / divisor / this.getLength();\r\n if (u >= 0 && u <= 1) {\r\n return ray.getPoint(t);\r\n }\r\n }\r\n return null;\r\n }\r\n /**\r\n * Returns the closes line between this and another collider, from this -> collider\r\n * @param shape\r\n */\r\n getClosestLineBetween(shape) {\r\n if (shape instanceof CircleCollider) {\r\n return ClosestLineJumpTable.CircleEdgeClosestLine(shape, this);\r\n }\r\n else if (shape instanceof PolygonCollider) {\r\n return ClosestLineJumpTable.PolygonEdgeClosestLine(shape, this).flip();\r\n }\r\n else if (shape instanceof EdgeCollider) {\r\n return ClosestLineJumpTable.EdgeEdgeClosestLine(this, shape);\r\n }\r\n else {\r\n throw new Error(`Polygon could not collide with unknown CollisionShape ${typeof shape}`);\r\n }\r\n }\r\n /**\r\n * @inheritdoc\r\n */\r\n collide(shape) {\r\n if (shape instanceof CircleCollider) {\r\n return CollisionJumpTable.CollideCircleEdge(shape, this);\r\n }\r\n else if (shape instanceof PolygonCollider) {\r\n return CollisionJumpTable.CollidePolygonEdge(shape, this);\r\n }\r\n else if (shape instanceof EdgeCollider) {\r\n return CollisionJumpTable.CollideEdgeEdge();\r\n }\r\n else {\r\n throw new Error(`Edge could not collide with unknown CollisionShape ${typeof shape}`);\r\n }\r\n }\r\n /**\r\n * Find the point on the collider furthest in the direction specified\r\n */\r\n getFurthestPoint(direction) {\r\n const transformedBegin = this._getTransformedBegin();\r\n const transformedEnd = this._getTransformedEnd();\r\n if (direction.dot(transformedBegin) > 0) {\r\n return transformedBegin;\r\n }\r\n else {\r\n return transformedEnd;\r\n }\r\n }\r\n _boundsFromBeginEnd(begin, end, padding = 10) {\r\n // A perfectly vertical or horizontal edge would have a bounds 0 width or height\r\n // this causes problems for the collision system so we give them some padding\r\n return new BoundingBox(Math.min(begin.x, end.x) - padding, Math.min(begin.y, end.y) - padding, Math.max(begin.x, end.x) + padding, Math.max(begin.y, end.y) + padding);\r\n }\r\n /**\r\n * Get the axis aligned bounding box for the edge collider in world space\r\n */\r\n get bounds() {\r\n const transformedBegin = this._getTransformedBegin();\r\n const transformedEnd = this._getTransformedEnd();\r\n return this._boundsFromBeginEnd(transformedBegin, transformedEnd);\r\n }\r\n /**\r\n * Get the axis aligned bounding box for the edge collider in local space\r\n */\r\n get localBounds() {\r\n return this._boundsFromBeginEnd(this.begin, this.end);\r\n }\r\n /**\r\n * Returns this edge represented as a line in world coordinates\r\n */\r\n asLine() {\r\n return new LineSegment(this._getTransformedBegin(), this._getTransformedEnd());\r\n }\r\n /**\r\n * Return this edge as a line in local line coordinates (relative to the position)\r\n */\r\n asLocalLine() {\r\n return new LineSegment(this.begin, this.end);\r\n }\r\n /**\r\n * Get the axis associated with the edge\r\n */\r\n get axes() {\r\n const e = this._getTransformedEnd().sub(this._getTransformedBegin());\r\n const edgeNormal = e.normal();\r\n const axes = [];\r\n axes.push(edgeNormal);\r\n axes.push(edgeNormal.negate());\r\n axes.push(edgeNormal.normal());\r\n axes.push(edgeNormal.normal().negate());\r\n return axes;\r\n }\r\n /**\r\n * Get the moment of inertia for an edge\r\n * https://en.wikipedia.org/wiki/List_of_moments_of_inertia\r\n */\r\n getInertia(mass) {\r\n const length = this.end.sub(this.begin).distance() / 2;\r\n return mass * length * length;\r\n }\r\n /**\r\n * @inheritdoc\r\n */\r\n update(transform) {\r\n var _a;\r\n this._transform = transform;\r\n const globalMat = (_a = transform.matrix) !== null && _a !== void 0 ? _a : this._globalMatrix;\r\n globalMat.clone(this._globalMatrix);\r\n this._globalMatrix.translate(this.offset.x, this.offset.y);\r\n }\r\n /**\r\n * Project the edge along a specified axis\r\n */\r\n project(axis) {\r\n const scalars = [];\r\n const points = [this._getTransformedBegin(), this._getTransformedEnd()];\r\n const len = points.length;\r\n for (let i = 0; i < len; i++) {\r\n scalars.push(points[i].dot(axis));\r\n }\r\n return new Projection(Math.min.apply(Math, scalars), Math.max.apply(Math, scalars));\r\n }\r\n debug(ex, color) {\r\n const begin = this._getTransformedBegin();\r\n const end = this._getTransformedEnd();\r\n ex.drawLine(begin, end, color, 2);\r\n ex.drawCircle(begin, 2, color);\r\n ex.drawCircle(end, 2, color);\r\n }\r\n}\r\n\n;// CONCATENATED MODULE: ./Collision/Colliders/PolygonCollider.ts\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n/**\r\n * Polygon collider for detecting collisions\r\n */\r\nclass PolygonCollider extends Collider {\r\n /**\r\n * Points in the polygon in order around the perimeter in local coordinates. These are relative from the body transform position.\r\n * Excalibur stores these in counter-clockwise order\r\n */\r\n set points(points) {\r\n this._localBoundsDirty = true;\r\n this._localSidesDirty = true;\r\n this._sidesDirty = true;\r\n this._points = points;\r\n }\r\n /**\r\n * Points in the polygon in order around the perimeter in local coordinates. These are relative from the body transform position.\r\n * Excalibur stores these in counter-clockwise order\r\n */\r\n get points() {\r\n return this._points;\r\n }\r\n constructor(options) {\r\n var _a, _b;\r\n super();\r\n this._logger = Logger.getInstance();\r\n this._transformedPoints = [];\r\n this._sides = [];\r\n this._localSides = [];\r\n this._globalMatrix = AffineMatrix.identity();\r\n this._transformedPointsDirty = true;\r\n this._sidesDirty = true;\r\n this._localSidesDirty = true;\r\n this._localBoundsDirty = true;\r\n this.offset = (_a = options.offset) !== null && _a !== void 0 ? _a : Vector.Zero;\r\n this._globalMatrix.translate(this.offset.x, this.offset.y);\r\n this.points = (_b = options.points) !== null && _b !== void 0 ? _b : [];\r\n const counterClockwise = this._isCounterClockwiseWinding(this.points);\r\n if (!counterClockwise) {\r\n this.points.reverse();\r\n }\r\n if (!this.isConvex()) {\r\n this._logger.warn('Excalibur only supports convex polygon colliders and will not behave properly.' +\r\n 'Call PolygonCollider.triangulate() to build a new collider composed of smaller convex triangles');\r\n }\r\n // calculate initial transformation\r\n this._calculateTransformation();\r\n }\r\n _isCounterClockwiseWinding(points) {\r\n // https://stackoverflow.com/a/1165943\r\n let sum = 0;\r\n for (let i = 0; i < points.length; i++) {\r\n sum += (points[(i + 1) % points.length].x - points[i].x) * (points[(i + 1) % points.length].y + points[i].y);\r\n }\r\n return sum < 0;\r\n }\r\n /**\r\n * Returns if the polygon collider is convex, Excalibur does not handle non-convex collision shapes.\r\n * Call [[Polygon.triangulate]] to generate a [[CompositeCollider]] from this non-convex shape\r\n */\r\n isConvex() {\r\n // From SO: https://stackoverflow.com/a/45372025\r\n if (this.points.length < 3) {\r\n return false;\r\n }\r\n let oldPoint = this.points[this.points.length - 2];\r\n let newPoint = this.points[this.points.length - 1];\r\n let direction = Math.atan2(newPoint.y - oldPoint.y, newPoint.x - oldPoint.x);\r\n let oldDirection = 0;\r\n let orientation = 0;\r\n let angleSum = 0;\r\n for (const [i, point] of this.points.entries()) {\r\n oldPoint = newPoint;\r\n oldDirection = direction;\r\n newPoint = point;\r\n direction = Math.atan2(newPoint.y - oldPoint.y, newPoint.x - oldPoint.x);\r\n if (oldPoint.equals(newPoint)) {\r\n return false; // repeat point\r\n }\r\n let angle = direction - oldDirection;\r\n if (angle <= -Math.PI) {\r\n angle += Math.PI * 2;\r\n }\r\n else if (angle > Math.PI) {\r\n angle -= Math.PI * 2;\r\n }\r\n if (i === 0) {\r\n if (angle === 0.0) {\r\n return false;\r\n }\r\n orientation = angle > 0 ? 1 : -1;\r\n }\r\n else {\r\n if (orientation * angle <= 0) {\r\n return false;\r\n }\r\n }\r\n angleSum += angle;\r\n }\r\n return Math.abs(Math.round(angleSum / (Math.PI * 2))) === 1;\r\n }\r\n /**\r\n * Tessellates the polygon into a triangle fan as a [[CompositeCollider]] of triangle polygons\r\n */\r\n tessellate() {\r\n const polygons = [];\r\n for (let i = 1; i < this.points.length - 2; i++) {\r\n polygons.push([this.points[0], this.points[i + 1], this.points[i + 2]]);\r\n }\r\n polygons.push([this.points[0], this.points[1], this.points[2]]);\r\n return new CompositeCollider(polygons.map(points => Shape.Polygon(points)));\r\n }\r\n /**\r\n * Triangulate the polygon collider using the \"Ear Clipping\" algorithm.\r\n * Returns a new [[CompositeCollider]] made up of smaller triangles.\r\n */\r\n triangulate() {\r\n // https://www.youtube.com/watch?v=hTJFcHutls8\r\n if (this.points.length < 3) {\r\n throw Error('Invalid polygon');\r\n }\r\n /**\r\n * Helper to get a vertex in the list\r\n */\r\n function getItem(index, list) {\r\n if (index >= list.length) {\r\n return list[index % list.length];\r\n }\r\n else if (index < 0) {\r\n return list[index % list.length + list.length];\r\n }\r\n else {\r\n return list[index];\r\n }\r\n }\r\n /**\r\n * Quick test for point in triangle\r\n */\r\n function isPointInTriangle(point, a, b, c) {\r\n const ab = b.sub(a);\r\n const bc = c.sub(b);\r\n const ca = a.sub(c);\r\n const ap = point.sub(a);\r\n const bp = point.sub(b);\r\n const cp = point.sub(c);\r\n const cross1 = ab.cross(ap);\r\n const cross2 = bc.cross(bp);\r\n const cross3 = ca.cross(cp);\r\n if (cross1 > 0 || cross2 > 0 || cross3 > 0) {\r\n return false;\r\n }\r\n return true;\r\n }\r\n const triangles = [];\r\n const vertices = [...this.points];\r\n const indices = range(0, this.points.length - 1);\r\n // 1. Loop through vertices clockwise\r\n // if the vertex is convex (interior angle is < 180) (cross product positive)\r\n // if the polygon formed by it's edges doesn't contain the points\r\n // it's an ear add it to our list of triangles, and restart\r\n while (indices.length > 3) {\r\n for (let i = 0; i < indices.length; i++) {\r\n const a = indices[i];\r\n const b = getItem(i - 1, indices);\r\n const c = getItem(i + 1, indices);\r\n const va = vertices[a];\r\n const vb = vertices[b];\r\n const vc = vertices[c];\r\n // Check convexity\r\n const leftArm = vb.sub(va);\r\n const rightArm = vc.sub(va);\r\n const isConvex = rightArm.cross(leftArm) > 0; // positive cross means convex\r\n if (!isConvex) {\r\n continue;\r\n }\r\n let isEar = true;\r\n // Check that if any vertices are in the triangle a, b, c\r\n for (let j = 0; j < indices.length; j++) {\r\n const vertIndex = indices[j];\r\n // We can skip these\r\n if (vertIndex === a || vertIndex === b || vertIndex === c) {\r\n continue;\r\n }\r\n const point = vertices[vertIndex];\r\n if (isPointInTriangle(point, vb, va, vc)) {\r\n isEar = false;\r\n break;\r\n }\r\n }\r\n // Add ear to polygon list and remove from list\r\n if (isEar) {\r\n triangles.push([vb, va, vc]);\r\n indices.splice(i, 1);\r\n break;\r\n }\r\n }\r\n }\r\n triangles.push([vertices[indices[0]], vertices[indices[1]], vertices[indices[2]]]);\r\n return new CompositeCollider(triangles.map(points => Shape.Polygon(points)));\r\n }\r\n /**\r\n * Returns a clone of this ConvexPolygon, not associated with any collider\r\n */\r\n clone() {\r\n return new PolygonCollider({\r\n offset: this.offset.clone(),\r\n points: this.points.map((p) => p.clone())\r\n });\r\n }\r\n /**\r\n * Returns the world position of the collider, which is the current body transform plus any defined offset\r\n */\r\n get worldPos() {\r\n if (this._transform) {\r\n return this._transform.pos.add(this.offset);\r\n }\r\n return this.offset;\r\n }\r\n /**\r\n * Get the center of the collider in world coordinates\r\n */\r\n get center() {\r\n return this.bounds.center;\r\n }\r\n /**\r\n * Calculates the underlying transformation from the body relative space to world space\r\n */\r\n _calculateTransformation() {\r\n const points = this.points;\r\n const len = points.length;\r\n this._transformedPoints.length = 0; // clear out old transform\r\n for (let i = 0; i < len; i++) {\r\n this._transformedPoints[i] = this._globalMatrix.multiply(points[i].clone());\r\n }\r\n }\r\n /**\r\n * Gets the points that make up the polygon in world space, from actor relative space (if specified)\r\n */\r\n getTransformedPoints() {\r\n if (this._transformedPointsDirty) {\r\n this._calculateTransformation();\r\n this._transformedPointsDirty = false;\r\n }\r\n return this._transformedPoints;\r\n }\r\n /**\r\n * Gets the sides of the polygon in world space\r\n */\r\n getSides() {\r\n if (this._sidesDirty) {\r\n const lines = [];\r\n const points = this.getTransformedPoints();\r\n const len = points.length;\r\n for (let i = 0; i < len; i++) {\r\n // This winding is important\r\n lines.push(new LineSegment(points[i], points[(i + 1) % len]));\r\n }\r\n this._sides = lines;\r\n this._sidesDirty = false;\r\n }\r\n return this._sides;\r\n }\r\n /**\r\n * Returns the local coordinate space sides\r\n */\r\n getLocalSides() {\r\n if (this._localSidesDirty) {\r\n const lines = [];\r\n const points = this.points;\r\n const len = points.length;\r\n for (let i = 0; i < len; i++) {\r\n // This winding is important\r\n lines.push(new LineSegment(points[i], points[(i + 1) % len]));\r\n }\r\n this._localSides = lines;\r\n this._localSidesDirty = false;\r\n }\r\n return this._localSides;\r\n }\r\n /**\r\n * Given a direction vector find the world space side that is most in that direction\r\n * @param direction\r\n */\r\n findSide(direction) {\r\n const sides = this.getSides();\r\n let bestSide = sides[0];\r\n let maxDistance = -Number.MAX_VALUE;\r\n for (let side = 0; side < sides.length; side++) {\r\n const currentSide = sides[side];\r\n const sideNormal = currentSide.normal();\r\n const mostDirection = sideNormal.dot(direction);\r\n if (mostDirection > maxDistance) {\r\n bestSide = currentSide;\r\n maxDistance = mostDirection;\r\n }\r\n }\r\n return bestSide;\r\n }\r\n /**\r\n * Given a direction vector find the local space side that is most in that direction\r\n * @param direction\r\n */\r\n findLocalSide(direction) {\r\n const sides = this.getLocalSides();\r\n let bestSide = sides[0];\r\n let maxDistance = -Number.MAX_VALUE;\r\n for (let side = 0; side < sides.length; side++) {\r\n const currentSide = sides[side];\r\n const sideNormal = currentSide.normal();\r\n const mostDirection = sideNormal.dot(direction);\r\n if (mostDirection > maxDistance) {\r\n bestSide = currentSide;\r\n maxDistance = mostDirection;\r\n }\r\n }\r\n return bestSide;\r\n }\r\n /**\r\n * Get the axis associated with the convex polygon\r\n */\r\n get axes() {\r\n const axes = [];\r\n const sides = this.getSides();\r\n for (let i = 0; i < sides.length; i++) {\r\n axes.push(sides[i].normal());\r\n }\r\n return axes;\r\n }\r\n /**\r\n * Updates the transform for the collision geometry\r\n *\r\n * Collision geometry (points/bounds) will not change until this is called.\r\n * @param transform\r\n */\r\n update(transform) {\r\n var _a;\r\n if (transform) {\r\n this._transform = transform;\r\n this._transformedPointsDirty = true;\r\n this._sidesDirty = true;\r\n // This change means an update must be performed in order for geometry to update\r\n const globalMat = (_a = transform.matrix) !== null && _a !== void 0 ? _a : this._globalMatrix;\r\n globalMat.clone(this._globalMatrix);\r\n this._globalMatrix.translate(this.offset.x, this.offset.y);\r\n }\r\n }\r\n /**\r\n * Tests if a point is contained in this collider in world space\r\n */\r\n contains(point) {\r\n // Always cast to the right, as long as we cast in a consistent fixed direction we\r\n // will be fine\r\n const testRay = new Ray(point, new Vector(1, 0));\r\n const intersectCount = this.getSides().reduce(function (accum, side) {\r\n if (testRay.intersect(side) >= 0) {\r\n return accum + 1;\r\n }\r\n return accum;\r\n }, 0);\r\n if (intersectCount % 2 === 0) {\r\n return false;\r\n }\r\n return true;\r\n }\r\n getClosestLineBetween(collider) {\r\n if (collider instanceof CircleCollider) {\r\n return ClosestLineJumpTable.PolygonCircleClosestLine(this, collider);\r\n }\r\n else if (collider instanceof PolygonCollider) {\r\n return ClosestLineJumpTable.PolygonPolygonClosestLine(this, collider);\r\n }\r\n else if (collider instanceof EdgeCollider) {\r\n return ClosestLineJumpTable.PolygonEdgeClosestLine(this, collider);\r\n }\r\n else {\r\n throw new Error(`Polygon could not collide with unknown CollisionShape ${typeof collider}`);\r\n }\r\n }\r\n /**\r\n * Returns a collision contact if the 2 colliders collide, otherwise collide will\r\n * return null.\r\n * @param collider\r\n */\r\n collide(collider) {\r\n if (collider instanceof CircleCollider) {\r\n return CollisionJumpTable.CollideCirclePolygon(collider, this);\r\n }\r\n else if (collider instanceof PolygonCollider) {\r\n return CollisionJumpTable.CollidePolygonPolygon(this, collider);\r\n }\r\n else if (collider instanceof EdgeCollider) {\r\n return CollisionJumpTable.CollidePolygonEdge(this, collider);\r\n }\r\n else {\r\n throw new Error(`Polygon could not collide with unknown CollisionShape ${typeof collider}`);\r\n }\r\n }\r\n /**\r\n * Find the point on the collider furthest in the direction specified\r\n */\r\n getFurthestPoint(direction) {\r\n const pts = this.getTransformedPoints();\r\n let furthestPoint = null;\r\n let maxDistance = -Number.MAX_VALUE;\r\n for (let i = 0; i < pts.length; i++) {\r\n const distance = direction.dot(pts[i]);\r\n if (distance > maxDistance) {\r\n maxDistance = distance;\r\n furthestPoint = pts[i];\r\n }\r\n }\r\n return furthestPoint;\r\n }\r\n /**\r\n * Find the local point on the collider furthest in the direction specified\r\n * @param direction\r\n */\r\n getFurthestLocalPoint(direction) {\r\n const pts = this.points;\r\n let furthestPoint = pts[0];\r\n let maxDistance = -Number.MAX_VALUE;\r\n for (let i = 0; i < pts.length; i++) {\r\n const distance = direction.dot(pts[i]);\r\n if (distance > maxDistance) {\r\n maxDistance = distance;\r\n furthestPoint = pts[i];\r\n }\r\n }\r\n return furthestPoint;\r\n }\r\n /**\r\n * Finds the closes face to the point using perpendicular distance\r\n * @param point point to test against polygon\r\n */\r\n getClosestFace(point) {\r\n const sides = this.getSides();\r\n let min = Number.POSITIVE_INFINITY;\r\n let faceIndex = -1;\r\n let distance = -1;\r\n for (let i = 0; i < sides.length; i++) {\r\n const dist = sides[i].distanceToPoint(point);\r\n if (dist < min) {\r\n min = dist;\r\n faceIndex = i;\r\n distance = dist;\r\n }\r\n }\r\n if (faceIndex !== -1) {\r\n return {\r\n distance: sides[faceIndex].normal().scale(distance),\r\n face: sides[faceIndex]\r\n };\r\n }\r\n return null;\r\n }\r\n /**\r\n * Get the axis aligned bounding box for the polygon collider in world coordinates\r\n */\r\n get bounds() {\r\n return this.localBounds.transform(this._globalMatrix);\r\n }\r\n /**\r\n * Get the axis aligned bounding box for the polygon collider in local coordinates\r\n */\r\n get localBounds() {\r\n if (this._localBoundsDirty) {\r\n this._localBounds = BoundingBox.fromPoints(this.points);\r\n this._localBoundsDirty = false;\r\n }\r\n return this._localBounds;\r\n }\r\n /**\r\n * Get the moment of inertia for an arbitrary polygon\r\n * https://en.wikipedia.org/wiki/List_of_moments_of_inertia\r\n */\r\n getInertia(mass) {\r\n if (this._cachedMass === mass && this._cachedInertia) {\r\n return this._cachedInertia;\r\n }\r\n let numerator = 0;\r\n let denominator = 0;\r\n const points = this.points;\r\n for (let i = 0; i < points.length; i++) {\r\n const iplusone = (i + 1) % points.length;\r\n const crossTerm = points[iplusone].cross(points[i]);\r\n numerator +=\r\n crossTerm *\r\n (points[i].dot(points[i]) + points[i].dot(points[iplusone]) + points[iplusone].dot(points[iplusone]));\r\n denominator += crossTerm;\r\n }\r\n this._cachedMass = mass;\r\n return this._cachedInertia = (mass / 6) * (numerator / denominator);\r\n }\r\n /**\r\n * Casts a ray into the polygon and returns a vector representing the point of contact (in world space) or null if no collision.\r\n */\r\n rayCast(ray, max = Infinity) {\r\n // find the minimum contact time greater than 0\r\n // contact times less than 0 are behind the ray and we don't want those\r\n const sides = this.getSides();\r\n const len = sides.length;\r\n let minContactTime = Number.MAX_VALUE;\r\n let contactIndex = -1;\r\n for (let i = 0; i < len; i++) {\r\n const contactTime = ray.intersect(sides[i]);\r\n if (contactTime >= 0 && contactTime < minContactTime && contactTime <= max) {\r\n minContactTime = contactTime;\r\n contactIndex = i;\r\n }\r\n }\r\n // contact was found\r\n if (contactIndex >= 0) {\r\n return ray.getPoint(minContactTime);\r\n }\r\n // no contact found\r\n return null;\r\n }\r\n /**\r\n * Project the edges of the polygon along a specified axis\r\n */\r\n project(axis) {\r\n const points = this.getTransformedPoints();\r\n const len = points.length;\r\n let min = Number.MAX_VALUE;\r\n let max = -Number.MAX_VALUE;\r\n for (let i = 0; i < len; i++) {\r\n const scalar = points[i].dot(axis);\r\n min = Math.min(min, scalar);\r\n max = Math.max(max, scalar);\r\n }\r\n return new Projection(min, max);\r\n }\r\n debug(ex, color) {\r\n const firstPoint = this.getTransformedPoints()[0];\r\n const points = [firstPoint, ...this.getTransformedPoints(), firstPoint];\r\n for (let i = 0; i < points.length - 1; i++) {\r\n ex.drawLine(points[i], points[i + 1], color, 2);\r\n ex.drawCircle(points[i], 2, color);\r\n ex.drawCircle(points[i + 1], 2, color);\r\n }\r\n }\r\n}\r\n\n;// CONCATENATED MODULE: ./Collision/Colliders/Shape.ts\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n/**\r\n * Excalibur helper for defining colliders quickly\r\n */\r\nclass Shape {\r\n /**\r\n * Creates a box collider, under the hood defines a [[PolygonCollider]] collider\r\n * @param width Width of the box\r\n * @param height Height of the box\r\n * @param anchor Anchor of the box (default (.5, .5)) which positions the box relative to the center of the collider's position\r\n * @param offset Optional offset relative to the collider in local coordinates\r\n */\r\n static Box(width, height, anchor = Vector.Half, offset = Vector.Zero) {\r\n return new PolygonCollider({\r\n points: new BoundingBox(-width * anchor.x, -height * anchor.y, width - width * anchor.x, height - height * anchor.y).getPoints(),\r\n offset: offset\r\n });\r\n }\r\n /**\r\n * Creates a new [[PolygonCollider|arbitrary polygon]] collider\r\n *\r\n * PolygonColliders are useful for creating convex polygon shapes\r\n * @param points Points specified in counter clockwise\r\n * @param offset Optional offset relative to the collider in local coordinates\r\n */\r\n static Polygon(points, offset = Vector.Zero) {\r\n return new PolygonCollider({\r\n points: points,\r\n offset: offset\r\n });\r\n }\r\n /**\r\n * Creates a new [[CircleCollider|circle]] collider\r\n *\r\n * Circle colliders are useful for balls, or to make collisions more forgiving on sharp edges\r\n * @param radius Radius of the circle collider\r\n * @param offset Optional offset relative to the collider in local coordinates\r\n */\r\n static Circle(radius, offset = Vector.Zero) {\r\n return new CircleCollider({\r\n radius: radius,\r\n offset: offset\r\n });\r\n }\r\n /**\r\n * Creates a new [[EdgeCollider|edge]] collider\r\n *\r\n * Edge colliders are useful for floors, walls, and other barriers\r\n * @param begin Beginning of the edge in local coordinates to the collider\r\n * @param end Ending of the edge in local coordinates to the collider\r\n */\r\n static Edge(begin, end) {\r\n return new EdgeCollider({\r\n begin: begin,\r\n end: end\r\n });\r\n }\r\n /**\r\n * Creates a new capsule shaped [[CompositeCollider]] using 2 circles and a box\r\n *\r\n * Capsule colliders are useful for platformers with incline or jagged floors to have a smooth\r\n * player experience.\r\n *\r\n * @param width\r\n * @param height\r\n * @param offset Optional offset\r\n */\r\n static Capsule(width, height, offset = Vector.Zero) {\r\n const logger = Logger.getInstance();\r\n if (width === height) {\r\n logger.warn('A capsule collider with equal width and height is a circle, consider using a ex.Shape.Circle or ex.CircleCollider');\r\n }\r\n const vertical = height >= width;\r\n if (vertical) {\r\n // height > width, if equal maybe use a circle\r\n const capsule = new CompositeCollider([\r\n Shape.Circle(width / 2, vec(0, -height / 2 + width / 2).add(offset)),\r\n Shape.Box(width, height - width, Vector.Half, offset),\r\n Shape.Circle(width / 2, vec(0, height / 2 - width / 2).add(offset))\r\n ]);\r\n return capsule;\r\n }\r\n else {\r\n // width > height, if equal maybe use a circle\r\n const capsule = new CompositeCollider([\r\n Shape.Circle(height / 2, vec(-width / 2 + height / 2, 0).add(offset)),\r\n Shape.Box(width - height, height, Vector.Half, offset),\r\n Shape.Circle(height / 2, vec(width / 2 - height / 2, 0).add(offset))\r\n ]);\r\n return capsule;\r\n }\r\n }\r\n}\r\n\n;// CONCATENATED MODULE: ./Collision/ColliderComponent.ts\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\nclass ColliderComponent extends Component {\r\n constructor(collider) {\r\n super();\r\n this.type = 'ex.collider';\r\n this.events = new EventEmitter();\r\n /**\r\n * Observable that notifies when a collider is added to the body\r\n */\r\n this.$colliderAdded = new Observable();\r\n /**\r\n * Observable that notifies when a collider is removed from the body\r\n */\r\n this.$colliderRemoved = new Observable();\r\n this.set(collider);\r\n }\r\n /**\r\n * Get the current collider geometry\r\n */\r\n get() {\r\n return this._collider;\r\n }\r\n /**\r\n * Set the collider geometry\r\n * @param collider\r\n * @returns the collider you set\r\n */\r\n set(collider) {\r\n this.clear();\r\n if (collider) {\r\n this._collider = collider;\r\n this._collider.owner = this.owner;\r\n collider.events.pipe(this.events);\r\n this.$colliderAdded.notifyAll(collider);\r\n this.update();\r\n }\r\n return collider;\r\n }\r\n /**\r\n * Remove collider geometry from collider component\r\n */\r\n clear() {\r\n if (this._collider) {\r\n this._collider.events.unpipe(this.events);\r\n this.$colliderRemoved.notifyAll(this._collider);\r\n this._collider.owner = null;\r\n this._collider = null;\r\n }\r\n }\r\n clone() {\r\n const clone = new ColliderComponent(this._collider.clone());\r\n return clone;\r\n }\r\n /**\r\n * Return world space bounds\r\n */\r\n get bounds() {\r\n var _a, _b;\r\n return (_b = (_a = this._collider) === null || _a === void 0 ? void 0 : _a.bounds) !== null && _b !== void 0 ? _b : new BoundingBox();\r\n }\r\n /**\r\n * Return local space bounds\r\n */\r\n get localBounds() {\r\n var _a, _b;\r\n return (_b = (_a = this._collider) === null || _a === void 0 ? void 0 : _a.localBounds) !== null && _b !== void 0 ? _b : new BoundingBox();\r\n }\r\n /**\r\n * Update the collider's transformed geometry\r\n */\r\n update() {\r\n var _a;\r\n const tx = (_a = this.owner) === null || _a === void 0 ? void 0 : _a.get(TransformComponent);\r\n if (this._collider) {\r\n this._collider.owner = this.owner;\r\n if (tx) {\r\n this._collider.update(tx.get());\r\n }\r\n }\r\n }\r\n /**\r\n * Collide component with another\r\n * @param other\r\n */\r\n collide(other) {\r\n let colliderA = this._collider;\r\n let colliderB = other._collider;\r\n if (!colliderA || !colliderB) {\r\n return [];\r\n }\r\n // If we have a composite lefthand side :(\r\n // Might bite us, but to avoid updating all the handlers make composite always left side\r\n let flipped = false;\r\n if (colliderB instanceof CompositeCollider) {\r\n colliderA = colliderB;\r\n colliderB = this._collider;\r\n flipped = true;\r\n }\r\n if (this._collider) {\r\n const contacts = colliderA.collide(colliderB);\r\n if (contacts) {\r\n if (flipped) {\r\n contacts.forEach((contact) => {\r\n contact.mtv = contact.mtv.negate();\r\n contact.normal = contact.normal.negate();\r\n contact.tangent = contact.normal.perpendicular();\r\n contact.colliderA = this._collider;\r\n contact.colliderB = other._collider;\r\n });\r\n }\r\n return contacts;\r\n }\r\n return [];\r\n }\r\n return [];\r\n }\r\n onAdd(entity) {\r\n if (this._collider) {\r\n this.update();\r\n }\r\n // Wire up the collider events to the owning entity\r\n this.events.on('precollision', (evt) => {\r\n const precollision = evt;\r\n entity.events.emit('precollision', new PreCollisionEvent(precollision.target.owner, precollision.other.owner, precollision.side, precollision.intersection));\r\n });\r\n this.events.on('postcollision', (evt) => {\r\n const postcollision = evt;\r\n entity.events.emit('postcollision', new PostCollisionEvent(postcollision.target.owner, postcollision.other.owner, postcollision.side, postcollision.intersection));\r\n });\r\n this.events.on('collisionstart', (evt) => {\r\n const start = evt;\r\n entity.events.emit('collisionstart', new CollisionStartEvent(start.target.owner, start.other.owner, start.contact));\r\n });\r\n this.events.on('collisionend', (evt) => {\r\n const end = evt;\r\n entity.events.emit('collisionend', new CollisionEndEvent(end.target.owner, end.other.owner));\r\n });\r\n }\r\n onRemove() {\r\n this.events.clear();\r\n this.$colliderRemoved.notifyAll(this._collider);\r\n }\r\n /**\r\n * Sets up a box geometry based on the current bounds of the associated actor of this physics body.\r\n *\r\n * If no width/height are specified the body will attempt to use the associated actor's width/height.\r\n *\r\n * By default, the box is center is at (0, 0) which means it is centered around the actors anchor.\r\n */\r\n useBoxCollider(width, height, anchor = Vector.Half, center = Vector.Zero) {\r\n const collider = Shape.Box(width, height, anchor, center);\r\n return (this.set(collider));\r\n }\r\n /**\r\n * Sets up a [[PolygonCollider|polygon]] collision geometry based on a list of of points relative\r\n * to the anchor of the associated actor\r\n * of this physics body.\r\n *\r\n * Only [convex polygon](https://en.wikipedia.org/wiki/Convex_polygon) definitions are supported.\r\n *\r\n * By default, the box is center is at (0, 0) which means it is centered around the actors anchor.\r\n */\r\n usePolygonCollider(points, center = Vector.Zero) {\r\n const poly = Shape.Polygon(points, center);\r\n return (this.set(poly));\r\n }\r\n /**\r\n * Sets up a [[Circle|circle collision geometry]] as the only collider with a specified radius in pixels.\r\n *\r\n * By default, the box is center is at (0, 0) which means it is centered around the actors anchor.\r\n */\r\n useCircleCollider(radius, center = Vector.Zero) {\r\n const collider = Shape.Circle(radius, center);\r\n return (this.set(collider));\r\n }\r\n /**\r\n * Sets up an [[Edge|edge collision geometry]] with a start point and an end point relative to the anchor of the associated actor\r\n * of this physics body.\r\n *\r\n * By default, the box is center is at (0, 0) which means it is centered around the actors anchor.\r\n */\r\n useEdgeCollider(begin, end) {\r\n const collider = Shape.Edge(begin, end);\r\n return (this.set(collider));\r\n }\r\n /**\r\n * Setups up a [[CompositeCollider]] which can define any arbitrary set of excalibur colliders\r\n * @param colliders\r\n */\r\n useCompositeCollider(colliders) {\r\n return (this.set(new CompositeCollider(colliders)));\r\n }\r\n}\r\n\n;// CONCATENATED MODULE: ./Collision/BodyComponent.ts\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\nvar DegreeOfFreedom;\r\n(function (DegreeOfFreedom) {\r\n DegreeOfFreedom[\"Rotation\"] = \"rotation\";\r\n DegreeOfFreedom[\"X\"] = \"x\";\r\n DegreeOfFreedom[\"Y\"] = \"y\";\r\n})(DegreeOfFreedom || (DegreeOfFreedom = {}));\r\n/**\r\n * Body describes all the physical properties pos, vel, acc, rotation, angular velocity for the purpose of\r\n * of physics simulation.\r\n */\r\nclass BodyComponent extends Component {\r\n constructor(options) {\r\n var _a, _b, _c;\r\n super();\r\n this.type = 'ex.body';\r\n this.dependencies = [TransformComponent, MotionComponent];\r\n this.id = createId('body', BodyComponent._ID++);\r\n this.events = new EventEmitter();\r\n this._oldTransform = new Transform();\r\n /**\r\n * Indicates whether the old transform has been captured at least once for interpolation\r\n * @internal\r\n */\r\n this.__oldTransformCaptured = false;\r\n /**\r\n * Enable or disabled the fixed update interpolation, by default interpolation is on.\r\n */\r\n this.enableFixedUpdateInterpolate = true;\r\n /**\r\n * Collision type for the rigidbody physics simulation, by default [[CollisionType.PreventCollision]]\r\n */\r\n this.collisionType = CollisionType.PreventCollision;\r\n /**\r\n * The collision group for the body's colliders, by default body colliders collide with everything\r\n */\r\n this.group = CollisionGroup.All;\r\n /**\r\n * The amount of mass the body has\r\n */\r\n this._mass = Physics.defaultMass;\r\n /**\r\n * Amount of \"motion\" the body has before sleeping. If below [[Physics.sleepEpsilon]] it goes to \"sleep\"\r\n */\r\n this.sleepMotion = Physics.sleepEpsilon * 5;\r\n /**\r\n * Can this body sleep, by default bodies do not sleep\r\n */\r\n this.canSleep = Physics.bodiesCanSleepByDefault;\r\n this._sleeping = false;\r\n /**\r\n * The also known as coefficient of restitution of this actor, represents the amount of energy preserved after collision or the\r\n * bounciness. If 1, it is 100% bouncy, 0 it completely absorbs.\r\n */\r\n this.bounciness = 0.2;\r\n /**\r\n * The coefficient of friction on this actor\r\n */\r\n this.friction = 0.99;\r\n /**\r\n * Should use global gravity [[Physics.gravity]] in it's physics simulation, default is true\r\n */\r\n this.useGravity = true;\r\n /**\r\n * Degrees of freedom to limit\r\n *\r\n * Note: this only limits responses in the realistic solver, if velocity/angularVelocity is set the actor will still respond\r\n */\r\n this.limitDegreeOfFreedom = [];\r\n /**\r\n * The velocity of the actor last frame (vx, vy) in pixels/second\r\n */\r\n this.oldVel = new Vector(0, 0);\r\n /**\r\n * Gets/sets the acceleration of the actor from the last frame. This does not include the global acc [[Physics.acc]].\r\n */\r\n this.oldAcc = Vector.Zero;\r\n if (options) {\r\n this.collisionType = (_a = options.type) !== null && _a !== void 0 ? _a : this.collisionType;\r\n this.group = (_b = options.group) !== null && _b !== void 0 ? _b : this.group;\r\n this.useGravity = (_c = options.useGravity) !== null && _c !== void 0 ? _c : this.useGravity;\r\n }\r\n }\r\n get matrix() {\r\n return this.transform.get().matrix;\r\n }\r\n get mass() {\r\n return this._mass;\r\n }\r\n set mass(newMass) {\r\n this._mass = newMass;\r\n this._cachedInertia = undefined;\r\n this._cachedInverseInertia = undefined;\r\n }\r\n /**\r\n * The inverse mass (1/mass) of the body. If [[CollisionType.Fixed]] this is 0, meaning \"infinite\" mass\r\n */\r\n get inverseMass() {\r\n return this.collisionType === CollisionType.Fixed ? 0 : 1 / this.mass;\r\n }\r\n /**\r\n * Whether this body is sleeping or not\r\n */\r\n get sleeping() {\r\n return this._sleeping;\r\n }\r\n /**\r\n * Set the sleep state of the body\r\n * @param sleeping\r\n */\r\n setSleeping(sleeping) {\r\n this._sleeping = sleeping;\r\n if (!sleeping) {\r\n // Give it a kick to keep it from falling asleep immediately\r\n this.sleepMotion = Physics.sleepEpsilon * 5;\r\n }\r\n else {\r\n this.vel = Vector.Zero;\r\n this.acc = Vector.Zero;\r\n this.angularVelocity = 0;\r\n this.sleepMotion = 0;\r\n }\r\n }\r\n /**\r\n * Update body's [[BodyComponent.sleepMotion]] for the purpose of sleeping\r\n */\r\n updateMotion() {\r\n if (this._sleeping) {\r\n this.setSleeping(true);\r\n }\r\n const currentMotion = this.vel.size * this.vel.size + Math.abs(this.angularVelocity * this.angularVelocity);\r\n const bias = Physics.sleepBias;\r\n this.sleepMotion = bias * this.sleepMotion + (1 - bias) * currentMotion;\r\n this.sleepMotion = clamp(this.sleepMotion, 0, 10 * Physics.sleepEpsilon);\r\n if (this.canSleep && this.sleepMotion < Physics.sleepEpsilon) {\r\n this.setSleeping(true);\r\n }\r\n }\r\n /**\r\n * Get the moment of inertia from the [[ColliderComponent]]\r\n */\r\n get inertia() {\r\n if (this._cachedInertia) {\r\n return this._cachedInertia;\r\n }\r\n // Inertia is a property of the geometry, so this is a little goofy but seems to be okay?\r\n const collider = this.owner.get(ColliderComponent);\r\n if (collider) {\r\n collider.$colliderAdded.subscribe(() => {\r\n this._cachedInertia = null;\r\n });\r\n collider.$colliderRemoved.subscribe(() => {\r\n this._cachedInertia = null;\r\n });\r\n const maybeCollider = collider.get();\r\n if (maybeCollider) {\r\n return this._cachedInertia = maybeCollider.getInertia(this.mass);\r\n }\r\n }\r\n return 0;\r\n }\r\n /**\r\n * Get the inverse moment of inertial from the [[ColliderComponent]]. If [[CollisionType.Fixed]] this is 0, meaning \"infinite\" mass\r\n */\r\n get inverseInertia() {\r\n if (this._cachedInverseInertia) {\r\n return this._cachedInverseInertia;\r\n }\r\n return this._cachedInverseInertia = this.collisionType === CollisionType.Fixed ? 0 : 1 / this.inertia;\r\n }\r\n /**\r\n * Returns if the owner is active\r\n */\r\n get active() {\r\n var _a;\r\n return !!((_a = this.owner) === null || _a === void 0 ? void 0 : _a.active);\r\n }\r\n /**\r\n * @deprecated Use globalP0s\r\n */\r\n get center() {\r\n return this.globalPos;\r\n }\r\n get transform() {\r\n var _a;\r\n return (_a = this.owner) === null || _a === void 0 ? void 0 : _a.get(TransformComponent);\r\n }\r\n get motion() {\r\n var _a;\r\n return (_a = this.owner) === null || _a === void 0 ? void 0 : _a.get(MotionComponent);\r\n }\r\n get pos() {\r\n return this.transform.pos;\r\n }\r\n set pos(val) {\r\n this.transform.pos = val;\r\n }\r\n /**\r\n * The (x, y) position of the actor this will be in the middle of the actor if the\r\n * [[Actor.anchor]] is set to (0.5, 0.5) which is default.\r\n * If you want the (x, y) position to be the top left of the actor specify an anchor of (0, 0).\r\n */\r\n get globalPos() {\r\n return this.transform.globalPos;\r\n }\r\n set globalPos(val) {\r\n this.transform.globalPos = val;\r\n }\r\n /**\r\n * The position of the actor last frame (x, y) in pixels\r\n */\r\n get oldPos() {\r\n return this._oldTransform.pos;\r\n }\r\n /**\r\n * The current velocity vector (vx, vy) of the actor in pixels/second\r\n */\r\n get vel() {\r\n return this.motion.vel;\r\n }\r\n set vel(val) {\r\n this.motion.vel = val;\r\n }\r\n /**\r\n * The current acceleration vector (ax, ay) of the actor in pixels/second/second. An acceleration pointing down such as (0, 100) may\r\n * be useful to simulate a gravitational effect.\r\n */\r\n get acc() {\r\n return this.motion.acc;\r\n }\r\n set acc(val) {\r\n this.motion.acc = val;\r\n }\r\n /**\r\n * The current torque applied to the actor\r\n */\r\n get torque() {\r\n return this.motion.torque;\r\n }\r\n set torque(val) {\r\n this.motion.torque = val;\r\n }\r\n /**\r\n * Gets/sets the rotation of the body from the last frame.\r\n */\r\n get oldRotation() {\r\n return this._oldTransform.rotation;\r\n }\r\n /**\r\n * The rotation of the body in radians\r\n */\r\n get rotation() {\r\n return this.transform.globalRotation;\r\n }\r\n set rotation(val) {\r\n this.transform.globalRotation = val;\r\n }\r\n /**\r\n * The scale vector of the actor\r\n */\r\n get scale() {\r\n return this.transform.globalScale;\r\n }\r\n set scale(val) {\r\n this.transform.globalScale = val;\r\n }\r\n /**\r\n * The scale of the actor last frame\r\n */\r\n get oldScale() {\r\n return this._oldTransform.scale;\r\n }\r\n /**\r\n * The scale rate of change of the actor in scale/second\r\n */\r\n get scaleFactor() {\r\n return this.motion.scaleFactor;\r\n }\r\n set scaleFactor(scaleFactor) {\r\n this.motion.scaleFactor = scaleFactor;\r\n }\r\n /**\r\n * Get the angular velocity in radians/second\r\n */\r\n get angularVelocity() {\r\n return this.motion.angularVelocity;\r\n }\r\n /**\r\n * Set the angular velocity in radians/second\r\n */\r\n set angularVelocity(value) {\r\n this.motion.angularVelocity = value;\r\n }\r\n /**\r\n * Apply a specific impulse to the body\r\n * @param point\r\n * @param impulse\r\n */\r\n applyImpulse(point, impulse) {\r\n if (this.collisionType !== CollisionType.Active) {\r\n return; // only active objects participate in the simulation\r\n }\r\n const finalImpulse = impulse.scale(this.inverseMass);\r\n if (this.limitDegreeOfFreedom.includes(DegreeOfFreedom.X)) {\r\n finalImpulse.x = 0;\r\n }\r\n if (this.limitDegreeOfFreedom.includes(DegreeOfFreedom.Y)) {\r\n finalImpulse.y = 0;\r\n }\r\n this.vel.addEqual(finalImpulse);\r\n if (!this.limitDegreeOfFreedom.includes(DegreeOfFreedom.Rotation)) {\r\n const distanceFromCenter = point.sub(this.globalPos);\r\n this.angularVelocity += this.inverseInertia * distanceFromCenter.cross(impulse);\r\n }\r\n }\r\n /**\r\n * Apply only linear impulse to the body\r\n * @param impulse\r\n */\r\n applyLinearImpulse(impulse) {\r\n if (this.collisionType !== CollisionType.Active) {\r\n return; // only active objects participate in the simulation\r\n }\r\n const finalImpulse = impulse.scale(this.inverseMass);\r\n if (this.limitDegreeOfFreedom.includes(DegreeOfFreedom.X)) {\r\n finalImpulse.x = 0;\r\n }\r\n if (this.limitDegreeOfFreedom.includes(DegreeOfFreedom.Y)) {\r\n finalImpulse.y = 0;\r\n }\r\n this.vel = this.vel.add(finalImpulse);\r\n }\r\n /**\r\n * Apply only angular impulse to the body\r\n * @param point\r\n * @param impulse\r\n */\r\n applyAngularImpulse(point, impulse) {\r\n if (this.collisionType !== CollisionType.Active) {\r\n return; // only active objects participate in the simulation\r\n }\r\n if (!this.limitDegreeOfFreedom.includes(DegreeOfFreedom.Rotation)) {\r\n const distanceFromCenter = point.sub(this.globalPos);\r\n this.angularVelocity += this.inverseInertia * distanceFromCenter.cross(impulse);\r\n }\r\n }\r\n /**\r\n * Sets the old versions of pos, vel, acc, and scale.\r\n */\r\n captureOldTransform() {\r\n // Capture old values before integration step updates them\r\n this.__oldTransformCaptured = true;\r\n this.transform.get().clone(this._oldTransform);\r\n this.oldVel.setTo(this.vel.x, this.vel.y);\r\n this.oldAcc.setTo(this.acc.x, this.acc.y);\r\n }\r\n clone() {\r\n const component = super.clone();\r\n return component;\r\n }\r\n}\r\nBodyComponent._ID = 0;\r\n\n;// CONCATENATED MODULE: ./EntityComponentSystem/Entity.ts\n\r\n\r\n\r\n\r\n/**\r\n * AddedComponent message\r\n */\r\nclass AddedComponent {\r\n constructor(data) {\r\n this.data = data;\r\n this.type = 'Component Added';\r\n }\r\n}\r\n/**\r\n * Type guard to know if message is f an Added Component\r\n */\r\nfunction isAddedComponent(x) {\r\n return !!x && x.type === 'Component Added';\r\n}\r\n/**\r\n * RemovedComponent message\r\n */\r\nclass RemovedComponent {\r\n constructor(data) {\r\n this.data = data;\r\n this.type = 'Component Removed';\r\n }\r\n}\r\n/**\r\n * Type guard to know if message is for a Removed Component\r\n */\r\nfunction isRemovedComponent(x) {\r\n return !!x && x.type === 'Component Removed';\r\n}\r\nconst EntityEvents = {\r\n Initialize: 'initialize',\r\n PreUpdate: 'preupdate',\r\n PostUpdate: 'postupdate'\r\n};\r\n/**\r\n * An Entity is the base type of anything that can have behavior in Excalibur, they are part of the built in entity component system\r\n *\r\n * Entities can be strongly typed with the components they contain\r\n *\r\n * ```typescript\r\n * const entity = new Entity();\r\n * entity.components.a; // Type ComponentA\r\n * entity.components.b; // Type ComponentB\r\n * ```\r\n */\r\nclass Entity {\r\n constructor(components, name) {\r\n /**\r\n * Listen to or emit events for an entity\r\n */\r\n this.events = new EventEmitter();\r\n /**\r\n * The unique identifier for the entity\r\n */\r\n this.id = Entity._ID++;\r\n /**\r\n * The scene that the entity is in, if any\r\n */\r\n this.scene = null;\r\n this._name = 'anonymous';\r\n /**\r\n * Whether this entity is active, if set to false it will be reclaimed\r\n */\r\n this.active = true;\r\n /**\r\n * Bucket to hold on to deferred removals\r\n */\r\n this._componentsToRemove = [];\r\n this._componentTypeToInstance = new Map();\r\n this._componentStringToInstance = new Map();\r\n this._tagsMemo = [];\r\n this._typesMemo = [];\r\n /**\r\n * Observable that keeps track of component add or remove changes on the entity\r\n */\r\n this.componentAdded$ = new Observable();\r\n this.componentRemoved$ = new Observable();\r\n this._parent = null;\r\n this.childrenAdded$ = new Observable();\r\n this.childrenRemoved$ = new Observable();\r\n this._children = [];\r\n this._isInitialized = false;\r\n this._setName(name);\r\n if (components) {\r\n for (const component of components) {\r\n this.addComponent(component);\r\n }\r\n }\r\n }\r\n _setName(name) {\r\n if (name) {\r\n this._name = name;\r\n }\r\n }\r\n get name() {\r\n return this._name;\r\n }\r\n /**\r\n * Kill the entity, means it will no longer be updated. Kills are deferred to the end of the update.\r\n * If parented it will be removed from the parent when killed.\r\n */\r\n kill() {\r\n if (this.active) {\r\n this.active = false;\r\n this.unparent();\r\n }\r\n }\r\n isKilled() {\r\n return !this.active;\r\n }\r\n /**\r\n * Specifically get the tags on the entity from [[TagComponent]]\r\n */\r\n get tags() {\r\n return this._tagsMemo;\r\n }\r\n /**\r\n * Check if a tag exists on the entity\r\n * @param tag name to check for\r\n */\r\n hasTag(tag) {\r\n return this.tags.includes(tag);\r\n }\r\n /**\r\n * Adds a tag to an entity\r\n * @param tag\r\n * @returns Entity\r\n */\r\n addTag(tag) {\r\n return this.addComponent(new TagComponent(tag));\r\n }\r\n /**\r\n * Removes a tag on the entity\r\n *\r\n * Removals are deferred until the end of update\r\n * @param tag\r\n * @param force Remove component immediately, no deferred\r\n */\r\n removeTag(tag, force = false) {\r\n return this.removeComponent(tag, force);\r\n }\r\n /**\r\n * The types of the components on the Entity\r\n */\r\n get types() {\r\n return this._typesMemo;\r\n }\r\n _rebuildMemos() {\r\n this._tagsMemo = Array.from(this._componentStringToInstance.values())\r\n .filter((c) => c instanceof TagComponent)\r\n .map((c) => c.type);\r\n this._typesMemo = Array.from(this._componentStringToInstance.keys());\r\n }\r\n getComponents() {\r\n return Array.from(this._componentStringToInstance.values());\r\n }\r\n _notifyAddComponent(component) {\r\n this._rebuildMemos();\r\n const added = new AddedComponent({\r\n component,\r\n entity: this\r\n });\r\n this.componentAdded$.notifyAll(added);\r\n }\r\n _notifyRemoveComponent(component) {\r\n const removed = new RemovedComponent({\r\n component,\r\n entity: this\r\n });\r\n this.componentRemoved$.notifyAll(removed);\r\n this._rebuildMemos();\r\n }\r\n get parent() {\r\n return this._parent;\r\n }\r\n /**\r\n * Get the direct children of this entity\r\n */\r\n get children() {\r\n return this._children;\r\n }\r\n /**\r\n * Unparents this entity, if there is a parent. Otherwise it does nothing.\r\n */\r\n unparent() {\r\n if (this._parent) {\r\n this._parent.removeChild(this);\r\n this._parent = null;\r\n }\r\n }\r\n /**\r\n * Adds an entity to be a child of this entity\r\n * @param entity\r\n */\r\n addChild(entity) {\r\n if (entity.parent === null) {\r\n if (this.getAncestors().includes(entity)) {\r\n throw new Error('Cycle detected, cannot add entity');\r\n }\r\n this._children.push(entity);\r\n entity._parent = this;\r\n this.childrenAdded$.notifyAll(entity);\r\n }\r\n else {\r\n throw new Error('Entity already has a parent, cannot add without unparenting');\r\n }\r\n return this;\r\n }\r\n /**\r\n * Remove an entity from children if it exists\r\n * @param entity\r\n */\r\n removeChild(entity) {\r\n if (entity.parent === this) {\r\n removeItemFromArray(entity, this._children);\r\n entity._parent = null;\r\n this.childrenRemoved$.notifyAll(entity);\r\n }\r\n return this;\r\n }\r\n /**\r\n * Removes all children from this entity\r\n */\r\n removeAllChildren() {\r\n // Avoid modifying the array issue by walking backwards\r\n for (let i = this.children.length - 1; i >= 0; i--) {\r\n this.removeChild(this.children[i]);\r\n }\r\n return this;\r\n }\r\n /**\r\n * Returns a list of parent entities starting with the topmost parent. Includes the current entity.\r\n */\r\n getAncestors() {\r\n const result = [this];\r\n let current = this.parent;\r\n while (current) {\r\n result.push(current);\r\n current = current.parent;\r\n }\r\n return result.reverse();\r\n }\r\n /**\r\n * Returns a list of all the entities that descend from this entity. Includes the current entity.\r\n */\r\n getDescendants() {\r\n let result = [this];\r\n let queue = [this];\r\n while (queue.length > 0) {\r\n const curr = queue.pop();\r\n queue = queue.concat(curr.children);\r\n result = result.concat(curr.children);\r\n }\r\n return result;\r\n }\r\n /**\r\n * Creates a deep copy of the entity and a copy of all its components\r\n */\r\n clone() {\r\n const newEntity = new Entity();\r\n for (const c of this.types) {\r\n newEntity.addComponent(this.get(c).clone());\r\n }\r\n for (const child of this.children) {\r\n newEntity.addChild(child.clone());\r\n }\r\n return newEntity;\r\n }\r\n /**\r\n * Adds a copy of all the components from another template entity as a \"prefab\"\r\n * @param templateEntity Entity to use as a template\r\n * @param force Force component replacement if it already exists on the target entity\r\n */\r\n addTemplate(templateEntity, force = false) {\r\n for (const c of templateEntity.getComponents()) {\r\n this.addComponent(c.clone(), force);\r\n }\r\n for (const child of templateEntity.children) {\r\n this.addChild(child.clone().addTemplate(child));\r\n }\r\n return this;\r\n }\r\n /**\r\n * Adds a component to the entity\r\n * @param component Component or Entity to add copy of components from\r\n * @param force Optionally overwrite any existing components of the same type\r\n */\r\n addComponent(component, force = false) {\r\n // if component already exists, skip if not forced\r\n if (this.has(component.type)) {\r\n if (force) {\r\n // Remove existing component type if exists when forced\r\n this.removeComponent(component, true);\r\n }\r\n else {\r\n // early exit component exits\r\n return this;\r\n }\r\n }\r\n // TODO circular dependencies will be a problem\r\n if (component.dependencies && component.dependencies.length) {\r\n for (const ctor of component.dependencies) {\r\n this.addComponent(new ctor());\r\n }\r\n }\r\n component.owner = this;\r\n const constuctorType = component.constructor;\r\n this._componentTypeToInstance.set(constuctorType, component);\r\n this._componentStringToInstance.set(component.type, component);\r\n if (component.onAdd) {\r\n component.onAdd(this);\r\n }\r\n this._notifyAddComponent(component);\r\n return this;\r\n }\r\n /**\r\n * Removes a component from the entity, by default removals are deferred to the end of entity update to avoid consistency issues\r\n *\r\n * Components can be force removed with the `force` flag, the removal is not deferred and happens immediately\r\n * @param componentOrType\r\n * @param force\r\n */\r\n removeComponent(componentOrType, force = false) {\r\n if (force) {\r\n if (typeof componentOrType === 'string') {\r\n this._removeComponentByType(componentOrType);\r\n }\r\n else if (componentOrType instanceof Component) {\r\n this._removeComponentByType(componentOrType.type);\r\n }\r\n }\r\n else {\r\n this._componentsToRemove.push(componentOrType);\r\n }\r\n return this;\r\n }\r\n clearComponents() {\r\n const components = this.getComponents();\r\n for (const c of components) {\r\n this.removeComponent(c);\r\n }\r\n }\r\n _removeComponentByType(type) {\r\n if (this.has(type)) {\r\n const component = this.get(type);\r\n component.owner = null;\r\n if (component.onRemove) {\r\n component.onRemove(this);\r\n }\r\n const ctor = component.constructor;\r\n this._componentTypeToInstance.delete(ctor);\r\n this._componentStringToInstance.delete(component.type);\r\n this._notifyRemoveComponent(component);\r\n }\r\n }\r\n /**\r\n * @hidden\r\n * @internal\r\n */\r\n processComponentRemoval() {\r\n for (const componentOrType of this._componentsToRemove) {\r\n const type = typeof componentOrType === 'string' ? componentOrType : componentOrType.type;\r\n this._removeComponentByType(type);\r\n }\r\n this._componentsToRemove.length = 0;\r\n }\r\n has(type) {\r\n if (typeof type === 'string') {\r\n return this._componentStringToInstance.has(type);\r\n }\r\n else {\r\n return this._componentTypeToInstance.has(type);\r\n }\r\n }\r\n get(type) {\r\n if (typeof type === 'string') {\r\n return this._componentStringToInstance.get(type);\r\n }\r\n else {\r\n return this._componentTypeToInstance.get(type);\r\n }\r\n }\r\n /**\r\n * Gets whether the actor is Initialized\r\n */\r\n get isInitialized() {\r\n return this._isInitialized;\r\n }\r\n /**\r\n * Initializes this entity, meant to be called by the Scene before first update not by users of Excalibur.\r\n *\r\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\r\n *\r\n * @internal\r\n */\r\n _initialize(engine) {\r\n if (!this.isInitialized) {\r\n this.onInitialize(engine);\r\n this.events.emit('initialize', new InitializeEvent(engine, this));\r\n this._isInitialized = true;\r\n }\r\n }\r\n /**\r\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\r\n *\r\n * Internal _preupdate handler for [[onPreUpdate]] lifecycle event\r\n * @internal\r\n */\r\n _preupdate(engine, delta) {\r\n this.events.emit('preupdate', new PreUpdateEvent(engine, delta, this));\r\n this.onPreUpdate(engine, delta);\r\n }\r\n /**\r\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\r\n *\r\n * Internal _preupdate handler for [[onPostUpdate]] lifecycle event\r\n * @internal\r\n */\r\n _postupdate(engine, delta) {\r\n this.events.emit('postupdate', new PostUpdateEvent(engine, delta, this));\r\n this.onPostUpdate(engine, delta);\r\n }\r\n /**\r\n * `onInitialize` is called before the first update of the entity. This method is meant to be\r\n * overridden.\r\n *\r\n * Synonymous with the event handler `.on('initialize', (evt) => {...})`\r\n */\r\n onInitialize(_engine) {\r\n // Override me\r\n }\r\n /**\r\n * Safe to override onPreUpdate lifecycle event handler. Synonymous with `.on('preupdate', (evt) =>{...})`\r\n *\r\n * `onPreUpdate` is called directly before an entity is updated.\r\n */\r\n onPreUpdate(_engine, _delta) {\r\n // Override me\r\n }\r\n /**\r\n * Safe to override onPostUpdate lifecycle event handler. Synonymous with `.on('postupdate', (evt) =>{...})`\r\n *\r\n * `onPostUpdate` is called directly after an entity is updated.\r\n */\r\n onPostUpdate(_engine, _delta) {\r\n // Override me\r\n }\r\n /**\r\n *\r\n * Entity update lifecycle, called internally\r\n *\r\n * @internal\r\n * @param engine\r\n * @param delta\r\n */\r\n update(engine, delta) {\r\n this._initialize(engine);\r\n this._preupdate(engine, delta);\r\n for (const child of this.children) {\r\n child.update(engine, delta);\r\n }\r\n this._postupdate(engine, delta);\r\n }\r\n emit(eventName, event) {\r\n this.events.emit(eventName, event);\r\n }\r\n on(eventName, handler) {\r\n return this.events.on(eventName, handler);\r\n }\r\n once(eventName, handler) {\r\n return this.events.once(eventName, handler);\r\n }\r\n off(eventName, handler) {\r\n this.events.off(eventName, handler);\r\n }\r\n}\r\nEntity._ID = 0;\r\n\n;// CONCATENATED MODULE: ./Graphics/GraphicsComponent.ts\n\r\n\r\n\r\n\r\n\r\n/**\r\n * Type guard for checking if a Graphic HasTick (used for graphics that change over time like animations)\r\n * @param graphic\r\n */\r\nfunction hasGraphicsTick(graphic) {\r\n return !!graphic.tick;\r\n}\r\nclass GraphicsLayer {\r\n constructor(_options, _graphics) {\r\n this._options = _options;\r\n this._graphics = _graphics;\r\n this.graphics = [];\r\n }\r\n get name() {\r\n return this._options.name;\r\n }\r\n hide(nameOrGraphic) {\r\n if (!nameOrGraphic) {\r\n this.graphics.length = 0;\r\n }\r\n else {\r\n let gfx = null;\r\n if (nameOrGraphic instanceof Graphic) {\r\n gfx = nameOrGraphic;\r\n }\r\n else {\r\n gfx = this._graphics.getGraphic(nameOrGraphic);\r\n }\r\n this.graphics = this.graphics.filter((g) => g.graphic !== gfx);\r\n this._graphics.recalculateBounds();\r\n }\r\n }\r\n /**\r\n * Show a graphic by name or instance at an offset, graphics are shown in the order in which `show()` is called.\r\n *\r\n * If `show()` is called multiple times for the same graphic it will be shown multiple times.\r\n * @param nameOrGraphic\r\n * @param options\r\n */\r\n show(nameOrGraphic, options) {\r\n options = { ...options };\r\n let gfx;\r\n if (nameOrGraphic instanceof Graphic) {\r\n gfx = this._graphics.copyGraphics ? nameOrGraphic.clone() : nameOrGraphic;\r\n }\r\n else {\r\n gfx = this._graphics.getGraphic(nameOrGraphic);\r\n if (!gfx) {\r\n Logger.getInstance().error(`No such graphic added to component named ${nameOrGraphic}. These named graphics are available: `, this._graphics.getNames());\r\n }\r\n }\r\n if (gfx) {\r\n this.graphics.push({ graphic: gfx, options });\r\n this._graphics.recalculateBounds();\r\n return gfx;\r\n }\r\n else {\r\n return null;\r\n }\r\n }\r\n /**\r\n * Use a specific graphic, swap out any current graphics being shown\r\n * @param nameOrGraphic\r\n * @param options\r\n */\r\n use(nameOrGraphic, options) {\r\n options = { ...options };\r\n this.hide();\r\n return this.show(nameOrGraphic, options);\r\n }\r\n /**\r\n * Current order of the layer, higher numbers are on top, lower numbers are on the bottom.\r\n *\r\n * For example a layer with `order = -1` would be under a layer of `order = 1`\r\n */\r\n get order() {\r\n return this._options.order;\r\n }\r\n /**\r\n * Set the order of the layer, higher numbers are on top, lower numbers are on the bottom.\r\n *\r\n * For example a layer with `order = -1` would be under a layer of `order = 1`\r\n */\r\n set order(order) {\r\n this._options.order = order;\r\n }\r\n /**\r\n * Get or set the pixel offset from the layer anchor for all graphics in the layer\r\n */\r\n get offset() {\r\n var _a;\r\n return (_a = this._options.offset) !== null && _a !== void 0 ? _a : Vector.Zero;\r\n }\r\n set offset(value) {\r\n this._options.offset = value;\r\n }\r\n get currentKeys() {\r\n var _a;\r\n return (_a = this.name) !== null && _a !== void 0 ? _a : 'anonymous';\r\n }\r\n clone(graphicsComponent) {\r\n const layer = new GraphicsLayer({ ...this._options }, graphicsComponent);\r\n layer.graphics = [...this.graphics.map(g => ({ graphic: g.graphic.clone(), options: { ...g.options } }))];\r\n return layer;\r\n }\r\n}\r\nclass GraphicsLayers {\r\n constructor(_component) {\r\n this._component = _component;\r\n this._layers = [];\r\n this._layerMap = {};\r\n this.default = new GraphicsLayer({ name: 'default', order: 0 }, _component);\r\n this._maybeAddLayer(this.default);\r\n }\r\n create(options) {\r\n const layer = new GraphicsLayer(options, this._component);\r\n return this._maybeAddLayer(layer);\r\n }\r\n get(name) {\r\n if (name) {\r\n return this._getLayer(name);\r\n }\r\n return this._layers;\r\n }\r\n currentKeys() {\r\n const graphicsLayerKeys = [];\r\n for (const layer of this._layers) {\r\n graphicsLayerKeys.push(layer.currentKeys);\r\n }\r\n return graphicsLayerKeys;\r\n }\r\n has(name) {\r\n return name in this._layerMap;\r\n }\r\n _maybeAddLayer(layer) {\r\n if (this._layerMap[layer.name]) {\r\n // todo log warning\r\n return this._layerMap[layer.name];\r\n }\r\n this._layerMap[layer.name] = layer;\r\n this._layers.push(layer);\r\n this._layers.sort((a, b) => a.order - b.order);\r\n return layer;\r\n }\r\n _getLayer(name) {\r\n return this._layerMap[name];\r\n }\r\n clone(graphicsComponent) {\r\n const layers = new GraphicsLayers(graphicsComponent);\r\n layers._layerMap = {};\r\n layers._layers = [];\r\n layers.default = this.default.clone(graphicsComponent);\r\n layers._maybeAddLayer(layers.default);\r\n // Remove the default layer out of the clone\r\n const clonedLayers = this._layers.filter(l => l.name !== 'default').map(l => l.clone(graphicsComponent));\r\n clonedLayers.forEach(layer => layers._maybeAddLayer(layer));\r\n return layers;\r\n }\r\n}\r\n/**\r\n * Component to manage drawings, using with the position component\r\n */\r\nclass GraphicsComponent extends Component {\r\n getGraphic(name) {\r\n return this._graphics[name];\r\n }\r\n /**\r\n * Get registered graphics names\r\n */\r\n getNames() {\r\n return Object.keys(this._graphics);\r\n }\r\n constructor(options) {\r\n super();\r\n this.type = 'ex.graphics';\r\n this._graphics = {};\r\n /**\r\n * Sets or gets wether any drawing should be visible in this component\r\n */\r\n this.visible = true;\r\n /**\r\n * Sets or gets wither all drawings should have an opacity applied\r\n */\r\n this.opacity = 1;\r\n /**\r\n * Offset to apply to graphics by default\r\n */\r\n this.offset = Vector.Zero;\r\n /**\r\n * Anchor to apply to graphics by default\r\n */\r\n this.anchor = Vector.Half;\r\n /**\r\n * Flip all graphics horizontally along the y-axis\r\n */\r\n this.flipHorizontal = false;\r\n /**\r\n * Flip all graphics vertically along the x-axis\r\n */\r\n this.flipVertical = false;\r\n /**\r\n * If set to true graphics added to the component will be copied. This can affect performance\r\n */\r\n this.copyGraphics = false;\r\n this._localBounds = null;\r\n // Defaults\r\n options = {\r\n visible: this.visible,\r\n ...options\r\n };\r\n const { current, anchor, opacity, visible, graphics, offset, copyGraphics, onPreDraw, onPostDraw } = options;\r\n this._graphics = graphics || {};\r\n this.offset = offset !== null && offset !== void 0 ? offset : this.offset;\r\n this.opacity = opacity !== null && opacity !== void 0 ? opacity : this.opacity;\r\n this.anchor = anchor !== null && anchor !== void 0 ? anchor : this.anchor;\r\n this.copyGraphics = copyGraphics !== null && copyGraphics !== void 0 ? copyGraphics : this.copyGraphics;\r\n this.onPreDraw = onPreDraw !== null && onPreDraw !== void 0 ? onPreDraw : this.onPreDraw;\r\n this.onPostDraw = onPostDraw !== null && onPostDraw !== void 0 ? onPostDraw : this.onPostDraw;\r\n this.visible = !!visible;\r\n this.layers = new GraphicsLayers(this);\r\n if (current && this._graphics[current]) {\r\n this.show(this._graphics[current]);\r\n }\r\n }\r\n /**\r\n * Returns the currently displayed graphics and their offsets, empty array if hidden\r\n */\r\n get current() {\r\n return this.layers.default.graphics;\r\n }\r\n /**\r\n * Returns all graphics associated with this component\r\n */\r\n get graphics() {\r\n return this._graphics;\r\n }\r\n add(nameOrGraphic, graphic) {\r\n let name = 'default';\r\n let graphicToSet = null;\r\n if (typeof nameOrGraphic === 'string') {\r\n name = nameOrGraphic;\r\n graphicToSet = graphic;\r\n }\r\n else {\r\n graphicToSet = nameOrGraphic;\r\n }\r\n this._graphics[name] = this.copyGraphics ? graphicToSet.clone() : graphicToSet;\r\n if (name === 'default') {\r\n this.show('default');\r\n }\r\n return graphicToSet;\r\n }\r\n /**\r\n * Show a graphic by name on the **default** layer, returns the new [[Graphic]]\r\n */\r\n show(nameOrGraphic, options) {\r\n const result = this.layers.default.show(nameOrGraphic, options);\r\n this.recalculateBounds();\r\n return result;\r\n }\r\n /**\r\n * Use a graphic only, swap out any graphics on the **default** layer, returns the new [[Graphic]]\r\n * @param nameOrGraphic\r\n * @param options\r\n */\r\n use(nameOrGraphic, options) {\r\n const result = this.layers.default.use(nameOrGraphic, options);\r\n this.recalculateBounds();\r\n return result;\r\n }\r\n hide(nameOrGraphic) {\r\n this.layers.default.hide(nameOrGraphic);\r\n }\r\n set localBounds(bounds) {\r\n this._localBounds = bounds;\r\n }\r\n recalculateBounds() {\r\n let bb = new BoundingBox();\r\n for (const layer of this.layers.get()) {\r\n for (const { graphic, options } of layer.graphics) {\r\n let anchor = this.anchor;\r\n let offset = this.offset;\r\n if (options === null || options === void 0 ? void 0 : options.anchor) {\r\n anchor = options.anchor;\r\n }\r\n if (options === null || options === void 0 ? void 0 : options.offset) {\r\n offset = options.offset;\r\n }\r\n const bounds = graphic.localBounds;\r\n const offsetX = -bounds.width * anchor.x + offset.x;\r\n const offsetY = -bounds.height * anchor.y + offset.y;\r\n bb = graphic === null || graphic === void 0 ? void 0 : graphic.localBounds.translate(vec(offsetX + layer.offset.x, offsetY + layer.offset.y)).combine(bb);\r\n }\r\n }\r\n this._localBounds = bb;\r\n }\r\n get localBounds() {\r\n if (!this._localBounds || this._localBounds.hasZeroDimensions()) {\r\n this.recalculateBounds();\r\n }\r\n return this._localBounds;\r\n }\r\n /**\r\n * Update underlying graphics if necesary, called internally\r\n * @param elapsed\r\n * @internal\r\n */\r\n update(elapsed, idempotencyToken = 0) {\r\n for (const layer of this.layers.get()) {\r\n for (const { graphic } of layer.graphics) {\r\n if (hasGraphicsTick(graphic)) {\r\n graphic === null || graphic === void 0 ? void 0 : graphic.tick(elapsed, idempotencyToken);\r\n }\r\n }\r\n }\r\n }\r\n clone() {\r\n const graphics = new GraphicsComponent();\r\n graphics._graphics = { ...this._graphics };\r\n graphics.offset = this.offset.clone();\r\n graphics.opacity = this.opacity;\r\n graphics.anchor = this.anchor.clone();\r\n graphics.copyGraphics = this.copyGraphics;\r\n graphics.onPreDraw = this.onPreDraw;\r\n graphics.onPostDraw = this.onPostDraw;\r\n graphics.visible = this.visible;\r\n graphics.layers = this.layers.clone(graphics);\r\n return graphics;\r\n }\r\n}\r\n\n;// CONCATENATED MODULE: ./Graphics/Rectangle.ts\n\r\n/**\r\n * A Rectangle [[Graphic]] for drawing rectangles to the [[ExcaliburGraphicsContext]]\r\n */\r\nclass Rectangle extends Raster {\r\n constructor(options) {\r\n super(options);\r\n this.width = options.width;\r\n this.height = options.height;\r\n this.rasterize();\r\n }\r\n clone() {\r\n return new Rectangle({\r\n width: this.width,\r\n height: this.height,\r\n ...this.cloneGraphicOptions(),\r\n ...this.cloneRasterOptions()\r\n });\r\n }\r\n execute(ctx) {\r\n if (this.color) {\r\n ctx.fillRect(0, 0, this.width, this.height);\r\n }\r\n if (this.strokeColor) {\r\n ctx.strokeRect(0, 0, this.width, this.height);\r\n }\r\n }\r\n}\r\n\n;// CONCATENATED MODULE: ./Graphics/Circle.ts\n\r\n\r\n/**\r\n * A circle [[Graphic]] for drawing circles to the [[ExcaliburGraphicsContext]]\r\n *\r\n * Circles default to [[ImageFiltering.Blended]]\r\n */\r\nclass Circle extends Raster {\r\n get radius() {\r\n return this._radius;\r\n }\r\n set radius(value) {\r\n this._radius = value;\r\n this.width = this._radius * 2;\r\n this.height = this._radius * 2;\r\n this.flagDirty();\r\n }\r\n constructor(options) {\r\n var _a, _b, _c;\r\n super(options);\r\n this._radius = 0;\r\n const lineWidth = (_a = options.lineWidth) !== null && _a !== void 0 ? _a : (options.strokeColor ? 1 : 0); // default lineWidth in canvas is 1px\r\n this.padding = (_b = options.padding) !== null && _b !== void 0 ? _b : 2 + (lineWidth / 2); // default 2 padding for circles looks nice\r\n this.radius = options.radius;\r\n this.filtering = (_c = options.filtering) !== null && _c !== void 0 ? _c : ImageFiltering.Blended;\r\n this.rasterize();\r\n }\r\n clone() {\r\n return new Circle({\r\n radius: this.radius,\r\n ...this.cloneGraphicOptions(),\r\n ...this.cloneRasterOptions()\r\n });\r\n }\r\n execute(ctx) {\r\n if (this.radius > 0) {\r\n ctx.beginPath();\r\n ctx.arc(this.radius, this.radius, this.radius, 0, Math.PI * 2);\r\n if (this.color) {\r\n ctx.fill();\r\n }\r\n if (this.strokeColor) {\r\n ctx.stroke();\r\n }\r\n }\r\n }\r\n}\r\n\n;// CONCATENATED MODULE: ./Input/PointerComponent.ts\n\r\n/**\r\n * Add this component to optionally configure how the pointer\r\n * system detects pointer events.\r\n *\r\n * By default the collider shape is used and graphics bounds is not.\r\n *\r\n * If both collider shape and graphics bounds are enabled it will fire events if either or\r\n * are intersecting the pointer.\r\n */\r\nclass PointerComponent extends Component {\r\n constructor() {\r\n super(...arguments);\r\n this.type = 'ex.pointer';\r\n /**\r\n * Use any existing Collider component geometry for pointer events. This is useful if you want\r\n * user pointer events only to trigger on the same collision geometry used in the collider component\r\n * for collision resolution. Default is `true`.\r\n */\r\n this.useColliderShape = true;\r\n /**\r\n * Use any existing Graphics component bounds for pointers. This is useful if you want the axis aligned\r\n * bounds around the graphic to trigger pointer events. Default is `false`.\r\n */\r\n this.useGraphicsBounds = false;\r\n }\r\n}\r\n\n;// CONCATENATED MODULE: ./Util/EasingFunctions.ts\n\r\n/**\r\n * Standard easing functions for motion in Excalibur, defined on a domain of [0, duration] and a range from [+startValue,+endValue]\r\n * Given a time, the function will return a value from positive startValue to positive endValue.\r\n *\r\n * ```js\r\n * function Linear (t) {\r\n * return t * t;\r\n * }\r\n *\r\n * // accelerating from zero velocity\r\n * function EaseInQuad (t) {\r\n * return t * t;\r\n * }\r\n *\r\n * // decelerating to zero velocity\r\n * function EaseOutQuad (t) {\r\n * return t * (2 - t);\r\n * }\r\n *\r\n * // acceleration until halfway, then deceleration\r\n * function EaseInOutQuad (t) {\r\n * return t < .5 ? 2 * t * t : -1 + (4 - 2 * t) * t;\r\n * }\r\n *\r\n * // accelerating from zero velocity\r\n * function EaseInCubic (t) {\r\n * return t * t * t;\r\n * }\r\n *\r\n * // decelerating to zero velocity\r\n * function EaseOutCubic (t) {\r\n * return (--t) * t * t + 1;\r\n * }\r\n *\r\n * // acceleration until halfway, then deceleration\r\n * function EaseInOutCubic (t) {\r\n * return t < .5 ? 4 * t * t * t : (t - 1) * (2 * t - 2) * (2 * t - 2) + 1;\r\n * }\r\n * ```\r\n */\r\nclass EasingFunctions {\r\n static CreateReversibleEasingFunction(easing) {\r\n return (time, start, end, duration) => {\r\n if (end < start) {\r\n return start - (easing(time, end, start, duration) - end);\r\n }\r\n else {\r\n return easing(time, start, end, duration);\r\n }\r\n };\r\n }\r\n static CreateVectorEasingFunction(easing) {\r\n return (time, start, end, duration) => {\r\n return new Vector(easing(time, start.x, end.x, duration), easing(time, start.y, end.y, duration));\r\n };\r\n }\r\n}\r\nEasingFunctions.Linear = EasingFunctions.CreateReversibleEasingFunction((currentTime, startValue, endValue, duration) => {\r\n endValue = endValue - startValue;\r\n return (endValue * currentTime) / duration + startValue;\r\n});\r\nEasingFunctions.EaseInQuad = EasingFunctions.CreateReversibleEasingFunction((currentTime, startValue, endValue, duration) => {\r\n endValue = endValue - startValue;\r\n currentTime /= duration;\r\n return endValue * currentTime * currentTime + startValue;\r\n});\r\nEasingFunctions.EaseOutQuad = EasingFunctions.CreateReversibleEasingFunction((currentTime, startValue, endValue, duration) => {\r\n endValue = endValue - startValue;\r\n currentTime /= duration;\r\n return -endValue * currentTime * (currentTime - 2) + startValue;\r\n});\r\nEasingFunctions.EaseInOutQuad = EasingFunctions.CreateReversibleEasingFunction((currentTime, startValue, endValue, duration) => {\r\n endValue = endValue - startValue;\r\n currentTime /= duration / 2;\r\n if (currentTime < 1) {\r\n return (endValue / 2) * currentTime * currentTime + startValue;\r\n }\r\n currentTime--;\r\n return (-endValue / 2) * (currentTime * (currentTime - 2) - 1) + startValue;\r\n});\r\nEasingFunctions.EaseInCubic = EasingFunctions.CreateReversibleEasingFunction((currentTime, startValue, endValue, duration) => {\r\n endValue = endValue - startValue;\r\n currentTime /= duration;\r\n return endValue * currentTime * currentTime * currentTime + startValue;\r\n});\r\nEasingFunctions.EaseOutCubic = EasingFunctions.CreateReversibleEasingFunction((currentTime, startValue, endValue, duration) => {\r\n endValue = endValue - startValue;\r\n currentTime /= duration;\r\n currentTime--;\r\n return endValue * (currentTime * currentTime * currentTime + 1) + startValue;\r\n});\r\nEasingFunctions.EaseInOutCubic = EasingFunctions.CreateReversibleEasingFunction((currentTime, startValue, endValue, duration) => {\r\n endValue = endValue - startValue;\r\n currentTime /= duration / 2;\r\n if (currentTime < 1) {\r\n return (endValue / 2) * currentTime * currentTime * currentTime + startValue;\r\n }\r\n currentTime -= 2;\r\n return (endValue / 2) * (currentTime * currentTime * currentTime + 2) + startValue;\r\n});\r\n\n;// CONCATENATED MODULE: ./Actions/ActionQueue.ts\n/**\r\n * Action Queues represent an ordered sequence of actions\r\n *\r\n * Action queues are part of the [[ActionContext|Action API]] and\r\n * store the list of actions to be executed for an [[Actor]].\r\n *\r\n * Actors implement [[Actor.actions]] which can be manipulated by\r\n * advanced users to adjust the actions currently being executed in the\r\n * queue.\r\n */\r\nclass ActionQueue {\r\n constructor(entity) {\r\n this._actions = [];\r\n this._completedActions = [];\r\n this._entity = entity;\r\n }\r\n /**\r\n * Add an action to the sequence\r\n * @param action\r\n */\r\n add(action) {\r\n this._actions.push(action);\r\n }\r\n /**\r\n * Remove an action by reference from the sequence\r\n * @param action\r\n */\r\n remove(action) {\r\n const index = this._actions.indexOf(action);\r\n this._actions.splice(index, 1);\r\n }\r\n /**\r\n * Removes all actions from this sequence\r\n */\r\n clearActions() {\r\n this._actions.length = 0;\r\n this._completedActions.length = 0;\r\n if (this._currentAction) {\r\n this._currentAction.stop();\r\n }\r\n }\r\n /**\r\n *\r\n * @returns The total list of actions in this sequence complete or not\r\n */\r\n getActions() {\r\n return this._actions.concat(this._completedActions);\r\n }\r\n /**\r\n *\r\n * @returns `true` if there are more actions to process in the sequence\r\n */\r\n hasNext() {\r\n return this._actions.length > 0;\r\n }\r\n /**\r\n * @returns `true` if the current sequence of actions is done\r\n */\r\n isComplete() {\r\n return this._actions.length === 0;\r\n }\r\n /**\r\n * Resets the sequence of actions, this is used to restart a sequence from the beginning\r\n */\r\n reset() {\r\n this._actions = this.getActions();\r\n const len = this._actions.length;\r\n for (let i = 0; i < len; i++) {\r\n this._actions[i].reset();\r\n }\r\n this._completedActions = [];\r\n }\r\n /**\r\n * Update the queue which updates actions and handles completing actions\r\n * @param elapsedMs\r\n */\r\n update(elapsedMs) {\r\n if (this._actions.length > 0) {\r\n this._currentAction = this._actions[0];\r\n this._currentAction.update(elapsedMs);\r\n if (this._currentAction.isComplete(this._entity)) {\r\n this._completedActions.push(this._actions.shift());\r\n }\r\n }\r\n }\r\n}\r\n\n;// CONCATENATED MODULE: ./Actions/Action/Repeat.ts\n\r\nclass Repeat {\r\n constructor(entity, repeatBuilder, repeat) {\r\n this._stopped = false;\r\n this._repeatBuilder = repeatBuilder;\r\n this._repeatContext = new ActionContext(entity);\r\n this._actionQueue = this._repeatContext.getQueue();\r\n this._repeat = repeat;\r\n this._originalRepeat = repeat;\r\n this._repeatBuilder(this._repeatContext);\r\n this._repeat--; // current execution is the first repeat\r\n }\r\n update(delta) {\r\n if (this._actionQueue.isComplete()) {\r\n this._actionQueue.clearActions();\r\n this._repeatBuilder(this._repeatContext);\r\n this._repeat--;\r\n }\r\n this._actionQueue.update(delta);\r\n }\r\n isComplete() {\r\n return this._stopped || (this._repeat <= 0 && this._actionQueue.isComplete());\r\n }\r\n stop() {\r\n this._stopped = true;\r\n }\r\n reset() {\r\n this._repeat = this._originalRepeat;\r\n }\r\n}\r\n\n;// CONCATENATED MODULE: ./Actions/Action/RepeatForever.ts\n\r\n/**\r\n * RepeatForever Action implementation, it is recommended you use the fluent action\r\n * context API.\r\n *\r\n *\r\n */\r\nclass RepeatForever {\r\n constructor(entity, repeatBuilder) {\r\n this._stopped = false;\r\n this._repeatBuilder = repeatBuilder;\r\n this._repeatContext = new ActionContext(entity);\r\n this._actionQueue = this._repeatContext.getQueue();\r\n this._repeatBuilder(this._repeatContext);\r\n }\r\n update(delta) {\r\n if (this._stopped) {\r\n return;\r\n }\r\n if (this._actionQueue.isComplete()) {\r\n this._actionQueue.clearActions();\r\n this._repeatBuilder(this._repeatContext);\r\n }\r\n this._actionQueue.update(delta);\r\n }\r\n isComplete() {\r\n return this._stopped;\r\n }\r\n stop() {\r\n this._stopped = true;\r\n this._actionQueue.clearActions();\r\n }\r\n reset() {\r\n return;\r\n }\r\n}\r\n\n;// CONCATENATED MODULE: ./Actions/Action/MoveBy.ts\n\r\n\r\n\r\n\r\nclass MoveBy {\r\n constructor(entity, offsetX, offsetY, speed) {\r\n this._started = false;\r\n this._stopped = false;\r\n this._entity = entity;\r\n this._tx = entity.get(TransformComponent);\r\n this._motion = entity.get(MotionComponent);\r\n this._speed = speed;\r\n this._offset = new Vector(offsetX, offsetY);\r\n if (speed <= 0) {\r\n Logger.getInstance().error('Attempted to moveBy with speed less than or equal to zero : ' + speed);\r\n throw new Error('Speed must be greater than 0 pixels per second');\r\n }\r\n }\r\n update(_delta) {\r\n if (!this._started) {\r\n this._started = true;\r\n this._start = new Vector(this._tx.pos.x, this._tx.pos.y);\r\n this._end = this._start.add(this._offset);\r\n this._distance = this._offset.size;\r\n this._dir = this._end.sub(this._start).normalize();\r\n }\r\n if (this.isComplete(this._entity)) {\r\n this._tx.pos = vec(this._end.x, this._end.y);\r\n this._motion.vel = vec(0, 0);\r\n }\r\n else {\r\n this._motion.vel = this._dir.scale(this._speed);\r\n }\r\n }\r\n isComplete(entity) {\r\n const tx = entity.get(TransformComponent);\r\n return this._stopped || tx.pos.distance(this._start) >= this._distance;\r\n }\r\n stop() {\r\n this._motion.vel = vec(0, 0);\r\n this._stopped = true;\r\n }\r\n reset() {\r\n this._started = false;\r\n this._stopped = false;\r\n }\r\n}\r\n\n;// CONCATENATED MODULE: ./Actions/Action/MoveTo.ts\n\r\n\r\n\r\nclass MoveTo {\r\n constructor(entity, destx, desty, speed) {\r\n this.entity = entity;\r\n this._started = false;\r\n this._stopped = false;\r\n this._tx = entity.get(TransformComponent);\r\n this._motion = entity.get(MotionComponent);\r\n this._end = new Vector(destx, desty);\r\n this._speed = speed;\r\n }\r\n update(_delta) {\r\n if (!this._started) {\r\n this._started = true;\r\n this._start = new Vector(this._tx.pos.x, this._tx.pos.y);\r\n this._distance = this._start.distance(this._end);\r\n this._dir = this._end.sub(this._start).normalize();\r\n }\r\n const m = this._dir.scale(this._speed);\r\n this._motion.vel = vec(m.x, m.y);\r\n if (this.isComplete(this.entity)) {\r\n this._tx.pos = vec(this._end.x, this._end.y);\r\n this._motion.vel = vec(0, 0);\r\n }\r\n }\r\n isComplete(entity) {\r\n const tx = entity.get(TransformComponent);\r\n return this._stopped || new Vector(tx.pos.x, tx.pos.y).distance(this._start) >= this._distance;\r\n }\r\n stop() {\r\n this._motion.vel = vec(0, 0);\r\n this._stopped = true;\r\n }\r\n reset() {\r\n this._started = false;\r\n this._stopped = false;\r\n }\r\n}\r\n\n;// CONCATENATED MODULE: ./Actions/RotationType.ts\n/**\r\n * An enum that describes the strategies that rotation actions can use\r\n */\r\nvar RotationType;\r\n(function (RotationType) {\r\n /**\r\n * Rotation via `ShortestPath` will use the smallest angle\r\n * between the starting and ending points. This strategy is the default behavior.\r\n */\r\n RotationType[RotationType[\"ShortestPath\"] = 0] = \"ShortestPath\";\r\n /**\r\n * Rotation via `LongestPath` will use the largest angle\r\n * between the starting and ending points.\r\n */\r\n RotationType[RotationType[\"LongestPath\"] = 1] = \"LongestPath\";\r\n /**\r\n * Rotation via `Clockwise` will travel in a clockwise direction,\r\n * regardless of the starting and ending points.\r\n */\r\n RotationType[RotationType[\"Clockwise\"] = 2] = \"Clockwise\";\r\n /**\r\n * Rotation via `CounterClockwise` will travel in a counterclockwise direction,\r\n * regardless of the starting and ending points.\r\n */\r\n RotationType[RotationType[\"CounterClockwise\"] = 3] = \"CounterClockwise\";\r\n})(RotationType || (RotationType = {}));\r\n\n;// CONCATENATED MODULE: ./Actions/Action/RotateTo.ts\n\r\n\r\n\r\n\r\nclass RotateTo {\r\n constructor(entity, angleRadians, speed, rotationType) {\r\n this._started = false;\r\n this._stopped = false;\r\n this._tx = entity.get(TransformComponent);\r\n this._motion = entity.get(MotionComponent);\r\n this._end = angleRadians;\r\n this._speed = speed;\r\n this._rotationType = rotationType || RotationType.ShortestPath;\r\n }\r\n update(_delta) {\r\n if (!this._started) {\r\n this._started = true;\r\n this._start = this._tx.rotation;\r\n this._currentNonCannonAngle = this._tx.rotation;\r\n const distance1 = Math.abs(this._end - this._start);\r\n const distance2 = TwoPI - distance1;\r\n if (distance1 > distance2) {\r\n this._shortDistance = distance2;\r\n this._longDistance = distance1;\r\n }\r\n else {\r\n this._shortDistance = distance1;\r\n this._longDistance = distance2;\r\n }\r\n this._shortestPathIsPositive = (this._start - this._end + TwoPI) % TwoPI >= Math.PI;\r\n switch (this._rotationType) {\r\n case RotationType.ShortestPath:\r\n this._distance = this._shortDistance;\r\n if (this._shortestPathIsPositive) {\r\n this._direction = 1;\r\n }\r\n else {\r\n this._direction = -1;\r\n }\r\n break;\r\n case RotationType.LongestPath:\r\n this._distance = this._longDistance;\r\n if (this._shortestPathIsPositive) {\r\n this._direction = -1;\r\n }\r\n else {\r\n this._direction = 1;\r\n }\r\n break;\r\n case RotationType.Clockwise:\r\n this._direction = 1;\r\n if (this._shortestPathIsPositive) {\r\n this._distance = this._shortDistance;\r\n }\r\n else {\r\n this._distance = this._longDistance;\r\n }\r\n break;\r\n case RotationType.CounterClockwise:\r\n this._direction = -1;\r\n if (!this._shortestPathIsPositive) {\r\n this._distance = this._shortDistance;\r\n }\r\n else {\r\n this._distance = this._longDistance;\r\n }\r\n break;\r\n }\r\n }\r\n this._motion.angularVelocity = this._direction * this._speed;\r\n this._currentNonCannonAngle += this._direction * this._speed * (_delta / 1000);\r\n if (this.isComplete()) {\r\n this._tx.rotation = this._end;\r\n this._motion.angularVelocity = 0;\r\n this._stopped = true;\r\n }\r\n }\r\n isComplete() {\r\n const distanceTraveled = Math.abs(this._currentNonCannonAngle - this._start);\r\n return this._stopped || distanceTraveled >= Math.abs(this._distance);\r\n }\r\n stop() {\r\n this._motion.angularVelocity = 0;\r\n this._stopped = true;\r\n }\r\n reset() {\r\n this._started = false;\r\n this._stopped = false;\r\n }\r\n}\r\n\n;// CONCATENATED MODULE: ./Actions/Action/RotateBy.ts\n\r\n\r\n\r\n\r\nclass RotateBy {\r\n constructor(entity, angleRadiansOffset, speed, rotationType) {\r\n this._started = false;\r\n this._stopped = false;\r\n this._tx = entity.get(TransformComponent);\r\n this._motion = entity.get(MotionComponent);\r\n this._speed = speed;\r\n this._offset = angleRadiansOffset;\r\n this._rotationType = rotationType || RotationType.ShortestPath;\r\n }\r\n update(_delta) {\r\n if (!this._started) {\r\n this._started = true;\r\n this._start = this._tx.rotation;\r\n this._currentNonCannonAngle = this._tx.rotation;\r\n this._end = this._start + this._offset;\r\n const distance1 = Math.abs(this._end - this._start);\r\n const distance2 = TwoPI - distance1;\r\n if (distance1 > distance2) {\r\n this._shortDistance = distance2;\r\n this._longDistance = distance1;\r\n }\r\n else {\r\n this._shortDistance = distance1;\r\n this._longDistance = distance2;\r\n }\r\n this._shortestPathIsPositive = (this._start - this._end + TwoPI) % TwoPI >= Math.PI;\r\n switch (this._rotationType) {\r\n case RotationType.ShortestPath:\r\n this._distance = this._shortDistance;\r\n if (this._shortestPathIsPositive) {\r\n this._direction = 1;\r\n }\r\n else {\r\n this._direction = -1;\r\n }\r\n break;\r\n case RotationType.LongestPath:\r\n this._distance = this._longDistance;\r\n if (this._shortestPathIsPositive) {\r\n this._direction = -1;\r\n }\r\n else {\r\n this._direction = 1;\r\n }\r\n break;\r\n case RotationType.Clockwise:\r\n this._direction = 1;\r\n if (this._shortDistance >= 0) {\r\n this._distance = this._shortDistance;\r\n }\r\n else {\r\n this._distance = this._longDistance;\r\n }\r\n break;\r\n case RotationType.CounterClockwise:\r\n this._direction = -1;\r\n if (this._shortDistance <= 0) {\r\n this._distance = this._shortDistance;\r\n }\r\n else {\r\n this._distance = this._longDistance;\r\n }\r\n break;\r\n }\r\n }\r\n this._motion.angularVelocity = this._direction * this._speed;\r\n this._currentNonCannonAngle += this._direction * this._speed * (_delta / 1000);\r\n if (this.isComplete()) {\r\n this._tx.rotation = this._end;\r\n this._motion.angularVelocity = 0;\r\n this._stopped = true;\r\n }\r\n }\r\n isComplete() {\r\n const distanceTraveled = Math.abs(this._currentNonCannonAngle - this._start);\r\n return this._stopped || distanceTraveled >= Math.abs(this._distance);\r\n }\r\n stop() {\r\n this._motion.angularVelocity = 0;\r\n this._stopped = true;\r\n }\r\n reset() {\r\n this._started = false;\r\n this._stopped = false;\r\n this._start = undefined;\r\n this._currentNonCannonAngle = undefined;\r\n this._distance = undefined;\r\n }\r\n}\r\n\n;// CONCATENATED MODULE: ./Actions/Action/ScaleTo.ts\n\r\n\r\n\r\nclass ScaleTo {\r\n constructor(entity, scaleX, scaleY, speedX, speedY) {\r\n this._started = false;\r\n this._stopped = false;\r\n this._tx = entity.get(TransformComponent);\r\n this._motion = entity.get(MotionComponent);\r\n this._endX = scaleX;\r\n this._endY = scaleY;\r\n this._speedX = speedX;\r\n this._speedY = speedY;\r\n }\r\n update(_delta) {\r\n if (!this._started) {\r\n this._started = true;\r\n this._startX = this._tx.scale.x;\r\n this._startY = this._tx.scale.y;\r\n this._distanceX = Math.abs(this._endX - this._startX);\r\n this._distanceY = Math.abs(this._endY - this._startY);\r\n }\r\n if (!(Math.abs(this._tx.scale.x - this._startX) >= this._distanceX)) {\r\n const directionX = this._endY < this._startY ? -1 : 1;\r\n this._motion.scaleFactor.x = this._speedX * directionX;\r\n }\r\n else {\r\n this._motion.scaleFactor.x = 0;\r\n }\r\n if (!(Math.abs(this._tx.scale.y - this._startY) >= this._distanceY)) {\r\n const directionY = this._endY < this._startY ? -1 : 1;\r\n this._motion.scaleFactor.y = this._speedY * directionY;\r\n }\r\n else {\r\n this._motion.scaleFactor.y = 0;\r\n }\r\n if (this.isComplete()) {\r\n this._tx.scale = vec(this._endX, this._endY);\r\n this._motion.scaleFactor.x = 0;\r\n this._motion.scaleFactor.y = 0;\r\n }\r\n }\r\n isComplete() {\r\n return (this._stopped ||\r\n (Math.abs(this._tx.scale.x - this._startX) >= (this._distanceX - 0.01) &&\r\n Math.abs(this._tx.scale.y - this._startY) >= (this._distanceY - 0.01)));\r\n }\r\n stop() {\r\n this._motion.scaleFactor.x = 0;\r\n this._motion.scaleFactor.y = 0;\r\n this._stopped = true;\r\n }\r\n reset() {\r\n this._started = false;\r\n this._stopped = false;\r\n }\r\n}\r\n\n;// CONCATENATED MODULE: ./Actions/Action/ScaleBy.ts\n\r\n\r\n\r\nclass ScaleBy {\r\n constructor(entity, scaleOffsetX, scaleOffsetY, speed) {\r\n this._started = false;\r\n this._stopped = false;\r\n this._tx = entity.get(TransformComponent);\r\n this._motion = entity.get(MotionComponent);\r\n this._offset = new Vector(scaleOffsetX, scaleOffsetY);\r\n this._speedX = this._speedY = speed;\r\n }\r\n update(_delta) {\r\n if (!this._started) {\r\n this._started = true;\r\n this._startScale = this._tx.scale.clone();\r\n this._endScale = this._startScale.add(this._offset);\r\n this._distanceX = Math.abs(this._endScale.x - this._startScale.x);\r\n this._distanceY = Math.abs(this._endScale.y - this._startScale.y);\r\n this._directionX = this._endScale.x < this._startScale.x ? -1 : 1;\r\n this._directionY = this._endScale.y < this._startScale.y ? -1 : 1;\r\n }\r\n this._motion.scaleFactor.x = this._speedX * this._directionX;\r\n this._motion.scaleFactor.y = this._speedY * this._directionY;\r\n if (this.isComplete()) {\r\n this._tx.scale = this._endScale;\r\n this._motion.scaleFactor.x = 0;\r\n this._motion.scaleFactor.y = 0;\r\n }\r\n }\r\n isComplete() {\r\n return (this._stopped ||\r\n (Math.abs(this._tx.scale.x - this._startScale.x) >= (this._distanceX - 0.01) &&\r\n Math.abs(this._tx.scale.y - this._startScale.y) >= (this._distanceY - 0.01)));\r\n }\r\n stop() {\r\n this._motion.scaleFactor.x = 0;\r\n this._motion.scaleFactor.y = 0;\r\n this._stopped = true;\r\n }\r\n reset() {\r\n this._started = false;\r\n this._stopped = false;\r\n }\r\n}\r\n\n;// CONCATENATED MODULE: ./Actions/Action/CallMethod.ts\nclass CallMethod {\r\n constructor(method) {\r\n this._method = null;\r\n this._hasBeenCalled = false;\r\n this._method = method;\r\n }\r\n update(_delta) {\r\n this._method();\r\n this._hasBeenCalled = true;\r\n }\r\n isComplete() {\r\n return this._hasBeenCalled;\r\n }\r\n reset() {\r\n this._hasBeenCalled = false;\r\n }\r\n stop() {\r\n this._hasBeenCalled = true;\r\n }\r\n}\r\n\n;// CONCATENATED MODULE: ./Actions/Action/EaseTo.ts\n\r\n\r\n\r\nclass EaseTo {\r\n constructor(entity, x, y, duration, easingFcn) {\r\n this.easingFcn = easingFcn;\r\n this._currentLerpTime = 0;\r\n this._lerpDuration = 1 * 1000; // 1 second\r\n this._lerpStart = new Vector(0, 0);\r\n this._lerpEnd = new Vector(0, 0);\r\n this._initialized = false;\r\n this._stopped = false;\r\n this._tx = entity.get(TransformComponent);\r\n this._motion = entity.get(MotionComponent);\r\n this._lerpDuration = duration;\r\n this._lerpEnd = new Vector(x, y);\r\n }\r\n _initialize() {\r\n this._lerpStart = new Vector(this._tx.pos.x, this._tx.pos.y);\r\n this._currentLerpTime = 0;\r\n }\r\n update(delta) {\r\n if (!this._initialized) {\r\n this._initialize();\r\n this._initialized = true;\r\n }\r\n // Need to update lerp time first, otherwise the first update will always be zero\r\n this._currentLerpTime += delta;\r\n let newX = this._tx.pos.x;\r\n let newY = this._tx.pos.y;\r\n if (this._currentLerpTime < this._lerpDuration) {\r\n if (this._lerpEnd.x < this._lerpStart.x) {\r\n newX =\r\n this._lerpStart.x -\r\n (this.easingFcn(this._currentLerpTime, this._lerpEnd.x, this._lerpStart.x, this._lerpDuration) - this._lerpEnd.x);\r\n }\r\n else {\r\n newX = this.easingFcn(this._currentLerpTime, this._lerpStart.x, this._lerpEnd.x, this._lerpDuration);\r\n }\r\n if (this._lerpEnd.y < this._lerpStart.y) {\r\n newY =\r\n this._lerpStart.y -\r\n (this.easingFcn(this._currentLerpTime, this._lerpEnd.y, this._lerpStart.y, this._lerpDuration) - this._lerpEnd.y);\r\n }\r\n else {\r\n newY = this.easingFcn(this._currentLerpTime, this._lerpStart.y, this._lerpEnd.y, this._lerpDuration);\r\n }\r\n // Given the lerp position figure out the velocity in pixels per second\r\n this._motion.vel = vec((newX - this._tx.pos.x) / (delta / 1000), (newY - this._tx.pos.y) / (delta / 1000));\r\n }\r\n else {\r\n this._tx.pos = vec(this._lerpEnd.x, this._lerpEnd.y);\r\n this._motion.vel = Vector.Zero;\r\n }\r\n }\r\n isComplete() {\r\n return this._stopped || this._currentLerpTime >= this._lerpDuration;\r\n }\r\n reset() {\r\n this._initialized = false;\r\n this._stopped = false;\r\n this._currentLerpTime = 0;\r\n }\r\n stop() {\r\n this._motion.vel = vec(0, 0);\r\n this._stopped = true;\r\n }\r\n}\r\n\n;// CONCATENATED MODULE: ./Actions/Action/EaseBy.ts\n\r\n\r\n\r\nclass EaseBy {\r\n constructor(entity, offsetX, offsetY, duration, easingFcn) {\r\n this.easingFcn = easingFcn;\r\n this._currentLerpTime = 0;\r\n this._lerpDuration = 1 * 1000; // 1 second\r\n this._lerpStart = new Vector(0, 0);\r\n this._lerpEnd = new Vector(0, 0);\r\n this._initialized = false;\r\n this._stopped = false;\r\n this._tx = entity.get(TransformComponent);\r\n this._motion = entity.get(MotionComponent);\r\n this._lerpDuration = duration;\r\n this._offset = new Vector(offsetX, offsetY);\r\n }\r\n _initialize() {\r\n this._lerpStart = new Vector(this._tx.pos.x, this._tx.pos.y);\r\n this._currentLerpTime = 0;\r\n this._lerpEnd = this._lerpStart.add(this._offset);\r\n }\r\n update(delta) {\r\n if (!this._initialized) {\r\n this._initialize();\r\n this._initialized = true;\r\n }\r\n // Need to update lerp time first, otherwise the first update will always be zero\r\n this._currentLerpTime += delta;\r\n let newX = this._tx.pos.x;\r\n let newY = this._tx.pos.y;\r\n if (this._currentLerpTime < this._lerpDuration) {\r\n if (this._lerpEnd.x < this._lerpStart.x) {\r\n newX =\r\n this._lerpStart.x -\r\n (this.easingFcn(this._currentLerpTime, this._lerpEnd.x, this._lerpStart.x, this._lerpDuration) - this._lerpEnd.x);\r\n }\r\n else {\r\n newX = this.easingFcn(this._currentLerpTime, this._lerpStart.x, this._lerpEnd.x, this._lerpDuration);\r\n }\r\n if (this._lerpEnd.y < this._lerpStart.y) {\r\n newY =\r\n this._lerpStart.y -\r\n (this.easingFcn(this._currentLerpTime, this._lerpEnd.y, this._lerpStart.y, this._lerpDuration) - this._lerpEnd.y);\r\n }\r\n else {\r\n newY = this.easingFcn(this._currentLerpTime, this._lerpStart.y, this._lerpEnd.y, this._lerpDuration);\r\n }\r\n // Given the lerp position figure out the velocity in pixels per second\r\n this._motion.vel = vec((newX - this._tx.pos.x) / (delta / 1000), (newY - this._tx.pos.y) / (delta / 1000));\r\n }\r\n else {\r\n this._tx.pos = vec(this._lerpEnd.x, this._lerpEnd.y);\r\n this._motion.vel = Vector.Zero;\r\n }\r\n }\r\n isComplete() {\r\n return this._stopped || this._currentLerpTime >= this._lerpDuration;\r\n }\r\n reset() {\r\n this._initialized = false;\r\n this._stopped = false;\r\n this._currentLerpTime = 0;\r\n }\r\n stop() {\r\n this._motion.vel = vec(0, 0);\r\n this._stopped = true;\r\n }\r\n}\r\n\n;// CONCATENATED MODULE: ./Actions/Action/Blink.ts\n\r\nclass Blink {\r\n constructor(entity, timeVisible, timeNotVisible, numBlinks = 1) {\r\n this._timeVisible = 0;\r\n this._timeNotVisible = 0;\r\n this._elapsedTime = 0;\r\n this._totalTime = 0;\r\n this._stopped = false;\r\n this._started = false;\r\n this._graphics = entity.get(GraphicsComponent);\r\n this._timeVisible = timeVisible;\r\n this._timeNotVisible = timeNotVisible;\r\n this._duration = (timeVisible + timeNotVisible) * numBlinks;\r\n }\r\n update(delta) {\r\n if (!this._started) {\r\n this._started = true;\r\n this._elapsedTime = 0;\r\n this._totalTime = 0;\r\n }\r\n if (!this._graphics) {\r\n return;\r\n }\r\n this._elapsedTime += delta;\r\n this._totalTime += delta;\r\n if (this._graphics.visible && this._elapsedTime >= this._timeVisible) {\r\n this._graphics.visible = false;\r\n this._elapsedTime = 0;\r\n }\r\n if (!this._graphics.visible && this._elapsedTime >= this._timeNotVisible) {\r\n this._graphics.visible = true;\r\n this._elapsedTime = 0;\r\n }\r\n if (this.isComplete()) {\r\n this._graphics.visible = true;\r\n }\r\n }\r\n isComplete() {\r\n return this._stopped || this._totalTime >= this._duration;\r\n }\r\n stop() {\r\n if (this._graphics) {\r\n this._graphics.visible = true;\r\n }\r\n this._stopped = true;\r\n }\r\n reset() {\r\n this._started = false;\r\n this._stopped = false;\r\n this._elapsedTime = 0;\r\n this._totalTime = 0;\r\n }\r\n}\r\n\n;// CONCATENATED MODULE: ./Actions/Action/Fade.ts\n\r\n\r\nclass Fade {\r\n constructor(entity, endOpacity, speed) {\r\n this._multiplier = 1;\r\n this._started = false;\r\n this._stopped = false;\r\n this._graphics = entity.get(GraphicsComponent);\r\n this._endOpacity = endOpacity;\r\n this._speed = this._ogspeed = speed;\r\n }\r\n update(delta) {\r\n if (!this._graphics) {\r\n return;\r\n }\r\n if (!this._started) {\r\n this._started = true;\r\n this._speed = this._ogspeed;\r\n // determine direction when we start\r\n if (this._endOpacity < this._graphics.opacity) {\r\n this._multiplier = -1;\r\n }\r\n else {\r\n this._multiplier = 1;\r\n }\r\n }\r\n if (this._speed > 0) {\r\n this._graphics.opacity += (this._multiplier *\r\n (Math.abs(this._graphics.opacity - this._endOpacity) * delta)) / this._speed;\r\n }\r\n this._speed -= delta;\r\n if (this.isComplete()) {\r\n this._graphics.opacity = this._endOpacity;\r\n }\r\n Logger.getInstance().debug('[Action fade] Actor opacity:', this._graphics.opacity);\r\n }\r\n isComplete() {\r\n return this._stopped || Math.abs(this._graphics.opacity - this._endOpacity) < 0.05;\r\n }\r\n stop() {\r\n this._stopped = true;\r\n }\r\n reset() {\r\n this._started = false;\r\n this._stopped = false;\r\n }\r\n}\r\n\n;// CONCATENATED MODULE: ./Actions/Action/Delay.ts\nclass Delay {\r\n constructor(delay) {\r\n this._elapsedTime = 0;\r\n this._started = false;\r\n this._stopped = false;\r\n this._delay = delay;\r\n }\r\n update(delta) {\r\n if (!this._started) {\r\n this._started = true;\r\n }\r\n this._elapsedTime += delta;\r\n }\r\n isComplete() {\r\n return this._stopped || this._elapsedTime >= this._delay;\r\n }\r\n stop() {\r\n this._stopped = true;\r\n }\r\n reset() {\r\n this._elapsedTime = 0;\r\n this._started = false;\r\n this._stopped = false;\r\n }\r\n}\r\n\n;// CONCATENATED MODULE: ./Actions/Action/Die.ts\n\r\nclass Die {\r\n constructor(entity) {\r\n this._stopped = false;\r\n this._entity = entity;\r\n }\r\n update(_delta) {\r\n this._entity.get(ActionsComponent).clearActions();\r\n this._entity.kill();\r\n this._stopped = true;\r\n }\r\n isComplete() {\r\n return this._stopped;\r\n }\r\n stop() {\r\n return;\r\n }\r\n reset() {\r\n return;\r\n }\r\n}\r\n\n;// CONCATENATED MODULE: ./Actions/Action/Follow.ts\n\r\n\r\n\r\nclass Follow {\r\n constructor(entity, entityToFollow, followDistance) {\r\n this._started = false;\r\n this._stopped = false;\r\n this._tx = entity.get(TransformComponent);\r\n this._motion = entity.get(MotionComponent);\r\n this._followTx = entityToFollow.get(TransformComponent);\r\n this._followMotion = entityToFollow.get(MotionComponent);\r\n this._current = new Vector(this._tx.pos.x, this._tx.pos.y);\r\n this._end = new Vector(this._followTx.pos.x, this._followTx.pos.y);\r\n this._maximumDistance = followDistance !== undefined ? followDistance : this._current.distance(this._end);\r\n this._speed = 0;\r\n }\r\n update(_delta) {\r\n if (!this._started) {\r\n this._started = true;\r\n this._distanceBetween = this._current.distance(this._end);\r\n this._dir = this._end.sub(this._current).normalize();\r\n }\r\n const actorToFollowSpeed = Math.sqrt(Math.pow(this._followMotion.vel.x, 2) + Math.pow(this._followMotion.vel.y, 2));\r\n if (actorToFollowSpeed !== 0) {\r\n this._speed = actorToFollowSpeed;\r\n }\r\n this._current = vec(this._tx.pos.x, this._tx.pos.y);\r\n this._end = vec(this._followTx.pos.x, this._followTx.pos.y);\r\n this._distanceBetween = this._current.distance(this._end);\r\n this._dir = this._end.sub(this._current).normalize();\r\n if (this._distanceBetween >= this._maximumDistance) {\r\n const m = this._dir.scale(this._speed);\r\n this._motion.vel = vec(m.x, m.y);\r\n }\r\n else {\r\n this._motion.vel = vec(0, 0);\r\n }\r\n if (this.isComplete()) {\r\n this._tx.pos = vec(this._end.x, this._end.y);\r\n this._motion.vel = vec(0, 0);\r\n }\r\n }\r\n stop() {\r\n this._motion.vel = vec(0, 0);\r\n this._stopped = true;\r\n }\r\n isComplete() {\r\n // the actor following should never stop unless specified to do so\r\n return this._stopped;\r\n }\r\n reset() {\r\n this._started = false;\r\n this._stopped = false;\r\n }\r\n}\r\n\n;// CONCATENATED MODULE: ./Actions/Action/Meet.ts\n\r\n\r\n\r\nclass Meet {\r\n constructor(actor, actorToMeet, speed) {\r\n this._started = false;\r\n this._stopped = false;\r\n this._speedWasSpecified = false;\r\n this._tx = actor.get(TransformComponent);\r\n this._motion = actor.get(MotionComponent);\r\n this._meetTx = actorToMeet.get(TransformComponent);\r\n this._meetMotion = actorToMeet.get(MotionComponent);\r\n this._current = new Vector(this._tx.pos.x, this._tx.pos.y);\r\n this._end = new Vector(this._meetTx.pos.x, this._meetTx.pos.y);\r\n this._speed = speed || 0;\r\n if (speed !== undefined) {\r\n this._speedWasSpecified = true;\r\n }\r\n }\r\n update(_delta) {\r\n if (!this._started) {\r\n this._started = true;\r\n this._distanceBetween = this._current.distance(this._end);\r\n this._dir = this._end.sub(this._current).normalize();\r\n }\r\n const actorToMeetSpeed = Math.sqrt(Math.pow(this._meetMotion.vel.x, 2) + Math.pow(this._meetMotion.vel.y, 2));\r\n if (actorToMeetSpeed !== 0 && !this._speedWasSpecified) {\r\n this._speed = actorToMeetSpeed;\r\n }\r\n this._current = vec(this._tx.pos.x, this._tx.pos.y);\r\n this._end = vec(this._meetTx.pos.x, this._meetTx.pos.y);\r\n this._distanceBetween = this._current.distance(this._end);\r\n this._dir = this._end.sub(this._current).normalize();\r\n const m = this._dir.scale(this._speed);\r\n this._motion.vel = vec(m.x, m.y);\r\n if (this.isComplete()) {\r\n this._tx.pos = vec(this._end.x, this._end.y);\r\n this._motion.vel = vec(0, 0);\r\n }\r\n }\r\n isComplete() {\r\n return this._stopped || this._distanceBetween <= 1;\r\n }\r\n stop() {\r\n this._motion.vel = vec(0, 0);\r\n this._stopped = true;\r\n }\r\n reset() {\r\n this._started = false;\r\n this._stopped = false;\r\n this._distanceBetween = undefined;\r\n }\r\n}\r\n\n;// CONCATENATED MODULE: ./Actions/ActionContext.ts\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n/**\r\n * The fluent Action API allows you to perform \"actions\" on\r\n * [[Actor|Actors]] such as following, moving, rotating, and\r\n * more. You can implement your own actions by implementing\r\n * the [[Action]] interface.\r\n */\r\nclass ActionContext {\r\n constructor(entity) {\r\n this._entity = entity;\r\n this._queue = new ActionQueue(entity);\r\n }\r\n getQueue() {\r\n return this._queue;\r\n }\r\n update(elapsedMs) {\r\n this._queue.update(elapsedMs);\r\n }\r\n /**\r\n * Clears all queued actions from the Actor\r\n */\r\n clearActions() {\r\n this._queue.clearActions();\r\n }\r\n runAction(action) {\r\n action.reset();\r\n this._queue.add(action);\r\n return this;\r\n }\r\n easeTo(...args) {\r\n var _a, _b;\r\n let x = 0;\r\n let y = 0;\r\n let duration = 0;\r\n let easingFcn = EasingFunctions.Linear;\r\n if (args[0] instanceof Vector) {\r\n x = args[0].x;\r\n y = args[0].y;\r\n duration = args[1];\r\n easingFcn = (_a = args[2]) !== null && _a !== void 0 ? _a : easingFcn;\r\n }\r\n else {\r\n x = args[0];\r\n y = args[1];\r\n duration = args[2];\r\n easingFcn = (_b = args[3]) !== null && _b !== void 0 ? _b : easingFcn;\r\n }\r\n this._queue.add(new EaseTo(this._entity, x, y, duration, easingFcn));\r\n return this;\r\n }\r\n easeBy(...args) {\r\n var _a, _b;\r\n let offsetX = 0;\r\n let offsetY = 0;\r\n let duration = 0;\r\n let easingFcn = EasingFunctions.Linear;\r\n if (args[0] instanceof Vector) {\r\n offsetX = args[0].x;\r\n offsetY = args[0].y;\r\n duration = args[1];\r\n easingFcn = (_a = args[2]) !== null && _a !== void 0 ? _a : easingFcn;\r\n }\r\n else {\r\n offsetX = args[0];\r\n offsetY = args[1];\r\n duration = args[2];\r\n easingFcn = (_b = args[3]) !== null && _b !== void 0 ? _b : easingFcn;\r\n }\r\n this._queue.add(new EaseBy(this._entity, offsetX, offsetY, duration, easingFcn));\r\n return this;\r\n }\r\n moveTo(xOrPos, yOrSpeed, speedOrUndefined) {\r\n let x = 0;\r\n let y = 0;\r\n let speed = 0;\r\n if (xOrPos instanceof Vector) {\r\n x = xOrPos.x;\r\n y = xOrPos.y;\r\n speed = yOrSpeed;\r\n }\r\n else {\r\n x = xOrPos;\r\n y = yOrSpeed;\r\n speed = speedOrUndefined;\r\n }\r\n this._queue.add(new MoveTo(this._entity, x, y, speed));\r\n return this;\r\n }\r\n moveBy(xOffsetOrVector, yOffsetOrSpeed, speedOrUndefined) {\r\n let xOffset = 0;\r\n let yOffset = 0;\r\n let speed = 0;\r\n if (xOffsetOrVector instanceof Vector) {\r\n xOffset = xOffsetOrVector.x;\r\n yOffset = xOffsetOrVector.y;\r\n speed = yOffsetOrSpeed;\r\n }\r\n else {\r\n xOffset = xOffsetOrVector;\r\n yOffset = yOffsetOrSpeed;\r\n speed = speedOrUndefined;\r\n }\r\n this._queue.add(new MoveBy(this._entity, xOffset, yOffset, speed));\r\n return this;\r\n }\r\n /**\r\n * This method will rotate an actor to the specified angle at the speed\r\n * specified (in radians per second) and return back the actor. This\r\n * method is part of the actor 'Action' fluent API allowing action chaining.\r\n * @param angleRadians The angle to rotate to in radians\r\n * @param speed The angular velocity of the rotation specified in radians per second\r\n * @param rotationType The [[RotationType]] to use for this rotation\r\n */\r\n rotateTo(angleRadians, speed, rotationType) {\r\n this._queue.add(new RotateTo(this._entity, angleRadians, speed, rotationType));\r\n return this;\r\n }\r\n /**\r\n * This method will rotate an actor by the specified angle offset, from it's current rotation given a certain speed\r\n * in radians/sec and return back the actor. This method is part\r\n * of the actor 'Action' fluent API allowing action chaining.\r\n * @param angleRadiansOffset The angle to rotate to in radians relative to the current rotation\r\n * @param speed The speed in radians/sec the actor should rotate at\r\n * @param rotationType The [[RotationType]] to use for this rotation, default is shortest path\r\n */\r\n rotateBy(angleRadiansOffset, speed, rotationType) {\r\n this._queue.add(new RotateBy(this._entity, angleRadiansOffset, speed, rotationType));\r\n return this;\r\n }\r\n scaleTo(sizeXOrVector, sizeYOrSpeed, speedXOrUndefined, speedYOrUndefined) {\r\n let sizeX = 1;\r\n let sizeY = 1;\r\n let speedX = 0;\r\n let speedY = 0;\r\n if (sizeXOrVector instanceof Vector && sizeYOrSpeed instanceof Vector) {\r\n sizeX = sizeXOrVector.x;\r\n sizeY = sizeXOrVector.y;\r\n speedX = sizeYOrSpeed.x;\r\n speedY = sizeYOrSpeed.y;\r\n }\r\n if (typeof sizeXOrVector === 'number' && typeof sizeYOrSpeed === 'number') {\r\n sizeX = sizeXOrVector;\r\n sizeY = sizeYOrSpeed;\r\n speedX = speedXOrUndefined;\r\n speedY = speedYOrUndefined;\r\n }\r\n this._queue.add(new ScaleTo(this._entity, sizeX, sizeY, speedX, speedY));\r\n return this;\r\n }\r\n scaleBy(sizeOffsetXOrVector, sizeOffsetYOrSpeed, speed) {\r\n let sizeOffsetX = 1;\r\n let sizeOffsetY = 1;\r\n if (sizeOffsetXOrVector instanceof Vector) {\r\n sizeOffsetX = sizeOffsetXOrVector.x;\r\n sizeOffsetY = sizeOffsetXOrVector.y;\r\n speed = sizeOffsetYOrSpeed;\r\n }\r\n if (typeof sizeOffsetXOrVector === 'number' && typeof sizeOffsetYOrSpeed === 'number') {\r\n sizeOffsetX = sizeOffsetXOrVector;\r\n sizeOffsetY = sizeOffsetYOrSpeed;\r\n }\r\n this._queue.add(new ScaleBy(this._entity, sizeOffsetX, sizeOffsetY, speed));\r\n return this;\r\n }\r\n /**\r\n * This method will cause an actor to blink (become visible and not\r\n * visible). Optionally, you may specify the number of blinks. Specify the amount of time\r\n * the actor should be visible per blink, and the amount of time not visible.\r\n * This method is part of the actor 'Action' fluent API allowing action chaining.\r\n * @param timeVisible The amount of time to stay visible per blink in milliseconds\r\n * @param timeNotVisible The amount of time to stay not visible per blink in milliseconds\r\n * @param numBlinks The number of times to blink\r\n */\r\n blink(timeVisible, timeNotVisible, numBlinks = 1) {\r\n this._queue.add(new Blink(this._entity, timeVisible, timeNotVisible, numBlinks));\r\n return this;\r\n }\r\n /**\r\n * This method will cause an actor's opacity to change from its current value\r\n * to the provided value by a specified time (in milliseconds). This method is\r\n * part of the actor 'Action' fluent API allowing action chaining.\r\n * @param opacity The ending opacity\r\n * @param time The time it should take to fade the actor (in milliseconds)\r\n */\r\n fade(opacity, time) {\r\n this._queue.add(new Fade(this._entity, opacity, time));\r\n return this;\r\n }\r\n /**\r\n * This method will delay the next action from executing for a certain\r\n * amount of time (in milliseconds). This method is part of the actor\r\n * 'Action' fluent API allowing action chaining.\r\n * @param time The amount of time to delay the next action in the queue from executing in milliseconds\r\n */\r\n delay(time) {\r\n this._queue.add(new Delay(time));\r\n return this;\r\n }\r\n /**\r\n * This method will add an action to the queue that will remove the actor from the\r\n * scene once it has completed its previous Any actions on the\r\n * action queue after this action will not be executed.\r\n */\r\n die() {\r\n this._queue.add(new Die(this._entity));\r\n return this;\r\n }\r\n /**\r\n * This method allows you to call an arbitrary method as the next action in the\r\n * action queue. This is useful if you want to execute code in after a specific\r\n * action, i.e An actor arrives at a destination after traversing a path\r\n */\r\n callMethod(method) {\r\n this._queue.add(new CallMethod(method));\r\n return this;\r\n }\r\n /**\r\n * This method will cause the actor to repeat all of the actions built in\r\n * the `repeatBuilder` callback. If the number of repeats\r\n * is not specified it will repeat forever. This method is part of\r\n * the actor 'Action' fluent API allowing action chaining\r\n *\r\n * ```typescript\r\n * // Move up in a zig-zag by repeated moveBy's\r\n * actor.actions.repeat(repeatCtx => {\r\n * repeatCtx.moveBy(10, 0, 10);\r\n * repeatCtx.moveBy(0, 10, 10);\r\n * }, 5);\r\n * ```\r\n *\r\n * @param repeatBuilder The builder to specify the repeatable list of actions\r\n * @param times The number of times to repeat all the previous actions in the action queue. If nothing is specified the actions\r\n * will repeat forever\r\n */\r\n repeat(repeatBuilder, times) {\r\n if (!times) {\r\n this.repeatForever(repeatBuilder);\r\n return this;\r\n }\r\n this._queue.add(new Repeat(this._entity, repeatBuilder, times));\r\n return this;\r\n }\r\n /**\r\n * This method will cause the actor to repeat all of the actions built in\r\n * the `repeatBuilder` callback. If the number of repeats\r\n * is not specified it will repeat forever. This method is part of\r\n * the actor 'Action' fluent API allowing action chaining\r\n *\r\n * ```typescript\r\n * // Move up in a zig-zag by repeated moveBy's\r\n * actor.actions.repeat(repeatCtx => {\r\n * repeatCtx.moveBy(10, 0, 10);\r\n * repeatCtx.moveBy(0, 10, 10);\r\n * }, 5);\r\n * ```\r\n *\r\n * @param repeatBuilder The builder to specify the repeatable list of actions\r\n */\r\n repeatForever(repeatBuilder) {\r\n this._queue.add(new RepeatForever(this._entity, repeatBuilder));\r\n return this;\r\n }\r\n /**\r\n * This method will cause the entity to follow another at a specified distance\r\n * @param entity The entity to follow\r\n * @param followDistance The distance to maintain when following, if not specified the actor will follow at the current distance.\r\n */\r\n follow(entity, followDistance) {\r\n if (followDistance === undefined) {\r\n this._queue.add(new Follow(this._entity, entity));\r\n }\r\n else {\r\n this._queue.add(new Follow(this._entity, entity, followDistance));\r\n }\r\n return this;\r\n }\r\n /**\r\n * This method will cause the entity to move towards another until they\r\n * collide \"meet\" at a specified speed.\r\n * @param entity The entity to meet\r\n * @param speed The speed in pixels per second to move, if not specified it will match the speed of the other actor\r\n */\r\n meet(entity, speed) {\r\n if (speed === undefined) {\r\n this._queue.add(new Meet(this._entity, entity));\r\n }\r\n else {\r\n this._queue.add(new Meet(this._entity, entity, speed));\r\n }\r\n return this;\r\n }\r\n /**\r\n * Returns a promise that resolves when the current action queue up to now\r\n * is finished.\r\n */\r\n toPromise() {\r\n const temp = new Promise((resolve) => {\r\n this._queue.add(new CallMethod(() => {\r\n resolve();\r\n }));\r\n });\r\n return temp;\r\n }\r\n}\r\n\n;// CONCATENATED MODULE: ./Actions/ActionsComponent.ts\n\r\n\r\n\r\n\r\n;\r\nclass ActionsComponent extends Component {\r\n constructor() {\r\n super(...arguments);\r\n this.type = 'ex.actions';\r\n this.dependencies = [TransformComponent, MotionComponent];\r\n }\r\n onAdd(entity) {\r\n this._ctx = new ActionContext(entity);\r\n }\r\n onRemove() {\r\n this._ctx = null;\r\n }\r\n /**\r\n * Returns the internal action queue\r\n * @returns action queue\r\n */\r\n getQueue() {\r\n var _a;\r\n return (_a = this._ctx) === null || _a === void 0 ? void 0 : _a.getQueue();\r\n }\r\n runAction(action) {\r\n var _a;\r\n return (_a = this._ctx) === null || _a === void 0 ? void 0 : _a.runAction(action);\r\n }\r\n /**\r\n * Updates the internal action context, performing action and moving through the internal queue\r\n * @param elapsedMs\r\n */\r\n update(elapsedMs) {\r\n var _a;\r\n return (_a = this._ctx) === null || _a === void 0 ? void 0 : _a.update(elapsedMs);\r\n }\r\n /**\r\n * Clears all queued actions from the Actor\r\n */\r\n clearActions() {\r\n var _a;\r\n (_a = this._ctx) === null || _a === void 0 ? void 0 : _a.clearActions();\r\n }\r\n easeTo(...args) {\r\n return this._ctx.easeTo.apply(this._ctx, args);\r\n }\r\n easeBy(...args) {\r\n return this._ctx.easeBy.apply(this._ctx, args);\r\n }\r\n moveTo(xOrPos, yOrSpeed, speedOrUndefined) {\r\n return this._ctx.moveTo.apply(this._ctx, [xOrPos, yOrSpeed, speedOrUndefined]);\r\n }\r\n moveBy(xOffsetOrVector, yOffsetOrSpeed, speedOrUndefined) {\r\n return this._ctx.moveBy.apply(this._ctx, [xOffsetOrVector, yOffsetOrSpeed, speedOrUndefined]);\r\n }\r\n /**\r\n * This method will rotate an actor to the specified angle at the speed\r\n * specified (in radians per second) and return back the actor. This\r\n * method is part of the actor 'Action' fluent API allowing action chaining.\r\n * @param angleRadians The angle to rotate to in radians\r\n * @param speed The angular velocity of the rotation specified in radians per second\r\n * @param rotationType The [[RotationType]] to use for this rotation\r\n */\r\n rotateTo(angleRadians, speed, rotationType) {\r\n return this._ctx.rotateTo(angleRadians, speed, rotationType);\r\n }\r\n /**\r\n * This method will rotate an actor by the specified angle offset, from it's current rotation given a certain speed\r\n * in radians/sec and return back the actor. This method is part\r\n * of the actor 'Action' fluent API allowing action chaining.\r\n * @param angleRadiansOffset The angle to rotate to in radians relative to the current rotation\r\n * @param speed The speed in radians/sec the actor should rotate at\r\n * @param rotationType The [[RotationType]] to use for this rotation, default is shortest path\r\n */\r\n rotateBy(angleRadiansOffset, speed, rotationType) {\r\n return this._ctx.rotateBy(angleRadiansOffset, speed, rotationType);\r\n }\r\n scaleTo(sizeXOrVector, sizeYOrSpeed, speedXOrUndefined, speedYOrUndefined) {\r\n return this._ctx.scaleTo.apply(this._ctx, [sizeXOrVector, sizeYOrSpeed, speedXOrUndefined, speedYOrUndefined]);\r\n }\r\n scaleBy(sizeOffsetXOrVector, sizeOffsetYOrSpeed, speed) {\r\n return this._ctx.scaleBy.apply(this._ctx, [sizeOffsetXOrVector, sizeOffsetYOrSpeed, speed]);\r\n }\r\n /**\r\n * This method will cause an actor to blink (become visible and not\r\n * visible). Optionally, you may specify the number of blinks. Specify the amount of time\r\n * the actor should be visible per blink, and the amount of time not visible.\r\n * This method is part of the actor 'Action' fluent API allowing action chaining.\r\n * @param timeVisible The amount of time to stay visible per blink in milliseconds\r\n * @param timeNotVisible The amount of time to stay not visible per blink in milliseconds\r\n * @param numBlinks The number of times to blink\r\n */\r\n blink(timeVisible, timeNotVisible, numBlinks) {\r\n return this._ctx.blink(timeVisible, timeNotVisible, numBlinks);\r\n }\r\n /**\r\n * This method will cause an actor's opacity to change from its current value\r\n * to the provided value by a specified time (in milliseconds). This method is\r\n * part of the actor 'Action' fluent API allowing action chaining.\r\n * @param opacity The ending opacity\r\n * @param time The time it should take to fade the actor (in milliseconds)\r\n */\r\n fade(opacity, time) {\r\n return this._ctx.fade(opacity, time);\r\n }\r\n /**\r\n * This method will delay the next action from executing for a certain\r\n * amount of time (in milliseconds). This method is part of the actor\r\n * 'Action' fluent API allowing action chaining.\r\n * @param time The amount of time to delay the next action in the queue from executing in milliseconds\r\n */\r\n delay(time) {\r\n return this._ctx.delay(time);\r\n }\r\n /**\r\n * This method will add an action to the queue that will remove the actor from the\r\n * scene once it has completed its previous Any actions on the\r\n * action queue after this action will not be executed.\r\n */\r\n die() {\r\n return this._ctx.die();\r\n }\r\n /**\r\n * This method allows you to call an arbitrary method as the next action in the\r\n * action queue. This is useful if you want to execute code in after a specific\r\n * action, i.e An actor arrives at a destination after traversing a path\r\n */\r\n callMethod(method) {\r\n return this._ctx.callMethod(method);\r\n }\r\n /**\r\n * This method will cause the actor to repeat all of the actions built in\r\n * the `repeatBuilder` callback. If the number of repeats\r\n * is not specified it will repeat forever. This method is part of\r\n * the actor 'Action' fluent API allowing action chaining\r\n *\r\n * ```typescript\r\n * // Move up in a zig-zag by repeated moveBy's\r\n * actor.actions.repeat(repeatCtx => {\r\n * repeatCtx.moveBy(10, 0, 10);\r\n * repeatCtx.moveBy(0, 10, 10);\r\n * }, 5);\r\n * ```\r\n *\r\n * @param repeatBuilder The builder to specify the repeatable list of actions\r\n * @param times The number of times to repeat all the previous actions in the action queue. If nothing is specified the actions\r\n * will repeat forever\r\n */\r\n repeat(repeatBuilder, times) {\r\n return this._ctx.repeat(repeatBuilder, times);\r\n }\r\n /**\r\n * This method will cause the actor to repeat all of the actions built in\r\n * the `repeatBuilder` callback. If the number of repeats\r\n * is not specified it will repeat forever. This method is part of\r\n * the actor 'Action' fluent API allowing action chaining\r\n *\r\n * ```typescript\r\n * // Move up in a zig-zag by repeated moveBy's\r\n * actor.actions.repeat(repeatCtx => {\r\n * repeatCtx.moveBy(10, 0, 10);\r\n * repeatCtx.moveBy(0, 10, 10);\r\n * }, 5);\r\n * ```\r\n *\r\n * @param repeatBuilder The builder to specify the repeatable list of actions\r\n */\r\n repeatForever(repeatBuilder) {\r\n return this._ctx.repeatForever(repeatBuilder);\r\n }\r\n /**\r\n * This method will cause the entity to follow another at a specified distance\r\n * @param entity The entity to follow\r\n * @param followDistance The distance to maintain when following, if not specified the actor will follow at the current distance.\r\n */\r\n follow(entity, followDistance) {\r\n return this._ctx.follow(entity, followDistance);\r\n }\r\n /**\r\n * This method will cause the entity to move towards another until they\r\n * collide \"meet\" at a specified speed.\r\n * @param entity The entity to meet\r\n * @param speed The speed in pixels per second to move, if not specified it will match the speed of the other actor\r\n */\r\n meet(entity, speed) {\r\n return this._ctx.meet(entity, speed);\r\n }\r\n /**\r\n * Returns a promise that resolves when the current action queue up to now\r\n * is finished.\r\n */\r\n toPromise() {\r\n return this._ctx.toPromise();\r\n }\r\n}\r\n\n;// CONCATENATED MODULE: ./Graphics/FontCommon.ts\n/**\r\n * Enum representing the different font size units\r\n * https://developer.mozilla.org/en-US/docs/Web/CSS/font-size\r\n */\r\nvar FontUnit;\r\n(function (FontUnit) {\r\n /**\r\n * Em is a scalable unit, 1 em is equal to the current font size of the current element, parent elements can effect em values\r\n */\r\n FontUnit[\"Em\"] = \"em\";\r\n /**\r\n * Rem is similar to the Em, it is a scalable unit. 1 rem is equal to the font size of the root element\r\n */\r\n FontUnit[\"Rem\"] = \"rem\";\r\n /**\r\n * Pixel is a unit of length in screen pixels\r\n */\r\n FontUnit[\"Px\"] = \"px\";\r\n /**\r\n * Point is a physical unit length (1/72 of an inch)\r\n */\r\n FontUnit[\"Pt\"] = \"pt\";\r\n /**\r\n * Percent is a scalable unit similar to Em, the only difference is the Em units scale faster when Text-Size stuff\r\n */\r\n FontUnit[\"Percent\"] = \"%\";\r\n})(FontUnit || (FontUnit = {}));\r\n/**\r\n * Enum representing the different horizontal text alignments\r\n */\r\nvar TextAlign;\r\n(function (TextAlign) {\r\n /**\r\n * The text is left-aligned.\r\n */\r\n TextAlign[\"Left\"] = \"left\";\r\n /**\r\n * The text is right-aligned.\r\n */\r\n TextAlign[\"Right\"] = \"right\";\r\n /**\r\n * The text is centered.\r\n */\r\n TextAlign[\"Center\"] = \"center\";\r\n /**\r\n * The text is aligned at the normal start of the line (left-aligned for left-to-right locales,\r\n * right-aligned for right-to-left locales).\r\n */\r\n TextAlign[\"Start\"] = \"start\";\r\n /**\r\n * The text is aligned at the normal end of the line (right-aligned for left-to-right locales,\r\n * left-aligned for right-to-left locales).\r\n */\r\n TextAlign[\"End\"] = \"end\";\r\n})(TextAlign || (TextAlign = {}));\r\n/**\r\n * Enum representing the different baseline text alignments\r\n */\r\nvar BaseAlign;\r\n(function (BaseAlign) {\r\n /**\r\n * The text baseline is the top of the em square.\r\n */\r\n BaseAlign[\"Top\"] = \"top\";\r\n /**\r\n * The text baseline is the hanging baseline. Currently unsupported; this will act like\r\n * alphabetic.\r\n */\r\n BaseAlign[\"Hanging\"] = \"hanging\";\r\n /**\r\n * The text baseline is the middle of the em square.\r\n */\r\n BaseAlign[\"Middle\"] = \"middle\";\r\n /**\r\n * The text baseline is the normal alphabetic baseline.\r\n */\r\n BaseAlign[\"Alphabetic\"] = \"alphabetic\";\r\n /**\r\n * The text baseline is the ideographic baseline; this is the bottom of\r\n * the body of the characters, if the main body of characters protrudes\r\n * beneath the alphabetic baseline. Currently unsupported; this will\r\n * act like alphabetic.\r\n */\r\n BaseAlign[\"Ideographic\"] = \"ideographic\";\r\n /**\r\n * The text baseline is the bottom of the bounding box. This differs\r\n * from the ideographic baseline in that the ideographic baseline\r\n * doesn't consider descenders.\r\n */\r\n BaseAlign[\"Bottom\"] = \"bottom\";\r\n})(BaseAlign || (BaseAlign = {}));\r\n/**\r\n * Enum representing the different possible font styles\r\n */\r\nvar FontStyle;\r\n(function (FontStyle) {\r\n FontStyle[\"Normal\"] = \"normal\";\r\n FontStyle[\"Italic\"] = \"italic\";\r\n FontStyle[\"Oblique\"] = \"oblique\";\r\n})(FontStyle || (FontStyle = {}));\r\n/**\r\n * Enum representing the text direction, useful for other languages, or writing text in reverse\r\n */\r\nvar Direction;\r\n(function (Direction) {\r\n Direction[\"LeftToRight\"] = \"ltr\";\r\n Direction[\"RightToLeft\"] = \"rtl\";\r\n})(Direction || (Direction = {}));\r\n\n;// CONCATENATED MODULE: ./Graphics/FontTextInstance.ts\n\r\n\r\n\r\n\r\nclass FontTextInstance {\r\n constructor(font, text, color, maxWidth) {\r\n this.font = font;\r\n this.text = text;\r\n this.color = color;\r\n this.maxWidth = maxWidth;\r\n this._textFragments = [];\r\n this.disposed = false;\r\n this._dirty = true;\r\n this.canvas = document.createElement('canvas');\r\n this.ctx = this.canvas.getContext('2d');\r\n this.dimensions = this.measureText(text);\r\n this._setDimension(this.dimensions, this.ctx);\r\n this._lastHashCode = this.getHashCode();\r\n }\r\n measureText(text, maxWidth) {\r\n if (this.disposed) {\r\n throw Error('Accessing disposed text instance! ' + this.text);\r\n }\r\n let lines = null;\r\n if (maxWidth != null) {\r\n lines = this._getLinesFromText(text, maxWidth);\r\n }\r\n else {\r\n lines = text.split('\\n');\r\n }\r\n const maxWidthLine = lines.reduce((a, b) => {\r\n return a.length > b.length ? a : b;\r\n });\r\n this._applyFont(this.ctx); // font must be applied to the context to measure it\r\n const metrics = this.ctx.measureText(maxWidthLine);\r\n let textHeight = Math.abs(metrics.actualBoundingBoxAscent) + Math.abs(metrics.actualBoundingBoxDescent);\r\n // TODO lineheight makes the text bounds wonky\r\n const lineAdjustedHeight = textHeight * lines.length;\r\n textHeight = lineAdjustedHeight;\r\n const bottomBounds = lineAdjustedHeight - Math.abs(metrics.actualBoundingBoxAscent);\r\n const x = 0;\r\n const y = 0;\r\n const measurement = new BoundingBox({\r\n left: x - Math.abs(metrics.actualBoundingBoxLeft) - this.font.padding,\r\n top: y - Math.abs(metrics.actualBoundingBoxAscent) - this.font.padding,\r\n bottom: y + bottomBounds + this.font.padding,\r\n right: x + Math.abs(metrics.actualBoundingBoxRight) + this.font.padding\r\n });\r\n return measurement;\r\n }\r\n _setDimension(textBounds, bitmap) {\r\n // Changing the width and height clears the context properties\r\n // We double the bitmap width to account for all possible alignment\r\n // We scale by \"quality\" so we render text without jaggies\r\n bitmap.canvas.width = (textBounds.width + this.font.padding * 2) * 2 * this.font.quality;\r\n bitmap.canvas.height = (textBounds.height + this.font.padding * 2) * 2 * this.font.quality;\r\n }\r\n static getHashCode(font, text, color) {\r\n var _a;\r\n const hash = text +\r\n '__hashcode__' +\r\n font.fontString +\r\n font.showDebug +\r\n font.textAlign +\r\n font.baseAlign +\r\n font.direction +\r\n JSON.stringify(font.shadow) +\r\n (font.padding.toString() +\r\n font.smoothing.toString() +\r\n font.lineWidth.toString() +\r\n font.lineDash.toString() +\r\n ((_a = font.strokeColor) === null || _a === void 0 ? void 0 : _a.toString()) +\r\n (color ? color.toString() : font.color.toString()));\r\n return hash;\r\n }\r\n getHashCode(includeColor = true) {\r\n return FontTextInstance.getHashCode(this.font, this.text, includeColor ? this.color : undefined);\r\n }\r\n _applyRasterProperties(ctx) {\r\n var _a, _b;\r\n ctx.translate(this.font.padding, this.font.padding);\r\n ctx.imageSmoothingEnabled = this.font.smoothing;\r\n ctx.lineWidth = this.font.lineWidth;\r\n ctx.setLineDash((_a = this.font.lineDash) !== null && _a !== void 0 ? _a : ctx.getLineDash());\r\n ctx.strokeStyle = (_b = this.font.strokeColor) === null || _b === void 0 ? void 0 : _b.toString();\r\n ctx.fillStyle = this.color.toString();\r\n }\r\n _applyFont(ctx) {\r\n ctx.resetTransform();\r\n ctx.translate(this.font.padding + ctx.canvas.width / 2, this.font.padding + ctx.canvas.height / 2);\r\n ctx.scale(this.font.quality, this.font.quality);\r\n ctx.textAlign = this.font.textAlign;\r\n ctx.textBaseline = this.font.baseAlign;\r\n ctx.font = this.font.fontString;\r\n ctx.direction = this.font.direction;\r\n if (this.font.shadow) {\r\n ctx.shadowColor = this.font.shadow.color.toString();\r\n ctx.shadowBlur = this.font.shadow.blur;\r\n ctx.shadowOffsetX = this.font.shadow.offset.x;\r\n ctx.shadowOffsetY = this.font.shadow.offset.y;\r\n }\r\n }\r\n _drawText(ctx, lines, lineHeight) {\r\n this._applyRasterProperties(ctx);\r\n this._applyFont(ctx);\r\n for (let i = 0; i < lines.length; i++) {\r\n const line = lines[i];\r\n if (this.color) {\r\n ctx.fillText(line, 0, i * lineHeight);\r\n }\r\n if (this.font.strokeColor) {\r\n ctx.strokeText(line, 0, i * lineHeight);\r\n }\r\n }\r\n if (this.font.showDebug) {\r\n // Horizontal line\r\n /* istanbul ignore next */\r\n line(ctx, Color.Green, -ctx.canvas.width / 2, 0, ctx.canvas.width / 2, 0, 2);\r\n // Vertical line\r\n /* istanbul ignore next */\r\n line(ctx, Color.Red, 0, -ctx.canvas.height / 2, 0, ctx.canvas.height / 2, 2);\r\n }\r\n }\r\n _splitTextBitmap(bitmap) {\r\n const textImages = [];\r\n let currentX = 0;\r\n let currentY = 0;\r\n // 4k is the max for mobile devices\r\n const width = Math.min(4096, bitmap.canvas.width);\r\n const height = Math.min(4096, bitmap.canvas.height);\r\n // Splits the original bitmap into 4k max chunks\r\n while (currentX < bitmap.canvas.width) {\r\n while (currentY < bitmap.canvas.height) {\r\n // create new bitmap\r\n const canvas = document.createElement('canvas');\r\n canvas.width = width;\r\n canvas.height = height;\r\n const ctx = canvas.getContext('2d');\r\n // draw current slice to new bitmap in < 4k chunks\r\n ctx.drawImage(bitmap.canvas, currentX, currentY, width, height, 0, 0, width, height);\r\n textImages.push({ x: currentX, y: currentY, canvas });\r\n currentY += height;\r\n }\r\n currentX += width;\r\n currentY = 0;\r\n }\r\n return textImages;\r\n }\r\n flagDirty() {\r\n this._dirty = true;\r\n }\r\n render(ex, x, y, maxWidth) {\r\n if (this.disposed) {\r\n throw Error('Accessing disposed text instance! ' + this.text);\r\n }\r\n this._ex = ex;\r\n const hashCode = this.getHashCode();\r\n if (this._lastHashCode !== hashCode) {\r\n this._dirty = true;\r\n }\r\n // Calculate image chunks\r\n if (this._dirty) {\r\n this.dimensions = this.measureText(this.text, maxWidth);\r\n this._setDimension(this.dimensions, this.ctx);\r\n const lines = this._getLinesFromText(this.text, maxWidth);\r\n const lineHeight = this.dimensions.height / lines.length;\r\n // draws the text to the main bitmap\r\n this._drawText(this.ctx, lines, lineHeight);\r\n // clear any out old fragments\r\n if (ex instanceof ExcaliburGraphicsContextWebGL) {\r\n for (const frag of this._textFragments) {\r\n ex.textureLoader.delete(frag.canvas);\r\n }\r\n }\r\n // splits to < 4k fragments for large text\r\n this._textFragments = this._splitTextBitmap(this.ctx);\r\n if (ex instanceof ExcaliburGraphicsContextWebGL) {\r\n for (const frag of this._textFragments) {\r\n ex.textureLoader.load(frag.canvas, this.font.filtering, true);\r\n }\r\n }\r\n this._lastHashCode = hashCode;\r\n this._dirty = false;\r\n }\r\n // draws the bitmap fragments to excalibur graphics context\r\n for (const frag of this._textFragments) {\r\n ex.drawImage(frag.canvas, 0, 0, frag.canvas.width, frag.canvas.height, frag.x / this.font.quality + x - this.ctx.canvas.width / this.font.quality / 2, frag.y / this.font.quality + y - this.ctx.canvas.height / this.font.quality / 2, frag.canvas.width / this.font.quality, frag.canvas.height / this.font.quality);\r\n }\r\n }\r\n dispose() {\r\n this.disposed = true;\r\n this.dimensions = undefined;\r\n this.canvas = undefined;\r\n this.ctx = undefined;\r\n if (this._ex instanceof ExcaliburGraphicsContextWebGL) {\r\n for (const frag of this._textFragments) {\r\n this._ex.textureLoader.delete(frag.canvas);\r\n }\r\n }\r\n this._textFragments.length = 0;\r\n }\r\n _getLinesFromText(text, maxWidth) {\r\n if (this._chachedText === text && this._cachedRenderWidth === maxWidth) {\r\n return this._chachedLines;\r\n }\r\n const lines = text.split('\\n');\r\n if (maxWidth == null) {\r\n return lines;\r\n }\r\n // If the current line goes past the maxWidth, append a new line without modifying the underlying text.\r\n for (let i = 0; i < lines.length; i++) {\r\n let line = lines[i];\r\n let newLine = '';\r\n if (this.measureText(line).width > maxWidth) {\r\n while (this.measureText(line).width > maxWidth) {\r\n newLine = line[line.length - 1] + newLine;\r\n line = line.slice(0, -1); // Remove last character from line\r\n }\r\n // Update the array with our new values\r\n lines[i] = line;\r\n lines[i + 1] = newLine;\r\n }\r\n }\r\n this._chachedText = text;\r\n this._chachedLines = lines;\r\n this._cachedRenderWidth = maxWidth;\r\n return lines;\r\n }\r\n}\r\n\n;// CONCATENATED MODULE: ./Graphics/FontCache.ts\n\r\n\r\nclass FontCache {\r\n static measureText(text, font, maxWidth) {\r\n const hash = FontTextInstance.getHashCode(font, text);\r\n if (FontCache._MEASURE_CACHE.has(hash)) {\r\n return FontCache._MEASURE_CACHE.get(hash);\r\n }\r\n FontCache._LOGGER.debug('Font text measurement cache miss');\r\n const measurement = font.measureTextWithoutCache(text, maxWidth);\r\n FontCache._MEASURE_CACHE.set(hash, measurement);\r\n return measurement;\r\n }\r\n static getTextInstance(text, font, color) {\r\n const hash = FontTextInstance.getHashCode(font, text, color);\r\n let textInstance = FontCache._TEXT_CACHE.get(hash);\r\n if (!textInstance) {\r\n textInstance = new FontTextInstance(font, text, color);\r\n FontCache._TEXT_CACHE.set(hash, textInstance);\r\n FontCache._LOGGER.debug('Font text instance cache miss');\r\n }\r\n // Cache the bitmap for certain amount of time\r\n FontCache._TEXT_USAGE.set(textInstance, performance.now());\r\n return textInstance;\r\n }\r\n static checkAndClearCache() {\r\n const deferred = [];\r\n const currentHashCodes = new Set();\r\n for (const [textInstance, time] of FontCache._TEXT_USAGE.entries()) {\r\n // if bitmap hasn't been used in 100 ms clear it\r\n if (time + 100 < performance.now()) {\r\n FontCache._LOGGER.debug(`Text cache entry timed out ${textInstance.text}`);\r\n deferred.push(textInstance);\r\n textInstance.dispose();\r\n }\r\n else {\r\n const hash = textInstance.getHashCode(false);\r\n currentHashCodes.add(hash);\r\n }\r\n }\r\n // Deferred removal of text instances\r\n deferred.forEach((t) => {\r\n FontCache._TEXT_USAGE.delete(t);\r\n });\r\n // Regenerate text instance cache\r\n this._TEXT_CACHE.clear();\r\n for (const [textInstance] of this._TEXT_USAGE.entries()) {\r\n this._TEXT_CACHE.set(textInstance.getHashCode(), textInstance);\r\n }\r\n // Regenerated measurement cache\r\n const newTextMeasurementCache = new Map();\r\n for (const current of currentHashCodes) {\r\n if (FontCache._MEASURE_CACHE.has(current)) {\r\n newTextMeasurementCache.set(current, FontCache._MEASURE_CACHE.get(current));\r\n }\r\n }\r\n this._MEASURE_CACHE.clear();\r\n this._MEASURE_CACHE = newTextMeasurementCache;\r\n }\r\n static get cacheSize() {\r\n return FontCache._TEXT_USAGE.size;\r\n }\r\n /**\r\n * Force clear all cached text bitmaps\r\n */\r\n static clearCache() {\r\n for (const [textInstance] of FontCache._TEXT_USAGE.entries()) {\r\n textInstance.dispose();\r\n }\r\n FontCache._TEXT_USAGE.clear();\r\n FontCache._TEXT_CACHE.clear();\r\n FontCache._MEASURE_CACHE.clear();\r\n }\r\n}\r\nFontCache._LOGGER = Logger.getInstance();\r\nFontCache._TEXT_USAGE = new Map();\r\nFontCache._TEXT_CACHE = new Map();\r\nFontCache._MEASURE_CACHE = new Map();\r\n\n;// CONCATENATED MODULE: ./Graphics/Font.ts\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n/**\r\n * Represents a system or web font in Excalibur\r\n *\r\n * If no options specified, the system sans-serif 10 pixel is used\r\n *\r\n * If loading a custom web font be sure to have the font loaded before you use it https://erikonarheim.com/posts/dont-test-fonts/\r\n */\r\nclass Font extends Graphic {\r\n constructor(options = {}) {\r\n var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u;\r\n super(options); // <- Graphics properties\r\n /**\r\n * Set the font filtering mode, by default set to [[ImageFiltering.Blended]] regardless of the engine default smoothing\r\n *\r\n * If you have a pixel style font that may be a reason to switch this to [[ImageFiltering.Pixel]]\r\n */\r\n this.filtering = ImageFiltering.Blended;\r\n /**\r\n * Font quality determines the size of the underlying raster text, higher quality means less jagged edges.\r\n * If quality is set to 1, then just enough raster bitmap is generated to render the text.\r\n *\r\n * You can think of quality as how zoomed in to the text you can get before seeing jagged edges.\r\n *\r\n * (Default 2)\r\n */\r\n this.quality = 2;\r\n // Raster properties for fonts\r\n this.padding = 2;\r\n this.smoothing = false;\r\n this.lineWidth = 1;\r\n this.lineDash = [];\r\n this.color = Color.Black;\r\n this.family = 'sans-serif';\r\n this.style = FontStyle.Normal;\r\n this.bold = false;\r\n this.unit = FontUnit.Px;\r\n this.textAlign = TextAlign.Left;\r\n this.baseAlign = BaseAlign.Alphabetic;\r\n this.direction = Direction.LeftToRight;\r\n this.size = 10;\r\n this.shadow = null;\r\n this._textBounds = new BoundingBox();\r\n this._textMeasurement = new FontTextInstance(this, '', Color.Black);\r\n // Raster properties\r\n this.smoothing = (_a = options === null || options === void 0 ? void 0 : options.smoothing) !== null && _a !== void 0 ? _a : this.smoothing;\r\n this.padding = (_b = options === null || options === void 0 ? void 0 : options.padding) !== null && _b !== void 0 ? _b : this.padding;\r\n this.color = (_c = options === null || options === void 0 ? void 0 : options.color) !== null && _c !== void 0 ? _c : this.color;\r\n this.strokeColor = (_d = options === null || options === void 0 ? void 0 : options.strokeColor) !== null && _d !== void 0 ? _d : this.strokeColor;\r\n this.lineDash = (_e = options === null || options === void 0 ? void 0 : options.lineDash) !== null && _e !== void 0 ? _e : this.lineDash;\r\n this.lineWidth = (_f = options === null || options === void 0 ? void 0 : options.lineWidth) !== null && _f !== void 0 ? _f : this.lineWidth;\r\n this.filtering = (_g = options === null || options === void 0 ? void 0 : options.filtering) !== null && _g !== void 0 ? _g : this.filtering;\r\n // Font specific properties\r\n this.family = (_h = options === null || options === void 0 ? void 0 : options.family) !== null && _h !== void 0 ? _h : this.family;\r\n this.style = (_j = options === null || options === void 0 ? void 0 : options.style) !== null && _j !== void 0 ? _j : this.style;\r\n this.bold = (_k = options === null || options === void 0 ? void 0 : options.bold) !== null && _k !== void 0 ? _k : this.bold;\r\n this.size = (_l = options === null || options === void 0 ? void 0 : options.size) !== null && _l !== void 0 ? _l : this.size;\r\n this.unit = (_m = options === null || options === void 0 ? void 0 : options.unit) !== null && _m !== void 0 ? _m : this.unit;\r\n this.textAlign = (_o = options === null || options === void 0 ? void 0 : options.textAlign) !== null && _o !== void 0 ? _o : this.textAlign;\r\n this.baseAlign = (_p = options === null || options === void 0 ? void 0 : options.baseAlign) !== null && _p !== void 0 ? _p : this.baseAlign;\r\n this.direction = (_q = options === null || options === void 0 ? void 0 : options.direction) !== null && _q !== void 0 ? _q : this.direction;\r\n this.quality = (_r = options === null || options === void 0 ? void 0 : options.quality) !== null && _r !== void 0 ? _r : this.quality;\r\n if (options === null || options === void 0 ? void 0 : options.shadow) {\r\n this.shadow = {};\r\n this.shadow.blur = (_s = options.shadow.blur) !== null && _s !== void 0 ? _s : this.shadow.blur;\r\n this.shadow.offset = (_t = options.shadow.offset) !== null && _t !== void 0 ? _t : this.shadow.offset;\r\n this.shadow.color = (_u = options.shadow.color) !== null && _u !== void 0 ? _u : this.shadow.color;\r\n }\r\n }\r\n clone() {\r\n return new Font({\r\n ...this.cloneGraphicOptions(),\r\n size: this.size,\r\n unit: this.unit,\r\n family: this.family,\r\n style: this.style,\r\n bold: this.bold,\r\n textAlign: this.textAlign,\r\n baseAlign: this.baseAlign,\r\n direction: this.direction,\r\n shadow: this.shadow\r\n ? {\r\n blur: this.shadow.blur,\r\n offset: this.shadow.offset,\r\n color: this.shadow.color\r\n }\r\n : null\r\n });\r\n }\r\n get fontString() {\r\n return `${this.style} ${this.bold ? 'bold' : ''} ${this.size}${this.unit} ${this.family}`;\r\n }\r\n get localBounds() {\r\n return this._textBounds;\r\n }\r\n _drawImage(_ex, _x, _y) {\r\n // TODO weird vestigial drawimage\r\n }\r\n _rotate(ex) {\r\n var _a;\r\n // TODO this needs to change depending on the bounding box...\r\n const origin = (_a = this.origin) !== null && _a !== void 0 ? _a : this._textBounds.center;\r\n ex.translate(origin.x, origin.y);\r\n ex.rotate(this.rotation);\r\n ex.translate(-origin.x, -origin.y);\r\n }\r\n _flip(ex) {\r\n if (this.flipHorizontal) {\r\n ex.translate(this._textBounds.width / this.scale.x, 0);\r\n ex.scale(-1, 1);\r\n }\r\n if (this.flipVertical) {\r\n ex.translate(0, -this._textBounds.height / 2 / this.scale.y);\r\n ex.scale(1, -1);\r\n }\r\n }\r\n measureTextWithoutCache(text, maxWidth) {\r\n return this._textMeasurement.measureText(text, maxWidth);\r\n }\r\n /**\r\n * Returns a BoundingBox that is the total size of the text including multiple lines\r\n *\r\n * Does not include any padding or adjustment\r\n * @param text\r\n * @returns BoundingBox\r\n */\r\n measureText(text, maxWidth) {\r\n return FontCache.measureText(text, this, maxWidth);\r\n }\r\n _postDraw(ex) {\r\n ex.restore();\r\n }\r\n render(ex, text, colorOverride, x, y, maxWidth) {\r\n const textInstance = FontCache.getTextInstance(text, this, colorOverride);\r\n // Apply affine transformations\r\n this._textBounds = textInstance.dimensions;\r\n this._preDraw(ex, x, y);\r\n textInstance.render(ex, x, y, maxWidth);\r\n this._postDraw(ex);\r\n }\r\n}\r\n\n;// CONCATENATED MODULE: ./Graphics/Text.ts\n\r\n\r\n\r\n/**\r\n * Represent Text graphics in excalibur\r\n *\r\n * Useful for in game labels, ui, or overlays\r\n */\r\nclass Text extends Graphic {\r\n constructor(options) {\r\n var _a, _b;\r\n super(options);\r\n this._text = '';\r\n this._textWidth = 0;\r\n this._textHeight = 0;\r\n // This order is important font, color, then text\r\n this.font = (_a = options.font) !== null && _a !== void 0 ? _a : new Font();\r\n this.color = (_b = options.color) !== null && _b !== void 0 ? _b : this.color;\r\n this.text = options.text;\r\n this.maxWidth = options.maxWidth;\r\n }\r\n clone() {\r\n var _a, _b;\r\n return new Text({\r\n text: this.text.slice(),\r\n color: (_b = (_a = this.color) === null || _a === void 0 ? void 0 : _a.clone()) !== null && _b !== void 0 ? _b : Color.Black,\r\n font: this.font.clone(),\r\n maxWidth: this.maxWidth\r\n });\r\n }\r\n get text() {\r\n return this._text;\r\n }\r\n set text(value) {\r\n this._text = value;\r\n this._calculateDimension();\r\n }\r\n get font() {\r\n return this._font;\r\n }\r\n set font(font) {\r\n this._font = font;\r\n }\r\n get width() {\r\n if (this._textWidth === 0) {\r\n this._calculateDimension();\r\n }\r\n return this._textWidth * this.scale.x;\r\n }\r\n get height() {\r\n if (this._textHeight === 0) {\r\n this._calculateDimension();\r\n }\r\n return this._textHeight * this.scale.y;\r\n }\r\n _calculateDimension() {\r\n const { width, height } = this.font.measureText(this._text, this.maxWidth);\r\n this._textWidth = width;\r\n this._textHeight = height;\r\n }\r\n get localBounds() {\r\n return this.font.measureText(this._text, this.maxWidth).scale(this.scale);\r\n }\r\n _rotate(_ex) {\r\n // None this is delegated to font\r\n // This override erases the default behavior\r\n }\r\n _flip(_ex) {\r\n // None this is delegated to font\r\n // This override erases the default behavior\r\n }\r\n _preDraw(ex, x, y) {\r\n if (this.isStale() || this.font.isStale()) {\r\n this.font.flipHorizontal = this.flipHorizontal;\r\n this.font.flipVertical = this.flipVertical;\r\n this.font.rotation = this.rotation;\r\n this.font.origin = this.origin;\r\n this.font.opacity = this.opacity;\r\n }\r\n this.font.tint = this.tint;\r\n super._preDraw(ex, x, y);\r\n }\r\n _drawImage(ex, x, y) {\r\n var _a;\r\n let color = Color.Black;\r\n if (this.font instanceof Font) {\r\n color = (_a = this.color) !== null && _a !== void 0 ? _a : this.font.color;\r\n }\r\n const { width, height } = this.font.measureText(this._text, this.maxWidth);\r\n this._textWidth = width;\r\n this._textHeight = height;\r\n this.font.render(ex, this._text, color, x, y, this.maxWidth);\r\n if (this.font.showDebug) {\r\n ex.debug.drawRect(x - width, y - height, width * 2, height * 2);\r\n if (this.maxWidth != null) {\r\n ex.debug.drawRect(x, y, this.maxWidth, this.height, {\r\n color: Color.Yellow\r\n });\r\n }\r\n }\r\n }\r\n}\r\n\n;// CONCATENATED MODULE: ./Actor.ts\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n/**\r\n * Type guard for checking if something is an Actor\r\n * @param x\r\n */\r\nfunction isActor(x) {\r\n return x instanceof Actor;\r\n}\r\nconst ActorEvents = {\r\n CollisionStart: 'collisionstart',\r\n CollisionEnd: 'collisionend',\r\n PreCollision: 'precollision',\r\n PostCollision: 'postcollision',\r\n Kill: 'kill',\r\n PreKill: 'prekill',\r\n PostKill: 'postkill',\r\n PreDraw: 'predraw',\r\n PostDraw: 'postdraw',\r\n PreDebugDraw: 'predebugdraw',\r\n PostDebugDraw: 'postdebugdraw',\r\n PointerUp: 'pointerup',\r\n PointerDown: 'pointerdown',\r\n PointerEnter: 'pointerenter',\r\n PointerLeave: 'pointerleave',\r\n PointerMove: 'pointermove',\r\n PointerCancel: 'pointercancel',\r\n Wheel: 'pointerwheel',\r\n PointerDrag: 'pointerdragstart',\r\n PointerDragEnd: 'pointerdragend',\r\n PointerDragEnter: 'pointerdragenter',\r\n PointerDragLeave: 'pointerdragleave',\r\n PointerDragMove: 'pointerdragmove',\r\n EnterViewPort: 'enterviewport',\r\n ExitViewPort: 'exitviewport'\r\n};\r\n/**\r\n * The most important primitive in Excalibur is an `Actor`. Anything that\r\n * can move on the screen, collide with another `Actor`, respond to events,\r\n * or interact with the current scene, must be an actor. An `Actor` **must**\r\n * be part of a [[Scene]] for it to be drawn to the screen.\r\n */\r\nclass Actor extends Entity {\r\n /**\r\n * The physics body the is associated with this actor. The body is the container for all physical properties, like position, velocity,\r\n * acceleration, mass, inertia, etc.\r\n */\r\n get body() {\r\n return this.get(BodyComponent);\r\n }\r\n /**\r\n * Access the Actor's built in [[TransformComponent]]\r\n */\r\n get transform() {\r\n return this.get(TransformComponent);\r\n }\r\n /**\r\n * Access the Actor's built in [[MotionComponent]]\r\n */\r\n get motion() {\r\n return this.get(MotionComponent);\r\n }\r\n /**\r\n * Access to the Actor's built in [[GraphicsComponent]]\r\n */\r\n get graphics() {\r\n return this.get(GraphicsComponent);\r\n }\r\n /**\r\n * Access to the Actor's built in [[ColliderComponent]]\r\n */\r\n get collider() {\r\n return this.get(ColliderComponent);\r\n }\r\n /**\r\n * Access to the Actor's built in [[PointerComponent]] config\r\n */\r\n get pointer() {\r\n return this.get(PointerComponent);\r\n }\r\n /**\r\n * Useful for quickly scripting actor behavior, like moving to a place, patrolling back and forth, blinking, etc.\r\n *\r\n * Access to the Actor's built in [[ActionsComponent]] which forwards to the\r\n * [[ActionContext|Action context]] of the actor.\r\n */\r\n get actions() {\r\n return this.get(ActionsComponent);\r\n }\r\n /**\r\n * Gets the position vector of the actor in pixels\r\n */\r\n get pos() {\r\n return this.transform.pos;\r\n }\r\n /**\r\n * Sets the position vector of the actor in pixels\r\n */\r\n set pos(thePos) {\r\n this.transform.pos = thePos.clone();\r\n }\r\n /**\r\n * Gets the position vector of the actor from the last frame\r\n */\r\n get oldPos() {\r\n return this.body.oldPos;\r\n }\r\n /**\r\n * Sets the position vector of the actor in the last frame\r\n */\r\n set oldPos(thePos) {\r\n this.body.oldPos.setTo(thePos.x, thePos.y);\r\n }\r\n /**\r\n * Gets the velocity vector of the actor in pixels/sec\r\n */\r\n get vel() {\r\n return this.motion.vel;\r\n }\r\n /**\r\n * Sets the velocity vector of the actor in pixels/sec\r\n */\r\n set vel(theVel) {\r\n this.motion.vel = theVel.clone();\r\n }\r\n /**\r\n * Gets the velocity vector of the actor from the last frame\r\n */\r\n get oldVel() {\r\n return this.body.oldVel;\r\n }\r\n /**\r\n * Sets the velocity vector of the actor from the last frame\r\n */\r\n set oldVel(theVel) {\r\n this.body.oldVel.setTo(theVel.x, theVel.y);\r\n }\r\n /**\r\n * Gets the acceleration vector of the actor in pixels/second/second. An acceleration pointing down such as (0, 100) may be\r\n * useful to simulate a gravitational effect.\r\n */\r\n get acc() {\r\n return this.motion.acc;\r\n }\r\n /**\r\n * Sets the acceleration vector of teh actor in pixels/second/second\r\n */\r\n set acc(theAcc) {\r\n this.motion.acc = theAcc.clone();\r\n }\r\n /**\r\n * Sets the acceleration of the actor from the last frame. This does not include the global acc [[Physics.acc]].\r\n */\r\n set oldAcc(theAcc) {\r\n this.body.oldAcc.setTo(theAcc.x, theAcc.y);\r\n }\r\n /**\r\n * Gets the acceleration of the actor from the last frame. This does not include the global acc [[Physics.acc]].\r\n */\r\n get oldAcc() {\r\n return this.body.oldAcc;\r\n }\r\n /**\r\n * Gets the rotation of the actor in radians. 1 radian = 180/PI Degrees.\r\n */\r\n get rotation() {\r\n return this.transform.rotation;\r\n }\r\n /**\r\n * Sets the rotation of the actor in radians. 1 radian = 180/PI Degrees.\r\n */\r\n set rotation(theAngle) {\r\n this.transform.rotation = theAngle;\r\n }\r\n /**\r\n * Gets the rotational velocity of the actor in radians/second\r\n */\r\n get angularVelocity() {\r\n return this.motion.angularVelocity;\r\n }\r\n /**\r\n * Sets the rotational velocity of the actor in radians/sec\r\n */\r\n set angularVelocity(angularVelocity) {\r\n this.motion.angularVelocity = angularVelocity;\r\n }\r\n get scale() {\r\n return this.get(TransformComponent).scale;\r\n }\r\n set scale(scale) {\r\n this.get(TransformComponent).scale = scale;\r\n }\r\n get anchor() {\r\n return this._anchor;\r\n }\r\n set anchor(vec) {\r\n this._anchor = watch(vec, (v) => this._handleAnchorChange(v));\r\n this._handleAnchorChange(vec);\r\n }\r\n _handleAnchorChange(v) {\r\n if (this.graphics) {\r\n this.graphics.anchor = v;\r\n }\r\n }\r\n /**\r\n * Indicates whether the actor is physically in the viewport\r\n */\r\n get isOffScreen() {\r\n return this.hasTag('ex.offscreen');\r\n }\r\n get draggable() {\r\n return this._draggable;\r\n }\r\n set draggable(isDraggable) {\r\n if (isDraggable) {\r\n if (isDraggable && !this._draggable) {\r\n this.events.on('pointerdragstart', this._pointerDragStartHandler);\r\n this.events.on('pointerdragend', this._pointerDragEndHandler);\r\n this.events.on('pointerdragmove', this._pointerDragMoveHandler);\r\n this.events.on('pointerdragleave', this._pointerDragLeaveHandler);\r\n }\r\n else if (!isDraggable && this._draggable) {\r\n this.events.off('pointerdragstart', this._pointerDragStartHandler);\r\n this.events.off('pointerdragend', this._pointerDragEndHandler);\r\n this.events.off('pointerdragmove', this._pointerDragMoveHandler);\r\n this.events.off('pointerdragleave', this._pointerDragLeaveHandler);\r\n }\r\n this._draggable = isDraggable;\r\n }\r\n }\r\n /**\r\n * Sets the color of the actor's current graphic\r\n */\r\n get color() {\r\n return this._color;\r\n }\r\n set color(v) {\r\n var _a;\r\n this._color = v.clone();\r\n const defaultLayer = this.graphics.layers.default;\r\n const currentGraphic = (_a = defaultLayer.graphics[0]) === null || _a === void 0 ? void 0 : _a.graphic;\r\n if (currentGraphic instanceof Raster || currentGraphic instanceof Text) {\r\n currentGraphic.color = this._color;\r\n }\r\n }\r\n // #endregion\r\n /**\r\n *\r\n * @param config\r\n */\r\n constructor(config) {\r\n super();\r\n this.events = new EventEmitter();\r\n /**\r\n * The anchor to apply all actor related transformations like rotation,\r\n * translation, and scaling. By default the anchor is in the center of\r\n * the actor. By default it is set to the center of the actor (.5, .5)\r\n *\r\n * An anchor of (.5, .5) will ensure that drawings are centered.\r\n *\r\n * Use `anchor.setTo` to set the anchor to a different point using\r\n * values between 0 and 1. For example, anchoring to the top-left would be\r\n * `Actor.anchor.setTo(0, 0)` and top-right would be `Actor.anchor.setTo(0, 1)`.\r\n */\r\n this._anchor = watch(Vector.Half, (v) => this._handleAnchorChange(v));\r\n /**\r\n * Convenience reference to the global logger\r\n */\r\n this.logger = Logger.getInstance();\r\n /**\r\n * Draggable helper\r\n */\r\n this._draggable = false;\r\n this._dragging = false;\r\n this._pointerDragStartHandler = () => {\r\n this._dragging = true;\r\n };\r\n this._pointerDragEndHandler = () => {\r\n this._dragging = false;\r\n };\r\n this._pointerDragMoveHandler = (pe) => {\r\n if (this._dragging) {\r\n this.pos = pe.worldPos;\r\n }\r\n };\r\n this._pointerDragLeaveHandler = (pe) => {\r\n if (this._dragging) {\r\n this.pos = pe.worldPos;\r\n }\r\n };\r\n const { name, x, y, pos, coordPlane, scale, width, height, radius, collider, vel, acc, rotation, angularVelocity, z, color, visible, anchor, collisionType, collisionGroup } = {\r\n ...config\r\n };\r\n this._setName(name);\r\n this.anchor = anchor !== null && anchor !== void 0 ? anchor : Actor.defaults.anchor.clone();\r\n const tx = new TransformComponent();\r\n this.addComponent(tx);\r\n this.pos = pos !== null && pos !== void 0 ? pos : vec(x !== null && x !== void 0 ? x : 0, y !== null && y !== void 0 ? y : 0);\r\n this.rotation = rotation !== null && rotation !== void 0 ? rotation : 0;\r\n this.scale = scale !== null && scale !== void 0 ? scale : vec(1, 1);\r\n this.z = z !== null && z !== void 0 ? z : 0;\r\n tx.coordPlane = coordPlane !== null && coordPlane !== void 0 ? coordPlane : CoordPlane.World;\r\n this.addComponent(new PointerComponent);\r\n this.addComponent(new GraphicsComponent({\r\n anchor: this.anchor\r\n }));\r\n this.addComponent(new MotionComponent());\r\n this.vel = vel !== null && vel !== void 0 ? vel : Vector.Zero;\r\n this.acc = acc !== null && acc !== void 0 ? acc : Vector.Zero;\r\n this.angularVelocity = angularVelocity !== null && angularVelocity !== void 0 ? angularVelocity : 0;\r\n this.addComponent(new ActionsComponent());\r\n this.addComponent(new BodyComponent());\r\n this.body.collisionType = collisionType !== null && collisionType !== void 0 ? collisionType : CollisionType.Passive;\r\n if (collisionGroup) {\r\n this.body.group = collisionGroup;\r\n }\r\n if (collider) {\r\n this.addComponent(new ColliderComponent(collider));\r\n }\r\n else if (radius) {\r\n this.addComponent(new ColliderComponent(Shape.Circle(radius)));\r\n }\r\n else {\r\n if (width > 0 && height > 0) {\r\n this.addComponent(new ColliderComponent(Shape.Box(width, height, this.anchor)));\r\n }\r\n else {\r\n this.addComponent(new ColliderComponent()); // no collider\r\n }\r\n }\r\n this.graphics.visible = visible !== null && visible !== void 0 ? visible : true;\r\n if (color) {\r\n this.color = color;\r\n if (width && height) {\r\n this.graphics.add(new Rectangle({\r\n color: color,\r\n width,\r\n height\r\n }));\r\n }\r\n else if (radius) {\r\n this.graphics.add(new Circle({\r\n color: color,\r\n radius\r\n }));\r\n }\r\n }\r\n }\r\n clone() {\r\n const clone = new Actor({\r\n color: this.color.clone(),\r\n anchor: this.anchor.clone()\r\n });\r\n clone.clearComponents();\r\n clone.processComponentRemoval();\r\n // Clone the current actors components\r\n const components = this.getComponents();\r\n for (const c of components) {\r\n clone.addComponent(c.clone(), true);\r\n }\r\n return clone;\r\n }\r\n /**\r\n * `onInitialize` is called before the first update of the actor. This method is meant to be\r\n * overridden. This is where initialization of child actors should take place.\r\n *\r\n * Synonymous with the event handler `.on('initialize', (evt) => {...})`\r\n */\r\n onInitialize(_engine) {\r\n // Override me\r\n }\r\n /**\r\n * Initializes this actor and all it's child actors, meant to be called by the Scene before first update not by users of Excalibur.\r\n *\r\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\r\n *\r\n * @internal\r\n */\r\n _initialize(engine) {\r\n super._initialize(engine);\r\n for (const child of this.children) {\r\n child._initialize(engine);\r\n }\r\n }\r\n emit(eventName, event) {\r\n this.events.emit(eventName, event);\r\n }\r\n on(eventName, handler) {\r\n return this.events.on(eventName, handler);\r\n }\r\n once(eventName, handler) {\r\n return this.events.once(eventName, handler);\r\n }\r\n off(eventName, handler) {\r\n this.events.off(eventName, handler);\r\n }\r\n // #endregion\r\n /**\r\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\r\n *\r\n * Internal _prekill handler for [[onPreKill]] lifecycle event\r\n * @internal\r\n */\r\n _prekill(_scene) {\r\n this.events.emit('prekill', new PreKillEvent(this));\r\n this.onPreKill(_scene);\r\n }\r\n /**\r\n * Safe to override onPreKill lifecycle event handler. Synonymous with `.on('prekill', (evt) =>{...})`\r\n *\r\n * `onPreKill` is called directly before an actor is killed and removed from its current [[Scene]].\r\n */\r\n onPreKill(_scene) {\r\n // Override me\r\n }\r\n /**\r\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\r\n *\r\n * Internal _prekill handler for [[onPostKill]] lifecycle event\r\n * @internal\r\n */\r\n _postkill(_scene) {\r\n this.events.emit('postkill', new PostKillEvent(this));\r\n this.onPostKill(_scene);\r\n }\r\n /**\r\n * Safe to override onPostKill lifecycle event handler. Synonymous with `.on('postkill', (evt) => {...})`\r\n *\r\n * `onPostKill` is called directly after an actor is killed and remove from its current [[Scene]].\r\n */\r\n onPostKill(_scene) {\r\n // Override me\r\n }\r\n /**\r\n * If the current actor is a member of the scene, this will remove\r\n * it from the scene graph. It will no longer be drawn or updated.\r\n */\r\n kill() {\r\n if (this.scene) {\r\n this._prekill(this.scene);\r\n this.events.emit('kill', new KillEvent(this));\r\n super.kill();\r\n this._postkill(this.scene);\r\n }\r\n else {\r\n this.logger.warn(`Cannot kill actor named \"${this.name}\", it was never added to the Scene`);\r\n }\r\n }\r\n /**\r\n * If the current actor is killed, it will now not be killed.\r\n */\r\n unkill() {\r\n this.active = true;\r\n }\r\n /**\r\n * Indicates wether the actor has been killed.\r\n */\r\n isKilled() {\r\n return !this.active;\r\n }\r\n /**\r\n * Gets the z-index of an actor. The z-index determines the relative order an actor is drawn in.\r\n * Actors with a higher z-index are drawn on top of actors with a lower z-index\r\n */\r\n get z() {\r\n return this.get(TransformComponent).z;\r\n }\r\n /**\r\n * Sets the z-index of an actor and updates it in the drawing list for the scene.\r\n * The z-index determines the relative order an actor is drawn in.\r\n * Actors with a higher z-index are drawn on top of actors with a lower z-index\r\n * @param newZ new z-index to assign\r\n */\r\n set z(newZ) {\r\n this.get(TransformComponent).z = newZ;\r\n }\r\n /**\r\n * Get the center point of an actor (global position)\r\n */\r\n get center() {\r\n const globalPos = this.getGlobalPos();\r\n return new Vector(globalPos.x + this.width / 2 - this.anchor.x * this.width, globalPos.y + this.height / 2 - this.anchor.y * this.height);\r\n }\r\n /**\r\n * Get the local center point of an actor\r\n */\r\n get localCenter() {\r\n return new Vector(this.pos.x + this.width / 2 - this.anchor.x * this.width, this.pos.y + this.height / 2 - this.anchor.y * this.height);\r\n }\r\n get width() {\r\n return this.collider.localBounds.width * this.getGlobalScale().x;\r\n }\r\n get height() {\r\n return this.collider.localBounds.height * this.getGlobalScale().y;\r\n }\r\n /**\r\n * Gets this actor's rotation taking into account any parent relationships\r\n *\r\n * @returns Rotation angle in radians\r\n */\r\n getGlobalRotation() {\r\n return this.get(TransformComponent).globalRotation;\r\n }\r\n /**\r\n * Gets an actor's world position taking into account parent relationships, scaling, rotation, and translation\r\n *\r\n * @returns Position in world coordinates\r\n */\r\n getGlobalPos() {\r\n return this.get(TransformComponent).globalPos;\r\n }\r\n /**\r\n * Gets the global scale of the Actor\r\n */\r\n getGlobalScale() {\r\n return this.get(TransformComponent).globalScale;\r\n }\r\n // #region Collision\r\n /**\r\n * Tests whether the x/y specified are contained in the actor\r\n * @param x X coordinate to test (in world coordinates)\r\n * @param y Y coordinate to test (in world coordinates)\r\n * @param recurse checks whether the x/y are contained in any child actors (if they exist).\r\n */\r\n contains(x, y, recurse = false) {\r\n const point = vec(x, y);\r\n const collider = this.get(ColliderComponent);\r\n collider.update();\r\n const geom = collider.get();\r\n if (!geom) {\r\n return false;\r\n }\r\n const containment = geom.contains(point);\r\n if (recurse) {\r\n return (containment ||\r\n this.children.some((child) => {\r\n return child.contains(x, y, true);\r\n }));\r\n }\r\n return containment;\r\n }\r\n /**\r\n * Returns true if the two actor.collider's surfaces are less than or equal to the distance specified from each other\r\n * @param actor Actor to test\r\n * @param distance Distance in pixels to test\r\n */\r\n within(actor, distance) {\r\n const collider = this.get(ColliderComponent);\r\n const otherCollider = actor.get(ColliderComponent);\r\n const me = collider.get();\r\n const other = otherCollider.get();\r\n if (me && other) {\r\n return me.getClosestLineBetween(other).getLength() <= distance;\r\n }\r\n return false;\r\n }\r\n // #endregion\r\n // #region Update\r\n /**\r\n * Called by the Engine, updates the state of the actor\r\n * @internal\r\n * @param engine The reference to the current game engine\r\n * @param delta The time elapsed since the last update in milliseconds\r\n */\r\n update(engine, delta) {\r\n this._initialize(engine);\r\n this._preupdate(engine, delta);\r\n this._postupdate(engine, delta);\r\n }\r\n /**\r\n * Safe to override onPreUpdate lifecycle event handler. Synonymous with `.on('preupdate', (evt) =>{...})`\r\n *\r\n * `onPreUpdate` is called directly before an actor is updated.\r\n */\r\n onPreUpdate(_engine, _delta) {\r\n // Override me\r\n }\r\n /**\r\n * Safe to override onPostUpdate lifecycle event handler. Synonymous with `.on('postupdate', (evt) =>{...})`\r\n *\r\n * `onPostUpdate` is called directly after an actor is updated.\r\n */\r\n onPostUpdate(_engine, _delta) {\r\n // Override me\r\n }\r\n /**\r\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\r\n *\r\n * Internal _preupdate handler for [[onPreUpdate]] lifecycle event\r\n * @internal\r\n */\r\n _preupdate(engine, delta) {\r\n this.events.emit('preupdate', new PreUpdateEvent(engine, delta, this));\r\n this.onPreUpdate(engine, delta);\r\n }\r\n /**\r\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\r\n *\r\n * Internal _preupdate handler for [[onPostUpdate]] lifecycle event\r\n * @internal\r\n */\r\n _postupdate(engine, delta) {\r\n this.events.emit('postupdate', new PostUpdateEvent(engine, delta, this));\r\n this.onPostUpdate(engine, delta);\r\n }\r\n}\r\n// #region Properties\r\n/**\r\n * Set defaults for all Actors\r\n */\r\nActor.defaults = {\r\n anchor: Vector.Half\r\n};\r\n\n;// CONCATENATED MODULE: ./ScreenElement.ts\n\r\n\r\n\r\n\r\n\r\n/**\r\n * Type guard to detect a screen element\r\n */\r\nfunction isScreenElement(actor) {\r\n return actor instanceof ScreenElement;\r\n}\r\n/**\r\n * Helper [[Actor]] primitive for drawing UI's, optimized for UI drawing. Does\r\n * not participate in collisions. Drawn on top of all other actors.\r\n */\r\nclass ScreenElement extends Actor {\r\n constructor(config) {\r\n var _a, _b;\r\n super({ ...config });\r\n this.get(TransformComponent).coordPlane = CoordPlane.Screen;\r\n this.anchor = (_a = config === null || config === void 0 ? void 0 : config.anchor) !== null && _a !== void 0 ? _a : vec(0, 0);\r\n this.body.collisionType = (_b = config === null || config === void 0 ? void 0 : config.collisionType) !== null && _b !== void 0 ? _b : CollisionType.PreventCollision;\r\n this.pointer.useGraphicsBounds = true;\r\n this.pointer.useColliderShape = false;\r\n if (!(config === null || config === void 0 ? void 0 : config.collider) &&\r\n (config === null || config === void 0 ? void 0 : config.width) > 0 &&\r\n (config === null || config === void 0 ? void 0 : config.height) > 0) {\r\n this.collider.useBoxCollider(this.width, this.height, this.anchor);\r\n }\r\n }\r\n _initialize(engine) {\r\n this._engine = engine;\r\n super._initialize(engine);\r\n }\r\n contains(x, y, useWorld = true) {\r\n if (useWorld) {\r\n return super.contains(x, y);\r\n }\r\n const coords = this._engine.worldToScreenCoordinates(new Vector(x, y));\r\n return super.contains(coords.x, coords.y);\r\n }\r\n}\r\n\n;// CONCATENATED MODULE: ./Timer.ts\n\r\n\r\n/**\r\n * The Excalibur timer hooks into the internal timer and fires callbacks,\r\n * after a certain interval, optionally repeating.\r\n */\r\nclass Timer {\r\n get complete() {\r\n return this._complete;\r\n }\r\n constructor(fcn, interval, repeats, numberOfRepeats, randomRange, random) {\r\n this._logger = Logger.getInstance();\r\n this.id = 0;\r\n this._elapsedTime = 0;\r\n this._totalTimeAlive = 0;\r\n this._running = false;\r\n this._numberOfTicks = 0;\r\n this.interval = 10;\r\n this.repeats = false;\r\n this.maxNumberOfRepeats = -1;\r\n this.randomRange = [0, 0];\r\n this._baseInterval = 10;\r\n this._generateRandomInterval = () => {\r\n return this._baseInterval + this.random.integer(this.randomRange[0], this.randomRange[1]);\r\n };\r\n this._complete = false;\r\n this.scene = null;\r\n if (typeof fcn !== 'function') {\r\n const options = fcn;\r\n fcn = options.fcn;\r\n interval = options.interval;\r\n repeats = options.repeats;\r\n numberOfRepeats = options.numberOfRepeats;\r\n randomRange = options.randomRange;\r\n random = options.random;\r\n }\r\n if (!!numberOfRepeats && numberOfRepeats >= 0) {\r\n this.maxNumberOfRepeats = numberOfRepeats;\r\n if (!repeats) {\r\n throw new Error('repeats must be set to true if numberOfRepeats is set');\r\n }\r\n }\r\n this.id = Timer._MAX_ID++;\r\n this._callbacks = [];\r\n this._baseInterval = this.interval = interval;\r\n if (!!randomRange) {\r\n if (randomRange[0] > randomRange[1]) {\r\n throw new Error('min value must be lower than max value for range');\r\n }\r\n //We use the instance of ex.Random to generate the range\r\n this.random = random !== null && random !== void 0 ? random : new Random();\r\n this.randomRange = randomRange;\r\n this.interval = this._generateRandomInterval();\r\n this.on(() => {\r\n this.interval = this._generateRandomInterval();\r\n });\r\n }\r\n ;\r\n this.repeats = repeats || this.repeats;\r\n if (fcn) {\r\n this.on(fcn);\r\n }\r\n }\r\n /**\r\n * Adds a new callback to be fired after the interval is complete\r\n * @param fcn The callback to be added to the callback list, to be fired after the interval is complete.\r\n */\r\n on(fcn) {\r\n this._callbacks.push(fcn);\r\n }\r\n /**\r\n * Removes a callback from the callback list to be fired after the interval is complete.\r\n * @param fcn The callback to be removed from the callback list, to be fired after the interval is complete.\r\n */\r\n off(fcn) {\r\n const index = this._callbacks.indexOf(fcn);\r\n this._callbacks.splice(index, 1);\r\n }\r\n /**\r\n * Updates the timer after a certain number of milliseconds have elapsed. This is used internally by the engine.\r\n * @param delta Number of elapsed milliseconds since the last update.\r\n */\r\n update(delta) {\r\n if (this._running) {\r\n this._totalTimeAlive += delta;\r\n this._elapsedTime += delta;\r\n if (this.maxNumberOfRepeats > -1 && this._numberOfTicks >= this.maxNumberOfRepeats) {\r\n this._complete = true;\r\n this._running = false;\r\n this._elapsedTime = 0;\r\n }\r\n if (!this.complete && this._elapsedTime >= this.interval) {\r\n this._callbacks.forEach((c) => {\r\n c.call(this);\r\n });\r\n this._numberOfTicks++;\r\n if (this.repeats) {\r\n this._elapsedTime = 0;\r\n }\r\n else {\r\n this._complete = true;\r\n this._running = false;\r\n this._elapsedTime = 0;\r\n }\r\n }\r\n }\r\n }\r\n /**\r\n * Resets the timer so that it can be reused, and optionally reconfigure the timers interval.\r\n *\r\n * Warning** you may need to call `timer.start()` again if the timer had completed\r\n * @param newInterval If specified, sets a new non-negative interval in milliseconds to refire the callback\r\n * @param newNumberOfRepeats If specified, sets a new non-negative upper limit to the number of time this timer executes\r\n */\r\n reset(newInterval, newNumberOfRepeats) {\r\n if (!!newInterval && newInterval >= 0) {\r\n this._baseInterval = this.interval = newInterval;\r\n }\r\n if (!!this.maxNumberOfRepeats && this.maxNumberOfRepeats >= 0) {\r\n this.maxNumberOfRepeats = newNumberOfRepeats;\r\n if (!this.repeats) {\r\n throw new Error('repeats must be set to true if numberOfRepeats is set');\r\n }\r\n }\r\n this._complete = false;\r\n this._elapsedTime = 0;\r\n this._numberOfTicks = 0;\r\n }\r\n get timesRepeated() {\r\n return this._numberOfTicks;\r\n }\r\n getTimeRunning() {\r\n return this._totalTimeAlive;\r\n }\r\n /**\r\n * @returns milliseconds until the next action callback, if complete will return 0\r\n */\r\n get timeToNextAction() {\r\n if (this.complete) {\r\n return 0;\r\n }\r\n return this.interval - this._elapsedTime;\r\n }\r\n /**\r\n * @returns milliseconds elapsed toward the next action\r\n */\r\n get timeElapsedTowardNextAction() {\r\n return this._elapsedTime;\r\n }\r\n get isRunning() {\r\n return this._running;\r\n }\r\n /**\r\n * Pauses the timer, time will no longer increment towards the next call\r\n */\r\n pause() {\r\n this._running = false;\r\n return this;\r\n }\r\n /**\r\n * Resumes the timer, time will now increment towards the next call.\r\n */\r\n resume() {\r\n this._running = true;\r\n return this;\r\n }\r\n /**\r\n * Starts the timer, if the timer was complete it will restart the timer and reset the elapsed time counter\r\n */\r\n start() {\r\n if (!this.scene) {\r\n this._logger.warn('Cannot start a timer not part of a scene, timer wont start until added');\r\n }\r\n this._running = true;\r\n if (this.complete) {\r\n this._complete = false;\r\n this._elapsedTime = 0;\r\n this._numberOfTicks = 0;\r\n }\r\n return this;\r\n }\r\n /**\r\n * Stops the timer and resets the elapsed time counter towards the next action invocation\r\n */\r\n stop() {\r\n this._running = false;\r\n this._elapsedTime = 0;\r\n this._numberOfTicks = 0;\r\n return this;\r\n }\r\n /**\r\n * Cancels the timer, preventing any further executions.\r\n */\r\n cancel() {\r\n this.pause();\r\n if (this.scene) {\r\n this.scene.cancelTimer(this);\r\n }\r\n }\r\n}\r\nTimer._MAX_ID = 0;\r\n\n;// CONCATENATED MODULE: ./Graphics/ParallaxComponent.ts\n\r\n\r\nclass ParallaxComponent extends Component {\r\n constructor(parallaxFactor) {\r\n super();\r\n this.type = 'ex.parallax';\r\n this.parallaxFactor = vec(1.0, 1.0);\r\n this.parallaxFactor = parallaxFactor !== null && parallaxFactor !== void 0 ? parallaxFactor : this.parallaxFactor;\r\n }\r\n}\r\n\n;// CONCATENATED MODULE: ./Graphics/DebugGraphicsComponent.ts\n\r\n/**\r\n * Provide arbitrary drawing for the purposes of debugging your game\r\n *\r\n * Will only show when the Engine is set to debug mode [[Engine.showDebug]] or [[Engine.toggleDebug]]\r\n *\r\n */\r\nclass DebugGraphicsComponent extends Component {\r\n constructor(draw, useTransform = true) {\r\n super();\r\n this.draw = draw;\r\n this.useTransform = useTransform;\r\n this.type = 'ex.debuggraphics';\r\n }\r\n}\r\n\n;// CONCATENATED MODULE: ./TileMap/TileMap.ts\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\nconst TileMapEvents = {\r\n PreUpdate: 'preupdate',\r\n PostUpdate: 'postupdate',\r\n PreDraw: 'predraw',\r\n PostDraw: 'postdraw'\r\n};\r\n/**\r\n * The TileMap provides a mechanism for doing flat 2D tiles rendered in a grid.\r\n *\r\n * TileMaps are useful for top down or side scrolling grid oriented games.\r\n */\r\nclass TileMap extends Entity {\r\n flagCollidersDirty() {\r\n this._collidersDirty = true;\r\n }\r\n flagTilesDirty() {\r\n for (let i = 0; i < this.tiles.length; i++) {\r\n if (this.tiles[i]) {\r\n this.tiles[i].flagDirty();\r\n }\r\n }\r\n }\r\n get x() {\r\n var _a;\r\n return (_a = this._transform.pos.x) !== null && _a !== void 0 ? _a : 0;\r\n }\r\n set x(val) {\r\n var _a;\r\n if ((_a = this._transform) === null || _a === void 0 ? void 0 : _a.pos) {\r\n this.get(TransformComponent).pos = vec(val, this.y);\r\n }\r\n }\r\n get y() {\r\n var _a, _b;\r\n return (_b = (_a = this._transform) === null || _a === void 0 ? void 0 : _a.pos.y) !== null && _b !== void 0 ? _b : 0;\r\n }\r\n set y(val) {\r\n var _a;\r\n if ((_a = this._transform) === null || _a === void 0 ? void 0 : _a.pos) {\r\n this._transform.pos = vec(this.x, val);\r\n }\r\n }\r\n get z() {\r\n var _a;\r\n return (_a = this._transform.z) !== null && _a !== void 0 ? _a : 0;\r\n }\r\n set z(val) {\r\n if (this._transform) {\r\n this._transform.z = val;\r\n }\r\n }\r\n get rotation() {\r\n var _a, _b;\r\n return (_b = (_a = this._transform) === null || _a === void 0 ? void 0 : _a.rotation) !== null && _b !== void 0 ? _b : 0;\r\n }\r\n set rotation(val) {\r\n var _a;\r\n if ((_a = this._transform) === null || _a === void 0 ? void 0 : _a.rotation) {\r\n this._transform.rotation = val;\r\n }\r\n }\r\n get scale() {\r\n var _a, _b;\r\n return (_b = (_a = this._transform) === null || _a === void 0 ? void 0 : _a.scale) !== null && _b !== void 0 ? _b : Vector.One;\r\n }\r\n set scale(val) {\r\n var _a;\r\n if ((_a = this._transform) === null || _a === void 0 ? void 0 : _a.scale) {\r\n this._transform.scale = val;\r\n }\r\n }\r\n get pos() {\r\n return this._transform.pos;\r\n }\r\n set pos(val) {\r\n this._transform.pos = val;\r\n }\r\n get vel() {\r\n return this._motion.vel;\r\n }\r\n set vel(val) {\r\n this._motion.vel = val;\r\n }\r\n emit(eventName, event) {\r\n this.events.emit(eventName, event);\r\n }\r\n on(eventName, handler) {\r\n return this.events.on(eventName, handler);\r\n }\r\n once(eventName, handler) {\r\n return this.events.once(eventName, handler);\r\n }\r\n off(eventName, handler) {\r\n this.events.off(eventName, handler);\r\n }\r\n /**\r\n * @param options\r\n */\r\n constructor(options) {\r\n var _a, _b;\r\n super(null, options.name);\r\n this.events = new EventEmitter();\r\n this._token = 0;\r\n this.logger = Logger.getInstance();\r\n this.tiles = [];\r\n this._rows = [];\r\n this._cols = [];\r\n this.renderFromTopOfGraphic = false;\r\n this._collidersDirty = true;\r\n this._originalOffsets = new WeakMap();\r\n this.addComponent(new TransformComponent());\r\n this.addComponent(new MotionComponent());\r\n this.addComponent(new BodyComponent({\r\n type: CollisionType.Fixed\r\n }));\r\n this.addComponent(new GraphicsComponent({\r\n onPostDraw: (ctx, delta) => this.draw(ctx, delta)\r\n }));\r\n this.addComponent(new DebugGraphicsComponent((ctx) => this.debug(ctx)));\r\n this.addComponent(new ColliderComponent());\r\n this._graphics = this.get(GraphicsComponent);\r\n this._transform = this.get(TransformComponent);\r\n this._motion = this.get(MotionComponent);\r\n this._collider = this.get(ColliderComponent);\r\n this._composite = this._collider.useCompositeCollider([]);\r\n this._transform.pos = (_a = options.pos) !== null && _a !== void 0 ? _a : Vector.Zero;\r\n this._oldPos = this._transform.pos.clone();\r\n this._oldScale = this._transform.scale.clone();\r\n this.renderFromTopOfGraphic = (_b = options.renderFromTopOfGraphic) !== null && _b !== void 0 ? _b : this.renderFromTopOfGraphic;\r\n this.tileWidth = options.tileWidth;\r\n this.tileHeight = options.tileHeight;\r\n this.rows = options.rows;\r\n this.columns = options.columns;\r\n this.tiles = new Array(this.rows * this.columns);\r\n this._rows = new Array(this.rows);\r\n this._cols = new Array(this.columns);\r\n let currentCol = [];\r\n for (let i = 0; i < this.columns; i++) {\r\n for (let j = 0; j < this.rows; j++) {\r\n const cd = new Tile({\r\n x: i,\r\n y: j,\r\n map: this\r\n });\r\n cd.map = this;\r\n this.tiles[i + j * this.columns] = cd;\r\n currentCol.push(cd);\r\n if (!this._rows[j]) {\r\n this._rows[j] = [];\r\n }\r\n this._rows[j].push(cd);\r\n }\r\n this._cols[i] = currentCol;\r\n currentCol = [];\r\n }\r\n this._graphics.localBounds = new BoundingBox({\r\n left: 0,\r\n top: 0,\r\n right: this.columns * this.tileWidth * this.scale.x,\r\n bottom: this.rows * this.tileHeight * this.scale.y\r\n });\r\n }\r\n _initialize(engine) {\r\n super._initialize(engine);\r\n this._engine = engine;\r\n }\r\n _getOrSetColliderOriginalOffset(collider) {\r\n if (!this._originalOffsets.has(collider)) {\r\n const originalOffset = collider.offset;\r\n this._originalOffsets.set(collider, originalOffset);\r\n return originalOffset;\r\n }\r\n else {\r\n return this._originalOffsets.get(collider);\r\n }\r\n }\r\n /**\r\n * Tiles colliders based on the solid tiles in the tilemap.\r\n */\r\n _updateColliders() {\r\n this._collider.$colliderRemoved.notifyAll(this._composite);\r\n this._composite.clearColliders();\r\n const colliders = [];\r\n this._composite = this._collider.useCompositeCollider([]);\r\n let current;\r\n // Bad square tesselation algo\r\n for (let i = 0; i < this.columns; i++) {\r\n // Scan column for colliders\r\n for (let j = 0; j < this.rows; j++) {\r\n // Columns start with a new collider\r\n if (j === 0) {\r\n current = null;\r\n }\r\n const tile = this.tiles[i + j * this.columns];\r\n // Current tile in column is solid build up current collider\r\n if (tile.solid) {\r\n // Use custom collider otherwise bounding box\r\n if (tile.getColliders().length > 0) {\r\n // tile with custom collider interrupting the current run\r\n for (const collider of tile.getColliders()) {\r\n const originalOffset = this._getOrSetColliderOriginalOffset(collider);\r\n collider.offset = vec(tile.x * this.tileWidth * this.scale.x, tile.y * this.tileHeight * this.scale.y).add(originalOffset);\r\n collider.owner = this;\r\n this._composite.addCollider(collider);\r\n }\r\n //we push any current collider before nulling the current run\r\n if (current) {\r\n colliders.push(current);\r\n }\r\n current = null;\r\n }\r\n else {\r\n if (!current) {\r\n // no current run, start one\r\n current = tile.bounds;\r\n }\r\n else {\r\n // combine with current run\r\n current = current.combine(tile.bounds);\r\n }\r\n }\r\n }\r\n else {\r\n // Not solid skip and cut off the current collider\r\n if (current) {\r\n colliders.push(current);\r\n }\r\n current = null;\r\n }\r\n }\r\n // After a column is complete check to see if it can be merged into the last one\r\n if (current) {\r\n // if previous is the same combine it\r\n const prev = colliders[colliders.length - 1];\r\n if (prev && prev.top === current.top && prev.bottom === current.bottom) {\r\n colliders[colliders.length - 1] = prev.combine(current);\r\n }\r\n else {\r\n // else new collider\r\n colliders.push(current);\r\n }\r\n }\r\n }\r\n for (const c of colliders) {\r\n const collider = Shape.Box(c.width, c.height, Vector.Zero, vec(c.left - this.pos.x, c.top - this.pos.y));\r\n collider.owner = this;\r\n this._composite.addCollider(collider);\r\n }\r\n this._collider.update();\r\n // Notify that colliders have been updated\r\n this._collider.$colliderAdded.notifyAll(this._composite);\r\n }\r\n /**\r\n * Returns the [[Tile]] by index (row major order)\r\n */\r\n getTileByIndex(index) {\r\n return this.tiles[index];\r\n }\r\n /**\r\n * Returns the [[Tile]] by its x and y integer coordinates\r\n */\r\n getTile(x, y) {\r\n if (x < 0 || y < 0 || x >= this.columns || y >= this.rows) {\r\n return null;\r\n }\r\n return this.tiles[x + y * this.columns];\r\n }\r\n /**\r\n * Returns the [[Tile]] by testing a point in world coordinates,\r\n * returns `null` if no Tile was found.\r\n */\r\n getTileByPoint(point) {\r\n const x = Math.floor((point.x - this.pos.x) / (this.tileWidth * this.scale.x));\r\n const y = Math.floor((point.y - this.pos.y) / (this.tileHeight * this.scale.y));\r\n const tile = this.getTile(x, y);\r\n if (x >= 0 && y >= 0 && x < this.columns && y < this.rows && tile) {\r\n return tile;\r\n }\r\n return null;\r\n }\r\n getRows() {\r\n return this._rows;\r\n }\r\n getColumns() {\r\n return this._cols;\r\n }\r\n update(engine, delta) {\r\n this.onPreUpdate(engine, delta);\r\n this.emit('preupdate', new PreUpdateEvent(engine, delta, this));\r\n if (!this._oldPos.equals(this.pos) ||\r\n !this._oldScale.equals(this.scale)) {\r\n this.flagCollidersDirty();\r\n this.flagTilesDirty();\r\n }\r\n if (this._collidersDirty) {\r\n this._collidersDirty = false;\r\n this._updateColliders();\r\n }\r\n this._token++;\r\n this.pos.clone(this._oldPos);\r\n this.scale.clone(this._oldScale);\r\n this._transform.pos = this.pos;\r\n this.onPostUpdate(engine, delta);\r\n this.emit('postupdate', new PostUpdateEvent(engine, delta, this));\r\n }\r\n /**\r\n * Draws the tile map to the screen. Called by the [[Scene]].\r\n * @param ctx ExcaliburGraphicsContext\r\n * @param delta The number of milliseconds since the last draw\r\n */\r\n draw(ctx, delta) {\r\n this.emit('predraw', new PreDrawEvent(ctx, delta, this)); // TODO fix event\r\n let worldBounds = this._engine.screen.getWorldBounds();\r\n // TODO can we trim this down by using world bounds?\r\n let x = 0;\r\n const xEnd = this.columns;\r\n let y = 0;\r\n const yEnd = this.rows;\r\n let graphics, graphicsIndex, graphicsLen;\r\n const maybeParallax = this.get(ParallaxComponent);\r\n if (maybeParallax) {\r\n let pos = this.pos;\r\n const oneMinusFactor = Vector.One.sub(maybeParallax.parallaxFactor);\r\n const parallaxOffset = this._engine.currentScene.camera.pos.scale(oneMinusFactor);\r\n pos = pos.sub(parallaxOffset);\r\n // adjust world bounds by parallax factor\r\n worldBounds = worldBounds.translate(pos);\r\n }\r\n let tile;\r\n for (x; x < xEnd; x++) {\r\n for (y; y < yEnd; y++) {\r\n tile = this.getTile(x, y);\r\n // fixme: This has a large perf impact, we iterate over every tile in the tilemap\r\n // this probably requires a spatial data structure to do more efficiently\r\n if (!worldBounds.overlaps(tile.bounds)) {\r\n continue;\r\n }\r\n // get non-negative tile sprites\r\n graphics = this.getTile(x, y).getGraphics();\r\n for (graphicsIndex = 0, graphicsLen = graphics.length; graphicsIndex < graphicsLen; graphicsIndex++) {\r\n // draw sprite, warning if sprite doesn't exist\r\n const graphic = graphics[graphicsIndex];\r\n if (graphic) {\r\n if (hasGraphicsTick(graphic)) {\r\n graphic === null || graphic === void 0 ? void 0 : graphic.tick(delta, this._token);\r\n }\r\n const offsetY = this.renderFromTopOfGraphic ? 0 : (graphic.height - this.tileHeight);\r\n graphic.draw(ctx, x * this.tileWidth, y * this.tileHeight - offsetY);\r\n }\r\n }\r\n }\r\n y = 0;\r\n }\r\n this.emit('postdraw', new PostDrawEvent(ctx, delta, this));\r\n }\r\n debug(gfx) {\r\n const width = this.tileWidth * this.columns;\r\n const height = this.tileHeight * this.rows;\r\n const pos = Vector.Zero;\r\n for (let r = 0; r < this.rows + 1; r++) {\r\n const yOffset = vec(0, r * this.tileHeight);\r\n gfx.drawLine(pos.add(yOffset), pos.add(vec(width, yOffset.y)), Color.Red, 2);\r\n }\r\n for (let c = 0; c < this.columns + 1; c++) {\r\n const xOffset = vec(c * this.tileWidth, 0);\r\n gfx.drawLine(pos.add(xOffset), pos.add(vec(xOffset.x, height)), Color.Red, 2);\r\n }\r\n const colliders = this._composite.getColliders();\r\n for (const collider of colliders) {\r\n const grayish = Color.Gray;\r\n grayish.a = 0.5;\r\n const bounds = collider.localBounds;\r\n const pos = collider.worldPos.sub(this.pos);\r\n gfx.drawRectangle(pos, bounds.width, bounds.height, grayish);\r\n }\r\n }\r\n}\r\n/**\r\n * TileMap Tile\r\n *\r\n * A light-weight object that occupies a space in a collision map. Generally\r\n * created by a [[TileMap]].\r\n *\r\n * Tiles can draw multiple sprites. Note that the order of drawing is the order\r\n * of the sprites in the array so the last one will be drawn on top. You can\r\n * use transparency to create layers this way.\r\n */\r\nclass Tile extends Entity {\r\n // private _transform: TransformComponent;\r\n /**\r\n * Return the world position of the top left corner of the tile\r\n */\r\n get pos() {\r\n if (this._posDirty) {\r\n this._recalculate();\r\n this._posDirty = false;\r\n }\r\n return this._pos;\r\n }\r\n /**\r\n * Width of the tile in pixels\r\n */\r\n get width() {\r\n return this._width;\r\n }\r\n /**\r\n * Height of the tile in pixels\r\n */\r\n get height() {\r\n return this._height;\r\n }\r\n /**\r\n * Wether this tile should be treated as solid by the tilemap\r\n */\r\n get solid() {\r\n return this._solid;\r\n }\r\n /**\r\n * Wether this tile should be treated as solid by the tilemap\r\n */\r\n set solid(val) {\r\n var _a;\r\n (_a = this.map) === null || _a === void 0 ? void 0 : _a.flagCollidersDirty();\r\n this._solid = val;\r\n }\r\n /**\r\n * Current list of graphics for this tile\r\n */\r\n getGraphics() {\r\n return this._graphics;\r\n }\r\n /**\r\n * Add another [[Graphic]] to this TileMap tile\r\n * @param graphic\r\n */\r\n addGraphic(graphic) {\r\n this._graphics.push(graphic);\r\n }\r\n /**\r\n * Remove an instance of a [[Graphic]] from this tile\r\n */\r\n removeGraphic(graphic) {\r\n removeItemFromArray(graphic, this._graphics);\r\n }\r\n /**\r\n * Clear all graphics from this tile\r\n */\r\n clearGraphics() {\r\n this._graphics.length = 0;\r\n }\r\n /**\r\n * Returns the list of colliders\r\n */\r\n getColliders() {\r\n return this._colliders;\r\n }\r\n /**\r\n * Adds a custom collider to the [[Tile]] to use instead of it's bounds\r\n *\r\n * If no collider is set but [[Tile.solid]] is set, the tile bounds are used as a collider.\r\n *\r\n * **Note!** the [[Tile.solid]] must be set to true for it to act as a \"fixed\" collider\r\n * @param collider\r\n */\r\n addCollider(collider) {\r\n this._colliders.push(collider);\r\n this.map.flagCollidersDirty();\r\n }\r\n /**\r\n * Removes a collider from the [[Tile]]\r\n * @param collider\r\n */\r\n removeCollider(collider) {\r\n const index = this._colliders.indexOf(collider);\r\n if (index > -1) {\r\n this._colliders.splice(index, 1);\r\n }\r\n this.map.flagCollidersDirty();\r\n }\r\n /**\r\n * Clears all colliders from the [[Tile]]\r\n */\r\n clearColliders() {\r\n this._colliders.length = 0;\r\n this.map.flagCollidersDirty();\r\n }\r\n constructor(options) {\r\n var _a, _b;\r\n super();\r\n this._posDirty = false;\r\n this._solid = false;\r\n this._graphics = [];\r\n /**\r\n * Current list of colliders for this tile\r\n */\r\n this._colliders = [];\r\n /**\r\n * Arbitrary data storage per tile, useful for any game specific data\r\n */\r\n this.data = new Map();\r\n this.x = options.x;\r\n this.y = options.y;\r\n this.map = options.map;\r\n this._width = options.map.tileWidth * this.map.scale.x;\r\n this._height = options.map.tileHeight * this.map.scale.y;\r\n this.solid = (_a = options.solid) !== null && _a !== void 0 ? _a : this.solid;\r\n this._graphics = (_b = options.graphics) !== null && _b !== void 0 ? _b : [];\r\n this._recalculate();\r\n }\r\n flagDirty() {\r\n return this._posDirty = true;\r\n }\r\n _recalculate() {\r\n this._width = this.map.tileWidth * this.map.scale.x;\r\n this._height = this.map.tileHeight * this.map.scale.y;\r\n this._pos = this.map.pos.add(vec(this.x * this._width, this.y * this._height));\r\n this._bounds = new BoundingBox(this._pos.x, this._pos.y, this._pos.x + this._width, this._pos.y + this._height);\r\n this._posDirty = false;\r\n }\r\n /**\r\n * Tile bounds in world space\r\n */\r\n get bounds() {\r\n if (this._posDirty) {\r\n this._recalculate();\r\n }\r\n return this._bounds;\r\n }\r\n /**\r\n * Tile position in world space\r\n */\r\n get center() {\r\n if (this._posDirty) {\r\n this._recalculate();\r\n }\r\n return new Vector(this._pos.x + this._width / 2, this._pos.y + this._height / 2);\r\n }\r\n}\r\n\n;// CONCATENATED MODULE: ./Camera.ts\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n/**\r\n * Container to house convenience strategy methods\r\n * @internal\r\n */\r\nclass StrategyContainer {\r\n constructor(camera) {\r\n this.camera = camera;\r\n }\r\n /**\r\n * Creates and adds the [[LockCameraToActorStrategy]] on the current camera.\r\n * @param actor The actor to lock the camera to\r\n */\r\n lockToActor(actor) {\r\n this.camera.addStrategy(new LockCameraToActorStrategy(actor));\r\n }\r\n /**\r\n * Creates and adds the [[LockCameraToActorAxisStrategy]] on the current camera\r\n * @param actor The actor to lock the camera to\r\n * @param axis The axis to follow the actor on\r\n */\r\n lockToActorAxis(actor, axis) {\r\n this.camera.addStrategy(new LockCameraToActorAxisStrategy(actor, axis));\r\n }\r\n /**\r\n * Creates and adds the [[ElasticToActorStrategy]] on the current camera\r\n * If cameraElasticity < cameraFriction < 1.0, the behavior will be a dampened spring that will slowly end at the target without bouncing\r\n * If cameraFriction < cameraElasticity < 1.0, the behavior will be an oscillating spring that will over\r\n * correct and bounce around the target\r\n *\r\n * @param actor Target actor to elastically follow\r\n * @param cameraElasticity [0 - 1.0] The higher the elasticity the more force that will drive the camera towards the target\r\n * @param cameraFriction [0 - 1.0] The higher the friction the more that the camera will resist motion towards the target\r\n */\r\n elasticToActor(actor, cameraElasticity, cameraFriction) {\r\n this.camera.addStrategy(new ElasticToActorStrategy(actor, cameraElasticity, cameraFriction));\r\n }\r\n /**\r\n * Creates and adds the [[RadiusAroundActorStrategy]] on the current camera\r\n * @param actor Target actor to follow when it is \"radius\" pixels away\r\n * @param radius Number of pixels away before the camera will follow\r\n */\r\n radiusAroundActor(actor, radius) {\r\n this.camera.addStrategy(new RadiusAroundActorStrategy(actor, radius));\r\n }\r\n /**\r\n * Creates and adds the [[LimitCameraBoundsStrategy]] on the current camera\r\n * @param box The bounding box to limit the camera to.\r\n */\r\n limitCameraBounds(box) {\r\n this.camera.addStrategy(new LimitCameraBoundsStrategy(box));\r\n }\r\n}\r\n/**\r\n * Camera axis enum\r\n */\r\nvar Axis;\r\n(function (Axis) {\r\n Axis[Axis[\"X\"] = 0] = \"X\";\r\n Axis[Axis[\"Y\"] = 1] = \"Y\";\r\n})(Axis || (Axis = {}));\r\n/**\r\n * Lock a camera to the exact x/y position of an actor.\r\n */\r\nclass LockCameraToActorStrategy {\r\n constructor(target) {\r\n this.target = target;\r\n this.action = (target, _cam, _eng, _delta) => {\r\n const center = target.center;\r\n return center;\r\n };\r\n }\r\n}\r\n/**\r\n * Lock a camera to a specific axis around an actor.\r\n */\r\nclass LockCameraToActorAxisStrategy {\r\n constructor(target, axis) {\r\n this.target = target;\r\n this.axis = axis;\r\n this.action = (target, cam, _eng, _delta) => {\r\n const center = target.center;\r\n const currentFocus = cam.getFocus();\r\n if (this.axis === Axis.X) {\r\n return new Vector(center.x, currentFocus.y);\r\n }\r\n else {\r\n return new Vector(currentFocus.x, center.y);\r\n }\r\n };\r\n }\r\n}\r\n/**\r\n * Using [Hook's law](https://en.wikipedia.org/wiki/Hooke's_law), elastically move the camera towards the target actor.\r\n */\r\nclass ElasticToActorStrategy {\r\n /**\r\n * If cameraElasticity < cameraFriction < 1.0, the behavior will be a dampened spring that will slowly end at the target without bouncing\r\n * If cameraFriction < cameraElasticity < 1.0, the behavior will be an oscillating spring that will over\r\n * correct and bounce around the target\r\n *\r\n * @param target Target actor to elastically follow\r\n * @param cameraElasticity [0 - 1.0] The higher the elasticity the more force that will drive the camera towards the target\r\n * @param cameraFriction [0 - 1.0] The higher the friction the more that the camera will resist motion towards the target\r\n */\r\n constructor(target, cameraElasticity, cameraFriction) {\r\n this.target = target;\r\n this.cameraElasticity = cameraElasticity;\r\n this.cameraFriction = cameraFriction;\r\n this.action = (target, cam, _eng, _delta) => {\r\n const position = target.center;\r\n let focus = cam.getFocus();\r\n let cameraVel = cam.vel.clone();\r\n // Calculate the stretch vector, using the spring equation\r\n // F = kX\r\n // https://en.wikipedia.org/wiki/Hooke's_law\r\n // Apply to the current camera velocity\r\n const stretch = position.sub(focus).scale(this.cameraElasticity); // stretch is X\r\n cameraVel = cameraVel.add(stretch);\r\n // Calculate the friction (-1 to apply a force in the opposition of motion)\r\n // Apply to the current camera velocity\r\n const friction = cameraVel.scale(-1).scale(this.cameraFriction);\r\n cameraVel = cameraVel.add(friction);\r\n // Update position by velocity deltas\r\n focus = focus.add(cameraVel);\r\n return focus;\r\n };\r\n }\r\n}\r\nclass RadiusAroundActorStrategy {\r\n /**\r\n *\r\n * @param target Target actor to follow when it is \"radius\" pixels away\r\n * @param radius Number of pixels away before the camera will follow\r\n */\r\n constructor(target, radius) {\r\n this.target = target;\r\n this.radius = radius;\r\n this.action = (target, cam, _eng, _delta) => {\r\n const position = target.center;\r\n const focus = cam.getFocus();\r\n const direction = position.sub(focus);\r\n const distance = direction.size;\r\n if (distance >= this.radius) {\r\n const offset = distance - this.radius;\r\n return focus.add(direction.normalize().scale(offset));\r\n }\r\n return focus;\r\n };\r\n }\r\n}\r\n/**\r\n * Prevent a camera from going beyond the given camera dimensions.\r\n */\r\nclass LimitCameraBoundsStrategy {\r\n constructor(target) {\r\n this.target = target;\r\n /**\r\n * Useful for limiting the camera to a [[TileMap]]'s dimensions, or a specific area inside the map.\r\n *\r\n * Note that this strategy does not perform any movement by itself.\r\n * It only sets the camera position to within the given bounds when the camera has gone beyond them.\r\n * Thus, it is a good idea to combine it with other camera strategies and set this strategy as the last one.\r\n *\r\n * Make sure that the camera bounds are at least as large as the viewport size.\r\n *\r\n * @param target The bounding box to limit the camera to\r\n */\r\n this.boundSizeChecked = false; // Check and warn only once\r\n this.action = (target, cam, _eng, _delta) => {\r\n const focus = cam.getFocus();\r\n if (!this.boundSizeChecked) {\r\n if (target.bottom - target.top < _eng.drawHeight || target.right - target.left < _eng.drawWidth) {\r\n Logger.getInstance().warn('Camera bounds should not be smaller than the engine viewport');\r\n }\r\n this.boundSizeChecked = true;\r\n }\r\n let focusX = focus.x;\r\n let focusY = focus.y;\r\n if (focus.x < target.left + _eng.halfDrawWidth) {\r\n focusX = target.left + _eng.halfDrawWidth;\r\n }\r\n else if (focus.x > target.right - _eng.halfDrawWidth) {\r\n focusX = target.right - _eng.halfDrawWidth;\r\n }\r\n if (focus.y < target.top + _eng.halfDrawHeight) {\r\n focusY = target.top + _eng.halfDrawHeight;\r\n }\r\n else if (focus.y > target.bottom - _eng.halfDrawHeight) {\r\n focusY = target.bottom - _eng.halfDrawHeight;\r\n }\r\n return vec(focusX, focusY);\r\n };\r\n }\r\n}\r\nconst CameraEvents = {\r\n Initialize: 'initialize',\r\n PreUpdate: 'preupdate',\r\n PostUpdate: 'postupdate'\r\n};\r\n/**\r\n * Cameras\r\n *\r\n * [[Camera]] is the base class for all Excalibur cameras. Cameras are used\r\n * to move around your game and set focus. They are used to determine\r\n * what is \"off screen\" and can be used to scale the game.\r\n *\r\n */\r\nclass Camera {\r\n constructor() {\r\n this.events = new EventEmitter();\r\n this.transform = AffineMatrix.identity();\r\n this.inverse = AffineMatrix.identity();\r\n this._cameraStrategies = [];\r\n this.strategy = new StrategyContainer(this);\r\n /**\r\n * Get or set current zoom of the camera, defaults to 1\r\n */\r\n this._z = 1;\r\n /**\r\n * Get or set rate of change in zoom, defaults to 0\r\n */\r\n this.dz = 0;\r\n /**\r\n * Get or set zoom acceleration\r\n */\r\n this.az = 0;\r\n /**\r\n * Current rotation of the camera\r\n */\r\n this.rotation = 0;\r\n this._angularVelocity = 0;\r\n /**\r\n * Get or set the camera's position\r\n */\r\n this._posChanged = false;\r\n this._pos = watchAny(Vector.Zero, () => (this._posChanged = true));\r\n /**\r\n * Get or set the camera's velocity\r\n */\r\n this.vel = Vector.Zero;\r\n /**\r\n * Get or set the camera's acceleration\r\n */\r\n this.acc = Vector.Zero;\r\n this._cameraMoving = false;\r\n this._currentLerpTime = 0;\r\n this._lerpDuration = 1000; // 1 second\r\n this._lerpStart = null;\r\n this._lerpEnd = null;\r\n //camera effects\r\n this._isShaking = false;\r\n this._shakeMagnitudeX = 0;\r\n this._shakeMagnitudeY = 0;\r\n this._shakeDuration = 0;\r\n this._elapsedShakeTime = 0;\r\n this._xShake = 0;\r\n this._yShake = 0;\r\n this._isZooming = false;\r\n this._zoomStart = 1;\r\n this._zoomEnd = 1;\r\n this._currentZoomTime = 0;\r\n this._zoomDuration = 0;\r\n this._zoomEasing = EasingFunctions.EaseInOutCubic;\r\n this._easing = EasingFunctions.EaseInOutCubic;\r\n this._halfWidth = 0;\r\n this._halfHeight = 0;\r\n this._viewport = null;\r\n this._isInitialized = false;\r\n }\r\n get zoom() {\r\n return this._z;\r\n }\r\n set zoom(val) {\r\n this._z = val;\r\n if (this._engine) {\r\n this._halfWidth = this._engine.halfDrawWidth;\r\n this._halfHeight = this._engine.halfDrawHeight;\r\n }\r\n }\r\n /**\r\n * Get or set the camera's angular velocity\r\n */\r\n get angularVelocity() {\r\n return this._angularVelocity;\r\n }\r\n set angularVelocity(value) {\r\n this._angularVelocity = value;\r\n }\r\n get pos() {\r\n return this._pos;\r\n }\r\n set pos(vec) {\r\n this._pos = watchAny(vec, () => (this._posChanged = true));\r\n this._posChanged = true;\r\n }\r\n /**\r\n * Get the camera's x position\r\n */\r\n get x() {\r\n return this.pos.x;\r\n }\r\n /**\r\n * Set the camera's x position (cannot be set when following an [[Actor]] or when moving)\r\n */\r\n set x(value) {\r\n if (!this._follow && !this._cameraMoving) {\r\n this.pos = vec(value, this.pos.y);\r\n }\r\n }\r\n /**\r\n * Get the camera's y position\r\n */\r\n get y() {\r\n return this.pos.y;\r\n }\r\n /**\r\n * Set the camera's y position (cannot be set when following an [[Actor]] or when moving)\r\n */\r\n set y(value) {\r\n if (!this._follow && !this._cameraMoving) {\r\n this.pos = vec(this.pos.x, value);\r\n }\r\n }\r\n /**\r\n * Get or set the camera's x velocity\r\n */\r\n get dx() {\r\n return this.vel.x;\r\n }\r\n set dx(value) {\r\n this.vel = vec(value, this.vel.y);\r\n }\r\n /**\r\n * Get or set the camera's y velocity\r\n */\r\n get dy() {\r\n return this.vel.y;\r\n }\r\n set dy(value) {\r\n this.vel = vec(this.vel.x, value);\r\n }\r\n /**\r\n * Get or set the camera's x acceleration\r\n */\r\n get ax() {\r\n return this.acc.x;\r\n }\r\n set ax(value) {\r\n this.acc = vec(value, this.acc.y);\r\n }\r\n /**\r\n * Get or set the camera's y acceleration\r\n */\r\n get ay() {\r\n return this.acc.y;\r\n }\r\n set ay(value) {\r\n this.acc = vec(this.acc.x, value);\r\n }\r\n /**\r\n * Returns the focal point of the camera, a new point giving the x and y position of the camera\r\n */\r\n getFocus() {\r\n return this.pos;\r\n }\r\n /**\r\n * This moves the camera focal point to the specified position using specified easing function. Cannot move when following an Actor.\r\n *\r\n * @param pos The target position to move to\r\n * @param duration The duration in milliseconds the move should last\r\n * @param [easingFn] An optional easing function ([[ex.EasingFunctions.EaseInOutCubic]] by default)\r\n * @returns A [[Promise]] that resolves when movement is finished, including if it's interrupted.\r\n * The [[Promise]] value is the [[Vector]] of the target position. It will be rejected if a move cannot be made.\r\n */\r\n move(pos, duration, easingFn = EasingFunctions.EaseInOutCubic) {\r\n if (typeof easingFn !== 'function') {\r\n throw 'Please specify an EasingFunction';\r\n }\r\n // cannot move when following an actor\r\n if (this._follow) {\r\n return Promise.reject(pos);\r\n }\r\n // resolve existing promise, if any\r\n if (this._lerpPromise && this._lerpResolve) {\r\n this._lerpResolve(pos);\r\n }\r\n this._lerpPromise = new Promise((resolve) => {\r\n this._lerpResolve = resolve;\r\n });\r\n this._lerpStart = this.getFocus().clone();\r\n this._lerpDuration = duration;\r\n this._lerpEnd = pos;\r\n this._currentLerpTime = 0;\r\n this._cameraMoving = true;\r\n this._easing = easingFn;\r\n return this._lerpPromise;\r\n }\r\n /**\r\n * Sets the camera to shake at the specified magnitudes for the specified duration\r\n * @param magnitudeX The x magnitude of the shake\r\n * @param magnitudeY The y magnitude of the shake\r\n * @param duration The duration of the shake in milliseconds\r\n */\r\n shake(magnitudeX, magnitudeY, duration) {\r\n this._isShaking = true;\r\n this._shakeMagnitudeX = magnitudeX;\r\n this._shakeMagnitudeY = magnitudeY;\r\n this._shakeDuration = duration;\r\n }\r\n /**\r\n * Zooms the camera in or out by the specified scale over the specified duration.\r\n * If no duration is specified, it take effect immediately.\r\n * @param scale The scale of the zoom\r\n * @param duration The duration of the zoom in milliseconds\r\n */\r\n zoomOverTime(scale, duration = 0, easingFn = EasingFunctions.EaseInOutCubic) {\r\n this._zoomPromise = new Promise((resolve) => {\r\n this._zoomResolve = resolve;\r\n });\r\n if (duration) {\r\n this._isZooming = true;\r\n this._zoomEasing = easingFn;\r\n this._currentZoomTime = 0;\r\n this._zoomDuration = duration;\r\n this._zoomStart = this.zoom;\r\n this._zoomEnd = scale;\r\n }\r\n else {\r\n this._isZooming = false;\r\n this.zoom = scale;\r\n return Promise.resolve(true);\r\n }\r\n return this._zoomPromise;\r\n }\r\n /**\r\n * Gets the bounding box of the viewport of this camera in world coordinates\r\n */\r\n get viewport() {\r\n if (this._viewport) {\r\n return this._viewport;\r\n }\r\n return new BoundingBox(0, 0, 0, 0);\r\n }\r\n /**\r\n * Adds a new camera strategy to this camera\r\n * @param cameraStrategy Instance of an [[CameraStrategy]]\r\n */\r\n addStrategy(cameraStrategy) {\r\n this._cameraStrategies.push(cameraStrategy);\r\n }\r\n /**\r\n * Removes a camera strategy by reference\r\n * @param cameraStrategy Instance of an [[CameraStrategy]]\r\n */\r\n removeStrategy(cameraStrategy) {\r\n removeItemFromArray(cameraStrategy, this._cameraStrategies);\r\n }\r\n /**\r\n * Clears all camera strategies from the camera\r\n */\r\n clearAllStrategies() {\r\n this._cameraStrategies.length = 0;\r\n }\r\n /**\r\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\r\n *\r\n * Internal _preupdate handler for [[onPreUpdate]] lifecycle event\r\n * @internal\r\n */\r\n _preupdate(engine, delta) {\r\n this.events.emit('preupdate', new PreUpdateEvent(engine, delta, this));\r\n this.onPreUpdate(engine, delta);\r\n }\r\n /**\r\n * Safe to override onPreUpdate lifecycle event handler. Synonymous with `.on('preupdate', (evt) =>{...})`\r\n *\r\n * `onPreUpdate` is called directly before a scene is updated.\r\n */\r\n onPreUpdate(_engine, _delta) {\r\n // Overridable\r\n }\r\n /**\r\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\r\n *\r\n * Internal _preupdate handler for [[onPostUpdate]] lifecycle event\r\n * @internal\r\n */\r\n _postupdate(engine, delta) {\r\n this.events.emit('postupdate', new PostUpdateEvent(engine, delta, this));\r\n this.onPostUpdate(engine, delta);\r\n }\r\n /**\r\n * Safe to override onPostUpdate lifecycle event handler. Synonymous with `.on('preupdate', (evt) =>{...})`\r\n *\r\n * `onPostUpdate` is called directly after a scene is updated.\r\n */\r\n onPostUpdate(_engine, _delta) {\r\n // Overridable\r\n }\r\n get isInitialized() {\r\n return this._isInitialized;\r\n }\r\n _initialize(_engine) {\r\n if (!this.isInitialized) {\r\n this._engine = _engine;\r\n this._screen = _engine.screen;\r\n const currentRes = this._screen.contentArea;\r\n let center = vec(currentRes.width / 2, currentRes.height / 2);\r\n if (!this._engine.loadingComplete) {\r\n // If there was a loading screen, we peek the configured resolution\r\n const res = this._screen.peekResolution();\r\n if (res) {\r\n center = vec(res.width / 2, res.height / 2);\r\n }\r\n }\r\n this._halfWidth = center.x;\r\n this._halfHeight = center.y;\r\n // If the user has not set the camera pos, apply default center screen position\r\n if (!this._posChanged) {\r\n this.pos = center;\r\n }\r\n // First frame bootstrap\r\n // Ensure camera tx is correct\r\n // Run update twice to ensure properties are init'd\r\n this.updateTransform();\r\n // Run strategies for first frame\r\n this.runStrategies(_engine, _engine.clock.elapsed());\r\n // Setup the first frame viewport\r\n this.updateViewport();\r\n // It's important to update the camera after strategies\r\n // This prevents jitter\r\n this.updateTransform();\r\n this.onInitialize(_engine);\r\n this.events.emit('initialize', new InitializeEvent(_engine, this));\r\n this._isInitialized = true;\r\n }\r\n }\r\n /**\r\n * Safe to override onPostUpdate lifecycle event handler. Synonymous with `.on('preupdate', (evt) =>{...})`\r\n *\r\n * `onPostUpdate` is called directly after a scene is updated.\r\n */\r\n onInitialize(_engine) {\r\n // Overridable\r\n }\r\n emit(eventName, event) {\r\n this.events.emit(eventName, event);\r\n }\r\n on(eventName, handler) {\r\n return this.events.on(eventName, handler);\r\n }\r\n once(eventName, handler) {\r\n return this.events.once(eventName, handler);\r\n }\r\n off(eventName, handler) {\r\n this.events.off(eventName, handler);\r\n }\r\n runStrategies(engine, delta) {\r\n for (const s of this._cameraStrategies) {\r\n this.pos = s.action.call(s, s.target, this, engine, delta);\r\n }\r\n }\r\n updateViewport() {\r\n // recalc viewport\r\n this._viewport = new BoundingBox(this.x - this._halfWidth, this.y - this._halfHeight, this.x + this._halfWidth, this.y + this._halfHeight);\r\n }\r\n update(_engine, delta) {\r\n this._initialize(_engine);\r\n this._preupdate(_engine, delta);\r\n // Update placements based on linear algebra\r\n this.pos = this.pos.add(this.vel.scale(delta / 1000));\r\n this.zoom += (this.dz * delta) / 1000;\r\n this.vel = this.vel.add(this.acc.scale(delta / 1000));\r\n this.dz += (this.az * delta) / 1000;\r\n this.rotation += (this.angularVelocity * delta) / 1000;\r\n if (this._isZooming) {\r\n if (this._currentZoomTime < this._zoomDuration) {\r\n const zoomEasing = this._zoomEasing;\r\n const newZoom = zoomEasing(this._currentZoomTime, this._zoomStart, this._zoomEnd, this._zoomDuration);\r\n this.zoom = newZoom;\r\n this._currentZoomTime += delta;\r\n }\r\n else {\r\n this._isZooming = false;\r\n this.zoom = this._zoomEnd;\r\n this._currentZoomTime = 0;\r\n this._zoomResolve(true);\r\n }\r\n }\r\n if (this._cameraMoving) {\r\n if (this._currentLerpTime < this._lerpDuration) {\r\n const moveEasing = EasingFunctions.CreateVectorEasingFunction(this._easing);\r\n const lerpPoint = moveEasing(this._currentLerpTime, this._lerpStart, this._lerpEnd, this._lerpDuration);\r\n this.pos = lerpPoint;\r\n this._currentLerpTime += delta;\r\n }\r\n else {\r\n this.pos = this._lerpEnd;\r\n const end = this._lerpEnd.clone();\r\n this._lerpStart = null;\r\n this._lerpEnd = null;\r\n this._currentLerpTime = 0;\r\n this._cameraMoving = false;\r\n // Order matters here, resolve should be last so any chain promises have a clean slate\r\n this._lerpResolve(end);\r\n }\r\n }\r\n if (this._isDoneShaking()) {\r\n this._isShaking = false;\r\n this._elapsedShakeTime = 0;\r\n this._shakeMagnitudeX = 0;\r\n this._shakeMagnitudeY = 0;\r\n this._shakeDuration = 0;\r\n this._xShake = 0;\r\n this._yShake = 0;\r\n }\r\n else {\r\n this._elapsedShakeTime += delta;\r\n this._xShake = ((Math.random() * this._shakeMagnitudeX) | 0) + 1;\r\n this._yShake = ((Math.random() * this._shakeMagnitudeY) | 0) + 1;\r\n }\r\n this.runStrategies(_engine, delta);\r\n this.updateViewport();\r\n // It's important to update the camera after strategies\r\n // This prevents jitter\r\n this.updateTransform();\r\n this._postupdate(_engine, delta);\r\n }\r\n /**\r\n * Applies the relevant transformations to the game canvas to \"move\" or apply effects to the Camera\r\n * @param ctx Canvas context to apply transformations\r\n */\r\n draw(ctx) {\r\n ctx.multiply(this.transform);\r\n }\r\n updateTransform() {\r\n // center the camera\r\n const newCanvasWidth = this._screen.resolution.width / this.zoom;\r\n const newCanvasHeight = this._screen.resolution.height / this.zoom;\r\n const cameraPos = vec(-this.x + newCanvasWidth / 2 + this._xShake, -this.y + newCanvasHeight / 2 + this._yShake);\r\n // Calculate camera transform\r\n this.transform.reset();\r\n this.transform.scale(this.zoom, this.zoom);\r\n // rotate about the focus\r\n this.transform.translate(newCanvasWidth / 2, newCanvasHeight / 2);\r\n this.transform.rotate(this.rotation);\r\n this.transform.translate(-newCanvasWidth / 2, -newCanvasHeight / 2);\r\n this.transform.translate(cameraPos.x, cameraPos.y);\r\n this.transform.inverse(this.inverse);\r\n }\r\n _isDoneShaking() {\r\n return !this._isShaking || this._elapsedShakeTime >= this._shakeDuration;\r\n }\r\n}\r\n\n;// CONCATENATED MODULE: ./Trigger.ts\n\r\n\r\n\r\n\r\n\r\nconst TriggerEvents = {\r\n ExitTrigger: 'exittrigger',\r\n EnterTrigger: 'entertrigger'\r\n};\r\nconst triggerDefaults = {\r\n pos: Vector.Zero,\r\n width: 10,\r\n height: 10,\r\n visible: false,\r\n action: () => {\r\n return;\r\n },\r\n filter: () => true,\r\n repeat: -1\r\n};\r\n/**\r\n * Triggers are a method of firing arbitrary code on collision. These are useful\r\n * as 'buttons', 'switches', or to trigger effects in a game. By default triggers\r\n * are invisible, and can only be seen when [[Trigger.visible]] is set to `true`.\r\n */\r\nclass Trigger extends Actor {\r\n /**\r\n *\r\n * @param opts Trigger options\r\n */\r\n constructor(opts) {\r\n super({ x: opts.pos.x, y: opts.pos.y, width: opts.width, height: opts.height });\r\n this.events = new EventEmitter();\r\n /**\r\n * Action to fire when triggered by collision\r\n */\r\n this.action = () => {\r\n return;\r\n };\r\n /**\r\n * Filter to add additional granularity to action dispatch, if a filter is specified the action will only fire when\r\n * filter return true for the collided actor.\r\n */\r\n this.filter = () => true;\r\n /**\r\n * Number of times to repeat before killing the trigger,\r\n */\r\n this.repeat = -1;\r\n opts = {\r\n ...triggerDefaults,\r\n ...opts\r\n };\r\n this.filter = opts.filter || this.filter;\r\n this.repeat = opts.repeat || this.repeat;\r\n this.action = opts.action || this.action;\r\n if (opts.target) {\r\n this.target = opts.target;\r\n }\r\n this.graphics.visible = opts.visible;\r\n this.body.collisionType = CollisionType.Passive;\r\n this.events.on('collisionstart', (evt) => {\r\n if (this.filter(evt.other)) {\r\n this.emit('enter', new EnterTriggerEvent(this, evt.other));\r\n this._dispatchAction();\r\n // remove trigger if its done, -1 repeat forever\r\n if (this.repeat === 0) {\r\n this.kill();\r\n }\r\n }\r\n });\r\n this.events.on('collisionend', (evt) => {\r\n if (this.filter(evt.other)) {\r\n this.emit('exit', new ExitTriggerEvent(this, evt.other));\r\n }\r\n });\r\n }\r\n set target(target) {\r\n this._target = target;\r\n this.filter = (actor) => actor === target;\r\n }\r\n get target() {\r\n return this._target;\r\n }\r\n _initialize(engine) {\r\n super._initialize(engine);\r\n }\r\n _dispatchAction() {\r\n if (this.repeat !== 0) {\r\n this.action.call(this);\r\n this.repeat--;\r\n }\r\n }\r\n}\r\n\n;// CONCATENATED MODULE: ./EntityComponentSystem/System.ts\n/**\r\n * Enum that determines whether to run the system in the update or draw phase\r\n */\r\nvar SystemType;\r\n(function (SystemType) {\r\n SystemType[\"Update\"] = \"update\";\r\n SystemType[\"Draw\"] = \"draw\";\r\n})(SystemType || (SystemType = {}));\r\n/**\r\n * An Excalibur [[System]] that updates entities of certain types.\r\n * Systems are scene specific\r\n *\r\n * Excalibur Systems currently require at least 1 Component type to operated\r\n *\r\n * Multiple types are declared as a type union\r\n * For example:\r\n *\r\n * ```typescript\r\n * class MySystem extends System {\r\n * public readonly types = ['a', 'b'] as const;\r\n * public readonly systemType = SystemType.Update;\r\n * public update(entities: Entity) {\r\n * ...\r\n * }\r\n * }\r\n * ```\r\n */\r\nclass System {\r\n constructor() {\r\n /**\r\n * System can execute in priority order, by default all systems are priority 0. Lower values indicated higher priority.\r\n * For a system to execute before all other a lower priority value (-1 for example) must be set.\r\n * For a system to execute after all other a higher priority value (10 for example) must be set.\r\n */\r\n this.priority = 0;\r\n }\r\n /**\r\n * Systems observe when entities match their types or no longer match their types, override\r\n * @param _entityAddedOrRemoved\r\n */\r\n notify(_entityAddedOrRemoved) {\r\n // Override me\r\n }\r\n}\r\n/**\r\n * An [[Entity]] with [[Component]] types that matches a [[System]] types exists in the current scene.\r\n */\r\nclass AddedEntity {\r\n constructor(data) {\r\n this.data = data;\r\n this.type = 'Entity Added';\r\n }\r\n}\r\n/**\r\n * Type guard to check for AddedEntity messages\r\n * @param x\r\n */\r\nfunction isAddedSystemEntity(x) {\r\n return !!x && x.type === 'Entity Added';\r\n}\r\n/**\r\n * An [[Entity]] with [[Component]] types that no longer matches a [[System]] types exists in the current scene.\r\n */\r\nclass RemovedEntity {\r\n constructor(data) {\r\n this.data = data;\r\n this.type = 'Entity Removed';\r\n }\r\n}\r\n/**\r\n * type guard to check for the RemovedEntity message\r\n */\r\nfunction isRemoveSystemEntity(x) {\r\n return !!x && x.type === 'Entity Removed';\r\n}\r\n\n;// CONCATENATED MODULE: ./EntityComponentSystem/EntityManager.ts\n\r\n\r\n// Add/Remove entities and components\r\nclass EntityManager {\r\n constructor(_world) {\r\n this._world = _world;\r\n this.entities = [];\r\n this._entityIndex = {};\r\n this._entitiesToRemove = [];\r\n }\r\n /**\r\n * Runs the entity lifecycle\r\n * @param _context\r\n */\r\n updateEntities(_context, elapsed) {\r\n for (const entity of this.entities) {\r\n // TODO is this right?\r\n entity.update(_context.engine, elapsed);\r\n if (!entity.active) {\r\n this.removeEntity(entity);\r\n }\r\n }\r\n }\r\n findEntitiesForRemoval() {\r\n for (const entity of this.entities) {\r\n if (!entity.active) {\r\n this.removeEntity(entity);\r\n }\r\n }\r\n }\r\n /**\r\n * EntityManager observes changes on entities\r\n * @param message\r\n */\r\n notify(message) {\r\n if (isAddedComponent(message)) {\r\n // we don't need the component, it's already on the entity\r\n this._world.queryManager.addEntity(message.data.entity);\r\n }\r\n if (isRemovedComponent(message)) {\r\n this._world.queryManager.removeComponent(message.data.entity, message.data.component);\r\n }\r\n }\r\n /**\r\n * Adds an entity to be tracked by the EntityManager\r\n * @param entity\r\n */\r\n addEntity(entity) {\r\n entity.active = true;\r\n entity.scene = this._world.context;\r\n if (entity && !this._entityIndex[entity.id]) {\r\n this._entityIndex[entity.id] = entity;\r\n this.entities.push(entity);\r\n this._world.queryManager.addEntity(entity);\r\n entity.componentAdded$.register(this);\r\n entity.componentRemoved$.register(this);\r\n // if entity has children\r\n entity.children.forEach((c) => {\r\n c.scene = entity.scene;\r\n this.addEntity(c);\r\n });\r\n entity.childrenAdded$.register({\r\n notify: (e) => {\r\n this.addEntity(e);\r\n }\r\n });\r\n entity.childrenRemoved$.register({\r\n notify: (e) => {\r\n this.removeEntity(e, false);\r\n }\r\n });\r\n }\r\n }\r\n removeEntity(idOrEntity, deferred = true) {\r\n var _a;\r\n let id = 0;\r\n if (idOrEntity instanceof Entity) {\r\n id = idOrEntity.id;\r\n }\r\n else {\r\n id = idOrEntity;\r\n }\r\n const entity = this._entityIndex[id];\r\n if (entity && entity.active) {\r\n entity.active = false;\r\n }\r\n if (entity && deferred) {\r\n this._entitiesToRemove.push(entity);\r\n return;\r\n }\r\n delete this._entityIndex[id];\r\n if (entity) {\r\n entity.scene = null;\r\n removeItemFromArray(entity, this.entities);\r\n this._world.queryManager.removeEntity(entity);\r\n entity.componentAdded$.unregister(this);\r\n entity.componentRemoved$.unregister(this);\r\n // if entity has children\r\n entity.children.forEach((c) => {\r\n c.scene = null;\r\n this.removeEntity(c, deferred);\r\n });\r\n entity.childrenAdded$.clear();\r\n entity.childrenRemoved$.clear();\r\n // stats\r\n if ((_a = this._world.context) === null || _a === void 0 ? void 0 : _a.engine) {\r\n this._world.context.engine.stats.currFrame.actors.killed++;\r\n }\r\n }\r\n }\r\n processEntityRemovals() {\r\n for (const entity of this._entitiesToRemove) {\r\n if (entity.active) {\r\n continue;\r\n }\r\n this.removeEntity(entity, false);\r\n }\r\n this._entitiesToRemove.length = 0;\r\n }\r\n processComponentRemovals() {\r\n for (const entity of this.entities) {\r\n entity.processComponentRemoval();\r\n }\r\n }\r\n getById(id) {\r\n return this._entityIndex[id];\r\n }\r\n getByName(name) {\r\n return this.entities.filter(e => e.name === name);\r\n }\r\n clear() {\r\n for (const entity of this.entities) {\r\n this.removeEntity(entity);\r\n }\r\n }\r\n}\r\n\n;// CONCATENATED MODULE: ./EntityComponentSystem/Util.ts\nconst buildTypeKey = (types) => {\r\n const key = [...types].sort((a, b) => a.localeCompare(b)).join('+');\r\n return key;\r\n};\r\n\n;// CONCATENATED MODULE: ./EntityComponentSystem/Query.ts\n\r\n\r\n\r\n\r\n\r\n/**\r\n * Represents query for entities that match a list of types that is cached and observable\r\n *\r\n * Queries can be strongly typed by supplying a type union in the optional type parameter\r\n * ```typescript\r\n * const queryAB = new ex.Query(['A', 'B']);\r\n * ```\r\n */\r\nclass Query extends Observable {\r\n get key() {\r\n if (this._key) {\r\n return this._key;\r\n }\r\n return (this._key = buildTypeKey(this.types));\r\n }\r\n constructor(types) {\r\n super();\r\n this._entities = [];\r\n if (types[0] instanceof Function) {\r\n this.types = types.map(T => (new T).type);\r\n }\r\n else {\r\n this.types = types;\r\n }\r\n }\r\n /**\r\n * Returns a list of entities that match the query\r\n *\r\n * @param sort Optional sorting function to sort entities returned from the query\r\n */\r\n getEntities(sort) {\r\n if (sort) {\r\n this._entities.sort(sort);\r\n }\r\n return this._entities;\r\n }\r\n /**\r\n * Add an entity to the query, will only be added if the entity matches the query types\r\n * @param entity\r\n */\r\n addEntity(entity) {\r\n if (!contains(this._entities, entity) && this.matches(entity)) {\r\n this._entities.push(entity);\r\n this.notifyAll(new AddedEntity(entity));\r\n }\r\n }\r\n /**\r\n * If the entity is part of the query it will be removed regardless of types\r\n * @param entity\r\n */\r\n removeEntity(entity) {\r\n if (removeItemFromArray(entity, this._entities)) {\r\n this.notifyAll(new RemovedEntity(entity));\r\n }\r\n }\r\n /**\r\n * Removes all entities and observers from the query\r\n */\r\n clear() {\r\n this._entities.length = 0;\r\n for (const observer of this.observers) {\r\n this.unregister(observer);\r\n }\r\n }\r\n matches(typesOrEntity) {\r\n let types = [];\r\n if (typesOrEntity instanceof Entity) {\r\n types = typesOrEntity.types;\r\n }\r\n else {\r\n types = typesOrEntity;\r\n }\r\n let matches = true;\r\n for (const type of this.types) {\r\n matches = matches && types.indexOf(type) > -1;\r\n if (!matches) {\r\n return false;\r\n }\r\n }\r\n return matches;\r\n }\r\n contain(type) {\r\n return this.types.indexOf(type) > -1;\r\n }\r\n}\r\n\n;// CONCATENATED MODULE: ./EntityComponentSystem/QueryManager.ts\n\r\n\r\n/**\r\n * The query manager is responsible for updating all queries when entities/components change\r\n */\r\nclass QueryManager {\r\n constructor(_world) {\r\n this._world = _world;\r\n this._queries = {};\r\n }\r\n /**\r\n * Adds a query to the manager and populates with any entities that match\r\n * @param query\r\n */\r\n _addQuery(query) {\r\n this._queries[buildTypeKey(query.types)] = query;\r\n for (const entity of this._world.entityManager.entities) {\r\n query.addEntity(entity);\r\n }\r\n }\r\n /**\r\n * Removes the query if there are no observers left\r\n * @param query\r\n */\r\n maybeRemoveQuery(query) {\r\n if (query.observers.length === 0) {\r\n query.clear();\r\n delete this._queries[buildTypeKey(query.types)];\r\n }\r\n }\r\n /**\r\n * Adds the entity to any matching query in the query manage\r\n * @param entity\r\n */\r\n addEntity(entity) {\r\n for (const queryType in this._queries) {\r\n if (this._queries[queryType]) {\r\n this._queries[queryType].addEntity(entity);\r\n }\r\n }\r\n }\r\n /**\r\n * Removes an entity from queries if the removed component disqualifies it\r\n * @param entity\r\n * @param component\r\n */\r\n removeComponent(entity, component) {\r\n for (const queryType in this._queries) {\r\n // If the component being removed from an entity is a part of a query,\r\n // it is now disqualified from that query, remove it\r\n if (this._queries[queryType].contain(component.type)) {\r\n this._queries[queryType].removeEntity(entity);\r\n }\r\n }\r\n }\r\n /**\r\n * Removes an entity from all queries it is currently a part of\r\n * @param entity\r\n */\r\n removeEntity(entity) {\r\n for (const queryType in this._queries) {\r\n this._queries[queryType].removeEntity(entity);\r\n }\r\n }\r\n /**\r\n * Creates a populated query and returns, if the query already exists that will be returned instead of a new instance\r\n * @param types\r\n */\r\n createQuery(types) {\r\n const maybeExistingQuery = this.getQuery(types);\r\n if (maybeExistingQuery) {\r\n return maybeExistingQuery;\r\n }\r\n const query = new Query(types);\r\n this._addQuery(query);\r\n return query;\r\n }\r\n /**\r\n * Retrieves an existing query by types if it exists otherwise returns null\r\n * @param types\r\n */\r\n getQuery(types) {\r\n const key = buildTypeKey(types);\r\n if (this._queries[key]) {\r\n return this._queries[key];\r\n }\r\n return null;\r\n }\r\n}\r\n\n;// CONCATENATED MODULE: ./EntityComponentSystem/SystemManager.ts\n\r\n/**\r\n * The SystemManager is responsible for keeping track of all systems in a scene.\r\n * Systems are scene specific\r\n */\r\nclass SystemManager {\r\n constructor(_world) {\r\n this._world = _world;\r\n /**\r\n * List of systems, to add a new system call [[SystemManager.addSystem]]\r\n */\r\n this.systems = [];\r\n this.initialized = false;\r\n }\r\n /**\r\n * Get a system registered in the manager by type\r\n * @param systemType\r\n */\r\n get(systemType) {\r\n return this.systems.find((s) => s instanceof systemType);\r\n }\r\n /**\r\n * Adds a system to the manager, it will now be updated every frame\r\n * @param system\r\n */\r\n addSystem(system) {\r\n // validate system has types\r\n if (!system.types || system.types.length === 0) {\r\n throw new Error(`Attempted to add a System without any types`);\r\n }\r\n const query = this._world.queryManager.createQuery(system.types);\r\n this.systems.push(system);\r\n this.systems.sort((a, b) => a.priority - b.priority);\r\n query.register(system);\r\n // If systems are added and the manager has already been init'd\r\n // then immediately init the system\r\n if (this.initialized && system.initialize) {\r\n system.initialize(this._world.context);\r\n }\r\n }\r\n /**\r\n * Removes a system from the manager, it will no longer be updated\r\n * @param system\r\n */\r\n removeSystem(system) {\r\n removeItemFromArray(system, this.systems);\r\n const query = this._world.queryManager.getQuery(system.types);\r\n if (query) {\r\n query.unregister(system);\r\n this._world.queryManager.maybeRemoveQuery(query);\r\n }\r\n }\r\n /**\r\n * Initialize all systems in the manager\r\n *\r\n * Systems added after initialize() will be initialized on add\r\n */\r\n initialize() {\r\n if (!this.initialized) {\r\n this.initialized = true;\r\n for (const s of this.systems) {\r\n if (s.initialize) {\r\n s.initialize(this._world.context);\r\n }\r\n }\r\n }\r\n }\r\n /**\r\n * Updates all systems\r\n * @param type whether this is an update or draw system\r\n * @param context context reference\r\n * @param delta time in milliseconds\r\n */\r\n updateSystems(type, context, delta) {\r\n const systems = this.systems.filter((s) => s.systemType === type);\r\n for (const s of systems) {\r\n if (s.preupdate) {\r\n s.preupdate(context, delta);\r\n }\r\n }\r\n for (const s of systems) {\r\n // Get entities that match the system types, pre-sort\r\n const entities = this._world.queryManager.getQuery(s.types).getEntities(s.sort);\r\n // Initialize entities if needed\r\n if (context instanceof Scene) {\r\n for (const entity of entities) {\r\n entity._initialize(context === null || context === void 0 ? void 0 : context.engine);\r\n }\r\n }\r\n s.update(entities, delta);\r\n }\r\n for (const s of systems) {\r\n if (s.postupdate) {\r\n s.postupdate(context, delta);\r\n }\r\n }\r\n }\r\n clear() {\r\n for (const system of this.systems) {\r\n this.removeSystem(system);\r\n }\r\n }\r\n}\r\n\n;// CONCATENATED MODULE: ./EntityComponentSystem/World.ts\n\r\n\r\n\r\n\r\n\r\n/**\r\n * The World is a self-contained entity component system for a particular context.\r\n */\r\nclass World {\r\n /**\r\n * The context type is passed to the system updates\r\n * @param context\r\n */\r\n constructor(context) {\r\n this.context = context;\r\n this.queryManager = new QueryManager(this);\r\n this.entityManager = new EntityManager(this);\r\n this.systemManager = new SystemManager(this);\r\n }\r\n /**\r\n * Update systems by type and time elapsed in milliseconds\r\n */\r\n update(type, delta) {\r\n if (type === SystemType.Update) {\r\n this.entityManager.updateEntities(this.context, delta);\r\n }\r\n this.systemManager.updateSystems(type, this.context, delta);\r\n this.entityManager.findEntitiesForRemoval();\r\n this.entityManager.processComponentRemovals();\r\n this.entityManager.processEntityRemovals();\r\n }\r\n add(entityOrSystem) {\r\n if (entityOrSystem instanceof Entity) {\r\n this.entityManager.addEntity(entityOrSystem);\r\n }\r\n if (entityOrSystem instanceof System) {\r\n this.systemManager.addSystem(entityOrSystem);\r\n }\r\n }\r\n remove(entityOrSystem, deferred = true) {\r\n if (entityOrSystem instanceof Entity) {\r\n this.entityManager.removeEntity(entityOrSystem, deferred);\r\n }\r\n if (entityOrSystem instanceof System) {\r\n this.systemManager.removeSystem(entityOrSystem);\r\n }\r\n }\r\n clearEntities() {\r\n this.entityManager.clear();\r\n }\r\n clearSystems() {\r\n this.systemManager.clear();\r\n }\r\n}\r\n\n;// CONCATENATED MODULE: ./Collision/Integrator.ts\n\r\nclass EulerIntegrator {\r\n static integrate(transform, motion, totalAcc, elapsedMs) {\r\n const seconds = elapsedMs / 1000;\r\n // This code looks a little wild, but it's to avoid creating any new Vector instances\r\n // integration is done in a tight loop so this is key to avoid GC'ing\r\n motion.vel.addEqual(totalAcc.scale(seconds, EulerIntegrator._ACC));\r\n transform.pos\r\n .add(motion.vel.scale(seconds, EulerIntegrator._VEL), EulerIntegrator._POS)\r\n .addEqual(totalAcc.scale(0.5 * seconds * seconds, EulerIntegrator._VEL_ACC));\r\n motion.angularVelocity += motion.torque * (1.0 / motion.inertia) * seconds;\r\n const rotation = transform.rotation + motion.angularVelocity * seconds;\r\n transform.scale.add(motion.scaleFactor.scale(seconds, this._SCALE_FACTOR), EulerIntegrator._SCALE);\r\n const tx = transform.get();\r\n tx.setTransform(EulerIntegrator._POS, rotation, EulerIntegrator._SCALE);\r\n }\r\n}\r\n// Scratch vectors to avoid allocation\r\nEulerIntegrator._POS = new Vector(0, 0);\r\nEulerIntegrator._SCALE = new Vector(1, 1);\r\nEulerIntegrator._ACC = new Vector(0, 0);\r\nEulerIntegrator._VEL = new Vector(0, 0);\r\nEulerIntegrator._VEL_ACC = new Vector(0, 0);\r\nEulerIntegrator._SCALE_FACTOR = new Vector(0, 0);\r\n\n;// CONCATENATED MODULE: ./Collision/MotionSystem.ts\n\r\n\r\n\r\n\r\n\r\n\r\n\r\nclass MotionSystem extends System {\r\n constructor() {\r\n super(...arguments);\r\n this.types = ['ex.transform', 'ex.motion'];\r\n this.systemType = SystemType.Update;\r\n this.priority = -1;\r\n }\r\n update(entities, elapsedMs) {\r\n let transform;\r\n let motion;\r\n for (let i = 0; i < entities.length; i++) {\r\n transform = entities[i].get(TransformComponent);\r\n motion = entities[i].get(MotionComponent);\r\n const optionalBody = entities[i].get(BodyComponent);\r\n if (optionalBody === null || optionalBody === void 0 ? void 0 : optionalBody.sleeping) {\r\n continue;\r\n }\r\n const totalAcc = motion.acc.clone();\r\n if ((optionalBody === null || optionalBody === void 0 ? void 0 : optionalBody.collisionType) === CollisionType.Active && (optionalBody === null || optionalBody === void 0 ? void 0 : optionalBody.useGravity)) {\r\n totalAcc.addEqual(Physics.gravity);\r\n }\r\n optionalBody === null || optionalBody === void 0 ? void 0 : optionalBody.captureOldTransform();\r\n // Update transform and motion based on Euler linear algebra\r\n EulerIntegrator.integrate(transform, motion, totalAcc, elapsedMs);\r\n }\r\n }\r\n}\r\n\n;// CONCATENATED MODULE: ./Collision/Solver/ArcadeSolver.ts\n\r\n\r\n\r\n\r\n/**\r\n * ArcadeSolver is the default in Excalibur. It solves collisions so that there is no overlap between contacts,\r\n * and negates velocity along the collision normal.\r\n *\r\n * This is usually the type of collisions used for 2D games that don't need a more realistic collision simulation.\r\n *\r\n */\r\nclass ArcadeSolver {\r\n constructor() {\r\n this.directionMap = new Map();\r\n this.distanceMap = new Map();\r\n }\r\n solve(contacts) {\r\n // Events and init\r\n this.preSolve(contacts);\r\n // Remove any canceled contacts\r\n contacts = contacts.filter(c => !c.isCanceled());\r\n // Sort contacts by distance to avoid artifacts with seams\r\n // It's important to solve in a specific order\r\n contacts.sort((a, b) => {\r\n const aDist = this.distanceMap.get(a.id);\r\n const bDist = this.distanceMap.get(b.id);\r\n return aDist - bDist;\r\n });\r\n for (const contact of contacts) {\r\n // Solve position first in arcade\r\n this.solvePosition(contact);\r\n // Solve velocity second in arcade\r\n this.solveVelocity(contact);\r\n }\r\n // Events and any contact house-keeping the solver needs\r\n this.postSolve(contacts);\r\n return contacts;\r\n }\r\n preSolve(contacts) {\r\n const epsilon = .0001;\r\n for (const contact of contacts) {\r\n if (Math.abs(contact.mtv.x) < epsilon && Math.abs(contact.mtv.y) < epsilon) {\r\n // Cancel near 0 mtv collisions\r\n contact.cancel();\r\n continue;\r\n }\r\n const side = Side.fromDirection(contact.mtv);\r\n const mtv = contact.mtv.negate();\r\n const distance = contact.colliderA.worldPos.squareDistance(contact.colliderB.worldPos);\r\n this.distanceMap.set(contact.id, distance);\r\n // Publish collision events on both participants\r\n contact.colliderA.events.emit('precollision', new PreCollisionEvent(contact.colliderA, contact.colliderB, side, mtv));\r\n contact.colliderB.events.emit('precollision', new PreCollisionEvent(contact.colliderB, contact.colliderA, Side.getOpposite(side), mtv.negate()));\r\n }\r\n }\r\n postSolve(contacts) {\r\n var _a, _b;\r\n for (const contact of contacts) {\r\n if (contact.isCanceled()) {\r\n continue;\r\n }\r\n const colliderA = contact.colliderA;\r\n const colliderB = contact.colliderB;\r\n const bodyA = (_a = colliderA.owner) === null || _a === void 0 ? void 0 : _a.get(BodyComponent);\r\n const bodyB = (_b = colliderB.owner) === null || _b === void 0 ? void 0 : _b.get(BodyComponent);\r\n if (bodyA && bodyB) {\r\n if (bodyA.collisionType === CollisionType.Passive || bodyB.collisionType === CollisionType.Passive) {\r\n continue;\r\n }\r\n }\r\n const side = Side.fromDirection(contact.mtv);\r\n const mtv = contact.mtv.negate();\r\n // Publish collision events on both participants\r\n contact.colliderA.events.emit('postcollision', new PostCollisionEvent(contact.colliderA, contact.colliderB, side, mtv));\r\n contact.colliderB.events.emit('postcollision', new PostCollisionEvent(contact.colliderB, contact.colliderA, Side.getOpposite(side), mtv.negate()));\r\n }\r\n }\r\n solvePosition(contact) {\r\n var _a, _b;\r\n const epsilon = .0001;\r\n // if bounds no longer intersect skip to the next\r\n // this removes jitter from overlapping/stacked solid tiles or a wall of solid tiles\r\n if (!contact.colliderA.bounds.overlaps(contact.colliderB.bounds, epsilon)) {\r\n // Cancel the contact to prevent and solving\r\n contact.cancel();\r\n return;\r\n }\r\n if (Math.abs(contact.mtv.x) < epsilon && Math.abs(contact.mtv.y) < epsilon) {\r\n // Cancel near 0 mtv collisions\r\n contact.cancel();\r\n return;\r\n }\r\n let mtv = contact.mtv;\r\n const colliderA = contact.colliderA;\r\n const colliderB = contact.colliderB;\r\n const bodyA = (_a = colliderA.owner) === null || _a === void 0 ? void 0 : _a.get(BodyComponent);\r\n const bodyB = (_b = colliderB.owner) === null || _b === void 0 ? void 0 : _b.get(BodyComponent);\r\n if (bodyA && bodyB) {\r\n if (bodyA.collisionType === CollisionType.Passive || bodyB.collisionType === CollisionType.Passive) {\r\n return;\r\n }\r\n if (bodyA.collisionType === CollisionType.Active && bodyB.collisionType === CollisionType.Active) {\r\n // split overlaps if both are Active\r\n mtv = mtv.scale(0.5);\r\n }\r\n // Resolve overlaps\r\n if (bodyA.collisionType === CollisionType.Active) {\r\n bodyA.globalPos.x -= mtv.x;\r\n bodyA.globalPos.y -= mtv.y;\r\n colliderA.update(bodyA.transform.get());\r\n }\r\n if (bodyB.collisionType === CollisionType.Active) {\r\n bodyB.globalPos.x += mtv.x;\r\n bodyB.globalPos.y += mtv.y;\r\n colliderB.update(bodyB.transform.get());\r\n }\r\n }\r\n }\r\n solveVelocity(contact) {\r\n var _a, _b;\r\n if (contact.isCanceled()) {\r\n return;\r\n }\r\n const colliderA = contact.colliderA;\r\n const colliderB = contact.colliderB;\r\n const bodyA = (_a = colliderA.owner) === null || _a === void 0 ? void 0 : _a.get(BodyComponent);\r\n const bodyB = (_b = colliderB.owner) === null || _b === void 0 ? void 0 : _b.get(BodyComponent);\r\n if (bodyA && bodyB) {\r\n if (bodyA.collisionType === CollisionType.Passive || bodyB.collisionType === CollisionType.Passive) {\r\n return;\r\n }\r\n const normal = contact.normal;\r\n const opposite = normal.negate();\r\n if (bodyA.collisionType === CollisionType.Active) {\r\n // only adjust velocity if the contact normal is opposite to the current velocity\r\n // this avoids catching edges on a platform when sliding off\r\n if (bodyA.vel.normalize().dot(opposite) < 0) {\r\n // Cancel out velocity opposite direction of collision normal\r\n const velAdj = normal.scale(normal.dot(bodyA.vel.negate()));\r\n bodyA.vel = bodyA.vel.add(velAdj);\r\n }\r\n }\r\n if (bodyB.collisionType === CollisionType.Active) {\r\n // only adjust velocity if the contact normal is opposite to the current velocity\r\n // this avoids catching edges on a platform\r\n if (bodyB.vel.normalize().dot(normal) < 0) {\r\n const velAdj = opposite.scale(opposite.dot(bodyB.vel.negate()));\r\n bodyB.vel = bodyB.vel.add(velAdj);\r\n }\r\n }\r\n }\r\n }\r\n}\r\n\n;// CONCATENATED MODULE: ./Collision/Solver/ContactConstraintPoint.ts\n\r\n\r\n/**\r\n * Holds information about contact points, meant to be reused over multiple frames of contact\r\n */\r\nclass ContactConstraintPoint {\r\n constructor(point, local, contact) {\r\n this.point = point;\r\n this.local = local;\r\n this.contact = contact;\r\n /**\r\n * Impulse accumulated over time in normal direction\r\n */\r\n this.normalImpulse = 0;\r\n /**\r\n * Impulse accumulated over time in the tangent direction\r\n */\r\n this.tangentImpulse = 0;\r\n /**\r\n * Effective mass seen in the normal direction\r\n */\r\n this.normalMass = 0;\r\n /**\r\n * Effective mass seen in the tangent direction\r\n */\r\n this.tangentMass = 0;\r\n /**\r\n * Direction from center of mass of bodyA to contact point\r\n */\r\n this.aToContact = new Vector(0, 0);\r\n /**\r\n * Direction from center of mass of bodyB to contact point\r\n */\r\n this.bToContact = new Vector(0, 0);\r\n /**\r\n * Original contact velocity combined with bounciness\r\n */\r\n this.originalVelocityAndRestitution = 0;\r\n this.update();\r\n }\r\n /**\r\n * Updates the contact information\r\n */\r\n update() {\r\n var _a, _b;\r\n const bodyA = (_a = this.contact.colliderA.owner) === null || _a === void 0 ? void 0 : _a.get(BodyComponent);\r\n const bodyB = (_b = this.contact.colliderB.owner) === null || _b === void 0 ? void 0 : _b.get(BodyComponent);\r\n if (bodyA && bodyB) {\r\n const normal = this.contact.normal;\r\n const tangent = this.contact.tangent;\r\n this.aToContact = this.point.sub(bodyA.globalPos);\r\n this.bToContact = this.point.sub(bodyB.globalPos);\r\n const aToContactNormal = this.aToContact.cross(normal);\r\n const bToContactNormal = this.bToContact.cross(normal);\r\n this.normalMass =\r\n bodyA.inverseMass +\r\n bodyB.inverseMass +\r\n bodyA.inverseInertia * aToContactNormal * aToContactNormal +\r\n bodyB.inverseInertia * bToContactNormal * bToContactNormal;\r\n const aToContactTangent = this.aToContact.cross(tangent);\r\n const bToContactTangent = this.bToContact.cross(tangent);\r\n this.tangentMass =\r\n bodyA.inverseMass +\r\n bodyB.inverseMass +\r\n bodyA.inverseInertia * aToContactTangent * aToContactTangent +\r\n bodyB.inverseInertia * bToContactTangent * bToContactTangent;\r\n }\r\n return this;\r\n }\r\n /**\r\n * Returns the relative velocity between bodyA and bodyB\r\n */\r\n getRelativeVelocity() {\r\n var _a, _b;\r\n const bodyA = (_a = this.contact.colliderA.owner) === null || _a === void 0 ? void 0 : _a.get(BodyComponent);\r\n const bodyB = (_b = this.contact.colliderB.owner) === null || _b === void 0 ? void 0 : _b.get(BodyComponent);\r\n if (bodyA && bodyB) {\r\n // Relative velocity in linear terms\r\n // Angular to linear velocity formula -> omega = velocity/radius so omega x radius = velocity\r\n const velA = bodyA.vel.add(Vector.cross(bodyA.angularVelocity, this.aToContact));\r\n const velB = bodyB.vel.add(Vector.cross(bodyB.angularVelocity, this.bToContact));\r\n return velB.sub(velA);\r\n }\r\n return Vector.Zero;\r\n }\r\n}\r\n\n;// CONCATENATED MODULE: ./Collision/Solver/RealisticSolver.ts\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\nclass RealisticSolver {\r\n constructor() {\r\n this.lastFrameContacts = new Map();\r\n // map contact id to contact points\r\n this.idToContactConstraint = new Map();\r\n }\r\n getContactConstraints(id) {\r\n var _a;\r\n return (_a = this.idToContactConstraint.get(id)) !== null && _a !== void 0 ? _a : [];\r\n }\r\n solve(contacts) {\r\n // Events and init\r\n this.preSolve(contacts);\r\n // Remove any canceled contacts\r\n contacts = contacts.filter(c => !c.isCanceled());\r\n // Solve velocity first\r\n this.solveVelocity(contacts);\r\n // Solve position last because non-overlap is the most important\r\n this.solvePosition(contacts);\r\n // Events and any contact house-keeping the solver needs\r\n this.postSolve(contacts);\r\n return contacts;\r\n }\r\n preSolve(contacts) {\r\n var _a, _b, _c;\r\n const epsilon = .0001;\r\n for (const contact of contacts) {\r\n if (Math.abs(contact.mtv.x) < epsilon && Math.abs(contact.mtv.y) < epsilon) {\r\n // Cancel near 0 mtv collisions\r\n contact.cancel();\r\n continue;\r\n }\r\n // Publish collision events on both participants\r\n const side = Side.fromDirection(contact.mtv);\r\n contact.colliderA.events.emit('precollision', new PreCollisionEvent(contact.colliderA, contact.colliderB, side, contact.mtv));\r\n contact.colliderA.events.emit('beforecollisionresolve', new CollisionPreSolveEvent(contact.colliderA, contact.colliderB, side, contact.mtv, contact));\r\n contact.colliderB.events.emit('precollision', new PreCollisionEvent(contact.colliderB, contact.colliderA, Side.getOpposite(side), contact.mtv.negate()));\r\n contact.colliderB.events.emit('beforecollisionresolve', new CollisionPreSolveEvent(contact.colliderB, contact.colliderA, Side.getOpposite(side), contact.mtv.negate(), contact));\r\n // Match awake state for sleeping\r\n contact.matchAwake();\r\n }\r\n // Keep track of contacts that done\r\n const finishedContactIds = Array.from(this.idToContactConstraint.keys());\r\n for (const contact of contacts) {\r\n // Remove all current contacts that are not done\r\n const index = finishedContactIds.indexOf(contact.id);\r\n if (index > -1) {\r\n finishedContactIds.splice(index, 1);\r\n }\r\n const contactPoints = (_a = this.idToContactConstraint.get(contact.id)) !== null && _a !== void 0 ? _a : [];\r\n let pointIndex = 0;\r\n const bodyA = contact.colliderA.owner.get(BodyComponent);\r\n const bodyB = contact.colliderB.owner.get(BodyComponent);\r\n if (bodyA && bodyB) {\r\n for (const point of contact.points) {\r\n const normal = contact.normal;\r\n const tangent = contact.tangent;\r\n const aToContact = point.sub(bodyA.globalPos);\r\n const bToContact = point.sub(bodyB.globalPos);\r\n const aToContactNormal = aToContact.cross(normal);\r\n const bToContactNormal = bToContact.cross(normal);\r\n const normalMass = bodyA.inverseMass +\r\n bodyB.inverseMass +\r\n bodyA.inverseInertia * aToContactNormal * aToContactNormal +\r\n bodyB.inverseInertia * bToContactNormal * bToContactNormal;\r\n const aToContactTangent = aToContact.cross(tangent);\r\n const bToContactTangent = bToContact.cross(tangent);\r\n const tangentMass = bodyA.inverseMass +\r\n bodyB.inverseMass +\r\n bodyA.inverseInertia * aToContactTangent * aToContactTangent +\r\n bodyB.inverseInertia * bToContactTangent * bToContactTangent;\r\n // Preserve normal/tangent impulse by re-using the contact point if it's close\r\n if (contactPoints[pointIndex] && ((_c = (_b = contactPoints[pointIndex]) === null || _b === void 0 ? void 0 : _b.point) === null || _c === void 0 ? void 0 : _c.squareDistance(point)) < 4) {\r\n contactPoints[pointIndex].point = point;\r\n contactPoints[pointIndex].local = contact.localPoints[pointIndex];\r\n }\r\n else {\r\n // new contact if it's not close or doesn't exist\r\n contactPoints[pointIndex] = new ContactConstraintPoint(point, contact.localPoints[pointIndex], contact);\r\n }\r\n // Update contact point calculations\r\n contactPoints[pointIndex].aToContact = aToContact;\r\n contactPoints[pointIndex].bToContact = bToContact;\r\n contactPoints[pointIndex].normalMass = 1.0 / normalMass;\r\n contactPoints[pointIndex].tangentMass = 1.0 / tangentMass;\r\n // Calculate relative velocity before solving to accurately do restitution\r\n const restitution = bodyA.bounciness > bodyB.bounciness ? bodyA.bounciness : bodyB.bounciness;\r\n const relativeVelocity = contact.normal.dot(contactPoints[pointIndex].getRelativeVelocity());\r\n contactPoints[pointIndex].originalVelocityAndRestitution = 0;\r\n if (relativeVelocity < -0.1) { // TODO what's a good threshold here?\r\n contactPoints[pointIndex].originalVelocityAndRestitution = -restitution * relativeVelocity;\r\n }\r\n pointIndex++;\r\n }\r\n }\r\n this.idToContactConstraint.set(contact.id, contactPoints);\r\n }\r\n // Clean up any contacts that did not occur last frame\r\n for (const id of finishedContactIds) {\r\n this.idToContactConstraint.delete(id);\r\n }\r\n // Warm contacts with accumulated impulse\r\n // Useful for tall stacks\r\n if (Physics.warmStart) {\r\n this.warmStart(contacts);\r\n }\r\n else {\r\n for (const contact of contacts) {\r\n const contactPoints = this.getContactConstraints(contact.id);\r\n for (const point of contactPoints) {\r\n point.normalImpulse = 0;\r\n point.tangentImpulse = 0;\r\n }\r\n }\r\n }\r\n }\r\n postSolve(contacts) {\r\n for (const contact of contacts) {\r\n const bodyA = contact.colliderA.owner.get(BodyComponent);\r\n const bodyB = contact.colliderB.owner.get(BodyComponent);\r\n if (bodyA && bodyB) {\r\n // Skip post solve for active+passive collisions\r\n if (bodyA.collisionType === CollisionType.Passive || bodyB.collisionType === CollisionType.Passive) {\r\n continue;\r\n }\r\n // Update motion values for sleeping\r\n bodyA.updateMotion();\r\n bodyB.updateMotion();\r\n }\r\n // Publish collision events on both participants\r\n const side = Side.fromDirection(contact.mtv);\r\n contact.colliderA.events.emit('postcollision', new PostCollisionEvent(contact.colliderA, contact.colliderB, side, contact.mtv));\r\n contact.colliderA.events.emit('aftercollisionresolve', new CollisionPostSolveEvent(contact.colliderA, contact.colliderB, side, contact.mtv, contact));\r\n contact.colliderB.events.emit('postcollision', new PostCollisionEvent(contact.colliderB, contact.colliderA, Side.getOpposite(side), contact.mtv.negate()));\r\n contact.colliderB.events.emit('aftercollisionresolve', new CollisionPostSolveEvent(contact.colliderB, contact.colliderA, Side.getOpposite(side), contact.mtv.negate(), contact));\r\n }\r\n // Store contacts\r\n this.lastFrameContacts.clear();\r\n for (const c of contacts) {\r\n this.lastFrameContacts.set(c.id, c);\r\n }\r\n }\r\n /**\r\n * Warm up body's based on previous frame contact points\r\n * @param contacts\r\n */\r\n warmStart(contacts) {\r\n var _a, _b, _c;\r\n for (const contact of contacts) {\r\n const bodyA = (_a = contact.colliderA.owner) === null || _a === void 0 ? void 0 : _a.get(BodyComponent);\r\n const bodyB = (_b = contact.colliderB.owner) === null || _b === void 0 ? void 0 : _b.get(BodyComponent);\r\n if (bodyA && bodyB) {\r\n const contactPoints = (_c = this.idToContactConstraint.get(contact.id)) !== null && _c !== void 0 ? _c : [];\r\n for (const point of contactPoints) {\r\n if (Physics.warmStart) {\r\n const normalImpulse = contact.normal.scale(point.normalImpulse);\r\n const tangentImpulse = contact.tangent.scale(point.tangentImpulse);\r\n const impulse = normalImpulse.add(tangentImpulse);\r\n bodyA.applyImpulse(point.point, impulse.negate());\r\n bodyB.applyImpulse(point.point, impulse);\r\n }\r\n else {\r\n point.normalImpulse = 0;\r\n point.tangentImpulse = 0;\r\n }\r\n }\r\n }\r\n }\r\n }\r\n /**\r\n * Iteratively solve the position overlap constraint\r\n * @param contacts\r\n */\r\n solvePosition(contacts) {\r\n var _a, _b, _c;\r\n for (let i = 0; i < Physics.positionIterations; i++) {\r\n for (const contact of contacts) {\r\n const bodyA = (_a = contact.colliderA.owner) === null || _a === void 0 ? void 0 : _a.get(BodyComponent);\r\n const bodyB = (_b = contact.colliderB.owner) === null || _b === void 0 ? void 0 : _b.get(BodyComponent);\r\n if (bodyA && bodyB) {\r\n // Skip solving active+passive\r\n if (bodyA.collisionType === CollisionType.Passive || bodyB.collisionType === CollisionType.Passive) {\r\n continue;\r\n }\r\n const constraints = (_c = this.idToContactConstraint.get(contact.id)) !== null && _c !== void 0 ? _c : [];\r\n for (const point of constraints) {\r\n const normal = contact.normal;\r\n const separation = CollisionJumpTable.FindContactSeparation(contact, point.local);\r\n const steeringConstant = Physics.steeringFactor; //0.2;\r\n const maxCorrection = -5;\r\n const slop = Physics.slop; //1;\r\n // Clamp to avoid over-correction\r\n // Remember that we are shooting for 0 overlap in the end\r\n const steeringForce = clamp(steeringConstant * (separation + slop), maxCorrection, 0);\r\n const impulse = normal.scale(-steeringForce * point.normalMass);\r\n // This is a pseudo impulse, meaning we aren't doing a real impulse calculation\r\n // We adjust position and rotation instead of doing the velocity\r\n if (bodyA.collisionType === CollisionType.Active) {\r\n // TODO make applyPseudoImpulse function?\r\n const impulseForce = impulse.negate().scale(bodyA.inverseMass);\r\n if (bodyA.limitDegreeOfFreedom.includes(DegreeOfFreedom.X)) {\r\n impulseForce.x = 0;\r\n }\r\n if (bodyA.limitDegreeOfFreedom.includes(DegreeOfFreedom.Y)) {\r\n impulseForce.y = 0;\r\n }\r\n bodyA.globalPos = bodyA.globalPos.add(impulseForce);\r\n if (!bodyA.limitDegreeOfFreedom.includes(DegreeOfFreedom.Rotation)) {\r\n bodyA.rotation -= point.aToContact.cross(impulse) * bodyA.inverseInertia;\r\n }\r\n }\r\n if (bodyB.collisionType === CollisionType.Active) {\r\n const impulseForce = impulse.scale(bodyB.inverseMass);\r\n if (bodyB.limitDegreeOfFreedom.includes(DegreeOfFreedom.X)) {\r\n impulseForce.x = 0;\r\n }\r\n if (bodyB.limitDegreeOfFreedom.includes(DegreeOfFreedom.Y)) {\r\n impulseForce.y = 0;\r\n }\r\n bodyB.globalPos = bodyB.globalPos.add(impulseForce);\r\n if (!bodyB.limitDegreeOfFreedom.includes(DegreeOfFreedom.Rotation)) {\r\n bodyB.rotation += point.bToContact.cross(impulse) * bodyB.inverseInertia;\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }\r\n solveVelocity(contacts) {\r\n var _a, _b, _c;\r\n for (let i = 0; i < Physics.velocityIterations; i++) {\r\n for (const contact of contacts) {\r\n const bodyA = (_a = contact.colliderA.owner) === null || _a === void 0 ? void 0 : _a.get(BodyComponent);\r\n const bodyB = (_b = contact.colliderB.owner) === null || _b === void 0 ? void 0 : _b.get(BodyComponent);\r\n if (bodyA && bodyB) {\r\n // Skip solving active+passive\r\n if (bodyA.collisionType === CollisionType.Passive || bodyB.collisionType === CollisionType.Passive) {\r\n continue;\r\n }\r\n const friction = Math.min(bodyA.friction, bodyB.friction);\r\n const constraints = (_c = this.idToContactConstraint.get(contact.id)) !== null && _c !== void 0 ? _c : [];\r\n // Friction constraint\r\n for (const point of constraints) {\r\n const relativeVelocity = point.getRelativeVelocity();\r\n // Negate velocity in tangent direction to simulate friction\r\n const tangentVelocity = -relativeVelocity.dot(contact.tangent);\r\n let impulseDelta = tangentVelocity * point.tangentMass;\r\n // Clamping based in Erin Catto's GDC 2006 talk\r\n // Correct clamping https://github.com/erincatto/box2d-lite/blob/master/docs/GDC2006_Catto_Erin_PhysicsTutorial.pdf\r\n // Accumulated fiction impulse is always between -uMaxFriction < dT < uMaxFriction\r\n // But deltas can vary\r\n const maxFriction = friction * point.normalImpulse;\r\n const newImpulse = clamp(point.tangentImpulse + impulseDelta, -maxFriction, maxFriction);\r\n impulseDelta = newImpulse - point.tangentImpulse;\r\n point.tangentImpulse = newImpulse;\r\n const impulse = contact.tangent.scale(impulseDelta);\r\n bodyA.applyImpulse(point.point, impulse.negate());\r\n bodyB.applyImpulse(point.point, impulse);\r\n }\r\n // Bounce constraint\r\n for (const point of constraints) {\r\n // Need to recalc relative velocity because the previous step could have changed vel\r\n const relativeVelocity = point.getRelativeVelocity();\r\n // Compute impulse in normal direction\r\n const normalVelocity = relativeVelocity.dot(contact.normal);\r\n // Per Erin it is a mistake to apply the restitution inside the iteration\r\n // From Erin Catto's Box2D we keep original contact velocity and adjust by small impulses\r\n let impulseDelta = -point.normalMass * (normalVelocity - point.originalVelocityAndRestitution);\r\n // Clamping based in Erin Catto's GDC 2014 talk\r\n // Accumulated impulse stored in the contact is always positive (dV > 0)\r\n // But deltas can be negative\r\n const newImpulse = Math.max(point.normalImpulse + impulseDelta, 0);\r\n impulseDelta = newImpulse - point.normalImpulse;\r\n point.normalImpulse = newImpulse;\r\n const impulse = contact.normal.scale(impulseDelta);\r\n bodyA.applyImpulse(point.point, impulse.negate());\r\n bodyB.applyImpulse(point.point, impulse);\r\n }\r\n }\r\n }\r\n }\r\n }\r\n}\r\n\n;// CONCATENATED MODULE: ./Collision/CollisionSystem.ts\n\r\n\r\n\r\n\r\n\r\n\r\n\r\nclass CollisionSystem extends System {\r\n constructor(physics) {\r\n super();\r\n this.types = ['ex.transform', 'ex.motion', 'ex.collider'];\r\n this.systemType = SystemType.Update;\r\n this.priority = -1;\r\n this._realisticSolver = new RealisticSolver();\r\n this._arcadeSolver = new ArcadeSolver();\r\n this._lastFrameContacts = new Map();\r\n this._currentFrameContacts = new Map();\r\n this._processor = physics.collisionProcessor;\r\n this._trackCollider = (c) => this._processor.track(c);\r\n this._untrackCollider = (c) => this._processor.untrack(c);\r\n }\r\n notify(message) {\r\n if (isAddedSystemEntity(message)) {\r\n const colliderComponent = message.data.get(ColliderComponent);\r\n colliderComponent.$colliderAdded.subscribe(this._trackCollider);\r\n colliderComponent.$colliderRemoved.subscribe(this._untrackCollider);\r\n const collider = colliderComponent.get();\r\n if (collider) {\r\n this._processor.track(collider);\r\n }\r\n }\r\n else {\r\n const colliderComponent = message.data.get(ColliderComponent);\r\n const collider = colliderComponent.get();\r\n if (colliderComponent && collider) {\r\n this._processor.untrack(collider);\r\n }\r\n }\r\n }\r\n initialize(scene) {\r\n this._engine = scene.engine;\r\n }\r\n update(entities, elapsedMs) {\r\n var _a, _b, _c, _d;\r\n if (!Physics.enabled) {\r\n return;\r\n }\r\n // Collect up all the colliders and update them\r\n let colliders = [];\r\n for (const entity of entities) {\r\n const colliderComp = entity.get(ColliderComponent);\r\n const collider = colliderComp === null || colliderComp === void 0 ? void 0 : colliderComp.get();\r\n if (colliderComp && ((_a = colliderComp.owner) === null || _a === void 0 ? void 0 : _a.active) && collider) {\r\n colliderComp.update();\r\n if (collider instanceof CompositeCollider) {\r\n const compositeColliders = collider.getColliders();\r\n colliders = colliders.concat(compositeColliders);\r\n }\r\n else {\r\n colliders.push(collider);\r\n }\r\n }\r\n }\r\n // Update the spatial partitioning data structures\r\n // TODO if collider invalid it will break the processor\r\n // TODO rename \"update\" to something more specific\r\n this._processor.update(colliders);\r\n // Run broadphase on all colliders and locates potential collisions\r\n const pairs = this._processor.broadphase(colliders, elapsedMs);\r\n this._currentFrameContacts.clear();\r\n // Given possible pairs find actual contacts\r\n let contacts = this._processor.narrowphase(pairs, (_d = (_c = (_b = this._engine) === null || _b === void 0 ? void 0 : _b.debug) === null || _c === void 0 ? void 0 : _c.stats) === null || _d === void 0 ? void 0 : _d.currFrame);\r\n const solver = this.getSolver();\r\n // Solve, this resolves the position/velocity so entities aren't overlapping\r\n contacts = solver.solve(contacts);\r\n // Record contacts for start/end\r\n for (const contact of contacts) {\r\n // Process composite ids, things with the same composite id are treated as the same collider for start/end\r\n const index = contact.id.indexOf('|');\r\n if (index > 0) {\r\n const compositeId = contact.id.substring(index + 1);\r\n this._currentFrameContacts.set(compositeId, contact);\r\n }\r\n else {\r\n this._currentFrameContacts.set(contact.id, contact);\r\n }\r\n }\r\n // Emit contact start/end events\r\n this.runContactStartEnd();\r\n // reset the last frame cache\r\n this._lastFrameContacts.clear();\r\n // Keep track of collisions contacts that have started or ended\r\n this._lastFrameContacts = new Map(this._currentFrameContacts);\r\n }\r\n getSolver() {\r\n return Physics.collisionResolutionStrategy === CollisionResolutionStrategy.Realistic ? this._realisticSolver : this._arcadeSolver;\r\n }\r\n debug(ex) {\r\n this._processor.debug(ex);\r\n }\r\n runContactStartEnd() {\r\n // Composite collider collisions may have a duplicate id because we want to treat those as a singular start/end\r\n for (const [id, c] of this._currentFrameContacts) {\r\n // find all new contacts\r\n if (!this._lastFrameContacts.has(id)) {\r\n const colliderA = c.colliderA;\r\n const colliderB = c.colliderB;\r\n colliderA.events.emit('collisionstart', new CollisionStartEvent(colliderA, colliderB, c));\r\n colliderA.events.emit('contactstart', new ContactStartEvent(colliderA, colliderB, c));\r\n colliderB.events.emit('collisionstart', new CollisionStartEvent(colliderB, colliderA, c));\r\n colliderB.events.emit('contactstart', new ContactStartEvent(colliderB, colliderA, c));\r\n }\r\n }\r\n // find all contacts that have ceased\r\n for (const [id, c] of this._lastFrameContacts) {\r\n if (!this._currentFrameContacts.has(id)) {\r\n const colliderA = c.colliderA;\r\n const colliderB = c.colliderB;\r\n colliderA.events.emit('collisionend', new CollisionEndEvent(colliderA, colliderB));\r\n colliderA.events.emit('contactend', new ContactEndEvent(colliderA, colliderB));\r\n colliderB.events.emit('collisionend', new CollisionEndEvent(colliderB, colliderA));\r\n colliderB.events.emit('contactend', new ContactEndEvent(colliderB, colliderA));\r\n }\r\n }\r\n }\r\n}\r\n\n;// CONCATENATED MODULE: ./Graphics/Animation.ts\n\r\n\r\n\r\n\r\nvar AnimationDirection;\r\n(function (AnimationDirection) {\r\n /**\r\n * Animation is playing forwards\r\n */\r\n AnimationDirection[\"Forward\"] = \"forward\";\r\n /**\r\n * Animation is playing backwards\r\n */\r\n AnimationDirection[\"Backward\"] = \"backward\";\r\n})(AnimationDirection || (AnimationDirection = {}));\r\nvar AnimationStrategy;\r\n(function (AnimationStrategy) {\r\n /**\r\n * Animation ends without displaying anything\r\n */\r\n AnimationStrategy[\"End\"] = \"end\";\r\n /**\r\n * Animation loops to the first frame after the last frame\r\n */\r\n AnimationStrategy[\"Loop\"] = \"loop\";\r\n /**\r\n * Animation plays to the last frame, then backwards to the first frame, then repeats\r\n */\r\n AnimationStrategy[\"PingPong\"] = \"pingpong\";\r\n /**\r\n * Animation ends stopping on the last frame\r\n */\r\n AnimationStrategy[\"Freeze\"] = \"freeze\";\r\n})(AnimationStrategy || (AnimationStrategy = {}));\r\nconst AnimationEvents = {\r\n Frame: 'frame',\r\n Loop: 'loop',\r\n Ended: 'ended'\r\n};\r\n/**\r\n * Create an Animation given a list of [[Frame|frames]] in [[AnimationOptions]]\r\n *\r\n * To create an Animation from a [[SpriteSheet]], use [[Animation.fromSpriteSheet]]\r\n */\r\nclass Animation extends Graphic {\r\n constructor(options) {\r\n var _a, _b;\r\n super(options);\r\n this.events = new EventEmitter();\r\n this.frames = [];\r\n this.strategy = AnimationStrategy.Loop;\r\n this.frameDuration = 100;\r\n this.timeScale = 1;\r\n this._idempotencyToken = -1;\r\n this._firstTick = true;\r\n this._currentFrame = 0;\r\n this._timeLeftInFrame = 0;\r\n this._pingPongDirection = 1;\r\n this._done = false;\r\n this._playing = true;\r\n this._reversed = false;\r\n this.frames = options.frames;\r\n this.strategy = (_a = options.strategy) !== null && _a !== void 0 ? _a : this.strategy;\r\n this.frameDuration = options.totalDuration ? options.totalDuration / this.frames.length : (_b = options.frameDuration) !== null && _b !== void 0 ? _b : this.frameDuration;\r\n if (options.reverse) {\r\n this.reverse();\r\n }\r\n this.goToFrame(0);\r\n }\r\n clone() {\r\n return new Animation({\r\n frames: this.frames.map((f) => ({ ...f })),\r\n frameDuration: this.frameDuration,\r\n reverse: this._reversed,\r\n strategy: this.strategy,\r\n ...this.cloneGraphicOptions()\r\n });\r\n }\r\n get width() {\r\n const maybeFrame = this.currentFrame;\r\n if (maybeFrame) {\r\n return Math.abs(maybeFrame.graphic.width * this.scale.x);\r\n }\r\n return 0;\r\n }\r\n get height() {\r\n const maybeFrame = this.currentFrame;\r\n if (maybeFrame) {\r\n return Math.abs(maybeFrame.graphic.height * this.scale.y);\r\n }\r\n return 0;\r\n }\r\n /**\r\n * Create an Animation from a [[SpriteSheet]], a list of indices into the sprite sheet, a duration per frame\r\n * and optional [[AnimationStrategy]]\r\n *\r\n * Example:\r\n * ```typescript\r\n * const spriteSheet = SpriteSheet.fromImageSource({...});\r\n *\r\n * const anim = Animation.fromSpriteSheet(spriteSheet, range(0, 5), 200, AnimationStrategy.Loop);\r\n * ```\r\n *\r\n * @param spriteSheet\r\n * @param frameIndices\r\n * @param durationPerFrameMs\r\n * @param strategy\r\n */\r\n static fromSpriteSheet(spriteSheet, frameIndices, durationPerFrameMs, strategy = AnimationStrategy.Loop) {\r\n const maxIndex = spriteSheet.sprites.length - 1;\r\n const invalidIndices = frameIndices.filter((index) => index < 0 || index > maxIndex);\r\n if (invalidIndices.length) {\r\n Animation._LOGGER.warn(`Indices into SpriteSheet were provided that don\\'t exist: ${invalidIndices.join(',')} no frame will be shown`);\r\n }\r\n return new Animation({\r\n frames: spriteSheet.sprites\r\n .filter((_, index) => frameIndices.indexOf(index) > -1)\r\n .map((f) => ({\r\n graphic: f,\r\n duration: durationPerFrameMs\r\n })),\r\n strategy: strategy\r\n });\r\n }\r\n /**\r\n * Create an [[Animation]] from a [[SpriteSheet]] given a list of coordinates\r\n *\r\n * Example:\r\n * ```typescript\r\n * const spriteSheet = SpriteSheet.fromImageSource({...});\r\n *\r\n * const anim = Animation.fromSpriteSheetCoordinates({\r\n * spriteSheet,\r\n * frameCoordinates: [\r\n * {x: 0, y: 5, duration: 100},\r\n * {x: 1, y: 5, duration: 200},\r\n * {x: 2, y: 5, duration: 100},\r\n * {x: 3, y: 5, duration: 500}\r\n * ],\r\n * strategy: AnimationStrategy.PingPong\r\n * });\r\n * ```\r\n *\r\n * @param options\r\n * @returns Animation\r\n */\r\n static fromSpriteSheetCoordinates(options) {\r\n const { spriteSheet, frameCoordinates, durationPerFrameMs, strategy, reverse } = options;\r\n const defaultDuration = durationPerFrameMs !== null && durationPerFrameMs !== void 0 ? durationPerFrameMs : 100;\r\n const frames = [];\r\n for (const coord of frameCoordinates) {\r\n const { x, y, duration } = coord;\r\n const sprite = spriteSheet.getSprite(x, y);\r\n if (sprite) {\r\n frames.push({\r\n graphic: sprite,\r\n duration: duration !== null && duration !== void 0 ? duration : defaultDuration\r\n });\r\n }\r\n else {\r\n Animation._LOGGER.warn(`Skipping frame! SpriteSheet does not have coordinate (${x}, ${y}), please check your SpriteSheet to confirm that sprite exists`);\r\n }\r\n }\r\n return new Animation({\r\n frames,\r\n strategy,\r\n reverse\r\n });\r\n }\r\n /**\r\n * Returns the current Frame of the animation\r\n *\r\n * Use [[Animation.currentFrameIndex]] to get the frame number and\r\n * [[Animation.goToFrame]] to set the current frame index\r\n */\r\n get currentFrame() {\r\n if (this._currentFrame >= 0 && this._currentFrame < this.frames.length) {\r\n return this.frames[this._currentFrame];\r\n }\r\n return null;\r\n }\r\n /**\r\n * Returns the current frame index of the animation\r\n *\r\n * Use [[Animation.currentFrame]] to grab the current [[Frame]] object\r\n */\r\n get currentFrameIndex() {\r\n return this._currentFrame;\r\n }\r\n /**\r\n * Returns `true` if the animation is playing\r\n */\r\n get isPlaying() {\r\n return this._playing;\r\n }\r\n /**\r\n * Reverses the play direction of the Animation, this preserves the current frame\r\n */\r\n reverse() {\r\n // Don't mutate with the original frame list, create a copy\r\n this.frames = this.frames.slice().reverse();\r\n this._reversed = !this._reversed;\r\n }\r\n /**\r\n * Returns the current play direction of the animation\r\n */\r\n get direction() {\r\n // Keep logically consistent with ping-pong direction\r\n // If ping-pong is forward = 1 and reversed is true then we are logically reversed\r\n const reversed = (this._reversed && this._pingPongDirection === 1) ? true : false;\r\n return reversed ? AnimationDirection.Backward : AnimationDirection.Forward;\r\n }\r\n /**\r\n * Plays or resumes the animation from the current frame\r\n */\r\n play() {\r\n this._playing = true;\r\n }\r\n /**\r\n * Pauses the animation on the current frame\r\n */\r\n pause() {\r\n this._playing = false;\r\n this._firstTick = true; // firstTick must be set to emit the proper frame event\r\n }\r\n /**\r\n * Reset the animation back to the beginning, including if the animation were done\r\n */\r\n reset() {\r\n this._done = false;\r\n this._firstTick = true;\r\n this._currentFrame = 0;\r\n }\r\n /**\r\n * Returns `true` if the animation can end\r\n */\r\n get canFinish() {\r\n switch (this.strategy) {\r\n case AnimationStrategy.End:\r\n case AnimationStrategy.Freeze: {\r\n return true;\r\n }\r\n default: {\r\n return false;\r\n }\r\n }\r\n }\r\n /**\r\n * Returns `true` if the animation is done, for looping type animations\r\n * `ex.AnimationStrategy.PingPong` and `ex.AnimationStrategy.Loop` this will always return `false`\r\n *\r\n * See the `ex.Animation.canFinish()` method to know if an animation type can end\r\n */\r\n get done() {\r\n return this._done;\r\n }\r\n /**\r\n * Jump the animation immediately to a specific frame if it exists\r\n * @param frameNumber\r\n */\r\n goToFrame(frameNumber) {\r\n this._currentFrame = frameNumber;\r\n this._timeLeftInFrame = this.frameDuration;\r\n const maybeFrame = this.frames[this._currentFrame];\r\n if (maybeFrame && !this._done) {\r\n this._timeLeftInFrame = (maybeFrame === null || maybeFrame === void 0 ? void 0 : maybeFrame.duration) || this.frameDuration;\r\n this.events.emit('frame', { ...maybeFrame, frameIndex: this.currentFrameIndex });\r\n }\r\n }\r\n _nextFrame() {\r\n const currentFrame = this._currentFrame;\r\n if (this._done) {\r\n return currentFrame;\r\n }\r\n let next = -1;\r\n switch (this.strategy) {\r\n case AnimationStrategy.Loop: {\r\n next = (currentFrame + 1) % this.frames.length;\r\n if (next === 0) {\r\n this.events.emit('loop', this);\r\n }\r\n break;\r\n }\r\n case AnimationStrategy.End: {\r\n next = currentFrame + 1;\r\n if (next >= this.frames.length) {\r\n this._done = true;\r\n this._currentFrame = this.frames.length;\r\n this.events.emit('end', this);\r\n }\r\n break;\r\n }\r\n case AnimationStrategy.Freeze: {\r\n next = clamp(currentFrame + 1, 0, this.frames.length - 1);\r\n if (next >= this.frames.length - 1) {\r\n this._done = true;\r\n this.events.emit('end', this);\r\n }\r\n break;\r\n }\r\n case AnimationStrategy.PingPong: {\r\n if (currentFrame + this._pingPongDirection >= this.frames.length) {\r\n this._pingPongDirection = -1;\r\n this.events.emit('loop', this);\r\n }\r\n if (currentFrame + this._pingPongDirection < 0) {\r\n this._pingPongDirection = 1;\r\n this.events.emit('loop', this);\r\n }\r\n next = currentFrame + (this._pingPongDirection % this.frames.length);\r\n break;\r\n }\r\n }\r\n return next;\r\n }\r\n /**\r\n * Called internally by Excalibur to update the state of the animation potential update the current frame\r\n * @param elapsedMilliseconds Milliseconds elapsed\r\n * @param idempotencyToken Prevents double ticking in a frame by passing a unique token to the frame\r\n */\r\n tick(elapsedMilliseconds, idempotencyToken = 0) {\r\n if (this._idempotencyToken === idempotencyToken) {\r\n return;\r\n }\r\n this._idempotencyToken = idempotencyToken;\r\n if (!this._playing) {\r\n return;\r\n }\r\n // if it's the first frame emit frame event\r\n if (this._firstTick) {\r\n this._firstTick = false;\r\n this.events.emit('frame', { ...this.currentFrame, frameIndex: this.currentFrameIndex });\r\n }\r\n this._timeLeftInFrame -= elapsedMilliseconds * this.timeScale;\r\n if (this._timeLeftInFrame <= 0) {\r\n this.goToFrame(this._nextFrame());\r\n }\r\n }\r\n _drawImage(ctx, x, y) {\r\n if (this.currentFrame) {\r\n this.currentFrame.graphic.draw(ctx, x, y);\r\n }\r\n }\r\n}\r\nAnimation._LOGGER = Logger.getInstance();\r\n\n;// CONCATENATED MODULE: ./Graphics/GraphicsGroup.ts\n\r\n\r\n\r\nclass GraphicsGroup extends Graphic {\r\n constructor(options) {\r\n super(options);\r\n this.members = [];\r\n this.members = options.members;\r\n this._updateDimensions();\r\n }\r\n clone() {\r\n return new GraphicsGroup({\r\n members: [...this.members],\r\n ...this.cloneGraphicOptions()\r\n });\r\n }\r\n _updateDimensions() {\r\n let bb = new BoundingBox();\r\n for (const { graphic, pos } of this.members) {\r\n bb = graphic.localBounds.translate(pos).combine(bb);\r\n }\r\n this.width = bb.width;\r\n this.height = bb.height;\r\n return bb;\r\n }\r\n get localBounds() {\r\n let bb = new BoundingBox();\r\n for (const { graphic, pos } of this.members) {\r\n bb = graphic.localBounds.translate(pos).combine(bb);\r\n }\r\n return bb;\r\n }\r\n _isAnimationOrGroup(graphic) {\r\n return graphic instanceof Animation || graphic instanceof GraphicsGroup;\r\n }\r\n tick(elapsedMilliseconds, idempotencyToken) {\r\n for (const member of this.members) {\r\n const maybeAnimation = member.graphic;\r\n if (this._isAnimationOrGroup(maybeAnimation)) {\r\n maybeAnimation.tick(elapsedMilliseconds, idempotencyToken);\r\n }\r\n }\r\n }\r\n reset() {\r\n for (const member of this.members) {\r\n const maybeAnimation = member.graphic;\r\n if (this._isAnimationOrGroup(maybeAnimation)) {\r\n maybeAnimation.reset();\r\n }\r\n }\r\n }\r\n _preDraw(ex, x, y) {\r\n this._updateDimensions();\r\n super._preDraw(ex, x, y);\r\n }\r\n _drawImage(ex, x, y) {\r\n for (const member of this.members) {\r\n ex.save();\r\n ex.translate(x, y);\r\n member.graphic.draw(ex, member.pos.x, member.pos.y);\r\n if (this.showDebug) {\r\n /* istanbul ignore next */\r\n ex.debug.drawRect(0, 0, this.width, this.height);\r\n }\r\n ex.restore();\r\n }\r\n }\r\n}\r\n\n;// CONCATENATED MODULE: ./Configurable.ts\n/**\r\n * Configurable helper extends base type and makes all properties available as option bag arguments\r\n * @internal\r\n * @param base\r\n */\r\nfunction Configurable(base) {\r\n return class extends base {\r\n assign(props) {\r\n //set the value of every property that was passed in,\r\n //if the constructor previously set this value, it will be overridden here\r\n for (const k in props) {\r\n // eslint-disable-next-line\r\n if (typeof this[k] !== 'function') {\r\n // eslint-disable-next-line\r\n this[k] = props[k];\r\n }\r\n }\r\n }\r\n constructor(...args) {\r\n super(...args);\r\n //get the number of arguments that aren't undefined. TS passes a value to all parameters\r\n //of whatever ctor is the implementation, so args.length doesn't work here.\r\n const size = args.filter(function (value) {\r\n return value !== undefined;\r\n }).length;\r\n if (size === 1 && args[0] && typeof args[0] === 'object' && !(args[0] instanceof Array)) {\r\n this.assign(args[0]);\r\n }\r\n }\r\n };\r\n}\r\n\n;// CONCATENATED MODULE: ./Particles.ts\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n/**\r\n * An enum that represents the types of emitter nozzles\r\n */\r\nvar EmitterType;\r\n(function (EmitterType) {\r\n /**\r\n * Constant for the circular emitter type\r\n */\r\n EmitterType[EmitterType[\"Circle\"] = 0] = \"Circle\";\r\n /**\r\n * Constant for the rectangular emitter type\r\n */\r\n EmitterType[EmitterType[\"Rectangle\"] = 1] = \"Rectangle\";\r\n})(EmitterType || (EmitterType = {}));\r\n/**\r\n * @hidden\r\n */\r\nclass ParticleImpl extends Entity {\r\n constructor(emitterOrConfig, life, opacity, beginColor, endColor, position, velocity, acceleration, startSize, endSize) {\r\n super();\r\n this.position = new Vector(0, 0);\r\n this.velocity = new Vector(0, 0);\r\n this.acceleration = new Vector(0, 0);\r\n this.particleRotationalVelocity = 0;\r\n this.currentRotation = 0;\r\n this.focus = null;\r\n this.focusAccel = 0;\r\n this.opacity = 1;\r\n this.beginColor = Color.White;\r\n this.endColor = Color.White;\r\n // Life is counted in ms\r\n this.life = 300;\r\n this.fadeFlag = false;\r\n // Color transitions\r\n this._rRate = 1;\r\n this._gRate = 1;\r\n this._bRate = 1;\r\n this._aRate = 0;\r\n this._currentColor = Color.White;\r\n this.emitter = null;\r\n this.particleSize = 5;\r\n this.particleSprite = null;\r\n this.sizeRate = 0;\r\n this.elapsedMultiplier = 0;\r\n this.visible = true;\r\n this.isOffscreen = false;\r\n let emitter = emitterOrConfig;\r\n if (emitter && !(emitterOrConfig instanceof ParticleEmitter)) {\r\n const config = emitterOrConfig;\r\n emitter = config.emitter;\r\n life = config.life;\r\n opacity = config.opacity;\r\n endColor = config.endColor;\r\n beginColor = config.beginColor;\r\n position = config.position;\r\n velocity = config.velocity;\r\n acceleration = config.acceleration;\r\n startSize = config.startSize;\r\n endSize = config.endSize;\r\n }\r\n this.emitter = emitter;\r\n this.life = life || this.life;\r\n this.opacity = opacity || this.opacity;\r\n this.endColor = endColor || this.endColor.clone();\r\n this.beginColor = beginColor || this.beginColor.clone();\r\n this._currentColor = this.beginColor.clone();\r\n if (this.emitter.particleTransform === ParticleTransform.Global) {\r\n const globalPos = this.emitter.transform.globalPos;\r\n this.position = (position || this.position).add(globalPos);\r\n this.velocity = (velocity || this.velocity).rotate(this.emitter.transform.globalRotation);\r\n }\r\n else {\r\n this.velocity = velocity || this.velocity;\r\n this.position = (position || this.position);\r\n }\r\n this.acceleration = acceleration || this.acceleration;\r\n this._rRate = (this.endColor.r - this.beginColor.r) / this.life;\r\n this._gRate = (this.endColor.g - this.beginColor.g) / this.life;\r\n this._bRate = (this.endColor.b - this.beginColor.b) / this.life;\r\n this._aRate = this.opacity / this.life;\r\n this.startSize = startSize || 0;\r\n this.endSize = endSize || 0;\r\n if (this.endSize > 0 && this.startSize > 0) {\r\n this.sizeRate = (this.endSize - this.startSize) / this.life;\r\n this.particleSize = this.startSize;\r\n }\r\n this.addComponent((this.transform = new TransformComponent()));\r\n this.addComponent((this.graphics = new GraphicsComponent()));\r\n this.transform.pos = this.position;\r\n this.transform.rotation = this.currentRotation;\r\n this.transform.scale = vec(1, 1); // TODO wut\r\n if (this.particleSprite) {\r\n this.graphics.opacity = this.opacity;\r\n this.graphics.use(this.particleSprite);\r\n }\r\n else {\r\n this.graphics.localBounds = BoundingBox.fromDimension(this.particleSize, this.particleSize, Vector.Half);\r\n this.graphics.onPostDraw = (ctx) => {\r\n ctx.save();\r\n this.graphics.opacity = this.opacity;\r\n const tmpColor = this._currentColor.clone();\r\n tmpColor.a = 1;\r\n ctx.debug.drawPoint(vec(0, 0), { color: tmpColor, size: this.particleSize });\r\n ctx.restore();\r\n };\r\n }\r\n }\r\n kill() {\r\n this.emitter.removeParticle(this);\r\n }\r\n update(_engine, delta) {\r\n this.life = this.life - delta;\r\n this.elapsedMultiplier = this.elapsedMultiplier + delta;\r\n if (this.life < 0) {\r\n this.kill();\r\n }\r\n if (this.fadeFlag) {\r\n this.opacity = clamp(this._aRate * this.life, 0.0001, 1);\r\n }\r\n if (this.startSize > 0 && this.endSize > 0) {\r\n this.particleSize = clamp(this.sizeRate * delta + this.particleSize, Math.min(this.startSize, this.endSize), Math.max(this.startSize, this.endSize));\r\n }\r\n this._currentColor.r = clamp(this._currentColor.r + this._rRate * delta, 0, 255);\r\n this._currentColor.g = clamp(this._currentColor.g + this._gRate * delta, 0, 255);\r\n this._currentColor.b = clamp(this._currentColor.b + this._bRate * delta, 0, 255);\r\n this._currentColor.a = clamp(this.opacity, 0.0001, 1);\r\n if (this.focus) {\r\n const accel = this.focus\r\n .sub(this.position)\r\n .normalize()\r\n .scale(this.focusAccel)\r\n .scale(delta / 1000);\r\n this.velocity = this.velocity.add(accel);\r\n }\r\n else {\r\n this.velocity = this.velocity.add(this.acceleration.scale(delta / 1000));\r\n }\r\n this.position = this.position.add(this.velocity.scale(delta / 1000));\r\n if (this.particleRotationalVelocity) {\r\n this.currentRotation = (this.currentRotation + (this.particleRotationalVelocity * delta) / 1000) % (2 * Math.PI);\r\n }\r\n this.transform.pos = this.position;\r\n this.transform.rotation = this.currentRotation;\r\n this.transform.scale = vec(1, 1); // todo wut\r\n this.graphics.opacity = this.opacity;\r\n }\r\n}\r\n/**\r\n * Particle is used in a [[ParticleEmitter]]\r\n */\r\nclass Particle extends Configurable(ParticleImpl) {\r\n constructor(emitterOrConfig, life, opacity, beginColor, endColor, position, velocity, acceleration, startSize, endSize) {\r\n super(emitterOrConfig, life, opacity, beginColor, endColor, position, velocity, acceleration, startSize, endSize);\r\n }\r\n}\r\nvar ParticleTransform;\r\n(function (ParticleTransform) {\r\n /**\r\n * [[ParticleTransform.Global]] is the default and emits particles as if\r\n * they were world space objects, useful for most effects.\r\n */\r\n ParticleTransform[\"Global\"] = \"global\";\r\n /**\r\n * [[ParticleTransform.Local]] particles are children of the emitter and move relative to the emitter\r\n * as they would in a parent/child actor relationship.\r\n */\r\n ParticleTransform[\"Local\"] = \"local\";\r\n})(ParticleTransform || (ParticleTransform = {}));\r\n/**\r\n * Using a particle emitter is a great way to create interesting effects\r\n * in your game, like smoke, fire, water, explosions, etc. `ParticleEmitter`\r\n * extend [[Actor]] allowing you to use all of the features that come with.\r\n */\r\nclass ParticleEmitter extends Actor {\r\n /**\r\n * Gets the opacity of each particle from 0 to 1.0\r\n */\r\n get opacity() {\r\n return super.graphics.opacity;\r\n }\r\n /**\r\n * Gets the opacity of each particle from 0 to 1.0\r\n */\r\n set opacity(opacity) {\r\n super.graphics.opacity = opacity;\r\n }\r\n /**\r\n * Gets or sets the sprite that a particle should use\r\n */\r\n get particleSprite() {\r\n return this._sprite;\r\n }\r\n set particleSprite(val) {\r\n if (val) {\r\n this._sprite = val;\r\n }\r\n }\r\n /**\r\n * @param config particle emitter options bag\r\n */\r\n constructor(config) {\r\n var _a, _b;\r\n super({ width: (_a = config.width) !== null && _a !== void 0 ? _a : 0, height: (_b = config.height) !== null && _b !== void 0 ? _b : 0 });\r\n this._particlesToEmit = 0;\r\n this.numParticles = 0;\r\n /**\r\n * Gets or sets the isEmitting flag\r\n */\r\n this.isEmitting = true;\r\n /**\r\n * Gets or sets the backing particle collection\r\n */\r\n this.particles = [];\r\n /**\r\n * Gets or sets the backing deadParticle collection\r\n */\r\n this.deadParticles = [];\r\n /**\r\n * Gets or sets the minimum particle velocity\r\n */\r\n this.minVel = 0;\r\n /**\r\n * Gets or sets the maximum particle velocity\r\n */\r\n this.maxVel = 0;\r\n /**\r\n * Gets or sets the acceleration vector for all particles\r\n */\r\n this.acceleration = new Vector(0, 0);\r\n /**\r\n * Gets or sets the minimum angle in radians\r\n */\r\n this.minAngle = 0;\r\n /**\r\n * Gets or sets the maximum angle in radians\r\n */\r\n this.maxAngle = 0;\r\n /**\r\n * Gets or sets the emission rate for particles (particles/sec)\r\n */\r\n this.emitRate = 1; //particles/sec\r\n /**\r\n * Gets or sets the life of each particle in milliseconds\r\n */\r\n this.particleLife = 2000;\r\n /**\r\n * Gets or sets the fade flag which causes particles to gradually fade out over the course of their life.\r\n */\r\n this.fadeFlag = false;\r\n /**\r\n * Gets or sets the optional focus where all particles should accelerate towards\r\n */\r\n this.focus = null;\r\n /**\r\n * Gets or sets the acceleration for focusing particles if a focus has been specified\r\n */\r\n this.focusAccel = null;\r\n /**\r\n * Gets or sets the optional starting size for the particles\r\n */\r\n this.startSize = null;\r\n /**\r\n * Gets or sets the optional ending size for the particles\r\n */\r\n this.endSize = null;\r\n /**\r\n * Gets or sets the minimum size of all particles\r\n */\r\n this.minSize = 5;\r\n /**\r\n * Gets or sets the maximum size of all particles\r\n */\r\n this.maxSize = 5;\r\n /**\r\n * Gets or sets the beginning color of all particles\r\n */\r\n this.beginColor = Color.White;\r\n /**\r\n * Gets or sets the ending color of all particles\r\n */\r\n this.endColor = Color.White;\r\n this._sprite = null;\r\n /**\r\n * Gets or sets the emitter type for the particle emitter\r\n */\r\n this.emitterType = EmitterType.Rectangle;\r\n /**\r\n * Gets or sets the emitter radius, only takes effect when the [[emitterType]] is [[EmitterType.Circle]]\r\n */\r\n this.radius = 0;\r\n /**\r\n * Gets or sets the particle rotational speed velocity\r\n */\r\n this.particleRotationalVelocity = 0;\r\n /**\r\n * Indicates whether particles should start with a random rotation\r\n */\r\n this.randomRotation = false;\r\n /**\r\n * Gets or sets the emitted particle transform style, [[ParticleTransform.Global]] is the default and emits particles as if\r\n * they were world space objects, useful for most effects.\r\n *\r\n * If set to [[ParticleTransform.Local]] particles are children of the emitter and move relative to the emitter\r\n * as they would in a parent/child actor relationship.\r\n */\r\n this.particleTransform = ParticleTransform.Global;\r\n const { x, y, pos, isEmitting, minVel, maxVel, acceleration, minAngle, maxAngle, emitRate, particleLife, opacity, fadeFlag, focus, focusAccel, startSize, endSize, minSize, maxSize, beginColor, endColor, particleSprite, emitterType, radius, particleRotationalVelocity, particleTransform, randomRotation, random } = { ...config };\r\n this.pos = pos !== null && pos !== void 0 ? pos : vec(x !== null && x !== void 0 ? x : 0, y !== null && y !== void 0 ? y : 0);\r\n this.isEmitting = isEmitting !== null && isEmitting !== void 0 ? isEmitting : this.isEmitting;\r\n this.minVel = minVel !== null && minVel !== void 0 ? minVel : this.minVel;\r\n this.maxVel = maxVel !== null && maxVel !== void 0 ? maxVel : this.maxVel;\r\n this.acceleration = acceleration !== null && acceleration !== void 0 ? acceleration : this.acceleration;\r\n this.minAngle = minAngle !== null && minAngle !== void 0 ? minAngle : this.minAngle;\r\n this.maxAngle = maxAngle !== null && maxAngle !== void 0 ? maxAngle : this.maxAngle;\r\n this.emitRate = emitRate !== null && emitRate !== void 0 ? emitRate : this.emitRate;\r\n this.particleLife = particleLife !== null && particleLife !== void 0 ? particleLife : this.particleLife;\r\n this.opacity = opacity !== null && opacity !== void 0 ? opacity : this.opacity;\r\n this.fadeFlag = fadeFlag !== null && fadeFlag !== void 0 ? fadeFlag : this.fadeFlag;\r\n this.focus = focus !== null && focus !== void 0 ? focus : this.focus;\r\n this.focusAccel = focusAccel !== null && focusAccel !== void 0 ? focusAccel : this.focusAccel;\r\n this.startSize = startSize !== null && startSize !== void 0 ? startSize : this.startSize;\r\n this.endSize = endSize !== null && endSize !== void 0 ? endSize : this.endSize;\r\n this.minSize = minSize !== null && minSize !== void 0 ? minSize : this.minSize;\r\n this.maxSize = maxSize !== null && maxSize !== void 0 ? maxSize : this.maxSize;\r\n this.beginColor = beginColor !== null && beginColor !== void 0 ? beginColor : this.beginColor;\r\n this.endColor = endColor !== null && endColor !== void 0 ? endColor : this.endColor;\r\n this.particleSprite = particleSprite !== null && particleSprite !== void 0 ? particleSprite : this.particleSprite;\r\n this.emitterType = emitterType !== null && emitterType !== void 0 ? emitterType : this.emitterType;\r\n this.radius = radius !== null && radius !== void 0 ? radius : this.radius;\r\n this.particleRotationalVelocity = particleRotationalVelocity !== null && particleRotationalVelocity !== void 0 ? particleRotationalVelocity : this.particleRotationalVelocity;\r\n this.randomRotation = randomRotation !== null && randomRotation !== void 0 ? randomRotation : this.randomRotation;\r\n this.particleTransform = particleTransform !== null && particleTransform !== void 0 ? particleTransform : this.particleTransform;\r\n this.body.collisionType = CollisionType.PreventCollision;\r\n this.random = random !== null && random !== void 0 ? random : new Random();\r\n }\r\n removeParticle(particle) {\r\n this.deadParticles.push(particle);\r\n }\r\n /**\r\n * Causes the emitter to emit particles\r\n * @param particleCount Number of particles to emit right now\r\n */\r\n emitParticles(particleCount) {\r\n var _a;\r\n for (let i = 0; i < particleCount; i++) {\r\n const p = this._createParticle();\r\n this.particles.push(p);\r\n if ((_a = this === null || this === void 0 ? void 0 : this.scene) === null || _a === void 0 ? void 0 : _a.world) {\r\n if (this.particleTransform === ParticleTransform.Global) {\r\n this.scene.world.add(p);\r\n }\r\n else {\r\n this.addChild(p);\r\n }\r\n }\r\n }\r\n }\r\n clearParticles() {\r\n this.particles.length = 0;\r\n }\r\n // Creates a new particle given the constraints of the emitter\r\n _createParticle() {\r\n // todo implement emitter constraints;\r\n let ranX = 0;\r\n let ranY = 0;\r\n const angle = randomInRange(this.minAngle, this.maxAngle, this.random);\r\n const vel = randomInRange(this.minVel, this.maxVel, this.random);\r\n const size = this.startSize || randomInRange(this.minSize, this.maxSize, this.random);\r\n const dx = vel * Math.cos(angle);\r\n const dy = vel * Math.sin(angle);\r\n if (this.emitterType === EmitterType.Rectangle) {\r\n ranX = randomInRange(0, this.width, this.random);\r\n ranY = randomInRange(0, this.height, this.random);\r\n }\r\n else if (this.emitterType === EmitterType.Circle) {\r\n const radius = randomInRange(0, this.radius, this.random);\r\n ranX = radius * Math.cos(angle);\r\n ranY = radius * Math.sin(angle);\r\n }\r\n const p = new Particle(this, this.particleLife, this.opacity, this.beginColor, this.endColor, new Vector(ranX, ranY), new Vector(dx, dy), this.acceleration, this.startSize, this.endSize);\r\n p.fadeFlag = this.fadeFlag;\r\n p.particleSize = size;\r\n if (this.particleSprite) {\r\n p.particleSprite = this.particleSprite;\r\n p.graphics.opacity = this.opacity;\r\n p.graphics.use(this._sprite);\r\n }\r\n p.particleRotationalVelocity = this.particleRotationalVelocity;\r\n if (this.randomRotation) {\r\n p.currentRotation = randomInRange(0, Math.PI * 2, this.random);\r\n }\r\n if (this.focus) {\r\n p.focus = this.focus.add(new Vector(this.pos.x, this.pos.y));\r\n p.focusAccel = this.focusAccel;\r\n }\r\n return p;\r\n }\r\n update(engine, delta) {\r\n var _a;\r\n super.update(engine, delta);\r\n if (this.isEmitting) {\r\n this._particlesToEmit += this.emitRate * (delta / 1000);\r\n if (this._particlesToEmit > 1.0) {\r\n this.emitParticles(Math.floor(this._particlesToEmit));\r\n this._particlesToEmit = this._particlesToEmit - Math.floor(this._particlesToEmit);\r\n }\r\n }\r\n // deferred removal\r\n for (let i = 0; i < this.deadParticles.length; i++) {\r\n removeItemFromArray(this.deadParticles[i], this.particles);\r\n if ((_a = this === null || this === void 0 ? void 0 : this.scene) === null || _a === void 0 ? void 0 : _a.world) {\r\n this.scene.world.remove(this.deadParticles[i], false);\r\n }\r\n }\r\n this.deadParticles.length = 0;\r\n }\r\n}\r\n\n;// CONCATENATED MODULE: ./Graphics/GraphicsSystem.ts\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\nclass GraphicsSystem extends System {\r\n constructor() {\r\n super(...arguments);\r\n this.types = ['ex.transform', 'ex.graphics'];\r\n this.systemType = SystemType.Draw;\r\n this.priority = 0;\r\n this._token = 0;\r\n this._sortedTransforms = [];\r\n this._zHasChanged = false;\r\n this._zIndexUpdate = () => {\r\n this._zHasChanged = true;\r\n };\r\n }\r\n get sortedTransforms() {\r\n return this._sortedTransforms;\r\n }\r\n initialize(scene) {\r\n this._camera = scene.camera;\r\n this._engine = scene.engine;\r\n }\r\n preupdate() {\r\n // Graphics context could be switched to fallback in a new frame\r\n this._graphicsContext = this._engine.graphicsContext;\r\n if (this._zHasChanged) {\r\n this._sortedTransforms.sort((a, b) => {\r\n return a.z - b.z;\r\n });\r\n this._zHasChanged = false;\r\n }\r\n }\r\n notify(entityAddedOrRemoved) {\r\n if (isAddedSystemEntity(entityAddedOrRemoved)) {\r\n const tx = entityAddedOrRemoved.data.get(TransformComponent);\r\n this._sortedTransforms.push(tx);\r\n tx.zIndexChanged$.subscribe(this._zIndexUpdate);\r\n this._zHasChanged = true;\r\n }\r\n else {\r\n const tx = entityAddedOrRemoved.data.get(TransformComponent);\r\n tx.zIndexChanged$.unsubscribe(this._zIndexUpdate);\r\n const index = this._sortedTransforms.indexOf(tx);\r\n if (index > -1) {\r\n this._sortedTransforms.splice(index, 1);\r\n }\r\n }\r\n }\r\n update(_entities, delta) {\r\n this._token++;\r\n let graphics;\r\n FontCache.checkAndClearCache();\r\n // This is a performance enhancement, most things are in world space\r\n // so if we can only do this once saves a ton of transform updates\r\n this._graphicsContext.save();\r\n if (this._camera) {\r\n this._camera.draw(this._graphicsContext);\r\n }\r\n for (const transform of this._sortedTransforms) {\r\n const entity = transform.owner;\r\n // If the entity is offscreen skip\r\n if (entity.hasTag('ex.offscreen')) {\r\n continue;\r\n }\r\n graphics = entity.get(GraphicsComponent);\r\n // Exit if graphics set to not visible\r\n if (!graphics.visible) {\r\n continue;\r\n }\r\n // This optionally sets our camera based on the entity coord plan (world vs. screen)\r\n if (transform.coordPlane === CoordPlane.Screen) {\r\n this._graphicsContext.restore();\r\n }\r\n this._graphicsContext.save();\r\n if (transform.coordPlane === CoordPlane.Screen) {\r\n this._graphicsContext.translate(this._engine.screen.contentArea.left, this._engine.screen.contentArea.top);\r\n }\r\n // Tick any graphics state (but only once) for animations and graphics groups\r\n graphics.update(delta, this._token);\r\n // Apply parallax\r\n const parallax = entity.get(ParallaxComponent);\r\n if (parallax) {\r\n // We use the Tiled formula\r\n // https://doc.mapeditor.org/en/latest/manual/layers/#parallax-scrolling-factor\r\n // cameraPos * (1 - parallaxFactor)\r\n const oneMinusFactor = Vector.One.sub(parallax.parallaxFactor);\r\n const parallaxOffset = this._camera.pos.scale(oneMinusFactor);\r\n this._graphicsContext.translate(parallaxOffset.x, parallaxOffset.y);\r\n }\r\n // Position the entity + estimate lag\r\n this._applyTransform(entity);\r\n // If there is a material enable it on the context\r\n if (graphics.material) {\r\n this._graphicsContext.material = graphics.material;\r\n }\r\n // Optionally run the onPreDraw graphics lifecycle draw\r\n if (graphics.onPreDraw) {\r\n graphics.onPreDraw(this._graphicsContext, delta);\r\n }\r\n // TODO remove this hack on the particle redo\r\n const particleOpacity = (entity instanceof Particle) ? entity.opacity : 1;\r\n this._graphicsContext.opacity *= graphics.opacity * particleOpacity;\r\n // Draw the graphics component\r\n this._drawGraphicsComponent(graphics);\r\n // Optionally run the onPostDraw graphics lifecycle draw\r\n if (graphics.onPostDraw) {\r\n graphics.onPostDraw(this._graphicsContext, delta);\r\n }\r\n this._graphicsContext.restore();\r\n // Reset the transform back to the original world space\r\n if (transform.coordPlane === CoordPlane.Screen) {\r\n this._graphicsContext.save();\r\n if (this._camera) {\r\n this._camera.draw(this._graphicsContext);\r\n }\r\n }\r\n }\r\n this._graphicsContext.restore();\r\n }\r\n _drawGraphicsComponent(graphicsComponent) {\r\n var _a, _b;\r\n if (graphicsComponent.visible) {\r\n const flipHorizontal = graphicsComponent.flipHorizontal;\r\n const flipVertical = graphicsComponent.flipVertical;\r\n for (const layer of graphicsComponent.layers.get()) {\r\n for (const { graphic, options } of layer.graphics) {\r\n let anchor = graphicsComponent.anchor;\r\n let offset = graphicsComponent.offset;\r\n // handle layer specific overrides\r\n if (options === null || options === void 0 ? void 0 : options.anchor) {\r\n anchor = options.anchor;\r\n }\r\n if (options === null || options === void 0 ? void 0 : options.offset) {\r\n offset = options.offset;\r\n }\r\n // See https://github.com/excaliburjs/Excalibur/pull/619 for discussion on this formula\r\n const offsetX = -graphic.width * anchor.x + offset.x;\r\n const offsetY = -graphic.height * anchor.y + offset.y;\r\n const oldFlipHorizontal = graphic.flipHorizontal;\r\n const oldFlipVertical = graphic.flipVertical;\r\n if (flipHorizontal || flipVertical) {\r\n // flip any currently flipped graphics\r\n graphic.flipHorizontal = flipHorizontal ? !oldFlipHorizontal : oldFlipHorizontal;\r\n graphic.flipVertical = flipVertical ? !oldFlipVertical : oldFlipVertical;\r\n }\r\n graphic === null || graphic === void 0 ? void 0 : graphic.draw(this._graphicsContext, offsetX + layer.offset.x, offsetY + layer.offset.y);\r\n if (flipHorizontal || flipVertical) {\r\n graphic.flipHorizontal = oldFlipHorizontal;\r\n graphic.flipVertical = oldFlipVertical;\r\n }\r\n if (((_a = this._engine) === null || _a === void 0 ? void 0 : _a.isDebug) && this._engine.debug.graphics.showBounds) {\r\n const offset = vec(offsetX + layer.offset.x, offsetY + layer.offset.y);\r\n if (graphic instanceof GraphicsGroup) {\r\n for (const g of graphic.members) {\r\n (_b = g.graphic) === null || _b === void 0 ? void 0 : _b.localBounds.translate(offset.add(g.pos)).draw(this._graphicsContext, this._engine.debug.graphics.boundsColor);\r\n }\r\n }\r\n else {\r\n /* istanbul ignore next */\r\n graphic === null || graphic === void 0 ? void 0 : graphic.localBounds.translate(offset).draw(this._graphicsContext, this._engine.debug.graphics.boundsColor);\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }\r\n /**\r\n * This applies the current entity transform to the graphics context\r\n * @param entity\r\n */\r\n _applyTransform(entity) {\r\n const ancestors = entity.getAncestors();\r\n for (const ancestor of ancestors) {\r\n const transform = ancestor === null || ancestor === void 0 ? void 0 : ancestor.get(TransformComponent);\r\n const optionalBody = ancestor === null || ancestor === void 0 ? void 0 : ancestor.get(BodyComponent);\r\n let interpolatedPos = transform.pos;\r\n let interpolatedScale = transform.scale;\r\n let interpolatedRotation = transform.rotation;\r\n if (optionalBody) {\r\n if (this._engine.fixedUpdateFps &&\r\n optionalBody.__oldTransformCaptured &&\r\n optionalBody.enableFixedUpdateInterpolate) {\r\n // Interpolate graphics if needed\r\n const blend = this._engine.currentFrameLagMs / (1000 / this._engine.fixedUpdateFps);\r\n interpolatedPos = transform.pos.scale(blend).add(optionalBody.oldPos.scale(1.0 - blend));\r\n interpolatedScale = transform.scale.scale(blend).add(optionalBody.oldScale.scale(1.0 - blend));\r\n // Rotational lerp https://stackoverflow.com/a/30129248\r\n const cosine = (1.0 - blend) * Math.cos(optionalBody.oldRotation) + blend * Math.cos(transform.rotation);\r\n const sine = (1.0 - blend) * Math.sin(optionalBody.oldRotation) + blend * Math.sin(transform.rotation);\r\n interpolatedRotation = Math.atan2(sine, cosine);\r\n }\r\n }\r\n if (transform) {\r\n this._graphicsContext.z = transform.z;\r\n this._graphicsContext.translate(interpolatedPos.x, interpolatedPos.y);\r\n this._graphicsContext.scale(interpolatedScale.x, interpolatedScale.y);\r\n this._graphicsContext.rotate(interpolatedRotation);\r\n }\r\n }\r\n }\r\n}\r\n\n;// CONCATENATED MODULE: ./Debug/DebugSystem.ts\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\nclass DebugSystem extends System {\r\n constructor() {\r\n super(...arguments);\r\n this.types = ['ex.transform'];\r\n this.systemType = SystemType.Draw;\r\n this.priority = 999; // lowest priority\r\n }\r\n initialize(scene) {\r\n this._graphicsContext = scene.engine.graphicsContext;\r\n this._camera = scene.camera;\r\n this._engine = scene.engine;\r\n this._collisionSystem = scene.world.systemManager.get(CollisionSystem);\r\n }\r\n update(entities, _delta) {\r\n var _a;\r\n if (!this._engine.isDebug) {\r\n return;\r\n }\r\n const filterSettings = this._engine.debug.filter;\r\n let id;\r\n let name;\r\n const entitySettings = this._engine.debug.entity;\r\n let tx;\r\n const txSettings = this._engine.debug.transform;\r\n let motion;\r\n const motionSettings = this._engine.debug.motion;\r\n let colliderComp;\r\n const colliderSettings = this._engine.debug.collider;\r\n const physicsSettings = this._engine.debug.physics;\r\n let graphics;\r\n const graphicsSettings = this._engine.debug.graphics;\r\n let debugDraw;\r\n let body;\r\n const bodySettings = this._engine.debug.body;\r\n const cameraSettings = this._engine.debug.camera;\r\n for (const entity of entities) {\r\n if (entity.hasTag('offscreen')) {\r\n // skip offscreen entities\r\n continue;\r\n }\r\n if (entity instanceof Particle) {\r\n // Particles crush the renderer :(\r\n continue;\r\n }\r\n if (filterSettings.useFilter) {\r\n const allIds = filterSettings.ids.length === 0;\r\n const idMatch = allIds || filterSettings.ids.includes(entity.id);\r\n if (!idMatch) {\r\n continue;\r\n }\r\n const allNames = filterSettings.nameQuery === '';\r\n const nameMatch = allNames || entity.name.includes(filterSettings.nameQuery);\r\n if (!nameMatch) {\r\n continue;\r\n }\r\n }\r\n let cursor = Vector.Zero;\r\n const lineHeight = vec(0, 16);\r\n id = entity.id;\r\n name = entity.name;\r\n tx = entity.get(TransformComponent);\r\n // This optionally sets our camera based on the entity coord plan (world vs. screen)\r\n this._pushCameraTransform(tx);\r\n this._graphicsContext.save();\r\n this._applyTransform(entity);\r\n if (tx) {\r\n if (txSettings.showAll || txSettings.showPosition) {\r\n this._graphicsContext.debug.drawPoint(Vector.Zero, { size: 4, color: txSettings.positionColor });\r\n }\r\n if (txSettings.showAll || txSettings.showPositionLabel) {\r\n this._graphicsContext.debug.drawText(`pos${tx.pos.toString(2)}`, cursor);\r\n cursor = cursor.add(lineHeight);\r\n }\r\n if (txSettings.showAll || txSettings.showZIndex) {\r\n this._graphicsContext.debug.drawText(`z(${tx.z.toFixed(1)})`, cursor);\r\n cursor = cursor.add(lineHeight);\r\n }\r\n if (entitySettings.showAll || entitySettings.showId) {\r\n this._graphicsContext.debug.drawText(`id(${id}) ${entity.parent ? 'child of id(' + ((_a = entity.parent) === null || _a === void 0 ? void 0 : _a.id) + ')' : ''}`, cursor);\r\n cursor = cursor.add(lineHeight);\r\n }\r\n if (entitySettings.showAll || entitySettings.showName) {\r\n this._graphicsContext.debug.drawText(`name(${name})`, cursor);\r\n cursor = cursor.add(lineHeight);\r\n }\r\n if (txSettings.showAll || txSettings.showRotation) {\r\n this._graphicsContext.drawLine(Vector.Zero, Vector.fromAngle(tx.rotation).scale(50).add(Vector.Zero), txSettings.rotationColor, 2);\r\n this._graphicsContext.debug.drawText(`rot deg(${toDegrees(tx.rotation).toFixed(2)})`, cursor);\r\n cursor = cursor.add(lineHeight);\r\n }\r\n if (txSettings.showAll || txSettings.showScale) {\r\n this._graphicsContext.drawLine(Vector.Zero, tx.scale.add(Vector.Zero), txSettings.scaleColor, 2);\r\n }\r\n }\r\n graphics = entity.get(GraphicsComponent);\r\n if (graphics) {\r\n if (graphicsSettings.showAll || graphicsSettings.showBounds) {\r\n const bounds = graphics.localBounds;\r\n bounds.draw(this._graphicsContext, graphicsSettings.boundsColor);\r\n }\r\n }\r\n debugDraw = entity.get(DebugGraphicsComponent);\r\n if (debugDraw) {\r\n if (!debugDraw.useTransform) {\r\n this._graphicsContext.restore();\r\n }\r\n debugDraw.draw(this._graphicsContext);\r\n if (!debugDraw.useTransform) {\r\n this._graphicsContext.save();\r\n this._applyTransform(entity);\r\n }\r\n }\r\n body = entity.get(BodyComponent);\r\n if (body) {\r\n if (bodySettings.showAll || bodySettings.showCollisionGroup) {\r\n this._graphicsContext.debug.drawText(`collision group(${body.group.name})`, cursor);\r\n cursor = cursor.add(lineHeight);\r\n }\r\n if (bodySettings.showAll || bodySettings.showCollisionType) {\r\n this._graphicsContext.debug.drawText(`collision type(${body.collisionType})`, cursor);\r\n cursor = cursor.add(lineHeight);\r\n }\r\n if (bodySettings.showAll || bodySettings.showMass) {\r\n this._graphicsContext.debug.drawText(`mass(${body.mass})`, cursor);\r\n cursor = cursor.add(lineHeight);\r\n }\r\n if (bodySettings.showAll || bodySettings.showMotion) {\r\n this._graphicsContext.debug.drawText(`motion(${body.sleepMotion})`, cursor);\r\n cursor = cursor.add(lineHeight);\r\n }\r\n if (bodySettings.showAll || bodySettings.showSleeping) {\r\n this._graphicsContext.debug.drawText(`sleeping(${body.canSleep ? body.sleeping : 'cant sleep'})`, cursor);\r\n cursor = cursor.add(lineHeight);\r\n }\r\n }\r\n this._graphicsContext.restore();\r\n motion = entity.get(MotionComponent);\r\n if (motion) {\r\n if (motionSettings.showAll || motionSettings.showVelocity) {\r\n this._graphicsContext.debug.drawText(`vel${motion.vel.toString(2)}`, cursor.add(tx.globalPos));\r\n this._graphicsContext.drawLine(tx.globalPos, tx.globalPos.add(motion.vel), motionSettings.velocityColor, 2);\r\n cursor = cursor.add(lineHeight);\r\n }\r\n if (motionSettings.showAll || motionSettings.showAcceleration) {\r\n this._graphicsContext.drawLine(tx.globalPos, tx.globalPos.add(motion.acc), motionSettings.accelerationColor, 2);\r\n }\r\n }\r\n // Colliders live in world space already so after the restore()\r\n colliderComp = entity.get(ColliderComponent);\r\n if (colliderComp) {\r\n const collider = colliderComp.get();\r\n if ((colliderSettings.showAll || colliderSettings.showGeometry) && collider) {\r\n collider.debug(this._graphicsContext, colliderSettings.geometryColor);\r\n }\r\n if (colliderSettings.showAll || colliderSettings.showBounds) {\r\n if (collider instanceof CompositeCollider) {\r\n const colliders = collider.getColliders();\r\n for (const collider of colliders) {\r\n const bounds = collider.bounds;\r\n const pos = vec(bounds.left, bounds.top);\r\n this._graphicsContext.debug.drawRect(pos.x, pos.y, bounds.width, bounds.height, { color: colliderSettings.boundsColor });\r\n if (colliderSettings.showAll || colliderSettings.showOwner) {\r\n this._graphicsContext.debug.drawText(`owner id(${collider.owner.id})`, pos);\r\n }\r\n }\r\n colliderComp.bounds.draw(this._graphicsContext, colliderSettings.boundsColor);\r\n }\r\n else if (collider) {\r\n const bounds = colliderComp.bounds;\r\n const pos = vec(bounds.left, bounds.top);\r\n this._graphicsContext.debug.drawRect(pos.x, pos.y, bounds.width, bounds.height, { color: colliderSettings.boundsColor });\r\n if (colliderSettings.showAll || colliderSettings.showOwner) {\r\n this._graphicsContext.debug.drawText(`owner id(${colliderComp.owner.id})`, pos);\r\n }\r\n }\r\n }\r\n }\r\n this._popCameraTransform(tx);\r\n }\r\n this._graphicsContext.save();\r\n this._camera.draw(this._graphicsContext);\r\n if (physicsSettings.showAll || physicsSettings.showBroadphaseSpacePartitionDebug) {\r\n this._collisionSystem.debug(this._graphicsContext);\r\n }\r\n if (physicsSettings.showAll || physicsSettings.showCollisionContacts || physicsSettings.showCollisionNormals) {\r\n for (const [_, contact] of this._engine.debug.stats.currFrame.physics.contacts) {\r\n if (physicsSettings.showAll || physicsSettings.showCollisionContacts) {\r\n for (const point of contact.points) {\r\n this._graphicsContext.debug.drawPoint(point, { size: 5, color: physicsSettings.collisionContactColor });\r\n }\r\n }\r\n if (physicsSettings.showAll || physicsSettings.showCollisionNormals) {\r\n for (const point of contact.points) {\r\n this._graphicsContext.debug.drawLine(point, contact.normal.scale(30).add(point), {\r\n color: physicsSettings.collisionNormalColor\r\n });\r\n }\r\n }\r\n }\r\n }\r\n this._graphicsContext.restore();\r\n if (cameraSettings) {\r\n this._graphicsContext.save();\r\n this._camera.draw(this._graphicsContext);\r\n if (cameraSettings.showAll || cameraSettings.showFocus) {\r\n this._graphicsContext.drawCircle(this._camera.pos, 4, cameraSettings.focusColor);\r\n }\r\n if (cameraSettings.showAll || cameraSettings.showZoom) {\r\n this._graphicsContext.debug.drawText(`zoom(${this._camera.zoom})`, this._camera.pos);\r\n }\r\n this._graphicsContext.restore();\r\n }\r\n this._graphicsContext.flush();\r\n }\r\n /**\r\n * This applies the current entity transform to the graphics context\r\n * @param entity\r\n */\r\n _applyTransform(entity) {\r\n const ancestors = entity.getAncestors();\r\n for (const ancestor of ancestors) {\r\n const transform = ancestor === null || ancestor === void 0 ? void 0 : ancestor.get(TransformComponent);\r\n if (transform) {\r\n this._graphicsContext.translate(transform.pos.x, transform.pos.y);\r\n this._graphicsContext.scale(transform.scale.x, transform.scale.y);\r\n this._graphicsContext.rotate(transform.rotation);\r\n }\r\n }\r\n }\r\n /**\r\n * Applies the current camera transform if in world coordinates\r\n * @param transform\r\n */\r\n _pushCameraTransform(transform) {\r\n // Establish camera offset per entity\r\n if (transform.coordPlane === CoordPlane.World) {\r\n this._graphicsContext.save();\r\n if (this._camera) {\r\n this._camera.draw(this._graphicsContext);\r\n }\r\n }\r\n }\r\n /**\r\n * Resets the current camera transform if in world coordinates\r\n * @param transform\r\n */\r\n _popCameraTransform(transform) {\r\n if (transform.coordPlane === CoordPlane.World) {\r\n // Apply camera world offset\r\n this._graphicsContext.restore();\r\n }\r\n }\r\n}\r\n\n;// CONCATENATED MODULE: ./Input/PointerSystem.ts\n\r\n\r\n\r\n\r\n\r\n/**\r\n * The PointerSystem is responsible for dispatching pointer events to entities\r\n * that need them.\r\n *\r\n * The PointerSystem can be optionally configured by the [[PointerComponent]], by default Entities use\r\n * the [[Collider]]'s shape for pointer events.\r\n */\r\nclass PointerSystem extends System {\r\n constructor() {\r\n super(...arguments);\r\n this.types = ['ex.transform', 'ex.pointer'];\r\n this.systemType = SystemType.Update;\r\n this.priority = -1;\r\n /**\r\n * Optionally override component configuration for all entities\r\n */\r\n this.overrideUseColliderShape = false;\r\n /**\r\n * Optionally override component configuration for all entities\r\n */\r\n this.overrideUseGraphicsBounds = false;\r\n this.lastFrameEntityToPointers = new Map();\r\n this.currentFrameEntityToPointers = new Map();\r\n this._sortedTransforms = [];\r\n this._sortedEntities = [];\r\n this._zHasChanged = false;\r\n this._zIndexUpdate = () => {\r\n this._zHasChanged = true;\r\n };\r\n }\r\n initialize(scene) {\r\n this._engine = scene.engine;\r\n }\r\n preupdate() {\r\n // event receiver might change per frame\r\n this._receiver = this._engine.input.pointers;\r\n if (this._zHasChanged) {\r\n this._sortedTransforms.sort((a, b) => {\r\n return b.z - a.z;\r\n });\r\n this._sortedEntities = this._sortedTransforms.map(t => t.owner);\r\n this._zHasChanged = false;\r\n }\r\n }\r\n notify(entityAddedOrRemoved) {\r\n if (isAddedSystemEntity(entityAddedOrRemoved)) {\r\n const tx = entityAddedOrRemoved.data.get(TransformComponent);\r\n this._sortedTransforms.push(tx);\r\n this._sortedEntities.push(tx.owner);\r\n tx.zIndexChanged$.subscribe(this._zIndexUpdate);\r\n this._zHasChanged = true;\r\n }\r\n else {\r\n const tx = entityAddedOrRemoved.data.get(TransformComponent);\r\n tx.zIndexChanged$.unsubscribe(this._zIndexUpdate);\r\n const index = this._sortedTransforms.indexOf(tx);\r\n if (index > -1) {\r\n this._sortedTransforms.splice(index, 1);\r\n this._sortedEntities.splice(index, 1);\r\n }\r\n }\r\n }\r\n entityCurrentlyUnderPointer(entity, pointerId) {\r\n return this.currentFrameEntityToPointers.has(entity.id) &&\r\n this.currentFrameEntityToPointers.get(entity.id).includes(pointerId);\r\n }\r\n entityWasUnderPointer(entity, pointerId) {\r\n return this.lastFrameEntityToPointers.has(entity.id) &&\r\n this.lastFrameEntityToPointers.get(entity.id).includes(pointerId);\r\n }\r\n entered(entity, pointerId) {\r\n return this.entityCurrentlyUnderPointer(entity, pointerId) &&\r\n !this.lastFrameEntityToPointers.has(entity.id);\r\n }\r\n left(entity, pointerId) {\r\n return !this.currentFrameEntityToPointers.has(entity.id) &&\r\n this.entityWasUnderPointer(entity, pointerId);\r\n }\r\n addPointerToEntity(entity, pointerId) {\r\n if (!this.currentFrameEntityToPointers.has(entity.id)) {\r\n this.currentFrameEntityToPointers.set(entity.id, [pointerId]);\r\n return;\r\n }\r\n const pointers = this.currentFrameEntityToPointers.get(entity.id);\r\n this.currentFrameEntityToPointers.set(entity.id, pointers.concat(pointerId));\r\n }\r\n update(_entities) {\r\n // Locate all the pointer/entity mappings\r\n this._processPointerToEntity(this._sortedEntities);\r\n // Dispatch pointer events on entities\r\n this._dispatchEvents(this._sortedEntities);\r\n // Clear last frame's events\r\n this._receiver.update();\r\n this.lastFrameEntityToPointers.clear();\r\n this.lastFrameEntityToPointers = new Map(this.currentFrameEntityToPointers);\r\n this.currentFrameEntityToPointers.clear();\r\n this._receiver.clear();\r\n }\r\n _processPointerToEntity(entities) {\r\n var _a;\r\n let transform;\r\n let collider;\r\n let graphics;\r\n let pointer;\r\n // TODO probably a spatial partition optimization here to quickly query bounds for pointer\r\n // doesn't seem to cause issues tho for perf\r\n // Pre-process find entities under pointers\r\n for (const entity of entities) {\r\n transform = entity.get(TransformComponent);\r\n pointer = (_a = entity.get(PointerComponent)) !== null && _a !== void 0 ? _a : new PointerComponent;\r\n // Check collider contains pointer\r\n collider = entity.get(ColliderComponent);\r\n if (collider && (pointer.useColliderShape || this.overrideUseColliderShape)) {\r\n collider.update();\r\n const geom = collider.get();\r\n if (geom) {\r\n for (const [pointerId, pos] of this._receiver.currentFramePointerCoords.entries()) {\r\n if (geom.contains(transform.coordPlane === CoordPlane.World ? pos.worldPos : pos.screenPos)) {\r\n this.addPointerToEntity(entity, pointerId);\r\n }\r\n }\r\n }\r\n }\r\n // Check graphics contains pointer\r\n graphics = entity.get(GraphicsComponent);\r\n if (graphics && (pointer.useGraphicsBounds || this.overrideUseGraphicsBounds)) {\r\n const graphicBounds = graphics.localBounds.transform(transform.get().matrix);\r\n for (const [pointerId, pos] of this._receiver.currentFramePointerCoords.entries()) {\r\n if (graphicBounds.contains(transform.coordPlane === CoordPlane.World ? pos.worldPos : pos.screenPos)) {\r\n this.addPointerToEntity(entity, pointerId);\r\n }\r\n }\r\n }\r\n }\r\n }\r\n _processDownAndEmit(entity) {\r\n const lastDownPerPointer = new Map();\r\n // Loop through down and dispatch to entities\r\n for (const event of this._receiver.currentFrameDown) {\r\n if (event.active && entity.active && this.entityCurrentlyUnderPointer(entity, event.pointerId)) {\r\n entity.events.emit('pointerdown', event);\r\n if (this._receiver.isDragStart(event.pointerId)) {\r\n entity.events.emit('pointerdragstart', event);\r\n }\r\n }\r\n lastDownPerPointer.set(event.pointerId, event);\r\n }\r\n return lastDownPerPointer;\r\n }\r\n _processUpAndEmit(entity) {\r\n const lastUpPerPointer = new Map();\r\n // Loop through up and dispatch to entities\r\n for (const event of this._receiver.currentFrameUp) {\r\n if (event.active && entity.active && this.entityCurrentlyUnderPointer(entity, event.pointerId)) {\r\n entity.events.emit('pointerup', event);\r\n if (this._receiver.isDragEnd(event.pointerId)) {\r\n entity.events.emit('pointerdragend', event);\r\n }\r\n }\r\n lastUpPerPointer.set(event.pointerId, event);\r\n }\r\n return lastUpPerPointer;\r\n }\r\n _processMoveAndEmit(entity) {\r\n const lastMovePerPointer = new Map();\r\n // Loop through move and dispatch to entities\r\n for (const event of this._receiver.currentFrameMove) {\r\n if (event.active && entity.active && this.entityCurrentlyUnderPointer(entity, event.pointerId)) {\r\n // move\r\n entity.events.emit('pointermove', event);\r\n if (this._receiver.isDragging(event.pointerId)) {\r\n entity.events.emit('pointerdragmove', event);\r\n }\r\n }\r\n lastMovePerPointer.set(event.pointerId, event);\r\n }\r\n return lastMovePerPointer;\r\n }\r\n _processEnterLeaveAndEmit(entity, lastUpDownMoveEvents) {\r\n // up, down, and move are considered for enter and leave\r\n for (const event of lastUpDownMoveEvents) {\r\n // enter\r\n if (event.active && entity.active && this.entered(entity, event.pointerId)) {\r\n entity.events.emit('pointerenter', event);\r\n if (this._receiver.isDragging(event.pointerId)) {\r\n entity.events.emit('pointerdragenter', event);\r\n }\r\n break;\r\n }\r\n if (event.active && entity.active &&\r\n // leave can happen on move\r\n (this.left(entity, event.pointerId) ||\r\n // or leave can happen on pointer up\r\n (this.entityCurrentlyUnderPointer(entity, event.pointerId) && event.type === 'up'))) {\r\n entity.events.emit('pointerleave', event);\r\n if (this._receiver.isDragging(event.pointerId)) {\r\n entity.events.emit('pointerdragleave', event);\r\n }\r\n break;\r\n }\r\n }\r\n }\r\n _processCancelAndEmit(entity) {\r\n // cancel\r\n for (const event of this._receiver.currentFrameCancel) {\r\n if (event.active && entity.active && this.entityCurrentlyUnderPointer(entity, event.pointerId)) {\r\n entity.events.emit('pointercancel', event);\r\n }\r\n }\r\n }\r\n _processWheelAndEmit(entity) {\r\n // wheel\r\n for (const event of this._receiver.currentFrameWheel) {\r\n // Currently the wheel only fires under the primary pointer '0'\r\n if (event.active && entity.active && this.entityCurrentlyUnderPointer(entity, 0)) {\r\n entity.events.emit('pointerwheel', event);\r\n }\r\n }\r\n }\r\n _dispatchEvents(entities) {\r\n const lastFrameEntities = new Set(this.lastFrameEntityToPointers.keys());\r\n const currentFrameEntities = new Set(this.currentFrameEntityToPointers.keys());\r\n // Filter preserves z order\r\n const entitiesWithEvents = entities.filter(e => lastFrameEntities.has(e.id) || currentFrameEntities.has(e.id));\r\n let lastMovePerPointer;\r\n let lastUpPerPointer;\r\n let lastDownPerPointer;\r\n // Dispatch events in entity z order\r\n for (const entity of entitiesWithEvents) {\r\n lastDownPerPointer = this._processDownAndEmit(entity);\r\n lastUpPerPointer = this._processUpAndEmit(entity);\r\n lastMovePerPointer = this._processMoveAndEmit(entity);\r\n const lastUpDownMoveEvents = [\r\n ...lastMovePerPointer.values(),\r\n ...lastDownPerPointer.values(),\r\n ...lastUpPerPointer.values()\r\n ];\r\n this._processEnterLeaveAndEmit(entity, lastUpDownMoveEvents);\r\n this._processCancelAndEmit(entity);\r\n this._processWheelAndEmit(entity);\r\n }\r\n }\r\n}\r\n\n;// CONCATENATED MODULE: ./Actions/ActionsSystem.ts\n\r\n\r\nclass ActionsSystem extends System {\r\n constructor() {\r\n super(...arguments);\r\n this.types = ['ex.actions'];\r\n this.systemType = SystemType.Update;\r\n this.priority = -1;\r\n this._actions = [];\r\n }\r\n notify(entityAddedOrRemoved) {\r\n if (isAddedSystemEntity(entityAddedOrRemoved)) {\r\n const action = entityAddedOrRemoved.data.get(ActionsComponent);\r\n this._actions.push(action);\r\n }\r\n else {\r\n const action = entityAddedOrRemoved.data.get(ActionsComponent);\r\n const index = this._actions.indexOf(action);\r\n if (index > -1) {\r\n this._actions.splice(index, 1);\r\n }\r\n }\r\n }\r\n update(_entities, delta) {\r\n for (const actions of this._actions) {\r\n actions.update(delta);\r\n }\r\n }\r\n}\r\n\n;// CONCATENATED MODULE: ./TileMap/IsometricEntityComponent.ts\n\r\nclass IsometricEntityComponent extends Component {\r\n /**\r\n * Specify the isometric map to use to position this entity's z-index\r\n * @param map\r\n */\r\n constructor(map) {\r\n super();\r\n this.type = 'ex.isometricentity';\r\n /**\r\n * Vertical \"height\" in the isometric world\r\n */\r\n this.elevation = 0;\r\n this.map = map;\r\n }\r\n}\r\n\n;// CONCATENATED MODULE: ./TileMap/IsometricEntitySystem.ts\n\r\n\r\n\r\nclass IsometricEntitySystem extends System {\r\n constructor() {\r\n super(...arguments);\r\n this.types = ['ex.transform', 'ex.isometricentity'];\r\n this.systemType = SystemType.Update;\r\n this.priority = 99;\r\n }\r\n update(entities, _delta) {\r\n let transform;\r\n let iso;\r\n for (const entity of entities) {\r\n transform = entity.get(TransformComponent);\r\n iso = entity.get(IsometricEntityComponent);\r\n const maxZindexPerElevation = Math.max(iso.map.columns * iso.map.tileWidth, iso.map.rows * iso.map.tileHeight);\r\n const newZ = maxZindexPerElevation * iso.elevation + transform.pos.y;\r\n transform.z = newZ;\r\n }\r\n }\r\n}\r\n\n;// CONCATENATED MODULE: ./Graphics/OffscreenSystem.ts\n\r\n\r\n\r\n\r\n\r\n\r\n\r\nclass OffscreenSystem extends System {\r\n constructor() {\r\n super(...arguments);\r\n this.types = ['ex.transform', 'ex.graphics'];\r\n this.systemType = SystemType.Draw;\r\n this.priority = -1;\r\n }\r\n initialize(scene) {\r\n this._camera = scene.camera;\r\n this._screen = scene.engine.screen;\r\n }\r\n update(entities) {\r\n this._worldBounds = this._screen.getWorldBounds();\r\n let transform;\r\n let graphics;\r\n let maybeParallax;\r\n for (const entity of entities) {\r\n graphics = entity.get(GraphicsComponent);\r\n transform = entity.get(TransformComponent);\r\n maybeParallax = entity.get(ParallaxComponent);\r\n let parallaxOffset;\r\n if (maybeParallax) {\r\n // We use the Tiled formula\r\n // https://doc.mapeditor.org/en/latest/manual/layers/#parallax-scrolling-factor\r\n // cameraPos * (1 - parallaxFactor)\r\n const oneMinusFactor = Vector.One.sub(maybeParallax.parallaxFactor);\r\n parallaxOffset = this._camera.pos.scale(oneMinusFactor);\r\n }\r\n // Figure out if entities are offscreen\r\n const entityOffscreen = this._isOffscreen(transform, graphics, parallaxOffset);\r\n if (entityOffscreen && !entity.hasTag('ex.offscreen')) {\r\n entity.events.emit('exitviewport', new ExitViewPortEvent(entity));\r\n entity.addTag('ex.offscreen');\r\n }\r\n if (!entityOffscreen && entity.hasTag('ex.offscreen')) {\r\n entity.events.emit('enterviewport', new EnterViewPortEvent(entity));\r\n entity.removeTag('ex.offscreen');\r\n }\r\n }\r\n }\r\n _isOffscreen(transform, graphics, parallaxOffset) {\r\n if (transform.coordPlane === CoordPlane.World) {\r\n let bounds = graphics.localBounds;\r\n if (parallaxOffset) {\r\n bounds = bounds.translate(parallaxOffset);\r\n }\r\n const transformedBounds = bounds.transform(transform.get().matrix);\r\n const graphicsOffscreen = !this._worldBounds.overlaps(transformedBounds);\r\n return graphicsOffscreen;\r\n }\r\n else {\r\n // TODO screen coordinates\r\n return false;\r\n }\r\n }\r\n}\r\n\n;// CONCATENATED MODULE: ./Collision/PhysicsWorld.ts\n\r\nclass PhysicsWorld {\r\n constructor() {\r\n this.collisionProcessor = new DynamicTreeCollisionProcessor();\r\n }\r\n rayCast(ray, options) {\r\n return this.collisionProcessor.rayCast(ray, options);\r\n }\r\n}\r\n\n;// CONCATENATED MODULE: ./Scene.ts\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\nconst SceneEvents = {\r\n Initialize: 'initialize',\r\n Activate: 'activate',\r\n Deactivate: 'deactivate',\r\n PreUpdate: 'preupdate',\r\n PostUpdate: 'postupdate',\r\n PreDraw: 'predraw',\r\n PostDraw: 'postdraw',\r\n PreDebugDraw: 'predebugdraw',\r\n PostDebugDraw: 'postdebugdraw'\r\n};\r\n/**\r\n * [[Actor|Actors]] are composed together into groupings called Scenes in\r\n * Excalibur. The metaphor models the same idea behind real world\r\n * actors in a scene. Only actors in scenes will be updated and drawn.\r\n *\r\n * Typical usages of a scene include: levels, menus, loading screens, etc.\r\n */\r\nclass Scene {\r\n /**\r\n * The actors in the current scene\r\n */\r\n get actors() {\r\n return this.world.entityManager.entities.filter((e) => {\r\n return e instanceof Actor;\r\n });\r\n }\r\n /**\r\n * The entities in the current scene\r\n */\r\n get entities() {\r\n return this.world.entityManager.entities;\r\n }\r\n /**\r\n * The triggers in the current scene\r\n */\r\n get triggers() {\r\n return this.world.entityManager.entities.filter((e) => {\r\n return e instanceof Trigger;\r\n });\r\n }\r\n /**\r\n * The [[TileMap]]s in the scene, if any\r\n */\r\n get tileMaps() {\r\n return this.world.entityManager.entities.filter((e) => {\r\n return e instanceof TileMap;\r\n });\r\n }\r\n get timers() {\r\n return this._timers;\r\n }\r\n constructor() {\r\n // Initialize systems\r\n this._logger = Logger.getInstance();\r\n this.events = new EventEmitter();\r\n /**\r\n * Gets or sets the current camera for the scene\r\n */\r\n this.camera = new Camera();\r\n /**\r\n * The ECS world for the scene\r\n */\r\n this.world = new World(this);\r\n /**\r\n * The Excalibur physics world for the scene. Used to interact\r\n * with colliders included in the scene.\r\n *\r\n * Can be used to perform scene ray casts, track colliders, broadphase, and narrowphase.\r\n */\r\n this.physics = new PhysicsWorld();\r\n this._isInitialized = false;\r\n this._timers = [];\r\n this._cancelQueue = [];\r\n // Update\r\n this.world.add(new ActionsSystem());\r\n this.world.add(new MotionSystem());\r\n this.world.add(new CollisionSystem(this.physics));\r\n this.world.add(new PointerSystem());\r\n this.world.add(new IsometricEntitySystem());\r\n // Draw\r\n this.world.add(new OffscreenSystem());\r\n this.world.add(new GraphicsSystem());\r\n this.world.add(new DebugSystem());\r\n }\r\n emit(eventName, event) {\r\n this.events.emit(eventName, event);\r\n }\r\n on(eventName, handler) {\r\n return this.events.on(eventName, handler);\r\n }\r\n once(eventName, handler) {\r\n return this.events.once(eventName, handler);\r\n }\r\n off(eventName, handler) {\r\n this.events.off(eventName, handler);\r\n }\r\n /**\r\n * This is called before the first update of the [[Scene]]. Initializes scene members like the camera. This method is meant to be\r\n * overridden. This is where initialization of child actors should take place.\r\n */\r\n onInitialize(_engine) {\r\n // will be overridden\r\n }\r\n /**\r\n * This is called when the scene is made active and started. It is meant to be overridden,\r\n * this is where you should setup any DOM UI or event handlers needed for the scene.\r\n */\r\n onActivate(_context) {\r\n // will be overridden\r\n }\r\n /**\r\n * This is called when the scene is made transitioned away from and stopped. It is meant to be overridden,\r\n * this is where you should cleanup any DOM UI or event handlers needed for the scene.\r\n */\r\n onDeactivate(_context) {\r\n // will be overridden\r\n }\r\n /**\r\n * Safe to override onPreUpdate lifecycle event handler. Synonymous with `.on('preupdate', (evt) =>{...})`\r\n *\r\n * `onPreUpdate` is called directly before a scene is updated.\r\n */\r\n onPreUpdate(_engine, _delta) {\r\n // will be overridden\r\n }\r\n /**\r\n * Safe to override onPostUpdate lifecycle event handler. Synonymous with `.on('preupdate', (evt) =>{...})`\r\n *\r\n * `onPostUpdate` is called directly after a scene is updated.\r\n */\r\n onPostUpdate(_engine, _delta) {\r\n // will be overridden\r\n }\r\n /**\r\n * Safe to override onPreDraw lifecycle event handler. Synonymous with `.on('preupdate', (evt) =>{...})`\r\n *\r\n * `onPreDraw` is called directly before a scene is drawn.\r\n *\r\n */\r\n onPreDraw(_ctx, _delta) {\r\n // will be overridden\r\n }\r\n /**\r\n * Safe to override onPostDraw lifecycle event handler. Synonymous with `.on('preupdate', (evt) =>{...})`\r\n *\r\n * `onPostDraw` is called directly after a scene is drawn.\r\n *\r\n */\r\n onPostDraw(_ctx, _delta) {\r\n // will be overridden\r\n }\r\n /**\r\n * Initializes actors in the scene\r\n */\r\n _initializeChildren() {\r\n for (const child of this.entities) {\r\n child._initialize(this.engine);\r\n }\r\n }\r\n /**\r\n * Gets whether or not the [[Scene]] has been initialized\r\n */\r\n get isInitialized() {\r\n return this._isInitialized;\r\n }\r\n /**\r\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\r\n *\r\n * Initializes the scene before the first update, meant to be called by engine not by users of\r\n * Excalibur\r\n * @internal\r\n */\r\n _initialize(engine) {\r\n if (!this.isInitialized) {\r\n this.engine = engine;\r\n // Initialize camera first\r\n this.camera._initialize(engine);\r\n this.world.systemManager.initialize();\r\n // This order is important! we want to be sure any custom init that add actors\r\n // fire before the actor init\r\n this.onInitialize.call(this, engine);\r\n this._initializeChildren();\r\n this._logger.debug('Scene.onInitialize', this, engine);\r\n this.events.emit('initialize', new InitializeEvent(engine, this));\r\n this._isInitialized = true;\r\n }\r\n }\r\n /**\r\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\r\n *\r\n * Activates the scene with the base behavior, then calls the overridable `onActivate` implementation.\r\n * @internal\r\n */\r\n _activate(context) {\r\n this._logger.debug('Scene.onActivate', this);\r\n this.onActivate(context);\r\n }\r\n /**\r\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\r\n *\r\n * Deactivates the scene with the base behavior, then calls the overridable `onDeactivate` implementation.\r\n * @internal\r\n */\r\n _deactivate(context) {\r\n this._logger.debug('Scene.onDeactivate', this);\r\n this.onDeactivate(context);\r\n }\r\n /**\r\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\r\n *\r\n * Internal _preupdate handler for [[onPreUpdate]] lifecycle event\r\n * @internal\r\n */\r\n _preupdate(_engine, delta) {\r\n this.emit('preupdate', new PreUpdateEvent(_engine, delta, this));\r\n this.onPreUpdate(_engine, delta);\r\n }\r\n /**\r\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\r\n *\r\n * Internal _preupdate handler for [[onPostUpdate]] lifecycle event\r\n * @internal\r\n */\r\n _postupdate(_engine, delta) {\r\n this.emit('postupdate', new PostUpdateEvent(_engine, delta, this));\r\n this.onPostUpdate(_engine, delta);\r\n }\r\n /**\r\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\r\n *\r\n * Internal _predraw handler for [[onPreDraw]] lifecycle event\r\n *\r\n * @internal\r\n */\r\n _predraw(_ctx, _delta) {\r\n this.emit('predraw', new PreDrawEvent(_ctx, _delta, this));\r\n this.onPreDraw(_ctx, _delta);\r\n }\r\n /**\r\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\r\n *\r\n * Internal _postdraw handler for [[onPostDraw]] lifecycle event\r\n *\r\n * @internal\r\n */\r\n _postdraw(_ctx, _delta) {\r\n this.emit('postdraw', new PostDrawEvent(_ctx, _delta, this));\r\n this.onPostDraw(_ctx, _delta);\r\n }\r\n /**\r\n * Updates all the actors and timers in the scene. Called by the [[Engine]].\r\n * @param engine Reference to the current Engine\r\n * @param delta The number of milliseconds since the last update\r\n */\r\n update(engine, delta) {\r\n this._preupdate(engine, delta);\r\n // TODO differed entity removal for timers\r\n let i, len;\r\n // Remove timers in the cancel queue before updating them\r\n for (i = 0, len = this._cancelQueue.length; i < len; i++) {\r\n this.removeTimer(this._cancelQueue[i]);\r\n }\r\n this._cancelQueue.length = 0;\r\n // Cycle through timers updating timers\r\n for (const timer of this._timers) {\r\n timer.update(delta);\r\n }\r\n this.world.update(SystemType.Update, delta);\r\n // Camera last keeps renders smooth that are based on entity/actor\r\n if (this.camera) {\r\n this.camera.update(engine, delta);\r\n }\r\n this._collectActorStats(engine);\r\n this._postupdate(engine, delta);\r\n }\r\n /**\r\n * Draws all the actors in the Scene. Called by the [[Engine]].\r\n *\r\n * @param ctx The current rendering context\r\n * @param delta The number of milliseconds since the last draw\r\n */\r\n draw(ctx, delta) {\r\n var _a;\r\n this._predraw(ctx, delta);\r\n this.world.update(SystemType.Draw, delta);\r\n if ((_a = this.engine) === null || _a === void 0 ? void 0 : _a.isDebug) {\r\n this.debugDraw(ctx);\r\n }\r\n this._postdraw(ctx, delta);\r\n }\r\n /**\r\n * Draws all the actors' debug information in the Scene. Called by the [[Engine]].\r\n * @param ctx The current rendering context\r\n */\r\n /* istanbul ignore next */\r\n debugDraw(ctx) {\r\n this.emit('predebugdraw', new PreDebugDrawEvent(ctx, this));\r\n // pass\r\n this.emit('postdebugdraw', new PostDebugDrawEvent(ctx, this));\r\n }\r\n /**\r\n * Checks whether an actor is contained in this scene or not\r\n */\r\n contains(actor) {\r\n return this.actors.indexOf(actor) > -1;\r\n }\r\n add(entity) {\r\n this.emit('entityadded', { target: entity });\r\n this.world.add(entity);\r\n entity.scene = this;\r\n if (entity instanceof Timer) {\r\n if (!contains(this._timers, entity)) {\r\n this.addTimer(entity);\r\n }\r\n return;\r\n }\r\n }\r\n /**\r\n * Removes an [[Entity]] (Actor, TileMap, Trigger, etc) or [[Timer]] from it's current scene\r\n * and adds it to this scene.\r\n *\r\n * Useful if you want to have an object be present in only 1 scene at a time.\r\n * @param entity\r\n */\r\n transfer(entity) {\r\n let scene;\r\n if (entity instanceof Entity && entity.scene && entity.scene !== this) {\r\n scene = entity.scene;\r\n entity.scene.world.remove(entity, false);\r\n }\r\n if (entity instanceof Timer && entity.scene) {\r\n scene = entity.scene;\r\n entity.scene.removeTimer(entity);\r\n }\r\n scene === null || scene === void 0 ? void 0 : scene.emit('entityremoved', { target: entity });\r\n this.add(entity);\r\n }\r\n remove(entity) {\r\n if (entity instanceof Entity) {\r\n this.emit('entityremoved', { target: entity });\r\n if (entity.active) {\r\n entity.kill();\r\n }\r\n this.world.remove(entity);\r\n }\r\n if (entity instanceof Timer) {\r\n this.removeTimer(entity);\r\n }\r\n }\r\n /**\r\n * Removes all entities and timers from the scene, optionally indicate whether deferred should or shouldn't be used.\r\n *\r\n * By default entities use deferred removal\r\n * @param deferred\r\n */\r\n clear(deferred = true) {\r\n for (const entity of this.entities) {\r\n this.world.remove(entity, deferred);\r\n }\r\n for (const timer of this.timers) {\r\n this.removeTimer(timer);\r\n }\r\n }\r\n /**\r\n * Adds a [[Timer]] to the scene\r\n * @param timer The timer to add\r\n */\r\n addTimer(timer) {\r\n this._timers.push(timer);\r\n timer.scene = this;\r\n return timer;\r\n }\r\n /**\r\n * Removes a [[Timer]] from the scene.\r\n * @warning Can be dangerous, use [[cancelTimer]] instead\r\n * @param timer The timer to remove\r\n */\r\n removeTimer(timer) {\r\n const i = this._timers.indexOf(timer);\r\n if (i !== -1) {\r\n this._timers.splice(i, 1);\r\n }\r\n return timer;\r\n }\r\n /**\r\n * Cancels a [[Timer]], removing it from the scene nicely\r\n * @param timer The timer to cancel\r\n */\r\n cancelTimer(timer) {\r\n this._cancelQueue.push(timer);\r\n return timer;\r\n }\r\n /**\r\n * Tests whether a [[Timer]] is active in the scene\r\n */\r\n isTimerActive(timer) {\r\n return this._timers.indexOf(timer) > -1 && !timer.complete;\r\n }\r\n isCurrentScene() {\r\n if (this.engine) {\r\n return this.engine.currentScene === this;\r\n }\r\n return false;\r\n }\r\n _collectActorStats(engine) {\r\n const screenElements = this.actors.filter((a) => a instanceof ScreenElement);\r\n for (const _ui of screenElements) {\r\n engine.stats.currFrame.actors.ui++;\r\n }\r\n for (const actor of this.actors) {\r\n engine.stats.currFrame.actors.alive++;\r\n for (const child of actor.children) {\r\n if (isScreenElement(child)) {\r\n // TODO not true\r\n engine.stats.currFrame.actors.ui++;\r\n }\r\n else {\r\n engine.stats.currFrame.actors.alive++;\r\n }\r\n }\r\n }\r\n }\r\n}\r\n\n;// CONCATENATED MODULE: ./Graphics/PostProcessor/ColorBlindnessMode.ts\nvar ColorBlindnessMode;\r\n(function (ColorBlindnessMode) {\r\n ColorBlindnessMode[\"Protanope\"] = \"Protanope\";\r\n ColorBlindnessMode[\"Deuteranope\"] = \"Deuteranope\";\r\n ColorBlindnessMode[\"Tritanope\"] = \"Tritanope\";\r\n})(ColorBlindnessMode || (ColorBlindnessMode = {}));\r\n\n;// CONCATENATED MODULE: ./Graphics/PostProcessor/color-blind-fragment.glsl\n/* harmony default export */ const color_blind_fragment = (\"#version 300 es\\r\\nprecision mediump float;\\r\\n// our texture\\r\\nuniform sampler2D u_image;\\r\\n// the texCoords passed in from the vertex shader.\\r\\nin vec2 v_texcoord;\\r\\n\\r\\n// color blind type\\r\\nuniform int u_type;\\r\\n\\r\\n// simulation?\\r\\nuniform bool u_simulate;\\r\\n\\r\\nout vec4 fragColor;\\r\\n\\r\\nvoid main() {\\r\\n vec4 o = texture(u_image, v_texcoord);\\r\\n // RGB to LMS matrix conversion\\r\\n float L = (17.8824 * o.r) + (43.5161 * o.g) + (4.11935 * o.b);\\r\\n float M = (3.45565 * o.r) + (27.1554 * o.g) + (3.86714 * o.b);\\r\\n float S = (0.0299566 * o.r) + (0.184309 * o.g) + (1.46709 * o.b);\\r\\n // Simulate color blindness\\r\\n float l;\\r\\n float m;\\r\\n float s;\\r\\n //MODE CODE//\\r\\n if (u_type == 0) {\\r\\n // Protanope\\r\\n l = 0.0 * L + 2.02344 * M + -2.52581 * S;\\r\\n m = 0.0 * L + 1.0 * M + 0.0 * S;\\r\\n s = 0.0 * L + 0.0 * M + 1.0 * S;;\\r\\n } else if (u_type == 1) {\\r\\n // Deuteranope\\r\\n l = 1.0 * L + 0.0 * M + 0.0 * S;\\r\\n m = 0.494207 * L + 0.0 * M + 1.24827 * S;\\r\\n s = 0.0 * L + 0.0 * M + 1.0 * S;\\r\\n } else if (u_type == 2) {\\r\\n // Tritanope\\r\\n l = 1.0 * L + 0.0 * M + 0.0 * S;\\r\\n m = 0.0 * L + 1.0 * M + 0.0 * S;\\r\\n s = -0.395913 * L + 0.801109 * M + 0.0 * S;\\r\\n }\\r\\n\\r\\n // LMS to RGB matrix conversion\\r\\n vec4 error; // simulate the colors\\r\\n error.r = (0.0809444479 * l) + (-0.130504409 * m) + (0.116721066 * s);\\r\\n error.g = (-0.0102485335 * l) + (0.0540193266 * m) + (-0.113614708 * s);\\r\\n error.b = (-0.000365296938 * l) + (-0.00412161469 * m) + (0.693511405 * s);\\r\\n error.a = 1.0;\\r\\n vec4 diff = o - error;\\r\\n vec4 correction; // correct the colors\\r\\n correction.r = 0.0;\\r\\n correction.g = (diff.r * 0.7) + (diff.g * 1.0);\\r\\n correction.b = (diff.r * 0.7) + (diff.b * 1.0);\\r\\n correction = o + correction;\\r\\n correction.a = o.a;\\r\\n //SIMULATE//\\r\\n\\r\\n // sim \\r\\n if (u_simulate) {\\r\\n fragColor = error.rgba;\\r\\n } else {\\r\\n fragColor = correction.rgba;\\r\\n }\\r\\n}\");\n;// CONCATENATED MODULE: ./Graphics/PostProcessor/ScreenShader.ts\n\r\n\r\n\r\n/**\r\n * Helper that defines a whole screen renderer, just provide a fragment source!\r\n *\r\n * Currently supports 1 varying\r\n * - vec2 a_texcoord between 0-1 which corresponds to screen position\r\n */\r\nclass ScreenShader {\r\n constructor(gl, fragmentSource) {\r\n this._shader = new Shader({\r\n gl,\r\n vertexSource: `#version 300 es\r\n in vec2 a_position;\r\n in vec2 a_texcoord;\r\n out vec2 v_texcoord;\r\n\r\n void main() {\r\n gl_Position = vec4(a_position, 0.0, 1.0);\r\n // Pass the texcoord to the fragment shader.\r\n v_texcoord = a_texcoord;\r\n }`,\r\n fragmentSource: fragmentSource\r\n });\r\n this._shader.compile();\r\n // Setup memory layout\r\n this._buffer = new VertexBuffer({\r\n gl,\r\n type: 'static',\r\n // clip space quad + uv since we don't need a camera\r\n data: new Float32Array([\r\n -1, -1, 0, 0,\r\n -1, 1, 0, 1,\r\n 1, -1, 1, 0,\r\n 1, -1, 1, 0,\r\n -1, 1, 0, 1,\r\n 1, 1, 1, 1\r\n ])\r\n });\r\n this._layout = new VertexLayout({\r\n gl,\r\n shader: this._shader,\r\n vertexBuffer: this._buffer,\r\n attributes: [\r\n ['a_position', 2],\r\n ['a_texcoord', 2]\r\n ]\r\n });\r\n this._buffer.upload();\r\n }\r\n getShader() {\r\n return this._shader;\r\n }\r\n getLayout() {\r\n return this._layout;\r\n }\r\n}\r\n\n;// CONCATENATED MODULE: ./Graphics/PostProcessor/ColorBlindnessPostProcessor.ts\n\r\n\r\n\r\nclass ColorBlindnessPostProcessor {\r\n constructor(_colorBlindnessMode, simulate = false) {\r\n this._colorBlindnessMode = _colorBlindnessMode;\r\n this._simulate = false;\r\n this._simulate = simulate;\r\n }\r\n initialize(gl) {\r\n this._shader = new ScreenShader(gl, color_blind_fragment);\r\n this.simulate = this._simulate;\r\n this.colorBlindnessMode = this._colorBlindnessMode;\r\n }\r\n getShader() {\r\n return this._shader.getShader();\r\n }\r\n getLayout() {\r\n return this._shader.getLayout();\r\n }\r\n set colorBlindnessMode(colorBlindMode) {\r\n this._colorBlindnessMode = colorBlindMode;\r\n if (this._shader) {\r\n const shader = this._shader.getShader();\r\n shader.use();\r\n if (this._colorBlindnessMode === ColorBlindnessMode.Protanope) {\r\n shader.setUniformInt('u_type', 0);\r\n }\r\n else if (this._colorBlindnessMode === ColorBlindnessMode.Deuteranope) {\r\n shader.setUniformInt('u_type', 1);\r\n }\r\n else if (this._colorBlindnessMode === ColorBlindnessMode.Tritanope) {\r\n shader.setUniformInt('u_type', 2);\r\n }\r\n }\r\n }\r\n get colorBlindnessMode() {\r\n return this._colorBlindnessMode;\r\n }\r\n set simulate(value) {\r\n this._simulate = value;\r\n if (this._shader) {\r\n const shader = this._shader.getShader();\r\n shader.use();\r\n shader.setUniformBoolean('u_simulate', value);\r\n }\r\n }\r\n get simulate() {\r\n return this._simulate;\r\n }\r\n}\r\n\n;// CONCATENATED MODULE: ./Debug/DebugFlags.ts\n\r\n\r\n\r\nclass ColorBlindFlags {\r\n constructor(engine) {\r\n this._engine = engine;\r\n this._colorBlindPostProcessor = new ColorBlindnessPostProcessor(ColorBlindnessMode.Protanope);\r\n }\r\n /**\r\n * Correct colors for a specified color blindness\r\n * @param colorBlindness\r\n */\r\n correct(colorBlindness) {\r\n if (this._engine.graphicsContext instanceof ExcaliburGraphicsContextWebGL) {\r\n this.clear();\r\n this._colorBlindPostProcessor.colorBlindnessMode = colorBlindness;\r\n this._colorBlindPostProcessor.simulate = false;\r\n this._engine.graphicsContext.addPostProcessor(this._colorBlindPostProcessor);\r\n }\r\n }\r\n /**\r\n * Simulate colors for a specified color blindness\r\n * @param colorBlindness\r\n */\r\n simulate(colorBlindness) {\r\n if (this._engine.graphicsContext instanceof ExcaliburGraphicsContextWebGL) {\r\n this.clear();\r\n this._colorBlindPostProcessor.colorBlindnessMode = colorBlindness;\r\n this._colorBlindPostProcessor.simulate = true;\r\n this._engine.graphicsContext.addPostProcessor(this._colorBlindPostProcessor);\r\n }\r\n }\r\n /**\r\n * Remove color blindness post processor\r\n */\r\n clear() {\r\n this._engine.graphicsContext.removePostProcessor(this._colorBlindPostProcessor);\r\n }\r\n}\r\n\n;// CONCATENATED MODULE: ./Debug/Debug.ts\n\r\n\r\n/**\r\n * Debug statistics and flags for Excalibur. If polling these values, it would be\r\n * best to do so on the `postupdate` event for [[Engine]], after all values have been\r\n * updated during a frame.\r\n */\r\nclass Debug {\r\n constructor(engine) {\r\n /**\r\n * Performance statistics\r\n */\r\n this.stats = {\r\n /**\r\n * Current frame statistics. Engine reuses this instance, use [[FrameStats.clone]] to copy frame stats.\r\n * Best accessed on [[postframe]] event. See [[FrameStats]]\r\n */\r\n currFrame: new FrameStats(),\r\n /**\r\n * Previous frame statistics. Engine reuses this instance, use [[FrameStats.clone]] to copy frame stats.\r\n * Best accessed on [[preframe]] event. Best inspected on engine event `preframe`. See [[FrameStats]]\r\n */\r\n prevFrame: new FrameStats()\r\n };\r\n /**\r\n * Filter debug context to named entities or entity ids\r\n */\r\n this.filter = {\r\n /**\r\n * Toggle filter on or off (default off) must be on for DebugDraw to use filters\r\n */\r\n useFilter: false,\r\n /**\r\n * Query for entities by name, if the entity name contains `nameQuery` it will be included\r\n */\r\n nameQuery: '',\r\n /**\r\n * Query for Entity ids, if the id matches it will be included\r\n */\r\n ids: []\r\n };\r\n /**\r\n * Entity debug settings\r\n */\r\n this.entity = {\r\n showAll: false,\r\n showId: true,\r\n showName: false\r\n };\r\n /**\r\n * Transform component debug settings\r\n */\r\n this.transform = {\r\n showAll: false,\r\n showPosition: false,\r\n showPositionLabel: false,\r\n positionColor: Color.Yellow,\r\n showZIndex: false,\r\n showScale: false,\r\n scaleColor: Color.Green,\r\n showRotation: false,\r\n rotationColor: Color.Blue\r\n };\r\n /**\r\n * Graphics component debug settings\r\n */\r\n this.graphics = {\r\n showAll: false,\r\n showBounds: true,\r\n boundsColor: Color.Yellow\r\n };\r\n /**\r\n * Collider component debug settings\r\n */\r\n this.collider = {\r\n showAll: false,\r\n showBounds: true,\r\n boundsColor: Color.Blue,\r\n showOwner: false,\r\n showGeometry: true,\r\n geometryColor: Color.Green\r\n };\r\n /**\r\n * Physics simulation debug settings\r\n */\r\n this.physics = {\r\n showAll: false,\r\n showBroadphaseSpacePartitionDebug: false,\r\n showCollisionNormals: false,\r\n collisionNormalColor: Color.Cyan,\r\n showCollisionContacts: true,\r\n collisionContactColor: Color.Red\r\n };\r\n /**\r\n * Motion component debug settings\r\n */\r\n this.motion = {\r\n showAll: false,\r\n showVelocity: false,\r\n velocityColor: Color.Yellow,\r\n showAcceleration: false,\r\n accelerationColor: Color.Red\r\n };\r\n /**\r\n * Body component debug settings\r\n */\r\n this.body = {\r\n showAll: false,\r\n showCollisionGroup: false,\r\n showCollisionType: false,\r\n showSleeping: false,\r\n showMotion: false,\r\n showMass: false\r\n };\r\n /**\r\n * Camera debug settings\r\n */\r\n this.camera = {\r\n showAll: false,\r\n showFocus: false,\r\n focusColor: Color.Red,\r\n showZoom: false\r\n };\r\n this._engine = engine;\r\n this.colorBlindMode = new ColorBlindFlags(this._engine);\r\n }\r\n /**\r\n * Switch the current excalibur clock with the [[TestClock]] and return\r\n * it in the same running state.\r\n *\r\n * This is useful when you need to debug frame by frame.\r\n */\r\n useTestClock() {\r\n const clock = this._engine.clock;\r\n const wasRunning = clock.isRunning();\r\n clock.stop();\r\n const testClock = clock.toTestClock();\r\n if (wasRunning) {\r\n testClock.start();\r\n }\r\n this._engine.clock = testClock;\r\n return testClock;\r\n }\r\n /**\r\n * Switch the current excalibur clock with the [[StandardClock]] and\r\n * return it in the same running state.\r\n *\r\n * This is useful when you need to switch back to normal mode after\r\n * debugging.\r\n */\r\n useStandardClock() {\r\n const currentClock = this._engine.clock;\r\n const wasRunning = currentClock.isRunning();\r\n currentClock.stop();\r\n const standardClock = currentClock.toStandardClock();\r\n if (wasRunning) {\r\n standardClock.start();\r\n }\r\n this._engine.clock = standardClock;\r\n return standardClock;\r\n }\r\n}\r\n/**\r\n * Implementation of a frame's stats. Meant to have values copied via [[FrameStats.reset]], avoid\r\n * creating instances of this every frame.\r\n */\r\nclass FrameStats {\r\n constructor() {\r\n this._id = 0;\r\n this._delta = 0;\r\n this._fps = 0;\r\n this._actorStats = {\r\n alive: 0,\r\n killed: 0,\r\n ui: 0,\r\n get remaining() {\r\n return this.alive - this.killed;\r\n },\r\n get total() {\r\n return this.remaining + this.ui;\r\n }\r\n };\r\n this._durationStats = {\r\n update: 0,\r\n draw: 0,\r\n get total() {\r\n return this.update + this.draw;\r\n }\r\n };\r\n this._physicsStats = new PhysicsStats();\r\n this._graphicsStats = {\r\n drawCalls: 0,\r\n drawnImages: 0\r\n };\r\n }\r\n /**\r\n * Zero out values or clone other IFrameStat stats. Allows instance reuse.\r\n *\r\n * @param [otherStats] Optional stats to clone\r\n */\r\n reset(otherStats) {\r\n if (otherStats) {\r\n this.id = otherStats.id;\r\n this.delta = otherStats.delta;\r\n this.fps = otherStats.fps;\r\n this.actors.alive = otherStats.actors.alive;\r\n this.actors.killed = otherStats.actors.killed;\r\n this.actors.ui = otherStats.actors.ui;\r\n this.duration.update = otherStats.duration.update;\r\n this.duration.draw = otherStats.duration.draw;\r\n this._physicsStats.reset(otherStats.physics);\r\n this.graphics.drawCalls = otherStats.graphics.drawCalls;\r\n this.graphics.drawnImages = otherStats.graphics.drawnImages;\r\n }\r\n else {\r\n this.id = this.delta = this.fps = 0;\r\n this.actors.alive = this.actors.killed = this.actors.ui = 0;\r\n this.duration.update = this.duration.draw = 0;\r\n this._physicsStats.reset();\r\n this.graphics.drawnImages = this.graphics.drawCalls = 0;\r\n }\r\n }\r\n /**\r\n * Provides a clone of this instance.\r\n */\r\n clone() {\r\n const fs = new FrameStats();\r\n fs.reset(this);\r\n return fs;\r\n }\r\n /**\r\n * Gets the frame's id\r\n */\r\n get id() {\r\n return this._id;\r\n }\r\n /**\r\n * Sets the frame's id\r\n */\r\n set id(value) {\r\n this._id = value;\r\n }\r\n /**\r\n * Gets the frame's delta (time since last frame)\r\n */\r\n get delta() {\r\n return this._delta;\r\n }\r\n /**\r\n * Sets the frame's delta (time since last frame). Internal use only.\r\n * @internal\r\n */\r\n set delta(value) {\r\n this._delta = value;\r\n }\r\n /**\r\n * Gets the frame's frames-per-second (FPS)\r\n */\r\n get fps() {\r\n return this._fps;\r\n }\r\n /**\r\n * Sets the frame's frames-per-second (FPS). Internal use only.\r\n * @internal\r\n */\r\n set fps(value) {\r\n this._fps = value;\r\n }\r\n /**\r\n * Gets the frame's actor statistics\r\n */\r\n get actors() {\r\n return this._actorStats;\r\n }\r\n /**\r\n * Gets the frame's duration statistics\r\n */\r\n get duration() {\r\n return this._durationStats;\r\n }\r\n /**\r\n * Gets the frame's physics statistics\r\n */\r\n get physics() {\r\n return this._physicsStats;\r\n }\r\n /**\r\n * Gets the frame's graphics statistics\r\n */\r\n get graphics() {\r\n return this._graphicsStats;\r\n }\r\n}\r\nclass PhysicsStats {\r\n constructor() {\r\n this._pairs = 0;\r\n this._collisions = 0;\r\n this._contacts = new Map();\r\n this._fastBodies = 0;\r\n this._fastBodyCollisions = 0;\r\n this._broadphase = 0;\r\n this._narrowphase = 0;\r\n }\r\n /**\r\n * Zero out values or clone other IPhysicsStats stats. Allows instance reuse.\r\n *\r\n * @param [otherStats] Optional stats to clone\r\n */\r\n reset(otherStats) {\r\n if (otherStats) {\r\n this.pairs = otherStats.pairs;\r\n this.collisions = otherStats.collisions;\r\n this.contacts = otherStats.contacts;\r\n this.fastBodies = otherStats.fastBodies;\r\n this.fastBodyCollisions = otherStats.fastBodyCollisions;\r\n this.broadphase = otherStats.broadphase;\r\n this.narrowphase = otherStats.narrowphase;\r\n }\r\n else {\r\n this.pairs = this.collisions = this.fastBodies = 0;\r\n this.fastBodyCollisions = this.broadphase = this.narrowphase = 0;\r\n this.contacts.clear();\r\n }\r\n }\r\n /**\r\n * Provides a clone of this instance.\r\n */\r\n clone() {\r\n const ps = new PhysicsStats();\r\n ps.reset(this);\r\n return ps;\r\n }\r\n get pairs() {\r\n return this._pairs;\r\n }\r\n set pairs(value) {\r\n this._pairs = value;\r\n }\r\n get collisions() {\r\n return this._collisions;\r\n }\r\n set collisions(value) {\r\n this._collisions = value;\r\n }\r\n get contacts() {\r\n return this._contacts;\r\n }\r\n set contacts(contacts) {\r\n this._contacts = contacts;\r\n }\r\n get fastBodies() {\r\n return this._fastBodies;\r\n }\r\n set fastBodies(value) {\r\n this._fastBodies = value;\r\n }\r\n get fastBodyCollisions() {\r\n return this._fastBodyCollisions;\r\n }\r\n set fastBodyCollisions(value) {\r\n this._fastBodyCollisions = value;\r\n }\r\n get broadphase() {\r\n return this._broadphase;\r\n }\r\n set broadphase(value) {\r\n this._broadphase = value;\r\n }\r\n get narrowphase() {\r\n return this._narrowphase;\r\n }\r\n set narrowphase(value) {\r\n this._narrowphase = value;\r\n }\r\n}\r\n\n;// CONCATENATED MODULE: ./Util/Browser.ts\nclass BrowserComponent {\r\n on(eventName, handler) {\r\n if (this._nativeHandlers[eventName]) {\r\n this.off(eventName, this._nativeHandlers[eventName]);\r\n }\r\n this._nativeHandlers[eventName] = this._decorate(handler);\r\n this.nativeComponent.addEventListener(eventName, this._nativeHandlers[eventName]);\r\n }\r\n off(eventName, handler) {\r\n if (!handler) {\r\n handler = this._nativeHandlers[eventName];\r\n }\r\n this.nativeComponent.removeEventListener(eventName, handler);\r\n this._nativeHandlers[eventName] = null;\r\n }\r\n _decorate(handler) {\r\n return (evt) => {\r\n if (!this._paused) {\r\n handler(evt);\r\n }\r\n };\r\n }\r\n pause() {\r\n this._paused = true;\r\n }\r\n resume() {\r\n this._paused = false;\r\n }\r\n clear() {\r\n for (const event in this._nativeHandlers) {\r\n this.off(event);\r\n }\r\n }\r\n constructor(nativeComponent) {\r\n this.nativeComponent = nativeComponent;\r\n this._paused = false;\r\n this._nativeHandlers = {};\r\n }\r\n}\r\nclass BrowserEvents {\r\n constructor(_windowGlobal, _documentGlobal) {\r\n this._windowGlobal = _windowGlobal;\r\n this._documentGlobal = _documentGlobal;\r\n this._windowComponent = new BrowserComponent(this._windowGlobal);\r\n this._documentComponent = new BrowserComponent(this._documentGlobal);\r\n }\r\n get window() {\r\n return this._windowComponent;\r\n }\r\n get document() {\r\n return this._documentComponent;\r\n }\r\n pause() {\r\n this.window.pause();\r\n this.document.pause();\r\n }\r\n resume() {\r\n this.window.resume();\r\n this.document.resume();\r\n }\r\n clear() {\r\n this.window.clear();\r\n this.document.clear();\r\n }\r\n}\r\n\n;// CONCATENATED MODULE: ./Math/global-coordinates.ts\n\r\nclass GlobalCoordinates {\r\n static fromPagePosition(xOrPos, yOrEngine, engineOrUndefined) {\r\n let pageX;\r\n let pageY;\r\n let pagePos;\r\n let engine;\r\n if (arguments.length === 3) {\r\n pageX = xOrPos;\r\n pageY = yOrEngine;\r\n pagePos = new Vector(pageX, pageY);\r\n engine = engineOrUndefined;\r\n }\r\n else {\r\n pagePos = xOrPos;\r\n pageX = pagePos.x;\r\n pageY = pagePos.y;\r\n engine = yOrEngine;\r\n }\r\n const screenPos = engine.screen.pageToScreenCoordinates(pagePos);\r\n const worldPos = engine.screen.screenToWorldCoordinates(screenPos);\r\n return new GlobalCoordinates(worldPos, pagePos, screenPos);\r\n }\r\n constructor(worldPos, pagePos, screenPos) {\r\n this.worldPos = worldPos;\r\n this.pagePos = pagePos;\r\n this.screenPos = screenPos;\r\n }\r\n}\r\n\n;// CONCATENATED MODULE: ./Input/PointerEvent.ts\nclass PointerEvent {\r\n cancel() {\r\n this.active = false;\r\n }\r\n get pagePos() {\r\n return this.coordinates.pagePos;\r\n }\r\n get screenPos() {\r\n return this.coordinates.screenPos;\r\n }\r\n get worldPos() {\r\n return this.coordinates.worldPos;\r\n }\r\n constructor(type, pointerId, button, pointerType, coordinates, nativeEvent) {\r\n this.type = type;\r\n this.pointerId = pointerId;\r\n this.button = button;\r\n this.pointerType = pointerType;\r\n this.coordinates = coordinates;\r\n this.nativeEvent = nativeEvent;\r\n this.active = true;\r\n }\r\n ;\r\n}\r\n\n;// CONCATENATED MODULE: ./Input/WheelEvent.ts\nclass WheelEvent {\r\n cancel() {\r\n this.active = false;\r\n }\r\n constructor(x, y, pageX, pageY, screenX, screenY, index, deltaX, deltaY, deltaZ, deltaMode, ev) {\r\n this.x = x;\r\n this.y = y;\r\n this.pageX = pageX;\r\n this.pageY = pageY;\r\n this.screenX = screenX;\r\n this.screenY = screenY;\r\n this.index = index;\r\n this.deltaX = deltaX;\r\n this.deltaY = deltaY;\r\n this.deltaZ = deltaZ;\r\n this.deltaMode = deltaMode;\r\n this.ev = ev;\r\n this.active = true;\r\n }\r\n}\r\n\n;// CONCATENATED MODULE: ./Input/PointerAbstraction.ts\n\r\n\r\nclass PointerAbstraction {\r\n constructor() {\r\n this.events = new EventEmitter();\r\n /**\r\n * The last position on the document this pointer was at. Can be `null` if pointer was never active.\r\n */\r\n this.lastPagePos = Vector.Zero;\r\n /**\r\n * The last position on the screen this pointer was at. Can be `null` if pointer was never active.\r\n */\r\n this.lastScreenPos = Vector.Zero;\r\n /**\r\n * The last position in the game world coordinates this pointer was at. Can be `null` if pointer was never active.\r\n */\r\n this.lastWorldPos = Vector.Zero;\r\n this._onPointerMove = (ev) => {\r\n this.lastPagePos = new Vector(ev.pagePos.x, ev.pagePos.y);\r\n this.lastScreenPos = new Vector(ev.screenPos.x, ev.screenPos.y);\r\n this.lastWorldPos = new Vector(ev.worldPos.x, ev.worldPos.y);\r\n };\r\n this._onPointerDown = (ev) => {\r\n this.lastPagePos = new Vector(ev.pagePos.x, ev.pagePos.y);\r\n this.lastScreenPos = new Vector(ev.screenPos.x, ev.screenPos.y);\r\n this.lastWorldPos = new Vector(ev.worldPos.x, ev.worldPos.y);\r\n };\r\n this.on('move', this._onPointerMove);\r\n this.on('down', this._onPointerDown);\r\n }\r\n emit(eventName, event) {\r\n this.events.emit(eventName, event);\r\n }\r\n on(eventName, handler) {\r\n return this.events.on(eventName, handler);\r\n }\r\n once(eventName, handler) {\r\n return this.events.once(eventName, handler);\r\n }\r\n off(eventName, handler) {\r\n this.events.off(eventName, handler);\r\n }\r\n}\r\n\n;// CONCATENATED MODULE: ./Input/WheelDeltaMode.ts\nvar WheelDeltaMode;\r\n(function (WheelDeltaMode) {\r\n WheelDeltaMode[\"Pixel\"] = \"Pixel\";\r\n WheelDeltaMode[\"Line\"] = \"Line\";\r\n WheelDeltaMode[\"Page\"] = \"Page\";\r\n})(WheelDeltaMode || (WheelDeltaMode = {}));\r\n\n;// CONCATENATED MODULE: ./Input/NativePointerButton.ts\n/**\r\n * Native browser button enumeration\r\n */\r\nvar NativePointerButton;\r\n(function (NativePointerButton) {\r\n NativePointerButton[NativePointerButton[\"NoButton\"] = -1] = \"NoButton\";\r\n NativePointerButton[NativePointerButton[\"Left\"] = 0] = \"Left\";\r\n NativePointerButton[NativePointerButton[\"Middle\"] = 1] = \"Middle\";\r\n NativePointerButton[NativePointerButton[\"Right\"] = 2] = \"Right\";\r\n NativePointerButton[NativePointerButton[\"Unknown\"] = 3] = \"Unknown\";\r\n})(NativePointerButton || (NativePointerButton = {}));\r\n\n;// CONCATENATED MODULE: ./Input/PointerButton.ts\n/**\r\n * The mouse button being pressed.\r\n */\r\nvar PointerButton;\r\n(function (PointerButton) {\r\n PointerButton[\"Left\"] = \"Left\";\r\n PointerButton[\"Middle\"] = \"Middle\";\r\n PointerButton[\"Right\"] = \"Right\";\r\n PointerButton[\"Unknown\"] = \"Unknown\";\r\n PointerButton[\"NoButton\"] = \"NoButton\";\r\n})(PointerButton || (PointerButton = {}));\r\n\n;// CONCATENATED MODULE: ./Input/PointerType.ts\n/**\r\n * The type of pointer for a [[PointerEvent]].\r\n */\r\nvar PointerType;\r\n(function (PointerType) {\r\n PointerType[\"Touch\"] = \"Touch\";\r\n PointerType[\"Mouse\"] = \"Mouse\";\r\n PointerType[\"Pen\"] = \"Pen\";\r\n PointerType[\"Unknown\"] = \"Unknown\";\r\n})(PointerType || (PointerType = {}));\r\n\n;// CONCATENATED MODULE: ./Input/PointerEventReceiver.ts\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\nconst PointerEvents = {\r\n Move: 'move',\r\n Down: 'down',\r\n Up: 'up',\r\n Wheel: 'wheel'\r\n};\r\n/**\r\n * Is this event a native touch event?\r\n */\r\nfunction isTouchEvent(value) {\r\n // Guard for Safari <= 13.1\r\n return globalThis.TouchEvent && value instanceof globalThis.TouchEvent;\r\n}\r\n/**\r\n * Is this event a native pointer event\r\n */\r\nfunction isPointerEvent(value) {\r\n // Guard for Safari <= 13.1\r\n return globalThis.PointerEvent && value instanceof globalThis.PointerEvent;\r\n}\r\n/**\r\n * The PointerEventProcessor is responsible for collecting all the events from the canvas and transforming them into GlobalCoordinates\r\n */\r\nclass PointerEventReceiver {\r\n constructor(target, engine) {\r\n this.target = target;\r\n this.engine = engine;\r\n this.events = new EventEmitter();\r\n this.primary = new PointerAbstraction();\r\n this._activeNativePointerIdsToNormalized = new Map();\r\n this.lastFramePointerCoords = new Map();\r\n this.currentFramePointerCoords = new Map();\r\n this.currentFramePointerDown = new Map();\r\n this.lastFramePointerDown = new Map();\r\n this.currentFrameDown = [];\r\n this.currentFrameUp = [];\r\n this.currentFrameMove = [];\r\n this.currentFrameCancel = [];\r\n this.currentFrameWheel = [];\r\n this._pointers = [this.primary];\r\n this._boundHandle = this._handle.bind(this);\r\n this._boundWheel = this._handleWheel.bind(this);\r\n }\r\n /**\r\n * Creates a new PointerEventReceiver with a new target and engine while preserving existing pointer event\r\n * handlers.\r\n * @param target\r\n * @param engine\r\n */\r\n recreate(target, engine) {\r\n const eventReceiver = new PointerEventReceiver(target, engine);\r\n eventReceiver.primary = this.primary;\r\n eventReceiver._pointers = this._pointers;\r\n return eventReceiver;\r\n }\r\n /**\r\n * Locates a specific pointer by id, creates it if it doesn't exist\r\n * @param index\r\n */\r\n at(index) {\r\n if (index >= this._pointers.length) {\r\n // Ensure there is a pointer to retrieve\r\n for (let i = this._pointers.length - 1, max = index; i < max; i++) {\r\n this._pointers.push(new PointerAbstraction());\r\n }\r\n }\r\n return this._pointers[index];\r\n }\r\n /**\r\n * The number of pointers currently being tracked by excalibur\r\n */\r\n count() {\r\n return this._pointers.length;\r\n }\r\n /**\r\n * Is the specified pointer id down this frame\r\n * @param pointerId\r\n */\r\n isDown(pointerId) {\r\n var _a;\r\n return (_a = this.currentFramePointerDown.get(pointerId)) !== null && _a !== void 0 ? _a : false;\r\n }\r\n /**\r\n * Was the specified pointer id down last frame\r\n * @param pointerId\r\n */\r\n wasDown(pointerId) {\r\n var _a;\r\n return (_a = this.lastFramePointerDown.get(pointerId)) !== null && _a !== void 0 ? _a : false;\r\n }\r\n /**\r\n * Whether the Pointer is currently dragging.\r\n */\r\n isDragging(pointerId) {\r\n return this.isDown(pointerId);\r\n }\r\n /**\r\n * Whether the Pointer just started dragging.\r\n */\r\n isDragStart(pointerId) {\r\n return this.isDown(pointerId) && !this.wasDown(pointerId);\r\n }\r\n /**\r\n * Whether the Pointer just ended dragging.\r\n */\r\n isDragEnd(pointerId) {\r\n return !this.isDown(pointerId) && this.wasDown(pointerId);\r\n }\r\n emit(eventName, event) {\r\n this.events.emit(eventName, event);\r\n }\r\n on(eventName, handler) {\r\n return this.events.on(eventName, handler);\r\n }\r\n once(eventName, handler) {\r\n return this.events.once(eventName, handler);\r\n }\r\n off(eventName, handler) {\r\n this.events.off(eventName, handler);\r\n }\r\n /**\r\n * Called internally by excalibur\r\n *\r\n * Updates the current frame pointer info and emits raw pointer events\r\n *\r\n * This does not emit events to entities, see PointerSystem\r\n */\r\n update() {\r\n this.lastFramePointerDown = new Map(this.currentFramePointerDown);\r\n this.lastFramePointerCoords = new Map(this.currentFramePointerCoords);\r\n for (const event of this.currentFrameDown) {\r\n this.emit('down', event);\r\n const pointer = this.at(event.pointerId);\r\n pointer.emit('down', event);\r\n this.primary.emit('pointerdown', event);\r\n }\r\n for (const event of this.currentFrameUp) {\r\n this.emit('up', event);\r\n const pointer = this.at(event.pointerId);\r\n pointer.emit('up', event);\r\n }\r\n for (const event of this.currentFrameMove) {\r\n this.emit('move', event);\r\n const pointer = this.at(event.pointerId);\r\n pointer.emit('move', event);\r\n }\r\n for (const event of this.currentFrameCancel) {\r\n this.emit('cancel', event);\r\n const pointer = this.at(event.pointerId);\r\n pointer.emit('cancel', event);\r\n }\r\n for (const event of this.currentFrameWheel) {\r\n this.emit('wheel', event);\r\n this.primary.emit('pointerwheel', event);\r\n }\r\n }\r\n /**\r\n * Clears the current frame event and pointer data\r\n */\r\n clear() {\r\n for (const event of this.currentFrameUp) {\r\n this.currentFramePointerCoords.delete(event.pointerId);\r\n const ids = this._activeNativePointerIdsToNormalized.entries();\r\n for (const [native, normalized] of ids) {\r\n if (normalized === event.pointerId) {\r\n this._activeNativePointerIdsToNormalized.delete(native);\r\n }\r\n }\r\n }\r\n this.currentFrameDown.length = 0;\r\n this.currentFrameUp.length = 0;\r\n this.currentFrameMove.length = 0;\r\n this.currentFrameCancel.length = 0;\r\n this.currentFrameWheel.length = 0;\r\n }\r\n /**\r\n * Initializes the pointer event receiver so that it can start listening to native\r\n * browser events.\r\n */\r\n init(options) {\r\n var _a;\r\n // Disabling the touch action avoids browser/platform gestures from firing on the canvas\r\n // It is important on mobile to have touch action 'none'\r\n // https://stackoverflow.com/questions/48124372/pointermove-event-not-working-with-touch-why-not\r\n if (this.target === this.engine.canvas) {\r\n this.engine.canvas.style.touchAction = 'none';\r\n }\r\n else {\r\n document.body.style.touchAction = 'none';\r\n }\r\n // Preferred pointer events\r\n if (window.PointerEvent) {\r\n this.target.addEventListener('pointerdown', this._boundHandle);\r\n this.target.addEventListener('pointerup', this._boundHandle);\r\n this.target.addEventListener('pointermove', this._boundHandle);\r\n this.target.addEventListener('pointercancel', this._boundHandle);\r\n }\r\n else {\r\n // Touch Events\r\n this.target.addEventListener('touchstart', this._boundHandle);\r\n this.target.addEventListener('touchend', this._boundHandle);\r\n this.target.addEventListener('touchmove', this._boundHandle);\r\n this.target.addEventListener('touchcancel', this._boundHandle);\r\n // Mouse Events\r\n this.target.addEventListener('mousedown', this._boundHandle);\r\n this.target.addEventListener('mouseup', this._boundHandle);\r\n this.target.addEventListener('mousemove', this._boundHandle);\r\n }\r\n // MDN MouseWheelEvent\r\n const wheelOptions = {\r\n passive: !(this.engine.pageScrollPreventionMode === ScrollPreventionMode.All ||\r\n this.engine.pageScrollPreventionMode === ScrollPreventionMode.Canvas)\r\n };\r\n if ('onwheel' in document.createElement('div')) {\r\n // Modern Browsers\r\n this.target.addEventListener('wheel', this._boundWheel, wheelOptions);\r\n }\r\n else if (document.onmousewheel !== undefined) {\r\n // Webkit and IE\r\n this.target.addEventListener('mousewheel', this._boundWheel, wheelOptions);\r\n }\r\n else {\r\n // Remaining browser and older Firefox\r\n this.target.addEventListener('MozMousePixelScroll', this._boundWheel, wheelOptions);\r\n }\r\n const grabWindowFocus = (_a = options === null || options === void 0 ? void 0 : options.grabWindowFocus) !== null && _a !== void 0 ? _a : true;\r\n // Handle cross origin iframe\r\n if (grabWindowFocus && isCrossOriginIframe()) {\r\n const grabFocus = () => {\r\n window.focus();\r\n };\r\n // Preferred pointer events\r\n if (window.PointerEvent) {\r\n this.target.addEventListener('pointerdown', grabFocus);\r\n }\r\n else {\r\n // Touch Events\r\n this.target.addEventListener('touchstart', grabFocus);\r\n // Mouse Events\r\n this.target.addEventListener('mousedown', grabFocus);\r\n }\r\n }\r\n }\r\n detach() {\r\n // Preferred pointer events\r\n if (window.PointerEvent) {\r\n this.target.removeEventListener('pointerdown', this._boundHandle);\r\n this.target.removeEventListener('pointerup', this._boundHandle);\r\n this.target.removeEventListener('pointermove', this._boundHandle);\r\n this.target.removeEventListener('pointercancel', this._boundHandle);\r\n }\r\n else {\r\n // Touch Events\r\n this.target.removeEventListener('touchstart', this._boundHandle);\r\n this.target.removeEventListener('touchend', this._boundHandle);\r\n this.target.removeEventListener('touchmove', this._boundHandle);\r\n this.target.removeEventListener('touchcancel', this._boundHandle);\r\n // Mouse Events\r\n this.target.removeEventListener('mousedown', this._boundHandle);\r\n this.target.removeEventListener('mouseup', this._boundHandle);\r\n this.target.removeEventListener('mousemove', this._boundHandle);\r\n }\r\n if ('onwheel' in document.createElement('div')) {\r\n // Modern Browsers\r\n this.target.removeEventListener('wheel', this._boundWheel);\r\n }\r\n else if (document.onmousewheel !== undefined) {\r\n // Webkit and IE\r\n this.target.addEventListener('mousewheel', this._boundWheel);\r\n }\r\n else {\r\n // Remaining browser and older Firefox\r\n this.target.addEventListener('MozMousePixelScroll', this._boundWheel);\r\n }\r\n }\r\n /**\r\n * Take native pointer id and map it to index in active pointers\r\n * @param nativePointerId\r\n */\r\n _normalizePointerId(nativePointerId) {\r\n // Add to the the native pointer set id\r\n this._activeNativePointerIdsToNormalized.set(nativePointerId, -1);\r\n // Native pointer ids in ascending order\r\n const currentPointerIds = Array.from(this._activeNativePointerIdsToNormalized.keys()).sort((a, b) => a - b);\r\n // The index into sorted ids will be the new id, will always have an id\r\n const id = currentPointerIds.findIndex(p => p === nativePointerId);\r\n // Save the mapping so we can reverse it later\r\n this._activeNativePointerIdsToNormalized.set(nativePointerId, id);\r\n // ignore pointer because game isn't watching\r\n return id;\r\n }\r\n /**\r\n * Responsible for handling and parsing pointer events\r\n */\r\n _handle(ev) {\r\n ev.preventDefault();\r\n const eventCoords = new Map();\r\n let button;\r\n let pointerType;\r\n if (isTouchEvent(ev)) {\r\n button = PointerButton.Unknown;\r\n pointerType = PointerType.Touch;\r\n // https://developer.mozilla.org/en-US/docs/Web/API/TouchEvent\r\n for (let i = 0; i < ev.changedTouches.length; i++) {\r\n const touch = ev.changedTouches[i];\r\n const coordinates = GlobalCoordinates.fromPagePosition(touch.pageX, touch.pageY, this.engine);\r\n const nativePointerId = i + 1;\r\n const pointerId = this._normalizePointerId(nativePointerId);\r\n this.currentFramePointerCoords.set(pointerId, coordinates);\r\n eventCoords.set(pointerId, coordinates);\r\n }\r\n }\r\n else {\r\n button = this._nativeButtonToPointerButton(ev.button);\r\n pointerType = PointerType.Mouse;\r\n const coordinates = GlobalCoordinates.fromPagePosition(ev.pageX, ev.pageY, this.engine);\r\n let nativePointerId = 1;\r\n if (isPointerEvent(ev)) {\r\n nativePointerId = ev.pointerId;\r\n pointerType = this._stringToPointerType(ev.pointerType);\r\n }\r\n const pointerId = this._normalizePointerId(nativePointerId);\r\n this.currentFramePointerCoords.set(pointerId, coordinates);\r\n eventCoords.set(pointerId, coordinates);\r\n }\r\n for (const [pointerId, coord] of eventCoords.entries()) {\r\n switch (ev.type) {\r\n case 'mousedown':\r\n case 'pointerdown':\r\n case 'touchstart':\r\n this.currentFrameDown.push(new PointerEvent('down', pointerId, button, pointerType, coord, ev));\r\n this.currentFramePointerDown.set(pointerId, true);\r\n break;\r\n case 'mouseup':\r\n case 'pointerup':\r\n case 'touchend':\r\n this.currentFrameUp.push(new PointerEvent('up', pointerId, button, pointerType, coord, ev));\r\n this.currentFramePointerDown.set(pointerId, false);\r\n break;\r\n case 'mousemove':\r\n case 'pointermove':\r\n case 'touchmove':\r\n this.currentFrameMove.push(new PointerEvent('move', pointerId, button, pointerType, coord, ev));\r\n break;\r\n case 'touchcancel':\r\n case 'pointercancel':\r\n this.currentFrameCancel.push(new PointerEvent('cancel', pointerId, button, pointerType, coord, ev));\r\n break;\r\n }\r\n }\r\n }\r\n _handleWheel(ev) {\r\n // Should we prevent page scroll because of this event\r\n if (this.engine.pageScrollPreventionMode === ScrollPreventionMode.All ||\r\n (this.engine.pageScrollPreventionMode === ScrollPreventionMode.Canvas && ev.target === this.engine.canvas)) {\r\n ev.preventDefault();\r\n }\r\n const screen = this.engine.screen.pageToScreenCoordinates(vec(ev.pageX, ev.pageY));\r\n const world = this.engine.screen.screenToWorldCoordinates(screen);\r\n /**\r\n * A constant used to normalize wheel events across different browsers\r\n *\r\n * This normalization factor is pulled from\r\n * https://developer.mozilla.org/en-US/docs/Web/Events/wheel#Listening_to_this_event_across_browser\r\n */\r\n const ScrollWheelNormalizationFactor = -1 / 40;\r\n const deltaX = ev.deltaX || ev.wheelDeltaX * ScrollWheelNormalizationFactor || 0;\r\n const deltaY = ev.deltaY || ev.wheelDeltaY * ScrollWheelNormalizationFactor || ev.wheelDelta * ScrollWheelNormalizationFactor || ev.detail || 0;\r\n const deltaZ = ev.deltaZ || 0;\r\n let deltaMode = WheelDeltaMode.Pixel;\r\n if (ev.deltaMode) {\r\n if (ev.deltaMode === 1) {\r\n deltaMode = WheelDeltaMode.Line;\r\n }\r\n else if (ev.deltaMode === 2) {\r\n deltaMode = WheelDeltaMode.Page;\r\n }\r\n }\r\n const we = new WheelEvent(world.x, world.y, ev.pageX, ev.pageY, screen.x, screen.y, 0, deltaX, deltaY, deltaZ, deltaMode, ev);\r\n this.currentFrameWheel.push(we);\r\n }\r\n /**\r\n * Triggers an excalibur pointer event in a world space pos\r\n *\r\n * Useful for testing pointers in excalibur\r\n * @param type\r\n * @param pos\r\n */\r\n triggerEvent(type, pos) {\r\n const page = this.engine.screen.worldToPageCoordinates(pos);\r\n // Send an event to the event receiver\r\n if (window.PointerEvent) {\r\n this._handle(new window.PointerEvent('pointer' + type, {\r\n pointerId: 0,\r\n clientX: page.x,\r\n clientY: page.y\r\n }));\r\n }\r\n else {\r\n // Safari hack\r\n this._handle(new window.MouseEvent('mouse' + type, {\r\n clientX: page.x,\r\n clientY: page.y\r\n }));\r\n }\r\n // Force update pointer system\r\n const pointerSystem = this.engine.currentScene.world.systemManager.get(PointerSystem);\r\n const transformEntities = this.engine.currentScene.world.queryManager.createQuery(pointerSystem.types);\r\n pointerSystem.preupdate();\r\n pointerSystem.update(transformEntities.getEntities());\r\n }\r\n _nativeButtonToPointerButton(s) {\r\n switch (s) {\r\n case NativePointerButton.NoButton:\r\n return PointerButton.NoButton;\r\n case NativePointerButton.Left:\r\n return PointerButton.Left;\r\n case NativePointerButton.Middle:\r\n return PointerButton.Middle;\r\n case NativePointerButton.Right:\r\n return PointerButton.Right;\r\n case NativePointerButton.Unknown:\r\n return PointerButton.Unknown;\r\n default:\r\n return fail(s);\r\n }\r\n }\r\n _stringToPointerType(s) {\r\n switch (s) {\r\n case 'touch':\r\n return PointerType.Touch;\r\n case 'mouse':\r\n return PointerType.Mouse;\r\n case 'pen':\r\n return PointerType.Pen;\r\n default:\r\n return PointerType.Unknown;\r\n }\r\n }\r\n}\r\n\n;// CONCATENATED MODULE: ./Util/Fps.ts\nclass FpsSampler {\r\n constructor(options) {\r\n var _a;\r\n this._samplePeriod = 100;\r\n this._currentFrameTime = 0;\r\n this._frames = 0;\r\n this._previousSampleTime = 0;\r\n this._beginFrameTime = 0;\r\n this._fps = options.initialFps;\r\n this._samplePeriod = (_a = options.samplePeriod) !== null && _a !== void 0 ? _a : this._samplePeriod;\r\n this._currentFrameTime = 1000 / options.initialFps;\r\n this._nowFn = options.nowFn;\r\n this._previousSampleTime = this._nowFn();\r\n }\r\n /**\r\n * Start of code block to sample FPS for\r\n */\r\n start() {\r\n this._beginFrameTime = this._nowFn();\r\n }\r\n /**\r\n * End of code block to sample FPS for\r\n */\r\n end() {\r\n this._frames++;\r\n const time = this._nowFn();\r\n this._currentFrameTime = time - this._beginFrameTime;\r\n if (time >= this._previousSampleTime + this._samplePeriod) {\r\n this._fps = (this._frames * 1000) / (time - this._previousSampleTime);\r\n this._previousSampleTime = time;\r\n this._frames = 0;\r\n }\r\n }\r\n /**\r\n * Return the currently sampled fps over the last sample period, by default every 100ms\r\n */\r\n get fps() {\r\n return this._fps;\r\n }\r\n /**\r\n * Return the instantaneous fps, this can be less useful because it will fluctuate given the current frames time\r\n */\r\n get instant() {\r\n return 1000 / this._currentFrameTime;\r\n }\r\n}\r\n\n;// CONCATENATED MODULE: ./Util/Clock.ts\n\r\n\r\n/**\r\n * Abstract Clock is the base type of all Clocks\r\n *\r\n * It has a few opinions\r\n * 1. It manages the calculation of what \"elapsed\" time means and thus maximum fps\r\n * 2. The default timing api is implemented in now()\r\n *\r\n * To implement your own clock, extend Clock and override start/stop to start and stop the clock, then call update() with whatever\r\n * method is unique to your clock implementation.\r\n */\r\nclass Clock {\r\n constructor(options) {\r\n var _a, _b, _c;\r\n this._onFatalException = () => { };\r\n this._maxFps = Infinity;\r\n this._lastTime = 0;\r\n this._elapsed = 1;\r\n this._scheduledCbs = [];\r\n this._totalElapsed = 0;\r\n this._options = options;\r\n this.tick = options.tick;\r\n this._lastTime = (_a = this.now()) !== null && _a !== void 0 ? _a : 0;\r\n this._maxFps = (_b = options.maxFps) !== null && _b !== void 0 ? _b : this._maxFps;\r\n this._onFatalException = (_c = options.onFatalException) !== null && _c !== void 0 ? _c : this._onFatalException;\r\n this.fpsSampler = new FpsSampler({\r\n initialFps: 60,\r\n nowFn: () => this.now()\r\n });\r\n }\r\n /**\r\n * Get the elapsed time for the last completed frame\r\n */\r\n elapsed() {\r\n return this._elapsed;\r\n }\r\n /**\r\n * Get the current time in milliseconds\r\n */\r\n now() {\r\n return performance.now();\r\n }\r\n toTestClock() {\r\n const testClock = new TestClock({\r\n ...this._options,\r\n defaultUpdateMs: 16.6\r\n });\r\n return testClock;\r\n }\r\n toStandardClock() {\r\n const clock = new StandardClock({\r\n ...this._options\r\n });\r\n return clock;\r\n }\r\n setFatalExceptionHandler(handler) {\r\n this._onFatalException = handler;\r\n }\r\n /**\r\n * Schedule a callback to fire given a timeout in milliseconds using the excalibur [[Clock]]\r\n *\r\n * This is useful to use over the built in browser `setTimeout` because callbacks will be tied to the\r\n * excalibur update clock, instead of browser time, this means that callbacks wont fire if the game is\r\n * stopped or paused.\r\n *\r\n * @param cb callback to fire\r\n * @param timeoutMs Optionally specify a timeout in milliseconds from now, default is 0ms which means the next possible tick\r\n */\r\n schedule(cb, timeoutMs = 0) {\r\n // Scheduled based on internal elapsed time\r\n const scheduledTime = this._totalElapsed + timeoutMs;\r\n this._scheduledCbs.push([cb, scheduledTime]);\r\n }\r\n _runScheduledCbs() {\r\n // walk backwards to delete items as we loop\r\n for (let i = this._scheduledCbs.length - 1; i > -1; i--) {\r\n if (this._scheduledCbs[i][1] <= this._totalElapsed) {\r\n this._scheduledCbs[i][0]();\r\n this._scheduledCbs.splice(i, 1);\r\n }\r\n }\r\n }\r\n update(overrideUpdateMs) {\r\n try {\r\n this.fpsSampler.start();\r\n // Get the time to calculate time-elapsed\r\n const now = this.now();\r\n let elapsed = now - this._lastTime || 1; // first frame\r\n // Constrain fps\r\n const fpsInterval = (1000 / this._maxFps);\r\n // only run frame if enough time has elapsed\r\n if (elapsed >= fpsInterval) {\r\n let leftover = 0;\r\n if (fpsInterval !== 0) {\r\n leftover = (elapsed % fpsInterval);\r\n elapsed = elapsed - leftover; // shift elapsed to be \"in phase\" with the current loop fps\r\n }\r\n // Resolves issue #138 if the game has been paused, or blurred for\r\n // more than a 200 milliseconds, reset elapsed time to 1. This improves reliability\r\n // and provides more expected behavior when the engine comes back\r\n // into focus\r\n if (elapsed > 200) {\r\n elapsed = 1;\r\n }\r\n // tick the mainloop and run scheduled callbacks\r\n this._elapsed = overrideUpdateMs || elapsed;\r\n this._totalElapsed += this._elapsed;\r\n this._runScheduledCbs();\r\n this.tick(overrideUpdateMs || elapsed);\r\n if (fpsInterval !== 0) {\r\n this._lastTime = now - leftover;\r\n }\r\n else {\r\n this._lastTime = now;\r\n }\r\n this.fpsSampler.end();\r\n }\r\n }\r\n catch (e) {\r\n this._onFatalException(e);\r\n this.stop();\r\n }\r\n }\r\n}\r\n/**\r\n * The [[StandardClock]] implements the requestAnimationFrame browser api to run the tick()\r\n */\r\nclass StandardClock extends Clock {\r\n constructor(options) {\r\n super(options);\r\n this._running = false;\r\n }\r\n isRunning() {\r\n return this._running;\r\n }\r\n start() {\r\n if (this._running) {\r\n return;\r\n }\r\n this._running = true;\r\n const mainloop = () => {\r\n // stop the loop\r\n if (!this._running) {\r\n return;\r\n }\r\n try {\r\n // request next loop\r\n this._requestId = window.requestAnimationFrame(mainloop);\r\n this.update();\r\n }\r\n catch (e) {\r\n window.cancelAnimationFrame(this._requestId);\r\n throw e;\r\n }\r\n };\r\n // begin the first frame\r\n mainloop();\r\n }\r\n stop() {\r\n this._running = false;\r\n }\r\n}\r\n/**\r\n * The TestClock is meant for debugging interactions in excalibur that require precise timing to replicate or test\r\n */\r\nclass TestClock extends Clock {\r\n constructor(options) {\r\n super({\r\n ...options\r\n });\r\n this._logger = Logger.getInstance();\r\n this._running = false;\r\n this._currentTime = 0;\r\n this._updateMs = options.defaultUpdateMs;\r\n }\r\n /**\r\n * Get the current time in milliseconds\r\n */\r\n now() {\r\n var _a;\r\n return (_a = this._currentTime) !== null && _a !== void 0 ? _a : 0;\r\n }\r\n isRunning() {\r\n return this._running;\r\n }\r\n start() {\r\n this._running = true;\r\n }\r\n stop() {\r\n this._running = false;\r\n }\r\n /**\r\n * Manually step the clock forward 1 tick, optionally specify an elapsed time in milliseconds\r\n * @param overrideUpdateMs\r\n */\r\n step(overrideUpdateMs) {\r\n const time = overrideUpdateMs !== null && overrideUpdateMs !== void 0 ? overrideUpdateMs : this._updateMs;\r\n if (this._running) {\r\n // to be comparable to RAF this needs to be a full blown Task\r\n // For example, images cannot decode synchronously in a single step\r\n this.update(time);\r\n this._currentTime += time;\r\n }\r\n else {\r\n this._logger.warn('The clock is not running, no step will be performed');\r\n }\r\n }\r\n /**\r\n * Run a number of steps that tick the clock, optionally specify an elapsed time in milliseconds\r\n * @param numberOfSteps\r\n * @param overrideUpdateMs\r\n */\r\n run(numberOfSteps, overrideUpdateMs) {\r\n for (let i = 0; i < numberOfSteps; i++) {\r\n this.step(overrideUpdateMs !== null && overrideUpdateMs !== void 0 ? overrideUpdateMs : this._updateMs);\r\n }\r\n }\r\n}\r\n\n// EXTERNAL MODULE: ./Util/Toaster.css\nvar Util_Toaster = __webpack_require__(7379);\n;// CONCATENATED MODULE: ./Util/Toaster.ts\n\r\n/**\r\n * The Toaster is only meant to be called from inside Excalibur to display messages to players\r\n */\r\nclass Toaster {\r\n constructor() {\r\n this._toasterCss = Util_Toaster/* default */.Z.toString();\r\n this._isInitialized = false;\r\n }\r\n _initialize() {\r\n if (!this._isInitialized) {\r\n this._container = document.createElement('div');\r\n this._container.id = 'ex-toast-container';\r\n document.body.appendChild(this._container);\r\n this._isInitialized = true;\r\n this._styleBlock = document.createElement('style');\r\n this._styleBlock.textContent = this._toasterCss;\r\n document.head.appendChild(this._styleBlock);\r\n }\r\n }\r\n dispose() {\r\n this._container.parentElement.removeChild(this._container);\r\n this._styleBlock.parentElement.removeChild(this._styleBlock);\r\n this._isInitialized = false;\r\n }\r\n _createFragment(message) {\r\n const toastMessage = document.createElement('span');\r\n toastMessage.innerText = message;\r\n return toastMessage;\r\n }\r\n /**\r\n * Display a toast message to a player\r\n * @param message Text of the message, messages may have a single \"[LINK]\" to influence placement\r\n * @param linkTarget Optionally specify a link location\r\n * @param linkName Optionally specify a name for that link location\r\n */\r\n toast(message, linkTarget, linkName) {\r\n this._initialize();\r\n const toast = document.createElement('div');\r\n toast.className = 'ex-toast-message';\r\n const messageFragments = message.split('[LINK]').map(message => this._createFragment(message));\r\n if (linkTarget) {\r\n const link = document.createElement('a');\r\n link.href = linkTarget;\r\n if (linkName) {\r\n link.innerText = linkName;\r\n }\r\n else {\r\n link.innerText = linkTarget;\r\n }\r\n messageFragments.splice(1, 0, link);\r\n }\r\n // Assembly message\r\n const finalMessage = document.createElement('div');\r\n messageFragments.forEach(message => {\r\n finalMessage.appendChild(message);\r\n });\r\n toast.appendChild(finalMessage);\r\n // Dismiss button\r\n const dismissBtn = document.createElement('button');\r\n dismissBtn.innerText = 'x';\r\n dismissBtn.addEventListener('click', () => {\r\n this._container.removeChild(toast);\r\n });\r\n toast.appendChild(dismissBtn);\r\n // Escape to dismiss\r\n const keydownHandler = (evt) => {\r\n if (evt.key === 'Escape') {\r\n try {\r\n this._container.removeChild(toast);\r\n }\r\n catch (_a) {\r\n // pass\r\n }\r\n }\r\n document.removeEventListener('keydown', keydownHandler);\r\n };\r\n document.addEventListener('keydown', keydownHandler);\r\n // Insert into container\r\n const first = this._container.firstChild;\r\n this._container.insertBefore(toast, first);\r\n }\r\n}\r\n\n;// CONCATENATED MODULE: ./Input/InputMapper.ts\n/**\r\n * This allows you to map multiple inputs to specific commands! This is especially useful when\r\n * you need to allow multiple input sources to control a specific action.\r\n */\r\nclass InputMapper {\r\n constructor(inputs) {\r\n this.inputs = inputs;\r\n this._handlers = new Map();\r\n }\r\n /**\r\n * Executes the input map, called internally by Excalibur\r\n */\r\n execute() {\r\n for (const [input, command] of this._handlers.entries()) {\r\n const results = input(this.inputs);\r\n if (results) {\r\n command(results);\r\n }\r\n }\r\n }\r\n /**\r\n * This allows you to map multiple inputs to specific commands! This is useful\r\n *\r\n * The inputHandler should return a truthy value if you wish the commandHandler to fire.\r\n *\r\n * Example:\r\n * ```typescript\r\n * const moveRight = (amount: number) => { actor.vel.x = 100 * amount }\r\n * const moveLeft = (amount: number) => { actor.vel.x = -100 * amount }\r\n * const moveUp = (amount: number) => { actor.vel.y = -100 * amount }\r\n * const moveDown = (amount: number) => { actor.vel.y = 100 * amount }\r\n *\r\n * engine.inputMapper.on(({keyboard}) => keyboard.isHeld(ex.Keys.ArrowRight) ? 1 : 0, moveRight);\r\n * engine.inputMapper.on(({gamepads}) => gamepads.at(0).isButtonPressed(ex.Buttons.DpadRight) ? 1 : 0, moveRight);\r\n * engine.inputMapper.on(({gamepads}) => gamepads.at(0).getAxes(ex.Axes.LeftStickX) > 0 ?\r\n * gamepads.at(0).getAxes(ex.Axes.LeftStickX) : 0, moveRight);\r\n * ```\r\n * @param inputHandler\r\n * @param commandHandler\r\n */\r\n on(inputHandler, commandHandler) {\r\n this._handlers.set(inputHandler, commandHandler);\r\n }\r\n}\r\n\n;// CONCATENATED MODULE: ./Engine.ts\n\r\n\r\n\r\n\r\n\r\n\r\n\r\npolyfill();\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\nconst EngineEvents = {\r\n FallbackGraphicsContext: 'fallbackgraphicscontext',\r\n Initialize: 'initialize',\r\n Visible: 'visible',\r\n Hidden: 'hidden',\r\n Start: 'start',\r\n Stop: 'stop',\r\n PreUpdate: 'preupdate',\r\n PostUpdate: 'postupdate',\r\n PreFrame: 'preframe',\r\n PostFrame: 'postframe',\r\n PreDraw: 'predraw',\r\n PostDraw: 'postdraw'\r\n};\r\n/**\r\n * Enum representing the different mousewheel event bubble prevention\r\n */\r\nvar ScrollPreventionMode;\r\n(function (ScrollPreventionMode) {\r\n /**\r\n * Do not prevent any page scrolling\r\n */\r\n ScrollPreventionMode[ScrollPreventionMode[\"None\"] = 0] = \"None\";\r\n /**\r\n * Prevent page scroll if mouse is over the game canvas\r\n */\r\n ScrollPreventionMode[ScrollPreventionMode[\"Canvas\"] = 1] = \"Canvas\";\r\n /**\r\n * Prevent all page scrolling via mouse wheel\r\n */\r\n ScrollPreventionMode[ScrollPreventionMode[\"All\"] = 2] = \"All\";\r\n})(ScrollPreventionMode || (ScrollPreventionMode = {}));\r\n/**\r\n * The Excalibur Engine\r\n *\r\n * The [[Engine]] is the main driver for a game. It is responsible for\r\n * starting/stopping the game, maintaining state, transmitting events,\r\n * loading resources, and managing the scene.\r\n */\r\nclass Engine {\r\n /**\r\n * The width of the game canvas in pixels (physical width component of the\r\n * resolution of the canvas element)\r\n */\r\n get canvasWidth() {\r\n return this.screen.canvasWidth;\r\n }\r\n /**\r\n * Returns half width of the game canvas in pixels (half physical width component)\r\n */\r\n get halfCanvasWidth() {\r\n return this.screen.halfCanvasWidth;\r\n }\r\n /**\r\n * The height of the game canvas in pixels, (physical height component of\r\n * the resolution of the canvas element)\r\n */\r\n get canvasHeight() {\r\n return this.screen.canvasHeight;\r\n }\r\n /**\r\n * Returns half height of the game canvas in pixels (half physical height component)\r\n */\r\n get halfCanvasHeight() {\r\n return this.screen.halfCanvasHeight;\r\n }\r\n /**\r\n * Returns the width of the engine's visible drawing surface in pixels including zoom and device pixel ratio.\r\n */\r\n get drawWidth() {\r\n return this.screen.drawWidth;\r\n }\r\n /**\r\n * Returns half the width of the engine's visible drawing surface in pixels including zoom and device pixel ratio.\r\n */\r\n get halfDrawWidth() {\r\n return this.screen.halfDrawWidth;\r\n }\r\n /**\r\n * Returns the height of the engine's visible drawing surface in pixels including zoom and device pixel ratio.\r\n */\r\n get drawHeight() {\r\n return this.screen.drawHeight;\r\n }\r\n /**\r\n * Returns half the height of the engine's visible drawing surface in pixels including zoom and device pixel ratio.\r\n */\r\n get halfDrawHeight() {\r\n return this.screen.halfDrawHeight;\r\n }\r\n /**\r\n * Returns whether excalibur detects the current screen to be HiDPI\r\n */\r\n get isHiDpi() {\r\n return this.screen.isHiDpi;\r\n }\r\n /**\r\n * Access [[stats]] that holds frame statistics.\r\n */\r\n get stats() {\r\n return this.debug.stats;\r\n }\r\n /**\r\n * Indicates whether the engine is set to fullscreen or not\r\n */\r\n get isFullscreen() {\r\n return this.screen.isFullScreen;\r\n }\r\n /**\r\n * Indicates the current [[DisplayMode]] of the engine.\r\n */\r\n get displayMode() {\r\n return this.screen.displayMode;\r\n }\r\n /**\r\n * Returns the calculated pixel ration for use in rendering\r\n */\r\n get pixelRatio() {\r\n return this.screen.pixelRatio;\r\n }\r\n get isDebug() {\r\n return this._isDebug;\r\n }\r\n /**\r\n * Hints the graphics context to truncate fractional world space coordinates\r\n */\r\n get snapToPixel() {\r\n return this.graphicsContext.snapToPixel;\r\n }\r\n ;\r\n set snapToPixel(shouldSnapToPixel) {\r\n this.graphicsContext.snapToPixel = shouldSnapToPixel;\r\n }\r\n ;\r\n emit(eventName, event) {\r\n this.events.emit(eventName, event);\r\n }\r\n on(eventName, handler) {\r\n return this.events.on(eventName, handler);\r\n }\r\n once(eventName, handler) {\r\n return this.events.once(eventName, handler);\r\n }\r\n off(eventName, handler) {\r\n this.events.off(eventName, handler);\r\n }\r\n /**\r\n * Creates a new game using the given [[EngineOptions]]. By default, if no options are provided,\r\n * the game will be rendered full screen (taking up all available browser window space).\r\n * You can customize the game rendering through [[EngineOptions]].\r\n *\r\n * Example:\r\n *\r\n * ```js\r\n * var game = new ex.Engine({\r\n * width: 0, // the width of the canvas\r\n * height: 0, // the height of the canvas\r\n * enableCanvasTransparency: true, // the transparencySection of the canvas\r\n * canvasElementId: '', // the DOM canvas element ID, if you are providing your own\r\n * displayMode: ex.DisplayMode.FullScreen, // the display mode\r\n * pointerScope: ex.PointerScope.Document, // the scope of capturing pointer (mouse/touch) events\r\n * backgroundColor: ex.Color.fromHex('#2185d0') // background color of the engine\r\n * });\r\n *\r\n * // call game.start, which is a Promise\r\n * game.start().then(function () {\r\n * // ready, set, go!\r\n * });\r\n * ```\r\n */\r\n constructor(options) {\r\n var _a, _b, _c, _d, _e, _f;\r\n /**\r\n * Listen to and emit events on the Engine\r\n */\r\n this.events = new EventEmitter();\r\n /**\r\n * Optionally set the maximum fps if not set Excalibur will go as fast as the device allows.\r\n *\r\n * You may want to constrain max fps if your game cannot maintain fps consistently, it can look and feel better to have a 30fps game than\r\n * one that bounces between 30fps and 60fps\r\n */\r\n this.maxFps = Number.POSITIVE_INFINITY;\r\n /**\r\n * Contains all the scenes currently registered with Excalibur\r\n */\r\n this.scenes = {};\r\n this._suppressPlayButton = false;\r\n /**\r\n * Indicates whether audio should be paused when the game is no longer visible.\r\n */\r\n this.pauseAudioWhenHidden = true;\r\n /**\r\n * Indicates whether the engine should draw with debug information\r\n */\r\n this._isDebug = false;\r\n /**\r\n * Sets the Transparency for the engine.\r\n */\r\n this.enableCanvasTransparency = true;\r\n /**\r\n * The action to take when a fatal exception is thrown\r\n */\r\n this.onFatalException = (e) => {\r\n Logger.getInstance().fatal(e);\r\n };\r\n this._toaster = new Toaster();\r\n this._timescale = 1.0;\r\n this._isInitialized = false;\r\n this._deferredGoTo = null;\r\n this._originalOptions = {};\r\n this._performanceThresholdTriggered = false;\r\n this._fpsSamples = [];\r\n this._loadingComplete = false;\r\n this._isReady = false;\r\n this._isReadyPromise = new Promise(resolve => {\r\n this._isReadyResolve = resolve;\r\n });\r\n /**\r\n * Returns the current frames elapsed milliseconds\r\n */\r\n this.currentFrameElapsedMs = 0;\r\n /**\r\n * Returns the current frame lag when in fixed update mode\r\n */\r\n this.currentFrameLagMs = 0;\r\n this._lagMs = 0;\r\n this._screenShotRequests = [];\r\n options = { ...Engine._DEFAULT_ENGINE_OPTIONS, ...options };\r\n this._originalOptions = options;\r\n Flags.freeze();\r\n // Initialize browser events facade\r\n this.browser = new BrowserEvents(window, document);\r\n // Check compatibility\r\n const detector = new Detector();\r\n if (!options.suppressMinimumBrowserFeatureDetection && !(this._compatible = detector.test())) {\r\n const message = document.createElement('div');\r\n message.innerText = 'Sorry, your browser does not support all the features needed for Excalibur';\r\n document.body.appendChild(message);\r\n detector.failedTests.forEach(function (test) {\r\n const testMessage = document.createElement('div');\r\n testMessage.innerText = 'Browser feature missing ' + test;\r\n document.body.appendChild(testMessage);\r\n });\r\n if (options.canvasElementId) {\r\n const canvas = document.getElementById(options.canvasElementId);\r\n if (canvas) {\r\n canvas.parentElement.removeChild(canvas);\r\n }\r\n }\r\n return;\r\n }\r\n else {\r\n this._compatible = true;\r\n }\r\n // Use native console API for color fun\r\n // eslint-disable-next-line no-console\r\n if (console.log && !options.suppressConsoleBootMessage) {\r\n // eslint-disable-next-line no-console\r\n console.log(`%cPowered by Excalibur.js (v${EX_VERSION})`, 'background: #176BAA; color: white; border-radius: 5px; padding: 15px; font-size: 1.5em; line-height: 80px;');\r\n // eslint-disable-next-line no-console\r\n console.log('\\n\\\r\n /| ________________\\n\\\r\nO|===|* >________________>\\n\\\r\n \\\\|');\r\n // eslint-disable-next-line no-console\r\n console.log('Visit', 'http://excaliburjs.com', 'for more information');\r\n }\r\n // Suppress play button\r\n if (options.suppressPlayButton) {\r\n this._suppressPlayButton = true;\r\n }\r\n this._logger = Logger.getInstance();\r\n // If debug is enabled, let's log browser features to the console.\r\n if (this._logger.defaultLevel === LogLevel.Debug) {\r\n detector.logBrowserFeatures();\r\n }\r\n this._logger.debug('Building engine...');\r\n this.canvasElementId = options.canvasElementId;\r\n if (options.canvasElementId) {\r\n this._logger.debug('Using Canvas element specified: ' + options.canvasElementId);\r\n this.canvas = document.getElementById(options.canvasElementId);\r\n }\r\n else if (options.canvasElement) {\r\n this._logger.debug('Using Canvas element specified:', options.canvasElement);\r\n this.canvas = options.canvasElement;\r\n }\r\n else {\r\n this._logger.debug('Using generated canvas element');\r\n this.canvas = document.createElement('canvas');\r\n }\r\n let displayMode = (_a = options.displayMode) !== null && _a !== void 0 ? _a : DisplayMode.Fixed;\r\n if ((options.width && options.height) || options.viewport) {\r\n if (options.displayMode === undefined) {\r\n displayMode = DisplayMode.Fixed;\r\n }\r\n this._logger.debug('Engine viewport is size ' + options.width + ' x ' + options.height);\r\n }\r\n else if (!options.displayMode) {\r\n this._logger.debug('Engine viewport is fit');\r\n displayMode = DisplayMode.FitScreen;\r\n }\r\n this._originalDisplayMode = displayMode;\r\n // Canvas 2D fallback can be flagged on\r\n let useCanvasGraphicsContext = Flags.isEnabled('use-canvas-context');\r\n if (!useCanvasGraphicsContext) {\r\n // Attempt webgl first\r\n try {\r\n this.graphicsContext = new ExcaliburGraphicsContextWebGL({\r\n canvasElement: this.canvas,\r\n enableTransparency: this.enableCanvasTransparency,\r\n smoothing: options.antialiasing,\r\n backgroundColor: options.backgroundColor,\r\n snapToPixel: options.snapToPixel,\r\n useDrawSorting: options.useDrawSorting\r\n });\r\n }\r\n catch (e) {\r\n this._logger.warn(`Excalibur could not load webgl for some reason (${e.message}) and loaded a Canvas 2D fallback. ` +\r\n `Some features of Excalibur will not work in this mode. \\n\\n` +\r\n 'Read more about this issue at https://excaliburjs.com/docs/webgl');\r\n // fallback to canvas in case of failure\r\n useCanvasGraphicsContext = true;\r\n }\r\n }\r\n if (useCanvasGraphicsContext) {\r\n this.graphicsContext = new ExcaliburGraphicsContext2DCanvas({\r\n canvasElement: this.canvas,\r\n enableTransparency: this.enableCanvasTransparency,\r\n smoothing: options.antialiasing,\r\n backgroundColor: options.backgroundColor,\r\n snapToPixel: options.snapToPixel,\r\n useDrawSorting: options.useDrawSorting\r\n });\r\n }\r\n this.screen = new Screen({\r\n canvas: this.canvas,\r\n context: this.graphicsContext,\r\n antialiasing: (_b = options.antialiasing) !== null && _b !== void 0 ? _b : true,\r\n browser: this.browser,\r\n viewport: (_c = options.viewport) !== null && _c !== void 0 ? _c : (options.width && options.height ? { width: options.width, height: options.height } : Resolution.SVGA),\r\n resolution: options.resolution,\r\n displayMode,\r\n pixelRatio: options.suppressHiDPIScaling ? 1 : ((_d = options.pixelRatio) !== null && _d !== void 0 ? _d : null)\r\n });\r\n // Set default filtering based on antialiasing\r\n TextureLoader.filtering = options.antialiasing ? ImageFiltering.Blended : ImageFiltering.Pixel;\r\n if (options.backgroundColor) {\r\n this.backgroundColor = options.backgroundColor.clone();\r\n }\r\n this.maxFps = (_e = options.maxFps) !== null && _e !== void 0 ? _e : this.maxFps;\r\n this.fixedUpdateFps = (_f = options.fixedUpdateFps) !== null && _f !== void 0 ? _f : this.fixedUpdateFps;\r\n this.clock = new StandardClock({\r\n maxFps: this.maxFps,\r\n tick: this._mainloop.bind(this),\r\n onFatalException: (e) => this.onFatalException(e)\r\n });\r\n this.enableCanvasTransparency = options.enableCanvasTransparency;\r\n this._loader = new Loader();\r\n this._loader.wireEngine(this);\r\n this.debug = new Debug(this);\r\n this._initialize(options);\r\n this.rootScene = this.currentScene = new Scene();\r\n this.addScene('root', this.rootScene);\r\n window.___EXCALIBUR_DEVTOOL = this;\r\n }\r\n _monitorPerformanceThresholdAndTriggerFallback() {\r\n const { allow } = this._originalOptions.configurePerformanceCanvas2DFallback;\r\n let { threshold, showPlayerMessage } = this._originalOptions.configurePerformanceCanvas2DFallback;\r\n if (threshold === undefined) {\r\n threshold = Engine._DEFAULT_ENGINE_OPTIONS.configurePerformanceCanvas2DFallback.threshold;\r\n }\r\n if (showPlayerMessage === undefined) {\r\n showPlayerMessage = Engine._DEFAULT_ENGINE_OPTIONS.configurePerformanceCanvas2DFallback.showPlayerMessage;\r\n }\r\n if (!Flags.isEnabled('use-canvas-context') && allow && this.ready && !this._performanceThresholdTriggered) {\r\n // Calculate Average fps for last X number of frames after start\r\n if (this._fpsSamples.length === threshold.numberOfFrames) {\r\n this._fpsSamples.splice(0, 1);\r\n }\r\n this._fpsSamples.push(this.clock.fpsSampler.fps);\r\n let total = 0;\r\n for (let i = 0; i < this._fpsSamples.length; i++) {\r\n total += this._fpsSamples[i];\r\n }\r\n const average = total / this._fpsSamples.length;\r\n if (this._fpsSamples.length === threshold.numberOfFrames) {\r\n if (average <= threshold.fps) {\r\n this._performanceThresholdTriggered = true;\r\n this._logger.warn(`Switching to browser 2D Canvas fallback due to performance. Some features of Excalibur will not work in this mode.\\n` +\r\n 'this might mean your browser doesn\\'t have webgl enabled or hardware acceleration is unavailable.\\n\\n' +\r\n 'If in Chrome:\\n' +\r\n ' * Visit Settings > Advanced > System, and ensure \"Use Hardware Acceleration\" is checked.\\n' +\r\n ' * Visit chrome://flags/#ignore-gpu-blocklist and ensure \"Override software rendering list\" is \"enabled\"\\n' +\r\n 'If in Firefox, visit about:config\\n' +\r\n ' * Ensure webgl.disabled = false\\n' +\r\n ' * Ensure webgl.force-enabled = true\\n' +\r\n ' * Ensure layers.acceleration.force-enabled = true\\n\\n' +\r\n 'Read more about this issue at https://excaliburjs.com/docs/performance');\r\n if (showPlayerMessage) {\r\n this._toaster.toast('Excalibur is encountering performance issues. ' +\r\n 'It\\'s possible that your browser doesn\\'t have hardware acceleration enabled. ' +\r\n 'Visit [LINK] for more information and potential solutions.', 'https://excaliburjs.com/docs/performance');\r\n }\r\n this.useCanvas2DFallback();\r\n this.emit('fallbackgraphicscontext', this.graphicsContext);\r\n }\r\n }\r\n }\r\n }\r\n /**\r\n * Switches the engine's graphics context to the 2D Canvas.\r\n * @warning Some features of Excalibur will not work in this mode.\r\n */\r\n useCanvas2DFallback() {\r\n var _a, _b, _c;\r\n // Swap out the canvas\r\n const newCanvas = this.canvas.cloneNode(false);\r\n this.canvas.parentNode.replaceChild(newCanvas, this.canvas);\r\n this.canvas = newCanvas;\r\n const options = this._originalOptions;\r\n const displayMode = this._originalDisplayMode;\r\n // New graphics context\r\n this.graphicsContext = new ExcaliburGraphicsContext2DCanvas({\r\n canvasElement: this.canvas,\r\n enableTransparency: this.enableCanvasTransparency,\r\n smoothing: options.antialiasing,\r\n backgroundColor: options.backgroundColor,\r\n snapToPixel: options.snapToPixel,\r\n useDrawSorting: options.useDrawSorting\r\n });\r\n // Reset screen\r\n if (this.screen) {\r\n this.screen.dispose();\r\n }\r\n this.screen = new Screen({\r\n canvas: this.canvas,\r\n context: this.graphicsContext,\r\n antialiasing: (_a = options.antialiasing) !== null && _a !== void 0 ? _a : true,\r\n browser: this.browser,\r\n viewport: (_b = options.viewport) !== null && _b !== void 0 ? _b : (options.width && options.height ? { width: options.width, height: options.height } : Resolution.SVGA),\r\n resolution: options.resolution,\r\n displayMode,\r\n pixelRatio: options.suppressHiDPIScaling ? 1 : ((_c = options.pixelRatio) !== null && _c !== void 0 ? _c : null)\r\n });\r\n this.screen.setCurrentCamera(this.currentScene.camera);\r\n // Reset pointers\r\n this.input.pointers.detach();\r\n const pointerTarget = options && options.pointerScope === PointerScope.Document ? document : this.canvas;\r\n this.input.pointers = this.input.pointers.recreate(pointerTarget, this);\r\n this.input.pointers.init();\r\n }\r\n /**\r\n * Returns a BoundingBox of the top left corner of the screen\r\n * and the bottom right corner of the screen.\r\n */\r\n getWorldBounds() {\r\n return this.screen.getWorldBounds();\r\n }\r\n /**\r\n * Gets the current engine timescale factor (default is 1.0 which is 1:1 time)\r\n */\r\n get timescale() {\r\n return this._timescale;\r\n }\r\n /**\r\n * Sets the current engine timescale factor. Useful for creating slow-motion effects or fast-forward effects\r\n * when using time-based movement.\r\n */\r\n set timescale(value) {\r\n if (value <= 0) {\r\n Logger.getInstance().error('Cannot set engine.timescale to a value of 0 or less than 0.');\r\n return;\r\n }\r\n this._timescale = value;\r\n }\r\n /**\r\n * Adds a [[Timer]] to the [[currentScene]].\r\n * @param timer The timer to add to the [[currentScene]].\r\n */\r\n addTimer(timer) {\r\n return this.currentScene.addTimer(timer);\r\n }\r\n /**\r\n * Removes a [[Timer]] from the [[currentScene]].\r\n * @param timer The timer to remove to the [[currentScene]].\r\n */\r\n removeTimer(timer) {\r\n return this.currentScene.removeTimer(timer);\r\n }\r\n /**\r\n * Adds a [[Scene]] to the engine, think of scenes in Excalibur as you\r\n * would levels or menus.\r\n *\r\n * @param key The name of the scene, must be unique\r\n * @param scene The scene to add to the engine\r\n */\r\n addScene(key, scene) {\r\n if (this.scenes[key]) {\r\n this._logger.warn('Scene', key, 'already exists overwriting');\r\n }\r\n this.scenes[key] = scene;\r\n }\r\n /**\r\n * @internal\r\n */\r\n removeScene(entity) {\r\n if (entity instanceof Scene) {\r\n // remove scene\r\n for (const key in this.scenes) {\r\n if (this.scenes.hasOwnProperty(key)) {\r\n if (this.scenes[key] === entity) {\r\n delete this.scenes[key];\r\n }\r\n }\r\n }\r\n }\r\n if (typeof entity === 'string') {\r\n // remove scene\r\n delete this.scenes[entity];\r\n }\r\n }\r\n add(entity) {\r\n if (arguments.length === 2) {\r\n this.addScene(arguments[0], arguments[1]);\r\n return;\r\n }\r\n if (this._deferredGoTo && this.scenes[this._deferredGoTo]) {\r\n this.scenes[this._deferredGoTo].add(entity);\r\n }\r\n else {\r\n this.currentScene.add(entity);\r\n }\r\n }\r\n remove(entity) {\r\n if (entity instanceof Entity) {\r\n this.currentScene.remove(entity);\r\n }\r\n if (entity instanceof Scene) {\r\n this.removeScene(entity);\r\n }\r\n if (typeof entity === 'string') {\r\n this.removeScene(entity);\r\n }\r\n }\r\n /**\r\n * Changes the currently updating and drawing scene to a different,\r\n * named scene. Calls the [[Scene]] lifecycle events.\r\n * @param key The key of the scene to transition to.\r\n * @param data Optional data to send to the scene's onActivate method\r\n */\r\n goToScene(key, data) {\r\n // if not yet initialized defer goToScene\r\n if (!this.isInitialized) {\r\n this._deferredGoTo = key;\r\n return;\r\n }\r\n if (this.scenes[key]) {\r\n const previousScene = this.currentScene;\r\n const nextScene = this.scenes[key];\r\n this._logger.debug('Going to scene:', key);\r\n // only deactivate when initialized\r\n if (this.currentScene.isInitialized) {\r\n const context = { engine: this, previousScene, nextScene };\r\n this.currentScene._deactivate.apply(this.currentScene, [context, nextScene]);\r\n this.currentScene.events.emit('deactivate', new DeactivateEvent(context, this.currentScene));\r\n }\r\n // set current scene to new one\r\n this.currentScene = nextScene;\r\n this.screen.setCurrentCamera(nextScene.camera);\r\n // initialize the current scene if has not been already\r\n this.currentScene._initialize(this);\r\n const context = { engine: this, previousScene, nextScene, data };\r\n this.currentScene._activate.apply(this.currentScene, [context, nextScene]);\r\n this.currentScene.events.emit('activate', new ActivateEvent(context, this.currentScene));\r\n }\r\n else {\r\n this._logger.error('Scene', key, 'does not exist!');\r\n }\r\n }\r\n /**\r\n * Transforms the current x, y from screen coordinates to world coordinates\r\n * @param point Screen coordinate to convert\r\n */\r\n screenToWorldCoordinates(point) {\r\n return this.screen.screenToWorldCoordinates(point);\r\n }\r\n /**\r\n * Transforms a world coordinate, to a screen coordinate\r\n * @param point World coordinate to convert\r\n */\r\n worldToScreenCoordinates(point) {\r\n return this.screen.worldToScreenCoordinates(point);\r\n }\r\n /**\r\n * Initializes the internal canvas, rendering context, display mode, and native event listeners\r\n */\r\n _initialize(options) {\r\n var _a, _b, _c, _d;\r\n this.pageScrollPreventionMode = options.scrollPreventionMode;\r\n // initialize inputs\r\n const pointerTarget = options && options.pointerScope === PointerScope.Document ? document : this.canvas;\r\n this.input = {\r\n keyboard: new Keyboard(),\r\n pointers: new PointerEventReceiver(pointerTarget, this),\r\n gamepads: new Gamepads()\r\n };\r\n this.input.keyboard.init({\r\n grabWindowFocus: (_b = (_a = this._originalOptions) === null || _a === void 0 ? void 0 : _a.grabWindowFocus) !== null && _b !== void 0 ? _b : true\r\n });\r\n this.input.pointers.init({\r\n grabWindowFocus: (_d = (_c = this._originalOptions) === null || _c === void 0 ? void 0 : _c.grabWindowFocus) !== null && _d !== void 0 ? _d : true\r\n });\r\n this.input.gamepads.init();\r\n this.inputMapper = new InputMapper(this.input);\r\n // Issue #385 make use of the visibility api\r\n // https://developer.mozilla.org/en-US/docs/Web/Guide/User_experience/Using_the_Page_Visibility_API\r\n this.browser.document.on('visibilitychange', () => {\r\n if (document.visibilityState === 'hidden') {\r\n this.events.emit('hidden', new HiddenEvent(this));\r\n this._logger.debug('Window hidden');\r\n }\r\n else if (document.visibilityState === 'visible') {\r\n this.events.emit('visible', new VisibleEvent(this));\r\n this._logger.debug('Window visible');\r\n }\r\n });\r\n if (!this.canvasElementId && !options.canvasElement) {\r\n document.body.appendChild(this.canvas);\r\n }\r\n }\r\n onInitialize(_engine) {\r\n // Override me\r\n }\r\n /**\r\n * If supported by the browser, this will set the antialiasing flag on the\r\n * canvas. Set this to `false` if you want a 'jagged' pixel art look to your\r\n * image resources.\r\n * @param isSmooth Set smoothing to true or false\r\n */\r\n setAntialiasing(isSmooth) {\r\n this.screen.antialiasing = isSmooth;\r\n }\r\n /**\r\n * Return the current smoothing status of the canvas\r\n */\r\n getAntialiasing() {\r\n return this.screen.antialiasing;\r\n }\r\n /**\r\n * Gets whether the actor is Initialized\r\n */\r\n get isInitialized() {\r\n return this._isInitialized;\r\n }\r\n _overrideInitialize(engine) {\r\n if (!this.isInitialized) {\r\n this.onInitialize(engine);\r\n this.events.emit('initialize', new InitializeEvent(engine, this));\r\n this._isInitialized = true;\r\n if (this._deferredGoTo) {\r\n const deferredScene = this._deferredGoTo;\r\n this._deferredGoTo = null;\r\n this.goToScene(deferredScene);\r\n }\r\n else {\r\n this.goToScene('root');\r\n }\r\n }\r\n }\r\n /**\r\n * Updates the entire state of the game\r\n * @param delta Number of milliseconds elapsed since the last update.\r\n */\r\n _update(delta) {\r\n if (!this.ready) {\r\n // suspend updates until loading is finished\r\n this._loader.update(this, delta);\r\n // Update input listeners\r\n this.input.keyboard.update();\r\n this.input.gamepads.update();\r\n this.inputMapper.execute();\r\n return;\r\n }\r\n // Publish preupdate events\r\n this._preupdate(delta);\r\n // process engine level events\r\n this.currentScene.update(this, delta);\r\n // Update graphics postprocessors\r\n this.graphicsContext.updatePostProcessors(delta);\r\n // Publish update event\r\n this._postupdate(delta);\r\n // Update input listeners\r\n this.input.keyboard.update();\r\n this.input.gamepads.update();\r\n this.inputMapper.execute();\r\n }\r\n /**\r\n * @internal\r\n */\r\n _preupdate(delta) {\r\n this.emit('preupdate', new PreUpdateEvent(this, delta, this));\r\n this.onPreUpdate(this, delta);\r\n }\r\n onPreUpdate(_engine, _delta) {\r\n // Override me\r\n }\r\n /**\r\n * @internal\r\n */\r\n _postupdate(delta) {\r\n this.emit('postupdate', new PostUpdateEvent(this, delta, this));\r\n this.onPostUpdate(this, delta);\r\n }\r\n onPostUpdate(_engine, _delta) {\r\n // Override me\r\n }\r\n /**\r\n * Draws the entire game\r\n * @param delta Number of milliseconds elapsed since the last draw.\r\n */\r\n _draw(delta) {\r\n this.graphicsContext.beginDrawLifecycle();\r\n this.graphicsContext.clear();\r\n this._predraw(this.graphicsContext, delta);\r\n // Drawing nothing else while loading\r\n if (!this._isReady) {\r\n this._loader.canvas.draw(this.graphicsContext, 0, 0);\r\n this.graphicsContext.flush();\r\n return;\r\n }\r\n this.graphicsContext.backgroundColor = this.backgroundColor;\r\n this.currentScene.draw(this.graphicsContext, delta);\r\n this._postdraw(this.graphicsContext, delta);\r\n // Flush any pending drawings\r\n this.graphicsContext.flush();\r\n this.graphicsContext.endDrawLifecycle();\r\n this._checkForScreenShots();\r\n }\r\n /**\r\n * @internal\r\n */\r\n _predraw(_ctx, delta) {\r\n this.emit('predraw', new PreDrawEvent(_ctx, delta, this));\r\n this.onPreDraw(_ctx, delta);\r\n }\r\n onPreDraw(_ctx, _delta) {\r\n // Override me\r\n }\r\n /**\r\n * @internal\r\n */\r\n _postdraw(_ctx, delta) {\r\n this.emit('postdraw', new PostDrawEvent(_ctx, delta, this));\r\n this.onPostDraw(_ctx, delta);\r\n }\r\n onPostDraw(_ctx, _delta) {\r\n // Override me\r\n }\r\n /**\r\n * Enable or disable Excalibur debugging functionality.\r\n * @param toggle a value that debug drawing will be changed to\r\n */\r\n showDebug(toggle) {\r\n this._isDebug = toggle;\r\n }\r\n /**\r\n * Toggle Excalibur debugging functionality.\r\n */\r\n toggleDebug() {\r\n this._isDebug = !this._isDebug;\r\n return this._isDebug;\r\n }\r\n /**\r\n * Returns true when loading is totally complete and the player has clicked start\r\n */\r\n get loadingComplete() {\r\n return this._loadingComplete;\r\n }\r\n get ready() {\r\n return this._isReady;\r\n }\r\n isReady() {\r\n return this._isReadyPromise;\r\n }\r\n /**\r\n * Starts the internal game loop for Excalibur after loading\r\n * any provided assets.\r\n * @param loader Optional [[Loader]] to use to load resources. The default loader is [[Loader]], override to provide your own\r\n * custom loader.\r\n *\r\n * Note: start() only resolves AFTER the user has clicked the play button\r\n */\r\n async start(loader) {\r\n if (!this._compatible) {\r\n throw new Error('Excalibur is incompatible with your browser');\r\n }\r\n // Wire loader if we have it\r\n if (loader) {\r\n // Push the current user entered resolution/viewport\r\n this.screen.pushResolutionAndViewport();\r\n // Configure resolution for loader, it expects resolution === viewport\r\n this.screen.resolution = this.screen.viewport;\r\n this.screen.applyResolutionAndViewport();\r\n this._loader = loader;\r\n this._loader.suppressPlayButton = this._suppressPlayButton || this._loader.suppressPlayButton;\r\n this._loader.wireEngine(this);\r\n }\r\n // Start the excalibur clock which drives the mainloop\r\n // has started is a slight misnomer, it's really mainloop started\r\n this._logger.debug('Starting game clock...');\r\n this.browser.resume();\r\n this.clock.start();\r\n this._logger.debug('Game clock started');\r\n if (loader) {\r\n await this.load(this._loader);\r\n this._loadingComplete = true;\r\n // reset back to previous user resolution/viewport\r\n this.screen.popResolutionAndViewport();\r\n this.screen.applyResolutionAndViewport();\r\n }\r\n this._loadingComplete = true;\r\n // Initialize before ready\r\n this._overrideInitialize(this);\r\n this._isReady = true;\r\n this._isReadyResolve();\r\n this.emit('start', new GameStartEvent(this));\r\n return this._isReadyPromise;\r\n }\r\n _mainloop(elapsed) {\r\n this.emit('preframe', new PreFrameEvent(this, this.stats.prevFrame));\r\n const delta = elapsed * this.timescale;\r\n this.currentFrameElapsedMs = delta;\r\n // reset frame stats (reuse existing instances)\r\n const frameId = this.stats.prevFrame.id + 1;\r\n this.stats.currFrame.reset();\r\n this.stats.currFrame.id = frameId;\r\n this.stats.currFrame.delta = delta;\r\n this.stats.currFrame.fps = this.clock.fpsSampler.fps;\r\n GraphicsDiagnostics.clear();\r\n const beforeUpdate = this.clock.now();\r\n const fixedTimestepMs = 1000 / this.fixedUpdateFps;\r\n if (this.fixedUpdateFps) {\r\n this._lagMs += delta;\r\n while (this._lagMs >= fixedTimestepMs) {\r\n this._update(fixedTimestepMs);\r\n this._lagMs -= fixedTimestepMs;\r\n }\r\n }\r\n else {\r\n this._update(delta);\r\n }\r\n const afterUpdate = this.clock.now();\r\n this.currentFrameLagMs = this._lagMs;\r\n this._draw(delta);\r\n const afterDraw = this.clock.now();\r\n this.stats.currFrame.duration.update = afterUpdate - beforeUpdate;\r\n this.stats.currFrame.duration.draw = afterDraw - afterUpdate;\r\n this.stats.currFrame.graphics.drawnImages = GraphicsDiagnostics.DrawnImagesCount;\r\n this.stats.currFrame.graphics.drawCalls = GraphicsDiagnostics.DrawCallCount;\r\n this.emit('postframe', new PostFrameEvent(this, this.stats.currFrame));\r\n this.stats.prevFrame.reset(this.stats.currFrame);\r\n this._monitorPerformanceThresholdAndTriggerFallback();\r\n }\r\n /**\r\n * Stops Excalibur's main loop, useful for pausing the game.\r\n */\r\n stop() {\r\n if (this.clock.isRunning()) {\r\n this.emit('stop', new GameStopEvent(this));\r\n this.browser.pause();\r\n this.clock.stop();\r\n this._logger.debug('Game stopped');\r\n }\r\n }\r\n /**\r\n * Returns the Engine's running status, Useful for checking whether engine is running or paused.\r\n */\r\n isRunning() {\r\n return this.clock.isRunning();\r\n }\r\n /**\r\n * Takes a screen shot of the current viewport and returns it as an\r\n * HTML Image Element.\r\n * @param preserveHiDPIResolution in the case of HiDPI return the full scaled backing image, by default false\r\n */\r\n screenshot(preserveHiDPIResolution = false) {\r\n const screenShotPromise = new Promise((resolve) => {\r\n this._screenShotRequests.push({ preserveHiDPIResolution, resolve });\r\n });\r\n return screenShotPromise;\r\n }\r\n _checkForScreenShots() {\r\n // We must grab the draw buffer before we yield to the browser\r\n // the draw buffer is cleared after compositing\r\n // the reason for the asynchrony is setting `preserveDrawingBuffer: true`\r\n // forces the browser to copy buffers which can have a mass perf impact on mobile\r\n for (const request of this._screenShotRequests) {\r\n const finalWidth = request.preserveHiDPIResolution ? this.canvas.width : this.screen.resolution.width;\r\n const finalHeight = request.preserveHiDPIResolution ? this.canvas.height : this.screen.resolution.height;\r\n const screenshot = document.createElement('canvas');\r\n screenshot.width = finalWidth;\r\n screenshot.height = finalHeight;\r\n const ctx = screenshot.getContext('2d');\r\n ctx.imageSmoothingEnabled = this.screen.antialiasing;\r\n ctx.drawImage(this.canvas, 0, 0, finalWidth, finalHeight);\r\n const result = new Image();\r\n const raw = screenshot.toDataURL('image/png');\r\n result.src = raw;\r\n request.resolve(result);\r\n }\r\n // Reset state\r\n this._screenShotRequests.length = 0;\r\n }\r\n /**\r\n * Another option available to you to load resources into the game.\r\n * Immediately after calling this the game will pause and the loading screen\r\n * will appear.\r\n * @param loader Some [[Loadable]] such as a [[Loader]] collection, [[Sound]], or [[Texture]].\r\n */\r\n async load(loader) {\r\n try {\r\n await loader.load();\r\n }\r\n catch (e) {\r\n this._logger.error('Error loading resources, things may not behave properly', e);\r\n await Promise.resolve();\r\n }\r\n }\r\n}\r\n/**\r\n * Default [[EngineOptions]]\r\n */\r\nEngine._DEFAULT_ENGINE_OPTIONS = {\r\n width: 0,\r\n height: 0,\r\n enableCanvasTransparency: true,\r\n useDrawSorting: true,\r\n configurePerformanceCanvas2DFallback: {\r\n allow: true,\r\n showPlayerMessage: false,\r\n threshold: { fps: 20, numberOfFrames: 100 }\r\n },\r\n canvasElementId: '',\r\n canvasElement: undefined,\r\n snapToPixel: false,\r\n pointerScope: PointerScope.Canvas,\r\n suppressConsoleBootMessage: null,\r\n suppressMinimumBrowserFeatureDetection: null,\r\n suppressHiDPIScaling: null,\r\n suppressPlayButton: null,\r\n grabWindowFocus: true,\r\n scrollPreventionMode: ScrollPreventionMode.Canvas,\r\n backgroundColor: Color.fromHex('#2185d0') // Excalibur blue\r\n};\r\n\n;// CONCATENATED MODULE: ./Math/Index.ts\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\n;// CONCATENATED MODULE: ./Debug/index.ts\n\r\n\r\n\r\n\n;// CONCATENATED MODULE: ./EventDispatcher.ts\n\r\n/**\r\n * @deprecated Use [[EventEmitter]] will be removed in v0.29.0\r\n */\r\nclass EventDispatcher {\r\n constructor() {\r\n this._handlers = {};\r\n this._wiredEventDispatchers = [];\r\n this._deferedHandlerRemovals = [];\r\n }\r\n /**\r\n * Clears any existing handlers or wired event dispatchers on this event dispatcher\r\n */\r\n clear() {\r\n this._handlers = {};\r\n this._wiredEventDispatchers = [];\r\n }\r\n _processDeferredHandlerRemovals() {\r\n for (const eventHandler of this._deferedHandlerRemovals) {\r\n this._removeHandler(eventHandler.name, eventHandler.handler);\r\n }\r\n this._deferedHandlerRemovals.length = 0;\r\n }\r\n /**\r\n * Emits an event for target\r\n * @param eventName The name of the event to publish\r\n * @param event Optionally pass an event data object to the handler\r\n */\r\n emit(eventName, event) {\r\n this._processDeferredHandlerRemovals();\r\n if (!eventName) {\r\n // key not mapped\r\n return;\r\n }\r\n eventName = eventName.toLowerCase();\r\n if (typeof event === 'undefined' || event === null) {\r\n event = new GameEvent();\r\n }\r\n let i, len;\r\n if (this._handlers[eventName]) {\r\n i = 0;\r\n len = this._handlers[eventName].length;\r\n for (i; i < len; i++) {\r\n this._handlers[eventName][i](event);\r\n }\r\n }\r\n i = 0;\r\n len = this._wiredEventDispatchers.length;\r\n for (i; i < len; i++) {\r\n this._wiredEventDispatchers[i].emit(eventName, event);\r\n }\r\n }\r\n /**\r\n * Subscribe an event handler to a particular event name, multiple handlers per event name are allowed.\r\n * @param eventName The name of the event to subscribe to\r\n * @param handler The handler callback to fire on this event\r\n */\r\n on(eventName, handler) {\r\n this._processDeferredHandlerRemovals();\r\n eventName = eventName.toLowerCase();\r\n if (!this._handlers[eventName]) {\r\n this._handlers[eventName] = [];\r\n }\r\n this._handlers[eventName].push(handler);\r\n }\r\n /**\r\n * Unsubscribe an event handler(s) from an event. If a specific handler\r\n * is specified for an event, only that handler will be unsubscribed.\r\n * Otherwise all handlers will be unsubscribed for that event.\r\n *\r\n * @param eventName The name of the event to unsubscribe\r\n * @param handler Optionally the specific handler to unsubscribe\r\n */\r\n off(eventName, handler) {\r\n this._deferedHandlerRemovals.push({ name: eventName, handler });\r\n }\r\n _removeHandler(eventName, handler) {\r\n eventName = eventName.toLowerCase();\r\n const eventHandlers = this._handlers[eventName];\r\n if (eventHandlers) {\r\n // if no explicit handler is give with the event name clear all handlers\r\n if (!handler) {\r\n this._handlers[eventName].length = 0;\r\n }\r\n else {\r\n const index = eventHandlers.indexOf(handler);\r\n if (index > -1) {\r\n this._handlers[eventName].splice(index, 1);\r\n }\r\n }\r\n }\r\n }\r\n /**\r\n * Once listens to an event one time, then unsubscribes from that event\r\n *\r\n * @param eventName The name of the event to subscribe to once\r\n * @param handler The handler of the event that will be auto unsubscribed\r\n */\r\n once(eventName, handler) {\r\n this._processDeferredHandlerRemovals();\r\n const metaHandler = (event) => {\r\n const ev = event || new GameEvent();\r\n this.off(eventName, metaHandler);\r\n handler(ev);\r\n };\r\n this.on(eventName, metaHandler);\r\n }\r\n /**\r\n * Wires this event dispatcher to also receive events from another\r\n */\r\n wire(eventDispatcher) {\r\n eventDispatcher._wiredEventDispatchers.push(this);\r\n }\r\n /**\r\n * Unwires this event dispatcher from another\r\n */\r\n unwire(eventDispatcher) {\r\n const index = eventDispatcher._wiredEventDispatchers.indexOf(this);\r\n if (index > -1) {\r\n eventDispatcher._wiredEventDispatchers.splice(index, 1);\r\n }\r\n }\r\n}\r\n\n;// CONCATENATED MODULE: ./Label.ts\n\r\n\r\n\r\n\r\n\r\n/**\r\n * Labels are the way to draw small amounts of text to the screen. They are\r\n * actors and inherit all of the benefits and capabilities.\r\n */\r\nclass Label extends Actor {\r\n get font() {\r\n return this._font;\r\n }\r\n set font(newFont) {\r\n this._font = newFont;\r\n this._text.font = newFont;\r\n }\r\n /**\r\n * The text to draw.\r\n */\r\n get text() {\r\n return this._text.text;\r\n }\r\n set text(text) {\r\n this._text.text = text;\r\n }\r\n get color() {\r\n return this._text.color;\r\n }\r\n set color(color) {\r\n if (this._text) {\r\n this._text.color = color;\r\n }\r\n }\r\n get opacity() {\r\n return this._text.opacity;\r\n }\r\n set opacity(opacity) {\r\n this._text.opacity = opacity;\r\n }\r\n /**\r\n * The [[SpriteFont]] to use, if any. Overrides [[Font|font]] if present.\r\n */\r\n get spriteFont() {\r\n return this._spriteFont;\r\n }\r\n set spriteFont(sf) {\r\n if (sf) {\r\n this._spriteFont = sf;\r\n this._text.font = this._spriteFont;\r\n }\r\n }\r\n /**\r\n * Build a new label\r\n * @param options\r\n */\r\n constructor(options) {\r\n super(options);\r\n this._font = new Font();\r\n this._text = new Text({ text: '', font: this._font });\r\n const { text, pos, x, y, spriteFont, font, color } = options;\r\n this.pos = pos !== null && pos !== void 0 ? pos : (x && y ? vec(x, y) : this.pos);\r\n this.text = text !== null && text !== void 0 ? text : this.text;\r\n this.font = font !== null && font !== void 0 ? font : this.font;\r\n this.spriteFont = spriteFont !== null && spriteFont !== void 0 ? spriteFont : this.spriteFont;\r\n this._text.color = color !== null && color !== void 0 ? color : this.color;\r\n const gfx = this.get(GraphicsComponent);\r\n gfx.anchor = Vector.Zero;\r\n gfx.use(this._text);\r\n }\r\n _initialize(engine) {\r\n super._initialize(engine);\r\n }\r\n /**\r\n * Returns the width of the text in the label (in pixels);\r\n */\r\n getTextWidth() {\r\n return this._text.width;\r\n }\r\n}\r\n\n;// CONCATENATED MODULE: ./TileMap/IsometricMap.ts\n\r\n\r\n\r\n\r\n\r\nclass IsometricTile extends Entity {\r\n getGraphics() {\r\n return this._graphics;\r\n }\r\n /**\r\n * Tile graphics\r\n */\r\n addGraphic(graphic) {\r\n this._graphics.push(graphic);\r\n this._gfx.visible = true;\r\n this._gfx.localBounds = this._recalculateBounds();\r\n }\r\n _recalculateBounds() {\r\n let bounds = this._tileBounds.clone();\r\n for (const graphic of this._graphics) {\r\n const offset = vec(this.map.graphicsOffset.x - this.map.tileWidth / 2, this.map.graphicsOffset.y - (this.map.renderFromTopOfGraphic ? 0 : (graphic.height - this.map.tileHeight)));\r\n bounds = bounds.combine(graphic.localBounds.translate(offset));\r\n }\r\n return bounds;\r\n }\r\n removeGraphic(graphic) {\r\n const index = this._graphics.indexOf(graphic);\r\n if (index > -1) {\r\n this._graphics.splice(index, 1);\r\n }\r\n this._gfx.localBounds = this._recalculateBounds();\r\n }\r\n clearGraphics() {\r\n this._graphics.length = 0;\r\n this._gfx.visible = false;\r\n this._gfx.localBounds = this._recalculateBounds();\r\n }\r\n getColliders() {\r\n return this._colliders;\r\n }\r\n /**\r\n * Adds a collider to the IsometricTile\r\n *\r\n * **Note!** the [[Tile.solid]] must be set to true for it to act as a \"fixed\" collider\r\n * @param collider\r\n */\r\n addCollider(collider) {\r\n this._colliders.push(collider);\r\n this.map.flagCollidersDirty();\r\n }\r\n /**\r\n * Removes a collider from the IsometricTile\r\n * @param collider\r\n */\r\n removeCollider(collider) {\r\n const index = this._colliders.indexOf(collider);\r\n if (index > -1) {\r\n this._colliders.splice(index, 1);\r\n }\r\n this.map.flagCollidersDirty();\r\n }\r\n /**\r\n * Clears all colliders from the IsometricTile\r\n */\r\n clearColliders() {\r\n this._colliders.length = 0;\r\n this.map.flagCollidersDirty();\r\n }\r\n /**\r\n * Returns the top left corner of the [[IsometricTile]] in world space\r\n */\r\n get pos() {\r\n return this.map.tileToWorld(vec(this.x, this.y));\r\n }\r\n /**\r\n * Returns the center of the [[IsometricTile]]\r\n */\r\n get center() {\r\n return this.pos.add(vec(0, this.map.tileHeight / 2));\r\n }\r\n /**\r\n * Construct a new IsometricTile\r\n * @param x tile coordinate in x (not world position)\r\n * @param y tile coordinate in y (not world position)\r\n * @param graphicsOffset offset that tile should be shifted by (default (0, 0))\r\n * @param map reference to owning IsometricMap\r\n */\r\n constructor(x, y, graphicsOffset, map) {\r\n super([\r\n new TransformComponent(),\r\n new GraphicsComponent({\r\n offset: graphicsOffset !== null && graphicsOffset !== void 0 ? graphicsOffset : Vector.Zero,\r\n onPostDraw: (gfx, elapsed) => this.draw(gfx, elapsed)\r\n }),\r\n new IsometricEntityComponent(map)\r\n ]);\r\n /**\r\n * Indicates whether this tile is solid\r\n */\r\n this.solid = false;\r\n this._tileBounds = new BoundingBox();\r\n this._graphics = [];\r\n /**\r\n * Tile colliders\r\n */\r\n this._colliders = [];\r\n this.x = x;\r\n this.y = y;\r\n this.map = map;\r\n this._transform = this.get(TransformComponent);\r\n this._isometricEntityComponent = this.get(IsometricEntityComponent);\r\n const halfTileWidth = this.map.tileWidth / 2;\r\n const halfTileHeight = this.map.tileHeight / 2;\r\n // See https://clintbellanger.net/articles/isometric_math/ for formula\r\n // The x position shifts left with every y step\r\n const xPos = (this.x - this.y) * halfTileWidth;\r\n // The y position needs to go down with every x step\r\n const yPos = (this.x + this.y) * halfTileHeight;\r\n this._transform.pos = vec(xPos, yPos);\r\n this._isometricEntityComponent.elevation = 0;\r\n this._gfx = this.get(GraphicsComponent);\r\n this._gfx.visible = false; // start not visible\r\n const totalWidth = this.map.tileWidth;\r\n const totalHeight = this.map.tileHeight;\r\n // initial guess at gfx bounds based on the tile\r\n const offset = vec(0, (this.map.renderFromTopOfGraphic ? totalHeight : 0));\r\n this._gfx.localBounds = this._tileBounds = new BoundingBox({\r\n left: -totalWidth / 2,\r\n top: -totalHeight,\r\n right: totalWidth / 2,\r\n bottom: totalHeight\r\n }).translate(offset);\r\n }\r\n draw(gfx, _elapsed) {\r\n const halfTileWidth = this.map.tileWidth / 2;\r\n gfx.save();\r\n // shift left origin to corner of map, not the left corner of the first sprite\r\n gfx.translate(-halfTileWidth, 0);\r\n for (const graphic of this._graphics) {\r\n graphic.draw(gfx, this.map.graphicsOffset.x, this.map.graphicsOffset.y - (this.map.renderFromTopOfGraphic ? 0 : (graphic.height - this.map.tileHeight)));\r\n }\r\n gfx.restore();\r\n }\r\n}\r\n/**\r\n * The IsometricMap is a special tile map that provides isometric rendering support to Excalibur\r\n *\r\n * The tileWidth and tileHeight should be the height and width in pixels of the parallelogram of the base of the tile art asset.\r\n * The tileWidth and tileHeight is not necessarily the same as your graphic pixel width and height.\r\n *\r\n * Please refer to the docs https://excaliburjs.com for more details calculating what your tile width and height should be given\r\n * your art assets.\r\n */\r\nclass IsometricMap extends Entity {\r\n constructor(options) {\r\n super([\r\n new TransformComponent(),\r\n new BodyComponent({\r\n type: CollisionType.Fixed\r\n }),\r\n new ColliderComponent(),\r\n new DebugGraphicsComponent((ctx) => this.debug(ctx), false)\r\n ], options.name);\r\n /**\r\n * Render the tile graphic from the top instead of the bottom\r\n *\r\n * default is `false` meaning rendering from the bottom\r\n */\r\n this.renderFromTopOfGraphic = false;\r\n this.graphicsOffset = vec(0, 0);\r\n this._collidersDirty = false;\r\n this._originalOffsets = new WeakMap();\r\n const { pos, tileWidth, tileHeight, columns: width, rows: height, renderFromTopOfGraphic, graphicsOffset } = options;\r\n this.transform = this.get(TransformComponent);\r\n if (pos) {\r\n this.transform.pos = pos;\r\n }\r\n this.collider = this.get(ColliderComponent);\r\n if (this.collider) {\r\n this.collider.set(this._composite = new CompositeCollider([]));\r\n }\r\n this.renderFromTopOfGraphic = renderFromTopOfGraphic !== null && renderFromTopOfGraphic !== void 0 ? renderFromTopOfGraphic : this.renderFromTopOfGraphic;\r\n this.graphicsOffset = graphicsOffset !== null && graphicsOffset !== void 0 ? graphicsOffset : this.graphicsOffset;\r\n this.tileWidth = tileWidth;\r\n this.tileHeight = tileHeight;\r\n this.columns = width;\r\n this.rows = height;\r\n this.tiles = new Array(width * height);\r\n // build up tile representation\r\n for (let y = 0; y < height; y++) {\r\n for (let x = 0; x < width; x++) {\r\n const tile = new IsometricTile(x, y, this.graphicsOffset, this);\r\n this.tiles[x + y * width] = tile;\r\n this.addChild(tile);\r\n // TODO row/columns helpers\r\n }\r\n }\r\n }\r\n update() {\r\n if (this._collidersDirty) {\r\n this.updateColliders();\r\n this._collidersDirty = false;\r\n }\r\n }\r\n flagCollidersDirty() {\r\n this._collidersDirty = true;\r\n }\r\n _getOrSetColliderOriginalOffset(collider) {\r\n if (!this._originalOffsets.has(collider)) {\r\n const originalOffset = collider.offset;\r\n this._originalOffsets.set(collider, originalOffset);\r\n return originalOffset;\r\n }\r\n else {\r\n return this._originalOffsets.get(collider);\r\n }\r\n }\r\n updateColliders() {\r\n this._composite.clearColliders();\r\n const pos = this.get(TransformComponent).pos;\r\n for (const tile of this.tiles) {\r\n if (tile.solid) {\r\n for (const collider of tile.getColliders()) {\r\n const originalOffset = this._getOrSetColliderOriginalOffset(collider);\r\n collider.offset = this.tileToWorld(vec(tile.x, tile.y))\r\n .sub(pos)\r\n .add(originalOffset)\r\n .sub(vec(this.tileWidth / 2, this.tileHeight)); // We need to unshift height based on drawing\r\n collider.owner = this;\r\n this._composite.addCollider(collider);\r\n }\r\n }\r\n }\r\n this.collider.update();\r\n }\r\n /**\r\n * Convert world space coordinates to the tile x, y coordinate\r\n * @param worldCoordinate\r\n */\r\n worldToTile(worldCoordinate) {\r\n worldCoordinate = worldCoordinate.sub(this.transform.globalPos);\r\n const halfTileWidth = this.tileWidth / 2;\r\n const halfTileHeight = this.tileHeight / 2;\r\n // See https://clintbellanger.net/articles/isometric_math/ for formula\r\n return vec(~~((worldCoordinate.x / halfTileWidth + (worldCoordinate.y / halfTileHeight)) / 2), ~~((worldCoordinate.y / halfTileHeight - (worldCoordinate.x / halfTileWidth)) / 2));\r\n }\r\n /**\r\n * Given a tile coordinate, return the top left corner in world space\r\n * @param tileCoordinate\r\n */\r\n tileToWorld(tileCoordinate) {\r\n const halfTileWidth = this.tileWidth / 2;\r\n const halfTileHeight = this.tileHeight / 2;\r\n // The x position shifts left with every y step\r\n const xPos = (tileCoordinate.x - tileCoordinate.y) * halfTileWidth;\r\n // The y position needs to go down with every x step\r\n const yPos = (tileCoordinate.x + tileCoordinate.y) * halfTileHeight;\r\n return vec(xPos, yPos).add(this.transform.pos);\r\n }\r\n /**\r\n * Returns the [[IsometricTile]] by its x and y coordinates\r\n */\r\n getTile(x, y) {\r\n if (x < 0 || y < 0 || x >= this.columns || y >= this.rows) {\r\n return null;\r\n }\r\n return this.tiles[x + y * this.columns];\r\n }\r\n /**\r\n * Returns the [[IsometricTile]] by testing a point in world coordinates,\r\n * returns `null` if no Tile was found.\r\n */\r\n getTileByPoint(point) {\r\n const tileCoord = this.worldToTile(point);\r\n const tile = this.getTile(tileCoord.x, tileCoord.y);\r\n return tile;\r\n }\r\n _getMaxZIndex() {\r\n let maxZ = Number.NEGATIVE_INFINITY;\r\n for (const tile of this.tiles) {\r\n const currentZ = tile.get(TransformComponent).z;\r\n if (currentZ > maxZ) {\r\n maxZ = currentZ;\r\n }\r\n }\r\n return maxZ;\r\n }\r\n /**\r\n * Debug draw for IsometricMap, called internally by excalibur when debug mode is toggled on\r\n * @param gfx\r\n */\r\n debug(gfx) {\r\n gfx.save();\r\n gfx.z = this._getMaxZIndex() + 0.5;\r\n for (let y = 0; y < this.rows + 1; y++) {\r\n const left = this.tileToWorld(vec(0, y));\r\n const right = this.tileToWorld(vec(this.columns, y));\r\n gfx.drawLine(left, right, Color.Red, 2);\r\n }\r\n for (let x = 0; x < this.columns + 1; x++) {\r\n const top = this.tileToWorld(vec(x, 0));\r\n const bottom = this.tileToWorld(vec(x, this.rows));\r\n gfx.drawLine(top, bottom, Color.Red, 2);\r\n }\r\n for (const tile of this.tiles) {\r\n gfx.drawCircle(this.tileToWorld(vec(tile.x, tile.y)), 3, Color.Yellow);\r\n }\r\n gfx.restore();\r\n }\r\n}\r\n\n;// CONCATENATED MODULE: ./TileMap/index.ts\n\r\n\r\n\r\n\r\n\n;// CONCATENATED MODULE: ./Actions/Action/ActionSequence.ts\n\r\n/**\r\n * Action that can represent a sequence of actions, this can be useful in conjunction with\r\n * [[ParallelActions]] to run multiple sequences in parallel.\r\n */\r\nclass ActionSequence {\r\n constructor(entity, actionBuilder) {\r\n this._stopped = false;\r\n this._sequenceBuilder = actionBuilder;\r\n this._sequenceContext = new ActionContext(entity);\r\n this._actionQueue = this._sequenceContext.getQueue();\r\n this._sequenceBuilder(this._sequenceContext);\r\n }\r\n update(delta) {\r\n this._actionQueue.update(delta);\r\n }\r\n isComplete() {\r\n return this._stopped || this._actionQueue.isComplete();\r\n }\r\n stop() {\r\n this._stopped = true;\r\n }\r\n reset() {\r\n this._stopped = false;\r\n this._actionQueue.reset();\r\n }\r\n clone(entity) {\r\n return new ActionSequence(entity, this._sequenceBuilder);\r\n }\r\n}\r\n\n;// CONCATENATED MODULE: ./Actions/Action/ParallelActions.ts\n/**\r\n * Action that can run multiple [[Action]]s or [[ActionSequence]]s at the same time\r\n */\r\nclass ParallelActions {\r\n constructor(parallelActions) {\r\n this._actions = parallelActions;\r\n }\r\n update(delta) {\r\n for (let i = 0; i < this._actions.length; i++) {\r\n this._actions[i].update(delta);\r\n }\r\n }\r\n isComplete(entity) {\r\n return this._actions.every(a => a.isComplete(entity));\r\n }\r\n reset() {\r\n this._actions.forEach(a => a.reset());\r\n }\r\n stop() {\r\n this._actions.forEach(a => a.stop());\r\n }\r\n}\r\n\n;// CONCATENATED MODULE: ./Actions/Index.ts\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\n;// CONCATENATED MODULE: ./Collision/Group/CollisionGroupManager.ts\n\r\n/**\r\n * Static class for managing collision groups in excalibur, there is a maximum of 32 collision groups possible in excalibur\r\n */\r\nclass CollisionGroupManager {\r\n /**\r\n * Create a new named collision group up to a max of 32.\r\n * @param name Name for the collision group\r\n * @param mask Optionally provide your own 32-bit mask, if none is provide the manager will generate one\r\n */\r\n static create(name, mask) {\r\n if (this._CURRENT_GROUP > this._MAX_GROUPS) {\r\n throw new Error(`Cannot have more than ${this._MAX_GROUPS} collision groups`);\r\n }\r\n if (this._GROUPS.get(name)) {\r\n throw new Error(`Collision group ${name} already exists`);\r\n }\r\n const group = new CollisionGroup(name, this._CURRENT_BIT, mask !== undefined ? mask : ~this._CURRENT_BIT);\r\n this._CURRENT_BIT = (this._CURRENT_BIT << 1) | 0;\r\n this._CURRENT_GROUP++;\r\n this._GROUPS.set(name, group);\r\n return group;\r\n }\r\n /**\r\n * Get all collision groups currently tracked by excalibur\r\n */\r\n static get groups() {\r\n return Array.from(this._GROUPS.values());\r\n }\r\n /**\r\n * Get a collision group by it's name\r\n * @param name\r\n */\r\n static groupByName(name) {\r\n return this._GROUPS.get(name);\r\n }\r\n /**\r\n * Resets the managers internal group management state\r\n */\r\n static reset() {\r\n this._GROUPS = new Map();\r\n this._CURRENT_BIT = this._STARTING_BIT;\r\n this._CURRENT_GROUP = 1;\r\n }\r\n}\r\n// using bitmasking the maximum number of groups is 32, because that is the highest 32bit integer that JS can present.\r\nCollisionGroupManager._STARTING_BIT = 0b1 | 0;\r\nCollisionGroupManager._MAX_GROUPS = 32;\r\nCollisionGroupManager._CURRENT_GROUP = 1;\r\nCollisionGroupManager._CURRENT_BIT = CollisionGroupManager._STARTING_BIT;\r\nCollisionGroupManager._GROUPS = new Map();\r\n\n;// CONCATENATED MODULE: ./Collision/Index.ts\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\n;// CONCATENATED MODULE: ./Interfaces/LifecycleEvents.ts\n/**\r\n * Type guard checking for internal initialize method\r\n * @internal\r\n * @param a\r\n */\r\nfunction has_initialize(a) {\r\n return !!a._initialize;\r\n}\r\n/**\r\n *\r\n */\r\nfunction hasOnInitialize(a) {\r\n return !!a.onInitialize;\r\n}\r\n/**\r\n *\r\n */\r\nfunction has_preupdate(a) {\r\n return !!a._preupdate;\r\n}\r\n/**\r\n *\r\n */\r\nfunction hasOnPreUpdate(a) {\r\n return !!a.onPreUpdate;\r\n}\r\n/**\r\n *\r\n */\r\nfunction has_postupdate(a) {\r\n return !!a.onPostUpdate;\r\n}\r\n/**\r\n *\r\n */\r\nfunction hasOnPostUpdate(a) {\r\n return !!a.onPostUpdate;\r\n}\r\n/**\r\n *\r\n */\r\nfunction hasPreDraw(a) {\r\n return !!a.onPreDraw;\r\n}\r\n/**\r\n *\r\n */\r\nfunction hasPostDraw(a) {\r\n return !!a.onPostDraw;\r\n}\r\n\n;// CONCATENATED MODULE: ./Interfaces/Index.ts\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\n;// CONCATENATED MODULE: ./Resources/Sound/Index.ts\n\r\n\r\n\r\n\n;// CONCATENATED MODULE: ./Resources/Gif.ts\n\r\n\r\n\r\n\r\n\r\n\r\n/**\r\n * The [[Texture]] object allows games built in Excalibur to load image resources.\r\n * [[Texture]] is an [[Loadable]] which means it can be passed to a [[Loader]]\r\n * to pre-load before starting a level or game.\r\n */\r\nclass Gif {\r\n /**\r\n * @param path Path to the image resource\r\n * @param color Optionally set the color to treat as transparent the gif, by default [[Color.Magenta]]\r\n * @param bustCache Optionally load texture with cache busting\r\n */\r\n constructor(path, color = Color.Magenta, bustCache = false) {\r\n this.path = path;\r\n this.color = color;\r\n this._stream = null;\r\n this._gif = null;\r\n this._textures = [];\r\n this._animation = null;\r\n this._transparentColor = null;\r\n this._resource = new Resource(path, 'arraybuffer', bustCache);\r\n this._transparentColor = color;\r\n }\r\n /**\r\n * Should excalibur add a cache busting querystring? By default false.\r\n * Must be set before loading\r\n */\r\n get bustCache() {\r\n return this._resource.bustCache;\r\n }\r\n set bustCache(val) {\r\n this._resource.bustCache = val;\r\n }\r\n /**\r\n * Begins loading the texture and returns a promise to be resolved on completion\r\n */\r\n async load() {\r\n const arraybuffer = await this._resource.load();\r\n this._stream = new Stream(arraybuffer);\r\n this._gif = new ParseGif(this._stream, this._transparentColor);\r\n const images = this._gif.images.map(i => new ImageSource(i.src, false));\r\n // Load all textures\r\n await Promise.all(images.map(t => t.load()));\r\n return this.data = this._textures = images;\r\n }\r\n isLoaded() {\r\n return !!this.data;\r\n }\r\n /**\r\n * Return a frame of the gif as a sprite by id\r\n * @param id\r\n */\r\n toSprite(id = 0) {\r\n const sprite = this._textures[id].toSprite();\r\n return sprite;\r\n }\r\n /**\r\n * Return the gif as a spritesheet\r\n */\r\n toSpriteSheet() {\r\n const sprites = this._textures.map((image) => {\r\n return image.toSprite();\r\n });\r\n return new SpriteSheet({ sprites });\r\n }\r\n /**\r\n * Transform the GIF into an animation with duration per frame\r\n */\r\n toAnimation(durationPerFrameMs) {\r\n const spriteSheet = this.toSpriteSheet();\r\n const length = spriteSheet.sprites.length;\r\n this._animation = Animation.fromSpriteSheet(spriteSheet, range(0, length), durationPerFrameMs);\r\n return this._animation;\r\n }\r\n get readCheckBytes() {\r\n return this._gif.checkBytes;\r\n }\r\n}\r\nconst bitsToNum = (ba) => {\r\n return ba.reduce(function (s, n) {\r\n return s * 2 + n;\r\n }, 0);\r\n};\r\nconst byteToBitArr = (bite) => {\r\n const a = [];\r\n for (let i = 7; i >= 0; i--) {\r\n a.push(!!(bite & (1 << i)));\r\n }\r\n return a;\r\n};\r\nclass Stream {\r\n constructor(dataArray) {\r\n this.data = null;\r\n this.len = 0;\r\n this.position = 0;\r\n this.readByte = () => {\r\n if (this.position >= this.data.byteLength) {\r\n throw new Error('Attempted to read past end of stream.');\r\n }\r\n return this.data[this.position++];\r\n };\r\n this.readBytes = (n) => {\r\n const bytes = [];\r\n for (let i = 0; i < n; i++) {\r\n bytes.push(this.readByte());\r\n }\r\n return bytes;\r\n };\r\n this.read = (n) => {\r\n let s = '';\r\n for (let i = 0; i < n; i++) {\r\n s += String.fromCharCode(this.readByte());\r\n }\r\n return s;\r\n };\r\n this.readUnsigned = () => {\r\n // Little-endian.\r\n const a = this.readBytes(2);\r\n return (a[1] << 8) + a[0];\r\n };\r\n this.data = new Uint8Array(dataArray);\r\n this.len = this.data.byteLength;\r\n if (this.len === 0) {\r\n throw new Error('No data loaded from file');\r\n }\r\n }\r\n}\r\nconst lzwDecode = function (minCodeSize, data) {\r\n // TODO: Now that the GIF parser is a bit different, maybe this should get an array of bytes instead of a String?\r\n let pos = 0; // Maybe this streaming thing should be merged with the Stream?\r\n const readCode = function (size) {\r\n let code = 0;\r\n for (let i = 0; i < size; i++) {\r\n if (data.charCodeAt(pos >> 3) & (1 << (pos & 7))) {\r\n code |= 1 << i;\r\n }\r\n pos++;\r\n }\r\n return code;\r\n };\r\n const output = [];\r\n const clearCode = 1 << minCodeSize;\r\n const eoiCode = clearCode + 1;\r\n let codeSize = minCodeSize + 1;\r\n let dict = [];\r\n const clear = function () {\r\n dict = [];\r\n codeSize = minCodeSize + 1;\r\n for (let i = 0; i < clearCode; i++) {\r\n dict[i] = [i];\r\n }\r\n dict[clearCode] = [];\r\n dict[eoiCode] = null;\r\n };\r\n let code;\r\n let last;\r\n while (true) {\r\n last = code;\r\n code = readCode(codeSize);\r\n if (code === clearCode) {\r\n clear();\r\n continue;\r\n }\r\n if (code === eoiCode) {\r\n break;\r\n }\r\n if (code < dict.length) {\r\n if (last !== clearCode) {\r\n dict.push(dict[last].concat(dict[code][0]));\r\n }\r\n }\r\n else {\r\n if (code !== dict.length) {\r\n throw new Error('Invalid LZW code.');\r\n }\r\n dict.push(dict[last].concat(dict[last][0]));\r\n }\r\n output.push.apply(output, dict[code]);\r\n if (dict.length === 1 << codeSize && codeSize < 12) {\r\n // If we're at the last code and codeSize is 12, the next code will be a clearCode, and it'll be 12 bits long.\r\n codeSize++;\r\n }\r\n }\r\n // I don't know if this is technically an error, but some GIFs do it.\r\n //if (Math.ceil(pos / 8) !== data.length) throw new Error('Extraneous LZW bytes.');\r\n return output;\r\n};\r\n// The actual parsing; returns an object with properties.\r\nclass ParseGif {\r\n constructor(stream, color = Color.Magenta) {\r\n this._st = null;\r\n this._handler = {};\r\n this._transparentColor = null;\r\n this.frames = [];\r\n this.images = [];\r\n this.globalColorTable = [];\r\n this.checkBytes = [];\r\n // LZW (GIF-specific)\r\n this.parseColorTable = (entries) => {\r\n // Each entry is 3 bytes, for RGB.\r\n const ct = [];\r\n for (let i = 0; i < entries; i++) {\r\n const rgb = this._st.readBytes(3);\r\n const rgba = '#' +\r\n rgb\r\n .map((x) => {\r\n const hex = x.toString(16);\r\n return hex.length === 1 ? '0' + hex : hex;\r\n })\r\n .join('');\r\n ct.push(rgba);\r\n }\r\n return ct;\r\n };\r\n this.readSubBlocks = () => {\r\n let size, data;\r\n data = '';\r\n do {\r\n size = this._st.readByte();\r\n data += this._st.read(size);\r\n } while (size !== 0);\r\n return data;\r\n };\r\n this.parseHeader = () => {\r\n const hdr = {\r\n sig: null,\r\n ver: null,\r\n width: null,\r\n height: null,\r\n colorRes: null,\r\n globalColorTableSize: null,\r\n gctFlag: null,\r\n sorted: null,\r\n globalColorTable: [],\r\n bgColor: null,\r\n pixelAspectRatio: null // if not 0, aspectRatio = (pixelAspectRatio + 15) / 64\r\n };\r\n hdr.sig = this._st.read(3);\r\n hdr.ver = this._st.read(3);\r\n if (hdr.sig !== 'GIF') {\r\n throw new Error('Not a GIF file.'); // XXX: This should probably be handled more nicely.\r\n }\r\n hdr.width = this._st.readUnsigned();\r\n hdr.height = this._st.readUnsigned();\r\n const bits = byteToBitArr(this._st.readByte());\r\n hdr.gctFlag = bits.shift();\r\n hdr.colorRes = bitsToNum(bits.splice(0, 3));\r\n hdr.sorted = bits.shift();\r\n hdr.globalColorTableSize = bitsToNum(bits.splice(0, 3));\r\n hdr.bgColor = this._st.readByte();\r\n hdr.pixelAspectRatio = this._st.readByte(); // if not 0, aspectRatio = (pixelAspectRatio + 15) / 64\r\n if (hdr.gctFlag) {\r\n hdr.globalColorTable = this.parseColorTable(1 << (hdr.globalColorTableSize + 1));\r\n this.globalColorTable = hdr.globalColorTable;\r\n }\r\n if (this._handler.hdr && this._handler.hdr(hdr)) {\r\n this.checkBytes.push(this._handler.hdr);\r\n }\r\n };\r\n this.parseExt = (block) => {\r\n const parseGCExt = (block) => {\r\n this.checkBytes.push(this._st.readByte()); // Always 4\r\n const bits = byteToBitArr(this._st.readByte());\r\n block.reserved = bits.splice(0, 3); // Reserved; should be 000.\r\n block.disposalMethod = bitsToNum(bits.splice(0, 3));\r\n block.userInput = bits.shift();\r\n block.transparencyGiven = bits.shift();\r\n block.delayTime = this._st.readUnsigned();\r\n block.transparencyIndex = this._st.readByte();\r\n block.terminator = this._st.readByte();\r\n if (this._handler.gce && this._handler.gce(block)) {\r\n this.checkBytes.push(this._handler.gce);\r\n }\r\n };\r\n const parseComExt = (block) => {\r\n block.comment = this.readSubBlocks();\r\n if (this._handler.com && this._handler.com(block)) {\r\n this.checkBytes.push(this._handler.com);\r\n }\r\n };\r\n const parsePTExt = (block) => {\r\n this.checkBytes.push(this._st.readByte()); // Always 12\r\n block.ptHeader = this._st.readBytes(12);\r\n block.ptData = this.readSubBlocks();\r\n if (this._handler.pte && this._handler.pte(block)) {\r\n this.checkBytes.push(this._handler.pte);\r\n }\r\n };\r\n const parseAppExt = (block) => {\r\n const parseNetscapeExt = (block) => {\r\n this.checkBytes.push(this._st.readByte()); // Always 3\r\n block.unknown = this._st.readByte(); // Q: Always 1? What is this?\r\n block.iterations = this._st.readUnsigned();\r\n block.terminator = this._st.readByte();\r\n if (this._handler.app && this._handler.app.NETSCAPE && this._handler.app.NETSCAPE(block)) {\r\n this.checkBytes.push(this._handler.app);\r\n }\r\n };\r\n const parseUnknownAppExt = (block) => {\r\n block.appData = this.readSubBlocks();\r\n // FIXME: This won't work if a handler wants to match on any identifier.\r\n if (this._handler.app && this._handler.app[block.identifier] && this._handler.app[block.identifier](block)) {\r\n this.checkBytes.push(this._handler.app[block.identifier]);\r\n }\r\n };\r\n this.checkBytes.push(this._st.readByte()); // Always 11\r\n block.identifier = this._st.read(8);\r\n block.authCode = this._st.read(3);\r\n switch (block.identifier) {\r\n case 'NETSCAPE':\r\n parseNetscapeExt(block);\r\n break;\r\n default:\r\n parseUnknownAppExt(block);\r\n break;\r\n }\r\n };\r\n const parseUnknownExt = (block) => {\r\n block.data = this.readSubBlocks();\r\n if (this._handler.unknown && this._handler.unknown(block)) {\r\n this.checkBytes.push(this._handler.unknown);\r\n }\r\n };\r\n block.label = this._st.readByte();\r\n switch (block.label) {\r\n case 0xf9:\r\n block.extType = 'gce';\r\n parseGCExt(block);\r\n break;\r\n case 0xfe:\r\n block.extType = 'com';\r\n parseComExt(block);\r\n break;\r\n case 0x01:\r\n block.extType = 'pte';\r\n parsePTExt(block);\r\n break;\r\n case 0xff:\r\n block.extType = 'app';\r\n parseAppExt(block);\r\n break;\r\n default:\r\n block.extType = 'unknown';\r\n parseUnknownExt(block);\r\n break;\r\n }\r\n };\r\n this.parseImg = (img) => {\r\n const deinterlace = (pixels, width) => {\r\n // Of course this defeats the purpose of interlacing. And it's *probably*\r\n // the least efficient way it's ever been implemented. But nevertheless...\r\n const newPixels = new Array(pixels.length);\r\n const rows = pixels.length / width;\r\n const cpRow = (toRow, fromRow) => {\r\n const fromPixels = pixels.slice(fromRow * width, (fromRow + 1) * width);\r\n newPixels.splice.apply(newPixels, [toRow * width, width].concat(fromPixels));\r\n };\r\n const offsets = [0, 4, 2, 1];\r\n const steps = [8, 8, 4, 2];\r\n let fromRow = 0;\r\n for (let pass = 0; pass < 4; pass++) {\r\n for (let toRow = offsets[pass]; toRow < rows; toRow += steps[pass]) {\r\n cpRow(toRow, fromRow);\r\n fromRow++;\r\n }\r\n }\r\n return newPixels;\r\n };\r\n img.leftPos = this._st.readUnsigned();\r\n img.topPos = this._st.readUnsigned();\r\n img.width = this._st.readUnsigned();\r\n img.height = this._st.readUnsigned();\r\n const bits = byteToBitArr(this._st.readByte());\r\n img.lctFlag = bits.shift();\r\n img.interlaced = bits.shift();\r\n img.sorted = bits.shift();\r\n img.reserved = bits.splice(0, 2);\r\n img.lctSize = bitsToNum(bits.splice(0, 3));\r\n if (img.lctFlag) {\r\n img.lct = this.parseColorTable(1 << (img.lctSize + 1));\r\n }\r\n img.lzwMinCodeSize = this._st.readByte();\r\n const lzwData = this.readSubBlocks();\r\n img.pixels = lzwDecode(img.lzwMinCodeSize, lzwData);\r\n if (img.interlaced) {\r\n // Move\r\n img.pixels = deinterlace(img.pixels, img.width);\r\n }\r\n this.frames.push(img);\r\n this.arrayToImage(img);\r\n if (this._handler.img && this._handler.img(img)) {\r\n this.checkBytes.push(this._handler);\r\n }\r\n };\r\n this.parseBlock = () => {\r\n const block = {\r\n sentinel: this._st.readByte(),\r\n type: ''\r\n };\r\n const blockChar = String.fromCharCode(block.sentinel);\r\n switch (blockChar) {\r\n case '!':\r\n block.type = 'ext';\r\n this.parseExt(block);\r\n break;\r\n case ',':\r\n block.type = 'img';\r\n this.parseImg(block);\r\n break;\r\n case ';':\r\n block.type = 'eof';\r\n if (this._handler.eof && this._handler.eof(block)) {\r\n this.checkBytes.push(this._handler.eof);\r\n }\r\n break;\r\n default:\r\n throw new Error('Unknown block: 0x' + block.sentinel.toString(16));\r\n }\r\n if (block.type !== 'eof') {\r\n this.parseBlock();\r\n }\r\n };\r\n this.arrayToImage = (frame) => {\r\n let count = 0;\r\n const c = document.createElement('canvas');\r\n c.id = count.toString();\r\n c.width = frame.width;\r\n c.height = frame.height;\r\n count++;\r\n const context = c.getContext('2d');\r\n const pixSize = 1;\r\n let y = 0;\r\n let x = 0;\r\n for (let i = 0; i < frame.pixels.length; i++) {\r\n if (x % frame.width === 0) {\r\n y++;\r\n x = 0;\r\n }\r\n if (this.globalColorTable[frame.pixels[i]] === this._transparentColor.toHex()) {\r\n context.fillStyle = `rgba(0, 0, 0, 0)`;\r\n }\r\n else {\r\n context.fillStyle = this.globalColorTable[frame.pixels[i]];\r\n }\r\n context.fillRect(x, y, pixSize, pixSize);\r\n x++;\r\n }\r\n const img = new Image();\r\n img.src = c.toDataURL();\r\n this.images.push(img);\r\n };\r\n this._st = stream;\r\n this._handler = {};\r\n this._transparentColor = color;\r\n this.parseHeader();\r\n this.parseBlock();\r\n }\r\n}\r\n\n;// CONCATENATED MODULE: ./Resources/Index.ts\n\r\n\r\n\r\n\n;// CONCATENATED MODULE: ./EntityComponentSystem/index.ts\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\n;// CONCATENATED MODULE: ./Graphics/Line.ts\n\r\n\r\n\r\nclass Line extends Graphic {\r\n constructor(options) {\r\n super();\r\n this.color = Color.Black;\r\n this.thickness = 1;\r\n const { start, end, color, thickness } = options;\r\n this.start = start;\r\n this.end = end;\r\n this.color = color !== null && color !== void 0 ? color : this.color;\r\n this.thickness = thickness !== null && thickness !== void 0 ? thickness : this.thickness;\r\n const { width, height } = BoundingBox.fromPoints([start, end]);\r\n this.width = width;\r\n this.height = height;\r\n }\r\n _drawImage(ctx, _x, _y) {\r\n ctx.drawLine(this.start, this.end, this.color, this.thickness);\r\n }\r\n clone() {\r\n return new Line({\r\n start: this.start,\r\n end: this.end,\r\n color: this.color,\r\n thickness: this.thickness\r\n });\r\n }\r\n}\r\n\n;// CONCATENATED MODULE: ./Graphics/Polygon.ts\n\r\n\r\n\r\n/**\r\n * A polygon [[Graphic]] for drawing arbitrary polygons to the [[ExcaliburGraphicsContext]]\r\n *\r\n * Polygons default to [[ImageFiltering.Blended]]\r\n */\r\nclass Polygon extends Raster {\r\n get points() {\r\n return this._points;\r\n }\r\n set points(points) {\r\n this._points = points;\r\n const min = this.minPoint;\r\n this.width = this._points.reduce((max, p) => Math.max(p.x, max), 0) - min.x;\r\n this.height = this._points.reduce((max, p) => Math.max(p.y, max), 0) - min.y;\r\n this.flagDirty();\r\n }\r\n get minPoint() {\r\n const minX = this._points.reduce((min, p) => Math.min(p.x, min), Infinity);\r\n const minY = this._points.reduce((min, p) => Math.min(p.y, min), Infinity);\r\n return vec(minX, minY);\r\n }\r\n constructor(options) {\r\n super(options);\r\n this.points = options.points;\r\n this.filtering = ImageFiltering.Blended;\r\n this.rasterize();\r\n }\r\n clone() {\r\n return new Polygon({\r\n points: this.points.map((p) => p.clone()),\r\n ...this.cloneGraphicOptions(),\r\n ...this.cloneRasterOptions()\r\n });\r\n }\r\n execute(ctx) {\r\n if (this.points && this.points.length) {\r\n ctx.beginPath();\r\n // Iterate through the supplied points and construct a 'polygon'\r\n const min = this.minPoint.negate();\r\n const firstPoint = this.points[0].add(min);\r\n ctx.moveTo(firstPoint.x, firstPoint.y);\r\n this.points.forEach((point) => {\r\n ctx.lineTo(point.x + min.x, point.y + min.y);\r\n });\r\n ctx.lineTo(firstPoint.x, firstPoint.y);\r\n ctx.closePath();\r\n if (this.color) {\r\n ctx.fill();\r\n }\r\n if (this.strokeColor) {\r\n ctx.stroke();\r\n }\r\n }\r\n }\r\n}\r\n\n;// CONCATENATED MODULE: ./Graphics/index.ts\n// Graphics\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n// Graphics ECS\r\n\r\n\r\n\r\n\r\n\r\n// Raster graphics\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n// Post Processor\r\n\r\n\r\n\r\n\r\n\r\n\r\n// Rendering\r\n\r\n\r\n\r\n\r\n\r\n// Util\r\n\r\n\r\n\n;// CONCATENATED MODULE: ./Input/Index.ts\n// This import site is deprecated\r\n// TODO remove deprecated exports in v0.29.0\r\n/**\r\n * @module\r\n * Provides support for mice, keyboards, and controllers.\r\n */\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n// Re-export hack to deprecate import site gently\r\n\r\n\n;// CONCATENATED MODULE: ./Util/Index.ts\n\r\n\r\n\r\n\r\n\r\n\r\n\n;// CONCATENATED MODULE: ./Util/Semaphore.ts\n\r\nclass AsyncWaitQueue {\r\n constructor() {\r\n // Code from StephenCleary https://gist.github.com/StephenCleary/ba50b2da419c03b9cba1d20cb4654d5e\r\n this._queue = [];\r\n }\r\n get length() {\r\n return this._queue.length;\r\n }\r\n enqueue() {\r\n const future = new Future();\r\n this._queue.push(future);\r\n return future.promise;\r\n }\r\n dequeue(value) {\r\n const future = this._queue.shift();\r\n future.resolve(value);\r\n }\r\n}\r\n/**\r\n * Semaphore allows you to limit the amount of async calls happening between `enter()` and `exit()`\r\n *\r\n * This can be useful when limiting the number of http calls, browser api calls, etc either for performance or to work\r\n * around browser limitations like max Image.decode() calls in chromium being 256.\r\n */\r\nclass Semaphore {\r\n constructor(_count) {\r\n this._count = _count;\r\n this._waitQueue = new AsyncWaitQueue();\r\n }\r\n get count() {\r\n return this._count;\r\n }\r\n get waiting() {\r\n return this._waitQueue.length;\r\n }\r\n async enter() {\r\n if (this._count !== 0) {\r\n this._count--;\r\n return Promise.resolve();\r\n }\r\n return this._waitQueue.enqueue();\r\n }\r\n exit(count = 1) {\r\n if (count === 0) {\r\n return;\r\n }\r\n while (count !== 0 && this._waitQueue.length !== 0) {\r\n this._waitQueue.dequeue(null);\r\n count--;\r\n }\r\n this._count += count;\r\n }\r\n}\r\n\n;// CONCATENATED MODULE: ./index.ts\n/**\r\n * The current Excalibur version string\r\n * @description `process.env.__EX_VERSION` gets replaced by Webpack on build\r\n */\r\nconst EX_VERSION = \"0.28.0\";\r\n\r\npolyfill();\r\n// This file is used as the bundle entry point and exports everything\r\n// that will be exposed as the `ex` global variable.\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n// ex.Events namespace\r\n\r\n\r\n// ex.Input namespace\r\n// TODO deprecated import site remove in v0.29.0\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n// ex.Util namespaces\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n// ex.Deprecated\r\n// import * as deprecated from './Deprecated';\r\n// export { deprecated as Deprecated };\r\n// export * from './Deprecated';\r\n\n})();\n\nvar __webpack_exports__ActionContext = __webpack_exports__.fWn;\nvar __webpack_exports__ActionQueue = __webpack_exports__.Ia8;\nvar __webpack_exports__ActionSequence = __webpack_exports__.rqv;\nvar __webpack_exports__ActionsComponent = __webpack_exports__.hLI;\nvar __webpack_exports__ActionsSystem = __webpack_exports__.yyv;\nvar __webpack_exports__ActivateEvent = __webpack_exports__.tX5;\nvar __webpack_exports__Actor = __webpack_exports__.vtX;\nvar __webpack_exports__AddedComponent = __webpack_exports__.r7K;\nvar __webpack_exports__AddedEntity = __webpack_exports__.lCh;\nvar __webpack_exports__AffineMatrix = __webpack_exports__.cE4;\nvar __webpack_exports__Animation = __webpack_exports__.fwF;\nvar __webpack_exports__AnimationDirection = __webpack_exports__.sce;\nvar __webpack_exports__AnimationEvents = __webpack_exports__.AQ6;\nvar __webpack_exports__AnimationStrategy = __webpack_exports__._c7;\nvar __webpack_exports__ArcadeSolver = __webpack_exports__.KUs;\nvar __webpack_exports__AudioContextFactory = __webpack_exports__.Ajp;\nvar __webpack_exports__Axes = __webpack_exports__.dkO;\nvar __webpack_exports__Axis = __webpack_exports__.RDh;\nvar __webpack_exports__BaseAlign = __webpack_exports__._H9;\nvar __webpack_exports__Blink = __webpack_exports__.mxs;\nvar __webpack_exports__BodyComponent = __webpack_exports__.OmD;\nvar __webpack_exports__BoundingBox = __webpack_exports__.kBf;\nvar __webpack_exports__BroadphaseStrategy = __webpack_exports__.C4F;\nvar __webpack_exports__BrowserComponent = __webpack_exports__.NQt;\nvar __webpack_exports__BrowserEvents = __webpack_exports__.JjN;\nvar __webpack_exports__Buttons = __webpack_exports__.EK_;\nvar __webpack_exports__Camera = __webpack_exports__.V1s;\nvar __webpack_exports__CameraEvents = __webpack_exports__.xHm;\nvar __webpack_exports__Canvas = __webpack_exports__.Xz7;\nvar __webpack_exports__Circle = __webpack_exports__.Cdc;\nvar __webpack_exports__CircleCollider = __webpack_exports__.FKn;\nvar __webpack_exports__Clock = __webpack_exports__.SUY;\nvar __webpack_exports__ClosestLine = __webpack_exports__.ab2;\nvar __webpack_exports__ClosestLineJumpTable = __webpack_exports__.GfZ;\nvar __webpack_exports__Collider = __webpack_exports__.YMS;\nvar __webpack_exports__ColliderComponent = __webpack_exports__.oyv;\nvar __webpack_exports__CollisionContact = __webpack_exports__.aUb;\nvar __webpack_exports__CollisionEndEvent = __webpack_exports__.SdD;\nvar __webpack_exports__CollisionGroup = __webpack_exports__.JUv;\nvar __webpack_exports__CollisionGroupManager = __webpack_exports__.jEj;\nvar __webpack_exports__CollisionJumpTable = __webpack_exports__.TFq;\nvar __webpack_exports__CollisionPostSolveEvent = __webpack_exports__.HDU;\nvar __webpack_exports__CollisionPreSolveEvent = __webpack_exports__.R_y;\nvar __webpack_exports__CollisionResolutionStrategy = __webpack_exports__.ydN;\nvar __webpack_exports__CollisionStartEvent = __webpack_exports__.t50;\nvar __webpack_exports__CollisionSystem = __webpack_exports__.s$$;\nvar __webpack_exports__CollisionType = __webpack_exports__.v2G;\nvar __webpack_exports__Color = __webpack_exports__.Ilk;\nvar __webpack_exports__ColorBlindFlags = __webpack_exports__.s9i;\nvar __webpack_exports__ColorBlindnessMode = __webpack_exports__.dxL;\nvar __webpack_exports__ColorBlindnessPostProcessor = __webpack_exports__.LLX;\nvar __webpack_exports__Component = __webpack_exports__.wA2;\nvar __webpack_exports__CompositeCollider = __webpack_exports__.R_p;\nvar __webpack_exports__Configurable = __webpack_exports__.IQ$;\nvar __webpack_exports__ConsoleAppender = __webpack_exports__.I5F;\nvar __webpack_exports__ContactConstraintPoint = __webpack_exports__.X8$;\nvar __webpack_exports__ContactEndEvent = __webpack_exports__.FR6;\nvar __webpack_exports__ContactStartEvent = __webpack_exports__.U8o;\nvar __webpack_exports__CoordPlane = __webpack_exports__.kbG;\nvar __webpack_exports__DeactivateEvent = __webpack_exports__.iS_;\nvar __webpack_exports__Debug = __webpack_exports__.cGG;\nvar __webpack_exports__DebugGraphicsComponent = __webpack_exports__.RPN;\nvar __webpack_exports__DebugSystem = __webpack_exports__.skb;\nvar __webpack_exports__DebugText = __webpack_exports__.SLU;\nvar __webpack_exports__DegreeOfFreedom = __webpack_exports__.RdJ;\nvar __webpack_exports__Delay = __webpack_exports__.cNu;\nvar __webpack_exports__Detector = __webpack_exports__.gU7;\nvar __webpack_exports__Die = __webpack_exports__.LSk;\nvar __webpack_exports__Direction = __webpack_exports__.Nmp;\nvar __webpack_exports__DisplayMode = __webpack_exports__.d1Y;\nvar __webpack_exports__DynamicTree = __webpack_exports__.xrL;\nvar __webpack_exports__DynamicTreeCollisionProcessor = __webpack_exports__.sRW;\nvar __webpack_exports__EX_VERSION = __webpack_exports__.cmV;\nvar __webpack_exports__EaseBy = __webpack_exports__.qWz;\nvar __webpack_exports__EaseTo = __webpack_exports__.N0Q;\nvar __webpack_exports__EasingFunctions = __webpack_exports__.q8b;\nvar __webpack_exports__EdgeCollider = __webpack_exports__.ynB;\nvar __webpack_exports__ElasticToActorStrategy = __webpack_exports__.jT9;\nvar __webpack_exports__EmitterType = __webpack_exports__.wAz;\nvar __webpack_exports__Engine = __webpack_exports__.D4V;\nvar __webpack_exports__EngineEvents = __webpack_exports__.NLr;\nvar __webpack_exports__EnterTriggerEvent = __webpack_exports__.N6H;\nvar __webpack_exports__EnterViewPortEvent = __webpack_exports__.W1A;\nvar __webpack_exports__Entity = __webpack_exports__.JHW;\nvar __webpack_exports__EntityEvents = __webpack_exports__.ZZ$;\nvar __webpack_exports__EntityManager = __webpack_exports__.v2K;\nvar __webpack_exports__EventDispatcher = __webpack_exports__.pBf;\nvar __webpack_exports__EventEmitter = __webpack_exports__.vpe;\nvar __webpack_exports__EventTypes = __webpack_exports__.GMl;\nvar __webpack_exports__Events = __webpack_exports__.zW2;\nvar __webpack_exports__ExResponse = __webpack_exports__.B0K;\nvar __webpack_exports__ExcaliburGraphicsContext2DCanvas = __webpack_exports__.Nv7;\nvar __webpack_exports__ExcaliburGraphicsContextWebGL = __webpack_exports__.C_p;\nvar __webpack_exports__ExitTriggerEvent = __webpack_exports__.MUA;\nvar __webpack_exports__ExitViewPortEvent = __webpack_exports__.xqU;\nvar __webpack_exports__Fade = __webpack_exports__.pTp;\nvar __webpack_exports__Flags = __webpack_exports__.vUK;\nvar __webpack_exports__Follow = __webpack_exports__.j9l;\nvar __webpack_exports__Font = __webpack_exports__.Zxw;\nvar __webpack_exports__FontCache = __webpack_exports__.v51;\nvar __webpack_exports__FontStyle = __webpack_exports__.Hdx;\nvar __webpack_exports__FontUnit = __webpack_exports__.Z$d;\nvar __webpack_exports__FpsSampler = __webpack_exports__.iqV;\nvar __webpack_exports__FrameStats = __webpack_exports__.o$7;\nvar __webpack_exports__Future = __webpack_exports__.olM;\nvar __webpack_exports__GameEvent = __webpack_exports__.Zm$;\nvar __webpack_exports__GameStartEvent = __webpack_exports__.$QH;\nvar __webpack_exports__GameStopEvent = __webpack_exports__.i78;\nvar __webpack_exports__Gamepad = __webpack_exports__.nJg;\nvar __webpack_exports__GamepadAxisEvent = __webpack_exports__.h6u;\nvar __webpack_exports__GamepadButtonEvent = __webpack_exports__.hts;\nvar __webpack_exports__GamepadConnectEvent = __webpack_exports__.j88;\nvar __webpack_exports__GamepadDisconnectEvent = __webpack_exports__.VME;\nvar __webpack_exports__Gamepads = __webpack_exports__.fy2;\nvar __webpack_exports__Gif = __webpack_exports__.nt;\nvar __webpack_exports__GlobalCoordinates = __webpack_exports__.Ukr;\nvar __webpack_exports__Graphic = __webpack_exports__.zsu;\nvar __webpack_exports__GraphicsComponent = __webpack_exports__.oA6;\nvar __webpack_exports__GraphicsGroup = __webpack_exports__.TVh;\nvar __webpack_exports__GraphicsLayer = __webpack_exports__.TwZ;\nvar __webpack_exports__GraphicsLayers = __webpack_exports__.GTT;\nvar __webpack_exports__GraphicsSystem = __webpack_exports__.xxj;\nvar __webpack_exports__HiddenEvent = __webpack_exports__.XdK;\nvar __webpack_exports__ImageFiltering = __webpack_exports__.Jmb;\nvar __webpack_exports__ImageSource = __webpack_exports__.cXo;\nvar __webpack_exports__InitializeEvent = __webpack_exports__.Dm5;\nvar __webpack_exports__Input = __webpack_exports__.IIB;\nvar __webpack_exports__InputMapper = __webpack_exports__.ebW;\nvar __webpack_exports__Integrator = __webpack_exports__.zI0;\nvar __webpack_exports__IsometricEntityComponent = __webpack_exports__.LYD;\nvar __webpack_exports__IsometricEntitySystem = __webpack_exports__.cEG;\nvar __webpack_exports__IsometricMap = __webpack_exports__.SEl;\nvar __webpack_exports__IsometricTile = __webpack_exports__.t9V;\nvar __webpack_exports__KeyEvent = __webpack_exports__.ez5;\nvar __webpack_exports__Keyboard = __webpack_exports__.N1d;\nvar __webpack_exports__Keys = __webpack_exports__.R8U;\nvar __webpack_exports__KillEvent = __webpack_exports__.SKZ;\nvar __webpack_exports__Label = __webpack_exports__.__J;\nvar __webpack_exports__LimitCameraBoundsStrategy = __webpack_exports__.RI$;\nvar __webpack_exports__Line = __webpack_exports__.x12;\nvar __webpack_exports__LineSegment = __webpack_exports__.ccz;\nvar __webpack_exports__Loader = __webpack_exports__.aNw;\nvar __webpack_exports__LoaderEvents = __webpack_exports__.XrL;\nvar __webpack_exports__LockCameraToActorAxisStrategy = __webpack_exports__.xwn;\nvar __webpack_exports__LockCameraToActorStrategy = __webpack_exports__.dNK;\nvar __webpack_exports__LogLevel = __webpack_exports__.ini;\nvar __webpack_exports__Logger = __webpack_exports__.YdH;\nvar __webpack_exports__Material = __webpack_exports__.F5T;\nvar __webpack_exports__Matrix = __webpack_exports__.y3G;\nvar __webpack_exports__MatrixLocations = __webpack_exports__.l57;\nvar __webpack_exports__MediaEvent = __webpack_exports__.xn0;\nvar __webpack_exports__Meet = __webpack_exports__.t2V;\nvar __webpack_exports__MotionComponent = __webpack_exports__.uxB;\nvar __webpack_exports__MotionSystem = __webpack_exports__.cpd;\nvar __webpack_exports__MoveBy = __webpack_exports__.fiy;\nvar __webpack_exports__MoveTo = __webpack_exports__.$XZ;\nvar __webpack_exports__NativePointerButton = __webpack_exports__.UG6;\nvar __webpack_exports__NativeSoundEvent = __webpack_exports__.uqK;\nvar __webpack_exports__NativeSoundProcessedEvent = __webpack_exports__.STE;\nvar __webpack_exports__Observable = __webpack_exports__.y$z;\nvar __webpack_exports__OffscreenSystem = __webpack_exports__.mAD;\nvar __webpack_exports__Pair = __webpack_exports__.sOq;\nvar __webpack_exports__ParallaxComponent = __webpack_exports__.hUw;\nvar __webpack_exports__ParallelActions = __webpack_exports__._0G;\nvar __webpack_exports__ParseGif = __webpack_exports__.Sqs;\nvar __webpack_exports__Particle = __webpack_exports__.hpZ;\nvar __webpack_exports__ParticleEmitter = __webpack_exports__.Vol;\nvar __webpack_exports__ParticleTransform = __webpack_exports__.vYX;\nvar __webpack_exports__Physics = __webpack_exports__.wIZ;\nvar __webpack_exports__PhysicsStats = __webpack_exports__.cBi;\nvar __webpack_exports__PhysicsWorld = __webpack_exports__.c30;\nvar __webpack_exports__PointerButton = __webpack_exports__.MPV;\nvar __webpack_exports__PointerComponent = __webpack_exports__.RFv;\nvar __webpack_exports__PointerEvent = __webpack_exports__.Ux6;\nvar __webpack_exports__PointerEventReceiver = __webpack_exports__.rxy;\nvar __webpack_exports__PointerScope = __webpack_exports__.I$c;\nvar __webpack_exports__PointerSystem = __webpack_exports__.kfC;\nvar __webpack_exports__PointerType = __webpack_exports__.VjY;\nvar __webpack_exports__Polygon = __webpack_exports__.mgq;\nvar __webpack_exports__PolygonCollider = __webpack_exports__.YVA;\nvar __webpack_exports__Pool = __webpack_exports__.Kgp;\nvar __webpack_exports__PostCollisionEvent = __webpack_exports__.HH$;\nvar __webpack_exports__PostDebugDrawEvent = __webpack_exports__.M_d;\nvar __webpack_exports__PostDrawEvent = __webpack_exports__.rgh;\nvar __webpack_exports__PostFrameEvent = __webpack_exports__.Ra6;\nvar __webpack_exports__PostKillEvent = __webpack_exports__.KhR;\nvar __webpack_exports__PostUpdateEvent = __webpack_exports__.BS5;\nvar __webpack_exports__PreCollisionEvent = __webpack_exports__.xhz;\nvar __webpack_exports__PreDebugDrawEvent = __webpack_exports__.xOq;\nvar __webpack_exports__PreDrawEvent = __webpack_exports__.a9j;\nvar __webpack_exports__PreFrameEvent = __webpack_exports__.bHk;\nvar __webpack_exports__PreKillEvent = __webpack_exports__.CgK;\nvar __webpack_exports__PreUpdateEvent = __webpack_exports__.cuY;\nvar __webpack_exports__Projection = __webpack_exports__.kvE;\nvar __webpack_exports__QuadIndexBuffer = __webpack_exports__.SBu;\nvar __webpack_exports__Query = __webpack_exports__.AE_;\nvar __webpack_exports__QueryManager = __webpack_exports__.ctO;\nvar __webpack_exports__RadiusAroundActorStrategy = __webpack_exports__.OLH;\nvar __webpack_exports__Random = __webpack_exports__.kky;\nvar __webpack_exports__Raster = __webpack_exports__.nSF;\nvar __webpack_exports__Ray = __webpack_exports__.zHn;\nvar __webpack_exports__RealisticSolver = __webpack_exports__.zwx;\nvar __webpack_exports__Rectangle = __webpack_exports__.AeJ;\nvar __webpack_exports__RemovedComponent = __webpack_exports__.hLz;\nvar __webpack_exports__RemovedEntity = __webpack_exports__.D9g;\nvar __webpack_exports__Repeat = __webpack_exports__.wA;\nvar __webpack_exports__RepeatForever = __webpack_exports__.jhr;\nvar __webpack_exports__Resolution = __webpack_exports__.GVs;\nvar __webpack_exports__Resource = __webpack_exports__._zO;\nvar __webpack_exports__ResourceEvents = __webpack_exports__.LXZ;\nvar __webpack_exports__RotateBy = __webpack_exports__.w6$;\nvar __webpack_exports__RotateTo = __webpack_exports__.mhV;\nvar __webpack_exports__RotationType = __webpack_exports__.MOD;\nvar __webpack_exports__ScaleBy = __webpack_exports__.kwd;\nvar __webpack_exports__ScaleTo = __webpack_exports__.Lmr;\nvar __webpack_exports__Scene = __webpack_exports__.xsS;\nvar __webpack_exports__SceneEvents = __webpack_exports__.K5l;\nvar __webpack_exports__Screen = __webpack_exports__.lLr;\nvar __webpack_exports__ScreenAppender = __webpack_exports__.Z$r;\nvar __webpack_exports__ScreenElement = __webpack_exports__.IXb;\nvar __webpack_exports__ScreenShader = __webpack_exports__.SGH;\nvar __webpack_exports__ScrollPreventionMode = __webpack_exports__.SMj;\nvar __webpack_exports__Semaphore = __webpack_exports__.L34;\nvar __webpack_exports__Shader = __webpack_exports__.exe;\nvar __webpack_exports__Shape = __webpack_exports__.bnF;\nvar __webpack_exports__Side = __webpack_exports__.MFA;\nvar __webpack_exports__Sound = __webpack_exports__.$uU;\nvar __webpack_exports__SoundEvents = __webpack_exports__.Sap;\nvar __webpack_exports__Sprite = __webpack_exports__.jyi;\nvar __webpack_exports__SpriteFont = __webpack_exports__.E03;\nvar __webpack_exports__SpriteSheet = __webpack_exports__.V6q;\nvar __webpack_exports__StandardClock = __webpack_exports__.rg2;\nvar __webpack_exports__StateMachine = __webpack_exports__.DVW;\nvar __webpack_exports__StrategyContainer = __webpack_exports__.nVo;\nvar __webpack_exports__Stream = __webpack_exports__.F6N;\nvar __webpack_exports__System = __webpack_exports__.xP7;\nvar __webpack_exports__SystemManager = __webpack_exports__.Odq;\nvar __webpack_exports__SystemType = __webpack_exports__.Zif;\nvar __webpack_exports__TagComponent = __webpack_exports__.ZGJ;\nvar __webpack_exports__TestClock = __webpack_exports__.MJk;\nvar __webpack_exports__Text = __webpack_exports__.xvT;\nvar __webpack_exports__TextAlign = __webpack_exports__.PHM;\nvar __webpack_exports__TextureLoader = __webpack_exports__.dpR;\nvar __webpack_exports__Tile = __webpack_exports__.n9L;\nvar __webpack_exports__TileMap = __webpack_exports__.KwO;\nvar __webpack_exports__TileMapEvents = __webpack_exports__.SxM;\nvar __webpack_exports__Timer = __webpack_exports__.B7y;\nvar __webpack_exports__Toaster = __webpack_exports__.x7r;\nvar __webpack_exports__Transform = __webpack_exports__.wx7;\nvar __webpack_exports__TransformComponent = __webpack_exports__.Uvn;\nvar __webpack_exports__TreeNode = __webpack_exports__.OFT;\nvar __webpack_exports__Trigger = __webpack_exports__.xzN;\nvar __webpack_exports__TriggerEvents = __webpack_exports__.CcZ;\nvar __webpack_exports__TwoPI = __webpack_exports__.M5Z;\nvar __webpack_exports__Util = __webpack_exports__.ZrN;\nvar __webpack_exports__Vector = __webpack_exports__.OWs;\nvar __webpack_exports__VectorView = __webpack_exports__.dF9;\nvar __webpack_exports__VertexBuffer = __webpack_exports__.oZy;\nvar __webpack_exports__VertexLayout = __webpack_exports__.rD2;\nvar __webpack_exports__VisibleEvent = __webpack_exports__.VHo;\nvar __webpack_exports__WebAudio = __webpack_exports__.ohE;\nvar __webpack_exports__WebAudioInstance = __webpack_exports__.R$E;\nvar __webpack_exports__WheelDeltaMode = __webpack_exports__.xQN;\nvar __webpack_exports__WheelEvent = __webpack_exports__.AdJ;\nvar __webpack_exports__World = __webpack_exports__.q3I;\nvar __webpack_exports__canonicalizeAngle = __webpack_exports__.Pab;\nvar __webpack_exports__clamp = __webpack_exports__.uZ5;\nvar __webpack_exports__createId = __webpack_exports__.McK;\nvar __webpack_exports__frac = __webpack_exports__.F9c;\nvar __webpack_exports__hasGraphicsTick = __webpack_exports__.k0b;\nvar __webpack_exports__hasOnInitialize = __webpack_exports__.hnT;\nvar __webpack_exports__hasOnPostUpdate = __webpack_exports__.RSJ;\nvar __webpack_exports__hasOnPreUpdate = __webpack_exports__.Mku;\nvar __webpack_exports__hasPostDraw = __webpack_exports__.h90;\nvar __webpack_exports__hasPreDraw = __webpack_exports__.rms;\nvar __webpack_exports__has_initialize = __webpack_exports__.ErP;\nvar __webpack_exports__has_postupdate = __webpack_exports__.aVg;\nvar __webpack_exports__has_preupdate = __webpack_exports__.lPc;\nvar __webpack_exports__isAddedComponent = __webpack_exports__.Z8E;\nvar __webpack_exports__isAddedSystemEntity = __webpack_exports__._N2;\nvar __webpack_exports__isRemoveSystemEntity = __webpack_exports__.yFn;\nvar __webpack_exports__isRemovedComponent = __webpack_exports__.lNv;\nvar __webpack_exports__isScreenElement = __webpack_exports__.cu9;\nvar __webpack_exports__maxMessages = __webpack_exports__.MZQ;\nvar __webpack_exports__obsolete = __webpack_exports__.FUM;\nvar __webpack_exports__pixelSnapEpsilon = __webpack_exports__.BxR;\nvar __webpack_exports__randomInRange = __webpack_exports__.vdf;\nvar __webpack_exports__randomIntInRange = __webpack_exports__.iaL;\nvar __webpack_exports__range = __webpack_exports__.w6H;\nvar __webpack_exports__resetObsoleteCounter = __webpack_exports__.Q4c;\nvar __webpack_exports__sign = __webpack_exports__.Xxe;\nvar __webpack_exports__toDegrees = __webpack_exports__.Uxb;\nvar __webpack_exports__toRadians = __webpack_exports__.Yr5;\nvar __webpack_exports__vec = __webpack_exports__.Bhw;\nvar __webpack_exports__webgl = __webpack_exports__.yOA;\nexport { __webpack_exports__ActionContext as ActionContext, __webpack_exports__ActionQueue as ActionQueue, __webpack_exports__ActionSequence as ActionSequence, __webpack_exports__ActionsComponent as ActionsComponent, __webpack_exports__ActionsSystem as ActionsSystem, __webpack_exports__ActivateEvent as ActivateEvent, __webpack_exports__Actor as Actor, __webpack_exports__AddedComponent as AddedComponent, __webpack_exports__AddedEntity as AddedEntity, __webpack_exports__AffineMatrix as AffineMatrix, __webpack_exports__Animation as Animation, __webpack_exports__AnimationDirection as AnimationDirection, __webpack_exports__AnimationEvents as AnimationEvents, __webpack_exports__AnimationStrategy as AnimationStrategy, __webpack_exports__ArcadeSolver as ArcadeSolver, __webpack_exports__AudioContextFactory as AudioContextFactory, __webpack_exports__Axes as Axes, __webpack_exports__Axis as Axis, __webpack_exports__BaseAlign as BaseAlign, __webpack_exports__Blink as Blink, __webpack_exports__BodyComponent as BodyComponent, __webpack_exports__BoundingBox as BoundingBox, __webpack_exports__BroadphaseStrategy as BroadphaseStrategy, __webpack_exports__BrowserComponent as BrowserComponent, __webpack_exports__BrowserEvents as BrowserEvents, __webpack_exports__Buttons as Buttons, __webpack_exports__Camera as Camera, __webpack_exports__CameraEvents as CameraEvents, __webpack_exports__Canvas as Canvas, __webpack_exports__Circle as Circle, __webpack_exports__CircleCollider as CircleCollider, __webpack_exports__Clock as Clock, __webpack_exports__ClosestLine as ClosestLine, __webpack_exports__ClosestLineJumpTable as ClosestLineJumpTable, __webpack_exports__Collider as Collider, __webpack_exports__ColliderComponent as ColliderComponent, __webpack_exports__CollisionContact as CollisionContact, __webpack_exports__CollisionEndEvent as CollisionEndEvent, __webpack_exports__CollisionGroup as CollisionGroup, __webpack_exports__CollisionGroupManager as CollisionGroupManager, __webpack_exports__CollisionJumpTable as CollisionJumpTable, __webpack_exports__CollisionPostSolveEvent as CollisionPostSolveEvent, __webpack_exports__CollisionPreSolveEvent as CollisionPreSolveEvent, __webpack_exports__CollisionResolutionStrategy as CollisionResolutionStrategy, __webpack_exports__CollisionStartEvent as CollisionStartEvent, __webpack_exports__CollisionSystem as CollisionSystem, __webpack_exports__CollisionType as CollisionType, __webpack_exports__Color as Color, __webpack_exports__ColorBlindFlags as ColorBlindFlags, __webpack_exports__ColorBlindnessMode as ColorBlindnessMode, __webpack_exports__ColorBlindnessPostProcessor as ColorBlindnessPostProcessor, __webpack_exports__Component as Component, __webpack_exports__CompositeCollider as CompositeCollider, __webpack_exports__Configurable as Configurable, __webpack_exports__ConsoleAppender as ConsoleAppender, __webpack_exports__ContactConstraintPoint as ContactConstraintPoint, __webpack_exports__ContactEndEvent as ContactEndEvent, __webpack_exports__ContactStartEvent as ContactStartEvent, __webpack_exports__CoordPlane as CoordPlane, __webpack_exports__DeactivateEvent as DeactivateEvent, __webpack_exports__Debug as Debug, __webpack_exports__DebugGraphicsComponent as DebugGraphicsComponent, __webpack_exports__DebugSystem as DebugSystem, __webpack_exports__DebugText as DebugText, __webpack_exports__DegreeOfFreedom as DegreeOfFreedom, __webpack_exports__Delay as Delay, __webpack_exports__Detector as Detector, __webpack_exports__Die as Die, __webpack_exports__Direction as Direction, __webpack_exports__DisplayMode as DisplayMode, __webpack_exports__DynamicTree as DynamicTree, __webpack_exports__DynamicTreeCollisionProcessor as DynamicTreeCollisionProcessor, __webpack_exports__EX_VERSION as EX_VERSION, __webpack_exports__EaseBy as EaseBy, __webpack_exports__EaseTo as EaseTo, __webpack_exports__EasingFunctions as EasingFunctions, __webpack_exports__EdgeCollider as EdgeCollider, __webpack_exports__ElasticToActorStrategy as ElasticToActorStrategy, __webpack_exports__EmitterType as EmitterType, __webpack_exports__Engine as Engine, __webpack_exports__EngineEvents as EngineEvents, __webpack_exports__EnterTriggerEvent as EnterTriggerEvent, __webpack_exports__EnterViewPortEvent as EnterViewPortEvent, __webpack_exports__Entity as Entity, __webpack_exports__EntityEvents as EntityEvents, __webpack_exports__EntityManager as EntityManager, __webpack_exports__EventDispatcher as EventDispatcher, __webpack_exports__EventEmitter as EventEmitter, __webpack_exports__EventTypes as EventTypes, __webpack_exports__Events as Events, __webpack_exports__ExResponse as ExResponse, __webpack_exports__ExcaliburGraphicsContext2DCanvas as ExcaliburGraphicsContext2DCanvas, __webpack_exports__ExcaliburGraphicsContextWebGL as ExcaliburGraphicsContextWebGL, __webpack_exports__ExitTriggerEvent as ExitTriggerEvent, __webpack_exports__ExitViewPortEvent as ExitViewPortEvent, __webpack_exports__Fade as Fade, __webpack_exports__Flags as Flags, __webpack_exports__Follow as Follow, __webpack_exports__Font as Font, __webpack_exports__FontCache as FontCache, __webpack_exports__FontStyle as FontStyle, __webpack_exports__FontUnit as FontUnit, __webpack_exports__FpsSampler as FpsSampler, __webpack_exports__FrameStats as FrameStats, __webpack_exports__Future as Future, __webpack_exports__GameEvent as GameEvent, __webpack_exports__GameStartEvent as GameStartEvent, __webpack_exports__GameStopEvent as GameStopEvent, __webpack_exports__Gamepad as Gamepad, __webpack_exports__GamepadAxisEvent as GamepadAxisEvent, __webpack_exports__GamepadButtonEvent as GamepadButtonEvent, __webpack_exports__GamepadConnectEvent as GamepadConnectEvent, __webpack_exports__GamepadDisconnectEvent as GamepadDisconnectEvent, __webpack_exports__Gamepads as Gamepads, __webpack_exports__Gif as Gif, __webpack_exports__GlobalCoordinates as GlobalCoordinates, __webpack_exports__Graphic as Graphic, __webpack_exports__GraphicsComponent as GraphicsComponent, __webpack_exports__GraphicsGroup as GraphicsGroup, __webpack_exports__GraphicsLayer as GraphicsLayer, __webpack_exports__GraphicsLayers as GraphicsLayers, __webpack_exports__GraphicsSystem as GraphicsSystem, __webpack_exports__HiddenEvent as HiddenEvent, __webpack_exports__ImageFiltering as ImageFiltering, __webpack_exports__ImageSource as ImageSource, __webpack_exports__InitializeEvent as InitializeEvent, __webpack_exports__Input as Input, __webpack_exports__InputMapper as InputMapper, __webpack_exports__Integrator as Integrator, __webpack_exports__IsometricEntityComponent as IsometricEntityComponent, __webpack_exports__IsometricEntitySystem as IsometricEntitySystem, __webpack_exports__IsometricMap as IsometricMap, __webpack_exports__IsometricTile as IsometricTile, __webpack_exports__KeyEvent as KeyEvent, __webpack_exports__Keyboard as Keyboard, __webpack_exports__Keys as Keys, __webpack_exports__KillEvent as KillEvent, __webpack_exports__Label as Label, __webpack_exports__LimitCameraBoundsStrategy as LimitCameraBoundsStrategy, __webpack_exports__Line as Line, __webpack_exports__LineSegment as LineSegment, __webpack_exports__Loader as Loader, __webpack_exports__LoaderEvents as LoaderEvents, __webpack_exports__LockCameraToActorAxisStrategy as LockCameraToActorAxisStrategy, __webpack_exports__LockCameraToActorStrategy as LockCameraToActorStrategy, __webpack_exports__LogLevel as LogLevel, __webpack_exports__Logger as Logger, __webpack_exports__Material as Material, __webpack_exports__Matrix as Matrix, __webpack_exports__MatrixLocations as MatrixLocations, __webpack_exports__MediaEvent as MediaEvent, __webpack_exports__Meet as Meet, __webpack_exports__MotionComponent as MotionComponent, __webpack_exports__MotionSystem as MotionSystem, __webpack_exports__MoveBy as MoveBy, __webpack_exports__MoveTo as MoveTo, __webpack_exports__NativePointerButton as NativePointerButton, __webpack_exports__NativeSoundEvent as NativeSoundEvent, __webpack_exports__NativeSoundProcessedEvent as NativeSoundProcessedEvent, __webpack_exports__Observable as Observable, __webpack_exports__OffscreenSystem as OffscreenSystem, __webpack_exports__Pair as Pair, __webpack_exports__ParallaxComponent as ParallaxComponent, __webpack_exports__ParallelActions as ParallelActions, __webpack_exports__ParseGif as ParseGif, __webpack_exports__Particle as Particle, __webpack_exports__ParticleEmitter as ParticleEmitter, __webpack_exports__ParticleTransform as ParticleTransform, __webpack_exports__Physics as Physics, __webpack_exports__PhysicsStats as PhysicsStats, __webpack_exports__PhysicsWorld as PhysicsWorld, __webpack_exports__PointerButton as PointerButton, __webpack_exports__PointerComponent as PointerComponent, __webpack_exports__PointerEvent as PointerEvent, __webpack_exports__PointerEventReceiver as PointerEventReceiver, __webpack_exports__PointerScope as PointerScope, __webpack_exports__PointerSystem as PointerSystem, __webpack_exports__PointerType as PointerType, __webpack_exports__Polygon as Polygon, __webpack_exports__PolygonCollider as PolygonCollider, __webpack_exports__Pool as Pool, __webpack_exports__PostCollisionEvent as PostCollisionEvent, __webpack_exports__PostDebugDrawEvent as PostDebugDrawEvent, __webpack_exports__PostDrawEvent as PostDrawEvent, __webpack_exports__PostFrameEvent as PostFrameEvent, __webpack_exports__PostKillEvent as PostKillEvent, __webpack_exports__PostUpdateEvent as PostUpdateEvent, __webpack_exports__PreCollisionEvent as PreCollisionEvent, __webpack_exports__PreDebugDrawEvent as PreDebugDrawEvent, __webpack_exports__PreDrawEvent as PreDrawEvent, __webpack_exports__PreFrameEvent as PreFrameEvent, __webpack_exports__PreKillEvent as PreKillEvent, __webpack_exports__PreUpdateEvent as PreUpdateEvent, __webpack_exports__Projection as Projection, __webpack_exports__QuadIndexBuffer as QuadIndexBuffer, __webpack_exports__Query as Query, __webpack_exports__QueryManager as QueryManager, __webpack_exports__RadiusAroundActorStrategy as RadiusAroundActorStrategy, __webpack_exports__Random as Random, __webpack_exports__Raster as Raster, __webpack_exports__Ray as Ray, __webpack_exports__RealisticSolver as RealisticSolver, __webpack_exports__Rectangle as Rectangle, __webpack_exports__RemovedComponent as RemovedComponent, __webpack_exports__RemovedEntity as RemovedEntity, __webpack_exports__Repeat as Repeat, __webpack_exports__RepeatForever as RepeatForever, __webpack_exports__Resolution as Resolution, __webpack_exports__Resource as Resource, __webpack_exports__ResourceEvents as ResourceEvents, __webpack_exports__RotateBy as RotateBy, __webpack_exports__RotateTo as RotateTo, __webpack_exports__RotationType as RotationType, __webpack_exports__ScaleBy as ScaleBy, __webpack_exports__ScaleTo as ScaleTo, __webpack_exports__Scene as Scene, __webpack_exports__SceneEvents as SceneEvents, __webpack_exports__Screen as Screen, __webpack_exports__ScreenAppender as ScreenAppender, __webpack_exports__ScreenElement as ScreenElement, __webpack_exports__ScreenShader as ScreenShader, __webpack_exports__ScrollPreventionMode as ScrollPreventionMode, __webpack_exports__Semaphore as Semaphore, __webpack_exports__Shader as Shader, __webpack_exports__Shape as Shape, __webpack_exports__Side as Side, __webpack_exports__Sound as Sound, __webpack_exports__SoundEvents as SoundEvents, __webpack_exports__Sprite as Sprite, __webpack_exports__SpriteFont as SpriteFont, __webpack_exports__SpriteSheet as SpriteSheet, __webpack_exports__StandardClock as StandardClock, __webpack_exports__StateMachine as StateMachine, __webpack_exports__StrategyContainer as StrategyContainer, __webpack_exports__Stream as Stream, __webpack_exports__System as System, __webpack_exports__SystemManager as SystemManager, __webpack_exports__SystemType as SystemType, __webpack_exports__TagComponent as TagComponent, __webpack_exports__TestClock as TestClock, __webpack_exports__Text as Text, __webpack_exports__TextAlign as TextAlign, __webpack_exports__TextureLoader as TextureLoader, __webpack_exports__Tile as Tile, __webpack_exports__TileMap as TileMap, __webpack_exports__TileMapEvents as TileMapEvents, __webpack_exports__Timer as Timer, __webpack_exports__Toaster as Toaster, __webpack_exports__Transform as Transform, __webpack_exports__TransformComponent as TransformComponent, __webpack_exports__TreeNode as TreeNode, __webpack_exports__Trigger as Trigger, __webpack_exports__TriggerEvents as TriggerEvents, __webpack_exports__TwoPI as TwoPI, __webpack_exports__Util as Util, __webpack_exports__Vector as Vector, __webpack_exports__VectorView as VectorView, __webpack_exports__VertexBuffer as VertexBuffer, __webpack_exports__VertexLayout as VertexLayout, __webpack_exports__VisibleEvent as VisibleEvent, __webpack_exports__WebAudio as WebAudio, __webpack_exports__WebAudioInstance as WebAudioInstance, __webpack_exports__WheelDeltaMode as WheelDeltaMode, __webpack_exports__WheelEvent as WheelEvent, __webpack_exports__World as World, __webpack_exports__canonicalizeAngle as canonicalizeAngle, __webpack_exports__clamp as clamp, __webpack_exports__createId as createId, __webpack_exports__frac as frac, __webpack_exports__hasGraphicsTick as hasGraphicsTick, __webpack_exports__hasOnInitialize as hasOnInitialize, __webpack_exports__hasOnPostUpdate as hasOnPostUpdate, __webpack_exports__hasOnPreUpdate as hasOnPreUpdate, __webpack_exports__hasPostDraw as hasPostDraw, __webpack_exports__hasPreDraw as hasPreDraw, __webpack_exports__has_initialize as has_initialize, __webpack_exports__has_postupdate as has_postupdate, __webpack_exports__has_preupdate as has_preupdate, __webpack_exports__isAddedComponent as isAddedComponent, __webpack_exports__isAddedSystemEntity as isAddedSystemEntity, __webpack_exports__isRemoveSystemEntity as isRemoveSystemEntity, __webpack_exports__isRemovedComponent as isRemovedComponent, __webpack_exports__isScreenElement as isScreenElement, __webpack_exports__maxMessages as maxMessages, __webpack_exports__obsolete as obsolete, __webpack_exports__pixelSnapEpsilon as pixelSnapEpsilon, __webpack_exports__randomInRange as randomInRange, __webpack_exports__randomIntInRange as randomIntInRange, __webpack_exports__range as range, __webpack_exports__resetObsoleteCounter as resetObsoleteCounter, __webpack_exports__sign as sign, __webpack_exports__toDegrees as toDegrees, __webpack_exports__toRadians as toRadians, __webpack_exports__vec as vec, __webpack_exports__webgl as webgl };\n\n//# sourceMappingURL=excalibur.js.map","'use strict';\nrequire('../../modules/es.array.sort');\nvar entryUnbind = require('../../internals/entry-unbind');\n\nmodule.exports = entryUnbind('Array', 'sort');\n","'use strict';\nrequire('../../modules/es.object.keys');\nvar path = require('../../internals/path');\n\nmodule.exports = path.Object.keys;\n","'use strict';\nvar isCallable = require('../internals/is-callable');\nvar tryToString = require('../internals/try-to-string');\n\nvar $TypeError = TypeError;\n\n// `Assert: IsCallable(argument) is true`\nmodule.exports = function (argument) {\n if (isCallable(argument)) return argument;\n throw $TypeError(tryToString(argument) + ' is not a function');\n};\n","'use strict';\nvar isObject = require('../internals/is-object');\n\nvar $String = String;\nvar $TypeError = TypeError;\n\n// `Assert: Type(argument) is Object`\nmodule.exports = function (argument) {\n if (isObject(argument)) return argument;\n throw $TypeError($String(argument) + ' is not an object');\n};\n","'use strict';\nvar toIndexedObject = require('../internals/to-indexed-object');\nvar toAbsoluteIndex = require('../internals/to-absolute-index');\nvar lengthOfArrayLike = require('../internals/length-of-array-like');\n\n// `Array.prototype.{ indexOf, includes }` methods implementation\nvar createMethod = function (IS_INCLUDES) {\n return function ($this, el, fromIndex) {\n var O = toIndexedObject($this);\n var length = lengthOfArrayLike(O);\n var index = toAbsoluteIndex(fromIndex, length);\n var value;\n // Array#includes uses SameValueZero equality algorithm\n // eslint-disable-next-line no-self-compare -- NaN check\n if (IS_INCLUDES && el != el) while (length > index) {\n value = O[index++];\n // eslint-disable-next-line no-self-compare -- NaN check\n if (value != value) return true;\n // Array#indexOf ignores holes, Array#includes - not\n } else for (;length > index; index++) {\n if ((IS_INCLUDES || index in O) && O[index] === el) return IS_INCLUDES || index || 0;\n } return !IS_INCLUDES && -1;\n };\n};\n\nmodule.exports = {\n // `Array.prototype.includes` method\n // https://tc39.es/ecma262/#sec-array.prototype.includes\n includes: createMethod(true),\n // `Array.prototype.indexOf` method\n // https://tc39.es/ecma262/#sec-array.prototype.indexof\n indexOf: createMethod(false)\n};\n","'use strict';\nvar fails = require('../internals/fails');\n\nmodule.exports = function (METHOD_NAME, argument) {\n var method = [][METHOD_NAME];\n return !!method && fails(function () {\n // eslint-disable-next-line no-useless-call -- required for testing\n method.call(null, argument || function () { return 1; }, 1);\n });\n};\n","'use strict';\nvar toAbsoluteIndex = require('../internals/to-absolute-index');\nvar lengthOfArrayLike = require('../internals/length-of-array-like');\nvar createProperty = require('../internals/create-property');\n\nvar $Array = Array;\nvar max = Math.max;\n\nmodule.exports = function (O, start, end) {\n var length = lengthOfArrayLike(O);\n var k = toAbsoluteIndex(start, length);\n var fin = toAbsoluteIndex(end === undefined ? length : end, length);\n var result = $Array(max(fin - k, 0));\n for (var n = 0; k < fin; k++, n++) createProperty(result, n, O[k]);\n result.length = n;\n return result;\n};\n","'use strict';\nvar arraySlice = require('../internals/array-slice-simple');\n\nvar floor = Math.floor;\n\nvar mergeSort = function (array, comparefn) {\n var length = array.length;\n var middle = floor(length / 2);\n return length < 8 ? insertionSort(array, comparefn) : merge(\n array,\n mergeSort(arraySlice(array, 0, middle), comparefn),\n mergeSort(arraySlice(array, middle), comparefn),\n comparefn\n );\n};\n\nvar insertionSort = function (array, comparefn) {\n var length = array.length;\n var i = 1;\n var element, j;\n\n while (i < length) {\n j = i;\n element = array[i];\n while (j && comparefn(array[j - 1], element) > 0) {\n array[j] = array[--j];\n }\n if (j !== i++) array[j] = element;\n } return array;\n};\n\nvar merge = function (array, left, right, comparefn) {\n var llength = left.length;\n var rlength = right.length;\n var lindex = 0;\n var rindex = 0;\n\n while (lindex < llength || rindex < rlength) {\n array[lindex + rindex] = (lindex < llength && rindex < rlength)\n ? comparefn(left[lindex], right[rindex]) <= 0 ? left[lindex++] : right[rindex++]\n : lindex < llength ? left[lindex++] : right[rindex++];\n } return array;\n};\n\nmodule.exports = mergeSort;\n","'use strict';\nvar uncurryThis = require('../internals/function-uncurry-this');\n\nvar toString = uncurryThis({}.toString);\nvar stringSlice = uncurryThis(''.slice);\n\nmodule.exports = function (it) {\n return stringSlice(toString(it), 8, -1);\n};\n","'use strict';\nvar TO_STRING_TAG_SUPPORT = require('../internals/to-string-tag-support');\nvar isCallable = require('../internals/is-callable');\nvar classofRaw = require('../internals/classof-raw');\nvar wellKnownSymbol = require('../internals/well-known-symbol');\n\nvar TO_STRING_TAG = wellKnownSymbol('toStringTag');\nvar $Object = Object;\n\n// ES3 wrong here\nvar CORRECT_ARGUMENTS = classofRaw(function () { return arguments; }()) == 'Arguments';\n\n// fallback for IE11 Script Access Denied error\nvar tryGet = function (it, key) {\n try {\n return it[key];\n } catch (error) { /* empty */ }\n};\n\n// getting tag from ES6+ `Object.prototype.toString`\nmodule.exports = TO_STRING_TAG_SUPPORT ? classofRaw : function (it) {\n var O, tag, result;\n return it === undefined ? 'Undefined' : it === null ? 'Null'\n // @@toStringTag case\n : typeof (tag = tryGet(O = $Object(it), TO_STRING_TAG)) == 'string' ? tag\n // builtinTag case\n : CORRECT_ARGUMENTS ? classofRaw(O)\n // ES3 arguments fallback\n : (result = classofRaw(O)) == 'Object' && isCallable(O.callee) ? 'Arguments' : result;\n};\n","'use strict';\nvar hasOwn = require('../internals/has-own-property');\nvar ownKeys = require('../internals/own-keys');\nvar getOwnPropertyDescriptorModule = require('../internals/object-get-own-property-descriptor');\nvar definePropertyModule = require('../internals/object-define-property');\n\nmodule.exports = function (target, source, exceptions) {\n var keys = ownKeys(source);\n var defineProperty = definePropertyModule.f;\n var getOwnPropertyDescriptor = getOwnPropertyDescriptorModule.f;\n for (var i = 0; i < keys.length; i++) {\n var key = keys[i];\n if (!hasOwn(target, key) && !(exceptions && hasOwn(exceptions, key))) {\n defineProperty(target, key, getOwnPropertyDescriptor(source, key));\n }\n }\n};\n","'use strict';\nvar DESCRIPTORS = require('../internals/descriptors');\nvar definePropertyModule = require('../internals/object-define-property');\nvar createPropertyDescriptor = require('../internals/create-property-descriptor');\n\nmodule.exports = DESCRIPTORS ? function (object, key, value) {\n return definePropertyModule.f(object, key, createPropertyDescriptor(1, value));\n} : function (object, key, value) {\n object[key] = value;\n return object;\n};\n","'use strict';\nmodule.exports = function (bitmap, value) {\n return {\n enumerable: !(bitmap & 1),\n configurable: !(bitmap & 2),\n writable: !(bitmap & 4),\n value: value\n };\n};\n","'use strict';\nvar toPropertyKey = require('../internals/to-property-key');\nvar definePropertyModule = require('../internals/object-define-property');\nvar createPropertyDescriptor = require('../internals/create-property-descriptor');\n\nmodule.exports = function (object, key, value) {\n var propertyKey = toPropertyKey(key);\n if (propertyKey in object) definePropertyModule.f(object, propertyKey, createPropertyDescriptor(0, value));\n else object[propertyKey] = value;\n};\n","'use strict';\nvar isCallable = require('../internals/is-callable');\nvar definePropertyModule = require('../internals/object-define-property');\nvar makeBuiltIn = require('../internals/make-built-in');\nvar defineGlobalProperty = require('../internals/define-global-property');\n\nmodule.exports = function (O, key, value, options) {\n if (!options) options = {};\n var simple = options.enumerable;\n var name = options.name !== undefined ? options.name : key;\n if (isCallable(value)) makeBuiltIn(value, name, options);\n if (options.global) {\n if (simple) O[key] = value;\n else defineGlobalProperty(key, value);\n } else {\n try {\n if (!options.unsafe) delete O[key];\n else if (O[key]) simple = true;\n } catch (error) { /* empty */ }\n if (simple) O[key] = value;\n else definePropertyModule.f(O, key, {\n value: value,\n enumerable: false,\n configurable: !options.nonConfigurable,\n writable: !options.nonWritable\n });\n } return O;\n};\n","'use strict';\nvar global = require('../internals/global');\n\n// eslint-disable-next-line es/no-object-defineproperty -- safe\nvar defineProperty = Object.defineProperty;\n\nmodule.exports = function (key, value) {\n try {\n defineProperty(global, key, { value: value, configurable: true, writable: true });\n } catch (error) {\n global[key] = value;\n } return value;\n};\n","'use strict';\nvar tryToString = require('../internals/try-to-string');\n\nvar $TypeError = TypeError;\n\nmodule.exports = function (O, P) {\n if (!delete O[P]) throw $TypeError('Cannot delete property ' + tryToString(P) + ' of ' + tryToString(O));\n};\n","'use strict';\nvar fails = require('../internals/fails');\n\n// Detect IE8's incomplete defineProperty implementation\nmodule.exports = !fails(function () {\n // eslint-disable-next-line es/no-object-defineproperty -- required for testing\n return Object.defineProperty({}, 1, { get: function () { return 7; } })[1] != 7;\n});\n","'use strict';\nvar documentAll = typeof document == 'object' && document.all;\n\n// https://tc39.es/ecma262/#sec-IsHTMLDDA-internal-slot\n// eslint-disable-next-line unicorn/no-typeof-undefined -- required for testing\nvar IS_HTMLDDA = typeof documentAll == 'undefined' && documentAll !== undefined;\n\nmodule.exports = {\n all: documentAll,\n IS_HTMLDDA: IS_HTMLDDA\n};\n","'use strict';\nvar global = require('../internals/global');\nvar isObject = require('../internals/is-object');\n\nvar document = global.document;\n// typeof document.createElement is 'object' in old IE\nvar EXISTS = isObject(document) && isObject(document.createElement);\n\nmodule.exports = function (it) {\n return EXISTS ? document.createElement(it) : {};\n};\n","'use strict';\nvar userAgent = require('../internals/engine-user-agent');\n\nvar firefox = userAgent.match(/firefox\\/(\\d+)/i);\n\nmodule.exports = !!firefox && +firefox[1];\n","'use strict';\nvar UA = require('../internals/engine-user-agent');\n\nmodule.exports = /MSIE|Trident/.test(UA);\n","'use strict';\nmodule.exports = typeof navigator != 'undefined' && String(navigator.userAgent) || '';\n","'use strict';\nvar global = require('../internals/global');\nvar userAgent = require('../internals/engine-user-agent');\n\nvar process = global.process;\nvar Deno = global.Deno;\nvar versions = process && process.versions || Deno && Deno.version;\nvar v8 = versions && versions.v8;\nvar match, version;\n\nif (v8) {\n match = v8.split('.');\n // in old Chrome, versions of V8 isn't V8 = Chrome / 10\n // but their correct versions are not interesting for us\n version = match[0] > 0 && match[0] < 4 ? 1 : +(match[0] + match[1]);\n}\n\n// BrowserFS NodeJS `process` polyfill incorrectly set `.v8` to `0.0`\n// so check `userAgent` even if `.v8` exists, but 0\nif (!version && userAgent) {\n match = userAgent.match(/Edge\\/(\\d+)/);\n if (!match || match[1] >= 74) {\n match = userAgent.match(/Chrome\\/(\\d+)/);\n if (match) version = +match[1];\n }\n}\n\nmodule.exports = version;\n","'use strict';\nvar userAgent = require('../internals/engine-user-agent');\n\nvar webkit = userAgent.match(/AppleWebKit\\/(\\d+)\\./);\n\nmodule.exports = !!webkit && +webkit[1];\n","'use strict';\nvar global = require('../internals/global');\nvar uncurryThis = require('../internals/function-uncurry-this');\n\nmodule.exports = function (CONSTRUCTOR, METHOD) {\n return uncurryThis(global[CONSTRUCTOR].prototype[METHOD]);\n};\n","'use strict';\n// IE8- don't enum bug keys\nmodule.exports = [\n 'constructor',\n 'hasOwnProperty',\n 'isPrototypeOf',\n 'propertyIsEnumerable',\n 'toLocaleString',\n 'toString',\n 'valueOf'\n];\n","'use strict';\nvar global = require('../internals/global');\nvar getOwnPropertyDescriptor = require('../internals/object-get-own-property-descriptor').f;\nvar createNonEnumerableProperty = require('../internals/create-non-enumerable-property');\nvar defineBuiltIn = require('../internals/define-built-in');\nvar defineGlobalProperty = require('../internals/define-global-property');\nvar copyConstructorProperties = require('../internals/copy-constructor-properties');\nvar isForced = require('../internals/is-forced');\n\n/*\n options.target - name of the target object\n options.global - target is the global object\n options.stat - export as static methods of target\n options.proto - export as prototype methods of target\n options.real - real prototype method for the `pure` version\n options.forced - export even if the native feature is available\n options.bind - bind methods to the target, required for the `pure` version\n options.wrap - wrap constructors to preventing global pollution, required for the `pure` version\n options.unsafe - use the simple assignment of property instead of delete + defineProperty\n options.sham - add a flag to not completely full polyfills\n options.enumerable - export as enumerable property\n options.dontCallGetSet - prevent calling a getter on target\n options.name - the .name of the function if it does not match the key\n*/\nmodule.exports = function (options, source) {\n var TARGET = options.target;\n var GLOBAL = options.global;\n var STATIC = options.stat;\n var FORCED, target, key, targetProperty, sourceProperty, descriptor;\n if (GLOBAL) {\n target = global;\n } else if (STATIC) {\n target = global[TARGET] || defineGlobalProperty(TARGET, {});\n } else {\n target = (global[TARGET] || {}).prototype;\n }\n if (target) for (key in source) {\n sourceProperty = source[key];\n if (options.dontCallGetSet) {\n descriptor = getOwnPropertyDescriptor(target, key);\n targetProperty = descriptor && descriptor.value;\n } else targetProperty = target[key];\n FORCED = isForced(GLOBAL ? key : TARGET + (STATIC ? '.' : '#') + key, options.forced);\n // contained in target\n if (!FORCED && targetProperty !== undefined) {\n if (typeof sourceProperty == typeof targetProperty) continue;\n copyConstructorProperties(sourceProperty, targetProperty);\n }\n // add a flag to not completely full polyfills\n if (options.sham || (targetProperty && targetProperty.sham)) {\n createNonEnumerableProperty(sourceProperty, 'sham', true);\n }\n defineBuiltIn(target, key, sourceProperty, options);\n }\n};\n","'use strict';\nmodule.exports = function (exec) {\n try {\n return !!exec();\n } catch (error) {\n return true;\n }\n};\n","'use strict';\nvar fails = require('../internals/fails');\n\nmodule.exports = !fails(function () {\n // eslint-disable-next-line es/no-function-prototype-bind -- safe\n var test = (function () { /* empty */ }).bind();\n // eslint-disable-next-line no-prototype-builtins -- safe\n return typeof test != 'function' || test.hasOwnProperty('prototype');\n});\n","'use strict';\nvar NATIVE_BIND = require('../internals/function-bind-native');\n\nvar call = Function.prototype.call;\n\nmodule.exports = NATIVE_BIND ? call.bind(call) : function () {\n return call.apply(call, arguments);\n};\n","'use strict';\nvar DESCRIPTORS = require('../internals/descriptors');\nvar hasOwn = require('../internals/has-own-property');\n\nvar FunctionPrototype = Function.prototype;\n// eslint-disable-next-line es/no-object-getownpropertydescriptor -- safe\nvar getDescriptor = DESCRIPTORS && Object.getOwnPropertyDescriptor;\n\nvar EXISTS = hasOwn(FunctionPrototype, 'name');\n// additional protection from minified / mangled / dropped function names\nvar PROPER = EXISTS && (function something() { /* empty */ }).name === 'something';\nvar CONFIGURABLE = EXISTS && (!DESCRIPTORS || (DESCRIPTORS && getDescriptor(FunctionPrototype, 'name').configurable));\n\nmodule.exports = {\n EXISTS: EXISTS,\n PROPER: PROPER,\n CONFIGURABLE: CONFIGURABLE\n};\n","'use strict';\nvar NATIVE_BIND = require('../internals/function-bind-native');\n\nvar FunctionPrototype = Function.prototype;\nvar call = FunctionPrototype.call;\nvar uncurryThisWithBind = NATIVE_BIND && FunctionPrototype.bind.bind(call, call);\n\nmodule.exports = NATIVE_BIND ? uncurryThisWithBind : function (fn) {\n return function () {\n return call.apply(fn, arguments);\n };\n};\n","'use strict';\nvar global = require('../internals/global');\nvar isCallable = require('../internals/is-callable');\n\nvar aFunction = function (argument) {\n return isCallable(argument) ? argument : undefined;\n};\n\nmodule.exports = function (namespace, method) {\n return arguments.length < 2 ? aFunction(global[namespace]) : global[namespace] && global[namespace][method];\n};\n","'use strict';\nvar aCallable = require('../internals/a-callable');\nvar isNullOrUndefined = require('../internals/is-null-or-undefined');\n\n// `GetMethod` abstract operation\n// https://tc39.es/ecma262/#sec-getmethod\nmodule.exports = function (V, P) {\n var func = V[P];\n return isNullOrUndefined(func) ? undefined : aCallable(func);\n};\n","'use strict';\nvar check = function (it) {\n return it && it.Math == Math && it;\n};\n\n// https://github.com/zloirock/core-js/issues/86#issuecomment-115759028\nmodule.exports =\n // eslint-disable-next-line es/no-global-this -- safe\n check(typeof globalThis == 'object' && globalThis) ||\n check(typeof window == 'object' && window) ||\n // eslint-disable-next-line no-restricted-globals -- safe\n check(typeof self == 'object' && self) ||\n check(typeof global == 'object' && global) ||\n // eslint-disable-next-line no-new-func -- fallback\n (function () { return this; })() || this || Function('return this')();\n","'use strict';\nvar uncurryThis = require('../internals/function-uncurry-this');\nvar toObject = require('../internals/to-object');\n\nvar hasOwnProperty = uncurryThis({}.hasOwnProperty);\n\n// `HasOwnProperty` abstract operation\n// https://tc39.es/ecma262/#sec-hasownproperty\n// eslint-disable-next-line es/no-object-hasown -- safe\nmodule.exports = Object.hasOwn || function hasOwn(it, key) {\n return hasOwnProperty(toObject(it), key);\n};\n","'use strict';\nmodule.exports = {};\n","'use strict';\nvar DESCRIPTORS = require('../internals/descriptors');\nvar fails = require('../internals/fails');\nvar createElement = require('../internals/document-create-element');\n\n// Thanks to IE8 for its funny defineProperty\nmodule.exports = !DESCRIPTORS && !fails(function () {\n // eslint-disable-next-line es/no-object-defineproperty -- required for testing\n return Object.defineProperty(createElement('div'), 'a', {\n get: function () { return 7; }\n }).a != 7;\n});\n","'use strict';\nvar uncurryThis = require('../internals/function-uncurry-this');\nvar fails = require('../internals/fails');\nvar classof = require('../internals/classof-raw');\n\nvar $Object = Object;\nvar split = uncurryThis(''.split);\n\n// fallback for non-array-like ES3 and non-enumerable old V8 strings\nmodule.exports = fails(function () {\n // throws an error in rhino, see https://github.com/mozilla/rhino/issues/346\n // eslint-disable-next-line no-prototype-builtins -- safe\n return !$Object('z').propertyIsEnumerable(0);\n}) ? function (it) {\n return classof(it) == 'String' ? split(it, '') : $Object(it);\n} : $Object;\n","'use strict';\nvar uncurryThis = require('../internals/function-uncurry-this');\nvar isCallable = require('../internals/is-callable');\nvar store = require('../internals/shared-store');\n\nvar functionToString = uncurryThis(Function.toString);\n\n// this helper broken in `core-js@3.4.1-3.4.4`, so we can't use `shared` helper\nif (!isCallable(store.inspectSource)) {\n store.inspectSource = function (it) {\n return functionToString(it);\n };\n}\n\nmodule.exports = store.inspectSource;\n","'use strict';\nvar NATIVE_WEAK_MAP = require('../internals/weak-map-basic-detection');\nvar global = require('../internals/global');\nvar isObject = require('../internals/is-object');\nvar createNonEnumerableProperty = require('../internals/create-non-enumerable-property');\nvar hasOwn = require('../internals/has-own-property');\nvar shared = require('../internals/shared-store');\nvar sharedKey = require('../internals/shared-key');\nvar hiddenKeys = require('../internals/hidden-keys');\n\nvar OBJECT_ALREADY_INITIALIZED = 'Object already initialized';\nvar TypeError = global.TypeError;\nvar WeakMap = global.WeakMap;\nvar set, get, has;\n\nvar enforce = function (it) {\n return has(it) ? get(it) : set(it, {});\n};\n\nvar getterFor = function (TYPE) {\n return function (it) {\n var state;\n if (!isObject(it) || (state = get(it)).type !== TYPE) {\n throw TypeError('Incompatible receiver, ' + TYPE + ' required');\n } return state;\n };\n};\n\nif (NATIVE_WEAK_MAP || shared.state) {\n var store = shared.state || (shared.state = new WeakMap());\n /* eslint-disable no-self-assign -- prototype methods protection */\n store.get = store.get;\n store.has = store.has;\n store.set = store.set;\n /* eslint-enable no-self-assign -- prototype methods protection */\n set = function (it, metadata) {\n if (store.has(it)) throw TypeError(OBJECT_ALREADY_INITIALIZED);\n metadata.facade = it;\n store.set(it, metadata);\n return metadata;\n };\n get = function (it) {\n return store.get(it) || {};\n };\n has = function (it) {\n return store.has(it);\n };\n} else {\n var STATE = sharedKey('state');\n hiddenKeys[STATE] = true;\n set = function (it, metadata) {\n if (hasOwn(it, STATE)) throw TypeError(OBJECT_ALREADY_INITIALIZED);\n metadata.facade = it;\n createNonEnumerableProperty(it, STATE, metadata);\n return metadata;\n };\n get = function (it) {\n return hasOwn(it, STATE) ? it[STATE] : {};\n };\n has = function (it) {\n return hasOwn(it, STATE);\n };\n}\n\nmodule.exports = {\n set: set,\n get: get,\n has: has,\n enforce: enforce,\n getterFor: getterFor\n};\n","'use strict';\nvar $documentAll = require('../internals/document-all');\n\nvar documentAll = $documentAll.all;\n\n// `IsCallable` abstract operation\n// https://tc39.es/ecma262/#sec-iscallable\nmodule.exports = $documentAll.IS_HTMLDDA ? function (argument) {\n return typeof argument == 'function' || argument === documentAll;\n} : function (argument) {\n return typeof argument == 'function';\n};\n","'use strict';\nvar fails = require('../internals/fails');\nvar isCallable = require('../internals/is-callable');\n\nvar replacement = /#|\\.prototype\\./;\n\nvar isForced = function (feature, detection) {\n var value = data[normalize(feature)];\n return value == POLYFILL ? true\n : value == NATIVE ? false\n : isCallable(detection) ? fails(detection)\n : !!detection;\n};\n\nvar normalize = isForced.normalize = function (string) {\n return String(string).replace(replacement, '.').toLowerCase();\n};\n\nvar data = isForced.data = {};\nvar NATIVE = isForced.NATIVE = 'N';\nvar POLYFILL = isForced.POLYFILL = 'P';\n\nmodule.exports = isForced;\n","'use strict';\n// we can't use just `it == null` since of `document.all` special case\n// https://tc39.es/ecma262/#sec-IsHTMLDDA-internal-slot-aec\nmodule.exports = function (it) {\n return it === null || it === undefined;\n};\n","'use strict';\nvar isCallable = require('../internals/is-callable');\nvar $documentAll = require('../internals/document-all');\n\nvar documentAll = $documentAll.all;\n\nmodule.exports = $documentAll.IS_HTMLDDA ? function (it) {\n return typeof it == 'object' ? it !== null : isCallable(it) || it === documentAll;\n} : function (it) {\n return typeof it == 'object' ? it !== null : isCallable(it);\n};\n","'use strict';\nmodule.exports = false;\n","'use strict';\nvar getBuiltIn = require('../internals/get-built-in');\nvar isCallable = require('../internals/is-callable');\nvar isPrototypeOf = require('../internals/object-is-prototype-of');\nvar USE_SYMBOL_AS_UID = require('../internals/use-symbol-as-uid');\n\nvar $Object = Object;\n\nmodule.exports = USE_SYMBOL_AS_UID ? function (it) {\n return typeof it == 'symbol';\n} : function (it) {\n var $Symbol = getBuiltIn('Symbol');\n return isCallable($Symbol) && isPrototypeOf($Symbol.prototype, $Object(it));\n};\n","'use strict';\nvar toLength = require('../internals/to-length');\n\n// `LengthOfArrayLike` abstract operation\n// https://tc39.es/ecma262/#sec-lengthofarraylike\nmodule.exports = function (obj) {\n return toLength(obj.length);\n};\n","'use strict';\nvar uncurryThis = require('../internals/function-uncurry-this');\nvar fails = require('../internals/fails');\nvar isCallable = require('../internals/is-callable');\nvar hasOwn = require('../internals/has-own-property');\nvar DESCRIPTORS = require('../internals/descriptors');\nvar CONFIGURABLE_FUNCTION_NAME = require('../internals/function-name').CONFIGURABLE;\nvar inspectSource = require('../internals/inspect-source');\nvar InternalStateModule = require('../internals/internal-state');\n\nvar enforceInternalState = InternalStateModule.enforce;\nvar getInternalState = InternalStateModule.get;\nvar $String = String;\n// eslint-disable-next-line es/no-object-defineproperty -- safe\nvar defineProperty = Object.defineProperty;\nvar stringSlice = uncurryThis(''.slice);\nvar replace = uncurryThis(''.replace);\nvar join = uncurryThis([].join);\n\nvar CONFIGURABLE_LENGTH = DESCRIPTORS && !fails(function () {\n return defineProperty(function () { /* empty */ }, 'length', { value: 8 }).length !== 8;\n});\n\nvar TEMPLATE = String(String).split('String');\n\nvar makeBuiltIn = module.exports = function (value, name, options) {\n if (stringSlice($String(name), 0, 7) === 'Symbol(') {\n name = '[' + replace($String(name), /^Symbol\\(([^)]*)\\)/, '$1') + ']';\n }\n if (options && options.getter) name = 'get ' + name;\n if (options && options.setter) name = 'set ' + name;\n if (!hasOwn(value, 'name') || (CONFIGURABLE_FUNCTION_NAME && value.name !== name)) {\n if (DESCRIPTORS) defineProperty(value, 'name', { value: name, configurable: true });\n else value.name = name;\n }\n if (CONFIGURABLE_LENGTH && options && hasOwn(options, 'arity') && value.length !== options.arity) {\n defineProperty(value, 'length', { value: options.arity });\n }\n try {\n if (options && hasOwn(options, 'constructor') && options.constructor) {\n if (DESCRIPTORS) defineProperty(value, 'prototype', { writable: false });\n // in V8 ~ Chrome 53, prototypes of some methods, like `Array.prototype.values`, are non-writable\n } else if (value.prototype) value.prototype = undefined;\n } catch (error) { /* empty */ }\n var state = enforceInternalState(value);\n if (!hasOwn(state, 'source')) {\n state.source = join(TEMPLATE, typeof name == 'string' ? name : '');\n } return value;\n};\n\n// add fake Function#toString for correct work wrapped methods / constructors with methods like LoDash isNative\n// eslint-disable-next-line no-extend-native -- required\nFunction.prototype.toString = makeBuiltIn(function toString() {\n return isCallable(this) && getInternalState(this).source || inspectSource(this);\n}, 'toString');\n","'use strict';\nvar ceil = Math.ceil;\nvar floor = Math.floor;\n\n// `Math.trunc` method\n// https://tc39.es/ecma262/#sec-math.trunc\n// eslint-disable-next-line es/no-math-trunc -- safe\nmodule.exports = Math.trunc || function trunc(x) {\n var n = +x;\n return (n > 0 ? floor : ceil)(n);\n};\n","'use strict';\nvar DESCRIPTORS = require('../internals/descriptors');\nvar IE8_DOM_DEFINE = require('../internals/ie8-dom-define');\nvar V8_PROTOTYPE_DEFINE_BUG = require('../internals/v8-prototype-define-bug');\nvar anObject = require('../internals/an-object');\nvar toPropertyKey = require('../internals/to-property-key');\n\nvar $TypeError = TypeError;\n// eslint-disable-next-line es/no-object-defineproperty -- safe\nvar $defineProperty = Object.defineProperty;\n// eslint-disable-next-line es/no-object-getownpropertydescriptor -- safe\nvar $getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;\nvar ENUMERABLE = 'enumerable';\nvar CONFIGURABLE = 'configurable';\nvar WRITABLE = 'writable';\n\n// `Object.defineProperty` method\n// https://tc39.es/ecma262/#sec-object.defineproperty\nexports.f = DESCRIPTORS ? V8_PROTOTYPE_DEFINE_BUG ? function defineProperty(O, P, Attributes) {\n anObject(O);\n P = toPropertyKey(P);\n anObject(Attributes);\n if (typeof O === 'function' && P === 'prototype' && 'value' in Attributes && WRITABLE in Attributes && !Attributes[WRITABLE]) {\n var current = $getOwnPropertyDescriptor(O, P);\n if (current && current[WRITABLE]) {\n O[P] = Attributes.value;\n Attributes = {\n configurable: CONFIGURABLE in Attributes ? Attributes[CONFIGURABLE] : current[CONFIGURABLE],\n enumerable: ENUMERABLE in Attributes ? Attributes[ENUMERABLE] : current[ENUMERABLE],\n writable: false\n };\n }\n } return $defineProperty(O, P, Attributes);\n} : $defineProperty : function defineProperty(O, P, Attributes) {\n anObject(O);\n P = toPropertyKey(P);\n anObject(Attributes);\n if (IE8_DOM_DEFINE) try {\n return $defineProperty(O, P, Attributes);\n } catch (error) { /* empty */ }\n if ('get' in Attributes || 'set' in Attributes) throw $TypeError('Accessors not supported');\n if ('value' in Attributes) O[P] = Attributes.value;\n return O;\n};\n","'use strict';\nvar DESCRIPTORS = require('../internals/descriptors');\nvar call = require('../internals/function-call');\nvar propertyIsEnumerableModule = require('../internals/object-property-is-enumerable');\nvar createPropertyDescriptor = require('../internals/create-property-descriptor');\nvar toIndexedObject = require('../internals/to-indexed-object');\nvar toPropertyKey = require('../internals/to-property-key');\nvar hasOwn = require('../internals/has-own-property');\nvar IE8_DOM_DEFINE = require('../internals/ie8-dom-define');\n\n// eslint-disable-next-line es/no-object-getownpropertydescriptor -- safe\nvar $getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;\n\n// `Object.getOwnPropertyDescriptor` method\n// https://tc39.es/ecma262/#sec-object.getownpropertydescriptor\nexports.f = DESCRIPTORS ? $getOwnPropertyDescriptor : function getOwnPropertyDescriptor(O, P) {\n O = toIndexedObject(O);\n P = toPropertyKey(P);\n if (IE8_DOM_DEFINE) try {\n return $getOwnPropertyDescriptor(O, P);\n } catch (error) { /* empty */ }\n if (hasOwn(O, P)) return createPropertyDescriptor(!call(propertyIsEnumerableModule.f, O, P), O[P]);\n};\n","'use strict';\nvar internalObjectKeys = require('../internals/object-keys-internal');\nvar enumBugKeys = require('../internals/enum-bug-keys');\n\nvar hiddenKeys = enumBugKeys.concat('length', 'prototype');\n\n// `Object.getOwnPropertyNames` method\n// https://tc39.es/ecma262/#sec-object.getownpropertynames\n// eslint-disable-next-line es/no-object-getownpropertynames -- safe\nexports.f = Object.getOwnPropertyNames || function getOwnPropertyNames(O) {\n return internalObjectKeys(O, hiddenKeys);\n};\n","'use strict';\n// eslint-disable-next-line es/no-object-getownpropertysymbols -- safe\nexports.f = Object.getOwnPropertySymbols;\n","'use strict';\nvar uncurryThis = require('../internals/function-uncurry-this');\n\nmodule.exports = uncurryThis({}.isPrototypeOf);\n","'use strict';\nvar uncurryThis = require('../internals/function-uncurry-this');\nvar hasOwn = require('../internals/has-own-property');\nvar toIndexedObject = require('../internals/to-indexed-object');\nvar indexOf = require('../internals/array-includes').indexOf;\nvar hiddenKeys = require('../internals/hidden-keys');\n\nvar push = uncurryThis([].push);\n\nmodule.exports = function (object, names) {\n var O = toIndexedObject(object);\n var i = 0;\n var result = [];\n var key;\n for (key in O) !hasOwn(hiddenKeys, key) && hasOwn(O, key) && push(result, key);\n // Don't enum bug & hidden keys\n while (names.length > i) if (hasOwn(O, key = names[i++])) {\n ~indexOf(result, key) || push(result, key);\n }\n return result;\n};\n","'use strict';\nvar internalObjectKeys = require('../internals/object-keys-internal');\nvar enumBugKeys = require('../internals/enum-bug-keys');\n\n// `Object.keys` method\n// https://tc39.es/ecma262/#sec-object.keys\n// eslint-disable-next-line es/no-object-keys -- safe\nmodule.exports = Object.keys || function keys(O) {\n return internalObjectKeys(O, enumBugKeys);\n};\n","'use strict';\nvar $propertyIsEnumerable = {}.propertyIsEnumerable;\n// eslint-disable-next-line es/no-object-getownpropertydescriptor -- safe\nvar getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;\n\n// Nashorn ~ JDK8 bug\nvar NASHORN_BUG = getOwnPropertyDescriptor && !$propertyIsEnumerable.call({ 1: 2 }, 1);\n\n// `Object.prototype.propertyIsEnumerable` method implementation\n// https://tc39.es/ecma262/#sec-object.prototype.propertyisenumerable\nexports.f = NASHORN_BUG ? function propertyIsEnumerable(V) {\n var descriptor = getOwnPropertyDescriptor(this, V);\n return !!descriptor && descriptor.enumerable;\n} : $propertyIsEnumerable;\n","'use strict';\nvar call = require('../internals/function-call');\nvar isCallable = require('../internals/is-callable');\nvar isObject = require('../internals/is-object');\n\nvar $TypeError = TypeError;\n\n// `OrdinaryToPrimitive` abstract operation\n// https://tc39.es/ecma262/#sec-ordinarytoprimitive\nmodule.exports = function (input, pref) {\n var fn, val;\n if (pref === 'string' && isCallable(fn = input.toString) && !isObject(val = call(fn, input))) return val;\n if (isCallable(fn = input.valueOf) && !isObject(val = call(fn, input))) return val;\n if (pref !== 'string' && isCallable(fn = input.toString) && !isObject(val = call(fn, input))) return val;\n throw $TypeError(\"Can't convert object to primitive value\");\n};\n","'use strict';\nvar getBuiltIn = require('../internals/get-built-in');\nvar uncurryThis = require('../internals/function-uncurry-this');\nvar getOwnPropertyNamesModule = require('../internals/object-get-own-property-names');\nvar getOwnPropertySymbolsModule = require('../internals/object-get-own-property-symbols');\nvar anObject = require('../internals/an-object');\n\nvar concat = uncurryThis([].concat);\n\n// all object keys, includes non-enumerable and symbols\nmodule.exports = getBuiltIn('Reflect', 'ownKeys') || function ownKeys(it) {\n var keys = getOwnPropertyNamesModule.f(anObject(it));\n var getOwnPropertySymbols = getOwnPropertySymbolsModule.f;\n return getOwnPropertySymbols ? concat(keys, getOwnPropertySymbols(it)) : keys;\n};\n","'use strict';\nvar global = require('../internals/global');\n\nmodule.exports = global;\n","'use strict';\nvar isNullOrUndefined = require('../internals/is-null-or-undefined');\n\nvar $TypeError = TypeError;\n\n// `RequireObjectCoercible` abstract operation\n// https://tc39.es/ecma262/#sec-requireobjectcoercible\nmodule.exports = function (it) {\n if (isNullOrUndefined(it)) throw $TypeError(\"Can't call method on \" + it);\n return it;\n};\n","'use strict';\nvar shared = require('../internals/shared');\nvar uid = require('../internals/uid');\n\nvar keys = shared('keys');\n\nmodule.exports = function (key) {\n return keys[key] || (keys[key] = uid(key));\n};\n","'use strict';\nvar global = require('../internals/global');\nvar defineGlobalProperty = require('../internals/define-global-property');\n\nvar SHARED = '__core-js_shared__';\nvar store = global[SHARED] || defineGlobalProperty(SHARED, {});\n\nmodule.exports = store;\n","'use strict';\nvar IS_PURE = require('../internals/is-pure');\nvar store = require('../internals/shared-store');\n\n(module.exports = function (key, value) {\n return store[key] || (store[key] = value !== undefined ? value : {});\n})('versions', []).push({\n version: '3.32.0',\n mode: IS_PURE ? 'pure' : 'global',\n copyright: '© 2014-2023 Denis Pushkarev (zloirock.ru)',\n license: 'https://github.com/zloirock/core-js/blob/v3.32.0/LICENSE',\n source: 'https://github.com/zloirock/core-js'\n});\n","'use strict';\n/* eslint-disable es/no-symbol -- required for testing */\nvar V8_VERSION = require('../internals/engine-v8-version');\nvar fails = require('../internals/fails');\nvar global = require('../internals/global');\n\nvar $String = global.String;\n\n// eslint-disable-next-line es/no-object-getownpropertysymbols -- required for testing\nmodule.exports = !!Object.getOwnPropertySymbols && !fails(function () {\n var symbol = Symbol();\n // Chrome 38 Symbol has incorrect toString conversion\n // `get-own-property-symbols` polyfill symbols converted to object are not Symbol instances\n // nb: Do not call `String` directly to avoid this being optimized out to `symbol+''` which will,\n // of course, fail.\n return !$String(symbol) || !(Object(symbol) instanceof Symbol) ||\n // Chrome 38-40 symbols are not inherited from DOM collections prototypes to instances\n !Symbol.sham && V8_VERSION && V8_VERSION < 41;\n});\n","'use strict';\nvar toIntegerOrInfinity = require('../internals/to-integer-or-infinity');\n\nvar max = Math.max;\nvar min = Math.min;\n\n// Helper for a popular repeating case of the spec:\n// Let integer be ? ToInteger(index).\n// If integer < 0, let result be max((length + integer), 0); else let result be min(integer, length).\nmodule.exports = function (index, length) {\n var integer = toIntegerOrInfinity(index);\n return integer < 0 ? max(integer + length, 0) : min(integer, length);\n};\n","'use strict';\n// toObject with fallback for non-array-like ES3 strings\nvar IndexedObject = require('../internals/indexed-object');\nvar requireObjectCoercible = require('../internals/require-object-coercible');\n\nmodule.exports = function (it) {\n return IndexedObject(requireObjectCoercible(it));\n};\n","'use strict';\nvar trunc = require('../internals/math-trunc');\n\n// `ToIntegerOrInfinity` abstract operation\n// https://tc39.es/ecma262/#sec-tointegerorinfinity\nmodule.exports = function (argument) {\n var number = +argument;\n // eslint-disable-next-line no-self-compare -- NaN check\n return number !== number || number === 0 ? 0 : trunc(number);\n};\n","'use strict';\nvar toIntegerOrInfinity = require('../internals/to-integer-or-infinity');\n\nvar min = Math.min;\n\n// `ToLength` abstract operation\n// https://tc39.es/ecma262/#sec-tolength\nmodule.exports = function (argument) {\n return argument > 0 ? min(toIntegerOrInfinity(argument), 0x1FFFFFFFFFFFFF) : 0; // 2 ** 53 - 1 == 9007199254740991\n};\n","'use strict';\nvar requireObjectCoercible = require('../internals/require-object-coercible');\n\nvar $Object = Object;\n\n// `ToObject` abstract operation\n// https://tc39.es/ecma262/#sec-toobject\nmodule.exports = function (argument) {\n return $Object(requireObjectCoercible(argument));\n};\n","'use strict';\nvar call = require('../internals/function-call');\nvar isObject = require('../internals/is-object');\nvar isSymbol = require('../internals/is-symbol');\nvar getMethod = require('../internals/get-method');\nvar ordinaryToPrimitive = require('../internals/ordinary-to-primitive');\nvar wellKnownSymbol = require('../internals/well-known-symbol');\n\nvar $TypeError = TypeError;\nvar TO_PRIMITIVE = wellKnownSymbol('toPrimitive');\n\n// `ToPrimitive` abstract operation\n// https://tc39.es/ecma262/#sec-toprimitive\nmodule.exports = function (input, pref) {\n if (!isObject(input) || isSymbol(input)) return input;\n var exoticToPrim = getMethod(input, TO_PRIMITIVE);\n var result;\n if (exoticToPrim) {\n if (pref === undefined) pref = 'default';\n result = call(exoticToPrim, input, pref);\n if (!isObject(result) || isSymbol(result)) return result;\n throw $TypeError(\"Can't convert object to primitive value\");\n }\n if (pref === undefined) pref = 'number';\n return ordinaryToPrimitive(input, pref);\n};\n","'use strict';\nvar toPrimitive = require('../internals/to-primitive');\nvar isSymbol = require('../internals/is-symbol');\n\n// `ToPropertyKey` abstract operation\n// https://tc39.es/ecma262/#sec-topropertykey\nmodule.exports = function (argument) {\n var key = toPrimitive(argument, 'string');\n return isSymbol(key) ? key : key + '';\n};\n","'use strict';\nvar wellKnownSymbol = require('../internals/well-known-symbol');\n\nvar TO_STRING_TAG = wellKnownSymbol('toStringTag');\nvar test = {};\n\ntest[TO_STRING_TAG] = 'z';\n\nmodule.exports = String(test) === '[object z]';\n","'use strict';\nvar classof = require('../internals/classof');\n\nvar $String = String;\n\nmodule.exports = function (argument) {\n if (classof(argument) === 'Symbol') throw TypeError('Cannot convert a Symbol value to a string');\n return $String(argument);\n};\n","'use strict';\nvar $String = String;\n\nmodule.exports = function (argument) {\n try {\n return $String(argument);\n } catch (error) {\n return 'Object';\n }\n};\n","'use strict';\nvar uncurryThis = require('../internals/function-uncurry-this');\n\nvar id = 0;\nvar postfix = Math.random();\nvar toString = uncurryThis(1.0.toString);\n\nmodule.exports = function (key) {\n return 'Symbol(' + (key === undefined ? '' : key) + ')_' + toString(++id + postfix, 36);\n};\n","'use strict';\n/* eslint-disable es/no-symbol -- required for testing */\nvar NATIVE_SYMBOL = require('../internals/symbol-constructor-detection');\n\nmodule.exports = NATIVE_SYMBOL\n && !Symbol.sham\n && typeof Symbol.iterator == 'symbol';\n","'use strict';\nvar DESCRIPTORS = require('../internals/descriptors');\nvar fails = require('../internals/fails');\n\n// V8 ~ Chrome 36-\n// https://bugs.chromium.org/p/v8/issues/detail?id=3334\nmodule.exports = DESCRIPTORS && fails(function () {\n // eslint-disable-next-line es/no-object-defineproperty -- required for testing\n return Object.defineProperty(function () { /* empty */ }, 'prototype', {\n value: 42,\n writable: false\n }).prototype != 42;\n});\n","'use strict';\nvar global = require('../internals/global');\nvar isCallable = require('../internals/is-callable');\n\nvar WeakMap = global.WeakMap;\n\nmodule.exports = isCallable(WeakMap) && /native code/.test(String(WeakMap));\n","'use strict';\nvar global = require('../internals/global');\nvar shared = require('../internals/shared');\nvar hasOwn = require('../internals/has-own-property');\nvar uid = require('../internals/uid');\nvar NATIVE_SYMBOL = require('../internals/symbol-constructor-detection');\nvar USE_SYMBOL_AS_UID = require('../internals/use-symbol-as-uid');\n\nvar Symbol = global.Symbol;\nvar WellKnownSymbolsStore = shared('wks');\nvar createWellKnownSymbol = USE_SYMBOL_AS_UID ? Symbol['for'] || Symbol : Symbol && Symbol.withoutSetter || uid;\n\nmodule.exports = function (name) {\n if (!hasOwn(WellKnownSymbolsStore, name)) {\n WellKnownSymbolsStore[name] = NATIVE_SYMBOL && hasOwn(Symbol, name)\n ? Symbol[name]\n : createWellKnownSymbol('Symbol.' + name);\n } return WellKnownSymbolsStore[name];\n};\n","'use strict';\nvar $ = require('../internals/export');\nvar uncurryThis = require('../internals/function-uncurry-this');\nvar aCallable = require('../internals/a-callable');\nvar toObject = require('../internals/to-object');\nvar lengthOfArrayLike = require('../internals/length-of-array-like');\nvar deletePropertyOrThrow = require('../internals/delete-property-or-throw');\nvar toString = require('../internals/to-string');\nvar fails = require('../internals/fails');\nvar internalSort = require('../internals/array-sort');\nvar arrayMethodIsStrict = require('../internals/array-method-is-strict');\nvar FF = require('../internals/engine-ff-version');\nvar IE_OR_EDGE = require('../internals/engine-is-ie-or-edge');\nvar V8 = require('../internals/engine-v8-version');\nvar WEBKIT = require('../internals/engine-webkit-version');\n\nvar test = [];\nvar nativeSort = uncurryThis(test.sort);\nvar push = uncurryThis(test.push);\n\n// IE8-\nvar FAILS_ON_UNDEFINED = fails(function () {\n test.sort(undefined);\n});\n// V8 bug\nvar FAILS_ON_NULL = fails(function () {\n test.sort(null);\n});\n// Old WebKit\nvar STRICT_METHOD = arrayMethodIsStrict('sort');\n\nvar STABLE_SORT = !fails(function () {\n // feature detection can be too slow, so check engines versions\n if (V8) return V8 < 70;\n if (FF && FF > 3) return;\n if (IE_OR_EDGE) return true;\n if (WEBKIT) return WEBKIT < 603;\n\n var result = '';\n var code, chr, value, index;\n\n // generate an array with more 512 elements (Chakra and old V8 fails only in this case)\n for (code = 65; code < 76; code++) {\n chr = String.fromCharCode(code);\n\n switch (code) {\n case 66: case 69: case 70: case 72: value = 3; break;\n case 68: case 71: value = 4; break;\n default: value = 2;\n }\n\n for (index = 0; index < 47; index++) {\n test.push({ k: chr + index, v: value });\n }\n }\n\n test.sort(function (a, b) { return b.v - a.v; });\n\n for (index = 0; index < test.length; index++) {\n chr = test[index].k.charAt(0);\n if (result.charAt(result.length - 1) !== chr) result += chr;\n }\n\n return result !== 'DGBEFHACIJK';\n});\n\nvar FORCED = FAILS_ON_UNDEFINED || !FAILS_ON_NULL || !STRICT_METHOD || !STABLE_SORT;\n\nvar getSortCompare = function (comparefn) {\n return function (x, y) {\n if (y === undefined) return -1;\n if (x === undefined) return 1;\n if (comparefn !== undefined) return +comparefn(x, y) || 0;\n return toString(x) > toString(y) ? 1 : -1;\n };\n};\n\n// `Array.prototype.sort` method\n// https://tc39.es/ecma262/#sec-array.prototype.sort\n$({ target: 'Array', proto: true, forced: FORCED }, {\n sort: function sort(comparefn) {\n if (comparefn !== undefined) aCallable(comparefn);\n\n var array = toObject(this);\n\n if (STABLE_SORT) return comparefn === undefined ? nativeSort(array) : nativeSort(array, comparefn);\n\n var items = [];\n var arrayLength = lengthOfArrayLike(array);\n var itemsLength, index;\n\n for (index = 0; index < arrayLength; index++) {\n if (index in array) push(items, array[index]);\n }\n\n internalSort(items, getSortCompare(comparefn));\n\n itemsLength = lengthOfArrayLike(items);\n index = 0;\n\n while (index < itemsLength) array[index] = items[index++];\n while (index < arrayLength) deletePropertyOrThrow(array, index++);\n\n return array;\n }\n});\n","'use strict';\nvar $ = require('../internals/export');\nvar toObject = require('../internals/to-object');\nvar nativeKeys = require('../internals/object-keys');\nvar fails = require('../internals/fails');\n\nvar FAILS_ON_PRIMITIVES = fails(function () { nativeKeys(1); });\n\n// `Object.keys` method\n// https://tc39.es/ecma262/#sec-object.keys\n$({ target: 'Object', stat: true, forced: FAILS_ON_PRIMITIVES }, {\n keys: function keys(it) {\n return nativeKeys(toObject(it));\n }\n});\n","// Imports\nimport ___CSS_LOADER_API_SOURCEMAP_IMPORT___ from \"../../node_modules/css-loader/dist/runtime/sourceMaps.js\";\nimport ___CSS_LOADER_API_IMPORT___ from \"../../node_modules/css-loader/dist/runtime/api.js\";\nvar ___CSS_LOADER_EXPORT___ = ___CSS_LOADER_API_IMPORT___(___CSS_LOADER_API_SOURCEMAP_IMPORT___);\n// Module\n___CSS_LOADER_EXPORT___.push([module.id, `/* Buttons styles start */\r\n\r\nbutton#excalibur-play {\r\n display: inline-block;\r\n position: relative;\r\n z-index: 999;\r\n border-radius: 6px;\r\n border: none;\r\n /*border: 3px solid;\r\n border-color: white;\r\n box-shadow: 0 0 10px #ccc;*/\r\n padding: 1rem 1.5rem 1rem 4rem;\r\n margin: 0;\r\n text-decoration: none;\r\n background: #00b233;\r\n color: #ffffff;\r\n font-family: sans-serif;\r\n font-size: 2rem;\r\n white-space: nowrap;\r\n line-height: 1;\r\n cursor: pointer;\r\n text-align: center;\r\n transition: background 250ms ease-in-out, transform 150ms ease;\r\n -webkit-appearance: none;\r\n -moz-appearance: none;\r\n\r\n -webkit-animation: excalibur-button-fadein 200ms; /* Safari, Chrome and Opera > 12.1 */\r\n -moz-animation: excalibur-button-fadein 200ms; /* Firefox < 16 */\r\n -ms-animation: excalibur-button-fadein 200ms; /* Internet Explorer */\r\n -o-animation: excalibur-button-fadein 200ms; /* Opera < 12.1 */\r\n animation: excalibur-button-fadein 200ms;\r\n}\r\n\r\n/*\r\nbutton#excalibur-play {\r\n display: none;\r\n}*/\r\n\r\nbutton#excalibur-play:after {\r\n position: absolute;\r\n content: '';\r\n border: 8px solid;\r\n border-color: transparent transparent transparent white;\r\n left: 35px;\r\n top: 24px;\r\n width: 0;\r\n height: 0;\r\n}\r\n\r\nbutton#excalibur-play:before {\r\n position: absolute;\r\n content: '';\r\n border: 3px solid;\r\n left: 19px;\r\n top: 14px;\r\n border-radius: 20px;\r\n width: 30px;\r\n height: 30px;\r\n}\r\n\r\nbutton#excalibur-play:hover,\r\nbutton#excalibur-play:focus {\r\n background: #00982c;\r\n}\r\n\r\nbutton#excalibur-play:focus {\r\n outline: 1px solid #fff;\r\n outline-offset: -4px;\r\n}\r\n\r\nbutton#excalibur-play:active {\r\n transform: scale(0.99);\r\n}\r\n\r\n@keyframes excalibur-button-fadein {\r\n from {\r\n opacity: 0;\r\n }\r\n to {\r\n opacity: 1;\r\n }\r\n}\r\n\r\n/* Firefox < 16 */\r\n@-moz-keyframes excalibur-button-fadein {\r\n from {\r\n opacity: 0;\r\n }\r\n to {\r\n opacity: 1;\r\n }\r\n}\r\n\r\n/* Safari, Chrome and Opera > 12.1 */\r\n@-webkit-keyframes excalibur-button-fadein {\r\n from {\r\n opacity: 0;\r\n }\r\n to {\r\n opacity: 1;\r\n }\r\n}\r\n\r\n/* Internet Explorer */\r\n@-ms-keyframes excalibur-button-fadein {\r\n from {\r\n opacity: 0;\r\n }\r\n to {\r\n opacity: 1;\r\n }\r\n}\r\n\r\n/* Opera < 12.1 */\r\n@-o-keyframes excalibur-button-fadein {\r\n from {\r\n opacity: 0;\r\n }\r\n to {\r\n opacity: 1;\r\n }\r\n}\r\n`, \"\",{\"version\":3,\"sources\":[\"webpack://./Loader.css\"],\"names\":[],\"mappings\":\"AAAA,yBAAyB;;AAEzB;EACE,qBAAqB;EACrB,kBAAkB;EAClB,YAAY;EACZ,kBAAkB;EAClB,YAAY;EACZ;;+BAE6B;EAC7B,8BAA8B;EAC9B,SAAS;EACT,qBAAqB;EACrB,mBAAmB;EACnB,cAAc;EACd,uBAAuB;EACvB,eAAe;EACf,mBAAmB;EACnB,cAAc;EACd,eAAe;EACf,kBAAkB;EAClB,8DAA8D;EAC9D,wBAAwB;EACxB,qBAAqB;;EAErB,gDAAgD,EAAE,oCAAoC;EACtF,6CAA6C,EAAE,iBAAiB;EAChE,4CAA4C,EAAE,sBAAsB;EACpE,2CAA2C,EAAE,iBAAiB;EAC9D,wCAAwC;AAC1C;;AAEA;;;EAGE;;AAEF;EACE,kBAAkB;EAClB,WAAW;EACX,iBAAiB;EACjB,uDAAuD;EACvD,UAAU;EACV,SAAS;EACT,QAAQ;EACR,SAAS;AACX;;AAEA;EACE,kBAAkB;EAClB,WAAW;EACX,iBAAiB;EACjB,UAAU;EACV,SAAS;EACT,mBAAmB;EACnB,WAAW;EACX,YAAY;AACd;;AAEA;;EAEE,mBAAmB;AACrB;;AAEA;EACE,uBAAuB;EACvB,oBAAoB;AACtB;;AAEA;EACE,sBAAsB;AACxB;;AAEA;EACE;IACE,UAAU;EACZ;EACA;IACE,UAAU;EACZ;AACF;;AAEA,iBAAiB;AACjB;EACE;IACE,UAAU;EACZ;EACA;IACE,UAAU;EACZ;AACF;;AAEA,oCAAoC;AACpC;EACE;IACE,UAAU;EACZ;EACA;IACE,UAAU;EACZ;AACF;;AAEA,sBAAsB;AACtB;EACE;IACE,UAAU;EACZ;EACA;IACE,UAAU;EACZ;AACF;;AAEA,iBAAiB;AACjB;EACE;IACE,UAAU;EACZ;EACA;IACE,UAAU;EACZ;AACF\",\"sourcesContent\":[\"/* Buttons styles start */\\r\\n\\r\\nbutton#excalibur-play {\\r\\n display: inline-block;\\r\\n position: relative;\\r\\n z-index: 999;\\r\\n border-radius: 6px;\\r\\n border: none;\\r\\n /*border: 3px solid;\\r\\n border-color: white;\\r\\n box-shadow: 0 0 10px #ccc;*/\\r\\n padding: 1rem 1.5rem 1rem 4rem;\\r\\n margin: 0;\\r\\n text-decoration: none;\\r\\n background: #00b233;\\r\\n color: #ffffff;\\r\\n font-family: sans-serif;\\r\\n font-size: 2rem;\\r\\n white-space: nowrap;\\r\\n line-height: 1;\\r\\n cursor: pointer;\\r\\n text-align: center;\\r\\n transition: background 250ms ease-in-out, transform 150ms ease;\\r\\n -webkit-appearance: none;\\r\\n -moz-appearance: none;\\r\\n\\r\\n -webkit-animation: excalibur-button-fadein 200ms; /* Safari, Chrome and Opera > 12.1 */\\r\\n -moz-animation: excalibur-button-fadein 200ms; /* Firefox < 16 */\\r\\n -ms-animation: excalibur-button-fadein 200ms; /* Internet Explorer */\\r\\n -o-animation: excalibur-button-fadein 200ms; /* Opera < 12.1 */\\r\\n animation: excalibur-button-fadein 200ms;\\r\\n}\\r\\n\\r\\n/*\\r\\nbutton#excalibur-play {\\r\\n display: none;\\r\\n}*/\\r\\n\\r\\nbutton#excalibur-play:after {\\r\\n position: absolute;\\r\\n content: '';\\r\\n border: 8px solid;\\r\\n border-color: transparent transparent transparent white;\\r\\n left: 35px;\\r\\n top: 24px;\\r\\n width: 0;\\r\\n height: 0;\\r\\n}\\r\\n\\r\\nbutton#excalibur-play:before {\\r\\n position: absolute;\\r\\n content: '';\\r\\n border: 3px solid;\\r\\n left: 19px;\\r\\n top: 14px;\\r\\n border-radius: 20px;\\r\\n width: 30px;\\r\\n height: 30px;\\r\\n}\\r\\n\\r\\nbutton#excalibur-play:hover,\\r\\nbutton#excalibur-play:focus {\\r\\n background: #00982c;\\r\\n}\\r\\n\\r\\nbutton#excalibur-play:focus {\\r\\n outline: 1px solid #fff;\\r\\n outline-offset: -4px;\\r\\n}\\r\\n\\r\\nbutton#excalibur-play:active {\\r\\n transform: scale(0.99);\\r\\n}\\r\\n\\r\\n@keyframes excalibur-button-fadein {\\r\\n from {\\r\\n opacity: 0;\\r\\n }\\r\\n to {\\r\\n opacity: 1;\\r\\n }\\r\\n}\\r\\n\\r\\n/* Firefox < 16 */\\r\\n@-moz-keyframes excalibur-button-fadein {\\r\\n from {\\r\\n opacity: 0;\\r\\n }\\r\\n to {\\r\\n opacity: 1;\\r\\n }\\r\\n}\\r\\n\\r\\n/* Safari, Chrome and Opera > 12.1 */\\r\\n@-webkit-keyframes excalibur-button-fadein {\\r\\n from {\\r\\n opacity: 0;\\r\\n }\\r\\n to {\\r\\n opacity: 1;\\r\\n }\\r\\n}\\r\\n\\r\\n/* Internet Explorer */\\r\\n@-ms-keyframes excalibur-button-fadein {\\r\\n from {\\r\\n opacity: 0;\\r\\n }\\r\\n to {\\r\\n opacity: 1;\\r\\n }\\r\\n}\\r\\n\\r\\n/* Opera < 12.1 */\\r\\n@-o-keyframes excalibur-button-fadein {\\r\\n from {\\r\\n opacity: 0;\\r\\n }\\r\\n to {\\r\\n opacity: 1;\\r\\n }\\r\\n}\\r\\n\"],\"sourceRoot\":\"\"}]);\n// Exports\nexport default ___CSS_LOADER_EXPORT___;\n","// Imports\nimport ___CSS_LOADER_API_SOURCEMAP_IMPORT___ from \"../../../node_modules/css-loader/dist/runtime/sourceMaps.js\";\nimport ___CSS_LOADER_API_IMPORT___ from \"../../../node_modules/css-loader/dist/runtime/api.js\";\nvar ___CSS_LOADER_EXPORT___ = ___CSS_LOADER_API_IMPORT___(___CSS_LOADER_API_SOURCEMAP_IMPORT___);\n// Module\n___CSS_LOADER_EXPORT___.push([module.id, `\r\n#ex-toast-container {\r\n position: absolute;\r\n height: 0;\r\n min-width: 50%;\r\n left: 50%;\r\n top: 0;\r\n}\r\n\r\n.ex-toast-message {\r\n left: -50%;\r\n position: relative;\r\n display: flex;\r\n justify-content: space-between;\r\n\r\n\r\n padding: 10px;\r\n margin-top: 5px;\r\n font-size: 18px;\r\n font-family: sans-serif;\r\n border-radius: 6px;\r\n border: 3px solid #b7b779;\r\n background-color: rgb(253, 253, 192);\r\n}\r\n\r\n\r\n.ex-toast-message button {\r\n align-self: flex-start;\r\n}`, \"\",{\"version\":3,\"sources\":[\"webpack://./Util/Toaster.css\"],\"names\":[],\"mappings\":\";AACA;EACE,kBAAkB;EAClB,SAAS;EACT,cAAc;EACd,SAAS;EACT,MAAM;AACR;;AAEA;EACE,UAAU;EACV,kBAAkB;EAClB,aAAa;EACb,8BAA8B;;;EAG9B,aAAa;EACb,eAAe;EACf,eAAe;EACf,uBAAuB;EACvB,kBAAkB;EAClB,yBAAyB;EACzB,oCAAoC;AACtC;;;AAGA;EACE,sBAAsB;AACxB\",\"sourcesContent\":[\"\\r\\n#ex-toast-container {\\r\\n position: absolute;\\r\\n height: 0;\\r\\n min-width: 50%;\\r\\n left: 50%;\\r\\n top: 0;\\r\\n}\\r\\n\\r\\n.ex-toast-message {\\r\\n left: -50%;\\r\\n position: relative;\\r\\n display: flex;\\r\\n justify-content: space-between;\\r\\n\\r\\n\\r\\n padding: 10px;\\r\\n margin-top: 5px;\\r\\n font-size: 18px;\\r\\n font-family: sans-serif;\\r\\n border-radius: 6px;\\r\\n border: 3px solid #b7b779;\\r\\n background-color: rgb(253, 253, 192);\\r\\n}\\r\\n\\r\\n\\r\\n.ex-toast-message button {\\r\\n align-self: flex-start;\\r\\n}\"],\"sourceRoot\":\"\"}]);\n// Exports\nexport default ___CSS_LOADER_EXPORT___;\n","\"use strict\";\n\n/*\n MIT License http://www.opensource.org/licenses/mit-license.php\n Author Tobias Koppers @sokra\n*/\nmodule.exports = function (cssWithMappingToString) {\n var list = [];\n\n // return the list of modules as css string\n list.toString = function toString() {\n return this.map(function (item) {\n var content = \"\";\n var needLayer = typeof item[5] !== \"undefined\";\n if (item[4]) {\n content += \"@supports (\".concat(item[4], \") {\");\n }\n if (item[2]) {\n content += \"@media \".concat(item[2], \" {\");\n }\n if (needLayer) {\n content += \"@layer\".concat(item[5].length > 0 ? \" \".concat(item[5]) : \"\", \" {\");\n }\n content += cssWithMappingToString(item);\n if (needLayer) {\n content += \"}\";\n }\n if (item[2]) {\n content += \"}\";\n }\n if (item[4]) {\n content += \"}\";\n }\n return content;\n }).join(\"\");\n };\n\n // import a list of modules into the list\n list.i = function i(modules, media, dedupe, supports, layer) {\n if (typeof modules === \"string\") {\n modules = [[null, modules, undefined]];\n }\n var alreadyImportedModules = {};\n if (dedupe) {\n for (var k = 0; k < this.length; k++) {\n var id = this[k][0];\n if (id != null) {\n alreadyImportedModules[id] = true;\n }\n }\n }\n for (var _k = 0; _k < modules.length; _k++) {\n var item = [].concat(modules[_k]);\n if (dedupe && alreadyImportedModules[item[0]]) {\n continue;\n }\n if (typeof layer !== \"undefined\") {\n if (typeof item[5] === \"undefined\") {\n item[5] = layer;\n } else {\n item[1] = \"@layer\".concat(item[5].length > 0 ? \" \".concat(item[5]) : \"\", \" {\").concat(item[1], \"}\");\n item[5] = layer;\n }\n }\n if (media) {\n if (!item[2]) {\n item[2] = media;\n } else {\n item[1] = \"@media \".concat(item[2], \" {\").concat(item[1], \"}\");\n item[2] = media;\n }\n }\n if (supports) {\n if (!item[4]) {\n item[4] = \"\".concat(supports);\n } else {\n item[1] = \"@supports (\".concat(item[4], \") {\").concat(item[1], \"}\");\n item[4] = supports;\n }\n }\n list.push(item);\n }\n };\n return list;\n};","\"use strict\";\n\nmodule.exports = function (item) {\n var content = item[1];\n var cssMapping = item[3];\n if (!cssMapping) {\n return content;\n }\n if (typeof btoa === \"function\") {\n var base64 = btoa(unescape(encodeURIComponent(JSON.stringify(cssMapping))));\n var data = \"sourceMappingURL=data:application/json;charset=utf-8;base64,\".concat(base64);\n var sourceMapping = \"/*# \".concat(data, \" */\");\n return [content].concat([sourceMapping]).join(\"\\n\");\n }\n return [content].join(\"\\n\");\n};","// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tvar cachedModule = __webpack_module_cache__[moduleId];\n\tif (cachedModule !== undefined) {\n\t\treturn cachedModule.exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\tid: moduleId,\n\t\t// no module.loaded needed\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\t__webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n","// getDefaultExport function for compatibility with non-harmony modules\n__webpack_require__.n = (module) => {\n\tvar getter = module && module.__esModule ?\n\t\t() => (module['default']) :\n\t\t() => (module);\n\t__webpack_require__.d(getter, { a: getter });\n\treturn getter;\n};","// define getter functions for harmony exports\n__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.g = (function() {\n\tif (typeof globalThis === 'object') return globalThis;\n\ttry {\n\t\treturn this || new Function('return this')();\n\t} catch (e) {\n\t\tif (typeof window === 'object') return window;\n\t}\n})();","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","import 'core-js/es/array/sort';\r\nimport 'core-js/es/object/keys';\r\n\r\n/**\r\n * Polyfill adding function\r\n */\r\nexport function polyfill() {\r\n /* istanbul ignore next */\r\n if (typeof window === 'undefined') {\r\n window = {\r\n audioContext: function () {\r\n return;\r\n }\r\n };\r\n }\r\n /* istanbul ignore next */\r\n if (typeof window !== 'undefined' && !window.requestAnimationFrame) {\r\n (window).requestAnimationFrame =\r\n (window).webkitRequestAnimationFrame ||\r\n (window).mozRequestAnimationFrame ||\r\n function (callback: Function) {\r\n window.setInterval(callback, 1000 / 60);\r\n };\r\n }\r\n /* istanbul ignore next */\r\n if (typeof window !== 'undefined' && !window.cancelAnimationFrame) {\r\n (window).cancelAnimationFrame =\r\n (window).webkitCancelAnimationFrame ||\r\n (window).mozCancelAnimationFrame ||\r\n function () {\r\n return;\r\n };\r\n }\r\n /* istanbul ignore next */\r\n if (typeof window !== 'undefined' && !(window).AudioContext) {\r\n if ((window).webkitAudioContext) {\r\n const ctx = (window).webkitAudioContext;\r\n const replaceMe = ctx.prototype.decodeAudioData;\r\n (window).webkitAudioContext.prototype.decodeAudioData = function (arrayBuffer: ArrayBuffer) {\r\n return new Promise((resolve, reject) => {\r\n replaceMe.call(this, arrayBuffer, resolve, reject);\r\n });\r\n };\r\n }\r\n\r\n (window).AudioContext =\r\n (window).AudioContext ||\r\n (window).webkitAudioContext ||\r\n (window).mozAudioContext ||\r\n (window).msAudioContext ||\r\n (window).oAudioContext;\r\n }\r\n\r\n /* istanbul ignore next */\r\n if (typeof window !== 'undefined' && !(window).devicePixelRatio) {\r\n (window).devicePixelRatio = window.devicePixelRatio || 1;\r\n }\r\n}\r\n","\r\n/**\r\n * Flags is a feature flag implementation for Excalibur. They can only be operated **before [[Engine]] construction**\r\n * after which they are frozen and are read-only.\r\n *\r\n * Flags are used to enable experimental or preview features in Excalibur.\r\n */\r\nexport class Flags {\r\n private static _FROZEN = false;\r\n private static _FLAGS: Record = {};\r\n\r\n\r\n /**\r\n * Force excalibur to load the Canvas 2D graphics context fallback\r\n *\r\n * @warning not all features of excalibur are supported in the Canvas 2D fallback\r\n */\r\n public static useCanvasGraphicsContext() {\r\n Flags.enable('use-canvas-context');\r\n }\r\n\r\n /**\r\n * Freeze all flag modifications making them readonly\r\n */\r\n public static freeze() {\r\n Flags._FROZEN = true;\r\n }\r\n\r\n /**\r\n * Resets internal flag state, not meant to be called by users. Only used for testing.\r\n *\r\n * Calling this in your game is UNSUPPORTED\r\n * @internal\r\n */\r\n public static _reset() {\r\n Flags._FROZEN = false;\r\n Flags._FLAGS = {};\r\n }\r\n /**\r\n * Enable a specific feature flag by name. **Note: can only be set before [[Engine]] constructor time**\r\n * @param flagName\r\n */\r\n public static enable(flagName: string): void {\r\n if (this._FROZEN) {\r\n throw Error('Feature flags can only be enabled before Engine constructor time');\r\n }\r\n Flags._FLAGS[flagName] = true;\r\n }\r\n\r\n /**\r\n * Disable a specific feature flag by name. **Note: can only be set before [[Engine]] constructor time**\r\n * @param flagName\r\n */\r\n public static disable(flagName: string): void {\r\n if (this._FROZEN) {\r\n throw Error('Feature flags can only be disabled before Engine constructor time');\r\n }\r\n Flags._FLAGS[flagName] = false;\r\n }\r\n\r\n /**\r\n * Check if a flag is enabled. If the flag is disabled or does not exist `false` is returned\r\n * @param flagName\r\n */\r\n public static isEnabled(flagName: string): boolean {\r\n return !!Flags._FLAGS[flagName];\r\n }\r\n\r\n /**\r\n * Show a list of currently known flags\r\n */\r\n public static show(): string[] {\r\n return Object.keys(Flags._FLAGS);\r\n }\r\n}\r\n","export type Id = {\r\n type: T,\r\n value: number\r\n};\r\n\r\n/**\r\n * Create a branded ID type from a number\r\n */\r\nexport function createId(type: T, value: number): Id {\r\n return { type, value };\r\n};\r\n","export type EventMap = Record;\r\nexport type EventKey = string & keyof T;\r\nexport type Handler = (event: EventType) => void;\r\n\r\n/**\r\n * Interface that represents a handle to a subscription that can be closed\r\n */\r\nexport interface Subscription {\r\n close(): void;\r\n}\r\n\r\n/**\r\n * Excalibur's typed event emitter, this allows events to be sent with any string to Type mapping\r\n */\r\nexport class EventEmitter {\r\n private _paused = false;\r\n private _listeners: Record[]> = {};\r\n private _listenersOnce: Record[]> = {};\r\n private _pipes: EventEmitter[] = [];\r\n\r\n clear() {\r\n this._listeners = {};\r\n this._listenersOnce = {};\r\n this._pipes.length = 0;\r\n }\r\n\r\n on>(eventName: TEventName, handler: Handler): Subscription;\r\n on(eventName: string, handler: Handler): Subscription;\r\n on | string>(eventName: TEventName, handler: Handler): Subscription {\r\n this._listeners[eventName] = this._listeners[eventName] ?? [];\r\n this._listeners[eventName].push(handler);\r\n return {\r\n close: () => this.off(eventName, handler)\r\n };\r\n }\r\n\r\n once>(eventName: TEventName, handler: Handler): Subscription;\r\n once(eventName: string, handler: Handler): Subscription;\r\n once | string>(eventName: TEventName, handler: Handler): Subscription {\r\n this._listenersOnce[eventName] = this._listenersOnce[eventName] ?? [];\r\n this._listenersOnce[eventName].push(handler);\r\n return {\r\n close: () => this.off(eventName, handler)\r\n };\r\n }\r\n\r\n off>(eventName: TEventName, handler: Handler): void;\r\n off(eventName: string, handler: Handler): void;\r\n off(eventName: string): void;\r\n off | string>(eventName: TEventName, handler?: Handler): void {\r\n if (handler) {\r\n const listenerIndex = this._listeners[eventName]?.indexOf(handler);\r\n if (listenerIndex > -1) {\r\n this._listeners[eventName]?.splice(listenerIndex, 1);\r\n }\r\n const onceIndex = this._listenersOnce[eventName]?.indexOf(handler);\r\n if (onceIndex > -1) {\r\n this._listenersOnce[eventName]?.splice(onceIndex, 1);\r\n }\r\n } else {\r\n delete this._listeners[eventName];\r\n }\r\n }\r\n\r\n emit>(eventName: TEventName, event: TEventMap[TEventName]): void;\r\n emit(eventName: string, event?: any): void;\r\n emit | string>(eventName: TEventName, event?: TEventMap[TEventName]): void {\r\n if (this._paused) {\r\n return;\r\n }\r\n this._listeners[eventName]?.forEach((fn) => fn(event));\r\n const onces = this._listenersOnce[eventName];\r\n this._listenersOnce[eventName] = [];\r\n if (onces) {\r\n onces.forEach((fn) => fn(event));\r\n }\r\n this._pipes.forEach((pipe) => {\r\n pipe.emit(eventName, event);\r\n });\r\n }\r\n\r\n pipe(emitter: EventEmitter): Subscription {\r\n if (this === emitter) {\r\n throw Error('Cannot pipe to self');\r\n }\r\n this._pipes.push(emitter);\r\n return {\r\n close: () => {\r\n const i = this._pipes.indexOf(emitter);\r\n if (i > -1) {\r\n this._pipes.splice(i, 1);\r\n }\r\n }\r\n };\r\n }\r\n\r\n unpipe(emitter: EventEmitter): void {\r\n const i = this._pipes.indexOf(emitter);\r\n if (i > -1) {\r\n this._pipes.splice(i, 1);\r\n }\r\n }\r\n\r\n pause(): void {\r\n this._paused = true;\r\n }\r\n\r\n unpause(): void {\r\n this._paused = false;\r\n }\r\n}","import { Scene } from './Scene';\r\nimport { Vector } from './Math/vector';\r\nimport { Actor } from './Actor';\r\nimport { Trigger } from './Trigger';\r\nimport { FrameStats } from './Debug';\r\nimport { Engine } from './Engine';\r\nimport { TileMap } from './TileMap';\r\nimport { Side } from './Collision/Side';\r\nimport { CollisionContact } from './Collision/Detection/CollisionContact';\r\nimport { Collider } from './Collision/Colliders/Collider';\r\nimport { Entity } from './EntityComponentSystem/Entity';\r\nimport { OnInitialize, OnPreUpdate, OnPostUpdate, SceneActivationContext } from './Interfaces/LifecycleEvents';\r\nimport { BodyComponent } from './Collision/BodyComponent';\r\nimport { ExcaliburGraphicsContext } from './Graphics';\r\nimport { Axes, Buttons, Gamepad } from './Input/Gamepad';\r\n\r\nexport enum EventTypes {\r\n Kill = 'kill',\r\n PreKill = 'prekill',\r\n PostKill = 'postkill',\r\n\r\n PreDraw = 'predraw',\r\n PostDraw = 'postdraw',\r\n\r\n PreDebugDraw = 'predebugdraw',\r\n PostDebugDraw = 'postdebugdraw',\r\n\r\n PreUpdate = 'preupdate',\r\n PostUpdate = 'postupdate',\r\n\r\n PreFrame = 'preframe',\r\n PostFrame = 'postframe',\r\n\r\n PreCollision = 'precollision',\r\n CollisionStart = 'collisionstart',\r\n CollisionEnd = 'collisionend',\r\n PostCollision = 'postcollision',\r\n\r\n Initialize = 'initialize',\r\n Activate = 'activate',\r\n Deactivate = 'deactivate',\r\n\r\n ExitViewport = 'exitviewport',\r\n EnterViewport = 'enterviewport',\r\n\r\n ExitTrigger = 'exit',\r\n EnterTrigger = 'enter',\r\n\r\n Connect = 'connect',\r\n Disconnect = 'disconnect',\r\n Button = 'button',\r\n Axis = 'axis',\r\n\r\n Visible = 'visible',\r\n Hidden = 'hidden',\r\n Start = 'start',\r\n Stop = 'stop',\r\n\r\n PointerUp = 'pointerup',\r\n PointerDown = 'pointerdown',\r\n PointerMove = 'pointermove',\r\n PointerEnter = 'pointerenter',\r\n PointerLeave = 'pointerleave',\r\n PointerCancel = 'pointercancel',\r\n PointerWheel = 'pointerwheel',\r\n\r\n Up = 'up',\r\n Down = 'down',\r\n Move = 'move',\r\n Enter = 'enter',\r\n Leave = 'leave',\r\n Cancel = 'cancel',\r\n Wheel = 'wheel',\r\n\r\n Press = 'press',\r\n Release = 'release',\r\n Hold = 'hold',\r\n\r\n PointerDragStart = 'pointerdragstart',\r\n PointerDragEnd = 'pointerdragend',\r\n PointerDragEnter = 'pointerdragenter',\r\n PointerDragLeave = 'pointerdragleave',\r\n PointerDragMove = 'pointerdragmove'\r\n}\r\n\r\n/* istanbul ignore next */\r\n/* compiler only: these are internal to lib */\r\nexport type kill = 'kill';\r\nexport type prekill = 'prekill';\r\nexport type postkill = 'postkill';\r\n\r\nexport type predraw = 'predraw';\r\nexport type postdraw = 'postdraw';\r\n\r\nexport type predebugdraw = 'predebugdraw';\r\nexport type postdebugdraw = 'postdebugdraw';\r\n\r\nexport type preupdate = 'preupdate';\r\nexport type postupdate = 'postupdate';\r\n\r\nexport type preframe = 'preframe';\r\nexport type postframe = 'postframe';\r\n\r\nexport type precollision = 'precollision';\r\nexport type collisionstart = 'collisionstart';\r\nexport type collisionend = 'collisionend';\r\nexport type postcollision = 'postcollision';\r\n\r\nexport type initialize = 'initialize';\r\nexport type activate = 'activate';\r\nexport type deactivate = 'deactivate';\r\n\r\nexport type exitviewport = 'exitviewport';\r\nexport type enterviewport = 'enterviewport';\r\n\r\nexport type exittrigger = 'exit';\r\nexport type entertrigger = 'enter';\r\n\r\nexport type connect = 'connect';\r\nexport type disconnect = 'disconnect';\r\nexport type button = 'button';\r\nexport type axis = 'axis';\r\n\r\nexport type subscribe = 'subscribe';\r\nexport type unsubscribe = 'unsubscribe';\r\n\r\nexport type visible = 'visible';\r\nexport type hidden = 'hidden';\r\nexport type start = 'start';\r\nexport type stop = 'stop';\r\n\r\nexport type pointerup = 'pointerup';\r\nexport type pointerdown = 'pointerdown';\r\nexport type pointermove = 'pointermove';\r\nexport type pointerenter = 'pointerenter';\r\nexport type pointerleave = 'pointerleave';\r\nexport type pointercancel = 'pointercancel';\r\nexport type pointerwheel = 'pointerwheel';\r\n\r\nexport type up = 'up';\r\nexport type down = 'down';\r\nexport type move = 'move';\r\nexport type enter = 'enter';\r\nexport type leave = 'leave';\r\nexport type cancel = 'cancel';\r\nexport type wheel = 'wheel';\r\n\r\nexport type press = 'press';\r\nexport type release = 'release';\r\nexport type hold = 'hold';\r\n\r\nexport type pointerdragstart = 'pointerdragstart';\r\nexport type pointerdragend = 'pointerdragend';\r\nexport type pointerdragenter = 'pointerdragenter';\r\nexport type pointerdragleave = 'pointerdragleave';\r\nexport type pointerdragmove = 'pointerdragmove';\r\n\r\n/**\r\n * Base event type in Excalibur that all other event types derive from. Not all event types are thrown on all Excalibur game objects,\r\n * some events are unique to a type, others are not.\r\n *\r\n */\r\nexport class GameEvent {\r\n /**\r\n * Target object for this event.\r\n */\r\n public target: T;\r\n\r\n /**\r\n * Other target object for this event\r\n */\r\n public other: U | null;\r\n\r\n /**\r\n * If set to false, prevents event from propagating to other actors. If true it will be propagated\r\n * to all actors that apply.\r\n */\r\n public get bubbles(): boolean {\r\n return this._bubbles;\r\n }\r\n\r\n public set bubbles(value: boolean) {\r\n this._bubbles = value;\r\n }\r\n\r\n private _bubbles: boolean = true;\r\n /**\r\n * Prevents event from bubbling\r\n */\r\n public stopPropagation() {\r\n this.bubbles = false;\r\n }\r\n}\r\n\r\n/**\r\n * The 'kill' event is emitted on actors when it is killed. The target is the actor that was killed.\r\n */\r\nexport class KillEvent extends GameEvent {\r\n constructor(public target: Actor) {\r\n super();\r\n }\r\n}\r\n\r\n/**\r\n * The 'prekill' event is emitted directly before an actor is killed.\r\n */\r\nexport class PreKillEvent extends GameEvent {\r\n constructor(public target: Actor) {\r\n super();\r\n }\r\n}\r\n\r\n/**\r\n * The 'postkill' event is emitted directly after the actor is killed.\r\n */\r\nexport class PostKillEvent extends GameEvent {\r\n constructor(public target: Actor) {\r\n super();\r\n }\r\n}\r\n\r\n/**\r\n * The 'start' event is emitted on engine when has started and is ready for interaction.\r\n */\r\nexport class GameStartEvent extends GameEvent {\r\n constructor(public target: Engine) {\r\n super();\r\n }\r\n}\r\n\r\n/**\r\n * The 'stop' event is emitted on engine when has been stopped and will no longer take input, update or draw.\r\n */\r\nexport class GameStopEvent extends GameEvent {\r\n constructor(public target: Engine) {\r\n super();\r\n }\r\n}\r\n\r\n/**\r\n * The 'predraw' event is emitted on actors, scenes, and engine before drawing starts. Actors' predraw happens inside their graphics\r\n * transform so that all drawing takes place with the actor as the origin.\r\n *\r\n */\r\nexport class PreDrawEvent extends GameEvent {\r\n constructor(public ctx: ExcaliburGraphicsContext, public delta: number, public target: Entity | Scene | Engine | TileMap) {\r\n super();\r\n }\r\n}\r\n\r\n/**\r\n * The 'postdraw' event is emitted on actors, scenes, and engine after drawing finishes. Actors' postdraw happens inside their graphics\r\n * transform so that all drawing takes place with the actor as the origin.\r\n *\r\n */\r\nexport class PostDrawEvent extends GameEvent {\r\n constructor(public ctx: ExcaliburGraphicsContext, public delta: number, public target: Entity | Scene | Engine | TileMap) {\r\n super();\r\n }\r\n}\r\n\r\n/**\r\n * The 'predebugdraw' event is emitted on actors, scenes, and engine before debug drawing starts.\r\n */\r\nexport class PreDebugDrawEvent extends GameEvent {\r\n constructor(public ctx: ExcaliburGraphicsContext, public target: Entity | Actor | Scene | Engine) {\r\n super();\r\n }\r\n}\r\n\r\n/**\r\n * The 'postdebugdraw' event is emitted on actors, scenes, and engine after debug drawing starts.\r\n */\r\nexport class PostDebugDrawEvent extends GameEvent {\r\n constructor(public ctx: ExcaliburGraphicsContext, public target: Entity | Actor | Scene | Engine) {\r\n super();\r\n }\r\n}\r\n\r\n/**\r\n * The 'preupdate' event is emitted on actors, scenes, camera, and engine before the update starts.\r\n */\r\nexport class PreUpdateEvent extends GameEvent {\r\n constructor(public engine: Engine, public delta: number, public target: T) {\r\n super();\r\n }\r\n}\r\n\r\n/**\r\n * The 'postupdate' event is emitted on actors, scenes, camera, and engine after the update ends.\r\n */\r\nexport class PostUpdateEvent extends GameEvent {\r\n constructor(public engine: Engine, public delta: number, public target: T) {\r\n super();\r\n }\r\n}\r\n\r\n/**\r\n * The 'preframe' event is emitted on the engine, before the frame begins.\r\n */\r\nexport class PreFrameEvent extends GameEvent {\r\n constructor(public engine: Engine, public prevStats: FrameStats) {\r\n super();\r\n this.target = engine;\r\n }\r\n}\r\n\r\n/**\r\n * The 'postframe' event is emitted on the engine, after a frame ends.\r\n */\r\nexport class PostFrameEvent extends GameEvent {\r\n constructor(public engine: Engine, public stats: FrameStats) {\r\n super();\r\n this.target = engine;\r\n }\r\n}\r\n\r\n/**\r\n * Event received when a gamepad is connected to Excalibur. [[Gamepads]] receives this event.\r\n */\r\nexport class GamepadConnectEvent extends GameEvent {\r\n constructor(public index: number, public gamepad: Gamepad) {\r\n super();\r\n this.target = gamepad;\r\n }\r\n}\r\n\r\n/**\r\n * Event received when a gamepad is disconnected from Excalibur. [[Gamepads]] receives this event.\r\n */\r\nexport class GamepadDisconnectEvent extends GameEvent {\r\n constructor(public index: number, public gamepad: Gamepad) {\r\n super();\r\n this.target = gamepad;\r\n }\r\n}\r\n\r\n/**\r\n * Gamepad button event. See [[Gamepads]] for information on responding to controller input. [[Gamepad]] instances receive this event;\r\n */\r\nexport class GamepadButtonEvent extends GameEvent {\r\n /**\r\n * @param button The Gamepad button\r\n * @param value A numeric value between 0 and 1\r\n */\r\n constructor(public button: Buttons, public value: number, public target: Gamepad) {\r\n super();\r\n }\r\n}\r\n\r\n/**\r\n * Gamepad axis event. See [[Gamepads]] for information on responding to controller input. [[Gamepad]] instances receive this event;\r\n */\r\nexport class GamepadAxisEvent extends GameEvent {\r\n /**\r\n * @param axis The Gamepad axis\r\n * @param value A numeric value between -1 and 1\r\n */\r\n constructor(public axis: Axes, public value: number, public target: Gamepad) {\r\n super();\r\n }\r\n}\r\n\r\n/**\r\n * Event received by the [[Engine]] when the browser window is visible on a screen.\r\n */\r\nexport class VisibleEvent extends GameEvent {\r\n constructor(public target: Engine) {\r\n super();\r\n }\r\n}\r\n\r\n/**\r\n * Event received by the [[Engine]] when the browser window is hidden from all screens.\r\n */\r\nexport class HiddenEvent extends GameEvent {\r\n constructor(public target: Engine) {\r\n super();\r\n }\r\n}\r\n\r\n/**\r\n * Event thrown on an [[Actor|actor]] when a collision will occur this frame if it resolves\r\n */\r\nexport class PreCollisionEvent extends GameEvent {\r\n /**\r\n * @param actor The actor the event was thrown on\r\n * @param other The actor that will collided with the current actor\r\n * @param side The side that will be collided with the current actor\r\n * @param intersection Intersection vector\r\n */\r\n constructor(actor: T, public other: T, public side: Side, public intersection: Vector) {\r\n super();\r\n this.target = actor;\r\n }\r\n}\r\n\r\n/**\r\n * Event thrown on an [[Actor|actor]] when a collision has been resolved (body reacted) this frame\r\n */\r\nexport class PostCollisionEvent extends GameEvent {\r\n /**\r\n * @param actor The actor the event was thrown on\r\n * @param other The actor that did collide with the current actor\r\n * @param side The side that did collide with the current actor\r\n * @param intersection Intersection vector\r\n */\r\n constructor(actor: T, public other: T, public side: Side, public intersection: Vector) {\r\n super();\r\n this.target = actor;\r\n }\r\n\r\n public get actor() {\r\n return this.target;\r\n }\r\n\r\n public set actor(actor: T) {\r\n this.target = actor;\r\n }\r\n}\r\n\r\nexport class ContactStartEvent {\r\n constructor(public target: T, public other: T, public contact: CollisionContact) {}\r\n}\r\n\r\nexport class ContactEndEvent {\r\n constructor(public target: T, public other: T) {}\r\n}\r\n\r\nexport class CollisionPreSolveEvent {\r\n constructor(public target: T, public other: T, public side: Side, public intersection: Vector, public contact: CollisionContact) {}\r\n}\r\n\r\nexport class CollisionPostSolveEvent {\r\n constructor(public target: T, public other: T, public side: Side, public intersection: Vector, public contact: CollisionContact) {}\r\n}\r\n\r\n/**\r\n * Event thrown the first time an [[Actor|actor]] collides with another, after an actor is in contact normal collision events are fired.\r\n */\r\nexport class CollisionStartEvent extends GameEvent {\r\n /**\r\n *\r\n * @param actor\r\n * @param other\r\n * @param contact\r\n */\r\n constructor(actor: T, public other: T, public contact: CollisionContact) {\r\n super();\r\n this.target = actor;\r\n }\r\n\r\n public get actor() {\r\n return this.target;\r\n }\r\n\r\n public set actor(actor: T) {\r\n this.target = actor;\r\n }\r\n}\r\n\r\n/**\r\n * Event thrown when the [[Actor|actor]] is no longer colliding with another\r\n */\r\nexport class CollisionEndEvent extends GameEvent {\r\n /**\r\n *\r\n */\r\n constructor(actor: T, public other: T) {\r\n super();\r\n this.target = actor;\r\n }\r\n\r\n public get actor() {\r\n return this.target;\r\n }\r\n\r\n public set actor(actor: T) {\r\n this.target = actor;\r\n }\r\n}\r\n\r\n/**\r\n * Event thrown on an [[Actor]], [[Scene]], and [[Engine]] only once before the first update call\r\n */\r\nexport class InitializeEvent extends GameEvent {\r\n /**\r\n * @param engine The reference to the current engine\r\n */\r\n constructor(public engine: Engine, public target: T) {\r\n super();\r\n }\r\n}\r\n\r\n/**\r\n * Event thrown on a [[Scene]] on activation\r\n */\r\nexport class ActivateEvent extends GameEvent {\r\n /**\r\n * @param context The context for the scene activation\r\n */\r\n constructor(public context: SceneActivationContext, public target: Scene) {\r\n super();\r\n }\r\n}\r\n\r\n/**\r\n * Event thrown on a [[Scene]] on deactivation\r\n */\r\nexport class DeactivateEvent extends GameEvent {\r\n /**\r\n * @param context The context for the scene deactivation\r\n */\r\n constructor(public context: SceneActivationContext, public target: Scene) {\r\n super();\r\n }\r\n}\r\n\r\n/**\r\n * Event thrown on an [[Actor]] when it completely leaves the screen.\r\n */\r\nexport class ExitViewPortEvent extends GameEvent {\r\n constructor(public target: Entity) {\r\n super();\r\n }\r\n}\r\n\r\n/**\r\n * Event thrown on an [[Actor]] when it completely leaves the screen.\r\n */\r\nexport class EnterViewPortEvent extends GameEvent {\r\n constructor(public target: Entity) {\r\n super();\r\n }\r\n}\r\n\r\nexport class EnterTriggerEvent extends GameEvent {\r\n constructor(public target: Trigger, public actor: Actor) {\r\n super();\r\n }\r\n}\r\n\r\nexport class ExitTriggerEvent extends GameEvent {\r\n constructor(public target: Trigger, public actor: Actor) {\r\n super();\r\n }\r\n}\r\n","import { GamepadConnectEvent, GamepadDisconnectEvent, GamepadButtonEvent, GamepadAxisEvent } from '../Events';\r\nimport { EventEmitter, EventKey, Handler, Subscription } from '../EventEmitter';\r\n\r\nexport type GamepadEvents = {\r\n connect: GamepadConnectEvent,\r\n disconnect: GamepadDisconnectEvent,\r\n button: GamepadButtonEvent,\r\n axis: GamepadAxisEvent\r\n}\r\n\r\nexport const GamepadEvents = {\r\n GamepadConnect: 'connect',\r\n GamepadDisconnect: 'disconnect',\r\n GamepadButton: 'button',\r\n GamepadAxis: 'axis'\r\n};\r\n\r\n/**\r\n * Excalibur leverages the HTML5 Gamepad API [where it is supported](http://caniuse.com/#feat=gamepad)\r\n * to provide controller support for your games.\r\n */\r\nexport class Gamepads {\r\n public events = new EventEmitter();\r\n /**\r\n * Whether or not to poll for Gamepad input (default: `false`)\r\n */\r\n public enabled = false;\r\n\r\n /**\r\n * Whether or not Gamepad API is supported\r\n */\r\n public supported = !!(navigator).getGamepads;\r\n\r\n /**\r\n * The minimum value an axis has to move before considering it a change\r\n */\r\n public static MinAxisMoveThreshold = 0.05;\r\n\r\n private _gamePadTimeStamps = [0, 0, 0, 0];\r\n private _oldPads: Gamepad[] = [];\r\n private _pads: Gamepad[] = [];\r\n private _initSuccess: boolean = false;\r\n private _navigator: NavigatorGamepads = navigator;\r\n private _minimumConfiguration: GamepadConfiguration = null;\r\n\r\n public init() {\r\n if (!this.supported) {\r\n return;\r\n }\r\n if (this._initSuccess) {\r\n return;\r\n }\r\n\r\n // In Chrome, this will return 4 undefined items until a button is pressed\r\n // In FF, this will not return any items until a button is pressed\r\n this._oldPads = this._clonePads(this._navigator.getGamepads());\r\n if (this._oldPads.length && this._oldPads[0]) {\r\n this._initSuccess = true;\r\n }\r\n }\r\n\r\n /**\r\n * Sets the minimum gamepad configuration, for example {axis: 4, buttons: 4} means\r\n * this game requires at minimum 4 axis inputs and 4 buttons, this is not restrictive\r\n * all other controllers with more axis or buttons are valid as well. If no minimum\r\n * configuration is set all pads are valid.\r\n */\r\n public setMinimumGamepadConfiguration(config: GamepadConfiguration): void {\r\n this._enableAndUpdate(); // if config is used, implicitly enable\r\n this._minimumConfiguration = config;\r\n }\r\n\r\n /**\r\n * When implicitly enabled, set the enabled flag and run an update so information is updated\r\n */\r\n private _enableAndUpdate() {\r\n if (!this.enabled) {\r\n this.enabled = true;\r\n this.update();\r\n }\r\n }\r\n\r\n /**\r\n * Checks a navigator gamepad against the minimum configuration if present.\r\n */\r\n private _isGamepadValid(pad: NavigatorGamepad): boolean {\r\n if (!this._minimumConfiguration) {\r\n return true;\r\n }\r\n if (!pad) {\r\n return false;\r\n }\r\n const axesLength = pad.axes.filter((value) => {\r\n return typeof value !== undefined;\r\n }).length;\r\n\r\n const buttonLength = pad.buttons.filter((value) => {\r\n return typeof value !== undefined;\r\n }).length;\r\n return axesLength >= this._minimumConfiguration.axis && buttonLength >= this._minimumConfiguration.buttons && pad.connected;\r\n }\r\n\r\n public emit>(eventName: TEventName, event: GamepadEvents[TEventName]): void;\r\n public emit(eventName: string, event?: any): void;\r\n public emit | string>(eventName: TEventName, event?: any): void {\r\n this.events.emit(eventName, event);\r\n }\r\n\r\n public on>(eventName: TEventName, handler: Handler): Subscription;\r\n public on(eventName: string, handler: Handler): Subscription;\r\n public on | string>(eventName: TEventName, handler: Handler): Subscription {\r\n this._enableAndUpdate(); // implicitly enable\r\n return this.events.on(eventName, handler);\r\n }\r\n\r\n public once>(eventName: TEventName, handler: Handler): Subscription;\r\n public once(eventName: string, handler: Handler): Subscription;\r\n public once | string>(eventName: TEventName, handler: Handler): Subscription {\r\n return this.events.once(eventName, handler);\r\n }\r\n\r\n public off>(eventName: TEventName, handler: Handler): void;\r\n public off(eventName: string, handler: Handler): void;\r\n public off(eventName: string): void;\r\n public off | string>(eventName: TEventName, handler?: Handler): void {\r\n this._enableAndUpdate(); // implicitly enable\r\n this.events.off(eventName, handler);\r\n }\r\n\r\n /**\r\n * Updates Gamepad state and publishes Gamepad events\r\n */\r\n public update() {\r\n if (!this.enabled || !this.supported) {\r\n return;\r\n }\r\n this.init();\r\n\r\n const gamepads = this._navigator.getGamepads();\r\n\r\n for (let i = 0; i < gamepads.length; i++) {\r\n if (!gamepads[i]) {\r\n const gamepad = this.at(i);\r\n // If was connected, but now isn't emit the disconnect event\r\n if (gamepad.connected) {\r\n this.events.emit('disconnect', new GamepadDisconnectEvent(i, gamepad));\r\n }\r\n // Reset connection status\r\n gamepad.connected = false;\r\n continue;\r\n } else {\r\n if (!this.at(i).connected && this._isGamepadValid(gamepads[i])) {\r\n this.events.emit('connect', new GamepadConnectEvent(i, this.at(i)));\r\n }\r\n // Set connection status\r\n this.at(i).connected = true;\r\n }\r\n\r\n this.at(i).update();\r\n\r\n // Only supported in Chrome\r\n if (gamepads[i].timestamp && gamepads[i].timestamp === this._gamePadTimeStamps[i]) {\r\n continue;\r\n }\r\n\r\n this._gamePadTimeStamps[i] = gamepads[i].timestamp;\r\n\r\n // Add reference to navigator gamepad\r\n this.at(i).navigatorGamepad = gamepads[i];\r\n\r\n // Buttons\r\n let b: string, bi: number, a: string, ai: number, value: number;\r\n\r\n for (b in Buttons) {\r\n bi = Buttons[b];\r\n if (typeof bi === 'number') {\r\n if (gamepads[i].buttons[bi]) {\r\n value = gamepads[i].buttons[bi].value;\r\n if (value !== this._oldPads[i].getButton(bi)) {\r\n if (gamepads[i].buttons[bi].pressed) {\r\n this.at(i).updateButton(bi, value);\r\n this.at(i).events.emit('button', new GamepadButtonEvent(bi, value, this.at(i)));\r\n } else {\r\n this.at(i).updateButton(bi, 0);\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n // Axes\r\n for (a in Axes) {\r\n ai = Axes[a];\r\n if (typeof ai === 'number') {\r\n value = gamepads[i].axes[ai];\r\n if (value !== this._oldPads[i].getAxes(ai)) {\r\n this.at(i).updateAxes(ai, value);\r\n this.at(i).events.emit('axis', new GamepadAxisEvent(ai, value, this.at(i)));\r\n }\r\n }\r\n }\r\n\r\n this._oldPads[i] = this._clonePad(gamepads[i]);\r\n }\r\n }\r\n\r\n /**\r\n * Safely retrieves a Gamepad at a specific index and creates one if it doesn't yet exist\r\n */\r\n public at(index: number): Gamepad {\r\n this._enableAndUpdate(); // implicitly enable gamepads when at() is called\r\n if (index >= this._pads.length) {\r\n // Ensure there is a pad to retrieve\r\n for (let i = this._pads.length - 1, max = index; i < max; i++) {\r\n this._pads.push(new Gamepad());\r\n this._oldPads.push(new Gamepad());\r\n }\r\n }\r\n\r\n return this._pads[index];\r\n }\r\n\r\n /**\r\n * Returns a list of all valid gamepads that meet the minimum configuration requirement.\r\n */\r\n public getValidGamepads(): Gamepad[] {\r\n this._enableAndUpdate();\r\n const result: Gamepad[] = [];\r\n for (let i = 0; i < this._pads.length; i++) {\r\n if (this._isGamepadValid(this.at(i).navigatorGamepad) && this.at(i).connected) {\r\n result.push(this.at(i));\r\n }\r\n }\r\n return result;\r\n }\r\n\r\n /**\r\n * Gets the number of connected gamepads\r\n */\r\n public count() {\r\n return this._pads.filter((p) => p.connected).length;\r\n }\r\n\r\n private _clonePads(pads: NavigatorGamepad[]): Gamepad[] {\r\n const arr = [];\r\n for (let i = 0, len = pads.length; i < len; i++) {\r\n arr.push(this._clonePad(pads[i]));\r\n }\r\n return arr;\r\n }\r\n\r\n /**\r\n * Fastest way to clone a known object is to do it yourself\r\n */\r\n private _clonePad(pad: NavigatorGamepad): Gamepad {\r\n let i, len;\r\n const clonedPad = new Gamepad();\r\n\r\n if (!pad) {\r\n return clonedPad;\r\n }\r\n\r\n for (i = 0, len = pad.buttons.length; i < len; i++) {\r\n if (pad.buttons[i]) {\r\n clonedPad.updateButton(i, pad.buttons[i].value);\r\n }\r\n }\r\n for (i = 0, len = pad.axes.length; i < len; i++) {\r\n clonedPad.updateAxes(i, pad.axes[i]);\r\n }\r\n\r\n\r\n return clonedPad;\r\n }\r\n}\r\n\r\n/**\r\n * Gamepad holds state information for a connected controller. See [[Gamepads]]\r\n * for more information on handling controller input.\r\n */\r\nexport class Gamepad {\r\n public events = new EventEmitter();\r\n public connected = false;\r\n public navigatorGamepad: NavigatorGamepad;\r\n private _axes: number[] = new Array(4);\r\n private _buttons: number[] = new Array(16);\r\n private _buttonsUp: number[] = new Array(16);\r\n private _buttonsDown: number[] = new Array(16);\r\n\r\n constructor() {\r\n for (let i = 0; i < this._buttons.length; i++) {\r\n this._buttons[i] = 0;\r\n }\r\n for (let i = 0; i < this._axes.length; i++) {\r\n this._axes[i] = 0;\r\n }\r\n }\r\n\r\n public update() {\r\n // Reset buttonsDown and buttonsUp after update is complete\r\n this._buttonsDown = new Array(16);\r\n this._buttonsUp = new Array(16);\r\n }\r\n\r\n /**\r\n * Whether or not the given button is pressed\r\n *\r\n * @deprecated will be removed in v0.28.0. Use isButtonHeld instead\r\n * @param button The button to query\r\n * @param threshold The threshold over which the button is considered to be pressed\r\n */\r\n public isButtonPressed(button: Buttons, threshold: number = 1) {\r\n return this._buttons[button] >= threshold;\r\n }\r\n\r\n /**\r\n * Tests if a certain button is held down. This is persisted between frames.\r\n *\r\n * @param button The button to query\r\n * @param threshold The threshold over which the button is considered to be pressed\r\n */\r\n public isButtonHeld(button: Buttons, threshold: number = 1) {\r\n return this._buttons[button] >= threshold;\r\n }\r\n\r\n /**\r\n * Tests if a certain button was just pressed this frame. This is cleared at the end of the update frame.\r\n *\r\n * @param button Test whether a button was just pressed\r\n * @param threshold The threshold over which the button is considered to be pressed\r\n */\r\n public wasButtonPressed(button: Buttons, threshold: number = 1) {\r\n return this._buttonsDown[button] >= threshold;\r\n }\r\n\r\n /**\r\n * Tests if a certain button was just released this frame. This is cleared at the end of the update frame.\r\n *\r\n * @param button Test whether a button was just released\r\n */\r\n public wasButtonReleased(button: Buttons) {\r\n return Boolean(this._buttonsUp[button]);\r\n }\r\n\r\n /**\r\n * Gets the given button value between 0 and 1\r\n */\r\n public getButton(button: Buttons) {\r\n return this._buttons[button];\r\n }\r\n\r\n /**\r\n * Gets the given axis value between -1 and 1. Values below\r\n * [[MinAxisMoveThreshold]] are considered 0.\r\n */\r\n public getAxes(axes: Axes) {\r\n const value = this._axes[axes];\r\n\r\n if (Math.abs(value) < Gamepads.MinAxisMoveThreshold) {\r\n return 0;\r\n } else {\r\n return value;\r\n }\r\n }\r\n\r\n public updateButton(buttonIndex: number, value: number) {\r\n // button was just released\r\n if (value === 0 && this._buttons[buttonIndex]) {\r\n this._buttonsUp[buttonIndex] = 1;\r\n\r\n // button was just pressed\r\n } else {\r\n this._buttonsDown[buttonIndex] = value;\r\n }\r\n\r\n this._buttons[buttonIndex] = value;\r\n }\r\n\r\n public updateAxes(axesIndex: number, value: number) {\r\n this._axes[axesIndex] = value;\r\n }\r\n\r\n public emit>(eventName: TEventName, event: GamepadEvents[TEventName]): void;\r\n public emit(eventName: string, event?: any): void;\r\n public emit | string>(eventName: TEventName, event?: any): void {\r\n this.events.emit(eventName, event);\r\n }\r\n\r\n public on>(eventName: TEventName, handler: Handler): Subscription;\r\n public on(eventName: string, handler: Handler): Subscription;\r\n public on | string>(eventName: TEventName, handler: Handler): Subscription {\r\n return this.events.on(eventName, handler);\r\n }\r\n\r\n public once>(eventName: TEventName, handler: Handler): Subscription;\r\n public once(eventName: string, handler: Handler): Subscription;\r\n public once | string>(eventName: TEventName, handler: Handler): Subscription {\r\n return this.events.once(eventName, handler);\r\n }\r\n\r\n public off>(eventName: TEventName, handler: Handler): void;\r\n public off(eventName: string, handler: Handler): void;\r\n public off(eventName: string): void;\r\n public off | string>(eventName: TEventName, handler?: Handler): void {\r\n this.events.off(eventName, handler);\r\n }\r\n}\r\n\r\n/**\r\n * Gamepad Buttons enumeration\r\n */\r\nexport enum Buttons {\r\n /**\r\n * Face 1 button (e.g. A)\r\n */\r\n Face1 = 0,\r\n /**\r\n * Face 2 button (e.g. B)\r\n */\r\n Face2 = 1,\r\n /**\r\n * Face 3 button (e.g. X)\r\n */\r\n Face3 = 2,\r\n /**\r\n * Face 4 button (e.g. Y)\r\n */\r\n Face4 = 3,\r\n /**\r\n * Left bumper button\r\n */\r\n LeftBumper = 4,\r\n /**\r\n * Right bumper button\r\n */\r\n RightBumper = 5,\r\n /**\r\n * Left trigger button\r\n */\r\n LeftTrigger = 6,\r\n /**\r\n * Right trigger button\r\n */\r\n RightTrigger = 7,\r\n /**\r\n * Select button\r\n */\r\n Select = 8,\r\n /**\r\n * Start button\r\n */\r\n Start = 9,\r\n /**\r\n * Left analog stick press (e.g. L3)\r\n */\r\n LeftStick = 10,\r\n /**\r\n * Right analog stick press (e.g. R3)\r\n */\r\n RightStick = 11,\r\n /**\r\n * D-pad up\r\n */\r\n DpadUp = 12,\r\n /**\r\n * D-pad down\r\n */\r\n DpadDown = 13,\r\n /**\r\n * D-pad left\r\n */\r\n DpadLeft = 14,\r\n /**\r\n * D-pad right\r\n */\r\n DpadRight = 15\r\n}\r\n\r\n/**\r\n * Gamepad Axes enumeration\r\n */\r\nexport enum Axes {\r\n /**\r\n * Left analogue stick X direction\r\n */\r\n LeftStickX = 0,\r\n /**\r\n * Left analogue stick Y direction\r\n */\r\n LeftStickY = 1,\r\n /**\r\n * Right analogue stick X direction\r\n */\r\n RightStickX = 2,\r\n /**\r\n * Right analogue stick Y direction\r\n */\r\n RightStickY = 3\r\n}\r\n\r\n/**\r\n * @internal\r\n */\r\nexport interface NavigatorGamepads {\r\n getGamepads(): NavigatorGamepad[];\r\n}\r\n\r\n/**\r\n * @internal\r\n */\r\nexport interface NavigatorGamepad {\r\n axes: number[];\r\n buttons: NavigatorGamepadButton[];\r\n connected: boolean;\r\n id: string;\r\n index: number;\r\n mapping: string;\r\n timestamp: number;\r\n}\r\n\r\n/**\r\n * @internal\r\n */\r\nexport interface NavigatorGamepadButton {\r\n pressed: boolean;\r\n value: number;\r\n}\r\n\r\n/**\r\n * @internal\r\n */\r\nexport interface NavigatorGamepadEvent {\r\n gamepad: NavigatorGamepad;\r\n}\r\n\r\n/**\r\n * @internal\r\n */\r\nexport interface GamepadConfiguration {\r\n axis: number;\r\n buttons: number;\r\n}\r\n","/* eslint-disable no-console */\r\n/**\r\n * Logging level that Excalibur will tag\r\n */\r\nexport enum LogLevel {\r\n Debug,\r\n Info,\r\n Warn,\r\n Error,\r\n Fatal\r\n}\r\n\r\n/**\r\n * Static singleton that represents the logging facility for Excalibur.\r\n * Excalibur comes built-in with a [[ConsoleAppender]] and [[ScreenAppender]].\r\n * Derive from [[Appender]] to create your own logging appenders.\r\n */\r\nexport class Logger {\r\n private static _INSTANCE: Logger = null;\r\n private _appenders: Appender[] = [];\r\n\r\n constructor() {\r\n if (Logger._INSTANCE) {\r\n throw new Error('Logger is a singleton');\r\n }\r\n Logger._INSTANCE = this;\r\n // Default console appender\r\n Logger._INSTANCE.addAppender(new ConsoleAppender());\r\n return Logger._INSTANCE;\r\n }\r\n\r\n /**\r\n * Gets or sets the default logging level. Excalibur will only log\r\n * messages if equal to or above this level. Default: [[LogLevel.Info]]\r\n */\r\n public defaultLevel: LogLevel = LogLevel.Info;\r\n\r\n /**\r\n * Gets the current static instance of Logger\r\n */\r\n public static getInstance(): Logger {\r\n if (Logger._INSTANCE == null) {\r\n Logger._INSTANCE = new Logger();\r\n }\r\n return Logger._INSTANCE;\r\n }\r\n\r\n /**\r\n * Adds a new [[Appender]] to the list of appenders to write to\r\n */\r\n public addAppender(appender: Appender): void {\r\n this._appenders.push(appender);\r\n }\r\n\r\n /**\r\n * Clears all appenders from the logger\r\n */\r\n public clearAppenders(): void {\r\n this._appenders.length = 0;\r\n }\r\n\r\n /**\r\n * Logs a message at a given LogLevel\r\n * @param level The LogLevel`to log the message at\r\n * @param args An array of arguments to write to an appender\r\n */\r\n private _log(level: LogLevel, args: any[]): void {\r\n if (level == null) {\r\n level = this.defaultLevel;\r\n }\r\n\r\n const len = this._appenders.length;\r\n\r\n for (let i = 0; i < len; i++) {\r\n if (level >= this.defaultLevel) {\r\n this._appenders[i].log(level, args);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Writes a log message at the [[LogLevel.Debug]] level\r\n * @param args Accepts any number of arguments\r\n */\r\n public debug(...args: any[]): void {\r\n this._log(LogLevel.Debug, args);\r\n }\r\n\r\n /**\r\n * Writes a log message at the [[LogLevel.Info]] level\r\n * @param args Accepts any number of arguments\r\n */\r\n public info(...args: any[]): void {\r\n this._log(LogLevel.Info, args);\r\n }\r\n\r\n /**\r\n * Writes a log message at the [[LogLevel.Warn]] level\r\n * @param args Accepts any number of arguments\r\n */\r\n public warn(...args: any[]): void {\r\n this._log(LogLevel.Warn, args);\r\n }\r\n\r\n /**\r\n * Writes a log message at the [[LogLevel.Error]] level\r\n * @param args Accepts any number of arguments\r\n */\r\n public error(...args: any[]): void {\r\n this._log(LogLevel.Error, args);\r\n }\r\n\r\n /**\r\n * Writes a log message at the [[LogLevel.Fatal]] level\r\n * @param args Accepts any number of arguments\r\n */\r\n public fatal(...args: any[]): void {\r\n this._log(LogLevel.Fatal, args);\r\n }\r\n}\r\n\r\n/**\r\n * Contract for any log appender (such as console/screen)\r\n */\r\nexport interface Appender {\r\n /**\r\n * Logs a message at the given [[LogLevel]]\r\n * @param level Level to log at\r\n * @param args Arguments to log\r\n */\r\n log(level: LogLevel, args: any[]): void;\r\n}\r\n\r\n/**\r\n * Console appender for browsers (i.e. `console.log`)\r\n */\r\nexport class ConsoleAppender implements Appender {\r\n /**\r\n * Logs a message at the given [[LogLevel]]\r\n * @param level Level to log at\r\n * @param args Arguments to log\r\n */\r\n public log(level: LogLevel, args: any[]): void {\r\n // Check for console support\r\n if (!console && !console.log && console.warn && console.error) {\r\n // todo maybe do something better than nothing\r\n return;\r\n }\r\n\r\n // Create a new console args array\r\n const consoleArgs: any[] = [];\r\n consoleArgs.unshift.apply(consoleArgs, args);\r\n consoleArgs.unshift('[' + LogLevel[level] + '] : ');\r\n\r\n if (level < LogLevel.Warn) {\r\n // Call .log for Debug/Info\r\n if (console.log.apply) {\r\n // this is required on some older browsers that don't support apply on console.log :(\r\n console.log.apply(console, consoleArgs);\r\n } else {\r\n console.log(consoleArgs.join(' '));\r\n }\r\n } else if (level < LogLevel.Error) {\r\n // Call .warn for Warn\r\n if (console.warn.apply) {\r\n console.warn.apply(console, consoleArgs);\r\n } else {\r\n console.warn(consoleArgs.join(' '));\r\n }\r\n } else {\r\n // Call .error for Error/Fatal\r\n if (console.error.apply) {\r\n console.error.apply(console, consoleArgs);\r\n } else {\r\n console.error(consoleArgs.join(' '));\r\n }\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * On-screen (canvas) appender\r\n */\r\nexport class ScreenAppender implements Appender {\r\n // @todo Clean this up\r\n\r\n private _messages: string[] = [];\r\n private _canvas: HTMLCanvasElement;\r\n private _ctx: CanvasRenderingContext2D;\r\n\r\n /**\r\n * @param width Width of the screen appender in pixels\r\n * @param height Height of the screen appender in pixels\r\n */\r\n constructor(width?: number, height?: number) {\r\n this._canvas = document.createElement('canvas');\r\n this._canvas.width = width || window.innerWidth;\r\n this._canvas.height = height || window.innerHeight;\r\n this._canvas.style.position = 'absolute';\r\n // eslint-disable-next-line\r\n this._ctx = this._canvas.getContext('2d'); // eslint-disable-line\r\n document.body.appendChild(this._canvas);\r\n }\r\n\r\n /**\r\n * Logs a message at the given [[LogLevel]]\r\n * @param level Level to log at\r\n * @param args Arguments to log\r\n */\r\n public log(level: LogLevel, args: any[]): void {\r\n const message = args.join(',');\r\n\r\n this._ctx.clearRect(0, 0, this._canvas.width, this._canvas.height);\r\n\r\n this._messages.unshift('[' + LogLevel[level] + '] : ' + message);\r\n\r\n let pos = 10;\r\n let opacity = 1.0;\r\n for (let i = 0; i < this._messages.length; i++) {\r\n this._ctx.fillStyle = 'rgba(255,255,255,' + opacity.toFixed(2) + ')';\r\n this._ctx.fillText(this._messages[i], 200, pos);\r\n pos += 10;\r\n opacity = opacity > 0 ? opacity - 0.05 : 0;\r\n }\r\n }\r\n}\r\n","\r\n\r\n/**\r\n * Checks if excalibur is in a x-origin iframe\r\n */\r\nexport function isCrossOriginIframe() {\r\n try {\r\n // Try and listen to events on top window frame if within an iframe.\r\n //\r\n // See https://github.com/excaliburjs/Excalibur/issues/1294\r\n //\r\n // Attempt to add an event listener, which triggers a DOMException on\r\n // cross-origin iframes\r\n const noop = () => {\r\n return;\r\n };\r\n window.top.addEventListener('blur', noop);\r\n window.top.removeEventListener('blur', noop);\r\n } catch {\r\n return true;\r\n }\r\n return false;\r\n}","import { Logger } from '../Util/Log';\r\nimport * as Events from '../Events';\r\nimport { isCrossOriginIframe } from '../Util/IFrame';\r\nimport { EventEmitter, EventKey, Handler, Subscription } from '../EventEmitter';\r\n\r\n/**\r\n * Enum representing physical input key codes\r\n */\r\nexport enum Keys {\r\n // NUMPAD\r\n Num0 = 'Numpad0',\r\n Num1 = 'Numpad1',\r\n Num2 = 'Numpad2',\r\n Num3 = 'Numpad3',\r\n Num4 = 'Numpad4',\r\n Num5 = 'Numpad5',\r\n Num6 = 'Numpad6',\r\n Num7 = 'Numpad7',\r\n Num8 = 'Numpad8',\r\n Num9 = 'Numpad9',\r\n NumAdd = 'NumpadAdd',\r\n NumSubtract = 'NumpadSubtract',\r\n NumMultiply = 'NumpadMultiply',\r\n NumDivide = 'NumpadDivide',\r\n // NumComma = 'NumpadComma', // not x-browser\r\n NumDecimal = 'NumpadDecimal',\r\n Numpad0 = 'Numpad0',\r\n Numpad1 = 'Numpad1',\r\n Numpad2 = 'Numpad2',\r\n Numpad3 = 'Numpad3',\r\n Numpad4 = 'Numpad4',\r\n Numpad5 = 'Numpad5',\r\n Numpad6 = 'Numpad6',\r\n Numpad7 = 'Numpad7',\r\n Numpad8 = 'Numpad8',\r\n Numpad9 = 'Numpad9',\r\n NumpadAdd = 'NumpadAdd',\r\n NumpadSubtract = 'NumpadSubtract',\r\n NumpadMultiply = 'NumpadMultiply',\r\n NumpadDivide = 'NumpadDivide',\r\n // NumpadComma = 'NumpadComma', // not x-browser\r\n NumpadDecimal = 'NumpadDecimal',\r\n\r\n // MODIFIERS\r\n NumLock = 'NumLock',\r\n ShiftLeft = 'ShiftLeft',\r\n ShiftRight = 'ShiftRight',\r\n AltLeft = 'AltLeft',\r\n AltRight = 'AltRight',\r\n ControlLeft = 'ControlLeft',\r\n ControlRight = 'ControlRight',\r\n MetaLeft = 'MetaLeft',\r\n MetaRight = 'MetaRight',\r\n\r\n // NUMBERS\r\n Key0 = 'Digit0',\r\n Key1 = 'Digit1',\r\n Key2 = 'Digit2',\r\n Key3 = 'Digit3',\r\n Key4 = 'Digit4',\r\n Key5 = 'Digit5',\r\n Key6 = 'Digit6',\r\n Key7 = 'Digit7',\r\n Key8 = 'Digit8',\r\n Key9 = 'Digit9',\r\n Digit0 = 'Digit0',\r\n Digit1 = 'Digit1',\r\n Digit2 = 'Digit2',\r\n Digit3 = 'Digit3',\r\n Digit4 = 'Digit4',\r\n Digit5 = 'Digit5',\r\n Digit6 = 'Digit6',\r\n Digit7 = 'Digit7',\r\n Digit8 = 'Digit8',\r\n Digit9 = 'Digit9',\r\n\r\n // FUNCTION KEYS\r\n F1 = 'F1',\r\n F2 = 'F2',\r\n F3 = 'F3',\r\n F4 = 'F4',\r\n F5 = 'F5',\r\n F6 = 'F6',\r\n F7 = 'F7',\r\n F8 = 'F8',\r\n F9 = 'F9',\r\n F10 = 'F10',\r\n F11 = 'F11',\r\n F12 = 'F12',\r\n\r\n // LETTERS\r\n A = 'KeyA',\r\n B = 'KeyB',\r\n C = 'KeyC',\r\n D = 'KeyD',\r\n E = 'KeyE',\r\n F = 'KeyF',\r\n G = 'KeyG',\r\n H = 'KeyH',\r\n I = 'KeyI',\r\n J = 'KeyJ',\r\n K = 'KeyK',\r\n L = 'KeyL',\r\n M = 'KeyM',\r\n N = 'KeyN',\r\n O = 'KeyO',\r\n P = 'KeyP',\r\n Q = 'KeyQ',\r\n R = 'KeyR',\r\n S = 'KeyS',\r\n T = 'KeyT',\r\n U = 'KeyU',\r\n V = 'KeyV',\r\n W = 'KeyW',\r\n X = 'KeyX',\r\n Y = 'KeyY',\r\n Z = 'KeyZ',\r\n KeyA = 'KeyA',\r\n KeyB = 'KeyB',\r\n KeyC = 'KeyC',\r\n KeyD = 'KeyD',\r\n KeyE = 'KeyE',\r\n KeyF = 'KeyF',\r\n KeyG = 'KeyG',\r\n KeyH = 'KeyH',\r\n KeyI = 'KeyI',\r\n KeyJ = 'KeyJ',\r\n KeyK = 'KeyK',\r\n KeyL = 'KeyL',\r\n KeyM = 'KeyM',\r\n KeyN = 'KeyN',\r\n KeyO = 'KeyO',\r\n KeyP = 'KeyP',\r\n KeyQ = 'KeyQ',\r\n KeyR = 'KeyR',\r\n KeyS = 'KeyS',\r\n KeyT = 'KeyT',\r\n KeyU = 'KeyU',\r\n KeyV = 'KeyV',\r\n KeyW = 'KeyW',\r\n KeyX = 'KeyX',\r\n KeyY = 'KeyY',\r\n KeyZ = 'KeyZ',\r\n\r\n // SYMBOLS\r\n Semicolon = 'Semicolon',\r\n Quote = 'Quote',\r\n Comma = 'Comma',\r\n Minus = 'Minus',\r\n Period = 'Period',\r\n Slash = 'Slash',\r\n Equal = 'Equal',\r\n BracketLeft = 'BracketLeft',\r\n Backslash = 'Backslash',\r\n BracketRight = 'BracketRight',\r\n Backquote = 'Backquote',\r\n\r\n // DIRECTIONS\r\n Up = 'ArrowUp',\r\n Down = 'ArrowDown',\r\n Left = 'ArrowLeft',\r\n Right = 'ArrowRight',\r\n ArrowUp = 'ArrowUp',\r\n ArrowDown = 'ArrowDown',\r\n ArrowLeft = 'ArrowLeft',\r\n ArrowRight = 'ArrowRight',\r\n\r\n // OTHER\r\n Space = 'Space',\r\n Backspace = 'Backspace',\r\n Delete = 'Delete',\r\n Esc = 'Escape',\r\n Escape = 'Escape',\r\n Enter = 'Enter',\r\n NumpadEnter = 'NumpadEnter',\r\n ContextMenu = 'ContextMenu'\r\n}\r\n\r\n/**\r\n * Event thrown on a game object for a key event\r\n */\r\nexport class KeyEvent extends Events.GameEvent {\r\n /**\r\n * @param key The key responsible for throwing the event\r\n * @param value The key's typed value the browser detected\r\n * @param originalEvent The original keyboard event that Excalibur handled\r\n */\r\n constructor(public key: Keys, public value?: string, public originalEvent?: KeyboardEvent) {\r\n super();\r\n }\r\n}\r\n\r\nexport interface KeyboardInitOptions {\r\n global?: GlobalEventHandlers,\r\n grabWindowFocus?: boolean\r\n}\r\n\r\nexport type KeyEvents = {\r\n press: KeyEvent,\r\n hold: KeyEvent,\r\n release: KeyEvent\r\n};\r\n\r\nexport const KeyEvents = {\r\n Press: 'press',\r\n Hold: 'hold',\r\n Release: 'release'\r\n};\r\n\r\n/**\r\n * Provides keyboard support for Excalibur.\r\n */\r\nexport class Keyboard {\r\n public events = new EventEmitter();\r\n /**\r\n * Keys that are currently held down\r\n */\r\n private _keys: Keys[] = [];\r\n /**\r\n * Keys up in the current frame\r\n */\r\n private _keysUp: Keys[] = [];\r\n /**\r\n * Keys down in the current frame\r\n */\r\n private _keysDown: Keys[] = [];\r\n\r\n public emit>(eventName: TEventName, event: KeyEvents[TEventName]): void;\r\n public emit(eventName: string, event?: any): void;\r\n public emit | string>(eventName: TEventName, event?: any): void {\r\n this.events.emit(eventName, event);\r\n }\r\n\r\n public on>(eventName: TEventName, handler: Handler): Subscription;\r\n public on(eventName: string, handler: Handler): Subscription;\r\n public on | string>(eventName: TEventName, handler: Handler): Subscription {\r\n return this.events.on(eventName, handler);\r\n }\r\n\r\n public once>(eventName: TEventName, handler: Handler): Subscription;\r\n public once(eventName: string, handler: Handler): Subscription;\r\n public once | string>(eventName: TEventName, handler: Handler): Subscription {\r\n return this.events.once(eventName, handler);\r\n }\r\n\r\n public off>(eventName: TEventName, handler: Handler): void;\r\n public off(eventName: string, handler: Handler): void;\r\n public off(eventName: string): void;\r\n public off | string>(eventName: TEventName, handler?: Handler): void {\r\n this.events.off(eventName, handler);\r\n }\r\n\r\n /**\r\n * Initialize Keyboard event listeners\r\n */\r\n init(keyboardOptions?: KeyboardInitOptions): void {\r\n let { global } = keyboardOptions;\r\n const { grabWindowFocus } = keyboardOptions;\r\n if (!global) {\r\n if (isCrossOriginIframe()) {\r\n global = window;\r\n // Workaround for iframes like for itch.io or codesandbox\r\n // https://www.reddit.com/r/gamemaker/comments/kfs5cs/keyboard_inputs_no_longer_working_in_html5_game/\r\n // https://forum.gamemaker.io/index.php?threads/solved-keyboard-issue-on-itch-io.87336/\r\n if (grabWindowFocus) {\r\n window.focus();\r\n }\r\n\r\n Logger.getInstance().warn('Excalibur might be in a cross-origin iframe, in order to receive keyboard events it must be in focus');\r\n } else {\r\n global = window.top;\r\n }\r\n }\r\n\r\n global.addEventListener('blur', () => {\r\n this._keys.length = 0; // empties array efficiently\r\n });\r\n\r\n // key up is on window because canvas cannot have focus\r\n global.addEventListener('keyup', this._handleKeyUp);\r\n\r\n // key down is on window because canvas cannot have focus\r\n global.addEventListener('keydown', this._handleKeyDown);\r\n }\r\n\r\n private _releaseAllKeys = (ev: KeyboardEvent) => {\r\n for (const code of this._keys) {\r\n const keyEvent = new KeyEvent(code, ev.key, ev);\r\n this.events.emit('up', keyEvent);\r\n this.events.emit('release', keyEvent);\r\n }\r\n this._keysUp = Array.from((new Set(this._keys.concat(this._keysUp))));\r\n this._keys.length = 0;\r\n };\r\n\r\n private _handleKeyDown = (ev: KeyboardEvent) => {\r\n // handle macos meta key issue\r\n // https://github.com/excaliburjs/Excalibur/issues/2608\r\n if (!ev.metaKey && (this._keys.includes(Keys.MetaLeft) || this._keys.includes(Keys.MetaRight))) {\r\n this._releaseAllKeys(ev);\r\n }\r\n\r\n const code = ev.code as Keys;\r\n if (this._keys.indexOf(code) === -1) {\r\n this._keys.push(code);\r\n this._keysDown.push(code);\r\n const keyEvent = new KeyEvent(code, ev.key, ev);\r\n this.events.emit('down', keyEvent);\r\n this.events.emit('press', keyEvent);\r\n }\r\n };\r\n\r\n private _handleKeyUp = (ev: KeyboardEvent) => {\r\n const code = ev.code as Keys;\r\n const key = this._keys.indexOf(code);\r\n this._keys.splice(key, 1);\r\n this._keysUp.push(code);\r\n const keyEvent = new KeyEvent(code, ev.key, ev);\r\n\r\n // alias the old api, we may want to deprecate this in the future\r\n this.events.emit('up', keyEvent);\r\n this.events.emit('release', keyEvent);\r\n\r\n // handle macos meta key issue\r\n // https://github.com/excaliburjs/Excalibur/issues/2608\r\n if (ev.key === 'Meta') {\r\n this._releaseAllKeys(ev);\r\n }\r\n };\r\n\r\n public update() {\r\n // Reset keysDown and keysUp after update is complete\r\n this._keysDown.length = 0;\r\n this._keysUp.length = 0;\r\n\r\n // Emit synthetic \"hold\" event\r\n for (let i = 0; i < this._keys.length; i++) {\r\n this.events.emit('hold', new KeyEvent(this._keys[i]));\r\n }\r\n }\r\n\r\n /**\r\n * Gets list of keys being pressed down\r\n */\r\n public getKeys(): Keys[] {\r\n return this._keys;\r\n }\r\n\r\n /**\r\n * Tests if a certain key was just pressed this frame. This is cleared at the end of the update frame.\r\n * @param key Test whether a key was just pressed\r\n */\r\n public wasPressed(key: Keys): boolean {\r\n return this._keysDown.indexOf(key) > -1;\r\n }\r\n\r\n /**\r\n * Tests if a certain key is held down. This is persisted between frames.\r\n * @param key Test whether a key is held down\r\n */\r\n public isHeld(key: Keys): boolean {\r\n return this._keys.indexOf(key) > -1;\r\n }\r\n\r\n /**\r\n * Tests if a certain key was just released this frame. This is cleared at the end of the update frame.\r\n * @param key Test whether a key was just released\r\n */\r\n public wasReleased(key: Keys): boolean {\r\n return this._keysUp.indexOf(key) > -1;\r\n }\r\n\r\n /**\r\n * Trigger a manual key event\r\n * @param type\r\n * @param key\r\n * @param character\r\n */\r\n public triggerEvent(type: 'down' | 'up', key: Keys, character?: string) {\r\n if (type === 'down') {\r\n this._handleKeyDown(new KeyboardEvent('keydown', {\r\n code: key,\r\n key: character ?? null\r\n }));\r\n }\r\n if (type === 'up') {\r\n this._handleKeyUp(new KeyboardEvent('keyup', {\r\n code: key,\r\n key: character ?? null\r\n }));\r\n }\r\n }\r\n}\r\n","/**\r\n * Determines the scope of handling mouse/touch events.\r\n */\r\n\r\nexport enum PointerScope {\r\n /**\r\n * Handle events on the `canvas` element only. Events originating outside the\r\n * `canvas` will not be handled.\r\n */\r\n Canvas = 'Canvas',\r\n\r\n /**\r\n * Handles events on the entire document. All events will be handled by Excalibur.\r\n */\r\n Document = 'Document'\r\n}\r\n","/**\r\n * @module\r\n * Pseudo-Random Utility\r\n *\r\n * A pseudo-random utility to add seeded random support for help in\r\n * generating things like terrain or reproducible randomness. Uses the\r\n * [Mersenne Twister](https://en.wikipedia.org/wiki/Mersenne_Twister) algorithm.\r\n */\r\n\r\n/**\r\n * 32-bit mask\r\n */\r\nconst BITMASK32: number = 0xffffffff;\r\n\r\n/**\r\n * Pseudo-random number generator following the Mersenne_Twister algorithm. Given a seed this generator will produce the same sequence\r\n * of numbers each time it is called.\r\n * See https://en.wikipedia.org/wiki/Mersenne_Twister for more details.\r\n * Uses the MT19937-32 (2002) implementation documented here http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/MT2002/emt19937ar.html\r\n *\r\n * Api inspired by http://chancejs.com/# https://github.com/chancejs/chancejs\r\n */\r\nexport class Random {\r\n // Separation point of one one word, the number of bits in the lower bitmask 0 <= r <= w-1\r\n private _lowerMask: number = 0x7fffffff; // 31 bits same as _r\r\n private _upperMask: number = 0x80000000; // 34 high bits\r\n\r\n // Word size, 64 bits\r\n private _w: number = 32;\r\n\r\n // Degree of recurrence\r\n private _n: number = 624;\r\n\r\n // Middle word, an offset used in the recurrence defining the series x, 1<=m(this._n);\r\n // need to mask to support higher bit machines\r\n this._mt[0] = (seed || Date.now()) >>> 0;\r\n\r\n for (let i = 1; i < this._n; i++) {\r\n const s = this._mt[i - 1] ^ (this._mt[i - 1] >>> (this._w - 2));\r\n // numbers are bigger than the JS max safe int, add in 16-bit chunks to prevent IEEE rounding errors on high bits\r\n this._mt[i] = (((this._f * ((s & 0xffff0000) >>> 16)) << 16) + this._f * (s & 0xffff) + i) >>> 0;\r\n }\r\n this._index = this._n;\r\n }\r\n\r\n /**\r\n * Apply the twist\r\n */\r\n private _twist(): void {\r\n const mag01 = [0x0, this._a];\r\n let y = 0,\r\n i = 0;\r\n for (; i < this._n - this._m; i++) {\r\n y = (this._mt[i] & this._upperMask) | (this._mt[i + 1] & this._lowerMask);\r\n this._mt[i] = this._mt[i + this._m] ^ (y >>> 1) ^ (mag01[y & 0x1] & BITMASK32);\r\n }\r\n for (; i < this._n - 1; i++) {\r\n y = (this._mt[i] & this._upperMask) | (this._mt[i + 1] & this._lowerMask);\r\n this._mt[i] = this._mt[i + (this._m - this._n)] ^ (y >>> 1) ^ (mag01[y & 0x1] & BITMASK32);\r\n }\r\n y = (this._mt[this._n - 1] & this._upperMask) | (this._mt[0] & this._lowerMask);\r\n this._mt[this._n - 1] = this._mt[this._m - 1] ^ (y >>> 1) ^ (mag01[y & 0x1] & BITMASK32);\r\n\r\n this._index = 0;\r\n }\r\n\r\n /**\r\n * Return next 32 bit integer number in sequence\r\n */\r\n public nextInt(): number {\r\n if (this._index >= this._n) {\r\n this._twist();\r\n }\r\n\r\n let y = this._mt[this._index++];\r\n\r\n y ^= y >>> this._u;\r\n y ^= (y << this._s) & this._b;\r\n y ^= (y << this._t) & this._c;\r\n y ^= y >>> this._l;\r\n\r\n return y >>> 0;\r\n }\r\n\r\n /**\r\n * Return a random floating point number between [0, 1)\r\n */\r\n public next(): number {\r\n return this.nextInt() * (1.0 / 4294967296.0); // divided by 2^32\r\n }\r\n\r\n /**\r\n * Return a random floating point in range [min, max) min is included, max is not included\r\n */\r\n public floating(min: number, max: number): number {\r\n return (max - min) * this.next() + min;\r\n }\r\n\r\n /**\r\n * Return a random integer in range [min, max] min is included, max is included.\r\n * Implemented with rejection sampling, see https://medium.com/@betable/tifu-by-using-math-random-f1c308c4fd9d#.i13tdiu5a\r\n */\r\n public integer(min: number, max: number): number {\r\n return Math.floor((max - min + 1) * this.next() + min);\r\n }\r\n\r\n /**\r\n * Returns true or false randomly with 50/50 odds by default.\r\n * By default the likelihood of returning a true is .5 (50%).\r\n * @param likelihood takes values between [0, 1]\r\n */\r\n public bool(likelihood: number = 0.5): boolean {\r\n return this.next() <= likelihood;\r\n }\r\n\r\n /**\r\n * Returns one element from an array at random\r\n */\r\n public pickOne(array: Array): T {\r\n return array[this.integer(0, array.length - 1)];\r\n }\r\n\r\n /**\r\n * Returns a new array random picking elements from the original\r\n * @param array Original array to pick from\r\n * @param numPicks can be any positive number\r\n * @param allowDuplicates indicates whether the returned set is allowed duplicates (it does not mean there will always be duplicates\r\n * just that it is possible)\r\n */\r\n public pickSet(array: Array, numPicks: number, allowDuplicates: boolean = false): Array {\r\n if (allowDuplicates) {\r\n return this._pickSetWithDuplicates(array, numPicks);\r\n } else {\r\n return this._pickSetWithoutDuplicates(array, numPicks);\r\n }\r\n }\r\n\r\n /**\r\n * Returns a new array randomly picking elements in the original (not reused)\r\n * @param array Array to pick elements out of\r\n * @param numPicks must be less than or equal to the number of elements in the array.\r\n */\r\n private _pickSetWithoutDuplicates(array: Array, numPicks: number): Array {\r\n if (numPicks > array.length || numPicks < 0) {\r\n throw new Error('Invalid number of elements to pick, must pick a value 0 < n <= length');\r\n }\r\n if (numPicks === array.length) {\r\n return array;\r\n }\r\n\r\n const result: Array = new Array(numPicks);\r\n let currentPick = 0;\r\n const tempArray = array.slice(0);\r\n while (currentPick < numPicks) {\r\n const index = this.integer(0, tempArray.length - 1);\r\n result[currentPick++] = tempArray[index];\r\n tempArray.splice(index, 1);\r\n }\r\n\r\n return result;\r\n }\r\n\r\n /**\r\n * Returns a new array random picking elements from the original allowing duplicates\r\n * @param array Array to pick elements out of\r\n * @param numPicks can be any positive number\r\n */\r\n private _pickSetWithDuplicates(array: Array, numPicks: number): Array {\r\n // Typescript numbers are all floating point, so do we add check for int? (or floor the input?)\r\n if (numPicks < 0) {\r\n throw new Error('Invalid number of elements to pick, must pick a value 0 <= n < MAX_INT');\r\n }\r\n const result = new Array(numPicks);\r\n for (let i = 0; i < numPicks; i++) {\r\n result[i] = this.pickOne(array);\r\n }\r\n return result;\r\n }\r\n\r\n /**\r\n * Returns a new array that has its elements shuffled. Using the Fisher/Yates method\r\n * https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle\r\n */\r\n public shuffle(array: Array): Array {\r\n const tempArray = array.slice(0);\r\n let swap: T = null;\r\n for (let i = 0; i < tempArray.length - 2; i++) {\r\n const randomIndex = this.integer(i, tempArray.length - 1);\r\n swap = tempArray[i];\r\n tempArray[i] = tempArray[randomIndex];\r\n tempArray[randomIndex] = swap;\r\n }\r\n\r\n return tempArray;\r\n }\r\n\r\n /**\r\n * Generate a list of random integer numbers\r\n * @param length the length of the final array\r\n * @param min the minimum integer number to generate inclusive\r\n * @param max the maximum integer number to generate inclusive\r\n */\r\n public range(length: number, min: number, max: number): Array {\r\n const result: Array = new Array(length);\r\n for (let i = 0; i < length; i++) {\r\n result[i] = this.integer(min, max);\r\n }\r\n return result;\r\n }\r\n\r\n /**\r\n * Returns the result of a d4 dice roll\r\n */\r\n public d4() {\r\n return this.integer(1, 4);\r\n }\r\n\r\n /**\r\n * Returns the result of a d6 dice roll\r\n */\r\n public d6() {\r\n return this.integer(1, 6);\r\n }\r\n\r\n /**\r\n * Returns the result of a d8 dice roll\r\n */\r\n public d8() {\r\n return this.integer(1, 8);\r\n }\r\n\r\n /**\r\n * Returns the result of a d10 dice roll\r\n */\r\n public d10() {\r\n return this.integer(1, 10);\r\n }\r\n\r\n /**\r\n * Returns the result of a d12 dice roll\r\n */\r\n public d12() {\r\n return this.integer(1, 12);\r\n }\r\n\r\n /**\r\n * Returns the result of a d20 dice roll\r\n */\r\n public d20() {\r\n return this.integer(1, 20);\r\n }\r\n}\r\n","import { Random } from './Random';\r\n\r\n/**\r\n * Two PI constant\r\n */\r\nexport const TwoPI: number = Math.PI * 2;\r\n\r\n/**\r\n * Returns the fractional part of a number\r\n * @param x\r\n */\r\nexport function frac(x: number): number {\r\n if (x >= 0) {\r\n return x - Math.floor(x);\r\n } else {\r\n return x - Math.ceil(x);\r\n }\r\n}\r\n\r\n/**\r\n * Returns the sign of a number, if 0 returns 0\r\n */\r\nexport function sign(val: number): number {\r\n if (val === 0) {\r\n return 0;\r\n }\r\n return val < 0 ? -1 : 1;\r\n};\r\n\r\n/**\r\n * Clamps a value between a min and max inclusive\r\n */\r\nexport function clamp(val: number, min: number, max: number) {\r\n return Math.min(Math.max(min, val), max);\r\n}\r\n\r\n\r\n/**\r\n * Convert an angle to be the equivalent in the range [0, 2PI]\r\n */\r\nexport function canonicalizeAngle(angle: number): number {\r\n let tmpAngle = angle;\r\n if (angle > TwoPI) {\r\n while (tmpAngle > TwoPI) {\r\n tmpAngle -= TwoPI;\r\n }\r\n }\r\n\r\n if (angle < 0) {\r\n while (tmpAngle < 0) {\r\n tmpAngle += TwoPI;\r\n }\r\n }\r\n return tmpAngle;\r\n}\r\n\r\n/**\r\n * Convert radians to degrees\r\n */\r\nexport function toDegrees(radians: number): number {\r\n return (180 / Math.PI) * radians;\r\n}\r\n\r\n/**\r\n * Convert degrees to radians\r\n */\r\nexport function toRadians(degrees: number): number {\r\n return (degrees / 180) * Math.PI;\r\n}\r\n\r\n/**\r\n * Generate a range of numbers\r\n * For example: range(0, 5) -> [0, 1, 2, 3, 4, 5]\r\n * @param from inclusive\r\n * @param to inclusive\r\n */\r\nexport const range = (from: number, to: number) => Array.from(new Array(to - from + 1), (_x, i) => i + from);\r\n\r\n/**\r\n * Find a random floating point number in range\r\n */\r\nexport function randomInRange(min: number, max: number, random: Random = new Random()): number {\r\n return random ? random.floating(min, max) : min + Math.random() * (max - min);\r\n}\r\n\r\n/**\r\n * Find a random integer in a range\r\n */\r\nexport function randomIntInRange(min: number, max: number, random: Random = new Random()): number {\r\n return random ? random.integer(min, max) : Math.round(randomInRange(min, max));\r\n}","import { Clonable } from '../Interfaces/Clonable';\r\nimport { clamp } from './util';\r\n\r\n/**\r\n * A 2D vector on a plane.\r\n */\r\n\r\nexport class Vector implements Clonable {\r\n /**\r\n * A (0, 0) vector\r\n */\r\n public static get Zero() {\r\n return new Vector(0, 0);\r\n }\r\n\r\n /**\r\n * A (1, 1) vector\r\n */\r\n public static get One() {\r\n return new Vector(1, 1);\r\n }\r\n\r\n /**\r\n * A (0.5, 0.5) vector\r\n */\r\n public static get Half() {\r\n return new Vector(0.5, 0.5);\r\n }\r\n\r\n /**\r\n * A unit vector pointing up (0, -1)\r\n */\r\n public static get Up() {\r\n return new Vector(0, -1);\r\n }\r\n\r\n /**\r\n * A unit vector pointing down (0, 1)\r\n */\r\n public static get Down() {\r\n return new Vector(0, 1);\r\n }\r\n\r\n /**\r\n * A unit vector pointing left (-1, 0)\r\n */\r\n public static get Left() {\r\n return new Vector(-1, 0);\r\n }\r\n /**\r\n * A unit vector pointing right (1, 0)\r\n */\r\n public static get Right() {\r\n return new Vector(1, 0);\r\n }\r\n\r\n /**\r\n * Returns a vector of unit length in the direction of the specified angle in Radians.\r\n * @param angle The angle to generate the vector\r\n */\r\n public static fromAngle(angle: number) {\r\n return new Vector(Math.cos(angle), Math.sin(angle));\r\n }\r\n\r\n /**\r\n * Checks if vector is not null, undefined, or if any of its components are NaN or Infinity.\r\n */\r\n public static isValid(vec: Vector) {\r\n if (vec === null || vec === undefined) {\r\n return false;\r\n }\r\n if (isNaN(vec.x) || isNaN(vec.y)) {\r\n return false;\r\n }\r\n\r\n if (vec.x === Infinity || vec.y === Infinity || vec.x === -Infinity || vec.y === -Infinity) {\r\n return false;\r\n }\r\n\r\n return true;\r\n }\r\n\r\n /**\r\n * Calculates distance between two Vectors\r\n * @param vec1\r\n * @param vec2\r\n */\r\n public static distance(vec1: Vector, vec2: Vector) {\r\n return Math.sqrt(Math.pow(vec1.x - vec2.x, 2) + Math.pow(vec1.y - vec2.y, 2));\r\n }\r\n\r\n public static min(vec1: Vector, vec2: Vector) {\r\n return new Vector(Math.min(vec1.x, vec2.x), Math.min(vec1.y, vec2.y));\r\n }\r\n\r\n public static max(vec1: Vector, vec2: Vector) {\r\n return new Vector(Math.max(vec1.x, vec2.x), Math.max(vec1.y, vec2.y));\r\n }\r\n\r\n /**\r\n * @param x X component of the Vector\r\n * @param y Y component of the Vector\r\n */\r\n constructor(x: number, y: number) {\r\n this._x = x;\r\n this._y = y;\r\n }\r\n\r\n protected _x = 0;\r\n /**\r\n * Get the x component of the vector\r\n */\r\n public get x(): number {\r\n return this._x;\r\n }\r\n\r\n /**\r\n * Set the x component, THIS MUTATES the current vector. It is usually better to create a new vector.\r\n * @warning **Be very careful setting components on shared vectors, mutating shared vectors can cause hard to find bugs**\r\n */\r\n public set x(val: number) {\r\n this._x = val;\r\n }\r\n\r\n protected _y = 0;\r\n /**\r\n * Get the y component of the vector\r\n */\r\n public get y(): number {\r\n return this._y;\r\n }\r\n\r\n /**\r\n * Set the y component, THIS MUTATES the current vector. It is usually better to create a new vector.\r\n * @warning **Be very careful setting components on shared vectors, mutating shared vectors can cause hard to find bugs**\r\n */\r\n public set y(val: number) {\r\n this._y = val;\r\n }\r\n\r\n /**\r\n * Sets the x and y components at once, THIS MUTATES the current vector. It is usually better to create a new vector.\r\n *\r\n * @warning **Be very careful using this, mutating vectors can cause hard to find bugs**\r\n */\r\n setTo(x: number, y: number) {\r\n (this.x as number) = x;\r\n (this.y as number) = y;\r\n }\r\n\r\n /**\r\n * Compares this point against another and tests for equality\r\n * @param vector The other point to compare to\r\n * @param tolerance Amount of euclidean distance off we are willing to tolerate\r\n */\r\n public equals(vector: Vector, tolerance: number = 0.001): boolean {\r\n return Math.abs(this.x - vector.x) <= tolerance && Math.abs(this.y - vector.y) <= tolerance;\r\n }\r\n\r\n /**\r\n * The distance to another vector. If no other Vector is specified, this will return the [[magnitude]].\r\n * @param v The other vector. Leave blank to use origin vector.\r\n */\r\n public distance(v?: Vector): number {\r\n if (!v) {\r\n return Math.sqrt(this.x * this.x + this.y * this.y);\r\n }\r\n const deltaX = this.x - v.x;\r\n const deltaY = this.y - v.y;\r\n return Math.sqrt(deltaX * deltaX + deltaY * deltaY);\r\n }\r\n\r\n public squareDistance(v?: Vector): number {\r\n if (!v) {\r\n v = Vector.Zero;\r\n }\r\n const deltaX = this.x - v.x;\r\n const deltaY = this.y - v.y;\r\n return deltaX * deltaX + deltaY * deltaY;\r\n }\r\n\r\n /**\r\n * Clamps the current vector's magnitude mutating it\r\n * @param magnitude\r\n */\r\n public clampMagnitude(magnitude: number): Vector {\r\n const size = this.size;\r\n const newSize = clamp(size, 0, magnitude);\r\n this.size = newSize;\r\n return this;\r\n }\r\n\r\n /**\r\n * The size (magnitude) of the Vector\r\n */\r\n public get size(): number {\r\n return this.distance();\r\n }\r\n\r\n /**\r\n * Setting the size mutates the current vector\r\n *\r\n * @warning Can be used to set the size of the vector, **be very careful using this, mutating vectors can cause hard to find bugs**\r\n */\r\n public set size(newLength: number) {\r\n const v = this.normalize().scale(newLength);\r\n this.setTo(v.x, v.y);\r\n }\r\n\r\n /**\r\n * Normalizes a vector to have a magnitude of 1.\r\n */\r\n public normalize(): Vector {\r\n const d = this.distance();\r\n if (d > 0) {\r\n return new Vector(this.x / d, this.y / d);\r\n } else {\r\n return new Vector(0, 1);\r\n }\r\n }\r\n\r\n /**\r\n * Returns the average (midpoint) between the current point and the specified\r\n */\r\n public average(vec: Vector): Vector {\r\n return this.add(vec).scale(0.5);\r\n }\r\n\r\n /**\r\n * Scales a vector's by a factor of size\r\n * @param size The factor to scale the magnitude by\r\n * @param dest Optionally provide a destination vector for the result\r\n */\r\n public scale(scale: Vector, dest?: Vector): Vector;\r\n public scale(size: number, dest?: Vector): Vector;\r\n public scale(sizeOrScale: number | Vector, dest?: Vector): Vector {\r\n const result = dest || new Vector(0, 0);\r\n if (sizeOrScale instanceof Vector) {\r\n result.x = this.x * sizeOrScale.x;\r\n result.y = this.y * sizeOrScale.y;\r\n } else {\r\n result.x = this.x * sizeOrScale;\r\n result.y = this.y * sizeOrScale;\r\n }\r\n return result;\r\n }\r\n\r\n /**\r\n * Adds one vector to another\r\n * @param v The vector to add\r\n * @param dest Optionally copy the result into a provided vector\r\n */\r\n public add(v: Vector, dest?: Vector): Vector {\r\n if (dest) {\r\n dest.x = this.x + v.x;\r\n dest.y = this.y + v.y;\r\n return dest;\r\n }\r\n return new Vector(this.x + v.x, this.y + v.y);\r\n }\r\n\r\n /**\r\n * Subtracts a vector from another, if you subtract vector `B.sub(A)` the resulting vector points from A -> B\r\n * @param v The vector to subtract\r\n */\r\n public sub(v: Vector): Vector {\r\n return new Vector(this.x - v.x, this.y - v.y);\r\n }\r\n\r\n /**\r\n * Adds one vector to this one modifying the original\r\n * @param v The vector to add\r\n * @warning Be very careful using this, mutating vectors can cause hard to find bugs\r\n */\r\n public addEqual(v: Vector): Vector {\r\n this.setTo(this.x + v.x, this.y + v.y);\r\n return this;\r\n }\r\n\r\n /**\r\n * Subtracts a vector from this one modifying the original\r\n * @param v The vector to subtract\r\n * @warning Be very careful using this, mutating vectors can cause hard to find bugs\r\n */\r\n public subEqual(v: Vector): Vector {\r\n this.setTo(this.x - v.x, this.y - v.y);\r\n return this;\r\n }\r\n\r\n /**\r\n * Scales this vector by a factor of size and modifies the original\r\n * @warning Be very careful using this, mutating vectors can cause hard to find bugs\r\n */\r\n public scaleEqual(size: number): Vector {\r\n this.setTo(this.x * size, this.y * size);\r\n return this;\r\n }\r\n\r\n /**\r\n * Performs a dot product with another vector\r\n * @param v The vector to dot\r\n */\r\n public dot(v: Vector): number {\r\n return this.x * v.x + this.y * v.y;\r\n }\r\n\r\n /**\r\n * Performs a 2D cross product with scalar. 2D cross products with a scalar return a vector.\r\n * @param v The scalar to cross\r\n */\r\n public cross(v: number): Vector;\r\n /**\r\n * Performs a 2D cross product with another vector. 2D cross products return a scalar value not a vector.\r\n * @param v The vector to cross\r\n */\r\n public cross(v: Vector): number;\r\n public cross(v: any): any {\r\n if (v instanceof Vector) {\r\n return this.x * v.y - this.y * v.x;\r\n } else if (typeof v === 'number') {\r\n return new Vector(v * this.y, -v * this.x);\r\n }\r\n }\r\n\r\n static cross(num: number, vec: Vector): Vector {\r\n return new Vector(-num * vec.y, num * vec.x);\r\n }\r\n\r\n /**\r\n * Returns the perpendicular vector to this one\r\n */\r\n public perpendicular(): Vector {\r\n return new Vector(this.y, -this.x);\r\n }\r\n\r\n /**\r\n * Returns the normal vector to this one, same as the perpendicular of length 1\r\n */\r\n public normal(): Vector {\r\n return this.perpendicular().normalize();\r\n }\r\n\r\n /**\r\n * Negate the current vector\r\n */\r\n public negate(): Vector {\r\n return this.scale(-1);\r\n }\r\n\r\n /**\r\n * Returns the angle of this vector.\r\n */\r\n public toAngle(): number {\r\n return Math.atan2(this.y, this.x);\r\n }\r\n\r\n /**\r\n * Rotates the current vector around a point by a certain number of\r\n * degrees in radians\r\n */\r\n public rotate(angle: number, anchor?: Vector): Vector {\r\n if (!anchor) {\r\n anchor = new Vector(0, 0);\r\n }\r\n const sinAngle = Math.sin(angle);\r\n const cosAngle = Math.cos(angle);\r\n const x = cosAngle * (this.x - anchor.x) - sinAngle * (this.y - anchor.y) + anchor.x;\r\n const y = sinAngle * (this.x - anchor.x) + cosAngle * (this.y - anchor.y) + anchor.y;\r\n return new Vector(x, y);\r\n }\r\n\r\n /**\r\n * Creates new vector that has the same values as the previous.\r\n */\r\n public clone(dest?: Vector): Vector {\r\n const v = dest ?? new Vector(0, 0);\r\n v.x = this.x;\r\n v.y = this.y;\r\n return v;\r\n }\r\n\r\n /**\r\n * Returns a string representation of the vector.\r\n */\r\n public toString(fixed?: number): string {\r\n if (fixed) {\r\n return `(${this.x.toFixed(fixed)}, ${this.y.toFixed(fixed)})`;\r\n }\r\n return `(${this.x}, ${this.y})`;\r\n }\r\n}\r\n\r\n/**\r\n * Shorthand for creating new Vectors - returns a new Vector instance with the\r\n * provided X and Y components.\r\n *\r\n * @param x X component of the Vector\r\n * @param y Y component of the Vector\r\n */\r\nexport function vec(x: number, y: number): Vector {\r\n return new Vector(x, y);\r\n}\r\n","\r\n/**\r\n * Provides standard colors (e.g. [[Color.Black]])\r\n * but you can also create custom colors using RGB, HSL, or Hex. Also provides\r\n * useful color operations like [[Color.lighten]], [[Color.darken]], and more.\r\n */\r\nexport class Color {\r\n /**\r\n * Red channel\r\n */\r\n public r: number;\r\n /**\r\n * Green channel\r\n */\r\n public g: number;\r\n /**\r\n * Blue channel\r\n */\r\n public b: number;\r\n /**\r\n * Alpha channel (between 0 and 1)\r\n */\r\n public a: number;\r\n\r\n /**\r\n * Hue\r\n */\r\n public h: number;\r\n /**\r\n * Saturation\r\n */\r\n public s: number;\r\n /**\r\n * Lightness\r\n */\r\n public l: number;\r\n\r\n /**\r\n * Creates a new instance of Color from an r, g, b, a\r\n *\r\n * @param r The red component of color (0-255)\r\n * @param g The green component of color (0-255)\r\n * @param b The blue component of color (0-255)\r\n * @param a The alpha component of color (0-1.0)\r\n */\r\n constructor(r: number, g: number, b: number, a?: number) {\r\n this.r = r;\r\n this.g = g;\r\n this.b = b;\r\n this.a = a != null ? a : 1;\r\n }\r\n\r\n /**\r\n * Creates a new instance of Color from an r, g, b, a\r\n *\r\n * @param r The red component of color (0-255)\r\n * @param g The green component of color (0-255)\r\n * @param b The blue component of color (0-255)\r\n * @param a The alpha component of color (0-1.0)\r\n */\r\n public static fromRGB(r: number, g: number, b: number, a?: number): Color {\r\n return new Color(r, g, b, a);\r\n }\r\n\r\n /**\r\n * Creates a new instance of Color from a rgb string\r\n *\r\n * @param string CSS color string of the form rgba(255, 255, 255, 1) or rgb(255, 255, 255)\r\n */\r\n public static fromRGBString(string: string): Color {\r\n const rgbaRegEx: RegExp = /^rgba?\\((\\d+),\\s*(\\d+),\\s*(\\d+)(?:,\\s*(\\d+(?:\\.\\d+)?))?\\)/i;\r\n let match = null;\r\n if ((match = string.match(rgbaRegEx))) {\r\n const r = parseInt(match[1], 10);\r\n const g = parseInt(match[2], 10);\r\n const b = parseInt(match[3], 10);\r\n let a = 1;\r\n if (match[4]) {\r\n a = parseFloat(match[4]);\r\n }\r\n return new Color(r, g, b, a);\r\n } else {\r\n throw new Error('Invalid rgb/a string: ' + string);\r\n }\r\n }\r\n\r\n /**\r\n * Creates a new instance of Color from a hex string\r\n *\r\n * @param hex CSS color string of the form #ffffff, the alpha component is optional\r\n */\r\n public static fromHex(hex: string): Color {\r\n const hexRegEx: RegExp = /^#?([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})?$/i;\r\n let match = null;\r\n if ((match = hex.match(hexRegEx))) {\r\n const r = parseInt(match[1], 16);\r\n const g = parseInt(match[2], 16);\r\n const b = parseInt(match[3], 16);\r\n let a = 1;\r\n if (match[4]) {\r\n a = parseInt(match[4], 16) / 255;\r\n }\r\n return new Color(r, g, b, a);\r\n } else {\r\n throw new Error('Invalid hex string: ' + hex);\r\n }\r\n }\r\n\r\n /**\r\n * Creates a new instance of Color from hsla values\r\n *\r\n * @param h Hue is represented [0-1]\r\n * @param s Saturation is represented [0-1]\r\n * @param l Luminance is represented [0-1]\r\n * @param a Alpha is represented [0-1]\r\n */\r\n public static fromHSL(h: number, s: number, l: number, a: number = 1.0): Color {\r\n const temp = new HSLColor(h, s, l, a);\r\n return temp.toRGBA();\r\n }\r\n\r\n /**\r\n * Lightens the current color by a specified amount\r\n *\r\n * @param factor The amount to lighten by [0-1]\r\n */\r\n public lighten(factor: number = 0.1): Color {\r\n const temp = HSLColor.fromRGBA(this.r, this.g, this.b, this.a);\r\n temp.l += (1 - temp.l) * factor;\r\n return temp.toRGBA();\r\n }\r\n\r\n /**\r\n * Darkens the current color by a specified amount\r\n *\r\n * @param factor The amount to darken by [0-1]\r\n */\r\n public darken(factor: number = 0.1): Color {\r\n const temp = HSLColor.fromRGBA(this.r, this.g, this.b, this.a);\r\n temp.l -= temp.l * factor;\r\n return temp.toRGBA();\r\n }\r\n\r\n /**\r\n * Saturates the current color by a specified amount\r\n *\r\n * @param factor The amount to saturate by [0-1]\r\n */\r\n public saturate(factor: number = 0.1): Color {\r\n const temp = HSLColor.fromRGBA(this.r, this.g, this.b, this.a);\r\n temp.s += temp.s * factor;\r\n return temp.toRGBA();\r\n }\r\n\r\n /**\r\n * Desaturates the current color by a specified amount\r\n *\r\n * @param factor The amount to desaturate by [0-1]\r\n */\r\n public desaturate(factor: number = 0.1): Color {\r\n const temp = HSLColor.fromRGBA(this.r, this.g, this.b, this.a);\r\n temp.s -= temp.s * factor;\r\n return temp.toRGBA();\r\n }\r\n\r\n /**\r\n * Multiplies a color by another, results in a darker color\r\n *\r\n * @param color The other color\r\n */\r\n public multiply(color: Color): Color {\r\n const newR = (((color.r / 255) * this.r) / 255) * 255;\r\n const newG = (((color.g / 255) * this.g) / 255) * 255;\r\n const newB = (((color.b / 255) * this.b) / 255) * 255;\r\n const newA = color.a * this.a;\r\n return new Color(newR, newG, newB, newA);\r\n }\r\n\r\n /**\r\n * Screens a color by another, results in a lighter color\r\n *\r\n * @param color The other color\r\n */\r\n public screen(color: Color): Color {\r\n const color1 = color.invert();\r\n const color2 = color.invert();\r\n return color1.multiply(color2).invert();\r\n }\r\n\r\n /**\r\n * Inverts the current color\r\n */\r\n public invert(): Color {\r\n return new Color(255 - this.r, 255 - this.g, 255 - this.b, 1.0 - this.a);\r\n }\r\n\r\n /**\r\n * Averages the current color with another\r\n *\r\n * @param color The other color\r\n */\r\n public average(color: Color): Color {\r\n const newR = (color.r + this.r) / 2;\r\n const newG = (color.g + this.g) / 2;\r\n const newB = (color.b + this.b) / 2;\r\n const newA = (color.a + this.a) / 2;\r\n return new Color(newR, newG, newB, newA);\r\n }\r\n\r\n public equal(color: Color): boolean {\r\n return this.toString() === color.toString();\r\n }\r\n\r\n /**\r\n * Returns a CSS string representation of a color.\r\n *\r\n * @param format Color representation, accepts: rgb, hsl, or hex\r\n */\r\n public toString(format: 'rgb' | 'hsl' | 'hex' = 'rgb') {\r\n switch (format) {\r\n case 'rgb':\r\n return this.toRGBA();\r\n case 'hsl':\r\n return this.toHSLA();\r\n case 'hex':\r\n return this.toHex();\r\n default:\r\n throw new Error('Invalid Color format');\r\n }\r\n }\r\n\r\n /**\r\n * Returns Hex Value of a color component\r\n * @param c color component\r\n * @see https://stackoverflow.com/questions/5623838/rgb-to-hex-and-hex-to-rgb\r\n */\r\n private _componentToHex(c: number) {\r\n const hex = c.toString(16);\r\n return hex.length === 1 ? '0' + hex : hex;\r\n }\r\n\r\n /**\r\n * Return Hex representation of a color.\r\n */\r\n public toHex() {\r\n return '#' + this._componentToHex(this.r) + this._componentToHex(this.g) + this._componentToHex(this.b);\r\n }\r\n\r\n /**\r\n * Return RGBA representation of a color.\r\n */\r\n public toRGBA() {\r\n const result = String(this.r.toFixed(0)) + ', ' + String(this.g.toFixed(0)) + ', ' + String(this.b.toFixed(0));\r\n if (this.a !== undefined || this.a !== null) {\r\n return 'rgba(' + result + ', ' + String(this.a) + ')';\r\n }\r\n return 'rgb(' + result + ')';\r\n }\r\n\r\n /**\r\n * Return HSLA representation of a color.\r\n */\r\n public toHSLA() {\r\n return HSLColor.fromRGBA(this.r, this.g, this.b, this.a).toString();\r\n }\r\n\r\n /**\r\n * Returns a CSS string representation of a color.\r\n */\r\n public fillStyle() {\r\n return this.toString();\r\n }\r\n\r\n /**\r\n * Returns a clone of the current color.\r\n */\r\n public clone(): Color {\r\n return new Color(this.r, this.g, this.b, this.a);\r\n }\r\n\r\n /**\r\n * Black (#000000)\r\n */\r\n public static get Black(): Color {\r\n return Color.fromHex('#000000');\r\n }\r\n\r\n /**\r\n * White (#FFFFFF)\r\n */\r\n public static get White(): Color {\r\n return Color.fromHex('#FFFFFF');\r\n }\r\n\r\n /**\r\n * Gray (#808080)\r\n */\r\n public static get Gray(): Color {\r\n return Color.fromHex('#808080');\r\n }\r\n\r\n /**\r\n * Light gray (#D3D3D3)\r\n */\r\n public static get LightGray(): Color {\r\n return Color.fromHex('#D3D3D3');\r\n }\r\n\r\n /**\r\n * Dark gray (#A9A9A9)\r\n */\r\n public static get DarkGray(): Color {\r\n return Color.fromHex('#A9A9A9');\r\n }\r\n\r\n /**\r\n * Yellow (#FFFF00)\r\n */\r\n public static get Yellow(): Color {\r\n return Color.fromHex('#FFFF00');\r\n }\r\n\r\n /**\r\n * Orange (#FFA500)\r\n */\r\n public static get Orange(): Color {\r\n return Color.fromHex('#FFA500');\r\n }\r\n\r\n /**\r\n * Red (#FF0000)\r\n */\r\n public static get Red(): Color {\r\n return Color.fromHex('#FF0000');\r\n }\r\n\r\n /**\r\n * Vermilion (#FF5B31)\r\n */\r\n public static get Vermilion(): Color {\r\n return Color.fromHex('#FF5B31');\r\n }\r\n\r\n /**\r\n * Rose (#FF007F)\r\n */\r\n public static get Rose(): Color {\r\n return Color.fromHex('#FF007F');\r\n }\r\n\r\n /**\r\n * Magenta (#FF00FF)\r\n */\r\n public static get Magenta(): Color {\r\n return Color.fromHex('#FF00FF');\r\n }\r\n\r\n /**\r\n * Violet (#7F00FF)\r\n */\r\n public static get Violet(): Color {\r\n return Color.fromHex('#7F00FF');\r\n }\r\n\r\n /**\r\n * Blue (#0000FF)\r\n */\r\n public static get Blue(): Color {\r\n return Color.fromHex('#0000FF');\r\n }\r\n\r\n /**\r\n * Azure (#007FFF)\r\n */\r\n public static get Azure(): Color {\r\n return Color.fromHex('#007FFF');\r\n }\r\n\r\n /**\r\n * Cyan (#00FFFF)\r\n */\r\n public static get Cyan(): Color {\r\n return Color.fromHex('#00FFFF');\r\n }\r\n\r\n /**\r\n * Viridian (#59978F)\r\n */\r\n public static get Viridian(): Color {\r\n return Color.fromHex('#59978F');\r\n }\r\n\r\n /**\r\n * Green (#00FF00)\r\n */\r\n public static get Green(): Color {\r\n return Color.fromHex('#00FF00');\r\n }\r\n\r\n /**\r\n * Chartreuse (#7FFF00)\r\n */\r\n public static get Chartreuse(): Color {\r\n return Color.fromHex('#7FFF00');\r\n }\r\n\r\n /**\r\n * Transparent (#FFFFFF00)\r\n */\r\n public static get Transparent(): Color {\r\n return Color.fromHex('#FFFFFF00');\r\n }\r\n\r\n /**\r\n * ExcaliburBlue (#176BAA)\r\n */\r\n public static get ExcaliburBlue(): Color {\r\n return Color.fromHex('#176BAA');\r\n }\r\n}\r\n\r\n/**\r\n * Internal HSL Color representation\r\n *\r\n * http://en.wikipedia.org/wiki/HSL_and_HSV\r\n * http://axonflux.com/handy-rgb-to-hsl-and-rgb-to-hsv-color-model-c\r\n */\r\nclass HSLColor {\r\n constructor(public h: number, public s: number, public l: number, public a: number) {}\r\n\r\n public static hue2rgb(p: number, q: number, t: number): number {\r\n if (t < 0) {\r\n t += 1;\r\n }\r\n if (t > 1) {\r\n t -= 1;\r\n }\r\n if (t < 1 / 6) {\r\n return p + (q - p) * 6 * t;\r\n }\r\n if (t < 1 / 2) {\r\n return q;\r\n }\r\n if (t < 2 / 3) {\r\n return p + (q - p) * (2 / 3 - t) * 6;\r\n }\r\n return p;\r\n }\r\n\r\n public static fromRGBA(r: number, g: number, b: number, a: number): HSLColor {\r\n r /= 255;\r\n g /= 255;\r\n b /= 255;\r\n const max = Math.max(r, g, b),\r\n min = Math.min(r, g, b);\r\n let h, s;\r\n const l = (max + min) / 2;\r\n\r\n if (max === min) {\r\n h = s = 0; // achromatic\r\n } else {\r\n const d = max - min;\r\n s = l > 0.5 ? d / (2 - max - min) : d / (max + min);\r\n switch (max) {\r\n case r:\r\n h = (g - b) / d + (g < b ? 6 : 0);\r\n break;\r\n case g:\r\n h = (b - r) / d + 2;\r\n break;\r\n case b:\r\n h = (r - g) / d + 4;\r\n break;\r\n }\r\n h /= 6;\r\n }\r\n\r\n return new HSLColor(h, s, l, a);\r\n }\r\n\r\n public toRGBA(): Color {\r\n let r: number, g: number, b: number;\r\n\r\n if (this.s === 0) {\r\n r = g = b = this.l; // achromatic\r\n } else {\r\n const q = this.l < 0.5 ? this.l * (1 + this.s) : this.l + this.s - this.l * this.s;\r\n const p = 2 * this.l - q;\r\n r = HSLColor.hue2rgb(p, q, this.h + 1 / 3);\r\n g = HSLColor.hue2rgb(p, q, this.h);\r\n b = HSLColor.hue2rgb(p, q, this.h - 1 / 3);\r\n }\r\n\r\n return new Color(r * 255, g * 255, b * 255, this.a);\r\n }\r\n\r\n public toString(): string {\r\n const h = this.h.toFixed(0),\r\n s = this.s.toFixed(0),\r\n l = this.l.toFixed(0),\r\n a = this.a.toFixed(0);\r\n return `hsla(${h}, ${s}, ${l}, ${a})`;\r\n }\r\n}\r\n","import { Vector } from '../Math/vector';\r\n\r\n/**\r\n * An enum that describes the sides of an axis aligned box for collision\r\n */\r\nexport enum Side {\r\n None = 'None',\r\n Top = 'Top',\r\n Bottom = 'Bottom',\r\n Left = 'Left',\r\n Right = 'Right'\r\n}\r\n\r\nexport module Side {\r\n /**\r\n * Returns the opposite side from the current\r\n */\r\n export function getOpposite(side: Side): Side {\r\n if (side === Side.Top) {\r\n return Side.Bottom;\r\n }\r\n if (side === Side.Bottom) {\r\n return Side.Top;\r\n }\r\n if (side === Side.Left) {\r\n return Side.Right;\r\n }\r\n if (side === Side.Right) {\r\n return Side.Left;\r\n }\r\n\r\n return Side.None;\r\n }\r\n\r\n /**\r\n * Given a vector, return the Side most in that direction (via dot product)\r\n */\r\n export function fromDirection(direction: Vector): Side {\r\n const directions = [Vector.Left, Vector.Right, Vector.Up, Vector.Down];\r\n const directionEnum = [Side.Left, Side.Right, Side.Top, Side.Bottom];\r\n\r\n let max = -Number.MAX_VALUE;\r\n let maxIndex = -1;\r\n for (let i = 0; i < directions.length; i++) {\r\n if (directions[i].dot(direction) > max) {\r\n max = directions[i].dot(direction);\r\n maxIndex = i;\r\n }\r\n }\r\n return directionEnum[maxIndex];\r\n }\r\n}\r\n","import { Vector } from '../Math/vector';\r\nimport { Ray } from '../Math/ray';\r\nimport { Color } from '../Color';\r\nimport { Side } from './Side';\r\nimport { ExcaliburGraphicsContext } from '../Graphics/Context/ExcaliburGraphicsContext';\r\nimport { AffineMatrix } from '../Math/affine-matrix';\r\n\r\nexport interface BoundingBoxOptions {\r\n left: number;\r\n right: number;\r\n top: number;\r\n bottom: number;\r\n}\r\n\r\n/**\r\n * Axis Aligned collision primitive for Excalibur.\r\n */\r\nexport class BoundingBox {\r\n public top: number;\r\n public right: number;\r\n public bottom: number;\r\n public left: number;\r\n\r\n /**\r\n * Constructor allows passing of either an object with all coordinate components,\r\n * or the coordinate components passed separately.\r\n * @param leftOrOptions Either x coordinate of the left edge or an options object\r\n * containing the four coordinate components.\r\n * @param top y coordinate of the top edge\r\n * @param right x coordinate of the right edge\r\n * @param bottom y coordinate of the bottom edge\r\n */\r\n constructor(leftOrOptions: number | BoundingBoxOptions = 0, top: number = 0, right: number = 0, bottom: number = 0) {\r\n if (typeof leftOrOptions === 'object') {\r\n this.left = leftOrOptions.left;\r\n this.top = leftOrOptions.top;\r\n this.right = leftOrOptions.right;\r\n this.bottom = leftOrOptions.bottom;\r\n } else if (typeof leftOrOptions === 'number') {\r\n this.left = leftOrOptions;\r\n this.top = top;\r\n this.right = right;\r\n this.bottom = bottom;\r\n }\r\n }\r\n\r\n /**\r\n * Returns a new instance of [[BoundingBox]] that is a copy of the current instance\r\n */\r\n public clone(): BoundingBox {\r\n return new BoundingBox(this.left, this.top, this.right, this.bottom);\r\n }\r\n\r\n /**\r\n * Given bounding box A & B, returns the side relative to A when intersection is performed.\r\n * @param intersection Intersection vector between 2 bounding boxes\r\n */\r\n public static getSideFromIntersection(intersection: Vector): Side {\r\n if (!intersection) {\r\n return Side.None;\r\n }\r\n if (intersection) {\r\n if (Math.abs(intersection.x) > Math.abs(intersection.y)) {\r\n if (intersection.x < 0) {\r\n return Side.Right;\r\n }\r\n return Side.Left;\r\n } else {\r\n if (intersection.y < 0) {\r\n return Side.Bottom;\r\n }\r\n return Side.Top;\r\n }\r\n }\r\n return Side.None;\r\n }\r\n\r\n public static fromPoints(points: Vector[]): BoundingBox {\r\n let minX = Infinity;\r\n let minY = Infinity;\r\n let maxX = -Infinity;\r\n let maxY = -Infinity;\r\n for (let i = 0; i < points.length; i++) {\r\n if (points[i].x < minX) {\r\n minX = points[i].x;\r\n }\r\n if (points[i].x > maxX) {\r\n maxX = points[i].x;\r\n }\r\n if (points[i].y < minY) {\r\n minY = points[i].y;\r\n }\r\n if (points[i].y > maxY) {\r\n maxY = points[i].y;\r\n }\r\n }\r\n return new BoundingBox(minX, minY, maxX, maxY);\r\n }\r\n\r\n public static fromDimension(width: number, height: number, anchor: Vector = Vector.Half, pos: Vector = Vector.Zero) {\r\n return new BoundingBox(\r\n -width * anchor.x + pos.x,\r\n -height * anchor.y + pos.y,\r\n width - width * anchor.x + pos.x,\r\n height - height * anchor.y + pos.y\r\n );\r\n }\r\n\r\n /**\r\n * Returns the calculated width of the bounding box\r\n */\r\n public get width() {\r\n return this.right - this.left;\r\n }\r\n\r\n /**\r\n * Returns the calculated height of the bounding box\r\n */\r\n public get height() {\r\n return this.bottom - this.top;\r\n }\r\n\r\n /**\r\n * Return whether the bounding box has zero dimensions in height,width or both\r\n */\r\n public hasZeroDimensions() {\r\n return this.width === 0 || this.height === 0;\r\n }\r\n\r\n /**\r\n * Returns the center of the bounding box\r\n */\r\n public get center(): Vector {\r\n return new Vector((this.left + this.right) / 2, (this.top + this.bottom) / 2);\r\n }\r\n\r\n public translate(pos: Vector): BoundingBox {\r\n return new BoundingBox(this.left + pos.x, this.top + pos.y, this.right + pos.x, this.bottom + pos.y);\r\n }\r\n\r\n /**\r\n * Rotates a bounding box by and angle and around a point, if no point is specified (0, 0) is used by default. The resulting bounding\r\n * box is also axis-align. This is useful when a new axis-aligned bounding box is needed for rotated geometry.\r\n */\r\n public rotate(angle: number, point: Vector = Vector.Zero): BoundingBox {\r\n const points = this.getPoints().map((p) => p.rotate(angle, point));\r\n return BoundingBox.fromPoints(points);\r\n }\r\n\r\n /**\r\n * Scale a bounding box by a scale factor, optionally provide a point\r\n * @param scale\r\n * @param point\r\n */\r\n public scale(scale: Vector, point: Vector = Vector.Zero): BoundingBox {\r\n const shifted = this.translate(point);\r\n return new BoundingBox(shifted.left * scale.x, shifted.top * scale.y, shifted.right * scale.x, shifted.bottom * scale.y);\r\n }\r\n\r\n /**\r\n * Transform the axis aligned bounding box by a [[Matrix]], producing a new axis aligned bounding box\r\n * @param matrix\r\n */\r\n public transform(matrix: AffineMatrix) {\r\n // inlined these calculations to not use vectors would speed it up slightly\r\n // const matFirstColumn = vec(matrix.data[0], matrix.data[1]);\r\n // const xa = matFirstColumn.scale(this.left);\r\n const xa1 = matrix.data[0] * this.left;\r\n const xa2 = matrix.data[1] * this.left;\r\n\r\n // const xb = matFirstColumn.scale(this.right);\r\n const xb1 = matrix.data[0] * this.right;\r\n const xb2 = matrix.data[1] * this.right;\r\n\r\n // const matSecondColumn = vec(matrix.data[2], matrix.data[3]);\r\n // const ya = matSecondColumn.scale(this.top);\r\n const ya1 = matrix.data[2] * this.top;\r\n const ya2 = matrix.data[3] * this.top;\r\n\r\n // const yb = matSecondColumn.scale(this.bottom);\r\n const yb1 = matrix.data[2] * this.bottom;\r\n const yb2 = matrix.data[3] * this.bottom;\r\n\r\n const matrixPos = matrix.getPosition();\r\n // const topLeft = Vector.min(xa, xb).add(Vector.min(ya, yb)).add(matrixPos);\r\n // const bottomRight = Vector.max(xa, xb).add(Vector.max(ya, yb)).add(matrixPos);\r\n const left = Math.min(xa1, xb1) + Math.min(ya1, yb1) + matrixPos.x;\r\n const top = Math.min(xa2, xb2) + Math.min(ya2, yb2) + matrixPos.y;\r\n const right = Math.max(xa1, xb1) + Math.max(ya1, yb1) + matrixPos.x;\r\n const bottom = Math.max(xa2, xb2) + Math.max(ya2, yb2) + matrixPos.y;\r\n\r\n return new BoundingBox({\r\n left,//: topLeft.x,\r\n top,//: topLeft.y,\r\n right,//: bottomRight.x,\r\n bottom//: bottomRight.y\r\n });\r\n }\r\n\r\n /**\r\n * Returns the perimeter of the bounding box\r\n */\r\n public getPerimeter(): number {\r\n const wx = this.width;\r\n const wy = this.height;\r\n return 2 * (wx + wy);\r\n }\r\n\r\n public getPoints(): Vector[] {\r\n const results = [];\r\n results.push(new Vector(this.left, this.top));\r\n results.push(new Vector(this.right, this.top));\r\n results.push(new Vector(this.right, this.bottom));\r\n results.push(new Vector(this.left, this.bottom));\r\n return results;\r\n }\r\n\r\n /**\r\n * Determines whether a ray intersects with a bounding box\r\n */\r\n public rayCast(ray: Ray, farClipDistance = Infinity): boolean {\r\n // algorithm from https://tavianator.com/fast-branchless-raybounding-box-intersections/\r\n let tmin = -Infinity;\r\n let tmax = +Infinity;\r\n\r\n const xinv = ray.dir.x === 0 ? Number.MAX_VALUE : 1 / ray.dir.x;\r\n const yinv = ray.dir.y === 0 ? Number.MAX_VALUE : 1 / ray.dir.y;\r\n\r\n const tx1 = (this.left - ray.pos.x) * xinv;\r\n const tx2 = (this.right - ray.pos.x) * xinv;\r\n tmin = Math.min(tx1, tx2);\r\n tmax = Math.max(tx1, tx2);\r\n\r\n const ty1 = (this.top - ray.pos.y) * yinv;\r\n const ty2 = (this.bottom - ray.pos.y) * yinv;\r\n tmin = Math.max(tmin, Math.min(ty1, ty2));\r\n tmax = Math.min(tmax, Math.max(ty1, ty2));\r\n\r\n return tmax >= Math.max(0, tmin) && tmin < farClipDistance;\r\n }\r\n\r\n public rayCastTime(ray: Ray, farClipDistance = Infinity): number {\r\n // algorithm from https://tavianator.com/fast-branchless-raybounding-box-intersections/\r\n let tmin = -Infinity;\r\n let tmax = +Infinity;\r\n\r\n const xinv = ray.dir.x === 0 ? Number.MAX_VALUE : 1 / ray.dir.x;\r\n const yinv = ray.dir.y === 0 ? Number.MAX_VALUE : 1 / ray.dir.y;\r\n\r\n const tx1 = (this.left - ray.pos.x) * xinv;\r\n const tx2 = (this.right - ray.pos.x) * xinv;\r\n tmin = Math.min(tx1, tx2);\r\n tmax = Math.max(tx1, tx2);\r\n\r\n const ty1 = (this.top - ray.pos.y) * yinv;\r\n const ty2 = (this.bottom - ray.pos.y) * yinv;\r\n tmin = Math.max(tmin, Math.min(ty1, ty2));\r\n tmax = Math.min(tmax, Math.max(ty1, ty2));\r\n\r\n if (tmax >= Math.max(0, tmin) && tmin < farClipDistance) {\r\n return tmin;\r\n }\r\n return -1;\r\n }\r\n\r\n /**\r\n * Tests whether a point is contained within the bounding box\r\n * @param p The point to test\r\n */\r\n public contains(p: Vector): boolean;\r\n\r\n /**\r\n * Tests whether another bounding box is totally contained in this one\r\n * @param bb The bounding box to test\r\n */\r\n public contains(bb: BoundingBox): boolean;\r\n public contains(val: any): boolean {\r\n if (val instanceof Vector) {\r\n return this.left <= val.x && this.top <= val.y && this.bottom >= val.y && this.right >= val.x;\r\n } else if (val instanceof BoundingBox) {\r\n if (this.left <= val.left && this.top <= val.top && val.bottom <= this.bottom && val.right <= this.right) {\r\n return true;\r\n }\r\n return false;\r\n }\r\n return false;\r\n }\r\n\r\n /**\r\n * Combines this bounding box and another together returning a new bounding box\r\n * @param other The bounding box to combine\r\n */\r\n public combine(other: BoundingBox): BoundingBox {\r\n const compositeBB = new BoundingBox(\r\n Math.min(this.left, other.left),\r\n Math.min(this.top, other.top),\r\n Math.max(this.right, other.right),\r\n Math.max(this.bottom, other.bottom)\r\n );\r\n return compositeBB;\r\n }\r\n\r\n public get dimensions(): Vector {\r\n return new Vector(this.width, this.height);\r\n }\r\n\r\n /**\r\n * Returns true if the bounding boxes overlap.\r\n * @param other\r\n * @param epsilon Optionally specify a small epsilon (default 0) as amount of overlap to ignore as overlap.\r\n * This epsilon is useful in stable collision simulations.\r\n */\r\n public overlaps(other: BoundingBox, epsilon?: number): boolean {\r\n const e = epsilon || 0;\r\n if (other.hasZeroDimensions()){\r\n return this.contains(other);\r\n }\r\n if (this.hasZeroDimensions()) {\r\n return other.contains(this);\r\n }\r\n const totalBoundingBox = this.combine(other);\r\n return totalBoundingBox.width + e < other.width + this.width &&\r\n totalBoundingBox.height + e < other.height + this.height;\r\n }\r\n\r\n /**\r\n * Test wether this bounding box intersects with another returning\r\n * the intersection vector that can be used to resolve the collision. If there\r\n * is no intersection null is returned.\r\n *\r\n * @param other Other [[BoundingBox]] to test intersection with\r\n * @returns A Vector in the direction of the current BoundingBox, this <- other\r\n */\r\n public intersect(other: BoundingBox): Vector {\r\n const totalBoundingBox = this.combine(other);\r\n\r\n // If the total bounding box is less than or equal the sum of the 2 bounds then there is collision\r\n if (\r\n totalBoundingBox.width < other.width + this.width &&\r\n totalBoundingBox.height < other.height + this.height &&\r\n !totalBoundingBox.dimensions.equals(other.dimensions) &&\r\n !totalBoundingBox.dimensions.equals(this.dimensions)\r\n ) {\r\n // collision\r\n let overlapX = 0;\r\n // right edge is between the other's left and right edge\r\n /**\r\n * +-this-+\r\n * | |\r\n * | +-other-+\r\n * +----|-+ |\r\n * | |\r\n * +-------+\r\n * <---\r\n * ^ overlap\r\n */\r\n if (this.right >= other.left && this.right <= other.right) {\r\n overlapX = other.left - this.right;\r\n // right edge is past the other's right edge\r\n /**\r\n * +-other-+\r\n * | |\r\n * | +-this-+\r\n * +----|--+ |\r\n * | |\r\n * +------+\r\n * --->\r\n * ^ overlap\r\n */\r\n } else {\r\n overlapX = other.right - this.left;\r\n }\r\n\r\n let overlapY = 0;\r\n // top edge is between the other's top and bottom edge\r\n /**\r\n * +-other-+\r\n * | |\r\n * | +-this-+ | <- overlap\r\n * +----|--+ | |\r\n * | | \\ /\r\n * +------+ '\r\n */\r\n if (this.top <= other.bottom && this.top >= other.top) {\r\n overlapY = other.bottom - this.top;\r\n // top edge is above the other top edge\r\n /**\r\n * +-this-+ .\r\n * | | / \\\r\n * | +-other-+ | <- overlap\r\n * +----|-+ | |\r\n * | |\r\n * +-------+\r\n */\r\n } else {\r\n overlapY = other.top - this.bottom;\r\n }\r\n\r\n if (Math.abs(overlapX) < Math.abs(overlapY)) {\r\n return new Vector(overlapX, 0);\r\n } else {\r\n return new Vector(0, overlapY);\r\n }\r\n // Case of total containment of one bounding box by another\r\n } else if (totalBoundingBox.dimensions.equals(other.dimensions) || totalBoundingBox.dimensions.equals(this.dimensions)) {\r\n let overlapX = 0;\r\n // this is wider than the other\r\n if (this.width - other.width >= 0) {\r\n // This right edge is closest to the others right edge\r\n if (this.right - other.right <= other.left - this.left) {\r\n overlapX = other.left - this.right;\r\n // This left edge is closest to the others left edge\r\n } else {\r\n overlapX = other.right - this.left;\r\n }\r\n // other is wider than this\r\n } else {\r\n // This right edge is closest to the others right edge\r\n if (other.right - this.right <= this.left - other.left) {\r\n overlapX = this.left - other.right;\r\n // This left edge is closest to the others left edge\r\n } else {\r\n overlapX = this.right - other.left;\r\n }\r\n }\r\n\r\n let overlapY = 0;\r\n // this is taller than other\r\n if (this.height - other.height >= 0) {\r\n // The bottom edge is closest to the others bottom edge\r\n if (this.bottom - other.bottom <= other.top - this.top) {\r\n overlapY = other.top - this.bottom;\r\n } else {\r\n overlapY = other.bottom - this.top;\r\n }\r\n // other is taller than this\r\n } else {\r\n // The bottom edge is closest to the others bottom edge\r\n if (other.bottom - this.bottom <= this.top - other.top) {\r\n overlapY = this.top - other.bottom;\r\n } else {\r\n overlapY = this.bottom - other.top;\r\n }\r\n }\r\n\r\n if (Math.abs(overlapX) < Math.abs(overlapY)) {\r\n return new Vector(overlapX, 0);\r\n } else {\r\n return new Vector(0, overlapY);\r\n }\r\n } else {\r\n return null;\r\n }\r\n }\r\n\r\n /**\r\n * Test whether the bounding box has intersected with another bounding box, returns the side of the current bb that intersected.\r\n * @param bb The other actor to test\r\n */\r\n public intersectWithSide(bb: BoundingBox): Side {\r\n const intersect = this.intersect(bb);\r\n return BoundingBox.getSideFromIntersection(intersect);\r\n }\r\n\r\n /**\r\n * Draw a debug bounding box\r\n * @param ex\r\n * @param color\r\n */\r\n public draw(ex: ExcaliburGraphicsContext, color: Color = Color.Yellow) {\r\n ex.debug.drawRect(this.left, this.top, this.width, this.height, { color });\r\n }\r\n}\r\n","\r\n/**\r\n * Future is a wrapper around a native browser Promise to allow resolving/rejecting at any time\r\n */\r\nexport class Future {\r\n // Code from StephenCleary https://gist.github.com/StephenCleary/ba50b2da419c03b9cba1d20cb4654d5e\r\n private _resolver: (value: T) => void;\r\n private _rejecter: (error: Error) => void;\r\n private _isCompleted: boolean = false;\r\n\r\n constructor() {\r\n this.promise = new Promise((resolve, reject) => {\r\n this._resolver = resolve;\r\n this._rejecter = reject;\r\n });\r\n }\r\n\r\n public readonly promise: Promise;\r\n\r\n public get isCompleted(): boolean {\r\n return this._isCompleted;\r\n }\r\n\r\n public resolve(value: T): void {\r\n if (this._isCompleted) {\r\n return;\r\n }\r\n this._isCompleted = true;\r\n this._resolver(value);\r\n }\r\n\r\n public reject(error: Error): void {\r\n if (this._isCompleted) {\r\n return;\r\n }\r\n this._isCompleted = true;\r\n this._rejecter(error);\r\n }\r\n}","import { Vector } from '../Math/vector';\r\nimport { Clock } from './Clock';\r\nimport { Future } from './Future';\r\n\r\n/**\r\n * Find the screen position of an HTML element\r\n */\r\nexport function getPosition(el: HTMLElement): Vector {\r\n let oLeft: number = 0,\r\n oTop: number = 0;\r\n\r\n const calcOffsetLeft = (parent: HTMLElement) => {\r\n oLeft += parent.offsetLeft;\r\n\r\n if (parent.offsetParent) {\r\n calcOffsetLeft(parent.offsetParent);\r\n }\r\n };\r\n const calcOffsetTop = (parent: HTMLElement) => {\r\n oTop += parent.offsetTop;\r\n if (parent.offsetParent) {\r\n calcOffsetTop(parent.offsetParent);\r\n }\r\n };\r\n\r\n calcOffsetLeft(el);\r\n calcOffsetTop(el);\r\n\r\n return new Vector(oLeft, oTop);\r\n}\r\n\r\n/**\r\n * Add an item to an array list if it doesn't already exist. Returns true if added, false if not and already exists in the array.\r\n * @deprecated Will be removed in v0.26.0\r\n */\r\nexport function addItemToArray(item: T, array: T[]): boolean {\r\n if (array.indexOf(item) === -1) {\r\n array.push(item);\r\n return true;\r\n }\r\n return false;\r\n}\r\n\r\n/**\r\n * Remove an item from an list\r\n * @deprecated Will be removed in v0.26.0\r\n */\r\nexport function removeItemFromArray(item: T, array: T[]): boolean {\r\n let index = -1;\r\n if ((index = array.indexOf(item)) > -1) {\r\n array.splice(index, 1);\r\n return true;\r\n }\r\n\r\n return false;\r\n}\r\n\r\n/**\r\n * See if an array contains something\r\n */\r\nexport function contains(array: Array, obj: any): boolean {\r\n for (let i = 0; i < array.length; i++) {\r\n if (array[i] === obj) {\r\n return true;\r\n }\r\n }\r\n return false;\r\n}\r\n\r\n/**\r\n * Used for exhaustive checks at compile time\r\n */\r\nexport function fail(message: never): never {\r\n throw new Error(message);\r\n}\r\n\r\n/**\r\n * Create a promise that resolves after a certain number of milliseconds\r\n *\r\n * It is strongly recommended you pass the excalibur clock so delays are bound to the\r\n * excalibur clock which would be unaffected by stop/pause.\r\n * @param milliseconds\r\n * @param clock\r\n */\r\nexport function delay(milliseconds: number, clock?: Clock): Promise {\r\n const future = new Future();\r\n const schedule = clock?.schedule.bind(clock) ?? setTimeout;\r\n schedule(() => {\r\n future.resolve();\r\n }, milliseconds);\r\n return future.promise;\r\n}\r\n","import { sign } from './util';\r\nimport { Vector, vec } from './vector';\r\nimport { canonicalizeAngle } from './util';\r\n\r\nexport enum MatrixLocations {\r\n X = 12,\r\n Y = 13\r\n}\r\n\r\n/**\r\n * Excalibur Matrix helper for 4x4 matrices\r\n *\r\n * Useful for webgl 4x4 matrices\r\n */\r\nexport class Matrix {\r\n /**\r\n * 4x4 matrix in column major order\r\n *\r\n * | | | | |\r\n * | ------- | ------- | -------- | -------- |\r\n * | data[0] | data[4] | data[8] | data[12] |\r\n * | data[1] | data[5] | data[9] | data[13] |\r\n * | data[2] | data[6] | data[10] | data[14] |\r\n * | data[3] | data[7] | data[11] | data[15] |\r\n *\r\n */\r\n public data: Float32Array = new Float32Array(16);\r\n\r\n /**\r\n * Creates an orthographic (flat non-perspective) projection\r\n * https://en.wikipedia.org/wiki/Orthographic_projection\r\n * @param left\r\n * @param right\r\n * @param bottom\r\n * @param top\r\n * @param near\r\n * @param far\r\n */\r\n public static ortho(left: number, right: number, bottom: number, top: number, near: number, far: number): Matrix {\r\n const mat = new Matrix();\r\n mat.data[0] = 2 / (right - left);\r\n mat.data[1] = 0;\r\n mat.data[2] = 0;\r\n mat.data[3] = 0;\r\n\r\n mat.data[4] = 0;\r\n mat.data[5] = 2 / (top - bottom);\r\n mat.data[6] = 0;\r\n mat.data[7] = 0;\r\n\r\n mat.data[8] = 0;\r\n mat.data[9] = 0;\r\n mat.data[10] = -2 / (far - near);\r\n mat.data[11] = 0;\r\n\r\n mat.data[12] = -(right + left) / (right - left);\r\n mat.data[13] = -(top + bottom) / (top - bottom);\r\n mat.data[14] = -(far + near) / (far - near);\r\n mat.data[15] = 1;\r\n return mat;\r\n }\r\n\r\n /**\r\n * Creates a new Matrix with the same data as the current 4x4\r\n */\r\n public clone(dest?: Matrix): Matrix {\r\n const mat = dest || new Matrix();\r\n mat.data[0] = this.data[0];\r\n mat.data[1] = this.data[1];\r\n mat.data[2] = this.data[2];\r\n mat.data[3] = this.data[3];\r\n\r\n mat.data[4] = this.data[4];\r\n mat.data[5] = this.data[5];\r\n mat.data[6] = this.data[6];\r\n mat.data[7] = this.data[7];\r\n\r\n mat.data[8] = this.data[8];\r\n mat.data[9] = this.data[9];\r\n mat.data[10] = this.data[10];\r\n mat.data[11] = this.data[11];\r\n\r\n mat.data[12] = this.data[12];\r\n mat.data[13] = this.data[13];\r\n mat.data[14] = this.data[14];\r\n mat.data[15] = this.data[15];\r\n return mat;\r\n }\r\n\r\n /**\r\n * Converts the current matrix into a DOMMatrix\r\n *\r\n * This is useful when working with the browser Canvas context\r\n * @returns {DOMMatrix} DOMMatrix\r\n */\r\n public toDOMMatrix(): DOMMatrix {\r\n return new DOMMatrix([...this.data]);\r\n }\r\n\r\n public static fromFloat32Array(data: Float32Array) {\r\n const matrix = new Matrix();\r\n matrix.data = data;\r\n return matrix;\r\n }\r\n\r\n /**\r\n * Creates a new identity matrix (a matrix that when applied does nothing)\r\n */\r\n public static identity(): Matrix {\r\n const mat = new Matrix();\r\n mat.data[0] = 1;\r\n mat.data[1] = 0;\r\n mat.data[2] = 0;\r\n mat.data[3] = 0;\r\n\r\n mat.data[4] = 0;\r\n mat.data[5] = 1;\r\n mat.data[6] = 0;\r\n mat.data[7] = 0;\r\n\r\n mat.data[8] = 0;\r\n mat.data[9] = 0;\r\n mat.data[10] = 1;\r\n mat.data[11] = 0;\r\n\r\n mat.data[12] = 0;\r\n mat.data[13] = 0;\r\n mat.data[14] = 0;\r\n mat.data[15] = 1;\r\n return mat;\r\n }\r\n\r\n /**\r\n * Resets the current matrix to the identity matrix, mutating it\r\n * @returns {Matrix} Current matrix as identity\r\n */\r\n public reset(): Matrix {\r\n const mat = this;\r\n mat.data[0] = 1;\r\n mat.data[1] = 0;\r\n mat.data[2] = 0;\r\n mat.data[3] = 0;\r\n\r\n mat.data[4] = 0;\r\n mat.data[5] = 1;\r\n mat.data[6] = 0;\r\n mat.data[7] = 0;\r\n\r\n mat.data[8] = 0;\r\n mat.data[9] = 0;\r\n mat.data[10] = 1;\r\n mat.data[11] = 0;\r\n\r\n mat.data[12] = 0;\r\n mat.data[13] = 0;\r\n mat.data[14] = 0;\r\n mat.data[15] = 1;\r\n return mat;\r\n }\r\n\r\n /**\r\n * Creates a brand new translation matrix at the specified 3d point\r\n * @param x\r\n * @param y\r\n */\r\n public static translation(x: number, y: number): Matrix {\r\n const mat = Matrix.identity();\r\n mat.data[12] = x;\r\n mat.data[13] = y;\r\n return mat;\r\n }\r\n\r\n /**\r\n * Creates a brand new scaling matrix with the specified scaling factor\r\n * @param sx\r\n * @param sy\r\n */\r\n public static scale(sx: number, sy: number): Matrix {\r\n const mat = Matrix.identity();\r\n mat.data[0] = sx;\r\n mat.data[5] = sy;\r\n mat.data[10] = 1;\r\n mat.data[15] = 1;\r\n return mat;\r\n }\r\n\r\n /**\r\n * Creates a brand new rotation matrix with the specified angle\r\n * @param angleRadians\r\n */\r\n public static rotation(angleRadians: number): Matrix {\r\n const mat = Matrix.identity();\r\n mat.data[0] = Math.cos(angleRadians);\r\n mat.data[4] = -Math.sin(angleRadians);\r\n mat.data[1] = Math.sin(angleRadians);\r\n mat.data[5] = Math.cos(angleRadians);\r\n return mat;\r\n }\r\n\r\n /**\r\n * Multiply the current matrix by a vector producing a new vector\r\n * @param vector\r\n * @param dest\r\n */\r\n multiply(vector: Vector, dest?: Vector): Vector;\r\n /**\r\n * Multiply the current matrix by another matrix producing a new matrix\r\n * @param matrix\r\n * @param dest\r\n */\r\n multiply(matrix: Matrix, dest?: Matrix): Matrix;\r\n multiply(vectorOrMatrix: Vector | Matrix, dest?: Vector | Matrix): Vector | Matrix {\r\n if (vectorOrMatrix instanceof Vector) {\r\n const result = (dest as Vector) || new Vector(0, 0);\r\n const vector = vectorOrMatrix;\r\n // these shenanigans are to allow dest and vector to be the same instance\r\n const resultX = vector.x * this.data[0] + vector.y * this.data[4] + this.data[12];\r\n const resultY = vector.x * this.data[1] + vector.y * this.data[5] + this.data[13];\r\n\r\n result.x = resultX;\r\n result.y = resultY;\r\n return result;\r\n } else {\r\n const result = (dest as Matrix) || new Matrix();\r\n const other = vectorOrMatrix;\r\n const a11 = this.data[0];\r\n const a21 = this.data[1];\r\n const a31 = this.data[2];\r\n const a41 = this.data[3];\r\n\r\n const a12 = this.data[4];\r\n const a22 = this.data[5];\r\n const a32 = this.data[6];\r\n const a42 = this.data[7];\r\n\r\n const a13 = this.data[8];\r\n const a23 = this.data[9];\r\n const a33 = this.data[10];\r\n const a43 = this.data[11];\r\n\r\n const a14 = this.data[12];\r\n const a24 = this.data[13];\r\n const a34 = this.data[14];\r\n const a44 = this.data[15];\r\n\r\n const b11 = other.data[0];\r\n const b21 = other.data[1];\r\n const b31 = other.data[2];\r\n const b41 = other.data[3];\r\n\r\n const b12 = other.data[4];\r\n const b22 = other.data[5];\r\n const b32 = other.data[6];\r\n const b42 = other.data[7];\r\n\r\n const b13 = other.data[8];\r\n const b23 = other.data[9];\r\n const b33 = other.data[10];\r\n const b43 = other.data[11];\r\n\r\n const b14 = other.data[12];\r\n const b24 = other.data[13];\r\n const b34 = other.data[14];\r\n const b44 = other.data[15];\r\n\r\n result.data[0] = a11 * b11 + a12 * b21 + a13 * b31 + a14 * b41;\r\n result.data[1] = a21 * b11 + a22 * b21 + a23 * b31 + a24 * b41;\r\n result.data[2] = a31 * b11 + a32 * b21 + a33 * b31 + a34 * b41;\r\n result.data[3] = a41 * b11 + a42 * b21 + a43 * b31 + a44 * b41;\r\n\r\n result.data[4] = a11 * b12 + a12 * b22 + a13 * b32 + a14 * b42;\r\n result.data[5] = a21 * b12 + a22 * b22 + a23 * b32 + a24 * b42;\r\n result.data[6] = a31 * b12 + a32 * b22 + a33 * b32 + a34 * b42;\r\n result.data[7] = a41 * b12 + a42 * b22 + a43 * b32 + a44 * b42;\r\n\r\n result.data[8] = a11 * b13 + a12 * b23 + a13 * b33 + a14 * b43;\r\n result.data[9] = a21 * b13 + a22 * b23 + a23 * b33 + a24 * b43;\r\n result.data[10] = a31 * b13 + a32 * b23 + a33 * b33 + a34 * b43;\r\n result.data[11] = a41 * b13 + a42 * b23 + a43 * b33 + a44 * b43;\r\n\r\n result.data[12] = a11 * b14 + a12 * b24 + a13 * b34 + a14 * b44;\r\n result.data[13] = a21 * b14 + a22 * b24 + a23 * b34 + a24 * b44;\r\n result.data[14] = a31 * b14 + a32 * b24 + a33 * b34 + a34 * b44;\r\n result.data[15] = a41 * b14 + a42 * b24 + a43 * b34 + a44 * b44;\r\n\r\n const s = this.getScale();\r\n result._scaleSignX = sign(s.x) * sign(result._scaleSignX);\r\n result._scaleSignY = sign(s.y) * sign(result._scaleSignY);\r\n\r\n return result;\r\n }\r\n }\r\n\r\n\r\n /**\r\n * Applies translation to the current matrix mutating it\r\n * @param x\r\n * @param y\r\n */\r\n translate(x: number, y: number) {\r\n const a11 = this.data[0];\r\n const a21 = this.data[1];\r\n const a31 = this.data[2];\r\n const a41 = this.data[3];\r\n\r\n const a12 = this.data[4];\r\n const a22 = this.data[5];\r\n const a32 = this.data[6];\r\n const a42 = this.data[7];\r\n\r\n const a13 = this.data[8];\r\n const a23 = this.data[9];\r\n const a33 = this.data[10];\r\n const a43 = this.data[11];\r\n\r\n const a14 = this.data[12];\r\n const a24 = this.data[13];\r\n const a34 = this.data[14];\r\n const a44 = this.data[15];\r\n\r\n // Doesn't change z\r\n const z = 0;\r\n const w = 1;\r\n this.data[12] = a11 * x + a12 * y + a13 * z + a14 * w;\r\n this.data[13] = a21 * x + a22 * y + a23 * z + a24 * w;\r\n this.data[14] = a31 * x + a32 * y + a33 * z + a34 * w;\r\n this.data[15] = a41 * x + a42 * y + a43 * z + a44 * w;\r\n\r\n return this;\r\n }\r\n\r\n public setPosition(x: number, y: number) {\r\n this.data[12] = x;\r\n this.data[13] = y;\r\n }\r\n\r\n public getPosition(): Vector {\r\n return vec(this.data[12], this.data[13]);\r\n }\r\n\r\n /**\r\n * Applies rotation to the current matrix mutating it\r\n * @param angle in Radians\r\n */\r\n rotate(angle: number) {\r\n const a11 = this.data[0];\r\n const a21 = this.data[1];\r\n const a31 = this.data[2];\r\n const a41 = this.data[3];\r\n\r\n const a12 = this.data[4];\r\n const a22 = this.data[5];\r\n const a32 = this.data[6];\r\n const a42 = this.data[7];\r\n\r\n const sine = Math.sin(angle);\r\n const cosine = Math.cos(angle);\r\n\r\n this.data[0] = cosine * a11 + sine * a12;\r\n this.data[1] = cosine * a21 + sine * a22;\r\n this.data[2] = cosine * a31 + sine * a32;\r\n this.data[3] = cosine * a41 + sine * a42;\r\n\r\n this.data[4] = cosine * a12 - sine * a11;\r\n this.data[5] = cosine * a22 - sine * a21;\r\n this.data[6] = cosine * a32 - sine * a31;\r\n this.data[7] = cosine * a42 - sine * a41;\r\n\r\n return this;\r\n }\r\n\r\n /**\r\n * Applies scaling to the current matrix mutating it\r\n * @param x\r\n * @param y\r\n */\r\n scale(x: number, y: number) {\r\n const a11 = this.data[0];\r\n const a21 = this.data[1];\r\n const a31 = this.data[2];\r\n const a41 = this.data[3];\r\n\r\n const a12 = this.data[4];\r\n const a22 = this.data[5];\r\n const a32 = this.data[6];\r\n const a42 = this.data[7];\r\n\r\n this.data[0] = a11 * x;\r\n this.data[1] = a21 * x;\r\n this.data[2] = a31 * x;\r\n this.data[3] = a41 * x;\r\n\r\n this.data[4] = a12 * y;\r\n this.data[5] = a22 * y;\r\n this.data[6] = a32 * y;\r\n this.data[7] = a42 * y;\r\n\r\n return this;\r\n }\r\n\r\n public setRotation(angle: number) {\r\n const currentScale = this.getScale();\r\n const sine = Math.sin(angle);\r\n const cosine = Math.cos(angle);\r\n\r\n this.data[0] = cosine * currentScale.x;\r\n this.data[1] = sine * currentScale.y;\r\n this.data[4] = -sine * currentScale.x;\r\n this.data[5] = cosine * currentScale.y;\r\n }\r\n\r\n public getRotation(): number {\r\n const angle = Math.atan2(this.data[1] / this.getScaleY(), this.data[0] / this.getScaleX());\r\n return canonicalizeAngle(angle);\r\n }\r\n\r\n public getScaleX(): number {\r\n // absolute scale of the matrix (we lose sign so need to add it back)\r\n const xscale = vec(this.data[0], this.data[4]).size;\r\n return this._scaleSignX * xscale;\r\n }\r\n\r\n public getScaleY(): number {\r\n // absolute scale of the matrix (we lose sign so need to add it back)\r\n const yscale = vec(this.data[1], this.data[5]).size;\r\n return this._scaleSignY * yscale;\r\n }\r\n\r\n /**\r\n * Get the scale of the matrix\r\n */\r\n public getScale(): Vector {\r\n return vec(this.getScaleX(), this.getScaleY());\r\n }\r\n\r\n private _scaleX = 1;\r\n private _scaleSignX = 1;\r\n public setScaleX(val: number) {\r\n if (this._scaleX === val) {\r\n return;\r\n }\r\n\r\n this._scaleSignX = sign(val);\r\n // negative scale acts like a 180 rotation, so flip\r\n const xscale = vec(this.data[0] * this._scaleSignX, this.data[4] * this._scaleSignX).normalize();\r\n this.data[0] = xscale.x * val;\r\n this.data[4] = xscale.y * val;\r\n this._scaleX = val;\r\n }\r\n\r\n private _scaleY = 1;\r\n private _scaleSignY = 1;\r\n public setScaleY(val: number) {\r\n if (this._scaleY === val) {\r\n return;\r\n }\r\n this._scaleSignY = sign(val);\r\n // negative scale acts like a 180 rotation, so flip\r\n const yscale = vec(this.data[1] * this._scaleSignY, this.data[5] * this._scaleSignY).normalize();\r\n this.data[1] = yscale.x * val;\r\n this.data[5] = yscale.y * val;\r\n this._scaleY = val;\r\n }\r\n\r\n public setScale(scale: Vector) {\r\n this.setScaleX(scale.x);\r\n this.setScaleY(scale.y);\r\n }\r\n\r\n /**\r\n * Determinant of the upper left 2x2 matrix\r\n */\r\n public getBasisDeterminant() {\r\n return this.data[0] * this.data[5] - this.data[1] * this.data[4];\r\n }\r\n\r\n /**\r\n * Return the affine inverse, optionally store it in a target matrix.\r\n *\r\n * It's recommended you call .reset() the target unless you know what you're doing\r\n * @param target\r\n */\r\n public getAffineInverse(target?: Matrix): Matrix {\r\n // See http://negativeprobability.blogspot.com/2011/11/affine-transformations-and-their.html\r\n // See https://www.mathsisfun.com/algebra/matrix-inverse.html\r\n // Since we are actually only doing 2D transformations we can use this hack\r\n // We don't actually use the 3rd or 4th dimension\r\n\r\n const det = this.getBasisDeterminant();\r\n const inverseDet = 1 / det; // todo zero check\r\n const a = this.data[0];\r\n const b = this.data[4];\r\n const c = this.data[1];\r\n const d = this.data[5];\r\n\r\n const m = target || Matrix.identity();\r\n // inverts rotation and scale\r\n m.data[0] = d * inverseDet;\r\n m.data[1] = -c * inverseDet;\r\n m.data[4] = -b * inverseDet;\r\n m.data[5] = a * inverseDet;\r\n\r\n const tx = this.data[12];\r\n const ty = this.data[13];\r\n // invert translation\r\n // transform translation into the matrix basis created by rot/scale\r\n m.data[12] = -(tx * m.data[0] + ty * m.data[4]);\r\n m.data[13] = -(tx * m.data[1] + ty * m.data[5]);\r\n\r\n return m;\r\n }\r\n\r\n public isIdentity(): boolean {\r\n return (\r\n this.data[0] === 1 &&\r\n this.data[1] === 0 &&\r\n this.data[2] === 0 &&\r\n this.data[3] === 0 &&\r\n this.data[4] === 0 &&\r\n this.data[5] === 1 &&\r\n this.data[6] === 0 &&\r\n this.data[7] === 0 &&\r\n this.data[8] === 0 &&\r\n this.data[9] === 0 &&\r\n this.data[10] === 1 &&\r\n this.data[11] === 0 &&\r\n this.data[12] === 0 &&\r\n this.data[13] === 0 &&\r\n this.data[14] === 0 &&\r\n this.data[15] === 1\r\n );\r\n }\r\n\r\n public toString() {\r\n return `\r\n[${this.data[0]} ${this.data[4]} ${this.data[8]} ${this.data[12]}]\r\n[${this.data[1]} ${this.data[5]} ${this.data[9]} ${this.data[13]}]\r\n[${this.data[2]} ${this.data[6]} ${this.data[10]} ${this.data[14]}]\r\n[${this.data[3]} ${this.data[7]} ${this.data[11]} ${this.data[15]}]\r\n`;\r\n }\r\n}\r\n","import { Matrix } from './matrix';\r\nimport { canonicalizeAngle, sign } from './util';\r\nimport { vec, Vector } from './vector';\r\n\r\n\r\nexport class AffineMatrix {\r\n /**\r\n * | | | |\r\n * | ------- | ------- | -------- |\r\n * | data[0] | data[2] | data[4] |\r\n * | data[1] | data[3] | data[5] |\r\n * | 0 | 0 | 1 |\r\n */\r\n public data = new Float64Array(6);\r\n\r\n /**\r\n * Converts the current matrix into a DOMMatrix\r\n *\r\n * This is useful when working with the browser Canvas context\r\n * @returns {DOMMatrix} DOMMatrix\r\n */\r\n public toDOMMatrix(): DOMMatrix {\r\n return new DOMMatrix([...this.data]);\r\n }\r\n\r\n public static identity(): AffineMatrix {\r\n const mat = new AffineMatrix();\r\n mat.data[0] = 1;\r\n mat.data[1] = 0;\r\n\r\n mat.data[2] = 0;\r\n mat.data[3] = 1;\r\n\r\n mat.data[4] = 0;\r\n mat.data[5] = 0;\r\n return mat;\r\n }\r\n\r\n /**\r\n * Creates a brand new translation matrix at the specified 3d point\r\n * @param x\r\n * @param y\r\n */\r\n public static translation(x: number, y: number): AffineMatrix {\r\n const mat = AffineMatrix.identity();\r\n mat.data[4] = x;\r\n mat.data[5] = y;\r\n return mat;\r\n }\r\n\r\n /**\r\n * Creates a brand new scaling matrix with the specified scaling factor\r\n * @param sx\r\n * @param sy\r\n */\r\n public static scale(sx: number, sy: number): AffineMatrix {\r\n const mat = AffineMatrix.identity();\r\n mat.data[0] = sx;\r\n mat.data[3] = sy;\r\n mat._scale[0] = sx;\r\n mat._scale[1] = sy;\r\n return mat;\r\n }\r\n\r\n /**\r\n * Creates a brand new rotation matrix with the specified angle\r\n * @param angleRadians\r\n */\r\n public static rotation(angleRadians: number): AffineMatrix {\r\n const mat = AffineMatrix.identity();\r\n mat.data[0] = Math.cos(angleRadians);\r\n mat.data[1] = Math.sin(angleRadians);\r\n mat.data[2] = -Math.sin(angleRadians);\r\n mat.data[3] = Math.cos(angleRadians);\r\n return mat;\r\n }\r\n\r\n public setPosition(x: number, y: number) {\r\n this.data[4] = x;\r\n this.data[5] = y;\r\n }\r\n\r\n public getPosition(): Vector {\r\n return vec(this.data[4], this.data[5]);\r\n }\r\n\r\n /**\r\n * Applies rotation to the current matrix mutating it\r\n * @param angle in Radians\r\n */\r\n rotate(angle: number) {\r\n const a11 = this.data[0];\r\n const a21 = this.data[1];\r\n\r\n const a12 = this.data[2];\r\n const a22 = this.data[3];\r\n\r\n const sine = Math.sin(angle);\r\n const cosine = Math.cos(angle);\r\n\r\n this.data[0] = cosine * a11 + sine * a12;\r\n this.data[1] = cosine * a21 + sine * a22;\r\n\r\n this.data[2] = cosine * a12 - sine * a11;\r\n this.data[3] = cosine * a22 - sine * a21;\r\n\r\n return this;\r\n }\r\n\r\n /**\r\n * Applies translation to the current matrix mutating it\r\n * @param x\r\n * @param y\r\n */\r\n translate(x: number, y: number) {\r\n const a11 = this.data[0];\r\n const a21 = this.data[1];\r\n // const a31 = 0;\r\n\r\n const a12 = this.data[2];\r\n const a22 = this.data[3];\r\n // const a32 = 0;\r\n\r\n const a13 = this.data[4];\r\n const a23 = this.data[5];\r\n // const a33 = 1;\r\n\r\n // Doesn't change z\r\n this.data[4] = a11 * x + a12 * y + a13;\r\n this.data[5] = a21 * x + a22 * y + a23;\r\n\r\n return this;\r\n }\r\n\r\n /**\r\n * Applies scaling to the current matrix mutating it\r\n * @param x\r\n * @param y\r\n */\r\n scale(x: number, y: number) {\r\n const a11 = this.data[0];\r\n const a21 = this.data[1];\r\n\r\n const a12 = this.data[2];\r\n const a22 = this.data[3];\r\n\r\n this.data[0] = a11 * x;\r\n this.data[1] = a21 * x;\r\n\r\n this.data[2] = a12 * y;\r\n this.data[3] = a22 * y;\r\n\r\n this._scale[0] = x;\r\n this._scale[1] = y;\r\n return this;\r\n }\r\n\r\n public determinant() {\r\n return this.data[0] * this.data[3] - this.data[1] * this.data[2];\r\n }\r\n\r\n /**\r\n * Return the affine inverse, optionally store it in a target matrix.\r\n *\r\n * It's recommended you call .reset() the target unless you know what you're doing\r\n * @param target\r\n */\r\n public inverse(target?: AffineMatrix): AffineMatrix {\r\n // See http://negativeprobability.blogspot.com/2011/11/affine-transformations-and-their.html\r\n // See https://www.mathsisfun.com/algebra/matrix-inverse.html\r\n // Since we are actually only doing 2D transformations we can use this hack\r\n // We don't actually use the 3rd or 4th dimension\r\n\r\n const det = this.determinant();\r\n const inverseDet = 1 / det; // TODO zero check\r\n const a = this.data[0];\r\n const b = this.data[2];\r\n const c = this.data[1];\r\n const d = this.data[3];\r\n\r\n const m = target || AffineMatrix.identity();\r\n // inverts rotation and scale\r\n m.data[0] = d * inverseDet;\r\n m.data[1] = -c * inverseDet;\r\n m.data[2] = -b * inverseDet;\r\n m.data[3] = a * inverseDet;\r\n\r\n const tx = this.data[4];\r\n const ty = this.data[5];\r\n // invert translation\r\n // transform translation into the matrix basis created by rot/scale\r\n m.data[4] = -(tx * m.data[0] + ty * m.data[2]);\r\n m.data[5] = -(tx * m.data[1] + ty * m.data[3]);\r\n\r\n return m;\r\n }\r\n\r\n /**\r\n * Multiply the current matrix by a vector producing a new vector\r\n * @param vector\r\n * @param dest\r\n */\r\n multiply(vector: Vector, dest?: Vector): Vector;\r\n /**\r\n * Multiply the current matrix by another matrix producing a new matrix\r\n * @param matrix\r\n * @param dest\r\n */\r\n multiply(matrix: AffineMatrix, dest?: AffineMatrix): AffineMatrix;\r\n multiply(vectorOrMatrix: Vector | AffineMatrix, dest?: Vector | AffineMatrix): Vector | AffineMatrix {\r\n if (vectorOrMatrix instanceof Vector) {\r\n const result = (dest as Vector) || new Vector(0, 0);\r\n const vector = vectorOrMatrix;\r\n // these shenanigans are to allow dest and vector to be the same instance\r\n const resultX = vector.x * this.data[0] + vector.y * this.data[2] + this.data[4];\r\n const resultY = vector.x * this.data[1] + vector.y * this.data[3] + this.data[5];\r\n\r\n result.x = resultX;\r\n result.y = resultY;\r\n return result;\r\n } else {\r\n const result = (dest as AffineMatrix) || new AffineMatrix();\r\n const other = vectorOrMatrix;\r\n const a11 = this.data[0];\r\n const a21 = this.data[1];\r\n // const a31 = 0;\r\n\r\n const a12 = this.data[2];\r\n const a22 = this.data[3];\r\n // const a32 = 0;\r\n\r\n const a13 = this.data[4];\r\n const a23 = this.data[5];\r\n // const a33 = 1;\r\n\r\n const b11 = other.data[0];\r\n const b21 = other.data[1];\r\n // const b31 = 0;\r\n\r\n const b12 = other.data[2];\r\n const b22 = other.data[3];\r\n // const b32 = 0;\r\n\r\n const b13 = other.data[4];\r\n const b23 = other.data[5];\r\n // const b33 = 1;\r\n\r\n\r\n result.data[0] = a11 * b11 + a12 * b21;// + a13 * b31; // zero\r\n result.data[1] = a21 * b11 + a22 * b21;// + a23 * b31; // zero\r\n\r\n result.data[2] = a11 * b12 + a12 * b22;// + a13 * b32; // zero\r\n result.data[3] = a21 * b12 + a22 * b22;// + a23 * b32; // zero\r\n\r\n result.data[4] = a11 * b13 + a12 * b23 + a13;// * b33; // one\r\n result.data[5] = a21 * b13 + a22 * b23 + a23;// * b33; // one\r\n\r\n const s = this.getScale();\r\n result._scaleSignX = sign(s.x) * sign(result._scaleSignX);\r\n result._scaleSignY = sign(s.y) * sign(result._scaleSignY);\r\n\r\n return result;\r\n }\r\n }\r\n\r\n to4x4() {\r\n const mat = new Matrix();\r\n mat.data[0] = this.data[0];\r\n mat.data[1] = this.data[1];\r\n mat.data[2] = 0;\r\n mat.data[3] = 0;\r\n\r\n mat.data[4] = this.data[2];\r\n mat.data[5] = this.data[3];\r\n mat.data[6] = 0;\r\n mat.data[7] = 0;\r\n\r\n mat.data[8] = 0;\r\n mat.data[9] = 0;\r\n mat.data[10] = 1;\r\n mat.data[11] = 0;\r\n\r\n mat.data[12] = this.data[4];\r\n mat.data[13] = this.data[5];\r\n mat.data[14] = 0;\r\n mat.data[15] = 1;\r\n return mat;\r\n }\r\n\r\n public setRotation(angle: number) {\r\n const currentScale = this.getScale();\r\n const sine = Math.sin(angle);\r\n const cosine = Math.cos(angle);\r\n\r\n this.data[0] = cosine * currentScale.x;\r\n this.data[1] = sine * currentScale.y;\r\n this.data[2] = -sine * currentScale.x;\r\n this.data[3] = cosine * currentScale.y;\r\n }\r\n\r\n public getRotation(): number {\r\n const angle = Math.atan2(this.data[1] / this.getScaleY(), this.data[0] / this.getScaleX());\r\n return canonicalizeAngle(angle);\r\n }\r\n\r\n public getScaleX(): number {\r\n // absolute scale of the matrix (we lose sign so need to add it back)\r\n const xscale = vec(this.data[0], this.data[2]).distance();\r\n return this._scaleSignX * xscale;\r\n }\r\n\r\n public getScaleY(): number {\r\n // absolute scale of the matrix (we lose sign so need to add it back)\r\n const yscale = vec(this.data[1], this.data[3]).distance();\r\n return this._scaleSignY * yscale;\r\n }\r\n\r\n /**\r\n * Get the scale of the matrix\r\n */\r\n public getScale(): Vector {\r\n return vec(this.getScaleX(), this.getScaleY());\r\n }\r\n\r\n private _scale = new Float64Array([1, 1]);\r\n private _scaleSignX = 1;\r\n public setScaleX(val: number) {\r\n if (val === this._scale[0]) {\r\n return;\r\n }\r\n this._scaleSignX = sign(val);\r\n // negative scale acts like a 180 rotation, so flip\r\n const xscale = vec(this.data[0] * this._scaleSignX, this.data[2] * this._scaleSignX).normalize();\r\n this.data[0] = xscale.x * val;\r\n this.data[2] = xscale.y * val;\r\n this._scale[0] = val;\r\n }\r\n\r\n private _scaleSignY = 1;\r\n public setScaleY(val: number) {\r\n if (val === this._scale[1]) {\r\n return;\r\n }\r\n this._scaleSignY = sign(val);\r\n // negative scale acts like a 180 rotation, so flip\r\n const yscale = vec(this.data[1] * this._scaleSignY, this.data[3] * this._scaleSignY).normalize();\r\n this.data[1] = yscale.x * val;\r\n this.data[3] = yscale.y * val;\r\n this._scale[1] = val;\r\n }\r\n\r\n public setScale(scale: Vector) {\r\n this.setScaleX(scale.x);\r\n this.setScaleY(scale.y);\r\n }\r\n\r\n public isIdentity(): boolean {\r\n return (\r\n this.data[0] === 1 &&\r\n this.data[1] === 0 &&\r\n this.data[2] === 0 &&\r\n this.data[3] === 1 &&\r\n this.data[4] === 0 &&\r\n this.data[5] === 0\r\n );\r\n }\r\n\r\n /**\r\n * Resets the current matrix to the identity matrix, mutating it\r\n * @returns {AffineMatrix} Current matrix as identity\r\n */\r\n public reset(): AffineMatrix {\r\n const mat = this;\r\n mat.data[0] = 1;\r\n mat.data[1] = 0;\r\n\r\n mat.data[2] = 0;\r\n mat.data[3] = 1;\r\n\r\n mat.data[4] = 0;\r\n mat.data[5] = 0;\r\n return mat;\r\n }\r\n\r\n /**\r\n * Creates a new Matrix with the same data as the current 4x4\r\n */\r\n public clone(dest?: AffineMatrix): AffineMatrix {\r\n const mat = dest || new AffineMatrix();\r\n mat.data[0] = this.data[0];\r\n mat.data[1] = this.data[1];\r\n\r\n mat.data[2] = this.data[2];\r\n mat.data[3] = this.data[3];\r\n\r\n mat.data[4] = this.data[4];\r\n mat.data[5] = this.data[5];\r\n return mat;\r\n }\r\n\r\n public toString() {\r\n return `\r\n[${this.data[0]} ${this.data[2]} ${this.data[4]}]\r\n[${this.data[1]} ${this.data[3]} ${this.data[5]}]\r\n[0 0 1]\r\n`;\r\n }\r\n\r\n}","import { AffineMatrix } from '../../Math/affine-matrix';\r\n\r\nexport class TransformStack {\r\n private _transforms: AffineMatrix[] = [];\r\n private _currentTransform: AffineMatrix = AffineMatrix.identity();\r\n\r\n public save(): void {\r\n this._transforms.push(this._currentTransform);\r\n this._currentTransform = this._currentTransform.clone();\r\n }\r\n\r\n public restore(): void {\r\n this._currentTransform = this._transforms.pop();\r\n }\r\n\r\n public translate(x: number, y: number): AffineMatrix {\r\n return this._currentTransform.translate(x, y);\r\n }\r\n\r\n public rotate(angle: number): AffineMatrix {\r\n return this._currentTransform.rotate(angle);\r\n }\r\n\r\n public scale(x: number, y: number): AffineMatrix {\r\n return this._currentTransform.scale(x, y);\r\n }\r\n\r\n public set current(matrix: AffineMatrix) {\r\n this._currentTransform = matrix;\r\n }\r\n\r\n public get current(): AffineMatrix {\r\n return this._currentTransform;\r\n }\r\n}\r\n","import { Color } from '../../Color';\r\nimport { ExcaliburGraphicsContextState } from './ExcaliburGraphicsContext';\r\nimport { Material } from './material';\r\n\r\nexport class StateStack {\r\n private _states: ExcaliburGraphicsContextState[] = [];\r\n private _currentState: ExcaliburGraphicsContextState = this._getDefaultState();\r\n\r\n private _getDefaultState() {\r\n return {\r\n opacity: 1,\r\n z: 0,\r\n tint: Color.White,\r\n material: null as Material\r\n };\r\n }\r\n\r\n private _cloneState() {\r\n return {\r\n opacity: this._currentState.opacity,\r\n z: this._currentState.z,\r\n tint: this._currentState.tint.clone(),\r\n material: this._currentState.material // TODO is this going to cause problems when cloning\r\n };\r\n }\r\n\r\n public save(): void {\r\n this._states.push(this._currentState);\r\n this._currentState = this._cloneState();\r\n }\r\n\r\n public restore(): void {\r\n this._currentState = this._states.pop();\r\n }\r\n\r\n public get current(): ExcaliburGraphicsContextState {\r\n return this._currentState;\r\n }\r\n\r\n public set current(val: ExcaliburGraphicsContextState) {\r\n this._currentState = val;\r\n }\r\n}\r\n","import { Loadable } from '../Interfaces/Loadable';\r\nimport { Logger } from '../Util/Log';\r\nimport { EventEmitter } from '../EventEmitter';\r\n\r\nexport type ResourceEvents = {\r\n complete: any,\r\n load: ProgressEvent,\r\n loadstart: ProgressEvent,\r\n progress: ProgressEvent,\r\n error: ProgressEvent\r\n}\r\n\r\nexport const ResourceEvents = {\r\n Complete: 'complete',\r\n Load: 'load',\r\n LoadStart: 'loadstart',\r\n Progress: 'progress',\r\n Error: 'error'\r\n};\r\n\r\n/**\r\n * The [[Resource]] type allows games built in Excalibur to load generic resources.\r\n * For any type of remote resource it is recommended to use [[Resource]] for preloading.\r\n */\r\nexport class Resource implements Loadable {\r\n public data: T = null;\r\n public logger: Logger = Logger.getInstance();\r\n public events = new EventEmitter();\r\n\r\n /**\r\n * @param path Path to the remote resource\r\n * @param responseType The type to expect as a response: \"\" | \"arraybuffer\" | \"blob\" | \"document\" | \"json\" | \"text\";\r\n * @param bustCache Whether or not to cache-bust requests\r\n */\r\n constructor(\r\n public path: string,\r\n public responseType: '' | 'arraybuffer' | 'blob' | 'document' | 'json' | 'text',\r\n public bustCache: boolean = false\r\n ) {}\r\n\r\n /**\r\n * Returns true if the Resource is completely loaded and is ready\r\n * to be drawn.\r\n */\r\n public isLoaded(): boolean {\r\n return this.data !== null;\r\n }\r\n\r\n\r\n private _cacheBust(uri: string): string {\r\n const query: RegExp = /\\?\\w*=\\w*/;\r\n if (query.test(uri)) {\r\n uri += '&__=' + Date.now();\r\n } else {\r\n uri += '?__=' + Date.now();\r\n }\r\n return uri;\r\n }\r\n /**\r\n * Begin loading the resource and returns a promise to be resolved on completion\r\n */\r\n public load(): Promise {\r\n return new Promise((resolve, reject) => {\r\n // Exit early if we already have data\r\n if (this.data !== null) {\r\n this.logger.debug('Already have data for resource', this.path);\r\n this.events.emit('complete', this.data as any);\r\n resolve(this.data);\r\n return;\r\n }\r\n\r\n const request = new XMLHttpRequest();\r\n request.open('GET', this.bustCache ? this._cacheBust(this.path) : this.path, true);\r\n request.responseType = this.responseType;\r\n request.addEventListener('loadstart', (e) => this.events.emit('loadstart', e as any));\r\n request.addEventListener('progress', (e) => this.events.emit('progress', e as any));\r\n request.addEventListener('error', (e) => this.events.emit('error', e as any));\r\n request.addEventListener('load', (e) => this.events.emit('load', e as any));\r\n request.addEventListener('load', () => {\r\n // XHR on file:// success status is 0, such as with PhantomJS\r\n if (request.status !== 0 && request.status !== 200) {\r\n this.logger.error('Failed to load resource ', this.path, ' server responded with error code', request.status);\r\n this.events.emit('error', request.response);\r\n reject(new Error(request.statusText));\r\n return;\r\n }\r\n\r\n this.data = request.response;\r\n this.events.emit('complete', this.data as any);\r\n this.logger.debug('Completed loading resource', this.path);\r\n resolve(this.data);\r\n });\r\n request.send();\r\n });\r\n }\r\n}\r\n","/**\r\n * Watch an object with a proxy, only fires if property value is different\r\n */\r\nexport function watch(type: T, change: (type: T) => any): T {\r\n if (!type) {\r\n return type;\r\n }\r\n if ((type as any).__isProxy === undefined) {\r\n // expando hack to mark a proxy\r\n return new Proxy(type, {\r\n set: (obj, prop, value) => {\r\n // The default behavior to store the value\r\n if ((obj as any)[prop] !== value) {\r\n (obj as any)[prop] = value;\r\n // Avoid watching private junk\r\n if (typeof prop === 'string') {\r\n if (prop[0] !== '_') {\r\n change(obj);\r\n }\r\n }\r\n }\r\n // Indicate success\r\n return true;\r\n },\r\n get: (obj, prop) => {\r\n if (prop !== '__isProxy') {\r\n return (obj as any)[prop];\r\n }\r\n return true;\r\n }\r\n });\r\n }\r\n return type;\r\n}\r\n\r\n/**\r\n * Watch an object with a proxy, fires change on any property value change\r\n */\r\nexport function watchAny(type: T, change: (type: T) => any): T {\r\n if (!type) {\r\n return type;\r\n }\r\n if ((type as any).__isProxy === undefined) {\r\n // expando hack to mark a proxy\r\n return new Proxy(type, {\r\n set: (obj, prop, value) => {\r\n // The default behavior to store the value\r\n (obj as any)[prop] = value;\r\n // Avoid watching private junk\r\n if (typeof prop === 'string') {\r\n if (prop[0] !== '_') {\r\n change(obj);\r\n }\r\n }\r\n\r\n // Indicate success\r\n return true;\r\n },\r\n get: (obj, prop) => {\r\n if (prop !== '__isProxy') {\r\n return (obj as any)[prop];\r\n }\r\n return true;\r\n }\r\n });\r\n }\r\n return type;\r\n}\r\n","import { Vector, vec } from '../Math/vector';\r\nimport { ExcaliburGraphicsContext } from './Context/ExcaliburGraphicsContext';\r\nimport { BoundingBox } from '../Collision/BoundingBox';\r\nimport { Color } from '../Color';\r\nimport { watch } from '../Util/Watch';\r\nimport { AffineMatrix } from '../Math/affine-matrix';\r\n\r\nexport interface GraphicOptions {\r\n /**\r\n * The width of the graphic\r\n */\r\n width?: number;\r\n /**\r\n * The height of the graphic\r\n */\r\n height?: number;\r\n /**\r\n * Should the graphic be flipped horizontally\r\n */\r\n flipHorizontal?: boolean;\r\n /**\r\n * Should the graphic be flipped vertically\r\n */\r\n flipVertical?: boolean;\r\n /**\r\n * The rotation of the graphic\r\n */\r\n rotation?: number;\r\n /**\r\n * The scale of the graphic\r\n */\r\n scale?: Vector;\r\n /**\r\n * The opacity of the graphic\r\n */\r\n opacity?: number;\r\n /**\r\n * The tint of the graphic, this color will be multiplied by the original pixel colors\r\n */\r\n tint?: Color;\r\n /**\r\n * The origin of the drawing in pixels to use when applying transforms, by default it will be the center of the image\r\n */\r\n origin?: Vector;\r\n}\r\n\r\n/**\r\n * A Graphic is the base Excalibur primitive for something that can be drawn to the [[ExcaliburGraphicsContext]].\r\n * [[Sprite]], [[Animation]], [[GraphicsGroup]], [[Canvas]], [[Rectangle]], [[Circle]], and [[Polygon]] all derive from the\r\n * [[Graphic]] abstract class.\r\n *\r\n * Implementors of a Graphic must override the abstract [[Graphic._drawImage]] method to render an image to the graphics context. Graphic\r\n * handles all the position, rotation, and scale transformations in [[Graphic._preDraw]] and [[Graphic._postDraw]]\r\n */\r\nexport abstract class Graphic {\r\n private static _ID: number = 0;\r\n readonly id = Graphic._ID++;\r\n\r\n public transform: AffineMatrix = AffineMatrix.identity();\r\n public tint: Color = null;\r\n\r\n private _transformStale = true;\r\n public isStale() {\r\n return this._transformStale;\r\n }\r\n\r\n /**\r\n * Gets or sets wether to show debug information about the graphic\r\n */\r\n public showDebug: boolean = false;\r\n\r\n\r\n private _flipHorizontal = false;\r\n /**\r\n * Gets or sets the flipHorizontal, which will flip the graphic horizontally (across the y axis)\r\n */\r\n public get flipHorizontal(): boolean {\r\n return this._flipHorizontal;\r\n }\r\n\r\n public set flipHorizontal(value: boolean) {\r\n this._flipHorizontal = value;\r\n this._transformStale = true;\r\n }\r\n\r\n private _flipVertical = false;\r\n /**\r\n * Gets or sets the flipVertical, which will flip the graphic vertically (across the x axis)\r\n */\r\n public get flipVertical(): boolean {\r\n return this._flipVertical;\r\n }\r\n\r\n public set flipVertical(value: boolean) {\r\n this._flipVertical = value;\r\n this._transformStale = true;\r\n }\r\n\r\n private _rotation = 0;\r\n /**\r\n * Gets or sets the rotation of the graphic\r\n */\r\n public get rotation(): number {\r\n return this._rotation;\r\n }\r\n\r\n public set rotation(value: number) {\r\n this._rotation = value;\r\n this._transformStale = true;\r\n }\r\n\r\n /**\r\n * Gets or sets the opacity of the graphic, 0 is transparent, 1 is solid (opaque).\r\n */\r\n public opacity: number = 1;\r\n\r\n private _scale = Vector.One;\r\n /**\r\n * Gets or sets the scale of the graphic, this affects the width and\r\n */\r\n public get scale() {\r\n return this._scale;\r\n }\r\n\r\n public set scale(value: Vector) {\r\n this._scale = watch(value, () => {\r\n this._transformStale = true;\r\n });\r\n this._transformStale = true;\r\n }\r\n\r\n private _origin: Vector | null = null;\r\n /**\r\n * Gets or sets the origin of the graphic, if not set the center of the graphic is the origin\r\n */\r\n public get origin(): Vector | null {\r\n return this._origin;\r\n }\r\n\r\n public set origin(value: Vector | null) {\r\n this._origin = watch(value, () => {\r\n this._transformStale = true;\r\n });\r\n this._transformStale = true;\r\n }\r\n\r\n constructor(options?: GraphicOptions) {\r\n if (options) {\r\n this.origin = options.origin ?? this.origin;\r\n this.flipHorizontal = options.flipHorizontal ?? this.flipHorizontal;\r\n this.flipVertical = options.flipVertical ?? this.flipVertical;\r\n this.rotation = options.rotation ?? this.rotation;\r\n this.opacity = options.opacity ?? this.opacity;\r\n this.scale = options.scale ?? this.scale;\r\n }\r\n }\r\n\r\n public cloneGraphicOptions(): GraphicOptions {\r\n return {\r\n origin: this.origin ? this.origin.clone() : null,\r\n flipHorizontal: this.flipHorizontal,\r\n flipVertical: this.flipVertical,\r\n rotation: this.rotation,\r\n opacity: this.opacity,\r\n scale: this.scale ? this.scale.clone() : null\r\n };\r\n }\r\n\r\n private _width: number = 0;\r\n\r\n /**\r\n * Gets or sets the width of the graphic (always positive)\r\n */\r\n public get width() {\r\n return Math.abs(this._width * this.scale.x);\r\n }\r\n\r\n private _height: number = 0;\r\n\r\n /**\r\n * Gets or sets the height of the graphic (always positive)\r\n */\r\n public get height() {\r\n return Math.abs(this._height * this.scale.y);\r\n }\r\n\r\n public set width(value: number) {\r\n this._width = value;\r\n this._transformStale = true;\r\n }\r\n\r\n public set height(value: number) {\r\n this._height = value;\r\n this._transformStale = true;\r\n }\r\n\r\n /**\r\n * Gets a copy of the bounds in pixels occupied by the graphic on the the screen. This includes scale.\r\n */\r\n public get localBounds(): BoundingBox {\r\n return BoundingBox.fromDimension(this.width, this.height, Vector.Zero);\r\n }\r\n\r\n /**\r\n * Draw the whole graphic to the context including transform\r\n * @param ex The excalibur graphics context\r\n * @param x\r\n * @param y\r\n */\r\n public draw(ex: ExcaliburGraphicsContext, x: number, y: number): void {\r\n this._preDraw(ex, x, y);\r\n this._drawImage(ex, 0, 0);\r\n this._postDraw(ex);\r\n }\r\n\r\n /**\r\n * Meant to be overridden by the graphic implementation to draw the underlying image (HTMLCanvasElement or HTMLImageElement)\r\n * to the graphics context without transform. Transformations like position, rotation, and scale are handled by [[Graphic._preDraw]]\r\n * and [[Graphic._postDraw]]\r\n * @param ex The excalibur graphics context\r\n * @param x\r\n * @param y\r\n */\r\n protected abstract _drawImage(ex: ExcaliburGraphicsContext, x: number, y: number): void;\r\n\r\n /**\r\n * Apply affine transformations to the graphics context to manipulate the graphic before [[Graphic._drawImage]]\r\n * @param ex\r\n * @param x\r\n * @param y\r\n */\r\n protected _preDraw(ex: ExcaliburGraphicsContext, x: number, y: number): void {\r\n ex.save();\r\n ex.translate(x, y);\r\n if (this._transformStale) {\r\n this.transform.reset();\r\n this.transform.scale(Math.abs(this.scale.x), Math.abs(this.scale.y));\r\n this._rotate(this.transform);\r\n this._flip(this.transform);\r\n this._transformStale = false;\r\n }\r\n ex.multiply(this.transform);\r\n // it is important to multiply alphas so graphics respect the current context\r\n ex.opacity = ex.opacity * this.opacity;\r\n if (this.tint) {\r\n ex.tint = this.tint;\r\n }\r\n }\r\n\r\n protected _rotate(ex: ExcaliburGraphicsContext | AffineMatrix) {\r\n const scaleDirX = this.scale.x > 0 ? 1 : -1;\r\n const scaleDirY = this.scale.y > 0 ? 1 : -1;\r\n const origin = this.origin ?? vec(this.width / 2, this.height / 2);\r\n ex.translate(origin.x, origin.y);\r\n ex.rotate(this.rotation);\r\n // This is for handling direction changes 1 or -1, that way we don't have mismatched translates()\r\n ex.scale(scaleDirX, scaleDirY);\r\n ex.translate(-origin.x, -origin.y);\r\n }\r\n\r\n protected _flip(ex: ExcaliburGraphicsContext | AffineMatrix) {\r\n if (this.flipHorizontal) {\r\n ex.translate(this.width / this.scale.x, 0);\r\n ex.scale(-1, 1);\r\n }\r\n\r\n if (this.flipVertical) {\r\n ex.translate(0, this.height / this.scale.y);\r\n ex.scale(1, -1);\r\n }\r\n }\r\n\r\n /**\r\n * Apply any additional work after [[Graphic._drawImage]] and restore the context state.\r\n * @param ex\r\n */\r\n protected _postDraw(ex: ExcaliburGraphicsContext): void {\r\n if (this.showDebug) {\r\n ex.debug.drawRect(0, 0, this.width, this.height);\r\n }\r\n ex.restore();\r\n }\r\n\r\n /**\r\n * Returns a new instance of the graphic that has the same properties\r\n */\r\n abstract clone(): Graphic;\r\n}\r\n","import { Graphic, GraphicOptions } from './Graphic';\r\nimport { ImageSource } from './ImageSource';\r\nimport { ExcaliburGraphicsContext } from './Context/ExcaliburGraphicsContext';\r\nimport { Logger } from '../Util/Log';\r\n\r\nexport type SourceView = { x: number; y: number; width: number; height: number };\r\nexport type DestinationSize = { width: number; height: number };\r\n\r\nexport interface SpriteOptions {\r\n /**\r\n * Image to create a sprite from\r\n */\r\n image: ImageSource;\r\n /**\r\n * By default the source is the entire dimension of the [[ImageSource]]\r\n */\r\n sourceView?: { x: number; y: number; width: number; height: number };\r\n /**\r\n * By default the size of the final sprite is the size of the [[ImageSource]]\r\n */\r\n destSize?: { width: number; height: number };\r\n}\r\n\r\nexport class Sprite extends Graphic {\r\n private _logger = Logger.getInstance();\r\n public image: ImageSource;\r\n public sourceView: SourceView;\r\n public destSize: DestinationSize;\r\n private _dirty = true;\r\n\r\n public static from(image: ImageSource): Sprite {\r\n return new Sprite({\r\n image: image\r\n });\r\n }\r\n\r\n constructor(options: GraphicOptions & SpriteOptions) {\r\n super(options);\r\n this.image = options.image;\r\n const { width, height } = options;\r\n this.sourceView = options.sourceView ?? { x: 0, y: 0, width: width ?? 0, height: height ?? 0 };\r\n this.destSize = options.destSize ?? { width: width ?? 0, height: height ?? 0 };\r\n this._updateSpriteDimensions();\r\n this.image.ready.then(() => {\r\n this._updateSpriteDimensions();\r\n });\r\n }\r\n\r\n public override get width(): number {\r\n return Math.abs(this.destSize.width * this.scale.x);\r\n }\r\n\r\n public override get height(): number {\r\n return Math.abs(this.destSize.height * this.scale.y);\r\n }\r\n\r\n public override set width(newWidth: number) {\r\n newWidth /= Math.abs(this.scale.x);\r\n this.destSize.width = newWidth;\r\n super.width = Math.ceil(this.destSize.width);\r\n }\r\n\r\n public override set height(newHeight: number) {\r\n newHeight /= Math.abs(this.scale.y);\r\n this.destSize.height = newHeight;\r\n super.height = Math.ceil(this.destSize.height);\r\n }\r\n\r\n private _updateSpriteDimensions() {\r\n const { width: nativeWidth, height: nativeHeight } = this.image;\r\n // This code uses || to avoid 0's\r\n // If the source is not specified, use the native dimension\r\n this.sourceView.width = this.sourceView?.width || nativeWidth;\r\n this.sourceView.height = this.sourceView?.height || nativeHeight;\r\n\r\n // If the destination is not specified, use the source if specified, then native\r\n this.destSize.width = this.destSize?.width || this.sourceView?.width || nativeWidth;\r\n this.destSize.height = this.destSize?.height || this.sourceView?.height || nativeHeight;\r\n\r\n this.width = Math.ceil(this.destSize.width) * this.scale.x;\r\n this.height = Math.ceil(this.destSize.height) * this.scale.y;\r\n }\r\n\r\n protected _preDraw(ex: ExcaliburGraphicsContext, x: number, y: number): void {\r\n if (this.image.isLoaded() && this._dirty) {\r\n this._dirty = false;\r\n this._updateSpriteDimensions();\r\n }\r\n super._preDraw(ex, x, y);\r\n }\r\n\r\n private _logNotLoadedWarning = false;\r\n public _drawImage(ex: ExcaliburGraphicsContext, x: number, y: number): void {\r\n if (this.image.isLoaded()) {\r\n ex.drawImage(\r\n this.image.image,\r\n this.sourceView.x,\r\n this.sourceView.y,\r\n this.sourceView.width,\r\n this.sourceView.height,\r\n x,\r\n y,\r\n this.destSize.width,\r\n this.destSize.height\r\n );\r\n } else {\r\n if (!this._logNotLoadedWarning) {\r\n this._logger.warn(\r\n `ImageSource ${this.image.path}` +\r\n ` is not yet loaded and won't be drawn. Please call .load() or include in a Loader.\\n\\n` +\r\n `Read https://excaliburjs.com/docs/imagesource for more information.`\r\n );\r\n }\r\n this._logNotLoadedWarning = true;\r\n }\r\n }\r\n\r\n public clone(): Sprite {\r\n return new Sprite({\r\n image: this.image,\r\n sourceView: { ...this.sourceView },\r\n destSize: { ...this.destSize },\r\n ...this.cloneGraphicOptions()\r\n });\r\n }\r\n}\r\n","\r\n/**\r\n * Describes the different image filtering modes\r\n */\r\nexport enum ImageFiltering {\r\n\r\n /**\r\n * Pixel is useful when you do not want smoothing aka antialiasing applied to your graphics.\r\n *\r\n * Useful for Pixel art aesthetics.\r\n */\r\n Pixel = 'Pixel',\r\n\r\n /**\r\n * Blended is useful when you have high resolution artwork and would like it blended and smoothed\r\n */\r\n Blended = 'Blended'\r\n}","import { Logger } from '../../Util/Log';\r\nimport { ImageFiltering } from '../Filtering';\r\nimport { HTMLImageSource } from './ExcaliburGraphicsContext';\r\n\r\n/**\r\n * Manages loading image sources into webgl textures, a unique id is associated with all sources\r\n */\r\nexport class TextureLoader {\r\n private static _LOGGER = Logger.getInstance();\r\n\r\n constructor(gl: WebGL2RenderingContext) {\r\n this._gl = gl;\r\n TextureLoader._MAX_TEXTURE_SIZE = gl.getParameter(gl.MAX_TEXTURE_SIZE);\r\n }\r\n\r\n /**\r\n * Sets the default filtering for the Excalibur texture loader, default [[ImageFiltering.Blended]]\r\n */\r\n public static filtering: ImageFiltering = ImageFiltering.Blended;\r\n\r\n private _gl: WebGL2RenderingContext;\r\n\r\n private _textureMap = new Map();\r\n\r\n private static _MAX_TEXTURE_SIZE: number = 4096;\r\n\r\n /**\r\n * Get the WebGL Texture from a source image\r\n * @param image\r\n */\r\n public get(image: HTMLImageSource): WebGLTexture {\r\n return this._textureMap.get(image);\r\n }\r\n\r\n /**\r\n * Returns whether a source image has been loaded as a texture\r\n * @param image\r\n */\r\n public has(image: HTMLImageSource): boolean {\r\n return this._textureMap.has(image);\r\n }\r\n\r\n /**\r\n * Loads a graphic into webgl and returns it's texture info, a webgl context must be previously registered\r\n * @param image Source graphic\r\n * @param filtering {ImageFiltering} The ImageFiltering mode to apply to the loaded texture\r\n * @param forceUpdate Optionally force a texture to be reloaded, useful if the source graphic has changed\r\n */\r\n public load(image: HTMLImageSource, filtering?: ImageFiltering, forceUpdate = false): WebGLTexture {\r\n // Ignore loading if webgl is not registered\r\n const gl = this._gl;\r\n if (!gl) {\r\n return null;\r\n }\r\n\r\n let tex: WebGLTexture = null;\r\n // If reuse the texture if it's from the same source\r\n if (this.has(image)) {\r\n tex = this.get(image);\r\n }\r\n\r\n // Update existing webgl texture and return early\r\n if (tex) {\r\n if (forceUpdate) {\r\n gl.bindTexture(gl.TEXTURE_2D, tex);\r\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image);\r\n }\r\n return tex;\r\n }\r\n\r\n // No texture exists create a new one\r\n tex = gl.createTexture();\r\n\r\n TextureLoader.checkImageSizeSupportedAndLog(image);\r\n\r\n gl.bindTexture(gl.TEXTURE_2D, tex);\r\n\r\n gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, true);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\r\n\r\n // NEAREST for pixel art, LINEAR for hi-res\r\n const filterMode = filtering ?? TextureLoader.filtering;\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, filterMode === ImageFiltering.Pixel ? gl.NEAREST : gl.LINEAR);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, filterMode === ImageFiltering.Pixel ? gl.NEAREST : gl.LINEAR);\r\n\r\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image);\r\n\r\n this._textureMap.set(image, tex);\r\n return tex;\r\n }\r\n\r\n public delete(image: HTMLImageSource): void {\r\n // Ignore loading if webgl is not registered\r\n const gl = this._gl;\r\n if (!gl) {\r\n return null;\r\n }\r\n\r\n let tex: WebGLTexture = null;\r\n if (this.has(image)) {\r\n tex = this.get(image);\r\n gl.deleteTexture(tex);\r\n }\r\n }\r\n\r\n /**\r\n * Takes an image and returns if it meets size criteria for hardware\r\n * @param image\r\n * @returns if the image will be supported at runtime\r\n */\r\n public static checkImageSizeSupportedAndLog(image: HTMLImageSource) {\r\n const originalSrc = image.dataset.originalSrc ?? 'internal canvas bitmap';\r\n if (image.width > TextureLoader._MAX_TEXTURE_SIZE || image.height > TextureLoader._MAX_TEXTURE_SIZE) {\r\n TextureLoader._LOGGER.error(\r\n `The image [${originalSrc}] provided to Excalibur is too large for the device's maximum texture size of `+\r\n `(${TextureLoader._MAX_TEXTURE_SIZE}x${TextureLoader._MAX_TEXTURE_SIZE}) please resize to an image `\r\n +`for excalibur to render properly.\\n\\nImages will likely render as black rectangles.\\n\\n`+\r\n `Read more here: https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API/WebGL_best_practices#understand_system_limits`);\r\n return false;\r\n } else if (image.width > 4096 || image.height > 4096) {\r\n // https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API/WebGL_best_practices#understand_system_limits\r\n TextureLoader._LOGGER.warn(\r\n `The image [${originalSrc}] provided to excalibur is too large may not work on all mobile devices, `+\r\n `it is recommended you resize images to a maximum (4096x4096).\\n\\n` +\r\n `Images will likely render as black rectangles on some mobile platforms.\\n\\n` +\r\n `Read more here: https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API/WebGL_best_practices#understand_system_limits`);\r\n }\r\n return true;\r\n }\r\n}\r\n","import { Resource } from '../Resources/Resource';\r\nimport { Sprite } from './Sprite';\r\nimport { Loadable } from '../Interfaces/Index';\r\nimport { Logger } from '../Util/Log';\r\nimport { ImageFiltering } from './Filtering';\r\nimport { Future } from '../Util/Future';\r\nimport { TextureLoader } from '../Graphics/Context/texture-loader';\r\n\r\nexport class ImageSource implements Loadable {\r\n private _logger = Logger.getInstance();\r\n private _resource: Resource;\r\n public filtering: ImageFiltering;\r\n\r\n /**\r\n * The original size of the source image in pixels\r\n */\r\n public get width() {\r\n return this.image.naturalWidth;\r\n }\r\n\r\n /**\r\n * The original height of the source image in pixels\r\n */\r\n public get height() {\r\n return this.image.naturalHeight;\r\n }\r\n\r\n private _src: string;\r\n /**\r\n * Returns true if the Texture is completely loaded and is ready\r\n * to be drawn.\r\n */\r\n public isLoaded(): boolean {\r\n if (!this._src) {\r\n // this boosts speed of access\r\n this._src = this.data.src;\r\n }\r\n return !!this._src;\r\n }\r\n\r\n /**\r\n * Access to the underlying html image element\r\n */\r\n public data: HTMLImageElement = new Image();\r\n public get image(): HTMLImageElement {\r\n return this.data;\r\n }\r\n\r\n private _readyFuture = new Future();\r\n /**\r\n * Promise the resolves when the image is loaded and ready for use, does not initiate loading\r\n */\r\n public ready: Promise = this._readyFuture.promise;\r\n\r\n /**\r\n * The path to the image, can also be a data url like 'data:image/'\r\n * @param path {string} Path to the image resource relative from the HTML document hosting the game, or absolute\r\n * @param bustCache {boolean} Should excalibur add a cache busting querystring?\r\n * @param filtering {ImageFiltering} Optionally override the image filtering set by [[EngineOptions.antialiasing]]\r\n */\r\n constructor(public readonly path: string, bustCache: boolean = false, filtering?: ImageFiltering) {\r\n this._resource = new Resource(path, 'blob', bustCache);\r\n this.filtering = filtering;\r\n if (path.endsWith('.svg') || path.endsWith('.gif')) {\r\n this._logger.warn(`Image type is not fully supported, you may have mixed results ${path}. Fully supported: jpg, bmp, and png`);\r\n }\r\n }\r\n\r\n /**\r\n * Should excalibur add a cache busting querystring? By default false.\r\n * Must be set before loading\r\n */\r\n public get bustCache() {\r\n return this._resource.bustCache;\r\n }\r\n\r\n public set bustCache(val: boolean) {\r\n this._resource.bustCache = val;\r\n }\r\n\r\n /**\r\n * Begins loading the image and returns a promise that resolves when the image is loaded\r\n */\r\n async load(): Promise {\r\n if (this.isLoaded()) {\r\n return this.data;\r\n }\r\n try {\r\n // Load base64 or blob if needed\r\n let url: string;\r\n if (!this.path.includes('data:image/')) {\r\n const blob = await this._resource.load();\r\n url = URL.createObjectURL(blob);\r\n } else {\r\n url = this.path;\r\n }\r\n\r\n // Decode the image\r\n const image = new Image();\r\n // Use Image.onload over Image.decode()\r\n // https://bugs.chromium.org/p/chromium/issues/detail?id=1055828#c7\r\n // Otherwise chrome will throw still Image.decode() failures for large textures\r\n const loadedFuture = new Future();\r\n image.onload = () => loadedFuture.resolve();\r\n image.src = url;\r\n image.setAttribute('data-original-src', this.path);\r\n\r\n await loadedFuture.promise;\r\n\r\n // Set results\r\n // We defer loading the texture into webgl until the first draw that way we avoid a singleton\r\n // and for the multi-engine case the texture needs to be created in EACH webgl context to work\r\n // See image-renderer.ts draw()\r\n this.data = image;\r\n\r\n // emit warning if potentially too big\r\n TextureLoader.checkImageSizeSupportedAndLog(this.data);\r\n } catch (error) {\r\n throw `Error loading ImageSource from path '${this.path}' with error [${error.message}]`;\r\n }\r\n // Do a bad thing to pass the filtering as an attribute\r\n this.data.setAttribute('filtering', this.filtering);\r\n\r\n // todo emit complete\r\n this._readyFuture.resolve(this.data);\r\n return this.data;\r\n }\r\n\r\n /**\r\n * Build a sprite from this ImageSource\r\n */\r\n public toSprite(): Sprite {\r\n return Sprite.from(this);\r\n }\r\n\r\n /**\r\n * Unload images from memory\r\n */\r\n unload(): void {\r\n this.data = new Image();\r\n }\r\n}\r\n","import { ImageSource } from './ImageSource';\r\nimport { SourceView, Sprite } from './Sprite';\r\nimport { Logger } from '../Util/Log';\r\n\r\n/**\r\n * Specify sprite sheet spacing options, useful if your sprites are not tightly packed\r\n * and have space between them.\r\n */\r\nexport interface SpriteSheetSpacingDimensions {\r\n /**\r\n * The starting point to offset and start slicing the sprite sheet from the top left of the image.\r\n * Default is (0, 0)\r\n */\r\n originOffset?: { x?: number, y?: number };\r\n\r\n /**\r\n * The margin between sprites.\r\n * Default is (0, 0)\r\n */\r\n margin?: {x?: number, y?: number};\r\n}\r\n\r\n/**\r\n * Sprite sheet options for slicing up images\r\n */\r\nexport interface SpriteSheetGridOptions {\r\n /**\r\n * Source image to use for each sprite\r\n */\r\n image: ImageSource;\r\n /**\r\n * Grid definition for the sprite sheet\r\n */\r\n grid: {\r\n /**\r\n * Number of rows in the sprite sheet\r\n */\r\n rows: number;\r\n /**\r\n * Number of columns in the sprite sheet\r\n */\r\n columns: number;\r\n /**\r\n * Width of each individual sprite\r\n */\r\n spriteWidth: number;\r\n /**\r\n * Height of each individual sprite\r\n */\r\n spriteHeight: number;\r\n };\r\n /**\r\n * Optionally specify any spacing information between sprites\r\n */\r\n spacing?: SpriteSheetSpacingDimensions;\r\n}\r\n\r\nexport interface SpriteSheetSparseOptions {\r\n /**\r\n * Source image to use for each sprite\r\n */\r\n image: ImageSource;\r\n /**\r\n * List of source view rectangles to create a sprite sheet from\r\n */\r\n sourceViews: SourceView[];\r\n}\r\n\r\nexport interface SpriteSheetOptions {\r\n /**\r\n * Source sprites for the sprite sheet\r\n */\r\n sprites: Sprite[];\r\n /**\r\n * Optionally specify the number of rows in a sprite sheet (default 1 row)\r\n */\r\n rows?: number;\r\n /**\r\n * Optionally specify the number of columns in a sprite sheet (default sprites.length)\r\n */\r\n columns?: number;\r\n}\r\n\r\n/**\r\n * Represents a collection of sprites from a source image with some organization in a grid\r\n */\r\nexport class SpriteSheet {\r\n private _logger = Logger.getInstance();\r\n public readonly sprites: Sprite[] = [];\r\n public readonly rows: number;\r\n public readonly columns: number;\r\n\r\n /**\r\n * Build a new sprite sheet from a list of sprites\r\n *\r\n * Use [[SpriteSheet.fromImageSource]] to create a SpriteSheet from an [[ImageSource]] organized in a grid\r\n * @param options\r\n */\r\n constructor(options: SpriteSheetOptions) {\r\n const { sprites, rows, columns } = options;\r\n this.sprites = sprites;\r\n this.rows = rows ?? 1;\r\n this.columns = columns ?? this.sprites.length;\r\n }\r\n\r\n /**\r\n * Find a sprite by their x/y position in the SpriteSheet, for example `getSprite(0, 0)` is the [[Sprite]] in the top-left\r\n * @param x\r\n * @param y\r\n */\r\n public getSprite(x: number, y: number): Sprite | null {\r\n if (x >= this.columns || x < 0) {\r\n this._logger.warn(`No sprite exists in the SpriteSheet at (${x}, ${y}), x: ${x} should be between 0 and ${this.columns - 1}`);\r\n return null;\r\n }\r\n if (y >= this.rows || y < 0) {\r\n this._logger.warn(`No sprite exists in the SpriteSheet at (${x}, ${y}), y: ${y} should be between 0 and ${this.rows - 1}`);\r\n return null;\r\n }\r\n const spriteIndex = x + y * this.columns;\r\n return this.sprites[spriteIndex];\r\n }\r\n\r\n /**\r\n * Create a sprite sheet from a sparse set of [[SourceView]] rectangles\r\n * @param options\r\n */\r\n public static fromImageSourceWithSourceViews(options: SpriteSheetSparseOptions): SpriteSheet {\r\n const sprites: Sprite[] = options.sourceViews.map(sourceView => {\r\n return new Sprite({\r\n image: options.image,\r\n sourceView\r\n });\r\n });\r\n return new SpriteSheet({sprites});\r\n }\r\n\r\n /**\r\n * Create a SpriteSheet from an [[ImageSource]] organized in a grid\r\n *\r\n * Example:\r\n * ```\r\n * const spriteSheet = SpriteSheet.fromImageSource({\r\n * image: imageSource,\r\n * grid: {\r\n * rows: 5,\r\n * columns: 2,\r\n * spriteWidth: 32, // pixels\r\n * spriteHeight: 32 // pixels\r\n * },\r\n * // Optionally specify spacing\r\n * spacing: {\r\n * // pixels from the top left to start the sprite parsing\r\n * originOffset: {\r\n * x: 5,\r\n * y: 5\r\n * },\r\n * // pixels between each sprite while parsing\r\n * margin: {\r\n * x: 1,\r\n * y: 1\r\n * }\r\n * }\r\n * })\r\n * ```\r\n *\r\n * @param options\r\n */\r\n public static fromImageSource(options: SpriteSheetGridOptions): SpriteSheet {\r\n const sprites: Sprite[] = [];\r\n options.spacing = options.spacing ?? {};\r\n const {\r\n image,\r\n grid: { rows, columns: cols, spriteWidth, spriteHeight },\r\n spacing: { originOffset, margin }\r\n } = options;\r\n const offsetDefaults = { x: 0, y: 0, ...originOffset};\r\n const marginDefaults = { x: 0, y: 0, ...margin};\r\n for (let x = 0; x < cols; x++) {\r\n for (let y = 0; y < rows; y++) {\r\n sprites[x + y * cols] = new Sprite({\r\n image: image,\r\n sourceView: {\r\n x: x * spriteWidth + marginDefaults.x * x + offsetDefaults.x,\r\n y: y * spriteHeight + marginDefaults.y * y + offsetDefaults.y,\r\n width: spriteWidth,\r\n height: spriteHeight\r\n },\r\n destSize: { height: spriteHeight, width: spriteWidth }\r\n });\r\n }\r\n }\r\n return new SpriteSheet({\r\n sprites: sprites,\r\n rows: rows,\r\n columns: cols\r\n });\r\n }\r\n\r\n public clone(): SpriteSheet {\r\n return new SpriteSheet({\r\n sprites: this.sprites.map(sprite => sprite.clone()),\r\n rows: this.rows,\r\n columns: this.columns\r\n });\r\n }\r\n}\r\n","import { Vector } from '../Math/vector';\r\nimport { Logger } from '../Util/Log';\r\nimport { ExcaliburGraphicsContext } from './Context/ExcaliburGraphicsContext';\r\nimport { FontRenderer } from './FontCommon';\r\nimport { Graphic, GraphicOptions } from './Graphic';\r\nimport { Sprite } from './Sprite';\r\nimport { SpriteSheet } from './SpriteSheet';\r\nimport { BoundingBox, Color } from '..';\r\n\r\nexport interface SpriteFontOptions {\r\n /**\r\n * Alphabet string in spritesheet order (default is row column order)\r\n * example: 'abcdefghijklmnopqrstuvwxyz'\r\n */\r\n alphabet: string;\r\n /**\r\n * [[SpriteSheet]] to source character sprites from\r\n */\r\n spriteSheet: SpriteSheet;\r\n /**\r\n * Optionally ignore case in the supplied text;\r\n */\r\n caseInsensitive?: boolean;\r\n /**\r\n * Optionally adjust the spacing between character sprites\r\n */\r\n spacing?: number;\r\n /**\r\n * Optionally specify a \"shadow\"\r\n */\r\n shadow?: { offset: Vector };\r\n}\r\n\r\nexport class SpriteFont extends Graphic implements FontRenderer {\r\n private _text: string = '';\r\n public alphabet: string = '';\r\n public spriteSheet: SpriteSheet;\r\n\r\n public shadow: { offset: Vector } = null;\r\n public caseInsensitive = false;\r\n public spacing: number = 0;\r\n\r\n private _logger = Logger.getInstance();\r\n\r\n constructor(options: SpriteFontOptions & GraphicOptions) {\r\n super(options);\r\n const { alphabet, spriteSheet, caseInsensitive, spacing, shadow } = options;\r\n this.alphabet = alphabet;\r\n this.spriteSheet = spriteSheet;\r\n this.caseInsensitive = caseInsensitive ?? this.caseInsensitive;\r\n this.spacing = spacing ?? this.spacing;\r\n this.shadow = shadow ?? this.shadow;\r\n }\r\n\r\n private _alreadyWarnedAlphabet = false;\r\n private _alreadyWarnedSpriteSheet = false;\r\n private _getCharacterSprites(text: string): Sprite[] {\r\n const results: Sprite[] = [];\r\n // handle case insensitive\r\n const textToRender = this.caseInsensitive ? text.toLocaleLowerCase() : text;\r\n const alphabet = this.caseInsensitive ? this.alphabet.toLocaleLowerCase() : this.alphabet;\r\n\r\n // for each letter in text\r\n for (let letterIndex = 0; letterIndex < textToRender.length; letterIndex++) {\r\n // find the sprite index in alphabet , if there is an error pick the first\r\n const letter = textToRender[letterIndex];\r\n let spriteIndex = alphabet.indexOf(letter);\r\n if (spriteIndex === -1) {\r\n spriteIndex = 0;\r\n if (!this._alreadyWarnedAlphabet) {\r\n this._logger.warn(`SpriteFont - Cannot find letter '${letter}' in configured alphabet '${alphabet}'.`);\r\n this._logger.warn('There maybe be more issues in the SpriteFont configuration. No additional warnings will be logged.');\r\n this._alreadyWarnedAlphabet = true;\r\n }\r\n }\r\n\r\n const letterSprite = this.spriteSheet.sprites[spriteIndex];\r\n if (letterSprite) {\r\n results.push(letterSprite);\r\n } else {\r\n if (!this._alreadyWarnedSpriteSheet) {\r\n this._logger.warn(`SpriteFont - Cannot find sprite for '${letter}' at index '${spriteIndex}' in configured SpriteSheet`);\r\n this._logger.warn('There maybe be more issues in the SpriteFont configuration. No additional warnings will be logged.');\r\n this._alreadyWarnedSpriteSheet = true;\r\n }\r\n }\r\n }\r\n return results;\r\n }\r\n\r\n public measureText(text: string, maxWidth?: number): BoundingBox {\r\n const lines = this._getLinesFromText(text, maxWidth);\r\n const maxWidthLine = lines.reduce((a, b) => {\r\n return a.length > b.length ? a : b;\r\n });\r\n const sprites = this._getCharacterSprites(maxWidthLine);\r\n let width = 0;\r\n let height = 0;\r\n for (const sprite of sprites) {\r\n width += sprite.width + this.spacing;\r\n height = Math.max(height, sprite.height);\r\n }\r\n return BoundingBox.fromDimension(width, height * lines.length, Vector.Zero);\r\n }\r\n\r\n protected _drawImage(ex: ExcaliburGraphicsContext, x: number, y: number, maxWidth?: number): void {\r\n let xCursor = 0;\r\n let yCursor = 0;\r\n let height = 0;\r\n const lines = this._getLinesFromText(this._text, maxWidth);\r\n for (const line of lines) {\r\n for (const sprite of this._getCharacterSprites(line)) {\r\n // draw it in the right spot and increase the cursor by sprite width\r\n sprite.draw(ex, x + xCursor, y + yCursor);\r\n xCursor += sprite.width + this.spacing;\r\n height = Math.max(height, sprite.height);\r\n }\r\n xCursor = 0;\r\n yCursor += height;\r\n }\r\n }\r\n\r\n render(ex: ExcaliburGraphicsContext, text: string, _color: Color, x: number, y: number, maxWidth?: number) {\r\n // SpriteFont doesn't support _color, yet...\r\n this._text = text;\r\n const bounds = this.measureText(text, maxWidth);\r\n this.width = bounds.width;\r\n this.height = bounds.height;\r\n if (this.shadow) {\r\n ex.save();\r\n ex.translate(this.shadow.offset.x, this.shadow.offset.y);\r\n this._preDraw(ex, x, y);\r\n this._drawImage(ex, 0, 0, maxWidth);\r\n this._postDraw(ex);\r\n ex.restore();\r\n }\r\n\r\n this._preDraw(ex, x, y);\r\n this._drawImage(ex, 0, 0, maxWidth);\r\n this._postDraw(ex);\r\n }\r\n\r\n clone(): SpriteFont {\r\n return new SpriteFont({\r\n alphabet: this.alphabet,\r\n spriteSheet: this.spriteSheet,\r\n spacing: this.spacing\r\n });\r\n }\r\n\r\n /**\r\n * Return array of lines split based on the \\n character, and the maxWidth? constraint\r\n * @param text\r\n * @param maxWidth\r\n */\r\n private _cachedText: string;\r\n private _cachedLines: string[];\r\n private _cachedRenderWidth: number;\r\n private _getLinesFromText(text: string, maxWidth?: number) {\r\n if (this._cachedText === text && this._cachedRenderWidth === maxWidth) {\r\n return this._cachedLines;\r\n }\r\n\r\n const lines = text.split('\\n');\r\n\r\n if (maxWidth == null) {\r\n return lines;\r\n }\r\n\r\n // If the current line goes past the maxWidth, append a new line without modifying the underlying text.\r\n for (let i = 0; i < lines.length; i++) {\r\n let line = lines[i];\r\n let newLine = '';\r\n // Note: we subtract the spacing to counter the initial padding on the left side.\r\n if (this.measureText(line).width > maxWidth) {\r\n while (this.measureText(line).width > maxWidth) {\r\n newLine = line[line.length - 1] + newLine;\r\n line = line.slice(0, -1); // Remove last character from line\r\n }\r\n\r\n // Update the array with our new values\r\n lines[i] = line;\r\n lines[i + 1] = newLine;\r\n }\r\n }\r\n\r\n this._cachedText = text;\r\n this._cachedLines = lines;\r\n this._cachedRenderWidth = maxWidth;\r\n\r\n return lines;\r\n }\r\n}\r\n","export default \"data:image/png;base64,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\"","import { ExcaliburGraphicsContext, ImageSource, SpriteFont, SpriteSheet } from '..';\r\nimport { Vector } from '../..';\r\nimport debugFont from './debug-font.png';\r\n\r\n/**\r\n * Internal debugtext helper\r\n */\r\nexport class DebugText {\r\n constructor() {\r\n this.load();\r\n }\r\n\r\n /**\r\n * base64 font\r\n */\r\n public readonly fontSheet = debugFont;\r\n public size: number = 16;\r\n private _imageSource: ImageSource;\r\n private _spriteSheet: SpriteSheet;\r\n private _spriteFont: SpriteFont;\r\n public load() {\r\n this._imageSource = new ImageSource(this.fontSheet);\r\n return this._imageSource.load().then(() => {\r\n this._spriteSheet = SpriteSheet.fromImageSource({\r\n image: this._imageSource,\r\n grid: {\r\n rows: 3,\r\n columns: 16,\r\n spriteWidth: 16,\r\n spriteHeight: 16\r\n }\r\n });\r\n this._spriteFont = new SpriteFont({\r\n alphabet: '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ,!\\'&.\"?-()+ ',\r\n caseInsensitive: true,\r\n spriteSheet: this._spriteSheet,\r\n spacing: -6\r\n });\r\n });\r\n }\r\n\r\n /**\r\n * Writes debug text using the built in sprint font\r\n * @param ctx\r\n * @param text\r\n * @param pos\r\n */\r\n public write(ctx: ExcaliburGraphicsContext, text: string, pos: Vector) {\r\n if (this._imageSource.isLoaded()) {\r\n this._spriteFont.render(ctx, text, null, pos.x, pos.y);\r\n }\r\n }\r\n}\r\n","export class RenderSource {\r\n constructor(\r\n private _gl: WebGLRenderingContext,\r\n private _texture: WebGLTexture) {}\r\n\r\n public use() {\r\n const gl = this._gl;\r\n gl.activeTexture(gl.TEXTURE0);\r\n gl.bindTexture(gl.TEXTURE_2D, this._texture);\r\n }\r\n\r\n public disable() {\r\n const gl = this._gl;\r\n gl.bindTexture(gl.TEXTURE_2D, null);\r\n }\r\n}","import { RenderSource } from './render-source';\r\n\r\nexport class RenderTarget {\r\n width: number;\r\n height: number;\r\n private _gl: WebGLRenderingContext;\r\n constructor(options: {gl: WebGLRenderingContext, width: number, height: number}) {\r\n this.width = options.width;\r\n this.height = options.height;\r\n this._gl = options.gl;\r\n this._setupFramebuffer();\r\n }\r\n\r\n setResolution(width: number, height: number) {\r\n const gl = this._gl;\r\n this.width = width;\r\n this.height = height;\r\n gl.bindTexture(gl.TEXTURE_2D, this._frameTexture);\r\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.width, this.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);\r\n }\r\n\r\n private _frameBuffer: WebGLFramebuffer;\r\n public get frameBuffer() {\r\n return this._frameBuffer;\r\n }\r\n private _frameTexture: WebGLTexture;\r\n public get frameTexture() {\r\n return this._frameTexture;\r\n }\r\n private _setupFramebuffer() {\r\n // Allocates frame buffer\r\n const gl = this._gl;\r\n this._frameTexture = gl.createTexture();\r\n gl.bindTexture(gl.TEXTURE_2D, this._frameTexture);\r\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.width, this.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);\r\n\r\n // set the filtering so we don't need mips\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\r\n\r\n\r\n // attach the texture as the first color attachment\r\n const attachmentPoint = gl.COLOR_ATTACHMENT0;\r\n\r\n // After this bind all draw calls will draw to this framebuffer texture\r\n this._frameBuffer = gl.createFramebuffer();\r\n gl.bindFramebuffer(gl.FRAMEBUFFER, this._frameBuffer);\r\n gl.framebufferTexture2D(gl.FRAMEBUFFER, attachmentPoint, gl.TEXTURE_2D, this._frameTexture, 0);\r\n // Reset after initialized\r\n this.disable();\r\n }\r\n\r\n public toRenderSource() {\r\n const source = new RenderSource(this._gl, this._frameTexture);\r\n return source;\r\n }\r\n\r\n /**\r\n * When called, all drawing gets redirected to this render target\r\n */\r\n public use() {\r\n const gl = this._gl;\r\n gl.bindFramebuffer(gl.FRAMEBUFFER, this._frameBuffer);\r\n // very important to set the viewport to the size of the framebuffer texture\r\n gl.viewport(0, 0, this.width, this.height);\r\n }\r\n\r\n /**\r\n * When called, all drawing is sent back to the canvas\r\n */\r\n public disable() {\r\n const gl = this._gl;\r\n // passing null switches rendering back to the canvas\r\n gl.bindFramebuffer(gl.FRAMEBUFFER, null);\r\n gl.bindTexture(gl.TEXTURE_2D, null);\r\n }\r\n}","export default \"#version 300 es\\r\\nin vec2 a_position;\\r\\nin vec4 a_color;\\r\\n\\r\\nout lowp vec4 v_color;\\r\\n\\r\\nuniform mat4 u_matrix;\\r\\n\\r\\nvoid main() {\\r\\n // Set the vertex position using the ortho transform matrix\\r\\n gl_Position = u_matrix * vec4(a_position, 0.0, 1.0);\\r\\n\\r\\n // Passthrough the color\\r\\n v_color = a_color;\\r\\n}\";","export default \"#version 300 es\\r\\nprecision mediump float;\\r\\n\\r\\n// Color\\r\\nin lowp vec4 v_color;\\r\\n\\r\\nout vec4 fragColor;\\r\\n\\r\\nvoid main() {\\r\\n fragColor = v_color;\\r\\n}\";","/**\r\n * Return the size of the GlType in bytes\r\n * @param gl\r\n * @param type\r\n */\r\nexport function getGlTypeSizeBytes(gl: WebGLRenderingContext, type: number): number {\r\n switch (type) {\r\n case gl.FLOAT:\r\n return 4;\r\n case gl.SHORT:\r\n return 2;\r\n case gl.UNSIGNED_SHORT:\r\n return 2;\r\n case gl.BYTE:\r\n return 1;\r\n case gl.UNSIGNED_BYTE:\r\n return 1;\r\n default:\r\n return 1;\r\n }\r\n}\r\n\r\n\r\n/**\r\n * Based on the type return the number of attribute components\r\n *\r\n * https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/vertexAttribPointer\r\n * @param gl\r\n * @param type\r\n */\r\nexport function getAttributeComponentSize(gl: WebGLRenderingContext, type: number): number {\r\n switch (type) {\r\n case gl.LOW_FLOAT:\r\n case gl.HIGH_FLOAT:\r\n case gl.FLOAT:\r\n return 1;\r\n case gl.FLOAT_VEC2:\r\n return 2;\r\n case gl.FLOAT_VEC3:\r\n return 3;\r\n case gl.FLOAT_VEC4:\r\n return 4;\r\n case gl.BYTE:\r\n return 1;\r\n case gl.UNSIGNED_BYTE:\r\n return 1;\r\n case gl.UNSIGNED_SHORT:\r\n case gl.SHORT:\r\n return 1;\r\n default:\r\n return 1;\r\n }\r\n}\r\n\r\n/**\r\n * Based on the attribute return the corresponding supported attrib pointer type\r\n * https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/vertexAttribPointer\r\n *\r\n * @param gl\r\n * @param type\r\n */\r\nexport function getAttributePointerType(gl: WebGLRenderingContext, type: number) {\r\n switch (type) {\r\n case gl.LOW_FLOAT:\r\n case gl.HIGH_FLOAT:\r\n case gl.FLOAT:\r\n case gl.FLOAT_VEC2:\r\n case gl.FLOAT_VEC3:\r\n case gl.FLOAT_VEC4:\r\n return gl.FLOAT;\r\n case gl.BYTE:\r\n return gl.BYTE;\r\n case gl.UNSIGNED_BYTE:\r\n return gl.UNSIGNED_BYTE;\r\n case gl.SHORT:\r\n return gl.SHORT;\r\n case gl.UNSIGNED_SHORT:\r\n return gl.UNSIGNED_SHORT;\r\n default:\r\n return gl.FLOAT;\r\n }\r\n}","import { Color, Logger, Vector } from '../..';\r\nimport { Matrix } from '../../Math/matrix';\r\nimport { getAttributeComponentSize, getAttributePointerType } from './webgl-util';\r\n\r\nexport type UniformTypeNames =\r\n 'uniform1f' |\r\n 'uniform1i' |\r\n 'uniform2f' |\r\n 'uniform2i' |\r\n 'uniform3f' |\r\n 'uniform3i' |\r\n 'uniform4f' |\r\n 'uniform4i' |\r\n 'uniform1fv' |\r\n 'uniform1iv' |\r\n 'uniform2fv' |\r\n 'uniform2iv' |\r\n 'uniform3fv' |\r\n 'uniform3iv' |\r\n 'uniform4fv' |\r\n 'uniform4iv' |\r\n 'uniformMatrix2fv' |\r\n 'uniformMatrix3fv' |\r\n 'uniformMatrix4fv';\r\n\r\ntype RemoveFirstFromTuple =\r\n T['length'] extends 0 ? undefined :\r\n (((...b: T) => void) extends (a: any, ...b: infer I) => void ? I : [])\r\n\r\ntype UniformParameters = RemoveFirstFromTuple>\r\n\r\nexport interface UniformDefinition {\r\n name: string;\r\n glType: number;\r\n location: WebGLUniformLocation;\r\n}\r\n\r\n\r\nexport interface VertexAttributeDefinition {\r\n /**\r\n * string name of the attribute in the shader program, commonly `a_nameofmyvariable`\r\n */\r\n name: string;\r\n /**\r\n * Number of components for a given attribute\r\n * Must be 1, 2, 3, or 4\r\n *\r\n * For example a vec4 attribute would be `4` floats, so 4\r\n */\r\n size: number;\r\n /**\r\n * Supported types in webgl 1\r\n * * gl.BYTE\r\n * * gl.SHORT\r\n * * gl.UNSIGNED_BYTE\r\n * * gl.UNSIGNED_SHORT\r\n * * gl.FLOAT\r\n * https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/vertexAttribPointer\r\n */\r\n glType: number;\r\n /**\r\n * Is the attribute normalized between (0-1)\r\n */\r\n normalized: boolean;\r\n /**\r\n * Location index in the shader program\r\n */\r\n location: number;\r\n}\r\n\r\nexport interface ShaderOptions {\r\n /**\r\n * WebGL2RenderingContext this layout will be attached to, these cannot be reused across webgl contexts.\r\n */\r\n gl: WebGL2RenderingContext;\r\n /**\r\n * Vertex shader source code in glsl #version 300 es\r\n */\r\n vertexSource: string;\r\n /**\r\n * Fragment shader source code in glsl #version 300 es\r\n */\r\n fragmentSource: string;\r\n}\r\n\r\nexport class Shader {\r\n private static _ACTIVE_SHADER_INSTANCE: Shader = null;\r\n private _logger = Logger.getInstance();\r\n private _gl: WebGL2RenderingContext;\r\n public program: WebGLProgram;\r\n public uniforms: { [variableName: string]: UniformDefinition } = {};\r\n public attributes: { [variableName: string]: VertexAttributeDefinition } = {};\r\n private _compiled = false;\r\n public readonly vertexSource: string;\r\n public readonly fragmentSource: string;\r\n\r\n public get compiled() {\r\n return this._compiled;\r\n }\r\n\r\n /**\r\n * Create a shader program in excalibur\r\n * @param options specify shader vertex and fragment source\r\n */\r\n constructor(options?: ShaderOptions) {\r\n const { gl, vertexSource, fragmentSource } = options;\r\n this._gl = gl;\r\n this.vertexSource = vertexSource;\r\n this.fragmentSource = fragmentSource;\r\n }\r\n\r\n /**\r\n * Binds the shader program\r\n */\r\n use() {\r\n const gl = this._gl;\r\n gl.useProgram(this.program);\r\n Shader._ACTIVE_SHADER_INSTANCE = this;\r\n }\r\n\r\n isCurrentlyBound() {\r\n return Shader._ACTIVE_SHADER_INSTANCE === this;\r\n }\r\n\r\n /**\r\n * Compile the current shader against a webgl context\r\n */\r\n compile(): WebGLProgram {\r\n const gl = this._gl;\r\n const vertexShader = this._compileShader(gl, this.vertexSource, gl.VERTEX_SHADER);\r\n const fragmentShader = this._compileShader(gl, this.fragmentSource, gl.FRAGMENT_SHADER);\r\n this.program = this._createProgram(gl, vertexShader, fragmentShader);\r\n\r\n const attributes = this.getAttributes();\r\n for (const attribute of attributes) {\r\n this.attributes[attribute.name] = attribute;\r\n }\r\n const uniforms = this.getUniforms();\r\n for (const uniform of uniforms) {\r\n this.uniforms[uniform.name] = uniform;\r\n }\r\n\r\n this._compiled = true;\r\n return this.program;\r\n }\r\n\r\n getUniforms(): UniformDefinition[] {\r\n const gl = this._gl;\r\n const uniformCount = gl.getProgramParameter(this.program, gl.ACTIVE_UNIFORMS);\r\n const uniforms: UniformDefinition[] = [];\r\n for (let i = 0; i < uniformCount; i++) {\r\n const uniform = gl.getActiveUniform(this.program, i);\r\n const uniformLocation = gl.getUniformLocation(this.program, uniform.name);\r\n uniforms.push({\r\n name: uniform.name,\r\n glType: uniform.type,\r\n location: uniformLocation\r\n });\r\n }\r\n return uniforms;\r\n }\r\n\r\n getAttributes(): VertexAttributeDefinition[] {\r\n const gl = this._gl;\r\n const attributeCount = gl.getProgramParameter(this.program, gl.ACTIVE_ATTRIBUTES);\r\n const attributes: VertexAttributeDefinition[] = [];\r\n for (let i = 0; i < attributeCount; i++) {\r\n const attribute = gl.getActiveAttrib(this.program, i);\r\n const attributeLocation = gl.getAttribLocation(this.program, attribute.name);\r\n attributes.push({\r\n name: attribute.name,\r\n glType: getAttributePointerType(gl, attribute.type),\r\n size: getAttributeComponentSize(gl, attribute.type),\r\n location: attributeLocation,\r\n normalized: false\r\n });\r\n }\r\n return attributes;\r\n }\r\n\r\n /**\r\n * Set a texture in a gpu texture slot\r\n * @param slotNumber\r\n * @param texture\r\n */\r\n setTexture(slotNumber: number, texture: WebGLTexture) {\r\n const gl = this._gl;\r\n gl.activeTexture(gl.TEXTURE0 + slotNumber);\r\n gl.bindTexture(gl.TEXTURE_2D, texture);\r\n }\r\n\r\n /**\r\n * Set an integer uniform for the current shader\r\n *\r\n * **Important** Must call ex.Shader.use() before setting a uniform!\r\n *\r\n * @param name\r\n * @param value\r\n */\r\n setUniformInt(name: string, value: number) {\r\n this.setUniform('uniform1i', name, ~~value);\r\n }\r\n\r\n /**\r\n * Set an integer uniform for the current shader, WILL NOT THROW on error.\r\n *\r\n * **Important** Must call ex.Shader.use() before setting a uniform!\r\n *\r\n * @param name\r\n * @param value\r\n */\r\n trySetUniformInt(name: string, value: number): boolean {\r\n return this.trySetUniform('uniform1i', name, ~~value);\r\n }\r\n\r\n /**\r\n * Set an integer array uniform for the current shader\r\n *\r\n * **Important** Must call ex.Shader.use() before setting a uniform!\r\n *\r\n * @param name\r\n * @param value\r\n */\r\n setUniformIntArray(name: string, value: number[]) {\r\n this.setUniform('uniform1iv', name, value);\r\n }\r\n\r\n /**\r\n * Set an integer array uniform for the current shader, WILL NOT THROW on error.\r\n *\r\n * **Important** Must call ex.Shader.use() before setting a uniform!\r\n *\r\n * @param name\r\n * @param value\r\n */\r\n trySetUniformIntArray(name: string, value: number[]): boolean {\r\n return this.trySetUniform('uniform1iv', name, value);\r\n }\r\n\r\n /**\r\n * Set a boolean uniform for the current shader\r\n *\r\n * **Important** Must call ex.Shader.use() before setting a uniform!\r\n *\r\n * @param name\r\n * @param value\r\n */\r\n setUniformBoolean(name: string, value: boolean) {\r\n this.setUniform('uniform1i', name, value ? 1 : 0);\r\n }\r\n\r\n /**\r\n * Set a boolean uniform for the current shader, WILL NOT THROW on error.\r\n *\r\n * **Important** Must call ex.Shader.use() before setting a uniform!\r\n *\r\n * @param name\r\n * @param value\r\n */\r\n trySetUniformBoolean(name: string, value: boolean): boolean {\r\n return this.trySetUniform('uniform1i', name, value ? 1 : 0);\r\n }\r\n\r\n /**\r\n * Set a float uniform for the current shader\r\n *\r\n * **Important** Must call ex.Shader.use() before setting a uniform!\r\n *\r\n * @param name\r\n * @param value\r\n */\r\n setUniformFloat(name: string, value: number) {\r\n this.setUniform('uniform1f', name, value);\r\n }\r\n\r\n /**\r\n * Set a float uniform for the current shader, WILL NOT THROW on error.\r\n *\r\n * **Important** Must call ex.Shader.use() before setting a uniform!\r\n *\r\n * @param name\r\n * @param value\r\n */\r\n trySetUniformFloat(name: string, value: number): boolean {\r\n return this.trySetUniform('uniform1f', name, value);\r\n }\r\n\r\n /**\r\n * Set a float array uniform for the current shader\r\n *\r\n * **Important** Must call ex.Shader.use() before setting a uniform!\r\n *\r\n * @param name\r\n * @param value\r\n */\r\n setUniformFloatArray(name: string, value: number[]) {\r\n this.setUniform('uniform1fv', name, value);\r\n }\r\n /**\r\n * Set a float array uniform for the current shader, WILL NOT THROW on error.\r\n *\r\n * **Important** Must call ex.Shader.use() before setting a uniform!\r\n *\r\n * @param name\r\n * @param value\r\n */\r\n trySetUniformFloatArray(name: string, value: number[]): boolean {\r\n return this.trySetUniform('uniform1fv', name, value);\r\n }\r\n\r\n /**\r\n * Set a [[Vector]] uniform for the current shader\r\n *\r\n * **Important** Must call ex.Shader.use() before setting a uniform!\r\n *\r\n * @param name\r\n * @param value\r\n */\r\n setUniformFloatVector(name: string, value: Vector) {\r\n this.setUniform('uniform2f', name, value.x, value.y);\r\n }\r\n\r\n /**\r\n * Set a [[Vector]] uniform for the current shader, WILL NOT THROW on error.\r\n *\r\n * **Important** Must call ex.Shader.use() before setting a uniform!\r\n *\r\n * @param name\r\n * @param value\r\n */\r\n trySetUniformFloatVector(name: string, value: Vector): boolean {\r\n return this.trySetUniform('uniform2f', name, value.x, value.y);\r\n }\r\n\r\n /**\r\n * Set a [[Color]] uniform for the current shader\r\n *\r\n * **Important** Must call ex.Shader.use() before setting a uniform!\r\n *\r\n * @param name\r\n * @param value\r\n */\r\n setUniformFloatColor(name: string, value: Color) {\r\n this.setUniform('uniform4f', name, value.r / 255, value.g / 255, value.b / 255, value.a);\r\n }\r\n\r\n /**\r\n * Set a [[Color]] uniform for the current shader, WILL NOT THROW on error.\r\n *\r\n * **Important** Must call ex.Shader.use() before setting a uniform!\r\n *\r\n * @param name\r\n * @param value\r\n */\r\n trySetUniformFloatColor(name: string, value: Color): boolean {\r\n return this.trySetUniform('uniform4f', name, value.r / 255, value.g / 255, value.b / 255, value.a);\r\n }\r\n\r\n /**\r\n * Set an [[Matrix]] uniform for the current shader\r\n *\r\n * **Important** Must call ex.Shader.use() before setting a uniform!\r\n *\r\n * @param name\r\n * @param value\r\n */\r\n setUniformMatrix(name: string, value: Matrix) {\r\n this.setUniform('uniformMatrix4fv', name, false, value.data);\r\n }\r\n\r\n /**\r\n * Set an [[Matrix]] uniform for the current shader, WILL NOT THROW on error.\r\n *\r\n * **Important** Must call ex.Shader.use() before setting a uniform!\r\n *\r\n * @param name\r\n * @param value\r\n */\r\n trySetUniformMatrix(name: string, value: Matrix): boolean {\r\n return this.trySetUniform('uniformMatrix4fv', name, false, value.data);\r\n }\r\n\r\n /**\r\n * Set any available uniform type in webgl\r\n *\r\n * For example setUniform('uniformMatrix2fv', 'u_my2x2_mat`, ...);\r\n */\r\n setUniform(uniformType: TUniformType, name: string, ...value: UniformParameters) {\r\n if (!this._compiled) {\r\n throw Error(`Must compile shader before setting a uniform ${uniformType}:${name}`);\r\n }\r\n if (!this.isCurrentlyBound()) {\r\n throw Error('Currently accessed shader instance is not the current active shader in WebGL,' +\r\n ' must call `shader.use()` before setting uniforms');\r\n }\r\n const gl = this._gl;\r\n const location = gl.getUniformLocation(this.program, name);\r\n if (location) {\r\n const args = [location, ...value];\r\n this._gl[uniformType].apply(this._gl, args);\r\n } else {\r\n throw Error(`Uniform ${uniformType}:${name} doesn\\'t exist or is not used in the shader source code,`+\r\n ' unused uniforms are optimized away by most browsers');\r\n }\r\n }\r\n\r\n /**\r\n * Set any available uniform type in webgl. Will try to set the uniform, will return false if the uniform didn't exist,\r\n * true if it was set.\r\n *\r\n * WILL NOT THROW on error\r\n *\r\n * For example setUniform('uniformMatrix2fv', 'u_my2x2_mat`, ...);\r\n *\r\n */\r\n trySetUniform(\r\n uniformType: TUniformType,\r\n name: string,\r\n ...value: UniformParameters): boolean {\r\n if (!this._compiled) {\r\n this._logger.warn(`Must compile shader before setting a uniform ${uniformType}:${name}`);\r\n return false;\r\n }\r\n if (!this.isCurrentlyBound()) {\r\n this._logger.warn('Currently accessed shader instance is not the current active shader in WebGL,' +\r\n ' must call `shader.use()` before setting uniforms');\r\n return false;\r\n }\r\n const gl = this._gl;\r\n const location = gl.getUniformLocation(this.program, name);\r\n if (location) {\r\n const args = [location, ...value];\r\n this._gl[uniformType].apply(this._gl, args);\r\n } else {\r\n return false;\r\n }\r\n return true;\r\n }\r\n\r\n private _createProgram(gl: WebGLRenderingContext, vertexShader: WebGLShader, fragmentShader: WebGLShader): WebGLProgram {\r\n const program = gl.createProgram();\r\n if (program === null) {\r\n throw Error('Could not create graphics shader program');\r\n }\r\n\r\n // attach the shaders.\r\n gl.attachShader(program, vertexShader);\r\n gl.attachShader(program, fragmentShader);\r\n\r\n // link the program.\r\n gl.linkProgram(program);\r\n\r\n const success = gl.getProgramParameter(program, gl.LINK_STATUS);\r\n if (!success) {\r\n throw Error(`Could not link the program: [${gl.getProgramInfoLog(program)}]`);\r\n }\r\n\r\n return program;\r\n }\r\n\r\n private _compileShader(gl: WebGLRenderingContext, source: string, type: number): WebGLShader {\r\n const typeName = gl.VERTEX_SHADER === type ? 'vertex' : 'fragment';\r\n const shader = gl.createShader(type);\r\n if (shader === null) {\r\n throw Error(`Could not build shader: [${source}]`);\r\n }\r\n\r\n gl.shaderSource(shader, source);\r\n gl.compileShader(shader);\r\n\r\n const success = gl.getShaderParameter(shader, gl.COMPILE_STATUS);\r\n if (!success) {\r\n const errorInfo = gl.getShaderInfoLog(shader);\r\n throw Error(`Could not compile ${typeName} shader:\\n\\n${errorInfo}${this._processSourceForError(source, errorInfo)}`);\r\n }\r\n return shader;\r\n }\r\n\r\n private _processSourceForError(source: string, errorInfo: string) {\r\n const lines = source.split('\\n');\r\n const errorLineStart = errorInfo.search(/\\d:\\d/);\r\n const errorLineEnd = errorInfo.indexOf(' ', errorLineStart);\r\n const [_, error2] = errorInfo.slice(errorLineStart, errorLineEnd).split(':').map(v => Number(v));\r\n for (let i = 0; i < lines.length; i++) {\r\n lines[i] = `${i+1}: ${lines[i]}${error2 === (i+1)? ' <----- ERROR!' : ''}`;\r\n }\r\n\r\n return '\\n\\nSource:\\n' + lines.join('\\n');\r\n }\r\n}","export interface VertexBufferOptions {\r\n /**\r\n * WebGL2RenderingContext this layout will be attached to, these cannot be reused across contexts.\r\n */\r\n gl: WebGL2RenderingContext,\r\n /**\r\n * Size in number of floats, so [4.2, 4.0, 2.1] is size = 3\r\n *\r\n * Ignored if data is passed directly\r\n */\r\n size?: number;\r\n /**\r\n * If the vertices never change switching 'static' can be more efficient on the gpu\r\n *\r\n * Default is 'dynamic'\r\n */\r\n type?: 'static' | 'dynamic';\r\n\r\n /**\r\n * Optionally pass pre-seeded data, size parameter is ignored\r\n */\r\n data?: Float32Array\r\n}\r\n\r\n/**\r\n * Helper around vertex buffer to simplify creating and uploading geometry\r\n *\r\n * Under the hood uses Float32Array\r\n */\r\nexport class VertexBuffer {\r\n private _gl: WebGL2RenderingContext;\r\n\r\n /**\r\n * Access to the webgl buffer handle\r\n */\r\n public readonly buffer: WebGLBuffer;\r\n /**\r\n * Access to the raw data of the vertex buffer\r\n */\r\n public readonly bufferData: Float32Array;\r\n\r\n /**\r\n * If the vertices never change switching 'static' can be more efficient on the gpu\r\n *\r\n * Default is 'dynamic'\r\n */\r\n public type: 'static' | 'dynamic' = 'dynamic';\r\n\r\n constructor(options: VertexBufferOptions) {\r\n const { gl, size, type, data } = options;\r\n this._gl = gl;\r\n this.buffer = this._gl.createBuffer();\r\n if (!data && !size) {\r\n throw Error('Must either provide data or a size to the VertexBuffer');\r\n }\r\n\r\n if (!data) {\r\n this.bufferData = new Float32Array(size);\r\n } else {\r\n this.bufferData = data;\r\n }\r\n this.type = type ?? this.type;\r\n // Allocate buffer\r\n gl.bindBuffer(gl.ARRAY_BUFFER, this.buffer);\r\n gl.bufferData(gl.ARRAY_BUFFER, this.bufferData, this.type === 'static' ? gl.STATIC_DRAW : gl.DYNAMIC_DRAW);\r\n }\r\n\r\n /**\r\n * Bind this vertex buffer\r\n */\r\n bind() {\r\n const gl = this._gl;\r\n gl.bindBuffer(gl.ARRAY_BUFFER, this.buffer);\r\n\r\n }\r\n\r\n /**\r\n * Upload vertex buffer geometry to the GPU\r\n */\r\n upload(count?: number) {\r\n const gl = this._gl;\r\n gl.bindBuffer(gl.ARRAY_BUFFER, this.buffer);\r\n if (count) {\r\n gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.bufferData, 0, count);\r\n } else {\r\n // TODO always use bufferSubData? need to perf test it\r\n gl.bufferData(gl.ARRAY_BUFFER, this.bufferData, this.type === 'static' ? gl.STATIC_DRAW : gl.DYNAMIC_DRAW);\r\n }\r\n }\r\n}","import { Logger } from '../..';\r\nimport { Shader, VertexAttributeDefinition } from './shader';\r\nimport { VertexBuffer } from './vertex-buffer';\r\nimport { getGlTypeSizeBytes } from './webgl-util';\r\n\r\n\r\nexport interface VertexLayoutOptions {\r\n /**\r\n * WebGL2RenderingContext this layout will be attached to, these cannot be reused across contexts.\r\n */\r\n gl: WebGL2RenderingContext,\r\n /**\r\n * Shader that this layout will be for, if null you must set a shader before using it.\r\n */\r\n shader?: Shader;\r\n /**\r\n * Vertex buffer to use for vertex data\r\n */\r\n vertexBuffer: VertexBuffer,\r\n /**\r\n * Specify the attributes that will exist in the vertex buffer\r\n *\r\n * **Important** must specify them in the order that they will be in the vertex buffer!!\r\n */\r\n attributes: [name: string, numberOfComponents: number][]\r\n}\r\n\r\n/**\r\n * Helper around creating vertex attributes in a given [[VertexBuffer]], this is useful for describing\r\n * the memory layout for your vertices inside a particular buffer\r\n *\r\n * Note: This helper assumes interleaved attributes in one [[VertexBuffer]], not many.\r\n *\r\n * Working with `gl.vertexAttribPointer` can be tricky, and this attempts to double check you\r\n */\r\nexport class VertexLayout {\r\n private _gl: WebGL2RenderingContext;\r\n private _logger = Logger.getInstance();\r\n private _shader: Shader;\r\n private _layout: VertexAttributeDefinition[] = [];\r\n private _attributes: [name: string, numberOfComponents: number][] = [];\r\n private _vertexBuffer: VertexBuffer;\r\n public get vertexBuffer() {\r\n return this._vertexBuffer;\r\n }\r\n\r\n public get attributes(): readonly [name: string, numberOfComponents: number][] {\r\n return this._attributes;\r\n }\r\n\r\n constructor(options: VertexLayoutOptions) {\r\n const {gl, shader, vertexBuffer, attributes} = options;\r\n this._gl = gl;\r\n this._vertexBuffer = vertexBuffer;\r\n this._attributes = attributes;\r\n this._shader = shader;\r\n if (shader) {\r\n this.initialize();\r\n }\r\n }\r\n\r\n private _vertexTotalSizeBytes = 0;\r\n /**\r\n * Total number of bytes that the vertex will take up\r\n */\r\n public get totalVertexSizeBytes(): number {\r\n return this._vertexTotalSizeBytes;\r\n }\r\n\r\n public set shader(shader: Shader) {\r\n if (shader && this._shader !== shader) {\r\n this._shader = shader;\r\n this.initialize();\r\n }\r\n }\r\n\r\n public get shader() {\r\n return this._shader;\r\n }\r\n\r\n /**\r\n * Layouts need shader locations and must be bound to a shader\r\n */\r\n initialize() {\r\n if (!this._shader) {\r\n return;\r\n }\r\n\r\n if (!this._shader.compiled) {\r\n throw Error('Shader not compiled, shader must be compiled before defining a vertex layout');\r\n }\r\n this._layout.length = 0;\r\n const shaderAttributes = this._shader.attributes;\r\n for (const attribute of this._attributes) {\r\n const attrib = shaderAttributes[attribute[0]];\r\n if (!attrib) {\r\n throw Error(`The attribute named: ${attribute[0]} size ${attribute[1]}`+\r\n ` not found in the shader source code:\\n ${this._shader.vertexSource}`);\r\n }\r\n if (attrib.size !== attribute[1]) {\r\n throw Error(`VertexLayout size definition for attribute: [${attribute[0]}, ${attribute[1]}],`\r\n +` doesnt match shader source size ${attrib.size}:\\n ${this._shader.vertexSource}`);\r\n }\r\n this._layout.push(attrib);\r\n }\r\n\r\n // calc size\r\n let componentsPerVertex = 0;\r\n for (const vertAttribute of this._layout) {\r\n const typeSize = getGlTypeSizeBytes(this._gl, vertAttribute.glType);\r\n this._vertexTotalSizeBytes += typeSize * vertAttribute.size;\r\n componentsPerVertex += vertAttribute.size;\r\n }\r\n\r\n if (this._vertexBuffer.bufferData.length % componentsPerVertex !== 0) {\r\n this._logger.warn(`The vertex component size (${componentsPerVertex}) does divide evenly into the specified vertex buffer`\r\n +` (${this._vertexBuffer.bufferData.length})`);\r\n }\r\n }\r\n\r\n /**\r\n * Bind this layout with it's associated vertex buffer\r\n *\r\n * @param uploadBuffer Optionally indicate you wish to upload the buffer to the GPU associated with this layout\r\n */\r\n use(uploadBuffer = false, count?: number) {\r\n if (!this._shader) {\r\n throw Error('No shader is associated with this vertex layout, a shader must be set');\r\n }\r\n\r\n const gl = this._gl;\r\n if (!this._shader.isCurrentlyBound()) {\r\n throw Error('Shader associated with this vertex layout is not active! Call shader.use() before layout.use()');\r\n }\r\n this._vertexBuffer.bind();\r\n if (uploadBuffer) {\r\n this._vertexBuffer.upload(count);\r\n }\r\n let offset = 0;\r\n // TODO switch to VAOs if the extension is\r\n for (const vert of this._layout) {\r\n gl.vertexAttribPointer(vert.location, vert.size, vert.glType, vert.normalized, this.totalVertexSizeBytes, offset);\r\n gl.enableVertexAttribArray(vert.location);\r\n offset += getGlTypeSizeBytes(gl, vert.glType) * vert.size;\r\n }\r\n }\r\n}","export class GraphicsDiagnostics {\r\n public static DrawCallCount: number = 0;\r\n public static DrawnImagesCount: number = 0;\r\n public static clear(): void {\r\n GraphicsDiagnostics.DrawCallCount = 0;\r\n GraphicsDiagnostics.DrawnImagesCount = 0;\r\n }\r\n}\r\n","import { Vector } from '../../../Math/vector';\r\nimport { Color } from '../../../Color';\r\nimport lineVertexSource from './line-vertex.glsl';\r\nimport lineFragmentSource from './line-fragment.glsl';\r\nimport { ExcaliburGraphicsContextWebGL } from '../ExcaliburGraphicsContextWebGL';\r\nimport { RendererPlugin } from '../renderer';\r\nimport { Shader, VertexBuffer, VertexLayout } from '../..';\r\nimport { GraphicsDiagnostics } from '../../GraphicsDiagnostics';\r\n\r\nexport class LineRenderer implements RendererPlugin {\r\n public readonly type = 'ex.line';\r\n public priority: number = 0;\r\n private _context: ExcaliburGraphicsContextWebGL;\r\n private _gl: WebGL2RenderingContext;\r\n private _shader: Shader;\r\n private _maxLines: number = 10922;\r\n private _vertexBuffer: VertexBuffer;\r\n private _layout: VertexLayout;\r\n private _vertexIndex = 0;\r\n private _lineCount = 0;\r\n initialize(gl: WebGL2RenderingContext, context: ExcaliburGraphicsContextWebGL): void {\r\n this._gl = gl;\r\n this._context = context;\r\n this._shader = new Shader({\r\n gl,\r\n vertexSource: lineVertexSource,\r\n fragmentSource: lineFragmentSource\r\n });\r\n this._shader.compile();\r\n this._shader.use();\r\n\r\n this._shader.setUniformMatrix('u_matrix', this._context.ortho);\r\n\r\n this._vertexBuffer = new VertexBuffer({\r\n gl,\r\n size: 6 * 2 * this._maxLines,\r\n type: 'dynamic'\r\n });\r\n\r\n this._layout = new VertexLayout({\r\n gl,\r\n vertexBuffer: this._vertexBuffer,\r\n shader: this._shader,\r\n attributes: [\r\n ['a_position', 2],\r\n ['a_color', 4]\r\n ]\r\n });\r\n }\r\n\r\n draw(start: Vector, end: Vector, color: Color): void {\r\n // Force a render if the batch is full\r\n if (this._isFull()) {\r\n this.flush();\r\n }\r\n\r\n this._lineCount++;\r\n\r\n const transform = this._context.getTransform();\r\n const finalStart = transform.multiply(start);\r\n const finalEnd = transform.multiply(end);\r\n\r\n\r\n const vertexBuffer = this._vertexBuffer.bufferData;\r\n // Start\r\n vertexBuffer[this._vertexIndex++] = finalStart.x;\r\n vertexBuffer[this._vertexIndex++] = finalStart.y;\r\n vertexBuffer[this._vertexIndex++] = color.r / 255;\r\n vertexBuffer[this._vertexIndex++] = color.g / 255;\r\n vertexBuffer[this._vertexIndex++] = color.b / 255;\r\n vertexBuffer[this._vertexIndex++] = color.a;\r\n\r\n // End\r\n vertexBuffer[this._vertexIndex++] = finalEnd.x;\r\n vertexBuffer[this._vertexIndex++] = finalEnd.y;\r\n vertexBuffer[this._vertexIndex++] = color.r / 255;\r\n vertexBuffer[this._vertexIndex++] = color.g / 255;\r\n vertexBuffer[this._vertexIndex++] = color.b / 255;\r\n vertexBuffer[this._vertexIndex++] = color.a;\r\n }\r\n\r\n private _isFull() {\r\n if (this._lineCount >= this._maxLines) {\r\n return true;\r\n }\r\n return false;\r\n }\r\n\r\n hasPendingDraws(): boolean {\r\n return this._lineCount !== 0;\r\n }\r\n\r\n flush(): void {\r\n // nothing to draw early exit\r\n if (this._lineCount === 0) {\r\n return;\r\n }\r\n\r\n const gl = this._gl;\r\n this._shader.use();\r\n this._layout.use(true);\r\n\r\n this._shader.setUniformMatrix('u_matrix', this._context.ortho);\r\n\r\n gl.drawArrays(gl.LINES, 0, this._lineCount * 2); // 2 verts per line\r\n\r\n GraphicsDiagnostics.DrawnImagesCount += this._lineCount;\r\n GraphicsDiagnostics.DrawCallCount++;\r\n\r\n // reset\r\n this._vertexIndex = 0;\r\n this._lineCount = 0;\r\n }\r\n}\r\n","export default \"#version 300 es\\r\\nin vec2 a_position;\\r\\nin vec4 a_color;\\r\\nin float a_size;\\r\\nout lowp vec4 v_color;\\r\\nuniform mat4 u_matrix;\\r\\n\\r\\nvoid main() {\\r\\n gl_Position = u_matrix * vec4(a_position, 0.0, 1.0);\\r\\n gl_PointSize = a_size * 2.0;\\r\\n v_color = a_color;\\r\\n}\";","export default \"#version 300 es\\r\\n\\r\\nprecision mediump float;\\r\\nin lowp vec4 v_color;\\r\\n\\r\\nout vec4 fragColor;\\r\\n\\r\\nvoid main() {\\r\\n float r = 0.0, delta = 0.0, alpha = 1.0;\\r\\n vec2 cxy = 2.0 * gl_PointCoord - 1.0;\\r\\n r = dot(cxy, cxy);\\r\\n\\r\\n delta = fwidth(r);\\r\\n alpha = 1.0 - smoothstep(1.0 - delta, 1.0 + delta, r);\\r\\n // \\\"premultiply\\\" the color by alpha\\r\\n vec4 color = v_color;\\r\\n color.a = color.a * alpha;\\r\\n color.rgb = color.rgb * color.a;\\r\\n fragColor = color;\\r\\n}\";","import pointVertexSource from './point-vertex.glsl';\r\nimport pointFragmentSource from './point-fragment.glsl';\r\nimport { Vector } from '../../../Math/vector';\r\nimport { Color } from '../../../Color';\r\nimport { ExcaliburGraphicsContextWebGL, pixelSnapEpsilon } from '../ExcaliburGraphicsContextWebGL';\r\nimport { RendererPlugin } from '../renderer';\r\nimport { Shader } from '../shader';\r\nimport { VertexBuffer } from '../vertex-buffer';\r\nimport { VertexLayout } from '../vertex-layout';\r\nimport { GraphicsDiagnostics } from '../../GraphicsDiagnostics';\r\n\r\nexport class PointRenderer implements RendererPlugin {\r\n public readonly type = 'ex.point';\r\n public priority: number = 0;\r\n private _shader: Shader;\r\n private _maxPoints: number = 10922;\r\n private _buffer: VertexBuffer;\r\n private _layout: VertexLayout;\r\n private _gl: WebGLRenderingContext;\r\n private _context: ExcaliburGraphicsContextWebGL;\r\n private _pointCount: number = 0;\r\n private _vertexIndex: number = 0;\r\n initialize(gl: WebGL2RenderingContext, context: ExcaliburGraphicsContextWebGL): void {\r\n this._gl = gl;\r\n this._context = context;\r\n this._shader = new Shader({\r\n gl,\r\n vertexSource: pointVertexSource,\r\n fragmentSource: pointFragmentSource\r\n });\r\n this._shader.compile();\r\n this._shader.use();\r\n this._shader.setUniformMatrix('u_matrix', this._context.ortho);\r\n this._buffer = new VertexBuffer({\r\n gl,\r\n size: 7 * this._maxPoints,\r\n type: 'dynamic'\r\n });\r\n\r\n this._layout = new VertexLayout({\r\n gl,\r\n shader: this._shader,\r\n vertexBuffer: this._buffer,\r\n attributes: [\r\n ['a_position', 2],\r\n ['a_color', 4],\r\n ['a_size', 1]\r\n ]\r\n });\r\n }\r\n\r\n draw(point: Vector, color: Color, size: number): void {\r\n // Force a render if the batch is full\r\n if (this._isFull()) {\r\n this.flush();\r\n }\r\n\r\n this._pointCount++;\r\n\r\n const transform = this._context.getTransform();\r\n const opacity = this._context.opacity;\r\n const snapToPixel = this._context.snapToPixel;\r\n\r\n const finalPoint = transform.multiply(point);\r\n\r\n if (snapToPixel) {\r\n finalPoint.x = ~~(finalPoint.x + pixelSnapEpsilon);\r\n finalPoint.y = ~~(finalPoint.y + pixelSnapEpsilon);\r\n }\r\n\r\n const vertexBuffer = this._buffer.bufferData;\r\n vertexBuffer[this._vertexIndex++] = finalPoint.x;\r\n vertexBuffer[this._vertexIndex++] = finalPoint.y;\r\n vertexBuffer[this._vertexIndex++] = color.r / 255;\r\n vertexBuffer[this._vertexIndex++] = color.g / 255;\r\n vertexBuffer[this._vertexIndex++] = color.b / 255;\r\n vertexBuffer[this._vertexIndex++] = color.a * opacity;\r\n vertexBuffer[this._vertexIndex++] = size * Math.max(transform.getScaleX(), transform.getScaleY());\r\n }\r\n\r\n private _isFull() {\r\n if (this._pointCount >= this._maxPoints) {\r\n return true;\r\n }\r\n return false;\r\n }\r\n\r\n hasPendingDraws(): boolean {\r\n return this._pointCount !== 0;\r\n }\r\n\r\n flush(): void {\r\n // nothing to draw early exit\r\n if (this._pointCount === 0) {\r\n return;\r\n }\r\n\r\n const gl = this._gl;\r\n this._shader.use();\r\n this._layout.use(true);\r\n\r\n this._shader.setUniformMatrix('u_matrix', this._context.ortho);\r\n\r\n gl.drawArrays(gl.POINTS, 0, this._pointCount);\r\n\r\n GraphicsDiagnostics.DrawnImagesCount += this._pointCount;\r\n GraphicsDiagnostics.DrawCallCount++;\r\n\r\n this._pointCount = 0;\r\n this._vertexIndex = 0;\r\n }\r\n}\r\n","export default \"#version 300 es\\r\\nin vec2 a_position;\\r\\n\\r\\nin vec2 a_texcoord;\\r\\nout vec2 v_texcoord;\\r\\n\\r\\nvoid main() {\\r\\n gl_Position = vec4(a_position, 0.0, 1.0);\\r\\n\\r\\n // Pass the texcoord to the fragment shader.\\r\\n v_texcoord = a_texcoord;\\r\\n}\";","export default \"#version 300 es\\r\\nprecision mediump float;\\r\\n\\r\\n// Passed in from the vertex shader.\\r\\nin vec2 v_texcoord;\\r\\n\\r\\n// The texture.\\r\\nuniform sampler2D u_texture;\\r\\n\\r\\nout vec4 fragColor;\\r\\n\\r\\nvoid main() {\\r\\n fragColor = texture(u_texture, v_texcoord);\\r\\n}\";","\r\nimport screenVertex from './screen-vertex.glsl';\r\nimport screenFragment from './screen-fragment.glsl';\r\nimport { Shader } from '../shader';\r\nimport { VertexBuffer } from '../vertex-buffer';\r\nimport { VertexLayout } from '../vertex-layout';\r\nimport { PostProcessor } from '../../PostProcessor/PostProcessor';\r\n\r\n/**\r\n * This is responsible for painting the entire screen during the render passes\r\n */\r\nexport class ScreenPassPainter {\r\n private _gl: WebGLRenderingContext;\r\n private _shader: Shader;\r\n private _buffer: VertexBuffer;\r\n private _layout: VertexLayout;\r\n constructor(gl: WebGL2RenderingContext) {\r\n this._gl = gl;\r\n this._shader = new Shader({\r\n gl,\r\n vertexSource: screenVertex,\r\n fragmentSource: screenFragment\r\n });\r\n this._shader.compile();\r\n // Setup memory layout\r\n this._buffer = new VertexBuffer({\r\n gl,\r\n type: 'static',\r\n // clip space quad + uv since we don't need a camera\r\n data: new Float32Array([\r\n -1, -1, 0, 0,\r\n -1, 1, 0, 1,\r\n 1, -1, 1, 0,\r\n\r\n 1, -1, 1, 0,\r\n -1, 1, 0, 1,\r\n 1, 1, 1, 1\r\n ])\r\n });\r\n this._layout = new VertexLayout({\r\n gl,\r\n shader: this._shader,\r\n vertexBuffer: this._buffer,\r\n attributes: [\r\n ['a_position', 2],\r\n ['a_texcoord', 2]\r\n ]\r\n });\r\n this._buffer.upload();\r\n }\r\n\r\n renderWithPostProcessor(postprocessor: PostProcessor): void {\r\n const gl = this._gl;\r\n postprocessor.getShader().use();\r\n postprocessor.getLayout().use();\r\n gl.drawArrays(gl.TRIANGLES, 0, 6);\r\n }\r\n\r\n renderToScreen(): void {\r\n const gl = this._gl;\r\n this._shader.use();\r\n this._layout.use();\r\n gl.drawArrays(gl.TRIANGLES, 0, 6);\r\n }\r\n}","import { Logger } from '../..';\r\n\r\n/**\r\n * Helper that defines and index buffer for quad geometry\r\n *\r\n * Index buffers allow you to save space in vertex buffers when you share vertices in geometry\r\n * it is almost always worth it in terms of performance to use an index buffer.\r\n */\r\nexport class QuadIndexBuffer {\r\n private _gl: WebGL2RenderingContext;\r\n private _logger: Logger = Logger.getInstance();\r\n /**\r\n * Access to the webgl buffer handle\r\n */\r\n public buffer: WebGLBuffer;\r\n /**\r\n * Access to the raw data of the index buffer\r\n */\r\n public bufferData: Uint16Array | Uint32Array;\r\n /**\r\n * Depending on the browser this is either gl.UNSIGNED_SHORT or gl.UNSIGNED_INT\r\n */\r\n public bufferGlType: number;\r\n\r\n /**\r\n * @param gl WebGL2RenderingContext this layout will be attached to, these cannot be reused across contexts.\r\n * @param numberOfQuads Specify the max number of quads you want to draw\r\n * @param useUint16 Optionally force a uint16 buffer\r\n */\r\n constructor(gl: WebGL2RenderingContext, numberOfQuads: number, useUint16?: boolean) {\r\n this._gl = gl;\r\n this.buffer = gl.createBuffer();\r\n gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.buffer);\r\n\r\n const totalVertices = numberOfQuads * 6;\r\n\r\n if (!useUint16) {\r\n this.bufferData = new Uint32Array(totalVertices);\r\n } else {\r\n // fall back to using gl.UNSIGNED_SHORT or tell the user they are out of luck\r\n const maxUint16 = 65_535;\r\n const maxUint16Index = Math.floor((maxUint16 - 1) / 4); // max quads\r\n\r\n this.bufferGlType = gl.UNSIGNED_SHORT;\r\n this.bufferData = new Uint16Array(totalVertices);\r\n // TODO Should we error if this happens?? maybe not might crash mid game\r\n if (numberOfQuads > maxUint16Index) {\r\n this._logger.warn(\r\n `Total quads exceeds hardware index buffer limit (uint16), max(${maxUint16Index}) requested quads(${numberOfQuads})`);\r\n }\r\n }\r\n\r\n\r\n let currentQuad = 0;\r\n for (let i = 0; i < totalVertices; i += 6) {\r\n // first triangle\r\n this.bufferData[i + 0] = currentQuad + 0;\r\n this.bufferData[i + 1] = currentQuad + 1;\r\n this.bufferData[i + 2] = currentQuad + 2;\r\n // second triangle\r\n this.bufferData[i + 3] = currentQuad + 2;\r\n this.bufferData[i + 4] = currentQuad + 1;\r\n this.bufferData[i + 5] = currentQuad + 3;\r\n currentQuad += 4;\r\n }\r\n gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, this.bufferData, gl.STATIC_DRAW);\r\n }\r\n\r\n public get size() {\r\n return this.bufferData.length;\r\n }\r\n\r\n /**\r\n * Upload data to the GPU\r\n */\r\n public upload() {\r\n const gl = this._gl;\r\n gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.buffer);\r\n gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, this.bufferData, gl.STATIC_DRAW);\r\n }\r\n\r\n /**\r\n * Bind this index buffer\r\n */\r\n public bind() {\r\n const gl = this._gl;\r\n gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.buffer);\r\n }\r\n}","export default \"#version 300 es\\r\\nprecision mediump float;\\r\\n\\r\\n// UV coord\\r\\nin vec2 v_texcoord;\\r\\n\\r\\n// Texture index\\r\\nin lowp float v_textureIndex;\\r\\n\\r\\n// Textures in the current draw\\r\\nuniform sampler2D u_textures[%%count%%];\\r\\n\\r\\n// Opacity\\r\\nin float v_opacity;\\r\\n\\r\\nin vec4 v_tint;\\r\\n\\r\\nout vec4 fragColor;\\r\\n\\r\\nvoid main() {\\r\\n // In order to support the most efficient sprite batching, we have multiple\\r\\n // textures loaded into the gpu (usually 8) this picker logic skips over textures\\r\\n // that do not apply to a particular sprite.\\r\\n\\r\\n vec4 color = vec4(1.0, 0, 0, 1.0);\\r\\n\\r\\n // GLSL is templated out to pick the right texture and set the vec4 color\\r\\n %%texture_picker%%\\r\\n\\r\\n color.rgb = color.rgb * v_opacity;\\r\\n color.a = color.a * v_opacity;\\r\\n fragColor = color * v_tint;\\r\\n}\";","export default \"#version 300 es\\r\\nin vec2 a_position;\\r\\n\\r\\n// Opacity \\r\\nin float a_opacity;\\r\\nout float v_opacity;\\r\\n\\r\\n// UV coordinate\\r\\nin vec2 a_texcoord;\\r\\nout vec2 v_texcoord;\\r\\n\\r\\n// Texture number\\r\\nin lowp float a_textureIndex;\\r\\nout lowp float v_textureIndex;\\r\\n\\r\\nin vec4 a_tint;\\r\\nout vec4 v_tint;\\r\\n\\r\\nuniform mat4 u_matrix;\\r\\n\\r\\nvoid main() {\\r\\n // Set the vertex position using the ortho transform matrix\\r\\n gl_Position = u_matrix * vec4(a_position, 0.0, 1.0);\\r\\n\\r\\n // Pass through the Opacity to the fragment shader\\r\\n v_opacity = a_opacity;\\r\\n // Pass through the UV coord to the fragment shader\\r\\n v_texcoord = a_texcoord;\\r\\n // Pass through the texture number to the fragment shader\\r\\n v_textureIndex = a_textureIndex;\\r\\n // Pass through the tint\\r\\n v_tint = a_tint;\\r\\n}\";","import { vec } from '../../../Math/vector';\r\nimport { ImageFiltering } from '../../Filtering';\r\nimport { GraphicsDiagnostics } from '../../GraphicsDiagnostics';\r\nimport { HTMLImageSource } from '../ExcaliburGraphicsContext';\r\nimport { ExcaliburGraphicsContextWebGL, pixelSnapEpsilon } from '../ExcaliburGraphicsContextWebGL';\r\nimport { QuadIndexBuffer } from '../quad-index-buffer';\r\nimport { RendererPlugin } from '../renderer';\r\nimport { Shader } from '../shader';\r\nimport { VertexBuffer } from '../vertex-buffer';\r\nimport { VertexLayout } from '../vertex-layout';\r\nimport frag from './image-renderer.frag.glsl';\r\nimport vert from './image-renderer.vert.glsl';\r\n\r\nexport class ImageRenderer implements RendererPlugin {\r\n public readonly type = 'ex.image';\r\n public priority: number = 0;\r\n\r\n private _maxImages: number = 10922; // max(uint16) / 6 verts\r\n private _maxTextures: number = 0;\r\n\r\n private _context: ExcaliburGraphicsContextWebGL;\r\n private _gl: WebGLRenderingContext;\r\n private _shader: Shader;\r\n private _buffer: VertexBuffer;\r\n private _layout: VertexLayout;\r\n private _quads: QuadIndexBuffer;\r\n\r\n // Per flush vars\r\n private _imageCount: number = 0;\r\n private _textures: WebGLTexture[] = [];\r\n private _vertexIndex: number = 0;\r\n\r\n initialize(gl: WebGL2RenderingContext, context: ExcaliburGraphicsContextWebGL): void {\r\n this._gl = gl;\r\n this._context = context;\r\n // Transform shader source\r\n // FIXME: PIXEL 6 complains `ERROR: Expression too complex.` if we use it's reported max texture units, 125 seems to work for now...\r\n this._maxTextures = Math.min(gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS), 125);\r\n const transformedFrag = this._transformFragmentSource(frag, this._maxTextures);\r\n // Compile shader\r\n this._shader = new Shader({\r\n gl,\r\n fragmentSource: transformedFrag,\r\n vertexSource: vert\r\n });\r\n this._shader.compile();\r\n\r\n // setup uniforms\r\n this._shader.use();\r\n this._shader.setUniformMatrix('u_matrix', context.ortho);\r\n // Initialize texture slots to [0, 1, 2, 3, 4, .... maxGPUTextures]\r\n this._shader.setUniformIntArray(\r\n 'u_textures',\r\n [...Array(this._maxTextures)].map((_, i) => i)\r\n );\r\n\r\n // Setup memory layout\r\n this._buffer = new VertexBuffer({\r\n gl,\r\n size: 10 * 4 * this._maxImages, // 10 components * 4 verts\r\n type: 'dynamic'\r\n });\r\n this._layout = new VertexLayout({\r\n gl,\r\n shader: this._shader,\r\n vertexBuffer: this._buffer,\r\n attributes: [\r\n ['a_position', 2],\r\n ['a_opacity', 1],\r\n ['a_texcoord', 2],\r\n ['a_textureIndex', 1],\r\n ['a_tint', 4]\r\n ]\r\n });\r\n\r\n // Setup index buffer\r\n this._quads = new QuadIndexBuffer(gl, this._maxImages, true);\r\n }\r\n\r\n private _transformFragmentSource(source: string, maxTextures: number): string {\r\n let newSource = source.replace('%%count%%', maxTextures.toString());\r\n let texturePickerBuilder = '';\r\n for (let i = 0; i < maxTextures; i++) {\r\n if (i === 0) {\r\n texturePickerBuilder += `if (v_textureIndex <= ${i}.5) {\\n`;\r\n } else {\r\n texturePickerBuilder += ` else if (v_textureIndex <= ${i}.5) {\\n`;\r\n }\r\n texturePickerBuilder += ` color = texture(u_textures[${i}], v_texcoord);\\n`;\r\n texturePickerBuilder += ` }\\n`;\r\n }\r\n newSource = newSource.replace('%%texture_picker%%', texturePickerBuilder);\r\n return newSource;\r\n }\r\n\r\n private _addImageAsTexture(image: HTMLImageSource) {\r\n const maybeFiltering = image.getAttribute('filtering');\r\n let filtering: ImageFiltering = null;\r\n if (maybeFiltering === ImageFiltering.Blended ||\r\n maybeFiltering === ImageFiltering.Pixel) {\r\n filtering = maybeFiltering;\r\n }\r\n\r\n const force = image.getAttribute('forceUpload') === 'true' ? true : false;\r\n const texture = this._context.textureLoader.load(image, filtering, force);\r\n // remove force attribute after upload\r\n image.removeAttribute('forceUpload');\r\n if (this._textures.indexOf(texture) === -1) {\r\n this._textures.push(texture);\r\n }\r\n }\r\n\r\n private _bindTextures(gl: WebGLRenderingContext) {\r\n // Bind textures in the correct order\r\n for (let i = 0; i < this._maxTextures; i++) {\r\n gl.activeTexture(gl.TEXTURE0 + i);\r\n gl.bindTexture(gl.TEXTURE_2D, this._textures[i] || this._textures[0]);\r\n }\r\n }\r\n\r\n private _getTextureIdForImage(image: HTMLImageSource) {\r\n if (image) {\r\n const maybeTexture = this._context.textureLoader.get(image);\r\n return this._textures.indexOf(maybeTexture);\r\n }\r\n return -1;\r\n }\r\n\r\n private _isFull() {\r\n if (this._imageCount >= this._maxImages) {\r\n return true;\r\n }\r\n if (this._textures.length >= this._maxTextures) {\r\n return true;\r\n }\r\n return false;\r\n }\r\n\r\n\r\n draw(image: HTMLImageSource,\r\n sx: number,\r\n sy: number,\r\n swidth?: number,\r\n sheight?: number,\r\n dx?: number,\r\n dy?: number,\r\n dwidth?: number,\r\n dheight?: number): void {\r\n\r\n // Force a render if the batch is full\r\n if (this._isFull()) {\r\n this.flush();\r\n }\r\n\r\n this._imageCount++;\r\n // This creates and uploads the texture if not already done\r\n this._addImageAsTexture(image);\r\n\r\n let width = image?.width || swidth || 0;\r\n let height = image?.height || sheight || 0;\r\n let view = [0, 0, swidth ?? image?.width ?? 0, sheight ?? image?.height ?? 0];\r\n let dest = [sx ?? 1, sy ?? 1];\r\n // If destination is specified, update view and dest\r\n if (dx !== undefined && dy !== undefined && dwidth !== undefined && dheight !== undefined) {\r\n view = [sx ?? 1, sy ?? 1, swidth ?? image?.width ?? 0, sheight ?? image?.height ?? 0];\r\n dest = [dx, dy];\r\n width = dwidth;\r\n height = dheight;\r\n }\r\n\r\n sx = view[0];\r\n sy = view[1];\r\n const sw = view[2];\r\n const sh = view[3];\r\n\r\n // transform based on current context\r\n const transform = this._context.getTransform();\r\n const opacity = this._context.opacity;\r\n const snapToPixel = this._context.snapToPixel;\r\n\r\n let topLeft = vec(dest[0], dest[1]);\r\n let topRight = vec(dest[0] + width, dest[1]);\r\n let bottomLeft = vec(dest[0], dest[1] + height);\r\n let bottomRight = vec(dest[0] + width, dest[1] + height);\r\n\r\n topLeft = transform.multiply(topLeft);\r\n topRight = transform.multiply(topRight);\r\n bottomLeft = transform.multiply(bottomLeft);\r\n bottomRight = transform.multiply(bottomRight);\r\n\r\n if (snapToPixel) {\r\n topLeft.x = ~~(topLeft.x + pixelSnapEpsilon);\r\n topLeft.y = ~~(topLeft.y + pixelSnapEpsilon);\r\n\r\n topRight.x = ~~(topRight.x + pixelSnapEpsilon);\r\n topRight.y = ~~(topRight.y + pixelSnapEpsilon);\r\n\r\n bottomLeft.x = ~~(bottomLeft.x + pixelSnapEpsilon);\r\n bottomLeft.y = ~~(bottomLeft.y + pixelSnapEpsilon);\r\n\r\n bottomRight.x = ~~(bottomRight.x + pixelSnapEpsilon);\r\n bottomRight.y = ~~(bottomRight.y + pixelSnapEpsilon);\r\n }\r\n\r\n const tint = this._context.tint;\r\n\r\n const textureId = this._getTextureIdForImage(image);\r\n const imageWidth = image.width || width;\r\n const imageHeight = image.height || height;\r\n\r\n const uvx0 = (sx) / imageWidth;\r\n const uvy0 = (sy) / imageHeight;\r\n const uvx1 = (sx + sw - 0.01) / imageWidth;\r\n const uvy1 = (sy + sh - 0.01) / imageHeight;\r\n\r\n // update data\r\n const vertexBuffer = this._layout.vertexBuffer.bufferData;\r\n\r\n // (0, 0) - 0\r\n vertexBuffer[this._vertexIndex++] = topLeft.x;\r\n vertexBuffer[this._vertexIndex++] = topLeft.y;\r\n vertexBuffer[this._vertexIndex++] = opacity;\r\n vertexBuffer[this._vertexIndex++] = uvx0;\r\n vertexBuffer[this._vertexIndex++] = uvy0;\r\n vertexBuffer[this._vertexIndex++] = textureId;\r\n vertexBuffer[this._vertexIndex++] = tint.r / 255;\r\n vertexBuffer[this._vertexIndex++] = tint.g / 255;\r\n vertexBuffer[this._vertexIndex++] = tint.b / 255;\r\n vertexBuffer[this._vertexIndex++] = tint.a;\r\n\r\n // (0, 1) - 1\r\n vertexBuffer[this._vertexIndex++] = bottomLeft.x;\r\n vertexBuffer[this._vertexIndex++] = bottomLeft.y;\r\n vertexBuffer[this._vertexIndex++] = opacity;\r\n vertexBuffer[this._vertexIndex++] = uvx0;\r\n vertexBuffer[this._vertexIndex++] = uvy1;\r\n vertexBuffer[this._vertexIndex++] = textureId;\r\n vertexBuffer[this._vertexIndex++] = tint.r / 255;\r\n vertexBuffer[this._vertexIndex++] = tint.g / 255;\r\n vertexBuffer[this._vertexIndex++] = tint.b / 255;\r\n vertexBuffer[this._vertexIndex++] = tint.a;\r\n\r\n // (1, 0) - 2\r\n vertexBuffer[this._vertexIndex++] = topRight.x;\r\n vertexBuffer[this._vertexIndex++] = topRight.y;\r\n vertexBuffer[this._vertexIndex++] = opacity;\r\n vertexBuffer[this._vertexIndex++] = uvx1;\r\n vertexBuffer[this._vertexIndex++] = uvy0;\r\n vertexBuffer[this._vertexIndex++] = textureId;\r\n vertexBuffer[this._vertexIndex++] = tint.r / 255;\r\n vertexBuffer[this._vertexIndex++] = tint.g / 255;\r\n vertexBuffer[this._vertexIndex++] = tint.b / 255;\r\n vertexBuffer[this._vertexIndex++] = tint.a;\r\n\r\n // (1, 1) - 3\r\n vertexBuffer[this._vertexIndex++] = bottomRight.x;\r\n vertexBuffer[this._vertexIndex++] = bottomRight.y;\r\n vertexBuffer[this._vertexIndex++] = opacity;\r\n vertexBuffer[this._vertexIndex++] = uvx1;\r\n vertexBuffer[this._vertexIndex++] = uvy1;\r\n vertexBuffer[this._vertexIndex++] = textureId;\r\n vertexBuffer[this._vertexIndex++] = tint.r / 255;\r\n vertexBuffer[this._vertexIndex++] = tint.g / 255;\r\n vertexBuffer[this._vertexIndex++] = tint.b / 255;\r\n vertexBuffer[this._vertexIndex++] = tint.a;\r\n }\r\n\r\n hasPendingDraws(): boolean {\r\n return this._imageCount !== 0;\r\n }\r\n\r\n flush(): void {\r\n // nothing to draw early exit\r\n if (this._imageCount === 0) {\r\n return;\r\n }\r\n\r\n const gl = this._gl;\r\n // Bind the shader\r\n this._shader.use();\r\n\r\n // Bind the memory layout and upload data\r\n this._layout.use(true, 4 * 10 * this._imageCount);\r\n\r\n // Update ortho matrix uniform\r\n this._shader.setUniformMatrix('u_matrix', this._context.ortho);\r\n\r\n // Bind textures to\r\n this._bindTextures(gl);\r\n\r\n // Bind index buffer\r\n this._quads.bind();\r\n\r\n // Draw all the quads\r\n gl.drawElements(gl.TRIANGLES, this._imageCount * 6, this._quads.bufferGlType, 0);\r\n\r\n GraphicsDiagnostics.DrawnImagesCount += this._imageCount;\r\n GraphicsDiagnostics.DrawCallCount++;\r\n\r\n // Reset\r\n this._imageCount = 0;\r\n this._vertexIndex = 0;\r\n this._textures.length = 0;\r\n }\r\n}","export default \"#version 300 es\\r\\n\\r\\nprecision mediump float;\\r\\n\\r\\n// UV coord\\r\\nin vec2 v_uv;\\r\\n\\r\\nin vec2 v_size; // in pixels\\r\\n\\r\\n// Color coord to blend with image\\r\\nin lowp vec4 v_color;\\r\\n\\r\\n// Stroke color if used\\r\\nin lowp vec4 v_strokeColor;\\r\\n\\r\\n// Stroke thickness if used\\r\\nin lowp float v_strokeThickness; // in pixels\\r\\n\\r\\n// Opacity\\r\\nin float v_opacity;\\r\\n\\r\\nout vec4 fragColor;\\r\\n\\r\\nvoid main() {\\r\\n // modified from https://stackoverflow.com/questions/59197671/glsl-rounded-rectangle-with-variable-border\\r\\n vec2 uv = v_uv;\\r\\n vec2 fragCoord = uv * v_size;\\r\\n float maxX = v_size.x - v_strokeThickness;\\r\\n float minX = v_strokeThickness;\\r\\n float maxY = v_size.y - v_strokeThickness;\\r\\n float minY = v_strokeThickness;\\r\\n\\r\\n if (fragCoord.x < maxX && fragCoord.x > minX &&\\r\\n fragCoord.y < maxY && fragCoord.y > minY) {\\r\\n fragColor = v_color;\\r\\n } else {\\r\\n fragColor = v_strokeColor;\\r\\n }\\r\\n fragColor.a *= v_opacity;\\r\\n fragColor.rgb *= fragColor.a;\\r\\n\\r\\n // vec2 v2CenteredPos = abs(fragCoord - v_size.xy / 2.0);\\r\\n // vec2 v2HalfShapeSizePx = v_size.xy/2.0 - v_strokeThickness/2.0;\\r\\n\\r\\n // float fHalfBorderDist = 0.0;\\r\\n // float fHalfBorderThickness = 0.0;\\r\\n\\r\\n // if (fragCoord.x > max(v_radius, v_strokeThickness) && \\r\\n // fragCoord.x < v_size.x - max(v_radius, v_strokeThickness))\\r\\n // {\\r\\n // fHalfBorderDist = v2CenteredPos.y - v2HalfShapeSizePx.y;\\r\\n // fHalfBorderThickness = v_strokeThickness / 2.0;\\r\\n // }\\r\\n // else if (fragCoord.y > max(v_radius, v_strokeThickness) && \\r\\n // fragCoord.y < v_size.y - max(v_radius, v_strokeThickness))\\r\\n // {\\r\\n // fHalfBorderDist = v2CenteredPos.x - v2HalfShapeSizePx.x;\\r\\n // fHalfBorderThickness = v_strokeThickness / 2.0;\\r\\n // }\\r\\n // else\\r\\n // {\\r\\n // vec2 edgeVec = max(vec2(0.0), v_radius - vec2(\\r\\n // uv.x > 0.5 ? v_size.x - fragCoord.x : fragCoord.x,\\r\\n // uv.y > 0.5 ? v_size.y - fragCoord.y : fragCoord.y));\\r\\n \\r\\n // float ellipse_ab = v_radius-v_strokeThickness;\\r\\n // vec2 ellipse_isect = (v_strokeThickness > v_radius || v_strokeThickness > v_radius) ? vec2(0.0) :\\r\\n // edgeVec.xy * ellipse_ab*ellipse_ab / length(ellipse_ab*edgeVec.yx); \\r\\n \\r\\n // fHalfBorderThickness = (v_radius - length(ellipse_isect)) / 2.0;\\r\\n // fHalfBorderDist = length(edgeVec) - (v_radius - fHalfBorderThickness);\\r\\n // }\\r\\n\\r\\n // vec4 v4FromColor = v_strokeColor;\\r\\n // v4FromColor.rgb *= v4FromColor.a;\\r\\n // vec4 v4ToColor = vec4(0.0); // background color is transparent\\r\\n // if (fHalfBorderDist < 0.0) {\\r\\n // v4ToColor = v_color;\\r\\n // v4ToColor.rgb *= v4ToColor.a;\\r\\n // }\\r\\n\\r\\n // float mixPct = abs(fHalfBorderDist) - fHalfBorderThickness;\\r\\n\\r\\n // vec4 finalColor = mix(v4FromColor, v4ToColor, mixPct);\\r\\n // gl_FragColor = finalColor;\\r\\n}\";","export default \"#version 300 es\\r\\nin vec2 a_position;\\r\\n\\r\\n// UV coordinate\\r\\nin vec2 a_uv;\\r\\nout vec2 v_uv;\\r\\n\\r\\nin vec2 a_size;\\r\\nout vec2 v_size;\\r\\n\\r\\n// Opacity \\r\\nin float a_opacity;\\r\\nout float v_opacity;\\r\\n\\r\\nin vec4 a_color;\\r\\nout vec4 v_color;\\r\\n\\r\\nin vec4 a_strokeColor;\\r\\nout vec4 v_strokeColor;\\r\\n\\r\\nin float a_strokeThickness;\\r\\nout float v_strokeThickness;\\r\\n\\r\\nuniform mat4 u_matrix;\\r\\n\\r\\n\\r\\nvoid main() {\\r\\n // Set the vertex position using the ortho transform matrix\\r\\n gl_Position = u_matrix * vec4(a_position, 0.0, 1.0);\\r\\n\\r\\n // Pass through UV coords\\r\\n v_uv = a_uv;\\r\\n // Pass through size\\r\\n v_size = a_size;\\r\\n // Pass through the Opacity to the fragment shader\\r\\n v_opacity = a_opacity;\\r\\n // Pass through the color to the fragment shader\\r\\n v_color = a_color;\\r\\n // Pass through the stroke color to the fragment shader\\r\\n v_strokeColor = a_strokeColor;\\r\\n // Pass through the stroke thickenss to the fragment shader\\r\\n v_strokeThickness = a_strokeThickness;\\r\\n}\";","import { Color } from '../../../Color';\r\nimport { vec, Vector } from '../../../Math/vector';\r\nimport { GraphicsDiagnostics } from '../../GraphicsDiagnostics';\r\nimport { ExcaliburGraphicsContextWebGL, pixelSnapEpsilon } from '../ExcaliburGraphicsContextWebGL';\r\nimport { QuadIndexBuffer } from '../quad-index-buffer';\r\nimport { RendererPlugin } from '../renderer';\r\nimport { Shader } from '../shader';\r\nimport { VertexBuffer } from '../vertex-buffer';\r\nimport { VertexLayout } from '../vertex-layout';\r\n\r\nimport frag from './rectangle-renderer.frag.glsl';\r\nimport vert from './rectangle-renderer.vert.glsl';\r\n\r\nexport class RectangleRenderer implements RendererPlugin {\r\n public readonly type = 'ex.rectangle';\r\n public priority: number = 0;\r\n\r\n private _maxRectangles: number = 10922; // max(uint16) / 6 verts\r\n\r\n private _shader: Shader;\r\n private _gl: WebGLRenderingContext;\r\n private _context: ExcaliburGraphicsContextWebGL;\r\n private _buffer: VertexBuffer;\r\n private _layout: VertexLayout;\r\n private _quads: QuadIndexBuffer;\r\n private _rectangleCount: number = 0;\r\n private _vertexIndex: number = 0;\r\n\r\n\r\n initialize(gl: WebGL2RenderingContext, context: ExcaliburGraphicsContextWebGL): void {\r\n this._gl = gl;\r\n this._context = context;\r\n // https://stackoverflow.com/questions/59197671/glsl-rounded-rectangle-with-variable-border\r\n this._shader = new Shader({\r\n gl,\r\n fragmentSource: frag,\r\n vertexSource: vert\r\n });\r\n this._shader.compile();\r\n\r\n // setup uniforms\r\n this._shader.use();\r\n this._shader.setUniformMatrix('u_matrix', context.ortho);\r\n\r\n this._buffer = new VertexBuffer({\r\n gl,\r\n size: 16 * 4 * this._maxRectangles,\r\n type: 'dynamic'\r\n });\r\n\r\n this._layout = new VertexLayout({\r\n gl,\r\n shader: this._shader,\r\n vertexBuffer: this._buffer,\r\n attributes: [\r\n ['a_position', 2],\r\n ['a_uv', 2],\r\n ['a_size', 2],\r\n ['a_opacity', 1],\r\n ['a_color', 4],\r\n ['a_strokeColor', 4],\r\n ['a_strokeThickness', 1]\r\n ]\r\n });\r\n this._quads = new QuadIndexBuffer(gl, this._maxRectangles, true);\r\n }\r\n\r\n private _isFull() {\r\n if (this._rectangleCount >= this._maxRectangles) {\r\n return true;\r\n }\r\n return false;\r\n }\r\n\r\n draw(...args: any[]): void {\r\n if (args[0] instanceof Vector && args[1] instanceof Vector) {\r\n this.drawLine.apply(this, args);\r\n } else {\r\n this.drawRectangle.apply(this, args);\r\n }\r\n }\r\n\r\n drawLine(start: Vector, end: Vector, color: Color, thickness: number = 1) {\r\n\r\n if (this._isFull()) {\r\n this.flush();\r\n }\r\n this._rectangleCount++;\r\n\r\n // transform based on current context\r\n const transform = this._context.getTransform();\r\n const opacity = this._context.opacity;\r\n const snapToPixel = this._context.snapToPixel;\r\n\r\n const dir = end.sub(start);\r\n const length = dir.size;\r\n const normal = dir.normalize().perpendicular();\r\n const halfThick = thickness / 2;\r\n\r\n /**\r\n * +---------------------^----------------------+\r\n * | | (normal) |\r\n * (startx, starty)------------------>(endx, endy)\r\n * | |\r\n * + -------------------------------------------+\r\n */\r\n const startTop = transform.multiply(normal.scale(halfThick).add(start));\r\n const startBottom = transform.multiply(normal.scale(-halfThick).add(start));\r\n const endTop = transform.multiply(normal.scale(halfThick).add(end));\r\n const endBottom = transform.multiply(normal.scale(-halfThick).add(end));\r\n\r\n if (snapToPixel) {\r\n startTop.x = ~~(startTop.x + pixelSnapEpsilon);\r\n startTop.y = ~~(startTop.y + pixelSnapEpsilon);\r\n\r\n endTop.x = ~~(endTop.x + pixelSnapEpsilon);\r\n endTop.y = ~~(endTop.y + pixelSnapEpsilon);\r\n\r\n startBottom.x = ~~(startBottom.x + pixelSnapEpsilon);\r\n startBottom.y = ~~(startBottom.y + pixelSnapEpsilon);\r\n\r\n endBottom.x = ~~(endBottom.x + pixelSnapEpsilon);\r\n endBottom.y = ~~(endBottom.y + pixelSnapEpsilon);\r\n }\r\n\r\n // TODO uv could be static vertex buffer\r\n const uvx0 = 0;\r\n const uvy0 = 0;\r\n const uvx1 = 1;\r\n const uvy1 = 1;\r\n\r\n const stroke = Color.Transparent;\r\n const strokeThickness = 0;\r\n const width = 1;\r\n\r\n // update data\r\n const vertexBuffer = this._layout.vertexBuffer.bufferData;\r\n\r\n // (0, 0) - 0\r\n vertexBuffer[this._vertexIndex++] = startTop.x;\r\n vertexBuffer[this._vertexIndex++] = startTop.y;\r\n vertexBuffer[this._vertexIndex++] = uvx0;\r\n vertexBuffer[this._vertexIndex++] = uvy0;\r\n vertexBuffer[this._vertexIndex++] = length;\r\n vertexBuffer[this._vertexIndex++] = thickness;\r\n vertexBuffer[this._vertexIndex++] = opacity;\r\n vertexBuffer[this._vertexIndex++] = color.r / 255;\r\n vertexBuffer[this._vertexIndex++] = color.g / 255;\r\n vertexBuffer[this._vertexIndex++] = color.b / 255;\r\n vertexBuffer[this._vertexIndex++] = color.a;\r\n vertexBuffer[this._vertexIndex++] = stroke.r / 255;\r\n vertexBuffer[this._vertexIndex++] = stroke.g / 255;\r\n vertexBuffer[this._vertexIndex++] = stroke.b / 255;\r\n vertexBuffer[this._vertexIndex++] = stroke.a;\r\n vertexBuffer[this._vertexIndex++] = strokeThickness / width;\r\n\r\n // (0, 1) - 1\r\n vertexBuffer[this._vertexIndex++] = startBottom.x;\r\n vertexBuffer[this._vertexIndex++] = startBottom.y;\r\n vertexBuffer[this._vertexIndex++] = uvx0;\r\n vertexBuffer[this._vertexIndex++] = uvy1;\r\n vertexBuffer[this._vertexIndex++] = length;\r\n vertexBuffer[this._vertexIndex++] = thickness;\r\n vertexBuffer[this._vertexIndex++] = opacity;\r\n vertexBuffer[this._vertexIndex++] = color.r / 255;\r\n vertexBuffer[this._vertexIndex++] = color.g / 255;\r\n vertexBuffer[this._vertexIndex++] = color.b / 255;\r\n vertexBuffer[this._vertexIndex++] = color.a;\r\n vertexBuffer[this._vertexIndex++] = stroke.r / 255;\r\n vertexBuffer[this._vertexIndex++] = stroke.g / 255;\r\n vertexBuffer[this._vertexIndex++] = stroke.b / 255;\r\n vertexBuffer[this._vertexIndex++] = stroke.a;\r\n vertexBuffer[this._vertexIndex++] = strokeThickness / width;\r\n\r\n // (1, 0) - 2\r\n vertexBuffer[this._vertexIndex++] = endTop.x;\r\n vertexBuffer[this._vertexIndex++] = endTop.y;\r\n vertexBuffer[this._vertexIndex++] = uvx1;\r\n vertexBuffer[this._vertexIndex++] = uvy0;\r\n vertexBuffer[this._vertexIndex++] = length;\r\n vertexBuffer[this._vertexIndex++] = thickness;\r\n vertexBuffer[this._vertexIndex++] = opacity;\r\n vertexBuffer[this._vertexIndex++] = color.r / 255;\r\n vertexBuffer[this._vertexIndex++] = color.g / 255;\r\n vertexBuffer[this._vertexIndex++] = color.b / 255;\r\n vertexBuffer[this._vertexIndex++] = color.a;\r\n vertexBuffer[this._vertexIndex++] = stroke.r / 255;\r\n vertexBuffer[this._vertexIndex++] = stroke.g / 255;\r\n vertexBuffer[this._vertexIndex++] = stroke.b / 255;\r\n vertexBuffer[this._vertexIndex++] = stroke.a;\r\n vertexBuffer[this._vertexIndex++] = strokeThickness / width;\r\n\r\n // (1, 1) - 3\r\n vertexBuffer[this._vertexIndex++] = endBottom.x;\r\n vertexBuffer[this._vertexIndex++] = endBottom.y;\r\n vertexBuffer[this._vertexIndex++] = uvx1;\r\n vertexBuffer[this._vertexIndex++] = uvy1;\r\n vertexBuffer[this._vertexIndex++] = length;\r\n vertexBuffer[this._vertexIndex++] = thickness;\r\n vertexBuffer[this._vertexIndex++] = opacity;\r\n vertexBuffer[this._vertexIndex++] = color.r / 255;\r\n vertexBuffer[this._vertexIndex++] = color.g / 255;\r\n vertexBuffer[this._vertexIndex++] = color.b / 255;\r\n vertexBuffer[this._vertexIndex++] = color.a;\r\n vertexBuffer[this._vertexIndex++] = stroke.r / 255;\r\n vertexBuffer[this._vertexIndex++] = stroke.g / 255;\r\n vertexBuffer[this._vertexIndex++] = stroke.b / 255;\r\n vertexBuffer[this._vertexIndex++] = stroke.a;\r\n vertexBuffer[this._vertexIndex++] = strokeThickness / width;\r\n }\r\n\r\n drawRectangle(\r\n pos: Vector,\r\n width: number,\r\n height: number,\r\n color: Color,\r\n stroke: Color = Color.Transparent,\r\n strokeThickness: number = 0): void {\r\n if (this._isFull()) {\r\n this.flush();\r\n }\r\n this._rectangleCount++;\r\n\r\n // transform based on current context\r\n const transform = this._context.getTransform();\r\n const opacity = this._context.opacity;\r\n const snapToPixel = this._context.snapToPixel;\r\n\r\n const topLeft = transform.multiply(pos.add(vec(0, 0)));\r\n const topRight = transform.multiply(pos.add(vec(width, 0)));\r\n const bottomRight = transform.multiply(pos.add(vec(width, height)));\r\n const bottomLeft = transform.multiply(pos.add(vec(0, height)));\r\n\r\n if (snapToPixel) {\r\n topLeft.x = ~~(topLeft.x + pixelSnapEpsilon);\r\n topLeft.y = ~~(topLeft.y + pixelSnapEpsilon);\r\n\r\n topRight.x = ~~(topRight.x + pixelSnapEpsilon);\r\n topRight.y = ~~(topRight.y + pixelSnapEpsilon);\r\n\r\n bottomLeft.x = ~~(bottomLeft.x + pixelSnapEpsilon);\r\n bottomLeft.y = ~~(bottomLeft.y + pixelSnapEpsilon);\r\n\r\n bottomRight.x = ~~(bottomRight.x + pixelSnapEpsilon);\r\n bottomRight.y = ~~(bottomRight.y + pixelSnapEpsilon);\r\n }\r\n\r\n // TODO uv could be static vertex buffer\r\n const uvx0 = 0;\r\n const uvy0 = 0;\r\n const uvx1 = 1;\r\n const uvy1 = 1;\r\n\r\n // update data\r\n const vertexBuffer = this._layout.vertexBuffer.bufferData;\r\n\r\n // (0, 0) - 0\r\n vertexBuffer[this._vertexIndex++] = topLeft.x;\r\n vertexBuffer[this._vertexIndex++] = topLeft.y;\r\n vertexBuffer[this._vertexIndex++] = uvx0;\r\n vertexBuffer[this._vertexIndex++] = uvy0;\r\n vertexBuffer[this._vertexIndex++] = width;\r\n vertexBuffer[this._vertexIndex++] = height;\r\n vertexBuffer[this._vertexIndex++] = opacity;\r\n vertexBuffer[this._vertexIndex++] = color.r / 255;\r\n vertexBuffer[this._vertexIndex++] = color.g / 255;\r\n vertexBuffer[this._vertexIndex++] = color.b / 255;\r\n vertexBuffer[this._vertexIndex++] = color.a;\r\n vertexBuffer[this._vertexIndex++] = stroke.r / 255;\r\n vertexBuffer[this._vertexIndex++] = stroke.g / 255;\r\n vertexBuffer[this._vertexIndex++] = stroke.b / 255;\r\n vertexBuffer[this._vertexIndex++] = stroke.a;\r\n vertexBuffer[this._vertexIndex++] = strokeThickness;\r\n\r\n // (0, 1) - 1\r\n vertexBuffer[this._vertexIndex++] = bottomLeft.x;\r\n vertexBuffer[this._vertexIndex++] = bottomLeft.y;\r\n vertexBuffer[this._vertexIndex++] = uvx0;\r\n vertexBuffer[this._vertexIndex++] = uvy1;\r\n vertexBuffer[this._vertexIndex++] = width;\r\n vertexBuffer[this._vertexIndex++] = height;\r\n vertexBuffer[this._vertexIndex++] = opacity;\r\n vertexBuffer[this._vertexIndex++] = color.r / 255;\r\n vertexBuffer[this._vertexIndex++] = color.g / 255;\r\n vertexBuffer[this._vertexIndex++] = color.b / 255;\r\n vertexBuffer[this._vertexIndex++] = color.a;\r\n vertexBuffer[this._vertexIndex++] = stroke.r / 255;\r\n vertexBuffer[this._vertexIndex++] = stroke.g / 255;\r\n vertexBuffer[this._vertexIndex++] = stroke.b / 255;\r\n vertexBuffer[this._vertexIndex++] = stroke.a;\r\n vertexBuffer[this._vertexIndex++] = strokeThickness;\r\n\r\n // (1, 0) - 2\r\n vertexBuffer[this._vertexIndex++] = topRight.x;\r\n vertexBuffer[this._vertexIndex++] = topRight.y;\r\n vertexBuffer[this._vertexIndex++] = uvx1;\r\n vertexBuffer[this._vertexIndex++] = uvy0;\r\n vertexBuffer[this._vertexIndex++] = width;\r\n vertexBuffer[this._vertexIndex++] = height;\r\n vertexBuffer[this._vertexIndex++] = opacity;\r\n vertexBuffer[this._vertexIndex++] = color.r / 255;\r\n vertexBuffer[this._vertexIndex++] = color.g / 255;\r\n vertexBuffer[this._vertexIndex++] = color.b / 255;\r\n vertexBuffer[this._vertexIndex++] = color.a;\r\n vertexBuffer[this._vertexIndex++] = stroke.r / 255;\r\n vertexBuffer[this._vertexIndex++] = stroke.g / 255;\r\n vertexBuffer[this._vertexIndex++] = stroke.b / 255;\r\n vertexBuffer[this._vertexIndex++] = stroke.a;\r\n vertexBuffer[this._vertexIndex++] = strokeThickness;\r\n\r\n // (1, 1) - 3\r\n vertexBuffer[this._vertexIndex++] = bottomRight.x;\r\n vertexBuffer[this._vertexIndex++] = bottomRight.y;\r\n vertexBuffer[this._vertexIndex++] = uvx1;\r\n vertexBuffer[this._vertexIndex++] = uvy1;\r\n vertexBuffer[this._vertexIndex++] = width;\r\n vertexBuffer[this._vertexIndex++] = height;\r\n vertexBuffer[this._vertexIndex++] = opacity;\r\n vertexBuffer[this._vertexIndex++] = color.r / 255;\r\n vertexBuffer[this._vertexIndex++] = color.g / 255;\r\n vertexBuffer[this._vertexIndex++] = color.b / 255;\r\n vertexBuffer[this._vertexIndex++] = color.a;\r\n vertexBuffer[this._vertexIndex++] = stroke.r / 255;\r\n vertexBuffer[this._vertexIndex++] = stroke.g / 255;\r\n vertexBuffer[this._vertexIndex++] = stroke.b / 255;\r\n vertexBuffer[this._vertexIndex++] = stroke.a;\r\n vertexBuffer[this._vertexIndex++] = strokeThickness;\r\n\r\n }\r\n\r\n hasPendingDraws(): boolean {\r\n return this._rectangleCount !== 0;\r\n }\r\n\r\n flush(): void {\r\n // nothing to draw early exit\r\n if (this._rectangleCount === 0) {\r\n return;\r\n }\r\n\r\n const gl = this._gl;\r\n // Bind the shader\r\n this._shader.use();\r\n\r\n // Bind the memory layout and upload data\r\n this._layout.use(true);\r\n\r\n // Update ortho matrix uniform\r\n this._shader.setUniformMatrix('u_matrix', this._context.ortho);\r\n\r\n // Bind index buffer\r\n this._quads.bind();\r\n\r\n // Draw all the quads\r\n gl.drawElements(gl.TRIANGLES, this._rectangleCount * 6, this._quads.bufferGlType, 0);\r\n\r\n GraphicsDiagnostics.DrawnImagesCount += this._rectangleCount;\r\n GraphicsDiagnostics.DrawCallCount++;\r\n\r\n // Reset\r\n this._rectangleCount = 0;\r\n this._vertexIndex = 0;\r\n }\r\n\r\n}","export default \"#version 300 es\\r\\nprecision highp float;\\r\\n\\r\\n// UV coord\\r\\nin vec2 v_uv;\\r\\n\\r\\n// Color coord to blend with image\\r\\nin lowp vec4 v_color;\\r\\n\\r\\n// Stroke color if used\\r\\nin lowp vec4 v_strokeColor;\\r\\n\\r\\n// Stroke thickness if used\\r\\nin lowp float v_strokeThickness;\\r\\n\\r\\n// Opacity\\r\\nin float v_opacity;\\r\\n\\r\\nout vec4 fragColor;\\r\\n\\r\\nvoid main() {\\r\\n // make (0, 0) the center the uv \\r\\n vec2 uv = v_uv * 2.0 - 1.0;\\r\\n\\r\\n vec4 color = v_color;\\r\\n vec4 strokeColor = v_strokeColor;\\r\\n\\r\\n // circle border is at radius 1.0 \\r\\n // dist is > 0 when inside the circle \\r\\n float d = length(uv);\\r\\n float dist = 1.0 - length(uv);\\r\\n\\r\\n // Fade based on fwidth\\r\\n float fade = fwidth(dot(uv, uv));\\r\\n\\r\\n // if dist is greater than 0 step to 1;\\r\\n // when we cross this 0 threshold add a smooth fade\\r\\n float fill = smoothstep(-fade/2.0, fade/2.0, dist);\\r\\n\\r\\n // if dist is greater than the stroke thickness step to 1\\r\\n float stroke = 1.0 - smoothstep(v_strokeThickness, v_strokeThickness + fade, dist);\\r\\n\\r\\n strokeColor.a *= fill * stroke;\\r\\n strokeColor.rgb *= strokeColor.a;\\r\\n\\r\\n color.a *= fill * (1.0 - stroke);\\r\\n color.rgb *= color.a;\\r\\n\\r\\n vec4 finalColor = mix(vec4(0.0), (color + strokeColor), fill);\\r\\n finalColor.rgb = finalColor.rgb * v_opacity;\\r\\n finalColor.a = finalColor.a * v_opacity;\\r\\n fragColor = finalColor;\\r\\n}\";","export default \"#version 300 es\\r\\nin vec2 a_position;\\r\\n\\r\\n// UV coordinate\\r\\nin vec2 a_uv;\\r\\nout vec2 v_uv;\\r\\n\\r\\n// Opacity \\r\\nin float a_opacity;\\r\\nout float v_opacity;\\r\\n\\r\\nin vec4 a_color;\\r\\nout vec4 v_color;\\r\\n\\r\\nin vec4 a_strokeColor;\\r\\nout vec4 v_strokeColor;\\r\\n\\r\\nin float a_strokeThickness;\\r\\nout float v_strokeThickness;\\r\\n\\r\\nuniform mat4 u_matrix;\\r\\n\\r\\n\\r\\nvoid main() {\\r\\n // Set the vertex position using the ortho transform matrix\\r\\n gl_Position = u_matrix * vec4(a_position, 0.0, 1.0);\\r\\n\\r\\n // Pass through UV coords\\r\\n v_uv = a_uv;\\r\\n // Pass through the Opacity to the fragment shader\\r\\n v_opacity = a_opacity;\\r\\n // Pass through the color to the fragment shader\\r\\n v_color = a_color;\\r\\n // Pass through the stroke color to the fragment shader\\r\\n v_strokeColor = a_strokeColor;\\r\\n // Pass through the stroke thickenss to the fragment shader\\r\\n v_strokeThickness = a_strokeThickness;\\r\\n}\";","import { Color } from '../../../Color';\r\nimport { vec, Vector } from '../../../Math/vector';\r\nimport { GraphicsDiagnostics } from '../../GraphicsDiagnostics';\r\nimport { ExcaliburGraphicsContextWebGL, pixelSnapEpsilon } from '../ExcaliburGraphicsContextWebGL';\r\nimport { QuadIndexBuffer } from '../quad-index-buffer';\r\nimport { RendererPlugin } from '../renderer';\r\nimport { Shader } from '../shader';\r\nimport { VertexBuffer } from '../vertex-buffer';\r\nimport { VertexLayout } from '../vertex-layout';\r\n\r\nimport frag from './circle-renderer.frag.glsl';\r\nimport vert from './circle-renderer.vert.glsl';\r\n\r\nexport class CircleRenderer implements RendererPlugin {\r\n public readonly type = 'ex.circle';\r\n public priority: number = 0;\r\n\r\n private _maxCircles: number = 10922; // max(uint16) / 6 verts\r\n\r\n private _shader: Shader;\r\n private _context: ExcaliburGraphicsContextWebGL;\r\n private _gl: WebGLRenderingContext;\r\n private _buffer: VertexBuffer;\r\n private _layout: VertexLayout;\r\n private _quads: QuadIndexBuffer;\r\n\r\n private _circleCount: number = 0;\r\n private _vertexIndex: number = 0;\r\n\r\n initialize(gl: WebGL2RenderingContext, context: ExcaliburGraphicsContextWebGL): void {\r\n this._gl = gl;\r\n this._context = context;\r\n this._shader = new Shader({\r\n gl,\r\n fragmentSource: frag,\r\n vertexSource: vert\r\n });\r\n this._shader.compile();\r\n\r\n // setup uniforms\r\n this._shader.use();\r\n this._shader.setUniformMatrix('u_matrix', context.ortho);\r\n\r\n this._buffer = new VertexBuffer({\r\n gl,\r\n size: 14 * 4 * this._maxCircles,\r\n type: 'dynamic'\r\n });\r\n\r\n this._layout = new VertexLayout({\r\n gl,\r\n shader: this._shader,\r\n vertexBuffer: this._buffer,\r\n attributes: [\r\n ['a_position', 2],\r\n ['a_uv', 2],\r\n ['a_opacity', 1],\r\n ['a_color', 4],\r\n ['a_strokeColor', 4],\r\n ['a_strokeThickness', 1]\r\n ]\r\n });\r\n\r\n this._quads = new QuadIndexBuffer(gl, this._maxCircles, true);\r\n }\r\n\r\n private _isFull() {\r\n if (this._circleCount >= this._maxCircles) {\r\n return true;\r\n }\r\n return false;\r\n }\r\n\r\n draw(pos: Vector, radius: number, color: Color, stroke: Color = Color.Transparent, strokeThickness: number = 0): void {\r\n if (this._isFull()) {\r\n this.flush();\r\n }\r\n this._circleCount++;\r\n\r\n // transform based on current context\r\n const transform = this._context.getTransform();\r\n const opacity = this._context.opacity;\r\n const snapToPixel = this._context.snapToPixel;\r\n\r\n const topLeft = transform.multiply(pos.add(vec(-radius, -radius)));\r\n const topRight = transform.multiply(pos.add(vec(radius, -radius)));\r\n const bottomRight = transform.multiply(pos.add(vec(radius, radius)));\r\n const bottomLeft = transform.multiply(pos.add(vec(-radius, radius)));\r\n\r\n if (snapToPixel) {\r\n topLeft.x = ~~(topLeft.x + pixelSnapEpsilon);\r\n topLeft.y = ~~(topLeft.y + pixelSnapEpsilon);\r\n\r\n topRight.x = ~~(topRight.x + pixelSnapEpsilon);\r\n topRight.y = ~~(topRight.y + pixelSnapEpsilon);\r\n\r\n bottomLeft.x = ~~(bottomLeft.x + pixelSnapEpsilon);\r\n bottomLeft.y = ~~(bottomLeft.y + pixelSnapEpsilon);\r\n\r\n bottomRight.x = ~~(bottomRight.x + pixelSnapEpsilon);\r\n bottomRight.y = ~~(bottomRight.y + pixelSnapEpsilon);\r\n }\r\n\r\n // TODO UV could be static vertex buffer\r\n const uvx0 = 0;\r\n const uvy0 = 0;\r\n const uvx1 = 1;\r\n const uvy1 = 1;\r\n\r\n // update data\r\n const vertexBuffer = this._layout.vertexBuffer.bufferData;\r\n\r\n // (0, 0) - 0\r\n vertexBuffer[this._vertexIndex++] = topLeft.x;\r\n vertexBuffer[this._vertexIndex++] = topLeft.y;\r\n vertexBuffer[this._vertexIndex++] = uvx0;\r\n vertexBuffer[this._vertexIndex++] = uvy0;\r\n vertexBuffer[this._vertexIndex++] = opacity;\r\n vertexBuffer[this._vertexIndex++] = color.r / 255;\r\n vertexBuffer[this._vertexIndex++] = color.g / 255;\r\n vertexBuffer[this._vertexIndex++] = color.b / 255;\r\n vertexBuffer[this._vertexIndex++] = color.a;\r\n vertexBuffer[this._vertexIndex++] = stroke.r / 255;\r\n vertexBuffer[this._vertexIndex++] = stroke.g / 255;\r\n vertexBuffer[this._vertexIndex++] = stroke.b / 255;\r\n vertexBuffer[this._vertexIndex++] = stroke.a;\r\n vertexBuffer[this._vertexIndex++] = strokeThickness / radius;\r\n\r\n // (0, 1) - 1\r\n vertexBuffer[this._vertexIndex++] = bottomLeft.x;\r\n vertexBuffer[this._vertexIndex++] = bottomLeft.y;\r\n vertexBuffer[this._vertexIndex++] = uvx0;\r\n vertexBuffer[this._vertexIndex++] = uvy1;\r\n vertexBuffer[this._vertexIndex++] = opacity;\r\n vertexBuffer[this._vertexIndex++] = color.r / 255;\r\n vertexBuffer[this._vertexIndex++] = color.g / 255;\r\n vertexBuffer[this._vertexIndex++] = color.b / 255;\r\n vertexBuffer[this._vertexIndex++] = color.a;\r\n vertexBuffer[this._vertexIndex++] = stroke.r / 255;\r\n vertexBuffer[this._vertexIndex++] = stroke.g / 255;\r\n vertexBuffer[this._vertexIndex++] = stroke.b / 255;\r\n vertexBuffer[this._vertexIndex++] = stroke.a;\r\n vertexBuffer[this._vertexIndex++] = strokeThickness / radius;\r\n\r\n // (1, 0) - 2\r\n vertexBuffer[this._vertexIndex++] = topRight.x;\r\n vertexBuffer[this._vertexIndex++] = topRight.y;\r\n vertexBuffer[this._vertexIndex++] = uvx1;\r\n vertexBuffer[this._vertexIndex++] = uvy0;\r\n vertexBuffer[this._vertexIndex++] = opacity;\r\n vertexBuffer[this._vertexIndex++] = color.r / 255;\r\n vertexBuffer[this._vertexIndex++] = color.g / 255;\r\n vertexBuffer[this._vertexIndex++] = color.b / 255;\r\n vertexBuffer[this._vertexIndex++] = color.a;\r\n vertexBuffer[this._vertexIndex++] = stroke.r / 255;\r\n vertexBuffer[this._vertexIndex++] = stroke.g / 255;\r\n vertexBuffer[this._vertexIndex++] = stroke.b / 255;\r\n vertexBuffer[this._vertexIndex++] = stroke.a;\r\n vertexBuffer[this._vertexIndex++] = strokeThickness / radius;\r\n\r\n // (1, 1) - 3\r\n vertexBuffer[this._vertexIndex++] = bottomRight.x;\r\n vertexBuffer[this._vertexIndex++] = bottomRight.y;\r\n vertexBuffer[this._vertexIndex++] = uvx1;\r\n vertexBuffer[this._vertexIndex++] = uvy1;\r\n vertexBuffer[this._vertexIndex++] = opacity;\r\n vertexBuffer[this._vertexIndex++] = color.r / 255;\r\n vertexBuffer[this._vertexIndex++] = color.g / 255;\r\n vertexBuffer[this._vertexIndex++] = color.b / 255;\r\n vertexBuffer[this._vertexIndex++] = color.a;\r\n vertexBuffer[this._vertexIndex++] = stroke.r / 255;\r\n vertexBuffer[this._vertexIndex++] = stroke.g / 255;\r\n vertexBuffer[this._vertexIndex++] = stroke.b / 255;\r\n vertexBuffer[this._vertexIndex++] = stroke.a;\r\n vertexBuffer[this._vertexIndex++] = strokeThickness / radius;\r\n }\r\n\r\n hasPendingDraws(): boolean {\r\n return this._circleCount !== 0;\r\n }\r\n\r\n flush(): void {\r\n // nothing to draw early exit\r\n if (this._circleCount === 0) {\r\n return;\r\n }\r\n\r\n const gl = this._gl;\r\n // Bind the shader\r\n this._shader.use();\r\n\r\n // Bind the memory layout and upload data\r\n this._layout.use(true);\r\n\r\n // Update ortho matrix uniform\r\n this._shader.setUniformMatrix('u_matrix', this._context.ortho);\r\n\r\n // Bind index buffer\r\n this._quads.bind();\r\n\r\n // Draw all the quads\r\n gl.drawElements(gl.TRIANGLES, this._circleCount * 6, this._quads.bufferGlType, 0);\r\n\r\n GraphicsDiagnostics.DrawnImagesCount += this._circleCount;\r\n GraphicsDiagnostics.DrawCallCount++;\r\n\r\n // Reset\r\n this._circleCount = 0;\r\n this._vertexIndex = 0;\r\n }\r\n\r\n}","import { Logger } from '..';\r\nexport class Pool {\r\n public totalAllocations = 0;\r\n public index = 0;\r\n public objects: Type[] = [];\r\n public disableWarnings = false;\r\n private _logger = Logger.getInstance();\r\n\r\n constructor(\r\n public builder: (...args: any[]) => Type,\r\n public recycler: (instance: Type, ...args: any[]) => Type,\r\n public maxObjects: number = 100\r\n ) {}\r\n\r\n preallocate() {\r\n for (let i = 0; i < this.maxObjects; i++) {\r\n this.objects[i] = this.builder();\r\n }\r\n }\r\n\r\n /**\r\n * Use many instances out of the in the context and return all to the pool.\r\n *\r\n * By returning values out of the context they will be un-hooked from the pool and are free to be passed to consumers\r\n * @param context\r\n */\r\n using(context: (pool: Pool) => Type[] | void) {\r\n const result = context(this);\r\n if (result) {\r\n return this.done(...result);\r\n }\r\n return this.done();\r\n }\r\n\r\n /**\r\n * Use a single instance out of th pool and immediately return it to the pool\r\n * @param context\r\n */\r\n borrow(context: (object: Type) => void) {\r\n const object = this.get();\r\n context(object);\r\n this.index--;\r\n }\r\n\r\n /**\r\n * Retrieve a value from the pool, will allocate a new instance if necessary or recycle from the pool\r\n * @param args\r\n */\r\n get(...args: any[]): Type {\r\n if (this.index === this.maxObjects) {\r\n if (!this.disableWarnings) {\r\n this._logger.warn('Max pooled objects reached, possible memory leak? Doubling');\r\n }\r\n this.maxObjects = this.maxObjects * 2;\r\n }\r\n\r\n if (this.objects[this.index]) {\r\n // Pool has an available object already constructed\r\n return this.recycler(this.objects[this.index++], ...args);\r\n } else {\r\n // New allocation\r\n this.totalAllocations++;\r\n const object = (this.objects[this.index++] = this.builder(...args));\r\n return object;\r\n }\r\n }\r\n\r\n /**\r\n * Signals we are done with the pool objects for now, Reclaims all objects in the pool.\r\n *\r\n * If a list of pooled objects is passed to done they are un-hooked from the pool and are free\r\n * to be passed to consumers\r\n * @param objects A list of object to separate from the pool\r\n */\r\n done(...objects: Type[]): Type[];\r\n done(): void;\r\n done(...objects: Type[]): Type[] | void {\r\n // All objects in pool now considered \"free\"\r\n this.index = 0;\r\n for (const object of objects) {\r\n const poolIndex = this.objects.indexOf(object);\r\n // Build a new object to take the pool place\r\n this.objects[poolIndex] = (this as any).builder(); // TODO problematic 0-arg only support\r\n this.totalAllocations++;\r\n }\r\n return objects;\r\n }\r\n}\r\n","import { AffineMatrix } from '../../Math/affine-matrix';\r\nimport { Color } from '../../Color';\r\nimport { ExcaliburGraphicsContextState } from './ExcaliburGraphicsContext';\r\n\r\nexport class DrawCall {\r\n public z: number = 0;\r\n public priority: number = 0;\r\n public renderer: string;\r\n public transform: AffineMatrix = AffineMatrix.identity();\r\n public state: ExcaliburGraphicsContextState = {\r\n z: 0,\r\n opacity: 1,\r\n tint: Color.White,\r\n material: null\r\n };\r\n public args: any[];\r\n}","import { Color } from '../../Color';\r\nimport { ExcaliburGraphicsContextWebGL } from './ExcaliburGraphicsContextWebGL';\r\nimport { Shader } from './shader';\r\n\r\nexport interface MaterialOptions {\r\n /**\r\n * Name the material for debugging\r\n */\r\n name?: string;\r\n\r\n /**\r\n * Optionally specify a vertex shader\r\n *\r\n * If none supplied the default will be used\r\n *\r\n * ```\r\n * #version 300 es\r\n * // vertex position in local space\r\n * in vec2 a_position;\r\n * in vec2 a_uv;\r\n * out vec2 v_uv;\r\n * // orthographic projection matrix\r\n * uniform mat4 u_matrix;\r\n * // world space transform matrix\r\n * uniform mat4 u_transform;\r\n * void main() {\r\n * // Set the vertex position using the ortho & transform matrix\r\n * gl_Position = u_matrix * u_transform * vec4(a_position, 0.0, 1.0);\r\n * // Pass through the UV coord to the fragment shader\r\n * v_uv = a_uv;\r\n * }\r\n * ```\r\n */\r\n vertexSource?: string,\r\n\r\n /**\r\n * Add custom fragment shader\r\n *\r\n * *Note: Excalibur image alpha's are pre-multiplied\r\n *\r\n * Pre-built varyings:\r\n *\r\n * * `in vec2 v_uv` - UV coordinate\r\n *\r\n * Pre-built uniforms:\r\n *\r\n * * `uniform sampler2D u_graphic` - The current graphic displayed by the GraphicsComponent\r\n * * `uniform vec2 u_resolution` - The current resolution of the screen\r\n * * `uniform vec2 u_size;` - The current size of the graphic\r\n * * `uniform vec4 u_color` - The current color of the material\r\n * * `uniform float u_opacity` - The current opacity of the graphics context\r\n *\r\n */\r\n fragmentSource: string,\r\n\r\n /**\r\n * Add custom color, by default ex.Color.Transparent\r\n */\r\n color?: Color,\r\n}\r\n\r\nconst defaultVertexSource = `#version 300 es\r\nin vec2 a_position;\r\n\r\nin vec2 a_uv;\r\nout vec2 v_uv;\r\n\r\nuniform mat4 u_matrix;\r\nuniform mat4 u_transform;\r\n\r\nvoid main() {\r\n // Set the vertex position using the ortho & transform matrix\r\n gl_Position = u_matrix * u_transform * vec4(a_position, 0.0, 1.0);\r\n\r\n // Pass through the UV coord to the fragment shader\r\n v_uv = a_uv;\r\n}\r\n`;\r\n\r\nexport class Material {\r\n private _name: string;\r\n private _shader: Shader;\r\n private _color: Color = Color.Transparent;\r\n private _initialized = false;\r\n private _fragmentSource: string;\r\n private _vertexSource: string;\r\n constructor(options: MaterialOptions) {\r\n const { color, name, vertexSource, fragmentSource } = options;\r\n this._name = name;\r\n this._vertexSource = vertexSource ?? defaultVertexSource;\r\n this._fragmentSource = fragmentSource;\r\n this._color = color ?? this._color;\r\n }\r\n\r\n initialize(_gl: WebGL2RenderingContext, _context: ExcaliburGraphicsContextWebGL) {\r\n if (this._initialized) {\r\n return;\r\n }\r\n\r\n this._shader = _context.createShader({\r\n vertexSource: this._vertexSource,\r\n fragmentSource: this._fragmentSource\r\n });\r\n this._shader.compile();\r\n this._initialized = true;\r\n }\r\n\r\n get name() {\r\n return this._name ?? 'anonymous material';\r\n }\r\n\r\n getShader(): Shader | null {\r\n return this._shader;\r\n }\r\n\r\n use() {\r\n if (this._initialized) {\r\n // bind the shader\r\n this._shader.use();\r\n // Apply standard uniforms\r\n this._shader.trySetUniformFloatColor('u_color', this._color);\r\n } else {\r\n throw Error(`Material ${this.name} not yet initialized, use the ExcaliburGraphicsContext.createMaterial() to work around this.`);\r\n }\r\n }\r\n}","import { vec } from '../../../Math/vector';\r\nimport { ImageFiltering } from '../../Filtering';\r\nimport { HTMLImageSource } from '../ExcaliburGraphicsContext';\r\nimport { ExcaliburGraphicsContextWebGL } from '../ExcaliburGraphicsContextWebGL';\r\nimport { QuadIndexBuffer } from '../quad-index-buffer';\r\nimport { RendererPlugin } from '../renderer';\r\nimport { VertexBuffer } from '../vertex-buffer';\r\nimport { VertexLayout } from '../vertex-layout';\r\n\r\n\r\nexport class MaterialRenderer implements RendererPlugin {\r\n public readonly type: string = 'ex.material';\r\n public priority: number = 0;\r\n // private _maxTextures = 8;\r\n private _context: ExcaliburGraphicsContextWebGL;\r\n private _gl: WebGL2RenderingContext;\r\n private _textures: WebGLTexture[] = [];\r\n private _quads: any;\r\n private _buffer: VertexBuffer;\r\n private _layout: VertexLayout;\r\n initialize(gl: WebGL2RenderingContext, context: ExcaliburGraphicsContextWebGL): void {\r\n this._gl = gl;\r\n this._context = context;\r\n\r\n // Setup memory layout\r\n this._buffer = new VertexBuffer({\r\n gl,\r\n size: 4 * 4, // 4 components * 4 verts\r\n type: 'dynamic'\r\n });\r\n\r\n // Setup a vertex layout/buffer to the material\r\n this._layout = new VertexLayout({\r\n gl,\r\n vertexBuffer: this._buffer,\r\n attributes: [\r\n ['a_position', 2],\r\n ['a_uv', 2]\r\n ]\r\n });\r\n\r\n // Setup index buffer\r\n this._quads = new QuadIndexBuffer(gl, 1, true);\r\n }\r\n\r\n draw(image: HTMLImageSource,\r\n sx: number,\r\n sy: number,\r\n swidth?: number,\r\n sheight?: number,\r\n dx?: number,\r\n dy?: number,\r\n dwidth?: number,\r\n dheight?: number): void {\r\n const gl = this._gl;\r\n\r\n // Extract context info\r\n const material = this._context.material;\r\n material.initialize(gl, this._context);\r\n\r\n const transform = this._context.getTransform();\r\n const opacity = this._context.opacity;\r\n\r\n // material shader\r\n const shader = material.getShader();\r\n\r\n // construct geometry, or hold on to it in the material?\r\n // geometry primitive for drawing rectangles?\r\n // update data\r\n const vertexBuffer = this._layout.vertexBuffer.bufferData;\r\n let vertexIndex = 0;\r\n\r\n let width = image?.width || swidth || 0;\r\n let height = image?.height || sheight || 0;\r\n let view = [0, 0, swidth ?? image?.width ?? 0, sheight ?? image?.height ?? 0];\r\n let dest = [sx ?? 1, sy ?? 1];\r\n // If destination is specified, update view and dest\r\n if (dx !== undefined && dy !== undefined && dwidth !== undefined && dheight !== undefined) {\r\n view = [sx ?? 1, sy ?? 1, swidth ?? image?.width ?? 0, sheight ?? image?.height ?? 0];\r\n dest = [dx, dy];\r\n width = dwidth;\r\n height = dheight;\r\n }\r\n\r\n sx = view[0];\r\n sy = view[1];\r\n const sw = view[2];\r\n const sh = view[3];\r\n\r\n const topLeft = vec(dest[0], dest[1]);\r\n const topRight = vec(dest[0] + width, dest[1]);\r\n const bottomLeft = vec(dest[0], dest[1] + height);\r\n const bottomRight = vec(dest[0] + width, dest[1] + height);\r\n\r\n const imageWidth = image.width || width;\r\n const imageHeight = image.height || height;\r\n\r\n const uvx0 = (sx) / imageWidth;\r\n const uvy0 = (sy) / imageHeight;\r\n const uvx1 = (sx + sw - 0.01) / imageWidth;\r\n const uvy1 = (sy + sh - 0.01) / imageHeight;\r\n\r\n // (0, 0) - 0\r\n vertexBuffer[vertexIndex++] = topLeft.x;\r\n vertexBuffer[vertexIndex++] = topLeft.y;\r\n vertexBuffer[vertexIndex++] = uvx0;\r\n vertexBuffer[vertexIndex++] = uvy0;\r\n\r\n // (0, 1) - 1\r\n vertexBuffer[vertexIndex++] = bottomLeft.x;\r\n vertexBuffer[vertexIndex++] = bottomLeft.y;\r\n vertexBuffer[vertexIndex++] = uvx0;\r\n vertexBuffer[vertexIndex++] = uvy1;\r\n\r\n // (1, 0) - 2\r\n vertexBuffer[vertexIndex++] = topRight.x;\r\n vertexBuffer[vertexIndex++] = topRight.y;\r\n vertexBuffer[vertexIndex++] = uvx1;\r\n vertexBuffer[vertexIndex++] = uvy0;\r\n\r\n // (1, 1) - 3\r\n vertexBuffer[vertexIndex++] = bottomRight.x;\r\n vertexBuffer[vertexIndex++] = bottomRight.y;\r\n vertexBuffer[vertexIndex++] = uvx1;\r\n vertexBuffer[vertexIndex++] = uvy1;\r\n\r\n // This creates and uploads the texture if not already done\r\n const texture = this._addImageAsTexture(image);\r\n\r\n // apply material\r\n material.use();\r\n\r\n this._layout.shader = shader;\r\n // apply layout and geometry\r\n this._layout.use(true);\r\n\r\n // apply opacity\r\n shader.trySetUniformFloat('u_opacity', opacity);\r\n\r\n // apply resolution\r\n shader.trySetUniformFloatVector('u_resolution', vec(this._context.width, this._context.height));\r\n\r\n // apply size\r\n shader.trySetUniformFloatVector('u_size', vec(sw, sh));\r\n\r\n // apply orthographic projection\r\n shader.trySetUniformMatrix('u_matrix', this._context.ortho);\r\n\r\n // apply geometry transform\r\n shader.trySetUniformMatrix('u_transform', transform.to4x4());\r\n\r\n // bind graphic image texture 'uniform sampler2D u_graphic;'\r\n gl.activeTexture(gl.TEXTURE0 + 0);\r\n gl.bindTexture(gl.TEXTURE_2D, texture);\r\n shader.trySetUniformInt('u_graphic', 0);\r\n\r\n // bind quad index buffer\r\n this._quads.bind();\r\n\r\n // Draw a single quad\r\n gl.drawElements(gl.TRIANGLES, 6, this._quads.bufferGlType, 0);\r\n }\r\n\r\n private _addImageAsTexture(image: HTMLImageSource) {\r\n const maybeFiltering = image.getAttribute('filtering');\r\n let filtering: ImageFiltering = null;\r\n if (maybeFiltering === ImageFiltering.Blended ||\r\n maybeFiltering === ImageFiltering.Pixel) {\r\n filtering = maybeFiltering;\r\n }\r\n\r\n const force = image.getAttribute('forceUpload') === 'true' ? true : false;\r\n const texture = this._context.textureLoader.load(image, filtering, force);\r\n // remove force attribute after upload\r\n image.removeAttribute('forceUpload');\r\n if (this._textures.indexOf(texture) === -1) {\r\n this._textures.push(texture);\r\n }\r\n\r\n return texture;\r\n }\r\n\r\n hasPendingDraws(): boolean {\r\n return false;\r\n }\r\n flush(): void {\r\n // flush does not do anything, material renderer renders immediately per draw\r\n }\r\n\r\n}","import {\r\n ExcaliburGraphicsContext,\r\n LineGraphicsOptions,\r\n RectGraphicsOptions,\r\n PointGraphicsOptions,\r\n ExcaliburGraphicsContextOptions,\r\n DebugDraw,\r\n HTMLImageSource\r\n} from './ExcaliburGraphicsContext';\r\n\r\nimport { Matrix } from '../../Math/matrix';\r\nimport { TransformStack } from './transform-stack';\r\nimport { Vector, vec } from '../../Math/vector';\r\nimport { Color } from '../../Color';\r\nimport { StateStack } from './state-stack';\r\nimport { Logger } from '../../Util/Log';\r\nimport { DebugText } from './debug-text';\r\nimport { ScreenDimension } from '../../Screen';\r\nimport { RenderTarget } from './render-target';\r\nimport { PostProcessor } from '../PostProcessor/PostProcessor';\r\nimport { TextureLoader } from './texture-loader';\r\nimport { RendererPlugin } from './renderer';\r\n\r\n// renderers\r\nimport { LineRenderer } from './line-renderer/line-renderer';\r\nimport { PointRenderer } from './point-renderer/point-renderer';\r\nimport { ScreenPassPainter } from './screen-pass-painter/screen-pass-painter';\r\nimport { ImageRenderer } from './image-renderer/image-renderer';\r\nimport { RectangleRenderer } from './rectangle-renderer/rectangle-renderer';\r\nimport { CircleRenderer } from './circle-renderer/circle-renderer';\r\nimport { Pool } from '../../Util/Pool';\r\nimport { DrawCall } from './draw-call';\r\nimport { AffineMatrix } from '../../Math/affine-matrix';\r\nimport { Material, MaterialOptions } from './material';\r\nimport { MaterialRenderer } from './material-renderer/material-renderer';\r\nimport { Shader, ShaderOptions } from './shader';\r\n\r\nexport const pixelSnapEpsilon = 0.0001;\r\n\r\nclass ExcaliburGraphicsContextWebGLDebug implements DebugDraw {\r\n private _debugText = new DebugText();\r\n constructor(private _webglCtx: ExcaliburGraphicsContextWebGL) {}\r\n\r\n /**\r\n * Draw a debugging rectangle to the context\r\n * @param x\r\n * @param y\r\n * @param width\r\n * @param height\r\n */\r\n drawRect(x: number, y: number, width: number, height: number, rectOptions: RectGraphicsOptions = { color: Color.Black }): void {\r\n this.drawLine(vec(x, y), vec(x + width, y), { ...rectOptions });\r\n this.drawLine(vec(x + width, y), vec(x + width, y + height), { ...rectOptions });\r\n this.drawLine(vec(x + width, y + height), vec(x, y + height), { ...rectOptions });\r\n this.drawLine(vec(x, y + height), vec(x, y), { ...rectOptions });\r\n }\r\n\r\n /**\r\n * Draw a debugging line to the context\r\n * @param start\r\n * @param end\r\n * @param lineOptions\r\n */\r\n drawLine(start: Vector, end: Vector, lineOptions: LineGraphicsOptions = { color: Color.Black }): void {\r\n this._webglCtx.draw('ex.line', start, end, lineOptions.color);\r\n }\r\n\r\n /**\r\n * Draw a debugging point to the context\r\n * @param point\r\n * @param pointOptions\r\n */\r\n drawPoint(point: Vector, pointOptions: PointGraphicsOptions = { color: Color.Black, size: 5 }): void {\r\n this._webglCtx.draw('ex.point', point, pointOptions.color, pointOptions.size);\r\n }\r\n\r\n drawText(text: string, pos: Vector) {\r\n this._debugText.write(this._webglCtx, text, pos);\r\n }\r\n}\r\n\r\nexport interface WebGLGraphicsContextInfo {\r\n transform: TransformStack;\r\n state: StateStack;\r\n ortho: Matrix;\r\n context: ExcaliburGraphicsContextWebGL;\r\n}\r\n\r\nexport class ExcaliburGraphicsContextWebGL implements ExcaliburGraphicsContext {\r\n private _logger = Logger.getInstance();\r\n private _renderers: Map = new Map();\r\n private _isDrawLifecycle = false;\r\n public useDrawSorting = true;\r\n\r\n private _drawCallPool = new Pool(\r\n () => new DrawCall(),\r\n (instance) => {\r\n instance.priority = 0;\r\n instance.z = 0;\r\n instance.renderer = undefined;\r\n instance.args = undefined;\r\n return instance;\r\n }, 4000);\r\n private _drawCalls: DrawCall[] = [];\r\n\r\n // Main render target\r\n private _renderTarget: RenderTarget;\r\n\r\n // Postprocessing is a tuple with 2 render targets, these are flip-flopped during the postprocessing process\r\n private _postProcessTargets: RenderTarget[] = [];\r\n\r\n private _screenRenderer: ScreenPassPainter;\r\n\r\n private _postprocessors: PostProcessor[] = [];\r\n /**\r\n * Meant for internal use only. Access the internal context at your own risk and no guarantees this will exist in the future.\r\n * @internal\r\n */\r\n public __gl: WebGL2RenderingContext;\r\n\r\n private _transform = new TransformStack();\r\n private _state = new StateStack();\r\n private _ortho!: Matrix;\r\n\r\n public snapToPixel: boolean = false;\r\n\r\n public smoothing: boolean = false;\r\n\r\n public backgroundColor: Color = Color.ExcaliburBlue;\r\n\r\n public textureLoader: TextureLoader;\r\n\r\n public get z(): number {\r\n return this._state.current.z;\r\n }\r\n\r\n public set z(value: number) {\r\n this._state.current.z = value;\r\n }\r\n\r\n public get opacity(): number {\r\n return this._state.current.opacity;\r\n }\r\n\r\n public set opacity(value: number) {\r\n this._state.current.opacity = value;\r\n }\r\n\r\n public get tint(): Color {\r\n return this._state.current.tint;\r\n }\r\n\r\n public set tint(color: Color) {\r\n this._state.current.tint = color;\r\n }\r\n\r\n public get width() {\r\n return this.__gl.canvas.width;\r\n }\r\n\r\n public get height() {\r\n return this.__gl.canvas.height;\r\n }\r\n\r\n public get ortho(): Matrix {\r\n return this._ortho;\r\n }\r\n\r\n /**\r\n * Checks the underlying webgl implementation if the requested internal resolution is supported\r\n * @param dim\r\n */\r\n public checkIfResolutionSupported(dim: ScreenDimension): boolean {\r\n // Slight hack based on this thread https://groups.google.com/g/webgl-dev-list/c/AHONvz3oQTo\r\n let supported = true;\r\n if (dim.width > 4096 || dim.height > 4096) {\r\n supported = false;\r\n }\r\n return supported;\r\n }\r\n\r\n constructor(options: ExcaliburGraphicsContextOptions) {\r\n const { canvasElement, enableTransparency, smoothing, snapToPixel, backgroundColor, useDrawSorting } = options;\r\n this.__gl = canvasElement.getContext('webgl2', {\r\n antialias: smoothing ?? this.smoothing,\r\n premultipliedAlpha: false,\r\n alpha: enableTransparency ?? true,\r\n depth: true,\r\n powerPreference: 'high-performance'\r\n // TODO Chromium fixed the bug where this didn't work now it breaks CI :(\r\n // failIfMajorPerformanceCaveat: true\r\n });\r\n if (!this.__gl) {\r\n throw Error('Failed to retrieve webgl context from browser');\r\n }\r\n this.textureLoader = new TextureLoader(this.__gl);\r\n this.snapToPixel = snapToPixel ?? this.snapToPixel;\r\n this.smoothing = smoothing ?? this.smoothing;\r\n this.backgroundColor = backgroundColor ?? this.backgroundColor;\r\n this.useDrawSorting = useDrawSorting ?? this.useDrawSorting;\r\n this._drawCallPool.disableWarnings = true;\r\n this._drawCallPool.preallocate();\r\n this._init();\r\n }\r\n\r\n private _init() {\r\n const gl = this.__gl;\r\n // Setup viewport and view matrix\r\n this._ortho = Matrix.ortho(0, gl.canvas.width, gl.canvas.height, 0, 400, -400);\r\n gl.viewport(0, 0, gl.canvas.width, gl.canvas.height);\r\n\r\n // Clear background\r\n gl.clearColor(this.backgroundColor.r / 255, this.backgroundColor.g / 255, this.backgroundColor.b / 255, this.backgroundColor.a);\r\n gl.clear(gl.COLOR_BUFFER_BIT);\r\n\r\n // Enable alpha blending\r\n // https://www.realtimerendering.com/blog/gpus-prefer-premultiplication/\r\n gl.enable(gl.BLEND);\r\n gl.blendEquation(gl.FUNC_ADD);\r\n gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA);\r\n gl.blendEquationSeparate(gl.FUNC_ADD, gl.FUNC_ADD);\r\n gl.blendFuncSeparate(gl.ONE, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA);\r\n\r\n // Setup builtin renderers\r\n this.register(new ImageRenderer());\r\n this.register(new MaterialRenderer());\r\n this.register(new RectangleRenderer());\r\n this.register(new CircleRenderer());\r\n this.register(new PointRenderer());\r\n this.register(new LineRenderer());\r\n\r\n this._screenRenderer = new ScreenPassPainter(gl);\r\n\r\n this._renderTarget = new RenderTarget({\r\n gl,\r\n width: gl.canvas.width,\r\n height: gl.canvas.height\r\n });\r\n\r\n\r\n this._postProcessTargets = [\r\n new RenderTarget({\r\n gl,\r\n width: gl.canvas.width,\r\n height: gl.canvas.height\r\n }),\r\n new RenderTarget({\r\n gl,\r\n width: gl.canvas.width,\r\n height: gl.canvas.height\r\n })\r\n ];\r\n }\r\n\r\n public register(renderer: T) {\r\n this._renderers.set(renderer.type, renderer);\r\n renderer.initialize(this.__gl, this);\r\n }\r\n\r\n public get(rendererName: string): RendererPlugin {\r\n return this._renderers.get(rendererName);\r\n }\r\n\r\n private _currentRenderer: RendererPlugin;\r\n\r\n private _isCurrentRenderer(renderer: RendererPlugin): boolean {\r\n if (!this._currentRenderer || this._currentRenderer === renderer) {\r\n return true;\r\n }\r\n return false;\r\n }\r\n\r\n public beginDrawLifecycle() {\r\n this._isDrawLifecycle = true;\r\n }\r\n\r\n public endDrawLifecycle() {\r\n this._isDrawLifecycle = false;\r\n }\r\n\r\n private _alreadyWarnedDrawLifecycle = false;\r\n\r\n public draw(rendererName: TRenderer['type'], ...args: Parameters) {\r\n if (!this._isDrawLifecycle && !this._alreadyWarnedDrawLifecycle) {\r\n this._logger.warn(\r\n `Attempting to draw outside the the drawing lifecycle (preDraw/postDraw) is not supported and is a source of bugs/errors.\\n` +\r\n `If you want to do custom drawing, use Actor.graphics, or any onPreDraw or onPostDraw handler.`);\r\n this._alreadyWarnedDrawLifecycle = true;\r\n }\r\n\r\n const renderer = this._renderers.get(rendererName);\r\n if (renderer) {\r\n if (this.useDrawSorting) {\r\n const drawCall = this._drawCallPool.get();\r\n drawCall.z = this._state.current.z;\r\n drawCall.priority = renderer.priority;\r\n drawCall.renderer = rendererName;\r\n this.getTransform().clone(drawCall.transform);\r\n drawCall.state.z = this._state.current.z;\r\n drawCall.state.opacity = this._state.current.opacity;\r\n drawCall.state.tint = this._state.current.tint;\r\n drawCall.state.material = this._state.current.material;\r\n drawCall.args = args;\r\n this._drawCalls.push(drawCall);\r\n } else {\r\n // Set the current renderer if not defined\r\n if (!this._currentRenderer) {\r\n this._currentRenderer = renderer;\r\n }\r\n\r\n if (!this._isCurrentRenderer(renderer)) {\r\n // switching graphics means we must flush the previous\r\n this._currentRenderer.flush();\r\n }\r\n\r\n // If we are still using the same renderer we can add to the current batch\r\n renderer.draw(...args);\r\n\r\n this._currentRenderer = renderer;\r\n }\r\n } else {\r\n throw Error(`No renderer with name ${rendererName} has been registered`);\r\n }\r\n }\r\n\r\n public resetTransform(): void {\r\n this._transform.current = AffineMatrix.identity();\r\n }\r\n\r\n public updateViewport(resolution: ScreenDimension): void {\r\n const gl = this.__gl;\r\n this._ortho = this._ortho = Matrix.ortho(0, resolution.width, resolution.height, 0, 400, -400);\r\n\r\n this._renderTarget.setResolution(gl.canvas.width, gl.canvas.height);\r\n this._postProcessTargets[0].setResolution(gl.canvas.width, gl.canvas.height);\r\n this._postProcessTargets[1].setResolution(gl.canvas.width, gl.canvas.height);\r\n }\r\n\r\n drawImage(image: HTMLImageSource, x: number, y: number): void;\r\n drawImage(image: HTMLImageSource, x: number, y: number, width: number, height: number): void;\r\n drawImage(\r\n image: HTMLImageSource,\r\n sx: number,\r\n sy: number,\r\n swidth?: number,\r\n sheight?: number,\r\n dx?: number,\r\n dy?: number,\r\n dwidth?: number,\r\n dheight?: number\r\n ): void;\r\n drawImage(\r\n image: HTMLImageSource,\r\n sx: number,\r\n sy: number,\r\n swidth?: number,\r\n sheight?: number,\r\n dx?: number,\r\n dy?: number,\r\n dwidth?: number,\r\n dheight?: number\r\n ): void {\r\n if (swidth === 0 || sheight === 0) {\r\n return; // zero dimension dest exit early\r\n } else if (dwidth === 0 || dheight === 0) {\r\n return; // zero dimension dest exit early\r\n } else if (image.width === 0 || image.height === 0) {\r\n return; // zero dimension source exit early\r\n }\r\n\r\n if (!image) {\r\n Logger.getInstance().warn('Cannot draw a null or undefined image');\r\n // tslint:disable-next-line: no-console\r\n if (console.trace) {\r\n // tslint:disable-next-line: no-console\r\n console.trace();\r\n }\r\n return;\r\n }\r\n\r\n if (this._state.current.material) {\r\n this.draw('ex.material', image, sx, sy, swidth, sheight, dx, dy, dwidth, dheight);\r\n } else {\r\n this.draw('ex.image', image, sx, sy, swidth, sheight, dx, dy, dwidth, dheight);\r\n }\r\n }\r\n\r\n public drawLine(start: Vector, end: Vector, color: Color, thickness = 1) {\r\n this.draw('ex.rectangle', start, end, color, thickness);\r\n }\r\n\r\n public drawRectangle(pos: Vector, width: number, height: number, color: Color, stroke?: Color, strokeThickness?: number) {\r\n this.draw('ex.rectangle', pos, width, height, color, stroke, strokeThickness);\r\n }\r\n\r\n public drawCircle(pos: Vector, radius: number, color: Color, stroke?: Color, thickness?: number) {\r\n this.draw('ex.circle', pos, radius, color, stroke, thickness);\r\n }\r\n\r\n debug = new ExcaliburGraphicsContextWebGLDebug(this);\r\n\r\n public save(): void {\r\n this._transform.save();\r\n this._state.save();\r\n }\r\n\r\n public restore(): void {\r\n this._transform.restore();\r\n this._state.restore();\r\n }\r\n\r\n public translate(x: number, y: number): void {\r\n this._transform.translate(this.snapToPixel ? ~~(x + pixelSnapEpsilon) : x, this.snapToPixel ? ~~(y + pixelSnapEpsilon) : y);\r\n }\r\n\r\n public rotate(angle: number): void {\r\n this._transform.rotate(angle);\r\n }\r\n\r\n public scale(x: number, y: number): void {\r\n this._transform.scale(x, y);\r\n }\r\n\r\n public transform(matrix: AffineMatrix) {\r\n this._transform.current = matrix;\r\n }\r\n\r\n public getTransform(): AffineMatrix {\r\n return this._transform.current;\r\n }\r\n\r\n public multiply(m: AffineMatrix) {\r\n this._transform.current.multiply(m, this._transform.current);\r\n }\r\n\r\n public addPostProcessor(postprocessor: PostProcessor) {\r\n this._postprocessors.push(postprocessor);\r\n postprocessor.initialize(this.__gl);\r\n }\r\n\r\n public removePostProcessor(postprocessor: PostProcessor) {\r\n const index = this._postprocessors.indexOf(postprocessor);\r\n if (index !== -1) {\r\n this._postprocessors.splice(index, 1);\r\n }\r\n }\r\n\r\n public clearPostProcessors() {\r\n this._postprocessors.length = 0;\r\n }\r\n\r\n private _totalPostProcessorTime = 0;\r\n public updatePostProcessors(delta: number) {\r\n for (const postprocessor of this._postprocessors) {\r\n const shader = postprocessor.getShader();\r\n shader.use();\r\n const uniforms = shader.getUniforms();\r\n this._totalPostProcessorTime += delta;\r\n\r\n if (uniforms.find(u => u.name ==='u_time_ms')) {\r\n shader.setUniformFloat('u_time_ms', this._totalPostProcessorTime);\r\n }\r\n if (uniforms.find(u => u.name ==='u_elapsed_ms')) {\r\n shader.setUniformFloat('u_elapsed_ms', delta);\r\n }\r\n if (uniforms.find(u => u.name ==='u_resolution')) {\r\n shader.setUniformFloatVector('u_resolution', vec(this.width, this.height));\r\n }\r\n\r\n if (postprocessor.onUpdate) {\r\n postprocessor.onUpdate(delta);\r\n }\r\n }\r\n }\r\n\r\n public set material(material: Material) {\r\n this._state.current.material = material;\r\n }\r\n\r\n public get material(): Material | null {\r\n return this._state.current.material;\r\n }\r\n\r\n /**\r\n * Creates and initializes the material which compiles the internal shader\r\n * @param options\r\n * @returns Material\r\n */\r\n public createMaterial(options: MaterialOptions): Material {\r\n const material = new Material(options);\r\n material.initialize(this.__gl, this);\r\n return material;\r\n }\r\n\r\n public createShader(options: Omit): Shader {\r\n const gl = this.__gl;\r\n const { vertexSource, fragmentSource } = options;\r\n const shader = new Shader({\r\n gl,\r\n vertexSource,\r\n fragmentSource\r\n });\r\n shader.compile();\r\n return shader;\r\n }\r\n\r\n clear() {\r\n const gl = this.__gl;\r\n this._renderTarget.use();\r\n gl.clearColor(this.backgroundColor.r / 255, this.backgroundColor.g / 255, this.backgroundColor.b / 255, this.backgroundColor.a);\r\n // Clear the context with the newly set color. This is\r\n // the function call that actually does the drawing.\r\n gl.clear(gl.COLOR_BUFFER_BIT);\r\n }\r\n\r\n /**\r\n * Flushes all batched rendering to the screen\r\n */\r\n flush() {\r\n const gl = this.__gl;\r\n\r\n // render target captures all draws and redirects to the render target\r\n this._renderTarget.use();\r\n\r\n if (this.useDrawSorting) {\r\n // sort draw calls\r\n // Find the original order of the first instance of the draw call\r\n const originalSort = new Map();\r\n for (const [name] of this._renderers) {\r\n const firstIndex = this._drawCalls.findIndex(dc => dc.renderer === name);\r\n originalSort.set(name, firstIndex);\r\n }\r\n\r\n this._drawCalls.sort((a, b) => {\r\n const zIndex = a.z - b.z;\r\n const originalSortOrder = originalSort.get(a.renderer) - originalSort.get(b.renderer);\r\n const priority = a.priority - b.priority;\r\n if (zIndex === 0) { // sort by z first\r\n if (priority === 0) { // sort by priority\r\n return originalSortOrder; // use the original order to inform draw call packing to maximally preserve painter order\r\n }\r\n return priority;\r\n }\r\n return zIndex;\r\n });\r\n\r\n const oldTransform = this._transform.current;\r\n const oldState = this._state.current;\r\n\r\n if (this._drawCalls.length) {\r\n let currentRendererName = this._drawCalls[0].renderer;\r\n let currentRenderer = this._renderers.get(currentRendererName);\r\n for (let i = 0; i < this._drawCalls.length; i++) {\r\n // hydrate the state for renderers\r\n this._transform.current = this._drawCalls[i].transform;\r\n this._state.current = this._drawCalls[i].state;\r\n\r\n if (this._drawCalls[i].renderer !== currentRendererName) {\r\n // switching graphics renderer means we must flush the previous\r\n currentRenderer.flush();\r\n currentRendererName = this._drawCalls[i].renderer;\r\n currentRenderer = this._renderers.get(currentRendererName);\r\n }\r\n\r\n // If we are still using the same renderer we can add to the current batch\r\n currentRenderer.draw(...this._drawCalls[i].args);\r\n }\r\n if (currentRenderer.hasPendingDraws()) {\r\n currentRenderer.flush();\r\n }\r\n }\r\n\r\n // reset state\r\n this._transform.current = oldTransform;\r\n this._state.current = oldState;\r\n\r\n // reclaim draw calls\r\n this._drawCallPool.done();\r\n this._drawCalls.length = 0;\r\n } else {\r\n // This is the final flush at the moment to draw any leftover pending draw\r\n for (const renderer of this._renderers.values()) {\r\n if (renderer.hasPendingDraws()) {\r\n renderer.flush();\r\n }\r\n }\r\n }\r\n\r\n this._renderTarget.disable();\r\n\r\n // post process step\r\n const source = this._renderTarget.toRenderSource();\r\n source.use();\r\n\r\n // flip flop render targets\r\n for (let i = 0; i < this._postprocessors.length; i++) {\r\n this._postProcessTargets[i % 2].use();\r\n this._screenRenderer.renderWithPostProcessor(this._postprocessors[i]);\r\n this._postProcessTargets[i % 2].toRenderSource().use();\r\n }\r\n\r\n // passing null switches rendering back to the canvas\r\n gl.bindFramebuffer(gl.FRAMEBUFFER, null);\r\n this._screenRenderer.renderToScreen();\r\n }\r\n}\r\n","import {\r\n ExcaliburGraphicsContext,\r\n LineGraphicsOptions,\r\n PointGraphicsOptions,\r\n ExcaliburGraphicsContextOptions,\r\n DebugDraw,\r\n HTMLImageSource\r\n} from './ExcaliburGraphicsContext';\r\nimport { Vector } from '../../Math/vector';\r\nimport { Color } from '../../Color';\r\nimport { StateStack } from './state-stack';\r\nimport { GraphicsDiagnostics } from '../GraphicsDiagnostics';\r\nimport { DebugText } from './debug-text';\r\nimport { ScreenDimension } from '../../Screen';\r\nimport { PostProcessor } from '../PostProcessor/PostProcessor';\r\nimport { AffineMatrix } from '../../Math/affine-matrix';\r\nimport { Material, MaterialOptions } from './material';\r\n\r\nconst pixelSnapEpsilon = 0.0001;\r\n\r\nclass ExcaliburGraphicsContext2DCanvasDebug implements DebugDraw {\r\n private _debugText = new DebugText();\r\n constructor(private _ex: ExcaliburGraphicsContext2DCanvas) {}\r\n /**\r\n * Draw a debug rectangle to the context\r\n * @param x\r\n * @param y\r\n * @param width\r\n * @param height\r\n */\r\n drawRect(x: number, y: number, width: number, height: number): void {\r\n this._ex.__ctx.save();\r\n this._ex.__ctx.strokeStyle = 'red';\r\n this._ex.__ctx.strokeRect(\r\n this._ex.snapToPixel ? ~~(x + pixelSnapEpsilon) : x,\r\n this._ex.snapToPixel ? ~~(y + pixelSnapEpsilon) : y,\r\n this._ex.snapToPixel ? ~~(width + pixelSnapEpsilon) : width,\r\n this._ex.snapToPixel ? ~~(height + pixelSnapEpsilon) : height\r\n );\r\n this._ex.__ctx.restore();\r\n }\r\n\r\n drawLine(start: Vector, end: Vector, lineOptions: LineGraphicsOptions = { color: Color.Black }): void {\r\n this._ex.__ctx.save();\r\n this._ex.__ctx.beginPath();\r\n this._ex.__ctx.strokeStyle = lineOptions.color.toString();\r\n this._ex.__ctx.moveTo(\r\n this._ex.snapToPixel ? ~~(start.x + pixelSnapEpsilon) : start.x,\r\n this._ex.snapToPixel ? ~~(start.y + pixelSnapEpsilon) : start.y\r\n );\r\n this._ex.__ctx.lineTo(\r\n this._ex.snapToPixel ? ~~(end.x + pixelSnapEpsilon) : end.x,\r\n this._ex.snapToPixel ? ~~(end.y + pixelSnapEpsilon) : end.y\r\n );\r\n this._ex.__ctx.lineWidth = 2;\r\n this._ex.__ctx.stroke();\r\n this._ex.__ctx.closePath();\r\n this._ex.__ctx.restore();\r\n }\r\n\r\n drawPoint(point: Vector, pointOptions: PointGraphicsOptions = { color: Color.Black, size: 5 }): void {\r\n this._ex.__ctx.save();\r\n this._ex.__ctx.beginPath();\r\n this._ex.__ctx.fillStyle = pointOptions.color.toString();\r\n this._ex.__ctx.arc(\r\n this._ex.snapToPixel ? ~~(point.x + pixelSnapEpsilon) : point.x,\r\n this._ex.snapToPixel ? ~~(point.y + pixelSnapEpsilon) : point.y,\r\n pointOptions.size,\r\n 0,\r\n Math.PI * 2\r\n );\r\n this._ex.__ctx.fill();\r\n this._ex.__ctx.closePath();\r\n this._ex.__ctx.restore();\r\n }\r\n\r\n drawText(text: string, pos: Vector) {\r\n this._debugText.write(this._ex, text, pos);\r\n }\r\n}\r\n\r\nexport class ExcaliburGraphicsContext2DCanvas implements ExcaliburGraphicsContext {\r\n /**\r\n * Meant for internal use only. Access the internal context at your own risk and no guarantees this will exist in the future.\r\n * @internal\r\n */\r\n public __ctx: CanvasRenderingContext2D;\r\n public get width() {\r\n return this.__ctx.canvas.width;\r\n }\r\n\r\n public get height() {\r\n return this.__ctx.canvas.height;\r\n }\r\n\r\n /**\r\n * Unused in Canvas implementation\r\n */\r\n public readonly useDrawSorting: boolean = false;\r\n\r\n /**\r\n * Unused in Canvas implementation\r\n */\r\n public z: number = 0;\r\n\r\n public backgroundColor: Color = Color.ExcaliburBlue;\r\n\r\n private _state = new StateStack();\r\n\r\n public get opacity(): number {\r\n return this._state.current.opacity;\r\n }\r\n\r\n public set opacity(value: number) {\r\n this._state.current.opacity = value;\r\n }\r\n\r\n public get tint(): Color {\r\n return this._state.current.tint;\r\n }\r\n\r\n public set tint(color: Color) {\r\n this._state.current.tint = color;\r\n }\r\n\r\n public snapToPixel: boolean = false;\r\n\r\n public get smoothing(): boolean {\r\n return this.__ctx.imageSmoothingEnabled;\r\n }\r\n\r\n public set smoothing(value: boolean) {\r\n this.__ctx.imageSmoothingEnabled = value;\r\n }\r\n\r\n constructor(options: ExcaliburGraphicsContextOptions) {\r\n const { canvasElement, enableTransparency, snapToPixel, smoothing, backgroundColor } = options;\r\n this.__ctx = canvasElement.getContext('2d', {\r\n alpha: enableTransparency ?? true\r\n });\r\n this.backgroundColor = backgroundColor ?? this.backgroundColor;\r\n this.snapToPixel = snapToPixel ?? this.snapToPixel;\r\n this.smoothing = smoothing ?? this.smoothing;\r\n }\r\n\r\n public resetTransform(): void {\r\n this.__ctx.resetTransform();\r\n }\r\n\r\n public updateViewport(_resolution: ScreenDimension): void {\r\n // pass\r\n }\r\n\r\n /**\r\n * Draw an image to the Excalibur Graphics context at an x and y coordinate using the images width and height\r\n */\r\n drawImage(image: HTMLImageSource, x: number, y: number): void;\r\n /**\r\n *\r\n * Draw an image to the Excalibur Graphics context at an x and y coordinate with a specific width and height\r\n */\r\n drawImage(image: HTMLImageSource, x: number, y: number, width: number, height: number): void;\r\n /**\r\n *\r\n * Draw an image to the Excalibur Graphics context specifying the source image coordinates (sx, sy, swidth, sheight)\r\n * and to a specific destination on the context (dx, dy, dwidth, dheight)\r\n */\r\n drawImage(\r\n image: HTMLImageSource,\r\n sx: number,\r\n sy: number,\r\n swidth?: number,\r\n sheight?: number,\r\n dx?: number,\r\n dy?: number,\r\n dwidth?: number,\r\n dheight?: number\r\n ): void;\r\n\r\n drawImage(\r\n image: HTMLImageSource,\r\n sx: number,\r\n sy: number,\r\n swidth?: number,\r\n sheight?: number,\r\n dx?: number,\r\n dy?: number,\r\n dwidth?: number,\r\n dheight?: number\r\n ): void {\r\n if (swidth === 0 || sheight === 0) {\r\n return; // zero dimension dest exit early\r\n } else if (dwidth === 0 || dheight === 0) {\r\n return; // zero dimension dest exit early\r\n } else if (image.width === 0 || image.height === 0) {\r\n return; // zero dimension source exit early\r\n }\r\n\r\n this.__ctx.globalAlpha = this.opacity;\r\n const args = [image, sx, sy, swidth, sheight, dx, dy, dwidth, dheight]\r\n .filter((a) => a !== undefined)\r\n .map((a) => (typeof a === 'number' && this.snapToPixel ? ~~a : a));\r\n this.__ctx.drawImage.apply(this.__ctx, args);\r\n GraphicsDiagnostics.DrawCallCount++;\r\n GraphicsDiagnostics.DrawnImagesCount = 1;\r\n }\r\n\r\n public drawLine(start: Vector, end: Vector, color: Color, thickness = 1) {\r\n this.__ctx.save();\r\n this.__ctx.beginPath();\r\n this.__ctx.strokeStyle = color.toString();\r\n this.__ctx.moveTo(\r\n this.snapToPixel ? ~~ (start.x + pixelSnapEpsilon) : start.x,\r\n this.snapToPixel ? ~~(start.y + pixelSnapEpsilon) : start.y\r\n );\r\n this.__ctx.lineTo(\r\n this.snapToPixel ? ~~ (end.x + pixelSnapEpsilon) : end.x,\r\n this.snapToPixel ? ~~(end.y + pixelSnapEpsilon) : end.y\r\n );\r\n this.__ctx.lineWidth = thickness;\r\n this.__ctx.stroke();\r\n this.__ctx.closePath();\r\n this.__ctx.restore();\r\n }\r\n\r\n public drawRectangle(pos: Vector, width: number, height: number, color: Color) {\r\n this.__ctx.save();\r\n this.__ctx.fillStyle = color.toString();\r\n this.__ctx.fillRect(\r\n this.snapToPixel ? ~~(pos.x + pixelSnapEpsilon) : pos.x,\r\n this.snapToPixel ? ~~(pos.y + pixelSnapEpsilon) : pos.y,\r\n this.snapToPixel ? ~~(width + pixelSnapEpsilon) : width,\r\n this.snapToPixel ? ~~(height + pixelSnapEpsilon) : height\r\n );\r\n this.__ctx.restore();\r\n }\r\n\r\n public drawCircle(pos: Vector, radius: number, color: Color, stroke?: Color, thickness?: number) {\r\n this.__ctx.save();\r\n this.__ctx.beginPath();\r\n if (stroke) {\r\n this.__ctx.strokeStyle = stroke.toString();\r\n }\r\n if (thickness) {\r\n this.__ctx.lineWidth = thickness;\r\n }\r\n this.__ctx.fillStyle = color.toString();\r\n this.__ctx.arc(\r\n this.snapToPixel ? ~~(pos.x + pixelSnapEpsilon) : pos.x,\r\n this.snapToPixel ? ~~(pos.y + pixelSnapEpsilon) : pos.y, radius, 0, Math.PI * 2\r\n );\r\n this.__ctx.fill();\r\n if (stroke) {\r\n this.__ctx.stroke();\r\n }\r\n this.__ctx.closePath();\r\n this.__ctx.restore();\r\n }\r\n\r\n debug = new ExcaliburGraphicsContext2DCanvasDebug(this);\r\n\r\n /**\r\n * Save the current state of the canvas to the stack (transforms and opacity)\r\n */\r\n save(): void {\r\n this.__ctx.save();\r\n }\r\n\r\n /**\r\n * Restore the state of the canvas from the stack\r\n */\r\n restore(): void {\r\n this.__ctx.restore();\r\n }\r\n\r\n /**\r\n * Translate the origin of the context by an x and y\r\n * @param x\r\n * @param y\r\n */\r\n translate(x: number, y: number): void {\r\n this.__ctx.translate(this.snapToPixel ? ~~(x + pixelSnapEpsilon) : x, this.snapToPixel ? ~~(y + pixelSnapEpsilon) : y);\r\n }\r\n\r\n /**\r\n * Rotate the context about the current origin\r\n */\r\n rotate(angle: number): void {\r\n this.__ctx.rotate(angle);\r\n }\r\n\r\n /**\r\n * Scale the context by an x and y factor\r\n * @param x\r\n * @param y\r\n */\r\n scale(x: number, y: number): void {\r\n this.__ctx.scale(x, y);\r\n }\r\n\r\n public getTransform(): AffineMatrix {\r\n throw new Error('Not implemented');\r\n }\r\n\r\n public multiply(_m: AffineMatrix): void {\r\n this.__ctx.setTransform(this.__ctx.getTransform().multiply(_m.toDOMMatrix()));\r\n }\r\n\r\n public addPostProcessor(_postprocessor: PostProcessor) {\r\n // pass\r\n }\r\n\r\n public removePostProcessor(_postprocessor: PostProcessor) {\r\n // pass\r\n }\r\n\r\n public clearPostProcessors() {\r\n // pass\r\n }\r\n\r\n public updatePostProcessors(_delta: number) {\r\n // pass\r\n }\r\n\r\n public beginDrawLifecycle() {\r\n // pass\r\n }\r\n\r\n public endDrawLifecycle() {\r\n // pass\r\n }\r\n\r\n public set material(material: Material) {\r\n this._state.current.material = material;\r\n }\r\n\r\n public get material(): Material | null {\r\n return this._state.current.material;\r\n }\r\n\r\n public createMaterial(_options: MaterialOptions): Material {\r\n // pass\r\n return null;\r\n }\r\n\r\n clear(): void {\r\n // Clear frame\r\n this.__ctx.clearRect(0, 0, this.width, this.height);\r\n this.__ctx.fillStyle = this.backgroundColor.toString();\r\n this.__ctx.fillRect(0, 0, this.width, this.height);\r\n GraphicsDiagnostics.clear();\r\n }\r\n\r\n /**\r\n * Flushes the batched draw calls to the screen\r\n */\r\n flush(): void {\r\n // pass\r\n }\r\n}\r\n","import { vec, Vector } from './Math/vector';\r\nimport { Logger } from './Util/Log';\r\nimport { Camera } from './Camera';\r\nimport { BrowserEvents } from './Util/Browser';\r\nimport { BoundingBox } from './Collision/Index';\r\nimport { ExcaliburGraphicsContext } from './Graphics/Context/ExcaliburGraphicsContext';\r\nimport { getPosition } from './Util/Util';\r\nimport { ExcaliburGraphicsContextWebGL } from './Graphics/Context/ExcaliburGraphicsContextWebGL';\r\nimport { ExcaliburGraphicsContext2DCanvas } from './Graphics/Context/ExcaliburGraphicsContext2DCanvas';\r\n\r\n/**\r\n * Enum representing the different display modes available to Excalibur.\r\n */\r\nexport enum DisplayMode {\r\n /**\r\n * Default, use a specified resolution for the game. Like 800x600 pixels for example.\r\n */\r\n Fixed = 'Fixed',\r\n\r\n /**\r\n * Fit the aspect ratio given by the game resolution within the container at all times will fill any gaps with canvas.\r\n * The displayed area outside the aspect ratio is not guaranteed to be on the screen, only the [[Screen.contentArea]]\r\n * is guaranteed to be on screen.\r\n */\r\n FitContainerAndFill = 'FitContainerAndFill',\r\n\r\n /**\r\n * Fit the aspect ratio given by the game resolution the screen at all times will fill the screen.\r\n * This displayed area outside the aspect ratio is not guaranteed to be on the screen, only the [[Screen.contentArea]]\r\n * is guaranteed to be on screen.\r\n */\r\n FitScreenAndFill = 'FitScreenAndFill',\r\n\r\n /**\r\n * Fit the viewport to the parent element maintaining aspect ratio given by the game resolution, but zooms in to avoid the black bars\r\n * (letterbox) that would otherwise be present in [[FitContainer]].\r\n *\r\n * **warning** This will clip some drawable area from the user because of the zoom,\r\n * use [[Screen.contentArea]] to know the safe to draw area.\r\n */\r\n FitContainerAndZoom = 'FitContainerAndZoom',\r\n\r\n /**\r\n * Fit the viewport to the device screen maintaining aspect ratio given by the game resolution, but zooms in to avoid the black bars\r\n * (letterbox) that would otherwise be present in [[FitScreen]].\r\n *\r\n * **warning** This will clip some drawable area from the user because of the zoom,\r\n * use [[Screen.contentArea]] to know the safe to draw area.\r\n */\r\n FitScreenAndZoom = 'FitScreenAndZoom',\r\n\r\n /**\r\n * Fit to screen using as much space as possible while maintaining aspect ratio and resolution.\r\n * This is not the same as [[Screen.goFullScreen]] but behaves in a similar way maintaining aspect ratio.\r\n *\r\n * You may want to center your game here is an example\r\n * ```html\r\n * \r\n * \r\n *
\r\n * \r\n *
\r\n * \r\n * ```\r\n *\r\n * ```css\r\n * // css\r\n * main {\r\n * display: flex;\r\n * align-items: center;\r\n * justify-content: center;\r\n * height: 100%;\r\n * width: 100%;\r\n * }\r\n * ```\r\n */\r\n FitScreen = 'FitScreen',\r\n\r\n /**\r\n * Fill the entire screen's css width/height for the game resolution dynamically. This means the resolution of the game will\r\n * change dynamically as the window is resized. This is not the same as [[Screen.goFullScreen]]\r\n */\r\n FillScreen = 'FillScreen',\r\n\r\n /**\r\n * Fit to parent element width/height using as much space as possible while maintaining aspect ratio and resolution.\r\n */\r\n FitContainer = 'FitContainer',\r\n\r\n /**\r\n * Use the parent DOM container's css width/height for the game resolution dynamically\r\n */\r\n FillContainer = 'FillContainer'\r\n}\r\n\r\n/**\r\n * Convenience class for quick resolutions\r\n * Mostly sourced from https://emulation.gametechwiki.com/index.php/Resolution\r\n */\r\nexport class Resolution {\r\n /* istanbul ignore next */\r\n public static get SVGA(): ScreenDimension {\r\n return { width: 800, height: 600 };\r\n }\r\n\r\n /* istanbul ignore next */\r\n public static get Standard(): ScreenDimension {\r\n return { width: 1920, height: 1080 };\r\n }\r\n\r\n /* istanbul ignore next */\r\n public static get Atari2600(): ScreenDimension {\r\n return { width: 160, height: 192 };\r\n }\r\n\r\n /* istanbul ignore next */\r\n public static get GameBoy(): ScreenDimension {\r\n return { width: 160, height: 144 };\r\n }\r\n\r\n /* istanbul ignore next */\r\n public static get GameBoyAdvance(): ScreenDimension {\r\n return { width: 240, height: 160 };\r\n }\r\n\r\n /* istanbul ignore next */\r\n public static get NintendoDS(): ScreenDimension {\r\n return { width: 256, height: 192 };\r\n }\r\n\r\n /* istanbul ignore next */\r\n public static get NES(): ScreenDimension {\r\n return { width: 256, height: 224 };\r\n }\r\n\r\n /* istanbul ignore next */\r\n public static get SNES(): ScreenDimension {\r\n return { width: 256, height: 244 };\r\n }\r\n}\r\n\r\nexport interface ScreenDimension {\r\n width: number;\r\n height: number;\r\n}\r\n\r\nexport interface ScreenOptions {\r\n /**\r\n * Canvas element to build a screen on\r\n */\r\n canvas: HTMLCanvasElement;\r\n\r\n /**\r\n * Graphics context for the screen\r\n */\r\n context: ExcaliburGraphicsContext;\r\n\r\n /**\r\n * Browser abstraction\r\n */\r\n browser: BrowserEvents;\r\n /**\r\n * Optionally set antialiasing, defaults to true. If set to true, images will be smoothed\r\n */\r\n antialiasing?: boolean;\r\n /**\r\n * Optionally override the pixel ratio to use for the screen, otherwise calculated automatically from the browser\r\n */\r\n pixelRatio?: number;\r\n /**\r\n * Optionally specify the actual pixel resolution in width/height pixels (also known as logical resolution), by default the\r\n * resolution will be the same as the viewport. Resolution will be overridden by [[DisplayMode.FillContainer]] and\r\n * [[DisplayMode.FillScreen]].\r\n */\r\n resolution?: ScreenDimension;\r\n /**\r\n * Visual viewport size in css pixel, if resolution is not specified it will be the same as the viewport\r\n */\r\n viewport: ScreenDimension;\r\n /**\r\n * Set the display mode of the screen, by default DisplayMode.Fixed.\r\n */\r\n displayMode?: DisplayMode;\r\n}\r\n\r\n/**\r\n * The Screen handles all aspects of interacting with the screen for Excalibur.\r\n */\r\nexport class Screen {\r\n public graphicsContext: ExcaliburGraphicsContext;\r\n private _canvas: HTMLCanvasElement;\r\n private _antialiasing: boolean = true;\r\n private _contentResolution: ScreenDimension;\r\n private _browser: BrowserEvents;\r\n private _camera: Camera;\r\n private _resolution: ScreenDimension;\r\n private _resolutionStack: ScreenDimension[] = [];\r\n private _viewport: ScreenDimension;\r\n private _viewportStack: ScreenDimension[] = [];\r\n private _pixelRatioOverride: number | null = null;\r\n private _displayMode: DisplayMode;\r\n private _isFullScreen = false;\r\n private _mediaQueryList: MediaQueryList;\r\n private _isDisposed = false;\r\n private _logger = Logger.getInstance();\r\n private _resizeObserver: ResizeObserver;\r\n\r\n constructor(options: ScreenOptions) {\r\n this.viewport = options.viewport;\r\n this.resolution = options.resolution ?? { ...this.viewport };\r\n this._contentResolution = this.resolution;\r\n this._displayMode = options.displayMode ?? DisplayMode.Fixed;\r\n this._canvas = options.canvas;\r\n this.graphicsContext = options.context;\r\n this._antialiasing = options.antialiasing ?? this._antialiasing;\r\n this._browser = options.browser;\r\n this._pixelRatioOverride = options.pixelRatio;\r\n\r\n this._applyDisplayMode();\r\n\r\n this._listenForPixelRatio();\r\n\r\n this._canvas.addEventListener('fullscreenchange', this._fullscreenChangeHandler);\r\n this.applyResolutionAndViewport();\r\n }\r\n\r\n private _listenForPixelRatio() {\r\n if (this._mediaQueryList && !this._mediaQueryList.addEventListener) {\r\n // Safari <=13.1 workaround, remove any existing handlers\r\n this._mediaQueryList.removeListener(this._pixelRatioChangeHandler);\r\n }\r\n this._mediaQueryList = this._browser.window.nativeComponent.matchMedia(`(resolution: ${window.devicePixelRatio}dppx)`);\r\n\r\n // Safari <=13.1 workaround\r\n if (this._mediaQueryList.addEventListener) {\r\n this._mediaQueryList.addEventListener('change', this._pixelRatioChangeHandler, { once: true });\r\n } else {\r\n this._mediaQueryList.addListener(this._pixelRatioChangeHandler);\r\n }\r\n }\r\n\r\n public dispose(): void {\r\n if (!this._isDisposed) {\r\n // Clean up handlers\r\n this._isDisposed = true;\r\n this._browser.window.off('resize', this._resizeHandler);\r\n if (this._resizeObserver) {\r\n this._resizeObserver.disconnect();\r\n }\r\n this.parent.removeEventListener('resize', this._resizeHandler);\r\n // Safari <=13.1 workaround\r\n if (this._mediaQueryList.removeEventListener) {\r\n this._mediaQueryList.removeEventListener('change', this._pixelRatioChangeHandler);\r\n } else {\r\n this._mediaQueryList.removeListener(this._pixelRatioChangeHandler);\r\n }\r\n this._canvas.removeEventListener('fullscreenchange', this._fullscreenChangeHandler);\r\n }\r\n }\r\n\r\n private _fullscreenChangeHandler = () => {\r\n this._isFullScreen = !this._isFullScreen;\r\n this._logger.debug('Fullscreen Change', this._isFullScreen);\r\n };\r\n\r\n private _pixelRatioChangeHandler = () => {\r\n this._logger.debug('Pixel Ratio Change', window.devicePixelRatio);\r\n this._listenForPixelRatio();\r\n this._devicePixelRatio = this._calculateDevicePixelRatio();\r\n this.applyResolutionAndViewport();\r\n };\r\n\r\n private _resizeHandler = () => {\r\n const parent = this.parent;\r\n this._logger.debug('View port resized');\r\n this._setResolutionAndViewportByDisplayMode(parent);\r\n this.applyResolutionAndViewport();\r\n };\r\n\r\n private _calculateDevicePixelRatio() {\r\n if (window.devicePixelRatio < 1) {\r\n return 1;\r\n }\r\n\r\n const devicePixelRatio = window.devicePixelRatio || 1;\r\n\r\n return devicePixelRatio;\r\n }\r\n\r\n // Asking the window.devicePixelRatio is expensive we do it once\r\n private _devicePixelRatio = this._calculateDevicePixelRatio();\r\n\r\n public get pixelRatio(): number {\r\n if (this._pixelRatioOverride) {\r\n return this._pixelRatioOverride;\r\n }\r\n\r\n return this._devicePixelRatio;\r\n }\r\n\r\n public get isHiDpi() {\r\n return this.pixelRatio !== 1;\r\n }\r\n\r\n public get displayMode(): DisplayMode {\r\n return this._displayMode;\r\n }\r\n\r\n public get canvas(): HTMLCanvasElement {\r\n return this._canvas;\r\n }\r\n\r\n public get parent(): HTMLElement | Window {\r\n switch (this.displayMode) {\r\n case DisplayMode.FillContainer:\r\n case DisplayMode.FitContainer:\r\n case DisplayMode.FitContainerAndFill:\r\n case DisplayMode.FitContainerAndZoom:\r\n return this.canvas.parentElement || document.body;\r\n default:\r\n return window;\r\n }\r\n }\r\n\r\n public get resolution(): ScreenDimension {\r\n return this._resolution;\r\n }\r\n\r\n public set resolution(resolution: ScreenDimension) {\r\n this._resolution = resolution;\r\n }\r\n\r\n public get viewport(): ScreenDimension {\r\n if (this._viewport) {\r\n return this._viewport;\r\n }\r\n return this._resolution;\r\n }\r\n\r\n public set viewport(viewport: ScreenDimension) {\r\n this._viewport = viewport;\r\n }\r\n\r\n public get aspectRatio() {\r\n return this._resolution.width / this._resolution.height;\r\n }\r\n\r\n public get scaledWidth() {\r\n return this._resolution.width * this.pixelRatio;\r\n }\r\n\r\n public get scaledHeight() {\r\n return this._resolution.height * this.pixelRatio;\r\n }\r\n\r\n public setCurrentCamera(camera: Camera) {\r\n this._camera = camera;\r\n }\r\n\r\n public pushResolutionAndViewport() {\r\n this._resolutionStack.push(this.resolution);\r\n this._viewportStack.push(this.viewport);\r\n\r\n this.resolution = { ...this.resolution };\r\n this.viewport = { ...this.viewport };\r\n }\r\n\r\n public peekViewport(): ScreenDimension {\r\n return this._viewportStack[this._viewportStack.length - 1];\r\n }\r\n\r\n public peekResolution(): ScreenDimension {\r\n return this._resolutionStack[this._resolutionStack.length - 1];\r\n }\r\n\r\n public popResolutionAndViewport() {\r\n this.resolution = this._resolutionStack.pop();\r\n this.viewport = this._viewportStack.pop();\r\n }\r\n\r\n private _alreadyWarned = false;\r\n public applyResolutionAndViewport() {\r\n this._canvas.width = this.scaledWidth;\r\n this._canvas.height = this.scaledHeight;\r\n\r\n if (this.graphicsContext instanceof ExcaliburGraphicsContextWebGL) {\r\n const supported = this.graphicsContext.checkIfResolutionSupported({\r\n width: this.scaledWidth,\r\n height: this.scaledHeight\r\n });\r\n if (!supported && !this._alreadyWarned) {\r\n this._alreadyWarned = true; // warn once\r\n this._logger.warn(\r\n `The currently configured resolution (${this.resolution.width}x${this.resolution.height}) and pixel ratio (${this.pixelRatio})` +\r\n ' are too large for the platform WebGL implementation, this may work but cause WebGL rendering to behave oddly.' +\r\n ' Try reducing the resolution or disabling Hi DPI scaling to avoid this' +\r\n ' (read more here https://excaliburjs.com/docs/screens#understanding-viewport--resolution).');\r\n }\r\n }\r\n\r\n if (this._antialiasing) {\r\n this._canvas.style.imageRendering = 'auto';\r\n } else {\r\n this._canvas.style.imageRendering = 'pixelated';\r\n // Fall back to 'crisp-edges' if 'pixelated' is not supported\r\n // Currently for firefox https://developer.mozilla.org/en-US/docs/Web/CSS/image-rendering\r\n if (this._canvas.style.imageRendering === '') {\r\n this._canvas.style.imageRendering = 'crisp-edges';\r\n }\r\n }\r\n this._canvas.style.width = this.viewport.width + 'px';\r\n this._canvas.style.height = this.viewport.height + 'px';\r\n\r\n // After messing with the canvas width/height the graphics context is invalidated and needs to have some properties reset\r\n this.graphicsContext.updateViewport(this.resolution);\r\n this.graphicsContext.resetTransform();\r\n this.graphicsContext.smoothing = this._antialiasing;\r\n if (this.graphicsContext instanceof ExcaliburGraphicsContext2DCanvas) {\r\n this.graphicsContext.scale(this.pixelRatio, this.pixelRatio);\r\n }\r\n }\r\n\r\n public get antialiasing() {\r\n return this._antialiasing;\r\n }\r\n\r\n public set antialiasing(isSmooth: boolean) {\r\n this._antialiasing = isSmooth;\r\n this.graphicsContext.smoothing = this._antialiasing;\r\n }\r\n\r\n /**\r\n * Returns true if excalibur is fullscreen using the browser fullscreen api\r\n */\r\n public get isFullScreen() {\r\n return this._isFullScreen;\r\n }\r\n\r\n /**\r\n * Requests to go fullscreen using the browser fullscreen api, requires user interaction to be successful.\r\n * For example, wire this to a user click handler.\r\n *\r\n * Optionally specify a target element id to go fullscreen, by default the game canvas is used\r\n * @param elementId\r\n */\r\n public goFullScreen(elementId?: string): Promise {\r\n if (elementId) {\r\n const maybeElement = document.getElementById(elementId);\r\n if (maybeElement) {\r\n return maybeElement.requestFullscreen();\r\n }\r\n }\r\n return this._canvas.requestFullscreen();\r\n }\r\n\r\n /**\r\n * Requests to exit fullscreen using the browser fullscreen api\r\n */\r\n public exitFullScreen(): Promise {\r\n return document.exitFullscreen();\r\n }\r\n\r\n /**\r\n * Takes a coordinate in normal html page space, for example from a pointer move event, and translates it to\r\n * Excalibur screen space.\r\n *\r\n * Excalibur screen space starts at the top left (0, 0) corner of the viewport, and extends to the\r\n * bottom right corner (resolutionX, resolutionY)\r\n * @param point\r\n */\r\n public pageToScreenCoordinates(point: Vector): Vector {\r\n let newX = point.x;\r\n let newY = point.y;\r\n\r\n if (!this._isFullScreen) {\r\n newX -= getPosition(this._canvas).x;\r\n newY -= getPosition(this._canvas).y;\r\n }\r\n\r\n // if fullscreen api on it centers with black bars\r\n // we need to adjust the screen to world coordinates in this case\r\n if (this._isFullScreen) {\r\n if (window.innerWidth / this.aspectRatio < window.innerHeight) {\r\n const screenHeight = window.innerWidth / this.aspectRatio;\r\n const screenMarginY = (window.innerHeight - screenHeight) / 2;\r\n newY = ((newY - screenMarginY) / screenHeight) * this.viewport.height;\r\n newX = (newX / window.innerWidth) * this.viewport.width;\r\n } else {\r\n const screenWidth = window.innerHeight * this.aspectRatio;\r\n const screenMarginX = (window.innerWidth - screenWidth) / 2;\r\n newX = ((newX - screenMarginX) / screenWidth) * this.viewport.width;\r\n newY = (newY / window.innerHeight) * this.viewport.height;\r\n }\r\n }\r\n\r\n newX = (newX / this.viewport.width) * this.resolution.width;\r\n newY = (newY / this.viewport.height) * this.resolution.height;\r\n\r\n return new Vector(newX, newY);\r\n }\r\n\r\n /**\r\n * Takes a coordinate in Excalibur screen space, and translates it to normal html page space. For example,\r\n * this is where html elements might live if you want to position them relative to Excalibur.\r\n *\r\n * Excalibur screen space starts at the top left (0, 0) corner of the viewport, and extends to the\r\n * bottom right corner (resolutionX, resolutionY)\r\n * @param point\r\n */\r\n public screenToPageCoordinates(point: Vector): Vector {\r\n let newX = point.x;\r\n let newY = point.y;\r\n\r\n newX = (newX / this.resolution.width) * this.viewport.width;\r\n newY = (newY / this.resolution.height) * this.viewport.height;\r\n\r\n if (this._isFullScreen) {\r\n if (window.innerWidth / this.aspectRatio < window.innerHeight) {\r\n const screenHeight = window.innerWidth / this.aspectRatio;\r\n const screenMarginY = (window.innerHeight - screenHeight) / 2;\r\n newY = (newY / this.viewport.height) * screenHeight + screenMarginY;\r\n newX = (newX / this.viewport.width) * window.innerWidth;\r\n } else {\r\n const screenWidth = window.innerHeight * this.aspectRatio;\r\n const screenMarginX = (window.innerWidth - screenWidth) / 2;\r\n newX = (newX / this.viewport.width) * screenWidth + screenMarginX;\r\n newY = (newY / this.viewport.height) * window.innerHeight;\r\n }\r\n }\r\n\r\n if (!this._isFullScreen) {\r\n newX += getPosition(this._canvas).x;\r\n newY += getPosition(this._canvas).y;\r\n }\r\n\r\n return new Vector(newX, newY);\r\n }\r\n\r\n /**\r\n * Takes a coordinate in Excalibur screen space, and translates it to Excalibur world space.\r\n *\r\n * World space is where [[Entity|entities]] in Excalibur live by default [[CoordPlane.World]]\r\n * and extends infinitely out relative from the [[Camera]].\r\n * @param point Screen coordinate to convert\r\n */\r\n public screenToWorldCoordinates(point: Vector): Vector {\r\n // the only difference between screen & world is the camera transform\r\n if (this._camera) {\r\n return this._camera.inverse.multiply(point);\r\n }\r\n return point.sub(vec(this.resolution.width / 2, this.resolution.height / 2));\r\n }\r\n\r\n /**\r\n * Takes a coordinate in Excalibur world space, and translates it to Excalibur screen space.\r\n *\r\n * Screen space is where [[ScreenElement|screen elements]] and [[Entity|entities]] with [[CoordPlane.Screen]] live.\r\n * @param point World coordinate to convert\r\n */\r\n public worldToScreenCoordinates(point: Vector): Vector {\r\n if (this._camera) {\r\n return this._camera.transform.multiply(point);\r\n }\r\n return point.add(vec(this.resolution.width / 2, this.resolution.height / 2));\r\n }\r\n\r\n public pageToWorldCoordinates(point: Vector): Vector {\r\n const screen = this.pageToScreenCoordinates(point);\r\n return this.screenToWorldCoordinates(screen);\r\n }\r\n\r\n public worldToPageCoordinates(point: Vector): Vector {\r\n const screen = this.worldToScreenCoordinates(point);\r\n return this.screenToPageCoordinates(screen);\r\n }\r\n\r\n /**\r\n * Returns a BoundingBox of the top left corner of the screen\r\n * and the bottom right corner of the screen.\r\n *\r\n * World bounds are in world coordinates, useful for culling objects offscreen\r\n */\r\n public getWorldBounds(): BoundingBox {\r\n const bounds = BoundingBox.fromDimension(\r\n this.resolution.width,\r\n this.resolution.height,\r\n Vector.Half)\r\n .scale(vec(1/this._camera.zoom, 1/this._camera.zoom))\r\n .rotate(this._camera.rotation)\r\n .translate(this._camera.pos);\r\n return bounds;\r\n }\r\n\r\n /**\r\n * The width of the game canvas in pixels (physical width component of the\r\n * resolution of the canvas element)\r\n */\r\n public get canvasWidth(): number {\r\n return this.canvas.width;\r\n }\r\n\r\n /**\r\n * Returns half width of the game canvas in pixels (half physical width component)\r\n */\r\n public get halfCanvasWidth(): number {\r\n return this.canvas.width / 2;\r\n }\r\n\r\n /**\r\n * The height of the game canvas in pixels, (physical height component of\r\n * the resolution of the canvas element)\r\n */\r\n public get canvasHeight(): number {\r\n return this.canvas.height;\r\n }\r\n\r\n /**\r\n * Returns half height of the game canvas in pixels (half physical height component)\r\n */\r\n public get halfCanvasHeight(): number {\r\n return this.canvas.height / 2;\r\n }\r\n\r\n /**\r\n * Returns the width of the engine's visible drawing surface in pixels including zoom and device pixel ratio.\r\n */\r\n public get drawWidth(): number {\r\n if (this._camera) {\r\n return this.resolution.width / this._camera.zoom;\r\n }\r\n return this.resolution.width;\r\n }\r\n\r\n /**\r\n * Returns half the width of the engine's visible drawing surface in pixels including zoom and device pixel ratio.\r\n */\r\n public get halfDrawWidth(): number {\r\n return this.drawWidth / 2;\r\n }\r\n\r\n /**\r\n * Returns the height of the engine's visible drawing surface in pixels including zoom and device pixel ratio.\r\n */\r\n public get drawHeight(): number {\r\n if (this._camera) {\r\n return this.resolution.height / this._camera.zoom;\r\n }\r\n return this.resolution.height;\r\n }\r\n\r\n /**\r\n * Returns half the height of the engine's visible drawing surface in pixels including zoom and device pixel ratio.\r\n */\r\n public get halfDrawHeight(): number {\r\n return this.drawHeight / 2;\r\n }\r\n\r\n /**\r\n * Returns screen center coordinates including zoom and device pixel ratio.\r\n */\r\n public get center(): Vector {\r\n return vec(this.halfDrawWidth, this.halfDrawHeight);\r\n }\r\n\r\n /**\r\n * Returns the content area in screen space where it is safe to place content\r\n */\r\n public get contentArea(): BoundingBox {\r\n return this._contentArea;\r\n }\r\n\r\n private _computeFit() {\r\n document.body.style.margin = '0px';\r\n document.body.style.overflow = 'hidden';\r\n const aspect = this.aspectRatio;\r\n let adjustedWidth = 0;\r\n let adjustedHeight = 0;\r\n if (window.innerWidth / aspect < window.innerHeight) {\r\n adjustedWidth = window.innerWidth;\r\n adjustedHeight = window.innerWidth / aspect;\r\n } else {\r\n adjustedWidth = window.innerHeight * aspect;\r\n adjustedHeight = window.innerHeight;\r\n }\r\n\r\n this.viewport = {\r\n width: adjustedWidth,\r\n height: adjustedHeight\r\n };\r\n this._contentArea = BoundingBox.fromDimension(this.resolution.width, this.resolution.height, Vector.Zero);\r\n }\r\n\r\n private _contentArea: BoundingBox = new BoundingBox();\r\n private _computeFitScreenAndFill() {\r\n document.body.style.margin = '0px';\r\n document.body.style.overflow = 'hidden';\r\n const vw = window.innerWidth;\r\n const vh = window.innerHeight;\r\n this._computeFitAndFill(vw, vh);\r\n }\r\n\r\n\r\n\r\n private _computeFitContainerAndFill() {\r\n document.body.style.margin = '0px';\r\n document.body.style.overflow = 'hidden';\r\n const parent = this.canvas.parentElement;\r\n const vw = parent.clientWidth;\r\n const vh = parent.clientHeight;\r\n this._computeFitAndFill(vw, vh);\r\n }\r\n\r\n private _computeFitAndFill(vw: number, vh: number) {\r\n this.viewport = {\r\n width: vw,\r\n height: vh\r\n };\r\n // if the current screen aspectRatio is less than the original aspectRatio\r\n if (vw / vh <= this._contentResolution.width / this._contentResolution.height) {\r\n // compute new resolution to match the original aspect ratio\r\n this.resolution = {\r\n width: vw * this._contentResolution.width / vw,\r\n height: vw * this._contentResolution.width / vw * vh / vw\r\n };\r\n const clip = (this.resolution.height - this._contentResolution.height) / 2;\r\n this._contentArea = new BoundingBox({\r\n top: clip,\r\n left: 0,\r\n right: this._contentResolution.width,\r\n bottom: this.resolution.height - clip\r\n });\r\n } else {\r\n this.resolution = {\r\n width: vh * this._contentResolution.height / vh * vw / vh,\r\n height: vh * this._contentResolution.height / vh\r\n };\r\n const clip = (this.resolution.width - this._contentResolution.width) / 2;\r\n this._contentArea = new BoundingBox({\r\n top: 0,\r\n left: clip,\r\n right: this.resolution.width - clip,\r\n bottom: this._contentResolution.height\r\n });\r\n }\r\n }\r\n\r\n private _computeFitScreenAndZoom() {\r\n document.body.style.margin = '0px';\r\n document.body.style.overflow = 'hidden';\r\n this.canvas.style.position = 'absolute';\r\n\r\n const vw = window.innerWidth;\r\n const vh = window.innerHeight;\r\n\r\n this._computeFitAndZoom(vw, vh);\r\n }\r\n\r\n private _computeFitContainerAndZoom() {\r\n document.body.style.margin = '0px';\r\n document.body.style.overflow = 'hidden';\r\n this.canvas.style.position = 'absolute';\r\n const parent = this.canvas.parentElement;\r\n parent.style.position = 'relative';\r\n parent.style.overflow = 'hidden';\r\n\r\n const vw = parent.clientWidth;\r\n const vh = parent.clientHeight;\r\n\r\n this._computeFitAndZoom(vw, vh);\r\n }\r\n\r\n private _computeFitAndZoom(vw: number, vh: number) {\r\n const aspect = this.aspectRatio;\r\n let adjustedWidth = 0;\r\n let adjustedHeight = 0;\r\n if (vw / aspect < vh) {\r\n adjustedWidth = vw;\r\n adjustedHeight = vw / aspect;\r\n } else {\r\n adjustedWidth = vh * aspect;\r\n adjustedHeight = vh;\r\n }\r\n\r\n const scaleX = vw / adjustedWidth;\r\n const scaleY = vh / adjustedHeight;\r\n\r\n const maxScaleFactor = Math.max(scaleX, scaleY);\r\n\r\n const zoomedWidth = adjustedWidth * maxScaleFactor;\r\n const zoomedHeight = adjustedHeight * maxScaleFactor;\r\n\r\n // Center zoomed dimension if bigger than the screen\r\n if (zoomedWidth > vw) {\r\n this.canvas.style.left = -(zoomedWidth - vw) / 2 + 'px';\r\n } else {\r\n this.canvas.style.left = '';\r\n }\r\n\r\n if (zoomedHeight > vh) {\r\n this.canvas.style.top = -(zoomedHeight - vh) / 2 + 'px';\r\n } else {\r\n this.canvas.style.top = '';\r\n }\r\n\r\n this.viewport = {\r\n width: zoomedWidth,\r\n height: zoomedHeight\r\n };\r\n\r\n const bounds = BoundingBox.fromDimension(this.viewport.width, this.viewport.height, Vector.Zero);\r\n // return safe area\r\n if (this.viewport.width > vw) {\r\n const clip = (this.viewport.width - vw)/this.viewport.width * this.resolution.width;\r\n bounds.top = 0;\r\n bounds.left = clip / 2;\r\n bounds.right = this.resolution.width - clip / 2;\r\n bounds.bottom = this.resolution.height;\r\n }\r\n\r\n if (this.viewport.height > vh) {\r\n const clip = (this.viewport.height - vh)/this.viewport.height * this.resolution.height;\r\n bounds.top = clip / 2;\r\n bounds.left = 0;\r\n bounds.bottom = this.resolution.height - clip / 2;\r\n bounds.right = this.resolution.width;\r\n }\r\n this._contentArea = bounds;\r\n }\r\n\r\n private _computeFitContainer() {\r\n const aspect = this.aspectRatio;\r\n let adjustedWidth = 0;\r\n let adjustedHeight = 0;\r\n const parent = this.canvas.parentElement;\r\n if (parent.clientWidth / aspect < parent.clientHeight) {\r\n adjustedWidth = parent.clientWidth;\r\n adjustedHeight = parent.clientWidth / aspect;\r\n } else {\r\n adjustedWidth = parent.clientHeight * aspect;\r\n adjustedHeight = parent.clientHeight;\r\n }\r\n\r\n this.viewport = {\r\n width: adjustedWidth,\r\n height: adjustedHeight\r\n };\r\n this._contentArea = BoundingBox.fromDimension(this.resolution.width, this.resolution.height, Vector.Zero);\r\n }\r\n\r\n private _applyDisplayMode() {\r\n this._setResolutionAndViewportByDisplayMode(this.parent);\r\n\r\n // watch resizing\r\n if (this.parent instanceof Window) {\r\n this._browser.window.on('resize', this._resizeHandler);\r\n } else {\r\n this._resizeObserver = new ResizeObserver(() => {\r\n this._resizeHandler();\r\n });\r\n this._resizeObserver.observe(this.parent);\r\n }\r\n this.parent.addEventListener('resize', this._resizeHandler);\r\n }\r\n\r\n /**\r\n * Sets the resolution and viewport based on the selected display mode.\r\n */\r\n private _setResolutionAndViewportByDisplayMode(parent: HTMLElement | Window) {\r\n if (this.displayMode === DisplayMode.FillContainer) {\r\n this.resolution = {\r\n width: ( parent).clientWidth,\r\n height: ( parent).clientHeight\r\n };\r\n\r\n this.viewport = this.resolution;\r\n }\r\n\r\n if (this.displayMode === DisplayMode.FillScreen) {\r\n document.body.style.margin = '0px';\r\n document.body.style.overflow = 'hidden';\r\n this.resolution = {\r\n width: ( parent).innerWidth,\r\n height: ( parent).innerHeight\r\n };\r\n\r\n this.viewport = this.resolution;\r\n }\r\n\r\n this._contentArea = BoundingBox.fromDimension(this.resolution.width, this.resolution.height, Vector.Zero);\r\n\r\n if (this.displayMode === DisplayMode.FitScreen) {\r\n this._computeFit();\r\n }\r\n\r\n if (this.displayMode === DisplayMode.FitContainer) {\r\n this._computeFitContainer();\r\n }\r\n\r\n if (this.displayMode === DisplayMode.FitScreenAndFill) {\r\n this._computeFitScreenAndFill();\r\n }\r\n\r\n if (this.displayMode === DisplayMode.FitContainerAndFill){\r\n this._computeFitContainerAndFill();\r\n }\r\n\r\n if (this.displayMode === DisplayMode.FitScreenAndZoom) {\r\n this._computeFitScreenAndZoom();\r\n }\r\n\r\n if (this.displayMode === DisplayMode.FitContainerAndZoom){\r\n this._computeFitContainerAndZoom();\r\n }\r\n }\r\n}\r\n","/**\r\n * Internal class used to build instances of AudioContext\r\n */\r\n/* istanbul ignore next */\r\nexport class AudioContextFactory {\r\n private static _INSTANCE: AudioContext = null;\r\n\r\n public static create(): AudioContext {\r\n if (!this._INSTANCE) {\r\n if ((window).AudioContext || (window).webkitAudioContext) {\r\n this._INSTANCE = new AudioContext();\r\n }\r\n }\r\n\r\n return this._INSTANCE;\r\n }\r\n}\r\n","import { AudioContextFactory } from '../Resources/Sound/AudioContext';\r\nimport { Logger } from './Log';\r\n\r\nexport interface LegacyWebAudioSource {\r\n playbackState: string;\r\n PLAYING_STATE: 'playing';\r\n FINISHED_STATE: 'finished';\r\n}\r\n\r\n/**\r\n * Patch for detecting legacy web audio in browsers\r\n * @internal\r\n * @param source\r\n */\r\nfunction isLegacyWebAudioSource(source: any): source is LegacyWebAudioSource {\r\n return !!source.playbackState;\r\n}\r\n\r\nexport class WebAudio {\r\n private static _UNLOCKED: boolean = false;\r\n\r\n /**\r\n * Play an empty sound to unlock Safari WebAudio context. Call this function\r\n * right after a user interaction event.\r\n * @source https://paulbakaus.com/tutorials/html5/web-audio-on-ios/\r\n */\r\n static unlock(): Promise {\r\n const promise = new Promise((resolve, reject) => {\r\n if (WebAudio._UNLOCKED || !AudioContextFactory.create()) {\r\n return resolve(true);\r\n }\r\n const unlockTimeoutTimer = setTimeout(() => {\r\n Logger.getInstance().warn('Excalibur was unable to unlock the audio context, audio probably will not play in this browser.');\r\n resolve(false);\r\n }, 200);\r\n\r\n const audioContext = AudioContextFactory.create();\r\n audioContext.resume().then(\r\n () => {\r\n // create empty buffer and play it\r\n const buffer = audioContext.createBuffer(1, 1, 22050);\r\n const source = audioContext.createBufferSource();\r\n let ended = false;\r\n\r\n source.buffer = buffer;\r\n source.connect(audioContext.destination);\r\n source.onended = () => (ended = true);\r\n\r\n source.start(0);\r\n\r\n // by checking the play state after some time, we know if we're really unlocked\r\n setTimeout(() => {\r\n if (isLegacyWebAudioSource(source)) {\r\n if (source.playbackState === source.PLAYING_STATE || source.playbackState === source.FINISHED_STATE) {\r\n WebAudio._UNLOCKED = true;\r\n }\r\n } else {\r\n if (audioContext.currentTime > 0 || ended) {\r\n WebAudio._UNLOCKED = true;\r\n }\r\n }\r\n }, 0);\r\n\r\n clearTimeout(unlockTimeoutTimer);\r\n resolve(true);\r\n },\r\n () => {\r\n reject();\r\n }\r\n );\r\n });\r\n\r\n return promise;\r\n }\r\n\r\n static isUnlocked() {\r\n return this._UNLOCKED;\r\n }\r\n}\r\n","import { Color } from '../Color';\r\nimport { Vector } from '../Math/vector';\r\n\r\n/**\r\n * A canvas linecap style. \"butt\" is the default flush style, \"round\" is a semi-circle cap with a radius half the width of\r\n * the line, and \"square\" is a rectangle that is an equal width and half height cap.\r\n */\r\nexport type LineCapStyle = 'butt' | 'round' | 'square';\r\n\r\n/* istanbul ignore next */\r\n/**\r\n * Draw a line on canvas context\r\n *\r\n * @param ctx The canvas context\r\n * @param color The color of the line\r\n * @param x1 The start x coordinate\r\n * @param y1 The start y coordinate\r\n * @param x2 The ending x coordinate\r\n * @param y2 The ending y coordinate\r\n * @param thickness The line thickness\r\n * @param cap The [[LineCapStyle]] (butt, round, or square)\r\n */\r\nexport function line(\r\n ctx: CanvasRenderingContext2D,\r\n color: Color = Color.Red,\r\n x1: number,\r\n y1: number,\r\n x2: number,\r\n y2: number,\r\n thickness: number = 1,\r\n cap: LineCapStyle = 'butt'\r\n) {\r\n ctx.save();\r\n ctx.beginPath();\r\n ctx.lineWidth = thickness;\r\n ctx.lineCap = cap;\r\n ctx.strokeStyle = color.toString();\r\n ctx.moveTo(x1, y1);\r\n ctx.lineTo(x2, y2);\r\n ctx.closePath();\r\n ctx.stroke();\r\n ctx.restore();\r\n}\r\n\r\n/* istanbul ignore next */\r\n/**\r\n * Draw the vector as a point onto the canvas.\r\n */\r\nexport function point(ctx: CanvasRenderingContext2D, color: Color = Color.Red, point: Vector): void {\r\n ctx.beginPath();\r\n ctx.strokeStyle = color.toString();\r\n ctx.arc(point.x, point.y, 5, 0, Math.PI * 2);\r\n ctx.closePath();\r\n ctx.stroke();\r\n}\r\n\r\n/**\r\n * Draw the vector as a line onto the canvas starting a origin point.\r\n */\r\n/* istanbul ignore next */\r\n/**\r\n *\r\n */\r\nexport function vector(ctx: CanvasRenderingContext2D, color: Color, origin: Vector, vector: Vector, scale: number = 1.0): void {\r\n const c = color ? color.toString() : 'blue';\r\n const v = vector.scale(scale);\r\n ctx.beginPath();\r\n ctx.strokeStyle = c;\r\n ctx.moveTo(origin.x, origin.y);\r\n ctx.lineTo(origin.x + v.x, origin.y + v.y);\r\n ctx.closePath();\r\n ctx.stroke();\r\n}\r\n\r\n/**\r\n * Represents border radius values\r\n */\r\nexport interface BorderRadius {\r\n /**\r\n * Top-left\r\n */\r\n tl: number;\r\n /**\r\n * Top-right\r\n */\r\n tr: number;\r\n /**\r\n * Bottom-right\r\n */\r\n br: number;\r\n /**\r\n * Bottom-left\r\n */\r\n bl: number;\r\n}\r\n\r\n/**\r\n * Draw a round rectangle on a canvas context\r\n *\r\n * @param ctx The canvas context\r\n * @param x The top-left x coordinate\r\n * @param y The top-left y coordinate\r\n * @param width The width of the rectangle\r\n * @param height The height of the rectangle\r\n * @param radius The border radius of the rectangle\r\n * @param stroke The [[Color]] to stroke rectangle with\r\n * @param fill The [[Color]] to fill rectangle with\r\n */\r\nexport function roundRect(\r\n ctx: CanvasRenderingContext2D,\r\n x: number,\r\n y: number,\r\n width: number,\r\n height: number,\r\n radius: number | BorderRadius = 5,\r\n stroke: Color = Color.White,\r\n fill: Color = null\r\n) {\r\n let br: BorderRadius;\r\n\r\n if (typeof radius === 'number') {\r\n br = { tl: radius, tr: radius, br: radius, bl: radius };\r\n } else {\r\n const defaultRadius: BorderRadius = { tl: 0, tr: 0, br: 0, bl: 0 };\r\n\r\n for (const prop in defaultRadius) {\r\n if (defaultRadius.hasOwnProperty(prop)) {\r\n const side = prop;\r\n br[side] = radius[side] || defaultRadius[side];\r\n }\r\n }\r\n }\r\n\r\n ctx.beginPath();\r\n ctx.moveTo(x + br.tl, y);\r\n ctx.lineTo(x + width - br.tr, y);\r\n ctx.quadraticCurveTo(x + width, y, x + width, y + br.tr);\r\n ctx.lineTo(x + width, y + height - br.br);\r\n ctx.quadraticCurveTo(x + width, y + height, x + width - br.br, y + height);\r\n ctx.lineTo(x + br.bl, y + height);\r\n ctx.quadraticCurveTo(x, y + height, x, y + height - br.bl);\r\n ctx.lineTo(x, y + br.tl);\r\n ctx.quadraticCurveTo(x, y, x + br.tl, y);\r\n ctx.closePath();\r\n\r\n if (fill) {\r\n ctx.fillStyle = fill.toString();\r\n ctx.fill();\r\n }\r\n\r\n if (stroke) {\r\n ctx.strokeStyle = stroke.toString();\r\n ctx.stroke();\r\n }\r\n}\r\n\r\n/**\r\n *\r\n */\r\nexport function circle(\r\n ctx: CanvasRenderingContext2D,\r\n x: number,\r\n y: number,\r\n radius: number,\r\n stroke: Color = Color.White,\r\n fill: Color = null\r\n) {\r\n ctx.beginPath();\r\n ctx.arc(x, y, radius, 0, Math.PI * 2);\r\n ctx.closePath();\r\n\r\n if (fill) {\r\n ctx.fillStyle = fill.toString();\r\n ctx.fill();\r\n }\r\n\r\n if (stroke) {\r\n ctx.strokeStyle = stroke.toString();\r\n ctx.stroke();\r\n }\r\n}\r\n","export default \"data:image/png;base64,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\"","import { Graphic, GraphicOptions } from './Graphic';\r\nimport { ExcaliburGraphicsContext } from './Context/ExcaliburGraphicsContext';\r\nimport { Color } from '../Color';\r\nimport { Vector } from '../Math/vector';\r\nimport { BoundingBox } from '../Collision/BoundingBox';\r\nimport { watch } from '../Util/Watch';\r\nimport { ImageFiltering } from './Filtering';\r\n\r\nexport interface RasterOptions {\r\n /**\r\n * Optionally specify a quality number, which is how much to scale the internal Raster. Default is 1.\r\n *\r\n * For example if the quality is set to 2, it doubles the internal raster bitmap in memory.\r\n *\r\n * Adjusting this value can be useful if you are working with small rasters.\r\n */\r\n quality?: number;\r\n /**\r\n * Optionally specify \"smoothing\" if you want antialiasing to apply to the raster's bitmap context, by default `false`\r\n */\r\n smoothing?: boolean;\r\n\r\n /**\r\n * Optionally specify the color of the raster's bitmap context, by default [[Color.Black]]\r\n */\r\n color?: Color;\r\n\r\n /**\r\n * Optionally specify the stroke color of the raster's bitmap context, by default undefined\r\n */\r\n strokeColor?: Color;\r\n\r\n /**\r\n * Optionally specify the line width of the raster's bitmap, by default 1 pixel\r\n */\r\n lineWidth?: number;\r\n\r\n /**\r\n * Optionally specify the line dash of the raster's bitmap, by default `[]` which means none\r\n */\r\n lineDash?: number[];\r\n\r\n /**\r\n * Optionally specify the line end style, default is \"butt\".\r\n */\r\n lineCap?: 'butt' | 'round' | 'square';\r\n\r\n /**\r\n * Optionally specify the padding to apply to the bitmap\r\n */\r\n padding?: number;\r\n\r\n /**\r\n * Optionally specify what image filtering mode should be used, [[ImageFiltering.Pixel]] for pixel art,\r\n * [[ImageFiltering.Blended]] for hi-res art\r\n *\r\n * By default unset, rasters defer to the engine antialiasing setting\r\n */\r\n filtering?: ImageFiltering;\r\n}\r\n\r\n/**\r\n * A Raster is a Graphic that needs to be first painted to a HTMLCanvasElement before it can be drawn to the\r\n * [[ExcaliburGraphicsContext]]. This is useful for generating custom images using the 2D canvas api.\r\n *\r\n * Implementors must implement the [[Raster.execute]] method to rasterize their drawing.\r\n */\r\nexport abstract class Raster extends Graphic {\r\n public filtering: ImageFiltering = null;\r\n public lineCap: 'butt' | 'round' | 'square' = 'butt';\r\n public quality: number = 1;\r\n\r\n public _bitmap: HTMLCanvasElement;\r\n protected _ctx: CanvasRenderingContext2D;\r\n private _dirty: boolean = true;\r\n\r\n constructor(options?: GraphicOptions & RasterOptions) {\r\n super(options);\r\n if (options) {\r\n this.quality = options.quality ?? this.quality;\r\n this.color = options.color ?? Color.Black;\r\n this.strokeColor = options?.strokeColor;\r\n this.smoothing = options.smoothing ?? this.smoothing;\r\n this.lineWidth = options.lineWidth ?? this.lineWidth;\r\n this.lineDash = options.lineDash ?? this.lineDash;\r\n this.lineCap = options.lineCap ?? this.lineCap;\r\n this.padding = options.padding ?? this.padding;\r\n this.filtering = options.filtering ?? this.filtering;\r\n }\r\n this._bitmap = document.createElement('canvas');\r\n // get the default canvas width/height as a fallback\r\n const bitmapWidth = options?.width ?? this._bitmap.width;\r\n const bitmapHeight = options?.height ?? this._bitmap.height;\r\n this.width = bitmapWidth;\r\n this.height = bitmapHeight;\r\n const maybeCtx = this._bitmap.getContext('2d');\r\n if (!maybeCtx) {\r\n /* istanbul ignore next */\r\n throw new Error('Browser does not support 2d canvas drawing, cannot create Raster graphic');\r\n } else {\r\n this._ctx = maybeCtx;\r\n }\r\n }\r\n\r\n public cloneRasterOptions(): RasterOptions {\r\n return {\r\n color: this.color ? this.color.clone() : null,\r\n strokeColor: this.strokeColor ? this.strokeColor.clone() : null,\r\n smoothing: this.smoothing,\r\n lineWidth: this.lineWidth,\r\n lineDash: this.lineDash,\r\n lineCap: this.lineCap,\r\n quality: this.quality,\r\n padding: this.padding\r\n };\r\n }\r\n\r\n /**\r\n * Gets whether the graphic is dirty, this means there are changes that haven't been re-rasterized\r\n */\r\n public get dirty() {\r\n return this._dirty;\r\n }\r\n\r\n /**\r\n * Flags the graphic as dirty, meaning it must be re-rasterized before draw.\r\n * This should be called any time the graphics state changes such that it affects the outputted drawing\r\n */\r\n public flagDirty() {\r\n this._dirty = true;\r\n }\r\n\r\n private _originalWidth: number;\r\n /**\r\n * Gets or sets the current width of the Raster graphic. Setting the width will cause the raster\r\n * to be flagged dirty causing a re-raster on the next draw.\r\n *\r\n * Any `padding`s or `quality` set will be factored into the width\r\n */\r\n public get width() {\r\n return Math.abs(this._getTotalWidth() * this.scale.x);\r\n }\r\n public set width(value: number) {\r\n value /= Math.abs(this.scale.x);\r\n this._bitmap.width = value;\r\n this._originalWidth = value;\r\n this.flagDirty();\r\n }\r\n\r\n private _originalHeight: number;\r\n /**\r\n * Gets or sets the current height of the Raster graphic. Setting the height will cause the raster\r\n * to be flagged dirty causing a re-raster on the next draw.\r\n *\r\n * Any `padding` or `quality` set will be factored into the height\r\n */\r\n public get height() {\r\n return Math.abs(this._getTotalHeight() * this.scale.y);\r\n }\r\n\r\n public set height(value: number) {\r\n value /= Math.abs(this.scale.y);\r\n this._bitmap.height = value;\r\n this._originalHeight = value;\r\n this.flagDirty();\r\n }\r\n\r\n private _getTotalWidth() {\r\n return ((this._originalWidth ?? this._bitmap.width) + this.padding * 2) * 1;\r\n }\r\n\r\n private _getTotalHeight() {\r\n return ((this._originalHeight ?? this._bitmap.height) + this.padding * 2) * 1;\r\n }\r\n\r\n /**\r\n * Returns the local bounds of the Raster including the padding\r\n */\r\n public get localBounds() {\r\n return BoundingBox.fromDimension(this._getTotalWidth() * this.scale.x, this._getTotalHeight() * this.scale.y, Vector.Zero);\r\n }\r\n\r\n private _smoothing: boolean = false;\r\n /**\r\n * Gets or sets the smoothing (anti-aliasing of the graphic). Setting the height will cause the raster\r\n * to be flagged dirty causing a re-raster on the next draw.\r\n */\r\n public get smoothing() {\r\n return this._smoothing;\r\n }\r\n public set smoothing(value: boolean) {\r\n this._smoothing = value;\r\n this.flagDirty();\r\n }\r\n\r\n private _color: Color = watch(Color.Black, () => this.flagDirty());\r\n /**\r\n * Gets or sets the fillStyle of the Raster graphic. Setting the fillStyle will cause the raster to be\r\n * flagged dirty causing a re-raster on the next draw.\r\n */\r\n public get color() {\r\n return this._color;\r\n }\r\n public set color(value) {\r\n this.flagDirty();\r\n this._color = watch(value, () => this.flagDirty());\r\n }\r\n\r\n private _strokeColor: Color;\r\n /**\r\n * Gets or sets the strokeStyle of the Raster graphic. Setting the strokeStyle will cause the raster to be\r\n * flagged dirty causing a re-raster on the next draw.\r\n */\r\n public get strokeColor() {\r\n return this._strokeColor;\r\n }\r\n public set strokeColor(value) {\r\n this.flagDirty();\r\n this._strokeColor = watch(value, () => this.flagDirty());\r\n }\r\n\r\n private _lineWidth: number = 1;\r\n /**\r\n * Gets or sets the line width of the Raster graphic. Setting the lineWidth will cause the raster to be\r\n * flagged dirty causing a re-raster on the next draw.\r\n */\r\n public get lineWidth() {\r\n return this._lineWidth;\r\n }\r\n public set lineWidth(value) {\r\n this._lineWidth = value;\r\n this.flagDirty();\r\n }\r\n\r\n private _lineDash: number[] = [];\r\n public get lineDash() {\r\n return this._lineDash;\r\n }\r\n\r\n public set lineDash(value) {\r\n this._lineDash = value;\r\n this.flagDirty();\r\n }\r\n\r\n private _padding: number = 0;\r\n public get padding() {\r\n return this._padding;\r\n }\r\n\r\n public set padding(value: number) {\r\n this._padding = value;\r\n this.flagDirty();\r\n }\r\n\r\n /**\r\n * Rasterize the graphic to a bitmap making it usable as in excalibur. Rasterize is called automatically if\r\n * the graphic is [[Raster.dirty]] on the next [[Graphic.draw]] call\r\n */\r\n public rasterize(): void {\r\n this._dirty = false;\r\n this._ctx.clearRect(0, 0, this._getTotalWidth(), this._getTotalHeight());\r\n this._ctx.save();\r\n this._applyRasterProperties(this._ctx);\r\n this.execute(this._ctx);\r\n this._ctx.restore();\r\n }\r\n\r\n protected _applyRasterProperties(ctx: CanvasRenderingContext2D) {\r\n this._bitmap.width = this._getTotalWidth() * this.quality;\r\n this._bitmap.height = this._getTotalHeight() * this.quality;\r\n // Do a bad thing to pass the filtering as an attribute\r\n this._bitmap.setAttribute('filtering', this.filtering);\r\n this._bitmap.setAttribute('forceUpload', 'true');\r\n ctx.scale(this.quality, this.quality);\r\n ctx.translate(this.padding, this.padding);\r\n ctx.imageSmoothingEnabled = this.smoothing;\r\n ctx.lineWidth = this.lineWidth;\r\n ctx.setLineDash(this.lineDash ?? ctx.getLineDash());\r\n ctx.lineCap = this.lineCap;\r\n ctx.strokeStyle = this.strokeColor?.toString();\r\n ctx.fillStyle = this.color?.toString();\r\n }\r\n\r\n protected _drawImage(ex: ExcaliburGraphicsContext, x: number, y: number) {\r\n if (this._dirty) {\r\n this.rasterize();\r\n }\r\n ex.scale(1 / this.quality, 1 / this.quality);\r\n ex.drawImage(this._bitmap, x, y);\r\n }\r\n\r\n /**\r\n * Executes drawing implementation of the graphic, this is where the specific drawing code for the graphic\r\n * should be implemented. Once `rasterize()` the graphic can be drawn to the [[ExcaliburGraphicsContext]] via `draw(...)`\r\n * @param ctx Canvas to draw the graphic to\r\n */\r\n abstract execute(ctx: CanvasRenderingContext2D): void;\r\n}\r\n","import { GraphicOptions } from './Graphic';\r\nimport { Raster, RasterOptions } from './Raster';\r\n\r\nexport interface CanvasOptions {\r\n draw?: (ctx: CanvasRenderingContext2D) => void;\r\n cache?: boolean;\r\n}\r\n\r\n/**\r\n * A canvas [[Graphic]] to provide an adapter between the 2D Canvas API and the [[ExcaliburGraphicsContext]].\r\n *\r\n * The [[Canvas]] works by re-rastering a draw handler to a HTMLCanvasElement for every draw which is then passed\r\n * to the [[ExcaliburGraphicsContext]] implementation as a rendered image.\r\n *\r\n * **Low performance API**\r\n */\r\nexport class Canvas extends Raster {\r\n /**\r\n * Return the 2D graphics context of this canvas\r\n */\r\n public get ctx() {\r\n return this._ctx;\r\n }\r\n\r\n constructor(private _options: GraphicOptions & RasterOptions & CanvasOptions) {\r\n super(_options);\r\n }\r\n\r\n public clone(): Canvas {\r\n return new Canvas({\r\n ...this._options,\r\n ...this.cloneGraphicOptions(),\r\n ...this.cloneRasterOptions()\r\n });\r\n }\r\n\r\n execute(ctx: CanvasRenderingContext2D): void {\r\n if (this._options?.draw) {\r\n this._options?.draw(ctx);\r\n }\r\n if (!this._options.cache) {\r\n this.flagDirty();\r\n }\r\n }\r\n}\r\n","import { Audio } from './Audio';\r\n\r\nexport type ExResponseType = '' | 'arraybuffer' | 'blob' | 'document' | 'json' | 'text';\r\n\r\nexport interface ExResponseTypesLookup {\r\n [name: string]: ExResponseType;\r\n}\r\n\r\nexport class ExResponse {\r\n public static type: ExResponseTypesLookup = {\r\n any: '',\r\n blob: 'blob',\r\n json: 'json',\r\n text: 'text',\r\n document: 'document',\r\n arraybuffer: 'arraybuffer'\r\n };\r\n}\r\n\r\n/**\r\n * Represents an audio implementation like [[WebAudioInstance]]\r\n */\r\nexport interface AudioImplementation {\r\n /**\r\n * XHR response type\r\n */\r\n responseType: ExResponseType;\r\n\r\n /**\r\n * Processes raw data and transforms into sound data\r\n */\r\n processData(data: Blob | ArrayBuffer): Promise;\r\n\r\n /**\r\n * Factory method that returns an instance of a played audio track\r\n */\r\n createInstance(data: string | AudioBuffer): Audio;\r\n}\r\n","\r\nexport interface State {\r\n name?: string;\r\n transitions: string[];\r\n onEnter?: (context: {from: string, eventData?: any, data: any}) => boolean | void;\r\n onState?: () => any;\r\n onExit?: (context: {to: string, data: any}) => boolean | void;\r\n onUpdate?: (data: any, elapsedMs: number) => any;\r\n}\r\n\r\nexport interface StateMachineDescription {\r\n start: string,\r\n states: { [name: string]: State }\r\n}\r\n\r\nexport type PossibleStates = TMachine extends StateMachineDescription ? Extract : never;\r\n\r\nexport interface StateMachineState {\r\n data: any;\r\n currentState: string;\r\n}\r\n\r\nexport class StateMachine {\r\n public startState: State;\r\n private _currentState: State;\r\n public get currentState(): State {\r\n return this._currentState;\r\n }\r\n public set currentState(state: State) {\r\n this._currentState = state;\r\n }\r\n public states = new Map();\r\n public data: TData;\r\n\r\n static create(\r\n machineDescription: TMachine, data?: TData): StateMachine, TData> {\r\n const machine = new StateMachine, TData>();\r\n machine.data = data;\r\n for (const stateName in machineDescription.states) {\r\n machine.states.set(stateName as PossibleStates, {\r\n name: stateName,\r\n ...machineDescription.states[stateName]\r\n });\r\n }\r\n\r\n // validate transitions are states\r\n for (const state of machine.states.values()) {\r\n for (const transitionState of state.transitions) {\r\n if (transitionState === '*') {\r\n continue;\r\n }\r\n if (!machine.states.has(transitionState)) {\r\n throw Error(\r\n `Invalid state machine, state [${state.name}] has a transition to another state that doesn't exist [${transitionState}]`\r\n );\r\n }\r\n }\r\n }\r\n machine.currentState = machine.startState = machine.states.get(machineDescription.start);\r\n return machine;\r\n }\r\n\r\n in(state: TPossibleStates): boolean {\r\n return this.currentState.name === state;\r\n }\r\n\r\n go(stateName: TPossibleStates, eventData?: any): boolean {\r\n if (this.currentState.transitions.includes(stateName) || this.currentState.transitions.includes('*')) {\r\n const potentialNewState = this.states.get(stateName);\r\n if (this.currentState.onExit) {\r\n const canExit = this.currentState?.onExit({to: potentialNewState.name, data: this.data});\r\n if (canExit === false) {\r\n return false;\r\n }\r\n }\r\n\r\n if (potentialNewState?.onEnter) {\r\n const canEnter = potentialNewState?.onEnter({from: this.currentState.name, eventData, data: this.data});\r\n if (canEnter === false) {\r\n return false;\r\n }\r\n }\r\n // console.log(`${this.currentState.name} => ${potentialNewState.name} (${eventData})`);\r\n this.currentState = potentialNewState;\r\n if (this.currentState?.onState) {\r\n this.currentState.onState();\r\n }\r\n return true;\r\n }\r\n return false;\r\n }\r\n\r\n update(elapsedMs: number) {\r\n if (this.currentState.onUpdate) {\r\n this.currentState.onUpdate(this.data, elapsedMs);\r\n }\r\n }\r\n\r\n save(saveKey: string) {\r\n localStorage.setItem(saveKey, JSON.stringify({\r\n currentState: this.currentState.name,\r\n data: this.data\r\n }));\r\n }\r\n\r\n restore(saveKey: string) {\r\n const state: StateMachineState = JSON.parse(localStorage.getItem(saveKey));\r\n this.currentState = this.states.get(state.currentState);\r\n this.data = state.data;\r\n }\r\n}\r\n\r\n","import { StateMachine } from '../../Util/StateMachine';\r\nimport { Audio } from '../../Interfaces/Audio';\r\nimport { clamp } from '../../Math/util';\r\nimport { AudioContextFactory } from './AudioContext';\r\n\r\ninterface SoundState {\r\n startedAt: number;\r\n pausedAt: number;\r\n}\r\n\r\n/**\r\n * Internal class representing a Web Audio AudioBufferSourceNode instance\r\n * @see https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API\r\n */\r\nexport class WebAudioInstance implements Audio {\r\n private _instance: AudioBufferSourceNode;\r\n private _audioContext: AudioContext = AudioContextFactory.create();\r\n private _volumeNode = this._audioContext.createGain();\r\n private _playingResolve: (value: boolean) => void;\r\n private _playingPromise = new Promise((resolve) => {\r\n this._playingResolve = resolve;\r\n });\r\n private _stateMachine = StateMachine.create({\r\n start: 'STOPPED',\r\n states: {\r\n PLAYING: {\r\n onEnter: ({data}: {from: string, data: SoundState}) => {\r\n\r\n // Buffer nodes are single use\r\n this._createNewBufferSource();\r\n this._handleEnd();\r\n if (this.loop) {\r\n // when looping don't set a duration\r\n this._instance.start(0, data.pausedAt * this._playbackRate);\r\n } else {\r\n this._instance.start(0, data.pausedAt * this._playbackRate, this.duration);\r\n }\r\n data.startedAt = (this._audioContext.currentTime - data.pausedAt);\r\n data.pausedAt = 0;\r\n },\r\n onState: () => this._playStarted(),\r\n onExit: ({to}) => {\r\n // If you've exited early only resolve if explicitly STOPPED\r\n if (to === 'STOPPED') {\r\n this._playingResolve(true);\r\n }\r\n // Whenever you're not playing... you stop!\r\n this._instance.onended = null; // disconnect the wired on-end handler\r\n this._instance.disconnect();\r\n this._instance.stop(0);\r\n this._instance = null;\r\n },\r\n transitions: ['STOPPED', 'PAUSED', 'SEEK']\r\n },\r\n SEEK: {\r\n onEnter: ({ eventData: position, data }: {eventData?: number, data: SoundState}) => {\r\n data.pausedAt = (position ?? 0) / this._playbackRate;\r\n data.startedAt = 0;\r\n },\r\n transitions: ['*']\r\n },\r\n STOPPED: {\r\n onEnter: ({data}: {from: string, data: SoundState}) => {\r\n data.pausedAt = 0;\r\n data.startedAt = 0;\r\n this._playingResolve(true);\r\n },\r\n transitions: ['PLAYING', 'PAUSED', 'SEEK']\r\n },\r\n PAUSED: {\r\n onEnter: ({data}: {data: SoundState}) => {\r\n // Playback rate will be a scale factor of how fast/slow the audio is being played\r\n // default is 1.0\r\n // we need to invert it to get the time scale\r\n data.pausedAt = (this._audioContext.currentTime - data.startedAt);\r\n },\r\n transitions: ['PLAYING', 'STOPPED', 'SEEK']\r\n }\r\n }\r\n }, {\r\n startedAt: 0,\r\n pausedAt: 0\r\n } as SoundState);\r\n\r\n private _createNewBufferSource() {\r\n this._instance = this._audioContext.createBufferSource();\r\n this._instance.buffer = this._src;\r\n this._instance.loop = this.loop;\r\n this._instance.playbackRate.value = this._playbackRate;\r\n this._instance.connect(this._volumeNode);\r\n this._volumeNode.connect(this._audioContext.destination);\r\n }\r\n\r\n private _handleEnd() {\r\n if (!this.loop) {\r\n this._instance.onended = () => {\r\n this._playingResolve(true);\r\n };\r\n }\r\n }\r\n\r\n private _volume = 1;\r\n private _loop = false;\r\n // eslint-disable-next-line @typescript-eslint/no-empty-function\r\n private _playStarted: () => any = () => {};\r\n public set loop(value: boolean) {\r\n this._loop = value;\r\n\r\n if (this._instance) {\r\n this._instance.loop = value;\r\n if (!this.loop) {\r\n this._instance.onended = () => {\r\n this._playingResolve(true);\r\n };\r\n }\r\n }\r\n }\r\n public get loop(): boolean {\r\n return this._loop;\r\n }\r\n\r\n public set volume(value: number) {\r\n value = clamp(value, 0, 1.0);\r\n\r\n this._volume = value;\r\n\r\n if (this._stateMachine.in('PLAYING') && this._volumeNode.gain.setTargetAtTime) {\r\n // https://developer.mozilla.org/en-US/docs/Web/API/AudioParam/setTargetAtTime\r\n // After each .1 seconds timestep, the target value will ~63.2% closer to the target value.\r\n // This exponential ramp provides a more pleasant transition in gain\r\n this._volumeNode.gain.setTargetAtTime(value, this._audioContext.currentTime, 0.1);\r\n } else {\r\n this._volumeNode.gain.value = value;\r\n }\r\n }\r\n public get volume(): number {\r\n return this._volume;\r\n }\r\n\r\n private _duration: number | undefined;\r\n /**\r\n * Returns the set duration to play, otherwise returns the total duration if unset\r\n */\r\n public get duration() {\r\n return this._duration ?? this.getTotalPlaybackDuration();\r\n }\r\n\r\n /**\r\n * Set the duration that this audio should play.\r\n *\r\n * Note: if you seek to a specific point the duration will start from that point, for example\r\n *\r\n * If you have a 10 second clip, seek to 5 seconds, then set the duration to 2, it will play the clip from 5-7 seconds.\r\n */\r\n public set duration(duration: number) {\r\n this._duration = duration;\r\n }\r\n\r\n constructor(private _src: AudioBuffer) {\r\n this._createNewBufferSource();\r\n }\r\n\r\n public isPlaying() {\r\n return this._stateMachine.in('PLAYING');\r\n }\r\n\r\n public isPaused() {\r\n return this._stateMachine.in('PAUSED') || this._stateMachine.in('SEEK');\r\n }\r\n\r\n // eslint-disable-next-line @typescript-eslint/no-empty-function\r\n public play(playStarted: () => any = () => {}) {\r\n this._playStarted = playStarted;\r\n this._stateMachine.go('PLAYING');\r\n return this._playingPromise;\r\n }\r\n\r\n public pause() {\r\n this._stateMachine.go('PAUSED');\r\n }\r\n\r\n public stop() {\r\n this._stateMachine.go('STOPPED');\r\n }\r\n\r\n public seek(position: number) {\r\n this._stateMachine.go('PAUSED');\r\n this._stateMachine.go('SEEK', position);\r\n }\r\n\r\n public getTotalPlaybackDuration() {\r\n return this._src.duration;\r\n }\r\n\r\n public getPlaybackPosition() {\r\n const {pausedAt, startedAt} = this._stateMachine.data;\r\n if (pausedAt) {\r\n return pausedAt * this._playbackRate;\r\n }\r\n if (startedAt) {\r\n return (this._audioContext.currentTime - startedAt) * this._playbackRate;\r\n }\r\n return 0;\r\n }\r\n\r\n private _playbackRate = 1.0;\r\n public set playbackRate(playbackRate: number) {\r\n this._instance.playbackRate.value = this._playbackRate = playbackRate;\r\n }\r\n\r\n public get playbackRate() {\r\n return this._instance.playbackRate.value;\r\n }\r\n}\r\n","import { GameEvent } from '../Events';\r\nimport { Sound } from '../Resources/Sound/Sound';\r\nimport { Actor } from '../Actor';\r\nimport { WebAudioInstance } from '../Resources/Sound/WebAudioInstance';\r\n\r\nexport class MediaEvent extends GameEvent {\r\n /**\r\n * Media event cannot bubble\r\n */\r\n public set bubbles(_value: boolean) {\r\n // stubbed\r\n }\r\n /**\r\n * Media event cannot bubble\r\n */\r\n public get bubbles(): boolean {\r\n return false;\r\n }\r\n /**\r\n * Media event cannot bubble, so they have no path\r\n */\r\n protected get _path(): Actor[] {\r\n return null;\r\n }\r\n /**\r\n * Media event cannot bubble, so they have no path\r\n */\r\n protected set _path(_val: Actor[]) {\r\n // stubbed\r\n }\r\n\r\n constructor(public target: Sound, protected _name: string = 'MediaEvent') {\r\n super();\r\n }\r\n\r\n /**\r\n * Prevents event from bubbling\r\n */\r\n public stopPropagation(): void {\r\n /**\r\n * Stub\r\n */\r\n }\r\n /**\r\n * Action, that calls when event happens\r\n */\r\n public action(): void {\r\n /**\r\n * Stub\r\n */\r\n }\r\n /**\r\n * Propagate event further through event path\r\n */\r\n public propagate(): void {\r\n /**\r\n * Stub\r\n */\r\n }\r\n\r\n public layPath(_actor: Actor): void {\r\n /**\r\n * Stub\r\n */\r\n }\r\n}\r\n\r\nexport class NativeSoundEvent extends MediaEvent {\r\n constructor(target: Sound, public track?: WebAudioInstance) {\r\n super(target, 'NativeSoundEvent');\r\n }\r\n}\r\n\r\nexport class NativeSoundProcessedEvent extends MediaEvent {\r\n public data: string | AudioBuffer;\r\n\r\n constructor(target: Sound, private _processedData: string | AudioBuffer) {\r\n super(target, 'NativeSoundProcessedEvent');\r\n\r\n this.data = this._processedData;\r\n }\r\n}\r\n","import { Logger } from './Log';\r\n\r\n/**\r\n * Whether or not the browser can play this file as HTML5 Audio\r\n */\r\nexport function canPlayFile(file: string): boolean {\r\n try {\r\n const a = new Audio();\r\n const filetype = /.*\\.([A-Za-z0-9]+)(?:(?:\\?|\\#).*)*$/;\r\n const type = file.match(filetype)[1];\r\n if (a.canPlayType('audio/' + type)) {\r\n return true;\r\n } else {\r\n return false;\r\n }\r\n } catch (e) {\r\n Logger.getInstance().warn('Cannot determine audio support, assuming no support for the Audio Tag', e);\r\n return false;\r\n }\r\n}\r\n","import { ExResponse } from '../../Interfaces/AudioImplementation';\r\nimport { Audio } from '../../Interfaces/Audio';\r\nimport { Engine } from '../../Engine';\r\nimport { Resource } from '../Resource';\r\nimport { WebAudioInstance } from './WebAudioInstance';\r\nimport { AudioContextFactory } from './AudioContext';\r\nimport { NativeSoundEvent, NativeSoundProcessedEvent } from '../../Events/MediaEvents';\r\nimport { canPlayFile } from '../../Util/Sound';\r\nimport { Loadable } from '../../Interfaces/Index';\r\nimport { Logger } from '../../Util/Log';\r\nimport { EventEmitter, EventKey, Handler, Subscription } from '../../EventEmitter';\r\n\r\nexport type SoundEvents = {\r\n volumechange: NativeSoundEvent,\r\n processed: NativeSoundProcessedEvent,\r\n pause: NativeSoundEvent,\r\n stop: NativeSoundEvent,\r\n playbackend: NativeSoundEvent,\r\n resume: NativeSoundEvent,\r\n playbackstart: NativeSoundEvent\r\n}\r\n\r\nexport const SoundEvents = {\r\n VolumeChange: 'volumechange',\r\n Processed: 'processed',\r\n Pause: 'pause',\r\n Stop: 'stop',\r\n PlaybackEnd: 'playbackend',\r\n Resume: 'resume',\r\n PlaybackStart: 'playbackstart'\r\n};\r\n\r\n/**\r\n * The [[Sound]] object allows games built in Excalibur to load audio\r\n * components, from soundtracks to sound effects. [[Sound]] is an [[Loadable]]\r\n * which means it can be passed to a [[Loader]] to pre-load before a game or level.\r\n */\r\nexport class Sound implements Audio, Loadable {\r\n public events = new EventEmitter();\r\n public logger: Logger = Logger.getInstance();\r\n public data: AudioBuffer;\r\n private _resource: Resource;\r\n /**\r\n * Indicates whether the clip should loop when complete\r\n * @param value Set the looping flag\r\n */\r\n public set loop(value: boolean) {\r\n this._loop = value;\r\n\r\n for (const track of this._tracks) {\r\n track.loop = this._loop;\r\n }\r\n\r\n this.logger.debug('Set loop for all instances of sound', this.path, 'to', this._loop);\r\n }\r\n public get loop(): boolean {\r\n return this._loop;\r\n }\r\n\r\n public set volume(value: number) {\r\n this._volume = value;\r\n\r\n for (const track of this._tracks) {\r\n track.volume = this._volume;\r\n }\r\n\r\n this.events.emit('volumechange', new NativeSoundEvent(this));\r\n\r\n this.logger.debug('Set loop for all instances of sound', this.path, 'to', this._volume);\r\n }\r\n public get volume(): number {\r\n return this._volume;\r\n }\r\n\r\n private _duration: number | undefined;\r\n /**\r\n * Get the duration that this audio should play. If unset the total natural playback duration will be used.\r\n */\r\n public get duration(): number | undefined {\r\n return this._duration;\r\n }\r\n /**\r\n * Set the duration that this audio should play. If unset the total natural playback duration will be used.\r\n *\r\n * Note: if you seek to a specific point the duration will start from that point, for example\r\n *\r\n * If you have a 10 second clip, seek to 5 seconds, then set the duration to 2, it will play the clip from 5-7 seconds.\r\n */\r\n public set duration(duration: number | undefined){\r\n this._duration = duration;\r\n }\r\n\r\n /**\r\n * Return array of Current AudioInstances playing or being paused\r\n */\r\n public get instances(): Audio[] {\r\n return this._tracks;\r\n }\r\n\r\n public get path() {\r\n return this._resource.path;\r\n }\r\n\r\n public set path(val: string) {\r\n this._resource.path = val;\r\n }\r\n\r\n\r\n /**\r\n * Should excalibur add a cache busting querystring? By default false.\r\n * Must be set before loading\r\n */\r\n public get bustCache() {\r\n return this._resource.bustCache;\r\n }\r\n\r\n public set bustCache(val: boolean) {\r\n this._resource.bustCache = val;\r\n }\r\n\r\n private _loop = false;\r\n private _volume = 1;\r\n private _isStopped = false;\r\n // private _isPaused = false;\r\n private _tracks: Audio[] = [];\r\n private _engine: Engine;\r\n private _wasPlayingOnHidden: boolean = false;\r\n private _playbackRate = 1.0;\r\n private _audioContext = AudioContextFactory.create();\r\n\r\n /**\r\n * @param paths A list of audio sources (clip.wav, clip.mp3, clip.ogg) for this audio clip. This is done for browser compatibility.\r\n */\r\n constructor(...paths: string[]) {\r\n this._resource = new Resource('', ExResponse.type.arraybuffer);\r\n /**\r\n * Chrome : MP3, WAV, Ogg\r\n * Firefox : WAV, Ogg,\r\n * IE : MP3, WAV coming soon\r\n * Safari MP3, WAV, Ogg\r\n */\r\n for (const path of paths) {\r\n if (canPlayFile(path)) {\r\n this.path = path;\r\n break;\r\n }\r\n }\r\n\r\n if (!this.path) {\r\n this.logger.warn('This browser does not support any of the audio files specified:', paths.join(', '));\r\n this.logger.warn('Attempting to use', paths[0]);\r\n this.path = paths[0]; // select the first specified\r\n }\r\n }\r\n\r\n public isLoaded() {\r\n return !!this.data;\r\n }\r\n\r\n public async load(): Promise {\r\n if (this.data) {\r\n return this.data;\r\n }\r\n const arraybuffer = await this._resource.load();\r\n const audiobuffer = await this.decodeAudio(arraybuffer.slice(0));\r\n this._duration = this._duration ?? audiobuffer?.duration ?? undefined;\r\n this.events.emit('processed', new NativeSoundProcessedEvent(this, audiobuffer));\r\n return this.data = audiobuffer;\r\n }\r\n\r\n public async decodeAudio(data: ArrayBuffer): Promise {\r\n try {\r\n return await this._audioContext.decodeAudioData(data.slice(0));\r\n } catch (e) {\r\n this.logger.error(\r\n 'Unable to decode ' +\r\n ' this browser may not fully support this format, or the file may be corrupt, ' +\r\n 'if this is an mp3 try removing id3 tags and album art from the file.'\r\n );\r\n return await Promise.reject();\r\n }\r\n }\r\n\r\n public wireEngine(engine: Engine) {\r\n if (engine) {\r\n this._engine = engine;\r\n\r\n this._engine.on('hidden', () => {\r\n if (engine.pauseAudioWhenHidden && this.isPlaying()) {\r\n this._wasPlayingOnHidden = true;\r\n this.pause();\r\n }\r\n });\r\n\r\n this._engine.on('visible', () => {\r\n if (engine.pauseAudioWhenHidden && this._wasPlayingOnHidden) {\r\n this.play();\r\n this._wasPlayingOnHidden = false;\r\n }\r\n });\r\n\r\n this._engine.on('start', () => {\r\n this._isStopped = false;\r\n });\r\n\r\n this._engine.on('stop', () => {\r\n this.stop();\r\n this._isStopped = true;\r\n });\r\n }\r\n }\r\n\r\n /**\r\n * Returns how many instances of the sound are currently playing\r\n */\r\n public instanceCount(): number {\r\n return this._tracks.length;\r\n }\r\n\r\n /**\r\n * Whether or not the sound is playing right now\r\n */\r\n public isPlaying(): boolean {\r\n return this._tracks.some((t) => t.isPlaying());\r\n }\r\n\r\n public isPaused(): boolean {\r\n return this._tracks.some(t => t.isPaused());\r\n }\r\n\r\n /**\r\n * Play the sound, returns a promise that resolves when the sound is done playing\r\n * An optional volume argument can be passed in to play the sound. Max volume is 1.0\r\n */\r\n public play(volume?: number): Promise {\r\n if (!this.isLoaded()) {\r\n this.logger.warn('Cannot start playing. Resource', this.path, 'is not loaded yet');\r\n\r\n return Promise.resolve(true);\r\n }\r\n\r\n if (this._isStopped) {\r\n this.logger.warn('Cannot start playing. Engine is in a stopped state.');\r\n return Promise.resolve(false);\r\n }\r\n\r\n this.volume = volume || this.volume;\r\n\r\n if (this.isPaused()) {\r\n return this._resumePlayback();\r\n } else {\r\n return this._startPlayback();\r\n }\r\n }\r\n\r\n /**\r\n * Stop the sound, and do not rewind\r\n */\r\n public pause() {\r\n if (!this.isPlaying()) {\r\n return;\r\n }\r\n\r\n for (const track of this._tracks) {\r\n track.pause();\r\n }\r\n\r\n this.events.emit('pause', new NativeSoundEvent(this));\r\n\r\n this.logger.debug('Paused all instances of sound', this.path);\r\n }\r\n\r\n /**\r\n * Stop the sound if it is currently playing and rewind the track. If the sound is not playing, rewinds the track.\r\n */\r\n public stop() {\r\n for (const track of this._tracks) {\r\n track.stop();\r\n }\r\n\r\n this.events.emit('stop', new NativeSoundEvent(this));\r\n\r\n this._tracks.length = 0;\r\n this.logger.debug('Stopped all instances of sound', this.path);\r\n }\r\n\r\n public get playbackRate(): number {\r\n return this._playbackRate;\r\n }\r\n\r\n public set playbackRate(playbackRate: number) {\r\n this._playbackRate = playbackRate;\r\n this._tracks.forEach(t => {\r\n t.playbackRate = this._playbackRate;\r\n });\r\n }\r\n\r\n public seek(position: number, trackId = 0) {\r\n if (this._tracks.length === 0) {\r\n this._getTrackInstance(this.data);\r\n }\r\n\r\n this._tracks[trackId].seek(position);\r\n }\r\n\r\n public getTotalPlaybackDuration() {\r\n return this.data.duration;\r\n }\r\n\r\n /**\r\n * Return the current playback time of the playing track in seconds from the start.\r\n *\r\n * Optionally specify the track to query if multiple are playing at once.\r\n * @param trackId\r\n */\r\n public getPlaybackPosition(trackId = 0) {\r\n if (this._tracks.length) {\r\n return this._tracks[trackId].getPlaybackPosition();\r\n }\r\n return 0;\r\n }\r\n\r\n\r\n\r\n /**\r\n * Get Id of provided AudioInstance in current trackList\r\n * @param track [[Audio]] which Id is to be given\r\n */\r\n public getTrackId(track: Audio): number {\r\n return this._tracks.indexOf(track);\r\n }\r\n\r\n private async _resumePlayback(): Promise {\r\n if (this.isPaused) {\r\n const resumed: Promise[] = [];\r\n // ensure we resume *current* tracks (if paused)\r\n for (const track of this._tracks) {\r\n resumed.push(track.play().then(() => {\r\n this.events.emit('playbackend', new NativeSoundEvent(this, track as WebAudioInstance));\r\n this._tracks.splice(this.getTrackId(track), 1);\r\n return true;\r\n }));\r\n }\r\n\r\n this.events.emit('resume', new NativeSoundEvent(this));\r\n\r\n this.logger.debug('Resuming paused instances for sound', this.path, this._tracks);\r\n // resolve when resumed tracks are done\r\n await Promise.all(resumed);\r\n }\r\n return true;\r\n }\r\n\r\n /**\r\n * Starts playback, returns a promise that resolves when playback is complete\r\n */\r\n private async _startPlayback(): Promise {\r\n const track = await this._getTrackInstance(this.data);\r\n\r\n const complete = await track.play(() => {\r\n this.events.emit('playbackstart', new NativeSoundEvent(this, track));\r\n this.logger.debug('Playing new instance for sound', this.path);\r\n });\r\n\r\n // when done, remove track\r\n this.events.emit('playbackend', new NativeSoundEvent(this, track));\r\n this._tracks.splice(this.getTrackId(track), 1);\r\n\r\n return complete;\r\n }\r\n\r\n private _getTrackInstance(data: AudioBuffer): WebAudioInstance {\r\n const newTrack = new WebAudioInstance(data);\r\n\r\n newTrack.loop = this.loop;\r\n newTrack.volume = this.volume;\r\n newTrack.duration = this.duration;\r\n newTrack.playbackRate = this._playbackRate;\r\n\r\n this._tracks.push(newTrack);\r\n\r\n return newTrack;\r\n }\r\n\r\n public emit>(eventName: TEventName, event: SoundEvents[TEventName]): void;\r\n public emit(eventName: string, event?: any): void;\r\n public emit | string>(eventName: TEventName, event?: any): void {\r\n this.events.emit(eventName, event);\r\n }\r\n\r\n public on>(eventName: TEventName, handler: Handler): Subscription;\r\n public on(eventName: string, handler: Handler): Subscription;\r\n public on | string>(eventName: TEventName, handler: Handler): Subscription {\r\n return this.events.on(eventName, handler);\r\n }\r\n\r\n public once>(eventName: TEventName, handler: Handler): Subscription;\r\n public once(eventName: string, handler: Handler): Subscription;\r\n public once | string>(eventName: TEventName, handler: Handler): Subscription {\r\n return this.events.once(eventName, handler);\r\n }\r\n\r\n public off>(eventName: TEventName, handler: Handler): void;\r\n public off(eventName: string, handler: Handler): void;\r\n public off(eventName: string): void;\r\n public off | string>(eventName: TEventName, handler?: Handler): void {\r\n this.events.off(eventName, handler);\r\n }\r\n}\r\n","import { Color } from './Color';\r\nimport { WebAudio } from './Util/WebAudio';\r\nimport { Engine } from './Engine';\r\nimport { Loadable } from './Interfaces/Loadable';\r\nimport * as DrawUtil from './Util/DrawUtil';\r\n\r\nimport logoImg from './Loader.logo.png';\r\nimport loaderCss from './Loader.css';\r\nimport { Canvas } from './Graphics/Canvas';\r\nimport { Vector } from './Math/vector';\r\nimport { delay } from './Util/Util';\r\nimport { ImageFiltering } from './Graphics/Filtering';\r\nimport { clamp } from './Math/util';\r\nimport { Sound } from './Resources/Sound/Sound';\r\nimport { Future } from './Util/Future';\r\nimport { EventEmitter, EventKey, Handler, Subscription } from './EventEmitter';\r\n\r\nexport type LoaderEvents = {\r\n // Add event types here\r\n}\r\n\r\nexport const LoaderEvents = {\r\n // Add event types here\r\n};\r\n\r\n/**\r\n * Pre-loading assets\r\n *\r\n * The loader provides a mechanism to preload multiple resources at\r\n * one time. The loader must be passed to the engine in order to\r\n * trigger the loading progress bar.\r\n *\r\n * The [[Loader]] itself implements [[Loadable]] so you can load loaders.\r\n *\r\n * ## Example: Pre-loading resources for a game\r\n *\r\n * ```js\r\n * // create a loader\r\n * var loader = new ex.Loader();\r\n *\r\n * // create a resource dictionary (best practice is to keep a separate file)\r\n * var resources = {\r\n * TextureGround: new ex.Texture(\"/images/textures/ground.png\"),\r\n * SoundDeath: new ex.Sound(\"/sound/death.wav\", \"/sound/death.mp3\")\r\n * };\r\n *\r\n * // loop through dictionary and add to loader\r\n * for (var loadable in resources) {\r\n * if (resources.hasOwnProperty(loadable)) {\r\n * loader.addResource(resources[loadable]);\r\n * }\r\n * }\r\n *\r\n * // start game\r\n * game.start(loader).then(function () {\r\n * console.log(\"Game started!\");\r\n * });\r\n * ```\r\n *\r\n * ## Customize the Loader\r\n *\r\n * The loader can be customized to show different, text, logo, background color, and button.\r\n *\r\n * ```typescript\r\n * const loader = new ex.Loader([playerTexture]);\r\n *\r\n * // The loaders button text can simply modified using this\r\n * loader.playButtonText = 'Start the best game ever';\r\n *\r\n * // The logo can be changed by inserting a base64 image string here\r\n *\r\n * loader.logo = 'data:image/png;base64,iVBORw...';\r\n * loader.logoWidth = 15;\r\n * loader.logoHeight = 14;\r\n *\r\n * // The background color can be changed like so by supplying a valid CSS color string\r\n *\r\n * loader.backgroundColor = 'red'\r\n * loader.backgroundColor = '#176BAA'\r\n *\r\n * // To build a completely new button\r\n * loader.startButtonFactory = () => {\r\n * let myButton = document.createElement('button');\r\n * myButton.textContent = 'The best button';\r\n * return myButton;\r\n * };\r\n *\r\n * engine.start(loader).then(() => {});\r\n * ```\r\n */\r\nexport class Loader implements Loadable[]> {\r\n public events = new EventEmitter();\r\n public canvas: Canvas = new Canvas({\r\n filtering: ImageFiltering.Blended,\r\n smoothing: true,\r\n cache: true,\r\n draw: this.draw.bind(this)\r\n });\r\n private _resourceList: Loadable[] = [];\r\n private _index = 0;\r\n\r\n private _playButtonShown: boolean = false;\r\n private _resourceCount: number = 0;\r\n private _numLoaded: number = 0;\r\n private _progressCounts: { [key: string]: number } = {};\r\n private _totalCounts: { [key: string]: number } = {};\r\n private _engine: Engine;\r\n\r\n // logo drawing stuff\r\n\r\n // base64 string encoding of the excalibur logo (logo-white.png)\r\n public logo = logoImg;\r\n public logoWidth = 468;\r\n public logoHeight = 118;\r\n /**\r\n * Positions the top left corner of the logo image\r\n * If not set, the loader automatically positions the logo\r\n */\r\n public logoPosition: Vector | null;\r\n /**\r\n * Positions the top left corner of the play button.\r\n * If not set, the loader automatically positions the play button\r\n */\r\n public playButtonPosition: Vector | null;\r\n /**\r\n * Positions the top left corner of the loading bar\r\n * If not set, the loader automatically positions the loading bar\r\n */\r\n public loadingBarPosition: Vector | null;\r\n\r\n /**\r\n * Gets or sets the color of the loading bar, default is [[Color.White]]\r\n */\r\n public loadingBarColor: Color = Color.White;\r\n\r\n /**\r\n * Gets or sets the background color of the loader as a hex string\r\n */\r\n public backgroundColor: string = '#176BAA';\r\n\r\n protected _imageElement: HTMLImageElement;\r\n protected get _image() {\r\n if (!this._imageElement) {\r\n this._imageElement = new Image();\r\n this._imageElement.src = this.logo;\r\n }\r\n\r\n return this._imageElement;\r\n }\r\n\r\n public suppressPlayButton: boolean = false;\r\n public get playButtonRootElement(): HTMLElement | null {\r\n return this._playButtonRootElement;\r\n }\r\n public get playButtonElement(): HTMLButtonElement | null {\r\n return this._playButtonElement;\r\n }\r\n protected _playButtonRootElement: HTMLElement;\r\n protected _playButtonElement: HTMLButtonElement;\r\n protected _styleBlock: HTMLStyleElement;\r\n /** Loads the css from Loader.css */\r\n protected _playButtonStyles: string = loaderCss.toString();\r\n protected get _playButton() {\r\n const existingRoot = document.getElementById('excalibur-play-root');\r\n if (existingRoot) {\r\n this._playButtonRootElement = existingRoot;\r\n }\r\n if (!this._playButtonRootElement) {\r\n this._playButtonRootElement = document.createElement('div');\r\n this._playButtonRootElement.id = 'excalibur-play-root';\r\n this._playButtonRootElement.style.position = 'absolute';\r\n document.body.appendChild(this._playButtonRootElement);\r\n }\r\n if (!this._styleBlock) {\r\n this._styleBlock = document.createElement('style');\r\n this._styleBlock.textContent = this._playButtonStyles;\r\n document.head.appendChild(this._styleBlock);\r\n }\r\n if (!this._playButtonElement) {\r\n this._playButtonElement = this.startButtonFactory();\r\n this._playButtonRootElement.appendChild(this._playButtonElement);\r\n }\r\n return this._playButtonElement;\r\n }\r\n\r\n /**\r\n * Get/set play button text\r\n */\r\n public playButtonText: string = 'Play game';\r\n\r\n /**\r\n * Return a html button element for excalibur to use as a play button\r\n */\r\n public startButtonFactory = () => {\r\n let buttonElement: HTMLButtonElement = document.getElementById('excalibur-play') as HTMLButtonElement;\r\n if (!buttonElement) {\r\n buttonElement = document.createElement('button');\r\n }\r\n\r\n buttonElement.id = 'excalibur-play';\r\n buttonElement.textContent = this.playButtonText;\r\n buttonElement.style.display = 'none';\r\n return buttonElement;\r\n };\r\n\r\n /**\r\n * @param loadables Optionally provide the list of resources you want to load at constructor time\r\n */\r\n constructor(loadables?: Loadable[]) {\r\n if (loadables) {\r\n this.addResources(loadables);\r\n }\r\n }\r\n\r\n public wireEngine(engine: Engine) {\r\n this._engine = engine;\r\n this.canvas.width = this._engine.canvas.width;\r\n this.canvas.height = this._engine.canvas.height;\r\n }\r\n\r\n /**\r\n * Add a resource to the loader to load\r\n * @param loadable Resource to add\r\n */\r\n public addResource(loadable: Loadable) {\r\n const key = this._index++;\r\n this._resourceList.push(loadable);\r\n this._progressCounts[key] = 0;\r\n this._totalCounts[key] = 1;\r\n this._resourceCount++;\r\n }\r\n\r\n /**\r\n * Add a list of resources to the loader to load\r\n * @param loadables The list of resources to load\r\n */\r\n public addResources(loadables: Loadable[]) {\r\n let i = 0;\r\n const len = loadables.length;\r\n\r\n for (i; i < len; i++) {\r\n this.addResource(loadables[i]);\r\n }\r\n }\r\n\r\n /**\r\n * Returns true if the loader has completely loaded all resources\r\n */\r\n public isLoaded() {\r\n return this._numLoaded === this._resourceCount;\r\n }\r\n\r\n /**\r\n * Shows the play button and returns a promise that resolves when clicked\r\n */\r\n public async showPlayButton(): Promise {\r\n if (this.suppressPlayButton) {\r\n this.hidePlayButton();\r\n // Delay is to give the logo a chance to show, otherwise don't delay\r\n await delay(500, this._engine?.clock);\r\n } else {\r\n const resizeHandler = () => {\r\n this._positionPlayButton();\r\n };\r\n if (this._engine?.browser) {\r\n this._engine.browser.window.on('resize', resizeHandler);\r\n }\r\n this._playButtonShown = true;\r\n this._playButton.style.display = 'block';\r\n document.body.addEventListener('keyup', (evt: KeyboardEvent) => {\r\n if (evt.key === 'Enter') {\r\n this._playButton.click();\r\n }\r\n });\r\n this._positionPlayButton();\r\n const playButtonClicked = new Promise((resolve) => {\r\n const startButtonHandler = (e: Event) => {\r\n // We want to stop propagation to keep bubbling to the engine pointer handlers\r\n e.stopPropagation();\r\n // Hide Button after click\r\n this.hidePlayButton();\r\n if (this._engine?.browser) {\r\n this._engine.browser.window.off('resize', resizeHandler);\r\n }\r\n resolve();\r\n };\r\n this._playButton.addEventListener('click', startButtonHandler);\r\n this._playButton.addEventListener('touchend', startButtonHandler);\r\n this._playButton.addEventListener('pointerup', startButtonHandler);\r\n });\r\n\r\n return await playButtonClicked;\r\n }\r\n }\r\n\r\n public hidePlayButton() {\r\n this._playButtonShown = false;\r\n this._playButton.style.display = 'none';\r\n }\r\n\r\n /**\r\n * Clean up generated elements for the loader\r\n */\r\n public dispose() {\r\n if (this._playButtonRootElement.parentElement) {\r\n this._playButtonRootElement.removeChild(this._playButtonElement);\r\n document.body.removeChild(this._playButtonRootElement);\r\n document.head.removeChild(this._styleBlock);\r\n this._playButtonRootElement = null;\r\n this._playButtonElement = null;\r\n this._styleBlock = null;\r\n }\r\n }\r\n\r\n update(_engine: Engine, _delta: number): void {\r\n // override me\r\n }\r\n\r\n data: Loadable[];\r\n\r\n private _loadingFuture = new Future();\r\n public areResourcesLoaded() {\r\n return this._loadingFuture.promise;\r\n }\r\n\r\n /**\r\n * Begin loading all of the supplied resources, returning a promise\r\n * that resolves when loading of all is complete AND the user has clicked the \"Play button\"\r\n */\r\n public async load(): Promise[]> {\r\n await this._image?.decode(); // decode logo if it exists\r\n this.canvas.flagDirty();\r\n\r\n await Promise.all(\r\n this._resourceList.map(async (r) => {\r\n await r.load().finally(() => {\r\n // capture progress\r\n this._numLoaded++;\r\n this.canvas.flagDirty();\r\n });\r\n })\r\n );\r\n // Wire all sound to the engine\r\n for (const resource of this._resourceList) {\r\n if (resource instanceof Sound) {\r\n resource.wireEngine(this._engine);\r\n }\r\n }\r\n\r\n this._loadingFuture.resolve();\r\n\r\n // short delay in showing the button for aesthetics\r\n await delay(200, this._engine?.clock);\r\n this.canvas.flagDirty();\r\n\r\n await this.showPlayButton();\r\n // Unlock browser AudioContext in after user gesture\r\n // See: https://github.com/excaliburjs/Excalibur/issues/262\r\n // See: https://github.com/excaliburjs/Excalibur/issues/1031\r\n await WebAudio.unlock();\r\n\r\n return (this.data = this._resourceList);\r\n }\r\n\r\n public markResourceComplete(): void {\r\n this._numLoaded++;\r\n }\r\n\r\n /**\r\n * Returns the progress of the loader as a number between [0, 1] inclusive.\r\n */\r\n public get progress(): number {\r\n return this._resourceCount > 0 ? clamp(this._numLoaded, 0, this._resourceCount) / this._resourceCount : 1;\r\n }\r\n\r\n private _positionPlayButton() {\r\n if (this._engine) {\r\n const screenHeight = this._engine.screen.viewport.height;\r\n const screenWidth = this._engine.screen.viewport.width;\r\n if (this._playButtonRootElement) {\r\n const left = this._engine.canvas.offsetLeft;\r\n const top = this._engine.canvas.offsetTop;\r\n const buttonWidth = this._playButton.clientWidth;\r\n const buttonHeight = this._playButton.clientHeight;\r\n if (this.playButtonPosition) {\r\n this._playButtonRootElement.style.left = `${this.playButtonPosition.x}px`;\r\n this._playButtonRootElement.style.top = `${this.playButtonPosition.y}px`;\r\n } else {\r\n this._playButtonRootElement.style.left = `${left + screenWidth / 2 - buttonWidth / 2}px`;\r\n this._playButtonRootElement.style.top = `${top + screenHeight / 2 - buttonHeight / 2 + 100}px`;\r\n }\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Loader draw function. Draws the default Excalibur loading screen.\r\n * Override `logo`, `logoWidth`, `logoHeight` and `backgroundColor` properties\r\n * to customize the drawing, or just override entire method.\r\n */\r\n public draw(ctx: CanvasRenderingContext2D) {\r\n const canvasHeight = this._engine.canvasHeight / this._engine.pixelRatio;\r\n const canvasWidth = this._engine.canvasWidth / this._engine.pixelRatio;\r\n\r\n this._positionPlayButton();\r\n\r\n ctx.fillStyle = this.backgroundColor;\r\n ctx.fillRect(0, 0, canvasWidth, canvasHeight);\r\n\r\n let logoY = canvasHeight / 2;\r\n const width = Math.min(this.logoWidth, canvasWidth * 0.75);\r\n let logoX = canvasWidth / 2 - width / 2;\r\n\r\n if (this.logoPosition) {\r\n logoX = this.logoPosition.x;\r\n logoY = this.logoPosition.y;\r\n }\r\n\r\n const imageHeight = Math.floor(width * (this.logoHeight / this.logoWidth)); // OG height/width factor\r\n const oldAntialias = this._engine.getAntialiasing();\r\n this._engine.setAntialiasing(true);\r\n if (!this.logoPosition) {\r\n ctx.drawImage(this._image, 0, 0, this.logoWidth, this.logoHeight, logoX, logoY - imageHeight - 20, width, imageHeight);\r\n } else {\r\n ctx.drawImage(this._image, 0, 0, this.logoWidth, this.logoHeight, logoX, logoY, width, imageHeight);\r\n }\r\n\r\n // loading box\r\n if (!this.suppressPlayButton && this._playButtonShown) {\r\n this._engine.setAntialiasing(oldAntialias);\r\n return;\r\n }\r\n\r\n let loadingX = logoX;\r\n let loadingY = logoY;\r\n if (this.loadingBarPosition) {\r\n loadingX = this.loadingBarPosition.x;\r\n loadingY = this.loadingBarPosition.y;\r\n }\r\n\r\n ctx.lineWidth = 2;\r\n DrawUtil.roundRect(ctx, loadingX, loadingY, width, 20, 10, this.loadingBarColor);\r\n const progress = width * this.progress;\r\n const margin = 5;\r\n const progressWidth = progress - margin * 2;\r\n const height = 20 - margin * 2;\r\n DrawUtil.roundRect(\r\n ctx,\r\n loadingX + margin,\r\n loadingY + margin,\r\n progressWidth > 10 ? progressWidth : 10,\r\n height,\r\n 5,\r\n null,\r\n this.loadingBarColor\r\n );\r\n this._engine.setAntialiasing(oldAntialias);\r\n }\r\n\r\n public emit>(eventName: TEventName, event: LoaderEvents[TEventName]): void;\r\n public emit(eventName: string, event?: any): void;\r\n public emit | string>(eventName: TEventName, event?: any): void {\r\n this.events.emit(eventName, event);\r\n }\r\n\r\n public on>(eventName: TEventName, handler: Handler): Subscription;\r\n public on(eventName: string, handler: Handler): Subscription;\r\n public on | string>(eventName: TEventName, handler: Handler): Subscription {\r\n return this.events.on(eventName, handler);\r\n }\r\n\r\n public once>(eventName: TEventName, handler: Handler): Subscription;\r\n public once(eventName: string, handler: Handler): Subscription;\r\n public once | string>(eventName: TEventName, handler: Handler): Subscription {\r\n return this.events.once(eventName, handler);\r\n }\r\n\r\n public off>(eventName: TEventName, handler: Handler): void;\r\n public off(eventName: string, handler: Handler): void;\r\n public off(eventName: string): void;\r\n public off | string>(eventName: TEventName, handler?: Handler): void {\r\n this.events.off(eventName, handler);\r\n }\r\n}\r\n","import { Logger } from './Log';\r\n/**\r\n * This is the list of features that will be used to log the supported\r\n * features to the console when Detector.logBrowserFeatures() is called.\r\n */\r\n\r\nconst REPORTED_FEATURES: { [key: string]: string } = {\r\n webgl: 'WebGL',\r\n webaudio: 'WebAudio',\r\n gamepadapi: 'Gamepad API'\r\n};\r\n\r\n/**\r\n * Interface for detected browser features matrix\r\n */\r\nexport interface DetectedFeatures {\r\n readonly canvas: boolean;\r\n readonly arraybuffer: boolean;\r\n readonly dataurl: boolean;\r\n readonly objecturl: boolean;\r\n readonly rgba: boolean;\r\n readonly webaudio: boolean;\r\n readonly webgl: boolean;\r\n readonly gamepadapi: boolean;\r\n}\r\n\r\ninterface CriticalTests {\r\n canvasSupport(): boolean;\r\n arrayBufferSupport(): boolean;\r\n dataUrlSupport(): boolean;\r\n objectUrlSupport(): boolean;\r\n rgbaSupport(): boolean;\r\n}\r\n\r\ninterface WarningTests {\r\n webAudioSupport(): boolean;\r\n webglSupport(): boolean;\r\n}\r\n\r\n/**\r\n * Excalibur internal feature detection helper class\r\n */\r\nexport class Detector {\r\n private _features: DetectedFeatures = null;\r\n\r\n public failedTests: string[] = [];\r\n\r\n public constructor() {\r\n this._features = this._loadBrowserFeatures();\r\n }\r\n\r\n /**\r\n * Returns a map of currently supported browser features. This method\r\n * treats the features as a singleton and will only calculate feature\r\n * support if it has not previously been done.\r\n */\r\n public getBrowserFeatures(): DetectedFeatures {\r\n if (this._features === null) {\r\n this._features = this._loadBrowserFeatures();\r\n }\r\n return this._features;\r\n }\r\n\r\n /**\r\n * Report on non-critical browser support for debugging purposes.\r\n * Use native browser console colors for visibility.\r\n */\r\n public logBrowserFeatures(): void {\r\n let msg = '%cSUPPORTED BROWSER FEATURES\\n==========================%c\\n';\r\n const args = ['font-weight: bold; color: navy', 'font-weight: normal; color: inherit'];\r\n\r\n const supported: any = this.getBrowserFeatures();\r\n for (const feature of Object.keys(REPORTED_FEATURES)) {\r\n if (supported[feature]) {\r\n msg += '(%c\\u2713%c)'; // (✓)\r\n args.push('font-weight: bold; color: green');\r\n args.push('font-weight: normal; color: inherit');\r\n } else {\r\n msg += '(%c\\u2717%c)'; // (✗)\r\n args.push('font-weight: bold; color: red');\r\n args.push('font-weight: normal; color: inherit');\r\n }\r\n\r\n msg += ' ' + REPORTED_FEATURES[feature] + '\\n';\r\n }\r\n\r\n args.unshift(msg);\r\n // eslint-disable-next-line no-console\r\n console.log.apply(console, args);\r\n }\r\n\r\n /**\r\n * Executes several IIFE's to get a constant reference to supported\r\n * features within the current execution context.\r\n */\r\n private _loadBrowserFeatures(): DetectedFeatures {\r\n return {\r\n // IIFE to check canvas support\r\n canvas: (() => {\r\n return this._criticalTests.canvasSupport();\r\n })(),\r\n\r\n // IIFE to check arraybuffer support\r\n arraybuffer: (() => {\r\n return this._criticalTests.arrayBufferSupport();\r\n })(),\r\n\r\n // IIFE to check dataurl support\r\n dataurl: (() => {\r\n return this._criticalTests.dataUrlSupport();\r\n })(),\r\n\r\n // IIFE to check objecturl support\r\n objecturl: (() => {\r\n return this._criticalTests.objectUrlSupport();\r\n })(),\r\n\r\n // IIFE to check rgba support\r\n rgba: (() => {\r\n return this._criticalTests.rgbaSupport();\r\n })(),\r\n\r\n // IIFE to check webaudio support\r\n webaudio: (() => {\r\n return this._warningTest.webAudioSupport();\r\n })(),\r\n\r\n // IIFE to check webgl support\r\n webgl: (() => {\r\n return this._warningTest.webglSupport();\r\n })(),\r\n\r\n // IIFE to check gamepadapi support\r\n gamepadapi: (() => {\r\n return !!(navigator).getGamepads;\r\n })()\r\n };\r\n }\r\n\r\n // critical browser features required for ex to run\r\n private _criticalTests: CriticalTests = {\r\n // Test canvas/2d context support\r\n canvasSupport: function() {\r\n const elem = document.createElement('canvas');\r\n return !!(elem.getContext && elem.getContext('2d'));\r\n },\r\n\r\n // Test array buffer support ex uses for downloading binary data\r\n arrayBufferSupport: function() {\r\n const xhr = new XMLHttpRequest();\r\n xhr.open('GET', '/');\r\n try {\r\n xhr.responseType = 'arraybuffer';\r\n } catch (e) {\r\n return false;\r\n }\r\n return xhr.responseType === 'arraybuffer';\r\n },\r\n\r\n // Test data urls ex uses for sprites\r\n dataUrlSupport: function() {\r\n const canvas = document.createElement('canvas');\r\n return canvas.toDataURL('image/png').indexOf('data:image/png') === 0;\r\n },\r\n\r\n // Test object url support for loading\r\n objectUrlSupport: function() {\r\n return 'URL' in window && 'revokeObjectURL' in URL && 'createObjectURL' in URL;\r\n },\r\n\r\n // RGBA support for colors\r\n rgbaSupport: function() {\r\n const style = document.createElement('a').style;\r\n style.cssText = 'background-color:rgba(150,255,150,.5)';\r\n return ('' + style.backgroundColor).indexOf('rgba') > -1;\r\n }\r\n };\r\n\r\n // warnings excalibur performance will be degraded\r\n private _warningTest: WarningTests = {\r\n webAudioSupport: function() {\r\n return !!(\r\n (window).AudioContext ||\r\n (window).webkitAudioContext ||\r\n (window).mozAudioContext ||\r\n (window).msAudioContext ||\r\n (window).oAudioContext\r\n );\r\n },\r\n webglSupport: function() {\r\n const elem = document.createElement('canvas');\r\n return !!(elem.getContext && elem.getContext('webgl'));\r\n }\r\n };\r\n\r\n public test(): boolean {\r\n // Critical test will for ex not to run\r\n let failedCritical = false;\r\n for (const test in this._criticalTests) {\r\n if (!this._criticalTests[test].call(this)) {\r\n this.failedTests.push(test);\r\n Logger.getInstance().error('Critical browser feature missing, Excalibur requires:', test);\r\n failedCritical = true;\r\n }\r\n }\r\n if (failedCritical) {\r\n return false;\r\n }\r\n\r\n // Warning tests do not for ex to return false to compatibility\r\n for (const warning in this._warningTest) {\r\n if (!this._warningTest[warning]()) {\r\n Logger.getInstance().warn('Warning browser feature missing, Excalibur will have reduced performance:', warning);\r\n }\r\n }\r\n\r\n return true;\r\n }\r\n}\r\n","/**\r\n * An enum that describes the types of collisions bodies can participate in\r\n */\r\nexport enum CollisionType {\r\n /**\r\n * Bodies with the `PreventCollision` setting do not participate in any\r\n * collisions and do not raise collision events.\r\n */\r\n PreventCollision = 'PreventCollision',\r\n /**\r\n * Bodies with the `Passive` setting only raise collision events, but are not\r\n * influenced or moved by other bodies and do not influence or move other bodies.\r\n * This is useful for use in trigger type behavior.\r\n */\r\n Passive = 'Passive',\r\n /**\r\n * Bodies with the `Active` setting raise collision events and participate\r\n * in collisions with other bodies and will be push or moved by bodies sharing\r\n * the `Active` or `Fixed` setting.\r\n */\r\n Active = 'Active',\r\n /**\r\n * Bodies with the `Fixed` setting raise collision events and participate in\r\n * collisions with other bodies. Actors with the `Fixed` setting will not be\r\n * pushed or moved by other bodies sharing the `Fixed`. Think of Fixed\r\n * bodies as \"immovable/unstoppable\" objects. If two `Fixed` bodies meet they will\r\n * not be pushed or moved by each other, they will not interact except to throw\r\n * collision events.\r\n */\r\n Fixed = 'Fixed'\r\n}\r\n","import { Flags } from '../Flags';\r\nimport { Logger } from './Log';\r\n\r\n/**\r\n * Obsolete decorator options\r\n */\r\nexport interface ObsoleteOptions {\r\n // Optionally specify a custom message\r\n message?: string;\r\n // Optionally indicate that an alternate method to the obsolete one exists\r\n alternateMethod?: string;\r\n // Optional show stack trace, by default off\r\n showStackTrace?: boolean;\r\n}\r\n\r\nexport const maxMessages = 5;\r\nconst obsoleteMessage: { [messageCount: string]: number } = {};\r\nexport const resetObsoleteCounter = () => {\r\n for (const message in obsoleteMessage) {\r\n obsoleteMessage[message] = 0;\r\n }\r\n};\r\n\r\nconst logMessage = (message: string, options: ObsoleteOptions) => {\r\n const suppressObsoleteMessages = Flags.isEnabled('suppress-obsolete-message');\r\n if (obsoleteMessage[message] < maxMessages && !suppressObsoleteMessages) {\r\n Logger.getInstance().warn(message);\r\n\r\n // tslint:disable-next-line: no-console\r\n if (console.trace && options.showStackTrace) {\r\n // tslint:disable-next-line: no-console\r\n console.trace();\r\n }\r\n }\r\n obsoleteMessage[message]++;\r\n};\r\n\r\n/**\r\n * Obsolete decorator for marking Excalibur methods obsolete, you can optionally specify a custom message and/or alternate replacement\r\n * method do the deprecated one. Inspired by https://github.com/jayphelps/core-decorators.js\r\n */\r\nexport function obsolete(options?: ObsoleteOptions): any {\r\n options = {\r\n message: 'This feature will be removed in future versions of Excalibur.',\r\n alternateMethod: null,\r\n showStackTrace: false,\r\n ...options\r\n };\r\n\r\n return function (target: any, property: string, descriptor: PropertyDescriptor): any {\r\n if (\r\n descriptor &&\r\n !(typeof descriptor.value === 'function' || typeof descriptor.get === 'function' || typeof descriptor.set === 'function')\r\n ) {\r\n throw new SyntaxError('Only classes/functions/getters/setters can be marked as obsolete');\r\n }\r\n const methodSignature = `${target.name || ''}${target.name && property ? '.' : ''}${property ? property : ''}`;\r\n\r\n const message =\r\n `${methodSignature} is marked obsolete: ${options.message}` +\r\n (options.alternateMethod ? ` Use ${options.alternateMethod} instead` : '');\r\n\r\n if (!obsoleteMessage[message]) {\r\n obsoleteMessage[message] = 0;\r\n }\r\n\r\n // If descriptor is null it is a class\r\n const method = descriptor ? { ...descriptor } : target;\r\n if (!descriptor) {\r\n // with es2015 classes we need to change our decoration tactic\r\n class DecoratedClass extends method {\r\n constructor(...args: any) {\r\n logMessage(message, options);\r\n super(...args);\r\n }\r\n }\r\n return DecoratedClass;\r\n }\r\n\r\n if (descriptor && descriptor.value) {\r\n method.value = function (this: any) {\r\n logMessage(message, options);\r\n return descriptor.value.apply(this, arguments);\r\n };\r\n return method;\r\n }\r\n\r\n if (descriptor && descriptor.get) {\r\n method.get = function (this: any) {\r\n logMessage(message, options);\r\n return descriptor.get.apply(this, arguments);\r\n };\r\n }\r\n\r\n if (descriptor && descriptor.set) {\r\n method.set = function (this: any) {\r\n logMessage(message, options);\r\n return descriptor.set.apply(this, arguments);\r\n };\r\n }\r\n return method;\r\n };\r\n}\r\n","import { Vector } from '../Math/vector';\r\nimport { obsolete } from '../Util/Decorators';\r\n\r\n\r\n/**\r\n * Possible collision resolution strategies\r\n *\r\n * The default is [[CollisionResolutionStrategy.Arcade]] which performs simple axis aligned arcade style physics. This is useful for things\r\n * like platformers or top down games.\r\n *\r\n * More advanced rigid body physics are enabled by setting [[CollisionResolutionStrategy.Realistic]] which allows for complicated\r\n * simulated physical interactions.\r\n */\r\nexport enum CollisionResolutionStrategy {\r\n Arcade = 'arcade',\r\n Realistic = 'realistic'\r\n}\r\n\r\n/**\r\n * Possible broadphase collision pair identification strategies\r\n *\r\n * The default strategy is [[BroadphaseStrategy.DynamicAABBTree]] which uses a binary tree of axis-aligned bounding boxes to identify\r\n * potential collision pairs which is O(nlog(n)) faster.\r\n */\r\nexport enum BroadphaseStrategy {\r\n DynamicAABBTree\r\n}\r\n\r\n/**\r\n * Possible numerical integrators for position and velocity\r\n */\r\nexport enum Integrator {\r\n Euler\r\n}\r\n\r\n/**\r\n * The [[Physics]] object is the global configuration object for all Excalibur physics.\r\n */\r\n/* istanbul ignore next */\r\nexport class Physics {\r\n /**\r\n * Global acceleration that is applied to all vanilla actors that have a [[CollisionType.Active|active]] collision type.\r\n * Global acceleration won't effect [[Label|labels]], [[ScreenElement|ui actors]], or [[Trigger|triggers]] in Excalibur.\r\n *\r\n * This is a great way to globally simulate effects like gravity.\r\n */\r\n public static acc = new Vector(0, 0);\r\n public static get gravity() {\r\n return Physics.acc;\r\n }\r\n public static set gravity(v: Vector) {\r\n Physics.acc = v;\r\n }\r\n\r\n /**\r\n * Globally switches all Excalibur physics behavior on or off.\r\n */\r\n public static enabled = true;\r\n\r\n /**\r\n * Gets or sets the broadphase pair identification strategy.\r\n *\r\n * The default strategy is [[BroadphaseStrategy.DynamicAABBTree]] which uses a binary tree of axis-aligned bounding boxes to identify\r\n * potential collision pairs which is O(nlog(n)) faster.\r\n */\r\n public static broadphaseStrategy: BroadphaseStrategy = BroadphaseStrategy.DynamicAABBTree;\r\n\r\n /**\r\n * Gets or sets the global collision resolution strategy (narrowphase).\r\n *\r\n * The default is [[CollisionResolutionStrategy.Arcade]] which performs simple axis aligned arcade style physics.\r\n *\r\n * More advanced rigid body physics are enabled by setting [[CollisionResolutionStrategy.Realistic]] which allows for complicated\r\n * simulated physical interactions.\r\n */\r\n public static collisionResolutionStrategy: CollisionResolutionStrategy = CollisionResolutionStrategy.Arcade;\r\n /**\r\n * The default mass to use if none is specified\r\n */\r\n public static defaultMass: number = 10;\r\n /**\r\n * Gets or sets the position and velocity positional integrator, currently only Euler is supported.\r\n */\r\n public static integrator: Integrator = Integrator.Euler;\r\n\r\n /**\r\n * Configures Excalibur to use \"arcade\" physics. Arcade physics which performs simple axis aligned arcade style physics.\r\n */\r\n public static useArcadePhysics(): void {\r\n Physics.collisionResolutionStrategy = CollisionResolutionStrategy.Arcade;\r\n }\r\n\r\n /**\r\n * Configures Excalibur to use rigid body physics. Rigid body physics allows for complicated\r\n * simulated physical interactions.\r\n */\r\n public static useRealisticPhysics(): void {\r\n Physics.collisionResolutionStrategy = CollisionResolutionStrategy.Realistic;\r\n }\r\n\r\n /**\r\n * Factor to add to the RigidBody BoundingBox, bounding box (dimensions += vel * dynamicTreeVelocityMultiplier);\r\n */\r\n public static dynamicTreeVelocityMultiplier = 2;\r\n\r\n @obsolete({\r\n message: 'Alias for incorrect spelling used in older versions, will be removed in v0.25.0',\r\n alternateMethod: 'dynamicTreeVelocityMultiplier'\r\n })\r\n public static get dynamicTreeVelocityMultiplyer() {\r\n return Physics.dynamicTreeVelocityMultiplier;\r\n }\r\n\r\n public static set dynamicTreeVelocityMultiplyer(value: number) {\r\n Physics.dynamicTreeVelocityMultiplier = value;\r\n }\r\n\r\n /**\r\n * Pad RigidBody BoundingBox by a constant amount\r\n */\r\n public static boundsPadding = 5;\r\n\r\n /**\r\n * Number of position iterations (overlap) to run in the solver\r\n */\r\n public static positionIterations = 3;\r\n\r\n /**\r\n * Number of velocity iteration (response) to run in the solver\r\n */\r\n public static velocityIterations = 8;\r\n\r\n /**\r\n * Amount of overlap to tolerate in pixels\r\n */\r\n public static slop = 1;\r\n\r\n /**\r\n * Amount of positional overlap correction to apply each position iteration of the solver\r\n * O - meaning no correction, 1 - meaning correct all overlap\r\n */\r\n public static steeringFactor = 0.2;\r\n\r\n /**\r\n * Warm start set to true re-uses impulses from previous frames back in the solver\r\n */\r\n public static warmStart = true;\r\n\r\n /**\r\n * By default bodies do not sleep\r\n */\r\n public static bodiesCanSleepByDefault = false;\r\n\r\n /**\r\n * Surface epsilon is used to help deal with surface penetration\r\n */\r\n public static surfaceEpsilon = 0.1;\r\n\r\n public static sleepEpsilon = 0.07;\r\n\r\n public static wakeThreshold = Physics.sleepEpsilon * 3;\r\n\r\n public static sleepBias = 0.9;\r\n\r\n /**\r\n * Enable fast moving body checking, this enables checking for collision pairs via raycast for fast moving objects to prevent\r\n * bodies from tunneling through one another.\r\n */\r\n public static checkForFastBodies = true;\r\n\r\n /**\r\n * Disable minimum fast moving body raycast, by default if ex.Physics.checkForFastBodies = true Excalibur will only check if the\r\n * body is moving at least half of its minimum dimension in an update. If ex.Physics.disableMinimumSpeedForFastBody is set to true,\r\n * Excalibur will always perform the fast body raycast regardless of speed.\r\n */\r\n public static disableMinimumSpeedForFastBody = false;\r\n}\r\n","/**\r\n * Enum representing the coordinate plane for the position 2D vector in the [[TransformComponent]]\r\n */\r\nexport enum CoordPlane {\r\n /**\r\n * The world coordinate plane (default) represents world space, any entities drawn with world\r\n * space move when the camera moves.\r\n */\r\n World = 'world',\r\n /**\r\n * The screen coordinate plane represents screen space, entities drawn in screen space are pinned\r\n * to screen coordinates ignoring the camera.\r\n */\r\n Screen = 'screen'\r\n}","import { Vector } from './vector';\r\n\r\nexport interface VectorViewOptions {\r\n getX: () => number;\r\n getY: () => number;\r\n setX: (x: number) => void;\r\n setY: (y: number) => void;\r\n}\r\nexport class VectorView extends Vector {\r\n private _getX: () => number;\r\n private _getY: () => number;\r\n private _setX: (x: number) => void;\r\n private _setY: (y: number) => void;\r\n constructor(options: VectorViewOptions) {\r\n super(0, 0);\r\n this._getX = options.getX;\r\n this._getY = options.getY;\r\n this._setX = options.setX;\r\n this._setY = options.setY;\r\n }\r\n public get x() {\r\n return (this._x = this._getX());\r\n }\r\n\r\n public set x(val) {\r\n this._setX(val);\r\n this._x = val;\r\n }\r\n\r\n public get y() {\r\n return (this._y = this._getY());\r\n }\r\n public set y(val) {\r\n this._setY(val);\r\n this._y = val;\r\n }\r\n}\r\n","import { Vector } from './vector';\r\n\r\n/**\r\n * Wraps a vector and watches for changes in the x/y, modifies the original vector.\r\n */\r\nexport class WatchVector extends Vector {\r\n constructor(public original: Vector, public change: (x: number, y: number) => any) {\r\n super(original.x, original.y);\r\n }\r\n public get x() {\r\n return this._x = this.original.x;\r\n }\r\n\r\n public set x(newX: number) {\r\n this.change(newX, this._y);\r\n this._x = this.original.x = newX;\r\n }\r\n\r\n public get y() {\r\n return this._y = this.original.y;\r\n }\r\n\r\n public set y(newY: number) {\r\n this.change(this._x, newY);\r\n this._y = this.original.y = newY;\r\n }\r\n}","import { AffineMatrix } from './affine-matrix';\r\nimport { canonicalizeAngle } from './util';\r\nimport { vec, Vector } from './vector';\r\nimport { VectorView } from './vector-view';\r\nimport { WatchVector } from './watch-vector';\r\n\r\nexport class Transform {\r\n private _parent: Transform | null = null;\r\n get parent() {\r\n return this._parent;\r\n }\r\n set parent(transform: Transform) {\r\n if (this._parent) {\r\n const index = this._parent._children.indexOf(this);\r\n if (index > -1) {\r\n this._parent._children.splice(index, 1);\r\n }\r\n }\r\n this._parent = transform;\r\n if (this._parent) {\r\n this._parent._children.push(this);\r\n }\r\n this.flagDirty();\r\n }\r\n get children(): readonly Transform[] {\r\n return this._children;\r\n }\r\n private _children: Transform[] = [];\r\n\r\n private _pos: Vector = vec(0, 0);\r\n set pos(v: Vector) {\r\n if (!v.equals(this._pos)) {\r\n this._pos.x = v.x;\r\n this._pos.y = v.y;\r\n this.flagDirty();\r\n }\r\n }\r\n get pos() {\r\n return new WatchVector(this._pos, (x, y) => {\r\n if (x !== this._pos.x || y !== this._pos.y) {\r\n this.flagDirty();\r\n }\r\n });\r\n }\r\n\r\n set globalPos(v: Vector) {\r\n let localPos = v.clone();\r\n if (this.parent) {\r\n localPos = this.parent.inverse.multiply(v);\r\n }\r\n if (!localPos.equals(this._pos)) {\r\n this._pos = localPos;\r\n this.flagDirty();\r\n }\r\n }\r\n get globalPos() {\r\n return new VectorView({\r\n getX: () => this.matrix.data[4],\r\n getY: () => this.matrix.data[5],\r\n setX: (x) => {\r\n if (this.parent) {\r\n const { x: newX } = this.parent.inverse.multiply(vec(x, this.pos.y));\r\n this.pos.x = newX;\r\n } else {\r\n this.pos.x = x;\r\n }\r\n if (x !== this.matrix.data[4]) {\r\n this.flagDirty();\r\n }\r\n },\r\n setY: (y) => {\r\n if (this.parent) {\r\n const { y: newY } = this.parent.inverse.multiply(vec(this.pos.x, y));\r\n this.pos.y = newY;\r\n } else {\r\n this.pos.y = y;\r\n }\r\n if (y !== this.matrix.data[5]) {\r\n this.flagDirty();\r\n }\r\n }\r\n });\r\n }\r\n\r\n private _rotation: number = 0;\r\n set rotation(rotation: number) {\r\n const canonRotation = canonicalizeAngle(rotation);\r\n if (canonRotation !== this._rotation) {\r\n this.flagDirty();\r\n }\r\n this._rotation = canonRotation;\r\n }\r\n get rotation() {\r\n return this._rotation;\r\n }\r\n\r\n set globalRotation(rotation: number) {\r\n let inverseRotation = 0;\r\n if (this.parent) {\r\n inverseRotation = this.parent.globalRotation;\r\n }\r\n const canonRotation = canonicalizeAngle(rotation + inverseRotation);\r\n if (canonRotation !== this._rotation) {\r\n this.flagDirty();\r\n }\r\n this._rotation = canonRotation;\r\n }\r\n\r\n get globalRotation() {\r\n if (this.parent) {\r\n return this.matrix.getRotation();\r\n }\r\n return this.rotation;\r\n }\r\n\r\n private _scale: Vector = vec(1, 1);\r\n set scale(v: Vector) {\r\n if (!v.equals(this._scale)) {\r\n this._scale.x = v.x;\r\n this._scale.y = v.y;\r\n this.flagDirty();\r\n }\r\n }\r\n get scale() {\r\n return new WatchVector(this._scale, (x, y) => {\r\n if (x !== this._scale.x || y !== this._scale.y) {\r\n this.flagDirty();\r\n }\r\n });\r\n }\r\n\r\n set globalScale(v: Vector) {\r\n let inverseScale = vec(1, 1);\r\n if (this.parent) {\r\n inverseScale = this.parent.globalScale;\r\n }\r\n this.scale = v.scale(vec(1 / inverseScale.x, 1 / inverseScale.y));\r\n }\r\n\r\n get globalScale() {\r\n return new VectorView({\r\n getX: () => this.parent ? this.matrix.getScaleX() : this.scale.x,\r\n getY: () => this.parent ? this.matrix.getScaleY() : this.scale.y,\r\n setX: (x) => {\r\n if (this.parent) {\r\n const globalScaleX = this.parent.globalScale.x;\r\n this.scale.x = x / globalScaleX;\r\n } else {\r\n this.scale.x = x;\r\n }\r\n },\r\n setY: (y) => {\r\n if (this.parent) {\r\n const globalScaleY = this.parent.globalScale.y;\r\n this.scale.y = y / globalScaleY;\r\n } else {\r\n this.scale.y = y;\r\n }\r\n }\r\n });\r\n }\r\n\r\n private _isDirty = false;\r\n private _isInverseDirty = false;\r\n private _matrix = AffineMatrix.identity();\r\n private _inverse = AffineMatrix.identity();\r\n\r\n public get matrix() {\r\n if (this._isDirty) {\r\n if (this.parent === null) {\r\n this._matrix = this._calculateMatrix();\r\n } else {\r\n this._matrix = this.parent.matrix.multiply(this._calculateMatrix());\r\n }\r\n this._isDirty = false;\r\n }\r\n return this._matrix;\r\n }\r\n\r\n public get inverse() {\r\n if (this._isInverseDirty) {\r\n this._inverse = this.matrix.inverse();\r\n this._isInverseDirty = false;\r\n }\r\n return this._inverse;\r\n }\r\n\r\n private _calculateMatrix(): AffineMatrix {\r\n const matrix = AffineMatrix.identity()\r\n .translate(this.pos.x, this.pos.y)\r\n .rotate(this.rotation)\r\n .scale(this.scale.x, this.scale.y);\r\n return matrix;\r\n }\r\n\r\n\r\n public flagDirty() {\r\n this._isDirty = true;\r\n this._isInverseDirty = true;\r\n for (let i = 0; i < this._children.length; i ++) {\r\n this._children[i].flagDirty();\r\n }\r\n }\r\n\r\n public apply(point: Vector): Vector {\r\n return this.matrix.multiply(point);\r\n }\r\n\r\n public applyInverse(point: Vector): Vector {\r\n return this.inverse.multiply(point);\r\n }\r\n\r\n public setTransform(pos: Vector, rotation: number, scale: Vector) {\r\n this._pos.x = pos.x;\r\n this._pos.y = pos.y;\r\n this._rotation = canonicalizeAngle(rotation);\r\n this._scale.x = scale.x;\r\n this._scale.y = scale.y;\r\n this.flagDirty();\r\n }\r\n\r\n public clone(dest?: Transform) {\r\n const target = dest ?? new Transform();\r\n this._pos.clone(target._pos);\r\n target._rotation = this._rotation;\r\n this._scale.clone(target._scale);\r\n target.flagDirty();\r\n return target;\r\n }\r\n}","import { Entity } from './Entity';\r\n\r\n/**\r\n * Component Contructor Types\r\n */\r\nexport declare type ComponentCtor = new (...args:any[]) => T;\r\n\r\n/**\r\n * Type guard to check if a component implements clone\r\n * @param x\r\n */\r\nfunction hasClone(x: any): x is { clone(): any } {\r\n return !!x?.clone;\r\n}\r\n\r\nexport type ComponentType = ComponentToParse extends Component ? TypeName : never;\r\n\r\n/**\r\n * Plucks the string type out of a component type\r\n */\r\nexport type ComponentStringType = T extends Component ? R : string;\r\n\r\n/**\r\n * Components are containers for state in Excalibur, the are meant to convey capabilities that an Entity possesses\r\n *\r\n * Implementations of Component must have a zero-arg constructor to support dependencies\r\n *\r\n * ```typescript\r\n * class MyComponent extends ex.Component<'my'> {\r\n * public readonly type = 'my';\r\n * // zero arg support required if you want to use component dependencies\r\n * constructor(public optionalPos?: ex.Vector) {}\r\n * }\r\n * ```\r\n */\r\nexport abstract class Component {\r\n /**\r\n * Optionally list any component types this component depends on\r\n * If the owner entity does not have these components, new components will be added to the entity\r\n *\r\n * Only components with zero-arg constructors are supported as automatic component dependencies\r\n */\r\n readonly dependencies?: ComponentCtor[];\r\n\r\n // todo implement optional\r\n readonly optional?: ComponentCtor[];\r\n\r\n /**\r\n * Type of this component, must be a unique type among component types in you game.\r\n */\r\n abstract readonly type: TypeName;\r\n\r\n /**\r\n * Current owning [[Entity]], if any, of this component. Null if not added to any [[Entity]]\r\n */\r\n owner?: Entity = null;\r\n\r\n /**\r\n * Clones any properties on this component, if that property value has a `clone()` method it will be called\r\n */\r\n clone(): Component {\r\n const newComponent = new (this.constructor as any)();\r\n for (const prop in this) {\r\n if (this.hasOwnProperty(prop)) {\r\n const val = this[prop];\r\n if (hasClone(val) && prop !== 'owner' && prop !== 'clone') {\r\n newComponent[prop] = val.clone();\r\n } else {\r\n newComponent[prop] = val;\r\n }\r\n }\r\n }\r\n return newComponent;\r\n }\r\n\r\n /**\r\n * Optional callback called when a component is added to an entity\r\n */\r\n onAdd?(owner: Entity): void;\r\n\r\n /**\r\n * Optional callback called when a component is added to an entity\r\n */\r\n onRemove?(previousOwner: Entity): void;\r\n}\r\n\r\n/**\r\n * Tag components are a way of tagging a component with label and a simple value\r\n *\r\n * For example:\r\n *\r\n * ```typescript\r\n * const isOffscreen = new TagComponent('offscreen');\r\n * entity.addComponent(isOffscreen);\r\n * entity.tags.includes\r\n * ```\r\n */\r\nexport class TagComponent extends Component<\r\nTypeName\r\n> {\r\n constructor(public readonly type: TypeName, public readonly value?: MaybeValueType) {\r\n super();\r\n }\r\n}\r\n","/**\r\n * Defines a generic message that can contain any data\r\n * @template T is the typescript Type of the data\r\n */\r\nexport interface Message {\r\n type: string;\r\n data: T;\r\n}\r\n\r\n/**\r\n * Defines an interface for an observer to receive a message via a notify() method\r\n */\r\nexport interface Observer {\r\n notify(message: T): void;\r\n}\r\n\r\n/**\r\n * Defines an interface for something that might be an observer if a notify() is present\r\n */\r\nexport type MaybeObserver = Partial>;\r\n\r\n/**\r\n * Simple Observable implementation\r\n * @template T is the typescript Type that defines the data being observed\r\n */\r\nexport class Observable {\r\n public observers: Observer[] = [];\r\n public subscriptions: ((val: T) => any)[] = [];\r\n\r\n /**\r\n * Register an observer to listen to this observable\r\n * @param observer\r\n */\r\n register(observer: Observer) {\r\n this.observers.push(observer);\r\n }\r\n\r\n /**\r\n * Register a callback to listen to this observable\r\n * @param func\r\n */\r\n subscribe(func: (val: T) => any) {\r\n this.subscriptions.push(func);\r\n }\r\n\r\n /**\r\n * Remove an observer from the observable\r\n * @param observer\r\n */\r\n unregister(observer: Observer) {\r\n const i = this.observers.indexOf(observer);\r\n if (i !== -1) {\r\n this.observers.splice(i, 1);\r\n }\r\n }\r\n\r\n /**\r\n * Remove a callback that is listening to this observable\r\n * @param func\r\n */\r\n unsubscribe(func: (val: T) => any) {\r\n const i = this.subscriptions.indexOf(func);\r\n if (i !== -1) {\r\n this.subscriptions.splice(i, 1);\r\n }\r\n }\r\n\r\n /**\r\n * Broadcasts a message to all observers and callbacks\r\n * @param message\r\n */\r\n notifyAll(message: T) {\r\n const observersLength = this.observers.length;\r\n for (let i = 0; i < observersLength; i++) {\r\n this.observers[i].notify(message);\r\n }\r\n const subscriptionsLength = this.subscriptions.length;\r\n for (let i = 0; i < subscriptionsLength; i++) {\r\n this.subscriptions[i](message);\r\n }\r\n }\r\n\r\n /**\r\n * Removes all observers and callbacks\r\n */\r\n clear() {\r\n this.observers.length = 0;\r\n this.subscriptions.length = 0;\r\n }\r\n}\r\n","import { Vector } from '../../Math/vector';\r\nimport { CoordPlane } from '../../Math/coord-plane';\r\nimport { Transform } from '../../Math/transform';\r\nimport { Component } from '../Component';\r\nimport { Entity } from '../Entity';\r\nimport { Observable } from '../../Util/Observable';\r\n\r\n\r\nexport class TransformComponent extends Component<'ex.transform'> {\r\n public readonly type = 'ex.transform';\r\n\r\n private _transform = new Transform();\r\n public get() {\r\n return this._transform;\r\n }\r\n\r\n private _addChildTransform = (child: Entity) => {\r\n const childTxComponent = child.get(TransformComponent);\r\n if (childTxComponent) {\r\n childTxComponent._transform.parent = this._transform;\r\n }\r\n };\r\n onAdd(owner: Entity): void {\r\n for (const child of owner.children) {\r\n this._addChildTransform(child);\r\n }\r\n owner.childrenAdded$.subscribe(child => this._addChildTransform(child));\r\n owner.childrenRemoved$.subscribe(child => {\r\n const childTxComponent = child.get(TransformComponent);\r\n if (childTxComponent) {\r\n childTxComponent._transform.parent = null;\r\n }\r\n });\r\n }\r\n onRemove(_previousOwner: Entity): void {\r\n this._transform.parent = null;\r\n }\r\n\r\n /**\r\n * Observable that emits when the z index changes on this component\r\n */\r\n public zIndexChanged$ = new Observable();\r\n private _z = 0;\r\n\r\n /**\r\n * The z-index ordering of the entity, a higher values are drawn on top of lower values.\r\n * For example z=99 would be drawn on top of z=0.\r\n */\r\n public get z(): number {\r\n return this._z;\r\n }\r\n\r\n public set z(val: number) {\r\n const oldz = this._z;\r\n this._z = val;\r\n if (oldz !== val) {\r\n this.zIndexChanged$.notifyAll(val);\r\n }\r\n }\r\n\r\n /**\r\n * The [[CoordPlane|coordinate plane|]] for this transform for the entity.\r\n */\r\n public coordPlane = CoordPlane.World;\r\n\r\n get pos() {\r\n return this._transform.pos;\r\n }\r\n set pos(v: Vector) {\r\n this._transform.pos = v;\r\n }\r\n\r\n get globalPos() {\r\n return this._transform.globalPos;\r\n }\r\n set globalPos(v: Vector) {\r\n this._transform.globalPos = v;\r\n }\r\n\r\n get rotation() {\r\n return this._transform.rotation;\r\n }\r\n set rotation(rotation) {\r\n this._transform.rotation = rotation;\r\n }\r\n\r\n get globalRotation() {\r\n return this._transform.globalRotation;\r\n }\r\n set globalRotation(rotation) {\r\n this._transform.globalRotation = rotation;\r\n }\r\n\r\n get scale() {\r\n return this._transform.scale;\r\n }\r\n set scale(v: Vector) {\r\n this._transform.scale = v;\r\n }\r\n\r\n get globalScale() {\r\n return this._transform.globalScale;\r\n }\r\n set globalScale(v: Vector) {\r\n this._transform.globalScale = v;\r\n }\r\n\r\n applyInverse(v: Vector) {\r\n return this._transform.applyInverse(v);\r\n }\r\n\r\n apply(v: Vector) {\r\n return this._transform.apply(v);\r\n }\r\n\r\n clone(): TransformComponent {\r\n const component = new TransformComponent();\r\n component._transform = this._transform.clone();\r\n component._z = this._z;\r\n return component;\r\n }\r\n}","import { Vector } from '../../Math/vector';\r\nimport { Component } from '../Component';\r\n\r\nexport interface Motion {\r\n /**\r\n * The velocity of an entity in pixels per second\r\n */\r\n vel: Vector;\r\n\r\n /**\r\n * The acceleration of entity in pixels per second^2\r\n */\r\n acc: Vector;\r\n\r\n /**\r\n * The scale rate of change in scale units per second\r\n */\r\n scaleFactor: Vector;\r\n\r\n /**\r\n * The angular velocity which is how quickly the entity is rotating in radians per second\r\n */\r\n angularVelocity: number;\r\n\r\n /**\r\n * The amount of torque applied to the entity, angular acceleration is torque * inertia\r\n */\r\n torque: number;\r\n\r\n /**\r\n * Inertia can be thought of as the resistance to motion\r\n */\r\n inertia: number;\r\n}\r\n\r\nexport class MotionComponent extends Component<'ex.motion'> {\r\n public readonly type = 'ex.motion';\r\n\r\n /**\r\n * The velocity of an entity in pixels per second\r\n */\r\n public vel: Vector = Vector.Zero;\r\n\r\n /**\r\n * The acceleration of entity in pixels per second^2\r\n */\r\n public acc: Vector = Vector.Zero;\r\n\r\n /**\r\n * The scale rate of change in scale units per second\r\n */\r\n public scaleFactor: Vector = Vector.Zero;\r\n\r\n /**\r\n * The angular velocity which is how quickly the entity is rotating in radians per second\r\n */\r\n public angularVelocity = 0;\r\n\r\n /**\r\n * The amount of torque applied to the entity, angular acceleration is torque * inertia\r\n */\r\n public torque: number = 0;\r\n\r\n /**\r\n * Inertia can be thought of as the resistance to motion\r\n */\r\n public inertia: number = 1;\r\n}\r\n","/**\r\n * CollisionGroups indicate like members that do not collide with each other. Use [[CollisionGroupManager]] to create [[CollisionGroup]]s\r\n *\r\n * For example:\r\n *\r\n * Players have collision group \"player\"\r\n *\r\n * ![Player Collision Group](/assets/images/docs/CollisionGroupsPlayer.png)\r\n *\r\n * Enemies have collision group \"enemy\"\r\n *\r\n * ![Enemy Collision Group](/assets/images/docs/CollisionGroupsEnemy.png)\r\n *\r\n * Blocks have collision group \"ground\"\r\n *\r\n * ![Ground collision group](/assets/images/docs/CollisionGroupsGround.png)\r\n *\r\n * Players don't collide with each other, but enemies and blocks. Likewise, enemies don't collide with each other but collide\r\n * with players and blocks.\r\n *\r\n * This is done with bitmasking, see the following pseudo-code\r\n *\r\n * PlayerGroup = `0b001`\r\n * PlayerGroupMask = `0b110`\r\n *\r\n * EnemyGroup = `0b010`\r\n * EnemyGroupMask = `0b101`\r\n *\r\n * BlockGroup = `0b100`\r\n * BlockGroupMask = `0b011`\r\n *\r\n * Should Players collide? No because the bitwise mask evaluates to 0\r\n * `(player1.group & player2.mask) === 0`\r\n * `(0b001 & 0b110) === 0`\r\n *\r\n * Should Players and Enemies collide? Yes because the bitwise mask is non-zero\r\n * `(player1.group & enemy1.mask) === 1`\r\n * `(0b001 & 0b101) === 1`\r\n *\r\n * Should Players and Blocks collide? Yes because the bitwise mask is non-zero\r\n * `(player1.group & blocks1.mask) === 1`\r\n * `(0b001 & 0b011) === 1`\r\n */\r\nexport class CollisionGroup {\r\n /**\r\n * The `All` [[CollisionGroup]] is a special group that collides with all other groups including itself,\r\n * it is the default collision group on colliders.\r\n */\r\n public static All = new CollisionGroup('Collide with all groups', -1, -1);\r\n\r\n private _name: string;\r\n private _category: number;\r\n private _mask: number;\r\n\r\n /**\r\n * STOP!!** It is preferred that [[CollisionGroupManager.create]] is used to create collision groups\r\n * unless you know how to construct the proper bitmasks. See https://github.com/excaliburjs/Excalibur/issues/1091 for more info.\r\n * @param name Name of the collision group\r\n * @param category 32 bit category for the group, should be a unique power of 2. For example `0b001` or `0b010`\r\n * @param mask 32 bit mask of category, or `~category` generally. For a category of `0b001`, the mask would be `0b110`\r\n */\r\n constructor(name: string, category: number, mask: number) {\r\n this._name = name;\r\n this._category = category;\r\n this._mask = mask;\r\n }\r\n\r\n /**\r\n * Get the name of the collision group\r\n */\r\n public get name() {\r\n return this._name;\r\n }\r\n\r\n /**\r\n * Get the category of the collision group, a 32 bit number which should be a unique power of 2\r\n */\r\n public get category() {\r\n return this._category;\r\n }\r\n\r\n /**\r\n * Get the mask for this collision group\r\n */\r\n public get mask() {\r\n return this._mask;\r\n }\r\n\r\n /**\r\n * Evaluates whether 2 collision groups can collide\r\n * @param other CollisionGroup\r\n */\r\n public canCollide(other: CollisionGroup): boolean {\r\n return (this.category & other.mask) !== 0 && (other.category & this.mask) !== 0;\r\n }\r\n\r\n /**\r\n * Inverts the collision group. For example, if before the group specified \"players\",\r\n * inverting would specify all groups except players\r\n * @returns CollisionGroup\r\n */\r\n public invert(): CollisionGroup {\r\n return new CollisionGroup('~(' + this.name + ')', ~this.category, ~this.mask);\r\n }\r\n\r\n /**\r\n * Combine collision groups with each other. The new group includes all of the previous groups.\r\n *\r\n * @param collisionGroups\r\n */\r\n public static combine(collisionGroups: CollisionGroup[]) {\r\n const combinedName = collisionGroups.map((c) => c.name).join('+');\r\n const combinedCategory = collisionGroups.reduce((current, g) => g.category | current, 0b0);\r\n const combinedMask = ~combinedCategory;\r\n\r\n return new CollisionGroup(combinedName, combinedCategory, combinedMask);\r\n }\r\n\r\n /**\r\n * Creates a collision group that collides with the listed groups\r\n * @param collisionGroups\r\n */\r\n public static collidesWith(collisionGroups: CollisionGroup[]) {\r\n return CollisionGroup.combine(collisionGroups).invert();\r\n }\r\n}\r\n","import { CollisionContact } from './CollisionContact';\r\nimport { CollisionType } from '../CollisionType';\r\nimport { BodyComponent } from '../BodyComponent';\r\nimport { Id } from '../../Id';\r\nimport { Collider } from '../Colliders/Collider';\r\n\r\n/**\r\n * Models a potential collision between 2 colliders\r\n */\r\nexport class Pair {\r\n public id: string = null;\r\n constructor(public colliderA: Collider, public colliderB: Collider) {\r\n this.id = Pair.calculatePairHash(colliderA.id, colliderB.id);\r\n }\r\n\r\n /**\r\n * Returns whether a it is allowed for 2 colliders in a Pair to collide\r\n * @param colliderA\r\n * @param colliderB\r\n */\r\n public static canCollide(colliderA: Collider, colliderB: Collider) {\r\n const bodyA = colliderA?.owner?.get(BodyComponent);\r\n const bodyB = colliderB?.owner?.get(BodyComponent);\r\n\r\n // Prevent self collision\r\n if (colliderA.id === colliderB.id) {\r\n return false;\r\n }\r\n\r\n // Colliders with the same owner do not collide (composite colliders)\r\n if (colliderA.owner &&\r\n colliderB.owner &&\r\n colliderA.owner.id === colliderB.owner.id) {\r\n return false;\r\n }\r\n\r\n // if the pair has a member with zero dimension don't collide\r\n if (colliderA.localBounds.hasZeroDimensions() || colliderB.localBounds.hasZeroDimensions()) {\r\n return false;\r\n }\r\n\r\n // Body's needed for collision in the current state\r\n // TODO can we collide without a body?\r\n if (!bodyA || !bodyB) {\r\n return false;\r\n }\r\n\r\n // If both are in the same collision group short circuit\r\n if (!bodyA.group.canCollide(bodyB.group)) {\r\n return false;\r\n }\r\n\r\n // if both are fixed short circuit\r\n if (bodyA.collisionType === CollisionType.Fixed && bodyB.collisionType === CollisionType.Fixed) {\r\n return false;\r\n }\r\n\r\n // if the either is prevent collision short circuit\r\n if (bodyB.collisionType === CollisionType.PreventCollision || bodyA.collisionType === CollisionType.PreventCollision) {\r\n return false;\r\n }\r\n\r\n // if either is dead short circuit\r\n if (!bodyA.active || !bodyB.active) {\r\n return false;\r\n }\r\n\r\n return true;\r\n }\r\n\r\n /**\r\n * Returns whether or not it is possible for the pairs to collide\r\n */\r\n public get canCollide(): boolean {\r\n const colliderA = this.colliderA;\r\n const colliderB = this.colliderB;\r\n return Pair.canCollide(colliderA, colliderB);\r\n }\r\n\r\n /**\r\n * Runs the collision intersection logic on the members of this pair\r\n */\r\n public collide(): CollisionContact[] {\r\n return this.colliderA.collide(this.colliderB);\r\n }\r\n\r\n /**\r\n * Check if the collider is part of the pair\r\n * @param collider\r\n */\r\n public hasCollider(collider: Collider) {\r\n return collider === this.colliderA || collider === this.colliderB;\r\n }\r\n\r\n /**\r\n * Calculates the unique pair hash id for this collision pair (owning id)\r\n */\r\n public static calculatePairHash(idA: Id<'collider'>, idB: Id<'collider'>): string {\r\n if (idA.value < idB.value) {\r\n return `#${idA.value}+${idB.value}`;\r\n } else {\r\n return `#${idB.value}+${idA.value}`;\r\n }\r\n }\r\n}\r\n","/**\r\n * A 1 dimensional projection on an axis, used to test overlaps\r\n */\r\n\r\nexport class Projection {\r\n constructor(public min: number, public max: number) {}\r\n public overlaps(projection: Projection): boolean {\r\n return this.max > projection.min && projection.max > this.min;\r\n }\r\n\r\n public getOverlap(projection: Projection): number {\r\n if (this.overlaps(projection)) {\r\n if (this.max > projection.max) {\r\n return projection.max - this.min;\r\n } else {\r\n return this.max - projection.min;\r\n }\r\n }\r\n return 0;\r\n }\r\n}\r\n","import { Physics } from '../Physics';\r\nimport { BoundingBox } from '../BoundingBox';\r\n\r\nimport { Ray } from '../../Math/ray';\r\nimport { Logger } from '../../Util/Log';\r\nimport { Id } from '../../Id';\r\nimport { Entity } from '../../EntityComponentSystem/Entity';\r\nimport { BodyComponent } from '../BodyComponent';\r\nimport { Color, ExcaliburGraphicsContext } from '../..';\r\n\r\n/**\r\n * Dynamic Tree Node used for tracking bounds within the tree\r\n */\r\nexport class TreeNode {\r\n public left: TreeNode;\r\n public right: TreeNode;\r\n public bounds: BoundingBox;\r\n public height: number;\r\n public data: T;\r\n constructor(public parent?: TreeNode) {\r\n this.parent = parent || null;\r\n this.data = null;\r\n this.bounds = new BoundingBox();\r\n this.left = null;\r\n this.right = null;\r\n this.height = 0;\r\n }\r\n\r\n public isLeaf(): boolean {\r\n return !this.left && !this.right;\r\n }\r\n}\r\n\r\nexport interface ColliderProxy {\r\n id: Id<'collider'>;\r\n owner: T;\r\n bounds: BoundingBox;\r\n}\r\n\r\n/**\r\n * The DynamicTrees provides a spatial partitioning data structure for quickly querying for overlapping bounding boxes for\r\n * all tracked bodies. The worst case performance of this is O(n*log(n)) where n is the number of bodies in the tree.\r\n *\r\n * Internally the bounding boxes are organized as a balanced binary tree of bounding boxes, where the leaf nodes are tracked bodies.\r\n * Every non-leaf node is a bounding box that contains child bounding boxes.\r\n */\r\nexport class DynamicTree> {\r\n public root: TreeNode;\r\n public nodes: { [key: number]: TreeNode };\r\n constructor(public worldBounds: BoundingBox = new BoundingBox(-Number.MAX_VALUE, -Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE)) {\r\n this.root = null;\r\n this.nodes = {};\r\n }\r\n\r\n /**\r\n * Inserts a node into the dynamic tree\r\n */\r\n private _insert(leaf: TreeNode): void {\r\n // If there are no nodes in the tree, make this the root leaf\r\n if (this.root === null) {\r\n this.root = leaf;\r\n this.root.parent = null;\r\n return;\r\n }\r\n\r\n // Search the tree for a node that is not a leaf and find the best place to insert\r\n const leafAABB = leaf.bounds;\r\n let currentRoot = this.root;\r\n while (!currentRoot.isLeaf()) {\r\n const left = currentRoot.left;\r\n const right = currentRoot.right;\r\n\r\n const area = currentRoot.bounds.getPerimeter();\r\n const combinedAABB = currentRoot.bounds.combine(leafAABB);\r\n const combinedArea = combinedAABB.getPerimeter();\r\n\r\n // Calculate cost heuristic for creating a new parent and leaf\r\n const cost = 2 * combinedArea;\r\n\r\n // Minimum cost of pushing the leaf down the tree\r\n const inheritanceCost = 2 * (combinedArea - area);\r\n\r\n // Cost of descending\r\n let leftCost = 0;\r\n const leftCombined = leafAABB.combine(left.bounds);\r\n let newArea;\r\n let oldArea;\r\n if (left.isLeaf()) {\r\n leftCost = leftCombined.getPerimeter() + inheritanceCost;\r\n } else {\r\n oldArea = left.bounds.getPerimeter();\r\n newArea = leftCombined.getPerimeter();\r\n leftCost = newArea - oldArea + inheritanceCost;\r\n }\r\n\r\n let rightCost = 0;\r\n const rightCombined = leafAABB.combine(right.bounds);\r\n if (right.isLeaf()) {\r\n rightCost = rightCombined.getPerimeter() + inheritanceCost;\r\n } else {\r\n oldArea = right.bounds.getPerimeter();\r\n newArea = rightCombined.getPerimeter();\r\n rightCost = newArea - oldArea + inheritanceCost;\r\n }\r\n\r\n // cost is acceptable\r\n if (cost < leftCost && cost < rightCost) {\r\n break;\r\n }\r\n\r\n // Descend to the depths\r\n if (leftCost < rightCost) {\r\n currentRoot = left;\r\n } else {\r\n currentRoot = right;\r\n }\r\n }\r\n\r\n // Create the new parent node and insert into the tree\r\n const oldParent = currentRoot.parent;\r\n const newParent = new TreeNode(oldParent);\r\n newParent.bounds = leafAABB.combine(currentRoot.bounds);\r\n newParent.height = currentRoot.height + 1;\r\n\r\n if (oldParent !== null) {\r\n // The sibling node was not the root\r\n if (oldParent.left === currentRoot) {\r\n oldParent.left = newParent;\r\n } else {\r\n oldParent.right = newParent;\r\n }\r\n\r\n newParent.left = currentRoot;\r\n newParent.right = leaf;\r\n\r\n currentRoot.parent = newParent;\r\n leaf.parent = newParent;\r\n } else {\r\n // The sibling node was the root\r\n newParent.left = currentRoot;\r\n newParent.right = leaf;\r\n\r\n currentRoot.parent = newParent;\r\n leaf.parent = newParent;\r\n this.root = newParent;\r\n }\r\n\r\n // Walk up the tree fixing heights and AABBs\r\n let currentNode = leaf.parent;\r\n while (currentNode) {\r\n currentNode = this._balance(currentNode);\r\n\r\n if (!currentNode.left) {\r\n throw new Error('Parent of current leaf cannot have a null left child' + currentNode);\r\n }\r\n if (!currentNode.right) {\r\n throw new Error('Parent of current leaf cannot have a null right child' + currentNode);\r\n }\r\n\r\n currentNode.height = 1 + Math.max(currentNode.left.height, currentNode.right.height);\r\n currentNode.bounds = currentNode.left.bounds.combine(currentNode.right.bounds);\r\n\r\n currentNode = currentNode.parent;\r\n }\r\n }\r\n\r\n /**\r\n * Removes a node from the dynamic tree\r\n */\r\n private _remove(leaf: TreeNode) {\r\n if (leaf === this.root) {\r\n this.root = null;\r\n return;\r\n }\r\n\r\n const parent = leaf.parent;\r\n const grandParent = parent.parent;\r\n let sibling: TreeNode;\r\n if (parent.left === leaf) {\r\n sibling = parent.right;\r\n } else {\r\n sibling = parent.left;\r\n }\r\n\r\n if (grandParent) {\r\n if (grandParent.left === parent) {\r\n grandParent.left = sibling;\r\n } else {\r\n grandParent.right = sibling;\r\n }\r\n sibling.parent = grandParent;\r\n\r\n let currentNode = grandParent;\r\n while (currentNode) {\r\n currentNode = this._balance(currentNode);\r\n currentNode.bounds = currentNode.left.bounds.combine(currentNode.right.bounds);\r\n currentNode.height = 1 + Math.max(currentNode.left.height, currentNode.right.height);\r\n\r\n currentNode = currentNode.parent;\r\n }\r\n } else {\r\n this.root = sibling;\r\n sibling.parent = null;\r\n }\r\n }\r\n\r\n /**\r\n * Tracks a body in the dynamic tree\r\n */\r\n public trackCollider(collider: T) {\r\n const node = new TreeNode();\r\n node.data = collider;\r\n node.bounds = collider.bounds;\r\n node.bounds.left -= 2;\r\n node.bounds.top -= 2;\r\n node.bounds.right += 2;\r\n node.bounds.bottom += 2;\r\n this.nodes[collider.id.value] = node;\r\n this._insert(node);\r\n }\r\n\r\n /**\r\n * Updates the dynamic tree given the current bounds of each body being tracked\r\n */\r\n public updateCollider(collider: T) {\r\n const node = this.nodes[collider.id.value];\r\n if (!node) {\r\n return false;\r\n }\r\n const b = collider.bounds;\r\n\r\n // if the body is outside the world no longer update it\r\n if (!this.worldBounds.contains(b)) {\r\n Logger.getInstance().warn(\r\n 'Collider with id ' + collider.id.value + ' is outside the world bounds and will no longer be tracked for physics'\r\n );\r\n this.untrackCollider(collider);\r\n return false;\r\n }\r\n\r\n if (node.bounds.contains(b)) {\r\n return false;\r\n }\r\n\r\n this._remove(node);\r\n b.left -= Physics.boundsPadding;\r\n b.top -= Physics.boundsPadding;\r\n b.right += Physics.boundsPadding;\r\n b.bottom += Physics.boundsPadding;\r\n\r\n // THIS IS CAUSING UNECESSARY CHECKS\r\n if (collider.owner) {\r\n const body = collider.owner?.get(BodyComponent);\r\n if (body) {\r\n const multdx = ((body.vel.x * 32) / 1000) * Physics.dynamicTreeVelocityMultiplier;\r\n const multdy = ((body.vel.y * 32) / 1000) * Physics.dynamicTreeVelocityMultiplier;\r\n\r\n if (multdx < 0) {\r\n b.left += multdx;\r\n } else {\r\n b.right += multdx;\r\n }\r\n\r\n if (multdy < 0) {\r\n b.top += multdy;\r\n } else {\r\n b.bottom += multdy;\r\n }\r\n }\r\n }\r\n\r\n node.bounds = b;\r\n this._insert(node);\r\n return true;\r\n }\r\n\r\n /**\r\n * Untracks a body from the dynamic tree\r\n */\r\n public untrackCollider(collider: T) {\r\n const node = this.nodes[collider.id.value];\r\n if (!node) {\r\n return;\r\n }\r\n this._remove(node);\r\n this.nodes[collider.id.value] = null;\r\n delete this.nodes[collider.id.value];\r\n }\r\n\r\n /**\r\n * Balances the tree about a node\r\n */\r\n private _balance(node: TreeNode) {\r\n if (node === null) {\r\n throw new Error('Cannot balance at null node');\r\n }\r\n\r\n if (node.isLeaf() || node.height < 2) {\r\n return node;\r\n }\r\n\r\n const left = node.left;\r\n const right = node.right;\r\n\r\n const a = node;\r\n const b = left;\r\n const c = right;\r\n const d = left.left;\r\n const e = left.right;\r\n const f = right.left;\r\n const g = right.right;\r\n\r\n const balance = c.height - b.height;\r\n // Rotate c node up\r\n if (balance > 1) {\r\n // Swap the right node with it's parent\r\n c.left = a;\r\n c.parent = a.parent;\r\n a.parent = c;\r\n\r\n // The original node's old parent should point to the right node\r\n // this is mega confusing\r\n if (c.parent) {\r\n if (c.parent.left === a) {\r\n c.parent.left = c;\r\n } else {\r\n c.parent.right = c;\r\n }\r\n } else {\r\n this.root = c;\r\n }\r\n\r\n // Rotate\r\n if (f.height > g.height) {\r\n c.right = f;\r\n a.right = g;\r\n g.parent = a;\r\n\r\n a.bounds = b.bounds.combine(g.bounds);\r\n c.bounds = a.bounds.combine(f.bounds);\r\n\r\n a.height = 1 + Math.max(b.height, g.height);\r\n c.height = 1 + Math.max(a.height, f.height);\r\n } else {\r\n c.right = g;\r\n a.right = f;\r\n f.parent = a;\r\n\r\n a.bounds = b.bounds.combine(f.bounds);\r\n c.bounds = a.bounds.combine(g.bounds);\r\n\r\n a.height = 1 + Math.max(b.height, f.height);\r\n c.height = 1 + Math.max(a.height, g.height);\r\n }\r\n\r\n return c;\r\n }\r\n // Rotate left node up\r\n if (balance < -1) {\r\n // swap\r\n b.left = a;\r\n b.parent = a.parent;\r\n a.parent = b;\r\n\r\n // node's old parent should point to b\r\n if (b.parent) {\r\n if (b.parent.left === a) {\r\n b.parent.left = b;\r\n } else {\r\n if (b.parent.right !== a) {\r\n throw 'Error rotating Dynamic Tree';\r\n }\r\n b.parent.right = b;\r\n }\r\n } else {\r\n this.root = b;\r\n }\r\n\r\n // rotate\r\n if (d.height > e.height) {\r\n b.right = d;\r\n a.left = e;\r\n e.parent = a;\r\n\r\n a.bounds = c.bounds.combine(e.bounds);\r\n b.bounds = a.bounds.combine(d.bounds);\r\n\r\n a.height = 1 + Math.max(c.height, e.height);\r\n b.height = 1 + Math.max(a.height, d.height);\r\n } else {\r\n b.right = e;\r\n a.left = d;\r\n d.parent = a;\r\n\r\n a.bounds = c.bounds.combine(d.bounds);\r\n b.bounds = a.bounds.combine(e.bounds);\r\n\r\n a.height = 1 + Math.max(c.height, d.height);\r\n b.height = 1 + Math.max(a.height, e.height);\r\n }\r\n return b;\r\n }\r\n\r\n return node;\r\n }\r\n\r\n /**\r\n * Returns the internal height of the tree, shorter trees are better. Performance drops as the tree grows\r\n */\r\n public getHeight(): number {\r\n if (this.root === null) {\r\n return 0;\r\n }\r\n return this.root.height;\r\n }\r\n\r\n /**\r\n * Queries the Dynamic Axis Aligned Tree for bodies that could be colliding with the provided body.\r\n *\r\n * In the query callback, it will be passed a potential collider. Returning true from this callback indicates\r\n * that you are complete with your query and you do not want to continue. Returning false will continue searching\r\n * the tree until all possible colliders have been returned.\r\n */\r\n public query(collider: T, callback: (other: T) => boolean): void {\r\n const bounds = collider.bounds;\r\n const helper = (currentNode: TreeNode): boolean => {\r\n if (currentNode && currentNode.bounds.overlaps(bounds)) {\r\n if (currentNode.isLeaf() && currentNode.data !== collider) {\r\n if (callback.call(collider, currentNode.data)) {\r\n return true;\r\n }\r\n } else {\r\n return helper(currentNode.left) || helper(currentNode.right);\r\n }\r\n }\r\n return false;\r\n };\r\n helper(this.root);\r\n }\r\n\r\n /**\r\n * Queries the Dynamic Axis Aligned Tree for bodies that could be intersecting. By default the raycast query uses an infinitely\r\n * long ray to test the tree specified by `max`.\r\n *\r\n * In the query callback, it will be passed a potential body that intersects with the raycast. Returning true from this\r\n * callback indicates that your are complete with your query and do not want to continue. Return false will continue searching\r\n * the tree until all possible bodies that would intersect with the ray have been returned.\r\n */\r\n public rayCastQuery(ray: Ray, max: number = Infinity, callback: (other: T) => boolean): void {\r\n const helper = (currentNode: TreeNode): boolean => {\r\n if (currentNode && currentNode.bounds.rayCast(ray, max)) {\r\n if (currentNode.isLeaf()) {\r\n if (callback.call(ray, currentNode.data)) {\r\n // ray hit a leaf! return the body\r\n return true;\r\n }\r\n } else {\r\n // ray hit but not at a leaf, recurse deeper\r\n return helper(currentNode.left) || helper(currentNode.right);\r\n }\r\n }\r\n return false; // ray missed\r\n };\r\n helper(this.root);\r\n }\r\n\r\n public getNodes(): TreeNode[] {\r\n const helper = (currentNode: TreeNode): TreeNode[] => {\r\n if (currentNode) {\r\n return [currentNode].concat(helper(currentNode.left), helper(currentNode.right));\r\n } else {\r\n return [];\r\n }\r\n };\r\n return helper(this.root);\r\n }\r\n\r\n public debug(ex: ExcaliburGraphicsContext) {\r\n // draw all the nodes in the Dynamic Tree\r\n const helper = (currentNode: TreeNode) => {\r\n if (currentNode) {\r\n if (currentNode.isLeaf()) {\r\n currentNode.bounds.draw(ex, Color.Green);\r\n } else {\r\n currentNode.bounds.draw(ex, Color.White);\r\n }\r\n\r\n if (currentNode.left) {\r\n helper(currentNode.left);\r\n }\r\n if (currentNode.right) {\r\n helper(currentNode.right);\r\n }\r\n }\r\n };\r\n\r\n helper(this.root);\r\n }\r\n}\r\n","import { LineSegment } from './line-segment';\r\nimport { Vector } from './vector';\r\n\r\n/**\r\n * A 2D ray that can be cast into the scene to do collision detection\r\n */\r\n\r\nexport class Ray {\r\n public pos: Vector;\r\n public dir: Vector;\r\n\r\n /**\r\n * @param pos The starting position for the ray\r\n * @param dir The vector indicating the direction of the ray\r\n */\r\n constructor(pos: Vector, dir: Vector) {\r\n this.pos = pos;\r\n this.dir = dir.normalize();\r\n }\r\n\r\n /**\r\n * Tests a whether this ray intersects with a line segment. Returns a number greater than or equal to 0 on success.\r\n * This number indicates the mathematical intersection time.\r\n * @param line The line to test\r\n */\r\n public intersect(line: LineSegment): number {\r\n const numerator = line.begin.sub(this.pos);\r\n\r\n // Test is line and ray are parallel and non intersecting\r\n if (this.dir.cross(line.getSlope()) === 0 && numerator.cross(this.dir) !== 0) {\r\n return -1;\r\n }\r\n\r\n // Lines are parallel\r\n const divisor = this.dir.cross(line.getSlope());\r\n if (divisor === 0) {\r\n return -1;\r\n }\r\n\r\n const t = numerator.cross(line.getSlope()) / divisor;\r\n\r\n if (t >= 0) {\r\n const u = numerator.cross(this.dir) / divisor / line.getLength();\r\n if (u >= 0 && u <= 1) {\r\n return t;\r\n }\r\n }\r\n return -1;\r\n }\r\n\r\n public intersectPoint(line: LineSegment): Vector {\r\n const time = this.intersect(line);\r\n if (time < 0) {\r\n return null;\r\n }\r\n return this.getPoint(time);\r\n }\r\n\r\n /**\r\n * Returns the point of intersection given the intersection time\r\n */\r\n public getPoint(time: number): Vector {\r\n return this.pos.add(this.dir.scale(time));\r\n }\r\n}\r\n","import { Physics } from '../Physics';\r\nimport { CollisionProcessor } from './CollisionProcessor';\r\nimport { DynamicTree } from './DynamicTree';\r\nimport { Pair } from './Pair';\r\n\r\nimport { Vector } from '../../Math/vector';\r\nimport { Ray } from '../../Math/ray';\r\nimport { FrameStats } from '../../Debug';\r\nimport { Logger } from '../../Util/Log';\r\nimport { CollisionType } from '../CollisionType';\r\nimport { Collider } from '../Colliders/Collider';\r\nimport { CollisionContact } from '../Detection/CollisionContact';\r\nimport { BodyComponent } from '../BodyComponent';\r\nimport { CompositeCollider } from '../Colliders/CompositeCollider';\r\nimport { CollisionGroup } from '../Group/CollisionGroup';\r\nimport { ExcaliburGraphicsContext } from '../../Graphics/Context/ExcaliburGraphicsContext';\r\n\r\nexport interface RayCastHit {\r\n /**\r\n * The distance along the ray cast in pixels that a hit was detected\r\n */\r\n distance: number;\r\n /**\r\n * Reference to the collider that was hit\r\n */\r\n collider: Collider;\r\n /**\r\n * Reference to the body that was hit\r\n */\r\n body: BodyComponent;\r\n /**\r\n * World space point of the hit\r\n */\r\n point: Vector;\r\n}\r\n\r\nexport interface RayCastOptions {\r\n /**\r\n * Optionally specify the maximum distance in pixels to ray cast, default is Infinity\r\n */\r\n maxDistance?: number;\r\n /**\r\n * Optionally specify a collision group to consider in the ray cast, default is All\r\n */\r\n collisionGroup?: CollisionGroup;\r\n /**\r\n * Optionally specify to search for all colliders that intersect the ray cast, not just the first which is the default\r\n */\r\n searchAllColliders?: boolean;\r\n}\r\n\r\n/**\r\n * Responsible for performing the collision broadphase (locating potential collisions) and\r\n * the narrowphase (actual collision contacts)\r\n */\r\nexport class DynamicTreeCollisionProcessor implements CollisionProcessor {\r\n private _dynamicCollisionTree = new DynamicTree();\r\n private _pairs = new Set();\r\n\r\n private _collisionPairCache: Pair[] = [];\r\n private _colliders: Collider[] = [];\r\n\r\n public getColliders(): readonly Collider[] {\r\n return this._colliders;\r\n }\r\n\r\n public rayCast(ray: Ray, options?: RayCastOptions): RayCastHit[] {\r\n const results: RayCastHit[] = [];\r\n const maxDistance = options?.maxDistance ?? Infinity;\r\n const collisionGroup = options?.collisionGroup ?? CollisionGroup.All;\r\n const searchAllColliders = options?.searchAllColliders ?? false;\r\n this._dynamicCollisionTree.rayCastQuery(ray, maxDistance, (collider) => {\r\n const owner = collider.owner;\r\n const maybeBody = owner.get(BodyComponent);\r\n // Early exit if not the right group\r\n if (collisionGroup.mask !== CollisionGroup.All.mask && maybeBody?.group?.mask !== collisionGroup.mask) {\r\n return false;\r\n }\r\n\r\n const hit = collider.rayCast(ray, maxDistance);\r\n if (hit) {\r\n results.push({\r\n distance: hit.sub(ray.pos).distance(),\r\n point: hit,\r\n collider: collider,\r\n body: maybeBody\r\n });\r\n if (!searchAllColliders) {\r\n // returning true exits the search\r\n return true;\r\n }\r\n }\r\n return false;\r\n });\r\n return results;\r\n }\r\n\r\n /**\r\n * Tracks a physics body for collisions\r\n */\r\n public track(target: Collider): void {\r\n if (!target) {\r\n Logger.getInstance().warn('Cannot track null collider');\r\n return;\r\n }\r\n if (target instanceof CompositeCollider) {\r\n const colliders = target.getColliders();\r\n for (const c of colliders) {\r\n c.owner = target.owner;\r\n this._colliders.push(c);\r\n this._dynamicCollisionTree.trackCollider(c);\r\n }\r\n } else {\r\n this._colliders.push(target);\r\n this._dynamicCollisionTree.trackCollider(target);\r\n }\r\n }\r\n\r\n /**\r\n * Untracks a physics body\r\n */\r\n public untrack(target: Collider): void {\r\n if (!target) {\r\n Logger.getInstance().warn('Cannot untrack a null collider');\r\n return;\r\n }\r\n\r\n if (target instanceof CompositeCollider) {\r\n const colliders = target.getColliders();\r\n for (const c of colliders) {\r\n const index = this._colliders.indexOf(c);\r\n if (index !== -1) {\r\n this._colliders.splice(index, 1);\r\n }\r\n this._dynamicCollisionTree.untrackCollider(c);\r\n }\r\n } else {\r\n const index = this._colliders.indexOf(target);\r\n if (index !== -1) {\r\n this._colliders.splice(index, 1);\r\n }\r\n this._dynamicCollisionTree.untrackCollider(target);\r\n }\r\n }\r\n\r\n private _pairExists(colliderA: Collider, colliderB: Collider) {\r\n // if the collision pair has been calculated already short circuit\r\n const hash = Pair.calculatePairHash(colliderA.id, colliderB.id);\r\n return this._pairs.has(hash);\r\n }\r\n\r\n /**\r\n * Detects potential collision pairs in a broadphase approach with the dynamic AABB tree strategy\r\n */\r\n public broadphase(targets: Collider[], delta: number, stats?: FrameStats): Pair[] {\r\n const seconds = delta / 1000;\r\n\r\n // Retrieve the list of potential colliders, exclude killed, prevented, and self\r\n const potentialColliders = targets.filter((other) => {\r\n const body = other.owner?.get(BodyComponent);\r\n return other.owner?.active && body.collisionType !== CollisionType.PreventCollision;\r\n });\r\n\r\n // clear old list of collision pairs\r\n this._collisionPairCache = [];\r\n this._pairs.clear();\r\n\r\n // check for normal collision pairs\r\n let collider: Collider;\r\n for (let j = 0, l = potentialColliders.length; j < l; j++) {\r\n collider = potentialColliders[j];\r\n // Query the collision tree for potential colliders\r\n this._dynamicCollisionTree.query(collider, (other: Collider) => {\r\n if (!this._pairExists(collider, other) && Pair.canCollide(collider, other)) {\r\n const pair = new Pair(collider, other);\r\n this._pairs.add(pair.id);\r\n this._collisionPairCache.push(pair);\r\n }\r\n // Always return false, to query whole tree. Returning true in the query method stops searching\r\n return false;\r\n });\r\n }\r\n if (stats) {\r\n stats.physics.pairs = this._collisionPairCache.length;\r\n }\r\n\r\n // Check dynamic tree for fast moving objects\r\n // Fast moving objects are those moving at least there smallest bound per frame\r\n if (Physics.checkForFastBodies) {\r\n for (const collider of potentialColliders) {\r\n const body = collider.owner.get(BodyComponent);\r\n // Skip non-active objects. Does not make sense on other collision types\r\n if (body.collisionType !== CollisionType.Active) {\r\n continue;\r\n }\r\n\r\n // Maximum travel distance next frame\r\n const updateDistance =\r\n body.vel.size * seconds + // velocity term\r\n body.acc.size * 0.5 * seconds * seconds; // acc term\r\n\r\n // Find the minimum dimension\r\n const minDimension = Math.min(collider.bounds.height, collider.bounds.width);\r\n if (Physics.disableMinimumSpeedForFastBody || updateDistance > minDimension / 2) {\r\n if (stats) {\r\n stats.physics.fastBodies++;\r\n }\r\n\r\n // start with the oldPos because the integration for actors has already happened\r\n // objects resting on a surface may be slightly penetrating in the current position\r\n const updateVec = body.globalPos.sub(body.oldPos);\r\n const centerPoint = collider.center;\r\n const furthestPoint = collider.getFurthestPoint(body.vel);\r\n const origin: Vector = furthestPoint.sub(updateVec);\r\n\r\n const ray: Ray = new Ray(origin, body.vel);\r\n\r\n // back the ray up by -2x surfaceEpsilon to account for fast moving objects starting on the surface\r\n ray.pos = ray.pos.add(ray.dir.scale(-2 * Physics.surfaceEpsilon));\r\n let minCollider: Collider;\r\n let minTranslate: Vector = new Vector(Infinity, Infinity);\r\n this._dynamicCollisionTree.rayCastQuery(ray, updateDistance + Physics.surfaceEpsilon * 2, (other: Collider) => {\r\n if (!this._pairExists(collider, other) && Pair.canCollide(collider, other)) {\r\n const hitPoint = other.rayCast(ray, updateDistance + Physics.surfaceEpsilon * 10);\r\n if (hitPoint) {\r\n const translate = hitPoint.sub(origin);\r\n if (translate.size < minTranslate.size) {\r\n minTranslate = translate;\r\n minCollider = other;\r\n }\r\n }\r\n }\r\n return false;\r\n });\r\n\r\n if (minCollider && Vector.isValid(minTranslate)) {\r\n const pair = new Pair(collider, minCollider);\r\n if (!this._pairs.has(pair.id)) {\r\n this._pairs.add(pair.id);\r\n this._collisionPairCache.push(pair);\r\n }\r\n // move the fast moving object to the other body\r\n // need to push into the surface by ex.Physics.surfaceEpsilon\r\n const shift = centerPoint.sub(furthestPoint);\r\n body.globalPos = origin\r\n .add(shift)\r\n .add(minTranslate)\r\n .add(ray.dir.scale(10 * Physics.surfaceEpsilon)); // needed to push the shape slightly into contact\r\n collider.update(body.transform.get());\r\n\r\n if (stats) {\r\n stats.physics.fastBodyCollisions++;\r\n }\r\n }\r\n }\r\n }\r\n }\r\n // return cache\r\n return this._collisionPairCache;\r\n }\r\n\r\n /**\r\n * Applies narrow phase on collision pairs to find actual area intersections\r\n * Adds actual colliding pairs to stats' Frame data\r\n */\r\n public narrowphase(pairs: Pair[], stats?: FrameStats): CollisionContact[] {\r\n let contacts: CollisionContact[] = [];\r\n for (let i = 0; i < pairs.length; i++) {\r\n const newContacts = pairs[i].collide();\r\n contacts = contacts.concat(newContacts);\r\n if (stats && newContacts.length > 0) {\r\n for (const c of newContacts) {\r\n stats.physics.contacts.set(c.id, c);\r\n }\r\n }\r\n }\r\n if (stats) {\r\n stats.physics.collisions += contacts.length;\r\n }\r\n return contacts;\r\n }\r\n\r\n /**\r\n * Update the dynamic tree positions\r\n */\r\n public update(targets: Collider[]): number {\r\n let updated = 0;\r\n const len = targets.length;\r\n\r\n for (let i = 0; i < len; i++) {\r\n if (this._dynamicCollisionTree.updateCollider(targets[i])) {\r\n updated++;\r\n }\r\n }\r\n return updated;\r\n }\r\n\r\n public debug(ex: ExcaliburGraphicsContext) {\r\n this._dynamicCollisionTree.debug(ex);\r\n }\r\n}\r\n","import { Color } from '../../Color';\r\nimport { CollisionContact } from '../Detection/CollisionContact';\r\nimport { BoundingBox } from '../BoundingBox';\r\nimport { Projection } from '../../Math/projection';\r\nimport { LineSegment } from '../../Math/line-segment';\r\nimport { Vector } from '../../Math/vector';\r\nimport { Ray } from '../../Math/ray';\r\nimport { Clonable } from '../../Interfaces/Clonable';\r\nimport { Entity } from '../../EntityComponentSystem';\r\nimport { createId, Id } from '../../Id';\r\nimport { ExcaliburGraphicsContext } from '../../Graphics/Context/ExcaliburGraphicsContext';\r\nimport { Transform } from '../../Math/transform';\r\nimport { EventEmitter } from '../../EventEmitter';\r\n\r\n/**\r\n * A collision collider specifies the geometry that can detect when other collision colliders intersect\r\n * for the purposes of colliding 2 objects in excalibur.\r\n */\r\nexport abstract class Collider implements Clonable {\r\n private static _ID = 0;\r\n public readonly id: Id<'collider'> = createId('collider', Collider._ID++);\r\n /**\r\n * Excalibur uses this to signal to the [[CollisionSystem]] this is part of a composite collider\r\n * @internal\r\n * @hidden\r\n */\r\n public __compositeColliderId: Id<'collider'> | null = null;\r\n public events = new EventEmitter();\r\n\r\n /**\r\n * Returns a boolean indicating whether this body collided with\r\n * or was in stationary contact with\r\n * the body of the other [[Collider]]\r\n */\r\n public touching(other: Collider): boolean {\r\n const contact = this.collide(other);\r\n\r\n if (contact) {\r\n return true;\r\n }\r\n\r\n return false;\r\n }\r\n\r\n public owner: Entity;\r\n\r\n /**\r\n * Pixel offset of the collision collider relative to the collider, by default (0, 0) meaning the collider is positioned\r\n * on top of the collider.\r\n */\r\n offset: Vector;\r\n\r\n /**\r\n * Position of the collision collider in world coordinates\r\n */\r\n abstract get worldPos(): Vector;\r\n\r\n /**\r\n * The center point of the collision collider, for example if the collider is a circle it would be the center.\r\n */\r\n abstract get center(): Vector;\r\n\r\n /**\r\n * Return the axis-aligned bounding box of the collision collider in world coordinates\r\n */\r\n abstract get bounds(): BoundingBox;\r\n\r\n /**\r\n * Return the axis-aligned bounding box of the collision collider in local coordinates\r\n */\r\n abstract get localBounds(): BoundingBox;\r\n\r\n /**\r\n * Return the axes of this particular collider\r\n */\r\n abstract get axes(): Vector[];\r\n /**\r\n * Find the furthest point on the convex hull of this particular collider in a certain direction.\r\n */\r\n abstract getFurthestPoint(direction: Vector): Vector;\r\n\r\n abstract getInertia(mass: number): number;\r\n\r\n // All new CollisionShape need to do the following\r\n // Create a new collision function in the CollisionJumpTable against all the primitives\r\n // Currently there are 3 primitive collision collider 3! = 6 jump functions\r\n abstract collide(collider: Collider): CollisionContact[];\r\n\r\n /**\r\n * Returns the closest line between the surfaces this collider and another\r\n * @param collider\r\n */\r\n abstract getClosestLineBetween(collider: Collider): LineSegment;\r\n\r\n /**\r\n * Return wether the collider contains a point inclusive to it's border\r\n */\r\n abstract contains(point: Vector): boolean;\r\n\r\n /**\r\n * Return the point on the border of the collision collider that intersects with a ray (if any).\r\n */\r\n abstract rayCast(ray: Ray, max?: number): Vector;\r\n\r\n /**\r\n * Create a projection of this collider along an axis. Think of this as casting a \"shadow\" along an axis\r\n */\r\n abstract project(axis: Vector): Projection;\r\n\r\n /**\r\n * Updates collider world space geometry\r\n */\r\n abstract update(transform: Transform): void;\r\n\r\n\r\n abstract debug(ex: ExcaliburGraphicsContext, color: Color): void;\r\n\r\n abstract clone(): Collider;\r\n}\r\n","import { Util } from '../..';\r\nimport { Pair } from '../Detection/Pair';\r\nimport { Color } from '../../Color';\r\nimport { ExcaliburGraphicsContext } from '../../Graphics/Context/ExcaliburGraphicsContext';\r\nimport { LineSegment } from '../../Math/line-segment';\r\nimport { Projection } from '../../Math/projection';\r\nimport { Ray } from '../../Math/ray';\r\nimport { Vector } from '../../Math/vector';\r\nimport { BoundingBox } from '../BoundingBox';\r\nimport { CollisionContact } from '../Detection/CollisionContact';\r\nimport { DynamicTree } from '../Detection/DynamicTree';\r\nimport { DynamicTreeCollisionProcessor } from '../Detection/DynamicTreeCollisionProcessor';\r\nimport { Collider } from './Collider';\r\nimport { Transform } from '../../Math/transform';\r\n\r\nexport class CompositeCollider extends Collider {\r\n private _transform: Transform;\r\n private _collisionProcessor = new DynamicTreeCollisionProcessor();\r\n private _dynamicAABBTree = new DynamicTree();\r\n private _colliders: Collider[] = [];\r\n\r\n constructor(colliders: Collider[]) {\r\n super();\r\n for (const c of colliders) {\r\n this.addCollider(c);\r\n }\r\n }\r\n\r\n clearColliders() {\r\n this._colliders = [];\r\n }\r\n\r\n addCollider(collider: Collider) {\r\n collider.events.pipe(this.events);\r\n collider.__compositeColliderId = this.id;\r\n this._colliders.push(collider);\r\n this._collisionProcessor.track(collider);\r\n this._dynamicAABBTree.trackCollider(collider);\r\n }\r\n\r\n removeCollider(collider: Collider) {\r\n collider.events.pipe(this.events);\r\n collider.__compositeColliderId = null;\r\n Util.removeItemFromArray(collider, this._colliders);\r\n this._collisionProcessor.untrack(collider);\r\n this._dynamicAABBTree.untrackCollider(collider);\r\n }\r\n\r\n getColliders(): Collider[] {\r\n return this._colliders;\r\n }\r\n\r\n get worldPos(): Vector {\r\n // TODO transform component world pos\r\n return this._transform?.pos ?? Vector.Zero;\r\n }\r\n\r\n get center(): Vector {\r\n return this._transform?.pos ?? Vector.Zero;\r\n }\r\n\r\n get bounds(): BoundingBox {\r\n // TODO cache this\r\n const colliders = this.getColliders();\r\n const results = colliders.reduce(\r\n (acc, collider) => acc.combine(collider.bounds),\r\n colliders[0]?.bounds ?? new BoundingBox().translate(this.worldPos)\r\n );\r\n\r\n return results;\r\n }\r\n\r\n get localBounds(): BoundingBox {\r\n // TODO cache this\r\n const colliders = this.getColliders();\r\n const results = colliders.reduce((acc, collider) => acc.combine(collider.localBounds), colliders[0]?.localBounds ?? new BoundingBox());\r\n\r\n return results;\r\n }\r\n\r\n get axes(): Vector[] {\r\n // TODO cache this\r\n const colliders = this.getColliders();\r\n let axes: Vector[] = [];\r\n for (const collider of colliders) {\r\n axes = axes.concat(collider.axes);\r\n }\r\n return axes;\r\n }\r\n\r\n getFurthestPoint(direction: Vector): Vector {\r\n const colliders = this.getColliders();\r\n const furthestPoints: Vector[] = [];\r\n for (const collider of colliders) {\r\n furthestPoints.push(collider.getFurthestPoint(direction));\r\n }\r\n // Pick best point from all colliders\r\n let bestPoint = furthestPoints[0];\r\n let maxDistance = -Number.MAX_VALUE;\r\n for (const point of furthestPoints) {\r\n const distance = point.dot(direction);\r\n if (distance > maxDistance) {\r\n bestPoint = point;\r\n maxDistance = distance;\r\n }\r\n }\r\n return bestPoint;\r\n }\r\n\r\n getInertia(mass: number): number {\r\n const colliders = this.getColliders();\r\n let totalInertia = 0;\r\n for (const collider of colliders) {\r\n totalInertia += collider.getInertia(mass);\r\n }\r\n return totalInertia;\r\n }\r\n\r\n collide(other: Collider): CollisionContact[] {\r\n let otherColliders = [other];\r\n if (other instanceof CompositeCollider) {\r\n otherColliders = other.getColliders();\r\n }\r\n\r\n const pairs: Pair[] = [];\r\n for (const c of otherColliders) {\r\n this._dynamicAABBTree.query(c, (potentialCollider: Collider) => {\r\n pairs.push(new Pair(c, potentialCollider));\r\n return false;\r\n });\r\n }\r\n\r\n let contacts: CollisionContact[] = [];\r\n for (const p of pairs) {\r\n contacts = contacts.concat(p.collide());\r\n }\r\n return contacts;\r\n }\r\n\r\n getClosestLineBetween(other: Collider): LineSegment {\r\n const colliders = this.getColliders();\r\n const lines: LineSegment[] = [];\r\n if (other instanceof CompositeCollider) {\r\n const otherColliders = other.getColliders();\r\n for (const colliderA of colliders) {\r\n for (const colliderB of otherColliders) {\r\n const maybeLine = colliderA.getClosestLineBetween(colliderB);\r\n if (maybeLine) {\r\n lines.push(maybeLine);\r\n }\r\n }\r\n }\r\n } else {\r\n for (const collider of colliders) {\r\n const maybeLine = other.getClosestLineBetween(collider);\r\n if (maybeLine) {\r\n lines.push(maybeLine);\r\n }\r\n }\r\n }\r\n\r\n if (lines.length) {\r\n let minLength = lines[0].getLength();\r\n let minLine = lines[0];\r\n for (const line of lines) {\r\n const length = line.getLength();\r\n if (length < minLength) {\r\n minLength = length;\r\n minLine = line;\r\n }\r\n }\r\n return minLine;\r\n }\r\n return null;\r\n }\r\n contains(point: Vector): boolean {\r\n const colliders = this.getColliders();\r\n for (const collider of colliders) {\r\n if (collider.contains(point)) {\r\n return true;\r\n }\r\n }\r\n return false;\r\n }\r\n rayCast(ray: Ray, max?: number): Vector {\r\n const colliders = this.getColliders();\r\n const points: Vector[] = [];\r\n for (const collider of colliders) {\r\n const vec = collider.rayCast(ray, max);\r\n if (vec) {\r\n points.push(vec);\r\n }\r\n }\r\n if (points.length) {\r\n let minPoint = points[0];\r\n let minDistance = minPoint.dot(ray.dir);\r\n for (const point of points) {\r\n const distance = ray.dir.dot(point);\r\n if (distance < minDistance) {\r\n minPoint = point;\r\n minDistance = distance;\r\n }\r\n }\r\n return minPoint;\r\n }\r\n return null;\r\n }\r\n project(axis: Vector): Projection {\r\n const colliders = this.getColliders();\r\n const projs: Projection[] = [];\r\n for (const collider of colliders) {\r\n const proj = collider.project(axis);\r\n if (proj) {\r\n projs.push(proj);\r\n }\r\n }\r\n // Merge all proj's on the same axis\r\n if (projs.length) {\r\n const newProjection = new Projection(projs[0].min, projs[0].max);\r\n for (const proj of projs) {\r\n newProjection.min = Math.min(proj.min, newProjection.min);\r\n newProjection.max = Math.max(proj.max, newProjection.max);\r\n }\r\n return newProjection;\r\n }\r\n return null;\r\n }\r\n\r\n update(transform: Transform): void {\r\n if (transform) {\r\n const colliders = this.getColliders();\r\n for (const collider of colliders) {\r\n collider.owner = this.owner;\r\n collider.update(transform);\r\n }\r\n }\r\n }\r\n\r\n public debug(ex: ExcaliburGraphicsContext, color: Color) {\r\n const colliders = this.getColliders();\r\n for (const collider of colliders) {\r\n collider.debug(ex, color);\r\n }\r\n }\r\n\r\n clone(): Collider {\r\n return new CompositeCollider(this._colliders.map((c) => c.clone()));\r\n }\r\n}\r\n","import { Vector } from './vector';\r\n\r\n/**\r\n * A 2D line segment\r\n */\r\n\r\nexport class LineSegment {\r\n\r\n /**\r\n * @param begin The starting point of the line segment\r\n * @param end The ending point of the line segment\r\n */\r\n constructor(public readonly begin: Vector, public readonly end: Vector) {}\r\n\r\n /**\r\n * Gets the raw slope (m) of the line. Will return (+/-)Infinity for vertical lines.\r\n */\r\n public get slope() {\r\n return (this.end.y - this.begin.y) / (this.end.x - this.begin.x);\r\n }\r\n\r\n /**\r\n * Gets the Y-intercept (b) of the line. Will return (+/-)Infinity if there is no intercept.\r\n */\r\n public get intercept() {\r\n return this.begin.y - this.slope * this.begin.x;\r\n }\r\n\r\n private _normal: Vector;\r\n /**\r\n * Gets the normal of the line\r\n */\r\n public normal(): Vector {\r\n if (this._normal) {\r\n return this._normal;\r\n }\r\n return this._normal = this.end.sub(this.begin).normal();\r\n }\r\n\r\n private _dir: Vector;\r\n public dir(): Vector {\r\n if (this._dir) {\r\n return this._dir;\r\n }\r\n return this._dir = this.end.sub(this.begin);\r\n }\r\n\r\n public getPoints(): Vector[] {\r\n return [this.begin, this.end];\r\n }\r\n\r\n private _slope: Vector;\r\n /**\r\n * Returns the slope of the line in the form of a vector of length 1\r\n */\r\n public getSlope(): Vector {\r\n if (this._slope) {\r\n return this._slope;\r\n }\r\n const begin = this.begin;\r\n const end = this.end;\r\n const distance = begin.distance(end);\r\n return this._slope = end.sub(begin).scale(1 / distance);\r\n }\r\n\r\n /**\r\n * Returns the edge of the line as vector, the length of the vector is the length of the edge\r\n */\r\n public getEdge(): Vector {\r\n const begin = this.begin;\r\n const end = this.end;\r\n return end.sub(begin);\r\n }\r\n\r\n private _length: number;\r\n /**\r\n * Returns the length of the line segment in pixels\r\n */\r\n public getLength(): number {\r\n if (this._length) {\r\n return this._length;\r\n }\r\n const begin = this.begin;\r\n const end = this.end;\r\n const distance = begin.distance(end);\r\n return this._length = distance;\r\n }\r\n\r\n /**\r\n * Returns the midpoint of the edge\r\n */\r\n public get midpoint(): Vector {\r\n return this.begin.add(this.end).scale(0.5);\r\n }\r\n\r\n /**\r\n * Flips the direction of the line segment\r\n */\r\n public flip(): LineSegment {\r\n return new LineSegment(this.end, this.begin);\r\n }\r\n\r\n /**\r\n * Tests if a given point is below the line, points in the normal direction above the line are considered above.\r\n * @param point\r\n */\r\n public below(point: Vector): boolean {\r\n const above2 = (this.end.x - this.begin.x) * (point.y - this.begin.y) - (this.end.y - this.begin.y) * (point.x - this.begin.x);\r\n return above2 >= 0;\r\n }\r\n\r\n /**\r\n * Returns the clip point\r\n * @param sideVector Vector that traces the line\r\n * @param length Length to clip along side\r\n */\r\n public clip(sideVector: Vector, length: number): LineSegment {\r\n let dir = sideVector;\r\n dir = dir.normalize();\r\n\r\n const near = dir.dot(this.begin) - length;\r\n const far = dir.dot(this.end) - length;\r\n\r\n const results = [];\r\n if (near <= 0) {\r\n results.push(this.begin);\r\n }\r\n if (far <= 0) {\r\n results.push(this.end);\r\n }\r\n\r\n if (near * far < 0) {\r\n const clipTime = near / (near - far);\r\n results.push(this.begin.add(this.end.sub(this.begin).scale(clipTime)));\r\n }\r\n if (results.length !== 2) {\r\n return null;\r\n }\r\n\r\n return new LineSegment(results[0], results[1]);\r\n }\r\n\r\n /**\r\n * Find the perpendicular distance from the line to a point\r\n * https://en.wikipedia.org/wiki/Distance_from_a_point_to_a_line\r\n * @param point\r\n */\r\n public distanceToPoint(point: Vector, signed: boolean = false) {\r\n const x0 = point.x;\r\n const y0 = point.y;\r\n\r\n const l = this.getLength();\r\n\r\n const dy = this.end.y - this.begin.y;\r\n const dx = this.end.x - this.begin.x;\r\n const distance = (dy * x0 - dx * y0 + this.end.x * this.begin.y - this.end.y * this.begin.x) / l;\r\n return signed ? distance : Math.abs(distance);\r\n }\r\n\r\n /**\r\n * Find the perpendicular line from the line to a point\r\n * https://en.wikipedia.org/wiki/Distance_from_a_point_to_a_line\r\n * (a - p) - ((a - p) * n)n\r\n * a is a point on the line\r\n * p is the arbitrary point above the line\r\n * n is a unit vector in direction of the line\r\n * @param point\r\n */\r\n public findVectorToPoint(point: Vector): Vector {\r\n const aMinusP = this.begin.sub(point);\r\n const n = this.getSlope();\r\n\r\n return aMinusP.sub(n.scale(aMinusP.dot(n)));\r\n }\r\n\r\n /**\r\n * Finds a point on the line given only an X or a Y value. Given an X value, the function returns\r\n * a new point with the calculated Y value and vice-versa.\r\n *\r\n * @param x The known X value of the target point\r\n * @param y The known Y value of the target point\r\n * @returns A new point with the other calculated axis value\r\n */\r\n public findPoint(x: number = null, y: number = null): Vector {\r\n const m = this.slope;\r\n const b = this.intercept;\r\n\r\n if (x !== null) {\r\n return new Vector(x, m * x + b);\r\n } else if (y !== null) {\r\n return new Vector((y - b) / m, y);\r\n } else {\r\n throw new Error('You must provide an X or a Y value');\r\n }\r\n }\r\n\r\n /**\r\n * Whether or not the given point lies on this line. This method is precise by default\r\n * meaning the point must lie exactly on the line. Adjust threshold to\r\n * loosen the strictness of the check for floating-point calculations.\r\n */\r\n public hasPoint(x: number, y: number, threshold?: number): boolean;\r\n\r\n /**\r\n * Whether or not the given point lies on this line. This method is precise by default\r\n * meaning the point must lie exactly on the line. Adjust threshold to\r\n * loosen the strictness of the check for floating-point calculations.\r\n */\r\n public hasPoint(v: Vector, threshold?: number): boolean;\r\n\r\n /**\r\n * @see http://stackoverflow.com/a/11908158/109458\r\n */\r\n public hasPoint(): boolean {\r\n let currPoint: Vector;\r\n let threshold = 0;\r\n\r\n if (typeof arguments[0] === 'number' && typeof arguments[1] === 'number') {\r\n currPoint = new Vector(arguments[0], arguments[1]);\r\n threshold = arguments[2] || 0;\r\n } else if (arguments[0] instanceof Vector) {\r\n currPoint = arguments[0];\r\n threshold = arguments[1] || 0;\r\n } else {\r\n throw 'Could not determine the arguments for Vector.hasPoint';\r\n }\r\n\r\n const dxc = currPoint.x - this.begin.x;\r\n const dyc = currPoint.y - this.begin.y;\r\n\r\n const dx1 = this.end.x - this.begin.x;\r\n const dy1 = this.end.y - this.begin.y;\r\n\r\n const cross = dxc * dy1 - dyc * dx1;\r\n\r\n // check whether point lines on the line\r\n if (Math.abs(cross) > threshold) {\r\n return false;\r\n }\r\n\r\n // check whether point lies in-between start and end\r\n if (Math.abs(dx1) >= Math.abs(dy1)) {\r\n return dx1 > 0 ? this.begin.x <= currPoint.x && currPoint.x <= this.end.x : this.end.x <= currPoint.x && currPoint.x <= this.begin.x;\r\n } else {\r\n return dy1 > 0 ? this.begin.y <= currPoint.y && currPoint.y <= this.end.y : this.end.y <= currPoint.y && currPoint.y <= this.begin.y;\r\n }\r\n }\r\n}\r\n","import { LineSegment } from '../../Math/line-segment';\r\nimport { Vector } from '../../Math/vector';\r\nimport { Ray } from '../../Math/ray';\r\nimport { PolygonCollider } from './PolygonCollider';\r\nimport { EdgeCollider } from './EdgeCollider';\r\nimport { CircleCollider } from './CircleCollider';\r\n\r\n/**\r\n * Finds the closes line between 2 line segments, were the magnitude of u, v are the lengths of each segment\r\n * L1 = P(s) = p0 + s * u, where s is time and p0 is the start of the line\r\n * L2 = Q(t) = q0 + t * v, where t is time and q0 is the start of the line\r\n * @param p0 Point where L1 begins\r\n * @param u Direction and length of L1\r\n * @param q0 Point were L2 begins\r\n * @param v Direction and length of L2\r\n */\r\nexport function ClosestLine(p0: Vector, u: Vector, q0: Vector, v: Vector) {\r\n // Distance between 2 lines http://geomalgorithms.com/a07-_distance.html\r\n\r\n // w(s, t) = P(s) - Q(t)\r\n // The w(s, t) that has the minimum distance we will say is w(sClosest, tClosest) = wClosest\r\n //\r\n // wClosest is the vector that is uniquely perpendicular to the 2 line directions u & v.\r\n // wClosest = w0 + sClosest * u - tClosest * v, where w0 is p0 - q0\r\n //\r\n // The closest point between 2 lines then satisfies this pair of equations\r\n // 1: u * wClosest = 0\r\n // 2: v * wClosest = 0\r\n //\r\n // Substituting wClosest into the equations we get\r\n //\r\n // 1: (u * u) * sClosest - (u * v) tClosest = -u * w0\r\n // 2: (v * u) * sClosest - (v * v) tClosest = -v * w0\r\n\r\n // simplify w0\r\n const w0 = p0.sub(q0);\r\n\r\n // simplify (u * u);\r\n const a = u.dot(u);\r\n // simplify (u * v);\r\n const b = u.dot(v);\r\n // simplify (v * v)\r\n const c = v.dot(v);\r\n // simplify (u * w0)\r\n const d = u.dot(w0);\r\n // simplify (v * w0)\r\n const e = v.dot(w0);\r\n\r\n // denominator ac - b^2\r\n const denom = a * c - b * b;\r\n let sDenom = denom;\r\n let tDenom = denom;\r\n // if denom is 0 they are parallel, use any point from either as the start in this case p0\r\n if (denom === 0 || denom <= 0.01) {\r\n const tClosestParallel = d / b;\r\n return new LineSegment(p0, q0.add(v.scale(tClosestParallel)));\r\n }\r\n\r\n // Solve for sClosest for infinite line\r\n let sClosest = b * e - c * d; // / denom;\r\n\r\n // Solve for tClosest for infinite line\r\n let tClosest = a * e - b * d; // / denom;\r\n\r\n // Solve for segments candidate edges, if sClosest and tClosest are outside their segments\r\n if (sClosest < 0) {\r\n sClosest = 0;\r\n tClosest = e;\r\n tDenom = c;\r\n } else if (sClosest > sDenom) {\r\n sClosest = sDenom;\r\n tClosest = e + b;\r\n tDenom = c;\r\n }\r\n\r\n if (tClosest < 0) {\r\n tClosest = 0;\r\n if (-d < 0) {\r\n sClosest = 0;\r\n } else if (-d > a) {\r\n sClosest = sDenom;\r\n } else {\r\n sClosest = -d;\r\n sDenom = a;\r\n }\r\n } else if (tClosest > tDenom) {\r\n tClosest = tDenom;\r\n if (-d + b < 0) {\r\n sClosest = 0;\r\n } else if (-d + b > a) {\r\n sClosest = sDenom;\r\n } else {\r\n sClosest = -d + b;\r\n sDenom = a;\r\n }\r\n }\r\n sClosest = Math.abs(sClosest) < 0.001 ? 0 : sClosest / sDenom;\r\n tClosest = Math.abs(tClosest) < 0.001 ? 0 : tClosest / tDenom;\r\n\r\n return new LineSegment(p0.add(u.scale(sClosest)), q0.add(v.scale(tClosest)));\r\n}\r\n\r\nexport const ClosestLineJumpTable = {\r\n PolygonPolygonClosestLine(polygonA: PolygonCollider, polygonB: PolygonCollider) {\r\n // Find the 2 closest faces on each polygon\r\n const otherWorldPos = polygonB.worldPos;\r\n const otherDirection = otherWorldPos.sub(polygonA.worldPos);\r\n const thisDirection = otherDirection.negate();\r\n\r\n const rayTowardsOther = new Ray(polygonA.worldPos, otherDirection);\r\n const rayTowardsThis = new Ray(otherWorldPos, thisDirection);\r\n\r\n const thisPoint = polygonA.rayCast(rayTowardsOther).add(rayTowardsOther.dir.scale(0.1));\r\n const otherPoint = polygonB.rayCast(rayTowardsThis).add(rayTowardsThis.dir.scale(0.1));\r\n\r\n const thisFace = polygonA.getClosestFace(thisPoint);\r\n const otherFace = polygonB.getClosestFace(otherPoint);\r\n\r\n // L1 = P(s) = p0 + s * u, where s is time and p0 is the start of the line\r\n const p0 = thisFace.face.begin;\r\n const u = thisFace.face.getEdge();\r\n\r\n // L2 = Q(t) = q0 + t * v, where t is time and q0 is the start of the line\r\n const q0 = otherFace.face.begin;\r\n const v = otherFace.face.getEdge();\r\n\r\n return ClosestLine(p0, u, q0, v);\r\n },\r\n\r\n PolygonEdgeClosestLine(polygon: PolygonCollider, edge: EdgeCollider) {\r\n // Find the 2 closest faces on each polygon\r\n const otherWorldPos = edge.worldPos;\r\n const otherDirection = otherWorldPos.sub(polygon.worldPos);\r\n\r\n const rayTowardsOther = new Ray(polygon.worldPos, otherDirection);\r\n\r\n const thisPoint = polygon.rayCast(rayTowardsOther).add(rayTowardsOther.dir.scale(0.1));\r\n\r\n const thisFace = polygon.getClosestFace(thisPoint);\r\n\r\n // L1 = P(s) = p0 + s * u, where s is time and p0 is the start of the line\r\n const p0 = thisFace.face.begin;\r\n const u = thisFace.face.getEdge();\r\n\r\n // L2 = Q(t) = q0 + t * v, where t is time and q0 is the start of the line\r\n const edgeLine = edge.asLine();\r\n const edgeStart = edgeLine.begin;\r\n const edgeVector = edgeLine.getEdge();\r\n const q0 = edgeStart;\r\n const v = edgeVector;\r\n\r\n return ClosestLine(p0, u, q0, v);\r\n },\r\n\r\n PolygonCircleClosestLine(polygon: PolygonCollider, circle: CircleCollider) {\r\n // https://math.stackexchange.com/questions/1919177/how-to-find-point-on-line-closest-to-sphere\r\n // Find the 2 closest faces on each polygon\r\n const otherWorldPos = circle.worldPos;\r\n const otherDirection = otherWorldPos.sub(polygon.worldPos);\r\n\r\n const rayTowardsOther = new Ray(polygon.worldPos, otherDirection.normalize());\r\n\r\n const thisPoint = polygon.rayCast(rayTowardsOther).add(rayTowardsOther.dir.scale(0.1));\r\n\r\n const thisFace = polygon.getClosestFace(thisPoint);\r\n\r\n // L1 = P(s) = p0 + s * u, where s is time and p0 is the start of the line\r\n const p0 = thisFace.face.begin;\r\n const u = thisFace.face.getEdge();\r\n\r\n // Time of minimum distance\r\n let t = (u.x * (otherWorldPos.x - p0.x) + u.y * (otherWorldPos.y - p0.y)) / (u.x * u.x + u.y * u.y);\r\n\r\n // If time of minimum is past the edge clamp\r\n if (t > 1) {\r\n t = 1;\r\n } else if (t < 0) {\r\n t = 0;\r\n }\r\n\r\n // Minimum distance\r\n const d = Math.sqrt(Math.pow(p0.x + u.x * t - otherWorldPos.x, 2) + Math.pow(p0.y + u.y * t - otherWorldPos.y, 2)) - circle.radius;\r\n\r\n const circlex = ((p0.x + u.x * t - otherWorldPos.x) * circle.radius) / (circle.radius + d);\r\n const circley = ((p0.y + u.y * t - otherWorldPos.y) * circle.radius) / (circle.radius + d);\r\n return new LineSegment(u.scale(t).add(p0), new Vector(otherWorldPos.x + circlex, otherWorldPos.y + circley));\r\n },\r\n\r\n CircleCircleClosestLine(circleA: CircleCollider, circleB: CircleCollider) {\r\n // Find the 2 closest faces on each polygon\r\n const otherWorldPos = circleB.worldPos;\r\n const otherDirection = otherWorldPos.sub(circleA.worldPos);\r\n\r\n const thisWorldPos = circleA.worldPos;\r\n const thisDirection = thisWorldPos.sub(circleB.worldPos);\r\n\r\n const rayTowardsOther = new Ray(circleA.worldPos, otherDirection);\r\n const rayTowardsThis = new Ray(circleB.worldPos, thisDirection);\r\n\r\n const thisPoint = circleA.rayCast(rayTowardsOther);\r\n const otherPoint = circleB.rayCast(rayTowardsThis);\r\n\r\n return new LineSegment(thisPoint, otherPoint);\r\n },\r\n\r\n CircleEdgeClosestLine(circle: CircleCollider, edge: EdgeCollider) {\r\n // https://math.stackexchange.com/questions/1919177/how-to-find-point-on-line-closest-to-sphere\r\n const circleWorlPos = circle.worldPos;\r\n\r\n // L1 = P(s) = p0 + s * u, where s is time and p0 is the start of the line\r\n const edgeLine = edge.asLine();\r\n const edgeStart = edgeLine.begin;\r\n const edgeVector = edgeLine.getEdge();\r\n const p0 = edgeStart;\r\n const u = edgeVector;\r\n\r\n // Time of minimum distance\r\n let t = (u.x * (circleWorlPos.x - p0.x) + u.y * (circleWorlPos.y - p0.y)) / (u.x * u.x + u.y * u.y);\r\n\r\n // If time of minimum is past the edge clamp to edge\r\n if (t > 1) {\r\n t = 1;\r\n } else if (t < 0) {\r\n t = 0;\r\n }\r\n\r\n // Minimum distance\r\n const d = Math.sqrt(Math.pow(p0.x + u.x * t - circleWorlPos.x, 2) + Math.pow(p0.y + u.y * t - circleWorlPos.y, 2)) - circle.radius;\r\n\r\n const circlex = ((p0.x + u.x * t - circleWorlPos.x) * circle.radius) / (circle.radius + d);\r\n const circley = ((p0.y + u.y * t - circleWorlPos.y) * circle.radius) / (circle.radius + d);\r\n return new LineSegment(u.scale(t).add(p0), new Vector(circleWorlPos.x + circlex, circleWorlPos.y + circley));\r\n },\r\n\r\n EdgeEdgeClosestLine(edgeA: EdgeCollider, edgeB: EdgeCollider) {\r\n // L1 = P(s) = p0 + s * u, where s is time and p0 is the start of the line\r\n const edgeLineA = edgeA.asLine();\r\n const edgeStartA = edgeLineA.begin;\r\n const edgeVectorA = edgeLineA.getEdge();\r\n const p0 = edgeStartA;\r\n const u = edgeVectorA;\r\n\r\n // L2 = Q(t) = q0 + t * v, where t is time and q0 is the start of the line\r\n const edgeLineB = edgeB.asLine();\r\n const edgeStartB = edgeLineB.begin;\r\n const edgeVectorB = edgeLineB.getEdge();\r\n const q0 = edgeStartB;\r\n const v = edgeVectorB;\r\n\r\n return ClosestLine(p0, u, q0, v);\r\n }\r\n};\r\n","import { BoundingBox } from '../BoundingBox';\r\nimport { CollisionJumpTable } from './CollisionJumpTable';\r\nimport { CollisionContact } from '../Detection/CollisionContact';\r\nimport { PolygonCollider } from './PolygonCollider';\r\nimport { EdgeCollider } from './EdgeCollider';\r\n\r\nimport { Projection } from '../../Math/projection';\r\nimport { LineSegment } from '../../Math/line-segment';\r\nimport { Vector } from '../../Math/vector';\r\nimport { Ray } from '../../Math/ray';\r\nimport { Color } from '../../Color';\r\nimport { Collider } from './Collider';\r\n\r\nimport { ClosestLineJumpTable } from './ClosestLineJumpTable';\r\nimport { ExcaliburGraphicsContext } from '../../Graphics/Context/ExcaliburGraphicsContext';\r\nimport { Transform } from '../../Math/transform';\r\nimport { AffineMatrix } from '../../Math/affine-matrix';\r\n\r\nexport interface CircleColliderOptions {\r\n /**\r\n * Optional pixel offset to shift the circle relative to the collider, by default (0, 0).\r\n */\r\n offset?: Vector;\r\n /**\r\n * Required radius of the circle\r\n */\r\n radius: number;\r\n}\r\n\r\n/**\r\n * This is a circle collider for the excalibur rigid body physics simulation\r\n */\r\nexport class CircleCollider extends Collider {\r\n /**\r\n * Position of the circle relative to the collider, by default (0, 0).\r\n */\r\n public offset: Vector = Vector.Zero;\r\n\r\n private _globalMatrix: AffineMatrix = AffineMatrix.identity();\r\n\r\n public get worldPos(): Vector {\r\n return this._globalMatrix.getPosition();\r\n }\r\n\r\n private _naturalRadius: number;\r\n /**\r\n * Get the radius of the circle\r\n */\r\n public get radius(): number {\r\n const tx = this._transform;\r\n const scale = tx?.globalScale ?? Vector.One;\r\n // This is a trade off, the alternative is retooling circles to support ellipse collisions\r\n return this._naturalRadius * Math.min(scale.x, scale.y);\r\n }\r\n\r\n /**\r\n * Set the radius of the circle\r\n */\r\n public set radius(val: number) {\r\n const tx = this._transform;\r\n const scale = tx?.globalScale ?? Vector.One;\r\n // This is a trade off, the alternative is retooling circles to support ellipse collisions\r\n this._naturalRadius = val / Math.min(scale.x, scale.y);\r\n }\r\n\r\n private _transform: Transform;\r\n\r\n constructor(options: CircleColliderOptions) {\r\n super();\r\n this.offset = options.offset || Vector.Zero;\r\n this.radius = options.radius || 0;\r\n this._globalMatrix.translate(this.offset.x, this.offset.y);\r\n }\r\n\r\n /**\r\n * Returns a clone of this shape, not associated with any collider\r\n */\r\n public clone(): CircleCollider {\r\n return new CircleCollider({\r\n offset: this.offset.clone(),\r\n radius: this.radius\r\n });\r\n }\r\n\r\n /**\r\n * Get the center of the collider in world coordinates\r\n */\r\n public get center(): Vector {\r\n return this._globalMatrix.getPosition();\r\n }\r\n\r\n /**\r\n * Tests if a point is contained in this collider\r\n */\r\n public contains(point: Vector): boolean {\r\n const pos = this._transform?.pos ?? this.offset;\r\n const distance = pos.distance(point);\r\n if (distance <= this.radius) {\r\n return true;\r\n }\r\n return false;\r\n }\r\n\r\n /**\r\n * Casts a ray at the Circle collider and returns the nearest point of collision\r\n * @param ray\r\n */\r\n public rayCast(ray: Ray, max: number = Infinity): Vector {\r\n //https://en.wikipedia.org/wiki/Line%E2%80%93sphere_intersection\r\n const c = this.center;\r\n const dir = ray.dir;\r\n const orig = ray.pos;\r\n\r\n const discriminant = Math.sqrt(Math.pow(dir.dot(orig.sub(c)), 2) - Math.pow(orig.sub(c).distance(), 2) + Math.pow(this.radius, 2));\r\n\r\n if (discriminant < 0) {\r\n // no intersection\r\n return null;\r\n } else {\r\n let toi = 0;\r\n if (discriminant === 0) {\r\n toi = -dir.dot(orig.sub(c));\r\n if (toi > 0 && toi < max) {\r\n return ray.getPoint(toi);\r\n }\r\n return null;\r\n } else {\r\n const toi1 = -dir.dot(orig.sub(c)) + discriminant;\r\n const toi2 = -dir.dot(orig.sub(c)) - discriminant;\r\n\r\n const positiveToi: number[] = [];\r\n if (toi1 >= 0) {\r\n positiveToi.push(toi1);\r\n }\r\n\r\n if (toi2 >= 0) {\r\n positiveToi.push(toi2);\r\n }\r\n\r\n const mintoi = Math.min(...positiveToi);\r\n if (mintoi <= max) {\r\n return ray.getPoint(mintoi);\r\n }\r\n return null;\r\n }\r\n }\r\n }\r\n\r\n public getClosestLineBetween(shape: Collider): LineSegment {\r\n if (shape instanceof CircleCollider) {\r\n return ClosestLineJumpTable.CircleCircleClosestLine(this, shape);\r\n } else if (shape instanceof PolygonCollider) {\r\n return ClosestLineJumpTable.PolygonCircleClosestLine(shape, this).flip();\r\n } else if (shape instanceof EdgeCollider) {\r\n return ClosestLineJumpTable.CircleEdgeClosestLine(this, shape).flip();\r\n } else {\r\n throw new Error(`Polygon could not collide with unknown CollisionShape ${typeof shape}`);\r\n }\r\n }\r\n\r\n /**\r\n * @inheritdoc\r\n */\r\n public collide(collider: Collider): CollisionContact[] {\r\n if (collider instanceof CircleCollider) {\r\n return CollisionJumpTable.CollideCircleCircle(this, collider);\r\n } else if (collider instanceof PolygonCollider) {\r\n return CollisionJumpTable.CollideCirclePolygon(this, collider);\r\n } else if (collider instanceof EdgeCollider) {\r\n return CollisionJumpTable.CollideCircleEdge(this, collider);\r\n } else {\r\n throw new Error(`Circle could not collide with unknown CollisionShape ${typeof collider}`);\r\n }\r\n }\r\n\r\n /**\r\n * Find the point on the collider furthest in the direction specified\r\n */\r\n public getFurthestPoint(direction: Vector): Vector {\r\n return this.center.add(direction.normalize().scale(this.radius));\r\n }\r\n\r\n /**\r\n * Find the local point on the shape in the direction specified\r\n * @param direction\r\n */\r\n public getFurthestLocalPoint(direction: Vector): Vector {\r\n const dir = direction.normalize();\r\n return dir.scale(this.radius);\r\n }\r\n\r\n /**\r\n * Get the axis aligned bounding box for the circle collider in world coordinates\r\n */\r\n public get bounds(): BoundingBox {\r\n const tx = this._transform;\r\n const scale = tx?.globalScale ?? Vector.One;\r\n const rotation = tx?.globalRotation ?? 0;\r\n const pos = (tx?.globalPos ?? Vector.Zero);\r\n return new BoundingBox(\r\n this.offset.x - this._naturalRadius,\r\n this.offset.y - this._naturalRadius,\r\n this.offset.x + this._naturalRadius,\r\n this.offset.y + this._naturalRadius\r\n ).rotate(rotation).scale(scale).translate(pos);\r\n }\r\n\r\n /**\r\n * Get the axis aligned bounding box for the circle collider in local coordinates\r\n */\r\n public get localBounds(): BoundingBox {\r\n return new BoundingBox(\r\n this.offset.x - this._naturalRadius,\r\n this.offset.y - this._naturalRadius,\r\n this.offset.x + this._naturalRadius,\r\n this.offset.y + this._naturalRadius\r\n );\r\n }\r\n\r\n /**\r\n * Get axis not implemented on circles, since there are infinite axis in a circle\r\n */\r\n public get axes(): Vector[] {\r\n return [];\r\n }\r\n\r\n /**\r\n * Returns the moment of inertia of a circle given it's mass\r\n * https://en.wikipedia.org/wiki/List_of_moments_of_inertia\r\n */\r\n public getInertia(mass: number): number {\r\n return (mass * this.radius * this.radius) / 2;\r\n }\r\n\r\n /* istanbul ignore next */\r\n public update(transform: Transform): void {\r\n this._transform = transform;\r\n const globalMat = transform.matrix ?? this._globalMatrix;\r\n globalMat.clone(this._globalMatrix);\r\n this._globalMatrix.translate(this.offset.x, this.offset.y);\r\n }\r\n\r\n /**\r\n * Project the circle along a specified axis\r\n */\r\n public project(axis: Vector): Projection {\r\n const scalars = [];\r\n const point = this.center;\r\n const dotProduct = point.dot(axis);\r\n scalars.push(dotProduct);\r\n scalars.push(dotProduct + this.radius);\r\n scalars.push(dotProduct - this.radius);\r\n return new Projection(Math.min.apply(Math, scalars), Math.max.apply(Math, scalars));\r\n }\r\n\r\n public debug(ex: ExcaliburGraphicsContext, color: Color) {\r\n const tx = this._transform;\r\n const scale = tx?.globalScale ?? Vector.One;\r\n const rotation = tx?.globalRotation ?? 0;\r\n const pos = (tx?.globalPos ?? Vector.Zero);\r\n ex.save();\r\n ex.translate(pos.x, pos.y);\r\n ex.rotate(rotation);\r\n ex.scale(scale.x, scale.y);\r\n ex.drawCircle((this.offset ?? Vector.Zero), this._naturalRadius, Color.Transparent, color, 2);\r\n ex.restore();\r\n }\r\n}\r\n","import { Vector } from '../../Math/vector';\r\nimport { Physics } from '../Physics';\r\nimport { Collider } from '../Colliders/Collider';\r\nimport { CollisionType } from '../CollisionType';\r\nimport { Pair } from './Pair';\r\nimport { SeparationInfo } from '../Colliders/SeparatingAxis';\r\nimport { BodyComponent } from '../BodyComponent';\r\n\r\n/**\r\n * Collision contacts are used internally by Excalibur to resolve collision between colliders. This\r\n * Pair prevents collisions from being evaluated more than one time\r\n */\r\nexport class CollisionContact {\r\n private _canceled = false;\r\n\r\n /**\r\n * Currently the ids between colliders\r\n */\r\n readonly id: string;\r\n\r\n /**\r\n * The first collider in the collision\r\n */\r\n colliderA: Collider;\r\n\r\n /**\r\n * The second collider in the collision\r\n */\r\n colliderB: Collider;\r\n\r\n /**\r\n * The minimum translation vector to resolve overlap, pointing away from colliderA\r\n */\r\n mtv: Vector;\r\n\r\n /**\r\n * World space contact points between colliderA and colliderB\r\n */\r\n points: Vector[];\r\n\r\n /**\r\n * Local space contact points between colliderA and colliderB\r\n */\r\n localPoints: Vector[];\r\n\r\n /**\r\n * The collision normal, pointing away from colliderA\r\n */\r\n normal: Vector;\r\n\r\n /**\r\n * The collision tangent\r\n */\r\n tangent: Vector;\r\n\r\n /**\r\n * Information about the specifics of the collision contact separation\r\n */\r\n info: SeparationInfo;\r\n\r\n constructor(\r\n colliderA: Collider,\r\n colliderB: Collider,\r\n mtv: Vector,\r\n normal: Vector,\r\n tangent: Vector,\r\n points: Vector[],\r\n localPoints: Vector[],\r\n info: SeparationInfo\r\n ) {\r\n this.colliderA = colliderA;\r\n this.colliderB = colliderB;\r\n this.mtv = mtv;\r\n this.normal = normal;\r\n this.tangent = tangent;\r\n this.points = points;\r\n this.localPoints = localPoints;\r\n this.info = info;\r\n this.id = Pair.calculatePairHash(colliderA.id, colliderB.id);\r\n if (colliderA.__compositeColliderId || colliderB.__compositeColliderId) {\r\n // Add on the parent composite pair for start/end contact\r\n this.id += '|' + Pair.calculatePairHash(\r\n colliderA.__compositeColliderId ?? colliderA.id,\r\n colliderB.__compositeColliderId ?? colliderB.id);\r\n }\r\n }\r\n\r\n /**\r\n * Match contact awake state, except if body's are Fixed\r\n */\r\n public matchAwake(): void {\r\n const bodyA = this.colliderA.owner.get(BodyComponent);\r\n const bodyB = this.colliderB.owner.get(BodyComponent);\r\n if (bodyA && bodyB) {\r\n if (bodyA.sleeping !== bodyB.sleeping) {\r\n if (bodyA.sleeping && bodyA.collisionType !== CollisionType.Fixed && bodyB.sleepMotion >= Physics.wakeThreshold) {\r\n bodyA.setSleeping(false);\r\n }\r\n if (bodyB.sleeping && bodyB.collisionType !== CollisionType.Fixed && bodyA.sleepMotion >= Physics.wakeThreshold) {\r\n bodyB.setSleeping(false);\r\n }\r\n }\r\n }\r\n }\r\n\r\n public isCanceled() {\r\n return this._canceled;\r\n }\r\n\r\n public cancel(): void {\r\n this._canceled = true;\r\n }\r\n}\r\n","import { LineSegment } from '../../Math/line-segment';\r\nimport { Vector } from '../../Math/vector';\r\nimport { Collider } from './Collider';\r\nimport { CircleCollider } from './CircleCollider';\r\nimport { PolygonCollider } from './PolygonCollider';\r\n\r\n/**\r\n * Specific information about a contact and it's separation\r\n */\r\nexport interface SeparationInfo {\r\n /**\r\n * Collider A\r\n */\r\n collider: Collider;\r\n\r\n /**\r\n * Signed value (negative means overlap, positive no overlap)\r\n */\r\n separation: number;\r\n\r\n /**\r\n * Axis of separation from the collider's perspective\r\n */\r\n axis: Vector;\r\n\r\n /**\r\n * Side of separation (reference) from the collider's perspective\r\n */\r\n\r\n side?: LineSegment;\r\n\r\n /**\r\n * Local side of separation (reference) from the collider's perspective\r\n */\r\n localSide?: LineSegment;\r\n\r\n /**\r\n * Index of the separation side (reference) from the collider's perspective\r\n */\r\n sideId?: number;\r\n\r\n /**\r\n * Point on collider B (incident point)\r\n */\r\n point: Vector;\r\n\r\n /**\r\n * Local point on collider B (incident point)\r\n */\r\n localPoint?: Vector;\r\n}\r\n\r\nexport class SeparatingAxis {\r\n static findPolygonPolygonSeparation(polyA: PolygonCollider, polyB: PolygonCollider): SeparationInfo {\r\n let bestSeparation = -Number.MAX_VALUE;\r\n let bestSide: LineSegment | null = null;\r\n let bestAxis: Vector | null = null;\r\n let bestSideIndex: number = -1;\r\n let bestOtherPoint: Vector | null = null;\r\n const sides = polyA.getSides();\r\n const localSides = polyA.getLocalSides();\r\n for (let i = 0; i < sides.length; i++) {\r\n const side = sides[i];\r\n const axis = side.normal();\r\n const vertB = polyB.getFurthestPoint(axis.negate());\r\n // Separation on side i's axis\r\n // We are looking for the largest separation between poly A's sides\r\n const vertSeparation = side.distanceToPoint(vertB, true);\r\n if (vertSeparation > bestSeparation) {\r\n bestSeparation = vertSeparation;\r\n bestSide = side;\r\n bestAxis = axis;\r\n bestSideIndex = i;\r\n bestOtherPoint = vertB;\r\n }\r\n }\r\n\r\n return {\r\n collider: polyA,\r\n separation: bestAxis ? bestSeparation : 99,\r\n axis: bestAxis as Vector,\r\n side: bestSide,\r\n localSide: localSides[bestSideIndex],\r\n sideId: bestSideIndex,\r\n point: bestOtherPoint as Vector,\r\n localPoint: bestAxis ? polyB.getFurthestLocalPoint(bestAxis!.negate()) : null\r\n };\r\n }\r\n\r\n static findCirclePolygonSeparation(circle: CircleCollider, polygon: PolygonCollider): Vector | null {\r\n const axes = polygon.axes;\r\n const pc = polygon.center;\r\n // Special SAT with circles\r\n const polyDir = pc.sub(circle.worldPos);\r\n const closestPointOnPoly = polygon.getFurthestPoint(polyDir.negate());\r\n axes.push(closestPointOnPoly.sub(circle.worldPos).normalize());\r\n\r\n let minOverlap = Number.MAX_VALUE;\r\n let minAxis = null;\r\n let minIndex = -1;\r\n for (let i = 0; i < axes.length; i++) {\r\n const proj1 = polygon.project(axes[i]);\r\n const proj2 = circle.project(axes[i]);\r\n const overlap = proj1.getOverlap(proj2);\r\n if (overlap <= 0) {\r\n return null;\r\n } else {\r\n if (overlap < minOverlap) {\r\n minOverlap = overlap;\r\n minAxis = axes[i];\r\n minIndex = i;\r\n }\r\n }\r\n }\r\n if (minIndex < 0) {\r\n return null;\r\n }\r\n return minAxis.normalize().scale(minOverlap);\r\n }\r\n}\r\n","import { CircleCollider } from './CircleCollider';\r\nimport { CollisionContact } from '../Detection/CollisionContact';\r\nimport { PolygonCollider } from './PolygonCollider';\r\nimport { EdgeCollider } from './EdgeCollider';\r\nimport { SeparatingAxis, SeparationInfo } from './SeparatingAxis';\r\nimport { LineSegment } from '../../Math/line-segment';\r\nimport { Vector } from '../../Math/vector';\r\nimport { TransformComponent } from '../../EntityComponentSystem';\r\nimport { Pair } from '../Detection/Pair';\r\n\r\nexport const CollisionJumpTable = {\r\n CollideCircleCircle(circleA: CircleCollider, circleB: CircleCollider): CollisionContact[] {\r\n const circleAPos = circleA.worldPos;\r\n const circleBPos = circleB.worldPos;\r\n const combinedRadius = circleA.radius + circleB.radius;\r\n const distance = circleAPos.distance(circleBPos);\r\n\r\n if (distance > combinedRadius) {\r\n return [];\r\n }\r\n\r\n // negative means overlap\r\n const separation = combinedRadius - distance;\r\n\r\n // Normal points from A -> B\r\n const normal = circleBPos.sub(circleAPos).normalize();\r\n const tangent = normal.perpendicular();\r\n const mvt = normal.scale(separation);\r\n\r\n const point = circleA.getFurthestPoint(normal);\r\n const local = circleA.getFurthestLocalPoint(normal);\r\n\r\n const info: SeparationInfo = {\r\n collider: circleA,\r\n separation,\r\n axis: normal,\r\n point: point\r\n };\r\n\r\n return [new CollisionContact(circleA, circleB, mvt, normal, tangent, [point], [local], info)];\r\n },\r\n\r\n CollideCirclePolygon(circle: CircleCollider, polygon: PolygonCollider): CollisionContact[] {\r\n let minAxis = SeparatingAxis.findCirclePolygonSeparation(circle, polygon);\r\n if (!minAxis) {\r\n return [];\r\n }\r\n\r\n // make sure that the minAxis is pointing away from circle\r\n const samedir = minAxis.dot(polygon.center.sub(circle.center));\r\n minAxis = samedir < 0 ? minAxis.negate() : minAxis;\r\n\r\n const point = circle.getFurthestPoint(minAxis);\r\n const xf = circle.owner?.get(TransformComponent) ?? new TransformComponent();\r\n const local = xf.applyInverse(point);\r\n const normal = minAxis.normalize();\r\n\r\n const info: SeparationInfo = {\r\n collider: circle,\r\n separation: -minAxis.size,\r\n axis: normal,\r\n point: point,\r\n localPoint: local,\r\n side: polygon.findSide(normal.negate()),\r\n localSide: polygon.findLocalSide(normal.negate())\r\n };\r\n\r\n return [new CollisionContact(circle, polygon, minAxis, normal, normal.perpendicular(), [point], [local], info)];\r\n },\r\n\r\n CollideCircleEdge(circle: CircleCollider, edge: EdgeCollider): CollisionContact[] {\r\n // TODO not sure this actually abides by local/world collisions\r\n // Are edge.begin and edge.end local space or world space? I think they should be local\r\n\r\n // center of the circle in world pos\r\n const cc = circle.center;\r\n // vector in the direction of the edge\r\n const edgeWorld = edge.asLine();\r\n const e = edgeWorld.end.sub(edgeWorld.begin);\r\n\r\n // amount of overlap with the circle's center along the edge direction\r\n const u = e.dot(edgeWorld.end.sub(cc));\r\n const v = e.dot(cc.sub(edgeWorld.begin));\r\n const side = edge.asLine();\r\n const localSide = edge.asLocalLine();\r\n\r\n // Potential region A collision (circle is on the left side of the edge, before the beginning)\r\n if (v <= 0) {\r\n const da = edgeWorld.begin.sub(cc);\r\n const dda = da.dot(da); // quick and dirty way of calc'n distance in r^2 terms saves some sqrts\r\n // save some sqrts\r\n if (dda > circle.radius * circle.radius) {\r\n return []; // no collision\r\n }\r\n\r\n const normal = da.normalize();\r\n const separation = circle.radius - Math.sqrt(dda);\r\n\r\n const info: SeparationInfo = {\r\n collider: circle,\r\n separation: separation,\r\n axis: normal,\r\n point: side.begin,\r\n side: side,\r\n localSide: localSide\r\n };\r\n\r\n return [\r\n new CollisionContact(circle, edge, normal.scale(separation), normal, normal.perpendicular(), [side.begin], [localSide.begin], info)\r\n ];\r\n }\r\n\r\n // Potential region B collision (circle is on the right side of the edge, after the end)\r\n if (u <= 0) {\r\n const db = edgeWorld.end.sub(cc);\r\n const ddb = db.dot(db);\r\n if (ddb > circle.radius * circle.radius) {\r\n return [];\r\n }\r\n\r\n const normal = db.normalize();\r\n const separation = circle.radius - Math.sqrt(ddb);\r\n\r\n const info: SeparationInfo = {\r\n collider: circle,\r\n separation: separation,\r\n axis: normal,\r\n point: side.end,\r\n side: side,\r\n localSide: localSide\r\n };\r\n\r\n return [\r\n new CollisionContact(circle, edge, normal.scale(separation), normal, normal.perpendicular(), [side.end], [localSide.end], info)\r\n ];\r\n }\r\n\r\n // Otherwise potential region AB collision (circle is in the middle of the edge between the beginning and end)\r\n const den = e.dot(e);\r\n const pointOnEdge = edgeWorld.begin\r\n .scale(u)\r\n .add(edgeWorld.end.scale(v))\r\n .scale(1 / den);\r\n const d = cc.sub(pointOnEdge);\r\n\r\n const dd = d.dot(d);\r\n if (dd > circle.radius * circle.radius) {\r\n return []; // no collision\r\n }\r\n\r\n let normal = e.perpendicular();\r\n // flip correct direction\r\n if (normal.dot(cc.sub(edgeWorld.begin)) < 0) {\r\n normal.x = -normal.x;\r\n normal.y = -normal.y;\r\n }\r\n\r\n normal = normal.normalize();\r\n const separation = circle.radius - Math.sqrt(dd);\r\n\r\n const mvt = normal.scale(separation);\r\n const info: SeparationInfo = {\r\n collider: circle,\r\n separation: separation,\r\n axis: normal,\r\n point: pointOnEdge,\r\n side: side,\r\n localSide: localSide\r\n };\r\n\r\n return [\r\n new CollisionContact(\r\n circle,\r\n edge,\r\n mvt,\r\n normal.negate(),\r\n normal.negate().perpendicular(),\r\n [pointOnEdge],\r\n [pointOnEdge.sub(edge.worldPos)],\r\n info\r\n )\r\n ];\r\n },\r\n\r\n CollideEdgeEdge(): CollisionContact[] {\r\n // Edge-edge collision doesn't make sense\r\n return [];\r\n },\r\n\r\n CollidePolygonEdge(polygon: PolygonCollider, edge: EdgeCollider): CollisionContact[] {\r\n const pc = polygon.center;\r\n const ec = edge.center;\r\n const dir = ec.sub(pc).normalize();\r\n\r\n // build a temporary polygon from the edge to use SAT\r\n const linePoly = new PolygonCollider({\r\n points: [edge.begin, edge.end, edge.end.add(dir.scale(100)), edge.begin.add(dir.scale(100))],\r\n offset: edge.offset\r\n });\r\n linePoly.owner = edge.owner;\r\n const tx = edge.owner?.get(TransformComponent);\r\n if (tx) {\r\n linePoly.update(edge.owner.get(TransformComponent).get());\r\n }\r\n // Gross hack but poly-poly works well\r\n const contact = this.CollidePolygonPolygon(polygon, linePoly);\r\n if (contact.length) {\r\n // Fudge the contact back to edge\r\n contact[0].colliderB = edge;\r\n (contact[0].id as any) = Pair.calculatePairHash(polygon.id, edge.id);\r\n }\r\n return contact;\r\n },\r\n\r\n CollidePolygonPolygon(polyA: PolygonCollider, polyB: PolygonCollider): CollisionContact[] {\r\n // Multi contact from SAT\r\n // https://gamedev.stackexchange.com/questions/111390/multiple-contacts-for-sat-collision-detection\r\n // do a SAT test to find a min axis if it exists\r\n const separationA = SeparatingAxis.findPolygonPolygonSeparation(polyA, polyB);\r\n // If there is no overlap from boxA's perspective we can end early\r\n if (separationA.separation > 0) {\r\n return [];\r\n }\r\n\r\n const separationB = SeparatingAxis.findPolygonPolygonSeparation(polyB, polyA);\r\n // If there is no overlap from boxB's perspective exit now\r\n if (separationB.separation > 0) {\r\n return [];\r\n }\r\n\r\n // Separations are both negative, we want to pick the least negative (minimal movement)\r\n const separation = separationA.separation > separationB.separation ? separationA : separationB;\r\n\r\n // The incident side is the most opposite from the axes of collision on the other collider\r\n const other = separation.collider === polyA ? polyB : polyA;\r\n const incident = other.findSide(separation.axis.negate()) as LineSegment;\r\n\r\n // Clip incident side by the perpendicular lines at each end of the reference side\r\n // https://en.wikipedia.org/wiki/Sutherland%E2%80%93Hodgman_algorithm\r\n const reference = separation.side;\r\n const refDir = reference.dir().normalize();\r\n\r\n // Find our contact points by clipping the incident by the collision side\r\n const clipRight = incident.clip(refDir.negate(), -refDir.dot(reference.begin));\r\n let clipLeft: LineSegment | null = null;\r\n if (clipRight) {\r\n clipLeft = clipRight.clip(refDir, refDir.dot(reference.end));\r\n }\r\n\r\n // If there is no left there is no collision\r\n if (clipLeft) {\r\n // We only want clip points below the reference edge, discard the others\r\n const points = clipLeft.getPoints().filter((p) => {\r\n return reference.below(p);\r\n });\r\n\r\n let normal = separation.axis;\r\n let tangent = normal.perpendicular();\r\n // Point Contact A -> B\r\n if (polyB.center.sub(polyA.center).dot(normal) < 0) {\r\n normal = normal.negate();\r\n tangent = normal.perpendicular();\r\n }\r\n // Points are clipped from incident which is the other collider\r\n // Store those as locals\r\n let localPoints: Vector[] = [];\r\n if (separation.collider === polyA) {\r\n const xf = polyB.owner?.get(TransformComponent) ?? new TransformComponent();\r\n localPoints = points.map((p) => xf.applyInverse(p));\r\n } else {\r\n const xf = polyA.owner?.get(TransformComponent) ?? new TransformComponent();\r\n localPoints = points.map((p) => xf.applyInverse(p));\r\n }\r\n return [new CollisionContact(polyA, polyB, normal.scale(-separation.separation), normal, tangent, points, localPoints, separation)];\r\n }\r\n return [];\r\n },\r\n\r\n FindContactSeparation(contact: CollisionContact, localPoint: Vector) {\r\n const shapeA = contact.colliderA;\r\n const txA = contact.colliderA.owner?.get(TransformComponent) ?? new TransformComponent();\r\n const shapeB = contact.colliderB;\r\n const txB = contact.colliderB.owner?.get(TransformComponent) ?? new TransformComponent();\r\n\r\n // both are circles\r\n if (shapeA instanceof CircleCollider && shapeB instanceof CircleCollider) {\r\n const combinedRadius = shapeA.radius + shapeB.radius;\r\n const distance = txA.pos.distance(txB.pos);\r\n const separation = combinedRadius - distance;\r\n return -separation;\r\n }\r\n\r\n // both are polygons\r\n if (shapeA instanceof PolygonCollider && shapeB instanceof PolygonCollider) {\r\n if (contact.info.localSide) {\r\n let side: LineSegment;\r\n let worldPoint: Vector;\r\n if (contact.info.collider === shapeA) {\r\n side = new LineSegment(txA.apply(contact.info.localSide.begin), txA.apply(contact.info.localSide.end));\r\n worldPoint = txB.apply(localPoint);\r\n } else {\r\n side = new LineSegment(txB.apply(contact.info.localSide.begin), txB.apply(contact.info.localSide.end));\r\n worldPoint = txA.apply(localPoint);\r\n }\r\n\r\n return side.distanceToPoint(worldPoint, true);\r\n }\r\n }\r\n\r\n // polygon v circle\r\n if (\r\n (shapeA instanceof PolygonCollider && shapeB instanceof CircleCollider) ||\r\n (shapeB instanceof PolygonCollider && shapeA instanceof CircleCollider)\r\n ) {\r\n const worldPoint = txA.apply(localPoint);\r\n if (contact.info.side) {\r\n return contact.info.side.distanceToPoint(worldPoint, true);\r\n }\r\n }\r\n\r\n // polygon v edge\r\n if (\r\n (shapeA instanceof EdgeCollider && shapeB instanceof PolygonCollider) ||\r\n (shapeB instanceof EdgeCollider && shapeA instanceof PolygonCollider)\r\n ) {\r\n let worldPoint: Vector;\r\n if (contact.info.collider === shapeA) {\r\n worldPoint = txB.apply(localPoint);\r\n } else {\r\n worldPoint = txA.apply(localPoint);\r\n }\r\n if (contact.info.side) {\r\n return contact.info.side.distanceToPoint(worldPoint, true);\r\n }\r\n }\r\n\r\n // circle v edge\r\n if (\r\n (shapeA instanceof CircleCollider && shapeB instanceof EdgeCollider) ||\r\n (shapeB instanceof CircleCollider && shapeA instanceof EdgeCollider)\r\n ) {\r\n // Local point is always on the edge which is always shapeB\r\n const worldPoint = txB.apply(localPoint);\r\n\r\n let circlePoint: Vector;\r\n if (shapeA instanceof CircleCollider) {\r\n circlePoint = shapeA.getFurthestPoint(contact.normal);\r\n }\r\n\r\n const dist = worldPoint.distance(circlePoint);\r\n\r\n if (contact.info.side) {\r\n return dist > 0 ? -dist : 0;\r\n }\r\n }\r\n\r\n return 0;\r\n }\r\n};\r\n","import { BoundingBox } from '../BoundingBox';\r\nimport { CollisionContact } from '../Detection/CollisionContact';\r\nimport { CollisionJumpTable } from './CollisionJumpTable';\r\nimport { CircleCollider } from './CircleCollider';\r\nimport { PolygonCollider } from './PolygonCollider';\r\n\r\nimport { Projection } from '../../Math/projection';\r\nimport { LineSegment } from '../../Math/line-segment';\r\nimport { Vector } from '../../Math/vector';\r\nimport { Ray } from '../../Math/ray';\r\nimport { Color } from '../../Color';\r\nimport { Collider } from './Collider';\r\nimport { ClosestLineJumpTable } from './ClosestLineJumpTable';\r\nimport { ExcaliburGraphicsContext } from '../../Graphics/Context/ExcaliburGraphicsContext';\r\nimport { Transform } from '../../Math/transform';\r\nimport { AffineMatrix } from '../../Math/affine-matrix';\r\n\r\nexport interface EdgeColliderOptions {\r\n /**\r\n * The beginning of the edge defined in local coordinates to the collider\r\n */\r\n begin: Vector;\r\n /**\r\n * The ending of the edge defined in local coordinates to the collider\r\n */\r\n end: Vector;\r\n /**\r\n * Optionally specify an offset\r\n */\r\n offset?: Vector;\r\n}\r\n\r\n/**\r\n * Edge is a single line collider to create collisions with a single line.\r\n */\r\nexport class EdgeCollider extends Collider {\r\n offset: Vector;\r\n begin: Vector;\r\n end: Vector;\r\n\r\n private _transform: Transform;\r\n private _globalMatrix: AffineMatrix = AffineMatrix.identity();\r\n\r\n constructor(options: EdgeColliderOptions) {\r\n super();\r\n this.begin = options.begin || Vector.Zero;\r\n this.end = options.end || Vector.Zero;\r\n this.offset = options.offset ?? Vector.Zero;\r\n }\r\n\r\n /**\r\n * Returns a clone of this Edge, not associated with any collider\r\n */\r\n public clone(): EdgeCollider {\r\n return new EdgeCollider({\r\n begin: this.begin.clone(),\r\n end: this.end.clone()\r\n });\r\n }\r\n\r\n public get worldPos(): Vector {\r\n const tx = this._transform;\r\n return tx?.globalPos.add(this.offset) ?? this.offset;\r\n }\r\n\r\n /**\r\n * Get the center of the collision area in world coordinates\r\n */\r\n public get center(): Vector {\r\n const begin = this._getTransformedBegin();\r\n const end = this._getTransformedEnd();\r\n const pos = begin.average(end);\r\n return pos;\r\n }\r\n\r\n private _getTransformedBegin(): Vector {\r\n return this._globalMatrix.multiply(this.begin);\r\n }\r\n\r\n private _getTransformedEnd(): Vector {\r\n return this._globalMatrix.multiply(this.end);\r\n }\r\n\r\n /**\r\n * Returns the slope of the line in the form of a vector\r\n */\r\n public getSlope(): Vector {\r\n const begin = this._getTransformedBegin();\r\n const end = this._getTransformedEnd();\r\n const distance = begin.distance(end);\r\n return end.sub(begin).scale(1 / distance);\r\n }\r\n\r\n /**\r\n * Returns the length of the line segment in pixels\r\n */\r\n public getLength(): number {\r\n const begin = this._getTransformedBegin();\r\n const end = this._getTransformedEnd();\r\n const distance = begin.distance(end);\r\n return distance;\r\n }\r\n\r\n /**\r\n * Tests if a point is contained in this collision area\r\n */\r\n public contains(): boolean {\r\n return false;\r\n }\r\n\r\n /**\r\n * @inheritdoc\r\n */\r\n public rayCast(ray: Ray, max: number = Infinity): Vector {\r\n const numerator = this._getTransformedBegin().sub(ray.pos);\r\n\r\n // Test is line and ray are parallel and non intersecting\r\n if (ray.dir.cross(this.getSlope()) === 0 && numerator.cross(ray.dir) !== 0) {\r\n return null;\r\n }\r\n\r\n // Lines are parallel\r\n const divisor = ray.dir.cross(this.getSlope());\r\n if (divisor === 0) {\r\n return null;\r\n }\r\n\r\n const t = numerator.cross(this.getSlope()) / divisor;\r\n\r\n if (t >= 0 && t <= max) {\r\n const u = numerator.cross(ray.dir) / divisor / this.getLength();\r\n if (u >= 0 && u <= 1) {\r\n return ray.getPoint(t);\r\n }\r\n }\r\n\r\n return null;\r\n }\r\n\r\n /**\r\n * Returns the closes line between this and another collider, from this -> collider\r\n * @param shape\r\n */\r\n public getClosestLineBetween(shape: Collider): LineSegment {\r\n if (shape instanceof CircleCollider) {\r\n return ClosestLineJumpTable.CircleEdgeClosestLine(shape, this);\r\n } else if (shape instanceof PolygonCollider) {\r\n return ClosestLineJumpTable.PolygonEdgeClosestLine(shape, this).flip();\r\n } else if (shape instanceof EdgeCollider) {\r\n return ClosestLineJumpTable.EdgeEdgeClosestLine(this, shape);\r\n } else {\r\n throw new Error(`Polygon could not collide with unknown CollisionShape ${typeof shape}`);\r\n }\r\n }\r\n\r\n /**\r\n * @inheritdoc\r\n */\r\n public collide(shape: Collider): CollisionContact[] {\r\n if (shape instanceof CircleCollider) {\r\n return CollisionJumpTable.CollideCircleEdge(shape, this);\r\n } else if (shape instanceof PolygonCollider) {\r\n return CollisionJumpTable.CollidePolygonEdge(shape, this);\r\n } else if (shape instanceof EdgeCollider) {\r\n return CollisionJumpTable.CollideEdgeEdge();\r\n } else {\r\n throw new Error(`Edge could not collide with unknown CollisionShape ${typeof shape}`);\r\n }\r\n }\r\n\r\n /**\r\n * Find the point on the collider furthest in the direction specified\r\n */\r\n public getFurthestPoint(direction: Vector): Vector {\r\n const transformedBegin = this._getTransformedBegin();\r\n const transformedEnd = this._getTransformedEnd();\r\n if (direction.dot(transformedBegin) > 0) {\r\n return transformedBegin;\r\n } else {\r\n return transformedEnd;\r\n }\r\n }\r\n\r\n private _boundsFromBeginEnd(begin: Vector, end: Vector, padding = 10) {\r\n // A perfectly vertical or horizontal edge would have a bounds 0 width or height\r\n // this causes problems for the collision system so we give them some padding\r\n return new BoundingBox(\r\n Math.min(begin.x, end.x) - padding,\r\n Math.min(begin.y, end.y) - padding,\r\n Math.max(begin.x, end.x) + padding,\r\n Math.max(begin.y, end.y) + padding\r\n );\r\n }\r\n\r\n /**\r\n * Get the axis aligned bounding box for the edge collider in world space\r\n */\r\n public get bounds(): BoundingBox {\r\n const transformedBegin = this._getTransformedBegin();\r\n const transformedEnd = this._getTransformedEnd();\r\n return this._boundsFromBeginEnd(transformedBegin, transformedEnd);\r\n }\r\n\r\n /**\r\n * Get the axis aligned bounding box for the edge collider in local space\r\n */\r\n public get localBounds(): BoundingBox {\r\n return this._boundsFromBeginEnd(this.begin, this.end);\r\n }\r\n\r\n /**\r\n * Returns this edge represented as a line in world coordinates\r\n */\r\n public asLine(): LineSegment {\r\n return new LineSegment(this._getTransformedBegin(), this._getTransformedEnd());\r\n }\r\n\r\n /**\r\n * Return this edge as a line in local line coordinates (relative to the position)\r\n */\r\n public asLocalLine(): LineSegment {\r\n return new LineSegment(this.begin, this.end);\r\n }\r\n\r\n /**\r\n * Get the axis associated with the edge\r\n */\r\n public get axes(): Vector[] {\r\n const e = this._getTransformedEnd().sub(this._getTransformedBegin());\r\n const edgeNormal = e.normal();\r\n\r\n const axes = [];\r\n axes.push(edgeNormal);\r\n axes.push(edgeNormal.negate());\r\n axes.push(edgeNormal.normal());\r\n axes.push(edgeNormal.normal().negate());\r\n return axes;\r\n }\r\n\r\n /**\r\n * Get the moment of inertia for an edge\r\n * https://en.wikipedia.org/wiki/List_of_moments_of_inertia\r\n */\r\n public getInertia(mass: number): number {\r\n const length = this.end.sub(this.begin).distance() / 2;\r\n return mass * length * length;\r\n }\r\n\r\n /**\r\n * @inheritdoc\r\n */\r\n public update(transform: Transform): void {\r\n this._transform = transform;\r\n const globalMat = transform.matrix ?? this._globalMatrix;\r\n globalMat.clone(this._globalMatrix);\r\n this._globalMatrix.translate(this.offset.x, this.offset.y);\r\n }\r\n\r\n /**\r\n * Project the edge along a specified axis\r\n */\r\n public project(axis: Vector): Projection {\r\n const scalars = [];\r\n\r\n const points = [this._getTransformedBegin(), this._getTransformedEnd()];\r\n const len = points.length;\r\n for (let i = 0; i < len; i++) {\r\n scalars.push(points[i].dot(axis));\r\n }\r\n\r\n return new Projection(Math.min.apply(Math, scalars), Math.max.apply(Math, scalars));\r\n }\r\n\r\n public debug(ex: ExcaliburGraphicsContext, color: Color) {\r\n const begin = this._getTransformedBegin();\r\n const end = this._getTransformedEnd();\r\n ex.drawLine(begin, end, color, 2);\r\n ex.drawCircle(begin, 2, color);\r\n ex.drawCircle(end, 2, color);\r\n }\r\n\r\n}\r\n","import { Color } from '../../Color';\r\nimport { BoundingBox } from '../BoundingBox';\r\nimport { EdgeCollider } from './EdgeCollider';\r\nimport { CollisionJumpTable } from './CollisionJumpTable';\r\nimport { CircleCollider } from './CircleCollider';\r\nimport { CollisionContact } from '../Detection/CollisionContact';\r\nimport { Projection } from '../../Math/projection';\r\nimport { LineSegment } from '../../Math/line-segment';\r\nimport { Vector } from '../../Math/vector';\r\nimport { AffineMatrix } from '../../Math/affine-matrix';\r\nimport { Ray } from '../../Math/ray';\r\nimport { ClosestLineJumpTable } from './ClosestLineJumpTable';\r\nimport { Collider } from './Collider';\r\nimport { ExcaliburGraphicsContext, Logger, range } from '../..';\r\nimport { CompositeCollider } from './CompositeCollider';\r\nimport { Shape } from './Shape';\r\nimport { Transform } from '../../Math/transform';\r\n\r\nexport interface PolygonColliderOptions {\r\n /**\r\n * Pixel offset relative to a collider's body transform position.\r\n */\r\n offset?: Vector;\r\n /**\r\n * Points in the polygon in order around the perimeter in local coordinates. These are relative from the body transform position.\r\n */\r\n points: Vector[];\r\n}\r\n\r\n/**\r\n * Polygon collider for detecting collisions\r\n */\r\nexport class PolygonCollider extends Collider {\r\n private _logger = Logger.getInstance();\r\n /**\r\n * Pixel offset relative to a collider's body transform position.\r\n */\r\n public offset: Vector;\r\n\r\n private _points: Vector[];\r\n /**\r\n * Points in the polygon in order around the perimeter in local coordinates. These are relative from the body transform position.\r\n * Excalibur stores these in counter-clockwise order\r\n */\r\n public set points(points: Vector[]) {\r\n this._localBoundsDirty = true;\r\n this._localSidesDirty = true;\r\n this._sidesDirty = true;\r\n this._points = points;\r\n }\r\n\r\n /**\r\n * Points in the polygon in order around the perimeter in local coordinates. These are relative from the body transform position.\r\n * Excalibur stores these in counter-clockwise order\r\n */\r\n public get points(): Vector[] {\r\n return this._points;\r\n }\r\n\r\n private _transform: Transform;\r\n\r\n private _transformedPoints: Vector[] = [];\r\n private _sides: LineSegment[] = [];\r\n private _localSides: LineSegment[] = [];\r\n\r\n constructor(options: PolygonColliderOptions) {\r\n super();\r\n this.offset = options.offset ?? Vector.Zero;\r\n this._globalMatrix.translate(this.offset.x, this.offset.y);\r\n this.points = options.points ?? [];\r\n const counterClockwise = this._isCounterClockwiseWinding(this.points);\r\n if (!counterClockwise) {\r\n this.points.reverse();\r\n }\r\n if (!this.isConvex()) {\r\n this._logger.warn(\r\n 'Excalibur only supports convex polygon colliders and will not behave properly.'+\r\n 'Call PolygonCollider.triangulate() to build a new collider composed of smaller convex triangles');\r\n }\r\n\r\n // calculate initial transformation\r\n this._calculateTransformation();\r\n }\r\n\r\n private _isCounterClockwiseWinding(points: Vector[]): boolean {\r\n // https://stackoverflow.com/a/1165943\r\n let sum = 0;\r\n for (let i = 0; i < points.length; i++) {\r\n sum += (points[(i + 1) % points.length].x - points[i].x) * (points[(i + 1) % points.length].y + points[i].y);\r\n }\r\n return sum < 0;\r\n }\r\n\r\n /**\r\n * Returns if the polygon collider is convex, Excalibur does not handle non-convex collision shapes.\r\n * Call [[Polygon.triangulate]] to generate a [[CompositeCollider]] from this non-convex shape\r\n */\r\n public isConvex(): boolean {\r\n // From SO: https://stackoverflow.com/a/45372025\r\n if (this.points.length < 3) {\r\n return false;\r\n }\r\n let oldPoint = this.points[this.points.length - 2];\r\n let newPoint = this.points[this.points.length - 1];\r\n let direction = Math.atan2(newPoint.y - oldPoint.y, newPoint.x - oldPoint.x);\r\n let oldDirection = 0;\r\n let orientation = 0;\r\n let angleSum = 0;\r\n for (const [i, point] of this.points.entries()) {\r\n oldPoint = newPoint;\r\n oldDirection = direction;\r\n newPoint = point;\r\n direction = Math.atan2(newPoint.y - oldPoint.y, newPoint.x - oldPoint.x);\r\n if (oldPoint.equals(newPoint)) {\r\n return false; // repeat point\r\n }\r\n let angle = direction - oldDirection;\r\n if (angle <= -Math.PI){\r\n angle += Math.PI * 2;\r\n } else if (angle > Math.PI) {\r\n angle -= Math.PI * 2;\r\n }\r\n if (i === 0) {\r\n if (angle === 0.0) {\r\n return false;\r\n }\r\n orientation = angle > 0 ? 1 : -1;\r\n } else {\r\n if (orientation * angle <= 0) {\r\n return false;\r\n }\r\n }\r\n angleSum += angle;\r\n }\r\n return Math.abs(Math.round(angleSum / (Math.PI * 2))) === 1;\r\n }\r\n\r\n /**\r\n * Tessellates the polygon into a triangle fan as a [[CompositeCollider]] of triangle polygons\r\n */\r\n public tessellate(): CompositeCollider {\r\n const polygons: Vector[][] = [];\r\n for (let i = 1; i < this.points.length - 2; i++) {\r\n polygons.push([this.points[0], this.points[i + 1], this.points[i + 2]]);\r\n }\r\n polygons.push([this.points[0], this.points[1], this.points[2]]);\r\n\r\n return new CompositeCollider(polygons.map(points => Shape.Polygon(points)));\r\n }\r\n\r\n /**\r\n * Triangulate the polygon collider using the \"Ear Clipping\" algorithm.\r\n * Returns a new [[CompositeCollider]] made up of smaller triangles.\r\n */\r\n public triangulate(): CompositeCollider {\r\n // https://www.youtube.com/watch?v=hTJFcHutls8\r\n if (this.points.length < 3) {\r\n throw Error('Invalid polygon');\r\n }\r\n\r\n /**\r\n * Helper to get a vertex in the list\r\n */\r\n function getItem(index: number, list: T[]) {\r\n if (index >= list.length) {\r\n return list[index % list.length];\r\n } else if (index < 0) {\r\n return list[index % list.length + list.length];\r\n } else {\r\n return list[index];\r\n }\r\n }\r\n\r\n /**\r\n * Quick test for point in triangle\r\n */\r\n function isPointInTriangle(point: Vector, a: Vector, b: Vector, c: Vector) {\r\n const ab = b.sub(a);\r\n const bc = c.sub(b);\r\n const ca = a.sub(c);\r\n\r\n const ap = point.sub(a);\r\n const bp = point.sub(b);\r\n const cp = point.sub(c);\r\n\r\n const cross1 = ab.cross(ap);\r\n const cross2 = bc.cross(bp);\r\n const cross3 = ca.cross(cp);\r\n\r\n if (cross1 > 0 || cross2 > 0 || cross3 > 0) {\r\n return false;\r\n }\r\n return true;\r\n }\r\n\r\n const triangles: Vector[][] = [];\r\n const vertices = [...this.points];\r\n const indices = range(0, this.points.length - 1);\r\n\r\n // 1. Loop through vertices clockwise\r\n // if the vertex is convex (interior angle is < 180) (cross product positive)\r\n // if the polygon formed by it's edges doesn't contain the points\r\n // it's an ear add it to our list of triangles, and restart\r\n\r\n while (indices.length > 3) {\r\n for (let i = 0; i < indices.length; i++) {\r\n const a = indices[i];\r\n const b = getItem(i - 1, indices);\r\n const c = getItem(i + 1, indices);\r\n\r\n const va = vertices[a];\r\n const vb = vertices[b];\r\n const vc = vertices[c];\r\n\r\n // Check convexity\r\n const leftArm = vb.sub(va);\r\n const rightArm = vc.sub(va);\r\n const isConvex = rightArm.cross(leftArm) > 0; // positive cross means convex\r\n if (!isConvex) {\r\n continue;\r\n }\r\n\r\n let isEar = true;\r\n // Check that if any vertices are in the triangle a, b, c\r\n for (let j = 0; j < indices.length; j++) {\r\n const vertIndex = indices[j];\r\n // We can skip these\r\n if (vertIndex === a || vertIndex === b || vertIndex === c) {\r\n continue;\r\n }\r\n\r\n const point = vertices[vertIndex];\r\n if (isPointInTriangle(point, vb, va, vc)) {\r\n isEar = false;\r\n break;\r\n }\r\n }\r\n\r\n // Add ear to polygon list and remove from list\r\n if (isEar) {\r\n triangles.push([vb, va, vc]);\r\n indices.splice(i, 1);\r\n break;\r\n }\r\n }\r\n }\r\n\r\n triangles.push([vertices[indices[0]], vertices[indices[1]], vertices[indices[2]]]);\r\n\r\n return new CompositeCollider(triangles.map(points => Shape.Polygon(points)));\r\n }\r\n\r\n /**\r\n * Returns a clone of this ConvexPolygon, not associated with any collider\r\n */\r\n public clone(): PolygonCollider {\r\n return new PolygonCollider({\r\n offset: this.offset.clone(),\r\n points: this.points.map((p) => p.clone())\r\n });\r\n }\r\n\r\n /**\r\n * Returns the world position of the collider, which is the current body transform plus any defined offset\r\n */\r\n public get worldPos(): Vector {\r\n if (this._transform) {\r\n return this._transform.pos.add(this.offset);\r\n }\r\n return this.offset;\r\n }\r\n\r\n /**\r\n * Get the center of the collider in world coordinates\r\n */\r\n public get center(): Vector {\r\n return this.bounds.center;\r\n }\r\n\r\n private _globalMatrix: AffineMatrix = AffineMatrix.identity();\r\n\r\n private _transformedPointsDirty = true;\r\n /**\r\n * Calculates the underlying transformation from the body relative space to world space\r\n */\r\n private _calculateTransformation() {\r\n const points = this.points;\r\n const len = points.length;\r\n this._transformedPoints.length = 0; // clear out old transform\r\n for (let i = 0; i < len; i++) {\r\n this._transformedPoints[i] = this._globalMatrix.multiply(points[i].clone());\r\n }\r\n }\r\n\r\n /**\r\n * Gets the points that make up the polygon in world space, from actor relative space (if specified)\r\n */\r\n public getTransformedPoints(): Vector[] {\r\n if (this._transformedPointsDirty) {\r\n this._calculateTransformation();\r\n this._transformedPointsDirty = false;\r\n }\r\n return this._transformedPoints;\r\n }\r\n\r\n private _sidesDirty = true;\r\n /**\r\n * Gets the sides of the polygon in world space\r\n */\r\n public getSides(): LineSegment[] {\r\n if (this._sidesDirty) {\r\n const lines = [];\r\n const points = this.getTransformedPoints();\r\n const len = points.length;\r\n for (let i = 0; i < len; i++) {\r\n // This winding is important\r\n lines.push(new LineSegment(points[i], points[(i + 1) % len]));\r\n }\r\n this._sides = lines;\r\n this._sidesDirty = false;\r\n }\r\n return this._sides;\r\n }\r\n\r\n private _localSidesDirty = true;\r\n /**\r\n * Returns the local coordinate space sides\r\n */\r\n public getLocalSides(): LineSegment[] {\r\n if (this._localSidesDirty) {\r\n const lines = [];\r\n const points = this.points;\r\n const len = points.length;\r\n for (let i = 0; i < len; i++) {\r\n // This winding is important\r\n lines.push(new LineSegment(points[i], points[(i + 1) % len]));\r\n }\r\n this._localSides = lines;\r\n this._localSidesDirty = false;\r\n }\r\n\r\n return this._localSides;\r\n }\r\n\r\n /**\r\n * Given a direction vector find the world space side that is most in that direction\r\n * @param direction\r\n */\r\n public findSide(direction: Vector): LineSegment {\r\n const sides = this.getSides();\r\n let bestSide = sides[0];\r\n let maxDistance = -Number.MAX_VALUE;\r\n for (let side = 0; side < sides.length; side++) {\r\n const currentSide = sides[side];\r\n const sideNormal = currentSide.normal();\r\n const mostDirection = sideNormal.dot(direction);\r\n if (mostDirection > maxDistance) {\r\n bestSide = currentSide;\r\n maxDistance = mostDirection;\r\n }\r\n }\r\n return bestSide;\r\n }\r\n\r\n /**\r\n * Given a direction vector find the local space side that is most in that direction\r\n * @param direction\r\n */\r\n public findLocalSide(direction: Vector): LineSegment {\r\n const sides = this.getLocalSides();\r\n let bestSide = sides[0];\r\n let maxDistance = -Number.MAX_VALUE;\r\n for (let side = 0; side < sides.length; side++) {\r\n const currentSide = sides[side];\r\n const sideNormal = currentSide.normal();\r\n const mostDirection = sideNormal.dot(direction);\r\n if (mostDirection > maxDistance) {\r\n bestSide = currentSide;\r\n maxDistance = mostDirection;\r\n }\r\n }\r\n return bestSide;\r\n }\r\n\r\n /**\r\n * Get the axis associated with the convex polygon\r\n */\r\n public get axes(): Vector[] {\r\n const axes: Vector[] = [];\r\n const sides = this.getSides();\r\n for (let i = 0; i < sides.length; i++) {\r\n axes.push(sides[i].normal());\r\n }\r\n return axes;\r\n }\r\n\r\n /**\r\n * Updates the transform for the collision geometry\r\n *\r\n * Collision geometry (points/bounds) will not change until this is called.\r\n * @param transform\r\n */\r\n public update(transform: Transform): void {\r\n if (transform) {\r\n this._transform = transform;\r\n this._transformedPointsDirty = true;\r\n this._sidesDirty = true;\r\n // This change means an update must be performed in order for geometry to update\r\n const globalMat = transform.matrix ?? this._globalMatrix;\r\n globalMat.clone(this._globalMatrix);\r\n this._globalMatrix.translate(this.offset.x, this.offset.y);\r\n }\r\n }\r\n\r\n /**\r\n * Tests if a point is contained in this collider in world space\r\n */\r\n public contains(point: Vector): boolean {\r\n // Always cast to the right, as long as we cast in a consistent fixed direction we\r\n // will be fine\r\n const testRay = new Ray(point, new Vector(1, 0));\r\n const intersectCount = this.getSides().reduce(function (accum, side) {\r\n if (testRay.intersect(side) >= 0) {\r\n return accum + 1;\r\n }\r\n return accum;\r\n }, 0);\r\n\r\n if (intersectCount % 2 === 0) {\r\n return false;\r\n }\r\n return true;\r\n }\r\n\r\n public getClosestLineBetween(collider: Collider): LineSegment {\r\n if (collider instanceof CircleCollider) {\r\n return ClosestLineJumpTable.PolygonCircleClosestLine(this, collider);\r\n } else if (collider instanceof PolygonCollider) {\r\n return ClosestLineJumpTable.PolygonPolygonClosestLine(this, collider);\r\n } else if (collider instanceof EdgeCollider) {\r\n return ClosestLineJumpTable.PolygonEdgeClosestLine(this, collider);\r\n } else {\r\n throw new Error(`Polygon could not collide with unknown CollisionShape ${typeof collider}`);\r\n }\r\n }\r\n\r\n /**\r\n * Returns a collision contact if the 2 colliders collide, otherwise collide will\r\n * return null.\r\n * @param collider\r\n */\r\n public collide(collider: Collider): CollisionContact[] {\r\n if (collider instanceof CircleCollider) {\r\n return CollisionJumpTable.CollideCirclePolygon(collider, this);\r\n } else if (collider instanceof PolygonCollider) {\r\n return CollisionJumpTable.CollidePolygonPolygon(this, collider);\r\n } else if (collider instanceof EdgeCollider) {\r\n return CollisionJumpTable.CollidePolygonEdge(this, collider);\r\n } else {\r\n throw new Error(`Polygon could not collide with unknown CollisionShape ${typeof collider}`);\r\n }\r\n }\r\n\r\n /**\r\n * Find the point on the collider furthest in the direction specified\r\n */\r\n public getFurthestPoint(direction: Vector): Vector {\r\n const pts = this.getTransformedPoints();\r\n let furthestPoint = null;\r\n let maxDistance = -Number.MAX_VALUE;\r\n for (let i = 0; i < pts.length; i++) {\r\n const distance = direction.dot(pts[i]);\r\n if (distance > maxDistance) {\r\n maxDistance = distance;\r\n furthestPoint = pts[i];\r\n }\r\n }\r\n return furthestPoint;\r\n }\r\n\r\n /**\r\n * Find the local point on the collider furthest in the direction specified\r\n * @param direction\r\n */\r\n public getFurthestLocalPoint(direction: Vector): Vector {\r\n const pts = this.points;\r\n let furthestPoint = pts[0];\r\n let maxDistance = -Number.MAX_VALUE;\r\n for (let i = 0; i < pts.length; i++) {\r\n const distance = direction.dot(pts[i]);\r\n if (distance > maxDistance) {\r\n maxDistance = distance;\r\n furthestPoint = pts[i];\r\n }\r\n }\r\n return furthestPoint;\r\n }\r\n\r\n /**\r\n * Finds the closes face to the point using perpendicular distance\r\n * @param point point to test against polygon\r\n */\r\n public getClosestFace(point: Vector): { distance: Vector; face: LineSegment } {\r\n const sides = this.getSides();\r\n let min = Number.POSITIVE_INFINITY;\r\n let faceIndex = -1;\r\n let distance = -1;\r\n for (let i = 0; i < sides.length; i++) {\r\n const dist = sides[i].distanceToPoint(point);\r\n if (dist < min) {\r\n min = dist;\r\n faceIndex = i;\r\n distance = dist;\r\n }\r\n }\r\n\r\n if (faceIndex !== -1) {\r\n return {\r\n distance: sides[faceIndex].normal().scale(distance),\r\n face: sides[faceIndex]\r\n };\r\n }\r\n\r\n return null;\r\n }\r\n\r\n /**\r\n * Get the axis aligned bounding box for the polygon collider in world coordinates\r\n */\r\n public get bounds(): BoundingBox {\r\n return this.localBounds.transform(this._globalMatrix);\r\n }\r\n\r\n private _localBoundsDirty = true;\r\n private _localBounds: BoundingBox;\r\n /**\r\n * Get the axis aligned bounding box for the polygon collider in local coordinates\r\n */\r\n public get localBounds(): BoundingBox {\r\n if (this._localBoundsDirty) {\r\n this._localBounds = BoundingBox.fromPoints(this.points);\r\n this._localBoundsDirty = false;\r\n }\r\n\r\n return this._localBounds;\r\n }\r\n\r\n private _cachedMass: number;\r\n private _cachedInertia: number;\r\n /**\r\n * Get the moment of inertia for an arbitrary polygon\r\n * https://en.wikipedia.org/wiki/List_of_moments_of_inertia\r\n */\r\n public getInertia(mass: number): number {\r\n if (this._cachedMass === mass && this._cachedInertia) {\r\n return this._cachedInertia;\r\n }\r\n let numerator = 0;\r\n let denominator = 0;\r\n const points = this.points;\r\n for (let i = 0; i < points.length; i++) {\r\n const iplusone = (i + 1) % points.length;\r\n const crossTerm = points[iplusone].cross(points[i]);\r\n numerator +=\r\n crossTerm *\r\n (points[i].dot(points[i]) + points[i].dot(points[iplusone]) + points[iplusone].dot(points[iplusone]));\r\n denominator += crossTerm;\r\n }\r\n this._cachedMass = mass;\r\n return this._cachedInertia = (mass / 6) * (numerator / denominator);\r\n }\r\n\r\n /**\r\n * Casts a ray into the polygon and returns a vector representing the point of contact (in world space) or null if no collision.\r\n */\r\n public rayCast(ray: Ray, max: number = Infinity) {\r\n // find the minimum contact time greater than 0\r\n // contact times less than 0 are behind the ray and we don't want those\r\n const sides = this.getSides();\r\n const len = sides.length;\r\n let minContactTime = Number.MAX_VALUE;\r\n let contactIndex = -1;\r\n for (let i = 0; i < len; i++) {\r\n const contactTime = ray.intersect(sides[i]);\r\n if (contactTime >= 0 && contactTime < minContactTime && contactTime <= max) {\r\n minContactTime = contactTime;\r\n contactIndex = i;\r\n }\r\n }\r\n\r\n // contact was found\r\n if (contactIndex >= 0) {\r\n return ray.getPoint(minContactTime);\r\n }\r\n\r\n // no contact found\r\n return null;\r\n }\r\n\r\n /**\r\n * Project the edges of the polygon along a specified axis\r\n */\r\n public project(axis: Vector): Projection {\r\n const points = this.getTransformedPoints();\r\n const len = points.length;\r\n let min = Number.MAX_VALUE;\r\n let max = -Number.MAX_VALUE;\r\n for (let i = 0; i < len; i++) {\r\n const scalar = points[i].dot(axis);\r\n min = Math.min(min, scalar);\r\n max = Math.max(max, scalar);\r\n }\r\n\r\n return new Projection(min, max);\r\n }\r\n\r\n public debug(ex: ExcaliburGraphicsContext, color: Color) {\r\n const firstPoint = this.getTransformedPoints()[0];\r\n const points = [firstPoint, ...this.getTransformedPoints(), firstPoint];\r\n for (let i = 0; i < points.length - 1; i++) {\r\n ex.drawLine(points[i], points[i + 1], color, 2);\r\n ex.drawCircle(points[i], 2, color);\r\n ex.drawCircle(points[i + 1], 2, color);\r\n }\r\n }\r\n}\r\n","import { PolygonCollider } from './PolygonCollider';\r\nimport { CircleCollider } from './CircleCollider';\r\nimport { EdgeCollider } from './EdgeCollider';\r\nimport { BoundingBox } from '../BoundingBox';\r\nimport { vec, Vector } from '../../Math/vector';\r\nimport { CompositeCollider } from './CompositeCollider';\r\nimport { Logger } from '../..';\r\n\r\n/**\r\n * Excalibur helper for defining colliders quickly\r\n */\r\nexport class Shape {\r\n /**\r\n * Creates a box collider, under the hood defines a [[PolygonCollider]] collider\r\n * @param width Width of the box\r\n * @param height Height of the box\r\n * @param anchor Anchor of the box (default (.5, .5)) which positions the box relative to the center of the collider's position\r\n * @param offset Optional offset relative to the collider in local coordinates\r\n */\r\n static Box(width: number, height: number, anchor: Vector = Vector.Half, offset: Vector = Vector.Zero): PolygonCollider {\r\n return new PolygonCollider({\r\n points: new BoundingBox(-width * anchor.x, -height * anchor.y, width - width * anchor.x, height - height * anchor.y).getPoints(),\r\n offset: offset\r\n });\r\n }\r\n\r\n /**\r\n * Creates a new [[PolygonCollider|arbitrary polygon]] collider\r\n *\r\n * PolygonColliders are useful for creating convex polygon shapes\r\n * @param points Points specified in counter clockwise\r\n * @param offset Optional offset relative to the collider in local coordinates\r\n */\r\n static Polygon(points: Vector[], offset: Vector = Vector.Zero): PolygonCollider {\r\n return new PolygonCollider({\r\n points: points,\r\n offset: offset\r\n });\r\n }\r\n\r\n /**\r\n * Creates a new [[CircleCollider|circle]] collider\r\n *\r\n * Circle colliders are useful for balls, or to make collisions more forgiving on sharp edges\r\n * @param radius Radius of the circle collider\r\n * @param offset Optional offset relative to the collider in local coordinates\r\n */\r\n static Circle(radius: number, offset: Vector = Vector.Zero): CircleCollider {\r\n return new CircleCollider({\r\n radius: radius,\r\n offset: offset\r\n });\r\n }\r\n\r\n /**\r\n * Creates a new [[EdgeCollider|edge]] collider\r\n *\r\n * Edge colliders are useful for floors, walls, and other barriers\r\n * @param begin Beginning of the edge in local coordinates to the collider\r\n * @param end Ending of the edge in local coordinates to the collider\r\n */\r\n static Edge(begin: Vector, end: Vector): EdgeCollider {\r\n return new EdgeCollider({\r\n begin: begin,\r\n end: end\r\n });\r\n }\r\n\r\n /**\r\n * Creates a new capsule shaped [[CompositeCollider]] using 2 circles and a box\r\n *\r\n * Capsule colliders are useful for platformers with incline or jagged floors to have a smooth\r\n * player experience.\r\n *\r\n * @param width\r\n * @param height\r\n * @param offset Optional offset\r\n */\r\n static Capsule(width: number, height: number, offset = Vector.Zero): CompositeCollider {\r\n const logger = Logger.getInstance();\r\n if (width === height) {\r\n logger.warn('A capsule collider with equal width and height is a circle, consider using a ex.Shape.Circle or ex.CircleCollider');\r\n }\r\n\r\n const vertical = height >= width;\r\n\r\n if (vertical) {\r\n // height > width, if equal maybe use a circle\r\n const capsule = new CompositeCollider([\r\n Shape.Circle(width / 2, vec(0, -height / 2 + width / 2).add(offset)),\r\n Shape.Box(width, height - width, Vector.Half, offset),\r\n Shape.Circle(width / 2, vec(0, height / 2 - width / 2).add(offset))\r\n ]);\r\n return capsule;\r\n } else {\r\n // width > height, if equal maybe use a circle\r\n const capsule = new CompositeCollider([\r\n Shape.Circle(height / 2, vec(-width / 2 + height / 2, 0).add(offset)),\r\n Shape.Box(width - height, height, Vector.Half, offset),\r\n Shape.Circle(height / 2, vec(width / 2 - height / 2, 0).add(offset))\r\n ]);\r\n return capsule;\r\n }\r\n }\r\n}\r\n","import { Vector } from '../Math/vector';\r\nimport { TransformComponent } from '../EntityComponentSystem';\r\nimport { Component } from '../EntityComponentSystem/Component';\r\nimport { Entity } from '../EntityComponentSystem/Entity';\r\nimport { CollisionEndEvent, CollisionStartEvent, PostCollisionEvent, PreCollisionEvent } from '../Events';\r\nimport { Observable } from '../Util/Observable';\r\nimport { BoundingBox } from './BoundingBox';\r\nimport { CollisionContact } from './Detection/CollisionContact';\r\nimport { CircleCollider } from './Colliders/CircleCollider';\r\nimport { Collider } from './Colliders/Collider';\r\nimport { CompositeCollider } from './Colliders/CompositeCollider';\r\nimport { PolygonCollider } from './Colliders/PolygonCollider';\r\nimport { EdgeCollider } from './Colliders/EdgeCollider';\r\nimport { Shape } from './Colliders/Shape';\r\nimport { EventEmitter } from '../EventEmitter';\r\n\r\nexport class ColliderComponent extends Component<'ex.collider'> {\r\n public readonly type = 'ex.collider';\r\n\r\n public events = new EventEmitter();\r\n /**\r\n * Observable that notifies when a collider is added to the body\r\n */\r\n public $colliderAdded = new Observable();\r\n\r\n /**\r\n * Observable that notifies when a collider is removed from the body\r\n */\r\n public $colliderRemoved = new Observable();\r\n\r\n constructor(collider?: Collider) {\r\n super();\r\n this.set(collider);\r\n }\r\n\r\n private _collider: Collider;\r\n /**\r\n * Get the current collider geometry\r\n */\r\n public get() {\r\n return this._collider;\r\n }\r\n\r\n /**\r\n * Set the collider geometry\r\n * @param collider\r\n * @returns the collider you set\r\n */\r\n public set(collider: T): T {\r\n this.clear();\r\n if (collider) {\r\n this._collider = collider;\r\n this._collider.owner = this.owner;\r\n collider.events.pipe(this.events);\r\n this.$colliderAdded.notifyAll(collider);\r\n this.update();\r\n }\r\n return collider;\r\n }\r\n\r\n /**\r\n * Remove collider geometry from collider component\r\n */\r\n public clear() {\r\n if (this._collider) {\r\n this._collider.events.unpipe(this.events);\r\n this.$colliderRemoved.notifyAll(this._collider);\r\n this._collider.owner = null;\r\n this._collider = null;\r\n }\r\n }\r\n\r\n public clone(): ColliderComponent {\r\n const clone = new ColliderComponent(this._collider.clone());\r\n\r\n return clone;\r\n }\r\n\r\n /**\r\n * Return world space bounds\r\n */\r\n public get bounds() {\r\n return this._collider?.bounds ?? new BoundingBox();\r\n }\r\n\r\n /**\r\n * Return local space bounds\r\n */\r\n public get localBounds() {\r\n return this._collider?.localBounds ?? new BoundingBox();\r\n }\r\n\r\n /**\r\n * Update the collider's transformed geometry\r\n */\r\n public update() {\r\n const tx = this.owner?.get(TransformComponent);\r\n if (this._collider) {\r\n this._collider.owner = this.owner;\r\n if (tx) {\r\n this._collider.update(tx.get());\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Collide component with another\r\n * @param other\r\n */\r\n collide(other: ColliderComponent): CollisionContact[] {\r\n let colliderA = this._collider;\r\n let colliderB = other._collider;\r\n if (!colliderA || !colliderB) {\r\n return [];\r\n }\r\n\r\n // If we have a composite lefthand side :(\r\n // Might bite us, but to avoid updating all the handlers make composite always left side\r\n let flipped = false;\r\n if (colliderB instanceof CompositeCollider) {\r\n colliderA = colliderB;\r\n colliderB = this._collider;\r\n flipped = true;\r\n }\r\n\r\n if (this._collider) {\r\n const contacts = colliderA.collide(colliderB);\r\n if (contacts) {\r\n if (flipped) {\r\n contacts.forEach((contact) => {\r\n contact.mtv = contact.mtv.negate();\r\n contact.normal = contact.normal.negate();\r\n contact.tangent = contact.normal.perpendicular();\r\n contact.colliderA = this._collider;\r\n contact.colliderB = other._collider;\r\n });\r\n }\r\n return contacts;\r\n }\r\n return [];\r\n }\r\n return [];\r\n }\r\n\r\n onAdd(entity: Entity) {\r\n if (this._collider) {\r\n this.update();\r\n }\r\n // Wire up the collider events to the owning entity\r\n this.events.on('precollision', (evt: any) => {\r\n const precollision = evt as PreCollisionEvent;\r\n entity.events.emit(\r\n 'precollision',\r\n new PreCollisionEvent(precollision.target.owner, precollision.other.owner, precollision.side, precollision.intersection)\r\n );\r\n });\r\n this.events.on('postcollision', (evt: any) => {\r\n const postcollision = evt as PostCollisionEvent;\r\n entity.events.emit(\r\n 'postcollision',\r\n new PostCollisionEvent(postcollision.target.owner, postcollision.other.owner, postcollision.side, postcollision.intersection)\r\n );\r\n });\r\n this.events.on('collisionstart', (evt: any) => {\r\n const start = evt as CollisionStartEvent;\r\n entity.events.emit('collisionstart', new CollisionStartEvent(start.target.owner, start.other.owner, start.contact));\r\n });\r\n this.events.on('collisionend', (evt: any) => {\r\n const end = evt as CollisionEndEvent;\r\n entity.events.emit('collisionend', new CollisionEndEvent(end.target.owner, end.other.owner));\r\n });\r\n }\r\n\r\n onRemove() {\r\n this.events.clear();\r\n this.$colliderRemoved.notifyAll(this._collider);\r\n }\r\n\r\n /**\r\n * Sets up a box geometry based on the current bounds of the associated actor of this physics body.\r\n *\r\n * If no width/height are specified the body will attempt to use the associated actor's width/height.\r\n *\r\n * By default, the box is center is at (0, 0) which means it is centered around the actors anchor.\r\n */\r\n useBoxCollider(width: number, height: number, anchor: Vector = Vector.Half, center: Vector = Vector.Zero): PolygonCollider {\r\n const collider = Shape.Box(width, height, anchor, center);\r\n return (this.set(collider));\r\n }\r\n\r\n /**\r\n * Sets up a [[PolygonCollider|polygon]] collision geometry based on a list of of points relative\r\n * to the anchor of the associated actor\r\n * of this physics body.\r\n *\r\n * Only [convex polygon](https://en.wikipedia.org/wiki/Convex_polygon) definitions are supported.\r\n *\r\n * By default, the box is center is at (0, 0) which means it is centered around the actors anchor.\r\n */\r\n usePolygonCollider(points: Vector[], center: Vector = Vector.Zero): PolygonCollider {\r\n const poly = Shape.Polygon(points, center);\r\n return (this.set(poly));\r\n }\r\n\r\n /**\r\n * Sets up a [[Circle|circle collision geometry]] as the only collider with a specified radius in pixels.\r\n *\r\n * By default, the box is center is at (0, 0) which means it is centered around the actors anchor.\r\n */\r\n useCircleCollider(radius: number, center: Vector = Vector.Zero): CircleCollider {\r\n const collider = Shape.Circle(radius, center);\r\n return (this.set(collider));\r\n }\r\n\r\n /**\r\n * Sets up an [[Edge|edge collision geometry]] with a start point and an end point relative to the anchor of the associated actor\r\n * of this physics body.\r\n *\r\n * By default, the box is center is at (0, 0) which means it is centered around the actors anchor.\r\n */\r\n useEdgeCollider(begin: Vector, end: Vector): EdgeCollider {\r\n const collider = Shape.Edge(begin, end);\r\n return (this.set(collider));\r\n }\r\n\r\n /**\r\n * Setups up a [[CompositeCollider]] which can define any arbitrary set of excalibur colliders\r\n * @param colliders\r\n */\r\n useCompositeCollider(colliders: Collider[]): CompositeCollider {\r\n return (this.set(new CompositeCollider(colliders)));\r\n }\r\n}\r\n","import { Vector } from '../Math/vector';\r\nimport { CollisionType } from './CollisionType';\r\nimport { Physics } from './Physics';\r\nimport { Clonable } from '../Interfaces/Clonable';\r\nimport { TransformComponent } from '../EntityComponentSystem/Components/TransformComponent';\r\nimport { MotionComponent } from '../EntityComponentSystem/Components/MotionComponent';\r\nimport { Component } from '../EntityComponentSystem/Component';\r\nimport { CollisionGroup } from './Group/CollisionGroup';\r\nimport { createId, Id } from '../Id';\r\nimport { clamp } from '../Math/util';\r\nimport { ColliderComponent } from './ColliderComponent';\r\nimport { Transform } from '../Math/transform';\r\nimport { EventEmitter } from '../EventEmitter';\r\n\r\nexport interface BodyComponentOptions {\r\n type?: CollisionType;\r\n group?: CollisionGroup;\r\n useGravity?: boolean;\r\n}\r\n\r\nexport enum DegreeOfFreedom {\r\n Rotation = 'rotation',\r\n X = 'x',\r\n Y = 'y'\r\n}\r\n\r\n/**\r\n * Body describes all the physical properties pos, vel, acc, rotation, angular velocity for the purpose of\r\n * of physics simulation.\r\n */\r\nexport class BodyComponent extends Component<'ex.body'> implements Clonable {\r\n public readonly type = 'ex.body';\r\n public dependencies = [TransformComponent, MotionComponent];\r\n public static _ID = 0;\r\n public readonly id: Id<'body'> = createId('body', BodyComponent._ID++);\r\n public events = new EventEmitter();\r\n\r\n private _oldTransform = new Transform();\r\n\r\n /**\r\n * Indicates whether the old transform has been captured at least once for interpolation\r\n * @internal\r\n */\r\n public __oldTransformCaptured: boolean = false;\r\n\r\n /**\r\n * Enable or disabled the fixed update interpolation, by default interpolation is on.\r\n */\r\n public enableFixedUpdateInterpolate = true;\r\n\r\n constructor(options?: BodyComponentOptions) {\r\n super();\r\n if (options) {\r\n this.collisionType = options.type ?? this.collisionType;\r\n this.group = options.group ?? this.group;\r\n this.useGravity = options.useGravity ?? this.useGravity;\r\n }\r\n }\r\n\r\n public get matrix() {\r\n return this.transform.get().matrix;\r\n }\r\n\r\n /**\r\n * Collision type for the rigidbody physics simulation, by default [[CollisionType.PreventCollision]]\r\n */\r\n public collisionType: CollisionType = CollisionType.PreventCollision;\r\n\r\n /**\r\n * The collision group for the body's colliders, by default body colliders collide with everything\r\n */\r\n public group: CollisionGroup = CollisionGroup.All;\r\n\r\n /**\r\n * The amount of mass the body has\r\n */\r\n private _mass: number = Physics.defaultMass;\r\n public get mass(): number {\r\n return this._mass;\r\n }\r\n\r\n public set mass(newMass: number) {\r\n this._mass = newMass;\r\n this._cachedInertia = undefined;\r\n this._cachedInverseInertia = undefined;\r\n }\r\n\r\n /**\r\n * The inverse mass (1/mass) of the body. If [[CollisionType.Fixed]] this is 0, meaning \"infinite\" mass\r\n */\r\n public get inverseMass(): number {\r\n return this.collisionType === CollisionType.Fixed ? 0 : 1 / this.mass;\r\n }\r\n\r\n /**\r\n * Amount of \"motion\" the body has before sleeping. If below [[Physics.sleepEpsilon]] it goes to \"sleep\"\r\n */\r\n public sleepMotion: number = Physics.sleepEpsilon * 5;\r\n\r\n /**\r\n * Can this body sleep, by default bodies do not sleep\r\n */\r\n public canSleep: boolean = Physics.bodiesCanSleepByDefault;\r\n\r\n private _sleeping = false;\r\n /**\r\n * Whether this body is sleeping or not\r\n */\r\n public get sleeping(): boolean {\r\n return this._sleeping;\r\n }\r\n\r\n /**\r\n * Set the sleep state of the body\r\n * @param sleeping\r\n */\r\n public setSleeping(sleeping: boolean) {\r\n this._sleeping = sleeping;\r\n if (!sleeping) {\r\n // Give it a kick to keep it from falling asleep immediately\r\n this.sleepMotion = Physics.sleepEpsilon * 5;\r\n } else {\r\n this.vel = Vector.Zero;\r\n this.acc = Vector.Zero;\r\n this.angularVelocity = 0;\r\n this.sleepMotion = 0;\r\n }\r\n }\r\n\r\n /**\r\n * Update body's [[BodyComponent.sleepMotion]] for the purpose of sleeping\r\n */\r\n public updateMotion() {\r\n if (this._sleeping) {\r\n this.setSleeping(true);\r\n }\r\n const currentMotion = this.vel.size * this.vel.size + Math.abs(this.angularVelocity * this.angularVelocity);\r\n const bias = Physics.sleepBias;\r\n this.sleepMotion = bias * this.sleepMotion + (1 - bias) * currentMotion;\r\n this.sleepMotion = clamp(this.sleepMotion, 0, 10 * Physics.sleepEpsilon);\r\n if (this.canSleep && this.sleepMotion < Physics.sleepEpsilon) {\r\n this.setSleeping(true);\r\n }\r\n }\r\n\r\n private _cachedInertia: number;\r\n /**\r\n * Get the moment of inertia from the [[ColliderComponent]]\r\n */\r\n public get inertia() {\r\n if (this._cachedInertia) {\r\n return this._cachedInertia;\r\n }\r\n\r\n // Inertia is a property of the geometry, so this is a little goofy but seems to be okay?\r\n const collider = this.owner.get(ColliderComponent);\r\n if (collider) {\r\n collider.$colliderAdded.subscribe(() => {\r\n this._cachedInertia = null;\r\n });\r\n collider.$colliderRemoved.subscribe(() => {\r\n this._cachedInertia = null;\r\n });\r\n const maybeCollider = collider.get();\r\n if (maybeCollider) {\r\n return this._cachedInertia = maybeCollider.getInertia(this.mass);\r\n }\r\n }\r\n return 0;\r\n }\r\n\r\n private _cachedInverseInertia: number;\r\n /**\r\n * Get the inverse moment of inertial from the [[ColliderComponent]]. If [[CollisionType.Fixed]] this is 0, meaning \"infinite\" mass\r\n */\r\n public get inverseInertia() {\r\n if (this._cachedInverseInertia) {\r\n return this._cachedInverseInertia;\r\n }\r\n return this._cachedInverseInertia = this.collisionType === CollisionType.Fixed ? 0 : 1 / this.inertia;\r\n }\r\n\r\n /**\r\n * The also known as coefficient of restitution of this actor, represents the amount of energy preserved after collision or the\r\n * bounciness. If 1, it is 100% bouncy, 0 it completely absorbs.\r\n */\r\n public bounciness: number = 0.2;\r\n\r\n /**\r\n * The coefficient of friction on this actor\r\n */\r\n public friction: number = 0.99;\r\n\r\n /**\r\n * Should use global gravity [[Physics.gravity]] in it's physics simulation, default is true\r\n */\r\n public useGravity: boolean = true;\r\n\r\n /**\r\n * Degrees of freedom to limit\r\n *\r\n * Note: this only limits responses in the realistic solver, if velocity/angularVelocity is set the actor will still respond\r\n */\r\n public limitDegreeOfFreedom: DegreeOfFreedom[] = [];\r\n\r\n /**\r\n * Returns if the owner is active\r\n */\r\n public get active() {\r\n return !!this.owner?.active;\r\n }\r\n\r\n /**\r\n * @deprecated Use globalP0s\r\n */\r\n public get center() {\r\n return this.globalPos;\r\n }\r\n\r\n public get transform(): TransformComponent {\r\n return this.owner?.get(TransformComponent);\r\n }\r\n\r\n public get motion(): MotionComponent {\r\n return this.owner?.get(MotionComponent);\r\n }\r\n\r\n public get pos(): Vector {\r\n return this.transform.pos;\r\n }\r\n\r\n public set pos(val: Vector) {\r\n this.transform.pos = val;\r\n }\r\n\r\n /**\r\n * The (x, y) position of the actor this will be in the middle of the actor if the\r\n * [[Actor.anchor]] is set to (0.5, 0.5) which is default.\r\n * If you want the (x, y) position to be the top left of the actor specify an anchor of (0, 0).\r\n */\r\n public get globalPos(): Vector {\r\n return this.transform.globalPos;\r\n }\r\n\r\n public set globalPos(val: Vector) {\r\n this.transform.globalPos = val;\r\n }\r\n\r\n /**\r\n * The position of the actor last frame (x, y) in pixels\r\n */\r\n public get oldPos(): Vector {\r\n return this._oldTransform.pos;\r\n }\r\n\r\n /**\r\n * The current velocity vector (vx, vy) of the actor in pixels/second\r\n */\r\n public get vel(): Vector {\r\n return this.motion.vel;\r\n }\r\n\r\n public set vel(val: Vector) {\r\n this.motion.vel = val;\r\n }\r\n\r\n /**\r\n * The velocity of the actor last frame (vx, vy) in pixels/second\r\n */\r\n public oldVel: Vector = new Vector(0, 0);\r\n\r\n /**\r\n * The current acceleration vector (ax, ay) of the actor in pixels/second/second. An acceleration pointing down such as (0, 100) may\r\n * be useful to simulate a gravitational effect.\r\n */\r\n public get acc(): Vector {\r\n return this.motion.acc;\r\n }\r\n\r\n public set acc(val: Vector) {\r\n this.motion.acc = val;\r\n }\r\n\r\n /**\r\n * Gets/sets the acceleration of the actor from the last frame. This does not include the global acc [[Physics.acc]].\r\n */\r\n public oldAcc: Vector = Vector.Zero;\r\n\r\n /**\r\n * The current torque applied to the actor\r\n */\r\n public get torque(): number {\r\n return this.motion.torque;\r\n }\r\n\r\n public set torque(val: number) {\r\n this.motion.torque = val;\r\n }\r\n\r\n /**\r\n * Gets/sets the rotation of the body from the last frame.\r\n */\r\n public get oldRotation(): number {\r\n return this._oldTransform.rotation;\r\n }\r\n\r\n /**\r\n * The rotation of the body in radians\r\n */\r\n public get rotation() {\r\n return this.transform.globalRotation;\r\n }\r\n\r\n public set rotation(val: number) {\r\n this.transform.globalRotation = val;\r\n }\r\n\r\n /**\r\n * The scale vector of the actor\r\n */\r\n public get scale(): Vector {\r\n return this.transform.globalScale;\r\n }\r\n\r\n public set scale(val: Vector) {\r\n this.transform.globalScale = val;\r\n }\r\n\r\n /**\r\n * The scale of the actor last frame\r\n */\r\n public get oldScale(): Vector {\r\n return this._oldTransform.scale;\r\n }\r\n\r\n /**\r\n * The scale rate of change of the actor in scale/second\r\n */\r\n public get scaleFactor(): Vector {\r\n return this.motion.scaleFactor;\r\n }\r\n\r\n public set scaleFactor(scaleFactor: Vector) {\r\n this.motion.scaleFactor = scaleFactor;\r\n }\r\n\r\n /**\r\n * Get the angular velocity in radians/second\r\n */\r\n public get angularVelocity(): number {\r\n return this.motion.angularVelocity;\r\n }\r\n\r\n /**\r\n * Set the angular velocity in radians/second\r\n */\r\n public set angularVelocity(value: number) {\r\n this.motion.angularVelocity = value;\r\n }\r\n\r\n /**\r\n * Apply a specific impulse to the body\r\n * @param point\r\n * @param impulse\r\n */\r\n public applyImpulse(point: Vector, impulse: Vector) {\r\n if (this.collisionType !== CollisionType.Active) {\r\n return; // only active objects participate in the simulation\r\n }\r\n\r\n const finalImpulse = impulse.scale(this.inverseMass);\r\n if (this.limitDegreeOfFreedom.includes(DegreeOfFreedom.X)) {\r\n finalImpulse.x = 0;\r\n }\r\n if (this.limitDegreeOfFreedom.includes(DegreeOfFreedom.Y)) {\r\n finalImpulse.y = 0;\r\n }\r\n\r\n this.vel.addEqual(finalImpulse);\r\n\r\n if (!this.limitDegreeOfFreedom.includes(DegreeOfFreedom.Rotation)) {\r\n const distanceFromCenter = point.sub(this.globalPos);\r\n this.angularVelocity += this.inverseInertia * distanceFromCenter.cross(impulse);\r\n }\r\n }\r\n\r\n /**\r\n * Apply only linear impulse to the body\r\n * @param impulse\r\n */\r\n public applyLinearImpulse(impulse: Vector) {\r\n if (this.collisionType !== CollisionType.Active) {\r\n return; // only active objects participate in the simulation\r\n }\r\n\r\n const finalImpulse = impulse.scale(this.inverseMass);\r\n\r\n if (this.limitDegreeOfFreedom.includes(DegreeOfFreedom.X)) {\r\n finalImpulse.x = 0;\r\n }\r\n if (this.limitDegreeOfFreedom.includes(DegreeOfFreedom.Y)) {\r\n finalImpulse.y = 0;\r\n }\r\n\r\n this.vel = this.vel.add(finalImpulse);\r\n }\r\n\r\n /**\r\n * Apply only angular impulse to the body\r\n * @param point\r\n * @param impulse\r\n */\r\n public applyAngularImpulse(point: Vector, impulse: Vector) {\r\n if (this.collisionType !== CollisionType.Active) {\r\n return; // only active objects participate in the simulation\r\n }\r\n\r\n if (!this.limitDegreeOfFreedom.includes(DegreeOfFreedom.Rotation)) {\r\n const distanceFromCenter = point.sub(this.globalPos);\r\n this.angularVelocity += this.inverseInertia * distanceFromCenter.cross(impulse);\r\n }\r\n }\r\n\r\n /**\r\n * Sets the old versions of pos, vel, acc, and scale.\r\n */\r\n public captureOldTransform() {\r\n // Capture old values before integration step updates them\r\n this.__oldTransformCaptured = true;\r\n this.transform.get().clone(this._oldTransform);\r\n this.oldVel.setTo(this.vel.x, this.vel.y);\r\n this.oldAcc.setTo(this.acc.x, this.acc.y);\r\n }\r\n\r\n public clone(): BodyComponent {\r\n const component = super.clone() as BodyComponent;\r\n return component;\r\n }\r\n}\r\n","import { Component, ComponentCtor, TagComponent } from './Component';\r\n\r\nimport { Observable, Message } from '../Util/Observable';\r\nimport { OnInitialize, OnPreUpdate, OnPostUpdate } from '../Interfaces/LifecycleEvents';\r\nimport { Engine } from '../Engine';\r\nimport { InitializeEvent, PreUpdateEvent, PostUpdateEvent } from '../Events';\r\nimport { EventEmitter, EventKey, Handler, Scene, Subscription, Util } from '..';\r\n\r\n/**\r\n * Interface holding an entity component pair\r\n */\r\nexport interface EntityComponent {\r\n component: Component;\r\n entity: Entity;\r\n}\r\n\r\n/**\r\n * AddedComponent message\r\n */\r\nexport class AddedComponent implements Message {\r\n readonly type: 'Component Added' = 'Component Added';\r\n constructor(public data: EntityComponent) {}\r\n}\r\n\r\n/**\r\n * Type guard to know if message is f an Added Component\r\n */\r\nexport function isAddedComponent(x: Message): x is AddedComponent {\r\n return !!x && x.type === 'Component Added';\r\n}\r\n\r\n/**\r\n * RemovedComponent message\r\n */\r\nexport class RemovedComponent implements Message {\r\n readonly type: 'Component Removed' = 'Component Removed';\r\n constructor(public data: EntityComponent) {}\r\n}\r\n\r\n/**\r\n * Type guard to know if message is for a Removed Component\r\n */\r\nexport function isRemovedComponent(x: Message): x is RemovedComponent {\r\n return !!x && x.type === 'Component Removed';\r\n}\r\n\r\n/**\r\n * Built in events supported by all entities\r\n */\r\nexport type EntityEvents = {\r\n 'initialize': InitializeEvent;\r\n 'preupdate': PreUpdateEvent;\r\n 'postupdate': PostUpdateEvent;\r\n};\r\n\r\nexport const EntityEvents = {\r\n Initialize: 'initialize',\r\n PreUpdate: 'preupdate',\r\n PostUpdate: 'postupdate'\r\n} as const;\r\n\r\n/**\r\n * An Entity is the base type of anything that can have behavior in Excalibur, they are part of the built in entity component system\r\n *\r\n * Entities can be strongly typed with the components they contain\r\n *\r\n * ```typescript\r\n * const entity = new Entity();\r\n * entity.components.a; // Type ComponentA\r\n * entity.components.b; // Type ComponentB\r\n * ```\r\n */\r\nexport class Entity implements OnInitialize, OnPreUpdate, OnPostUpdate {\r\n private static _ID = 0;\r\n\r\n /**\r\n * Listen to or emit events for an entity\r\n */\r\n public events = new EventEmitter();\r\n\r\n constructor(components?: Component[], name?: string) {\r\n this._setName(name);\r\n if (components) {\r\n for (const component of components) {\r\n this.addComponent(component);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * The unique identifier for the entity\r\n */\r\n public id: number = Entity._ID++;\r\n\r\n /**\r\n * The scene that the entity is in, if any\r\n */\r\n public scene: Scene = null;\r\n\r\n private _name: string = 'anonymous';\r\n protected _setName(name: string) {\r\n if (name) {\r\n this._name = name;\r\n }\r\n }\r\n public get name(): string {\r\n return this._name;\r\n }\r\n\r\n /**\r\n * Whether this entity is active, if set to false it will be reclaimed\r\n */\r\n public active: boolean = true;\r\n\r\n /**\r\n * Kill the entity, means it will no longer be updated. Kills are deferred to the end of the update.\r\n * If parented it will be removed from the parent when killed.\r\n */\r\n public kill() {\r\n if (this.active) {\r\n this.active = false;\r\n this.unparent();\r\n }\r\n }\r\n\r\n public isKilled() {\r\n return !this.active;\r\n }\r\n\r\n /**\r\n * Specifically get the tags on the entity from [[TagComponent]]\r\n */\r\n public get tags(): readonly string[] {\r\n return this._tagsMemo;\r\n }\r\n\r\n /**\r\n * Check if a tag exists on the entity\r\n * @param tag name to check for\r\n */\r\n public hasTag(tag: string): boolean {\r\n return this.tags.includes(tag);\r\n }\r\n\r\n /**\r\n * Adds a tag to an entity\r\n * @param tag\r\n * @returns Entity\r\n */\r\n public addTag(tag: string) {\r\n return this.addComponent(new TagComponent(tag));\r\n }\r\n\r\n /**\r\n * Removes a tag on the entity\r\n *\r\n * Removals are deferred until the end of update\r\n * @param tag\r\n * @param force Remove component immediately, no deferred\r\n */\r\n public removeTag(tag: string, force = false) {\r\n return this.removeComponent(tag, force);\r\n }\r\n\r\n /**\r\n * The types of the components on the Entity\r\n */\r\n public get types(): string[] {\r\n return this._typesMemo;\r\n }\r\n\r\n /**\r\n * Bucket to hold on to deferred removals\r\n */\r\n private _componentsToRemove: (Component | string)[] = [];\r\n private _componentTypeToInstance = new Map();\r\n private _componentStringToInstance = new Map();\r\n\r\n private _tagsMemo: string[] = [];\r\n private _typesMemo: string[] = [];\r\n private _rebuildMemos() {\r\n this._tagsMemo = Array.from(this._componentStringToInstance.values())\r\n .filter((c) => c instanceof TagComponent)\r\n .map((c) => c.type);\r\n this._typesMemo = Array.from(this._componentStringToInstance.keys());\r\n }\r\n\r\n public getComponents(): Component[] {\r\n return Array.from(this._componentStringToInstance.values());\r\n }\r\n\r\n /**\r\n * Observable that keeps track of component add or remove changes on the entity\r\n */\r\n public componentAdded$ = new Observable();\r\n private _notifyAddComponent(component: Component) {\r\n this._rebuildMemos();\r\n const added = new AddedComponent({\r\n component,\r\n entity: this\r\n });\r\n this.componentAdded$.notifyAll(added);\r\n }\r\n\r\n public componentRemoved$ = new Observable();\r\n private _notifyRemoveComponent(component: Component) {\r\n const removed = new RemovedComponent({\r\n component,\r\n entity: this\r\n });\r\n this.componentRemoved$.notifyAll(removed);\r\n this._rebuildMemos();\r\n }\r\n\r\n private _parent: Entity = null;\r\n public get parent(): Entity {\r\n return this._parent;\r\n }\r\n\r\n public childrenAdded$ = new Observable();\r\n public childrenRemoved$ = new Observable();\r\n\r\n private _children: Entity[] = [];\r\n /**\r\n * Get the direct children of this entity\r\n */\r\n public get children(): readonly Entity[] {\r\n return this._children;\r\n }\r\n\r\n /**\r\n * Unparents this entity, if there is a parent. Otherwise it does nothing.\r\n */\r\n public unparent() {\r\n if (this._parent) {\r\n this._parent.removeChild(this);\r\n this._parent = null;\r\n }\r\n }\r\n\r\n /**\r\n * Adds an entity to be a child of this entity\r\n * @param entity\r\n */\r\n public addChild(entity: Entity): Entity {\r\n if (entity.parent === null) {\r\n if (this.getAncestors().includes(entity)) {\r\n throw new Error('Cycle detected, cannot add entity');\r\n }\r\n this._children.push(entity);\r\n entity._parent = this;\r\n this.childrenAdded$.notifyAll(entity);\r\n } else {\r\n throw new Error('Entity already has a parent, cannot add without unparenting');\r\n }\r\n return this;\r\n }\r\n\r\n /**\r\n * Remove an entity from children if it exists\r\n * @param entity\r\n */\r\n public removeChild(entity: Entity): Entity {\r\n if (entity.parent === this) {\r\n Util.removeItemFromArray(entity, this._children);\r\n entity._parent = null;\r\n this.childrenRemoved$.notifyAll(entity);\r\n }\r\n return this;\r\n }\r\n\r\n /**\r\n * Removes all children from this entity\r\n */\r\n public removeAllChildren(): Entity {\r\n // Avoid modifying the array issue by walking backwards\r\n for (let i = this.children.length - 1; i >= 0; i--) {\r\n this.removeChild(this.children[i]);\r\n }\r\n return this;\r\n }\r\n\r\n /**\r\n * Returns a list of parent entities starting with the topmost parent. Includes the current entity.\r\n */\r\n public getAncestors(): Entity[] {\r\n const result: Entity[] = [this];\r\n let current = this.parent;\r\n while (current) {\r\n result.push(current);\r\n current = current.parent;\r\n }\r\n return result.reverse();\r\n }\r\n\r\n /**\r\n * Returns a list of all the entities that descend from this entity. Includes the current entity.\r\n */\r\n public getDescendants(): Entity[] {\r\n let result: Entity[] = [this];\r\n let queue: Entity[] = [this];\r\n while (queue.length > 0) {\r\n const curr = queue.pop();\r\n queue = queue.concat(curr.children);\r\n result = result.concat(curr.children);\r\n }\r\n return result;\r\n }\r\n\r\n /**\r\n * Creates a deep copy of the entity and a copy of all its components\r\n */\r\n public clone(): Entity {\r\n const newEntity = new Entity();\r\n for (const c of this.types) {\r\n newEntity.addComponent(this.get(c).clone());\r\n }\r\n for (const child of this.children) {\r\n newEntity.addChild(child.clone());\r\n }\r\n return newEntity;\r\n }\r\n\r\n /**\r\n * Adds a copy of all the components from another template entity as a \"prefab\"\r\n * @param templateEntity Entity to use as a template\r\n * @param force Force component replacement if it already exists on the target entity\r\n */\r\n public addTemplate(templateEntity: Entity, force: boolean = false): Entity {\r\n for (const c of templateEntity.getComponents()) {\r\n this.addComponent(c.clone(), force);\r\n }\r\n for (const child of templateEntity.children) {\r\n this.addChild(child.clone().addTemplate(child));\r\n }\r\n return this;\r\n }\r\n\r\n /**\r\n * Adds a component to the entity\r\n * @param component Component or Entity to add copy of components from\r\n * @param force Optionally overwrite any existing components of the same type\r\n */\r\n public addComponent(component: T, force: boolean = false): Entity {\r\n // if component already exists, skip if not forced\r\n if (this.has(component.type)) {\r\n if (force) {\r\n // Remove existing component type if exists when forced\r\n this.removeComponent(component, true);\r\n } else {\r\n // early exit component exits\r\n return this;\r\n }\r\n }\r\n\r\n // TODO circular dependencies will be a problem\r\n if (component.dependencies && component.dependencies.length) {\r\n for (const ctor of component.dependencies) {\r\n this.addComponent(new ctor());\r\n }\r\n }\r\n\r\n component.owner = this;\r\n const constuctorType = component.constructor as ComponentCtor;\r\n this._componentTypeToInstance.set(constuctorType, component);\r\n this._componentStringToInstance.set(component.type, component);\r\n if (component.onAdd) {\r\n component.onAdd(this);\r\n }\r\n this._notifyAddComponent(component);\r\n\r\n return this;\r\n }\r\n\r\n /**\r\n * Removes a component from the entity, by default removals are deferred to the end of entity update to avoid consistency issues\r\n *\r\n * Components can be force removed with the `force` flag, the removal is not deferred and happens immediately\r\n * @param componentOrType\r\n * @param force\r\n */\r\n public removeComponent(componentOrType: ComponentOrType, force = false): Entity {\r\n if (force) {\r\n if (typeof componentOrType === 'string') {\r\n this._removeComponentByType(componentOrType);\r\n } else if (componentOrType instanceof Component) {\r\n this._removeComponentByType(componentOrType.type);\r\n }\r\n } else {\r\n this._componentsToRemove.push(componentOrType);\r\n }\r\n\r\n return this as any;\r\n }\r\n\r\n public clearComponents() {\r\n const components = this.getComponents();\r\n for (const c of components) {\r\n this.removeComponent(c);\r\n }\r\n }\r\n\r\n private _removeComponentByType(type: string) {\r\n if (this.has(type)) {\r\n const component = this.get(type);\r\n component.owner = null;\r\n if (component.onRemove) {\r\n component.onRemove(this);\r\n }\r\n const ctor = component.constructor as ComponentCtor;\r\n this._componentTypeToInstance.delete(ctor);\r\n this._componentStringToInstance.delete(component.type);\r\n this._notifyRemoveComponent(component);\r\n }\r\n }\r\n\r\n /**\r\n * @hidden\r\n * @internal\r\n */\r\n public processComponentRemoval() {\r\n for (const componentOrType of this._componentsToRemove) {\r\n const type = typeof componentOrType === 'string' ? componentOrType : componentOrType.type;\r\n this._removeComponentByType(type);\r\n }\r\n this._componentsToRemove.length = 0;\r\n }\r\n\r\n /**\r\n * Check if a component type exists\r\n * @param type\r\n */\r\n public has(type: ComponentCtor): boolean;\r\n public has(type: string): boolean;\r\n public has(type: ComponentCtor | string): boolean {\r\n if (typeof type === 'string') {\r\n return this._componentStringToInstance.has(type);\r\n } else {\r\n return this._componentTypeToInstance.has(type);\r\n }\r\n }\r\n\r\n /**\r\n * Get a component by type with typecheck\r\n *\r\n * (Does not work on tag components, use .hasTag(\"mytag\") instead)\r\n * @param type\r\n */\r\n public get(type: ComponentCtor): T | null;\r\n public get(type: string): T | null;\r\n public get(type: ComponentCtor | string): T | null {\r\n if (typeof type === 'string') {\r\n return this._componentStringToInstance.get(type) as T;\r\n } else {\r\n return this._componentTypeToInstance.get(type) as T;\r\n }\r\n }\r\n\r\n private _isInitialized = false;\r\n\r\n /**\r\n * Gets whether the actor is Initialized\r\n */\r\n public get isInitialized(): boolean {\r\n return this._isInitialized;\r\n }\r\n\r\n /**\r\n * Initializes this entity, meant to be called by the Scene before first update not by users of Excalibur.\r\n *\r\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\r\n *\r\n * @internal\r\n */\r\n public _initialize(engine: Engine) {\r\n if (!this.isInitialized) {\r\n this.onInitialize(engine);\r\n this.events.emit('initialize', new InitializeEvent(engine, this));\r\n this._isInitialized = true;\r\n }\r\n }\r\n\r\n /**\r\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\r\n *\r\n * Internal _preupdate handler for [[onPreUpdate]] lifecycle event\r\n * @internal\r\n */\r\n public _preupdate(engine: Engine, delta: number): void {\r\n this.events.emit('preupdate', new PreUpdateEvent(engine, delta, this));\r\n this.onPreUpdate(engine, delta);\r\n }\r\n\r\n /**\r\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\r\n *\r\n * Internal _preupdate handler for [[onPostUpdate]] lifecycle event\r\n * @internal\r\n */\r\n public _postupdate(engine: Engine, delta: number): void {\r\n this.events.emit('postupdate', new PostUpdateEvent(engine, delta, this));\r\n this.onPostUpdate(engine, delta);\r\n }\r\n\r\n /**\r\n * `onInitialize` is called before the first update of the entity. This method is meant to be\r\n * overridden.\r\n *\r\n * Synonymous with the event handler `.on('initialize', (evt) => {...})`\r\n */\r\n public onInitialize(_engine: Engine): void {\r\n // Override me\r\n }\r\n\r\n /**\r\n * Safe to override onPreUpdate lifecycle event handler. Synonymous with `.on('preupdate', (evt) =>{...})`\r\n *\r\n * `onPreUpdate` is called directly before an entity is updated.\r\n */\r\n public onPreUpdate(_engine: Engine, _delta: number): void {\r\n // Override me\r\n }\r\n\r\n /**\r\n * Safe to override onPostUpdate lifecycle event handler. Synonymous with `.on('postupdate', (evt) =>{...})`\r\n *\r\n * `onPostUpdate` is called directly after an entity is updated.\r\n */\r\n public onPostUpdate(_engine: Engine, _delta: number): void {\r\n // Override me\r\n }\r\n\r\n /**\r\n *\r\n * Entity update lifecycle, called internally\r\n *\r\n * @internal\r\n * @param engine\r\n * @param delta\r\n */\r\n public update(engine: Engine, delta: number): void {\r\n this._initialize(engine);\r\n this._preupdate(engine, delta);\r\n for (const child of this.children) {\r\n child.update(engine, delta);\r\n }\r\n this._postupdate(engine, delta);\r\n }\r\n\r\n public emit>(eventName: TEventName, event: EntityEvents[TEventName]): void;\r\n public emit(eventName: string, event?: any): void;\r\n public emit | string>(eventName: TEventName, event?: any): void {\r\n this.events.emit(eventName, event);\r\n }\r\n\r\n public on>(eventName: TEventName, handler: Handler): Subscription;\r\n public on(eventName: string, handler: Handler): Subscription;\r\n public on | string>(eventName: TEventName, handler: Handler): Subscription {\r\n return this.events.on(eventName, handler);\r\n }\r\n\r\n public once>(eventName: TEventName, handler: Handler): Subscription;\r\n public once(eventName: string, handler: Handler): Subscription;\r\n public once | string>(eventName: TEventName, handler: Handler): Subscription {\r\n return this.events.once(eventName, handler);\r\n }\r\n\r\n public off>(eventName: TEventName, handler: Handler): void;\r\n public off(eventName: string, handler: Handler): void;\r\n public off(eventName: string): void;\r\n public off | string>(eventName: TEventName, handler?: Handler): void {\r\n this.events.off(eventName, handler);\r\n }\r\n}\r\n","import { Vector, vec } from '../Math/vector';\r\nimport { Graphic } from './Graphic';\r\nimport { HasTick } from './Animation';\r\nimport { ExcaliburGraphicsContext } from './Context/ExcaliburGraphicsContext';\r\nimport { Logger } from '../Util/Log';\r\nimport { BoundingBox } from '../Collision/Index';\r\nimport { Component } from '../EntityComponentSystem/Component';\r\nimport { Material } from './Context/material';\r\n\r\n/**\r\n * Type guard for checking if a Graphic HasTick (used for graphics that change over time like animations)\r\n * @param graphic\r\n */\r\nexport function hasGraphicsTick(graphic: Graphic): graphic is Graphic & HasTick {\r\n return !!(graphic as unknown as HasTick).tick;\r\n}\r\nexport interface GraphicsShowOptions {\r\n offset?: Vector;\r\n anchor?: Vector;\r\n}\r\n\r\nexport interface GraphicsComponentOptions {\r\n onPostDraw?: (ex: ExcaliburGraphicsContext, elapsed: number) => void;\r\n onPreDraw?: (ex: ExcaliburGraphicsContext, elapsed: number) => void;\r\n\r\n /**\r\n * Name of current graphic to use\r\n */\r\n current?: string;\r\n\r\n /**\r\n * Optionally copy instances of graphics by calling .clone(), you may set this to false to avoid sharing graphics when added to the\r\n * component for performance reasons. By default graphics are not copied and are shared when added to the component.\r\n */\r\n copyGraphics?: boolean;\r\n\r\n /**\r\n * Optional visible flag, if the graphics component is not visible it will not be displayed\r\n */\r\n visible?: boolean;\r\n\r\n /**\r\n * Optional opacity\r\n */\r\n opacity?: number;\r\n\r\n /**\r\n * List of graphics\r\n */\r\n graphics?: { [graphicName: string]: Graphic };\r\n\r\n /**\r\n * Optional offset in absolute pixels to shift all graphics in this component from each graphic's anchor (default is top left corner)\r\n */\r\n offset?: Vector;\r\n\r\n /**\r\n * Optional anchor\r\n */\r\n anchor?: Vector;\r\n}\r\n\r\nexport interface GraphicsLayerOptions {\r\n /**\r\n * Name of the layer required, for example 'background'\r\n */\r\n name: string;\r\n /**\r\n * Order of the layer, a layer with order -1 will be below a layer with order of 1\r\n */\r\n order: number;\r\n /**\r\n * Offset to shift the entire layer\r\n */\r\n offset?: Vector;\r\n}\r\nexport class GraphicsLayer {\r\n public graphics: { graphic: Graphic; options: GraphicsShowOptions }[] = [];\r\n constructor(private _options: GraphicsLayerOptions, private _graphics: GraphicsComponent) {}\r\n public get name(): string {\r\n return this._options.name;\r\n }\r\n\r\n /**\r\n * Remove any instance(s) of a graphic currently being shown in this layer\r\n */\r\n public hide(nameOrGraphic: string | Graphic): void;\r\n /**\r\n * Remove all currently shown graphics in this layer\r\n */\r\n public hide(): void;\r\n public hide(nameOrGraphic?: string | Graphic): void {\r\n if (!nameOrGraphic) {\r\n this.graphics.length = 0;\r\n } else {\r\n let gfx: Graphic = null;\r\n if (nameOrGraphic instanceof Graphic) {\r\n gfx = nameOrGraphic;\r\n } else {\r\n gfx = this._graphics.getGraphic(nameOrGraphic);\r\n }\r\n this.graphics = this.graphics.filter((g) => g.graphic !== gfx);\r\n this._graphics.recalculateBounds();\r\n }\r\n }\r\n\r\n /**\r\n * Show a graphic by name or instance at an offset, graphics are shown in the order in which `show()` is called.\r\n *\r\n * If `show()` is called multiple times for the same graphic it will be shown multiple times.\r\n * @param nameOrGraphic\r\n * @param options\r\n */\r\n public show(nameOrGraphic: string | T, options?: GraphicsShowOptions): T {\r\n options = { ...options };\r\n let gfx: Graphic;\r\n if (nameOrGraphic instanceof Graphic) {\r\n gfx = this._graphics.copyGraphics ? nameOrGraphic.clone() : nameOrGraphic;\r\n } else {\r\n gfx = this._graphics.getGraphic(nameOrGraphic);\r\n if (!gfx) {\r\n Logger.getInstance().error(\r\n `No such graphic added to component named ${nameOrGraphic}. These named graphics are available: `,\r\n this._graphics.getNames()\r\n );\r\n }\r\n }\r\n if (gfx) {\r\n this.graphics.push({ graphic: gfx, options });\r\n this._graphics.recalculateBounds();\r\n return gfx as T;\r\n } else {\r\n return null;\r\n }\r\n }\r\n\r\n /**\r\n * Use a specific graphic, swap out any current graphics being shown\r\n * @param nameOrGraphic\r\n * @param options\r\n */\r\n public use(nameOrGraphic: string | T, options?: GraphicsShowOptions): T {\r\n options = { ...options };\r\n this.hide();\r\n return this.show(nameOrGraphic, options);\r\n }\r\n\r\n /**\r\n * Current order of the layer, higher numbers are on top, lower numbers are on the bottom.\r\n *\r\n * For example a layer with `order = -1` would be under a layer of `order = 1`\r\n */\r\n public get order(): number {\r\n return this._options.order;\r\n }\r\n\r\n /**\r\n * Set the order of the layer, higher numbers are on top, lower numbers are on the bottom.\r\n *\r\n * For example a layer with `order = -1` would be under a layer of `order = 1`\r\n */\r\n public set order(order: number) {\r\n this._options.order = order;\r\n }\r\n\r\n /**\r\n * Get or set the pixel offset from the layer anchor for all graphics in the layer\r\n */\r\n public get offset(): Vector {\r\n return this._options.offset ?? Vector.Zero;\r\n }\r\n\r\n public set offset(value: Vector) {\r\n this._options.offset = value;\r\n }\r\n\r\n public get currentKeys(): string {\r\n return this.name ?? 'anonymous';\r\n }\r\n\r\n public clone(graphicsComponent: GraphicsComponent): GraphicsLayer {\r\n const layer = new GraphicsLayer({...this._options}, graphicsComponent);\r\n layer.graphics = [...this.graphics.map(g => ({graphic: g.graphic.clone(), options: {...g.options}}))];\r\n return layer;\r\n }\r\n}\r\n\r\nexport class GraphicsLayers {\r\n private _layers: GraphicsLayer[] = [];\r\n private _layerMap: { [layerName: string]: GraphicsLayer } = {};\r\n public default: GraphicsLayer;\r\n constructor(private _component: GraphicsComponent) {\r\n this.default = new GraphicsLayer({ name: 'default', order: 0 }, _component);\r\n this._maybeAddLayer(this.default);\r\n }\r\n public create(options: GraphicsLayerOptions): GraphicsLayer {\r\n const layer = new GraphicsLayer(options, this._component);\r\n return this._maybeAddLayer(layer);\r\n }\r\n\r\n /**\r\n * Retrieve a single layer by name\r\n * @param name\r\n */\r\n public get(name: string): GraphicsLayer;\r\n /**\r\n * Retrieve all layers\r\n */\r\n public get(): readonly GraphicsLayer[];\r\n public get(name?: string): GraphicsLayer | readonly GraphicsLayer[] {\r\n if (name) {\r\n return this._getLayer(name);\r\n }\r\n return this._layers;\r\n }\r\n\r\n public currentKeys() {\r\n const graphicsLayerKeys = [];\r\n for (const layer of this._layers) {\r\n graphicsLayerKeys.push(layer.currentKeys);\r\n }\r\n return graphicsLayerKeys;\r\n }\r\n\r\n public has(name: string): boolean {\r\n return name in this._layerMap;\r\n }\r\n\r\n private _maybeAddLayer(layer: GraphicsLayer) {\r\n if (this._layerMap[layer.name]) {\r\n // todo log warning\r\n return this._layerMap[layer.name];\r\n }\r\n this._layerMap[layer.name] = layer;\r\n this._layers.push(layer);\r\n this._layers.sort((a, b) => a.order - b.order);\r\n return layer;\r\n }\r\n\r\n private _getLayer(name: string): GraphicsLayer | undefined {\r\n return this._layerMap[name];\r\n }\r\n\r\n public clone(graphicsComponent: GraphicsComponent): GraphicsLayers {\r\n const layers = new GraphicsLayers(graphicsComponent);\r\n layers._layerMap = {};\r\n layers._layers = [];\r\n layers.default = this.default.clone(graphicsComponent);\r\n layers._maybeAddLayer(layers.default);\r\n // Remove the default layer out of the clone\r\n const clonedLayers = this._layers.filter(l => l.name !== 'default').map(l => l.clone(graphicsComponent));\r\n clonedLayers.forEach(layer => layers._maybeAddLayer(layer));\r\n return layers;\r\n }\r\n}\r\n\r\n/**\r\n * Component to manage drawings, using with the position component\r\n */\r\nexport class GraphicsComponent extends Component<'ex.graphics'> {\r\n readonly type = 'ex.graphics';\r\n\r\n private _graphics: { [graphicName: string]: Graphic } = {};\r\n\r\n public layers: GraphicsLayers;\r\n\r\n public material: Material;\r\n\r\n public getGraphic(name: string): Graphic | undefined {\r\n return this._graphics[name];\r\n }\r\n\r\n /**\r\n * Get registered graphics names\r\n */\r\n public getNames(): string[] {\r\n return Object.keys(this._graphics);\r\n }\r\n\r\n /**\r\n * Draws after the entity transform has bene applied, but before graphics component graphics have been drawn\r\n */\r\n public onPreDraw: (ctx: ExcaliburGraphicsContext, elapsedMilliseconds: number) => void;\r\n\r\n /**\r\n * Draws after the entity transform has been applied, and after graphics component graphics has been drawn\r\n */\r\n public onPostDraw: (ctx: ExcaliburGraphicsContext, elapsedMilliseconds: number) => void;\r\n\r\n /**\r\n * Sets or gets wether any drawing should be visible in this component\r\n */\r\n public visible: boolean = true;\r\n\r\n /**\r\n * Sets or gets wither all drawings should have an opacity applied\r\n */\r\n public opacity: number = 1;\r\n\r\n /**\r\n * Offset to apply to graphics by default\r\n */\r\n public offset: Vector = Vector.Zero;\r\n\r\n /**\r\n * Anchor to apply to graphics by default\r\n */\r\n public anchor: Vector = Vector.Half;\r\n\r\n /**\r\n * Flip all graphics horizontally along the y-axis\r\n */\r\n public flipHorizontal: boolean = false;\r\n\r\n /**\r\n * Flip all graphics vertically along the x-axis\r\n */\r\n public flipVertical: boolean = false;\r\n\r\n /**\r\n * If set to true graphics added to the component will be copied. This can affect performance\r\n */\r\n public copyGraphics: boolean = false;\r\n\r\n constructor(options?: GraphicsComponentOptions) {\r\n super();\r\n // Defaults\r\n options = {\r\n visible: this.visible,\r\n ...options\r\n };\r\n\r\n const { current, anchor, opacity, visible, graphics, offset, copyGraphics, onPreDraw, onPostDraw } = options;\r\n\r\n this._graphics = graphics || {};\r\n this.offset = offset ?? this.offset;\r\n this.opacity = opacity ?? this.opacity;\r\n this.anchor = anchor ?? this.anchor;\r\n this.copyGraphics = copyGraphics ?? this.copyGraphics;\r\n this.onPreDraw = onPreDraw ?? this.onPreDraw;\r\n this.onPostDraw = onPostDraw ?? this.onPostDraw;\r\n this.visible = !!visible;\r\n\r\n this.layers = new GraphicsLayers(this);\r\n if (current && this._graphics[current]) {\r\n this.show(this._graphics[current]);\r\n }\r\n }\r\n\r\n /**\r\n * Returns the currently displayed graphics and their offsets, empty array if hidden\r\n */\r\n public get current(): { graphic: Graphic; options: GraphicsShowOptions }[] {\r\n return this.layers.default.graphics;\r\n }\r\n\r\n /**\r\n * Returns all graphics associated with this component\r\n */\r\n public get graphics(): { [graphicName: string]: Graphic } {\r\n return this._graphics;\r\n }\r\n\r\n /**\r\n * Adds a named graphic to this component, if the name is \"default\" or not specified, it will be shown by default without needing to call\r\n * `show(\"default\")`\r\n * @param graphic\r\n */\r\n public add(graphic: Graphic): Graphic;\r\n public add(name: string, graphic: Graphic): Graphic;\r\n public add(nameOrGraphic: string | Graphic, graphic?: Graphic): Graphic {\r\n let name = 'default';\r\n let graphicToSet: Graphic = null;\r\n if (typeof nameOrGraphic === 'string') {\r\n name = nameOrGraphic;\r\n graphicToSet = graphic;\r\n } else {\r\n graphicToSet = nameOrGraphic;\r\n }\r\n\r\n this._graphics[name] = this.copyGraphics ? graphicToSet.clone() : graphicToSet;\r\n if (name === 'default') {\r\n this.show('default');\r\n }\r\n return graphicToSet;\r\n }\r\n\r\n /**\r\n * Show a graphic by name on the **default** layer, returns the new [[Graphic]]\r\n */\r\n public show(nameOrGraphic: string | T, options?: GraphicsShowOptions): T {\r\n const result = this.layers.default.show(nameOrGraphic, options);\r\n this.recalculateBounds();\r\n return result;\r\n }\r\n\r\n /**\r\n * Use a graphic only, swap out any graphics on the **default** layer, returns the new [[Graphic]]\r\n * @param nameOrGraphic\r\n * @param options\r\n */\r\n public use(nameOrGraphic: string | T, options?: GraphicsShowOptions): T {\r\n const result = this.layers.default.use(nameOrGraphic, options);\r\n this.recalculateBounds();\r\n return result;\r\n }\r\n\r\n /**\r\n * Remove any instance(s) of a graphic currently being shown in the **default** layer\r\n */\r\n public hide(nameOrGraphic: string | Graphic): void;\r\n /**\r\n * Remove all currently shown graphics in the **default** layer\r\n */\r\n public hide(): void;\r\n public hide(nameOrGraphic?: string | Graphic): void {\r\n this.layers.default.hide(nameOrGraphic);\r\n }\r\n\r\n private _localBounds: BoundingBox = null;\r\n public set localBounds(bounds: BoundingBox) {\r\n this._localBounds = bounds;\r\n }\r\n\r\n public recalculateBounds() {\r\n let bb = new BoundingBox();\r\n for (const layer of this.layers.get()) {\r\n for (const { graphic, options } of layer.graphics) {\r\n let anchor = this.anchor;\r\n let offset = this.offset;\r\n if (options?.anchor) {\r\n anchor = options.anchor;\r\n }\r\n if (options?.offset) {\r\n offset = options.offset;\r\n }\r\n const bounds = graphic.localBounds;\r\n const offsetX = -bounds.width * anchor.x + offset.x;\r\n const offsetY = -bounds.height * anchor.y + offset.y;\r\n bb = graphic?.localBounds.translate(vec(offsetX + layer.offset.x, offsetY + layer.offset.y)).combine(bb);\r\n }\r\n }\r\n this._localBounds = bb;\r\n }\r\n\r\n public get localBounds(): BoundingBox {\r\n if (!this._localBounds || this._localBounds.hasZeroDimensions()) {\r\n this.recalculateBounds();\r\n }\r\n return this._localBounds;\r\n }\r\n\r\n /**\r\n * Update underlying graphics if necesary, called internally\r\n * @param elapsed\r\n * @internal\r\n */\r\n public update(elapsed: number, idempotencyToken: number = 0) {\r\n for (const layer of this.layers.get()) {\r\n for (const { graphic } of layer.graphics) {\r\n if (hasGraphicsTick(graphic)) {\r\n graphic?.tick(elapsed, idempotencyToken);\r\n }\r\n }\r\n }\r\n }\r\n\r\n public clone(): GraphicsComponent {\r\n const graphics = new GraphicsComponent();\r\n graphics._graphics = { ...this._graphics };\r\n graphics.offset = this.offset.clone();\r\n graphics.opacity = this.opacity;\r\n graphics.anchor = this.anchor.clone();\r\n graphics.copyGraphics = this.copyGraphics;\r\n graphics.onPreDraw = this.onPreDraw;\r\n graphics.onPostDraw = this.onPostDraw;\r\n graphics.visible = this.visible;\r\n graphics.layers = this.layers.clone(graphics);\r\n\r\n return graphics;\r\n }\r\n}\r\n","import { Raster, RasterOptions } from './Raster';\r\n\r\nexport interface RectangleOptions {\r\n width: number;\r\n height: number;\r\n}\r\n\r\n/**\r\n * A Rectangle [[Graphic]] for drawing rectangles to the [[ExcaliburGraphicsContext]]\r\n */\r\nexport class Rectangle extends Raster {\r\n constructor(options: RasterOptions & RectangleOptions) {\r\n super(options);\r\n this.width = options.width;\r\n this.height = options.height;\r\n this.rasterize();\r\n }\r\n\r\n public clone(): Rectangle {\r\n return new Rectangle({\r\n width: this.width,\r\n height: this.height,\r\n ...this.cloneGraphicOptions(),\r\n ...this.cloneRasterOptions()\r\n });\r\n }\r\n\r\n execute(ctx: CanvasRenderingContext2D): void {\r\n if (this.color) {\r\n ctx.fillRect(0, 0, this.width, this.height);\r\n }\r\n if (this.strokeColor) {\r\n ctx.strokeRect(0, 0, this.width, this.height);\r\n }\r\n }\r\n}\r\n","import { ImageFiltering } from '.';\r\nimport { Raster, RasterOptions } from './Raster';\r\n\r\nexport interface CircleOptions {\r\n radius: number;\r\n}\r\n\r\n/**\r\n * A circle [[Graphic]] for drawing circles to the [[ExcaliburGraphicsContext]]\r\n *\r\n * Circles default to [[ImageFiltering.Blended]]\r\n */\r\nexport class Circle extends Raster {\r\n private _radius: number = 0;\r\n public get radius() {\r\n return this._radius;\r\n }\r\n public set radius(value: number) {\r\n this._radius = value;\r\n this.width = this._radius * 2;\r\n this.height = this._radius * 2;\r\n this.flagDirty();\r\n }\r\n constructor(options: RasterOptions & CircleOptions) {\r\n super(options);\r\n const lineWidth = options.lineWidth ?? (options.strokeColor ? 1 : 0); // default lineWidth in canvas is 1px\r\n this.padding = options.padding ?? 2 + (lineWidth / 2); // default 2 padding for circles looks nice\r\n this.radius = options.radius;\r\n this.filtering = options.filtering ?? ImageFiltering.Blended;\r\n this.rasterize();\r\n }\r\n\r\n public clone(): Circle {\r\n return new Circle({\r\n radius: this.radius,\r\n ...this.cloneGraphicOptions(),\r\n ...this.cloneRasterOptions()\r\n });\r\n }\r\n\r\n execute(ctx: CanvasRenderingContext2D): void {\r\n if (this.radius > 0) {\r\n ctx.beginPath();\r\n ctx.arc(this.radius, this.radius, this.radius, 0, Math.PI * 2);\r\n\r\n if (this.color) {\r\n ctx.fill();\r\n }\r\n\r\n if (this.strokeColor) {\r\n ctx.stroke();\r\n }\r\n }\r\n }\r\n}\r\n","import { Component } from '../EntityComponentSystem/Component';\r\n\r\n/**\r\n * Add this component to optionally configure how the pointer\r\n * system detects pointer events.\r\n *\r\n * By default the collider shape is used and graphics bounds is not.\r\n *\r\n * If both collider shape and graphics bounds are enabled it will fire events if either or\r\n * are intersecting the pointer.\r\n */\r\nexport class PointerComponent extends Component<'ex.pointer'> {\r\n public readonly type = 'ex.pointer';\r\n /**\r\n * Use any existing Collider component geometry for pointer events. This is useful if you want\r\n * user pointer events only to trigger on the same collision geometry used in the collider component\r\n * for collision resolution. Default is `true`.\r\n */\r\n public useColliderShape = true;\r\n /**\r\n * Use any existing Graphics component bounds for pointers. This is useful if you want the axis aligned\r\n * bounds around the graphic to trigger pointer events. Default is `false`.\r\n */\r\n public useGraphicsBounds = false;\r\n}","import { Vector } from '../Math/vector';\r\n\r\n/**\r\n * A definition of an EasingFunction. See [[EasingFunctions]].\r\n */\r\n// tslint:disable-next-line\r\nexport interface EasingFunction {\r\n (currentTime: number, startValue: number, endValue: number, duration: number): number;\r\n}\r\n\r\n/**\r\n * Standard easing functions for motion in Excalibur, defined on a domain of [0, duration] and a range from [+startValue,+endValue]\r\n * Given a time, the function will return a value from positive startValue to positive endValue.\r\n *\r\n * ```js\r\n * function Linear (t) {\r\n * return t * t;\r\n * }\r\n *\r\n * // accelerating from zero velocity\r\n * function EaseInQuad (t) {\r\n * return t * t;\r\n * }\r\n *\r\n * // decelerating to zero velocity\r\n * function EaseOutQuad (t) {\r\n * return t * (2 - t);\r\n * }\r\n *\r\n * // acceleration until halfway, then deceleration\r\n * function EaseInOutQuad (t) {\r\n * return t < .5 ? 2 * t * t : -1 + (4 - 2 * t) * t;\r\n * }\r\n *\r\n * // accelerating from zero velocity\r\n * function EaseInCubic (t) {\r\n * return t * t * t;\r\n * }\r\n *\r\n * // decelerating to zero velocity\r\n * function EaseOutCubic (t) {\r\n * return (--t) * t * t + 1;\r\n * }\r\n *\r\n * // acceleration until halfway, then deceleration\r\n * function EaseInOutCubic (t) {\r\n * return t < .5 ? 4 * t * t * t : (t - 1) * (2 * t - 2) * (2 * t - 2) + 1;\r\n * }\r\n * ```\r\n */\r\nexport class EasingFunctions {\r\n public static CreateReversibleEasingFunction(easing: EasingFunction) {\r\n return (time: number, start: number, end: number, duration: number) => {\r\n if (end < start) {\r\n return start - (easing(time, end, start, duration) - end);\r\n } else {\r\n return easing(time, start, end, duration);\r\n }\r\n };\r\n }\r\n\r\n public static CreateVectorEasingFunction(easing: EasingFunction) {\r\n return (time: number, start: Vector, end: Vector, duration: number) => {\r\n return new Vector(easing(time, start.x, end.x, duration), easing(time, start.y, end.y, duration));\r\n };\r\n }\r\n\r\n public static Linear: EasingFunction = EasingFunctions.CreateReversibleEasingFunction(\r\n (currentTime: number, startValue: number, endValue: number, duration: number) => {\r\n endValue = endValue - startValue;\r\n return (endValue * currentTime) / duration + startValue;\r\n }\r\n );\r\n\r\n public static EaseInQuad = EasingFunctions.CreateReversibleEasingFunction(\r\n (currentTime: number, startValue: number, endValue: number, duration: number) => {\r\n endValue = endValue - startValue;\r\n currentTime /= duration;\r\n\r\n return endValue * currentTime * currentTime + startValue;\r\n }\r\n );\r\n\r\n public static EaseOutQuad: EasingFunction = EasingFunctions.CreateReversibleEasingFunction(\r\n (currentTime: number, startValue: number, endValue: number, duration: number) => {\r\n endValue = endValue - startValue;\r\n currentTime /= duration;\r\n return -endValue * currentTime * (currentTime - 2) + startValue;\r\n }\r\n );\r\n\r\n public static EaseInOutQuad: EasingFunction = EasingFunctions.CreateReversibleEasingFunction(\r\n (currentTime: number, startValue: number, endValue: number, duration: number) => {\r\n endValue = endValue - startValue;\r\n currentTime /= duration / 2;\r\n\r\n if (currentTime < 1) {\r\n return (endValue / 2) * currentTime * currentTime + startValue;\r\n }\r\n currentTime--;\r\n\r\n return (-endValue / 2) * (currentTime * (currentTime - 2) - 1) + startValue;\r\n }\r\n );\r\n\r\n public static EaseInCubic: EasingFunction = EasingFunctions.CreateReversibleEasingFunction(\r\n (currentTime: number, startValue: number, endValue: number, duration: number) => {\r\n endValue = endValue - startValue;\r\n currentTime /= duration;\r\n return endValue * currentTime * currentTime * currentTime + startValue;\r\n }\r\n );\r\n\r\n public static EaseOutCubic: EasingFunction = EasingFunctions.CreateReversibleEasingFunction(\r\n (currentTime: number, startValue: number, endValue: number, duration: number) => {\r\n endValue = endValue - startValue;\r\n currentTime /= duration;\r\n currentTime--;\r\n return endValue * (currentTime * currentTime * currentTime + 1) + startValue;\r\n }\r\n );\r\n\r\n public static EaseInOutCubic: EasingFunction = EasingFunctions.CreateReversibleEasingFunction(\r\n (currentTime: number, startValue: number, endValue: number, duration: number) => {\r\n endValue = endValue - startValue;\r\n currentTime /= duration / 2;\r\n if (currentTime < 1) {\r\n return (endValue / 2) * currentTime * currentTime * currentTime + startValue;\r\n }\r\n currentTime -= 2;\r\n return (endValue / 2) * (currentTime * currentTime * currentTime + 2) + startValue;\r\n }\r\n );\r\n}\r\n","import { Entity } from '../EntityComponentSystem/Entity';\r\nimport { Action } from './Action';\r\n\r\n/**\r\n * Action Queues represent an ordered sequence of actions\r\n *\r\n * Action queues are part of the [[ActionContext|Action API]] and\r\n * store the list of actions to be executed for an [[Actor]].\r\n *\r\n * Actors implement [[Actor.actions]] which can be manipulated by\r\n * advanced users to adjust the actions currently being executed in the\r\n * queue.\r\n */\r\nexport class ActionQueue {\r\n private _entity: Entity;\r\n private _actions: Action[] = [];\r\n private _currentAction: Action;\r\n private _completedActions: Action[] = [];\r\n constructor(entity: Entity) {\r\n this._entity = entity;\r\n }\r\n\r\n /**\r\n * Add an action to the sequence\r\n * @param action\r\n */\r\n public add(action: Action) {\r\n this._actions.push(action);\r\n }\r\n\r\n /**\r\n * Remove an action by reference from the sequence\r\n * @param action\r\n */\r\n public remove(action: Action) {\r\n const index = this._actions.indexOf(action);\r\n this._actions.splice(index, 1);\r\n }\r\n\r\n /**\r\n * Removes all actions from this sequence\r\n */\r\n public clearActions(): void {\r\n this._actions.length = 0;\r\n this._completedActions.length = 0;\r\n if (this._currentAction) {\r\n this._currentAction.stop();\r\n }\r\n }\r\n\r\n /**\r\n *\r\n * @returns The total list of actions in this sequence complete or not\r\n */\r\n public getActions(): Action[] {\r\n return this._actions.concat(this._completedActions);\r\n }\r\n\r\n /**\r\n *\r\n * @returns `true` if there are more actions to process in the sequence\r\n */\r\n public hasNext(): boolean {\r\n return this._actions.length > 0;\r\n }\r\n\r\n /**\r\n * @returns `true` if the current sequence of actions is done\r\n */\r\n public isComplete(): boolean {\r\n return this._actions.length === 0;\r\n }\r\n\r\n /**\r\n * Resets the sequence of actions, this is used to restart a sequence from the beginning\r\n */\r\n public reset(): void {\r\n this._actions = this.getActions();\r\n\r\n const len = this._actions.length;\r\n for (let i = 0; i < len; i++) {\r\n this._actions[i].reset();\r\n }\r\n this._completedActions = [];\r\n }\r\n\r\n /**\r\n * Update the queue which updates actions and handles completing actions\r\n * @param elapsedMs\r\n */\r\n public update(elapsedMs: number) {\r\n if (this._actions.length > 0) {\r\n this._currentAction = this._actions[0];\r\n this._currentAction.update(elapsedMs);\r\n\r\n if (this._currentAction.isComplete(this._entity)) {\r\n this._completedActions.push(this._actions.shift());\r\n }\r\n }\r\n }\r\n}\r\n","import { Entity } from '../../EntityComponentSystem/Entity';\r\nimport { Action } from '../Action';\r\nimport { ActionContext } from '../ActionContext';\r\nimport { ActionQueue } from '../ActionQueue';\r\n\r\nexport class Repeat implements Action {\r\n private _actionQueue: ActionQueue;\r\n private _repeat: number;\r\n private _originalRepeat: number;\r\n private _stopped: boolean = false;\r\n private _repeatContext: ActionContext;\r\n private _repeatBuilder: (repeatContext: ActionContext) => any;\r\n constructor(entity: Entity, repeatBuilder: (repeatContext: ActionContext) => any, repeat: number) {\r\n this._repeatBuilder = repeatBuilder;\r\n this._repeatContext = new ActionContext(entity);\r\n this._actionQueue = this._repeatContext.getQueue();\r\n\r\n this._repeat = repeat;\r\n this._originalRepeat = repeat;\r\n\r\n this._repeatBuilder(this._repeatContext);\r\n this._repeat--; // current execution is the first repeat\r\n }\r\n\r\n public update(delta: number): void {\r\n if (this._actionQueue.isComplete()) {\r\n this._actionQueue.clearActions();\r\n this._repeatBuilder(this._repeatContext);\r\n this._repeat--;\r\n }\r\n this._actionQueue.update(delta);\r\n }\r\n\r\n public isComplete(): boolean {\r\n return this._stopped || (this._repeat <= 0 && this._actionQueue.isComplete());\r\n }\r\n\r\n public stop(): void {\r\n this._stopped = true;\r\n }\r\n\r\n public reset(): void {\r\n this._repeat = this._originalRepeat;\r\n }\r\n}\r\n","import { Entity } from '../../EntityComponentSystem/Entity';\r\nimport { Action } from '../Action';\r\nimport { ActionContext } from '../ActionContext';\r\nimport { ActionQueue } from '../ActionQueue';\r\n\r\n/**\r\n * RepeatForever Action implementation, it is recommended you use the fluent action\r\n * context API.\r\n *\r\n *\r\n */\r\nexport class RepeatForever implements Action {\r\n private _actionQueue: ActionQueue;\r\n private _stopped: boolean = false;\r\n private _repeatContext: ActionContext;\r\n private _repeatBuilder: (repeatContext: ActionContext) => any;\r\n constructor(entity: Entity, repeatBuilder: (repeatContext: ActionContext) => any) {\r\n this._repeatBuilder = repeatBuilder;\r\n this._repeatContext = new ActionContext(entity);\r\n this._actionQueue = this._repeatContext.getQueue();\r\n\r\n this._repeatBuilder(this._repeatContext);\r\n }\r\n\r\n public update(delta: number): void {\r\n if (this._stopped) {\r\n return;\r\n }\r\n\r\n if (this._actionQueue.isComplete()) {\r\n this._actionQueue.clearActions();\r\n this._repeatBuilder(this._repeatContext);\r\n }\r\n\r\n this._actionQueue.update(delta);\r\n }\r\n\r\n public isComplete(): boolean {\r\n return this._stopped;\r\n }\r\n\r\n public stop(): void {\r\n this._stopped = true;\r\n this._actionQueue.clearActions();\r\n }\r\n\r\n public reset(): void {\r\n return;\r\n }\r\n}\r\n","import { MotionComponent } from '../../EntityComponentSystem/Components/MotionComponent';\r\nimport { TransformComponent } from '../../EntityComponentSystem/Components/TransformComponent';\r\nimport { Entity } from '../../EntityComponentSystem/Entity';\r\nimport { Vector, vec } from '../../Math/vector';\r\nimport { Logger } from '../../Util/Log';\r\nimport { Action } from '../Action';\r\n\r\nexport class MoveBy implements Action {\r\n private _tx: TransformComponent;\r\n private _motion: MotionComponent;\r\n private _entity: Entity;\r\n public x: number;\r\n public y: number;\r\n private _distance: number;\r\n private _speed: number;\r\n\r\n private _start: Vector;\r\n private _offset: Vector;\r\n private _end: Vector;\r\n private _dir: Vector;\r\n private _started = false;\r\n private _stopped = false;\r\n\r\n constructor(entity: Entity, offsetX: number, offsetY: number, speed: number) {\r\n this._entity = entity;\r\n this._tx = entity.get(TransformComponent);\r\n this._motion = entity.get(MotionComponent);\r\n this._speed = speed;\r\n this._offset = new Vector(offsetX, offsetY);\r\n if (speed <= 0) {\r\n Logger.getInstance().error('Attempted to moveBy with speed less than or equal to zero : ' + speed);\r\n throw new Error('Speed must be greater than 0 pixels per second');\r\n }\r\n }\r\n\r\n public update(_delta: number) {\r\n if (!this._started) {\r\n this._started = true;\r\n this._start = new Vector(this._tx.pos.x, this._tx.pos.y);\r\n this._end = this._start.add(this._offset);\r\n this._distance = this._offset.size;\r\n this._dir = this._end.sub(this._start).normalize();\r\n }\r\n\r\n if (this.isComplete(this._entity)) {\r\n this._tx.pos = vec(this._end.x, this._end.y);\r\n this._motion.vel = vec(0, 0);\r\n } else {\r\n this._motion.vel = this._dir.scale(this._speed);\r\n }\r\n }\r\n\r\n public isComplete(entity: Entity): boolean {\r\n const tx = entity.get(TransformComponent);\r\n return this._stopped || tx.pos.distance(this._start) >= this._distance;\r\n }\r\n\r\n public stop(): void {\r\n this._motion.vel = vec(0, 0);\r\n this._stopped = true;\r\n }\r\n\r\n public reset(): void {\r\n this._started = false;\r\n this._stopped = false;\r\n }\r\n}\r\n","import { MotionComponent } from '../../EntityComponentSystem/Components/MotionComponent';\r\nimport { TransformComponent } from '../../EntityComponentSystem/Components/TransformComponent';\r\nimport { Entity } from '../../EntityComponentSystem/Entity';\r\nimport { Vector, vec } from '../../Math/vector';\r\nimport { Action } from '../Action';\r\n\r\nexport class MoveTo implements Action {\r\n private _tx: TransformComponent;\r\n private _motion: MotionComponent;\r\n public x: number;\r\n public y: number;\r\n private _start: Vector;\r\n private _end: Vector;\r\n private _dir: Vector;\r\n private _speed: number;\r\n private _distance: number;\r\n private _started = false;\r\n private _stopped = false;\r\n constructor(public entity: Entity, destx: number, desty: number, speed: number) {\r\n this._tx = entity.get(TransformComponent);\r\n this._motion = entity.get(MotionComponent);\r\n this._end = new Vector(destx, desty);\r\n this._speed = speed;\r\n }\r\n\r\n public update(_delta: number): void {\r\n if (!this._started) {\r\n this._started = true;\r\n this._start = new Vector(this._tx.pos.x, this._tx.pos.y);\r\n this._distance = this._start.distance(this._end);\r\n this._dir = this._end.sub(this._start).normalize();\r\n }\r\n const m = this._dir.scale(this._speed);\r\n this._motion.vel = vec(m.x, m.y);\r\n\r\n if (this.isComplete(this.entity)) {\r\n this._tx.pos = vec(this._end.x, this._end.y);\r\n this._motion.vel = vec(0, 0);\r\n }\r\n }\r\n\r\n public isComplete(entity: Entity): boolean {\r\n const tx = entity.get(TransformComponent);\r\n return this._stopped || new Vector(tx.pos.x, tx.pos.y).distance(this._start) >= this._distance;\r\n }\r\n\r\n public stop(): void {\r\n this._motion.vel = vec(0, 0);\r\n this._stopped = true;\r\n }\r\n\r\n public reset(): void {\r\n this._started = false;\r\n this._stopped = false;\r\n }\r\n}\r\n","/**\r\n * An enum that describes the strategies that rotation actions can use\r\n */\r\nexport enum RotationType {\r\n /**\r\n * Rotation via `ShortestPath` will use the smallest angle\r\n * between the starting and ending points. This strategy is the default behavior.\r\n */\r\n ShortestPath = 0,\r\n /**\r\n * Rotation via `LongestPath` will use the largest angle\r\n * between the starting and ending points.\r\n */\r\n LongestPath = 1,\r\n /**\r\n * Rotation via `Clockwise` will travel in a clockwise direction,\r\n * regardless of the starting and ending points.\r\n */\r\n Clockwise = 2,\r\n /**\r\n * Rotation via `CounterClockwise` will travel in a counterclockwise direction,\r\n * regardless of the starting and ending points.\r\n */\r\n CounterClockwise = 3\r\n}\r\n","import { Action } from '../Action';\r\nimport { RotationType } from '../RotationType';\r\nimport { TransformComponent } from '../../EntityComponentSystem/Components/TransformComponent';\r\nimport { MotionComponent } from '../../EntityComponentSystem/Components/MotionComponent';\r\nimport { Entity } from '../../EntityComponentSystem/Entity';\r\nimport { TwoPI } from '../../Math/util';\r\n\r\nexport class RotateTo implements Action {\r\n private _tx: TransformComponent;\r\n private _motion: MotionComponent;\r\n public x: number;\r\n public y: number;\r\n private _start: number;\r\n private _end: number;\r\n private _speed: number;\r\n private _rotationType: RotationType;\r\n private _direction: number;\r\n private _distance: number;\r\n private _shortDistance: number;\r\n private _longDistance: number;\r\n private _shortestPathIsPositive: boolean;\r\n private _currentNonCannonAngle: number;\r\n private _started = false;\r\n private _stopped = false;\r\n constructor(entity: Entity, angleRadians: number, speed: number, rotationType?: RotationType) {\r\n this._tx = entity.get(TransformComponent);\r\n this._motion = entity.get(MotionComponent);\r\n this._end = angleRadians;\r\n this._speed = speed;\r\n this._rotationType = rotationType || RotationType.ShortestPath;\r\n }\r\n\r\n public update(_delta: number): void {\r\n if (!this._started) {\r\n this._started = true;\r\n this._start = this._tx.rotation;\r\n this._currentNonCannonAngle = this._tx.rotation;\r\n const distance1 = Math.abs(this._end - this._start);\r\n const distance2 = TwoPI - distance1;\r\n if (distance1 > distance2) {\r\n this._shortDistance = distance2;\r\n this._longDistance = distance1;\r\n } else {\r\n this._shortDistance = distance1;\r\n this._longDistance = distance2;\r\n }\r\n\r\n this._shortestPathIsPositive = (this._start - this._end + TwoPI) % TwoPI >= Math.PI;\r\n\r\n switch (this._rotationType) {\r\n case RotationType.ShortestPath:\r\n this._distance = this._shortDistance;\r\n if (this._shortestPathIsPositive) {\r\n this._direction = 1;\r\n } else {\r\n this._direction = -1;\r\n }\r\n break;\r\n case RotationType.LongestPath:\r\n this._distance = this._longDistance;\r\n if (this._shortestPathIsPositive) {\r\n this._direction = -1;\r\n } else {\r\n this._direction = 1;\r\n }\r\n break;\r\n case RotationType.Clockwise:\r\n this._direction = 1;\r\n if (this._shortestPathIsPositive) {\r\n this._distance = this._shortDistance;\r\n } else {\r\n this._distance = this._longDistance;\r\n }\r\n break;\r\n case RotationType.CounterClockwise:\r\n this._direction = -1;\r\n if (!this._shortestPathIsPositive) {\r\n this._distance = this._shortDistance;\r\n } else {\r\n this._distance = this._longDistance;\r\n }\r\n break;\r\n }\r\n }\r\n\r\n this._motion.angularVelocity = this._direction * this._speed;\r\n this._currentNonCannonAngle += this._direction * this._speed * (_delta / 1000);\r\n\r\n if (this.isComplete()) {\r\n this._tx.rotation = this._end;\r\n this._motion.angularVelocity = 0;\r\n this._stopped = true;\r\n }\r\n }\r\n\r\n public isComplete(): boolean {\r\n const distanceTraveled = Math.abs(this._currentNonCannonAngle - this._start);\r\n return this._stopped || distanceTraveled >= Math.abs(this._distance);\r\n }\r\n\r\n public stop(): void {\r\n this._motion.angularVelocity = 0;\r\n this._stopped = true;\r\n }\r\n\r\n public reset(): void {\r\n this._started = false;\r\n this._stopped = false;\r\n }\r\n}\r\n","import { Action } from '../Action';\r\nimport { RotationType } from '../RotationType';\r\nimport { TransformComponent } from '../../EntityComponentSystem/Components/TransformComponent';\r\nimport { MotionComponent } from '../../EntityComponentSystem/Components/MotionComponent';\r\nimport { Entity } from '../../EntityComponentSystem/Entity';\r\nimport { TwoPI } from '../../Math/util';\r\n\r\nexport class RotateBy implements Action {\r\n private _tx: TransformComponent;\r\n private _motion: MotionComponent;\r\n public x: number;\r\n public y: number;\r\n private _start: number;\r\n private _end: number;\r\n private _speed: number;\r\n private _offset: number;\r\n\r\n private _rotationType: RotationType;\r\n private _direction: number;\r\n private _distance: number;\r\n private _shortDistance: number;\r\n private _longDistance: number;\r\n private _shortestPathIsPositive: boolean;\r\n private _currentNonCannonAngle: number;\r\n private _started = false;\r\n private _stopped = false;\r\n constructor(entity: Entity, angleRadiansOffset: number, speed: number, rotationType?: RotationType) {\r\n this._tx = entity.get(TransformComponent);\r\n this._motion = entity.get(MotionComponent);\r\n this._speed = speed;\r\n this._offset = angleRadiansOffset;\r\n this._rotationType = rotationType || RotationType.ShortestPath;\r\n }\r\n\r\n public update(_delta: number): void {\r\n if (!this._started) {\r\n this._started = true;\r\n this._start = this._tx.rotation;\r\n this._currentNonCannonAngle = this._tx.rotation;\r\n this._end = this._start + this._offset;\r\n\r\n const distance1 = Math.abs(this._end - this._start);\r\n const distance2 = TwoPI - distance1;\r\n if (distance1 > distance2) {\r\n this._shortDistance = distance2;\r\n this._longDistance = distance1;\r\n } else {\r\n this._shortDistance = distance1;\r\n this._longDistance = distance2;\r\n }\r\n\r\n this._shortestPathIsPositive = (this._start - this._end + TwoPI) % TwoPI >= Math.PI;\r\n\r\n switch (this._rotationType) {\r\n case RotationType.ShortestPath:\r\n this._distance = this._shortDistance;\r\n if (this._shortestPathIsPositive) {\r\n this._direction = 1;\r\n } else {\r\n this._direction = -1;\r\n }\r\n break;\r\n case RotationType.LongestPath:\r\n this._distance = this._longDistance;\r\n if (this._shortestPathIsPositive) {\r\n this._direction = -1;\r\n } else {\r\n this._direction = 1;\r\n }\r\n break;\r\n case RotationType.Clockwise:\r\n this._direction = 1;\r\n if (this._shortDistance >= 0) {\r\n this._distance = this._shortDistance;\r\n } else {\r\n this._distance = this._longDistance;\r\n }\r\n break;\r\n case RotationType.CounterClockwise:\r\n this._direction = -1;\r\n if (this._shortDistance <= 0) {\r\n this._distance = this._shortDistance;\r\n } else {\r\n this._distance = this._longDistance;\r\n }\r\n break;\r\n }\r\n }\r\n\r\n this._motion.angularVelocity = this._direction * this._speed;\r\n this._currentNonCannonAngle += this._direction * this._speed * (_delta / 1000);\r\n\r\n if (this.isComplete()) {\r\n this._tx.rotation = this._end;\r\n this._motion.angularVelocity = 0;\r\n this._stopped = true;\r\n }\r\n }\r\n\r\n public isComplete(): boolean {\r\n const distanceTraveled = Math.abs(this._currentNonCannonAngle - this._start);\r\n return this._stopped || distanceTraveled >= Math.abs(this._distance);\r\n }\r\n\r\n public stop(): void {\r\n this._motion.angularVelocity = 0;\r\n this._stopped = true;\r\n }\r\n\r\n public reset(): void {\r\n this._started = false;\r\n this._stopped = false;\r\n this._start = undefined;\r\n this._currentNonCannonAngle = undefined;\r\n this._distance = undefined;\r\n }\r\n}\r\n","import { vec } from '../../Math/vector';\r\nimport { MotionComponent } from '../../EntityComponentSystem/Components/MotionComponent';\r\nimport { TransformComponent } from '../../EntityComponentSystem/Components/TransformComponent';\r\nimport { Action } from '../Action';\r\nimport { Entity } from '../../EntityComponentSystem/Entity';\r\n\r\nexport class ScaleTo implements Action {\r\n private _tx: TransformComponent;\r\n private _motion: MotionComponent;\r\n public x: number;\r\n public y: number;\r\n private _startX: number;\r\n private _startY: number;\r\n private _endX: number;\r\n private _endY: number;\r\n private _speedX: number;\r\n private _speedY: number;\r\n private _distanceX: number;\r\n private _distanceY: number;\r\n private _started = false;\r\n private _stopped = false;\r\n constructor(entity: Entity, scaleX: number, scaleY: number, speedX: number, speedY: number) {\r\n this._tx = entity.get(TransformComponent);\r\n this._motion = entity.get(MotionComponent);\r\n this._endX = scaleX;\r\n this._endY = scaleY;\r\n this._speedX = speedX;\r\n this._speedY = speedY;\r\n }\r\n\r\n public update(_delta: number): void {\r\n if (!this._started) {\r\n this._started = true;\r\n this._startX = this._tx.scale.x;\r\n this._startY = this._tx.scale.y;\r\n this._distanceX = Math.abs(this._endX - this._startX);\r\n this._distanceY = Math.abs(this._endY - this._startY);\r\n }\r\n\r\n if (!(Math.abs(this._tx.scale.x - this._startX) >= this._distanceX)) {\r\n const directionX = this._endY < this._startY ? -1 : 1;\r\n this._motion.scaleFactor.x = this._speedX * directionX;\r\n } else {\r\n this._motion.scaleFactor.x = 0;\r\n }\r\n\r\n if (!(Math.abs(this._tx.scale.y - this._startY) >= this._distanceY)) {\r\n const directionY = this._endY < this._startY ? -1 : 1;\r\n this._motion.scaleFactor.y = this._speedY * directionY;\r\n } else {\r\n this._motion.scaleFactor.y = 0;\r\n }\r\n\r\n if (this.isComplete()) {\r\n this._tx.scale = vec(this._endX, this._endY);\r\n this._motion.scaleFactor.x = 0;\r\n this._motion.scaleFactor.y = 0;\r\n }\r\n }\r\n\r\n public isComplete(): boolean {\r\n return (\r\n this._stopped ||\r\n (Math.abs(this._tx.scale.x - this._startX) >= (this._distanceX - 0.01) &&\r\n Math.abs(this._tx.scale.y - this._startY) >= (this._distanceY - 0.01))\r\n );\r\n }\r\n\r\n public stop(): void {\r\n this._motion.scaleFactor.x = 0;\r\n this._motion.scaleFactor.y = 0;\r\n this._stopped = true;\r\n }\r\n\r\n public reset(): void {\r\n this._started = false;\r\n this._stopped = false;\r\n }\r\n}\r\n","import { Vector } from '../../Math/vector';\r\nimport { Entity } from '../../EntityComponentSystem/Entity';\r\nimport { MotionComponent } from '../../EntityComponentSystem/Components/MotionComponent';\r\nimport { TransformComponent } from '../../EntityComponentSystem/Components/TransformComponent';\r\nimport { Action } from '../Action';\r\n\r\nexport class ScaleBy implements Action {\r\n private _tx: TransformComponent;\r\n private _motion: MotionComponent;\r\n public x: number;\r\n public y: number;\r\n private _startScale: Vector;\r\n private _endScale: Vector;\r\n private _offset: Vector;\r\n private _distanceX: number;\r\n private _distanceY: number;\r\n private _directionX: number;\r\n private _directionY: number;\r\n private _started = false;\r\n private _stopped = false;\r\n private _speedX: number;\r\n private _speedY: number;\r\n constructor(entity: Entity, scaleOffsetX: number, scaleOffsetY: number, speed: number) {\r\n this._tx = entity.get(TransformComponent);\r\n this._motion = entity.get(MotionComponent);\r\n this._offset = new Vector(scaleOffsetX, scaleOffsetY);\r\n this._speedX = this._speedY = speed;\r\n }\r\n\r\n public update(_delta: number): void {\r\n if (!this._started) {\r\n this._started = true;\r\n this._startScale = this._tx.scale.clone();\r\n this._endScale = this._startScale.add(this._offset);\r\n this._distanceX = Math.abs(this._endScale.x - this._startScale.x);\r\n this._distanceY = Math.abs(this._endScale.y - this._startScale.y);\r\n this._directionX = this._endScale.x < this._startScale.x ? -1 : 1;\r\n this._directionY = this._endScale.y < this._startScale.y ? -1 : 1;\r\n }\r\n\r\n this._motion.scaleFactor.x = this._speedX * this._directionX;\r\n this._motion.scaleFactor.y = this._speedY * this._directionY;\r\n\r\n if (this.isComplete()) {\r\n this._tx.scale = this._endScale;\r\n this._motion.scaleFactor.x = 0;\r\n this._motion.scaleFactor.y = 0;\r\n }\r\n }\r\n\r\n public isComplete(): boolean {\r\n return (\r\n this._stopped ||\r\n (Math.abs(this._tx.scale.x - this._startScale.x) >= (this._distanceX - 0.01) &&\r\n Math.abs(this._tx.scale.y - this._startScale.y) >= (this._distanceY - 0.01))\r\n );\r\n }\r\n\r\n public stop(): void {\r\n this._motion.scaleFactor.x = 0;\r\n this._motion.scaleFactor.y = 0;\r\n this._stopped = true;\r\n }\r\n\r\n public reset(): void {\r\n this._started = false;\r\n this._stopped = false;\r\n }\r\n}\r\n","import { Action } from '../Action';\r\n\r\nexport class CallMethod implements Action {\r\n private _method: () => any = null;\r\n private _hasBeenCalled: boolean = false;\r\n constructor(method: () => any) {\r\n this._method = method;\r\n }\r\n\r\n public update(_delta: number) {\r\n this._method();\r\n this._hasBeenCalled = true;\r\n }\r\n public isComplete() {\r\n return this._hasBeenCalled;\r\n }\r\n public reset() {\r\n this._hasBeenCalled = false;\r\n }\r\n public stop() {\r\n this._hasBeenCalled = true;\r\n }\r\n}\r\n","import { Entity} from '../../EntityComponentSystem/Entity';\r\nimport { TransformComponent } from '../../EntityComponentSystem/Components/TransformComponent';\r\nimport { MotionComponent } from '../../EntityComponentSystem/Components/MotionComponent';\r\nimport { vec, Vector } from '../../Math/vector';\r\nimport { Action } from '../Action';\r\n\r\nexport class EaseTo implements Action {\r\n private _tx: TransformComponent;\r\n private _motion: MotionComponent;\r\n private _currentLerpTime: number = 0;\r\n private _lerpDuration: number = 1 * 1000; // 1 second\r\n private _lerpStart: Vector = new Vector(0, 0);\r\n private _lerpEnd: Vector = new Vector(0, 0);\r\n private _initialized: boolean = false;\r\n private _stopped: boolean = false;\r\n constructor(\r\n entity: Entity,\r\n x: number,\r\n y: number,\r\n duration: number,\r\n public easingFcn: (currentTime: number, startValue: number, endValue: number, duration: number) => number\r\n ) {\r\n this._tx = entity.get(TransformComponent);\r\n this._motion = entity.get(MotionComponent);\r\n this._lerpDuration = duration;\r\n this._lerpEnd = new Vector(x, y);\r\n }\r\n private _initialize() {\r\n this._lerpStart = new Vector(this._tx.pos.x, this._tx.pos.y);\r\n this._currentLerpTime = 0;\r\n }\r\n\r\n public update(delta: number): void {\r\n if (!this._initialized) {\r\n this._initialize();\r\n this._initialized = true;\r\n }\r\n\r\n // Need to update lerp time first, otherwise the first update will always be zero\r\n this._currentLerpTime += delta;\r\n let newX = this._tx.pos.x;\r\n let newY = this._tx.pos.y;\r\n if (this._currentLerpTime < this._lerpDuration) {\r\n if (this._lerpEnd.x < this._lerpStart.x) {\r\n newX =\r\n this._lerpStart.x -\r\n (this.easingFcn(this._currentLerpTime, this._lerpEnd.x, this._lerpStart.x, this._lerpDuration) - this._lerpEnd.x);\r\n } else {\r\n newX = this.easingFcn(this._currentLerpTime, this._lerpStart.x, this._lerpEnd.x, this._lerpDuration);\r\n }\r\n\r\n if (this._lerpEnd.y < this._lerpStart.y) {\r\n newY =\r\n this._lerpStart.y -\r\n (this.easingFcn(this._currentLerpTime, this._lerpEnd.y, this._lerpStart.y, this._lerpDuration) - this._lerpEnd.y);\r\n } else {\r\n newY = this.easingFcn(this._currentLerpTime, this._lerpStart.y, this._lerpEnd.y, this._lerpDuration);\r\n }\r\n // Given the lerp position figure out the velocity in pixels per second\r\n this._motion.vel = vec((newX - this._tx.pos.x) / (delta / 1000), (newY - this._tx.pos.y) / (delta / 1000));\r\n } else {\r\n this._tx.pos = vec(this._lerpEnd.x, this._lerpEnd.y);\r\n this._motion.vel = Vector.Zero;\r\n }\r\n }\r\n public isComplete(): boolean {\r\n return this._stopped || this._currentLerpTime >= this._lerpDuration;\r\n }\r\n\r\n public reset(): void {\r\n this._initialized = false;\r\n this._stopped = false;\r\n this._currentLerpTime = 0;\r\n }\r\n public stop(): void {\r\n this._motion.vel = vec(0, 0);\r\n this._stopped = true;\r\n }\r\n}\r\n","import { MotionComponent } from '../../EntityComponentSystem/Components/MotionComponent';\r\nimport { TransformComponent } from '../../EntityComponentSystem/Components/TransformComponent';\r\nimport { Entity } from '../../EntityComponentSystem/Entity';\r\nimport { vec, Vector } from '../../Math/vector';\r\nimport { Action } from '../Action';\r\n\r\nexport class EaseBy implements Action {\r\n private _tx: TransformComponent;\r\n private _motion: MotionComponent;\r\n private _currentLerpTime: number = 0;\r\n private _lerpDuration: number = 1 * 1000; // 1 second\r\n private _lerpStart: Vector = new Vector(0, 0);\r\n private _lerpEnd: Vector = new Vector(0, 0);\r\n private _offset: Vector;\r\n private _initialized: boolean = false;\r\n private _stopped: boolean = false;\r\n constructor(\r\n entity: Entity,\r\n offsetX: number,\r\n offsetY: number,\r\n duration: number,\r\n public easingFcn: (currentTime: number, startValue: number, endValue: number, duration: number) => number\r\n ) {\r\n this._tx = entity.get(TransformComponent);\r\n this._motion = entity.get(MotionComponent);\r\n this._lerpDuration = duration;\r\n this._offset = new Vector(offsetX, offsetY);\r\n }\r\n private _initialize() {\r\n this._lerpStart = new Vector(this._tx.pos.x, this._tx.pos.y);\r\n this._currentLerpTime = 0;\r\n this._lerpEnd = this._lerpStart.add(this._offset);\r\n }\r\n\r\n public update(delta: number): void {\r\n if (!this._initialized) {\r\n this._initialize();\r\n this._initialized = true;\r\n }\r\n\r\n // Need to update lerp time first, otherwise the first update will always be zero\r\n this._currentLerpTime += delta;\r\n let newX = this._tx.pos.x;\r\n let newY = this._tx.pos.y;\r\n if (this._currentLerpTime < this._lerpDuration) {\r\n if (this._lerpEnd.x < this._lerpStart.x) {\r\n newX =\r\n this._lerpStart.x -\r\n (this.easingFcn(this._currentLerpTime, this._lerpEnd.x, this._lerpStart.x, this._lerpDuration) - this._lerpEnd.x);\r\n } else {\r\n newX = this.easingFcn(this._currentLerpTime, this._lerpStart.x, this._lerpEnd.x, this._lerpDuration);\r\n }\r\n\r\n if (this._lerpEnd.y < this._lerpStart.y) {\r\n newY =\r\n this._lerpStart.y -\r\n (this.easingFcn(this._currentLerpTime, this._lerpEnd.y, this._lerpStart.y, this._lerpDuration) - this._lerpEnd.y);\r\n } else {\r\n newY = this.easingFcn(this._currentLerpTime, this._lerpStart.y, this._lerpEnd.y, this._lerpDuration);\r\n }\r\n // Given the lerp position figure out the velocity in pixels per second\r\n this._motion.vel = vec((newX - this._tx.pos.x) / (delta / 1000), (newY - this._tx.pos.y) / (delta / 1000));\r\n } else {\r\n this._tx.pos = vec(this._lerpEnd.x, this._lerpEnd.y);\r\n this._motion.vel = Vector.Zero;\r\n }\r\n }\r\n public isComplete(): boolean {\r\n return this._stopped || this._currentLerpTime >= this._lerpDuration;\r\n }\r\n\r\n public reset(): void {\r\n this._initialized = false;\r\n this._stopped = false;\r\n this._currentLerpTime = 0;\r\n }\r\n public stop(): void {\r\n this._motion.vel = vec(0, 0);\r\n this._stopped = true;\r\n }\r\n}","import { GraphicsComponent } from '../../Graphics/GraphicsComponent';\r\nimport { Entity } from '../../EntityComponentSystem/Entity';\r\nimport { Action } from '../Action';\r\n\r\nexport class Blink implements Action {\r\n private _graphics: GraphicsComponent;\r\n private _timeVisible: number = 0;\r\n private _timeNotVisible: number = 0;\r\n private _elapsedTime: number = 0;\r\n private _totalTime: number = 0;\r\n private _duration: number;\r\n private _stopped: boolean = false;\r\n private _started: boolean = false;\r\n constructor(entity: Entity, timeVisible: number, timeNotVisible: number, numBlinks: number = 1) {\r\n this._graphics = entity.get(GraphicsComponent);\r\n this._timeVisible = timeVisible;\r\n this._timeNotVisible = timeNotVisible;\r\n this._duration = (timeVisible + timeNotVisible) * numBlinks;\r\n }\r\n\r\n public update(delta: number): void {\r\n if (!this._started) {\r\n this._started = true;\r\n this._elapsedTime = 0;\r\n this._totalTime = 0;\r\n }\r\n if (!this._graphics) {\r\n return;\r\n }\r\n\r\n this._elapsedTime += delta;\r\n this._totalTime += delta;\r\n if (this._graphics.visible && this._elapsedTime >= this._timeVisible) {\r\n this._graphics.visible = false;\r\n this._elapsedTime = 0;\r\n }\r\n\r\n if (!this._graphics.visible && this._elapsedTime >= this._timeNotVisible) {\r\n this._graphics.visible = true;\r\n this._elapsedTime = 0;\r\n }\r\n\r\n if (this.isComplete()) {\r\n this._graphics.visible = true;\r\n }\r\n }\r\n\r\n public isComplete(): boolean {\r\n return this._stopped || this._totalTime >= this._duration;\r\n }\r\n\r\n public stop(): void {\r\n if (this._graphics) {\r\n this._graphics.visible = true;\r\n }\r\n this._stopped = true;\r\n }\r\n\r\n public reset() {\r\n this._started = false;\r\n this._stopped = false;\r\n this._elapsedTime = 0;\r\n this._totalTime = 0;\r\n }\r\n}\r\n","import { Entity } from '../../EntityComponentSystem/Entity';\r\nimport { GraphicsComponent } from '../../Graphics/GraphicsComponent';\r\nimport { Logger } from '../../Util/Log';\r\nimport { Action } from '../Action';\r\n\r\nexport class Fade implements Action {\r\n private _graphics: GraphicsComponent;\r\n public x: number;\r\n public y: number;\r\n\r\n private _endOpacity: number;\r\n private _speed: number;\r\n private _ogspeed: number;\r\n private _multiplier: number = 1;\r\n private _started = false;\r\n private _stopped = false;\r\n\r\n constructor(entity: Entity, endOpacity: number, speed: number) {\r\n this._graphics = entity.get(GraphicsComponent);\r\n this._endOpacity = endOpacity;\r\n this._speed = this._ogspeed = speed;\r\n }\r\n\r\n public update(delta: number): void {\r\n if (!this._graphics) {\r\n return;\r\n }\r\n\r\n if (!this._started) {\r\n this._started = true;\r\n this._speed = this._ogspeed;\r\n\r\n // determine direction when we start\r\n if (this._endOpacity < this._graphics.opacity) {\r\n this._multiplier = -1;\r\n } else {\r\n this._multiplier = 1;\r\n }\r\n }\r\n\r\n if (this._speed > 0) {\r\n this._graphics.opacity += (this._multiplier *\r\n (Math.abs(this._graphics.opacity - this._endOpacity) * delta)) / this._speed;\r\n }\r\n\r\n this._speed -= delta;\r\n\r\n if (this.isComplete()) {\r\n this._graphics.opacity = this._endOpacity;\r\n }\r\n\r\n Logger.getInstance().debug('[Action fade] Actor opacity:', this._graphics.opacity);\r\n }\r\n\r\n public isComplete(): boolean {\r\n return this._stopped || Math.abs(this._graphics.opacity - this._endOpacity) < 0.05;\r\n }\r\n\r\n public stop(): void {\r\n this._stopped = true;\r\n }\r\n\r\n public reset(): void {\r\n this._started = false;\r\n this._stopped = false;\r\n }\r\n}\r\n","import { Action } from '../Action';\r\n\r\nexport class Delay implements Action {\r\n private _elapsedTime: number = 0;\r\n private _delay: number;\r\n private _started: boolean = false;\r\n private _stopped = false;\r\n constructor(delay: number) {\r\n this._delay = delay;\r\n }\r\n\r\n public update(delta: number): void {\r\n if (!this._started) {\r\n this._started = true;\r\n }\r\n\r\n this._elapsedTime += delta;\r\n }\r\n\r\n isComplete(): boolean {\r\n return this._stopped || this._elapsedTime >= this._delay;\r\n }\r\n\r\n public stop(): void {\r\n this._stopped = true;\r\n }\r\n\r\n reset(): void {\r\n this._elapsedTime = 0;\r\n this._started = false;\r\n this._stopped = false;\r\n }\r\n}\r\n","import { Entity } from '../../EntityComponentSystem/Entity';\r\nimport { Action } from '../Action';\r\nimport { ActionsComponent } from '../ActionsComponent';\r\n\r\nexport class Die implements Action {\r\n private _entity: Entity;\r\n private _stopped = false;\r\n\r\n constructor(entity: Entity) {\r\n this._entity = entity;\r\n }\r\n\r\n public update(_delta: number): void {\r\n this._entity.get(ActionsComponent).clearActions();\r\n this._entity.kill();\r\n this._stopped = true;\r\n }\r\n\r\n public isComplete(): boolean {\r\n return this._stopped;\r\n }\r\n\r\n public stop(): void {\r\n return;\r\n }\r\n\r\n public reset(): void {\r\n return;\r\n }\r\n}\r\n","import { MotionComponent } from '../../EntityComponentSystem/Components/MotionComponent';\r\nimport { TransformComponent } from '../../EntityComponentSystem/Components/TransformComponent';\r\nimport { Entity } from '../../EntityComponentSystem/Entity';\r\nimport { vec, Vector } from '../../Math/vector';\r\nimport { Action } from '../Action';\r\n\r\nexport class Follow implements Action {\r\n private _tx: TransformComponent;\r\n private _motion: MotionComponent;\r\n private _followTx: TransformComponent;\r\n private _followMotion: MotionComponent;\r\n\r\n public x: number;\r\n public y: number;\r\n private _current: Vector;\r\n private _end: Vector;\r\n private _dir: Vector;\r\n private _speed: number;\r\n private _maximumDistance: number;\r\n private _distanceBetween: number;\r\n private _started = false;\r\n private _stopped = false;\r\n\r\n constructor(entity: Entity, entityToFollow: Entity, followDistance?: number) {\r\n this._tx = entity.get(TransformComponent);\r\n this._motion = entity.get(MotionComponent);\r\n this._followTx = entityToFollow.get(TransformComponent);\r\n this._followMotion = entityToFollow.get(MotionComponent);\r\n this._current = new Vector(this._tx.pos.x, this._tx.pos.y);\r\n this._end = new Vector(this._followTx.pos.x, this._followTx.pos.y);\r\n this._maximumDistance = followDistance !== undefined ? followDistance : this._current.distance(this._end);\r\n this._speed = 0;\r\n }\r\n\r\n public update(_delta: number): void {\r\n if (!this._started) {\r\n this._started = true;\r\n this._distanceBetween = this._current.distance(this._end);\r\n this._dir = this._end.sub(this._current).normalize();\r\n }\r\n\r\n const actorToFollowSpeed = Math.sqrt(Math.pow(this._followMotion.vel.x, 2) + Math.pow(this._followMotion.vel.y, 2));\r\n if (actorToFollowSpeed !== 0) {\r\n this._speed = actorToFollowSpeed;\r\n }\r\n this._current = vec(this._tx.pos.x, this._tx.pos.y);\r\n\r\n this._end = vec(this._followTx.pos.x, this._followTx.pos.y);\r\n this._distanceBetween = this._current.distance(this._end);\r\n this._dir = this._end.sub(this._current).normalize();\r\n\r\n if (this._distanceBetween >= this._maximumDistance) {\r\n const m = this._dir.scale(this._speed);\r\n this._motion.vel = vec(m.x, m.y);\r\n } else {\r\n this._motion.vel = vec(0, 0);\r\n }\r\n\r\n if (this.isComplete()) {\r\n this._tx.pos = vec(this._end.x, this._end.y);\r\n this._motion.vel = vec(0, 0);\r\n }\r\n }\r\n\r\n public stop(): void {\r\n this._motion.vel = vec(0, 0);\r\n this._stopped = true;\r\n }\r\n\r\n public isComplete(): boolean {\r\n // the actor following should never stop unless specified to do so\r\n return this._stopped;\r\n }\r\n\r\n public reset(): void {\r\n this._started = false;\r\n this._stopped = false;\r\n }\r\n}\r\n","import { MotionComponent } from '../../EntityComponentSystem/Components/MotionComponent';\r\nimport { TransformComponent } from '../../EntityComponentSystem/Components/TransformComponent';\r\nimport { Entity } from '../../EntityComponentSystem/Entity';\r\nimport { Vector, vec } from '../../Math/vector';\r\nimport { Action } from '../Action';\r\n\r\nexport class Meet implements Action {\r\n private _tx: TransformComponent;\r\n private _motion: MotionComponent;\r\n private _meetTx: TransformComponent;\r\n private _meetMotion: MotionComponent;\r\n public x: number;\r\n public y: number;\r\n private _current: Vector;\r\n private _end: Vector;\r\n private _dir: Vector;\r\n private _speed: number;\r\n private _distanceBetween: number;\r\n private _started = false;\r\n private _stopped = false;\r\n private _speedWasSpecified = false;\r\n\r\n constructor(actor: Entity, actorToMeet: Entity, speed?: number) {\r\n this._tx = actor.get(TransformComponent);\r\n this._motion = actor.get(MotionComponent);\r\n this._meetTx = actorToMeet.get(TransformComponent);\r\n this._meetMotion = actorToMeet.get(MotionComponent);\r\n this._current = new Vector(this._tx.pos.x, this._tx.pos.y);\r\n this._end = new Vector(this._meetTx.pos.x, this._meetTx.pos.y);\r\n this._speed = speed || 0;\r\n\r\n if (speed !== undefined) {\r\n this._speedWasSpecified = true;\r\n }\r\n }\r\n\r\n public update(_delta: number): void {\r\n if (!this._started) {\r\n this._started = true;\r\n this._distanceBetween = this._current.distance(this._end);\r\n this._dir = this._end.sub(this._current).normalize();\r\n }\r\n\r\n const actorToMeetSpeed = Math.sqrt(Math.pow(this._meetMotion.vel.x, 2) + Math.pow(this._meetMotion.vel.y, 2));\r\n if (actorToMeetSpeed !== 0 && !this._speedWasSpecified) {\r\n this._speed = actorToMeetSpeed;\r\n }\r\n this._current = vec(this._tx.pos.x, this._tx.pos.y);\r\n\r\n this._end = vec(this._meetTx.pos.x, this._meetTx.pos.y);\r\n this._distanceBetween = this._current.distance(this._end);\r\n this._dir = this._end.sub(this._current).normalize();\r\n\r\n const m = this._dir.scale(this._speed);\r\n this._motion.vel = vec(m.x, m.y);\r\n\r\n if (this.isComplete()) {\r\n this._tx.pos = vec(this._end.x, this._end.y);\r\n this._motion.vel = vec(0, 0);\r\n }\r\n }\r\n\r\n public isComplete(): boolean {\r\n return this._stopped || this._distanceBetween <= 1;\r\n }\r\n\r\n public stop(): void {\r\n this._motion.vel = vec(0, 0);\r\n this._stopped = true;\r\n }\r\n\r\n public reset(): void {\r\n this._started = false;\r\n this._stopped = false;\r\n this._distanceBetween = undefined;\r\n }\r\n}\r\n","import { RotationType } from './RotationType';\r\n\r\nimport { EasingFunction, EasingFunctions } from '../Util/EasingFunctions';\r\nimport { ActionQueue } from './ActionQueue';\r\nimport { Repeat } from './Action/Repeat';\r\nimport { RepeatForever } from './Action/RepeatForever';\r\nimport { MoveBy } from './Action/MoveBy';\r\nimport { MoveTo } from './Action/MoveTo';\r\nimport { RotateTo } from './Action/RotateTo';\r\nimport { RotateBy } from './Action/RotateBy';\r\nimport { ScaleTo } from './Action/ScaleTo';\r\nimport { ScaleBy } from './Action/ScaleBy';\r\nimport { CallMethod } from './Action/CallMethod';\r\nimport { EaseTo } from './Action/EaseTo';\r\nimport { EaseBy } from './Action/EaseBy';\r\nimport { Blink } from './Action/Blink';\r\nimport { Fade } from './Action/Fade';\r\nimport { Delay } from './Action/Delay';\r\nimport { Die } from './Action/Die';\r\nimport { Follow } from './Action/Follow';\r\nimport { Meet } from './Action/Meet';\r\nimport { Vector } from '../Math/vector';\r\nimport { Entity } from '../EntityComponentSystem/Entity';\r\nimport { Action } from './Action';\r\n\r\n/**\r\n * The fluent Action API allows you to perform \"actions\" on\r\n * [[Actor|Actors]] such as following, moving, rotating, and\r\n * more. You can implement your own actions by implementing\r\n * the [[Action]] interface.\r\n */\r\nexport class ActionContext {\r\n private _entity: Entity;\r\n private _queue: ActionQueue;\r\n\r\n constructor(entity: Entity) {\r\n this._entity = entity;\r\n this._queue = new ActionQueue(entity);\r\n }\r\n\r\n public getQueue(): ActionQueue {\r\n return this._queue;\r\n }\r\n\r\n public update(elapsedMs: number) {\r\n this._queue.update(elapsedMs);\r\n }\r\n\r\n /**\r\n * Clears all queued actions from the Actor\r\n */\r\n public clearActions(): void {\r\n this._queue.clearActions();\r\n }\r\n\r\n public runAction(action: Action) {\r\n action.reset();\r\n this._queue.add(action);\r\n return this;\r\n }\r\n\r\n /**\r\n * This method will move an actor to the specified `x` and `y` position over the\r\n * specified duration using a given [[EasingFunctions]] and return back the actor. This\r\n * method is part of the actor 'Action' fluent API allowing action chaining.\r\n * @param pos The x,y vector location to move the actor to\r\n * @param duration The time it should take the actor to move to the new location in milliseconds\r\n * @param easingFcn Use [[EasingFunction]] or a custom function to use to calculate position, Default is [[EasingFunctions.Linear]]\r\n */\r\n public easeTo(pos: Vector, duration: number, easingFcn?: EasingFunction): ActionContext\r\n /**\r\n * This method will move an actor to the specified `x` and `y` position over the\r\n * specified duration using a given [[EasingFunctions]] and return back the actor. This\r\n * method is part of the actor 'Action' fluent API allowing action chaining.\r\n * @param x The x location to move the actor to\r\n * @param y The y location to move the actor to\r\n * @param duration The time it should take the actor to move to the new location in milliseconds\r\n * @param easingFcn Use [[EasingFunction]] or a custom function to use to calculate position, Default is [[EasingFunctions.Linear]]\r\n */\r\n public easeTo(x: number, y: number, duration: number, easingFcn?: EasingFunction): ActionContext\r\n public easeTo(...args: any[]): ActionContext {\r\n let x = 0;\r\n let y = 0;\r\n let duration = 0;\r\n let easingFcn = EasingFunctions.Linear;\r\n if (args[0] instanceof Vector) {\r\n x = args[0].x;\r\n y = args[0].y;\r\n duration = args[1];\r\n easingFcn = args[2] ?? easingFcn;\r\n } else {\r\n x = args[0];\r\n y = args[1];\r\n duration = args[2];\r\n easingFcn = args[3] ?? easingFcn;\r\n }\r\n\r\n this._queue.add(new EaseTo(this._entity, x, y, duration, easingFcn));\r\n return this;\r\n }\r\n\r\n /**\r\n * This method will move an actor by a specified vector offset relative to the current position given\r\n * a duration and a [[EasingFunction]]. This method is part of the actor 'Action' fluent API allowing action chaining.\r\n * @param offset Vector offset relative to the current position\r\n * @param duration The duration in milliseconds\r\n * @param easingFcn Use [[EasingFunction]] or a custom function to use to calculate position, Default is [[EasingFunctions.Linear]]\r\n */\r\n public easeBy(offset: Vector, duration: number, easingFcn?: EasingFunction): ActionContext;\r\n /**\r\n * This method will move an actor by a specified x and y offset relative to the current position given\r\n * a duration and a [[EasingFunction]]. This method is part of the actor 'Action' fluent API allowing action chaining.\r\n * @param offset Vector offset relative to the current position\r\n * @param duration The duration in milliseconds\r\n * @param easingFcn Use [[EasingFunction]] or a custom function to use to calculate position, Default is [[EasingFunctions.Linear]]\r\n */\r\n public easeBy(offsetX: number, offsetY: number, duration: number, easingFcn?: EasingFunction): ActionContext;\r\n public easeBy(...args: any[]): ActionContext {\r\n let offsetX = 0;\r\n let offsetY = 0;\r\n let duration = 0;\r\n let easingFcn = EasingFunctions.Linear;\r\n if (args[0] instanceof Vector) {\r\n offsetX = args[0].x;\r\n offsetY = args[0].y;\r\n duration = args[1];\r\n easingFcn = args[2] ?? easingFcn;\r\n } else {\r\n offsetX = args[0];\r\n offsetY = args[1];\r\n duration = args[2];\r\n easingFcn = args[3] ?? easingFcn;\r\n }\r\n\r\n this._queue.add(new EaseBy(this._entity, offsetX, offsetY, duration, easingFcn));\r\n return this;\r\n }\r\n\r\n /**\r\n * This method will move an actor to the specified x and y position at the\r\n * speed specified (in pixels per second) and return back the actor. This\r\n * method is part of the actor 'Action' fluent API allowing action chaining.\r\n * @param pos The x,y vector location to move the actor to\r\n * @param speed The speed in pixels per second to move\r\n */\r\n public moveTo(pos: Vector, speed: number): ActionContext;\r\n /**\r\n * This method will move an actor to the specified x and y position at the\r\n * speed specified (in pixels per second) and return back the actor. This\r\n * method is part of the actor 'Action' fluent API allowing action chaining.\r\n * @param x The x location to move the actor to\r\n * @param y The y location to move the actor to\r\n * @param speed The speed in pixels per second to move\r\n */\r\n public moveTo(x: number, y: number, speed: number): ActionContext;\r\n public moveTo(xOrPos: number | Vector, yOrSpeed: number, speedOrUndefined?: number | undefined): ActionContext {\r\n let x = 0;\r\n let y = 0;\r\n let speed = 0;\r\n if (xOrPos instanceof Vector) {\r\n x = xOrPos.x;\r\n y = xOrPos.y;\r\n speed = yOrSpeed;\r\n } else {\r\n x = xOrPos;\r\n y = yOrSpeed;\r\n speed = speedOrUndefined;\r\n }\r\n this._queue.add(new MoveTo(this._entity, x, y, speed));\r\n return this;\r\n }\r\n\r\n /**\r\n * This method will move an actor by the specified x offset and y offset from its current position, at a certain speed.\r\n * This method is part of the actor 'Action' fluent API allowing action chaining.\r\n * @param xOffset The x offset to apply to this actor\r\n * @param yOffset The y location to move the actor to\r\n * @param speed The speed in pixels per second the actor should move\r\n */\r\n public moveBy(offset: Vector, speed: number): ActionContext;\r\n public moveBy(xOffset: number, yOffset: number, speed: number): ActionContext;\r\n public moveBy(xOffsetOrVector: number | Vector, yOffsetOrSpeed: number, speedOrUndefined?: number | undefined): ActionContext {\r\n let xOffset = 0;\r\n let yOffset = 0;\r\n let speed = 0;\r\n if (xOffsetOrVector instanceof Vector) {\r\n xOffset = xOffsetOrVector.x;\r\n yOffset = xOffsetOrVector.y;\r\n speed = yOffsetOrSpeed;\r\n } else {\r\n xOffset = xOffsetOrVector;\r\n yOffset = yOffsetOrSpeed;\r\n speed = speedOrUndefined;\r\n }\r\n this._queue.add(new MoveBy(this._entity, xOffset, yOffset, speed));\r\n return this;\r\n }\r\n\r\n /**\r\n * This method will rotate an actor to the specified angle at the speed\r\n * specified (in radians per second) and return back the actor. This\r\n * method is part of the actor 'Action' fluent API allowing action chaining.\r\n * @param angleRadians The angle to rotate to in radians\r\n * @param speed The angular velocity of the rotation specified in radians per second\r\n * @param rotationType The [[RotationType]] to use for this rotation\r\n */\r\n public rotateTo(angleRadians: number, speed: number, rotationType?: RotationType): ActionContext {\r\n this._queue.add(new RotateTo(this._entity, angleRadians, speed, rotationType));\r\n return this;\r\n }\r\n\r\n /**\r\n * This method will rotate an actor by the specified angle offset, from it's current rotation given a certain speed\r\n * in radians/sec and return back the actor. This method is part\r\n * of the actor 'Action' fluent API allowing action chaining.\r\n * @param angleRadiansOffset The angle to rotate to in radians relative to the current rotation\r\n * @param speed The speed in radians/sec the actor should rotate at\r\n * @param rotationType The [[RotationType]] to use for this rotation, default is shortest path\r\n */\r\n public rotateBy(angleRadiansOffset: number, speed: number, rotationType?: RotationType): ActionContext {\r\n this._queue.add(new RotateBy(this._entity, angleRadiansOffset, speed, rotationType));\r\n return this;\r\n }\r\n\r\n /**\r\n * This method will scale an actor to the specified size at the speed\r\n * specified (in magnitude increase per second) and return back the\r\n * actor. This method is part of the actor 'Action' fluent API allowing\r\n * action chaining.\r\n * @param size The scale to adjust the actor to over time\r\n * @param speed The speed of scaling specified in magnitude increase per second\r\n */\r\n public scaleTo(size: Vector, speed: Vector): ActionContext;\r\n /**\r\n * This method will scale an actor to the specified size at the speed\r\n * specified (in magnitude increase per second) and return back the\r\n * actor. This method is part of the actor 'Action' fluent API allowing\r\n * action chaining.\r\n * @param sizeX The scaling factor to apply on X axis\r\n * @param sizeY The scaling factor to apply on Y axis\r\n * @param speedX The speed of scaling specified in magnitude increase per second on X axis\r\n * @param speedY The speed of scaling specified in magnitude increase per second on Y axis\r\n */\r\n public scaleTo(sizeX: number, sizeY: number, speedX: number, speedY: number): ActionContext;\r\n public scaleTo(sizeXOrVector: number | Vector,\r\n sizeYOrSpeed: number | Vector,\r\n speedXOrUndefined?: number | undefined,\r\n speedYOrUndefined?: number | undefined): ActionContext {\r\n\r\n let sizeX = 1;\r\n let sizeY = 1;\r\n let speedX = 0;\r\n let speedY = 0;\r\n\r\n if (sizeXOrVector instanceof Vector && sizeYOrSpeed instanceof Vector) {\r\n sizeX = sizeXOrVector.x;\r\n sizeY = sizeXOrVector.y;\r\n\r\n speedX = sizeYOrSpeed.x;\r\n speedY = sizeYOrSpeed.y;\r\n }\r\n if (typeof sizeXOrVector === 'number' && typeof sizeYOrSpeed === 'number') {\r\n sizeX = sizeXOrVector;\r\n sizeY = sizeYOrSpeed;\r\n\r\n speedX = speedXOrUndefined;\r\n speedY = speedYOrUndefined;\r\n }\r\n\r\n this._queue.add(new ScaleTo(this._entity, sizeX, sizeY, speedX, speedY));\r\n return this;\r\n }\r\n\r\n /**\r\n * This method will scale an actor by an amount relative to the current scale at a certain speed in scale units/sec\r\n * and return back the actor. This method is part of the\r\n * actor 'Action' fluent API allowing action chaining.\r\n * @param offset The scaling factor to apply to the actor\r\n * @param speed The speed to scale at in scale units/sec\r\n */\r\n public scaleBy(offset: Vector, speed: number): ActionContext;\r\n /**\r\n * This method will scale an actor by an amount relative to the current scale at a certain speed in scale units/sec\r\n * and return back the actor. This method is part of the\r\n * actor 'Action' fluent API allowing action chaining.\r\n * @param sizeOffsetX The scaling factor to apply on X axis\r\n * @param sizeOffsetY The scaling factor to apply on Y axis\r\n * @param speed The speed to scale at in scale units/sec\r\n */\r\n public scaleBy(sizeOffsetX: number, sizeOffsetY: number, speed: number): ActionContext;\r\n public scaleBy(sizeOffsetXOrVector: number | Vector, sizeOffsetYOrSpeed: number, speed?: number | undefined): ActionContext {\r\n let sizeOffsetX = 1;\r\n let sizeOffsetY = 1;\r\n\r\n if (sizeOffsetXOrVector instanceof Vector) {\r\n sizeOffsetX = sizeOffsetXOrVector.x;\r\n sizeOffsetY = sizeOffsetXOrVector.y;\r\n\r\n speed = sizeOffsetYOrSpeed;\r\n }\r\n if (typeof sizeOffsetXOrVector === 'number' && typeof sizeOffsetYOrSpeed === 'number') {\r\n sizeOffsetX = sizeOffsetXOrVector;\r\n sizeOffsetY = sizeOffsetYOrSpeed;\r\n }\r\n\r\n this._queue.add(new ScaleBy(this._entity, sizeOffsetX, sizeOffsetY, speed));\r\n return this;\r\n }\r\n\r\n /**\r\n * This method will cause an actor to blink (become visible and not\r\n * visible). Optionally, you may specify the number of blinks. Specify the amount of time\r\n * the actor should be visible per blink, and the amount of time not visible.\r\n * This method is part of the actor 'Action' fluent API allowing action chaining.\r\n * @param timeVisible The amount of time to stay visible per blink in milliseconds\r\n * @param timeNotVisible The amount of time to stay not visible per blink in milliseconds\r\n * @param numBlinks The number of times to blink\r\n */\r\n public blink(timeVisible: number, timeNotVisible: number, numBlinks: number = 1): ActionContext {\r\n this._queue.add(new Blink(this._entity, timeVisible, timeNotVisible, numBlinks));\r\n return this;\r\n }\r\n\r\n /**\r\n * This method will cause an actor's opacity to change from its current value\r\n * to the provided value by a specified time (in milliseconds). This method is\r\n * part of the actor 'Action' fluent API allowing action chaining.\r\n * @param opacity The ending opacity\r\n * @param time The time it should take to fade the actor (in milliseconds)\r\n */\r\n public fade(opacity: number, time: number): ActionContext {\r\n this._queue.add(new Fade(this._entity, opacity, time));\r\n return this;\r\n }\r\n\r\n /**\r\n * This method will delay the next action from executing for a certain\r\n * amount of time (in milliseconds). This method is part of the actor\r\n * 'Action' fluent API allowing action chaining.\r\n * @param time The amount of time to delay the next action in the queue from executing in milliseconds\r\n */\r\n public delay(time: number): ActionContext {\r\n this._queue.add(new Delay(time));\r\n return this;\r\n }\r\n\r\n /**\r\n * This method will add an action to the queue that will remove the actor from the\r\n * scene once it has completed its previous Any actions on the\r\n * action queue after this action will not be executed.\r\n */\r\n public die(): ActionContext {\r\n this._queue.add(new Die(this._entity));\r\n return this;\r\n }\r\n\r\n /**\r\n * This method allows you to call an arbitrary method as the next action in the\r\n * action queue. This is useful if you want to execute code in after a specific\r\n * action, i.e An actor arrives at a destination after traversing a path\r\n */\r\n public callMethod(method: () => any): ActionContext {\r\n this._queue.add(new CallMethod(method));\r\n return this;\r\n }\r\n\r\n /**\r\n * This method will cause the actor to repeat all of the actions built in\r\n * the `repeatBuilder` callback. If the number of repeats\r\n * is not specified it will repeat forever. This method is part of\r\n * the actor 'Action' fluent API allowing action chaining\r\n *\r\n * ```typescript\r\n * // Move up in a zig-zag by repeated moveBy's\r\n * actor.actions.repeat(repeatCtx => {\r\n * repeatCtx.moveBy(10, 0, 10);\r\n * repeatCtx.moveBy(0, 10, 10);\r\n * }, 5);\r\n * ```\r\n *\r\n * @param repeatBuilder The builder to specify the repeatable list of actions\r\n * @param times The number of times to repeat all the previous actions in the action queue. If nothing is specified the actions\r\n * will repeat forever\r\n */\r\n public repeat(repeatBuilder: (repeatContext: ActionContext) => any, times?: number): ActionContext {\r\n if (!times) {\r\n this.repeatForever(repeatBuilder);\r\n return this;\r\n }\r\n this._queue.add(new Repeat(this._entity, repeatBuilder, times));\r\n\r\n return this;\r\n }\r\n\r\n /**\r\n * This method will cause the actor to repeat all of the actions built in\r\n * the `repeatBuilder` callback. If the number of repeats\r\n * is not specified it will repeat forever. This method is part of\r\n * the actor 'Action' fluent API allowing action chaining\r\n *\r\n * ```typescript\r\n * // Move up in a zig-zag by repeated moveBy's\r\n * actor.actions.repeat(repeatCtx => {\r\n * repeatCtx.moveBy(10, 0, 10);\r\n * repeatCtx.moveBy(0, 10, 10);\r\n * }, 5);\r\n * ```\r\n *\r\n * @param repeatBuilder The builder to specify the repeatable list of actions\r\n */\r\n public repeatForever(repeatBuilder: (repeatContext: ActionContext) => any): ActionContext {\r\n this._queue.add(new RepeatForever(this._entity, repeatBuilder));\r\n return this;\r\n }\r\n\r\n /**\r\n * This method will cause the entity to follow another at a specified distance\r\n * @param entity The entity to follow\r\n * @param followDistance The distance to maintain when following, if not specified the actor will follow at the current distance.\r\n */\r\n public follow(entity: Entity, followDistance?: number): ActionContext {\r\n if (followDistance === undefined) {\r\n this._queue.add(new Follow(this._entity, entity));\r\n } else {\r\n this._queue.add(new Follow(this._entity, entity, followDistance));\r\n }\r\n return this;\r\n }\r\n\r\n /**\r\n * This method will cause the entity to move towards another until they\r\n * collide \"meet\" at a specified speed.\r\n * @param entity The entity to meet\r\n * @param speed The speed in pixels per second to move, if not specified it will match the speed of the other actor\r\n */\r\n public meet(entity: Entity, speed?: number): ActionContext {\r\n if (speed === undefined) {\r\n this._queue.add(new Meet(this._entity, entity));\r\n } else {\r\n this._queue.add(new Meet(this._entity, entity, speed));\r\n }\r\n return this;\r\n }\r\n\r\n /**\r\n * Returns a promise that resolves when the current action queue up to now\r\n * is finished.\r\n */\r\n public toPromise(): Promise {\r\n const temp = new Promise((resolve) => {\r\n this._queue.add(\r\n new CallMethod(() => {\r\n resolve();\r\n })\r\n );\r\n });\r\n return temp;\r\n }\r\n}\r\n","import { ActionContext } from './ActionContext';\r\nimport { Component } from '../EntityComponentSystem/Component';\r\nimport { Entity } from '../EntityComponentSystem/Entity';\r\nimport { Actor } from '../Actor';\r\nimport { MotionComponent } from '../EntityComponentSystem/Components/MotionComponent';\r\nimport { TransformComponent } from '../EntityComponentSystem/Components/TransformComponent';\r\nimport { Vector } from '../Math/vector';\r\nimport { EasingFunction } from '../Util/EasingFunctions';\r\nimport { ActionQueue } from './ActionQueue';\r\nimport { RotationType } from './RotationType';\r\nimport { Action } from './Action';\r\n\r\nexport interface ActionContextMethods extends Pick { };\r\n\r\nexport class ActionsComponent extends Component<'ex.actions'> implements ActionContextMethods {\r\n public readonly type = 'ex.actions';\r\n dependencies = [TransformComponent, MotionComponent];\r\n private _ctx: ActionContext;\r\n\r\n onAdd(entity: Entity) {\r\n this._ctx = new ActionContext(entity);\r\n }\r\n\r\n onRemove() {\r\n this._ctx = null;\r\n }\r\n\r\n /**\r\n * Returns the internal action queue\r\n * @returns action queue\r\n */\r\n public getQueue(): ActionQueue {\r\n return this._ctx?.getQueue();\r\n }\r\n\r\n public runAction(action: Action): ActionContext {\r\n return this._ctx?.runAction(action);\r\n }\r\n\r\n /**\r\n * Updates the internal action context, performing action and moving through the internal queue\r\n * @param elapsedMs\r\n */\r\n public update(elapsedMs: number): void {\r\n return this._ctx?.update(elapsedMs);\r\n }\r\n\r\n /**\r\n * Clears all queued actions from the Actor\r\n */\r\n public clearActions(): void {\r\n this._ctx?.clearActions();\r\n }\r\n\r\n /**\r\n * This method will move an actor to the specified `x` and `y` position over the\r\n * specified duration using a given [[EasingFunctions]] and return back the actor. This\r\n * method is part of the actor 'Action' fluent API allowing action chaining.\r\n * @param pos The x,y vector location to move the actor to\r\n * @param duration The time it should take the actor to move to the new location in milliseconds\r\n * @param easingFcn Use [[EasingFunctions]] or a custom function to use to calculate position, Default is [[EasingFunctions.Linear]]\r\n */\r\n public easeTo(pos: Vector, duration: number, easingFcn?: EasingFunction): ActionContext;\r\n /**\r\n * This method will move an actor to the specified `x` and `y` position over the\r\n * specified duration using a given [[EasingFunctions]] and return back the actor. This\r\n * method is part of the actor 'Action' fluent API allowing action chaining.\r\n * @param x The x location to move the actor to\r\n * @param y The y location to move the actor to\r\n * @param duration The time it should take the actor to move to the new location in milliseconds\r\n * @param easingFcn Use [[EasingFunctions]] or a custom function to use to calculate position, Default is [[EasingFunctions.Linear]]\r\n */\r\n public easeTo(x: number, y: number, duration: number, easingFcn?: EasingFunction): ActionContext;\r\n public easeTo(...args: any[]): ActionContext {\r\n return this._ctx.easeTo.apply(this._ctx, args);\r\n }\r\n\r\n public easeBy(offset: Vector, duration: number, easingFcn?: EasingFunction): ActionContext;\r\n public easeBy(offsetX: number, offsetY: number, duration: number, easingFcn?: EasingFunction): ActionContext;\r\n public easeBy(...args: any[]): ActionContext {\r\n return this._ctx.easeBy.apply(this._ctx, args);\r\n }\r\n\r\n /**\r\n * This method will move an actor to the specified x and y position at the\r\n * speed specified (in pixels per second) and return back the actor. This\r\n * method is part of the actor 'Action' fluent API allowing action chaining.\r\n * @param pos The x,y vector location to move the actor to\r\n * @param speed The speed in pixels per second to move\r\n */\r\n public moveTo(pos: Vector, speed: number): ActionContext;\r\n /**\r\n * This method will move an actor to the specified x and y position at the\r\n * speed specified (in pixels per second) and return back the actor. This\r\n * method is part of the actor 'Action' fluent API allowing action chaining.\r\n * @param x The x location to move the actor to\r\n * @param y The y location to move the actor to\r\n * @param speed The speed in pixels per second to move\r\n */\r\n public moveTo(x: number, y: number, speed: number): ActionContext;\r\n public moveTo(xOrPos: number | Vector, yOrSpeed: number, speedOrUndefined?: number): ActionContext {\r\n return this._ctx.moveTo.apply(this._ctx, [xOrPos, yOrSpeed, speedOrUndefined]);\r\n }\r\n\r\n /**\r\n * This method will move an actor by the specified x offset and y offset from its current position, at a certain speed.\r\n * This method is part of the actor 'Action' fluent API allowing action chaining.\r\n * @param offset The (x, y) offset to apply to this actor\r\n * @param speed The speed in pixels per second the actor should move\r\n */\r\n public moveBy(offset: Vector, speed: number): ActionContext;\r\n /**\r\n * This method will move an actor by the specified x offset and y offset from its current position, at a certain speed.\r\n * This method is part of the actor 'Action' fluent API allowing action chaining.\r\n * @param xOffset The x offset to apply to this actor\r\n * @param yOffset The y location to move the actor to\r\n * @param speed The speed in pixels per second the actor should move\r\n */\r\n public moveBy(xOffset: number, yOffset: number, speed: number): ActionContext;\r\n public moveBy(xOffsetOrVector: number | Vector, yOffsetOrSpeed: number, speedOrUndefined?: number): ActionContext {\r\n return this._ctx.moveBy.apply(this._ctx, [xOffsetOrVector, yOffsetOrSpeed, speedOrUndefined]);\r\n }\r\n\r\n /**\r\n * This method will rotate an actor to the specified angle at the speed\r\n * specified (in radians per second) and return back the actor. This\r\n * method is part of the actor 'Action' fluent API allowing action chaining.\r\n * @param angleRadians The angle to rotate to in radians\r\n * @param speed The angular velocity of the rotation specified in radians per second\r\n * @param rotationType The [[RotationType]] to use for this rotation\r\n */\r\n public rotateTo(angleRadians: number, speed: number, rotationType?: RotationType): ActionContext {\r\n return this._ctx.rotateTo(angleRadians, speed, rotationType);\r\n }\r\n\r\n /**\r\n * This method will rotate an actor by the specified angle offset, from it's current rotation given a certain speed\r\n * in radians/sec and return back the actor. This method is part\r\n * of the actor 'Action' fluent API allowing action chaining.\r\n * @param angleRadiansOffset The angle to rotate to in radians relative to the current rotation\r\n * @param speed The speed in radians/sec the actor should rotate at\r\n * @param rotationType The [[RotationType]] to use for this rotation, default is shortest path\r\n */\r\n public rotateBy(angleRadiansOffset: number, speed: number, rotationType?: RotationType): ActionContext {\r\n return this._ctx.rotateBy(angleRadiansOffset, speed, rotationType);\r\n }\r\n\r\n /**\r\n * This method will scale an actor to the specified size at the speed\r\n * specified (in magnitude increase per second) and return back the\r\n * actor. This method is part of the actor 'Action' fluent API allowing\r\n * action chaining.\r\n * @param size The scale to adjust the actor to over time\r\n * @param speed The speed of scaling specified in magnitude increase per second\r\n */\r\n public scaleTo(size: Vector, speed: Vector): ActionContext;\r\n /**\r\n * This method will scale an actor to the specified size at the speed\r\n * specified (in magnitude increase per second) and return back the\r\n * actor. This method is part of the actor 'Action' fluent API allowing\r\n * action chaining.\r\n * @param sizeX The scaling factor to apply on X axis\r\n * @param sizeY The scaling factor to apply on Y axis\r\n * @param speedX The speed of scaling specified in magnitude increase per second on X axis\r\n * @param speedY The speed of scaling specified in magnitude increase per second on Y axis\r\n */\r\n public scaleTo(sizeX: number, sizeY: number, speedX: number, speedY: number): ActionContext;\r\n public scaleTo(\r\n sizeXOrVector: number | Vector,\r\n sizeYOrSpeed: number | Vector,\r\n speedXOrUndefined?: number,\r\n speedYOrUndefined?: number): ActionContext {\r\n return this._ctx.scaleTo.apply(this._ctx, [sizeXOrVector, sizeYOrSpeed, speedXOrUndefined, speedYOrUndefined]);\r\n }\r\n\r\n /**\r\n * This method will scale an actor by an amount relative to the current scale at a certain speed in scale units/sec\r\n * and return back the actor. This method is part of the\r\n * actor 'Action' fluent API allowing action chaining.\r\n * @param offset The scaling factor to apply to the actor\r\n * @param speed The speed to scale at in scale units/sec\r\n */\r\n public scaleBy(offset: Vector, speed: number): ActionContext;\r\n /**\r\n * This method will scale an actor by an amount relative to the current scale at a certain speed in scale units/sec\r\n * and return back the actor. This method is part of the\r\n * actor 'Action' fluent API allowing action chaining.\r\n * @param sizeOffsetX The scaling factor to apply on X axis\r\n * @param sizeOffsetY The scaling factor to apply on Y axis\r\n * @param speed The speed to scale at in scale units/sec\r\n */\r\n public scaleBy(sizeOffsetX: number, sizeOffsetY: number, speed: number): ActionContext;\r\n public scaleBy(sizeOffsetXOrVector: number | Vector, sizeOffsetYOrSpeed: number, speed?: number): ActionContext {\r\n return this._ctx.scaleBy.apply(this._ctx, [sizeOffsetXOrVector, sizeOffsetYOrSpeed, speed]);\r\n }\r\n\r\n /**\r\n * This method will cause an actor to blink (become visible and not\r\n * visible). Optionally, you may specify the number of blinks. Specify the amount of time\r\n * the actor should be visible per blink, and the amount of time not visible.\r\n * This method is part of the actor 'Action' fluent API allowing action chaining.\r\n * @param timeVisible The amount of time to stay visible per blink in milliseconds\r\n * @param timeNotVisible The amount of time to stay not visible per blink in milliseconds\r\n * @param numBlinks The number of times to blink\r\n */\r\n public blink(timeVisible: number, timeNotVisible: number, numBlinks?: number): ActionContext {\r\n return this._ctx.blink(timeVisible, timeNotVisible, numBlinks);\r\n }\r\n\r\n /**\r\n * This method will cause an actor's opacity to change from its current value\r\n * to the provided value by a specified time (in milliseconds). This method is\r\n * part of the actor 'Action' fluent API allowing action chaining.\r\n * @param opacity The ending opacity\r\n * @param time The time it should take to fade the actor (in milliseconds)\r\n */\r\n public fade(opacity: number, time: number): ActionContext {\r\n return this._ctx.fade(opacity, time);\r\n }\r\n\r\n /**\r\n * This method will delay the next action from executing for a certain\r\n * amount of time (in milliseconds). This method is part of the actor\r\n * 'Action' fluent API allowing action chaining.\r\n * @param time The amount of time to delay the next action in the queue from executing in milliseconds\r\n */\r\n public delay(time: number): ActionContext {\r\n return this._ctx.delay(time);\r\n }\r\n\r\n /**\r\n * This method will add an action to the queue that will remove the actor from the\r\n * scene once it has completed its previous Any actions on the\r\n * action queue after this action will not be executed.\r\n */\r\n public die(): ActionContext {\r\n return this._ctx.die();\r\n }\r\n\r\n /**\r\n * This method allows you to call an arbitrary method as the next action in the\r\n * action queue. This is useful if you want to execute code in after a specific\r\n * action, i.e An actor arrives at a destination after traversing a path\r\n */\r\n public callMethod(method: () => any): ActionContext {\r\n return this._ctx.callMethod(method);\r\n }\r\n\r\n /**\r\n * This method will cause the actor to repeat all of the actions built in\r\n * the `repeatBuilder` callback. If the number of repeats\r\n * is not specified it will repeat forever. This method is part of\r\n * the actor 'Action' fluent API allowing action chaining\r\n *\r\n * ```typescript\r\n * // Move up in a zig-zag by repeated moveBy's\r\n * actor.actions.repeat(repeatCtx => {\r\n * repeatCtx.moveBy(10, 0, 10);\r\n * repeatCtx.moveBy(0, 10, 10);\r\n * }, 5);\r\n * ```\r\n *\r\n * @param repeatBuilder The builder to specify the repeatable list of actions\r\n * @param times The number of times to repeat all the previous actions in the action queue. If nothing is specified the actions\r\n * will repeat forever\r\n */\r\n public repeat(repeatBuilder: (repeatContext: ActionContext) => any, times?: number): ActionContext {\r\n return this._ctx.repeat(repeatBuilder, times);\r\n }\r\n\r\n /**\r\n * This method will cause the actor to repeat all of the actions built in\r\n * the `repeatBuilder` callback. If the number of repeats\r\n * is not specified it will repeat forever. This method is part of\r\n * the actor 'Action' fluent API allowing action chaining\r\n *\r\n * ```typescript\r\n * // Move up in a zig-zag by repeated moveBy's\r\n * actor.actions.repeat(repeatCtx => {\r\n * repeatCtx.moveBy(10, 0, 10);\r\n * repeatCtx.moveBy(0, 10, 10);\r\n * }, 5);\r\n * ```\r\n *\r\n * @param repeatBuilder The builder to specify the repeatable list of actions\r\n */\r\n public repeatForever(repeatBuilder: (repeatContext: ActionContext) => any): ActionContext {\r\n return this._ctx.repeatForever(repeatBuilder);\r\n }\r\n\r\n /**\r\n * This method will cause the entity to follow another at a specified distance\r\n * @param entity The entity to follow\r\n * @param followDistance The distance to maintain when following, if not specified the actor will follow at the current distance.\r\n */\r\n public follow(entity: Actor, followDistance?: number): ActionContext {\r\n return this._ctx.follow(entity, followDistance);\r\n }\r\n\r\n /**\r\n * This method will cause the entity to move towards another until they\r\n * collide \"meet\" at a specified speed.\r\n * @param entity The entity to meet\r\n * @param speed The speed in pixels per second to move, if not specified it will match the speed of the other actor\r\n */\r\n public meet(entity: Actor, speed?: number): ActionContext {\r\n return this._ctx.meet(entity, speed);\r\n }\r\n\r\n /**\r\n * Returns a promise that resolves when the current action queue up to now\r\n * is finished.\r\n */\r\n public toPromise(): Promise {\r\n return this._ctx.toPromise();\r\n }\r\n}","import { BoundingBox } from '../Collision/BoundingBox';\r\nimport { Color } from '../Color';\r\nimport { Vector } from '../Math/vector';\r\nimport { ExcaliburGraphicsContext } from './Context/ExcaliburGraphicsContext';\r\n\r\n/**\r\n * Enum representing the different font size units\r\n * https://developer.mozilla.org/en-US/docs/Web/CSS/font-size\r\n */\r\nexport enum FontUnit {\r\n /**\r\n * Em is a scalable unit, 1 em is equal to the current font size of the current element, parent elements can effect em values\r\n */\r\n Em = 'em',\r\n /**\r\n * Rem is similar to the Em, it is a scalable unit. 1 rem is equal to the font size of the root element\r\n */\r\n Rem = 'rem',\r\n /**\r\n * Pixel is a unit of length in screen pixels\r\n */\r\n Px = 'px',\r\n /**\r\n * Point is a physical unit length (1/72 of an inch)\r\n */\r\n Pt = 'pt',\r\n /**\r\n * Percent is a scalable unit similar to Em, the only difference is the Em units scale faster when Text-Size stuff\r\n */\r\n Percent = '%'\r\n}\r\n\r\n/**\r\n * Enum representing the different horizontal text alignments\r\n */\r\nexport enum TextAlign {\r\n /**\r\n * The text is left-aligned.\r\n */\r\n Left = 'left',\r\n /**\r\n * The text is right-aligned.\r\n */\r\n Right = 'right',\r\n /**\r\n * The text is centered.\r\n */\r\n Center = 'center',\r\n /**\r\n * The text is aligned at the normal start of the line (left-aligned for left-to-right locales,\r\n * right-aligned for right-to-left locales).\r\n */\r\n Start = 'start',\r\n /**\r\n * The text is aligned at the normal end of the line (right-aligned for left-to-right locales,\r\n * left-aligned for right-to-left locales).\r\n */\r\n End = 'end'\r\n}\r\n\r\n/**\r\n * Enum representing the different baseline text alignments\r\n */\r\nexport enum BaseAlign {\r\n /**\r\n * The text baseline is the top of the em square.\r\n */\r\n Top = 'top',\r\n /**\r\n * The text baseline is the hanging baseline. Currently unsupported; this will act like\r\n * alphabetic.\r\n */\r\n Hanging = 'hanging',\r\n /**\r\n * The text baseline is the middle of the em square.\r\n */\r\n Middle = 'middle',\r\n /**\r\n * The text baseline is the normal alphabetic baseline.\r\n */\r\n Alphabetic = 'alphabetic',\r\n /**\r\n * The text baseline is the ideographic baseline; this is the bottom of\r\n * the body of the characters, if the main body of characters protrudes\r\n * beneath the alphabetic baseline. Currently unsupported; this will\r\n * act like alphabetic.\r\n */\r\n Ideographic = 'ideographic',\r\n /**\r\n * The text baseline is the bottom of the bounding box. This differs\r\n * from the ideographic baseline in that the ideographic baseline\r\n * doesn't consider descenders.\r\n */\r\n Bottom = 'bottom'\r\n}\r\n\r\n/**\r\n * Enum representing the different possible font styles\r\n */\r\nexport enum FontStyle {\r\n Normal = 'normal',\r\n Italic = 'italic',\r\n Oblique = 'oblique'\r\n}\r\n\r\n/**\r\n * Enum representing the text direction, useful for other languages, or writing text in reverse\r\n */\r\nexport enum Direction {\r\n LeftToRight = 'ltr',\r\n RightToLeft = 'rtl'\r\n}\r\n\r\n/**\r\n * Font rendering option\r\n */\r\nexport interface FontOptions {\r\n /**\r\n * Optionally the size of the font in the specified [[FontUnit]] by default 10.\r\n */\r\n size?: number;\r\n /**\r\n * Optionally specify unit to measure fonts in, by default Pixels\r\n */\r\n unit?: FontUnit;\r\n /**\r\n * Optionally specify the font family, by default 'sans-serif'\r\n */\r\n family?: string;\r\n /**\r\n * Optionally specify the font style, by default Normal\r\n */\r\n style?: FontStyle;\r\n /**\r\n * Optionally set whether the font is bold, by default false\r\n */\r\n bold?: boolean;\r\n /**\r\n * Optionally specify the text align, by default Left\r\n */\r\n textAlign?: TextAlign;\r\n /**\r\n * Optionally specify the text base align, by default Alphabetic\r\n */\r\n baseAlign?: BaseAlign;\r\n /**\r\n * Optionally specify the text direction, by default LeftToRight\r\n */\r\n direction?: Direction;\r\n /**\r\n * Optionally specify the quality of the text bitmap, it is a multiplier on the size size, by default 2.\r\n * Higher quality text has a higher memory impact\r\n */\r\n quality?: number;\r\n /**\r\n * Optionally specify a text shadow, by default none is specified\r\n */\r\n shadow?: {\r\n blur?: number;\r\n offset?: Vector;\r\n color?: Color;\r\n };\r\n}\r\n\r\n/**\r\n * @internal\r\n */\r\nexport interface FontRenderer {\r\n measureText(text: string): BoundingBox;\r\n render(ex: ExcaliburGraphicsContext, text: string, color: Color, x: number, y: number): void;\r\n}\r\n","import { BoundingBox } from '../Collision/BoundingBox';\r\nimport { Color } from '../Color';\r\nimport { line } from '../Util/DrawUtil';\r\nimport { ExcaliburGraphicsContextWebGL } from './Context/ExcaliburGraphicsContextWebGL';\r\nimport { ExcaliburGraphicsContext } from './Context/ExcaliburGraphicsContext';\r\nimport { Font } from './Font';\r\n\r\nexport class FontTextInstance {\r\n public canvas: HTMLCanvasElement;\r\n public ctx: CanvasRenderingContext2D;\r\n private _textFragments: { x: number; y: number; canvas: HTMLCanvasElement }[] = [];\r\n public dimensions: BoundingBox;\r\n public disposed: boolean = false;\r\n private _lastHashCode: string;\r\n\r\n constructor(public readonly font: Font, public readonly text: string, public readonly color: Color, public readonly maxWidth?: number) {\r\n this.canvas = document.createElement('canvas');\r\n this.ctx = this.canvas.getContext('2d');\r\n this.dimensions = this.measureText(text);\r\n this._setDimension(this.dimensions, this.ctx);\r\n this._lastHashCode = this.getHashCode();\r\n }\r\n\r\n measureText(text: string, maxWidth?: number): BoundingBox {\r\n if (this.disposed) {\r\n throw Error('Accessing disposed text instance! ' + this.text);\r\n }\r\n let lines = null;\r\n if (maxWidth != null) {\r\n lines = this._getLinesFromText(text, maxWidth);\r\n } else {\r\n lines = text.split('\\n');\r\n }\r\n\r\n const maxWidthLine = lines.reduce((a, b) => {\r\n return a.length > b.length ? a : b;\r\n });\r\n\r\n this._applyFont(this.ctx); // font must be applied to the context to measure it\r\n const metrics = this.ctx.measureText(maxWidthLine);\r\n let textHeight = Math.abs(metrics.actualBoundingBoxAscent) + Math.abs(metrics.actualBoundingBoxDescent);\r\n\r\n // TODO lineheight makes the text bounds wonky\r\n const lineAdjustedHeight = textHeight * lines.length;\r\n textHeight = lineAdjustedHeight;\r\n const bottomBounds = lineAdjustedHeight - Math.abs(metrics.actualBoundingBoxAscent);\r\n const x = 0;\r\n const y = 0;\r\n const measurement = new BoundingBox({\r\n left: x - Math.abs(metrics.actualBoundingBoxLeft) - this.font.padding,\r\n top: y - Math.abs(metrics.actualBoundingBoxAscent) - this.font.padding,\r\n bottom: y + bottomBounds + this.font.padding,\r\n right: x + Math.abs(metrics.actualBoundingBoxRight) + this.font.padding\r\n });\r\n\r\n return measurement;\r\n }\r\n\r\n private _setDimension(textBounds: BoundingBox, bitmap: CanvasRenderingContext2D) {\r\n // Changing the width and height clears the context properties\r\n // We double the bitmap width to account for all possible alignment\r\n // We scale by \"quality\" so we render text without jaggies\r\n bitmap.canvas.width = (textBounds.width + this.font.padding * 2) * 2 * this.font.quality;\r\n bitmap.canvas.height = (textBounds.height + this.font.padding * 2) * 2 * this.font.quality;\r\n }\r\n\r\n public static getHashCode(font: Font, text: string, color?: Color) {\r\n const hash =\r\n text +\r\n '__hashcode__' +\r\n font.fontString +\r\n font.showDebug +\r\n font.textAlign +\r\n font.baseAlign +\r\n font.direction +\r\n JSON.stringify(font.shadow) +\r\n (font.padding.toString() +\r\n font.smoothing.toString() +\r\n font.lineWidth.toString() +\r\n font.lineDash.toString() +\r\n font.strokeColor?.toString() +\r\n (color ? color.toString() : font.color.toString()));\r\n return hash;\r\n }\r\n\r\n getHashCode(includeColor: boolean = true) {\r\n return FontTextInstance.getHashCode(this.font, this.text, includeColor ? this.color : undefined);\r\n }\r\n\r\n protected _applyRasterProperties(ctx: CanvasRenderingContext2D) {\r\n ctx.translate(this.font.padding, this.font.padding);\r\n ctx.imageSmoothingEnabled = this.font.smoothing;\r\n ctx.lineWidth = this.font.lineWidth;\r\n ctx.setLineDash(this.font.lineDash ?? ctx.getLineDash());\r\n ctx.strokeStyle = this.font.strokeColor?.toString();\r\n ctx.fillStyle = this.color.toString();\r\n }\r\n\r\n private _applyFont(ctx: CanvasRenderingContext2D) {\r\n ctx.resetTransform();\r\n ctx.translate(this.font.padding + ctx.canvas.width / 2, this.font.padding + ctx.canvas.height / 2);\r\n ctx.scale(this.font.quality, this.font.quality);\r\n ctx.textAlign = this.font.textAlign;\r\n ctx.textBaseline = this.font.baseAlign;\r\n ctx.font = this.font.fontString;\r\n ctx.direction = this.font.direction;\r\n\r\n if (this.font.shadow) {\r\n ctx.shadowColor = this.font.shadow.color.toString();\r\n ctx.shadowBlur = this.font.shadow.blur;\r\n ctx.shadowOffsetX = this.font.shadow.offset.x;\r\n ctx.shadowOffsetY = this.font.shadow.offset.y;\r\n }\r\n }\r\n\r\n private _drawText(ctx: CanvasRenderingContext2D, lines: string[], lineHeight: number): void {\r\n this._applyRasterProperties(ctx);\r\n this._applyFont(ctx);\r\n\r\n for (let i = 0; i < lines.length; i++) {\r\n const line = lines[i];\r\n if (this.color) {\r\n ctx.fillText(line, 0, i * lineHeight);\r\n }\r\n\r\n if (this.font.strokeColor) {\r\n ctx.strokeText(line, 0, i * lineHeight);\r\n }\r\n }\r\n\r\n if (this.font.showDebug) {\r\n // Horizontal line\r\n /* istanbul ignore next */\r\n line(ctx, Color.Green, -ctx.canvas.width / 2, 0, ctx.canvas.width / 2, 0, 2);\r\n // Vertical line\r\n /* istanbul ignore next */\r\n line(ctx, Color.Red, 0, -ctx.canvas.height / 2, 0, ctx.canvas.height / 2, 2);\r\n }\r\n }\r\n\r\n private _splitTextBitmap(bitmap: CanvasRenderingContext2D) {\r\n const textImages: { x: number; y: number; canvas: HTMLCanvasElement }[] = [];\r\n let currentX = 0;\r\n let currentY = 0;\r\n // 4k is the max for mobile devices\r\n const width = Math.min(4096, bitmap.canvas.width);\r\n const height = Math.min(4096, bitmap.canvas.height);\r\n\r\n // Splits the original bitmap into 4k max chunks\r\n while (currentX < bitmap.canvas.width) {\r\n while (currentY < bitmap.canvas.height) {\r\n // create new bitmap\r\n const canvas = document.createElement('canvas');\r\n canvas.width = width;\r\n canvas.height = height;\r\n const ctx = canvas.getContext('2d');\r\n\r\n // draw current slice to new bitmap in < 4k chunks\r\n ctx.drawImage(bitmap.canvas, currentX, currentY, width, height, 0, 0, width, height);\r\n\r\n textImages.push({ x: currentX, y: currentY, canvas });\r\n currentY += height;\r\n }\r\n currentX += width;\r\n currentY = 0;\r\n }\r\n return textImages;\r\n }\r\n\r\n public flagDirty() {\r\n this._dirty = true;\r\n }\r\n private _dirty = true;\r\n private _ex: ExcaliburGraphicsContext;\r\n public render(ex: ExcaliburGraphicsContext, x: number, y: number, maxWidth?: number) {\r\n if (this.disposed) {\r\n throw Error('Accessing disposed text instance! ' + this.text);\r\n }\r\n this._ex = ex;\r\n const hashCode = this.getHashCode();\r\n if (this._lastHashCode !== hashCode) {\r\n this._dirty = true;\r\n }\r\n\r\n // Calculate image chunks\r\n if (this._dirty) {\r\n this.dimensions = this.measureText(this.text, maxWidth);\r\n this._setDimension(this.dimensions, this.ctx);\r\n const lines = this._getLinesFromText(this.text, maxWidth);\r\n const lineHeight = this.dimensions.height / lines.length;\r\n\r\n // draws the text to the main bitmap\r\n this._drawText(this.ctx, lines, lineHeight);\r\n\r\n // clear any out old fragments\r\n if (ex instanceof ExcaliburGraphicsContextWebGL) {\r\n for (const frag of this._textFragments) {\r\n ex.textureLoader.delete(frag.canvas);\r\n }\r\n }\r\n\r\n // splits to < 4k fragments for large text\r\n this._textFragments = this._splitTextBitmap(this.ctx);\r\n\r\n if (ex instanceof ExcaliburGraphicsContextWebGL) {\r\n for (const frag of this._textFragments) {\r\n ex.textureLoader.load(frag.canvas, this.font.filtering, true);\r\n }\r\n }\r\n this._lastHashCode = hashCode;\r\n this._dirty = false;\r\n }\r\n\r\n // draws the bitmap fragments to excalibur graphics context\r\n for (const frag of this._textFragments) {\r\n ex.drawImage(\r\n frag.canvas,\r\n 0,\r\n 0,\r\n frag.canvas.width,\r\n frag.canvas.height,\r\n frag.x / this.font.quality + x - this.ctx.canvas.width / this.font.quality / 2,\r\n frag.y / this.font.quality + y - this.ctx.canvas.height / this.font.quality / 2,\r\n frag.canvas.width / this.font.quality,\r\n frag.canvas.height / this.font.quality\r\n );\r\n }\r\n }\r\n\r\n dispose() {\r\n this.disposed = true;\r\n this.dimensions = undefined;\r\n this.canvas = undefined;\r\n this.ctx = undefined;\r\n if (this._ex instanceof ExcaliburGraphicsContextWebGL) {\r\n for (const frag of this._textFragments) {\r\n this._ex.textureLoader.delete(frag.canvas);\r\n }\r\n }\r\n this._textFragments.length = 0;\r\n }\r\n\r\n /**\r\n * Return array of lines split based on the \\n character, and the maxWidth? constraint\r\n * @param text\r\n * @param maxWidth\r\n */\r\n private _chachedText: string;\r\n private _chachedLines: string[];\r\n private _cachedRenderWidth: number;\r\n private _getLinesFromText(text: string, maxWidth?: number) {\r\n if (this._chachedText === text && this._cachedRenderWidth === maxWidth) {\r\n return this._chachedLines;\r\n }\r\n\r\n const lines = text.split('\\n');\r\n\r\n if (maxWidth == null) {\r\n return lines;\r\n }\r\n\r\n // If the current line goes past the maxWidth, append a new line without modifying the underlying text.\r\n for (let i = 0; i < lines.length; i++) {\r\n let line = lines[i];\r\n let newLine = '';\r\n if (this.measureText(line).width > maxWidth) {\r\n while (this.measureText(line).width > maxWidth) {\r\n newLine = line[line.length - 1] + newLine;\r\n line = line.slice(0, -1); // Remove last character from line\r\n }\r\n\r\n // Update the array with our new values\r\n lines[i] = line;\r\n lines[i + 1] = newLine;\r\n }\r\n }\r\n\r\n this._chachedText = text;\r\n this._chachedLines = lines;\r\n this._cachedRenderWidth = maxWidth;\r\n\r\n return lines;\r\n }\r\n}\r\n","import { BoundingBox } from '../Collision/BoundingBox';\r\nimport { Color } from '../Color';\r\nimport { Logger } from '../Util/Log';\r\nimport { Font } from './Font';\r\nimport { FontTextInstance } from './FontTextInstance';\r\n\r\nexport class FontCache {\r\n private static _LOGGER = Logger.getInstance();\r\n private static _TEXT_USAGE = new Map();\r\n private static _TEXT_CACHE = new Map();\r\n private static _MEASURE_CACHE = new Map();\r\n\r\n static measureText(text: string, font: Font, maxWidth?: number) {\r\n const hash = FontTextInstance.getHashCode(font, text);\r\n if (FontCache._MEASURE_CACHE.has(hash)) {\r\n return FontCache._MEASURE_CACHE.get(hash);\r\n }\r\n FontCache._LOGGER.debug('Font text measurement cache miss');\r\n const measurement = font.measureTextWithoutCache(text, maxWidth);\r\n FontCache._MEASURE_CACHE.set(hash, measurement);\r\n return measurement;\r\n }\r\n\r\n static getTextInstance(text: string, font: Font, color: Color) {\r\n const hash = FontTextInstance.getHashCode(font, text, color);\r\n let textInstance = FontCache._TEXT_CACHE.get(hash);\r\n if (!textInstance) {\r\n textInstance = new FontTextInstance(font, text, color);\r\n FontCache._TEXT_CACHE.set(hash, textInstance);\r\n FontCache._LOGGER.debug('Font text instance cache miss');\r\n }\r\n\r\n // Cache the bitmap for certain amount of time\r\n FontCache._TEXT_USAGE.set(textInstance, performance.now());\r\n\r\n return textInstance;\r\n }\r\n\r\n static checkAndClearCache() {\r\n const deferred: FontTextInstance[] = [];\r\n const currentHashCodes = new Set();\r\n for (const [textInstance, time] of FontCache._TEXT_USAGE.entries()) {\r\n // if bitmap hasn't been used in 100 ms clear it\r\n if (time + 100 < performance.now()) {\r\n FontCache._LOGGER.debug(`Text cache entry timed out ${textInstance.text}`);\r\n deferred.push(textInstance);\r\n textInstance.dispose();\r\n } else {\r\n const hash = textInstance.getHashCode(false);\r\n currentHashCodes.add(hash);\r\n }\r\n }\r\n // Deferred removal of text instances\r\n deferred.forEach((t) => {\r\n FontCache._TEXT_USAGE.delete(t);\r\n });\r\n\r\n // Regenerate text instance cache\r\n this._TEXT_CACHE.clear();\r\n for (const [textInstance] of this._TEXT_USAGE.entries()) {\r\n this._TEXT_CACHE.set(textInstance.getHashCode(), textInstance);\r\n }\r\n\r\n // Regenerated measurement cache\r\n const newTextMeasurementCache = new Map();\r\n for (const current of currentHashCodes) {\r\n if (FontCache._MEASURE_CACHE.has(current)) {\r\n newTextMeasurementCache.set(current, FontCache._MEASURE_CACHE.get(current));\r\n }\r\n }\r\n this._MEASURE_CACHE.clear();\r\n this._MEASURE_CACHE = newTextMeasurementCache;\r\n }\r\n\r\n public static get cacheSize() {\r\n return FontCache._TEXT_USAGE.size;\r\n }\r\n\r\n /**\r\n * Force clear all cached text bitmaps\r\n */\r\n public static clearCache() {\r\n for (const [textInstance] of FontCache._TEXT_USAGE.entries()) {\r\n textInstance.dispose();\r\n }\r\n FontCache._TEXT_USAGE.clear();\r\n FontCache._TEXT_CACHE.clear();\r\n FontCache._MEASURE_CACHE.clear();\r\n }\r\n}\r\n","import { Vector } from '../Math/vector';\r\nimport { BoundingBox } from '../Collision/Index';\r\nimport { Color } from '../Color';\r\nimport { ExcaliburGraphicsContext } from './Context/ExcaliburGraphicsContext';\r\nimport { BaseAlign, Direction, FontOptions, FontStyle, FontUnit, TextAlign, FontRenderer } from './FontCommon';\r\nimport { Graphic, GraphicOptions } from './Graphic';\r\nimport { RasterOptions } from './Raster';\r\nimport { ImageFiltering } from './Filtering';\r\nimport { FontTextInstance } from './FontTextInstance';\r\nimport { FontCache } from './FontCache';\r\n/**\r\n * Represents a system or web font in Excalibur\r\n *\r\n * If no options specified, the system sans-serif 10 pixel is used\r\n *\r\n * If loading a custom web font be sure to have the font loaded before you use it https://erikonarheim.com/posts/dont-test-fonts/\r\n */\r\nexport class Font extends Graphic implements FontRenderer {\r\n /**\r\n * Set the font filtering mode, by default set to [[ImageFiltering.Blended]] regardless of the engine default smoothing\r\n *\r\n * If you have a pixel style font that may be a reason to switch this to [[ImageFiltering.Pixel]]\r\n */\r\n public filtering: ImageFiltering = ImageFiltering.Blended;\r\n constructor(options: FontOptions & GraphicOptions & RasterOptions = {}) {\r\n super(options); // <- Graphics properties\r\n\r\n // Raster properties\r\n this.smoothing = options?.smoothing ?? this.smoothing;\r\n this.padding = options?.padding ?? this.padding;\r\n this.color = options?.color ?? this.color;\r\n this.strokeColor = options?.strokeColor ?? this.strokeColor;\r\n this.lineDash = options?.lineDash ?? this.lineDash;\r\n this.lineWidth = options?.lineWidth ?? this.lineWidth;\r\n this.filtering = options?.filtering ?? this.filtering;\r\n\r\n // Font specific properties\r\n this.family = options?.family ?? this.family;\r\n this.style = options?.style ?? this.style;\r\n this.bold = options?.bold ?? this.bold;\r\n this.size = options?.size ?? this.size;\r\n this.unit = options?.unit ?? this.unit;\r\n this.textAlign = options?.textAlign ?? this.textAlign;\r\n this.baseAlign = options?.baseAlign ?? this.baseAlign;\r\n this.direction = options?.direction ?? this.direction;\r\n this.quality = options?.quality ?? this.quality;\r\n if (options?.shadow) {\r\n this.shadow = {};\r\n this.shadow.blur = options.shadow.blur ?? this.shadow.blur;\r\n this.shadow.offset = options.shadow.offset ?? this.shadow.offset;\r\n this.shadow.color = options.shadow.color ?? this.shadow.color;\r\n }\r\n }\r\n\r\n public clone() {\r\n return new Font({\r\n ...this.cloneGraphicOptions(),\r\n size: this.size,\r\n unit: this.unit,\r\n family: this.family,\r\n style: this.style,\r\n bold: this.bold,\r\n textAlign: this.textAlign,\r\n baseAlign: this.baseAlign,\r\n direction: this.direction,\r\n shadow: this.shadow\r\n ? {\r\n blur: this.shadow.blur,\r\n offset: this.shadow.offset,\r\n color: this.shadow.color\r\n }\r\n : null\r\n });\r\n }\r\n\r\n /**\r\n * Font quality determines the size of the underlying raster text, higher quality means less jagged edges.\r\n * If quality is set to 1, then just enough raster bitmap is generated to render the text.\r\n *\r\n * You can think of quality as how zoomed in to the text you can get before seeing jagged edges.\r\n *\r\n * (Default 2)\r\n */\r\n public quality = 2;\r\n\r\n // Raster properties for fonts\r\n public padding = 2;\r\n public smoothing = false;\r\n public lineWidth = 1;\r\n public lineDash: number[] = [];\r\n public color: Color = Color.Black;\r\n public strokeColor: Color;\r\n\r\n public family: string = 'sans-serif';\r\n public style: FontStyle = FontStyle.Normal;\r\n public bold: boolean = false;\r\n public unit: FontUnit = FontUnit.Px;\r\n public textAlign: TextAlign = TextAlign.Left;\r\n public baseAlign: BaseAlign = BaseAlign.Alphabetic;\r\n public direction: Direction = Direction.LeftToRight;\r\n public size: number = 10;\r\n public shadow: { blur?: number; offset?: Vector; color?: Color } = null;\r\n\r\n public get fontString() {\r\n return `${this.style} ${this.bold ? 'bold' : ''} ${this.size}${this.unit} ${this.family}`;\r\n }\r\n\r\n private _textBounds: BoundingBox = new BoundingBox();\r\n\r\n public get localBounds(): BoundingBox {\r\n return this._textBounds;\r\n }\r\n\r\n protected _drawImage(_ex: ExcaliburGraphicsContext, _x: number, _y: number) {\r\n // TODO weird vestigial drawimage\r\n }\r\n\r\n protected _rotate(ex: ExcaliburGraphicsContext) {\r\n // TODO this needs to change depending on the bounding box...\r\n const origin = this.origin ?? this._textBounds.center;\r\n ex.translate(origin.x, origin.y);\r\n ex.rotate(this.rotation);\r\n ex.translate(-origin.x, -origin.y);\r\n }\r\n\r\n protected _flip(ex: ExcaliburGraphicsContext) {\r\n if (this.flipHorizontal) {\r\n ex.translate(this._textBounds.width / this.scale.x, 0);\r\n ex.scale(-1, 1);\r\n }\r\n\r\n if (this.flipVertical) {\r\n ex.translate(0, -this._textBounds.height / 2 / this.scale.y);\r\n ex.scale(1, -1);\r\n }\r\n }\r\n\r\n private _textMeasurement = new FontTextInstance(this, '', Color.Black);\r\n\r\n public measureTextWithoutCache(text: string, maxWidth?: number) {\r\n return this._textMeasurement.measureText(text, maxWidth);\r\n }\r\n\r\n /**\r\n * Returns a BoundingBox that is the total size of the text including multiple lines\r\n *\r\n * Does not include any padding or adjustment\r\n * @param text\r\n * @returns BoundingBox\r\n */\r\n public measureText(text: string, maxWidth?: number): BoundingBox {\r\n return FontCache.measureText(text, this, maxWidth);\r\n }\r\n\r\n protected _postDraw(ex: ExcaliburGraphicsContext): void {\r\n ex.restore();\r\n }\r\n\r\n public render(ex: ExcaliburGraphicsContext, text: string, colorOverride: Color, x: number, y: number, maxWidth?: number) {\r\n const textInstance = FontCache.getTextInstance(text, this, colorOverride);\r\n\r\n // Apply affine transformations\r\n this._textBounds = textInstance.dimensions;\r\n this._preDraw(ex, x, y);\r\n\r\n textInstance.render(ex, x, y, maxWidth);\r\n\r\n this._postDraw(ex);\r\n }\r\n}\r\n","import { ExcaliburGraphicsContext } from './Context/ExcaliburGraphicsContext';\r\nimport { BoundingBox } from '../Collision/BoundingBox';\r\nimport { SpriteFont } from './SpriteFont';\r\nimport { Graphic, GraphicOptions } from './Graphic';\r\nimport { Color } from '../Color';\r\nimport { Font } from './Font';\r\n\r\nexport interface TextOptions {\r\n /**\r\n * Text to draw\r\n */\r\n text: string;\r\n\r\n /**\r\n * Optionally override the font color, currently unsupported by SpriteFont\r\n */\r\n color?: Color;\r\n\r\n /**\r\n * Optionally specify a font, if none specified a default font is used (System sans-serif 10 pixel)\r\n */\r\n font?: Font | SpriteFont;\r\n\r\n /**\r\n * Optionally specify a maximum width in pixels for our text, and wrap to the next line if needed.\r\n */\r\n maxWidth?: number;\r\n}\r\n\r\n/**\r\n * Represent Text graphics in excalibur\r\n *\r\n * Useful for in game labels, ui, or overlays\r\n */\r\nexport class Text extends Graphic {\r\n public color?: Color;\r\n public maxWidth?: number;\r\n constructor(options: TextOptions & GraphicOptions) {\r\n super(options);\r\n // This order is important font, color, then text\r\n this.font = options.font ?? new Font();\r\n this.color = options.color ?? this.color;\r\n this.text = options.text;\r\n this.maxWidth = options.maxWidth;\r\n }\r\n\r\n public clone(): Text {\r\n return new Text({\r\n text: this.text.slice(),\r\n color: this.color?.clone() ?? Color.Black,\r\n font: this.font.clone(),\r\n maxWidth: this.maxWidth\r\n });\r\n }\r\n\r\n private _text: string = '';\r\n public get text() {\r\n return this._text;\r\n }\r\n\r\n public set text(value: string) {\r\n this._text = value;\r\n this._calculateDimension();\r\n }\r\n\r\n private _font: Font | SpriteFont;\r\n public get font(): Font | SpriteFont {\r\n return this._font;\r\n }\r\n public set font(font: Font | SpriteFont) {\r\n this._font = font;\r\n }\r\n\r\n private _textWidth: number = 0;\r\n\r\n public get width() {\r\n if (this._textWidth === 0) {\r\n this._calculateDimension();\r\n }\r\n return this._textWidth * this.scale.x;\r\n }\r\n\r\n private _textHeight: number = 0;\r\n public get height() {\r\n if (this._textHeight === 0) {\r\n this._calculateDimension();\r\n }\r\n return this._textHeight * this.scale.y;\r\n }\r\n\r\n private _calculateDimension() {\r\n const { width, height } = this.font.measureText(this._text, this.maxWidth);\r\n this._textWidth = width;\r\n this._textHeight = height;\r\n }\r\n\r\n public get localBounds(): BoundingBox {\r\n return this.font.measureText(this._text, this.maxWidth).scale(this.scale);\r\n }\r\n\r\n protected override _rotate(_ex: ExcaliburGraphicsContext) {\r\n // None this is delegated to font\r\n // This override erases the default behavior\r\n }\r\n\r\n protected override _flip(_ex: ExcaliburGraphicsContext) {\r\n // None this is delegated to font\r\n // This override erases the default behavior\r\n }\r\n\r\n protected override _preDraw(ex: ExcaliburGraphicsContext, x: number, y: number): void {\r\n if (this.isStale() || this.font.isStale()) {\r\n this.font.flipHorizontal = this.flipHorizontal;\r\n this.font.flipVertical = this.flipVertical;\r\n this.font.rotation = this.rotation;\r\n this.font.origin = this.origin;\r\n this.font.opacity = this.opacity;\r\n }\r\n this.font.tint = this.tint;\r\n super._preDraw(ex, x, y);\r\n }\r\n\r\n protected override _drawImage(ex: ExcaliburGraphicsContext, x: number, y: number) {\r\n let color = Color.Black;\r\n if (this.font instanceof Font) {\r\n color = this.color ?? this.font.color;\r\n }\r\n\r\n const { width, height } = this.font.measureText(this._text, this.maxWidth);\r\n this._textWidth = width;\r\n this._textHeight = height;\r\n\r\n this.font.render(ex, this._text, color, x, y, this.maxWidth);\r\n\r\n if (this.font.showDebug) {\r\n ex.debug.drawRect(x - width, y - height, width * 2, height * 2);\r\n if (this.maxWidth != null) {\r\n ex.debug.drawRect(x, y, this.maxWidth, this.height, {\r\n color: Color.Yellow\r\n });\r\n }\r\n }\r\n }\r\n}\r\n","import {\r\n KillEvent,\r\n PreUpdateEvent,\r\n PostUpdateEvent,\r\n PostCollisionEvent,\r\n PreCollisionEvent,\r\n CollisionStartEvent,\r\n CollisionEndEvent,\r\n PostKillEvent,\r\n PreKillEvent,\r\n EnterViewPortEvent,\r\n ExitViewPortEvent,\r\n PreDrawEvent,\r\n PostDrawEvent,\r\n PreDebugDrawEvent,\r\n PostDebugDrawEvent\r\n} from './Events';\r\nimport { Engine } from './Engine';\r\nimport { Color } from './Color';\r\nimport { CanInitialize, CanUpdate, CanBeKilled } from './Interfaces/LifecycleEvents';\r\nimport { Scene } from './Scene';\r\nimport { Logger } from './Util/Log';\r\nimport { Vector, vec } from './Math/vector';\r\nimport { BodyComponent } from './Collision/BodyComponent';\r\nimport { Eventable } from './Interfaces/Evented';\r\nimport { PointerEvents } from './Interfaces/PointerEventHandlers';\r\nimport { CollisionType } from './Collision/CollisionType';\r\n\r\nimport { Entity, EntityEvents } from './EntityComponentSystem/Entity';\r\nimport { TransformComponent } from './EntityComponentSystem/Components/TransformComponent';\r\nimport { MotionComponent } from './EntityComponentSystem/Components/MotionComponent';\r\nimport { GraphicsComponent } from './Graphics/GraphicsComponent';\r\nimport { Rectangle } from './Graphics/Rectangle';\r\nimport { ColliderComponent } from './Collision/ColliderComponent';\r\nimport { Shape } from './Collision/Colliders/Shape';\r\nimport { watch } from './Util/Watch';\r\nimport { Collider, CollisionGroup } from './Collision/Index';\r\nimport { Circle } from './Graphics/Circle';\r\nimport { PointerEvent } from './Input/PointerEvent';\r\nimport { WheelEvent } from './Input/WheelEvent';\r\nimport { PointerComponent } from './Input/PointerComponent';\r\nimport { ActionsComponent } from './Actions/ActionsComponent';\r\nimport { Raster } from './Graphics/Raster';\r\nimport { Text } from './Graphics/Text';\r\nimport { CoordPlane } from './Math/coord-plane';\r\nimport { EventEmitter, EventKey, Handler, Subscription } from './EventEmitter';\r\n\r\n/**\r\n * Type guard for checking if something is an Actor\r\n * @param x\r\n */\r\nexport function isActor(x: any): x is Actor {\r\n return x instanceof Actor;\r\n}\r\n\r\n/**\r\n * Actor contructor options\r\n */\r\nexport interface ActorArgs {\r\n /**\r\n * Optionally set the name of the actor, default is 'anonymous'\r\n */\r\n name?: string;\r\n /**\r\n * Optionally set the x position of the actor, default is 0\r\n */\r\n x?: number;\r\n /**\r\n * Optionally set the y position of the actor, default is 0\r\n */\r\n y?: number;\r\n /**\r\n * Optionally set the (x, y) position of the actor as a vector, default is (0, 0)\r\n */\r\n pos?: Vector;\r\n /**\r\n * Optionally set the coordinate plane of the actor, default is [[CoordPlane.World]] meaning actor is subject to camera positioning\r\n */\r\n coordPlane?: CoordPlane;\r\n /**\r\n * Optionally set the width of a box collider for the actor\r\n */\r\n width?: number;\r\n /**\r\n * Optionally set the height of a box collider for the actor\r\n */\r\n height?: number;\r\n /**\r\n * Optionally set the radius of the circle collider for the actor\r\n */\r\n radius?: number;\r\n /**\r\n * Optionally set the velocity of the actor in pixels/sec\r\n */\r\n vel?: Vector;\r\n /**\r\n * Optionally set the acceleration of the actor in pixels/sec^2\r\n */\r\n acc?: Vector;\r\n /**\r\n * Optionally se the rotation in radians (180 degrees = Math.PI radians)\r\n */\r\n rotation?: number;\r\n /**\r\n * Optionally set the angular velocity of the actor in radians/sec (180 degrees = Math.PI radians)\r\n */\r\n angularVelocity?: number;\r\n /**\r\n * Optionally set the scale of the actor's transform\r\n */\r\n scale?: Vector;\r\n /**\r\n * Optionally set the z index of the actor, default is 0\r\n */\r\n z?: number;\r\n /**\r\n * Optionally set the color of an actor, only used if no graphics are present\r\n * If a width/height or a radius was set a default graphic will be added\r\n */\r\n color?: Color;\r\n /**\r\n * Optionally set the visibility of the actor\r\n */\r\n visible?: boolean;\r\n /**\r\n * Optionally set the anchor for graphics in the actor\r\n */\r\n anchor?: Vector;\r\n /**\r\n * Optionally set the collision type\r\n */\r\n collisionType?: CollisionType;\r\n /**\r\n * Optionally supply a collider for an actor, if supplied ignores any supplied width/height\r\n */\r\n collider?: Collider;\r\n /**\r\n * Optionally suppy a [[CollisionGroup]]\r\n */\r\n collisionGroup?: CollisionGroup;\r\n}\r\n\r\nexport type ActorEvents = EntityEvents & {\r\n collisionstart: CollisionStartEvent;\r\n collisionend: CollisionEndEvent;\r\n precollision: PreCollisionEvent;\r\n postcollision: PostCollisionEvent;\r\n kill: KillEvent;\r\n prekill: PreKillEvent;\r\n postkill: PostKillEvent;\r\n predraw: PreDrawEvent;\r\n postdraw: PostDrawEvent;\r\n predebugdraw: PreDebugDrawEvent;\r\n postdebugdraw: PostDebugDrawEvent;\r\n pointerup: PointerEvent;\r\n pointerdown: PointerEvent;\r\n pointerenter: PointerEvent;\r\n pointerleave: PointerEvent;\r\n pointermove: PointerEvent;\r\n pointercancel: PointerEvent;\r\n pointerwheel: WheelEvent;\r\n pointerdragstart: PointerEvent;\r\n pointerdragend: PointerEvent;\r\n pointerdragenter: PointerEvent;\r\n pointerdragleave: PointerEvent;\r\n pointerdragmove: PointerEvent;\r\n enterviewport: EnterViewPortEvent;\r\n exitviewport: ExitViewPortEvent;\r\n}\r\n\r\nexport const ActorEvents = {\r\n CollisionStart: 'collisionstart',\r\n CollisionEnd: 'collisionend',\r\n PreCollision: 'precollision',\r\n PostCollision: 'postcollision',\r\n Kill: 'kill',\r\n PreKill: 'prekill',\r\n PostKill: 'postkill',\r\n PreDraw: 'predraw',\r\n PostDraw: 'postdraw',\r\n PreDebugDraw: 'predebugdraw',\r\n PostDebugDraw: 'postdebugdraw',\r\n PointerUp: 'pointerup',\r\n PointerDown: 'pointerdown',\r\n PointerEnter: 'pointerenter',\r\n PointerLeave: 'pointerleave',\r\n PointerMove: 'pointermove',\r\n PointerCancel: 'pointercancel',\r\n Wheel: 'pointerwheel',\r\n PointerDrag: 'pointerdragstart',\r\n PointerDragEnd: 'pointerdragend',\r\n PointerDragEnter: 'pointerdragenter',\r\n PointerDragLeave: 'pointerdragleave',\r\n PointerDragMove: 'pointerdragmove',\r\n EnterViewPort: 'enterviewport',\r\n ExitViewPort: 'exitviewport'\r\n};\r\n\r\n/**\r\n * The most important primitive in Excalibur is an `Actor`. Anything that\r\n * can move on the screen, collide with another `Actor`, respond to events,\r\n * or interact with the current scene, must be an actor. An `Actor` **must**\r\n * be part of a [[Scene]] for it to be drawn to the screen.\r\n */\r\nexport class Actor extends Entity implements Eventable, PointerEvents, CanInitialize, CanUpdate, CanBeKilled {\r\n public events = new EventEmitter();\r\n // #region Properties\r\n\r\n /**\r\n * Set defaults for all Actors\r\n */\r\n public static defaults = {\r\n anchor: Vector.Half\r\n };\r\n\r\n /**\r\n * The physics body the is associated with this actor. The body is the container for all physical properties, like position, velocity,\r\n * acceleration, mass, inertia, etc.\r\n */\r\n public get body(): BodyComponent {\r\n return this.get(BodyComponent);\r\n }\r\n\r\n /**\r\n * Access the Actor's built in [[TransformComponent]]\r\n */\r\n public get transform(): TransformComponent {\r\n return this.get(TransformComponent);\r\n }\r\n\r\n /**\r\n * Access the Actor's built in [[MotionComponent]]\r\n */\r\n public get motion(): MotionComponent {\r\n return this.get(MotionComponent);\r\n }\r\n\r\n /**\r\n * Access to the Actor's built in [[GraphicsComponent]]\r\n */\r\n public get graphics(): GraphicsComponent {\r\n return this.get(GraphicsComponent);\r\n }\r\n\r\n /**\r\n * Access to the Actor's built in [[ColliderComponent]]\r\n */\r\n public get collider(): ColliderComponent {\r\n return this.get(ColliderComponent);\r\n }\r\n\r\n /**\r\n * Access to the Actor's built in [[PointerComponent]] config\r\n */\r\n public get pointer(): PointerComponent {\r\n return this.get(PointerComponent);\r\n }\r\n\r\n /**\r\n * Useful for quickly scripting actor behavior, like moving to a place, patrolling back and forth, blinking, etc.\r\n *\r\n * Access to the Actor's built in [[ActionsComponent]] which forwards to the\r\n * [[ActionContext|Action context]] of the actor.\r\n */\r\n public get actions(): ActionsComponent {\r\n return this.get(ActionsComponent);\r\n }\r\n\r\n /**\r\n * Gets the position vector of the actor in pixels\r\n */\r\n public get pos(): Vector {\r\n return this.transform.pos;\r\n }\r\n\r\n /**\r\n * Sets the position vector of the actor in pixels\r\n */\r\n public set pos(thePos: Vector) {\r\n this.transform.pos = thePos.clone();\r\n }\r\n\r\n /**\r\n * Gets the position vector of the actor from the last frame\r\n */\r\n public get oldPos(): Vector {\r\n return this.body.oldPos;\r\n }\r\n\r\n /**\r\n * Sets the position vector of the actor in the last frame\r\n */\r\n public set oldPos(thePos: Vector) {\r\n this.body.oldPos.setTo(thePos.x, thePos.y);\r\n }\r\n\r\n /**\r\n * Gets the velocity vector of the actor in pixels/sec\r\n */\r\n public get vel(): Vector {\r\n return this.motion.vel;\r\n }\r\n\r\n /**\r\n * Sets the velocity vector of the actor in pixels/sec\r\n */\r\n public set vel(theVel: Vector) {\r\n this.motion.vel = theVel.clone();\r\n }\r\n\r\n /**\r\n * Gets the velocity vector of the actor from the last frame\r\n */\r\n public get oldVel(): Vector {\r\n return this.body.oldVel;\r\n }\r\n\r\n /**\r\n * Sets the velocity vector of the actor from the last frame\r\n */\r\n public set oldVel(theVel: Vector) {\r\n this.body.oldVel.setTo(theVel.x, theVel.y);\r\n }\r\n\r\n /**\r\n * Gets the acceleration vector of the actor in pixels/second/second. An acceleration pointing down such as (0, 100) may be\r\n * useful to simulate a gravitational effect.\r\n */\r\n public get acc(): Vector {\r\n return this.motion.acc;\r\n }\r\n\r\n /**\r\n * Sets the acceleration vector of teh actor in pixels/second/second\r\n */\r\n public set acc(theAcc: Vector) {\r\n this.motion.acc = theAcc.clone();\r\n }\r\n\r\n /**\r\n * Sets the acceleration of the actor from the last frame. This does not include the global acc [[Physics.acc]].\r\n */\r\n public set oldAcc(theAcc: Vector) {\r\n this.body.oldAcc.setTo(theAcc.x, theAcc.y);\r\n }\r\n\r\n /**\r\n * Gets the acceleration of the actor from the last frame. This does not include the global acc [[Physics.acc]].\r\n */\r\n public get oldAcc(): Vector {\r\n return this.body.oldAcc;\r\n }\r\n\r\n /**\r\n * Gets the rotation of the actor in radians. 1 radian = 180/PI Degrees.\r\n */\r\n public get rotation(): number {\r\n return this.transform.rotation;\r\n }\r\n\r\n /**\r\n * Sets the rotation of the actor in radians. 1 radian = 180/PI Degrees.\r\n */\r\n public set rotation(theAngle: number) {\r\n this.transform.rotation = theAngle;\r\n }\r\n\r\n /**\r\n * Gets the rotational velocity of the actor in radians/second\r\n */\r\n public get angularVelocity(): number {\r\n return this.motion.angularVelocity;\r\n }\r\n\r\n /**\r\n * Sets the rotational velocity of the actor in radians/sec\r\n */\r\n public set angularVelocity(angularVelocity: number) {\r\n this.motion.angularVelocity = angularVelocity;\r\n }\r\n\r\n public get scale(): Vector {\r\n return this.get(TransformComponent).scale;\r\n }\r\n\r\n public set scale(scale: Vector) {\r\n this.get(TransformComponent).scale = scale;\r\n }\r\n\r\n /**\r\n * The anchor to apply all actor related transformations like rotation,\r\n * translation, and scaling. By default the anchor is in the center of\r\n * the actor. By default it is set to the center of the actor (.5, .5)\r\n *\r\n * An anchor of (.5, .5) will ensure that drawings are centered.\r\n *\r\n * Use `anchor.setTo` to set the anchor to a different point using\r\n * values between 0 and 1. For example, anchoring to the top-left would be\r\n * `Actor.anchor.setTo(0, 0)` and top-right would be `Actor.anchor.setTo(0, 1)`.\r\n */\r\n private _anchor: Vector = watch(Vector.Half, (v) => this._handleAnchorChange(v));\r\n public get anchor(): Vector {\r\n return this._anchor;\r\n }\r\n\r\n public set anchor(vec: Vector) {\r\n this._anchor = watch(vec, (v) => this._handleAnchorChange(v));\r\n this._handleAnchorChange(vec);\r\n }\r\n\r\n private _handleAnchorChange(v: Vector) {\r\n if (this.graphics) {\r\n this.graphics.anchor = v;\r\n }\r\n }\r\n\r\n /**\r\n * Indicates whether the actor is physically in the viewport\r\n */\r\n public get isOffScreen(): boolean {\r\n return this.hasTag('ex.offscreen');\r\n }\r\n\r\n /**\r\n * Convenience reference to the global logger\r\n */\r\n public logger: Logger = Logger.getInstance();\r\n\r\n /**\r\n * Draggable helper\r\n */\r\n private _draggable: boolean = false;\r\n private _dragging: boolean = false;\r\n\r\n private _pointerDragStartHandler = () => {\r\n this._dragging = true;\r\n };\r\n\r\n private _pointerDragEndHandler = () => {\r\n this._dragging = false;\r\n };\r\n\r\n private _pointerDragMoveHandler = (pe: PointerEvent) => {\r\n if (this._dragging) {\r\n this.pos = pe.worldPos;\r\n }\r\n };\r\n\r\n private _pointerDragLeaveHandler = (pe: PointerEvent) => {\r\n if (this._dragging) {\r\n this.pos = pe.worldPos;\r\n }\r\n };\r\n\r\n public get draggable(): boolean {\r\n return this._draggable;\r\n }\r\n\r\n public set draggable(isDraggable: boolean) {\r\n if (isDraggable) {\r\n if (isDraggable && !this._draggable) {\r\n this.events.on('pointerdragstart', this._pointerDragStartHandler);\r\n this.events.on('pointerdragend', this._pointerDragEndHandler);\r\n this.events.on('pointerdragmove', this._pointerDragMoveHandler);\r\n this.events.on('pointerdragleave', this._pointerDragLeaveHandler);\r\n } else if (!isDraggable && this._draggable) {\r\n this.events.off('pointerdragstart', this._pointerDragStartHandler);\r\n this.events.off('pointerdragend', this._pointerDragEndHandler);\r\n this.events.off('pointerdragmove', this._pointerDragMoveHandler);\r\n this.events.off('pointerdragleave', this._pointerDragLeaveHandler);\r\n }\r\n\r\n this._draggable = isDraggable;\r\n }\r\n }\r\n\r\n /**\r\n * Sets the color of the actor's current graphic\r\n */\r\n public get color(): Color {\r\n return this._color;\r\n }\r\n public set color(v: Color) {\r\n this._color = v.clone();\r\n const defaultLayer = this.graphics.layers.default;\r\n const currentGraphic = defaultLayer.graphics[0]?.graphic;\r\n if (currentGraphic instanceof Raster || currentGraphic instanceof Text) {\r\n currentGraphic.color = this._color;\r\n }\r\n }\r\n private _color: Color;\r\n\r\n // #endregion\r\n\r\n /**\r\n *\r\n * @param config\r\n */\r\n constructor(config?: ActorArgs) {\r\n super();\r\n\r\n const {\r\n name,\r\n x,\r\n y,\r\n pos,\r\n coordPlane,\r\n scale,\r\n width,\r\n height,\r\n radius,\r\n collider,\r\n vel,\r\n acc,\r\n rotation,\r\n angularVelocity,\r\n z,\r\n color,\r\n visible,\r\n anchor,\r\n collisionType,\r\n collisionGroup\r\n } = {\r\n ...config\r\n };\r\n\r\n this._setName(name);\r\n this.anchor = anchor ?? Actor.defaults.anchor.clone();\r\n const tx = new TransformComponent();\r\n this.addComponent(tx);\r\n this.pos = pos ?? vec(x ?? 0, y ?? 0);\r\n this.rotation = rotation ?? 0;\r\n this.scale = scale ?? vec(1, 1);\r\n this.z = z ?? 0;\r\n tx.coordPlane = coordPlane ?? CoordPlane.World;\r\n\r\n this.addComponent(new PointerComponent);\r\n\r\n this.addComponent(new GraphicsComponent({\r\n anchor: this.anchor\r\n }));\r\n this.addComponent(new MotionComponent());\r\n this.vel = vel ?? Vector.Zero;\r\n this.acc = acc ?? Vector.Zero;\r\n this.angularVelocity = angularVelocity ?? 0;\r\n\r\n this.addComponent(new ActionsComponent());\r\n\r\n this.addComponent(new BodyComponent());\r\n this.body.collisionType = collisionType ?? CollisionType.Passive;\r\n if (collisionGroup) {\r\n this.body.group = collisionGroup;\r\n }\r\n\r\n if (collider) {\r\n this.addComponent(new ColliderComponent(collider));\r\n } else if (radius) {\r\n this.addComponent(new ColliderComponent(Shape.Circle(radius)));\r\n } else {\r\n if (width > 0 && height > 0) {\r\n this.addComponent(new ColliderComponent(Shape.Box(width, height, this.anchor)));\r\n } else {\r\n this.addComponent(new ColliderComponent()); // no collider\r\n }\r\n }\r\n\r\n this.graphics.visible = visible ?? true;\r\n\r\n if (color) {\r\n this.color = color;\r\n if (width && height) {\r\n this.graphics.add(\r\n new Rectangle({\r\n color: color,\r\n width,\r\n height\r\n })\r\n );\r\n } else if (radius) {\r\n this.graphics.add(\r\n new Circle({\r\n color: color,\r\n radius\r\n })\r\n );\r\n }\r\n }\r\n }\r\n\r\n public clone(): Actor {\r\n const clone = new Actor({\r\n color: this.color.clone(),\r\n anchor: this.anchor.clone()\r\n });\r\n clone.clearComponents();\r\n clone.processComponentRemoval();\r\n\r\n // Clone the current actors components\r\n const components = this.getComponents();\r\n for (const c of components) {\r\n clone.addComponent(c.clone(), true);\r\n }\r\n return clone;\r\n }\r\n\r\n /**\r\n * `onInitialize` is called before the first update of the actor. This method is meant to be\r\n * overridden. This is where initialization of child actors should take place.\r\n *\r\n * Synonymous with the event handler `.on('initialize', (evt) => {...})`\r\n */\r\n public onInitialize(_engine: Engine): void {\r\n // Override me\r\n }\r\n\r\n /**\r\n * Initializes this actor and all it's child actors, meant to be called by the Scene before first update not by users of Excalibur.\r\n *\r\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\r\n *\r\n * @internal\r\n */\r\n public _initialize(engine: Engine) {\r\n super._initialize(engine);\r\n for (const child of this.children) {\r\n child._initialize(engine);\r\n }\r\n }\r\n\r\n // #region Events\r\n public emit>(eventName: TEventName, event: ActorEvents[TEventName]): void;\r\n public emit(eventName: string, event?: any): void;\r\n public emit | string>(eventName: TEventName, event?: any): void {\r\n this.events.emit(eventName, event);\r\n }\r\n\r\n public on>(eventName: TEventName, handler: Handler): Subscription;\r\n public on(eventName: string, handler: Handler): Subscription;\r\n public on | string>(eventName: TEventName, handler: Handler): Subscription {\r\n return this.events.on(eventName, handler);\r\n }\r\n\r\n public once>(eventName: TEventName, handler: Handler): Subscription;\r\n public once(eventName: string, handler: Handler): Subscription;\r\n public once | string>(eventName: TEventName, handler: Handler): Subscription {\r\n return this.events.once(eventName, handler);\r\n }\r\n\r\n public off>(eventName: TEventName, handler: Handler): void;\r\n public off(eventName: string, handler: Handler): void;\r\n public off(eventName: string): void;\r\n public off | string>(eventName: TEventName, handler?: Handler): void {\r\n this.events.off(eventName, handler);\r\n }\r\n\r\n // #endregion\r\n\r\n /**\r\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\r\n *\r\n * Internal _prekill handler for [[onPreKill]] lifecycle event\r\n * @internal\r\n */\r\n public _prekill(_scene: Scene) {\r\n this.events.emit('prekill', new PreKillEvent(this));\r\n this.onPreKill(_scene);\r\n }\r\n\r\n /**\r\n * Safe to override onPreKill lifecycle event handler. Synonymous with `.on('prekill', (evt) =>{...})`\r\n *\r\n * `onPreKill` is called directly before an actor is killed and removed from its current [[Scene]].\r\n */\r\n public onPreKill(_scene: Scene) {\r\n // Override me\r\n }\r\n\r\n /**\r\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\r\n *\r\n * Internal _prekill handler for [[onPostKill]] lifecycle event\r\n * @internal\r\n */\r\n public _postkill(_scene: Scene) {\r\n this.events.emit('postkill', new PostKillEvent(this));\r\n this.onPostKill(_scene);\r\n }\r\n\r\n /**\r\n * Safe to override onPostKill lifecycle event handler. Synonymous with `.on('postkill', (evt) => {...})`\r\n *\r\n * `onPostKill` is called directly after an actor is killed and remove from its current [[Scene]].\r\n */\r\n public onPostKill(_scene: Scene) {\r\n // Override me\r\n }\r\n\r\n /**\r\n * If the current actor is a member of the scene, this will remove\r\n * it from the scene graph. It will no longer be drawn or updated.\r\n */\r\n public kill() {\r\n if (this.scene) {\r\n this._prekill(this.scene);\r\n this.events.emit('kill', new KillEvent(this));\r\n super.kill();\r\n this._postkill(this.scene);\r\n } else {\r\n this.logger.warn(`Cannot kill actor named \"${this.name}\", it was never added to the Scene`);\r\n }\r\n }\r\n\r\n /**\r\n * If the current actor is killed, it will now not be killed.\r\n */\r\n public unkill() {\r\n this.active = true;\r\n }\r\n\r\n /**\r\n * Indicates wether the actor has been killed.\r\n */\r\n public isKilled(): boolean {\r\n return !this.active;\r\n }\r\n\r\n /**\r\n * Gets the z-index of an actor. The z-index determines the relative order an actor is drawn in.\r\n * Actors with a higher z-index are drawn on top of actors with a lower z-index\r\n */\r\n public get z(): number {\r\n return this.get(TransformComponent).z;\r\n }\r\n\r\n\r\n /**\r\n * Sets the z-index of an actor and updates it in the drawing list for the scene.\r\n * The z-index determines the relative order an actor is drawn in.\r\n * Actors with a higher z-index are drawn on top of actors with a lower z-index\r\n * @param newZ new z-index to assign\r\n */\r\n public set z(newZ: number) {\r\n this.get(TransformComponent).z = newZ;\r\n }\r\n\r\n /**\r\n * Get the center point of an actor (global position)\r\n */\r\n public get center(): Vector {\r\n const globalPos = this.getGlobalPos();\r\n return new Vector(\r\n globalPos.x + this.width / 2 - this.anchor.x * this.width,\r\n globalPos.y + this.height / 2 - this.anchor.y * this.height);\r\n }\r\n\r\n /**\r\n * Get the local center point of an actor\r\n */\r\n public get localCenter(): Vector {\r\n return new Vector(\r\n this.pos.x + this.width / 2 - this.anchor.x * this.width,\r\n this.pos.y + this.height / 2 - this.anchor.y * this.height);\r\n }\r\n\r\n public get width() {\r\n return this.collider.localBounds.width * this.getGlobalScale().x;\r\n }\r\n\r\n public get height() {\r\n return this.collider.localBounds.height * this.getGlobalScale().y;\r\n }\r\n\r\n /**\r\n * Gets this actor's rotation taking into account any parent relationships\r\n *\r\n * @returns Rotation angle in radians\r\n */\r\n public getGlobalRotation(): number {\r\n return this.get(TransformComponent).globalRotation;\r\n }\r\n\r\n /**\r\n * Gets an actor's world position taking into account parent relationships, scaling, rotation, and translation\r\n *\r\n * @returns Position in world coordinates\r\n */\r\n public getGlobalPos(): Vector {\r\n return this.get(TransformComponent).globalPos;\r\n }\r\n\r\n /**\r\n * Gets the global scale of the Actor\r\n */\r\n public getGlobalScale(): Vector {\r\n return this.get(TransformComponent).globalScale;\r\n }\r\n\r\n // #region Collision\r\n\r\n /**\r\n * Tests whether the x/y specified are contained in the actor\r\n * @param x X coordinate to test (in world coordinates)\r\n * @param y Y coordinate to test (in world coordinates)\r\n * @param recurse checks whether the x/y are contained in any child actors (if they exist).\r\n */\r\n public contains(x: number, y: number, recurse: boolean = false): boolean {\r\n const point = vec(x, y);\r\n const collider = this.get(ColliderComponent);\r\n collider.update();\r\n const geom = collider.get();\r\n if (!geom) {\r\n return false;\r\n }\r\n const containment = geom.contains(point);\r\n\r\n if (recurse) {\r\n return (\r\n containment ||\r\n this.children.some((child: Actor) => {\r\n return child.contains(x, y, true);\r\n })\r\n );\r\n }\r\n\r\n return containment;\r\n }\r\n\r\n /**\r\n * Returns true if the two actor.collider's surfaces are less than or equal to the distance specified from each other\r\n * @param actor Actor to test\r\n * @param distance Distance in pixels to test\r\n */\r\n public within(actor: Actor, distance: number): boolean {\r\n const collider = this.get(ColliderComponent);\r\n const otherCollider = actor.get(ColliderComponent);\r\n const me = collider.get();\r\n const other = otherCollider.get();\r\n if (me && other) {\r\n return me.getClosestLineBetween(other).getLength() <= distance;\r\n }\r\n return false;\r\n }\r\n\r\n // #endregion\r\n\r\n // #region Update\r\n\r\n /**\r\n * Called by the Engine, updates the state of the actor\r\n * @internal\r\n * @param engine The reference to the current game engine\r\n * @param delta The time elapsed since the last update in milliseconds\r\n */\r\n public update(engine: Engine, delta: number) {\r\n this._initialize(engine);\r\n this._preupdate(engine, delta);\r\n this._postupdate(engine, delta);\r\n }\r\n\r\n /**\r\n * Safe to override onPreUpdate lifecycle event handler. Synonymous with `.on('preupdate', (evt) =>{...})`\r\n *\r\n * `onPreUpdate` is called directly before an actor is updated.\r\n */\r\n public onPreUpdate(_engine: Engine, _delta: number): void {\r\n // Override me\r\n }\r\n\r\n /**\r\n * Safe to override onPostUpdate lifecycle event handler. Synonymous with `.on('postupdate', (evt) =>{...})`\r\n *\r\n * `onPostUpdate` is called directly after an actor is updated.\r\n */\r\n public onPostUpdate(_engine: Engine, _delta: number): void {\r\n // Override me\r\n }\r\n\r\n /**\r\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\r\n *\r\n * Internal _preupdate handler for [[onPreUpdate]] lifecycle event\r\n * @internal\r\n */\r\n public _preupdate(engine: Engine, delta: number): void {\r\n this.events.emit('preupdate', new PreUpdateEvent(engine, delta, this));\r\n this.onPreUpdate(engine, delta);\r\n }\r\n\r\n /**\r\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\r\n *\r\n * Internal _preupdate handler for [[onPostUpdate]] lifecycle event\r\n * @internal\r\n */\r\n public _postupdate(engine: Engine, delta: number): void {\r\n this.events.emit('postupdate', new PostUpdateEvent(engine, delta, this));\r\n this.onPostUpdate(engine, delta);\r\n }\r\n\r\n // endregion\r\n}\r\n","import { Vector, vec } from './Math/vector';\r\nimport { Engine } from './Engine';\r\nimport { Actor, ActorArgs } from './Actor';\r\nimport { TransformComponent } from './EntityComponentSystem/Components/TransformComponent';\r\nimport { CollisionType } from './Collision/CollisionType';\r\nimport { CoordPlane } from './Math/coord-plane';\r\n\r\n/**\r\n * Type guard to detect a screen element\r\n */\r\nexport function isScreenElement(actor: Actor) {\r\n return actor instanceof ScreenElement;\r\n}\r\n\r\n/**\r\n * Helper [[Actor]] primitive for drawing UI's, optimized for UI drawing. Does\r\n * not participate in collisions. Drawn on top of all other actors.\r\n */\r\nexport class ScreenElement extends Actor {\r\n protected _engine: Engine;\r\n\r\n constructor();\r\n constructor(config?: ActorArgs);\r\n\r\n constructor(config?: ActorArgs) {\r\n super({ ...config });\r\n this.get(TransformComponent).coordPlane = CoordPlane.Screen;\r\n this.anchor = config?.anchor ?? vec(0, 0);\r\n this.body.collisionType = config?.collisionType ?? CollisionType.PreventCollision;\r\n this.pointer.useGraphicsBounds = true;\r\n this.pointer.useColliderShape = false;\r\n if (!config?.collider &&\r\n config?.width > 0 &&\r\n config?.height > 0) {\r\n this.collider.useBoxCollider(this.width, this.height, this.anchor);\r\n }\r\n }\r\n\r\n public _initialize(engine: Engine) {\r\n this._engine = engine;\r\n super._initialize(engine);\r\n }\r\n\r\n public contains(x: number, y: number, useWorld: boolean = true) {\r\n if (useWorld) {\r\n return super.contains(x, y);\r\n }\r\n\r\n const coords = this._engine.worldToScreenCoordinates(new Vector(x, y));\r\n return super.contains(coords.x, coords.y);\r\n }\r\n}\r\n","import { Scene } from './Scene';\r\nimport { Logger } from './Util/Log';\r\nimport * as ex from './index';\r\nimport { Random } from './Math/Random';\r\n\r\n\r\nexport interface TimerOptions {\r\n repeats?: boolean;\r\n numberOfRepeats?: number;\r\n fcn?: () => void;\r\n interval: number;\r\n randomRange?: [number, number];\r\n random?: ex.Random;\r\n}\r\n\r\n/**\r\n * The Excalibur timer hooks into the internal timer and fires callbacks,\r\n * after a certain interval, optionally repeating.\r\n */\r\nexport class Timer {\r\n private _logger = Logger.getInstance();\r\n private static _MAX_ID: number = 0;\r\n public id: number = 0;\r\n\r\n private _elapsedTime: number = 0;\r\n private _totalTimeAlive: number = 0;\r\n\r\n private _running = false;\r\n\r\n private _numberOfTicks: number = 0;\r\n private _callbacks: Array<() => void>;\r\n\r\n public interval: number = 10;\r\n public repeats: boolean = false;\r\n public maxNumberOfRepeats: number = -1;\r\n public randomRange: [number, number] = [0,0];\r\n public random: ex.Random;\r\n private _baseInterval = 10;\r\n private _generateRandomInterval = () => {\r\n return this._baseInterval + this.random.integer(this.randomRange[0], this.randomRange[1]);\r\n };\r\n\r\n private _complete = false;\r\n public get complete() {\r\n return this._complete;\r\n }\r\n\r\n public scene: Scene = null;\r\n\r\n /**\r\n * @param options Options - repeats, numberOfRepeats, fcn, interval\r\n * @param repeats Indicates whether this call back should be fired only once, or repeat after every interval as completed.\r\n * @param numberOfRepeats Specifies a maximum number of times that this timer will execute.\r\n * @param fcn The callback to be fired after the interval is complete.\r\n * @param randomRange Indicates a range to select a random number to be added onto the interval\r\n */\r\n constructor(options: TimerOptions);\r\n constructor(fcn: TimerOptions | (() => void), interval?: number,\r\n repeats?: boolean, numberOfRepeats?: number, randomRange?: [number, number], random?: ex.Random) {\r\n if (typeof fcn !== 'function') {\r\n const options = fcn;\r\n fcn = options.fcn;\r\n interval = options.interval;\r\n repeats = options.repeats;\r\n numberOfRepeats = options.numberOfRepeats;\r\n randomRange = options.randomRange;\r\n random= options.random;\r\n }\r\n\r\n if (!!numberOfRepeats && numberOfRepeats >= 0) {\r\n this.maxNumberOfRepeats = numberOfRepeats;\r\n if (!repeats) {\r\n throw new Error('repeats must be set to true if numberOfRepeats is set');\r\n }\r\n }\r\n\r\n this.id = Timer._MAX_ID++;\r\n this._callbacks = [];\r\n this._baseInterval = this.interval = interval;\r\n if (!!randomRange){\r\n if (randomRange[0] > randomRange[1]) {\r\n throw new Error('min value must be lower than max value for range');\r\n }\r\n //We use the instance of ex.Random to generate the range\r\n this.random = random ?? new Random();\r\n this.randomRange = randomRange;\r\n\r\n this.interval = this._generateRandomInterval();\r\n this.on(() => {\r\n this.interval = this._generateRandomInterval();\r\n });\r\n };\r\n this.repeats = repeats || this.repeats;\r\n if (fcn) {\r\n this.on(fcn);\r\n }\r\n }\r\n\r\n /**\r\n * Adds a new callback to be fired after the interval is complete\r\n * @param fcn The callback to be added to the callback list, to be fired after the interval is complete.\r\n */\r\n public on(fcn: () => void) {\r\n this._callbacks.push(fcn);\r\n }\r\n\r\n /**\r\n * Removes a callback from the callback list to be fired after the interval is complete.\r\n * @param fcn The callback to be removed from the callback list, to be fired after the interval is complete.\r\n */\r\n public off(fcn: () => void) {\r\n const index = this._callbacks.indexOf(fcn);\r\n this._callbacks.splice(index, 1);\r\n }\r\n /**\r\n * Updates the timer after a certain number of milliseconds have elapsed. This is used internally by the engine.\r\n * @param delta Number of elapsed milliseconds since the last update.\r\n */\r\n public update(delta: number) {\r\n if (this._running) {\r\n this._totalTimeAlive += delta;\r\n this._elapsedTime += delta;\r\n\r\n if (this.maxNumberOfRepeats > -1 && this._numberOfTicks >= this.maxNumberOfRepeats) {\r\n this._complete = true;\r\n this._running = false;\r\n this._elapsedTime = 0;\r\n }\r\n\r\n if (!this.complete && this._elapsedTime >= this.interval) {\r\n this._callbacks.forEach((c) => {\r\n c.call(this);\r\n });\r\n this._numberOfTicks++;\r\n if (this.repeats) {\r\n this._elapsedTime = 0;\r\n } else {\r\n this._complete = true;\r\n this._running = false;\r\n this._elapsedTime = 0;\r\n }\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Resets the timer so that it can be reused, and optionally reconfigure the timers interval.\r\n *\r\n * Warning** you may need to call `timer.start()` again if the timer had completed\r\n * @param newInterval If specified, sets a new non-negative interval in milliseconds to refire the callback\r\n * @param newNumberOfRepeats If specified, sets a new non-negative upper limit to the number of time this timer executes\r\n */\r\n public reset(newInterval?: number, newNumberOfRepeats?: number) {\r\n if (!!newInterval && newInterval >= 0) {\r\n this._baseInterval = this.interval= newInterval;\r\n }\r\n\r\n if (!!this.maxNumberOfRepeats && this.maxNumberOfRepeats >= 0) {\r\n this.maxNumberOfRepeats = newNumberOfRepeats;\r\n if (!this.repeats) {\r\n throw new Error('repeats must be set to true if numberOfRepeats is set');\r\n }\r\n }\r\n\r\n this._complete = false;\r\n this._elapsedTime = 0;\r\n this._numberOfTicks = 0;\r\n }\r\n\r\n public get timesRepeated(): number {\r\n return this._numberOfTicks;\r\n }\r\n\r\n public getTimeRunning(): number {\r\n return this._totalTimeAlive;\r\n }\r\n\r\n /**\r\n * @returns milliseconds until the next action callback, if complete will return 0\r\n */\r\n public get timeToNextAction() {\r\n if (this.complete) {\r\n return 0;\r\n }\r\n return this.interval - this._elapsedTime;\r\n }\r\n\r\n /**\r\n * @returns milliseconds elapsed toward the next action\r\n */\r\n public get timeElapsedTowardNextAction() {\r\n return this._elapsedTime;\r\n }\r\n\r\n public get isRunning() {\r\n return this._running;\r\n }\r\n\r\n /**\r\n * Pauses the timer, time will no longer increment towards the next call\r\n */\r\n public pause(): Timer {\r\n this._running = false;\r\n return this;\r\n }\r\n\r\n /**\r\n * Resumes the timer, time will now increment towards the next call.\r\n */\r\n public resume(): Timer {\r\n this._running = true;\r\n return this;\r\n }\r\n\r\n /**\r\n * Starts the timer, if the timer was complete it will restart the timer and reset the elapsed time counter\r\n */\r\n public start(): Timer {\r\n if (!this.scene) {\r\n this._logger.warn('Cannot start a timer not part of a scene, timer wont start until added');\r\n }\r\n\r\n this._running = true;\r\n if (this.complete) {\r\n this._complete = false;\r\n this._elapsedTime = 0;\r\n this._numberOfTicks = 0;\r\n }\r\n\r\n return this;\r\n }\r\n\r\n /**\r\n * Stops the timer and resets the elapsed time counter towards the next action invocation\r\n */\r\n public stop(): Timer {\r\n this._running = false;\r\n this._elapsedTime = 0;\r\n this._numberOfTicks = 0;\r\n return this;\r\n }\r\n\r\n /**\r\n * Cancels the timer, preventing any further executions.\r\n */\r\n public cancel() {\r\n this.pause();\r\n if (this.scene) {\r\n this.scene.cancelTimer(this);\r\n }\r\n }\r\n}\r\n\r\n","import { Component } from '../EntityComponentSystem/Component';\r\nimport { vec, Vector } from '../Math/vector';\r\n\r\nexport class ParallaxComponent extends Component<'ex.parallax'> {\r\n readonly type = 'ex.parallax';\r\n\r\n parallaxFactor = vec(1.0, 1.0);\r\n\r\n constructor(parallaxFactor?: Vector) {\r\n super();\r\n this.parallaxFactor = parallaxFactor ?? this.parallaxFactor;\r\n }\r\n}","import { ExcaliburGraphicsContext } from '.';\r\nimport { Component } from '../EntityComponentSystem/Component';\r\n\r\n\r\n/**\r\n * Provide arbitrary drawing for the purposes of debugging your game\r\n *\r\n * Will only show when the Engine is set to debug mode [[Engine.showDebug]] or [[Engine.toggleDebug]]\r\n *\r\n */\r\nexport class DebugGraphicsComponent extends Component<'ex.debuggraphics'> {\r\n readonly type = 'ex.debuggraphics';\r\n constructor(public draw: (ctx: ExcaliburGraphicsContext) => void, public useTransform = true) {\r\n super();\r\n }\r\n}","import { BoundingBox } from '../Collision/BoundingBox';\r\nimport { Engine } from '../Engine';\r\nimport { Vector, vec } from '../Math/vector';\r\nimport { Logger } from '../Util/Log';\r\nimport { Entity, EntityEvents } from '../EntityComponentSystem/Entity';\r\nimport { TransformComponent } from '../EntityComponentSystem/Components/TransformComponent';\r\nimport { BodyComponent } from '../Collision/BodyComponent';\r\nimport { CollisionType } from '../Collision/CollisionType';\r\nimport { Shape } from '../Collision/Colliders/Shape';\r\nimport { ExcaliburGraphicsContext, Graphic, GraphicsComponent, hasGraphicsTick, ParallaxComponent } from '../Graphics';\r\nimport { removeItemFromArray } from '../Util/Util';\r\nimport { MotionComponent } from '../EntityComponentSystem/Components/MotionComponent';\r\nimport { ColliderComponent } from '../Collision/ColliderComponent';\r\nimport { CompositeCollider } from '../Collision/Colliders/CompositeCollider';\r\nimport { Color } from '../Color';\r\nimport { DebugGraphicsComponent } from '../Graphics/DebugGraphicsComponent';\r\nimport { Collider } from '../Collision/Colliders/Collider';\r\nimport { PostDrawEvent, PostUpdateEvent, PreDrawEvent, PreUpdateEvent } from '../Events';\r\nimport { EventEmitter, EventKey, Handler, Subscription } from '../EventEmitter';\r\n\r\nexport interface TileMapOptions {\r\n /**\r\n * Optionally name the isometric tile map\r\n */\r\n name?: string;\r\n /**\r\n * Optionally specify the position of the isometric tile map\r\n */\r\n pos?: Vector;\r\n /**\r\n * Width of an individual tile in pixels\r\n */\r\n tileWidth: number;\r\n /**\r\n * Height of an individual tile in pixels\r\n */\r\n tileHeight: number;\r\n /**\r\n * The number of tile columns, or the number of tiles wide\r\n */\r\n columns: number;\r\n /**\r\n * The number of tile rows, or the number of tiles high\r\n */\r\n rows: number;\r\n\r\n /**\r\n * Optionally render from the top of the graphic, by default tiles are rendered from the bottom\r\n */\r\n renderFromTopOfGraphic?: boolean;\r\n}\r\n\r\nexport type TileMapEvents = EntityEvents & {\r\n preupdate: PreUpdateEvent;\r\n postupdate: PostUpdateEvent;\r\n predraw: PreDrawEvent;\r\n postdraw: PostDrawEvent\r\n}\r\n\r\nexport const TileMapEvents = {\r\n PreUpdate: 'preupdate',\r\n PostUpdate: 'postupdate',\r\n PreDraw: 'predraw',\r\n PostDraw: 'postdraw'\r\n};\r\n\r\n/**\r\n * The TileMap provides a mechanism for doing flat 2D tiles rendered in a grid.\r\n *\r\n * TileMaps are useful for top down or side scrolling grid oriented games.\r\n */\r\nexport class TileMap extends Entity {\r\n public events = new EventEmitter();\r\n private _token = 0;\r\n private _engine: Engine;\r\n\r\n public logger: Logger = Logger.getInstance();\r\n public readonly tiles: Tile[] = [];\r\n private _rows: Tile[][] = [];\r\n private _cols: Tile[][] = [];\r\n\r\n public readonly tileWidth: number;\r\n public readonly tileHeight: number;\r\n public readonly rows: number;\r\n public readonly columns: number;\r\n\r\n public renderFromTopOfGraphic = false;\r\n\r\n private _collidersDirty = true;\r\n public flagCollidersDirty() {\r\n this._collidersDirty = true;\r\n }\r\n\r\n public flagTilesDirty() {\r\n for (let i = 0; i < this.tiles.length; i++) {\r\n if (this.tiles[i]) {\r\n this.tiles[i].flagDirty();\r\n }\r\n }\r\n }\r\n\r\n private _transform: TransformComponent;\r\n private _motion: MotionComponent;\r\n private _graphics: GraphicsComponent;\r\n private _collider: ColliderComponent;\r\n private _composite: CompositeCollider;\r\n\r\n public get x(): number {\r\n return this._transform.pos.x ?? 0;\r\n }\r\n\r\n public set x(val: number) {\r\n if (this._transform?.pos) {\r\n this.get(TransformComponent).pos = vec(val, this.y);\r\n }\r\n }\r\n\r\n public get y(): number {\r\n return this._transform?.pos.y ?? 0;\r\n }\r\n\r\n public set y(val: number) {\r\n if (this._transform?.pos) {\r\n this._transform.pos = vec(this.x, val);\r\n }\r\n }\r\n\r\n public get z(): number {\r\n return this._transform.z ?? 0;\r\n }\r\n\r\n public set z(val: number) {\r\n if (this._transform) {\r\n this._transform.z = val;\r\n }\r\n }\r\n\r\n public get rotation(): number {\r\n return this._transform?.rotation ?? 0;\r\n }\r\n\r\n public set rotation(val: number) {\r\n if (this._transform?.rotation) {\r\n this._transform.rotation = val;\r\n }\r\n }\r\n\r\n private _oldScale: Vector;\r\n public get scale(): Vector {\r\n return this._transform?.scale ?? Vector.One;\r\n }\r\n\r\n public set scale(val: Vector) {\r\n if (this._transform?.scale) {\r\n this._transform.scale = val;\r\n }\r\n }\r\n\r\n private _oldPos: Vector;\r\n public get pos(): Vector {\r\n return this._transform.pos;\r\n }\r\n\r\n public set pos(val: Vector) {\r\n this._transform.pos = val;\r\n }\r\n\r\n public get vel(): Vector {\r\n return this._motion.vel;\r\n }\r\n\r\n public set vel(val: Vector) {\r\n this._motion.vel = val;\r\n }\r\n\r\n public emit>(eventName: TEventName, event: TileMapEvents[TEventName]): void;\r\n public emit(eventName: string, event?: any): void;\r\n public emit | string>(eventName: TEventName, event?: any): void {\r\n this.events.emit(eventName, event);\r\n }\r\n\r\n public on>(eventName: TEventName, handler: Handler): Subscription;\r\n public on(eventName: string, handler: Handler): Subscription;\r\n public on | string>(eventName: TEventName, handler: Handler): Subscription {\r\n return this.events.on(eventName, handler);\r\n }\r\n\r\n public once>(eventName: TEventName, handler: Handler): Subscription;\r\n public once(eventName: string, handler: Handler): Subscription;\r\n public once | string>(eventName: TEventName, handler: Handler): Subscription {\r\n return this.events.once(eventName, handler);\r\n }\r\n\r\n public off>(eventName: TEventName, handler: Handler): void;\r\n public off(eventName: string, handler: Handler): void;\r\n public off(eventName: string): void;\r\n public off | string>(eventName: TEventName, handler?: Handler): void {\r\n this.events.off(eventName, handler);\r\n }\r\n\r\n\r\n /**\r\n * @param options\r\n */\r\n constructor(options: TileMapOptions) {\r\n super(null, options.name);\r\n this.addComponent(new TransformComponent());\r\n this.addComponent(new MotionComponent());\r\n this.addComponent(\r\n new BodyComponent({\r\n type: CollisionType.Fixed\r\n })\r\n );\r\n this.addComponent(\r\n new GraphicsComponent({\r\n onPostDraw: (ctx, delta) => this.draw(ctx, delta)\r\n })\r\n );\r\n this.addComponent(new DebugGraphicsComponent((ctx) => this.debug(ctx)));\r\n this.addComponent(new ColliderComponent());\r\n this._graphics = this.get(GraphicsComponent);\r\n this._transform = this.get(TransformComponent);\r\n this._motion = this.get(MotionComponent);\r\n this._collider = this.get(ColliderComponent);\r\n this._composite = this._collider.useCompositeCollider([]);\r\n\r\n this._transform.pos = options.pos ?? Vector.Zero;\r\n this._oldPos = this._transform.pos.clone();\r\n this._oldScale = this._transform.scale.clone();\r\n this.renderFromTopOfGraphic = options.renderFromTopOfGraphic ?? this.renderFromTopOfGraphic;\r\n this.tileWidth = options.tileWidth;\r\n this.tileHeight = options.tileHeight;\r\n this.rows = options.rows;\r\n this.columns = options.columns;\r\n this.tiles = new Array(this.rows * this.columns);\r\n this._rows = new Array(this.rows);\r\n this._cols = new Array(this.columns);\r\n let currentCol: Tile[] = [];\r\n for (let i = 0; i < this.columns; i++) {\r\n for (let j = 0; j < this.rows; j++) {\r\n const cd = new Tile({\r\n x: i,\r\n y: j,\r\n map: this\r\n });\r\n cd.map = this;\r\n this.tiles[i + j * this.columns] = cd;\r\n currentCol.push(cd);\r\n if (!this._rows[j]) {\r\n this._rows[j] = [];\r\n }\r\n this._rows[j].push(cd);\r\n }\r\n this._cols[i] = currentCol;\r\n currentCol = [];\r\n }\r\n\r\n this._graphics.localBounds = new BoundingBox({\r\n left: 0,\r\n top: 0,\r\n right: this.columns * this.tileWidth * this.scale.x,\r\n bottom: this.rows * this.tileHeight * this.scale.y\r\n });\r\n }\r\n\r\n public _initialize(engine: Engine) {\r\n super._initialize(engine);\r\n this._engine = engine;\r\n }\r\n\r\n\r\n private _originalOffsets = new WeakMap();\r\n private _getOrSetColliderOriginalOffset(collider: Collider): Vector {\r\n if (!this._originalOffsets.has(collider)) {\r\n const originalOffset = collider.offset;\r\n this._originalOffsets.set(collider, originalOffset);\r\n return originalOffset;\r\n } else {\r\n return this._originalOffsets.get(collider);\r\n }\r\n }\r\n /**\r\n * Tiles colliders based on the solid tiles in the tilemap.\r\n */\r\n private _updateColliders(): void {\r\n this._collider.$colliderRemoved.notifyAll(this._composite);\r\n this._composite.clearColliders();\r\n const colliders: BoundingBox[] = [];\r\n this._composite = this._collider.useCompositeCollider([]);\r\n let current: BoundingBox;\r\n // Bad square tesselation algo\r\n for (let i = 0; i < this.columns; i++) {\r\n // Scan column for colliders\r\n for (let j = 0; j < this.rows; j++) {\r\n // Columns start with a new collider\r\n if (j === 0) {\r\n current = null;\r\n }\r\n const tile = this.tiles[i + j * this.columns];\r\n // Current tile in column is solid build up current collider\r\n if (tile.solid) {\r\n // Use custom collider otherwise bounding box\r\n if (tile.getColliders().length > 0) {\r\n // tile with custom collider interrupting the current run\r\n for (const collider of tile.getColliders()) {\r\n const originalOffset = this._getOrSetColliderOriginalOffset(collider);\r\n collider.offset = vec(tile.x * this.tileWidth * this.scale.x, tile.y * this.tileHeight * this.scale.y).add(originalOffset);\r\n collider.owner = this;\r\n this._composite.addCollider(collider);\r\n }\r\n //we push any current collider before nulling the current run\r\n if (current) {\r\n colliders.push(current);\r\n }\r\n current = null;\r\n } else {\r\n if (!current) {\r\n // no current run, start one\r\n current = tile.bounds;\r\n } else {\r\n // combine with current run\r\n current = current.combine(tile.bounds);\r\n }\r\n }\r\n } else {\r\n // Not solid skip and cut off the current collider\r\n if (current) {\r\n colliders.push(current);\r\n }\r\n current = null;\r\n }\r\n }\r\n // After a column is complete check to see if it can be merged into the last one\r\n if (current) {\r\n // if previous is the same combine it\r\n const prev = colliders[colliders.length - 1];\r\n if (prev && prev.top === current.top && prev.bottom === current.bottom) {\r\n colliders[colliders.length - 1] = prev.combine(current);\r\n } else {\r\n // else new collider\r\n colliders.push(current);\r\n }\r\n }\r\n }\r\n\r\n for (const c of colliders) {\r\n const collider = Shape.Box(c.width, c.height, Vector.Zero, vec(c.left - this.pos.x, c.top - this.pos.y));\r\n collider.owner = this;\r\n this._composite.addCollider(collider);\r\n }\r\n this._collider.update();\r\n // Notify that colliders have been updated\r\n this._collider.$colliderAdded.notifyAll(this._composite);\r\n }\r\n\r\n /**\r\n * Returns the [[Tile]] by index (row major order)\r\n */\r\n public getTileByIndex(index: number): Tile {\r\n return this.tiles[index];\r\n }\r\n /**\r\n * Returns the [[Tile]] by its x and y integer coordinates\r\n */\r\n public getTile(x: number, y: number): Tile {\r\n if (x < 0 || y < 0 || x >= this.columns || y >= this.rows) {\r\n return null;\r\n }\r\n return this.tiles[x + y * this.columns];\r\n }\r\n /**\r\n * Returns the [[Tile]] by testing a point in world coordinates,\r\n * returns `null` if no Tile was found.\r\n */\r\n public getTileByPoint(point: Vector): Tile {\r\n const x = Math.floor((point.x - this.pos.x) / (this.tileWidth * this.scale.x));\r\n const y = Math.floor((point.y - this.pos.y) / (this.tileHeight * this.scale.y));\r\n const tile = this.getTile(x, y);\r\n if (x >= 0 && y >= 0 && x < this.columns && y < this.rows && tile) {\r\n return tile;\r\n }\r\n return null;\r\n }\r\n\r\n public getRows(): readonly Tile[][] {\r\n return this._rows;\r\n }\r\n\r\n public getColumns(): readonly Tile[][] {\r\n return this._cols;\r\n }\r\n\r\n public update(engine: Engine, delta: number) {\r\n this.onPreUpdate(engine, delta);\r\n this.emit('preupdate', new PreUpdateEvent(engine, delta, this));\r\n if (!this._oldPos.equals(this.pos) ||\r\n !this._oldScale.equals(this.scale)) {\r\n this.flagCollidersDirty();\r\n this.flagTilesDirty();\r\n }\r\n if (this._collidersDirty) {\r\n this._collidersDirty = false;\r\n this._updateColliders();\r\n }\r\n\r\n this._token++;\r\n\r\n this.pos.clone(this._oldPos);\r\n this.scale.clone(this._oldScale);\r\n this._transform.pos = this.pos;\r\n this.onPostUpdate(engine, delta);\r\n this.emit('postupdate', new PostUpdateEvent(engine, delta, this));\r\n }\r\n\r\n /**\r\n * Draws the tile map to the screen. Called by the [[Scene]].\r\n * @param ctx ExcaliburGraphicsContext\r\n * @param delta The number of milliseconds since the last draw\r\n */\r\n public draw(ctx: ExcaliburGraphicsContext, delta: number): void {\r\n this.emit('predraw', new PreDrawEvent(ctx as any, delta, this)); // TODO fix event\r\n let worldBounds = this._engine.screen.getWorldBounds();\r\n // TODO can we trim this down by using world bounds?\r\n let x = 0;\r\n const xEnd = this.columns;\r\n let y = 0;\r\n const yEnd = this.rows;\r\n\r\n let graphics: readonly Graphic[], graphicsIndex: number, graphicsLen: number;\r\n\r\n const maybeParallax = this.get(ParallaxComponent);\r\n if (maybeParallax) {\r\n let pos = this.pos;\r\n const oneMinusFactor = Vector.One.sub(maybeParallax.parallaxFactor);\r\n const parallaxOffset = this._engine.currentScene.camera.pos.scale(oneMinusFactor);\r\n pos = pos.sub(parallaxOffset);\r\n // adjust world bounds by parallax factor\r\n worldBounds = worldBounds.translate(pos);\r\n }\r\n\r\n let tile: Tile;\r\n for (x; x < xEnd; x++) {\r\n for (y; y < yEnd; y++) {\r\n tile = this.getTile(x, y);\r\n // fixme: This has a large perf impact, we iterate over every tile in the tilemap\r\n // this probably requires a spatial data structure to do more efficiently\r\n if (!worldBounds.overlaps(tile.bounds)) {\r\n continue;\r\n }\r\n // get non-negative tile sprites\r\n graphics = this.getTile(x, y).getGraphics();\r\n\r\n for (graphicsIndex = 0, graphicsLen = graphics.length; graphicsIndex < graphicsLen; graphicsIndex++) {\r\n // draw sprite, warning if sprite doesn't exist\r\n const graphic = graphics[graphicsIndex];\r\n if (graphic) {\r\n if (hasGraphicsTick(graphic)) {\r\n graphic?.tick(delta, this._token);\r\n }\r\n const offsetY = this.renderFromTopOfGraphic ? 0 : (graphic.height - this.tileHeight);\r\n graphic.draw(ctx, x * this.tileWidth, y * this.tileHeight - offsetY);\r\n }\r\n }\r\n }\r\n y = 0;\r\n }\r\n\r\n this.emit('postdraw', new PostDrawEvent(ctx as any, delta, this));\r\n }\r\n\r\n public debug(gfx: ExcaliburGraphicsContext) {\r\n const width = this.tileWidth * this.columns;\r\n const height = this.tileHeight * this.rows;\r\n const pos = Vector.Zero;\r\n for (let r = 0; r < this.rows + 1; r++) {\r\n const yOffset = vec(0, r * this.tileHeight);\r\n gfx.drawLine(pos.add(yOffset), pos.add(vec(width, yOffset.y)), Color.Red, 2);\r\n }\r\n\r\n for (let c = 0; c < this.columns + 1; c++) {\r\n const xOffset = vec(c * this.tileWidth, 0);\r\n gfx.drawLine(pos.add(xOffset), pos.add(vec(xOffset.x, height)), Color.Red, 2);\r\n }\r\n\r\n const colliders = this._composite.getColliders();\r\n for (const collider of colliders) {\r\n const grayish = Color.Gray;\r\n grayish.a = 0.5;\r\n const bounds = collider.localBounds;\r\n const pos = collider.worldPos.sub(this.pos);\r\n gfx.drawRectangle(pos, bounds.width, bounds.height, grayish);\r\n }\r\n }\r\n}\r\n\r\nexport interface TileOptions {\r\n /**\r\n * Integer tile x coordinate\r\n */\r\n x: number;\r\n /**\r\n * Integer tile y coordinate\r\n */\r\n y: number;\r\n map: TileMap;\r\n solid?: boolean;\r\n graphics?: Graphic[];\r\n}\r\n\r\n/**\r\n * TileMap Tile\r\n *\r\n * A light-weight object that occupies a space in a collision map. Generally\r\n * created by a [[TileMap]].\r\n *\r\n * Tiles can draw multiple sprites. Note that the order of drawing is the order\r\n * of the sprites in the array so the last one will be drawn on top. You can\r\n * use transparency to create layers this way.\r\n */\r\nexport class Tile extends Entity {\r\n private _bounds: BoundingBox;\r\n private _pos: Vector;\r\n private _posDirty = false;\r\n // private _transform: TransformComponent;\r\n\r\n /**\r\n * Return the world position of the top left corner of the tile\r\n */\r\n public get pos() {\r\n if (this._posDirty) {\r\n this._recalculate();\r\n this._posDirty = false;\r\n }\r\n return this._pos;\r\n }\r\n\r\n /**\r\n * Integer x coordinate of the tile\r\n */\r\n public readonly x: number;\r\n\r\n /**\r\n * Integer y coordinate of the tile\r\n */\r\n public readonly y: number;\r\n\r\n private _width: number;\r\n /**\r\n * Width of the tile in pixels\r\n */\r\n public get width(): number {\r\n return this._width;\r\n }\r\n\r\n private _height: number;\r\n /**\r\n * Height of the tile in pixels\r\n */\r\n public get height(): number {\r\n return this._height;\r\n }\r\n\r\n /**\r\n * Reference to the TileMap this tile is associated with\r\n */\r\n public map: TileMap;\r\n\r\n private _solid = false;\r\n /**\r\n * Wether this tile should be treated as solid by the tilemap\r\n */\r\n public get solid(): boolean {\r\n return this._solid;\r\n }\r\n /**\r\n * Wether this tile should be treated as solid by the tilemap\r\n */\r\n public set solid(val: boolean) {\r\n this.map?.flagCollidersDirty();\r\n this._solid = val;\r\n }\r\n\r\n private _graphics: Graphic[] = [];\r\n\r\n /**\r\n * Current list of graphics for this tile\r\n */\r\n public getGraphics(): readonly Graphic[] {\r\n return this._graphics;\r\n }\r\n\r\n /**\r\n * Add another [[Graphic]] to this TileMap tile\r\n * @param graphic\r\n */\r\n public addGraphic(graphic: Graphic) {\r\n this._graphics.push(graphic);\r\n }\r\n\r\n /**\r\n * Remove an instance of a [[Graphic]] from this tile\r\n */\r\n public removeGraphic(graphic: Graphic) {\r\n removeItemFromArray(graphic, this._graphics);\r\n }\r\n\r\n /**\r\n * Clear all graphics from this tile\r\n */\r\n public clearGraphics() {\r\n this._graphics.length = 0;\r\n }\r\n\r\n /**\r\n * Current list of colliders for this tile\r\n */\r\n private _colliders: Collider[] = [];\r\n\r\n /**\r\n * Returns the list of colliders\r\n */\r\n public getColliders(): readonly Collider[] {\r\n return this._colliders;\r\n }\r\n\r\n /**\r\n * Adds a custom collider to the [[Tile]] to use instead of it's bounds\r\n *\r\n * If no collider is set but [[Tile.solid]] is set, the tile bounds are used as a collider.\r\n *\r\n * **Note!** the [[Tile.solid]] must be set to true for it to act as a \"fixed\" collider\r\n * @param collider\r\n */\r\n public addCollider(collider: Collider) {\r\n this._colliders.push(collider);\r\n this.map.flagCollidersDirty();\r\n }\r\n\r\n /**\r\n * Removes a collider from the [[Tile]]\r\n * @param collider\r\n */\r\n public removeCollider(collider: Collider) {\r\n const index = this._colliders.indexOf(collider);\r\n if (index > -1) {\r\n this._colliders.splice(index, 1);\r\n }\r\n this.map.flagCollidersDirty();\r\n }\r\n\r\n /**\r\n * Clears all colliders from the [[Tile]]\r\n */\r\n public clearColliders() {\r\n this._colliders.length = 0;\r\n this.map.flagCollidersDirty();\r\n }\r\n\r\n /**\r\n * Arbitrary data storage per tile, useful for any game specific data\r\n */\r\n public data = new Map();\r\n\r\n constructor(options: TileOptions) {\r\n super();\r\n this.x = options.x;\r\n this.y = options.y;\r\n this.map = options.map;\r\n this._width = options.map.tileWidth * this.map.scale.x;\r\n this._height = options.map.tileHeight * this.map.scale.y;\r\n this.solid = options.solid ?? this.solid;\r\n this._graphics = options.graphics ?? [];\r\n this._recalculate();\r\n }\r\n\r\n public flagDirty() {\r\n return this._posDirty = true;\r\n }\r\n\r\n private _recalculate() {\r\n this._width = this.map.tileWidth * this.map.scale.x;\r\n this._height = this.map.tileHeight * this.map.scale.y;\r\n this._pos = this.map.pos.add(\r\n vec(\r\n this.x * this._width,\r\n this.y * this._height));\r\n this._bounds = new BoundingBox(this._pos.x, this._pos.y, this._pos.x + this._width, this._pos.y + this._height);\r\n this._posDirty = false;\r\n }\r\n\r\n /**\r\n * Tile bounds in world space\r\n */\r\n public get bounds() {\r\n if (this._posDirty) {\r\n this._recalculate();\r\n }\r\n return this._bounds;\r\n }\r\n\r\n /**\r\n * Tile position in world space\r\n */\r\n public get center(): Vector {\r\n if (this._posDirty) {\r\n this._recalculate();\r\n }\r\n return new Vector(this._pos.x + this._width / 2, this._pos.y + this._height / 2);\r\n }\r\n}","import { Engine } from './Engine';\r\nimport { Screen } from './Screen';\r\nimport { EasingFunction, EasingFunctions } from './Util/EasingFunctions';\r\nimport { Vector, vec } from './Math/vector';\r\nimport { Actor } from './Actor';\r\nimport { removeItemFromArray } from './Util/Util';\r\nimport { CanUpdate, CanInitialize } from './Interfaces/LifecycleEvents';\r\nimport { PreUpdateEvent, PostUpdateEvent, InitializeEvent } from './Events';\r\nimport { BoundingBox } from './Collision/BoundingBox';\r\nimport { Logger } from './Util/Log';\r\nimport { ExcaliburGraphicsContext } from './Graphics/Context/ExcaliburGraphicsContext';\r\nimport { watchAny } from './Util/Watch';\r\nimport { AffineMatrix } from './Math/affine-matrix';\r\nimport { EventEmitter, EventKey, Handler, Subscription } from './EventEmitter';\r\n\r\n/**\r\n * Interface that describes a custom camera strategy for tracking targets\r\n */\r\nexport interface CameraStrategy {\r\n /**\r\n * Target of the camera strategy that will be passed to the action\r\n */\r\n target: T;\r\n\r\n /**\r\n * Camera strategies perform an action to calculate a new focus returned out of the strategy\r\n * @param target The target object to apply this camera strategy (if any)\r\n * @param camera The current camera implementation in excalibur running the game\r\n * @param engine The current engine running the game\r\n * @param delta The elapsed time in milliseconds since the last frame\r\n */\r\n action: (target: T, camera: Camera, engine: Engine, delta: number) => Vector;\r\n}\r\n\r\n/**\r\n * Container to house convenience strategy methods\r\n * @internal\r\n */\r\nexport class StrategyContainer {\r\n constructor(public camera: Camera) {}\r\n\r\n /**\r\n * Creates and adds the [[LockCameraToActorStrategy]] on the current camera.\r\n * @param actor The actor to lock the camera to\r\n */\r\n public lockToActor(actor: Actor) {\r\n this.camera.addStrategy(new LockCameraToActorStrategy(actor));\r\n }\r\n\r\n /**\r\n * Creates and adds the [[LockCameraToActorAxisStrategy]] on the current camera\r\n * @param actor The actor to lock the camera to\r\n * @param axis The axis to follow the actor on\r\n */\r\n public lockToActorAxis(actor: Actor, axis: Axis) {\r\n this.camera.addStrategy(new LockCameraToActorAxisStrategy(actor, axis));\r\n }\r\n\r\n /**\r\n * Creates and adds the [[ElasticToActorStrategy]] on the current camera\r\n * If cameraElasticity < cameraFriction < 1.0, the behavior will be a dampened spring that will slowly end at the target without bouncing\r\n * If cameraFriction < cameraElasticity < 1.0, the behavior will be an oscillating spring that will over\r\n * correct and bounce around the target\r\n *\r\n * @param actor Target actor to elastically follow\r\n * @param cameraElasticity [0 - 1.0] The higher the elasticity the more force that will drive the camera towards the target\r\n * @param cameraFriction [0 - 1.0] The higher the friction the more that the camera will resist motion towards the target\r\n */\r\n public elasticToActor(actor: Actor, cameraElasticity: number, cameraFriction: number) {\r\n this.camera.addStrategy(new ElasticToActorStrategy(actor, cameraElasticity, cameraFriction));\r\n }\r\n\r\n /**\r\n * Creates and adds the [[RadiusAroundActorStrategy]] on the current camera\r\n * @param actor Target actor to follow when it is \"radius\" pixels away\r\n * @param radius Number of pixels away before the camera will follow\r\n */\r\n public radiusAroundActor(actor: Actor, radius: number) {\r\n this.camera.addStrategy(new RadiusAroundActorStrategy(actor, radius));\r\n }\r\n\r\n /**\r\n * Creates and adds the [[LimitCameraBoundsStrategy]] on the current camera\r\n * @param box The bounding box to limit the camera to.\r\n */\r\n public limitCameraBounds(box: BoundingBox) {\r\n this.camera.addStrategy(new LimitCameraBoundsStrategy(box));\r\n }\r\n}\r\n\r\n/**\r\n * Camera axis enum\r\n */\r\nexport enum Axis {\r\n X,\r\n Y\r\n}\r\n\r\n/**\r\n * Lock a camera to the exact x/y position of an actor.\r\n */\r\nexport class LockCameraToActorStrategy implements CameraStrategy {\r\n constructor(public target: Actor) {}\r\n public action = (target: Actor, _cam: Camera, _eng: Engine, _delta: number) => {\r\n const center = target.center;\r\n return center;\r\n };\r\n}\r\n\r\n/**\r\n * Lock a camera to a specific axis around an actor.\r\n */\r\nexport class LockCameraToActorAxisStrategy implements CameraStrategy {\r\n constructor(public target: Actor, public axis: Axis) {}\r\n public action = (target: Actor, cam: Camera, _eng: Engine, _delta: number) => {\r\n const center = target.center;\r\n const currentFocus = cam.getFocus();\r\n if (this.axis === Axis.X) {\r\n return new Vector(center.x, currentFocus.y);\r\n } else {\r\n return new Vector(currentFocus.x, center.y);\r\n }\r\n };\r\n}\r\n\r\n/**\r\n * Using [Hook's law](https://en.wikipedia.org/wiki/Hooke's_law), elastically move the camera towards the target actor.\r\n */\r\nexport class ElasticToActorStrategy implements CameraStrategy {\r\n /**\r\n * If cameraElasticity < cameraFriction < 1.0, the behavior will be a dampened spring that will slowly end at the target without bouncing\r\n * If cameraFriction < cameraElasticity < 1.0, the behavior will be an oscillating spring that will over\r\n * correct and bounce around the target\r\n *\r\n * @param target Target actor to elastically follow\r\n * @param cameraElasticity [0 - 1.0] The higher the elasticity the more force that will drive the camera towards the target\r\n * @param cameraFriction [0 - 1.0] The higher the friction the more that the camera will resist motion towards the target\r\n */\r\n constructor(public target: Actor, public cameraElasticity: number, public cameraFriction: number) {}\r\n public action = (target: Actor, cam: Camera, _eng: Engine, _delta: number) => {\r\n const position = target.center;\r\n let focus = cam.getFocus();\r\n let cameraVel = cam.vel.clone();\r\n\r\n // Calculate the stretch vector, using the spring equation\r\n // F = kX\r\n // https://en.wikipedia.org/wiki/Hooke's_law\r\n // Apply to the current camera velocity\r\n const stretch = position.sub(focus).scale(this.cameraElasticity); // stretch is X\r\n cameraVel = cameraVel.add(stretch);\r\n\r\n // Calculate the friction (-1 to apply a force in the opposition of motion)\r\n // Apply to the current camera velocity\r\n const friction = cameraVel.scale(-1).scale(this.cameraFriction);\r\n cameraVel = cameraVel.add(friction);\r\n\r\n // Update position by velocity deltas\r\n focus = focus.add(cameraVel);\r\n\r\n return focus;\r\n };\r\n}\r\n\r\nexport class RadiusAroundActorStrategy implements CameraStrategy {\r\n /**\r\n *\r\n * @param target Target actor to follow when it is \"radius\" pixels away\r\n * @param radius Number of pixels away before the camera will follow\r\n */\r\n constructor(public target: Actor, public radius: number) {}\r\n public action = (target: Actor, cam: Camera, _eng: Engine, _delta: number) => {\r\n const position = target.center;\r\n const focus = cam.getFocus();\r\n\r\n const direction = position.sub(focus);\r\n const distance = direction.size;\r\n if (distance >= this.radius) {\r\n const offset = distance - this.radius;\r\n return focus.add(direction.normalize().scale(offset));\r\n }\r\n return focus;\r\n };\r\n}\r\n\r\n/**\r\n * Prevent a camera from going beyond the given camera dimensions.\r\n */\r\nexport class LimitCameraBoundsStrategy implements CameraStrategy {\r\n /**\r\n * Useful for limiting the camera to a [[TileMap]]'s dimensions, or a specific area inside the map.\r\n *\r\n * Note that this strategy does not perform any movement by itself.\r\n * It only sets the camera position to within the given bounds when the camera has gone beyond them.\r\n * Thus, it is a good idea to combine it with other camera strategies and set this strategy as the last one.\r\n *\r\n * Make sure that the camera bounds are at least as large as the viewport size.\r\n *\r\n * @param target The bounding box to limit the camera to\r\n */\r\n\r\n boundSizeChecked: boolean = false; // Check and warn only once\r\n\r\n constructor(public target: BoundingBox) {}\r\n\r\n public action = (target: BoundingBox, cam: Camera, _eng: Engine, _delta: number) => {\r\n const focus = cam.getFocus();\r\n\r\n if (!this.boundSizeChecked) {\r\n if (target.bottom - target.top < _eng.drawHeight || target.right - target.left < _eng.drawWidth) {\r\n Logger.getInstance().warn('Camera bounds should not be smaller than the engine viewport');\r\n }\r\n this.boundSizeChecked = true;\r\n }\r\n\r\n let focusX = focus.x;\r\n let focusY = focus.y;\r\n if (focus.x < target.left + _eng.halfDrawWidth) {\r\n focusX = target.left + _eng.halfDrawWidth;\r\n } else if (focus.x > target.right - _eng.halfDrawWidth) {\r\n focusX = target.right - _eng.halfDrawWidth;\r\n }\r\n\r\n if (focus.y < target.top + _eng.halfDrawHeight) {\r\n focusY = target.top + _eng.halfDrawHeight;\r\n } else if (focus.y > target.bottom - _eng.halfDrawHeight) {\r\n focusY = target.bottom - _eng.halfDrawHeight;\r\n }\r\n\r\n return vec(focusX, focusY);\r\n };\r\n}\r\n\r\nexport type CameraEvents = {\r\n preupdate: PreUpdateEvent,\r\n postupdate: PostUpdateEvent,\r\n initialize: InitializeEvent,\r\n\r\n}\r\n\r\nexport const CameraEvents = {\r\n Initialize: 'initialize',\r\n PreUpdate: 'preupdate',\r\n PostUpdate: 'postupdate'\r\n};\r\n\r\n/**\r\n * Cameras\r\n *\r\n * [[Camera]] is the base class for all Excalibur cameras. Cameras are used\r\n * to move around your game and set focus. They are used to determine\r\n * what is \"off screen\" and can be used to scale the game.\r\n *\r\n */\r\nexport class Camera implements CanUpdate, CanInitialize {\r\n public events = new EventEmitter();\r\n public transform: AffineMatrix = AffineMatrix.identity();\r\n public inverse: AffineMatrix = AffineMatrix.identity();\r\n\r\n\r\n protected _follow: Actor;\r\n\r\n private _cameraStrategies: CameraStrategy[] = [];\r\n\r\n public strategy: StrategyContainer = new StrategyContainer(this);\r\n\r\n /**\r\n * Get or set current zoom of the camera, defaults to 1\r\n */\r\n private _z = 1;\r\n public get zoom(): number {\r\n return this._z;\r\n }\r\n\r\n public set zoom(val: number) {\r\n this._z = val;\r\n if (this._engine) {\r\n this._halfWidth = this._engine.halfDrawWidth;\r\n this._halfHeight = this._engine.halfDrawHeight;\r\n }\r\n }\r\n /**\r\n * Get or set rate of change in zoom, defaults to 0\r\n */\r\n public dz: number = 0;\r\n /**\r\n * Get or set zoom acceleration\r\n */\r\n public az: number = 0;\r\n\r\n /**\r\n * Current rotation of the camera\r\n */\r\n public rotation: number = 0;\r\n\r\n private _angularVelocity: number = 0;\r\n\r\n /**\r\n * Get or set the camera's angular velocity\r\n */\r\n public get angularVelocity(): number {\r\n return this._angularVelocity;\r\n }\r\n\r\n public set angularVelocity(value: number) {\r\n this._angularVelocity = value;\r\n }\r\n\r\n /**\r\n * Get or set the camera's position\r\n */\r\n private _posChanged = false;\r\n private _pos: Vector = watchAny(Vector.Zero, () => (this._posChanged = true));\r\n public get pos(): Vector {\r\n return this._pos;\r\n }\r\n public set pos(vec: Vector) {\r\n this._pos = watchAny(vec, () => (this._posChanged = true));\r\n this._posChanged = true;\r\n }\r\n\r\n /**\r\n * Get or set the camera's velocity\r\n */\r\n public vel: Vector = Vector.Zero;\r\n\r\n /**\r\n * Get or set the camera's acceleration\r\n */\r\n public acc: Vector = Vector.Zero;\r\n\r\n private _cameraMoving: boolean = false;\r\n private _currentLerpTime: number = 0;\r\n private _lerpDuration: number = 1000; // 1 second\r\n private _lerpStart: Vector = null;\r\n private _lerpEnd: Vector = null;\r\n private _lerpResolve: (value: Vector) => void;\r\n private _lerpPromise: Promise;\r\n\r\n //camera effects\r\n protected _isShaking: boolean = false;\r\n private _shakeMagnitudeX: number = 0;\r\n private _shakeMagnitudeY: number = 0;\r\n private _shakeDuration: number = 0;\r\n private _elapsedShakeTime: number = 0;\r\n private _xShake: number = 0;\r\n private _yShake: number = 0;\r\n\r\n protected _isZooming: boolean = false;\r\n private _zoomStart: number = 1;\r\n private _zoomEnd: number = 1;\r\n private _currentZoomTime: number = 0;\r\n private _zoomDuration: number = 0;\r\n\r\n private _zoomResolve: (val: boolean) => void;\r\n private _zoomPromise: Promise;\r\n private _zoomEasing: EasingFunction = EasingFunctions.EaseInOutCubic;\r\n private _easing: EasingFunction = EasingFunctions.EaseInOutCubic;\r\n\r\n private _halfWidth: number = 0;\r\n private _halfHeight: number = 0;\r\n\r\n /**\r\n * Get the camera's x position\r\n */\r\n public get x() {\r\n return this.pos.x;\r\n }\r\n\r\n /**\r\n * Set the camera's x position (cannot be set when following an [[Actor]] or when moving)\r\n */\r\n public set x(value: number) {\r\n if (!this._follow && !this._cameraMoving) {\r\n this.pos = vec(value, this.pos.y);\r\n }\r\n }\r\n\r\n /**\r\n * Get the camera's y position\r\n */\r\n public get y() {\r\n return this.pos.y;\r\n }\r\n\r\n /**\r\n * Set the camera's y position (cannot be set when following an [[Actor]] or when moving)\r\n */\r\n public set y(value: number) {\r\n if (!this._follow && !this._cameraMoving) {\r\n this.pos = vec(this.pos.x, value);\r\n }\r\n }\r\n\r\n /**\r\n * Get or set the camera's x velocity\r\n */\r\n public get dx() {\r\n return this.vel.x;\r\n }\r\n\r\n public set dx(value: number) {\r\n this.vel = vec(value, this.vel.y);\r\n }\r\n\r\n /**\r\n * Get or set the camera's y velocity\r\n */\r\n public get dy() {\r\n return this.vel.y;\r\n }\r\n\r\n public set dy(value: number) {\r\n this.vel = vec(this.vel.x, value);\r\n }\r\n\r\n /**\r\n * Get or set the camera's x acceleration\r\n */\r\n public get ax() {\r\n return this.acc.x;\r\n }\r\n\r\n public set ax(value: number) {\r\n this.acc = vec(value, this.acc.y);\r\n }\r\n\r\n /**\r\n * Get or set the camera's y acceleration\r\n */\r\n public get ay() {\r\n return this.acc.y;\r\n }\r\n\r\n public set ay(value: number) {\r\n this.acc = vec(this.acc.x, value);\r\n }\r\n\r\n /**\r\n * Returns the focal point of the camera, a new point giving the x and y position of the camera\r\n */\r\n public getFocus() {\r\n return this.pos;\r\n }\r\n\r\n /**\r\n * This moves the camera focal point to the specified position using specified easing function. Cannot move when following an Actor.\r\n *\r\n * @param pos The target position to move to\r\n * @param duration The duration in milliseconds the move should last\r\n * @param [easingFn] An optional easing function ([[ex.EasingFunctions.EaseInOutCubic]] by default)\r\n * @returns A [[Promise]] that resolves when movement is finished, including if it's interrupted.\r\n * The [[Promise]] value is the [[Vector]] of the target position. It will be rejected if a move cannot be made.\r\n */\r\n public move(pos: Vector, duration: number, easingFn: EasingFunction = EasingFunctions.EaseInOutCubic): Promise {\r\n if (typeof easingFn !== 'function') {\r\n throw 'Please specify an EasingFunction';\r\n }\r\n\r\n // cannot move when following an actor\r\n if (this._follow) {\r\n return Promise.reject(pos);\r\n }\r\n\r\n // resolve existing promise, if any\r\n if (this._lerpPromise && this._lerpResolve) {\r\n this._lerpResolve(pos);\r\n }\r\n\r\n this._lerpPromise = new Promise((resolve) => {\r\n this._lerpResolve = resolve;\r\n });\r\n this._lerpStart = this.getFocus().clone();\r\n this._lerpDuration = duration;\r\n this._lerpEnd = pos;\r\n this._currentLerpTime = 0;\r\n this._cameraMoving = true;\r\n this._easing = easingFn;\r\n\r\n return this._lerpPromise;\r\n }\r\n\r\n /**\r\n * Sets the camera to shake at the specified magnitudes for the specified duration\r\n * @param magnitudeX The x magnitude of the shake\r\n * @param magnitudeY The y magnitude of the shake\r\n * @param duration The duration of the shake in milliseconds\r\n */\r\n public shake(magnitudeX: number, magnitudeY: number, duration: number) {\r\n this._isShaking = true;\r\n this._shakeMagnitudeX = magnitudeX;\r\n this._shakeMagnitudeY = magnitudeY;\r\n this._shakeDuration = duration;\r\n }\r\n\r\n /**\r\n * Zooms the camera in or out by the specified scale over the specified duration.\r\n * If no duration is specified, it take effect immediately.\r\n * @param scale The scale of the zoom\r\n * @param duration The duration of the zoom in milliseconds\r\n */\r\n public zoomOverTime(scale: number, duration: number = 0, easingFn: EasingFunction = EasingFunctions.EaseInOutCubic): Promise {\r\n this._zoomPromise = new Promise((resolve) => {\r\n this._zoomResolve = resolve;\r\n });\r\n\r\n if (duration) {\r\n this._isZooming = true;\r\n this._zoomEasing = easingFn;\r\n this._currentZoomTime = 0;\r\n this._zoomDuration = duration;\r\n this._zoomStart = this.zoom;\r\n this._zoomEnd = scale;\r\n } else {\r\n this._isZooming = false;\r\n this.zoom = scale;\r\n return Promise.resolve(true);\r\n }\r\n\r\n return this._zoomPromise;\r\n }\r\n\r\n private _viewport: BoundingBox = null;\r\n /**\r\n * Gets the bounding box of the viewport of this camera in world coordinates\r\n */\r\n public get viewport(): BoundingBox {\r\n if (this._viewport) {\r\n return this._viewport;\r\n }\r\n\r\n return new BoundingBox(0, 0, 0, 0);\r\n }\r\n\r\n /**\r\n * Adds a new camera strategy to this camera\r\n * @param cameraStrategy Instance of an [[CameraStrategy]]\r\n */\r\n public addStrategy(cameraStrategy: CameraStrategy) {\r\n this._cameraStrategies.push(cameraStrategy);\r\n }\r\n\r\n /**\r\n * Removes a camera strategy by reference\r\n * @param cameraStrategy Instance of an [[CameraStrategy]]\r\n */\r\n public removeStrategy(cameraStrategy: CameraStrategy) {\r\n removeItemFromArray(cameraStrategy, this._cameraStrategies);\r\n }\r\n\r\n /**\r\n * Clears all camera strategies from the camera\r\n */\r\n public clearAllStrategies() {\r\n this._cameraStrategies.length = 0;\r\n }\r\n\r\n /**\r\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\r\n *\r\n * Internal _preupdate handler for [[onPreUpdate]] lifecycle event\r\n * @internal\r\n */\r\n public _preupdate(engine: Engine, delta: number): void {\r\n this.events.emit('preupdate', new PreUpdateEvent(engine, delta, this));\r\n this.onPreUpdate(engine, delta);\r\n }\r\n\r\n /**\r\n * Safe to override onPreUpdate lifecycle event handler. Synonymous with `.on('preupdate', (evt) =>{...})`\r\n *\r\n * `onPreUpdate` is called directly before a scene is updated.\r\n */\r\n public onPreUpdate(_engine: Engine, _delta: number): void {\r\n // Overridable\r\n }\r\n\r\n /**\r\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\r\n *\r\n * Internal _preupdate handler for [[onPostUpdate]] lifecycle event\r\n * @internal\r\n */\r\n public _postupdate(engine: Engine, delta: number): void {\r\n this.events.emit('postupdate', new PostUpdateEvent(engine, delta, this));\r\n this.onPostUpdate(engine, delta);\r\n }\r\n\r\n /**\r\n * Safe to override onPostUpdate lifecycle event handler. Synonymous with `.on('preupdate', (evt) =>{...})`\r\n *\r\n * `onPostUpdate` is called directly after a scene is updated.\r\n */\r\n public onPostUpdate(_engine: Engine, _delta: number): void {\r\n // Overridable\r\n }\r\n\r\n private _engine: Engine;\r\n private _screen: Screen;\r\n private _isInitialized = false;\r\n public get isInitialized() {\r\n return this._isInitialized;\r\n }\r\n\r\n public _initialize(_engine: Engine) {\r\n if (!this.isInitialized) {\r\n this._engine = _engine;\r\n this._screen = _engine.screen;\r\n\r\n const currentRes = this._screen.contentArea;\r\n let center = vec(currentRes.width / 2, currentRes.height / 2);\r\n if (!this._engine.loadingComplete) {\r\n // If there was a loading screen, we peek the configured resolution\r\n const res = this._screen.peekResolution();\r\n if (res) {\r\n center = vec(res.width / 2, res.height / 2);\r\n }\r\n }\r\n this._halfWidth = center.x;\r\n this._halfHeight = center.y;\r\n\r\n // If the user has not set the camera pos, apply default center screen position\r\n if (!this._posChanged) {\r\n this.pos = center;\r\n }\r\n // First frame bootstrap\r\n\r\n // Ensure camera tx is correct\r\n // Run update twice to ensure properties are init'd\r\n this.updateTransform();\r\n\r\n // Run strategies for first frame\r\n this.runStrategies(_engine, _engine.clock.elapsed());\r\n\r\n // Setup the first frame viewport\r\n this.updateViewport();\r\n\r\n // It's important to update the camera after strategies\r\n // This prevents jitter\r\n this.updateTransform();\r\n\r\n this.onInitialize(_engine);\r\n this.events.emit('initialize', new InitializeEvent(_engine, this));\r\n this._isInitialized = true;\r\n }\r\n }\r\n\r\n /**\r\n * Safe to override onPostUpdate lifecycle event handler. Synonymous with `.on('preupdate', (evt) =>{...})`\r\n *\r\n * `onPostUpdate` is called directly after a scene is updated.\r\n */\r\n public onInitialize(_engine: Engine) {\r\n // Overridable\r\n }\r\n\r\n public emit>(eventName: TEventName, event: CameraEvents[TEventName]): void;\r\n public emit(eventName: string, event?: any): void;\r\n public emit | string>(eventName: TEventName, event?: any): void {\r\n this.events.emit(eventName, event);\r\n }\r\n\r\n public on>(eventName: TEventName, handler: Handler): Subscription;\r\n public on(eventName: string, handler: Handler): Subscription;\r\n public on | string>(eventName: TEventName, handler: Handler): Subscription {\r\n return this.events.on(eventName, handler);\r\n }\r\n\r\n public once>(eventName: TEventName, handler: Handler): Subscription;\r\n public once(eventName: string, handler: Handler): Subscription;\r\n public once | string>(eventName: TEventName, handler: Handler): Subscription {\r\n return this.events.once(eventName, handler);\r\n }\r\n\r\n public off>(eventName: TEventName, handler: Handler): void;\r\n public off(eventName: string, handler: Handler): void;\r\n public off(eventName: string): void;\r\n public off | string>(eventName: TEventName, handler?: Handler): void {\r\n this.events.off(eventName, handler);\r\n }\r\n\r\n public runStrategies(engine: Engine, delta: number) {\r\n for (const s of this._cameraStrategies) {\r\n this.pos = s.action.call(s, s.target, this, engine, delta);\r\n }\r\n }\r\n\r\n public updateViewport() {\r\n // recalc viewport\r\n this._viewport = new BoundingBox(\r\n this.x - this._halfWidth,\r\n this.y - this._halfHeight,\r\n this.x + this._halfWidth,\r\n this.y + this._halfHeight\r\n );\r\n }\r\n\r\n public update(_engine: Engine, delta: number) {\r\n this._initialize(_engine);\r\n this._preupdate(_engine, delta);\r\n\r\n // Update placements based on linear algebra\r\n this.pos = this.pos.add(this.vel.scale(delta / 1000));\r\n this.zoom += (this.dz * delta) / 1000;\r\n\r\n this.vel = this.vel.add(this.acc.scale(delta / 1000));\r\n this.dz += (this.az * delta) / 1000;\r\n\r\n this.rotation += (this.angularVelocity * delta) / 1000;\r\n\r\n if (this._isZooming) {\r\n if (this._currentZoomTime < this._zoomDuration) {\r\n const zoomEasing = this._zoomEasing;\r\n const newZoom = zoomEasing(this._currentZoomTime, this._zoomStart, this._zoomEnd, this._zoomDuration);\r\n\r\n this.zoom = newZoom;\r\n this._currentZoomTime += delta;\r\n } else {\r\n this._isZooming = false;\r\n this.zoom = this._zoomEnd;\r\n this._currentZoomTime = 0;\r\n this._zoomResolve(true);\r\n }\r\n }\r\n\r\n if (this._cameraMoving) {\r\n if (this._currentLerpTime < this._lerpDuration) {\r\n const moveEasing = EasingFunctions.CreateVectorEasingFunction(this._easing);\r\n\r\n const lerpPoint = moveEasing(this._currentLerpTime, this._lerpStart, this._lerpEnd, this._lerpDuration);\r\n\r\n this.pos = lerpPoint;\r\n\r\n this._currentLerpTime += delta;\r\n } else {\r\n this.pos = this._lerpEnd;\r\n const end = this._lerpEnd.clone();\r\n\r\n this._lerpStart = null;\r\n this._lerpEnd = null;\r\n this._currentLerpTime = 0;\r\n this._cameraMoving = false;\r\n // Order matters here, resolve should be last so any chain promises have a clean slate\r\n this._lerpResolve(end);\r\n }\r\n }\r\n\r\n if (this._isDoneShaking()) {\r\n this._isShaking = false;\r\n this._elapsedShakeTime = 0;\r\n this._shakeMagnitudeX = 0;\r\n this._shakeMagnitudeY = 0;\r\n this._shakeDuration = 0;\r\n this._xShake = 0;\r\n this._yShake = 0;\r\n } else {\r\n this._elapsedShakeTime += delta;\r\n this._xShake = ((Math.random() * this._shakeMagnitudeX) | 0) + 1;\r\n this._yShake = ((Math.random() * this._shakeMagnitudeY) | 0) + 1;\r\n }\r\n\r\n this.runStrategies(_engine, delta);\r\n\r\n this.updateViewport();\r\n\r\n // It's important to update the camera after strategies\r\n // This prevents jitter\r\n this.updateTransform();\r\n\r\n this._postupdate(_engine, delta);\r\n }\r\n\r\n /**\r\n * Applies the relevant transformations to the game canvas to \"move\" or apply effects to the Camera\r\n * @param ctx Canvas context to apply transformations\r\n */\r\n public draw(ctx: ExcaliburGraphicsContext): void {\r\n ctx.multiply(this.transform);\r\n }\r\n\r\n public updateTransform() {\r\n // center the camera\r\n const newCanvasWidth = this._screen.resolution.width / this.zoom;\r\n const newCanvasHeight = this._screen.resolution.height / this.zoom;\r\n const cameraPos = vec(-this.x + newCanvasWidth / 2 + this._xShake, -this.y + newCanvasHeight / 2 + this._yShake);\r\n\r\n // Calculate camera transform\r\n this.transform.reset();\r\n\r\n this.transform.scale(this.zoom, this.zoom);\r\n\r\n // rotate about the focus\r\n this.transform.translate(newCanvasWidth / 2, newCanvasHeight / 2);\r\n this.transform.rotate(this.rotation);\r\n this.transform.translate(-newCanvasWidth / 2, -newCanvasHeight / 2);\r\n\r\n this.transform.translate(cameraPos.x, cameraPos.y);\r\n this.transform.inverse(this.inverse);\r\n }\r\n\r\n private _isDoneShaking(): boolean {\r\n return !this._isShaking || this._elapsedShakeTime >= this._shakeDuration;\r\n }\r\n}\r\n","import { Engine } from './Engine';\r\nimport { Vector } from './Math/vector';\r\nimport { ExitTriggerEvent, EnterTriggerEvent, CollisionEndEvent, CollisionStartEvent } from './Events';\r\nimport { CollisionType } from './Collision/CollisionType';\r\nimport { Entity } from './EntityComponentSystem';\r\nimport { Actor, ActorEvents } from './Actor';\r\nimport { EventEmitter } from './EventEmitter';\r\n\r\nexport type TriggerEvents = ActorEvents & {\r\n exittrigger: ExitTriggerEvent,\r\n entertrigger: EnterTriggerEvent\r\n}\r\n\r\nexport const TriggerEvents = {\r\n ExitTrigger: 'exittrigger',\r\n EnterTrigger: 'entertrigger'\r\n};\r\n\r\n/**\r\n * TriggerOptions\r\n */\r\nexport interface TriggerOptions {\r\n // position of the trigger\r\n pos: Vector;\r\n // width of the trigger\r\n width: number;\r\n // height of the trigger\r\n height: number;\r\n // whether the trigger is visible or not\r\n visible: boolean;\r\n // action to take when triggered\r\n action: () => void;\r\n // if specified the trigger will only fire on a specific actor and overrides any filter\r\n target: Entity;\r\n // Returns true if the triggers should fire on the collided actor\r\n filter: (actor: Entity) => boolean;\r\n // -1 if it should repeat forever\r\n repeat: number;\r\n}\r\n\r\nconst triggerDefaults: Partial = {\r\n pos: Vector.Zero,\r\n width: 10,\r\n height: 10,\r\n visible: false,\r\n action: () => {\r\n return;\r\n },\r\n filter: () => true,\r\n repeat: -1\r\n};\r\n\r\n/**\r\n * Triggers are a method of firing arbitrary code on collision. These are useful\r\n * as 'buttons', 'switches', or to trigger effects in a game. By default triggers\r\n * are invisible, and can only be seen when [[Trigger.visible]] is set to `true`.\r\n */\r\nexport class Trigger extends Actor {\r\n public events = new EventEmitter();\r\n private _target: Entity;\r\n /**\r\n * Action to fire when triggered by collision\r\n */\r\n public action: () => void = () => {\r\n return;\r\n };\r\n /**\r\n * Filter to add additional granularity to action dispatch, if a filter is specified the action will only fire when\r\n * filter return true for the collided actor.\r\n */\r\n public filter: (actor: Entity) => boolean = () => true;\r\n /**\r\n * Number of times to repeat before killing the trigger,\r\n */\r\n public repeat: number = -1;\r\n\r\n /**\r\n *\r\n * @param opts Trigger options\r\n */\r\n constructor(opts: Partial) {\r\n super({ x: opts.pos.x, y: opts.pos.y, width: opts.width, height: opts.height });\r\n opts = {\r\n ...triggerDefaults,\r\n ...opts\r\n };\r\n\r\n this.filter = opts.filter || this.filter;\r\n this.repeat = opts.repeat || this.repeat;\r\n this.action = opts.action || this.action;\r\n if (opts.target) {\r\n this.target = opts.target;\r\n }\r\n\r\n this.graphics.visible = opts.visible;\r\n this.body.collisionType = CollisionType.Passive;\r\n\r\n this.events.on('collisionstart', (evt: CollisionStartEvent) => {\r\n if (this.filter(evt.other)) {\r\n this.emit('enter', new EnterTriggerEvent(this, evt.other));\r\n this._dispatchAction();\r\n // remove trigger if its done, -1 repeat forever\r\n if (this.repeat === 0) {\r\n this.kill();\r\n }\r\n }\r\n });\r\n\r\n this.events.on('collisionend', (evt: CollisionEndEvent) => {\r\n if (this.filter(evt.other)) {\r\n this.emit('exit', new ExitTriggerEvent(this, evt.other));\r\n }\r\n });\r\n }\r\n\r\n public set target(target: Entity) {\r\n this._target = target;\r\n this.filter = (actor: Entity) => actor === target;\r\n }\r\n\r\n public get target() {\r\n return this._target;\r\n }\r\n\r\n public _initialize(engine: Engine) {\r\n super._initialize(engine);\r\n }\r\n\r\n private _dispatchAction() {\r\n if (this.repeat !== 0) {\r\n this.action.call(this);\r\n this.repeat--;\r\n }\r\n }\r\n}\r\n","import { Entity } from './Entity';\r\nimport { Message, Observer } from '../Util/Observable';\r\nimport { Component } from './Component';\r\nimport { Scene } from '../Scene';\r\n\r\n/**\r\n * Enum that determines whether to run the system in the update or draw phase\r\n */\r\nexport enum SystemType {\r\n Update = 'update',\r\n Draw = 'draw'\r\n}\r\n\r\nexport type SystemTypes = ComponentTypes extends Component ? TypeName : never;\r\n\r\n/**\r\n * An Excalibur [[System]] that updates entities of certain types.\r\n * Systems are scene specific\r\n *\r\n * Excalibur Systems currently require at least 1 Component type to operated\r\n *\r\n * Multiple types are declared as a type union\r\n * For example:\r\n *\r\n * ```typescript\r\n * class MySystem extends System {\r\n * public readonly types = ['a', 'b'] as const;\r\n * public readonly systemType = SystemType.Update;\r\n * public update(entities: Entity) {\r\n * ...\r\n * }\r\n * }\r\n * ```\r\n */\r\nexport abstract class System\r\nimplements Observer {\r\n /**\r\n * The types of entities that this system operates on\r\n * For example ['transform', 'motion']\r\n */\r\n abstract readonly types: readonly SystemTypes[];\r\n\r\n /**\r\n * Determine whether the system is called in the [[SystemType.Update]] or the [[SystemType.Draw]] phase. Update is first, then Draw.\r\n */\r\n abstract readonly systemType: SystemType;\r\n\r\n /**\r\n * System can execute in priority order, by default all systems are priority 0. Lower values indicated higher priority.\r\n * For a system to execute before all other a lower priority value (-1 for example) must be set.\r\n * For a system to execute after all other a higher priority value (10 for example) must be set.\r\n */\r\n public priority: number = 0;\r\n\r\n /**\r\n * Optionally specify a sort order for entities passed to the your system\r\n * @param a The left entity\r\n * @param b The right entity\r\n */\r\n sort?(a: Entity, b: Entity): number;\r\n\r\n /**\r\n * Optionally specify an initialize handler\r\n * @param scene\r\n */\r\n initialize?(engine: ContextType): void;\r\n\r\n /**\r\n * Update all entities that match this system's types\r\n * @param entities Entities to update that match this system's types\r\n * @param delta Time in milliseconds\r\n */\r\n abstract update(entities: Entity[], delta: number): void;\r\n\r\n /**\r\n * Optionally run a preupdate before the system processes matching entities\r\n * @param engine\r\n * @param elapsedMs Time in milliseconds since the last frame\r\n */\r\n preupdate?(engine: ContextType, elapsedMs: number): void;\r\n\r\n /**\r\n * Optionally run a postupdate after the system processes matching entities\r\n * @param engine\r\n * @param elapsedMs Time in milliseconds since the last frame\r\n */\r\n postupdate?(engine: ContextType, elapsedMs: number): void;\r\n\r\n /**\r\n * Systems observe when entities match their types or no longer match their types, override\r\n * @param _entityAddedOrRemoved\r\n */\r\n public notify(_entityAddedOrRemoved: AddedEntity | RemovedEntity) {\r\n // Override me\r\n }\r\n}\r\n\r\n/**\r\n * An [[Entity]] with [[Component]] types that matches a [[System]] types exists in the current scene.\r\n */\r\nexport class AddedEntity implements Message {\r\n readonly type: 'Entity Added' = 'Entity Added';\r\n constructor(public data: Entity) {}\r\n}\r\n\r\n/**\r\n * Type guard to check for AddedEntity messages\r\n * @param x\r\n */\r\nexport function isAddedSystemEntity(x: Message): x is AddedEntity {\r\n return !!x && x.type === 'Entity Added';\r\n}\r\n\r\n/**\r\n * An [[Entity]] with [[Component]] types that no longer matches a [[System]] types exists in the current scene.\r\n */\r\nexport class RemovedEntity implements Message {\r\n readonly type: 'Entity Removed' = 'Entity Removed';\r\n constructor(public data: Entity) {}\r\n}\r\n\r\n/**\r\n * type guard to check for the RemovedEntity message\r\n */\r\nexport function isRemoveSystemEntity(x: Message): x is RemovedEntity {\r\n return !!x && x.type === 'Entity Removed';\r\n}\r\n","import { Entity, RemovedComponent, AddedComponent, isAddedComponent, isRemovedComponent } from './Entity';\r\nimport { Observer } from '../Util/Observable';\r\nimport { World } from './World';\r\nimport { Util } from '..';\r\n\r\n// Add/Remove entities and components\r\n\r\nexport class EntityManager implements Observer {\r\n public entities: Entity[] = [];\r\n public _entityIndex: { [entityId: string]: Entity } = {};\r\n\r\n constructor(private _world: World) {}\r\n\r\n /**\r\n * Runs the entity lifecycle\r\n * @param _context\r\n */\r\n public updateEntities(_context: ContextType, elapsed: number) {\r\n for (const entity of this.entities) {\r\n // TODO is this right?\r\n entity.update((_context as any).engine, elapsed);\r\n if (!entity.active) {\r\n this.removeEntity(entity);\r\n }\r\n }\r\n }\r\n\r\n public findEntitiesForRemoval() {\r\n for (const entity of this.entities) {\r\n if (!entity.active) {\r\n this.removeEntity(entity);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * EntityManager observes changes on entities\r\n * @param message\r\n */\r\n public notify(message: RemovedComponent | AddedComponent): void {\r\n if (isAddedComponent(message)) {\r\n // we don't need the component, it's already on the entity\r\n this._world.queryManager.addEntity(message.data.entity);\r\n }\r\n\r\n if (isRemovedComponent(message)) {\r\n this._world.queryManager.removeComponent(message.data.entity, message.data.component);\r\n }\r\n }\r\n\r\n /**\r\n * Adds an entity to be tracked by the EntityManager\r\n * @param entity\r\n */\r\n public addEntity(entity: Entity): void {\r\n entity.active = true;\r\n entity.scene = (this._world.context as any);\r\n if (entity && !this._entityIndex[entity.id]) {\r\n this._entityIndex[entity.id] = entity;\r\n this.entities.push(entity);\r\n this._world.queryManager.addEntity(entity);\r\n entity.componentAdded$.register(this);\r\n entity.componentRemoved$.register(this);\r\n\r\n // if entity has children\r\n entity.children.forEach((c) => {\r\n c.scene = entity.scene;\r\n this.addEntity(c);\r\n });\r\n entity.childrenAdded$.register({\r\n notify: (e) => {\r\n this.addEntity(e);\r\n }\r\n });\r\n entity.childrenRemoved$.register({\r\n notify: (e) => {\r\n this.removeEntity(e, false);\r\n }\r\n });\r\n }\r\n }\r\n\r\n public removeEntity(entity: Entity, deferred?: boolean): void;\r\n public removeEntity(id: number, deferred?: boolean): void;\r\n public removeEntity(idOrEntity: number | Entity, deferred = true): void {\r\n let id = 0;\r\n if (idOrEntity instanceof Entity) {\r\n id = idOrEntity.id;\r\n } else {\r\n id = idOrEntity;\r\n }\r\n const entity = this._entityIndex[id];\r\n if (entity && entity.active) {\r\n entity.active = false;\r\n }\r\n\r\n if (entity && deferred) {\r\n this._entitiesToRemove.push(entity);\r\n return;\r\n }\r\n\r\n delete this._entityIndex[id];\r\n if (entity) {\r\n entity.scene = null;\r\n Util.removeItemFromArray(entity, this.entities);\r\n this._world.queryManager.removeEntity(entity);\r\n entity.componentAdded$.unregister(this);\r\n entity.componentRemoved$.unregister(this);\r\n\r\n // if entity has children\r\n entity.children.forEach((c) => {\r\n c.scene = null;\r\n this.removeEntity(c, deferred);\r\n });\r\n entity.childrenAdded$.clear();\r\n entity.childrenRemoved$.clear();\r\n\r\n // stats\r\n if ((this._world.context as any)?.engine) {\r\n (this._world.context as any).engine.stats.currFrame.actors.killed++;\r\n }\r\n }\r\n }\r\n\r\n private _entitiesToRemove: Entity[] = [];\r\n public processEntityRemovals(): void {\r\n for (const entity of this._entitiesToRemove) {\r\n if (entity.active) {\r\n continue;\r\n }\r\n this.removeEntity(entity, false);\r\n }\r\n this._entitiesToRemove.length = 0;\r\n }\r\n\r\n public processComponentRemovals(): void {\r\n for (const entity of this.entities) {\r\n entity.processComponentRemoval();\r\n }\r\n }\r\n\r\n public getById(id: number): Entity {\r\n return this._entityIndex[id];\r\n }\r\n\r\n public getByName(name: string): Entity[]{\r\n return this.entities.filter(e => e.name === name);\r\n }\r\n\r\n public clear(): void {\r\n for (const entity of this.entities) {\r\n this.removeEntity(entity);\r\n }\r\n }\r\n}\r\n","export const buildTypeKey = (types: readonly string[]) => {\r\n const key = [...types].sort((a, b) => a.localeCompare(b)).join('+');\r\n return key;\r\n};\r\n","import { Entity } from './Entity';\r\nimport { buildTypeKey } from './Util';\r\nimport { Observable } from '../Util/Observable';\r\nimport { Util, Component, ComponentCtor } from '..';\r\nimport { AddedEntity, RemovedEntity } from './System';\r\n\r\n/**\r\n * Represents query for entities that match a list of types that is cached and observable\r\n *\r\n * Queries can be strongly typed by supplying a type union in the optional type parameter\r\n * ```typescript\r\n * const queryAB = new ex.Query(['A', 'B']);\r\n * ```\r\n */\r\nexport class Query extends Observable {\r\n public types: readonly string[];\r\n private _entities: Entity[] = [];\r\n private _key: string;\r\n public get key(): string {\r\n if (this._key) {\r\n return this._key;\r\n }\r\n return (this._key = buildTypeKey(this.types));\r\n }\r\n\r\n constructor(types: readonly string[]);\r\n constructor(types: readonly ComponentCtor[]);\r\n constructor(types: readonly string[] | readonly ComponentCtor[]) {\r\n super();\r\n if (types[0] instanceof Function) {\r\n this.types = (types as ComponentCtor[]).map(T => (new T).type);\r\n } else {\r\n this.types = types as string[];\r\n }\r\n }\r\n\r\n /**\r\n * Returns a list of entities that match the query\r\n *\r\n * @param sort Optional sorting function to sort entities returned from the query\r\n */\r\n public getEntities(sort?: (a: Entity, b: Entity) => number): Entity[] {\r\n if (sort) {\r\n this._entities.sort(sort);\r\n }\r\n return this._entities;\r\n }\r\n\r\n /**\r\n * Add an entity to the query, will only be added if the entity matches the query types\r\n * @param entity\r\n */\r\n public addEntity(entity: Entity): void {\r\n if (!Util.contains(this._entities, entity) && this.matches(entity)) {\r\n this._entities.push(entity);\r\n this.notifyAll(new AddedEntity(entity));\r\n }\r\n }\r\n\r\n /**\r\n * If the entity is part of the query it will be removed regardless of types\r\n * @param entity\r\n */\r\n public removeEntity(entity: Entity): void {\r\n if (Util.removeItemFromArray(entity, this._entities)) {\r\n this.notifyAll(new RemovedEntity(entity));\r\n }\r\n }\r\n\r\n /**\r\n * Removes all entities and observers from the query\r\n */\r\n public clear(): void {\r\n this._entities.length = 0;\r\n for (const observer of this.observers) {\r\n this.unregister(observer);\r\n }\r\n }\r\n\r\n /**\r\n * Returns whether the entity's types match query\r\n * @param entity\r\n */\r\n public matches(entity: Entity): boolean;\r\n\r\n /**\r\n * Returns whether the list of ComponentTypes have at least the same types as the query\r\n * @param types\r\n */\r\n public matches(types: string[]): boolean;\r\n public matches(typesOrEntity: string[] | Entity): boolean {\r\n let types: string[] = [];\r\n if (typesOrEntity instanceof Entity) {\r\n types = typesOrEntity.types;\r\n } else {\r\n types = typesOrEntity;\r\n }\r\n\r\n let matches = true;\r\n for (const type of this.types) {\r\n matches = matches && types.indexOf(type) > -1;\r\n if (!matches) {\r\n return false;\r\n }\r\n }\r\n return matches;\r\n }\r\n\r\n public contain(type: string) {\r\n return this.types.indexOf(type) > -1;\r\n }\r\n}\r\n","import { Entity } from './Entity';\r\nimport { buildTypeKey } from './Util';\r\nimport { Query } from './Query';\r\nimport { Component } from './Component';\r\nimport { World } from './World';\r\n\r\n/**\r\n * The query manager is responsible for updating all queries when entities/components change\r\n */\r\nexport class QueryManager {\r\n private _queries: { [entityComponentKey: string]: Query } = {};\r\n\r\n constructor(private _world: World) {}\r\n\r\n /**\r\n * Adds a query to the manager and populates with any entities that match\r\n * @param query\r\n */\r\n private _addQuery(query: Query) {\r\n this._queries[buildTypeKey(query.types)] = query;\r\n for (const entity of this._world.entityManager.entities) {\r\n query.addEntity(entity);\r\n }\r\n }\r\n\r\n /**\r\n * Removes the query if there are no observers left\r\n * @param query\r\n */\r\n public maybeRemoveQuery(query: Query): void {\r\n if (query.observers.length === 0) {\r\n query.clear();\r\n delete this._queries[buildTypeKey(query.types)];\r\n }\r\n }\r\n\r\n /**\r\n * Adds the entity to any matching query in the query manage\r\n * @param entity\r\n */\r\n public addEntity(entity: Entity) {\r\n for (const queryType in this._queries) {\r\n if (this._queries[queryType]) {\r\n this._queries[queryType].addEntity(entity);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Removes an entity from queries if the removed component disqualifies it\r\n * @param entity\r\n * @param component\r\n */\r\n public removeComponent(entity: Entity, component: Component) {\r\n for (const queryType in this._queries) {\r\n // If the component being removed from an entity is a part of a query,\r\n // it is now disqualified from that query, remove it\r\n if (this._queries[queryType].contain(component.type)) {\r\n this._queries[queryType].removeEntity(entity);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Removes an entity from all queries it is currently a part of\r\n * @param entity\r\n */\r\n public removeEntity(entity: Entity) {\r\n for (const queryType in this._queries) {\r\n this._queries[queryType].removeEntity(entity);\r\n }\r\n }\r\n\r\n /**\r\n * Creates a populated query and returns, if the query already exists that will be returned instead of a new instance\r\n * @param types\r\n */\r\n public createQuery(types: readonly string[]): Query {\r\n const maybeExistingQuery = this.getQuery(types);\r\n if (maybeExistingQuery) {\r\n return maybeExistingQuery;\r\n }\r\n const query = new Query(types);\r\n this._addQuery(query);\r\n return query;\r\n }\r\n\r\n /**\r\n * Retrieves an existing query by types if it exists otherwise returns null\r\n * @param types\r\n */\r\n public getQuery(types: readonly string[]): Query {\r\n const key = buildTypeKey(types);\r\n if (this._queries[key]) {\r\n return this._queries[key] as Query;\r\n }\r\n return null;\r\n }\r\n}\r\n","import { System, SystemType } from './System';\r\nimport { Scene, Util } from '..';\r\nimport { World } from './World';\r\n\r\nexport interface SystemCtor {\r\n new (...args: any[]): T;\r\n}\r\n\r\n/**\r\n * The SystemManager is responsible for keeping track of all systems in a scene.\r\n * Systems are scene specific\r\n */\r\nexport class SystemManager {\r\n /**\r\n * List of systems, to add a new system call [[SystemManager.addSystem]]\r\n */\r\n public systems: System[] = [];\r\n public _keyToSystem: { [key: string]: System };\r\n public initialized = false;\r\n constructor(private _world: World) {}\r\n\r\n /**\r\n * Get a system registered in the manager by type\r\n * @param systemType\r\n */\r\n public get(systemType: SystemCtor): T | null {\r\n return this.systems.find((s) => s instanceof systemType) as unknown as T;\r\n }\r\n\r\n /**\r\n * Adds a system to the manager, it will now be updated every frame\r\n * @param system\r\n */\r\n public addSystem(system: System): void {\r\n // validate system has types\r\n if (!system.types || system.types.length === 0) {\r\n throw new Error(`Attempted to add a System without any types`);\r\n }\r\n\r\n const query = this._world.queryManager.createQuery(system.types);\r\n this.systems.push(system);\r\n this.systems.sort((a, b) => a.priority - b.priority);\r\n query.register(system);\r\n // If systems are added and the manager has already been init'd\r\n // then immediately init the system\r\n if (this.initialized && system.initialize) {\r\n system.initialize(this._world.context);\r\n }\r\n }\r\n\r\n /**\r\n * Removes a system from the manager, it will no longer be updated\r\n * @param system\r\n */\r\n public removeSystem(system: System) {\r\n Util.removeItemFromArray(system, this.systems);\r\n const query = this._world.queryManager.getQuery(system.types);\r\n if (query) {\r\n query.unregister(system);\r\n this._world.queryManager.maybeRemoveQuery(query);\r\n }\r\n }\r\n\r\n /**\r\n * Initialize all systems in the manager\r\n *\r\n * Systems added after initialize() will be initialized on add\r\n */\r\n public initialize() {\r\n if (!this.initialized) {\r\n this.initialized = true;\r\n for (const s of this.systems) {\r\n if (s.initialize) {\r\n s.initialize(this._world.context);\r\n }\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Updates all systems\r\n * @param type whether this is an update or draw system\r\n * @param context context reference\r\n * @param delta time in milliseconds\r\n */\r\n public updateSystems(type: SystemType, context: ContextType, delta: number) {\r\n const systems = this.systems.filter((s) => s.systemType === type);\r\n for (const s of systems) {\r\n if (s.preupdate) {\r\n s.preupdate(context, delta);\r\n }\r\n }\r\n\r\n for (const s of systems) {\r\n // Get entities that match the system types, pre-sort\r\n const entities = this._world.queryManager.getQuery(s.types).getEntities(s.sort);\r\n // Initialize entities if needed\r\n if (context instanceof Scene) {\r\n for (const entity of entities) {\r\n entity._initialize(context?.engine);\r\n }\r\n }\r\n s.update(entities, delta);\r\n }\r\n\r\n for (const s of systems) {\r\n if (s.postupdate) {\r\n s.postupdate(context, delta);\r\n }\r\n }\r\n }\r\n\r\n public clear(): void {\r\n for (const system of this.systems) {\r\n this.removeSystem(system);\r\n }\r\n }\r\n}\r\n","import { Entity } from './Entity';\r\nimport { EntityManager } from './EntityManager';\r\nimport { QueryManager } from './QueryManager';\r\nimport { System, SystemType } from './System';\r\nimport { SystemManager } from './SystemManager';\r\n\r\n/**\r\n * The World is a self-contained entity component system for a particular context.\r\n */\r\nexport class World {\r\n public queryManager: QueryManager = new QueryManager(this);\r\n public entityManager: EntityManager = new EntityManager(this);\r\n public systemManager: SystemManager = new SystemManager(this);\r\n\r\n /**\r\n * The context type is passed to the system updates\r\n * @param context\r\n */\r\n constructor(public context: ContextType) {}\r\n\r\n /**\r\n * Update systems by type and time elapsed in milliseconds\r\n */\r\n update(type: SystemType, delta: number) {\r\n if (type === SystemType.Update) {\r\n this.entityManager.updateEntities(this.context, delta);\r\n }\r\n this.systemManager.updateSystems(type, this.context, delta);\r\n this.entityManager.findEntitiesForRemoval();\r\n this.entityManager.processComponentRemovals();\r\n this.entityManager.processEntityRemovals();\r\n }\r\n\r\n /**\r\n * Add an entity to the ECS world\r\n * @param entity\r\n */\r\n add(entity: Entity): void;\r\n /**\r\n * Add a system to the ECS world\r\n * @param system\r\n */\r\n add(system: System): void;\r\n add(entityOrSystem: Entity | System): void {\r\n if (entityOrSystem instanceof Entity) {\r\n this.entityManager.addEntity(entityOrSystem);\r\n }\r\n\r\n if (entityOrSystem instanceof System) {\r\n this.systemManager.addSystem(entityOrSystem);\r\n }\r\n }\r\n\r\n /**\r\n * Remove an entity from the ECS world\r\n * @param entity\r\n */\r\n remove(entity: Entity, deferred?: boolean): void;\r\n /**\r\n * Remove a system from the ECS world\r\n * @param system\r\n */\r\n remove(system: System): void;\r\n remove(entityOrSystem: Entity | System, deferred = true): void {\r\n if (entityOrSystem instanceof Entity) {\r\n this.entityManager.removeEntity(entityOrSystem, deferred);\r\n }\r\n\r\n if (entityOrSystem instanceof System) {\r\n this.systemManager.removeSystem(entityOrSystem);\r\n }\r\n }\r\n\r\n clearEntities(): void {\r\n this.entityManager.clear();\r\n }\r\n\r\n clearSystems(): void {\r\n this.systemManager.clear();\r\n }\r\n}\r\n","import { Vector } from '../Math/vector';\r\nimport { TransformComponent } from '../EntityComponentSystem';\r\nimport { MotionComponent } from '../EntityComponentSystem/Components/MotionComponent';\r\n\r\nexport class EulerIntegrator {\r\n // Scratch vectors to avoid allocation\r\n private static _POS = new Vector(0, 0);\r\n private static _SCALE = new Vector(1, 1);\r\n\r\n private static _ACC = new Vector(0, 0);\r\n private static _VEL = new Vector(0, 0);\r\n private static _VEL_ACC = new Vector(0, 0);\r\n private static _SCALE_FACTOR = new Vector(0, 0);\r\n\r\n static integrate(transform: TransformComponent, motion: MotionComponent, totalAcc: Vector, elapsedMs: number): void {\r\n const seconds = elapsedMs / 1000;\r\n // This code looks a little wild, but it's to avoid creating any new Vector instances\r\n // integration is done in a tight loop so this is key to avoid GC'ing\r\n motion.vel.addEqual(totalAcc.scale(seconds, EulerIntegrator._ACC));\r\n transform.pos\r\n .add(motion.vel.scale(seconds, EulerIntegrator._VEL), EulerIntegrator._POS)\r\n .addEqual(totalAcc.scale(0.5 * seconds * seconds, EulerIntegrator._VEL_ACC));\r\n\r\n motion.angularVelocity += motion.torque * (1.0 / motion.inertia) * seconds;\r\n const rotation = transform.rotation + motion.angularVelocity * seconds;\r\n\r\n transform.scale.add(motion.scaleFactor.scale(seconds, this._SCALE_FACTOR), EulerIntegrator._SCALE);\r\n const tx = transform.get();\r\n tx.setTransform(EulerIntegrator._POS, rotation, EulerIntegrator._SCALE);\r\n }\r\n}\r\n","import { Entity } from '../EntityComponentSystem';\r\nimport { MotionComponent } from '../EntityComponentSystem/Components/MotionComponent';\r\nimport { TransformComponent } from '../EntityComponentSystem/Components/TransformComponent';\r\nimport { System, SystemType } from '../EntityComponentSystem/System';\r\nimport { Physics } from './Physics';\r\nimport { BodyComponent } from './BodyComponent';\r\nimport { CollisionType } from './CollisionType';\r\nimport { EulerIntegrator } from './Integrator';\r\n\r\nexport class MotionSystem extends System {\r\n public readonly types = ['ex.transform', 'ex.motion'] as const;\r\n public systemType = SystemType.Update;\r\n public priority = -1;\r\n\r\n update(entities: Entity[], elapsedMs: number): void {\r\n let transform: TransformComponent;\r\n let motion: MotionComponent;\r\n for (let i = 0; i < entities.length; i++) {\r\n transform = entities[i].get(TransformComponent);\r\n motion = entities[i].get(MotionComponent);\r\n\r\n const optionalBody = entities[i].get(BodyComponent);\r\n if (optionalBody?.sleeping) {\r\n continue;\r\n }\r\n\r\n const totalAcc = motion.acc.clone();\r\n if (optionalBody?.collisionType === CollisionType.Active && optionalBody?.useGravity) {\r\n totalAcc.addEqual(Physics.gravity);\r\n }\r\n optionalBody?.captureOldTransform();\r\n\r\n // Update transform and motion based on Euler linear algebra\r\n EulerIntegrator.integrate(transform, motion, totalAcc, elapsedMs);\r\n }\r\n }\r\n}\r\n","import { PostCollisionEvent, PreCollisionEvent } from '../../Events';\r\nimport { CollisionContact } from '../Detection/CollisionContact';\r\nimport { CollisionType } from '../CollisionType';\r\nimport { Side } from '../Side';\r\nimport { CollisionSolver } from './Solver';\r\nimport { BodyComponent } from '../BodyComponent';\r\n\r\n/**\r\n * ArcadeSolver is the default in Excalibur. It solves collisions so that there is no overlap between contacts,\r\n * and negates velocity along the collision normal.\r\n *\r\n * This is usually the type of collisions used for 2D games that don't need a more realistic collision simulation.\r\n *\r\n */\r\nexport class ArcadeSolver implements CollisionSolver {\r\n directionMap = new Map();\r\n distanceMap = new Map();\r\n\r\n public solve(contacts: CollisionContact[]): CollisionContact[] {\r\n // Events and init\r\n this.preSolve(contacts);\r\n\r\n // Remove any canceled contacts\r\n contacts = contacts.filter(c => !c.isCanceled());\r\n\r\n // Sort contacts by distance to avoid artifacts with seams\r\n // It's important to solve in a specific order\r\n contacts.sort((a, b) => {\r\n const aDist = this.distanceMap.get(a.id);\r\n const bDist = this.distanceMap.get(b.id);\r\n return aDist - bDist;\r\n });\r\n\r\n for (const contact of contacts) {\r\n // Solve position first in arcade\r\n this.solvePosition(contact);\r\n\r\n // Solve velocity second in arcade\r\n this.solveVelocity(contact);\r\n }\r\n\r\n // Events and any contact house-keeping the solver needs\r\n this.postSolve(contacts);\r\n\r\n return contacts;\r\n }\r\n\r\n public preSolve(contacts: CollisionContact[]) {\r\n const epsilon = .0001;\r\n for (const contact of contacts) {\r\n if (Math.abs(contact.mtv.x) < epsilon && Math.abs(contact.mtv.y) < epsilon) {\r\n // Cancel near 0 mtv collisions\r\n contact.cancel();\r\n continue;\r\n }\r\n const side = Side.fromDirection(contact.mtv);\r\n const mtv = contact.mtv.negate();\r\n\r\n const distance = contact.colliderA.worldPos.squareDistance(contact.colliderB.worldPos);\r\n this.distanceMap.set(contact.id, distance);\r\n\r\n // Publish collision events on both participants\r\n contact.colliderA.events.emit('precollision', new PreCollisionEvent(contact.colliderA, contact.colliderB, side, mtv));\r\n contact.colliderB.events.emit(\r\n 'precollision',\r\n new PreCollisionEvent(contact.colliderB, contact.colliderA, Side.getOpposite(side), mtv.negate())\r\n );\r\n }\r\n }\r\n\r\n public postSolve(contacts: CollisionContact[]) {\r\n for (const contact of contacts) {\r\n if (contact.isCanceled()) {\r\n continue;\r\n }\r\n const colliderA = contact.colliderA;\r\n const colliderB = contact.colliderB;\r\n const bodyA = colliderA.owner?.get(BodyComponent);\r\n const bodyB = colliderB.owner?.get(BodyComponent);\r\n if (bodyA && bodyB) {\r\n if (bodyA.collisionType === CollisionType.Passive || bodyB.collisionType === CollisionType.Passive) {\r\n continue;\r\n }\r\n }\r\n\r\n const side = Side.fromDirection(contact.mtv);\r\n const mtv = contact.mtv.negate();\r\n // Publish collision events on both participants\r\n contact.colliderA.events.emit('postcollision', new PostCollisionEvent(contact.colliderA, contact.colliderB, side, mtv));\r\n contact.colliderB.events.emit(\r\n 'postcollision',\r\n new PostCollisionEvent(contact.colliderB, contact.colliderA, Side.getOpposite(side), mtv.negate())\r\n );\r\n }\r\n }\r\n\r\n public solvePosition(contact: CollisionContact) {\r\n const epsilon = .0001;\r\n // if bounds no longer intersect skip to the next\r\n // this removes jitter from overlapping/stacked solid tiles or a wall of solid tiles\r\n if (!contact.colliderA.bounds.overlaps(contact.colliderB.bounds, epsilon)) {\r\n // Cancel the contact to prevent and solving\r\n contact.cancel();\r\n return;\r\n }\r\n\r\n if (Math.abs(contact.mtv.x) < epsilon && Math.abs(contact.mtv.y) < epsilon) {\r\n // Cancel near 0 mtv collisions\r\n contact.cancel();\r\n return;\r\n }\r\n\r\n let mtv = contact.mtv;\r\n const colliderA = contact.colliderA;\r\n const colliderB = contact.colliderB;\r\n const bodyA = colliderA.owner?.get(BodyComponent);\r\n const bodyB = colliderB.owner?.get(BodyComponent);\r\n if (bodyA && bodyB) {\r\n if (bodyA.collisionType === CollisionType.Passive || bodyB.collisionType === CollisionType.Passive) {\r\n return;\r\n }\r\n\r\n if (bodyA.collisionType === CollisionType.Active && bodyB.collisionType === CollisionType.Active) {\r\n // split overlaps if both are Active\r\n mtv = mtv.scale(0.5);\r\n }\r\n\r\n // Resolve overlaps\r\n if (bodyA.collisionType === CollisionType.Active) {\r\n bodyA.globalPos.x -= mtv.x;\r\n bodyA.globalPos.y -= mtv.y;\r\n colliderA.update(bodyA.transform.get());\r\n }\r\n\r\n if (bodyB.collisionType === CollisionType.Active) {\r\n bodyB.globalPos.x += mtv.x;\r\n bodyB.globalPos.y += mtv.y;\r\n colliderB.update(bodyB.transform.get());\r\n }\r\n }\r\n }\r\n\r\n\r\n public solveVelocity(contact: CollisionContact) {\r\n if (contact.isCanceled()) {\r\n return;\r\n }\r\n\r\n const colliderA = contact.colliderA;\r\n const colliderB = contact.colliderB;\r\n const bodyA = colliderA.owner?.get(BodyComponent);\r\n const bodyB = colliderB.owner?.get(BodyComponent);\r\n\r\n if (bodyA && bodyB) {\r\n\r\n if (bodyA.collisionType === CollisionType.Passive || bodyB.collisionType === CollisionType.Passive) {\r\n return;\r\n }\r\n\r\n const normal = contact.normal;\r\n const opposite = normal.negate();\r\n\r\n if (bodyA.collisionType === CollisionType.Active) {\r\n // only adjust velocity if the contact normal is opposite to the current velocity\r\n // this avoids catching edges on a platform when sliding off\r\n if (bodyA.vel.normalize().dot(opposite) < 0) {\r\n // Cancel out velocity opposite direction of collision normal\r\n const velAdj = normal.scale(normal.dot(bodyA.vel.negate()));\r\n bodyA.vel = bodyA.vel.add(velAdj);\r\n }\r\n }\r\n\r\n if (bodyB.collisionType === CollisionType.Active) {\r\n // only adjust velocity if the contact normal is opposite to the current velocity\r\n // this avoids catching edges on a platform\r\n if (bodyB.vel.normalize().dot(normal) < 0) {\r\n const velAdj = opposite.scale(opposite.dot(bodyB.vel.negate()));\r\n bodyB.vel = bodyB.vel.add(velAdj);\r\n }\r\n }\r\n }\r\n }\r\n}\r\n","import { Vector } from '../../Math/vector';\r\nimport { BodyComponent } from '../BodyComponent';\r\nimport { CollisionContact } from '../Detection/CollisionContact';\r\n\r\n/**\r\n * Holds information about contact points, meant to be reused over multiple frames of contact\r\n */\r\nexport class ContactConstraintPoint {\r\n constructor(public point: Vector, public local: Vector, public contact: CollisionContact) {\r\n this.update();\r\n }\r\n\r\n /**\r\n * Updates the contact information\r\n */\r\n update() {\r\n const bodyA = this.contact.colliderA.owner?.get(BodyComponent);\r\n const bodyB = this.contact.colliderB.owner?.get(BodyComponent);\r\n\r\n if (bodyA && bodyB) {\r\n const normal = this.contact.normal;\r\n const tangent = this.contact.tangent;\r\n\r\n this.aToContact = this.point.sub(bodyA.globalPos);\r\n this.bToContact = this.point.sub(bodyB.globalPos);\r\n\r\n const aToContactNormal = this.aToContact.cross(normal);\r\n const bToContactNormal = this.bToContact.cross(normal);\r\n\r\n this.normalMass =\r\n bodyA.inverseMass +\r\n bodyB.inverseMass +\r\n bodyA.inverseInertia * aToContactNormal * aToContactNormal +\r\n bodyB.inverseInertia * bToContactNormal * bToContactNormal;\r\n\r\n const aToContactTangent = this.aToContact.cross(tangent);\r\n const bToContactTangent = this.bToContact.cross(tangent);\r\n\r\n this.tangentMass =\r\n bodyA.inverseMass +\r\n bodyB.inverseMass +\r\n bodyA.inverseInertia * aToContactTangent * aToContactTangent +\r\n bodyB.inverseInertia * bToContactTangent * bToContactTangent;\r\n }\r\n\r\n return this;\r\n }\r\n\r\n /**\r\n * Returns the relative velocity between bodyA and bodyB\r\n */\r\n public getRelativeVelocity() {\r\n const bodyA = this.contact.colliderA.owner?.get(BodyComponent);\r\n const bodyB = this.contact.colliderB.owner?.get(BodyComponent);\r\n if (bodyA && bodyB) {\r\n // Relative velocity in linear terms\r\n // Angular to linear velocity formula -> omega = velocity/radius so omega x radius = velocity\r\n const velA = bodyA.vel.add(Vector.cross(bodyA.angularVelocity, this.aToContact));\r\n const velB = bodyB.vel.add(Vector.cross(bodyB.angularVelocity, this.bToContact));\r\n return velB.sub(velA);\r\n }\r\n return Vector.Zero;\r\n }\r\n\r\n /**\r\n * Impulse accumulated over time in normal direction\r\n */\r\n public normalImpulse: number = 0;\r\n\r\n /**\r\n * Impulse accumulated over time in the tangent direction\r\n */\r\n public tangentImpulse: number = 0;\r\n\r\n /**\r\n * Effective mass seen in the normal direction\r\n */\r\n public normalMass: number = 0;\r\n\r\n /**\r\n * Effective mass seen in the tangent direction\r\n */\r\n public tangentMass: number = 0;\r\n\r\n /**\r\n * Direction from center of mass of bodyA to contact point\r\n */\r\n public aToContact: Vector = new Vector(0, 0);\r\n\r\n /**\r\n * Direction from center of mass of bodyB to contact point\r\n */\r\n public bToContact: Vector = new Vector(0, 0);\r\n\r\n /**\r\n * Original contact velocity combined with bounciness\r\n */\r\n public originalVelocityAndRestitution: number = 0;\r\n}\r\n","import { CollisionPostSolveEvent, CollisionPreSolveEvent, PostCollisionEvent, PreCollisionEvent } from '../../Events';\r\nimport { clamp } from '../../Math/util';\r\nimport { CollisionContact } from '../Detection/CollisionContact';\r\nimport { CollisionType } from '../CollisionType';\r\nimport { ContactConstraintPoint } from './ContactConstraintPoint';\r\nimport { Side } from '../Side';\r\nimport { Physics } from '../Physics';\r\nimport { CollisionSolver } from './Solver';\r\nimport { BodyComponent, DegreeOfFreedom } from '../BodyComponent';\r\nimport { CollisionJumpTable } from '../Colliders/CollisionJumpTable';\r\n\r\nexport class RealisticSolver implements CollisionSolver {\r\n lastFrameContacts: Map = new Map();\r\n\r\n // map contact id to contact points\r\n idToContactConstraint: Map = new Map();\r\n\r\n getContactConstraints(id: string) {\r\n return this.idToContactConstraint.get(id) ?? [];\r\n }\r\n\r\n public solve(contacts: CollisionContact[]): CollisionContact[] {\r\n // Events and init\r\n this.preSolve(contacts);\r\n\r\n // Remove any canceled contacts\r\n contacts = contacts.filter(c => !c.isCanceled());\r\n\r\n // Solve velocity first\r\n this.solveVelocity(contacts);\r\n\r\n // Solve position last because non-overlap is the most important\r\n this.solvePosition(contacts);\r\n\r\n // Events and any contact house-keeping the solver needs\r\n this.postSolve(contacts);\r\n\r\n return contacts;\r\n }\r\n\r\n preSolve(contacts: CollisionContact[]) {\r\n const epsilon = .0001;\r\n for (const contact of contacts) {\r\n if (Math.abs(contact.mtv.x) < epsilon && Math.abs(contact.mtv.y) < epsilon) {\r\n // Cancel near 0 mtv collisions\r\n contact.cancel();\r\n continue;\r\n }\r\n // Publish collision events on both participants\r\n const side = Side.fromDirection(contact.mtv);\r\n contact.colliderA.events.emit('precollision', new PreCollisionEvent(contact.colliderA, contact.colliderB, side, contact.mtv));\r\n contact.colliderA.events.emit(\r\n 'beforecollisionresolve',\r\n new CollisionPreSolveEvent(contact.colliderA, contact.colliderB, side, contact.mtv, contact) as any\r\n );\r\n contact.colliderB.events.emit(\r\n 'precollision',\r\n new PreCollisionEvent(contact.colliderB, contact.colliderA, Side.getOpposite(side), contact.mtv.negate())\r\n );\r\n contact.colliderB.events.emit(\r\n 'beforecollisionresolve',\r\n new CollisionPreSolveEvent(contact.colliderB, contact.colliderA, Side.getOpposite(side), contact.mtv.negate(), contact) as any\r\n );\r\n\r\n // Match awake state for sleeping\r\n contact.matchAwake();\r\n }\r\n\r\n // Keep track of contacts that done\r\n const finishedContactIds = Array.from(this.idToContactConstraint.keys());\r\n for (const contact of contacts) {\r\n // Remove all current contacts that are not done\r\n const index = finishedContactIds.indexOf(contact.id);\r\n if (index > -1) {\r\n finishedContactIds.splice(index, 1);\r\n }\r\n const contactPoints = this.idToContactConstraint.get(contact.id) ?? [];\r\n\r\n let pointIndex = 0;\r\n const bodyA = contact.colliderA.owner.get(BodyComponent);\r\n const bodyB = contact.colliderB.owner.get(BodyComponent);\r\n if (bodyA && bodyB) {\r\n for (const point of contact.points) {\r\n const normal = contact.normal;\r\n const tangent = contact.tangent;\r\n\r\n const aToContact = point.sub(bodyA.globalPos);\r\n const bToContact = point.sub(bodyB.globalPos);\r\n\r\n const aToContactNormal = aToContact.cross(normal);\r\n const bToContactNormal = bToContact.cross(normal);\r\n\r\n const normalMass =\r\n bodyA.inverseMass +\r\n bodyB.inverseMass +\r\n bodyA.inverseInertia * aToContactNormal * aToContactNormal +\r\n bodyB.inverseInertia * bToContactNormal * bToContactNormal;\r\n\r\n const aToContactTangent = aToContact.cross(tangent);\r\n const bToContactTangent = bToContact.cross(tangent);\r\n\r\n const tangentMass =\r\n bodyA.inverseMass +\r\n bodyB.inverseMass +\r\n bodyA.inverseInertia * aToContactTangent * aToContactTangent +\r\n bodyB.inverseInertia * bToContactTangent * bToContactTangent;\r\n\r\n // Preserve normal/tangent impulse by re-using the contact point if it's close\r\n if (contactPoints[pointIndex] && contactPoints[pointIndex]?.point?.squareDistance(point) < 4) {\r\n contactPoints[pointIndex].point = point;\r\n contactPoints[pointIndex].local = contact.localPoints[pointIndex];\r\n } else {\r\n // new contact if it's not close or doesn't exist\r\n contactPoints[pointIndex] = new ContactConstraintPoint(point, contact.localPoints[pointIndex], contact);\r\n }\r\n\r\n // Update contact point calculations\r\n contactPoints[pointIndex].aToContact = aToContact;\r\n contactPoints[pointIndex].bToContact = bToContact;\r\n contactPoints[pointIndex].normalMass = 1.0 / normalMass;\r\n contactPoints[pointIndex].tangentMass = 1.0 / tangentMass;\r\n\r\n // Calculate relative velocity before solving to accurately do restitution\r\n const restitution = bodyA.bounciness > bodyB.bounciness ? bodyA.bounciness : bodyB.bounciness;\r\n const relativeVelocity = contact.normal.dot(contactPoints[pointIndex].getRelativeVelocity());\r\n contactPoints[pointIndex].originalVelocityAndRestitution = 0;\r\n if (relativeVelocity < -0.1) { // TODO what's a good threshold here?\r\n contactPoints[pointIndex].originalVelocityAndRestitution = -restitution * relativeVelocity;\r\n }\r\n pointIndex++;\r\n }\r\n }\r\n this.idToContactConstraint.set(contact.id, contactPoints);\r\n }\r\n\r\n // Clean up any contacts that did not occur last frame\r\n for (const id of finishedContactIds) {\r\n this.idToContactConstraint.delete(id);\r\n }\r\n\r\n // Warm contacts with accumulated impulse\r\n // Useful for tall stacks\r\n if (Physics.warmStart) {\r\n this.warmStart(contacts);\r\n } else {\r\n for (const contact of contacts) {\r\n const contactPoints = this.getContactConstraints(contact.id);\r\n for (const point of contactPoints) {\r\n point.normalImpulse = 0;\r\n point.tangentImpulse = 0;\r\n }\r\n }\r\n }\r\n }\r\n\r\n postSolve(contacts: CollisionContact[]) {\r\n for (const contact of contacts) {\r\n const bodyA = contact.colliderA.owner.get(BodyComponent);\r\n const bodyB = contact.colliderB.owner.get(BodyComponent);\r\n\r\n if (bodyA && bodyB) {\r\n // Skip post solve for active+passive collisions\r\n if (bodyA.collisionType === CollisionType.Passive || bodyB.collisionType === CollisionType.Passive) {\r\n continue;\r\n }\r\n\r\n // Update motion values for sleeping\r\n bodyA.updateMotion();\r\n bodyB.updateMotion();\r\n }\r\n\r\n // Publish collision events on both participants\r\n const side = Side.fromDirection(contact.mtv);\r\n contact.colliderA.events.emit('postcollision', new PostCollisionEvent(contact.colliderA, contact.colliderB, side, contact.mtv));\r\n contact.colliderA.events.emit(\r\n 'aftercollisionresolve',\r\n new CollisionPostSolveEvent(contact.colliderA, contact.colliderB, side, contact.mtv, contact) as any\r\n );\r\n contact.colliderB.events.emit(\r\n 'postcollision',\r\n new PostCollisionEvent(contact.colliderB, contact.colliderA, Side.getOpposite(side), contact.mtv.negate())\r\n );\r\n contact.colliderB.events.emit(\r\n 'aftercollisionresolve',\r\n new CollisionPostSolveEvent(contact.colliderB, contact.colliderA, Side.getOpposite(side), contact.mtv.negate(), contact) as any\r\n );\r\n }\r\n\r\n // Store contacts\r\n this.lastFrameContacts.clear();\r\n for (const c of contacts) {\r\n this.lastFrameContacts.set(c.id, c);\r\n }\r\n }\r\n\r\n /**\r\n * Warm up body's based on previous frame contact points\r\n * @param contacts\r\n */\r\n warmStart(contacts: CollisionContact[]) {\r\n for (const contact of contacts) {\r\n const bodyA = contact.colliderA.owner?.get(BodyComponent);\r\n const bodyB = contact.colliderB.owner?.get(BodyComponent);\r\n if (bodyA && bodyB) {\r\n const contactPoints = this.idToContactConstraint.get(contact.id) ?? [];\r\n for (const point of contactPoints) {\r\n if (Physics.warmStart) {\r\n const normalImpulse = contact.normal.scale(point.normalImpulse);\r\n const tangentImpulse = contact.tangent.scale(point.tangentImpulse);\r\n const impulse = normalImpulse.add(tangentImpulse);\r\n\r\n bodyA.applyImpulse(point.point, impulse.negate());\r\n bodyB.applyImpulse(point.point, impulse);\r\n } else {\r\n point.normalImpulse = 0;\r\n point.tangentImpulse = 0;\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Iteratively solve the position overlap constraint\r\n * @param contacts\r\n */\r\n solvePosition(contacts: CollisionContact[]) {\r\n for (let i = 0; i < Physics.positionIterations; i++) {\r\n for (const contact of contacts) {\r\n const bodyA = contact.colliderA.owner?.get(BodyComponent);\r\n const bodyB = contact.colliderB.owner?.get(BodyComponent);\r\n\r\n if (bodyA && bodyB) {\r\n // Skip solving active+passive\r\n if (bodyA.collisionType === CollisionType.Passive || bodyB.collisionType === CollisionType.Passive) {\r\n continue;\r\n }\r\n\r\n const constraints = this.idToContactConstraint.get(contact.id) ?? [];\r\n for (const point of constraints) {\r\n const normal = contact.normal;\r\n const separation = CollisionJumpTable.FindContactSeparation(contact, point.local);\r\n\r\n const steeringConstant = Physics.steeringFactor; //0.2;\r\n const maxCorrection = -5;\r\n const slop = Physics.slop; //1;\r\n\r\n // Clamp to avoid over-correction\r\n // Remember that we are shooting for 0 overlap in the end\r\n const steeringForce = clamp(steeringConstant * (separation + slop), maxCorrection, 0);\r\n const impulse = normal.scale(-steeringForce * point.normalMass);\r\n\r\n // This is a pseudo impulse, meaning we aren't doing a real impulse calculation\r\n // We adjust position and rotation instead of doing the velocity\r\n if (bodyA.collisionType === CollisionType.Active) {\r\n // TODO make applyPseudoImpulse function?\r\n const impulseForce = impulse.negate().scale(bodyA.inverseMass);\r\n if (bodyA.limitDegreeOfFreedom.includes(DegreeOfFreedom.X)) {\r\n impulseForce.x = 0;\r\n }\r\n if (bodyA.limitDegreeOfFreedom.includes(DegreeOfFreedom.Y)) {\r\n impulseForce.y = 0;\r\n }\r\n\r\n bodyA.globalPos = bodyA.globalPos.add(impulseForce);\r\n if (!bodyA.limitDegreeOfFreedom.includes(DegreeOfFreedom.Rotation)) {\r\n bodyA.rotation -= point.aToContact.cross(impulse) * bodyA.inverseInertia;\r\n }\r\n }\r\n\r\n if (bodyB.collisionType === CollisionType.Active) {\r\n const impulseForce = impulse.scale(bodyB.inverseMass);\r\n if (bodyB.limitDegreeOfFreedom.includes(DegreeOfFreedom.X)) {\r\n impulseForce.x = 0;\r\n }\r\n if (bodyB.limitDegreeOfFreedom.includes(DegreeOfFreedom.Y)) {\r\n impulseForce.y = 0;\r\n }\r\n\r\n bodyB.globalPos = bodyB.globalPos.add(impulseForce);\r\n if (!bodyB.limitDegreeOfFreedom.includes(DegreeOfFreedom.Rotation)) {\r\n bodyB.rotation += point.bToContact.cross(impulse) * bodyB.inverseInertia;\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n solveVelocity(contacts: CollisionContact[]) {\r\n for (let i = 0; i < Physics.velocityIterations; i++) {\r\n for (const contact of contacts) {\r\n const bodyA = contact.colliderA.owner?.get(BodyComponent);\r\n const bodyB = contact.colliderB.owner?.get(BodyComponent);\r\n\r\n if (bodyA && bodyB) {\r\n // Skip solving active+passive\r\n if (bodyA.collisionType === CollisionType.Passive || bodyB.collisionType === CollisionType.Passive) {\r\n continue;\r\n }\r\n\r\n const friction = Math.min(bodyA.friction, bodyB.friction);\r\n\r\n const constraints = this.idToContactConstraint.get(contact.id) ?? [];\r\n\r\n // Friction constraint\r\n for (const point of constraints) {\r\n const relativeVelocity = point.getRelativeVelocity();\r\n\r\n // Negate velocity in tangent direction to simulate friction\r\n const tangentVelocity = -relativeVelocity.dot(contact.tangent);\r\n let impulseDelta = tangentVelocity * point.tangentMass;\r\n\r\n // Clamping based in Erin Catto's GDC 2006 talk\r\n // Correct clamping https://github.com/erincatto/box2d-lite/blob/master/docs/GDC2006_Catto_Erin_PhysicsTutorial.pdf\r\n // Accumulated fiction impulse is always between -uMaxFriction < dT < uMaxFriction\r\n // But deltas can vary\r\n const maxFriction = friction * point.normalImpulse;\r\n const newImpulse = clamp(point.tangentImpulse + impulseDelta, -maxFriction, maxFriction);\r\n impulseDelta = newImpulse - point.tangentImpulse;\r\n point.tangentImpulse = newImpulse;\r\n\r\n const impulse = contact.tangent.scale(impulseDelta);\r\n bodyA.applyImpulse(point.point, impulse.negate());\r\n bodyB.applyImpulse(point.point, impulse);\r\n }\r\n\r\n // Bounce constraint\r\n for (const point of constraints) {\r\n // Need to recalc relative velocity because the previous step could have changed vel\r\n const relativeVelocity = point.getRelativeVelocity();\r\n\r\n // Compute impulse in normal direction\r\n const normalVelocity = relativeVelocity.dot(contact.normal);\r\n\r\n // Per Erin it is a mistake to apply the restitution inside the iteration\r\n // From Erin Catto's Box2D we keep original contact velocity and adjust by small impulses\r\n let impulseDelta = -point.normalMass * (normalVelocity - point.originalVelocityAndRestitution);\r\n\r\n // Clamping based in Erin Catto's GDC 2014 talk\r\n // Accumulated impulse stored in the contact is always positive (dV > 0)\r\n // But deltas can be negative\r\n const newImpulse = Math.max(point.normalImpulse + impulseDelta, 0);\r\n impulseDelta = newImpulse - point.normalImpulse;\r\n point.normalImpulse = newImpulse;\r\n\r\n const impulse = contact.normal.scale(impulseDelta);\r\n bodyA.applyImpulse(point.point, impulse.negate());\r\n bodyB.applyImpulse(point.point, impulse);\r\n }\r\n }\r\n }\r\n }\r\n }\r\n}\r\n","import { Entity } from '../EntityComponentSystem';\r\nimport { MotionComponent } from '../EntityComponentSystem/Components/MotionComponent';\r\nimport { TransformComponent } from '../EntityComponentSystem/Components/TransformComponent';\r\nimport { AddedEntity, isAddedSystemEntity, RemovedEntity, System, SystemType } from '../EntityComponentSystem/System';\r\nimport { CollisionEndEvent, CollisionStartEvent, ContactEndEvent, ContactStartEvent } from '../Events';\r\nimport { CollisionResolutionStrategy, Physics } from './Physics';\r\nimport { ArcadeSolver } from './Solver/ArcadeSolver';\r\nimport { Collider } from './Colliders/Collider';\r\nimport { CollisionContact } from './Detection/CollisionContact';\r\nimport { RealisticSolver } from './Solver/RealisticSolver';\r\nimport { CollisionSolver } from './Solver/Solver';\r\nimport { ColliderComponent } from './ColliderComponent';\r\nimport { CompositeCollider } from './Colliders/CompositeCollider';\r\nimport { Engine, ExcaliburGraphicsContext, Scene } from '..';\r\nimport { DynamicTreeCollisionProcessor } from './Detection/DynamicTreeCollisionProcessor';\r\nimport { PhysicsWorld } from './PhysicsWorld';\r\nexport class CollisionSystem extends System {\r\n public readonly types = ['ex.transform', 'ex.motion', 'ex.collider'] as const;\r\n public systemType = SystemType.Update;\r\n public priority = -1;\r\n\r\n private _engine: Engine;\r\n private _realisticSolver = new RealisticSolver();\r\n private _arcadeSolver = new ArcadeSolver();\r\n private _lastFrameContacts = new Map();\r\n private _currentFrameContacts = new Map();\r\n private _processor: DynamicTreeCollisionProcessor;\r\n\r\n private _trackCollider: (c: Collider) => void;\r\n private _untrackCollider: (c: Collider) => void;\r\n\r\n constructor(physics: PhysicsWorld) {\r\n super();\r\n this._processor = physics.collisionProcessor;\r\n this._trackCollider = (c: Collider) => this._processor.track(c);\r\n this._untrackCollider = (c: Collider) => this._processor.untrack(c);\r\n }\r\n\r\n notify(message: AddedEntity | RemovedEntity) {\r\n if (isAddedSystemEntity(message)) {\r\n const colliderComponent = message.data.get(ColliderComponent);\r\n colliderComponent.$colliderAdded.subscribe(this._trackCollider);\r\n colliderComponent.$colliderRemoved.subscribe(this._untrackCollider);\r\n const collider = colliderComponent.get();\r\n if (collider) {\r\n this._processor.track(collider);\r\n }\r\n } else {\r\n const colliderComponent = message.data.get(ColliderComponent);\r\n const collider = colliderComponent.get();\r\n if (colliderComponent && collider) {\r\n this._processor.untrack(collider);\r\n }\r\n }\r\n }\r\n\r\n initialize(scene: Scene) {\r\n this._engine = scene.engine;\r\n\r\n }\r\n\r\n update(entities: Entity[], elapsedMs: number): void {\r\n if (!Physics.enabled) {\r\n return;\r\n }\r\n\r\n // Collect up all the colliders and update them\r\n let colliders: Collider[] = [];\r\n for (const entity of entities) {\r\n const colliderComp = entity.get(ColliderComponent);\r\n const collider = colliderComp?.get();\r\n if (colliderComp && colliderComp.owner?.active && collider) {\r\n colliderComp.update();\r\n if (collider instanceof CompositeCollider) {\r\n const compositeColliders = collider.getColliders();\r\n colliders = colliders.concat(compositeColliders);\r\n } else {\r\n colliders.push(collider);\r\n }\r\n }\r\n }\r\n\r\n // Update the spatial partitioning data structures\r\n // TODO if collider invalid it will break the processor\r\n // TODO rename \"update\" to something more specific\r\n this._processor.update(colliders);\r\n\r\n // Run broadphase on all colliders and locates potential collisions\r\n const pairs = this._processor.broadphase(colliders, elapsedMs);\r\n\r\n this._currentFrameContacts.clear();\r\n\r\n // Given possible pairs find actual contacts\r\n let contacts = this._processor.narrowphase(pairs, this._engine?.debug?.stats?.currFrame);\r\n\r\n const solver: CollisionSolver = this.getSolver();\r\n\r\n // Solve, this resolves the position/velocity so entities aren't overlapping\r\n contacts = solver.solve(contacts);\r\n\r\n // Record contacts for start/end\r\n for (const contact of contacts) {\r\n // Process composite ids, things with the same composite id are treated as the same collider for start/end\r\n const index = contact.id.indexOf('|');\r\n if (index > 0) {\r\n const compositeId = contact.id.substring(index + 1);\r\n this._currentFrameContacts.set(compositeId, contact);\r\n } else {\r\n this._currentFrameContacts.set(contact.id, contact);\r\n }\r\n }\r\n\r\n // Emit contact start/end events\r\n this.runContactStartEnd();\r\n\r\n // reset the last frame cache\r\n this._lastFrameContacts.clear();\r\n\r\n // Keep track of collisions contacts that have started or ended\r\n this._lastFrameContacts = new Map(this._currentFrameContacts);\r\n }\r\n\r\n getSolver(): CollisionSolver {\r\n return Physics.collisionResolutionStrategy === CollisionResolutionStrategy.Realistic ? this._realisticSolver : this._arcadeSolver;\r\n }\r\n\r\n debug(ex: ExcaliburGraphicsContext) {\r\n this._processor.debug(ex);\r\n }\r\n\r\n public runContactStartEnd() {\r\n // Composite collider collisions may have a duplicate id because we want to treat those as a singular start/end\r\n for (const [id, c] of this._currentFrameContacts) {\r\n // find all new contacts\r\n if (!this._lastFrameContacts.has(id)) {\r\n const colliderA = c.colliderA;\r\n const colliderB = c.colliderB;\r\n colliderA.events.emit('collisionstart', new CollisionStartEvent(colliderA, colliderB, c));\r\n colliderA.events.emit('contactstart', new ContactStartEvent(colliderA, colliderB, c) as any);\r\n colliderB.events.emit('collisionstart', new CollisionStartEvent(colliderB, colliderA, c));\r\n colliderB.events.emit('contactstart', new ContactStartEvent(colliderB, colliderA, c) as any);\r\n }\r\n }\r\n\r\n // find all contacts that have ceased\r\n for (const [id, c] of this._lastFrameContacts) {\r\n if (!this._currentFrameContacts.has(id)) {\r\n const colliderA = c.colliderA;\r\n const colliderB = c.colliderB;\r\n colliderA.events.emit('collisionend', new CollisionEndEvent(colliderA, colliderB));\r\n colliderA.events.emit('contactend', new ContactEndEvent(colliderA, colliderB) as any);\r\n colliderB.events.emit('collisionend', new CollisionEndEvent(colliderB, colliderA));\r\n colliderB.events.emit('contactend', new ContactEndEvent(colliderB, colliderA) as any);\r\n }\r\n }\r\n }\r\n}\r\n","import { Graphic, GraphicOptions } from './Graphic';\r\nimport { ExcaliburGraphicsContext } from './Context/ExcaliburGraphicsContext';\r\nimport { SpriteSheet } from './SpriteSheet';\r\nimport { Logger } from '../Util/Log';\r\nimport { clamp } from '../Math/util';\r\nimport { EventEmitter } from '../EventEmitter';\r\n\r\nexport interface HasTick {\r\n /**\r\n *\r\n * @param elapsedMilliseconds The amount of real world time in milliseconds that has elapsed that must be updated in the animation\r\n * @param idempotencyToken Optional idempotencyToken prevents a ticking animation from updating twice per frame\r\n */\r\n tick(elapsedMilliseconds: number, idempotencyToken?: number): void;\r\n}\r\n\r\nexport enum AnimationDirection {\r\n /**\r\n * Animation is playing forwards\r\n */\r\n Forward = 'forward',\r\n /**\r\n * Animation is playing backwards\r\n */\r\n Backward = 'backward'\r\n}\r\n\r\nexport enum AnimationStrategy {\r\n /**\r\n * Animation ends without displaying anything\r\n */\r\n End = 'end',\r\n /**\r\n * Animation loops to the first frame after the last frame\r\n */\r\n Loop = 'loop',\r\n /**\r\n * Animation plays to the last frame, then backwards to the first frame, then repeats\r\n */\r\n PingPong = 'pingpong',\r\n /**\r\n * Animation ends stopping on the last frame\r\n */\r\n Freeze = 'freeze'\r\n}\r\n\r\n/**\r\n * Frame of animation\r\n */\r\nexport interface Frame {\r\n /**\r\n * Optionally specify a graphic to show, no graphic shows an empty frame\r\n */\r\n graphic?: Graphic;\r\n /**\r\n * Optionally specify the number of ms the frame should be visible, overrides the animation duration (default 100 ms)\r\n */\r\n duration?: number;\r\n}\r\n\r\nexport interface FrameEvent extends Frame {\r\n frameIndex: number;\r\n}\r\n\r\n/**\r\n * Animation options for building an animation via constructor.\r\n */\r\nexport interface AnimationOptions {\r\n /**\r\n * List of frames in the order you wish to play them\r\n */\r\n frames: Frame[];\r\n /**\r\n * Optionally reverse the direction of play\r\n */\r\n reverse?: boolean;\r\n /**\r\n * Optionally specify a default frame duration in ms (Default is 1000)\r\n */\r\n frameDuration?: number;\r\n /**\r\n * Optionally specify a total duration of the animation in ms to calculate each frame's duration\r\n */\r\n totalDuration?: number;\r\n /**\r\n * Optionally specify the [[AnimationStrategy]] for the Animation\r\n */\r\n strategy?: AnimationStrategy;\r\n}\r\n\r\nexport type AnimationEvents = {\r\n frame: FrameEvent;\r\n loop: Animation;\r\n ended: Animation;\r\n};\r\n\r\nexport const AnimationEvents = {\r\n Frame: 'frame',\r\n Loop: 'loop',\r\n Ended: 'ended'\r\n};\r\n\r\nexport interface FromSpriteSheetOptions {\r\n /**\r\n * [[SpriteSheet]] to source the animation frames from\r\n */\r\n spriteSheet: SpriteSheet;\r\n /**\r\n * The list of (x, y) positions of sprites in the [[SpriteSheet]] of each frame, for example (0, 0)\r\n * is the the top left sprite, (0, 1) is the sprite directly below that, and so on.\r\n *\r\n * You may optionally specify a duration for the frame in milliseconds as well, this will override\r\n * the default duration.\r\n */\r\n frameCoordinates: {x: number, y: number, duration?: number}[];\r\n /**\r\n * Optionally specify a default duration for frames in milliseconds\r\n */\r\n durationPerFrameMs?: number;\r\n /**\r\n * Optionally specify the animation strategy for this animation, by default animations loop [[AnimationStrategy.Loop]]\r\n */\r\n strategy?: AnimationStrategy\r\n /**\r\n * Optionally specify the animation should be reversed\r\n */\r\n reverse?: boolean;\r\n}\r\n\r\n/**\r\n * Create an Animation given a list of [[Frame|frames]] in [[AnimationOptions]]\r\n *\r\n * To create an Animation from a [[SpriteSheet]], use [[Animation.fromSpriteSheet]]\r\n */\r\nexport class Animation extends Graphic implements HasTick {\r\n private static _LOGGER = Logger.getInstance();\r\n public events = new EventEmitter();\r\n public frames: Frame[] = [];\r\n public strategy: AnimationStrategy = AnimationStrategy.Loop;\r\n public frameDuration: number = 100;\r\n public timeScale: number = 1;\r\n\r\n private _idempotencyToken = -1;\r\n\r\n private _firstTick = true;\r\n private _currentFrame = 0;\r\n private _timeLeftInFrame = 0;\r\n private _pingPongDirection = 1;\r\n private _done = false;\r\n private _playing = true;\r\n\r\n constructor(options: GraphicOptions & AnimationOptions) {\r\n super(options);\r\n this.frames = options.frames;\r\n this.strategy = options.strategy ?? this.strategy;\r\n this.frameDuration = options.totalDuration ? options.totalDuration / this.frames.length : options.frameDuration ?? this.frameDuration;\r\n if (options.reverse) {\r\n this.reverse();\r\n }\r\n this.goToFrame(0);\r\n }\r\n\r\n public clone(): Animation {\r\n return new Animation({\r\n frames: this.frames.map((f) => ({ ...f })),\r\n frameDuration: this.frameDuration,\r\n reverse: this._reversed,\r\n strategy: this.strategy,\r\n ...this.cloneGraphicOptions()\r\n });\r\n }\r\n\r\n public override get width(): number {\r\n const maybeFrame = this.currentFrame;\r\n if (maybeFrame) {\r\n return Math.abs(maybeFrame.graphic.width * this.scale.x);\r\n }\r\n return 0;\r\n }\r\n\r\n public override get height(): number {\r\n const maybeFrame = this.currentFrame;\r\n if (maybeFrame) {\r\n return Math.abs(maybeFrame.graphic.height * this.scale.y);\r\n }\r\n return 0;\r\n }\r\n\r\n\r\n /**\r\n * Create an Animation from a [[SpriteSheet]], a list of indices into the sprite sheet, a duration per frame\r\n * and optional [[AnimationStrategy]]\r\n *\r\n * Example:\r\n * ```typescript\r\n * const spriteSheet = SpriteSheet.fromImageSource({...});\r\n *\r\n * const anim = Animation.fromSpriteSheet(spriteSheet, range(0, 5), 200, AnimationStrategy.Loop);\r\n * ```\r\n *\r\n * @param spriteSheet\r\n * @param frameIndices\r\n * @param durationPerFrameMs\r\n * @param strategy\r\n */\r\n public static fromSpriteSheet(\r\n spriteSheet: SpriteSheet,\r\n frameIndices: number[],\r\n durationPerFrameMs: number,\r\n strategy: AnimationStrategy = AnimationStrategy.Loop\r\n ): Animation {\r\n const maxIndex = spriteSheet.sprites.length - 1;\r\n const invalidIndices = frameIndices.filter((index) => index < 0 || index > maxIndex);\r\n if (invalidIndices.length) {\r\n Animation._LOGGER.warn(\r\n `Indices into SpriteSheet were provided that don\\'t exist: ${invalidIndices.join(',')} no frame will be shown`\r\n );\r\n }\r\n return new Animation({\r\n frames: spriteSheet.sprites\r\n .filter((_, index) => frameIndices.indexOf(index) > -1)\r\n .map((f) => ({\r\n graphic: f,\r\n duration: durationPerFrameMs\r\n })),\r\n strategy: strategy\r\n });\r\n }\r\n\r\n /**\r\n * Create an [[Animation]] from a [[SpriteSheet]] given a list of coordinates\r\n *\r\n * Example:\r\n * ```typescript\r\n * const spriteSheet = SpriteSheet.fromImageSource({...});\r\n *\r\n * const anim = Animation.fromSpriteSheetCoordinates({\r\n * spriteSheet,\r\n * frameCoordinates: [\r\n * {x: 0, y: 5, duration: 100},\r\n * {x: 1, y: 5, duration: 200},\r\n * {x: 2, y: 5, duration: 100},\r\n * {x: 3, y: 5, duration: 500}\r\n * ],\r\n * strategy: AnimationStrategy.PingPong\r\n * });\r\n * ```\r\n *\r\n * @param options\r\n * @returns Animation\r\n */\r\n public static fromSpriteSheetCoordinates(options: FromSpriteSheetOptions): Animation {\r\n const { spriteSheet, frameCoordinates, durationPerFrameMs, strategy, reverse } = options;\r\n const defaultDuration = durationPerFrameMs ?? 100;\r\n const frames: Frame[] = [];\r\n for (const coord of frameCoordinates) {\r\n const {x, y, duration} = coord;\r\n const sprite = spriteSheet.getSprite(x, y);\r\n if (sprite) {\r\n frames.push({\r\n graphic: sprite,\r\n duration: duration ?? defaultDuration\r\n });\r\n } else {\r\n Animation._LOGGER.warn(\r\n `Skipping frame! SpriteSheet does not have coordinate (${x}, ${y}), please check your SpriteSheet to confirm that sprite exists`\r\n );\r\n }\r\n }\r\n\r\n return new Animation({\r\n frames,\r\n strategy,\r\n reverse\r\n });\r\n }\r\n\r\n /**\r\n * Returns the current Frame of the animation\r\n *\r\n * Use [[Animation.currentFrameIndex]] to get the frame number and\r\n * [[Animation.goToFrame]] to set the current frame index\r\n */\r\n public get currentFrame(): Frame | null {\r\n if (this._currentFrame >= 0 && this._currentFrame < this.frames.length) {\r\n return this.frames[this._currentFrame];\r\n }\r\n return null;\r\n }\r\n\r\n /**\r\n * Returns the current frame index of the animation\r\n *\r\n * Use [[Animation.currentFrame]] to grab the current [[Frame]] object\r\n */\r\n public get currentFrameIndex(): number {\r\n return this._currentFrame;\r\n }\r\n\r\n /**\r\n * Returns `true` if the animation is playing\r\n */\r\n public get isPlaying(): boolean {\r\n return this._playing;\r\n }\r\n\r\n private _reversed = false;\r\n /**\r\n * Reverses the play direction of the Animation, this preserves the current frame\r\n */\r\n public reverse(): void {\r\n // Don't mutate with the original frame list, create a copy\r\n this.frames = this.frames.slice().reverse();\r\n this._reversed = !this._reversed;\r\n }\r\n\r\n /**\r\n * Returns the current play direction of the animation\r\n */\r\n public get direction(): AnimationDirection {\r\n // Keep logically consistent with ping-pong direction\r\n // If ping-pong is forward = 1 and reversed is true then we are logically reversed\r\n const reversed = (this._reversed && this._pingPongDirection === 1) ? true : false;\r\n return reversed ? AnimationDirection.Backward : AnimationDirection.Forward;\r\n }\r\n\r\n /**\r\n * Plays or resumes the animation from the current frame\r\n */\r\n public play(): void {\r\n this._playing = true;\r\n }\r\n\r\n /**\r\n * Pauses the animation on the current frame\r\n */\r\n public pause(): void {\r\n this._playing = false;\r\n this._firstTick = true; // firstTick must be set to emit the proper frame event\r\n }\r\n\r\n /**\r\n * Reset the animation back to the beginning, including if the animation were done\r\n */\r\n public reset(): void {\r\n this._done = false;\r\n this._firstTick = true;\r\n this._currentFrame = 0;\r\n }\r\n\r\n /**\r\n * Returns `true` if the animation can end\r\n */\r\n public get canFinish(): boolean {\r\n switch (this.strategy) {\r\n case AnimationStrategy.End:\r\n case AnimationStrategy.Freeze: {\r\n return true;\r\n }\r\n default: {\r\n return false;\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Returns `true` if the animation is done, for looping type animations\r\n * `ex.AnimationStrategy.PingPong` and `ex.AnimationStrategy.Loop` this will always return `false`\r\n *\r\n * See the `ex.Animation.canFinish()` method to know if an animation type can end\r\n */\r\n public get done(): boolean {\r\n return this._done;\r\n }\r\n\r\n /**\r\n * Jump the animation immediately to a specific frame if it exists\r\n * @param frameNumber\r\n */\r\n public goToFrame(frameNumber: number) {\r\n this._currentFrame = frameNumber;\r\n this._timeLeftInFrame = this.frameDuration;\r\n const maybeFrame = this.frames[this._currentFrame];\r\n if (maybeFrame && !this._done) {\r\n this._timeLeftInFrame = maybeFrame?.duration || this.frameDuration;\r\n this.events.emit('frame', {...maybeFrame, frameIndex: this.currentFrameIndex });\r\n }\r\n }\r\n\r\n private _nextFrame(): number {\r\n const currentFrame = this._currentFrame;\r\n if (this._done) {\r\n return currentFrame;\r\n }\r\n let next = -1;\r\n\r\n switch (this.strategy) {\r\n case AnimationStrategy.Loop: {\r\n next = (currentFrame + 1) % this.frames.length;\r\n if (next === 0) {\r\n this.events.emit('loop', this);\r\n }\r\n break;\r\n }\r\n case AnimationStrategy.End: {\r\n next = currentFrame + 1;\r\n if (next >= this.frames.length) {\r\n this._done = true;\r\n this._currentFrame = this.frames.length;\r\n this.events.emit('end', this);\r\n }\r\n break;\r\n }\r\n case AnimationStrategy.Freeze: {\r\n next = clamp(currentFrame + 1, 0, this.frames.length - 1);\r\n if (next >= this.frames.length - 1) {\r\n this._done = true;\r\n this.events.emit('end', this);\r\n }\r\n break;\r\n }\r\n case AnimationStrategy.PingPong: {\r\n if (currentFrame + this._pingPongDirection >= this.frames.length) {\r\n this._pingPongDirection = -1;\r\n this.events.emit('loop', this);\r\n }\r\n\r\n if (currentFrame + this._pingPongDirection < 0) {\r\n this._pingPongDirection = 1;\r\n this.events.emit('loop', this);\r\n }\r\n\r\n next = currentFrame + (this._pingPongDirection % this.frames.length);\r\n break;\r\n }\r\n }\r\n return next;\r\n }\r\n\r\n /**\r\n * Called internally by Excalibur to update the state of the animation potential update the current frame\r\n * @param elapsedMilliseconds Milliseconds elapsed\r\n * @param idempotencyToken Prevents double ticking in a frame by passing a unique token to the frame\r\n */\r\n public tick(elapsedMilliseconds: number, idempotencyToken: number = 0): void {\r\n if (this._idempotencyToken === idempotencyToken) {\r\n return;\r\n }\r\n this._idempotencyToken = idempotencyToken;\r\n if (!this._playing) {\r\n return;\r\n }\r\n\r\n // if it's the first frame emit frame event\r\n if (this._firstTick) {\r\n this._firstTick = false;\r\n this.events.emit('frame', {...this.currentFrame, frameIndex: this.currentFrameIndex });\r\n }\r\n\r\n this._timeLeftInFrame -= elapsedMilliseconds * this.timeScale;\r\n if (this._timeLeftInFrame <= 0) {\r\n this.goToFrame(this._nextFrame());\r\n }\r\n }\r\n\r\n protected _drawImage(ctx: ExcaliburGraphicsContext, x: number, y: number) {\r\n if (this.currentFrame) {\r\n this.currentFrame.graphic.draw(ctx, x, y);\r\n }\r\n }\r\n}\r\n","import { Vector } from '../Math/vector';\r\nimport { Graphic, GraphicOptions } from './Graphic';\r\nimport { Animation, HasTick } from './Animation';\r\nimport { ExcaliburGraphicsContext } from './Context/ExcaliburGraphicsContext';\r\nimport { BoundingBox } from '../Collision/Index';\r\n\r\nexport interface GraphicsGroupingOptions {\r\n members: GraphicsGrouping[];\r\n}\r\n\r\nexport interface GraphicsGrouping {\r\n pos: Vector;\r\n graphic: Graphic;\r\n}\r\n\r\nexport class GraphicsGroup extends Graphic implements HasTick {\r\n public members: GraphicsGrouping[] = [];\r\n\r\n constructor(options: GraphicsGroupingOptions & GraphicOptions) {\r\n super(options);\r\n this.members = options.members;\r\n this._updateDimensions();\r\n }\r\n\r\n public clone(): GraphicsGroup {\r\n return new GraphicsGroup({\r\n members: [...this.members],\r\n ...this.cloneGraphicOptions()\r\n });\r\n }\r\n\r\n private _updateDimensions(): BoundingBox {\r\n let bb = new BoundingBox();\r\n for (const { graphic, pos } of this.members) {\r\n bb = graphic.localBounds.translate(pos).combine(bb);\r\n }\r\n\r\n this.width = bb.width;\r\n this.height = bb.height;\r\n\r\n return bb;\r\n }\r\n\r\n public get localBounds(): BoundingBox {\r\n let bb = new BoundingBox();\r\n for (const { graphic, pos } of this.members) {\r\n bb = graphic.localBounds.translate(pos).combine(bb);\r\n }\r\n return bb;\r\n }\r\n\r\n private _isAnimationOrGroup(graphic: Graphic): graphic is Animation | GraphicsGroup {\r\n return graphic instanceof Animation || graphic instanceof GraphicsGroup;\r\n }\r\n\r\n public tick(elapsedMilliseconds: number, idempotencyToken?: number) {\r\n for (const member of this.members) {\r\n const maybeAnimation = member.graphic;\r\n if (this._isAnimationOrGroup(maybeAnimation)) {\r\n maybeAnimation.tick(elapsedMilliseconds, idempotencyToken);\r\n }\r\n }\r\n }\r\n\r\n public reset() {\r\n for (const member of this.members) {\r\n const maybeAnimation = member.graphic;\r\n if (this._isAnimationOrGroup(maybeAnimation)) {\r\n maybeAnimation.reset();\r\n }\r\n }\r\n }\r\n\r\n protected _preDraw(ex: ExcaliburGraphicsContext, x: number, y: number) {\r\n this._updateDimensions();\r\n super._preDraw(ex, x, y);\r\n }\r\n\r\n protected _drawImage(ex: ExcaliburGraphicsContext, x: number, y: number) {\r\n for (const member of this.members) {\r\n ex.save();\r\n ex.translate(x, y);\r\n member.graphic.draw(ex, member.pos.x, member.pos.y);\r\n if (this.showDebug) {\r\n /* istanbul ignore next */\r\n ex.debug.drawRect(0, 0, this.width, this.height);\r\n }\r\n ex.restore();\r\n }\r\n }\r\n}\r\n","export type Constructor = {\r\n new (...args: any[]): T;\r\n};\r\n/**\r\n * Configurable helper extends base type and makes all properties available as option bag arguments\r\n * @internal\r\n * @param base\r\n */\r\nexport function Configurable>(base: T): T {\r\n return class extends base {\r\n public assign(props: Partial) {\r\n //set the value of every property that was passed in,\r\n //if the constructor previously set this value, it will be overridden here\r\n for (const k in props) {\r\n // eslint-disable-next-line\r\n if (typeof (this)[k] !== 'function') {\r\n // eslint-disable-next-line\r\n (this)[k] = (props)[k];\r\n }\r\n }\r\n }\r\n\r\n constructor(...args: any[]) {\r\n super(...args);\r\n //get the number of arguments that aren't undefined. TS passes a value to all parameters\r\n //of whatever ctor is the implementation, so args.length doesn't work here.\r\n const size = args.filter(function(value) {\r\n return value !== undefined;\r\n }).length;\r\n if (size === 1 && args[0] && typeof args[0] === 'object' && !(args[0] instanceof Array)) {\r\n this.assign(args[0]);\r\n }\r\n }\r\n };\r\n}\r\n","import { Engine } from './Engine';\r\nimport { Actor } from './Actor';\r\nimport { Color } from './Color';\r\nimport { Vector, vec } from './Math/vector';\r\nimport * as Util from './Util/Util';\r\nimport { Configurable } from './Configurable';\r\nimport { Random } from './Math/Random';\r\nimport { CollisionType } from './Collision/CollisionType';\r\nimport { TransformComponent } from './EntityComponentSystem/Components/TransformComponent';\r\nimport { GraphicsComponent } from './Graphics/GraphicsComponent';\r\nimport { Entity } from './EntityComponentSystem/Entity';\r\nimport { Sprite } from './Graphics/Sprite';\r\nimport { BoundingBox } from './Collision/BoundingBox';\r\nimport { clamp, randomInRange } from './Math/util';\r\n\r\n/**\r\n * An enum that represents the types of emitter nozzles\r\n */\r\nexport enum EmitterType {\r\n /**\r\n * Constant for the circular emitter type\r\n */\r\n Circle,\r\n /**\r\n * Constant for the rectangular emitter type\r\n */\r\n Rectangle\r\n}\r\n\r\n/**\r\n * @hidden\r\n */\r\nexport class ParticleImpl extends Entity {\r\n public position: Vector = new Vector(0, 0);\r\n public velocity: Vector = new Vector(0, 0);\r\n public acceleration: Vector = new Vector(0, 0);\r\n public particleRotationalVelocity: number = 0;\r\n public currentRotation: number = 0;\r\n\r\n public focus: Vector = null;\r\n public focusAccel: number = 0;\r\n public opacity: number = 1;\r\n public beginColor: Color = Color.White;\r\n public endColor: Color = Color.White;\r\n\r\n // Life is counted in ms\r\n public life: number = 300;\r\n public fadeFlag: boolean = false;\r\n\r\n // Color transitions\r\n private _rRate: number = 1;\r\n private _gRate: number = 1;\r\n private _bRate: number = 1;\r\n private _aRate: number = 0;\r\n private _currentColor: Color = Color.White;\r\n\r\n public emitter: ParticleEmitter = null;\r\n public particleSize: number = 5;\r\n public particleSprite: Sprite = null;\r\n\r\n public startSize: number;\r\n public endSize: number;\r\n public sizeRate: number = 0;\r\n public elapsedMultiplier: number = 0;\r\n\r\n public visible = true;\r\n public isOffscreen = false;\r\n\r\n public transform: TransformComponent;\r\n public graphics: GraphicsComponent;\r\n\r\n constructor(\r\n emitterOrConfig: ParticleEmitter | ParticleArgs,\r\n life?: number,\r\n opacity?: number,\r\n beginColor?: Color,\r\n endColor?: Color,\r\n position?: Vector,\r\n velocity?: Vector,\r\n acceleration?: Vector,\r\n startSize?: number,\r\n endSize?: number\r\n ) {\r\n super();\r\n let emitter = emitterOrConfig;\r\n if (emitter && !(emitterOrConfig instanceof ParticleEmitter)) {\r\n const config = emitterOrConfig;\r\n emitter = config.emitter;\r\n life = config.life;\r\n opacity = config.opacity;\r\n endColor = config.endColor;\r\n beginColor = config.beginColor;\r\n position = config.position;\r\n velocity = config.velocity;\r\n acceleration = config.acceleration;\r\n startSize = config.startSize;\r\n endSize = config.endSize;\r\n }\r\n this.emitter = emitter;\r\n this.life = life || this.life;\r\n this.opacity = opacity || this.opacity;\r\n this.endColor = endColor || this.endColor.clone();\r\n this.beginColor = beginColor || this.beginColor.clone();\r\n this._currentColor = this.beginColor.clone();\r\n\r\n if (this.emitter.particleTransform === ParticleTransform.Global) {\r\n const globalPos = this.emitter.transform.globalPos;\r\n this.position = (position || this.position).add(globalPos);\r\n this.velocity = (velocity || this.velocity).rotate(this.emitter.transform.globalRotation);\r\n } else {\r\n this.velocity = velocity || this.velocity;\r\n this.position = (position || this.position);\r\n }\r\n this.acceleration = acceleration || this.acceleration;\r\n this._rRate = (this.endColor.r - this.beginColor.r) / this.life;\r\n this._gRate = (this.endColor.g - this.beginColor.g) / this.life;\r\n this._bRate = (this.endColor.b - this.beginColor.b) / this.life;\r\n this._aRate = this.opacity / this.life;\r\n\r\n this.startSize = startSize || 0;\r\n this.endSize = endSize || 0;\r\n\r\n if (this.endSize > 0 && this.startSize > 0) {\r\n this.sizeRate = (this.endSize - this.startSize) / this.life;\r\n this.particleSize = this.startSize;\r\n }\r\n\r\n this.addComponent((this.transform = new TransformComponent()));\r\n this.addComponent((this.graphics = new GraphicsComponent()));\r\n\r\n this.transform.pos = this.position;\r\n this.transform.rotation = this.currentRotation;\r\n this.transform.scale = vec(1, 1); // TODO wut\r\n if (this.particleSprite) {\r\n this.graphics.opacity = this.opacity;\r\n this.graphics.use(this.particleSprite);\r\n } else {\r\n this.graphics.localBounds = BoundingBox.fromDimension(this.particleSize, this.particleSize, Vector.Half);\r\n this.graphics.onPostDraw = (ctx) => {\r\n ctx.save();\r\n this.graphics.opacity = this.opacity;\r\n const tmpColor = this._currentColor.clone();\r\n tmpColor.a = 1;\r\n ctx.debug.drawPoint(vec(0, 0), { color: tmpColor, size: this.particleSize });\r\n ctx.restore();\r\n };\r\n }\r\n }\r\n\r\n public kill() {\r\n this.emitter.removeParticle(this);\r\n }\r\n\r\n public update(_engine: Engine, delta: number) {\r\n this.life = this.life - delta;\r\n this.elapsedMultiplier = this.elapsedMultiplier + delta;\r\n\r\n if (this.life < 0) {\r\n this.kill();\r\n }\r\n\r\n if (this.fadeFlag) {\r\n this.opacity = clamp(this._aRate * this.life, 0.0001, 1);\r\n }\r\n\r\n if (this.startSize > 0 && this.endSize > 0) {\r\n this.particleSize = clamp(\r\n this.sizeRate * delta + this.particleSize,\r\n Math.min(this.startSize, this.endSize),\r\n Math.max(this.startSize, this.endSize)\r\n );\r\n }\r\n\r\n this._currentColor.r = clamp(this._currentColor.r + this._rRate * delta, 0, 255);\r\n this._currentColor.g = clamp(this._currentColor.g + this._gRate * delta, 0, 255);\r\n this._currentColor.b = clamp(this._currentColor.b + this._bRate * delta, 0, 255);\r\n this._currentColor.a = clamp(this.opacity, 0.0001, 1);\r\n\r\n if (this.focus) {\r\n const accel = this.focus\r\n .sub(this.position)\r\n .normalize()\r\n .scale(this.focusAccel)\r\n .scale(delta / 1000);\r\n this.velocity = this.velocity.add(accel);\r\n } else {\r\n this.velocity = this.velocity.add(this.acceleration.scale(delta / 1000));\r\n }\r\n this.position = this.position.add(this.velocity.scale(delta / 1000));\r\n\r\n if (this.particleRotationalVelocity) {\r\n this.currentRotation = (this.currentRotation + (this.particleRotationalVelocity * delta) / 1000) % (2 * Math.PI);\r\n }\r\n\r\n this.transform.pos = this.position;\r\n this.transform.rotation = this.currentRotation;\r\n this.transform.scale = vec(1, 1); // todo wut\r\n this.graphics.opacity = this.opacity;\r\n }\r\n}\r\n\r\nexport interface ParticleArgs extends Partial {\r\n emitter: ParticleEmitter;\r\n position?: Vector;\r\n velocity?: Vector;\r\n acceleration?: Vector;\r\n particleRotationalVelocity?: number;\r\n currentRotation?: number;\r\n particleSize?: number;\r\n particleSprite?: Sprite;\r\n}\r\n\r\n/**\r\n * Particle is used in a [[ParticleEmitter]]\r\n */\r\nexport class Particle extends Configurable(ParticleImpl) {\r\n constructor(config: ParticleArgs);\r\n constructor(\r\n emitter: ParticleEmitter,\r\n life?: number,\r\n opacity?: number,\r\n beginColor?: Color,\r\n endColor?: Color,\r\n position?: Vector,\r\n velocity?: Vector,\r\n acceleration?: Vector,\r\n startSize?: number,\r\n endSize?: number\r\n );\r\n constructor(\r\n emitterOrConfig: ParticleEmitter | ParticleArgs,\r\n life?: number,\r\n opacity?: number,\r\n beginColor?: Color,\r\n endColor?: Color,\r\n position?: Vector,\r\n velocity?: Vector,\r\n acceleration?: Vector,\r\n startSize?: number,\r\n endSize?: number\r\n ) {\r\n super(emitterOrConfig, life, opacity, beginColor, endColor, position, velocity, acceleration, startSize, endSize);\r\n }\r\n}\r\n\r\nexport enum ParticleTransform {\r\n /**\r\n * [[ParticleTransform.Global]] is the default and emits particles as if\r\n * they were world space objects, useful for most effects.\r\n */\r\n Global = 'global',\r\n /**\r\n * [[ParticleTransform.Local]] particles are children of the emitter and move relative to the emitter\r\n * as they would in a parent/child actor relationship.\r\n */\r\n Local = 'local'\r\n}\r\n\r\nexport interface ParticleEmitterArgs {\r\n x?: number;\r\n y?: number;\r\n pos?: Vector;\r\n width?: number;\r\n height?: number;\r\n isEmitting?: boolean;\r\n minVel?: number;\r\n maxVel?: number;\r\n acceleration?: Vector;\r\n minAngle?: number;\r\n maxAngle?: number;\r\n emitRate?: number;\r\n particleLife?: number;\r\n /**\r\n * Optionally set the emitted particle transform style, [[ParticleTransform.Global]] is the default and emits particles as if\r\n * they were world space objects, useful for most effects.\r\n *\r\n * If set to [[ParticleTransform.Local]] particles are children of the emitter and move relative to the emitter\r\n * as they would in a parent/child actor relationship.\r\n */\r\n particleTransform?: ParticleTransform;\r\n opacity?: number;\r\n fadeFlag?: boolean;\r\n focus?: Vector;\r\n focusAccel?: number;\r\n startSize?: number;\r\n endSize?: number;\r\n minSize?: number;\r\n maxSize?: number;\r\n beginColor?: Color;\r\n endColor?: Color;\r\n particleSprite?: Sprite;\r\n emitterType?: EmitterType;\r\n radius?: number;\r\n particleRotationalVelocity?: number;\r\n randomRotation?: boolean;\r\n random?: Random;\r\n}\r\n\r\n/**\r\n * Using a particle emitter is a great way to create interesting effects\r\n * in your game, like smoke, fire, water, explosions, etc. `ParticleEmitter`\r\n * extend [[Actor]] allowing you to use all of the features that come with.\r\n */\r\nexport class ParticleEmitter extends Actor {\r\n private _particlesToEmit: number = 0;\r\n\r\n public numParticles: number = 0;\r\n\r\n /**\r\n * Random number generator\r\n */\r\n public random: Random;\r\n\r\n /**\r\n * Gets or sets the isEmitting flag\r\n */\r\n public isEmitting: boolean = true;\r\n /**\r\n * Gets or sets the backing particle collection\r\n */\r\n public particles: Particle[] = [];\r\n\r\n /**\r\n * Gets or sets the backing deadParticle collection\r\n */\r\n public deadParticles: Particle[] = [];\r\n\r\n /**\r\n * Gets or sets the minimum particle velocity\r\n */\r\n public minVel: number = 0;\r\n /**\r\n * Gets or sets the maximum particle velocity\r\n */\r\n public maxVel: number = 0;\r\n\r\n /**\r\n * Gets or sets the acceleration vector for all particles\r\n */\r\n public acceleration: Vector = new Vector(0, 0);\r\n\r\n /**\r\n * Gets or sets the minimum angle in radians\r\n */\r\n public minAngle: number = 0;\r\n /**\r\n * Gets or sets the maximum angle in radians\r\n */\r\n public maxAngle: number = 0;\r\n\r\n /**\r\n * Gets or sets the emission rate for particles (particles/sec)\r\n */\r\n public emitRate: number = 1; //particles/sec\r\n /**\r\n * Gets or sets the life of each particle in milliseconds\r\n */\r\n public particleLife: number = 2000;\r\n /**\r\n * Gets the opacity of each particle from 0 to 1.0\r\n */\r\n public get opacity(): number {\r\n return super.graphics.opacity;\r\n }\r\n /**\r\n * Gets the opacity of each particle from 0 to 1.0\r\n */\r\n public set opacity(opacity: number) {\r\n super.graphics.opacity = opacity;\r\n }\r\n /**\r\n * Gets or sets the fade flag which causes particles to gradually fade out over the course of their life.\r\n */\r\n public fadeFlag: boolean = false;\r\n\r\n /**\r\n * Gets or sets the optional focus where all particles should accelerate towards\r\n */\r\n public focus: Vector = null;\r\n /**\r\n * Gets or sets the acceleration for focusing particles if a focus has been specified\r\n */\r\n public focusAccel: number = null;\r\n /**\r\n * Gets or sets the optional starting size for the particles\r\n */\r\n public startSize: number = null;\r\n /**\r\n * Gets or sets the optional ending size for the particles\r\n */\r\n public endSize: number = null;\r\n\r\n /**\r\n * Gets or sets the minimum size of all particles\r\n */\r\n public minSize: number = 5;\r\n /**\r\n * Gets or sets the maximum size of all particles\r\n */\r\n public maxSize: number = 5;\r\n\r\n /**\r\n * Gets or sets the beginning color of all particles\r\n */\r\n public beginColor: Color = Color.White;\r\n /**\r\n * Gets or sets the ending color of all particles\r\n */\r\n public endColor: Color = Color.White;\r\n\r\n private _sprite: Sprite = null;\r\n /**\r\n * Gets or sets the sprite that a particle should use\r\n */\r\n public get particleSprite(): Sprite {\r\n return this._sprite;\r\n }\r\n\r\n public set particleSprite(val: Sprite) {\r\n if (val) {\r\n this._sprite = val;\r\n }\r\n }\r\n\r\n /**\r\n * Gets or sets the emitter type for the particle emitter\r\n */\r\n public emitterType: EmitterType = EmitterType.Rectangle;\r\n\r\n /**\r\n * Gets or sets the emitter radius, only takes effect when the [[emitterType]] is [[EmitterType.Circle]]\r\n */\r\n public radius: number = 0;\r\n\r\n /**\r\n * Gets or sets the particle rotational speed velocity\r\n */\r\n public particleRotationalVelocity: number = 0;\r\n\r\n /**\r\n * Indicates whether particles should start with a random rotation\r\n */\r\n public randomRotation: boolean = false;\r\n\r\n /**\r\n * Gets or sets the emitted particle transform style, [[ParticleTransform.Global]] is the default and emits particles as if\r\n * they were world space objects, useful for most effects.\r\n *\r\n * If set to [[ParticleTransform.Local]] particles are children of the emitter and move relative to the emitter\r\n * as they would in a parent/child actor relationship.\r\n */\r\n public particleTransform: ParticleTransform = ParticleTransform.Global;\r\n\r\n /**\r\n * @param config particle emitter options bag\r\n */\r\n constructor(config: ParticleEmitterArgs) {\r\n super({ width: config.width ?? 0, height: config.height ?? 0 });\r\n\r\n const {\r\n x,\r\n y,\r\n pos,\r\n isEmitting,\r\n minVel,\r\n maxVel,\r\n acceleration,\r\n minAngle,\r\n maxAngle,\r\n emitRate,\r\n particleLife,\r\n opacity,\r\n fadeFlag,\r\n focus,\r\n focusAccel,\r\n startSize,\r\n endSize,\r\n minSize,\r\n maxSize,\r\n beginColor,\r\n endColor,\r\n particleSprite,\r\n emitterType,\r\n radius,\r\n particleRotationalVelocity,\r\n particleTransform,\r\n randomRotation,\r\n random\r\n } = { ...config };\r\n\r\n this.pos = pos ?? vec(x ?? 0, y ?? 0);\r\n this.isEmitting = isEmitting ?? this.isEmitting;\r\n this.minVel = minVel ?? this.minVel;\r\n this.maxVel = maxVel ?? this.maxVel;\r\n this.acceleration = acceleration ?? this.acceleration;\r\n this.minAngle = minAngle ?? this.minAngle;\r\n this.maxAngle = maxAngle ?? this.maxAngle;\r\n this.emitRate = emitRate ?? this.emitRate;\r\n this.particleLife = particleLife ?? this.particleLife;\r\n this.opacity = opacity ?? this.opacity;\r\n this.fadeFlag = fadeFlag ?? this.fadeFlag;\r\n this.focus = focus ?? this.focus;\r\n this.focusAccel = focusAccel ?? this.focusAccel;\r\n this.startSize = startSize ?? this.startSize;\r\n this.endSize = endSize ?? this.endSize;\r\n this.minSize = minSize ?? this.minSize;\r\n this.maxSize = maxSize ?? this.maxSize;\r\n this.beginColor = beginColor ?? this.beginColor;\r\n this.endColor = endColor ?? this.endColor;\r\n this.particleSprite = particleSprite ?? this.particleSprite;\r\n this.emitterType = emitterType ?? this.emitterType;\r\n this.radius = radius ?? this.radius;\r\n this.particleRotationalVelocity = particleRotationalVelocity ?? this.particleRotationalVelocity;\r\n this.randomRotation = randomRotation ?? this.randomRotation;\r\n this.particleTransform = particleTransform ?? this.particleTransform;\r\n\r\n this.body.collisionType = CollisionType.PreventCollision;\r\n\r\n this.random = random ?? new Random();\r\n }\r\n\r\n public removeParticle(particle: Particle) {\r\n this.deadParticles.push(particle);\r\n }\r\n\r\n /**\r\n * Causes the emitter to emit particles\r\n * @param particleCount Number of particles to emit right now\r\n */\r\n public emitParticles(particleCount: number) {\r\n for (let i = 0; i < particleCount; i++) {\r\n const p = this._createParticle();\r\n this.particles.push(p);\r\n if (this?.scene?.world) {\r\n if (this.particleTransform === ParticleTransform.Global) {\r\n this.scene.world.add(p);\r\n } else {\r\n this.addChild(p);\r\n }\r\n }\r\n }\r\n }\r\n\r\n public clearParticles() {\r\n this.particles.length = 0;\r\n }\r\n\r\n // Creates a new particle given the constraints of the emitter\r\n private _createParticle(): Particle {\r\n // todo implement emitter constraints;\r\n let ranX = 0;\r\n let ranY = 0;\r\n\r\n const angle = randomInRange(this.minAngle, this.maxAngle, this.random);\r\n const vel = randomInRange(this.minVel, this.maxVel, this.random);\r\n const size = this.startSize || randomInRange(this.minSize, this.maxSize, this.random);\r\n const dx = vel * Math.cos(angle);\r\n const dy = vel * Math.sin(angle);\r\n\r\n if (this.emitterType === EmitterType.Rectangle) {\r\n ranX = randomInRange(0, this.width, this.random);\r\n ranY = randomInRange(0, this.height, this.random);\r\n } else if (this.emitterType === EmitterType.Circle) {\r\n const radius = randomInRange(0, this.radius, this.random);\r\n ranX = radius * Math.cos(angle);\r\n ranY = radius * Math.sin(angle);\r\n }\r\n\r\n const p = new Particle(\r\n this,\r\n this.particleLife,\r\n this.opacity,\r\n this.beginColor,\r\n this.endColor,\r\n new Vector(ranX, ranY),\r\n new Vector(dx, dy),\r\n this.acceleration,\r\n this.startSize,\r\n this.endSize\r\n );\r\n p.fadeFlag = this.fadeFlag;\r\n p.particleSize = size;\r\n if (this.particleSprite) {\r\n p.particleSprite = this.particleSprite;\r\n p.graphics.opacity = this.opacity;\r\n p.graphics.use(this._sprite);\r\n }\r\n p.particleRotationalVelocity = this.particleRotationalVelocity;\r\n if (this.randomRotation) {\r\n p.currentRotation = randomInRange(0, Math.PI * 2, this.random);\r\n }\r\n if (this.focus) {\r\n p.focus = this.focus.add(new Vector(this.pos.x, this.pos.y));\r\n p.focusAccel = this.focusAccel;\r\n }\r\n return p;\r\n }\r\n\r\n public update(engine: Engine, delta: number) {\r\n super.update(engine, delta);\r\n\r\n if (this.isEmitting) {\r\n this._particlesToEmit += this.emitRate * (delta / 1000);\r\n if (this._particlesToEmit > 1.0) {\r\n this.emitParticles(Math.floor(this._particlesToEmit));\r\n this._particlesToEmit = this._particlesToEmit - Math.floor(this._particlesToEmit);\r\n }\r\n }\r\n\r\n // deferred removal\r\n for (let i = 0; i < this.deadParticles.length; i++) {\r\n Util.removeItemFromArray(this.deadParticles[i], this.particles);\r\n if (this?.scene?.world) {\r\n this.scene.world.remove(this.deadParticles[i], false);\r\n }\r\n }\r\n this.deadParticles.length = 0;\r\n }\r\n}\r\n","import { ExcaliburGraphicsContext } from './Context/ExcaliburGraphicsContext';\r\nimport { Scene } from '../Scene';\r\nimport { GraphicsComponent } from './GraphicsComponent';\r\nimport { vec, Vector } from '../Math/vector';\r\nimport { TransformComponent } from '../EntityComponentSystem/Components/TransformComponent';\r\nimport { Entity } from '../EntityComponentSystem/Entity';\r\nimport { Camera } from '../Camera';\r\nimport { AddedEntity, isAddedSystemEntity, RemovedEntity, System, SystemType } from '../EntityComponentSystem';\r\nimport { Engine } from '../Engine';\r\nimport { GraphicsGroup } from '.';\r\nimport { Particle } from '../Particles';\r\nimport { ParallaxComponent } from './ParallaxComponent';\r\nimport { CoordPlane } from '../Math/coord-plane';\r\nimport { BodyComponent } from '../Collision/BodyComponent';\r\nimport { FontCache } from './FontCache';\r\n\r\nexport class GraphicsSystem extends System {\r\n public readonly types = ['ex.transform', 'ex.graphics'] as const;\r\n public readonly systemType = SystemType.Draw;\r\n public priority = 0;\r\n private _token = 0;\r\n private _graphicsContext: ExcaliburGraphicsContext;\r\n private _camera: Camera;\r\n private _engine: Engine;\r\n\r\n private _sortedTransforms: TransformComponent[] = [];\r\n public get sortedTransforms() {\r\n return this._sortedTransforms;\r\n }\r\n\r\n public initialize(scene: Scene): void {\r\n this._camera = scene.camera;\r\n this._engine = scene.engine;\r\n }\r\n\r\n private _zHasChanged = false;\r\n private _zIndexUpdate = () => {\r\n this._zHasChanged = true;\r\n };\r\n\r\n public preupdate(): void {\r\n // Graphics context could be switched to fallback in a new frame\r\n this._graphicsContext = this._engine.graphicsContext;\r\n if (this._zHasChanged) {\r\n this._sortedTransforms.sort((a, b) => {\r\n return a.z - b.z;\r\n });\r\n this._zHasChanged = false;\r\n }\r\n }\r\n\r\n public notify(entityAddedOrRemoved: AddedEntity | RemovedEntity): void {\r\n if (isAddedSystemEntity(entityAddedOrRemoved)) {\r\n const tx = entityAddedOrRemoved.data.get(TransformComponent);\r\n this._sortedTransforms.push(tx);\r\n tx.zIndexChanged$.subscribe(this._zIndexUpdate);\r\n this._zHasChanged = true;\r\n } else {\r\n const tx = entityAddedOrRemoved.data.get(TransformComponent);\r\n tx.zIndexChanged$.unsubscribe(this._zIndexUpdate);\r\n const index = this._sortedTransforms.indexOf(tx);\r\n if (index > -1) {\r\n this._sortedTransforms.splice(index, 1);\r\n }\r\n }\r\n }\r\n\r\n public update(_entities: Entity[], delta: number): void {\r\n this._token++;\r\n let graphics: GraphicsComponent;\r\n FontCache.checkAndClearCache();\r\n\r\n // This is a performance enhancement, most things are in world space\r\n // so if we can only do this once saves a ton of transform updates\r\n this._graphicsContext.save();\r\n if (this._camera) {\r\n this._camera.draw(this._graphicsContext);\r\n }\r\n for (const transform of this._sortedTransforms) {\r\n const entity = transform.owner as Entity;\r\n\r\n // If the entity is offscreen skip\r\n if (entity.hasTag('ex.offscreen')) {\r\n continue;\r\n }\r\n\r\n graphics = entity.get(GraphicsComponent);\r\n // Exit if graphics set to not visible\r\n if (!graphics.visible) {\r\n continue;\r\n }\r\n\r\n // This optionally sets our camera based on the entity coord plan (world vs. screen)\r\n if (transform.coordPlane === CoordPlane.Screen) {\r\n this._graphicsContext.restore();\r\n }\r\n\r\n this._graphicsContext.save();\r\n if (transform.coordPlane === CoordPlane.Screen) {\r\n this._graphicsContext.translate(this._engine.screen.contentArea.left, this._engine.screen.contentArea.top);\r\n }\r\n\r\n // Tick any graphics state (but only once) for animations and graphics groups\r\n graphics.update(delta, this._token);\r\n\r\n // Apply parallax\r\n const parallax = entity.get(ParallaxComponent);\r\n if (parallax) {\r\n // We use the Tiled formula\r\n // https://doc.mapeditor.org/en/latest/manual/layers/#parallax-scrolling-factor\r\n // cameraPos * (1 - parallaxFactor)\r\n const oneMinusFactor = Vector.One.sub(parallax.parallaxFactor);\r\n const parallaxOffset = this._camera.pos.scale(oneMinusFactor);\r\n this._graphicsContext.translate(parallaxOffset.x, parallaxOffset.y);\r\n }\r\n\r\n // Position the entity + estimate lag\r\n this._applyTransform(entity);\r\n\r\n // If there is a material enable it on the context\r\n if (graphics.material) {\r\n this._graphicsContext.material = graphics.material;\r\n }\r\n\r\n // Optionally run the onPreDraw graphics lifecycle draw\r\n if (graphics.onPreDraw) {\r\n graphics.onPreDraw(this._graphicsContext, delta);\r\n }\r\n\r\n // TODO remove this hack on the particle redo\r\n const particleOpacity = (entity instanceof Particle) ? entity.opacity : 1;\r\n this._graphicsContext.opacity *= graphics.opacity * particleOpacity;\r\n\r\n // Draw the graphics component\r\n this._drawGraphicsComponent(graphics);\r\n\r\n // Optionally run the onPostDraw graphics lifecycle draw\r\n if (graphics.onPostDraw) {\r\n graphics.onPostDraw(this._graphicsContext, delta);\r\n }\r\n\r\n this._graphicsContext.restore();\r\n\r\n // Reset the transform back to the original world space\r\n if (transform.coordPlane === CoordPlane.Screen) {\r\n this._graphicsContext.save();\r\n if (this._camera) {\r\n this._camera.draw(this._graphicsContext);\r\n }\r\n }\r\n }\r\n this._graphicsContext.restore();\r\n }\r\n\r\n private _drawGraphicsComponent(graphicsComponent: GraphicsComponent) {\r\n if (graphicsComponent.visible) {\r\n const flipHorizontal = graphicsComponent.flipHorizontal;\r\n const flipVertical = graphicsComponent.flipVertical;\r\n\r\n for (const layer of graphicsComponent.layers.get()) {\r\n for (const { graphic, options } of layer.graphics) {\r\n let anchor = graphicsComponent.anchor;\r\n let offset = graphicsComponent.offset;\r\n\r\n // handle layer specific overrides\r\n if (options?.anchor) {\r\n anchor = options.anchor;\r\n }\r\n if (options?.offset) {\r\n offset = options.offset;\r\n }\r\n // See https://github.com/excaliburjs/Excalibur/pull/619 for discussion on this formula\r\n const offsetX = -graphic.width * anchor.x + offset.x;\r\n const offsetY = -graphic.height * anchor.y + offset.y;\r\n\r\n const oldFlipHorizontal = graphic.flipHorizontal;\r\n const oldFlipVertical = graphic.flipVertical;\r\n if (flipHorizontal || flipVertical) {\r\n\r\n // flip any currently flipped graphics\r\n graphic.flipHorizontal = flipHorizontal ? !oldFlipHorizontal : oldFlipHorizontal;\r\n graphic.flipVertical = flipVertical ? !oldFlipVertical : oldFlipVertical;\r\n }\r\n\r\n graphic?.draw(\r\n this._graphicsContext,\r\n offsetX + layer.offset.x,\r\n offsetY + layer.offset.y);\r\n\r\n if (flipHorizontal || flipVertical) {\r\n graphic.flipHorizontal = oldFlipHorizontal;\r\n graphic.flipVertical = oldFlipVertical;\r\n }\r\n\r\n if (this._engine?.isDebug && this._engine.debug.graphics.showBounds) {\r\n const offset = vec(offsetX + layer.offset.x, offsetY + layer.offset.y);\r\n if (graphic instanceof GraphicsGroup) {\r\n for (const g of graphic.members) {\r\n g.graphic?.localBounds.translate(offset.add(g.pos)).draw(this._graphicsContext, this._engine.debug.graphics.boundsColor);\r\n }\r\n } else {\r\n /* istanbul ignore next */\r\n graphic?.localBounds.translate(offset).draw(this._graphicsContext, this._engine.debug.graphics.boundsColor);\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * This applies the current entity transform to the graphics context\r\n * @param entity\r\n */\r\n private _applyTransform(entity: Entity): void {\r\n const ancestors = entity.getAncestors();\r\n for (const ancestor of ancestors) {\r\n const transform = ancestor?.get(TransformComponent);\r\n const optionalBody = ancestor?.get(BodyComponent);\r\n let interpolatedPos = transform.pos;\r\n let interpolatedScale = transform.scale;\r\n let interpolatedRotation = transform.rotation;\r\n if (optionalBody) {\r\n if (this._engine.fixedUpdateFps &&\r\n optionalBody.__oldTransformCaptured &&\r\n optionalBody.enableFixedUpdateInterpolate) {\r\n\r\n // Interpolate graphics if needed\r\n const blend = this._engine.currentFrameLagMs / (1000 / this._engine.fixedUpdateFps);\r\n interpolatedPos = transform.pos.scale(blend).add(\r\n optionalBody.oldPos.scale(1.0 - blend)\r\n );\r\n interpolatedScale = transform.scale.scale(blend).add(\r\n optionalBody.oldScale.scale(1.0 - blend)\r\n );\r\n // Rotational lerp https://stackoverflow.com/a/30129248\r\n const cosine = (1.0 - blend) * Math.cos(optionalBody.oldRotation) + blend * Math.cos(transform.rotation);\r\n const sine = (1.0 - blend) * Math.sin(optionalBody.oldRotation) + blend * Math.sin(transform.rotation);\r\n interpolatedRotation = Math.atan2(sine, cosine);\r\n }\r\n }\r\n\r\n if (transform) {\r\n this._graphicsContext.z = transform.z;\r\n this._graphicsContext.translate(interpolatedPos.x, interpolatedPos.y);\r\n this._graphicsContext.scale(interpolatedScale.x, interpolatedScale.y);\r\n this._graphicsContext.rotate(interpolatedRotation);\r\n }\r\n }\r\n }\r\n}\r\n","import { Engine } from '../Engine';\r\nimport { Scene } from '../Scene';\r\nimport { Camera } from '../Camera';\r\nimport { MotionComponent } from '../EntityComponentSystem/Components/MotionComponent';\r\nimport { ColliderComponent } from '../Collision/ColliderComponent';\r\nimport { Entity, TransformComponent } from '../EntityComponentSystem';\r\nimport { System, SystemType } from '../EntityComponentSystem/System';\r\nimport { ExcaliburGraphicsContext } from '../Graphics/Context/ExcaliburGraphicsContext';\r\nimport { vec, Vector } from '../Math/vector';\r\nimport { toDegrees } from '../Math/util';\r\nimport { BodyComponent, CollisionSystem, CompositeCollider, GraphicsComponent, Particle } from '..';\r\nimport { DebugGraphicsComponent } from '../Graphics/DebugGraphicsComponent';\r\nimport { CoordPlane } from '../Math/coord-plane';\r\n\r\nexport class DebugSystem extends System {\r\n public readonly types = ['ex.transform'] as const;\r\n public readonly systemType = SystemType.Draw;\r\n public priority = 999; // lowest priority\r\n private _graphicsContext: ExcaliburGraphicsContext;\r\n private _collisionSystem: CollisionSystem;\r\n private _camera: Camera;\r\n private _engine: Engine;\r\n\r\n public initialize(scene: Scene): void {\r\n this._graphicsContext = scene.engine.graphicsContext;\r\n this._camera = scene.camera;\r\n this._engine = scene.engine;\r\n this._collisionSystem = scene.world.systemManager.get(CollisionSystem);\r\n }\r\n\r\n update(entities: Entity[], _delta: number): void {\r\n if (!this._engine.isDebug) {\r\n return;\r\n }\r\n\r\n const filterSettings = this._engine.debug.filter;\r\n\r\n let id: number;\r\n let name: string;\r\n const entitySettings = this._engine.debug.entity;\r\n\r\n let tx: TransformComponent;\r\n const txSettings = this._engine.debug.transform;\r\n\r\n let motion: MotionComponent;\r\n const motionSettings = this._engine.debug.motion;\r\n\r\n let colliderComp: ColliderComponent;\r\n const colliderSettings = this._engine.debug.collider;\r\n\r\n const physicsSettings = this._engine.debug.physics;\r\n\r\n let graphics: GraphicsComponent;\r\n const graphicsSettings = this._engine.debug.graphics;\r\n\r\n let debugDraw: DebugGraphicsComponent;\r\n\r\n let body: BodyComponent;\r\n const bodySettings = this._engine.debug.body;\r\n\r\n const cameraSettings = this._engine.debug.camera;\r\n for (const entity of entities) {\r\n if (entity.hasTag('offscreen')) {\r\n // skip offscreen entities\r\n continue;\r\n }\r\n if (entity instanceof Particle) {\r\n // Particles crush the renderer :(\r\n continue;\r\n }\r\n if (filterSettings.useFilter) {\r\n const allIds = filterSettings.ids.length === 0;\r\n const idMatch = allIds || filterSettings.ids.includes(entity.id);\r\n if (!idMatch) {\r\n continue;\r\n }\r\n const allNames = filterSettings.nameQuery === '';\r\n const nameMatch = allNames || entity.name.includes(filterSettings.nameQuery);\r\n if (!nameMatch) {\r\n continue;\r\n }\r\n }\r\n\r\n let cursor = Vector.Zero;\r\n const lineHeight = vec(0, 16);\r\n id = entity.id;\r\n name = entity.name;\r\n tx = entity.get(TransformComponent);\r\n\r\n // This optionally sets our camera based on the entity coord plan (world vs. screen)\r\n this._pushCameraTransform(tx);\r\n\r\n this._graphicsContext.save();\r\n\r\n this._applyTransform(entity);\r\n if (tx) {\r\n if (txSettings.showAll || txSettings.showPosition) {\r\n this._graphicsContext.debug.drawPoint(Vector.Zero, { size: 4, color: txSettings.positionColor });\r\n }\r\n if (txSettings.showAll || txSettings.showPositionLabel) {\r\n this._graphicsContext.debug.drawText(`pos${tx.pos.toString(2)}`, cursor);\r\n cursor = cursor.add(lineHeight);\r\n }\r\n if (txSettings.showAll || txSettings.showZIndex) {\r\n this._graphicsContext.debug.drawText(`z(${tx.z.toFixed(1)})`, cursor);\r\n cursor = cursor.add(lineHeight);\r\n }\r\n\r\n if (entitySettings.showAll || entitySettings.showId) {\r\n this._graphicsContext.debug.drawText(`id(${id}) ${entity.parent ? 'child of id(' + entity.parent?.id + ')' : ''}`, cursor);\r\n cursor = cursor.add(lineHeight);\r\n }\r\n\r\n if (entitySettings.showAll || entitySettings.showName) {\r\n this._graphicsContext.debug.drawText(`name(${name})`, cursor);\r\n cursor = cursor.add(lineHeight);\r\n }\r\n\r\n if (txSettings.showAll || txSettings.showRotation) {\r\n this._graphicsContext.drawLine(\r\n Vector.Zero,\r\n Vector.fromAngle(tx.rotation).scale(50).add(Vector.Zero),\r\n txSettings.rotationColor,\r\n 2\r\n );\r\n this._graphicsContext.debug.drawText(`rot deg(${toDegrees(tx.rotation).toFixed(2)})`, cursor);\r\n cursor = cursor.add(lineHeight);\r\n }\r\n\r\n if (txSettings.showAll || txSettings.showScale) {\r\n this._graphicsContext.drawLine(Vector.Zero, tx.scale.add(Vector.Zero), txSettings.scaleColor, 2);\r\n }\r\n }\r\n\r\n graphics = entity.get(GraphicsComponent);\r\n if (graphics) {\r\n if (graphicsSettings.showAll || graphicsSettings.showBounds) {\r\n const bounds = graphics.localBounds;\r\n bounds.draw(this._graphicsContext, graphicsSettings.boundsColor);\r\n }\r\n }\r\n\r\n debugDraw = entity.get(DebugGraphicsComponent);\r\n if (debugDraw) {\r\n if (!debugDraw.useTransform) {\r\n this._graphicsContext.restore();\r\n }\r\n debugDraw.draw(this._graphicsContext);\r\n if (!debugDraw.useTransform) {\r\n this._graphicsContext.save();\r\n this._applyTransform(entity);\r\n }\r\n }\r\n\r\n body = entity.get(BodyComponent);\r\n if (body) {\r\n if (bodySettings.showAll || bodySettings.showCollisionGroup) {\r\n this._graphicsContext.debug.drawText(`collision group(${body.group.name})`, cursor);\r\n cursor = cursor.add(lineHeight);\r\n }\r\n\r\n if (bodySettings.showAll || bodySettings.showCollisionType) {\r\n this._graphicsContext.debug.drawText(`collision type(${body.collisionType})`, cursor);\r\n cursor = cursor.add(lineHeight);\r\n }\r\n\r\n if (bodySettings.showAll || bodySettings.showMass) {\r\n this._graphicsContext.debug.drawText(`mass(${body.mass})`, cursor);\r\n cursor = cursor.add(lineHeight);\r\n }\r\n\r\n if (bodySettings.showAll || bodySettings.showMotion) {\r\n this._graphicsContext.debug.drawText(`motion(${body.sleepMotion})`, cursor);\r\n cursor = cursor.add(lineHeight);\r\n }\r\n\r\n if (bodySettings.showAll || bodySettings.showSleeping) {\r\n this._graphicsContext.debug.drawText(`sleeping(${body.canSleep ? body.sleeping: 'cant sleep'})`, cursor);\r\n cursor = cursor.add(lineHeight);\r\n }\r\n }\r\n\r\n this._graphicsContext.restore();\r\n\r\n motion = entity.get(MotionComponent);\r\n if (motion) {\r\n if (motionSettings.showAll || motionSettings.showVelocity) {\r\n this._graphicsContext.debug.drawText(`vel${motion.vel.toString(2)}`, cursor.add(tx.globalPos));\r\n this._graphicsContext.drawLine(tx.globalPos, tx.globalPos.add(motion.vel), motionSettings.velocityColor, 2);\r\n cursor = cursor.add(lineHeight);\r\n }\r\n\r\n if (motionSettings.showAll || motionSettings.showAcceleration) {\r\n this._graphicsContext.drawLine(tx.globalPos, tx.globalPos.add(motion.acc), motionSettings.accelerationColor, 2);\r\n }\r\n }\r\n\r\n // Colliders live in world space already so after the restore()\r\n colliderComp = entity.get(ColliderComponent);\r\n if (colliderComp) {\r\n const collider = colliderComp.get();\r\n if ((colliderSettings.showAll || colliderSettings.showGeometry) && collider) {\r\n collider.debug(this._graphicsContext, colliderSettings.geometryColor);\r\n }\r\n if (colliderSettings.showAll || colliderSettings.showBounds) {\r\n if (collider instanceof CompositeCollider) {\r\n const colliders = collider.getColliders();\r\n for (const collider of colliders) {\r\n const bounds = collider.bounds;\r\n const pos = vec(bounds.left, bounds.top);\r\n this._graphicsContext.debug.drawRect(pos.x, pos.y, bounds.width, bounds.height, { color: colliderSettings.boundsColor });\r\n if (colliderSettings.showAll || colliderSettings.showOwner) {\r\n this._graphicsContext.debug.drawText(`owner id(${collider.owner.id})`, pos);\r\n }\r\n }\r\n colliderComp.bounds.draw(this._graphicsContext, colliderSettings.boundsColor);\r\n } else if (collider) {\r\n const bounds = colliderComp.bounds;\r\n const pos = vec(bounds.left, bounds.top);\r\n this._graphicsContext.debug.drawRect(pos.x, pos.y, bounds.width, bounds.height, { color: colliderSettings.boundsColor });\r\n if (colliderSettings.showAll || colliderSettings.showOwner) {\r\n this._graphicsContext.debug.drawText(`owner id(${colliderComp.owner.id})`, pos);\r\n }\r\n }\r\n }\r\n }\r\n\r\n this._popCameraTransform(tx);\r\n }\r\n\r\n this._graphicsContext.save();\r\n this._camera.draw(this._graphicsContext);\r\n if (physicsSettings.showAll || physicsSettings.showBroadphaseSpacePartitionDebug) {\r\n this._collisionSystem.debug(this._graphicsContext);\r\n }\r\n if (physicsSettings.showAll || physicsSettings.showCollisionContacts || physicsSettings.showCollisionNormals) {\r\n for (const [_, contact] of this._engine.debug.stats.currFrame.physics.contacts) {\r\n if (physicsSettings.showAll || physicsSettings.showCollisionContacts) {\r\n for (const point of contact.points) {\r\n this._graphicsContext.debug.drawPoint(point, { size: 5, color: physicsSettings.collisionContactColor });\r\n }\r\n }\r\n\r\n if (physicsSettings.showAll || physicsSettings.showCollisionNormals) {\r\n for (const point of contact.points) {\r\n this._graphicsContext.debug.drawLine(point, contact.normal.scale(30).add(point), {\r\n color: physicsSettings.collisionNormalColor\r\n });\r\n }\r\n }\r\n }\r\n }\r\n this._graphicsContext.restore();\r\n\r\n if (cameraSettings) {\r\n this._graphicsContext.save();\r\n this._camera.draw(this._graphicsContext);\r\n if (cameraSettings.showAll || cameraSettings.showFocus) {\r\n this._graphicsContext.drawCircle(this._camera.pos, 4, cameraSettings.focusColor);\r\n }\r\n if (cameraSettings.showAll || cameraSettings.showZoom) {\r\n this._graphicsContext.debug.drawText(`zoom(${this._camera.zoom})`, this._camera.pos);\r\n }\r\n this._graphicsContext.restore();\r\n }\r\n\r\n this._graphicsContext.flush();\r\n }\r\n\r\n /**\r\n * This applies the current entity transform to the graphics context\r\n * @param entity\r\n */\r\n private _applyTransform(entity: Entity): void {\r\n const ancestors = entity.getAncestors();\r\n for (const ancestor of ancestors) {\r\n const transform = ancestor?.get(TransformComponent);\r\n if (transform) {\r\n this._graphicsContext.translate(transform.pos.x, transform.pos.y);\r\n this._graphicsContext.scale(transform.scale.x, transform.scale.y);\r\n this._graphicsContext.rotate(transform.rotation);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Applies the current camera transform if in world coordinates\r\n * @param transform\r\n */\r\n private _pushCameraTransform(transform: TransformComponent) {\r\n // Establish camera offset per entity\r\n if (transform.coordPlane === CoordPlane.World) {\r\n this._graphicsContext.save();\r\n if (this._camera) {\r\n this._camera.draw(this._graphicsContext);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Resets the current camera transform if in world coordinates\r\n * @param transform\r\n */\r\n private _popCameraTransform(transform: TransformComponent) {\r\n if (transform.coordPlane === CoordPlane.World) {\r\n // Apply camera world offset\r\n this._graphicsContext.restore();\r\n }\r\n }\r\n}\r\n","import { ColliderComponent } from '../Collision/ColliderComponent';\r\nimport { Engine } from '../Engine';\r\nimport {\r\n System,\r\n TransformComponent,\r\n SystemType,\r\n Entity,\r\n AddedEntity,\r\n RemovedEntity,\r\n isAddedSystemEntity\r\n} from '../EntityComponentSystem';\r\nimport { GraphicsComponent } from '../Graphics/GraphicsComponent';\r\nimport { Scene } from '../Scene';\r\nimport { PointerComponent } from './PointerComponent';\r\nimport { PointerEventReceiver } from './PointerEventReceiver';\r\nimport { PointerEvent } from './PointerEvent';\r\nimport { CoordPlane } from '../Math/coord-plane';\r\n\r\n/**\r\n * The PointerSystem is responsible for dispatching pointer events to entities\r\n * that need them.\r\n *\r\n * The PointerSystem can be optionally configured by the [[PointerComponent]], by default Entities use\r\n * the [[Collider]]'s shape for pointer events.\r\n */\r\nexport class PointerSystem extends System {\r\n public readonly types = ['ex.transform', 'ex.pointer'] as const;\r\n public readonly systemType = SystemType.Update;\r\n public priority = -1;\r\n\r\n private _engine: Engine;\r\n private _receiver: PointerEventReceiver;\r\n\r\n /**\r\n * Optionally override component configuration for all entities\r\n */\r\n public overrideUseColliderShape = false;\r\n /**\r\n * Optionally override component configuration for all entities\r\n */\r\n public overrideUseGraphicsBounds = false;\r\n\r\n public lastFrameEntityToPointers = new Map();\r\n public currentFrameEntityToPointers = new Map();\r\n\r\n public initialize(scene: Scene): void {\r\n this._engine = scene.engine;\r\n }\r\n\r\n private _sortedTransforms: TransformComponent[] = [];\r\n private _sortedEntities: Entity[] = [];\r\n\r\n private _zHasChanged = false;\r\n private _zIndexUpdate = () => {\r\n this._zHasChanged = true;\r\n };\r\n\r\n public preupdate(): void {\r\n // event receiver might change per frame\r\n this._receiver = this._engine.input.pointers;\r\n if (this._zHasChanged) {\r\n this._sortedTransforms.sort((a, b) => {\r\n return b.z - a.z;\r\n });\r\n this._sortedEntities = this._sortedTransforms.map(t => t.owner);\r\n this._zHasChanged = false;\r\n }\r\n }\r\n\r\n public notify(entityAddedOrRemoved: AddedEntity | RemovedEntity): void {\r\n if (isAddedSystemEntity(entityAddedOrRemoved)) {\r\n const tx = entityAddedOrRemoved.data.get(TransformComponent);\r\n this._sortedTransforms.push(tx);\r\n this._sortedEntities.push(tx.owner);\r\n tx.zIndexChanged$.subscribe(this._zIndexUpdate);\r\n this._zHasChanged = true;\r\n } else {\r\n const tx = entityAddedOrRemoved.data.get(TransformComponent);\r\n tx.zIndexChanged$.unsubscribe(this._zIndexUpdate);\r\n const index = this._sortedTransforms.indexOf(tx);\r\n if (index > -1) {\r\n this._sortedTransforms.splice(index, 1);\r\n this._sortedEntities.splice(index, 1);\r\n }\r\n }\r\n }\r\n\r\n public entityCurrentlyUnderPointer(entity: Entity, pointerId: number) {\r\n return this.currentFrameEntityToPointers.has(entity.id) &&\r\n this.currentFrameEntityToPointers.get(entity.id).includes(pointerId);\r\n }\r\n\r\n public entityWasUnderPointer(entity: Entity, pointerId: number) {\r\n return this.lastFrameEntityToPointers.has(entity.id) &&\r\n this.lastFrameEntityToPointers.get(entity.id).includes(pointerId);\r\n }\r\n\r\n public entered(entity: Entity, pointerId: number) {\r\n return this.entityCurrentlyUnderPointer(entity, pointerId) &&\r\n !this.lastFrameEntityToPointers.has(entity.id);\r\n }\r\n\r\n public left(entity: Entity, pointerId: number) {\r\n return !this.currentFrameEntityToPointers.has(entity.id) &&\r\n this.entityWasUnderPointer(entity, pointerId);\r\n }\r\n\r\n public addPointerToEntity(entity: Entity, pointerId: number) {\r\n if (!this.currentFrameEntityToPointers.has(entity.id)) {\r\n this.currentFrameEntityToPointers.set(entity.id, [pointerId]);\r\n return;\r\n }\r\n const pointers = this.currentFrameEntityToPointers.get(entity.id);\r\n this.currentFrameEntityToPointers.set(entity.id, pointers.concat(pointerId));\r\n }\r\n\r\n public update(_entities: Entity[]): void {\r\n // Locate all the pointer/entity mappings\r\n this._processPointerToEntity(this._sortedEntities);\r\n\r\n // Dispatch pointer events on entities\r\n this._dispatchEvents(this._sortedEntities);\r\n\r\n // Clear last frame's events\r\n this._receiver.update();\r\n this.lastFrameEntityToPointers.clear();\r\n this.lastFrameEntityToPointers = new Map(this.currentFrameEntityToPointers);\r\n this.currentFrameEntityToPointers.clear();\r\n this._receiver.clear();\r\n }\r\n\r\n private _processPointerToEntity(entities: Entity[]) {\r\n let transform: TransformComponent;\r\n let collider: ColliderComponent;\r\n let graphics: GraphicsComponent;\r\n let pointer: PointerComponent;\r\n\r\n // TODO probably a spatial partition optimization here to quickly query bounds for pointer\r\n // doesn't seem to cause issues tho for perf\r\n\r\n // Pre-process find entities under pointers\r\n for (const entity of entities) {\r\n transform = entity.get(TransformComponent);\r\n pointer = entity.get(PointerComponent) ?? new PointerComponent;\r\n // Check collider contains pointer\r\n collider = entity.get(ColliderComponent);\r\n if (collider && (pointer.useColliderShape || this.overrideUseColliderShape)) {\r\n collider.update();\r\n const geom = collider.get();\r\n if (geom) {\r\n for (const [pointerId, pos] of this._receiver.currentFramePointerCoords.entries()) {\r\n if (geom.contains(transform.coordPlane === CoordPlane.World ? pos.worldPos : pos.screenPos)) {\r\n this.addPointerToEntity(entity, pointerId);\r\n }\r\n }\r\n }\r\n }\r\n\r\n // Check graphics contains pointer\r\n graphics = entity.get(GraphicsComponent);\r\n if (graphics && (pointer.useGraphicsBounds || this.overrideUseGraphicsBounds)) {\r\n const graphicBounds = graphics.localBounds.transform(transform.get().matrix);\r\n for (const [pointerId, pos] of this._receiver.currentFramePointerCoords.entries()) {\r\n if (graphicBounds.contains(transform.coordPlane === CoordPlane.World ? pos.worldPos : pos.screenPos)) {\r\n this.addPointerToEntity(entity, pointerId);\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n private _processDownAndEmit(entity: Entity): Map {\r\n const lastDownPerPointer = new Map();\r\n // Loop through down and dispatch to entities\r\n for (const event of this._receiver.currentFrameDown) {\r\n if (event.active && entity.active && this.entityCurrentlyUnderPointer(entity, event.pointerId)) {\r\n entity.events.emit('pointerdown', event as any);\r\n if (this._receiver.isDragStart(event.pointerId)) {\r\n entity.events.emit('pointerdragstart', event as any);\r\n }\r\n }\r\n lastDownPerPointer.set(event.pointerId, event);\r\n }\r\n return lastDownPerPointer;\r\n }\r\n\r\n private _processUpAndEmit(entity: Entity): Map {\r\n const lastUpPerPointer = new Map();\r\n // Loop through up and dispatch to entities\r\n for (const event of this._receiver.currentFrameUp) {\r\n if (event.active && entity.active && this.entityCurrentlyUnderPointer(entity, event.pointerId)) {\r\n entity.events.emit('pointerup', event as any);\r\n if (this._receiver.isDragEnd(event.pointerId)) {\r\n entity.events.emit('pointerdragend', event as any);\r\n }\r\n }\r\n lastUpPerPointer.set(event.pointerId, event);\r\n }\r\n return lastUpPerPointer;\r\n }\r\n\r\n private _processMoveAndEmit(entity: Entity): Map {\r\n const lastMovePerPointer = new Map();\r\n // Loop through move and dispatch to entities\r\n for (const event of this._receiver.currentFrameMove) {\r\n if (event.active && entity.active && this.entityCurrentlyUnderPointer(entity, event.pointerId)) {\r\n // move\r\n entity.events.emit('pointermove', event as any);\r\n\r\n if (this._receiver.isDragging(event.pointerId)) {\r\n entity.events.emit('pointerdragmove', event as any);\r\n }\r\n }\r\n lastMovePerPointer.set(event.pointerId, event);\r\n }\r\n return lastMovePerPointer;\r\n }\r\n\r\n private _processEnterLeaveAndEmit(entity: Entity, lastUpDownMoveEvents: PointerEvent[]) {\r\n // up, down, and move are considered for enter and leave\r\n for (const event of lastUpDownMoveEvents) {\r\n // enter\r\n if (event.active && entity.active && this.entered(entity, event.pointerId)) {\r\n entity.events.emit('pointerenter', event as any);\r\n if (this._receiver.isDragging(event.pointerId)) {\r\n entity.events.emit('pointerdragenter', event as any);\r\n }\r\n break;\r\n }\r\n if (event.active && entity.active &&\r\n // leave can happen on move\r\n (this.left(entity, event.pointerId) ||\r\n // or leave can happen on pointer up\r\n (this.entityCurrentlyUnderPointer(entity, event.pointerId) && event.type === 'up'))) {\r\n entity.events.emit('pointerleave', event as any);\r\n if (this._receiver.isDragging(event.pointerId)) {\r\n entity.events.emit('pointerdragleave', event as any);\r\n }\r\n break;\r\n }\r\n }\r\n }\r\n\r\n private _processCancelAndEmit(entity: Entity) {\r\n // cancel\r\n for (const event of this._receiver.currentFrameCancel) {\r\n if (event.active && entity.active && this.entityCurrentlyUnderPointer(entity, event.pointerId)){\r\n entity.events.emit('pointercancel', event as any);\r\n }\r\n }\r\n }\r\n\r\n private _processWheelAndEmit(entity: Entity) {\r\n // wheel\r\n for (const event of this._receiver.currentFrameWheel) {\r\n // Currently the wheel only fires under the primary pointer '0'\r\n if (event.active && entity.active && this.entityCurrentlyUnderPointer(entity, 0)) {\r\n entity.events.emit('pointerwheel', event as any);\r\n }\r\n }\r\n }\r\n\r\n private _dispatchEvents(entities: Entity[]) {\r\n const lastFrameEntities = new Set(this.lastFrameEntityToPointers.keys());\r\n const currentFrameEntities = new Set(this.currentFrameEntityToPointers.keys());\r\n // Filter preserves z order\r\n const entitiesWithEvents = entities.filter(e => lastFrameEntities.has(e.id) || currentFrameEntities.has(e.id));\r\n let lastMovePerPointer: Map;\r\n let lastUpPerPointer: Map;\r\n let lastDownPerPointer: Map;\r\n // Dispatch events in entity z order\r\n for (const entity of entitiesWithEvents) {\r\n lastDownPerPointer = this._processDownAndEmit(entity);\r\n\r\n lastUpPerPointer = this._processUpAndEmit(entity);\r\n\r\n lastMovePerPointer = this._processMoveAndEmit(entity);\r\n\r\n const lastUpDownMoveEvents = [\r\n ...lastMovePerPointer.values(),\r\n ...lastDownPerPointer.values(),\r\n ...lastUpPerPointer.values()\r\n ];\r\n this._processEnterLeaveAndEmit(entity, lastUpDownMoveEvents);\r\n\r\n this._processCancelAndEmit(entity);\r\n\r\n this._processWheelAndEmit(entity);\r\n }\r\n }\r\n}","import { Entity } from '../EntityComponentSystem';\r\nimport { AddedEntity, isAddedSystemEntity, RemovedEntity, System, SystemType } from '../EntityComponentSystem/System';\r\nimport { ActionsComponent } from './ActionsComponent';\r\n\r\n\r\nexport class ActionsSystem extends System {\r\n public readonly types = ['ex.actions'] as const;\r\n systemType = SystemType.Update;\r\n priority = -1;\r\n\r\n private _actions: ActionsComponent[] = [];\r\n public notify(entityAddedOrRemoved: AddedEntity | RemovedEntity): void {\r\n if (isAddedSystemEntity(entityAddedOrRemoved)) {\r\n const action = entityAddedOrRemoved.data.get(ActionsComponent);\r\n this._actions.push(action);\r\n } else {\r\n const action = entityAddedOrRemoved.data.get(ActionsComponent);\r\n const index = this._actions.indexOf(action);\r\n if (index > -1) {\r\n this._actions.splice(index, 1);\r\n }\r\n }\r\n }\r\n\r\n update(_entities: Entity[], delta: number): void {\r\n for (const actions of this._actions) {\r\n actions.update(delta);\r\n }\r\n }\r\n}","import { Component } from '../EntityComponentSystem/Component';\r\nimport { IsometricMap } from './IsometricMap';\r\n\r\nexport class IsometricEntityComponent extends Component<'ex.isometricentity'> {\r\n public readonly type = 'ex.isometricentity';\r\n /**\r\n * Vertical \"height\" in the isometric world\r\n */\r\n public elevation: number = 0;\r\n\r\n public map: IsometricMap;\r\n\r\n /**\r\n * Specify the isometric map to use to position this entity's z-index\r\n * @param map\r\n */\r\n constructor(map: IsometricMap) {\r\n super();\r\n this.map = map;\r\n }\r\n}","import { System, SystemType } from '../EntityComponentSystem/System';\r\nimport { Entity } from '../EntityComponentSystem/Entity';\r\nimport { TransformComponent } from '../EntityComponentSystem/Components/TransformComponent';\r\nimport { IsometricEntityComponent } from './IsometricEntityComponent';\r\n\r\n\r\nexport class IsometricEntitySystem extends System {\r\n public readonly types = ['ex.transform', 'ex.isometricentity'] as const;\r\n public readonly systemType = SystemType.Update;\r\n priority: number = 99;\r\n update(entities: Entity[], _delta: number): void {\r\n let transform: TransformComponent;\r\n let iso: IsometricEntityComponent;\r\n for (const entity of entities) {\r\n transform = entity.get(TransformComponent);\r\n iso = entity.get(IsometricEntityComponent);\r\n\r\n const maxZindexPerElevation = Math.max(iso.map.columns * iso.map.tileWidth, iso.map.rows * iso.map.tileHeight);\r\n\r\n const newZ = maxZindexPerElevation * iso.elevation + transform.pos.y;\r\n transform.z = newZ;\r\n }\r\n }\r\n}","import { GraphicsComponent } from './GraphicsComponent';\r\nimport { EnterViewPortEvent, ExitViewPortEvent } from '../Events';\r\nimport { Scene } from '../Scene';\r\nimport { Screen } from '../Screen';\r\nimport { Entity } from '../EntityComponentSystem/Entity';\r\nimport { TransformComponent } from '../EntityComponentSystem/Components/TransformComponent';\r\nimport { Camera } from '../Camera';\r\nimport { System, SystemType } from '../EntityComponentSystem/System';\r\nimport { ParallaxComponent } from './ParallaxComponent';\r\nimport { Vector } from '../Math/vector';\r\nimport { CoordPlane } from '../Math/coord-plane';\r\nimport { BoundingBox } from '../Collision/BoundingBox';\r\n\r\nexport class OffscreenSystem extends System {\r\n public readonly types = ['ex.transform', 'ex.graphics'] as const;\r\n public systemType = SystemType.Draw;\r\n priority: number = -1;\r\n private _camera: Camera;\r\n private _screen: Screen;\r\n private _worldBounds: BoundingBox;\r\n\r\n public initialize(scene: Scene): void {\r\n this._camera = scene.camera;\r\n this._screen = scene.engine.screen;\r\n }\r\n\r\n update(entities: Entity[]): void {\r\n this._worldBounds = this._screen.getWorldBounds();\r\n let transform: TransformComponent;\r\n let graphics: GraphicsComponent;\r\n let maybeParallax: ParallaxComponent;\r\n\r\n for (const entity of entities) {\r\n graphics = entity.get(GraphicsComponent);\r\n transform = entity.get(TransformComponent);\r\n maybeParallax = entity.get(ParallaxComponent);\r\n\r\n let parallaxOffset: Vector;\r\n if (maybeParallax) {\r\n // We use the Tiled formula\r\n // https://doc.mapeditor.org/en/latest/manual/layers/#parallax-scrolling-factor\r\n // cameraPos * (1 - parallaxFactor)\r\n const oneMinusFactor = Vector.One.sub(maybeParallax.parallaxFactor);\r\n parallaxOffset = this._camera.pos.scale(oneMinusFactor);\r\n }\r\n\r\n // Figure out if entities are offscreen\r\n const entityOffscreen = this._isOffscreen(transform, graphics, parallaxOffset);\r\n if (entityOffscreen && !entity.hasTag('ex.offscreen')) {\r\n entity.events.emit('exitviewport', new ExitViewPortEvent(entity));\r\n entity.addTag('ex.offscreen');\r\n }\r\n\r\n if (!entityOffscreen && entity.hasTag('ex.offscreen')) {\r\n entity.events.emit('enterviewport', new EnterViewPortEvent(entity));\r\n entity.removeTag('ex.offscreen');\r\n }\r\n }\r\n }\r\n\r\n private _isOffscreen(transform: TransformComponent, graphics: GraphicsComponent, parallaxOffset: Vector) {\r\n if (transform.coordPlane === CoordPlane.World) {\r\n let bounds = graphics.localBounds;\r\n if (parallaxOffset) {\r\n bounds = bounds.translate(parallaxOffset);\r\n }\r\n const transformedBounds = bounds.transform(transform.get().matrix);\r\n const graphicsOffscreen = !this._worldBounds.overlaps(transformedBounds);\r\n return graphicsOffscreen;\r\n } else {\r\n // TODO screen coordinates\r\n return false;\r\n }\r\n }\r\n\r\n}","import { Ray } from '../Math/ray';\r\nimport { DynamicTreeCollisionProcessor, RayCastHit, RayCastOptions } from './Index';\r\n\r\n\r\nexport class PhysicsWorld {\r\n public collisionProcessor: DynamicTreeCollisionProcessor;\r\n constructor() {\r\n this.collisionProcessor = new DynamicTreeCollisionProcessor();\r\n }\r\n\r\n public rayCast(ray: Ray, options?: RayCastOptions): RayCastHit[] {\r\n return this.collisionProcessor.rayCast(ray, options);\r\n }\r\n}","import { isScreenElement, ScreenElement } from './ScreenElement';\r\nimport {\r\n InitializeEvent,\r\n ActivateEvent,\r\n DeactivateEvent,\r\n PreUpdateEvent,\r\n PostUpdateEvent,\r\n PreDrawEvent,\r\n PostDrawEvent,\r\n PreDebugDrawEvent,\r\n PostDebugDrawEvent\r\n} from './Events';\r\nimport { Logger } from './Util/Log';\r\nimport { Timer } from './Timer';\r\nimport { Engine } from './Engine';\r\nimport { TileMap } from './TileMap';\r\nimport { Camera } from './Camera';\r\nimport { Actor } from './Actor';\r\nimport { CanInitialize, CanActivate, CanDeactivate, CanUpdate, CanDraw, SceneActivationContext } from './Interfaces/LifecycleEvents';\r\nimport * as Util from './Util/Util';\r\nimport { Trigger } from './Trigger';\r\nimport { SystemType } from './EntityComponentSystem/System';\r\nimport { World } from './EntityComponentSystem/World';\r\nimport { MotionSystem } from './Collision/MotionSystem';\r\nimport { CollisionSystem } from './Collision/CollisionSystem';\r\nimport { Entity } from './EntityComponentSystem/Entity';\r\nimport { GraphicsSystem } from './Graphics/GraphicsSystem';\r\nimport { DebugSystem } from './Debug/DebugSystem';\r\nimport { PointerSystem } from './Input/PointerSystem';\r\nimport { ActionsSystem } from './Actions/ActionsSystem';\r\nimport { IsometricEntitySystem } from './TileMap/IsometricEntitySystem';\r\nimport { OffscreenSystem } from './Graphics/OffscreenSystem';\r\nimport { ExcaliburGraphicsContext } from './Graphics';\r\nimport { PhysicsWorld } from './Collision/PhysicsWorld';\r\nimport { EventEmitter, EventKey, Handler, Subscription } from './EventEmitter';\r\n\r\nexport type SceneEvents = {\r\n initialize: InitializeEvent,\r\n activate: ActivateEvent,\r\n deactivate: DeactivateEvent,\r\n preupdate: PreUpdateEvent,\r\n postupdate: PostUpdateEvent,\r\n predraw: PreDrawEvent,\r\n postdraw: PostDrawEvent,\r\n predebugdraw: PreDebugDrawEvent,\r\n postdebugdraw: PostDebugDrawEvent\r\n}\r\n\r\nexport const SceneEvents = {\r\n Initialize: 'initialize',\r\n Activate: 'activate',\r\n Deactivate: 'deactivate',\r\n PreUpdate: 'preupdate',\r\n PostUpdate: 'postupdate',\r\n PreDraw: 'predraw',\r\n PostDraw: 'postdraw',\r\n PreDebugDraw: 'predebugdraw',\r\n PostDebugDraw: 'postdebugdraw'\r\n};\r\n\r\n/**\r\n * [[Actor|Actors]] are composed together into groupings called Scenes in\r\n * Excalibur. The metaphor models the same idea behind real world\r\n * actors in a scene. Only actors in scenes will be updated and drawn.\r\n *\r\n * Typical usages of a scene include: levels, menus, loading screens, etc.\r\n */\r\nexport class Scene\r\nimplements CanInitialize, CanActivate, CanDeactivate, CanUpdate, CanDraw {\r\n private _logger: Logger = Logger.getInstance();\r\n public events = new EventEmitter();\r\n\r\n /**\r\n * Gets or sets the current camera for the scene\r\n */\r\n public camera: Camera = new Camera();\r\n\r\n /**\r\n * The ECS world for the scene\r\n */\r\n public world = new World(this);\r\n\r\n /**\r\n * The Excalibur physics world for the scene. Used to interact\r\n * with colliders included in the scene.\r\n *\r\n * Can be used to perform scene ray casts, track colliders, broadphase, and narrowphase.\r\n */\r\n public physics = new PhysicsWorld();\r\n\r\n /**\r\n * The actors in the current scene\r\n */\r\n public get actors(): readonly Actor[] {\r\n return this.world.entityManager.entities.filter((e) => {\r\n return e instanceof Actor;\r\n }) as Actor[];\r\n }\r\n\r\n /**\r\n * The entities in the current scene\r\n */\r\n public get entities(): readonly Entity[] {\r\n return this.world.entityManager.entities;\r\n }\r\n\r\n /**\r\n * The triggers in the current scene\r\n */\r\n public get triggers(): readonly Trigger[] {\r\n return this.world.entityManager.entities.filter((e) => {\r\n return e instanceof Trigger;\r\n }) as Trigger[];\r\n }\r\n\r\n /**\r\n * The [[TileMap]]s in the scene, if any\r\n */\r\n public get tileMaps(): readonly TileMap[] {\r\n return this.world.entityManager.entities.filter((e) => {\r\n return e instanceof TileMap;\r\n }) as TileMap[];\r\n }\r\n\r\n /**\r\n * Access to the Excalibur engine\r\n */\r\n public engine: Engine;\r\n\r\n private _isInitialized: boolean = false;\r\n private _timers: Timer[] = [];\r\n public get timers(): readonly Timer[] {\r\n return this._timers;\r\n }\r\n private _cancelQueue: Timer[] = [];\r\n\r\n constructor() {\r\n // Initialize systems\r\n\r\n // Update\r\n this.world.add(new ActionsSystem());\r\n this.world.add(new MotionSystem());\r\n this.world.add(new CollisionSystem(this.physics));\r\n this.world.add(new PointerSystem());\r\n this.world.add(new IsometricEntitySystem());\r\n // Draw\r\n this.world.add(new OffscreenSystem());\r\n this.world.add(new GraphicsSystem());\r\n this.world.add(new DebugSystem());\r\n }\r\n\r\n public emit>(eventName: TEventName, event: SceneEvents[TEventName]): void;\r\n public emit(eventName: string, event?: any): void;\r\n public emit | string>(eventName: TEventName, event?: any): void {\r\n this.events.emit(eventName, event);\r\n }\r\n\r\n public on>(eventName: TEventName, handler: Handler): Subscription;\r\n public on(eventName: string, handler: Handler): Subscription;\r\n public on | string>(eventName: TEventName, handler: Handler): Subscription {\r\n return this.events.on(eventName, handler);\r\n }\r\n\r\n public once>(eventName: TEventName, handler: Handler): Subscription;\r\n public once(eventName: string, handler: Handler): Subscription;\r\n public once | string>(eventName: TEventName, handler: Handler): Subscription {\r\n return this.events.once(eventName, handler);\r\n }\r\n\r\n public off>(eventName: TEventName, handler: Handler): void;\r\n public off(eventName: string, handler: Handler): void;\r\n public off(eventName: string): void;\r\n public off | string>(eventName: TEventName, handler?: Handler): void {\r\n this.events.off(eventName, handler);\r\n }\r\n\r\n /**\r\n * This is called before the first update of the [[Scene]]. Initializes scene members like the camera. This method is meant to be\r\n * overridden. This is where initialization of child actors should take place.\r\n */\r\n public onInitialize(_engine: Engine): void {\r\n // will be overridden\r\n }\r\n\r\n /**\r\n * This is called when the scene is made active and started. It is meant to be overridden,\r\n * this is where you should setup any DOM UI or event handlers needed for the scene.\r\n */\r\n public onActivate(_context: SceneActivationContext): void {\r\n // will be overridden\r\n }\r\n\r\n /**\r\n * This is called when the scene is made transitioned away from and stopped. It is meant to be overridden,\r\n * this is where you should cleanup any DOM UI or event handlers needed for the scene.\r\n */\r\n public onDeactivate(_context: SceneActivationContext): void {\r\n // will be overridden\r\n }\r\n\r\n /**\r\n * Safe to override onPreUpdate lifecycle event handler. Synonymous with `.on('preupdate', (evt) =>{...})`\r\n *\r\n * `onPreUpdate` is called directly before a scene is updated.\r\n */\r\n public onPreUpdate(_engine: Engine, _delta: number): void {\r\n // will be overridden\r\n }\r\n\r\n /**\r\n * Safe to override onPostUpdate lifecycle event handler. Synonymous with `.on('preupdate', (evt) =>{...})`\r\n *\r\n * `onPostUpdate` is called directly after a scene is updated.\r\n */\r\n public onPostUpdate(_engine: Engine, _delta: number): void {\r\n // will be overridden\r\n }\r\n\r\n /**\r\n * Safe to override onPreDraw lifecycle event handler. Synonymous with `.on('preupdate', (evt) =>{...})`\r\n *\r\n * `onPreDraw` is called directly before a scene is drawn.\r\n *\r\n */\r\n public onPreDraw(_ctx: ExcaliburGraphicsContext, _delta: number): void {\r\n // will be overridden\r\n }\r\n\r\n /**\r\n * Safe to override onPostDraw lifecycle event handler. Synonymous with `.on('preupdate', (evt) =>{...})`\r\n *\r\n * `onPostDraw` is called directly after a scene is drawn.\r\n *\r\n */\r\n public onPostDraw(_ctx: ExcaliburGraphicsContext, _delta: number): void {\r\n // will be overridden\r\n }\r\n\r\n /**\r\n * Initializes actors in the scene\r\n */\r\n private _initializeChildren(): void {\r\n for (const child of this.entities) {\r\n child._initialize(this.engine);\r\n }\r\n }\r\n\r\n /**\r\n * Gets whether or not the [[Scene]] has been initialized\r\n */\r\n public get isInitialized(): boolean {\r\n return this._isInitialized;\r\n }\r\n\r\n /**\r\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\r\n *\r\n * Initializes the scene before the first update, meant to be called by engine not by users of\r\n * Excalibur\r\n * @internal\r\n */\r\n public _initialize(engine: Engine) {\r\n if (!this.isInitialized) {\r\n this.engine = engine;\r\n // Initialize camera first\r\n this.camera._initialize(engine);\r\n\r\n this.world.systemManager.initialize();\r\n\r\n // This order is important! we want to be sure any custom init that add actors\r\n // fire before the actor init\r\n this.onInitialize.call(this, engine);\r\n this._initializeChildren();\r\n\r\n this._logger.debug('Scene.onInitialize', this, engine);\r\n this.events.emit('initialize', new InitializeEvent(engine, this));\r\n this._isInitialized = true;\r\n }\r\n }\r\n\r\n /**\r\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\r\n *\r\n * Activates the scene with the base behavior, then calls the overridable `onActivate` implementation.\r\n * @internal\r\n */\r\n public _activate(context: SceneActivationContext): void {\r\n this._logger.debug('Scene.onActivate', this);\r\n this.onActivate(context);\r\n }\r\n\r\n /**\r\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\r\n *\r\n * Deactivates the scene with the base behavior, then calls the overridable `onDeactivate` implementation.\r\n * @internal\r\n */\r\n public _deactivate(context: SceneActivationContext): void {\r\n this._logger.debug('Scene.onDeactivate', this);\r\n this.onDeactivate(context);\r\n }\r\n\r\n /**\r\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\r\n *\r\n * Internal _preupdate handler for [[onPreUpdate]] lifecycle event\r\n * @internal\r\n */\r\n public _preupdate(_engine: Engine, delta: number): void {\r\n this.emit('preupdate', new PreUpdateEvent(_engine, delta, this));\r\n this.onPreUpdate(_engine, delta);\r\n }\r\n\r\n /**\r\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\r\n *\r\n * Internal _preupdate handler for [[onPostUpdate]] lifecycle event\r\n * @internal\r\n */\r\n public _postupdate(_engine: Engine, delta: number): void {\r\n this.emit('postupdate', new PostUpdateEvent(_engine, delta, this));\r\n this.onPostUpdate(_engine, delta);\r\n }\r\n\r\n /**\r\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\r\n *\r\n * Internal _predraw handler for [[onPreDraw]] lifecycle event\r\n *\r\n * @internal\r\n */\r\n public _predraw(_ctx: ExcaliburGraphicsContext, _delta: number): void {\r\n this.emit('predraw', new PreDrawEvent(_ctx, _delta, this));\r\n this.onPreDraw(_ctx, _delta);\r\n }\r\n\r\n /**\r\n * It is not recommended that internal excalibur methods be overridden, do so at your own risk.\r\n *\r\n * Internal _postdraw handler for [[onPostDraw]] lifecycle event\r\n *\r\n * @internal\r\n */\r\n public _postdraw(_ctx: ExcaliburGraphicsContext, _delta: number): void {\r\n this.emit('postdraw', new PostDrawEvent(_ctx, _delta, this));\r\n this.onPostDraw(_ctx, _delta);\r\n }\r\n\r\n /**\r\n * Updates all the actors and timers in the scene. Called by the [[Engine]].\r\n * @param engine Reference to the current Engine\r\n * @param delta The number of milliseconds since the last update\r\n */\r\n public update(engine: Engine, delta: number) {\r\n this._preupdate(engine, delta);\r\n\r\n // TODO differed entity removal for timers\r\n let i: number, len: number;\r\n // Remove timers in the cancel queue before updating them\r\n for (i = 0, len = this._cancelQueue.length; i < len; i++) {\r\n this.removeTimer(this._cancelQueue[i]);\r\n }\r\n this._cancelQueue.length = 0;\r\n\r\n // Cycle through timers updating timers\r\n for (const timer of this._timers) {\r\n timer.update(delta);\r\n }\r\n\r\n this.world.update(SystemType.Update, delta);\r\n\r\n // Camera last keeps renders smooth that are based on entity/actor\r\n if (this.camera) {\r\n this.camera.update(engine, delta);\r\n }\r\n\r\n this._collectActorStats(engine);\r\n\r\n this._postupdate(engine, delta);\r\n }\r\n\r\n /**\r\n * Draws all the actors in the Scene. Called by the [[Engine]].\r\n *\r\n * @param ctx The current rendering context\r\n * @param delta The number of milliseconds since the last draw\r\n */\r\n public draw(ctx: ExcaliburGraphicsContext, delta: number) {\r\n this._predraw(ctx, delta);\r\n\r\n this.world.update(SystemType.Draw, delta);\r\n\r\n if (this.engine?.isDebug) {\r\n this.debugDraw(ctx);\r\n }\r\n this._postdraw(ctx, delta);\r\n }\r\n\r\n /**\r\n * Draws all the actors' debug information in the Scene. Called by the [[Engine]].\r\n * @param ctx The current rendering context\r\n */\r\n /* istanbul ignore next */\r\n public debugDraw(ctx: ExcaliburGraphicsContext) {\r\n this.emit('predebugdraw', new PreDebugDrawEvent(ctx, this));\r\n // pass\r\n this.emit('postdebugdraw', new PostDebugDrawEvent(ctx, this));\r\n }\r\n\r\n /**\r\n * Checks whether an actor is contained in this scene or not\r\n */\r\n public contains(actor: Actor): boolean {\r\n return this.actors.indexOf(actor) > -1;\r\n }\r\n\r\n /**\r\n * Adds a [[Timer]] to the current [[Scene]].\r\n * @param timer The timer to add to the current [[Scene]].\r\n */\r\n public add(timer: Timer): void;\r\n\r\n /**\r\n * Adds a [[TileMap]] to the [[Scene]], once this is done the [[TileMap]] will be drawn and updated.\r\n */\r\n public add(tileMap: TileMap): void;\r\n\r\n /**\r\n * Adds a [[Trigger]] to the [[Scene]], once this is done the [[Trigger]] will listen for interactions with other actors.\r\n * @param trigger\r\n */\r\n public add(trigger: Trigger): void;\r\n\r\n /**\r\n * Adds an actor to the scene, once this is done the [[Actor]] will be drawn and updated.\r\n * @param actor The actor to add to the current scene\r\n */\r\n public add(actor: Actor): void;\r\n\r\n /**\r\n * Adds an [[Entity]] to the scene, once this is done the [[Actor]] will be drawn and updated.\r\n * @param entity The entity to add to the current scene\r\n */\r\n public add(entity: Entity): void;\r\n\r\n /**\r\n * Adds a [[ScreenElement]] to the scene.\r\n * @param screenElement The ScreenElement to add to the current scene\r\n */\r\n public add(screenElement: ScreenElement): void;\r\n public add(entity: any): void {\r\n this.emit('entityadded', { target: entity } as any);\r\n this.world.add(entity);\r\n entity.scene = this;\r\n if (entity instanceof Timer) {\r\n if (!Util.contains(this._timers, entity)) {\r\n this.addTimer(entity);\r\n }\r\n return;\r\n }\r\n }\r\n\r\n\r\n\r\n /**\r\n * Removes a [[Timer]] from it's current scene\r\n * and adds it to this scene.\r\n *\r\n * Useful if you want to have an object be present in only 1 scene at a time.\r\n * @param timer The Timer to transfer to the current scene\r\n */\r\n public transfer(timer: Timer): void;\r\n\r\n /**\r\n * Removes a [[TileMap]] from it's current scene\r\n * and adds it to this scene.\r\n *\r\n * Useful if you want to have an object be present in only 1 scene at a time.\r\n * @param tileMap The TileMap to transfer to the current scene\r\n */\r\n public transfer(tileMap: TileMap): void;\r\n\r\n /**\r\n * Removes a [[Trigger]] from it's current scene\r\n * and adds it to this scene.\r\n *\r\n * Useful if you want to have an object be present in only 1 scene at a time.\r\n * @param trigger The Trigger to transfer to the current scene\r\n */\r\n public transfer(trigger: Trigger): void;\r\n\r\n /**\r\n * Removes an [[Actor]] from it's current scene\r\n * and adds it to this scene.\r\n *\r\n * Useful if you want to have an object be present in only 1 scene at a time.\r\n * @param actor The Actor to transfer to the current scene\r\n */\r\n public transfer(actor: Actor): void;\r\n\r\n /**\r\n * Removes an [[Entity]] from it's current scene\r\n * and adds it to this scene.\r\n *\r\n * Useful if you want to have an object be present in only 1 scene at a time.\r\n * @param entity The Entity to transfer to the current scene\r\n */\r\n public transfer(entity: Entity): void;\r\n\r\n /**\r\n * Removes a [[ScreenElement]] from it's current scene\r\n * and adds it to this scene.\r\n *\r\n * Useful if you want to have an object be present in only 1 scene at a time.\r\n * @param screenElement The ScreenElement to transfer to the current scene\r\n */\r\n public transfer(screenElement: ScreenElement): void;\r\n\r\n /**\r\n * Removes an [[Entity]] (Actor, TileMap, Trigger, etc) or [[Timer]] from it's current scene\r\n * and adds it to this scene.\r\n *\r\n * Useful if you want to have an object be present in only 1 scene at a time.\r\n * @param entity\r\n */\r\n public transfer(entity: any): void {\r\n let scene: Scene;\r\n if (entity instanceof Entity && entity.scene && entity.scene !== this) {\r\n scene = entity.scene;\r\n entity.scene.world.remove(entity, false);\r\n }\r\n if (entity instanceof Timer && entity.scene) {\r\n scene = entity.scene;\r\n entity.scene.removeTimer(entity);\r\n }\r\n scene?.emit('entityremoved', { target: entity } as any);\r\n this.add(entity);\r\n }\r\n\r\n /**\r\n * Removes a [[Timer]] from the current scene, it will no longer be updated.\r\n * @param timer The timer to remove to the current scene.\r\n */\r\n public remove(timer: Timer): void;\r\n\r\n /**\r\n * Removes a [[TileMap]] from the scene, it will no longer be drawn or updated.\r\n * @param tileMap {TileMap}\r\n */\r\n public remove(tileMap: TileMap): void;\r\n\r\n /**\r\n * Removes an actor from the scene, it will no longer be drawn or updated.\r\n * @param actor The actor to remove from the current scene.\r\n */\r\n public remove(actor: Actor): void;\r\n\r\n public remove(entity: Entity): void;\r\n\r\n /**\r\n * Removes a [[ScreenElement]] to the scene, it will no longer be drawn or updated\r\n * @param screenElement The ScreenElement to remove from the current scene\r\n */\r\n public remove(screenElement: ScreenElement): void;\r\n public remove(entity: any): void {\r\n if (entity instanceof Entity) {\r\n this.emit('entityremoved', { target: entity } as any);\r\n if (entity.active) {\r\n entity.kill();\r\n }\r\n this.world.remove(entity);\r\n }\r\n if (entity instanceof Timer) {\r\n this.removeTimer(entity);\r\n }\r\n }\r\n\r\n /**\r\n * Removes all entities and timers from the scene, optionally indicate whether deferred should or shouldn't be used.\r\n *\r\n * By default entities use deferred removal\r\n * @param deferred\r\n */\r\n public clear(deferred: boolean = true): void {\r\n for (const entity of this.entities) {\r\n this.world.remove(entity, deferred);\r\n }\r\n for (const timer of this.timers) {\r\n this.removeTimer(timer);\r\n }\r\n }\r\n\r\n /**\r\n * Adds a [[Timer]] to the scene\r\n * @param timer The timer to add\r\n */\r\n public addTimer(timer: Timer): Timer {\r\n this._timers.push(timer);\r\n timer.scene = this;\r\n return timer;\r\n }\r\n\r\n /**\r\n * Removes a [[Timer]] from the scene.\r\n * @warning Can be dangerous, use [[cancelTimer]] instead\r\n * @param timer The timer to remove\r\n */\r\n public removeTimer(timer: Timer): Timer {\r\n const i = this._timers.indexOf(timer);\r\n if (i !== -1) {\r\n this._timers.splice(i, 1);\r\n }\r\n return timer;\r\n }\r\n\r\n /**\r\n * Cancels a [[Timer]], removing it from the scene nicely\r\n * @param timer The timer to cancel\r\n */\r\n public cancelTimer(timer: Timer): Timer {\r\n this._cancelQueue.push(timer);\r\n return timer;\r\n }\r\n\r\n /**\r\n * Tests whether a [[Timer]] is active in the scene\r\n */\r\n public isTimerActive(timer: Timer): boolean {\r\n return this._timers.indexOf(timer) > -1 && !timer.complete;\r\n }\r\n\r\n public isCurrentScene(): boolean {\r\n if (this.engine) {\r\n return this.engine.currentScene === this;\r\n }\r\n return false;\r\n }\r\n\r\n private _collectActorStats(engine: Engine) {\r\n const screenElements = this.actors.filter((a) => a instanceof ScreenElement) as ScreenElement[];\r\n for (const _ui of screenElements) {\r\n engine.stats.currFrame.actors.ui++;\r\n }\r\n\r\n for (const actor of this.actors) {\r\n engine.stats.currFrame.actors.alive++;\r\n for (const child of actor.children) {\r\n if (isScreenElement(child as Actor)) {\r\n // TODO not true\r\n engine.stats.currFrame.actors.ui++;\r\n } else {\r\n engine.stats.currFrame.actors.alive++;\r\n }\r\n }\r\n }\r\n }\r\n}\r\n","\r\n\r\nexport enum ColorBlindnessMode {\r\n Protanope = 'Protanope',\r\n Deuteranope = 'Deuteranope',\r\n Tritanope = 'Tritanope'\r\n}\r\n","export default \"#version 300 es\\r\\nprecision mediump float;\\r\\n// our texture\\r\\nuniform sampler2D u_image;\\r\\n// the texCoords passed in from the vertex shader.\\r\\nin vec2 v_texcoord;\\r\\n\\r\\n// color blind type\\r\\nuniform int u_type;\\r\\n\\r\\n// simulation?\\r\\nuniform bool u_simulate;\\r\\n\\r\\nout vec4 fragColor;\\r\\n\\r\\nvoid main() {\\r\\n vec4 o = texture(u_image, v_texcoord);\\r\\n // RGB to LMS matrix conversion\\r\\n float L = (17.8824 * o.r) + (43.5161 * o.g) + (4.11935 * o.b);\\r\\n float M = (3.45565 * o.r) + (27.1554 * o.g) + (3.86714 * o.b);\\r\\n float S = (0.0299566 * o.r) + (0.184309 * o.g) + (1.46709 * o.b);\\r\\n // Simulate color blindness\\r\\n float l;\\r\\n float m;\\r\\n float s;\\r\\n //MODE CODE//\\r\\n if (u_type == 0) {\\r\\n // Protanope\\r\\n l = 0.0 * L + 2.02344 * M + -2.52581 * S;\\r\\n m = 0.0 * L + 1.0 * M + 0.0 * S;\\r\\n s = 0.0 * L + 0.0 * M + 1.0 * S;;\\r\\n } else if (u_type == 1) {\\r\\n // Deuteranope\\r\\n l = 1.0 * L + 0.0 * M + 0.0 * S;\\r\\n m = 0.494207 * L + 0.0 * M + 1.24827 * S;\\r\\n s = 0.0 * L + 0.0 * M + 1.0 * S;\\r\\n } else if (u_type == 2) {\\r\\n // Tritanope\\r\\n l = 1.0 * L + 0.0 * M + 0.0 * S;\\r\\n m = 0.0 * L + 1.0 * M + 0.0 * S;\\r\\n s = -0.395913 * L + 0.801109 * M + 0.0 * S;\\r\\n }\\r\\n\\r\\n // LMS to RGB matrix conversion\\r\\n vec4 error; // simulate the colors\\r\\n error.r = (0.0809444479 * l) + (-0.130504409 * m) + (0.116721066 * s);\\r\\n error.g = (-0.0102485335 * l) + (0.0540193266 * m) + (-0.113614708 * s);\\r\\n error.b = (-0.000365296938 * l) + (-0.00412161469 * m) + (0.693511405 * s);\\r\\n error.a = 1.0;\\r\\n vec4 diff = o - error;\\r\\n vec4 correction; // correct the colors\\r\\n correction.r = 0.0;\\r\\n correction.g = (diff.r * 0.7) + (diff.g * 1.0);\\r\\n correction.b = (diff.r * 0.7) + (diff.b * 1.0);\\r\\n correction = o + correction;\\r\\n correction.a = o.a;\\r\\n //SIMULATE//\\r\\n\\r\\n // sim \\r\\n if (u_simulate) {\\r\\n fragColor = error.rgba;\\r\\n } else {\\r\\n fragColor = correction.rgba;\\r\\n }\\r\\n}\";","import { Shader } from '../Context/shader';\r\nimport { VertexBuffer } from '../Context/vertex-buffer';\r\nimport { VertexLayout } from '../Context/vertex-layout';\r\n\r\n/**\r\n * Helper that defines a whole screen renderer, just provide a fragment source!\r\n *\r\n * Currently supports 1 varying\r\n * - vec2 a_texcoord between 0-1 which corresponds to screen position\r\n */\r\nexport class ScreenShader {\r\n private _shader: Shader;\r\n private _buffer: VertexBuffer;\r\n private _layout: VertexLayout;\r\n constructor(gl: WebGL2RenderingContext, fragmentSource: string) {\r\n this._shader = new Shader({\r\n gl,\r\n vertexSource: `#version 300 es\r\n in vec2 a_position;\r\n in vec2 a_texcoord;\r\n out vec2 v_texcoord;\r\n\r\n void main() {\r\n gl_Position = vec4(a_position, 0.0, 1.0);\r\n // Pass the texcoord to the fragment shader.\r\n v_texcoord = a_texcoord;\r\n }`,\r\n fragmentSource: fragmentSource\r\n });\r\n this._shader.compile();\r\n // Setup memory layout\r\n this._buffer = new VertexBuffer({\r\n gl,\r\n type: 'static',\r\n // clip space quad + uv since we don't need a camera\r\n data: new Float32Array([\r\n -1, -1, 0, 0,\r\n -1, 1, 0, 1,\r\n 1, -1, 1, 0,\r\n\r\n 1, -1, 1, 0,\r\n -1, 1, 0, 1,\r\n 1, 1, 1, 1\r\n ])\r\n });\r\n this._layout = new VertexLayout({\r\n gl,\r\n shader: this._shader,\r\n vertexBuffer: this._buffer,\r\n attributes: [\r\n ['a_position', 2],\r\n ['a_texcoord', 2]\r\n ]\r\n });\r\n this._buffer.upload();\r\n }\r\n\r\n public getShader() {\r\n return this._shader;\r\n }\r\n public getLayout() {\r\n return this._layout;\r\n }\r\n}","import colorBlindCorrectSource from './color-blind-fragment.glsl';\r\nimport { PostProcessor } from './PostProcessor';\r\nimport { ColorBlindnessMode } from './ColorBlindnessMode';\r\nimport { Shader } from '../Context/shader';\r\nimport { VertexLayout } from '../Context/vertex-layout';\r\nimport { ScreenShader } from './ScreenShader';\r\n\r\nexport class ColorBlindnessPostProcessor implements PostProcessor {\r\n private _shader: ScreenShader;\r\n private _simulate = false;\r\n constructor(private _colorBlindnessMode: ColorBlindnessMode, simulate = false) {\r\n this._simulate = simulate;\r\n }\r\n\r\n initialize(gl: WebGL2RenderingContext): void {\r\n this._shader = new ScreenShader(gl, colorBlindCorrectSource);\r\n this.simulate = this._simulate;\r\n this.colorBlindnessMode = this._colorBlindnessMode;\r\n }\r\n\r\n getShader(): Shader {\r\n return this._shader.getShader();\r\n }\r\n\r\n getLayout(): VertexLayout {\r\n return this._shader.getLayout();\r\n }\r\n\r\n set colorBlindnessMode(colorBlindMode: ColorBlindnessMode) {\r\n this._colorBlindnessMode = colorBlindMode;\r\n if (this._shader) {\r\n const shader = this._shader.getShader();\r\n shader.use();\r\n if (this._colorBlindnessMode === ColorBlindnessMode.Protanope) {\r\n shader.setUniformInt('u_type', 0);\r\n } else if (this._colorBlindnessMode === ColorBlindnessMode.Deuteranope) {\r\n shader.setUniformInt('u_type', 1);\r\n } else if (this._colorBlindnessMode === ColorBlindnessMode.Tritanope) {\r\n shader.setUniformInt('u_type', 2);\r\n }\r\n }\r\n }\r\n\r\n get colorBlindnessMode(): ColorBlindnessMode {\r\n return this._colorBlindnessMode;\r\n }\r\n\r\n set simulate(value: boolean) {\r\n this._simulate = value;\r\n if (this._shader) {\r\n\r\n const shader = this._shader.getShader();\r\n shader.use();\r\n shader.setUniformBoolean('u_simulate', value);\r\n }\r\n }\r\n\r\n get simulate(): boolean {\r\n return this._simulate;\r\n }\r\n}\r\n","import { ColorBlindnessMode } from '../Graphics/PostProcessor/ColorBlindnessMode';\r\nimport { ColorBlindnessPostProcessor } from '../Graphics/PostProcessor/ColorBlindnessPostProcessor';\r\nimport { Engine } from '../Engine';\r\nimport { ExcaliburGraphicsContextWebGL } from '..';\r\n\r\nexport interface DebugFlags {\r\n colorBlindMode: ColorBlindFlags;\r\n}\r\n\r\nexport class ColorBlindFlags {\r\n private _engine: Engine;\r\n private _colorBlindPostProcessor: ColorBlindnessPostProcessor;\r\n\r\n constructor(engine: Engine) {\r\n this._engine = engine;\r\n this._colorBlindPostProcessor = new ColorBlindnessPostProcessor(ColorBlindnessMode.Protanope);\r\n }\r\n\r\n /**\r\n * Correct colors for a specified color blindness\r\n * @param colorBlindness\r\n */\r\n public correct(colorBlindness: ColorBlindnessMode) {\r\n if (this._engine.graphicsContext instanceof ExcaliburGraphicsContextWebGL) {\r\n this.clear();\r\n this._colorBlindPostProcessor.colorBlindnessMode = colorBlindness;\r\n this._colorBlindPostProcessor.simulate = false;\r\n this._engine.graphicsContext.addPostProcessor(this._colorBlindPostProcessor);\r\n }\r\n }\r\n\r\n /**\r\n * Simulate colors for a specified color blindness\r\n * @param colorBlindness\r\n */\r\n public simulate(colorBlindness: ColorBlindnessMode) {\r\n if (this._engine.graphicsContext instanceof ExcaliburGraphicsContextWebGL) {\r\n this.clear();\r\n this._colorBlindPostProcessor.colorBlindnessMode = colorBlindness;\r\n this._colorBlindPostProcessor.simulate = true;\r\n this._engine.graphicsContext.addPostProcessor(this._colorBlindPostProcessor);\r\n }\r\n }\r\n\r\n /**\r\n * Remove color blindness post processor\r\n */\r\n public clear() {\r\n this._engine.graphicsContext.removePostProcessor(this._colorBlindPostProcessor);\r\n }\r\n}\r\n","import { DebugFlags, ColorBlindFlags } from './DebugFlags';\r\nimport { Engine } from '../Engine';\r\nimport { Color } from '../Color';\r\nimport { CollisionContact } from '../Collision/Detection/CollisionContact';\r\nimport { StandardClock, TestClock } from '..';\r\n\r\n/**\r\n * Debug stats containing current and previous frame statistics\r\n */\r\nexport interface DebugStats {\r\n currFrame: FrameStats;\r\n prevFrame: FrameStats;\r\n}\r\n\r\n/**\r\n * Represents a frame's individual statistics\r\n */\r\nexport interface FrameStatistics {\r\n /**\r\n * The number of the frame\r\n */\r\n id: number;\r\n\r\n /**\r\n * Gets the frame's delta (time since last frame scaled by [[Engine.timescale]]) (in ms)\r\n */\r\n delta: number;\r\n\r\n /**\r\n * Gets the frame's frames-per-second (FPS)\r\n */\r\n fps: number;\r\n\r\n /**\r\n * Duration statistics (in ms)\r\n */\r\n duration: FrameDurationStats;\r\n\r\n /**\r\n * Actor statistics\r\n */\r\n actors: FrameActorStats;\r\n\r\n /**\r\n * Physics statistics\r\n */\r\n physics: PhysicsStatistics;\r\n\r\n /**\r\n * Graphics statistics\r\n */\r\n graphics: GraphicsStatistics;\r\n}\r\n\r\n/**\r\n * Represents actor stats for a frame\r\n */\r\nexport interface FrameActorStats {\r\n /**\r\n * Gets the frame's number of actors (alive)\r\n */\r\n alive: number;\r\n\r\n /**\r\n * Gets the frame's number of actors (killed)\r\n */\r\n killed: number;\r\n\r\n /**\r\n * Gets the frame's number of remaining actors (alive - killed)\r\n */\r\n remaining: number;\r\n\r\n /**\r\n * Gets the frame's number of UI actors\r\n */\r\n ui: number;\r\n\r\n /**\r\n * Gets the frame's number of total actors (remaining + UI)\r\n */\r\n total: number;\r\n}\r\n\r\n/**\r\n * Represents duration stats for a frame\r\n */\r\nexport interface FrameDurationStats {\r\n /**\r\n * Gets the frame's total time to run the update function (in ms)\r\n */\r\n update: number;\r\n\r\n /**\r\n * Gets the frame's total time to run the draw function (in ms)\r\n */\r\n draw: number;\r\n\r\n /**\r\n * Gets the frame's total render duration (update + draw duration) (in ms)\r\n */\r\n total: number;\r\n}\r\n\r\n/**\r\n * Represents physics stats for the current frame\r\n */\r\nexport interface PhysicsStatistics {\r\n /**\r\n * Gets the number of broadphase collision pairs which\r\n */\r\n pairs: number;\r\n\r\n /**\r\n * Gets the number of actual collisions\r\n */\r\n collisions: number;\r\n\r\n /**\r\n * Copy of the current frame contacts (only updated if debug is toggled on)\r\n */\r\n contacts: Map;\r\n\r\n /**\r\n * Gets the number of fast moving bodies using raycast continuous collisions in the scene\r\n */\r\n fastBodies: number;\r\n\r\n /**\r\n * Gets the number of bodies that had a fast body collision resolution\r\n */\r\n fastBodyCollisions: number;\r\n\r\n /**\r\n * Gets the time it took to calculate the broadphase pairs\r\n */\r\n broadphase: number;\r\n\r\n /**\r\n * Gets the time it took to calculate the narrowphase\r\n */\r\n narrowphase: number;\r\n}\r\n\r\nexport interface GraphicsStatistics {\r\n drawCalls: number;\r\n drawnImages: number;\r\n}\r\n\r\n/**\r\n * Debug statistics and flags for Excalibur. If polling these values, it would be\r\n * best to do so on the `postupdate` event for [[Engine]], after all values have been\r\n * updated during a frame.\r\n */\r\nexport class Debug implements DebugFlags {\r\n private _engine: Engine;\r\n\r\n constructor(engine: Engine) {\r\n this._engine = engine;\r\n\r\n this.colorBlindMode = new ColorBlindFlags(this._engine);\r\n }\r\n\r\n /**\r\n * Switch the current excalibur clock with the [[TestClock]] and return\r\n * it in the same running state.\r\n *\r\n * This is useful when you need to debug frame by frame.\r\n */\r\n public useTestClock(): TestClock {\r\n const clock = this._engine.clock;\r\n const wasRunning = clock.isRunning();\r\n clock.stop();\r\n\r\n const testClock = clock.toTestClock();\r\n if (wasRunning) {\r\n testClock.start();\r\n }\r\n this._engine.clock = testClock;\r\n return testClock;\r\n }\r\n\r\n /**\r\n * Switch the current excalibur clock with the [[StandardClock]] and\r\n * return it in the same running state.\r\n *\r\n * This is useful when you need to switch back to normal mode after\r\n * debugging.\r\n */\r\n public useStandardClock(): StandardClock {\r\n const currentClock = this._engine.clock;\r\n const wasRunning = currentClock.isRunning();\r\n currentClock.stop();\r\n\r\n const standardClock = currentClock.toStandardClock();\r\n if (wasRunning) {\r\n standardClock.start();\r\n }\r\n this._engine.clock = standardClock;\r\n return standardClock;\r\n }\r\n\r\n /**\r\n * Performance statistics\r\n */\r\n public stats: DebugStats = {\r\n /**\r\n * Current frame statistics. Engine reuses this instance, use [[FrameStats.clone]] to copy frame stats.\r\n * Best accessed on [[postframe]] event. See [[FrameStats]]\r\n */\r\n currFrame: new FrameStats(),\r\n\r\n /**\r\n * Previous frame statistics. Engine reuses this instance, use [[FrameStats.clone]] to copy frame stats.\r\n * Best accessed on [[preframe]] event. Best inspected on engine event `preframe`. See [[FrameStats]]\r\n */\r\n prevFrame: new FrameStats()\r\n };\r\n\r\n /**\r\n * Correct or simulate color blindness using [[ColorBlindnessPostProcessor]].\r\n * @warning Will reduce FPS.\r\n */\r\n public colorBlindMode: ColorBlindFlags;\r\n\r\n /**\r\n * Filter debug context to named entities or entity ids\r\n */\r\n public filter: { useFilter: boolean; nameQuery: string; ids: number[] } = {\r\n /**\r\n * Toggle filter on or off (default off) must be on for DebugDraw to use filters\r\n */\r\n useFilter: false,\r\n /**\r\n * Query for entities by name, if the entity name contains `nameQuery` it will be included\r\n */\r\n nameQuery: '',\r\n /**\r\n * Query for Entity ids, if the id matches it will be included\r\n */\r\n ids: []\r\n };\r\n\r\n /**\r\n * Entity debug settings\r\n */\r\n public entity = {\r\n showAll: false,\r\n showId: true,\r\n showName: false\r\n };\r\n\r\n /**\r\n * Transform component debug settings\r\n */\r\n public transform = {\r\n showAll: false,\r\n\r\n showPosition: false,\r\n showPositionLabel: false,\r\n positionColor: Color.Yellow,\r\n\r\n showZIndex: false,\r\n\r\n showScale: false,\r\n scaleColor: Color.Green,\r\n\r\n showRotation: false,\r\n rotationColor: Color.Blue\r\n };\r\n\r\n /**\r\n * Graphics component debug settings\r\n */\r\n public graphics = {\r\n showAll: false,\r\n\r\n showBounds: true,\r\n boundsColor: Color.Yellow\r\n };\r\n\r\n /**\r\n * Collider component debug settings\r\n */\r\n public collider = {\r\n showAll: false,\r\n\r\n showBounds: true,\r\n boundsColor: Color.Blue,\r\n\r\n showOwner: false,\r\n\r\n showGeometry: true,\r\n geometryColor: Color.Green\r\n };\r\n\r\n /**\r\n * Physics simulation debug settings\r\n */\r\n public physics = {\r\n showAll: false,\r\n\r\n showBroadphaseSpacePartitionDebug: false,\r\n\r\n showCollisionNormals: false,\r\n collisionNormalColor: Color.Cyan,\r\n\r\n showCollisionContacts: true,\r\n collisionContactColor: Color.Red\r\n };\r\n\r\n /**\r\n * Motion component debug settings\r\n */\r\n public motion = {\r\n showAll: false,\r\n\r\n showVelocity: false,\r\n velocityColor: Color.Yellow,\r\n\r\n showAcceleration: false,\r\n accelerationColor: Color.Red\r\n };\r\n\r\n /**\r\n * Body component debug settings\r\n */\r\n public body = {\r\n showAll: false,\r\n\r\n showCollisionGroup: false,\r\n showCollisionType: false,\r\n showSleeping: false,\r\n showMotion: false,\r\n showMass: false\r\n };\r\n\r\n /**\r\n * Camera debug settings\r\n */\r\n public camera = {\r\n showAll: false,\r\n\r\n showFocus: false,\r\n focusColor: Color.Red,\r\n\r\n showZoom: false\r\n };\r\n}\r\n\r\n/**\r\n * Implementation of a frame's stats. Meant to have values copied via [[FrameStats.reset]], avoid\r\n * creating instances of this every frame.\r\n */\r\nexport class FrameStats implements FrameStatistics {\r\n private _id: number = 0;\r\n private _delta: number = 0;\r\n private _fps: number = 0;\r\n private _actorStats: FrameActorStats = {\r\n alive: 0,\r\n killed: 0,\r\n ui: 0,\r\n get remaining() {\r\n return this.alive - this.killed;\r\n },\r\n get total() {\r\n return this.remaining + this.ui;\r\n }\r\n };\r\n private _durationStats: FrameDurationStats = {\r\n update: 0,\r\n draw: 0,\r\n get total() {\r\n return this.update + this.draw;\r\n }\r\n };\r\n\r\n private _physicsStats: PhysicsStats = new PhysicsStats();\r\n\r\n private _graphicsStats: GraphicsStatistics = {\r\n drawCalls: 0,\r\n drawnImages: 0\r\n };\r\n\r\n /**\r\n * Zero out values or clone other IFrameStat stats. Allows instance reuse.\r\n *\r\n * @param [otherStats] Optional stats to clone\r\n */\r\n public reset(otherStats?: FrameStatistics) {\r\n if (otherStats) {\r\n this.id = otherStats.id;\r\n this.delta = otherStats.delta;\r\n this.fps = otherStats.fps;\r\n this.actors.alive = otherStats.actors.alive;\r\n this.actors.killed = otherStats.actors.killed;\r\n this.actors.ui = otherStats.actors.ui;\r\n this.duration.update = otherStats.duration.update;\r\n this.duration.draw = otherStats.duration.draw;\r\n this._physicsStats.reset(otherStats.physics);\r\n this.graphics.drawCalls = otherStats.graphics.drawCalls;\r\n this.graphics.drawnImages = otherStats.graphics.drawnImages;\r\n } else {\r\n this.id = this.delta = this.fps = 0;\r\n this.actors.alive = this.actors.killed = this.actors.ui = 0;\r\n this.duration.update = this.duration.draw = 0;\r\n this._physicsStats.reset();\r\n this.graphics.drawnImages = this.graphics.drawCalls = 0;\r\n }\r\n }\r\n\r\n /**\r\n * Provides a clone of this instance.\r\n */\r\n public clone(): FrameStats {\r\n const fs = new FrameStats();\r\n\r\n fs.reset(this);\r\n\r\n return fs;\r\n }\r\n\r\n /**\r\n * Gets the frame's id\r\n */\r\n public get id() {\r\n return this._id;\r\n }\r\n\r\n /**\r\n * Sets the frame's id\r\n */\r\n public set id(value: number) {\r\n this._id = value;\r\n }\r\n\r\n /**\r\n * Gets the frame's delta (time since last frame)\r\n */\r\n public get delta() {\r\n return this._delta;\r\n }\r\n\r\n /**\r\n * Sets the frame's delta (time since last frame). Internal use only.\r\n * @internal\r\n */\r\n public set delta(value: number) {\r\n this._delta = value;\r\n }\r\n\r\n /**\r\n * Gets the frame's frames-per-second (FPS)\r\n */\r\n public get fps() {\r\n return this._fps;\r\n }\r\n\r\n /**\r\n * Sets the frame's frames-per-second (FPS). Internal use only.\r\n * @internal\r\n */\r\n public set fps(value: number) {\r\n this._fps = value;\r\n }\r\n\r\n /**\r\n * Gets the frame's actor statistics\r\n */\r\n public get actors() {\r\n return this._actorStats;\r\n }\r\n\r\n /**\r\n * Gets the frame's duration statistics\r\n */\r\n public get duration() {\r\n return this._durationStats;\r\n }\r\n\r\n /**\r\n * Gets the frame's physics statistics\r\n */\r\n public get physics() {\r\n return this._physicsStats;\r\n }\r\n\r\n /**\r\n * Gets the frame's graphics statistics\r\n */\r\n public get graphics() {\r\n return this._graphicsStats;\r\n }\r\n}\r\n\r\nexport class PhysicsStats implements PhysicsStatistics {\r\n private _pairs: number = 0;\r\n private _collisions: number = 0;\r\n private _contacts: Map = new Map();\r\n private _fastBodies: number = 0;\r\n private _fastBodyCollisions: number = 0;\r\n private _broadphase: number = 0;\r\n private _narrowphase: number = 0;\r\n\r\n /**\r\n * Zero out values or clone other IPhysicsStats stats. Allows instance reuse.\r\n *\r\n * @param [otherStats] Optional stats to clone\r\n */\r\n public reset(otherStats?: PhysicsStatistics) {\r\n if (otherStats) {\r\n this.pairs = otherStats.pairs;\r\n this.collisions = otherStats.collisions;\r\n this.contacts = otherStats.contacts;\r\n this.fastBodies = otherStats.fastBodies;\r\n this.fastBodyCollisions = otherStats.fastBodyCollisions;\r\n this.broadphase = otherStats.broadphase;\r\n this.narrowphase = otherStats.narrowphase;\r\n } else {\r\n this.pairs = this.collisions = this.fastBodies = 0;\r\n this.fastBodyCollisions = this.broadphase = this.narrowphase = 0;\r\n this.contacts.clear();\r\n }\r\n }\r\n\r\n /**\r\n * Provides a clone of this instance.\r\n */\r\n public clone(): PhysicsStatistics {\r\n const ps = new PhysicsStats();\r\n\r\n ps.reset(this);\r\n\r\n return ps;\r\n }\r\n\r\n public get pairs(): number {\r\n return this._pairs;\r\n }\r\n\r\n public set pairs(value: number) {\r\n this._pairs = value;\r\n }\r\n\r\n public get collisions(): number {\r\n return this._collisions;\r\n }\r\n\r\n public set collisions(value: number) {\r\n this._collisions = value;\r\n }\r\n\r\n public get contacts(): Map {\r\n return this._contacts;\r\n }\r\n\r\n public set contacts(contacts: Map) {\r\n this._contacts = contacts;\r\n }\r\n\r\n public get fastBodies(): number {\r\n return this._fastBodies;\r\n }\r\n\r\n public set fastBodies(value: number) {\r\n this._fastBodies = value;\r\n }\r\n\r\n public get fastBodyCollisions(): number {\r\n return this._fastBodyCollisions;\r\n }\r\n\r\n public set fastBodyCollisions(value: number) {\r\n this._fastBodyCollisions = value;\r\n }\r\n\r\n public get broadphase(): number {\r\n return this._broadphase;\r\n }\r\n\r\n public set broadphase(value: number) {\r\n this._broadphase = value;\r\n }\r\n\r\n public get narrowphase(): number {\r\n return this._narrowphase;\r\n }\r\n\r\n public set narrowphase(value: number) {\r\n this._narrowphase = value;\r\n }\r\n}\r\n","export interface NativeEventable {\r\n addEventListener(name: string, handler: (...any: any[]) => any): any;\r\n removeEventListener(name: string, handler: (...any: any[]) => any): any;\r\n}\r\n\r\nexport class BrowserComponent {\r\n private _paused = false;\r\n private _nativeHandlers: { [key: string]: (handler: any) => void } = {};\r\n\r\n on(eventName: string, handler: (evt: any) => void): void {\r\n if (this._nativeHandlers[eventName]) {\r\n this.off(eventName, this._nativeHandlers[eventName]);\r\n }\r\n this._nativeHandlers[eventName] = this._decorate(handler);\r\n this.nativeComponent.addEventListener(eventName, this._nativeHandlers[eventName]);\r\n }\r\n off(eventName: string, handler?: (event: any) => void): void {\r\n if (!handler) {\r\n handler = this._nativeHandlers[eventName];\r\n }\r\n this.nativeComponent.removeEventListener(eventName, handler);\r\n this._nativeHandlers[eventName] = null;\r\n }\r\n\r\n private _decorate(handler: (evt: any) => void): (evt: any) => void {\r\n return (evt: any) => {\r\n if (!this._paused) {\r\n handler(evt);\r\n }\r\n };\r\n }\r\n\r\n public pause() {\r\n this._paused = true;\r\n }\r\n\r\n public resume() {\r\n this._paused = false;\r\n }\r\n\r\n public clear() {\r\n for (const event in this._nativeHandlers) {\r\n this.off(event);\r\n }\r\n }\r\n\r\n constructor(public nativeComponent: T) {}\r\n}\r\n\r\nexport class BrowserEvents {\r\n private _windowComponent: BrowserComponent;\r\n private _documentComponent: BrowserComponent;\r\n constructor(private _windowGlobal: Window, private _documentGlobal: Document) {\r\n this._windowComponent = new BrowserComponent(this._windowGlobal);\r\n this._documentComponent = new BrowserComponent(this._documentGlobal);\r\n }\r\n\r\n public get window(): BrowserComponent {\r\n return this._windowComponent;\r\n }\r\n\r\n public get document(): BrowserComponent {\r\n return this._documentComponent;\r\n }\r\n\r\n public pause() {\r\n this.window.pause();\r\n this.document.pause();\r\n }\r\n\r\n public resume() {\r\n this.window.resume();\r\n this.document.resume();\r\n }\r\n\r\n public clear() {\r\n this.window.clear();\r\n this.document.clear();\r\n }\r\n}\r\n","import { Engine } from '../Engine';\r\nimport { Vector } from './vector';\r\n\r\nexport class GlobalCoordinates {\r\n public static fromPagePosition(x: number, y: number, engine: Engine): GlobalCoordinates;\r\n public static fromPagePosition(pos: Vector, engine: Engine): GlobalCoordinates;\r\n public static fromPagePosition(xOrPos: number | Vector, yOrEngine: number | Engine, engineOrUndefined?: Engine): GlobalCoordinates {\r\n let pageX: number;\r\n let pageY: number;\r\n let pagePos: Vector;\r\n let engine: Engine;\r\n\r\n if (arguments.length === 3) {\r\n pageX = xOrPos;\r\n pageY = yOrEngine;\r\n pagePos = new Vector(pageX, pageY);\r\n engine = engineOrUndefined;\r\n } else {\r\n pagePos = xOrPos;\r\n pageX = pagePos.x;\r\n pageY = pagePos.y;\r\n engine = yOrEngine;\r\n }\r\n\r\n const screenPos = engine.screen.pageToScreenCoordinates(pagePos);\r\n const worldPos = engine.screen.screenToWorldCoordinates(screenPos);\r\n\r\n return new GlobalCoordinates(worldPos, pagePos, screenPos);\r\n }\r\n\r\n constructor(public worldPos: Vector, public pagePos: Vector, public screenPos: Vector) {}\r\n}\r\n","import { GlobalCoordinates } from '../Math/global-coordinates';\r\nimport { Vector } from '../Math/vector';\r\nimport { PointerButton } from './PointerButton';\r\nimport { PointerType } from './PointerType';\r\n\r\nexport class PointerEvent {\r\n public active = true;\r\n public cancel() {\r\n this.active = false;\r\n }\r\n\r\n get pagePos(): Vector {\r\n return this.coordinates.pagePos;\r\n }\r\n\r\n get screenPos(): Vector {\r\n return this.coordinates.screenPos;\r\n }\r\n\r\n get worldPos(): Vector {\r\n return this.coordinates.worldPos;\r\n }\r\n\r\n constructor(\r\n public type: 'down' | 'up' | 'move' | 'cancel',\r\n public pointerId: number,\r\n public button: PointerButton,\r\n public pointerType: PointerType,\r\n public coordinates: GlobalCoordinates,\r\n public nativeEvent: Event) { };\r\n}\r\n","import { WheelDeltaMode } from './WheelDeltaMode';\r\n\r\n\r\nexport class WheelEvent {\r\n public active = true;\r\n public cancel() {\r\n this.active = false;\r\n }\r\n constructor(\r\n public x: number,\r\n public y: number,\r\n public pageX: number,\r\n public pageY: number,\r\n public screenX: number,\r\n public screenY: number,\r\n public index: number,\r\n public deltaX: number,\r\n public deltaY: number,\r\n public deltaZ: number,\r\n public deltaMode: WheelDeltaMode,\r\n public ev: Event\r\n ) { }\r\n}\r\n","import { Vector } from '../Math/vector';\r\nimport { PointerEvent } from './PointerEvent';\r\nimport { EventEmitter, EventKey, Handler, Subscription } from '../EventEmitter';\r\nimport { PointerEvents } from './PointerEventReceiver';\r\n\r\nexport class PointerAbstraction {\r\n public events = new EventEmitter();\r\n /**\r\n * The last position on the document this pointer was at. Can be `null` if pointer was never active.\r\n */\r\n public lastPagePos: Vector = Vector.Zero;\r\n\r\n /**\r\n * The last position on the screen this pointer was at. Can be `null` if pointer was never active.\r\n */\r\n public lastScreenPos: Vector = Vector.Zero;\r\n\r\n /**\r\n * The last position in the game world coordinates this pointer was at. Can be `null` if pointer was never active.\r\n */\r\n public lastWorldPos: Vector = Vector.Zero;\r\n\r\n constructor() {\r\n this.on('move', this._onPointerMove);\r\n this.on('down', this._onPointerDown);\r\n }\r\n\r\n public emit>(eventName: TEventName, event: PointerEvents[TEventName]): void;\r\n public emit(eventName: string, event?: any): void;\r\n public emit | string>(eventName: TEventName, event?: any): void {\r\n this.events.emit(eventName, event);\r\n }\r\n\r\n public on>(eventName: TEventName, handler: Handler): Subscription;\r\n public on(eventName: string, handler: Handler): Subscription;\r\n public on | string>(eventName: TEventName, handler: Handler): Subscription {\r\n return this.events.on(eventName, handler);\r\n }\r\n\r\n public once>(eventName: TEventName, handler: Handler): Subscription;\r\n public once(eventName: string, handler: Handler): Subscription;\r\n public once | string>(eventName: TEventName, handler: Handler): Subscription {\r\n return this.events.once(eventName, handler);\r\n }\r\n\r\n public off>(eventName: TEventName, handler: Handler): void;\r\n public off(eventName: string, handler: Handler): void;\r\n public off(eventName: string): void;\r\n public off | string>(eventName: TEventName, handler?: Handler): void {\r\n this.events.off(eventName, handler);\r\n }\r\n\r\n private _onPointerMove = (ev: PointerEvent): void => {\r\n this.lastPagePos = new Vector(ev.pagePos.x, ev.pagePos.y);\r\n this.lastScreenPos = new Vector(ev.screenPos.x, ev.screenPos.y);\r\n this.lastWorldPos = new Vector(ev.worldPos.x, ev.worldPos.y);\r\n };\r\n\r\n private _onPointerDown = (ev: PointerEvent): void => {\r\n this.lastPagePos = new Vector(ev.pagePos.x, ev.pagePos.y);\r\n this.lastScreenPos = new Vector(ev.screenPos.x, ev.screenPos.y);\r\n this.lastWorldPos = new Vector(ev.worldPos.x, ev.worldPos.y);\r\n };\r\n}\r\n","\r\nexport enum WheelDeltaMode {\r\n Pixel = 'Pixel',\r\n Line = 'Line',\r\n Page = 'Page'\r\n}\r\n","/**\r\n * Native browser button enumeration\r\n */\r\nexport enum NativePointerButton {\r\n NoButton = -1,\r\n Left = 0,\r\n Middle = 1,\r\n Right = 2,\r\n Unknown = 3\r\n}\r\n","/**\r\n * The mouse button being pressed.\r\n */\r\nexport enum PointerButton {\r\n Left = 'Left',\r\n Middle = 'Middle',\r\n Right = 'Right',\r\n Unknown = 'Unknown',\r\n NoButton = 'NoButton'\r\n}\r\n","/**\r\n * The type of pointer for a [[PointerEvent]].\r\n */\r\nexport enum PointerType {\r\n Touch = 'Touch',\r\n Mouse = 'Mouse',\r\n Pen = 'Pen',\r\n Unknown = 'Unknown'\r\n}\r\n","import { Engine, ScrollPreventionMode } from '../Engine';\r\nimport { GlobalCoordinates } from '../Math/global-coordinates';\r\nimport { vec, Vector } from '../Math/vector';\r\nimport { PointerEvent } from './PointerEvent';\r\nimport { WheelEvent } from './WheelEvent';\r\nimport { PointerAbstraction } from './PointerAbstraction';\r\n\r\nimport { WheelDeltaMode } from './WheelDeltaMode';\r\nimport { PointerSystem } from './PointerSystem';\r\nimport { NativePointerButton } from './NativePointerButton';\r\nimport { PointerButton } from './PointerButton';\r\nimport { fail } from '../Util/Util';\r\nimport { PointerType } from './PointerType';\r\nimport { isCrossOriginIframe } from '../Util/IFrame';\r\nimport { EventEmitter, EventKey, Handler, Subscription } from '../EventEmitter';\r\n\r\n\r\nexport type NativePointerEvent = globalThis.PointerEvent;\r\nexport type NativeMouseEvent = globalThis.MouseEvent;\r\nexport type NativeTouchEvent = globalThis.TouchEvent;\r\nexport type NativeWheelEvent = globalThis.WheelEvent;\r\n\r\nexport type PointerEvents = {\r\n move: PointerEvent,\r\n down: PointerEvent,\r\n up: PointerEvent,\r\n wheel: WheelEvent\r\n}\r\n\r\nexport const PointerEvents = {\r\n Move: 'move',\r\n Down: 'down',\r\n Up: 'up',\r\n Wheel: 'wheel'\r\n};\r\n\r\n/**\r\n * Is this event a native touch event?\r\n */\r\nfunction isTouchEvent(value: any): value is NativeTouchEvent {\r\n // Guard for Safari <= 13.1\r\n return globalThis.TouchEvent && value instanceof globalThis.TouchEvent;\r\n}\r\n\r\n/**\r\n * Is this event a native pointer event\r\n */\r\nfunction isPointerEvent(value: any): value is NativePointerEvent {\r\n // Guard for Safari <= 13.1\r\n return globalThis.PointerEvent && value instanceof globalThis.PointerEvent;\r\n}\r\n\r\nexport interface PointerInitOptions {\r\n grabWindowFocus?: boolean;\r\n}\r\n\r\n/**\r\n * The PointerEventProcessor is responsible for collecting all the events from the canvas and transforming them into GlobalCoordinates\r\n */\r\nexport class PointerEventReceiver {\r\n public events = new EventEmitter();\r\n public primary: PointerAbstraction = new PointerAbstraction();\r\n\r\n private _activeNativePointerIdsToNormalized = new Map();\r\n public lastFramePointerCoords = new Map();\r\n public currentFramePointerCoords = new Map();\r\n\r\n public currentFramePointerDown = new Map();\r\n public lastFramePointerDown = new Map();\r\n\r\n public currentFrameDown: PointerEvent[] = [];\r\n public currentFrameUp: PointerEvent[] = [];\r\n public currentFrameMove: PointerEvent[] = [];\r\n public currentFrameCancel: PointerEvent[] = [];\r\n public currentFrameWheel: WheelEvent[] = [];\r\n\r\n constructor(public readonly target: GlobalEventHandlers & EventTarget, public engine: Engine) {}\r\n\r\n /**\r\n * Creates a new PointerEventReceiver with a new target and engine while preserving existing pointer event\r\n * handlers.\r\n * @param target\r\n * @param engine\r\n */\r\n public recreate(target: GlobalEventHandlers & EventTarget, engine: Engine) {\r\n const eventReceiver = new PointerEventReceiver(target, engine);\r\n eventReceiver.primary = this.primary;\r\n eventReceiver._pointers = this._pointers;\r\n return eventReceiver;\r\n }\r\n\r\n private _pointers: PointerAbstraction[] = [this.primary];\r\n /**\r\n * Locates a specific pointer by id, creates it if it doesn't exist\r\n * @param index\r\n */\r\n public at(index: number): PointerAbstraction {\r\n if (index >= this._pointers.length) {\r\n // Ensure there is a pointer to retrieve\r\n for (let i = this._pointers.length - 1, max = index; i < max; i++) {\r\n this._pointers.push(new PointerAbstraction());\r\n }\r\n }\r\n return this._pointers[index];\r\n }\r\n\r\n /**\r\n * The number of pointers currently being tracked by excalibur\r\n */\r\n public count(): number {\r\n return this._pointers.length;\r\n }\r\n\r\n /**\r\n * Is the specified pointer id down this frame\r\n * @param pointerId\r\n */\r\n public isDown(pointerId: number) {\r\n return this.currentFramePointerDown.get(pointerId) ?? false;\r\n }\r\n\r\n /**\r\n * Was the specified pointer id down last frame\r\n * @param pointerId\r\n */\r\n public wasDown(pointerId: number) {\r\n return this.lastFramePointerDown.get(pointerId) ?? false;\r\n }\r\n\r\n /**\r\n * Whether the Pointer is currently dragging.\r\n */\r\n public isDragging(pointerId: number): boolean {\r\n return this.isDown(pointerId);\r\n }\r\n\r\n /**\r\n * Whether the Pointer just started dragging.\r\n */\r\n public isDragStart(pointerId: number): boolean {\r\n return this.isDown(pointerId) && !this.wasDown(pointerId);\r\n }\r\n\r\n /**\r\n * Whether the Pointer just ended dragging.\r\n */\r\n public isDragEnd(pointerId: number): boolean {\r\n return !this.isDown(pointerId) && this.wasDown(pointerId);\r\n }\r\n\r\n public emit>(eventName: TEventName, event: PointerEvents[TEventName]): void;\r\n public emit(eventName: string, event?: any): void;\r\n public emit | string>(eventName: TEventName, event?: any): void {\r\n this.events.emit(eventName, event);\r\n }\r\n\r\n public on>(eventName: TEventName, handler: Handler): Subscription;\r\n public on(eventName: string, handler: Handler): Subscription;\r\n public on | string>(eventName: TEventName, handler: Handler): Subscription {\r\n return this.events.on(eventName, handler);\r\n }\r\n\r\n public once>(eventName: TEventName, handler: Handler): Subscription;\r\n public once(eventName: string, handler: Handler): Subscription;\r\n public once | string>(eventName: TEventName, handler: Handler): Subscription {\r\n return this.events.once(eventName, handler);\r\n }\r\n\r\n public off>(eventName: TEventName, handler: Handler): void;\r\n public off(eventName: string, handler: Handler): void;\r\n public off(eventName: string): void;\r\n public off | string>(eventName: TEventName, handler?: Handler): void {\r\n this.events.off(eventName, handler);\r\n }\r\n\r\n /**\r\n * Called internally by excalibur\r\n *\r\n * Updates the current frame pointer info and emits raw pointer events\r\n *\r\n * This does not emit events to entities, see PointerSystem\r\n */\r\n public update() {\r\n this.lastFramePointerDown = new Map(this.currentFramePointerDown);\r\n this.lastFramePointerCoords = new Map(this.currentFramePointerCoords);\r\n\r\n for (const event of this.currentFrameDown) {\r\n this.emit('down', event);\r\n const pointer = this.at(event.pointerId);\r\n pointer.emit('down', event);\r\n this.primary.emit('pointerdown', event);\r\n }\r\n\r\n for (const event of this.currentFrameUp) {\r\n this.emit('up', event);\r\n const pointer = this.at(event.pointerId);\r\n pointer.emit('up', event);\r\n }\r\n\r\n for (const event of this.currentFrameMove) {\r\n this.emit('move', event);\r\n const pointer = this.at(event.pointerId);\r\n pointer.emit('move', event);\r\n }\r\n\r\n for (const event of this.currentFrameCancel) {\r\n this.emit('cancel', event);\r\n const pointer = this.at(event.pointerId);\r\n pointer.emit('cancel', event);\r\n }\r\n\r\n for (const event of this.currentFrameWheel) {\r\n this.emit('wheel', event);\r\n this.primary.emit('pointerwheel', event);\r\n }\r\n }\r\n\r\n /**\r\n * Clears the current frame event and pointer data\r\n */\r\n public clear() {\r\n for (const event of this.currentFrameUp) {\r\n this.currentFramePointerCoords.delete(event.pointerId);\r\n const ids = this._activeNativePointerIdsToNormalized.entries();\r\n for (const [native, normalized] of ids) {\r\n if (normalized === event.pointerId) {\r\n this._activeNativePointerIdsToNormalized.delete(native);\r\n }\r\n }\r\n }\r\n this.currentFrameDown.length = 0;\r\n this.currentFrameUp.length = 0;\r\n this.currentFrameMove.length = 0;\r\n this.currentFrameCancel.length = 0;\r\n this.currentFrameWheel.length = 0;\r\n }\r\n\r\n private _boundHandle = this._handle.bind(this);\r\n private _boundWheel = this._handleWheel.bind(this);\r\n /**\r\n * Initializes the pointer event receiver so that it can start listening to native\r\n * browser events.\r\n */\r\n public init(options?: PointerInitOptions) {\r\n // Disabling the touch action avoids browser/platform gestures from firing on the canvas\r\n // It is important on mobile to have touch action 'none'\r\n // https://stackoverflow.com/questions/48124372/pointermove-event-not-working-with-touch-why-not\r\n if (this.target === this.engine.canvas) {\r\n this.engine.canvas.style.touchAction = 'none';\r\n } else {\r\n document.body.style.touchAction = 'none';\r\n }\r\n // Preferred pointer events\r\n if (window.PointerEvent) {\r\n this.target.addEventListener('pointerdown', this._boundHandle);\r\n this.target.addEventListener('pointerup', this._boundHandle);\r\n this.target.addEventListener('pointermove', this._boundHandle);\r\n this.target.addEventListener('pointercancel', this._boundHandle);\r\n } else {\r\n // Touch Events\r\n this.target.addEventListener('touchstart', this._boundHandle);\r\n this.target.addEventListener('touchend', this._boundHandle);\r\n this.target.addEventListener('touchmove', this._boundHandle);\r\n this.target.addEventListener('touchcancel', this._boundHandle);\r\n\r\n // Mouse Events\r\n this.target.addEventListener('mousedown', this._boundHandle);\r\n this.target.addEventListener('mouseup', this._boundHandle);\r\n this.target.addEventListener('mousemove', this._boundHandle);\r\n }\r\n\r\n // MDN MouseWheelEvent\r\n const wheelOptions = {\r\n passive: !(\r\n this.engine.pageScrollPreventionMode === ScrollPreventionMode.All ||\r\n this.engine.pageScrollPreventionMode === ScrollPreventionMode.Canvas\r\n )\r\n };\r\n if ('onwheel' in document.createElement('div')) {\r\n // Modern Browsers\r\n this.target.addEventListener('wheel', this._boundWheel, wheelOptions);\r\n } else if (document.onmousewheel !== undefined) {\r\n // Webkit and IE\r\n this.target.addEventListener('mousewheel', this._boundWheel, wheelOptions);\r\n } else {\r\n // Remaining browser and older Firefox\r\n this.target.addEventListener('MozMousePixelScroll', this._boundWheel, wheelOptions);\r\n }\r\n\r\n const grabWindowFocus = options?.grabWindowFocus ?? true;\r\n // Handle cross origin iframe\r\n if (grabWindowFocus && isCrossOriginIframe()) {\r\n const grabFocus = () => {\r\n window.focus();\r\n };\r\n // Preferred pointer events\r\n if (window.PointerEvent) {\r\n this.target.addEventListener('pointerdown', grabFocus);\r\n } else {\r\n // Touch Events\r\n this.target.addEventListener('touchstart', grabFocus);\r\n\r\n // Mouse Events\r\n this.target.addEventListener('mousedown', grabFocus);\r\n }\r\n }\r\n }\r\n\r\n public detach() {\r\n // Preferred pointer events\r\n if (window.PointerEvent) {\r\n this.target.removeEventListener('pointerdown', this._boundHandle);\r\n this.target.removeEventListener('pointerup', this._boundHandle);\r\n this.target.removeEventListener('pointermove', this._boundHandle);\r\n this.target.removeEventListener('pointercancel', this._boundHandle);\r\n } else {\r\n // Touch Events\r\n this.target.removeEventListener('touchstart', this._boundHandle);\r\n this.target.removeEventListener('touchend', this._boundHandle);\r\n this.target.removeEventListener('touchmove', this._boundHandle);\r\n this.target.removeEventListener('touchcancel', this._boundHandle);\r\n\r\n // Mouse Events\r\n this.target.removeEventListener('mousedown', this._boundHandle);\r\n this.target.removeEventListener('mouseup', this._boundHandle);\r\n this.target.removeEventListener('mousemove', this._boundHandle);\r\n }\r\n\r\n if ('onwheel' in document.createElement('div')) {\r\n // Modern Browsers\r\n this.target.removeEventListener('wheel', this._boundWheel);\r\n } else if (document.onmousewheel !== undefined) {\r\n // Webkit and IE\r\n this.target.addEventListener('mousewheel', this._boundWheel);\r\n } else {\r\n // Remaining browser and older Firefox\r\n this.target.addEventListener('MozMousePixelScroll', this._boundWheel);\r\n }\r\n }\r\n\r\n /**\r\n * Take native pointer id and map it to index in active pointers\r\n * @param nativePointerId\r\n */\r\n private _normalizePointerId(nativePointerId: number) {\r\n // Add to the the native pointer set id\r\n this._activeNativePointerIdsToNormalized.set(nativePointerId, -1);\r\n\r\n // Native pointer ids in ascending order\r\n const currentPointerIds = Array.from(this._activeNativePointerIdsToNormalized.keys()).sort((a, b) => a - b);\r\n\r\n // The index into sorted ids will be the new id, will always have an id\r\n const id = currentPointerIds.findIndex(p => p === nativePointerId);\r\n\r\n // Save the mapping so we can reverse it later\r\n this._activeNativePointerIdsToNormalized.set(nativePointerId, id);\r\n\r\n // ignore pointer because game isn't watching\r\n return id;\r\n }\r\n\r\n /**\r\n * Responsible for handling and parsing pointer events\r\n */\r\n private _handle(ev: NativeTouchEvent | NativePointerEvent | NativeMouseEvent) {\r\n ev.preventDefault();\r\n const eventCoords = new Map();\r\n let button: PointerButton;\r\n let pointerType: PointerType;\r\n if (isTouchEvent(ev)) {\r\n button = PointerButton.Unknown;\r\n pointerType = PointerType.Touch;\r\n // https://developer.mozilla.org/en-US/docs/Web/API/TouchEvent\r\n for (let i = 0; i < ev.changedTouches.length; i++) {\r\n const touch = ev.changedTouches[i];\r\n const coordinates = GlobalCoordinates.fromPagePosition(touch.pageX, touch.pageY, this.engine);\r\n const nativePointerId = i + 1;\r\n const pointerId = this._normalizePointerId(nativePointerId);\r\n this.currentFramePointerCoords.set(pointerId, coordinates);\r\n eventCoords.set(pointerId, coordinates);\r\n }\r\n } else {\r\n button = this._nativeButtonToPointerButton(ev.button);\r\n pointerType = PointerType.Mouse;\r\n const coordinates = GlobalCoordinates.fromPagePosition(ev.pageX, ev.pageY, this.engine);\r\n let nativePointerId = 1;\r\n if (isPointerEvent(ev)) {\r\n nativePointerId = ev.pointerId;\r\n pointerType = this._stringToPointerType(ev.pointerType);\r\n }\r\n const pointerId = this._normalizePointerId(nativePointerId);\r\n this.currentFramePointerCoords.set(pointerId, coordinates);\r\n eventCoords.set(pointerId, coordinates);\r\n }\r\n\r\n for (const [pointerId, coord] of eventCoords.entries()) {\r\n switch (ev.type) {\r\n case 'mousedown':\r\n case 'pointerdown':\r\n case 'touchstart':\r\n this.currentFrameDown.push(new PointerEvent('down', pointerId, button, pointerType, coord, ev));\r\n this.currentFramePointerDown.set(pointerId, true);\r\n break;\r\n case 'mouseup':\r\n case 'pointerup':\r\n case 'touchend':\r\n this.currentFrameUp.push(new PointerEvent('up', pointerId, button, pointerType, coord, ev));\r\n this.currentFramePointerDown.set(pointerId, false);\r\n break;\r\n case 'mousemove':\r\n case 'pointermove':\r\n case 'touchmove':\r\n this.currentFrameMove.push(new PointerEvent('move', pointerId, button, pointerType, coord, ev));\r\n break;\r\n case 'touchcancel':\r\n case 'pointercancel':\r\n this.currentFrameCancel.push(new PointerEvent('cancel', pointerId, button, pointerType, coord, ev));\r\n break;\r\n }\r\n }\r\n }\r\n\r\n private _handleWheel(ev: NativeWheelEvent) {\r\n // Should we prevent page scroll because of this event\r\n if (\r\n this.engine.pageScrollPreventionMode === ScrollPreventionMode.All ||\r\n (this.engine.pageScrollPreventionMode === ScrollPreventionMode.Canvas && ev.target === this.engine.canvas)\r\n ) {\r\n ev.preventDefault();\r\n }\r\n const screen = this.engine.screen.pageToScreenCoordinates(vec(ev.pageX, ev.pageY));\r\n const world = this.engine.screen.screenToWorldCoordinates(screen);\r\n\r\n /**\r\n * A constant used to normalize wheel events across different browsers\r\n *\r\n * This normalization factor is pulled from\r\n * https://developer.mozilla.org/en-US/docs/Web/Events/wheel#Listening_to_this_event_across_browser\r\n */\r\n const ScrollWheelNormalizationFactor = -1 / 40;\r\n\r\n const deltaX = ev.deltaX || ev.wheelDeltaX * ScrollWheelNormalizationFactor || 0;\r\n const deltaY =\r\n ev.deltaY || ev.wheelDeltaY * ScrollWheelNormalizationFactor || ev.wheelDelta * ScrollWheelNormalizationFactor || ev.detail || 0;\r\n const deltaZ = ev.deltaZ || 0;\r\n let deltaMode = WheelDeltaMode.Pixel;\r\n\r\n if (ev.deltaMode) {\r\n if (ev.deltaMode === 1) {\r\n deltaMode = WheelDeltaMode.Line;\r\n } else if (ev.deltaMode === 2) {\r\n deltaMode = WheelDeltaMode.Page;\r\n }\r\n }\r\n\r\n const we = new WheelEvent(world.x, world.y, ev.pageX, ev.pageY, screen.x, screen.y, 0, deltaX, deltaY, deltaZ, deltaMode, ev);\r\n this.currentFrameWheel.push(we);\r\n }\r\n\r\n /**\r\n * Triggers an excalibur pointer event in a world space pos\r\n *\r\n * Useful for testing pointers in excalibur\r\n * @param type\r\n * @param pos\r\n */\r\n public triggerEvent(type: 'down' | 'up' | 'move' | 'cancel', pos: Vector) {\r\n const page = this.engine.screen.worldToPageCoordinates(pos);\r\n // Send an event to the event receiver\r\n if (window.PointerEvent) {\r\n this._handle(new window.PointerEvent('pointer' + type, {\r\n pointerId: 0,\r\n clientX: page.x,\r\n clientY: page.y\r\n }));\r\n } else {\r\n // Safari hack\r\n this._handle(new window.MouseEvent('mouse' + type, {\r\n clientX: page.x,\r\n clientY: page.y\r\n }));\r\n }\r\n\r\n // Force update pointer system\r\n const pointerSystem = this.engine.currentScene.world.systemManager.get(PointerSystem);\r\n const transformEntities = this.engine.currentScene.world.queryManager.createQuery(pointerSystem.types);\r\n pointerSystem.preupdate();\r\n pointerSystem.update(transformEntities.getEntities());\r\n }\r\n\r\n private _nativeButtonToPointerButton(s: NativePointerButton): PointerButton {\r\n switch (s) {\r\n case NativePointerButton.NoButton:\r\n return PointerButton.NoButton;\r\n case NativePointerButton.Left:\r\n return PointerButton.Left;\r\n case NativePointerButton.Middle:\r\n return PointerButton.Middle;\r\n case NativePointerButton.Right:\r\n return PointerButton.Right;\r\n case NativePointerButton.Unknown:\r\n return PointerButton.Unknown;\r\n default:\r\n return fail(s);\r\n }\r\n }\r\n\r\n private _stringToPointerType(s: string) {\r\n switch (s) {\r\n case 'touch':\r\n return PointerType.Touch;\r\n case 'mouse':\r\n return PointerType.Mouse;\r\n case 'pen':\r\n return PointerType.Pen;\r\n default:\r\n return PointerType.Unknown;\r\n }\r\n }\r\n}","export interface FpsSamplerOptions {\r\n /**\r\n * Specify the sampling period in milliseconds (default 100)\r\n */\r\n samplePeriod?: number;\r\n /**\r\n * Specify the initial FPS\r\n */\r\n initialFps: number;\r\n\r\n /**\r\n * Specify the function used to return the current time (in milliseconds)\r\n */\r\n nowFn: () => number;\r\n}\r\n\r\nexport class FpsSampler {\r\n private _fps: number;\r\n private _samplePeriod: number = 100;\r\n private _currentFrameTime: number = 0;\r\n private _frames: number = 0;\r\n private _previousSampleTime: number = 0;\r\n private _beginFrameTime: number = 0;\r\n private _nowFn: () => number;\r\n\r\n constructor(options: FpsSamplerOptions) {\r\n this._fps = options.initialFps;\r\n this._samplePeriod = options.samplePeriod ?? this._samplePeriod;\r\n this._currentFrameTime = 1000/options.initialFps;\r\n this._nowFn = options.nowFn;\r\n this._previousSampleTime = this._nowFn();\r\n }\r\n\r\n /**\r\n * Start of code block to sample FPS for\r\n */\r\n start() {\r\n this._beginFrameTime = this._nowFn();\r\n }\r\n\r\n /**\r\n * End of code block to sample FPS for\r\n */\r\n end() {\r\n this._frames++;\r\n const time = this._nowFn();\r\n\r\n this._currentFrameTime = time - this._beginFrameTime;\r\n\r\n if (time >= this._previousSampleTime + this._samplePeriod) {\r\n this._fps = (this._frames * 1000) / (time - this._previousSampleTime);\r\n this._previousSampleTime = time;\r\n this._frames = 0;\r\n }\r\n }\r\n\r\n /**\r\n * Return the currently sampled fps over the last sample period, by default every 100ms\r\n */\r\n get fps() {\r\n return this._fps;\r\n }\r\n\r\n /**\r\n * Return the instantaneous fps, this can be less useful because it will fluctuate given the current frames time\r\n */\r\n get instant() {\r\n return 1000 / this._currentFrameTime;\r\n }\r\n}","import { Logger } from '..';\r\nimport { FpsSampler } from './Fps';\r\n\r\nexport interface ClockOptions {\r\n /**\r\n * Define the function you'd like the clock to tick when it is started\r\n */\r\n tick: (elapsedMs: number) => any;\r\n /**\r\n * Optionally define the fatal exception handler, used if an error is thrown in tick\r\n */\r\n onFatalException?: (e: unknown) => any;\r\n /**\r\n * Optionally limit the maximum FPS of the clock\r\n */\r\n maxFps?: number;\r\n}\r\n\r\n\r\n/**\r\n * Abstract Clock is the base type of all Clocks\r\n *\r\n * It has a few opinions\r\n * 1. It manages the calculation of what \"elapsed\" time means and thus maximum fps\r\n * 2. The default timing api is implemented in now()\r\n *\r\n * To implement your own clock, extend Clock and override start/stop to start and stop the clock, then call update() with whatever\r\n * method is unique to your clock implementation.\r\n */\r\nexport abstract class Clock {\r\n protected tick: (elapsedMs: number) => any;\r\n private _onFatalException: (e: unknown) => any = () => { /* default nothing */ };\r\n private _maxFps: number = Infinity;\r\n private _lastTime: number = 0;\r\n public fpsSampler: FpsSampler;\r\n private _options: ClockOptions;\r\n private _elapsed: number = 1;\r\n private _scheduledCbs: [cb: () => any, scheduledTime: number][] = [];\r\n private _totalElapsed: number = 0;\r\n constructor(options: ClockOptions) {\r\n this._options = options;\r\n this.tick = options.tick;\r\n this._lastTime = this.now() ?? 0;\r\n this._maxFps = options.maxFps ?? this._maxFps;\r\n this._onFatalException = options.onFatalException ?? this._onFatalException;\r\n this.fpsSampler = new FpsSampler({\r\n initialFps: 60,\r\n nowFn: () => this.now()\r\n });\r\n }\r\n\r\n /**\r\n * Get the elapsed time for the last completed frame\r\n */\r\n public elapsed(): number {\r\n return this._elapsed;\r\n }\r\n\r\n /**\r\n * Get the current time in milliseconds\r\n */\r\n public now(): number {\r\n return performance.now();\r\n }\r\n\r\n public toTestClock() {\r\n const testClock = new TestClock({\r\n ...this._options,\r\n defaultUpdateMs: 16.6\r\n });\r\n return testClock;\r\n }\r\n\r\n public toStandardClock() {\r\n const clock = new StandardClock({\r\n ...this._options\r\n });\r\n return clock;\r\n }\r\n\r\n public setFatalExceptionHandler(handler: (e: unknown) => any) {\r\n this._onFatalException = handler;\r\n }\r\n\r\n /**\r\n * Schedule a callback to fire given a timeout in milliseconds using the excalibur [[Clock]]\r\n *\r\n * This is useful to use over the built in browser `setTimeout` because callbacks will be tied to the\r\n * excalibur update clock, instead of browser time, this means that callbacks wont fire if the game is\r\n * stopped or paused.\r\n *\r\n * @param cb callback to fire\r\n * @param timeoutMs Optionally specify a timeout in milliseconds from now, default is 0ms which means the next possible tick\r\n */\r\n public schedule(cb: () => any, timeoutMs: number = 0) {\r\n // Scheduled based on internal elapsed time\r\n const scheduledTime = this._totalElapsed + timeoutMs;\r\n this._scheduledCbs.push([cb, scheduledTime]);\r\n }\r\n\r\n private _runScheduledCbs() {\r\n // walk backwards to delete items as we loop\r\n for (let i = this._scheduledCbs.length - 1; i > -1; i--) {\r\n if (this._scheduledCbs[i][1] <= this._totalElapsed) {\r\n this._scheduledCbs[i][0]();\r\n this._scheduledCbs.splice(i, 1);\r\n }\r\n }\r\n }\r\n\r\n protected update(overrideUpdateMs?: number): void {\r\n try {\r\n this.fpsSampler.start();\r\n // Get the time to calculate time-elapsed\r\n const now = this.now();\r\n let elapsed = now - this._lastTime || 1; // first frame\r\n\r\n // Constrain fps\r\n const fpsInterval = (1000 / this._maxFps);\r\n\r\n // only run frame if enough time has elapsed\r\n if (elapsed >= fpsInterval) {\r\n let leftover = 0;\r\n if (fpsInterval !== 0) {\r\n leftover = (elapsed % fpsInterval);\r\n elapsed = elapsed - leftover; // shift elapsed to be \"in phase\" with the current loop fps\r\n }\r\n\r\n // Resolves issue #138 if the game has been paused, or blurred for\r\n // more than a 200 milliseconds, reset elapsed time to 1. This improves reliability\r\n // and provides more expected behavior when the engine comes back\r\n // into focus\r\n if (elapsed > 200) {\r\n elapsed = 1;\r\n }\r\n\r\n // tick the mainloop and run scheduled callbacks\r\n this._elapsed = overrideUpdateMs || elapsed;\r\n this._totalElapsed += this._elapsed;\r\n this._runScheduledCbs();\r\n this.tick(overrideUpdateMs || elapsed);\r\n\r\n if (fpsInterval !== 0) {\r\n this._lastTime = now - leftover;\r\n } else {\r\n this._lastTime = now;\r\n }\r\n this.fpsSampler.end();\r\n }\r\n } catch (e) {\r\n this._onFatalException(e);\r\n this.stop();\r\n }\r\n }\r\n\r\n /**\r\n * Returns if the clock is currently running\r\n */\r\n public abstract isRunning(): boolean;\r\n\r\n /**\r\n * Start the clock, it will then periodically call the tick(elapsedMilliseconds) since the last tick\r\n */\r\n public abstract start(): void;\r\n\r\n /**\r\n * Stop the clock, tick() is no longer called\r\n */\r\n public abstract stop(): void;\r\n}\r\n\r\n\r\n/**\r\n * The [[StandardClock]] implements the requestAnimationFrame browser api to run the tick()\r\n */\r\nexport class StandardClock extends Clock {\r\n\r\n private _running = false;\r\n private _requestId: number;\r\n constructor(options: ClockOptions) {\r\n super(options);\r\n }\r\n\r\n public isRunning(): boolean {\r\n return this._running;\r\n }\r\n\r\n public start(): void {\r\n if (this._running) {\r\n return;\r\n }\r\n this._running = true;\r\n const mainloop = () => {\r\n // stop the loop\r\n if (!this._running) {\r\n return;\r\n }\r\n try {\r\n // request next loop\r\n this._requestId = window.requestAnimationFrame(mainloop);\r\n this.update();\r\n } catch (e) {\r\n window.cancelAnimationFrame(this._requestId);\r\n throw e;\r\n }\r\n };\r\n\r\n // begin the first frame\r\n mainloop();\r\n }\r\n\r\n public stop(): void {\r\n this._running = false;\r\n }\r\n}\r\n\r\nexport interface TestClockOptions {\r\n /**\r\n * Specify the update milliseconds to use for each manual step()\r\n */\r\n defaultUpdateMs: number;\r\n}\r\n\r\n/**\r\n * The TestClock is meant for debugging interactions in excalibur that require precise timing to replicate or test\r\n */\r\nexport class TestClock extends Clock {\r\n private _logger = Logger.getInstance();\r\n private _updateMs: number;\r\n private _running: boolean = false;\r\n private _currentTime = 0;\r\n constructor(options: ClockOptions & TestClockOptions) {\r\n super({\r\n ...options\r\n });\r\n this._updateMs = options.defaultUpdateMs;\r\n }\r\n\r\n /**\r\n * Get the current time in milliseconds\r\n */\r\n public override now() {\r\n return this._currentTime ?? 0;\r\n }\r\n\r\n public isRunning(): boolean {\r\n return this._running;\r\n }\r\n public start(): void {\r\n this._running = true;\r\n }\r\n public stop(): void {\r\n this._running = false;\r\n }\r\n\r\n /**\r\n * Manually step the clock forward 1 tick, optionally specify an elapsed time in milliseconds\r\n * @param overrideUpdateMs\r\n */\r\n step(overrideUpdateMs?: number): void {\r\n const time = overrideUpdateMs ?? this._updateMs;\r\n\r\n if (this._running) {\r\n // to be comparable to RAF this needs to be a full blown Task\r\n // For example, images cannot decode synchronously in a single step\r\n this.update(time);\r\n this._currentTime += time;\r\n } else {\r\n this._logger.warn('The clock is not running, no step will be performed');\r\n }\r\n }\r\n\r\n /**\r\n * Run a number of steps that tick the clock, optionally specify an elapsed time in milliseconds\r\n * @param numberOfSteps\r\n * @param overrideUpdateMs\r\n */\r\n run(numberOfSteps: number, overrideUpdateMs?: number): void {\r\n for (let i = 0; i < numberOfSteps; i++) {\r\n this.step(overrideUpdateMs ?? this._updateMs);\r\n }\r\n }\r\n}","import toasterCss from './Toaster.css';\r\n\r\n/**\r\n * The Toaster is only meant to be called from inside Excalibur to display messages to players\r\n */\r\nexport class Toaster {\r\n private _styleBlock: HTMLStyleElement;\r\n private _container: HTMLDivElement;\r\n private _toasterCss: string = toasterCss.toString();\r\n\r\n private _isInitialized = false;\r\n private _initialize() {\r\n if (!this._isInitialized) {\r\n this._container = document.createElement('div');\r\n this._container.id = 'ex-toast-container';\r\n document.body.appendChild(this._container);\r\n this._isInitialized = true;\r\n\r\n this._styleBlock = document.createElement('style');\r\n this._styleBlock.textContent = this._toasterCss;\r\n document.head.appendChild(this._styleBlock);\r\n }\r\n }\r\n\r\n public dispose() {\r\n this._container.parentElement.removeChild(this._container);\r\n\r\n this._styleBlock.parentElement.removeChild(this._styleBlock);\r\n\r\n this._isInitialized = false;\r\n }\r\n\r\n private _createFragment(message: string) {\r\n const toastMessage = document.createElement('span');\r\n toastMessage.innerText = message;\r\n return toastMessage;\r\n }\r\n\r\n /**\r\n * Display a toast message to a player\r\n * @param message Text of the message, messages may have a single \"[LINK]\" to influence placement\r\n * @param linkTarget Optionally specify a link location\r\n * @param linkName Optionally specify a name for that link location\r\n */\r\n public toast(message: string, linkTarget?: string, linkName?: string) {\r\n this._initialize();\r\n const toast = document.createElement('div');\r\n toast.className = 'ex-toast-message';\r\n\r\n const messageFragments: HTMLElement[] = message.split('[LINK]').map(message => this._createFragment(message));\r\n\r\n if (linkTarget) {\r\n const link = document.createElement('a');\r\n link.href = linkTarget;\r\n if (linkName) {\r\n link.innerText = linkName;\r\n } else {\r\n link.innerText = linkTarget;\r\n }\r\n messageFragments.splice(1, 0, link);\r\n }\r\n\r\n // Assembly message\r\n const finalMessage = document.createElement('div');\r\n messageFragments.forEach(message => {\r\n finalMessage.appendChild(message);\r\n });\r\n toast.appendChild(finalMessage);\r\n\r\n // Dismiss button\r\n const dismissBtn = document.createElement('button');\r\n dismissBtn.innerText = 'x';\r\n dismissBtn.addEventListener('click', () => {\r\n this._container.removeChild(toast);\r\n });\r\n toast.appendChild(dismissBtn);\r\n\r\n // Escape to dismiss\r\n const keydownHandler = (evt: KeyboardEvent) => {\r\n if (evt.key === 'Escape') {\r\n try {\r\n this._container.removeChild(toast);\r\n } catch {\r\n // pass\r\n }\r\n }\r\n document.removeEventListener('keydown', keydownHandler);\r\n };\r\n document.addEventListener('keydown', keydownHandler);\r\n\r\n // Insert into container\r\n const first = this._container.firstChild;\r\n this._container.insertBefore(toast, first);\r\n }\r\n}","import { Gamepads } from './Gamepad';\r\nimport { Keyboard } from './Keyboard';\r\nimport { PointerEventReceiver } from './PointerEventReceiver';\r\n\r\nexport interface InputsOptions {\r\n keyboard: Keyboard;\r\n gamepads: Gamepads;\r\n pointers: PointerEventReceiver;\r\n}\r\n\r\n/**\r\n * This allows you to map multiple inputs to specific commands! This is especially useful when\r\n * you need to allow multiple input sources to control a specific action.\r\n */\r\nexport class InputMapper {\r\n\r\n private _handlers = new Map();\r\n constructor(public inputs: InputsOptions) {}\r\n\r\n /**\r\n * Executes the input map, called internally by Excalibur\r\n */\r\n execute() {\r\n for (const [input, command] of this._handlers.entries()) {\r\n const results = input(this.inputs);\r\n if (results) {\r\n command(results);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * This allows you to map multiple inputs to specific commands! This is useful\r\n *\r\n * The inputHandler should return a truthy value if you wish the commandHandler to fire.\r\n *\r\n * Example:\r\n * ```typescript\r\n * const moveRight = (amount: number) => { actor.vel.x = 100 * amount }\r\n * const moveLeft = (amount: number) => { actor.vel.x = -100 * amount }\r\n * const moveUp = (amount: number) => { actor.vel.y = -100 * amount }\r\n * const moveDown = (amount: number) => { actor.vel.y = 100 * amount }\r\n *\r\n * engine.inputMapper.on(({keyboard}) => keyboard.isHeld(ex.Keys.ArrowRight) ? 1 : 0, moveRight);\r\n * engine.inputMapper.on(({gamepads}) => gamepads.at(0).isButtonPressed(ex.Buttons.DpadRight) ? 1 : 0, moveRight);\r\n * engine.inputMapper.on(({gamepads}) => gamepads.at(0).getAxes(ex.Axes.LeftStickX) > 0 ?\r\n * gamepads.at(0).getAxes(ex.Axes.LeftStickX) : 0, moveRight);\r\n * ```\r\n * @param inputHandler\r\n * @param commandHandler\r\n */\r\n on(\r\n inputHandler: (inputs: InputsOptions) => TInputHandlerData | false,\r\n commandHandler: (data: TInputHandlerData) => any) {\r\n this._handlers.set(inputHandler, commandHandler);\r\n }\r\n}","import { EX_VERSION } from './';\r\nimport { EventEmitter, EventKey, Handler, Subscription } from './EventEmitter';\r\nimport { Gamepads } from './Input/Gamepad';\r\nimport { Keyboard } from './Input/Keyboard';\r\nimport { PointerScope } from './Input/PointerScope';\r\nimport { EngineInput } from './Input/EngineInput';\r\nimport { Flags } from './Flags';\r\nimport { polyfill } from './Polyfill';\r\npolyfill();\r\nimport { CanUpdate, CanDraw, CanInitialize } from './Interfaces/LifecycleEvents';\r\nimport { Loadable } from './Interfaces/Loadable';\r\nimport { Vector } from './Math/vector';\r\nimport { Screen, DisplayMode, ScreenDimension, Resolution } from './Screen';\r\nimport { ScreenElement } from './ScreenElement';\r\nimport { Actor } from './Actor';\r\nimport { Timer } from './Timer';\r\nimport { TileMap } from './TileMap';\r\nimport { Loader } from './Loader';\r\nimport { Detector } from './Util/Detector';\r\nimport {\r\n VisibleEvent,\r\n HiddenEvent,\r\n GameStartEvent,\r\n GameStopEvent,\r\n PreUpdateEvent,\r\n PostUpdateEvent,\r\n PreFrameEvent,\r\n PostFrameEvent,\r\n DeactivateEvent,\r\n ActivateEvent,\r\n PreDrawEvent,\r\n PostDrawEvent,\r\n InitializeEvent\r\n} from './Events';\r\nimport { Logger, LogLevel } from './Util/Log';\r\nimport { Color } from './Color';\r\nimport { Scene } from './Scene';\r\nimport { Entity } from './EntityComponentSystem/Entity';\r\nimport { Debug, DebugStats } from './Debug/Debug';\r\nimport { BrowserEvents } from './Util/Browser';\r\nimport { ExcaliburGraphicsContext, ExcaliburGraphicsContext2DCanvas, ExcaliburGraphicsContextWebGL, TextureLoader } from './Graphics';\r\nimport { PointerEventReceiver } from './Input/PointerEventReceiver';\r\nimport { Clock, StandardClock } from './Util/Clock';\r\nimport { ImageFiltering } from './Graphics/Filtering';\r\nimport { GraphicsDiagnostics } from './Graphics/GraphicsDiagnostics';\r\nimport { Toaster } from './Util/Toaster';\r\nimport { InputMapper } from './Input/InputMapper';\r\n\r\nexport type EngineEvents = {\r\n fallbackgraphicscontext: ExcaliburGraphicsContext2DCanvas,\r\n initialize: InitializeEvent,\r\n visible: VisibleEvent,\r\n hidden: HiddenEvent,\r\n start: GameStartEvent,\r\n stop: GameStopEvent,\r\n preupdate: PreUpdateEvent,\r\n postupdate: PostUpdateEvent,\r\n preframe: PreFrameEvent,\r\n postframe: PostFrameEvent,\r\n predraw: PreDrawEvent,\r\n postdraw: PostDrawEvent,\r\n}\r\n\r\nexport const EngineEvents = {\r\n FallbackGraphicsContext: 'fallbackgraphicscontext',\r\n Initialize: 'initialize',\r\n Visible: 'visible',\r\n Hidden: 'hidden',\r\n Start: 'start',\r\n Stop: 'stop',\r\n PreUpdate: 'preupdate',\r\n PostUpdate: 'postupdate',\r\n PreFrame: 'preframe',\r\n PostFrame: 'postframe',\r\n PreDraw: 'predraw',\r\n PostDraw: 'postdraw'\r\n} as const;\r\n\r\n/**\r\n * Enum representing the different mousewheel event bubble prevention\r\n */\r\nexport enum ScrollPreventionMode {\r\n /**\r\n * Do not prevent any page scrolling\r\n */\r\n None,\r\n /**\r\n * Prevent page scroll if mouse is over the game canvas\r\n */\r\n Canvas,\r\n /**\r\n * Prevent all page scrolling via mouse wheel\r\n */\r\n All\r\n}\r\n\r\n/**\r\n * Defines the available options to configure the Excalibur engine at constructor time.\r\n */\r\nexport interface EngineOptions {\r\n /**\r\n * Optionally configure the width of the viewport in css pixels\r\n */\r\n width?: number;\r\n\r\n /**\r\n * Optionally configure the height of the viewport in css pixels\r\n */\r\n height?: number;\r\n\r\n /**\r\n * Optionally configure the width & height of the viewport in css pixels.\r\n * Use `viewport` instead of [[EngineOptions.width]] and [[EngineOptions.height]], or vice versa.\r\n */\r\n viewport?: ScreenDimension;\r\n\r\n /**\r\n * Optionally specify the size the logical pixel resolution, if not specified it will be width x height.\r\n * See [[Resolution]] for common presets.\r\n */\r\n resolution?: ScreenDimension;\r\n\r\n /**\r\n * Optionally specify antialiasing (smoothing), by default true (smooth pixels)\r\n *\r\n * * `true` - useful for high resolution art work you would like smoothed, this also hints excalibur to load images\r\n * with [[ImageFiltering.Blended]]\r\n *\r\n * * `false` - useful for pixel art style art work you would like sharp, this also hints excalibur to load images\r\n * with [[ImageFiltering.Pixel]]\r\n */\r\n antialiasing?: boolean;\r\n\r\n /**\r\n * Optionally upscale the number of pixels in the canvas. Normally only useful if you need a smoother look to your assets, especially\r\n * [[Text]].\r\n *\r\n * **WARNING** It is recommended you try using `antialiasing: true` before adjusting pixel ratio. Pixel ratio will consume more memory\r\n * and on mobile may break if the internal size of the canvas exceeds 4k pixels in width or height.\r\n *\r\n * Default is based the display's pixel ratio, for example a HiDPI screen might have the value 2;\r\n */\r\n pixelRatio?: number;\r\n\r\n /**\r\n * Optionally configure the native canvas transparent backdrop\r\n */\r\n enableCanvasTransparency?: boolean;\r\n\r\n /**\r\n * Optionally specify the target canvas DOM element to render the game in\r\n */\r\n canvasElementId?: string;\r\n\r\n /**\r\n * Optionally specify the target canvas DOM element directly\r\n */\r\n canvasElement?: HTMLCanvasElement;\r\n\r\n /**\r\n * Optionally snap graphics to nearest pixel, default is false\r\n */\r\n snapToPixel?: boolean;\r\n\r\n /**\r\n * The [[DisplayMode]] of the game, by default [[DisplayMode.FitScreen]] with aspect ratio 4:3 (800x600).\r\n * Depending on this value, [[width]] and [[height]] may be ignored.\r\n */\r\n displayMode?: DisplayMode;\r\n\r\n /**\r\n * Configures the pointer scope. Pointers scoped to the 'Canvas' can only fire events within the canvas viewport; whereas, 'Document'\r\n * (default) scoped will fire anywhere on the page.\r\n */\r\n pointerScope?: PointerScope;\r\n\r\n /**\r\n * Suppress boot up console message, which contains the \"powered by Excalibur message\"\r\n */\r\n suppressConsoleBootMessage?: boolean;\r\n\r\n /**\r\n * Suppress minimum browser feature detection, it is not recommended users of excalibur switch this off. This feature ensures that\r\n * the currently running browser meets the minimum requirements for running excalibur. This can be useful if running on non-standard\r\n * browsers or if there is a bug in excalibur preventing execution.\r\n */\r\n suppressMinimumBrowserFeatureDetection?: boolean;\r\n\r\n /**\r\n * Suppress HiDPI auto detection and scaling, it is not recommended users of excalibur switch off this feature. This feature detects\r\n * and scales the drawing canvas appropriately to accommodate HiDPI screens.\r\n */\r\n suppressHiDPIScaling?: boolean;\r\n\r\n /**\r\n * Suppress play button, it is not recommended users of excalibur switch this feature. Some browsers require a user gesture (like a click)\r\n * for certain browser features to work like web audio.\r\n */\r\n suppressPlayButton?: boolean;\r\n\r\n /**\r\n * Sets the focus of the window, this is needed when hosting excalibur in a cross-origin iframe in order for certain events\r\n * (like keyboard) to work.\r\n * For example: itch.io or codesandbox.io\r\n *\r\n * By default set to true,\r\n */\r\n grabWindowFocus?: boolean;\r\n\r\n /**\r\n * Scroll prevention method.\r\n */\r\n scrollPreventionMode?: ScrollPreventionMode;\r\n\r\n /**\r\n * Optionally set the background color\r\n */\r\n backgroundColor?: Color;\r\n\r\n /**\r\n * Optionally set the maximum fps if not set Excalibur will go as fast as the device allows.\r\n *\r\n * You may want to constrain max fps if your game cannot maintain fps consistently, it can look and feel better to have a 30fps game than\r\n * one that bounces between 30fps and 60fps\r\n */\r\n maxFps?: number;\r\n\r\n /**\r\n * Optionally configure a fixed update fps, this can be desireable if you need the physics simulation to be very stable. When set\r\n * the update step and physics will use the same elapsed time for each tick even if the graphical framerate drops. In order for the\r\n * simulation to be correct, excalibur will run multiple updates in a row (at the configured update elapsed) to catch up, for example\r\n * there could be X updates and 1 draw each clock step.\r\n *\r\n * **NOTE:** This does come at a potential perf cost because each catch-up update will need to be run if the fixed rate is greater than\r\n * the current instantaneous framerate, or perf gain if the fixed rate is less than the current framerate.\r\n *\r\n * By default is unset and updates will use the current instantaneous framerate with 1 update and 1 draw each clock step.\r\n */\r\n fixedUpdateFps?: number\r\n\r\n /**\r\n * Default `true`, optionally configure excalibur to use optimal draw call sorting, to opt out set this to `false`.\r\n *\r\n * Excalibur will automatically sort draw calls by z and priority into renderer batches for maximal draw performance,\r\n * this can disrupt a specific desired painter order.\r\n */\r\n useDrawSorting?: boolean;\r\n\r\n /**\r\n * Optionally configure how excalibur handles poor performance on a player's browser\r\n */\r\n configurePerformanceCanvas2DFallback?: {\r\n /**\r\n * By default `true`, this will switch the internal graphics context to Canvas2D which can improve performance on non hardware\r\n * accelerated browsers.\r\n */\r\n allow: boolean;\r\n /**\r\n * By default `false`, if set to `true` a dialogue will be presented to the player about their browser and how to potentially\r\n * address any issues.\r\n */\r\n showPlayerMessage?: boolean;\r\n /**\r\n * Default `{ numberOfFrames: 100, fps: 20 }`, optionally configure excalibur to fallback to the 2D Canvas renderer\r\n * if bad performance is detected.\r\n *\r\n * In this example of the default if excalibur is running at 20fps or less for 100 frames it will trigger the fallback to the 2D\r\n * Canvas renderer.\r\n */\r\n threshold?: { numberOfFrames: number, fps: number };\r\n }\r\n}\r\n\r\n/**\r\n * The Excalibur Engine\r\n *\r\n * The [[Engine]] is the main driver for a game. It is responsible for\r\n * starting/stopping the game, maintaining state, transmitting events,\r\n * loading resources, and managing the scene.\r\n */\r\nexport class Engine implements CanInitialize, CanUpdate, CanDraw {\r\n /**\r\n * Listen to and emit events on the Engine\r\n */\r\n public events = new EventEmitter();\r\n\r\n /**\r\n * Excalibur browser events abstraction used for wiring to native browser events safely\r\n */\r\n public browser: BrowserEvents;\r\n\r\n /**\r\n * Screen abstraction\r\n */\r\n public screen: Screen;\r\n\r\n /**\r\n * Direct access to the engine's canvas element\r\n */\r\n public canvas: HTMLCanvasElement;\r\n\r\n /**\r\n * Direct access to the ExcaliburGraphicsContext used for drawing things to the screen\r\n */\r\n public graphicsContext: ExcaliburGraphicsContext;\r\n\r\n /**\r\n * Direct access to the canvas element ID, if an ID exists\r\n */\r\n public canvasElementId: string;\r\n\r\n /**\r\n * Optionally set the maximum fps if not set Excalibur will go as fast as the device allows.\r\n *\r\n * You may want to constrain max fps if your game cannot maintain fps consistently, it can look and feel better to have a 30fps game than\r\n * one that bounces between 30fps and 60fps\r\n */\r\n public maxFps: number = Number.POSITIVE_INFINITY;\r\n\r\n /**\r\n * Optionally configure a fixed update fps, this can be desireable if you need the physics simulation to be very stable. When set\r\n * the update step and physics will use the same elapsed time for each tick even if the graphical framerate drops. In order for the\r\n * simulation to be correct, excalibur will run multiple updates in a row (at the configured update elapsed) to catch up, for example\r\n * there could be X updates and 1 draw each clock step.\r\n *\r\n * **NOTE:** This does come at a potential perf cost because each catch-up update will need to be run if the fixed rate is greater than\r\n * the current instantaneous framerate, or perf gain if the fixed rate is less than the current framerate.\r\n *\r\n * By default is unset and updates will use the current instantaneous framerate with 1 update and 1 draw each clock step.\r\n */\r\n public fixedUpdateFps?: number;\r\n\r\n /**\r\n * Direct access to the excalibur clock\r\n */\r\n public clock: Clock;\r\n\r\n /**\r\n * The width of the game canvas in pixels (physical width component of the\r\n * resolution of the canvas element)\r\n */\r\n public get canvasWidth(): number {\r\n return this.screen.canvasWidth;\r\n }\r\n\r\n /**\r\n * Returns half width of the game canvas in pixels (half physical width component)\r\n */\r\n public get halfCanvasWidth(): number {\r\n return this.screen.halfCanvasWidth;\r\n }\r\n\r\n /**\r\n * The height of the game canvas in pixels, (physical height component of\r\n * the resolution of the canvas element)\r\n */\r\n public get canvasHeight(): number {\r\n return this.screen.canvasHeight;\r\n }\r\n\r\n /**\r\n * Returns half height of the game canvas in pixels (half physical height component)\r\n */\r\n public get halfCanvasHeight(): number {\r\n return this.screen.halfCanvasHeight;\r\n }\r\n\r\n /**\r\n * Returns the width of the engine's visible drawing surface in pixels including zoom and device pixel ratio.\r\n */\r\n public get drawWidth(): number {\r\n return this.screen.drawWidth;\r\n }\r\n\r\n /**\r\n * Returns half the width of the engine's visible drawing surface in pixels including zoom and device pixel ratio.\r\n */\r\n public get halfDrawWidth(): number {\r\n return this.screen.halfDrawWidth;\r\n }\r\n\r\n /**\r\n * Returns the height of the engine's visible drawing surface in pixels including zoom and device pixel ratio.\r\n */\r\n public get drawHeight(): number {\r\n return this.screen.drawHeight;\r\n }\r\n\r\n /**\r\n * Returns half the height of the engine's visible drawing surface in pixels including zoom and device pixel ratio.\r\n */\r\n public get halfDrawHeight(): number {\r\n return this.screen.halfDrawHeight;\r\n }\r\n\r\n /**\r\n * Returns whether excalibur detects the current screen to be HiDPI\r\n */\r\n public get isHiDpi(): boolean {\r\n return this.screen.isHiDpi;\r\n }\r\n\r\n /**\r\n * Access engine input like pointer, keyboard, or gamepad\r\n */\r\n public input: EngineInput;\r\n\r\n /**\r\n * Map multiple input sources to specific game actions actions\r\n */\r\n public inputMapper: InputMapper;\r\n\r\n /**\r\n * Access Excalibur debugging functionality.\r\n *\r\n * Useful when you want to debug different aspects of built in engine features like\r\n * * Transform\r\n * * Graphics\r\n * * Colliders\r\n */\r\n public debug: Debug;\r\n\r\n /**\r\n * Access [[stats]] that holds frame statistics.\r\n */\r\n public get stats(): DebugStats {\r\n return this.debug.stats;\r\n }\r\n\r\n /**\r\n * The current [[Scene]] being drawn and updated on screen\r\n */\r\n public currentScene: Scene;\r\n\r\n /**\r\n * The default [[Scene]] of the game, use [[Engine.goToScene]] to transition to different scenes.\r\n */\r\n public readonly rootScene: Scene;\r\n\r\n /**\r\n * Contains all the scenes currently registered with Excalibur\r\n */\r\n public readonly scenes: { [key: string]: Scene } = {};\r\n\r\n /**\r\n * Indicates whether the engine is set to fullscreen or not\r\n */\r\n public get isFullscreen(): boolean {\r\n return this.screen.isFullScreen;\r\n }\r\n\r\n /**\r\n * Indicates the current [[DisplayMode]] of the engine.\r\n */\r\n public get displayMode(): DisplayMode {\r\n return this.screen.displayMode;\r\n }\r\n\r\n private _suppressPlayButton: boolean = false;\r\n /**\r\n * Returns the calculated pixel ration for use in rendering\r\n */\r\n public get pixelRatio(): number {\r\n return this.screen.pixelRatio;\r\n }\r\n\r\n /**\r\n * Indicates whether audio should be paused when the game is no longer visible.\r\n */\r\n public pauseAudioWhenHidden: boolean = true;\r\n\r\n /**\r\n * Indicates whether the engine should draw with debug information\r\n */\r\n private _isDebug: boolean = false;\r\n public get isDebug(): boolean {\r\n return this._isDebug;\r\n }\r\n\r\n /**\r\n * Sets the background color for the engine.\r\n */\r\n public backgroundColor: Color;\r\n\r\n /**\r\n * Sets the Transparency for the engine.\r\n */\r\n public enableCanvasTransparency: boolean = true;\r\n\r\n /**\r\n * Hints the graphics context to truncate fractional world space coordinates\r\n */\r\n public get snapToPixel(): boolean {\r\n return this.graphicsContext.snapToPixel;\r\n };\r\n\r\n public set snapToPixel(shouldSnapToPixel: boolean) {\r\n this.graphicsContext.snapToPixel = shouldSnapToPixel;\r\n };\r\n\r\n /**\r\n * The action to take when a fatal exception is thrown\r\n */\r\n public onFatalException = (e: any) => {\r\n Logger.getInstance().fatal(e);\r\n };\r\n\r\n /**\r\n * The mouse wheel scroll prevention mode\r\n */\r\n public pageScrollPreventionMode: ScrollPreventionMode;\r\n\r\n private _logger: Logger;\r\n\r\n private _toaster: Toaster = new Toaster();\r\n\r\n // this determines whether excalibur is compatible with your browser\r\n private _compatible: boolean;\r\n\r\n private _timescale: number = 1.0;\r\n\r\n // loading\r\n private _loader: Loader;\r\n\r\n private _isInitialized: boolean = false;\r\n\r\n private _deferredGoTo: string = null;\r\n\r\n public emit>(eventName: TEventName, event: EngineEvents[TEventName]): void;\r\n public emit(eventName: string, event?: any): void;\r\n public emit | string>(eventName: TEventName, event?: any): void {\r\n this.events.emit(eventName, event);\r\n }\r\n\r\n public on>(eventName: TEventName, handler: Handler): Subscription;\r\n public on(eventName: string, handler: Handler): Subscription;\r\n public on | string>(eventName: TEventName, handler: Handler): Subscription {\r\n return this.events.on(eventName, handler);\r\n }\r\n\r\n public once>(eventName: TEventName, handler: Handler): Subscription;\r\n public once(eventName: string, handler: Handler): Subscription;\r\n public once | string>(eventName: TEventName, handler: Handler): Subscription {\r\n return this.events.once(eventName, handler);\r\n }\r\n\r\n public off>(eventName: TEventName, handler: Handler): void;\r\n public off(eventName: string, handler: Handler): void;\r\n public off(eventName: string): void;\r\n public off | string>(eventName: TEventName, handler?: Handler): void {\r\n this.events.off(eventName, handler);\r\n }\r\n\r\n /**\r\n * Default [[EngineOptions]]\r\n */\r\n private static _DEFAULT_ENGINE_OPTIONS: EngineOptions = {\r\n width: 0,\r\n height: 0,\r\n enableCanvasTransparency: true,\r\n useDrawSorting: true,\r\n configurePerformanceCanvas2DFallback: {\r\n allow: true,\r\n showPlayerMessage: false,\r\n threshold: { fps: 20, numberOfFrames: 100 }\r\n },\r\n canvasElementId: '',\r\n canvasElement: undefined,\r\n snapToPixel: false,\r\n pointerScope: PointerScope.Canvas,\r\n suppressConsoleBootMessage: null,\r\n suppressMinimumBrowserFeatureDetection: null,\r\n suppressHiDPIScaling: null,\r\n suppressPlayButton: null,\r\n grabWindowFocus: true,\r\n scrollPreventionMode: ScrollPreventionMode.Canvas,\r\n backgroundColor: Color.fromHex('#2185d0') // Excalibur blue\r\n };\r\n\r\n private _originalOptions: EngineOptions = {};\r\n public readonly _originalDisplayMode: DisplayMode;\r\n\r\n /**\r\n * Creates a new game using the given [[EngineOptions]]. By default, if no options are provided,\r\n * the game will be rendered full screen (taking up all available browser window space).\r\n * You can customize the game rendering through [[EngineOptions]].\r\n *\r\n * Example:\r\n *\r\n * ```js\r\n * var game = new ex.Engine({\r\n * width: 0, // the width of the canvas\r\n * height: 0, // the height of the canvas\r\n * enableCanvasTransparency: true, // the transparencySection of the canvas\r\n * canvasElementId: '', // the DOM canvas element ID, if you are providing your own\r\n * displayMode: ex.DisplayMode.FullScreen, // the display mode\r\n * pointerScope: ex.PointerScope.Document, // the scope of capturing pointer (mouse/touch) events\r\n * backgroundColor: ex.Color.fromHex('#2185d0') // background color of the engine\r\n * });\r\n *\r\n * // call game.start, which is a Promise\r\n * game.start().then(function () {\r\n * // ready, set, go!\r\n * });\r\n * ```\r\n */\r\n constructor(options?: EngineOptions) {\r\n options = { ...Engine._DEFAULT_ENGINE_OPTIONS, ...options };\r\n this._originalOptions = options;\r\n\r\n Flags.freeze();\r\n\r\n // Initialize browser events facade\r\n this.browser = new BrowserEvents(window, document);\r\n\r\n // Check compatibility\r\n const detector = new Detector();\r\n if (!options.suppressMinimumBrowserFeatureDetection && !(this._compatible = detector.test())) {\r\n const message = document.createElement('div');\r\n message.innerText = 'Sorry, your browser does not support all the features needed for Excalibur';\r\n document.body.appendChild(message);\r\n\r\n detector.failedTests.forEach(function (test) {\r\n const testMessage = document.createElement('div');\r\n testMessage.innerText = 'Browser feature missing ' + test;\r\n document.body.appendChild(testMessage);\r\n });\r\n\r\n if (options.canvasElementId) {\r\n const canvas = document.getElementById(options.canvasElementId);\r\n if (canvas) {\r\n canvas.parentElement.removeChild(canvas);\r\n }\r\n }\r\n\r\n return;\r\n } else {\r\n this._compatible = true;\r\n }\r\n\r\n // Use native console API for color fun\r\n // eslint-disable-next-line no-console\r\n if (console.log && !options.suppressConsoleBootMessage) {\r\n // eslint-disable-next-line no-console\r\n console.log(\r\n `%cPowered by Excalibur.js (v${EX_VERSION})`,\r\n 'background: #176BAA; color: white; border-radius: 5px; padding: 15px; font-size: 1.5em; line-height: 80px;'\r\n );\r\n // eslint-disable-next-line no-console\r\n console.log('\\n\\\r\n /| ________________\\n\\\r\nO|===|* >________________>\\n\\\r\n \\\\|');\r\n // eslint-disable-next-line no-console\r\n console.log('Visit', 'http://excaliburjs.com', 'for more information');\r\n }\r\n\r\n // Suppress play button\r\n if (options.suppressPlayButton) {\r\n this._suppressPlayButton = true;\r\n }\r\n\r\n this._logger = Logger.getInstance();\r\n\r\n // If debug is enabled, let's log browser features to the console.\r\n if (this._logger.defaultLevel === LogLevel.Debug) {\r\n detector.logBrowserFeatures();\r\n }\r\n\r\n this._logger.debug('Building engine...');\r\n\r\n this.canvasElementId = options.canvasElementId;\r\n\r\n if (options.canvasElementId) {\r\n this._logger.debug('Using Canvas element specified: ' + options.canvasElementId);\r\n this.canvas = document.getElementById(options.canvasElementId);\r\n } else if (options.canvasElement) {\r\n this._logger.debug('Using Canvas element specified:', options.canvasElement);\r\n this.canvas = options.canvasElement;\r\n } else {\r\n this._logger.debug('Using generated canvas element');\r\n this.canvas = document.createElement('canvas');\r\n }\r\n\r\n let displayMode = options.displayMode ?? DisplayMode.Fixed;\r\n if ((options.width && options.height) || options.viewport) {\r\n if (options.displayMode === undefined) {\r\n displayMode = DisplayMode.Fixed;\r\n }\r\n this._logger.debug('Engine viewport is size ' + options.width + ' x ' + options.height);\r\n } else if (!options.displayMode) {\r\n this._logger.debug('Engine viewport is fit');\r\n displayMode = DisplayMode.FitScreen;\r\n }\r\n\r\n this._originalDisplayMode = displayMode;\r\n\r\n // Canvas 2D fallback can be flagged on\r\n let useCanvasGraphicsContext = Flags.isEnabled('use-canvas-context');\r\n if (!useCanvasGraphicsContext) {\r\n // Attempt webgl first\r\n try {\r\n this.graphicsContext = new ExcaliburGraphicsContextWebGL({\r\n canvasElement: this.canvas,\r\n enableTransparency: this.enableCanvasTransparency,\r\n smoothing: options.antialiasing,\r\n backgroundColor: options.backgroundColor,\r\n snapToPixel: options.snapToPixel,\r\n useDrawSorting: options.useDrawSorting\r\n });\r\n } catch (e) {\r\n this._logger.warn(\r\n `Excalibur could not load webgl for some reason (${(e as Error).message}) and loaded a Canvas 2D fallback. ` +\r\n `Some features of Excalibur will not work in this mode. \\n\\n` +\r\n 'Read more about this issue at https://excaliburjs.com/docs/webgl'\r\n );\r\n // fallback to canvas in case of failure\r\n useCanvasGraphicsContext = true;\r\n }\r\n }\r\n\r\n if (useCanvasGraphicsContext) {\r\n this.graphicsContext = new ExcaliburGraphicsContext2DCanvas({\r\n canvasElement: this.canvas,\r\n enableTransparency: this.enableCanvasTransparency,\r\n smoothing: options.antialiasing,\r\n backgroundColor: options.backgroundColor,\r\n snapToPixel: options.snapToPixel,\r\n useDrawSorting: options.useDrawSorting\r\n });\r\n }\r\n\r\n this.screen = new Screen({\r\n canvas: this.canvas,\r\n context: this.graphicsContext,\r\n antialiasing: options.antialiasing ?? true,\r\n browser: this.browser,\r\n viewport: options.viewport ?? (options.width && options.height ? { width: options.width, height: options.height } : Resolution.SVGA),\r\n resolution: options.resolution,\r\n displayMode,\r\n pixelRatio: options.suppressHiDPIScaling ? 1 : (options.pixelRatio ?? null)\r\n });\r\n\r\n // Set default filtering based on antialiasing\r\n TextureLoader.filtering = options.antialiasing ? ImageFiltering.Blended : ImageFiltering.Pixel;\r\n\r\n if (options.backgroundColor) {\r\n this.backgroundColor = options.backgroundColor.clone();\r\n }\r\n\r\n this.maxFps = options.maxFps ?? this.maxFps;\r\n this.fixedUpdateFps = options.fixedUpdateFps ?? this.fixedUpdateFps;\r\n\r\n this.clock = new StandardClock({\r\n maxFps: this.maxFps,\r\n tick: this._mainloop.bind(this),\r\n onFatalException: (e) => this.onFatalException(e)\r\n });\r\n\r\n this.enableCanvasTransparency = options.enableCanvasTransparency;\r\n\r\n this._loader = new Loader();\r\n this._loader.wireEngine(this);\r\n this.debug = new Debug(this);\r\n\r\n this._initialize(options);\r\n\r\n this.rootScene = this.currentScene = new Scene();\r\n\r\n this.addScene('root', this.rootScene);\r\n (window as any).___EXCALIBUR_DEVTOOL = this;\r\n }\r\n\r\n private _performanceThresholdTriggered = false;\r\n private _fpsSamples: number[] = [];\r\n private _monitorPerformanceThresholdAndTriggerFallback() {\r\n const { allow } = this._originalOptions.configurePerformanceCanvas2DFallback;\r\n let { threshold, showPlayerMessage } = this._originalOptions.configurePerformanceCanvas2DFallback;\r\n if (threshold === undefined) {\r\n threshold = Engine._DEFAULT_ENGINE_OPTIONS.configurePerformanceCanvas2DFallback.threshold;\r\n }\r\n if (showPlayerMessage === undefined) {\r\n showPlayerMessage = Engine._DEFAULT_ENGINE_OPTIONS.configurePerformanceCanvas2DFallback.showPlayerMessage;\r\n }\r\n if (!Flags.isEnabled('use-canvas-context') && allow && this.ready && !this._performanceThresholdTriggered) {\r\n // Calculate Average fps for last X number of frames after start\r\n if (this._fpsSamples.length === threshold.numberOfFrames) {\r\n this._fpsSamples.splice(0, 1);\r\n }\r\n this._fpsSamples.push(this.clock.fpsSampler.fps);\r\n let total = 0;\r\n for (let i = 0; i < this._fpsSamples.length; i++) {\r\n total += this._fpsSamples[i];\r\n }\r\n const average = total / this._fpsSamples.length;\r\n\r\n if (this._fpsSamples.length === threshold.numberOfFrames) {\r\n if (average <= threshold.fps) {\r\n this._performanceThresholdTriggered = true;\r\n this._logger.warn(\r\n `Switching to browser 2D Canvas fallback due to performance. Some features of Excalibur will not work in this mode.\\n` +\r\n 'this might mean your browser doesn\\'t have webgl enabled or hardware acceleration is unavailable.\\n\\n' +\r\n 'If in Chrome:\\n' +\r\n ' * Visit Settings > Advanced > System, and ensure \"Use Hardware Acceleration\" is checked.\\n'+\r\n ' * Visit chrome://flags/#ignore-gpu-blocklist and ensure \"Override software rendering list\" is \"enabled\"\\n' +\r\n 'If in Firefox, visit about:config\\n' +\r\n ' * Ensure webgl.disabled = false\\n' +\r\n ' * Ensure webgl.force-enabled = true\\n' +\r\n ' * Ensure layers.acceleration.force-enabled = true\\n\\n' +\r\n 'Read more about this issue at https://excaliburjs.com/docs/performance'\r\n );\r\n\r\n if (showPlayerMessage) {\r\n this._toaster.toast(\r\n 'Excalibur is encountering performance issues. '+\r\n 'It\\'s possible that your browser doesn\\'t have hardware acceleration enabled. ' +\r\n 'Visit [LINK] for more information and potential solutions.',\r\n 'https://excaliburjs.com/docs/performance'\r\n );\r\n }\r\n this.useCanvas2DFallback();\r\n this.emit('fallbackgraphicscontext', this.graphicsContext);\r\n }\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Switches the engine's graphics context to the 2D Canvas.\r\n * @warning Some features of Excalibur will not work in this mode.\r\n */\r\n public useCanvas2DFallback() {\r\n // Swap out the canvas\r\n const newCanvas = this.canvas.cloneNode(false) as HTMLCanvasElement;\r\n this.canvas.parentNode.replaceChild(newCanvas, this.canvas);\r\n this.canvas = newCanvas;\r\n\r\n const options = this._originalOptions;\r\n const displayMode = this._originalDisplayMode;\r\n\r\n // New graphics context\r\n this.graphicsContext = new ExcaliburGraphicsContext2DCanvas({\r\n canvasElement: this.canvas,\r\n enableTransparency: this.enableCanvasTransparency,\r\n smoothing: options.antialiasing,\r\n backgroundColor: options.backgroundColor,\r\n snapToPixel: options.snapToPixel,\r\n useDrawSorting: options.useDrawSorting\r\n });\r\n\r\n // Reset screen\r\n if (this.screen) {\r\n this.screen.dispose();\r\n }\r\n\r\n this.screen = new Screen({\r\n canvas: this.canvas,\r\n context: this.graphicsContext,\r\n antialiasing: options.antialiasing ?? true,\r\n browser: this.browser,\r\n viewport: options.viewport ?? (options.width && options.height ? { width: options.width, height: options.height } : Resolution.SVGA),\r\n resolution: options.resolution,\r\n displayMode,\r\n pixelRatio: options.suppressHiDPIScaling ? 1 : (options.pixelRatio ?? null)\r\n });\r\n this.screen.setCurrentCamera(this.currentScene.camera);\r\n\r\n // Reset pointers\r\n this.input.pointers.detach();\r\n const pointerTarget = options && options.pointerScope === PointerScope.Document ? document : this.canvas;\r\n this.input.pointers = this.input.pointers.recreate(pointerTarget, this);\r\n this.input.pointers.init();\r\n }\r\n\r\n /**\r\n * Returns a BoundingBox of the top left corner of the screen\r\n * and the bottom right corner of the screen.\r\n */\r\n public getWorldBounds() {\r\n return this.screen.getWorldBounds();\r\n }\r\n\r\n /**\r\n * Gets the current engine timescale factor (default is 1.0 which is 1:1 time)\r\n */\r\n public get timescale() {\r\n return this._timescale;\r\n }\r\n\r\n /**\r\n * Sets the current engine timescale factor. Useful for creating slow-motion effects or fast-forward effects\r\n * when using time-based movement.\r\n */\r\n public set timescale(value: number) {\r\n if (value <= 0) {\r\n Logger.getInstance().error('Cannot set engine.timescale to a value of 0 or less than 0.');\r\n return;\r\n }\r\n\r\n this._timescale = value;\r\n }\r\n\r\n /**\r\n * Adds a [[Timer]] to the [[currentScene]].\r\n * @param timer The timer to add to the [[currentScene]].\r\n */\r\n public addTimer(timer: Timer): Timer {\r\n return this.currentScene.addTimer(timer);\r\n }\r\n\r\n /**\r\n * Removes a [[Timer]] from the [[currentScene]].\r\n * @param timer The timer to remove to the [[currentScene]].\r\n */\r\n public removeTimer(timer: Timer): Timer {\r\n return this.currentScene.removeTimer(timer);\r\n }\r\n\r\n /**\r\n * Adds a [[Scene]] to the engine, think of scenes in Excalibur as you\r\n * would levels or menus.\r\n *\r\n * @param key The name of the scene, must be unique\r\n * @param scene The scene to add to the engine\r\n */\r\n public addScene(key: string, scene: Scene) {\r\n if (this.scenes[key]) {\r\n this._logger.warn('Scene', key, 'already exists overwriting');\r\n }\r\n this.scenes[key] = scene;\r\n }\r\n\r\n /**\r\n * Removes a [[Scene]] instance from the engine\r\n * @param scene The scene to remove\r\n */\r\n public removeScene(scene: Scene): void;\r\n /**\r\n * Removes a scene from the engine by key\r\n * @param key The scene key to remove\r\n */\r\n public removeScene(key: string): void;\r\n /**\r\n * @internal\r\n */\r\n public removeScene(entity: any): void {\r\n if (entity instanceof Scene) {\r\n // remove scene\r\n for (const key in this.scenes) {\r\n if (this.scenes.hasOwnProperty(key)) {\r\n if (this.scenes[key] === entity) {\r\n delete this.scenes[key];\r\n }\r\n }\r\n }\r\n }\r\n\r\n if (typeof entity === 'string') {\r\n // remove scene\r\n delete this.scenes[entity];\r\n }\r\n }\r\n\r\n /**\r\n * Adds a [[Scene]] to the engine, think of scenes in Excalibur as you\r\n * would levels or menus.\r\n * @param sceneKey The key of the scene, must be unique\r\n * @param scene The scene to add to the engine\r\n */\r\n public add(sceneKey: string, scene: Scene): void;\r\n /**\r\n * Adds a [[Timer]] to the [[currentScene]].\r\n * @param timer The timer to add to the [[currentScene]].\r\n */\r\n public add(timer: Timer): void;\r\n /**\r\n * Adds a [[TileMap]] to the [[currentScene]], once this is done the TileMap\r\n * will be drawn and updated.\r\n */\r\n public add(tileMap: TileMap): void;\r\n /**\r\n * Adds an actor to the [[currentScene]] of the game. This is synonymous\r\n * to calling `engine.currentScene.add(actor)`.\r\n *\r\n * Actors can only be drawn if they are a member of a scene, and only\r\n * the [[currentScene]] may be drawn or updated.\r\n *\r\n * @param actor The actor to add to the [[currentScene]]\r\n */\r\n public add(actor: Actor): void;\r\n\r\n public add(entity: Entity): void;\r\n\r\n /**\r\n * Adds a [[ScreenElement]] to the [[currentScene]] of the game,\r\n * ScreenElements do not participate in collisions, instead the\r\n * remain in the same place on the screen.\r\n * @param screenElement The ScreenElement to add to the [[currentScene]]\r\n */\r\n public add(screenElement: ScreenElement): void;\r\n public add(entity: any): void {\r\n if (arguments.length === 2) {\r\n this.addScene(arguments[0], arguments[1]);\r\n return;\r\n }\r\n if (this._deferredGoTo && this.scenes[this._deferredGoTo]) {\r\n this.scenes[this._deferredGoTo].add(entity);\r\n } else {\r\n this.currentScene.add(entity);\r\n }\r\n }\r\n\r\n /**\r\n * Removes a scene instance from the engine\r\n * @param scene The scene to remove\r\n */\r\n public remove(scene: Scene): void;\r\n /**\r\n * Removes a scene from the engine by key\r\n * @param sceneKey The scene to remove\r\n */\r\n public remove(sceneKey: string): void;\r\n /**\r\n * Removes a [[Timer]] from the [[currentScene]].\r\n * @param timer The timer to remove to the [[currentScene]].\r\n */\r\n public remove(timer: Timer): void;\r\n /**\r\n * Removes a [[TileMap]] from the [[currentScene]], it will no longer be drawn or updated.\r\n */\r\n public remove(tileMap: TileMap): void;\r\n /**\r\n * Removes an actor from the [[currentScene]] of the game. This is synonymous\r\n * to calling `engine.currentScene.removeChild(actor)`.\r\n * Actors that are removed from a scene will no longer be drawn or updated.\r\n *\r\n * @param actor The actor to remove from the [[currentScene]].\r\n */\r\n public remove(actor: Actor): void;\r\n /**\r\n * Removes a [[ScreenElement]] to the scene, it will no longer be drawn or updated\r\n * @param screenElement The ScreenElement to remove from the [[currentScene]]\r\n */\r\n public remove(screenElement: ScreenElement): void;\r\n public remove(entity: any): void {\r\n if (entity instanceof Entity) {\r\n this.currentScene.remove(entity);\r\n }\r\n\r\n if (entity instanceof Scene) {\r\n this.removeScene(entity);\r\n }\r\n\r\n if (typeof entity === 'string') {\r\n this.removeScene(entity);\r\n }\r\n }\r\n\r\n /**\r\n * Changes the currently updating and drawing scene to a different,\r\n * named scene. Calls the [[Scene]] lifecycle events.\r\n * @param key The key of the scene to transition to.\r\n * @param data Optional data to send to the scene's onActivate method\r\n */\r\n public goToScene(key: string, data?: TData): void {\r\n // if not yet initialized defer goToScene\r\n if (!this.isInitialized) {\r\n this._deferredGoTo = key;\r\n return;\r\n }\r\n\r\n if (this.scenes[key]) {\r\n const previousScene = this.currentScene;\r\n const nextScene = this.scenes[key];\r\n\r\n this._logger.debug('Going to scene:', key);\r\n\r\n // only deactivate when initialized\r\n if (this.currentScene.isInitialized) {\r\n const context = { engine: this, previousScene, nextScene };\r\n this.currentScene._deactivate.apply(this.currentScene, [context, nextScene]);\r\n this.currentScene.events.emit('deactivate', new DeactivateEvent(context, this.currentScene));\r\n }\r\n\r\n // set current scene to new one\r\n this.currentScene = nextScene;\r\n this.screen.setCurrentCamera(nextScene.camera);\r\n\r\n // initialize the current scene if has not been already\r\n this.currentScene._initialize(this);\r\n\r\n const context = { engine: this, previousScene, nextScene, data };\r\n this.currentScene._activate.apply(this.currentScene, [context, nextScene]);\r\n this.currentScene.events.emit('activate', new ActivateEvent(context, this.currentScene));\r\n } else {\r\n this._logger.error('Scene', key, 'does not exist!');\r\n }\r\n }\r\n\r\n /**\r\n * Transforms the current x, y from screen coordinates to world coordinates\r\n * @param point Screen coordinate to convert\r\n */\r\n public screenToWorldCoordinates(point: Vector): Vector {\r\n return this.screen.screenToWorldCoordinates(point);\r\n }\r\n\r\n /**\r\n * Transforms a world coordinate, to a screen coordinate\r\n * @param point World coordinate to convert\r\n */\r\n public worldToScreenCoordinates(point: Vector): Vector {\r\n return this.screen.worldToScreenCoordinates(point);\r\n }\r\n\r\n /**\r\n * Initializes the internal canvas, rendering context, display mode, and native event listeners\r\n */\r\n private _initialize(options?: EngineOptions) {\r\n this.pageScrollPreventionMode = options.scrollPreventionMode;\r\n\r\n // initialize inputs\r\n const pointerTarget = options && options.pointerScope === PointerScope.Document ? document : this.canvas;\r\n this.input = {\r\n keyboard: new Keyboard(),\r\n pointers: new PointerEventReceiver(pointerTarget, this),\r\n gamepads: new Gamepads()\r\n };\r\n this.input.keyboard.init({\r\n grabWindowFocus: this._originalOptions?.grabWindowFocus ?? true\r\n });\r\n this.input.pointers.init({\r\n grabWindowFocus: this._originalOptions?.grabWindowFocus ?? true\r\n });\r\n this.input.gamepads.init();\r\n this.inputMapper = new InputMapper(this.input);\r\n\r\n // Issue #385 make use of the visibility api\r\n // https://developer.mozilla.org/en-US/docs/Web/Guide/User_experience/Using_the_Page_Visibility_API\r\n\r\n this.browser.document.on('visibilitychange', () => {\r\n if (document.visibilityState === 'hidden') {\r\n this.events.emit('hidden', new HiddenEvent(this));\r\n this._logger.debug('Window hidden');\r\n } else if (document.visibilityState === 'visible') {\r\n this.events.emit('visible', new VisibleEvent(this));\r\n this._logger.debug('Window visible');\r\n }\r\n });\r\n\r\n if (!this.canvasElementId && !options.canvasElement) {\r\n document.body.appendChild(this.canvas);\r\n }\r\n }\r\n\r\n public onInitialize(_engine: Engine) {\r\n // Override me\r\n }\r\n\r\n /**\r\n * If supported by the browser, this will set the antialiasing flag on the\r\n * canvas. Set this to `false` if you want a 'jagged' pixel art look to your\r\n * image resources.\r\n * @param isSmooth Set smoothing to true or false\r\n */\r\n public setAntialiasing(isSmooth: boolean) {\r\n this.screen.antialiasing = isSmooth;\r\n }\r\n\r\n /**\r\n * Return the current smoothing status of the canvas\r\n */\r\n public getAntialiasing(): boolean {\r\n return this.screen.antialiasing;\r\n }\r\n\r\n /**\r\n * Gets whether the actor is Initialized\r\n */\r\n public get isInitialized(): boolean {\r\n return this._isInitialized;\r\n }\r\n\r\n private _overrideInitialize(engine: Engine) {\r\n if (!this.isInitialized) {\r\n this.onInitialize(engine);\r\n this.events.emit('initialize', new InitializeEvent(engine, this));\r\n this._isInitialized = true;\r\n if (this._deferredGoTo) {\r\n const deferredScene = this._deferredGoTo;\r\n this._deferredGoTo = null;\r\n this.goToScene(deferredScene);\r\n } else {\r\n this.goToScene('root');\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Updates the entire state of the game\r\n * @param delta Number of milliseconds elapsed since the last update.\r\n */\r\n private _update(delta: number) {\r\n if (!this.ready) {\r\n // suspend updates until loading is finished\r\n this._loader.update(this, delta);\r\n // Update input listeners\r\n this.input.keyboard.update();\r\n this.input.gamepads.update();\r\n this.inputMapper.execute();\r\n return;\r\n }\r\n\r\n\r\n // Publish preupdate events\r\n this._preupdate(delta);\r\n\r\n // process engine level events\r\n this.currentScene.update(this, delta);\r\n\r\n // Update graphics postprocessors\r\n this.graphicsContext.updatePostProcessors(delta);\r\n\r\n // Publish update event\r\n this._postupdate(delta);\r\n\r\n // Update input listeners\r\n this.input.keyboard.update();\r\n this.input.gamepads.update();\r\n this.inputMapper.execute();\r\n }\r\n\r\n /**\r\n * @internal\r\n */\r\n public _preupdate(delta: number) {\r\n this.emit('preupdate', new PreUpdateEvent(this, delta, this));\r\n this.onPreUpdate(this, delta);\r\n }\r\n\r\n public onPreUpdate(_engine: Engine, _delta: number) {\r\n // Override me\r\n }\r\n\r\n /**\r\n * @internal\r\n */\r\n public _postupdate(delta: number) {\r\n this.emit('postupdate', new PostUpdateEvent(this, delta, this));\r\n this.onPostUpdate(this, delta);\r\n }\r\n\r\n public onPostUpdate(_engine: Engine, _delta: number) {\r\n // Override me\r\n }\r\n\r\n /**\r\n * Draws the entire game\r\n * @param delta Number of milliseconds elapsed since the last draw.\r\n */\r\n private _draw(delta: number) {\r\n this.graphicsContext.beginDrawLifecycle();\r\n this.graphicsContext.clear();\r\n this._predraw(this.graphicsContext, delta);\r\n\r\n // Drawing nothing else while loading\r\n if (!this._isReady) {\r\n this._loader.canvas.draw(this.graphicsContext, 0, 0);\r\n this.graphicsContext.flush();\r\n return;\r\n }\r\n\r\n this.graphicsContext.backgroundColor = this.backgroundColor;\r\n\r\n this.currentScene.draw(this.graphicsContext, delta);\r\n\r\n this._postdraw(this.graphicsContext, delta);\r\n\r\n // Flush any pending drawings\r\n this.graphicsContext.flush();\r\n this.graphicsContext.endDrawLifecycle();\r\n\r\n this._checkForScreenShots();\r\n }\r\n\r\n /**\r\n * @internal\r\n */\r\n public _predraw(_ctx: ExcaliburGraphicsContext, delta: number) {\r\n this.emit('predraw', new PreDrawEvent(_ctx, delta, this));\r\n this.onPreDraw(_ctx, delta);\r\n }\r\n\r\n public onPreDraw(_ctx: ExcaliburGraphicsContext, _delta: number) {\r\n // Override me\r\n }\r\n\r\n /**\r\n * @internal\r\n */\r\n public _postdraw(_ctx: ExcaliburGraphicsContext, delta: number) {\r\n this.emit('postdraw', new PostDrawEvent(_ctx, delta, this));\r\n this.onPostDraw(_ctx, delta);\r\n }\r\n\r\n public onPostDraw(_ctx: ExcaliburGraphicsContext, _delta: number) {\r\n // Override me\r\n }\r\n\r\n /**\r\n * Enable or disable Excalibur debugging functionality.\r\n * @param toggle a value that debug drawing will be changed to\r\n */\r\n public showDebug(toggle: boolean): void {\r\n this._isDebug = toggle;\r\n }\r\n\r\n /**\r\n * Toggle Excalibur debugging functionality.\r\n */\r\n public toggleDebug(): boolean {\r\n this._isDebug = !this._isDebug;\r\n return this._isDebug;\r\n }\r\n\r\n private _loadingComplete: boolean = false;\r\n\r\n /**\r\n * Returns true when loading is totally complete and the player has clicked start\r\n */\r\n public get loadingComplete() {\r\n return this._loadingComplete;\r\n }\r\n\r\n private _isReady = false;\r\n public get ready() {\r\n return this._isReady;\r\n }\r\n private _isReadyResolve: () => any;\r\n private _isReadyPromise = new Promise(resolve => {\r\n this._isReadyResolve = resolve;\r\n });\r\n public isReady(): Promise {\r\n return this._isReadyPromise;\r\n }\r\n\r\n\r\n /**\r\n * Starts the internal game loop for Excalibur after loading\r\n * any provided assets.\r\n * @param loader Optional [[Loader]] to use to load resources. The default loader is [[Loader]], override to provide your own\r\n * custom loader.\r\n *\r\n * Note: start() only resolves AFTER the user has clicked the play button\r\n */\r\n public async start(loader?: Loader): Promise {\r\n if (!this._compatible) {\r\n throw new Error('Excalibur is incompatible with your browser');\r\n }\r\n\r\n // Wire loader if we have it\r\n if (loader) {\r\n // Push the current user entered resolution/viewport\r\n this.screen.pushResolutionAndViewport();\r\n\r\n // Configure resolution for loader, it expects resolution === viewport\r\n this.screen.resolution = this.screen.viewport;\r\n this.screen.applyResolutionAndViewport();\r\n this._loader = loader;\r\n this._loader.suppressPlayButton = this._suppressPlayButton || this._loader.suppressPlayButton;\r\n this._loader.wireEngine(this);\r\n }\r\n\r\n // Start the excalibur clock which drives the mainloop\r\n // has started is a slight misnomer, it's really mainloop started\r\n this._logger.debug('Starting game clock...');\r\n this.browser.resume();\r\n this.clock.start();\r\n this._logger.debug('Game clock started');\r\n\r\n if (loader) {\r\n await this.load(this._loader);\r\n this._loadingComplete = true;\r\n\r\n // reset back to previous user resolution/viewport\r\n this.screen.popResolutionAndViewport();\r\n this.screen.applyResolutionAndViewport();\r\n }\r\n\r\n this._loadingComplete = true;\r\n\r\n // Initialize before ready\r\n this._overrideInitialize(this);\r\n\r\n this._isReady = true;\r\n\r\n this._isReadyResolve();\r\n this.emit('start', new GameStartEvent(this));\r\n return this._isReadyPromise;\r\n }\r\n\r\n /**\r\n * Returns the current frames elapsed milliseconds\r\n */\r\n public currentFrameElapsedMs = 0;\r\n\r\n /**\r\n * Returns the current frame lag when in fixed update mode\r\n */\r\n public currentFrameLagMs = 0;\r\n\r\n private _lagMs = 0;\r\n private _mainloop(elapsed: number) {\r\n this.emit('preframe', new PreFrameEvent(this, this.stats.prevFrame));\r\n const delta = elapsed * this.timescale;\r\n this.currentFrameElapsedMs = delta;\r\n\r\n // reset frame stats (reuse existing instances)\r\n const frameId = this.stats.prevFrame.id + 1;\r\n this.stats.currFrame.reset();\r\n this.stats.currFrame.id = frameId;\r\n this.stats.currFrame.delta = delta;\r\n this.stats.currFrame.fps = this.clock.fpsSampler.fps;\r\n GraphicsDiagnostics.clear();\r\n\r\n const beforeUpdate = this.clock.now();\r\n const fixedTimestepMs = 1000 / this.fixedUpdateFps;\r\n if (this.fixedUpdateFps) {\r\n this._lagMs += delta;\r\n while (this._lagMs >= fixedTimestepMs) {\r\n this._update(fixedTimestepMs);\r\n this._lagMs -= fixedTimestepMs;\r\n }\r\n } else {\r\n this._update(delta);\r\n }\r\n const afterUpdate = this.clock.now();\r\n this.currentFrameLagMs = this._lagMs;\r\n this._draw(delta);\r\n const afterDraw = this.clock.now();\r\n\r\n this.stats.currFrame.duration.update = afterUpdate - beforeUpdate;\r\n this.stats.currFrame.duration.draw = afterDraw - afterUpdate;\r\n this.stats.currFrame.graphics.drawnImages = GraphicsDiagnostics.DrawnImagesCount;\r\n this.stats.currFrame.graphics.drawCalls = GraphicsDiagnostics.DrawCallCount;\r\n\r\n this.emit('postframe', new PostFrameEvent(this, this.stats.currFrame));\r\n this.stats.prevFrame.reset(this.stats.currFrame);\r\n\r\n this._monitorPerformanceThresholdAndTriggerFallback();\r\n }\r\n\r\n /**\r\n * Stops Excalibur's main loop, useful for pausing the game.\r\n */\r\n public stop() {\r\n if (this.clock.isRunning()) {\r\n this.emit('stop', new GameStopEvent(this));\r\n this.browser.pause();\r\n this.clock.stop();\r\n this._logger.debug('Game stopped');\r\n }\r\n }\r\n\r\n /**\r\n * Returns the Engine's running status, Useful for checking whether engine is running or paused.\r\n */\r\n public isRunning() {\r\n return this.clock.isRunning();\r\n }\r\n\r\n\r\n private _screenShotRequests: { preserveHiDPIResolution: boolean, resolve: (image: HTMLImageElement) => void }[] = [];\r\n /**\r\n * Takes a screen shot of the current viewport and returns it as an\r\n * HTML Image Element.\r\n * @param preserveHiDPIResolution in the case of HiDPI return the full scaled backing image, by default false\r\n */\r\n public screenshot(preserveHiDPIResolution = false): Promise {\r\n const screenShotPromise = new Promise((resolve) => {\r\n this._screenShotRequests.push({preserveHiDPIResolution, resolve});\r\n });\r\n return screenShotPromise;\r\n }\r\n\r\n private _checkForScreenShots() {\r\n // We must grab the draw buffer before we yield to the browser\r\n // the draw buffer is cleared after compositing\r\n // the reason for the asynchrony is setting `preserveDrawingBuffer: true`\r\n // forces the browser to copy buffers which can have a mass perf impact on mobile\r\n for (const request of this._screenShotRequests) {\r\n const finalWidth = request.preserveHiDPIResolution ? this.canvas.width : this.screen.resolution.width;\r\n const finalHeight = request.preserveHiDPIResolution ? this.canvas.height : this.screen.resolution.height;\r\n const screenshot = document.createElement('canvas');\r\n screenshot.width = finalWidth;\r\n screenshot.height = finalHeight;\r\n const ctx = screenshot.getContext('2d');\r\n ctx.imageSmoothingEnabled = this.screen.antialiasing;\r\n ctx.drawImage(this.canvas, 0, 0, finalWidth, finalHeight);\r\n\r\n const result = new Image();\r\n const raw = screenshot.toDataURL('image/png');\r\n result.src = raw;\r\n request.resolve(result);\r\n }\r\n // Reset state\r\n this._screenShotRequests.length = 0;\r\n }\r\n\r\n /**\r\n * Another option available to you to load resources into the game.\r\n * Immediately after calling this the game will pause and the loading screen\r\n * will appear.\r\n * @param loader Some [[Loadable]] such as a [[Loader]] collection, [[Sound]], or [[Texture]].\r\n */\r\n public async load(loader: Loadable): Promise {\r\n try {\r\n await loader.load();\r\n } catch (e) {\r\n this._logger.error('Error loading resources, things may not behave properly', e);\r\n await Promise.resolve();\r\n }\r\n }\r\n}","export * from './vector';\r\nexport * from './vector-view';\r\nexport * from './matrix';\r\nexport * from './affine-matrix';\r\nexport * from './transform';\r\nexport * from './coord-plane';\r\nexport * from './Random';\r\nexport * from './global-coordinates';\r\nexport * from './line-segment';\r\nexport * from './projection';\r\nexport * from './ray';\r\nexport * from './util';","export * from './Debug';\r\nexport * from './DebugFlags';\r\nexport * from './DebugSystem';\r\n","import { GameEvent } from './Events';\r\nimport { Eventable } from './Interfaces/Evented';\r\n\r\n/**\r\n * @deprecated Use [[EventEmitter]] will be removed in v0.29.0\r\n */\r\nexport class EventDispatcher implements Eventable {\r\n private _handlers: { [key: string]: { (event: GameEvent): void }[] } = {};\r\n private _wiredEventDispatchers: Eventable[] = [];\r\n\r\n /**\r\n * Clears any existing handlers or wired event dispatchers on this event dispatcher\r\n */\r\n public clear() {\r\n this._handlers = {};\r\n this._wiredEventDispatchers = [];\r\n }\r\n\r\n private _deferedHandlerRemovals: {name: string, handler?: (...args: any[]) => any }[] = [];\r\n private _processDeferredHandlerRemovals() {\r\n for (const eventHandler of this._deferedHandlerRemovals) {\r\n this._removeHandler(eventHandler.name, eventHandler.handler);\r\n }\r\n this._deferedHandlerRemovals.length = 0;\r\n }\r\n\r\n /**\r\n * Emits an event for target\r\n * @param eventName The name of the event to publish\r\n * @param event Optionally pass an event data object to the handler\r\n */\r\n public emit(eventName: string, event: GameEvent) {\r\n this._processDeferredHandlerRemovals();\r\n if (!eventName) {\r\n // key not mapped\r\n return;\r\n }\r\n eventName = eventName.toLowerCase();\r\n if (typeof event === 'undefined' || event === null) {\r\n event = new GameEvent();\r\n }\r\n let i: number, len: number;\r\n\r\n if (this._handlers[eventName]) {\r\n i = 0;\r\n len = this._handlers[eventName].length;\r\n for (i; i < len; i++) {\r\n this._handlers[eventName][i](event);\r\n }\r\n }\r\n\r\n i = 0;\r\n len = this._wiredEventDispatchers.length;\r\n\r\n for (i; i < len; i++) {\r\n this._wiredEventDispatchers[i].emit(eventName, event);\r\n }\r\n }\r\n\r\n /**\r\n * Subscribe an event handler to a particular event name, multiple handlers per event name are allowed.\r\n * @param eventName The name of the event to subscribe to\r\n * @param handler The handler callback to fire on this event\r\n */\r\n public on(eventName: string, handler: (event: GameEvent) => void) {\r\n this._processDeferredHandlerRemovals();\r\n eventName = eventName.toLowerCase();\r\n\r\n if (!this._handlers[eventName]) {\r\n this._handlers[eventName] = [];\r\n }\r\n this._handlers[eventName].push(handler);\r\n }\r\n\r\n /**\r\n * Unsubscribe an event handler(s) from an event. If a specific handler\r\n * is specified for an event, only that handler will be unsubscribed.\r\n * Otherwise all handlers will be unsubscribed for that event.\r\n *\r\n * @param eventName The name of the event to unsubscribe\r\n * @param handler Optionally the specific handler to unsubscribe\r\n */\r\n public off(eventName: string, handler?: (event: GameEvent) => void) {\r\n this._deferedHandlerRemovals.push({name: eventName, handler});\r\n }\r\n\r\n private _removeHandler(eventName: string, handler?: (event: GameEvent) => void) {\r\n eventName = eventName.toLowerCase();\r\n const eventHandlers = this._handlers[eventName];\r\n\r\n if (eventHandlers) {\r\n // if no explicit handler is give with the event name clear all handlers\r\n if (!handler) {\r\n this._handlers[eventName].length = 0;\r\n } else {\r\n const index = eventHandlers.indexOf(handler);\r\n if (index > -1) {\r\n this._handlers[eventName].splice(index, 1);\r\n }\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Once listens to an event one time, then unsubscribes from that event\r\n *\r\n * @param eventName The name of the event to subscribe to once\r\n * @param handler The handler of the event that will be auto unsubscribed\r\n */\r\n public once(eventName: string, handler: (event: GameEvent) => void) {\r\n this._processDeferredHandlerRemovals();\r\n const metaHandler = (event: GameEvent) => {\r\n const ev = event || new GameEvent();\r\n this.off(eventName, metaHandler);\r\n handler(ev);\r\n };\r\n\r\n this.on(eventName, metaHandler);\r\n }\r\n\r\n /**\r\n * Wires this event dispatcher to also receive events from another\r\n */\r\n public wire(eventDispatcher: EventDispatcher): void {\r\n eventDispatcher._wiredEventDispatchers.push(this);\r\n }\r\n\r\n /**\r\n * Unwires this event dispatcher from another\r\n */\r\n public unwire(eventDispatcher: EventDispatcher): void {\r\n const index = eventDispatcher._wiredEventDispatchers.indexOf(this);\r\n if (index > -1) {\r\n eventDispatcher._wiredEventDispatchers.splice(index, 1);\r\n }\r\n }\r\n}\r\n","import { Engine } from './Engine';\r\nimport { Color } from './Color';\r\nimport { vec, Vector } from './Math/vector';\r\nimport { Text } from './Graphics/Text';\r\nimport { GraphicsComponent, SpriteFont } from './Graphics';\r\nimport { Font } from './Graphics/Font';\r\nimport { Actor } from './Actor';\r\nimport { ActorArgs } from '.';\r\n\r\n/**\r\n * Option for creating a label\r\n */\r\nexport interface LabelOptions {\r\n /**\r\n * Specify the label text\r\n */\r\n text?: string;\r\n /**\r\n * Specify the color of the text (does not apply to SpriteFonts)\r\n */\r\n color?: Color;\r\n x?: number;\r\n y?: number;\r\n pos?: Vector;\r\n /**\r\n * Optionally specify a sprite font, will take precedence over any other [[Font]]\r\n */\r\n spriteFont?: SpriteFont;\r\n /**\r\n * Specify a custom font\r\n */\r\n font?: Font\r\n}\r\n\r\n/**\r\n * Labels are the way to draw small amounts of text to the screen. They are\r\n * actors and inherit all of the benefits and capabilities.\r\n */\r\nexport class Label extends Actor {\r\n private _font: Font = new Font();\r\n private _text: Text = new Text({ text: '', font: this._font });\r\n\r\n public get font(): Font {\r\n return this._font;\r\n }\r\n\r\n public set font(newFont: Font) {\r\n this._font = newFont;\r\n this._text.font = newFont;\r\n }\r\n\r\n /**\r\n * The text to draw.\r\n */\r\n public get text(): string {\r\n return this._text.text;\r\n }\r\n\r\n public set text(text: string) {\r\n this._text.text = text;\r\n }\r\n\r\n public override get color(): Color {\r\n return this._text.color;\r\n }\r\n\r\n public override set color(color: Color) {\r\n if (this._text) {\r\n this._text.color = color;\r\n }\r\n }\r\n\r\n public get opacity(): number {\r\n return this._text.opacity;\r\n }\r\n\r\n public set opacity(opacity: number) {\r\n this._text.opacity = opacity;\r\n }\r\n\r\n private _spriteFont: SpriteFont;\r\n /**\r\n * The [[SpriteFont]] to use, if any. Overrides [[Font|font]] if present.\r\n */\r\n public get spriteFont(): SpriteFont {\r\n return this._spriteFont;\r\n }\r\n\r\n public set spriteFont(sf: SpriteFont) {\r\n if (sf) {\r\n this._spriteFont = sf;\r\n this._text.font = this._spriteFont;\r\n }\r\n }\r\n\r\n /**\r\n * Build a new label\r\n * @param options\r\n */\r\n constructor(options?: LabelOptions & ActorArgs) {\r\n super(options);\r\n const {text, pos, x, y, spriteFont, font, color} = options;\r\n\r\n this.pos = pos ?? (x && y ? vec(x, y) : this.pos);\r\n this.text = text ?? this.text;\r\n this.font = font ?? this.font;\r\n this.spriteFont = spriteFont ?? this.spriteFont;\r\n this._text.color = color ?? this.color;\r\n const gfx = this.get(GraphicsComponent);\r\n gfx.anchor = Vector.Zero;\r\n gfx.use(this._text);\r\n }\r\n\r\n public _initialize(engine: Engine) {\r\n super._initialize(engine);\r\n }\r\n\r\n /**\r\n * Returns the width of the text in the label (in pixels);\r\n */\r\n public getTextWidth(): number {\r\n return this._text.width;\r\n }\r\n}\r\n","import { BodyComponent, BoundingBox, Collider, ColliderComponent, CollisionType, Color, CompositeCollider, vec, Vector } from '..';\r\nimport { TransformComponent } from '../EntityComponentSystem/Components/TransformComponent';\r\nimport { Entity } from '../EntityComponentSystem/Entity';\r\nimport { DebugGraphicsComponent, ExcaliburGraphicsContext, Graphic, GraphicsComponent } from '../Graphics';\r\nimport { IsometricEntityComponent } from './IsometricEntityComponent';\r\n\r\nexport class IsometricTile extends Entity {\r\n /**\r\n * Indicates whether this tile is solid\r\n */\r\n public solid: boolean = false;\r\n\r\n private _gfx: GraphicsComponent;\r\n private _tileBounds = new BoundingBox();\r\n private _graphics: Graphic[] = [];\r\n public getGraphics(): readonly Graphic[] {\r\n return this._graphics;\r\n }\r\n /**\r\n * Tile graphics\r\n */\r\n public addGraphic(graphic: Graphic) {\r\n this._graphics.push(graphic);\r\n this._gfx.visible = true;\r\n this._gfx.localBounds = this._recalculateBounds();\r\n }\r\n\r\n private _recalculateBounds(): BoundingBox {\r\n let bounds = this._tileBounds.clone();\r\n for (const graphic of this._graphics) {\r\n const offset = vec(\r\n this.map.graphicsOffset.x - this.map.tileWidth / 2,\r\n this.map.graphicsOffset.y - (this.map.renderFromTopOfGraphic ? 0 : (graphic.height - this.map.tileHeight)));\r\n bounds = bounds.combine(graphic.localBounds.translate(offset));\r\n }\r\n return bounds;\r\n }\r\n\r\n public removeGraphic(graphic: Graphic) {\r\n const index = this._graphics.indexOf(graphic);\r\n if (index > -1) {\r\n this._graphics.splice(index, 1);\r\n }\r\n this._gfx.localBounds = this._recalculateBounds();\r\n }\r\n\r\n public clearGraphics() {\r\n this._graphics.length = 0;\r\n this._gfx.visible = false;\r\n this._gfx.localBounds = this._recalculateBounds();\r\n }\r\n\r\n /**\r\n * Tile colliders\r\n */\r\n private _colliders: Collider[] = [];\r\n public getColliders(): readonly Collider[] {\r\n return this._colliders;\r\n }\r\n\r\n /**\r\n * Adds a collider to the IsometricTile\r\n *\r\n * **Note!** the [[Tile.solid]] must be set to true for it to act as a \"fixed\" collider\r\n * @param collider\r\n */\r\n public addCollider(collider: Collider) {\r\n this._colliders.push(collider);\r\n this.map.flagCollidersDirty();\r\n }\r\n\r\n /**\r\n * Removes a collider from the IsometricTile\r\n * @param collider\r\n */\r\n public removeCollider(collider: Collider) {\r\n const index = this._colliders.indexOf(collider);\r\n if (index > -1) {\r\n this._colliders.splice(index, 1);\r\n }\r\n this.map.flagCollidersDirty();\r\n }\r\n\r\n /**\r\n * Clears all colliders from the IsometricTile\r\n */\r\n public clearColliders(): void {\r\n this._colliders.length = 0;\r\n this.map.flagCollidersDirty();\r\n }\r\n\r\n /**\r\n * Integer tile x coordinate\r\n */\r\n public readonly x: number;\r\n /**\r\n * Integer tile y coordinate\r\n */\r\n public readonly y: number;\r\n /**\r\n * Reference to the [[IsometricMap]] this tile is part of\r\n */\r\n public readonly map: IsometricMap;\r\n\r\n private _transform: TransformComponent;\r\n private _isometricEntityComponent: IsometricEntityComponent;\r\n\r\n /**\r\n * Returns the top left corner of the [[IsometricTile]] in world space\r\n */\r\n public get pos(): Vector {\r\n return this.map.tileToWorld(vec(this.x, this.y));\r\n }\r\n\r\n /**\r\n * Returns the center of the [[IsometricTile]]\r\n */\r\n public get center(): Vector {\r\n return this.pos.add(vec(0, this.map.tileHeight / 2));\r\n }\r\n\r\n /**\r\n * Construct a new IsometricTile\r\n * @param x tile coordinate in x (not world position)\r\n * @param y tile coordinate in y (not world position)\r\n * @param graphicsOffset offset that tile should be shifted by (default (0, 0))\r\n * @param map reference to owning IsometricMap\r\n */\r\n constructor(x: number, y: number, graphicsOffset: Vector | null, map: IsometricMap) {\r\n super([\r\n new TransformComponent(),\r\n new GraphicsComponent({\r\n offset: graphicsOffset ?? Vector.Zero,\r\n onPostDraw: (gfx, elapsed) => this.draw(gfx, elapsed)\r\n }),\r\n new IsometricEntityComponent(map)\r\n ]);\r\n this.x = x;\r\n this.y = y;\r\n this.map = map;\r\n this._transform = this.get(TransformComponent);\r\n this._isometricEntityComponent = this.get(IsometricEntityComponent);\r\n\r\n const halfTileWidth = this.map.tileWidth / 2;\r\n const halfTileHeight = this.map.tileHeight / 2;\r\n // See https://clintbellanger.net/articles/isometric_math/ for formula\r\n // The x position shifts left with every y step\r\n const xPos = (this.x - this.y) * halfTileWidth;\r\n // The y position needs to go down with every x step\r\n const yPos = (this.x + this.y) * halfTileHeight;\r\n this._transform.pos = vec(xPos, yPos);\r\n this._isometricEntityComponent.elevation = 0;\r\n\r\n this._gfx = this.get(GraphicsComponent);\r\n this._gfx.visible = false; // start not visible\r\n const totalWidth = this.map.tileWidth;\r\n const totalHeight = this.map.tileHeight;\r\n\r\n // initial guess at gfx bounds based on the tile\r\n const offset = vec(0, (this.map.renderFromTopOfGraphic ? totalHeight : 0));\r\n this._gfx.localBounds = this._tileBounds = new BoundingBox({\r\n left: -totalWidth / 2,\r\n top: -totalHeight,\r\n right: totalWidth / 2,\r\n bottom: totalHeight\r\n }).translate(offset);\r\n }\r\n\r\n draw(gfx: ExcaliburGraphicsContext, _elapsed: number) {\r\n const halfTileWidth = this.map.tileWidth / 2;\r\n gfx.save();\r\n // shift left origin to corner of map, not the left corner of the first sprite\r\n gfx.translate(-halfTileWidth, 0);\r\n for (const graphic of this._graphics) {\r\n graphic.draw(\r\n gfx,\r\n this.map.graphicsOffset.x,\r\n this.map.graphicsOffset.y - (this.map.renderFromTopOfGraphic ? 0 : (graphic.height - this.map.tileHeight)));\r\n }\r\n gfx.restore();\r\n }\r\n}\r\n\r\nexport interface IsometricMapOptions {\r\n /**\r\n * Optionally name the isometric tile map\r\n */\r\n name?: string;\r\n /**\r\n * Optionally specify the position of the isometric tile map\r\n */\r\n pos?: Vector;\r\n /**\r\n * Optionally render from the top of the graphic, by default tiles are rendered from the bottom\r\n */\r\n renderFromTopOfGraphic?: boolean;\r\n /**\r\n * Optionally present a graphics offset, this can be useful depending on your tile graphics\r\n */\r\n graphicsOffset?: Vector;\r\n /**\r\n * Width of an individual tile in pixels, this should be the width of the parallelogram of the base of the tile art asset.\r\n */\r\n tileWidth: number;\r\n /**\r\n * Height of an individual tile in pixels, this should be the height of the parallelogram of the base of the tile art asset.\r\n */\r\n tileHeight: number;\r\n /**\r\n * The number of tile columns, or the number of tiles wide\r\n */\r\n columns: number;\r\n /**\r\n * The number of tile rows, or the number of tiles high\r\n */\r\n rows: number;\r\n}\r\n\r\n/**\r\n * The IsometricMap is a special tile map that provides isometric rendering support to Excalibur\r\n *\r\n * The tileWidth and tileHeight should be the height and width in pixels of the parallelogram of the base of the tile art asset.\r\n * The tileWidth and tileHeight is not necessarily the same as your graphic pixel width and height.\r\n *\r\n * Please refer to the docs https://excaliburjs.com for more details calculating what your tile width and height should be given\r\n * your art assets.\r\n */\r\nexport class IsometricMap extends Entity {\r\n /**\r\n * Width of individual tile in pixels\r\n */\r\n public readonly tileWidth: number;\r\n /**\r\n * Height of individual tile in pixels\r\n */\r\n public readonly tileHeight: number;\r\n /**\r\n * Number of tiles wide\r\n */\r\n public readonly columns: number;\r\n /**\r\n * Number of tiles high\r\n */\r\n public readonly rows: number;\r\n /**\r\n * List containing all of the tiles in IsometricMap\r\n */\r\n public readonly tiles: IsometricTile[];\r\n\r\n /**\r\n * Render the tile graphic from the top instead of the bottom\r\n *\r\n * default is `false` meaning rendering from the bottom\r\n */\r\n public renderFromTopOfGraphic: boolean = false;\r\n public graphicsOffset: Vector = vec(0, 0);\r\n\r\n /**\r\n * Isometric map [[TransformComponent]]\r\n */\r\n public transform: TransformComponent;\r\n\r\n /**\r\n * Isometric map [[ColliderComponent]]\r\n */\r\n public collider: ColliderComponent;\r\n\r\n private _composite: CompositeCollider;\r\n\r\n constructor(options: IsometricMapOptions) {\r\n super([\r\n new TransformComponent(),\r\n new BodyComponent({\r\n type: CollisionType.Fixed\r\n }),\r\n new ColliderComponent(),\r\n new DebugGraphicsComponent((ctx) => this.debug(ctx), false)\r\n ], options.name);\r\n const { pos, tileWidth, tileHeight, columns: width, rows: height, renderFromTopOfGraphic, graphicsOffset } = options;\r\n\r\n this.transform = this.get(TransformComponent);\r\n if (pos) {\r\n this.transform.pos = pos;\r\n }\r\n\r\n this.collider = this.get(ColliderComponent);\r\n if (this.collider) {\r\n this.collider.set(this._composite = new CompositeCollider([]));\r\n }\r\n\r\n\r\n this.renderFromTopOfGraphic = renderFromTopOfGraphic ?? this.renderFromTopOfGraphic;\r\n this.graphicsOffset = graphicsOffset ?? this.graphicsOffset;\r\n\r\n this.tileWidth = tileWidth;\r\n this.tileHeight = tileHeight;\r\n this.columns = width;\r\n this.rows = height;\r\n\r\n this.tiles = new Array(width * height);\r\n\r\n // build up tile representation\r\n for (let y = 0; y < height; y++) {\r\n for (let x = 0; x < width; x++) {\r\n const tile = new IsometricTile(x, y, this.graphicsOffset, this);\r\n this.tiles[x + y * width] = tile;\r\n this.addChild(tile);\r\n // TODO row/columns helpers\r\n }\r\n }\r\n }\r\n\r\n public update(): void {\r\n if (this._collidersDirty) {\r\n this.updateColliders();\r\n this._collidersDirty = false;\r\n }\r\n }\r\n\r\n private _collidersDirty = false;\r\n public flagCollidersDirty() {\r\n this._collidersDirty = true;\r\n }\r\n\r\n private _originalOffsets = new WeakMap();\r\n private _getOrSetColliderOriginalOffset(collider: Collider): Vector {\r\n if (!this._originalOffsets.has(collider)) {\r\n const originalOffset = collider.offset;\r\n this._originalOffsets.set(collider, originalOffset);\r\n return originalOffset;\r\n } else {\r\n return this._originalOffsets.get(collider);\r\n }\r\n }\r\n public updateColliders() {\r\n this._composite.clearColliders();\r\n const pos = this.get(TransformComponent).pos;\r\n for (const tile of this.tiles) {\r\n if (tile.solid) {\r\n for (const collider of tile.getColliders()) {\r\n const originalOffset = this._getOrSetColliderOriginalOffset(collider);\r\n collider.offset = this.tileToWorld(vec(tile.x, tile.y))\r\n .sub(pos)\r\n .add(originalOffset)\r\n .sub(vec(this.tileWidth / 2, this.tileHeight)); // We need to unshift height based on drawing\r\n collider.owner = this;\r\n this._composite.addCollider(collider);\r\n }\r\n }\r\n }\r\n this.collider.update();\r\n }\r\n\r\n /**\r\n * Convert world space coordinates to the tile x, y coordinate\r\n * @param worldCoordinate\r\n */\r\n public worldToTile(worldCoordinate: Vector): Vector {\r\n worldCoordinate = worldCoordinate.sub(this.transform.globalPos);\r\n\r\n const halfTileWidth = this.tileWidth / 2;\r\n const halfTileHeight = this.tileHeight / 2;\r\n // See https://clintbellanger.net/articles/isometric_math/ for formula\r\n return vec(\r\n ~~((worldCoordinate.x / halfTileWidth + (worldCoordinate.y / halfTileHeight)) / 2),\r\n ~~((worldCoordinate.y / halfTileHeight - (worldCoordinate.x / halfTileWidth)) / 2));\r\n }\r\n\r\n /**\r\n * Given a tile coordinate, return the top left corner in world space\r\n * @param tileCoordinate\r\n */\r\n public tileToWorld(tileCoordinate: Vector): Vector {\r\n const halfTileWidth = this.tileWidth / 2;\r\n const halfTileHeight = this.tileHeight / 2;\r\n // The x position shifts left with every y step\r\n const xPos = (tileCoordinate.x - tileCoordinate.y) * halfTileWidth;\r\n // The y position needs to go down with every x step\r\n const yPos = (tileCoordinate.x + tileCoordinate.y) * halfTileHeight;\r\n return vec(xPos, yPos).add(this.transform.pos);\r\n }\r\n\r\n /**\r\n * Returns the [[IsometricTile]] by its x and y coordinates\r\n */\r\n public getTile(x: number, y: number): IsometricTile | null {\r\n if (x < 0 || y < 0 || x >= this.columns || y >= this.rows) {\r\n return null;\r\n }\r\n return this.tiles[x + y * this.columns];\r\n }\r\n\r\n /**\r\n * Returns the [[IsometricTile]] by testing a point in world coordinates,\r\n * returns `null` if no Tile was found.\r\n */\r\n public getTileByPoint(point: Vector): IsometricTile | null {\r\n const tileCoord = this.worldToTile(point);\r\n const tile = this.getTile(tileCoord.x, tileCoord.y);\r\n return tile;\r\n }\r\n\r\n private _getMaxZIndex(): number {\r\n let maxZ = Number.NEGATIVE_INFINITY;\r\n for (const tile of this.tiles) {\r\n const currentZ = tile.get(TransformComponent).z;\r\n if (currentZ > maxZ) {\r\n maxZ = currentZ;\r\n }\r\n }\r\n return maxZ;\r\n }\r\n\r\n /**\r\n * Debug draw for IsometricMap, called internally by excalibur when debug mode is toggled on\r\n * @param gfx\r\n */\r\n public debug(gfx: ExcaliburGraphicsContext) {\r\n gfx.save();\r\n gfx.z = this._getMaxZIndex() + 0.5;\r\n for (let y = 0; y < this.rows + 1; y++) {\r\n const left = this.tileToWorld(vec(0, y));\r\n const right = this.tileToWorld(vec(this.columns, y));\r\n gfx.drawLine(left, right, Color.Red, 2);\r\n }\r\n\r\n for (let x = 0; x < this.columns + 1; x++) {\r\n const top = this.tileToWorld(vec(x, 0));\r\n const bottom = this.tileToWorld(vec(x, this.rows));\r\n gfx.drawLine(top, bottom, Color.Red, 2);\r\n }\r\n\r\n for (const tile of this.tiles) {\r\n gfx.drawCircle(this.tileToWorld(vec(tile.x, tile.y)), 3, Color.Yellow);\r\n }\r\n gfx.restore();\r\n }\r\n}","export * from './TileMap';\r\nexport * from './IsometricMap';\r\nexport * from './IsometricEntityComponent';\r\nexport * from './IsometricEntitySystem';","import { Entity } from '../../EntityComponentSystem';\r\nimport { Action } from '../Action';\r\nimport { ActionContext } from '../ActionContext';\r\nimport { ActionQueue } from '../ActionQueue';\r\n\r\n/**\r\n * Action that can represent a sequence of actions, this can be useful in conjunction with\r\n * [[ParallelActions]] to run multiple sequences in parallel.\r\n */\r\nexport class ActionSequence implements Action {\r\n private _actionQueue: ActionQueue;\r\n private _stopped: boolean = false;\r\n private _sequenceContext: ActionContext;\r\n private _sequenceBuilder: (actionContext: ActionContext) => any;\r\n constructor(entity: Entity, actionBuilder: (actionContext: ActionContext) => any) {\r\n this._sequenceBuilder = actionBuilder;\r\n this._sequenceContext = new ActionContext(entity);\r\n this._actionQueue = this._sequenceContext.getQueue();\r\n this._sequenceBuilder(this._sequenceContext);\r\n }\r\n\r\n public update(delta: number): void {\r\n this._actionQueue.update(delta);\r\n }\r\n\r\n public isComplete(): boolean {\r\n return this._stopped || this._actionQueue.isComplete();\r\n }\r\n\r\n public stop(): void {\r\n this._stopped = true;\r\n }\r\n\r\n public reset(): void {\r\n this._stopped = false;\r\n this._actionQueue.reset();\r\n }\r\n\r\n public clone(entity: Entity) {\r\n return new ActionSequence(entity, this._sequenceBuilder);\r\n }\r\n}","import { Entity } from '../../EntityComponentSystem';\r\nimport { Action } from '../Action';\r\n\r\n\r\n/**\r\n * Action that can run multiple [[Action]]s or [[ActionSequence]]s at the same time\r\n */\r\nexport class ParallelActions implements Action {\r\n private _actions: Action[];\r\n\r\n constructor(parallelActions: Action[]) {\r\n this._actions = parallelActions;\r\n }\r\n\r\n update(delta: number): void {\r\n for (let i = 0; i < this._actions.length; i++) {\r\n this._actions[i].update(delta);\r\n }\r\n }\r\n isComplete(entity: Entity): boolean {\r\n return this._actions.every(a => a.isComplete(entity));\r\n }\r\n reset(): void {\r\n this._actions.forEach(a => a.reset());\r\n }\r\n stop(): void {\r\n this._actions.forEach(a => a.stop());\r\n }\r\n}","export * from './ActionContext';\r\nexport * from './ActionQueue';\r\nexport * from './Actionable';\r\nexport * from './RotationType';\r\n\r\nexport * from './Action';\r\nexport * from './Action/ActionSequence';\r\nexport * from './Action/ParallelActions';\r\nexport * from './Action/Repeat';\r\nexport * from './Action/RepeatForever';\r\nexport * from './Action/Blink';\r\nexport * from './Action/Die';\r\nexport * from './Action/EaseTo';\r\nexport * from './Action/EaseBy';\r\nexport * from './Action/Fade';\r\nexport * from './Action/Follow';\r\nexport * from './Action/Meet';\r\nexport * from './Action/MoveBy';\r\nexport * from './Action/MoveTo';\r\nexport * from './Action/RotateBy';\r\nexport * from './Action/RotateTo';\r\nexport * from './Action/ScaleBy';\r\nexport * from './Action/ScaleTo';\r\nexport * from './Action/Delay';\r\n\r\nexport * from './ActionsComponent';\r\nexport * from './ActionsSystem';","import { CollisionGroup } from './CollisionGroup';\r\n\r\n/**\r\n * Static class for managing collision groups in excalibur, there is a maximum of 32 collision groups possible in excalibur\r\n */\r\nexport class CollisionGroupManager {\r\n // using bitmasking the maximum number of groups is 32, because that is the highest 32bit integer that JS can present.\r\n private static _STARTING_BIT = 0b1 | 0;\r\n private static _MAX_GROUPS = 32;\r\n private static _CURRENT_GROUP = 1;\r\n private static _CURRENT_BIT = CollisionGroupManager._STARTING_BIT;\r\n private static _GROUPS: Map = new Map();\r\n\r\n /**\r\n * Create a new named collision group up to a max of 32.\r\n * @param name Name for the collision group\r\n * @param mask Optionally provide your own 32-bit mask, if none is provide the manager will generate one\r\n */\r\n public static create(name: string, mask?: number) {\r\n if (this._CURRENT_GROUP > this._MAX_GROUPS) {\r\n throw new Error(`Cannot have more than ${this._MAX_GROUPS} collision groups`);\r\n }\r\n if (this._GROUPS.get(name)) {\r\n throw new Error(`Collision group ${name} already exists`);\r\n }\r\n const group = new CollisionGroup(name, this._CURRENT_BIT, mask !== undefined ? mask : ~this._CURRENT_BIT);\r\n this._CURRENT_BIT = (this._CURRENT_BIT << 1) | 0;\r\n this._CURRENT_GROUP++;\r\n this._GROUPS.set(name, group);\r\n return group;\r\n }\r\n\r\n /**\r\n * Get all collision groups currently tracked by excalibur\r\n */\r\n public static get groups(): CollisionGroup[] {\r\n return Array.from(this._GROUPS.values());\r\n }\r\n\r\n /**\r\n * Get a collision group by it's name\r\n * @param name\r\n */\r\n public static groupByName(name: string) {\r\n return this._GROUPS.get(name);\r\n }\r\n\r\n /**\r\n * Resets the managers internal group management state\r\n */\r\n public static reset() {\r\n this._GROUPS = new Map();\r\n this._CURRENT_BIT = this._STARTING_BIT;\r\n this._CURRENT_GROUP = 1;\r\n }\r\n}\r\n","export * from './BodyComponent';\r\nexport * from './ColliderComponent';\r\nexport * from './CollisionType';\r\n\r\nexport * from './Colliders/Collider';\r\nexport * from './BoundingBox';\r\n\r\nexport * from './Colliders/Shape';\r\nexport * from './Colliders/Collider';\r\nexport * from './Colliders/CompositeCollider';\r\nexport * from './Colliders/CircleCollider';\r\nexport * from './Colliders/EdgeCollider';\r\nexport * from './Colliders/PolygonCollider';\r\nexport * from './Colliders/CollisionJumpTable';\r\nexport * from './Colliders/ClosestLineJumpTable';\r\n\r\nexport * from './Group/CollisionGroup';\r\nexport * from './Group/CollisionGroupManager';\r\n\r\nexport * from './Detection/Pair';\r\nexport * from './Detection/CollisionContact';\r\nexport * from './Detection/CollisionProcessor';\r\nexport * from './Detection/DynamicTree';\r\nexport * from './Detection/DynamicTreeCollisionProcessor';\r\n\r\nexport * from './Solver/ArcadeSolver';\r\nexport * from './Solver/ContactConstraintPoint';\r\nexport * from './Solver/RealisticSolver';\r\nexport * from './Solver/Solver';\r\n\r\nexport * from './CollisionSystem';\r\nexport * from './MotionSystem';\r\n\r\nexport * from './PhysicsWorld';\r\nexport * from './Physics';\r\nexport * from './Side';\r\n","import { Engine } from './../Engine';\r\nimport * as Events from './../Events';\r\nimport { Scene } from '../Scene';\r\nimport { ExcaliburGraphicsContext } from '../Graphics';\r\n\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport interface _initialize {\r\n _initialize(engine: Engine): void;\r\n}\r\n\r\n/**\r\n * Type guard checking for internal initialize method\r\n * @internal\r\n * @param a\r\n */\r\nexport function has_initialize(a: any): a is _initialize {\r\n return !!a._initialize;\r\n}\r\n\r\nexport interface OnInitialize {\r\n onInitialize(engine: Engine): void;\r\n}\r\n\r\n/**\r\n *\r\n */\r\nexport function hasOnInitialize(a: any): a is OnInitialize {\r\n return !!a.onInitialize;\r\n}\r\n\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport interface _preupdate {\r\n _preupdate(engine: Engine, delta: number): void;\r\n}\r\n\r\n/**\r\n *\r\n */\r\nexport function has_preupdate(a: any): a is _preupdate {\r\n return !!a._preupdate;\r\n}\r\n\r\nexport interface OnPreUpdate {\r\n onPreUpdate(engine: Engine, delta: number): void;\r\n}\r\n\r\n/**\r\n *\r\n */\r\nexport function hasOnPreUpdate(a: any): a is OnPreUpdate {\r\n return !!a.onPreUpdate;\r\n}\r\n\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport interface _postupdate {\r\n _postupdate(engine: Engine, delta: number): void;\r\n}\r\n\r\n/**\r\n *\r\n */\r\nexport function has_postupdate(a: any): a is _postupdate {\r\n return !!a.onPostUpdate;\r\n}\r\n\r\nexport interface OnPostUpdate {\r\n onPostUpdate(engine: Engine, delta: number): void;\r\n}\r\n\r\n/**\r\n *\r\n */\r\nexport function hasOnPostUpdate(a: any): a is OnPostUpdate {\r\n return !!a.onPostUpdate;\r\n}\r\n\r\nexport interface CanInitialize {\r\n /**\r\n * Overridable implementation\r\n */\r\n onInitialize(_engine: Engine): void;\r\n\r\n /**\r\n * Event signatures\r\n */\r\n on(eventName: Events.initialize, handler: (event: Events.InitializeEvent) => void): void;\r\n once(eventName: Events.initialize, handler: (event: Events.InitializeEvent) => void): void;\r\n off(eventName: Events.initialize, handler?: (event: Events.InitializeEvent) => void): void;\r\n}\r\n\r\nexport interface SceneActivationContext {\r\n data?: TData;\r\n previousScene: Scene;\r\n nextScene: Scene;\r\n engine: Engine;\r\n}\r\n\r\nexport interface CanActivate {\r\n /**\r\n * Overridable implementation\r\n */\r\n onActivate(context: SceneActivationContext): void;\r\n\r\n /**\r\n * Event signatures\r\n */\r\n on(eventName: Events.activate, handler: (event: Events.ActivateEvent) => void): void;\r\n once(eventName: Events.activate, handler: (event: Events.ActivateEvent) => void): void;\r\n off(eventName: Events.activate, handler?: (event: Events.ActivateEvent) => void): void;\r\n}\r\n\r\nexport interface CanDeactivate {\r\n /**\r\n * Overridable implementation\r\n */\r\n onDeactivate(context: SceneActivationContext): void;\r\n\r\n /**\r\n * Event signature\r\n */\r\n on(eventName: Events.deactivate, handler: (event: Events.DeactivateEvent) => void): void;\r\n once(eventName: Events.deactivate, handler: (event: Events.DeactivateEvent) => void): void;\r\n off(eventName: Events.deactivate, handler?: (event: Events.DeactivateEvent) => void): void;\r\n}\r\n\r\nexport interface CanUpdate {\r\n /**\r\n * Overridable implementation\r\n */\r\n onPreUpdate(_engine: Engine, _delta: number): void;\r\n\r\n /**\r\n * Event signature\r\n */\r\n on(eventName: Events.preupdate, handler: (event: Events.PreUpdateEvent) => void): void;\r\n once(eventName: Events.preupdate, handler: (event: Events.PreUpdateEvent) => void): void;\r\n off(eventName: Events.preupdate, handler?: (event: Events.PreUpdateEvent) => void): void;\r\n\r\n /**\r\n * Overridable implementation\r\n */\r\n onPostUpdate(_engine: Engine, _delta: number): void;\r\n\r\n /**\r\n * Event signatures\r\n */\r\n on(eventName: Events.postupdate, handler: (event: Events.PostUpdateEvent) => void): void;\r\n once(eventName: Events.postupdate, handler: (event: Events.PostUpdateEvent) => void): void;\r\n off(eventName: Events.postupdate, handler?: (event: Events.PostUpdateEvent) => void): void;\r\n}\r\n\r\nexport interface OnPreDraw {\r\n /**\r\n * Overridable implementation\r\n */\r\n onPreDraw(_ctx: ExcaliburGraphicsContext, _delta: number): void;\r\n\r\n /**\r\n * Event signatures\r\n */\r\n on(eventName: Events.predraw, handler: (event: Events.PreDrawEvent) => void): void;\r\n once(eventName: Events.predraw, handler: (event: Events.PreDrawEvent) => void): void;\r\n off(eventName: Events.predraw, handler?: (event: Events.PreDrawEvent) => void): void;\r\n}\r\n\r\nexport interface OnPostDraw {\r\n /**\r\n * Overridable implementation\r\n */\r\n onPostDraw(_ctx: ExcaliburGraphicsContext, _delta: number): void;\r\n\r\n /**\r\n * Event signatures\r\n */\r\n on(eventName: Events.postdraw, handler: (event: Events.PostDrawEvent) => void): void;\r\n once(eventName: Events.postdraw, handler: (event: Events.PostDrawEvent) => void): void;\r\n off(eventName: Events.postdraw, handler?: (event: Events.PostDrawEvent) => void): void;\r\n}\r\n\r\nexport interface CanDraw extends OnPreDraw, OnPostDraw {\r\n on(eventName: Events.predraw, handler: (event: Events.PreDrawEvent) => void): void;\r\n on(eventName: Events.postdraw, handler: (event: Events.PostDrawEvent) => void): void;\r\n\r\n once(eventName: Events.predraw, handler: (event: Events.PreDrawEvent) => void): void;\r\n once(eventName: Events.postdraw, handler: (event: Events.PostDrawEvent) => void): void;\r\n\r\n off(eventName: Events.predraw, handler?: (event: Events.PreDrawEvent) => void): void;\r\n off(eventName: Events.postdraw, handler?: (event: Events.PostDrawEvent) => void): void;\r\n}\r\n\r\n/**\r\n *\r\n */\r\nexport function hasPreDraw(a: any): a is OnPreDraw {\r\n return !!a.onPreDraw;\r\n}\r\n\r\n/**\r\n *\r\n */\r\nexport function hasPostDraw(a: any): a is OnPostDraw {\r\n return !!a.onPostDraw;\r\n}\r\n\r\nexport interface CanBeKilled {\r\n /**\r\n * Overridable implementation\r\n */\r\n onPreKill(_scene: Scene): void;\r\n\r\n /**\r\n * Event signatures\r\n */\r\n on(eventName: Events.prekill, handler: (event: Events.PreKillEvent) => void): void;\r\n once(eventName: Events.prekill, handler: (event: Events.PreKillEvent) => void): void;\r\n off(eventName: Events.prekill, handler: (event: Events.PreKillEvent) => void): void;\r\n\r\n /**\r\n * Overridable implementation\r\n */\r\n onPostKill(_scene: Scene): void;\r\n\r\n /**\r\n * Event signatures\r\n */\r\n on(eventName: Events.postkill, handler: (event: Events.PostKillEvent) => void): void;\r\n once(eventName: Events.postkill, handler: (event: Events.PostKillEvent) => void): void;\r\n off(eventName: Events.postkill, handler: (event: Events.PostKillEvent) => void): void;\r\n}\r\n","export * from './Clonable';\r\nexport * from './Audio';\r\nexport * from './AudioImplementation';\r\nexport * from './Evented';\r\nexport * from './Loadable';\r\nexport * from './LifecycleEvents';\r\nexport * from './PointerEventHandlers';\r\n","export * from './Sound';\r\nexport * from './AudioContext';\r\nexport * from './WebAudioInstance';\r\n","import { Resource } from './Resource';\r\nimport { Sprite } from '../Graphics/Sprite';\r\nimport { Color } from '../Color';\r\nimport { SpriteSheet } from '../Graphics/SpriteSheet';\r\nimport { Animation } from '../Graphics/Animation';\r\nimport { Loadable } from '../Interfaces/Index';\r\nimport { ImageSource } from '../Graphics/ImageSource';\r\nimport { range } from '../Math/util';\r\n/**\r\n * The [[Texture]] object allows games built in Excalibur to load image resources.\r\n * [[Texture]] is an [[Loadable]] which means it can be passed to a [[Loader]]\r\n * to pre-load before starting a level or game.\r\n */\r\nexport class Gif implements Loadable {\r\n private _resource: Resource;\r\n\r\n /**\r\n * The width of the texture in pixels\r\n */\r\n public width: number;\r\n\r\n /**\r\n * The height of the texture in pixels\r\n */\r\n public height: number;\r\n\r\n\r\n private _stream: Stream = null;\r\n private _gif: ParseGif = null;\r\n private _textures: ImageSource[] = [];\r\n private _animation: Animation = null;\r\n private _transparentColor: Color = null;\r\n\r\n public data: ImageSource[];\r\n\r\n /**\r\n * @param path Path to the image resource\r\n * @param color Optionally set the color to treat as transparent the gif, by default [[Color.Magenta]]\r\n * @param bustCache Optionally load texture with cache busting\r\n */\r\n constructor(public path: string, public color: Color = Color.Magenta, bustCache = false) {\r\n this._resource = new Resource(path, 'arraybuffer', bustCache);\r\n this._transparentColor = color;\r\n }\r\n\r\n /**\r\n * Should excalibur add a cache busting querystring? By default false.\r\n * Must be set before loading\r\n */\r\n public get bustCache() {\r\n return this._resource.bustCache;\r\n }\r\n\r\n public set bustCache(val: boolean) {\r\n this._resource.bustCache = val;\r\n }\r\n\r\n /**\r\n * Begins loading the texture and returns a promise to be resolved on completion\r\n */\r\n public async load(): Promise {\r\n const arraybuffer = await this._resource.load();\r\n this._stream = new Stream(arraybuffer);\r\n this._gif = new ParseGif(this._stream, this._transparentColor);\r\n const images = this._gif.images.map(i => new ImageSource(i.src, false));\r\n\r\n // Load all textures\r\n await Promise.all(images.map(t => t.load()));\r\n return this.data = this._textures = images;\r\n }\r\n\r\n public isLoaded() {\r\n return !!this.data;\r\n }\r\n\r\n /**\r\n * Return a frame of the gif as a sprite by id\r\n * @param id\r\n */\r\n public toSprite(id: number = 0): Sprite {\r\n const sprite = this._textures[id].toSprite();\r\n return sprite;\r\n }\r\n\r\n /**\r\n * Return the gif as a spritesheet\r\n */\r\n public toSpriteSheet(): SpriteSheet {\r\n const sprites: Sprite[] = this._textures.map((image) => {\r\n return image.toSprite();\r\n });\r\n return new SpriteSheet({ sprites });\r\n }\r\n\r\n /**\r\n * Transform the GIF into an animation with duration per frame\r\n */\r\n public toAnimation(durationPerFrameMs: number): Animation {\r\n const spriteSheet: SpriteSheet = this.toSpriteSheet();\r\n const length = spriteSheet.sprites.length;\r\n this._animation = Animation.fromSpriteSheet(spriteSheet, range(0, length), durationPerFrameMs);\r\n return this._animation;\r\n }\r\n\r\n public get readCheckBytes(): number[] {\r\n return this._gif.checkBytes;\r\n }\r\n}\r\n\r\nexport interface GifFrame {\r\n sentinel: number;\r\n type: string;\r\n leftPos: number;\r\n topPos: number;\r\n width: number;\r\n height: number;\r\n lctFlag: boolean;\r\n interlaced: boolean;\r\n sorted: boolean;\r\n reserved: boolean[];\r\n lctSize: number;\r\n lzwMinCodeSize: number;\r\n pixels: number[];\r\n}\r\n\r\nconst bitsToNum = (ba: any) => {\r\n return ba.reduce(function (s: number, n: number) {\r\n return s * 2 + n;\r\n }, 0);\r\n};\r\n\r\nconst byteToBitArr = (bite: any) => {\r\n const a = [];\r\n for (let i = 7; i >= 0; i--) {\r\n a.push(!!(bite & (1 << i)));\r\n }\r\n return a;\r\n};\r\n\r\nexport class Stream {\r\n data: any = null;\r\n len: number = 0;\r\n position: number = 0;\r\n\r\n constructor(dataArray: ArrayBuffer) {\r\n this.data = new Uint8Array(dataArray);\r\n this.len = this.data.byteLength;\r\n if (this.len === 0) {\r\n throw new Error('No data loaded from file');\r\n }\r\n }\r\n\r\n public readByte = () => {\r\n if (this.position >= this.data.byteLength) {\r\n throw new Error('Attempted to read past end of stream.');\r\n }\r\n return this.data[this.position++];\r\n };\r\n\r\n public readBytes = (n: number) => {\r\n const bytes = [];\r\n for (let i = 0; i < n; i++) {\r\n bytes.push(this.readByte());\r\n }\r\n return bytes;\r\n };\r\n\r\n public read = (n: number) => {\r\n let s = '';\r\n for (let i = 0; i < n; i++) {\r\n s += String.fromCharCode(this.readByte());\r\n }\r\n return s;\r\n };\r\n\r\n public readUnsigned = () => {\r\n // Little-endian.\r\n const a = this.readBytes(2);\r\n return (a[1] << 8) + a[0];\r\n };\r\n}\r\n\r\nconst lzwDecode = function (minCodeSize: number, data: any) {\r\n // TODO: Now that the GIF parser is a bit different, maybe this should get an array of bytes instead of a String?\r\n let pos = 0; // Maybe this streaming thing should be merged with the Stream?\r\n\r\n const readCode = function (size: number) {\r\n let code = 0;\r\n for (let i = 0; i < size; i++) {\r\n if (data.charCodeAt(pos >> 3) & (1 << (pos & 7))) {\r\n code |= 1 << i;\r\n }\r\n pos++;\r\n }\r\n return code;\r\n };\r\n\r\n const output: any[] = [];\r\n\r\n const clearCode = 1 << minCodeSize;\r\n const eoiCode = clearCode + 1;\r\n\r\n let codeSize = minCodeSize + 1;\r\n\r\n let dict: any[] = [];\r\n\r\n const clear = function () {\r\n dict = [];\r\n codeSize = minCodeSize + 1;\r\n for (let i = 0; i < clearCode; i++) {\r\n dict[i] = [i];\r\n }\r\n dict[clearCode] = [];\r\n dict[eoiCode] = null;\r\n };\r\n\r\n let code;\r\n let last;\r\n\r\n while (true) {\r\n last = code;\r\n code = readCode(codeSize);\r\n if (code === clearCode) {\r\n clear();\r\n continue;\r\n }\r\n if (code === eoiCode) {\r\n break;\r\n }\r\n\r\n if (code < dict.length) {\r\n if (last !== clearCode) {\r\n dict.push(dict[last].concat(dict[code][0]));\r\n }\r\n } else {\r\n if (code !== dict.length) {\r\n throw new Error('Invalid LZW code.');\r\n }\r\n dict.push(dict[last].concat(dict[last][0]));\r\n }\r\n output.push.apply(output, dict[code]);\r\n\r\n if (dict.length === 1 << codeSize && codeSize < 12) {\r\n // If we're at the last code and codeSize is 12, the next code will be a clearCode, and it'll be 12 bits long.\r\n codeSize++;\r\n }\r\n }\r\n\r\n // I don't know if this is technically an error, but some GIFs do it.\r\n //if (Math.ceil(pos / 8) !== data.length) throw new Error('Extraneous LZW bytes.');\r\n return output;\r\n};\r\n\r\n// The actual parsing; returns an object with properties.\r\nexport class ParseGif {\r\n private _st: Stream = null;\r\n private _handler: any = {};\r\n private _transparentColor: Color = null;\r\n public frames: GifFrame[] = [];\r\n public images: HTMLImageElement[] = [];\r\n public globalColorTable: any[] = [];\r\n public checkBytes: number[] = [];\r\n\r\n constructor(stream: Stream, color: Color = Color.Magenta) {\r\n this._st = stream;\r\n this._handler = {};\r\n this._transparentColor = color;\r\n this.parseHeader();\r\n this.parseBlock();\r\n }\r\n\r\n // LZW (GIF-specific)\r\n parseColorTable = (entries: any) => {\r\n // Each entry is 3 bytes, for RGB.\r\n const ct = [];\r\n for (let i = 0; i < entries; i++) {\r\n const rgb: number[] = this._st.readBytes(3);\r\n const rgba =\r\n '#' +\r\n rgb\r\n .map((x: any) => {\r\n const hex = x.toString(16);\r\n return hex.length === 1 ? '0' + hex : hex;\r\n })\r\n .join('');\r\n ct.push(rgba);\r\n }\r\n return ct;\r\n };\r\n\r\n readSubBlocks = () => {\r\n let size, data;\r\n data = '';\r\n do {\r\n size = this._st.readByte();\r\n data += this._st.read(size);\r\n } while (size !== 0);\r\n return data;\r\n };\r\n\r\n parseHeader = () => {\r\n const hdr: any = {\r\n sig: null,\r\n ver: null,\r\n width: null,\r\n height: null,\r\n colorRes: null,\r\n globalColorTableSize: null,\r\n gctFlag: null,\r\n sorted: null,\r\n globalColorTable: [],\r\n bgColor: null,\r\n pixelAspectRatio: null // if not 0, aspectRatio = (pixelAspectRatio + 15) / 64\r\n };\r\n\r\n hdr.sig = this._st.read(3);\r\n hdr.ver = this._st.read(3);\r\n if (hdr.sig !== 'GIF') {\r\n throw new Error('Not a GIF file.'); // XXX: This should probably be handled more nicely.\r\n }\r\n\r\n hdr.width = this._st.readUnsigned();\r\n hdr.height = this._st.readUnsigned();\r\n\r\n const bits = byteToBitArr(this._st.readByte());\r\n hdr.gctFlag = bits.shift();\r\n hdr.colorRes = bitsToNum(bits.splice(0, 3));\r\n hdr.sorted = bits.shift();\r\n hdr.globalColorTableSize = bitsToNum(bits.splice(0, 3));\r\n\r\n hdr.bgColor = this._st.readByte();\r\n hdr.pixelAspectRatio = this._st.readByte(); // if not 0, aspectRatio = (pixelAspectRatio + 15) / 64\r\n\r\n if (hdr.gctFlag) {\r\n hdr.globalColorTable = this.parseColorTable(1 << (hdr.globalColorTableSize + 1));\r\n this.globalColorTable = hdr.globalColorTable;\r\n }\r\n if (this._handler.hdr && this._handler.hdr(hdr)) {\r\n this.checkBytes.push(this._handler.hdr);\r\n }\r\n };\r\n\r\n parseExt = (block: any) => {\r\n const parseGCExt = (block: any) => {\r\n this.checkBytes.push(this._st.readByte()); // Always 4\r\n\r\n const bits = byteToBitArr(this._st.readByte());\r\n block.reserved = bits.splice(0, 3); // Reserved; should be 000.\r\n block.disposalMethod = bitsToNum(bits.splice(0, 3));\r\n block.userInput = bits.shift();\r\n block.transparencyGiven = bits.shift();\r\n\r\n block.delayTime = this._st.readUnsigned();\r\n\r\n block.transparencyIndex = this._st.readByte();\r\n\r\n block.terminator = this._st.readByte();\r\n\r\n if (this._handler.gce && this._handler.gce(block)) {\r\n this.checkBytes.push(this._handler.gce);\r\n }\r\n };\r\n\r\n const parseComExt = (block: any) => {\r\n block.comment = this.readSubBlocks();\r\n if (this._handler.com && this._handler.com(block)) {\r\n this.checkBytes.push(this._handler.com);\r\n }\r\n };\r\n\r\n const parsePTExt = (block: any) => {\r\n this.checkBytes.push(this._st.readByte()); // Always 12\r\n block.ptHeader = this._st.readBytes(12);\r\n block.ptData = this.readSubBlocks();\r\n if (this._handler.pte && this._handler.pte(block)) {\r\n this.checkBytes.push(this._handler.pte);\r\n }\r\n };\r\n\r\n const parseAppExt = (block: any) => {\r\n const parseNetscapeExt = (block: any) => {\r\n this.checkBytes.push(this._st.readByte()); // Always 3\r\n block.unknown = this._st.readByte(); // Q: Always 1? What is this?\r\n block.iterations = this._st.readUnsigned();\r\n block.terminator = this._st.readByte();\r\n if (this._handler.app && this._handler.app.NETSCAPE && this._handler.app.NETSCAPE(block)) {\r\n this.checkBytes.push(this._handler.app);\r\n }\r\n };\r\n\r\n const parseUnknownAppExt = (block: any) => {\r\n block.appData = this.readSubBlocks();\r\n // FIXME: This won't work if a handler wants to match on any identifier.\r\n if (this._handler.app && this._handler.app[block.identifier] && this._handler.app[block.identifier](block)) {\r\n this.checkBytes.push(this._handler.app[block.identifier]);\r\n }\r\n };\r\n\r\n this.checkBytes.push(this._st.readByte()); // Always 11\r\n block.identifier = this._st.read(8);\r\n block.authCode = this._st.read(3);\r\n switch (block.identifier) {\r\n case 'NETSCAPE':\r\n parseNetscapeExt(block);\r\n break;\r\n default:\r\n parseUnknownAppExt(block);\r\n break;\r\n }\r\n };\r\n\r\n const parseUnknownExt = (block: any) => {\r\n block.data = this.readSubBlocks();\r\n if (this._handler.unknown && this._handler.unknown(block)) {\r\n this.checkBytes.push(this._handler.unknown);\r\n }\r\n };\r\n\r\n block.label = this._st.readByte();\r\n switch (block.label) {\r\n case 0xf9:\r\n block.extType = 'gce';\r\n parseGCExt(block);\r\n break;\r\n case 0xfe:\r\n block.extType = 'com';\r\n parseComExt(block);\r\n break;\r\n case 0x01:\r\n block.extType = 'pte';\r\n parsePTExt(block);\r\n break;\r\n case 0xff:\r\n block.extType = 'app';\r\n parseAppExt(block);\r\n break;\r\n default:\r\n block.extType = 'unknown';\r\n parseUnknownExt(block);\r\n break;\r\n }\r\n };\r\n\r\n parseImg = (img: any) => {\r\n const deinterlace = (pixels: any, width: any) => {\r\n // Of course this defeats the purpose of interlacing. And it's *probably*\r\n // the least efficient way it's ever been implemented. But nevertheless...\r\n\r\n const newPixels = new Array(pixels.length);\r\n const rows = pixels.length / width;\r\n const cpRow = (toRow: any, fromRow: any) => {\r\n const fromPixels = pixels.slice(fromRow * width, (fromRow + 1) * width);\r\n newPixels.splice.apply(newPixels, [toRow * width, width].concat(fromPixels));\r\n };\r\n\r\n const offsets = [0, 4, 2, 1];\r\n const steps = [8, 8, 4, 2];\r\n\r\n let fromRow = 0;\r\n for (let pass = 0; pass < 4; pass++) {\r\n for (let toRow = offsets[pass]; toRow < rows; toRow += steps[pass]) {\r\n cpRow(toRow, fromRow);\r\n fromRow++;\r\n }\r\n }\r\n\r\n return newPixels;\r\n };\r\n\r\n img.leftPos = this._st.readUnsigned();\r\n img.topPos = this._st.readUnsigned();\r\n img.width = this._st.readUnsigned();\r\n img.height = this._st.readUnsigned();\r\n\r\n const bits = byteToBitArr(this._st.readByte());\r\n img.lctFlag = bits.shift();\r\n img.interlaced = bits.shift();\r\n img.sorted = bits.shift();\r\n img.reserved = bits.splice(0, 2);\r\n img.lctSize = bitsToNum(bits.splice(0, 3));\r\n\r\n if (img.lctFlag) {\r\n img.lct = this.parseColorTable(1 << (img.lctSize + 1));\r\n }\r\n\r\n img.lzwMinCodeSize = this._st.readByte();\r\n\r\n const lzwData = this.readSubBlocks();\r\n\r\n img.pixels = lzwDecode(img.lzwMinCodeSize, lzwData);\r\n\r\n if (img.interlaced) {\r\n // Move\r\n img.pixels = deinterlace(img.pixels, img.width);\r\n }\r\n\r\n this.frames.push(img);\r\n this.arrayToImage(img);\r\n if (this._handler.img && this._handler.img(img)) {\r\n this.checkBytes.push(this._handler);\r\n }\r\n };\r\n\r\n public parseBlock = () => {\r\n const block = {\r\n sentinel: this._st.readByte(),\r\n type: ''\r\n };\r\n const blockChar = String.fromCharCode(block.sentinel);\r\n switch (blockChar) {\r\n case '!':\r\n block.type = 'ext';\r\n this.parseExt(block);\r\n break;\r\n case ',':\r\n block.type = 'img';\r\n this.parseImg(block);\r\n break;\r\n case ';':\r\n block.type = 'eof';\r\n if (this._handler.eof && this._handler.eof(block)) {\r\n this.checkBytes.push(this._handler.eof);\r\n }\r\n break;\r\n default:\r\n throw new Error('Unknown block: 0x' + block.sentinel.toString(16));\r\n }\r\n\r\n if (block.type !== 'eof') {\r\n this.parseBlock();\r\n }\r\n };\r\n\r\n arrayToImage = (frame: GifFrame) => {\r\n let count = 0;\r\n const c = document.createElement('canvas');\r\n c.id = count.toString();\r\n c.width = frame.width;\r\n c.height = frame.height;\r\n count++;\r\n const context = c.getContext('2d');\r\n const pixSize = 1;\r\n let y = 0;\r\n let x = 0;\r\n for (let i = 0; i < frame.pixels.length; i++) {\r\n if (x % frame.width === 0) {\r\n y++;\r\n x = 0;\r\n }\r\n if (this.globalColorTable[frame.pixels[i]] === this._transparentColor.toHex()) {\r\n context.fillStyle = `rgba(0, 0, 0, 0)`;\r\n } else {\r\n context.fillStyle = this.globalColorTable[frame.pixels[i]];\r\n }\r\n\r\n context.fillRect(x, y, pixSize, pixSize);\r\n x++;\r\n }\r\n const img = new Image();\r\n img.src = c.toDataURL();\r\n this.images.push(img);\r\n };\r\n}\r\n","export * from './Resource';\r\nexport * from './Sound/Index';\r\nexport * from './Gif';\r\n","export * from './Component';\r\nexport * from './Entity';\r\nexport * from './EntityManager';\r\nexport * from './Query';\r\nexport * from './QueryManager';\r\nexport * from './System';\r\nexport * from './SystemManager';\r\nexport * from './World';\r\n\r\nexport * from './Components/TransformComponent';\r\nexport * from './Components/MotionComponent';\r\n","import { BoundingBox } from '../Collision/BoundingBox';\r\nimport { Color } from '../Color';\r\nimport { Vector } from '../Math/vector';\r\nimport { ExcaliburGraphicsContext } from './Context/ExcaliburGraphicsContext';\r\nimport { Graphic } from './Graphic';\r\n\r\nexport interface LineOptions {\r\n start: Vector;\r\n end: Vector;\r\n color?: Color;\r\n thickness?: number;\r\n}\r\nexport class Line extends Graphic {\r\n readonly start: Vector;\r\n readonly end: Vector;\r\n color: Color = Color.Black;\r\n thickness: number = 1;\r\n constructor(options: LineOptions) {\r\n super();\r\n const { start, end, color, thickness } = options;\r\n this.start = start;\r\n this.end = end;\r\n this.color = color ?? this.color;\r\n this.thickness = thickness ?? this.thickness;\r\n const { width, height } = BoundingBox.fromPoints([start, end]);\r\n this.width = width;\r\n this.height = height;\r\n }\r\n\r\n protected _drawImage(ctx: ExcaliburGraphicsContext, _x: number, _y: number): void {\r\n ctx.drawLine(this.start, this.end, this.color, this.thickness);\r\n }\r\n\r\n clone(): Line {\r\n return new Line({\r\n start: this.start,\r\n end: this.end,\r\n color: this.color,\r\n thickness: this.thickness\r\n });\r\n }\r\n}","import { ImageFiltering } from '.';\r\nimport { Vector, vec } from '../Math/vector';\r\nimport { Raster, RasterOptions } from './Raster';\r\n\r\nexport interface PolygonOptions {\r\n points: Vector[];\r\n}\r\n\r\n/**\r\n * A polygon [[Graphic]] for drawing arbitrary polygons to the [[ExcaliburGraphicsContext]]\r\n *\r\n * Polygons default to [[ImageFiltering.Blended]]\r\n */\r\nexport class Polygon extends Raster {\r\n private _points: Vector[];\r\n public get points(): Vector[] {\r\n return this._points;\r\n }\r\n public set points(points: Vector[]) {\r\n this._points = points;\r\n const min = this.minPoint;\r\n this.width = this._points.reduce((max, p) => Math.max(p.x, max), 0) - min.x;\r\n this.height = this._points.reduce((max, p) => Math.max(p.y, max), 0) - min.y;\r\n this.flagDirty();\r\n }\r\n\r\n public get minPoint() {\r\n const minX = this._points.reduce((min, p) => Math.min(p.x, min), Infinity);\r\n const minY = this._points.reduce((min, p) => Math.min(p.y, min), Infinity);\r\n return vec(minX, minY);\r\n }\r\n\r\n constructor(options: RasterOptions & PolygonOptions) {\r\n super(options);\r\n this.points = options.points;\r\n this.filtering = ImageFiltering.Blended;\r\n this.rasterize();\r\n }\r\n\r\n public clone(): Polygon {\r\n return new Polygon({\r\n points: this.points.map((p) => p.clone()),\r\n ...this.cloneGraphicOptions(),\r\n ...this.cloneRasterOptions()\r\n });\r\n }\r\n\r\n execute(ctx: CanvasRenderingContext2D): void {\r\n if (this.points && this.points.length) {\r\n ctx.beginPath();\r\n // Iterate through the supplied points and construct a 'polygon'\r\n const min = this.minPoint.negate();\r\n const firstPoint = this.points[0].add(min);\r\n ctx.moveTo(firstPoint.x, firstPoint.y);\r\n this.points.forEach((point) => {\r\n ctx.lineTo(point.x + min.x, point.y + min.y);\r\n });\r\n ctx.lineTo(firstPoint.x, firstPoint.y);\r\n ctx.closePath();\r\n if (this.color) {\r\n ctx.fill();\r\n }\r\n if (this.strokeColor) {\r\n ctx.stroke();\r\n }\r\n }\r\n }\r\n}\r\n","// Graphics\r\nexport * from './Graphic';\r\nexport * from './Sprite';\r\nexport * from './SpriteSheet';\r\nexport * from './GraphicsGroup';\r\nexport * from './ImageSource';\r\nexport * from './Animation';\r\nexport * from './Line';\r\n\r\n// Graphics ECS\r\nexport * from './GraphicsComponent';\r\nexport * from './DebugGraphicsComponent';\r\nexport * from './GraphicsSystem';\r\nexport * from './OffscreenSystem';\r\nexport * from './ParallaxComponent';\r\n\r\n// Raster graphics\r\nexport * from './Raster';\r\nexport * from './Circle';\r\nexport * from './Rectangle';\r\nexport * from './Polygon';\r\nexport * from './Text';\r\nexport * from './FontCommon';\r\nexport * from './Font';\r\nexport * from './FontCache';\r\nexport * from './SpriteFont';\r\nexport * from './Canvas';\r\n\r\nexport * from './Context/ExcaliburGraphicsContext';\r\nexport * from './Context/ExcaliburGraphicsContext2DCanvas';\r\nexport * from './Context/ExcaliburGraphicsContextWebGL';\r\n\r\nexport * from './Context/debug-text';\r\n\r\n// Post Processor\r\nexport * from './PostProcessor/PostProcessor';\r\nexport * from './PostProcessor/ScreenShader';\r\nexport * from './PostProcessor/ColorBlindnessMode';\r\nexport * from './PostProcessor/ColorBlindnessPostProcessor';\r\n\r\nexport * from './Context/texture-loader';\r\nexport * from './Filtering';\r\n\r\n\r\n// Rendering\r\nexport * from './Context/shader';\r\nexport * from './Context/vertex-buffer';\r\nexport * from './Context/vertex-layout';\r\nexport * from './Context/quad-index-buffer';\r\nexport * from './Context/material';\r\n\r\n// Util\r\n\r\nimport * as webgl from './Context/webgl-util';\r\nexport { webgl };","// This import site is deprecated\r\n// TODO remove deprecated exports in v0.29.0\r\n\r\n/**\r\n * @module\r\n * Provides support for mice, keyboards, and controllers.\r\n */\r\n\r\nexport {\r\n /**\r\n * @deprecated ex.Input.WheelEvent import site will be removed in v0.29.0, use ex.WheelEvent\r\n */\r\n WheelEvent\r\n} from './WheelEvent';\r\n\r\nexport {\r\n /**\r\n * @deprecated ex.Input.PointerEvent import site will be removed in v0.29.0, use ex.PointerEvent\r\n */\r\n PointerEvent\r\n} from './PointerEvent';\r\n\r\nexport {\r\n /**\r\n * @deprecated ex.Input.WheelDeltaMode import site will be removed in v0.29.0, use ex.WheelDeltaMode\r\n */\r\n WheelDeltaMode\r\n} from './WheelDeltaMode';\r\n\r\nexport {\r\n /**\r\n * @deprecated ex.Input.PointerButton import site will be removed in v0.29.0, use ex.PointerButton\r\n */\r\n PointerButton\r\n} from './PointerButton';\r\n\r\nexport {\r\n /**\r\n * @deprecated ex.Input.NativePointerButton import site will be removed in v0.29.0, use ex.NativePointerButton\r\n */\r\n NativePointerButton\r\n} from './NativePointerButton';\r\n\r\nexport {\r\n /**\r\n * @deprecated ex.Input.CapturePointerConfig import site will be removed in v0.29.0, use ex.CapturePointerConfig\r\n */\r\n CapturePointerConfig\r\n} from './CapturePointerConfig';\r\n\r\nexport {\r\n /**\r\n * @deprecated ex.Input.EngineInput import site will be removed in v0.29.0, use ex.EngineInput\r\n */\r\n EngineInput\r\n} from './EngineInput';\r\n\r\nexport {\r\n /**\r\n * @deprecated ex.Input.NativePointerEvent import site will be removed in v0.29.0, use ex.NativePointerEvent\r\n */\r\n NativePointerEvent,\r\n /**\r\n * @deprecated ex.Input.NativeMouseEvent import site will be removed in v0.29.0, use ex.NativeMouseEvent\r\n */\r\n NativeMouseEvent,\r\n /**\r\n * @deprecated ex.Input.NativeTouchEvent import site will be removed in v0.29.0, use ex.NativeTouchEvent\r\n */\r\n NativeTouchEvent,\r\n /**\r\n * @deprecated ex.Input.NativeWheelEvent import site will be removed in v0.29.0, use ex.NativeWheelEvent\r\n */\r\n NativeWheelEvent,\r\n /**\r\n * @deprecated ex.Input.PointerInitOptions import site will be removed in v0.29.0, use ex.PointerInitOptions\r\n */\r\n PointerInitOptions,\r\n /**\r\n * @deprecated ex.Input.PointerEventReceiver import site will be removed in v0.29.0, use ex.PointerEventReceiver\r\n */\r\n PointerEventReceiver\r\n} from './PointerEventReceiver';\r\n\r\nexport {\r\n /**\r\n * @deprecated ex.Input.PointerComponent import site will be removed in v0.29.0, use ex.PointerComponent\r\n */\r\n PointerComponent\r\n} from './PointerComponent';\r\n\r\nexport {\r\n /**\r\n * @deprecated ex.Input.PointerSystem import site will be removed in v0.29.0, use ex.PointerSystem\r\n */\r\n PointerSystem\r\n} from './PointerSystem';\r\n\r\nexport {\r\n /**\r\n * @deprecated ex.Input.PointerType import site will be removed in v0.29.0, use ex.PointerType\r\n */\r\n PointerType\r\n} from './PointerType';\r\n\r\nexport {\r\n /**\r\n * @deprecated ex.Input.PointerScope import site will be removed in v0.29.0, use ex.PointerScope\r\n */\r\n PointerScope\r\n} from './PointerScope';\r\n\r\nexport {\r\n /**\r\n * @deprecated ex.Input.Keys import site will be removed in v0.29.0, use ex.Keys\r\n */\r\n Keys,\r\n /**\r\n * @deprecated ex.Input.KeyEvent import site will be removed in v0.29.0, use ex.KeyEvent\r\n */\r\n KeyEvent,\r\n /**\r\n * @deprecated ex.Input.KeyboardInitOptions import site will be removed in v0.29.0, use ex.KeyboardInitOptions\r\n */\r\n KeyboardInitOptions,\r\n /**\r\n * @deprecated ex.Input.Keyboard import site will be removed in v0.29.0, use ex.Keyboard\r\n */\r\n Keyboard\r\n} from './Keyboard';\r\n\r\n// Re-export hack to deprecate import site gently\r\nexport {\r\n /**\r\n * @deprecated ex.Input.Gamepads import site will be removed in v0.29.0, use ex.Gamepads\r\n */\r\n Gamepads,\r\n /**\r\n * @deprecated ex.Input.Gamepad import site will be removed in v0.29.0, use ex.Gamepad\r\n */\r\n Gamepad,\r\n /**\r\n * @deprecated ex.Input.Buttons import site will be removed in v0.29.0, use ex.Buttons\r\n */\r\n Buttons,\r\n /**\r\n * @deprecated ex.Input.Axes import site will be removed in v0.29.0, use ex.Axes\r\n */\r\n Axes,\r\n /**\r\n * @deprecated ex.Input.NavigatorGamepads import site will be removed in v0.29.0, use ex.NavigatorGamepads\r\n */\r\n NavigatorGamepads,\r\n /**\r\n * @deprecated ex.Input.NavigatorGamepad import site will be removed in v0.29.0, use ex.NavigatorGamepad\r\n */\r\n NavigatorGamepad,\r\n /**\r\n * @deprecated ex.Input.NavigatorGamepadButton import site will be removed in v0.29.0, use ex.NavigatorGamepadButton\r\n */\r\n NavigatorGamepadButton,\r\n /**\r\n * @deprecated ex.Input.NavigatorGamepadEvent import site will be removed in v0.29.0, use ex.NavigatorGamepadEvent\r\n */\r\n NavigatorGamepadEvent,\r\n /**\r\n * @deprecated ex.Input.GamepadConfiguration import site will be removed in v0.29.0, use ex.GamepadConfiguration\r\n */\r\n GamepadConfiguration\r\n} from './Gamepad';","export * from './Util';\r\n\r\nexport * from './Log';\r\n\r\nexport * from './Observable';\r\n\r\nexport * from './EasingFunctions';\r\n\r\nimport * as drawUtil from './DrawUtil';\r\nexport { drawUtil as DrawUtil };\r\n","import { Future } from './Future';\r\n\r\nclass AsyncWaitQueue {\r\n // Code from StephenCleary https://gist.github.com/StephenCleary/ba50b2da419c03b9cba1d20cb4654d5e\r\n private _queue: Future[] = [];\r\n\r\n public get length(): number {\r\n return this._queue.length;\r\n }\r\n\r\n public enqueue(): Promise {\r\n const future = new Future();\r\n this._queue.push(future);\r\n return future.promise;\r\n }\r\n\r\n public dequeue(value: T): void {\r\n const future = this._queue.shift();\r\n future.resolve(value);\r\n }\r\n}\r\n\r\n/**\r\n * Semaphore allows you to limit the amount of async calls happening between `enter()` and `exit()`\r\n *\r\n * This can be useful when limiting the number of http calls, browser api calls, etc either for performance or to work\r\n * around browser limitations like max Image.decode() calls in chromium being 256.\r\n */\r\nexport class Semaphore {\r\n private _waitQueue = new AsyncWaitQueue();\r\n constructor(private _count: number) { }\r\n\r\n public get count() {\r\n return this._count;\r\n }\r\n\r\n public get waiting() {\r\n return this._waitQueue.length;\r\n }\r\n\r\n public async enter() {\r\n if (this._count !== 0) {\r\n this._count--;\r\n return Promise.resolve();\r\n }\r\n return this._waitQueue.enqueue();\r\n }\r\n\r\n public exit(count: number = 1) {\r\n if (count === 0) {\r\n return;\r\n }\r\n while (count !== 0 && this._waitQueue.length !== 0) {\r\n this._waitQueue.dequeue(null);\r\n count--;\r\n }\r\n this._count += count;\r\n }\r\n}","/**\r\n * The current Excalibur version string\r\n * @description `process.env.__EX_VERSION` gets replaced by Webpack on build\r\n */\r\nexport const EX_VERSION = process.env.__EX_VERSION;\r\nimport { polyfill } from './Polyfill';\r\npolyfill();\r\n\r\n// This file is used as the bundle entry point and exports everything\r\n// that will be exposed as the `ex` global variable.\r\nexport * from './Flags';\r\nexport * from './Id';\r\nexport * from './Engine';\r\nexport * from './Screen';\r\nexport { Actor, ActorArgs } from './Actor';\r\nexport * from './Math/Index';\r\nexport * from './Camera';\r\nexport * from './Configurable';\r\nexport * from './Debug/index';\r\nexport * from './EventDispatcher';\r\nexport * from './EventEmitter';\r\nexport * from './Events/MediaEvents';\r\nexport * from './Events';\r\nexport * from './Label';\r\nexport { FontStyle, FontUnit, TextAlign, BaseAlign } from './Graphics/FontCommon';\r\nexport * from './Loader';\r\nexport { Particle, ParticleTransform, ParticleEmitter, ParticleArgs, ParticleEmitterArgs, EmitterType } from './Particles';\r\nexport * from './Collision/Physics';\r\nexport * from './Scene';\r\n\r\nexport * from './TileMap/index';\r\n\r\nexport * from './Timer';\r\nexport * from './Trigger';\r\nexport * from './ScreenElement';\r\n\r\nexport * from './Actions/Index';\r\nexport * from './Collision/Index';\r\n\r\nexport * from './Interfaces/Index';\r\nexport * from './Resources/Index';\r\n\r\nexport * from './EntityComponentSystem/index';\r\n\r\nexport * from './Color';\r\n\r\nexport * from './Graphics/index';\r\n\r\n// ex.Events namespace\r\nimport * as events from './Events';\r\nexport { events as Events };\r\n\r\n// ex.Input namespace\r\n// TODO deprecated import site remove in v0.29.0\r\nimport * as input from './Input/Index';\r\nexport { input as Input };\r\n\r\nexport {\r\n WheelEvent\r\n} from './Input/WheelEvent';\r\n\r\nexport {\r\n PointerEvent\r\n} from './Input/PointerEvent';\r\n\r\nexport {\r\n WheelDeltaMode\r\n} from './Input/WheelDeltaMode';\r\n\r\nexport {\r\n PointerButton\r\n} from './Input/PointerButton';\r\n\r\nexport {\r\n NativePointerButton\r\n} from './Input/NativePointerButton';\r\n\r\nexport {\r\n CapturePointerConfig\r\n} from './Input/CapturePointerConfig';\r\n\r\nexport {\r\n EngineInput\r\n} from './Input/EngineInput';\r\n\r\nexport {\r\n NativePointerEvent,\r\n NativeMouseEvent,\r\n NativeTouchEvent,\r\n NativeWheelEvent,\r\n PointerInitOptions,\r\n PointerEventReceiver\r\n} from './Input/PointerEventReceiver';\r\n\r\nexport { PointerComponent } from './Input/PointerComponent';\r\nexport { PointerSystem } from './Input/PointerSystem';\r\nexport { PointerType } from './Input/PointerType';\r\nexport { PointerScope } from './Input/PointerScope';\r\n\r\nexport {\r\n Gamepads,\r\n Gamepad,\r\n Buttons,\r\n Axes,\r\n NavigatorGamepads,\r\n NavigatorGamepad,\r\n NavigatorGamepadButton,\r\n NavigatorGamepadEvent,\r\n GamepadConfiguration\r\n} from './Input/Gamepad';\r\n\r\nexport {\r\n Keys,\r\n KeyEvent,\r\n KeyboardInitOptions,\r\n Keyboard\r\n} from './Input/Keyboard';\r\nexport * from './Input/InputMapper';\r\n\r\n// ex.Util namespaces\r\nimport * as util from './Util/Index';\r\nexport { util as Util };\r\n\r\nexport * from './Util/Browser';\r\nexport * from './Util/Decorators';\r\nexport * from './Util/Detector';\r\nexport * from './Util/EasingFunctions';\r\nexport * from './Util/Observable';\r\nexport * from './Util/Log';\r\nexport * from './Util/Pool';\r\nexport * from './Util/Fps';\r\nexport * from './Util/Clock';\r\nexport * from './Util/WebAudio';\r\nexport * from './Util/Toaster';\r\nexport * from './Util/StateMachine';\r\nexport * from './Util/Future';\r\nexport * from './Util/Semaphore';\r\n\r\n// ex.Deprecated\r\n// import * as deprecated from './Deprecated';\r\n// export { deprecated as Deprecated };\r\n// export * from './Deprecated';\r\n","import * as ex from 'excalibur';\n\n\nimport TitleImagePath from '../res/title.png';\nimport KnightSpriteSheetPath from '../res/KnightSheet.png';\nimport SpiderSheetPath from '../res/SpiderSheet.png';\nimport HeartSheetPath from '../res/HeartSheet.png';\nimport UISheetPath from '../res/UISheet.png';\nimport TerrainSheetPath from '../res/TerrainSheet.png';\nimport HighlightSheetPath from '../res/HighlightSheet.png';\nimport RedHighlightSheetPath from '../res/RedHighlightSheet.png';\nimport CloudSheetPath from '../res/Cloud.png';\nimport SmokePath from '../res/Smoke.png';\nimport HitSoundPath from '../res/hit.wav';\nimport MoveSoundPath from '../res/move.wav';\nimport SelectSoundPath from '../res/unitselect.wav';\nimport TargetSelectPath from '../res/targetselect.wav';\nimport TutorialTextPath from '../res/tutorial-text.png';\nimport LevelMusic1Path from '../res/5 Action Chiptunes By Juhani Junkala/Juhani Junkala [Retro Game Music Pack] Level 3.wav';\nimport LevelMusic2Path from '../res/gba1complete.mp3';\nimport ExplosionPath from '../res/explosion.png';\nimport ExplosionSoundPath from '../res/explosion.wav';\nimport TitleScreenMusic from '../res/two_left_socks.ogg';\n\nexport const Resources = {\n TitleImage: new ex.ImageSource(TitleImagePath),\n KnightSpriteSheet: new ex.ImageSource(KnightSpriteSheetPath),\n SpiderSheet: new ex.ImageSource(SpiderSheetPath),\n HeartSheet: new ex.ImageSource(HeartSheetPath),\n UISheet: new ex.ImageSource(UISheetPath),\n TerrainSheet: new ex.ImageSource(TerrainSheetPath),\n HighlightSheet: new ex.ImageSource(HighlightSheetPath),\n RedHighlightSheet: new ex.ImageSource(RedHighlightSheetPath),\n CloudSheet: new ex.ImageSource(CloudSheetPath),\n SmokeSheet: new ex.ImageSource(SmokePath),\n TutorialText: new ex.ImageSource(TutorialTextPath),\n ExplosionSheet: new ex.ImageSource(ExplosionPath),\n HitSound: new ex.Sound(HitSoundPath),\n MoveSound: new ex.Sound(MoveSoundPath),\n SelectSound: new ex.Sound(SelectSoundPath),\n TargetSelectSound: new ex.Sound(TargetSelectPath),\n LevelMusic1: new ex.Sound(LevelMusic1Path),\n LevelMusic2: new ex.Sound(LevelMusic2Path),\n ExplosionSound: new ex.Sound(ExplosionSoundPath),\n TitleMusic: new ex.Sound(TitleScreenMusic),\n} as const;\n\nexport const TutorialTextSheet = ex.SpriteSheet.fromImageSource({\n image: Resources.TutorialText,\n grid: {\n rows: 1,\n columns: 8,\n spriteWidth: 128,\n spriteHeight: 64\n }\n})\n\nexport const TerrainSpriteSheet = ex.SpriteSheet.fromImageSource({\n image: Resources.TerrainSheet,\n grid: {\n rows: 5,\n columns: 5,\n spriteHeight: 32,\n spriteWidth: 32\n }\n});\n\nexport const CursorAnimation = ex.Animation.fromSpriteSheetCoordinates({\n spriteSheet: TerrainSpriteSheet,\n frameCoordinates: [\n { x: 1, y: 1, duration: 200 },\n { x: 2, y: 1, duration: 200 },\n { x: 3, y: 1, duration: 200 },\n { x: 3, y: 1, duration: 200 },\n { x: 3, y: 1, duration: 200 },\n { x: 2, y: 1, duration: 200 },\n ]\n});\n\nexport const HighlightSpriteSheet = ex.SpriteSheet.fromImageSource({\n image: Resources.HighlightSheet,\n grid: {\n rows: 1,\n columns: 5,\n spriteHeight: 32,\n spriteWidth: 32\n }\n});\nexport const RedHighlightSpriteSheet = ex.SpriteSheet.fromImageSource({\n image: Resources.RedHighlightSheet,\n grid: {\n rows: 1,\n columns: 5,\n spriteHeight: 32,\n spriteWidth: 32\n }\n});\n\nexport const HighlightAnimation = ex.Animation.fromSpriteSheetCoordinates({\n spriteSheet: HighlightSpriteSheet,\n strategy: ex.AnimationStrategy.Loop,\n frameCoordinates: [\n {x: 0, y: 0, duration: 100 },\n {x: 1, y: 0, duration: 100 },\n {x: 2, y: 0, duration: 100 },\n {x: 3, y: 0, duration: 100 },\n {x: 4, y: 0, duration: 100 },\n ]\n});\n\nexport const RedHighlightAnimation = ex.Animation.fromSpriteSheetCoordinates({\n spriteSheet: RedHighlightSpriteSheet,\n strategy: ex.AnimationStrategy.Loop,\n frameCoordinates: [\n {x: 0, y: 0, duration: 100 },\n {x: 1, y: 0, duration: 100 },\n {x: 2, y: 0, duration: 100 },\n {x: 3, y: 0, duration: 100 },\n {x: 4, y: 0, duration: 100 },\n ]\n})\n\n\nexport const SpiderSpriteSheet = ex.SpriteSheet.fromImageSource({\n image: Resources.SpiderSheet,\n grid: {\n rows: 1,\n columns: 4,\n spriteHeight: 32,\n spriteWidth: 32\n }\n});\n\nexport const SpiderIdle = ex.Animation.fromSpriteSheetCoordinates({\n spriteSheet: SpiderSpriteSheet,\n strategy: ex.AnimationStrategy.Loop,\n frameCoordinates: [\n {x: 0, y: 0, duration: 200},\n {x: 1, y: 0, duration: 200},\n {x: 2, y: 0, duration: 200},\n {x: 3, y: 0, duration: 200}\n ]\n});\n\nexport const KnightSpriteSheet = ex.SpriteSheet.fromImageSource({\n image: Resources.KnightSpriteSheet,\n grid: {\n rows: 1,\n columns: 4,\n spriteHeight: 32,\n spriteWidth: 32\n }\n});\n\nexport const KnightIdle = ex.Animation.fromSpriteSheetCoordinates({\n spriteSheet: KnightSpriteSheet,\n strategy: ex.AnimationStrategy.Loop,\n frameCoordinates: [\n {x: 0, y: 0, duration: 200},\n {x: 1, y: 0, duration: 200},\n {x: 2, y: 0, duration: 200},\n {x: 3, y: 0, duration: 200}\n ]\n});\n\nexport const HeartSpriteSheet = ex.SpriteSheet.fromImageSource({\n image: Resources.HeartSheet,\n grid: {\n rows: 1,\n columns: 6,\n spriteHeight: 32,\n spriteWidth: 32\n }\n});\n\nexport const ExplosionSpriteSheet = ex.SpriteSheet.fromImageSource({\n image: Resources.ExplosionSheet,\n grid: {\n rows: 2,\n columns: 5,\n spriteHeight: 32,\n spriteWidth: 32\n }\n});\n\nexport const Explosion = ex.Animation.fromSpriteSheetCoordinates({\n spriteSheet: ExplosionSpriteSheet,\n frameCoordinates: [\n {x: 0, y: 0, duration: 100 },\n {x: 1, y: 0, duration: 100 },\n {x: 2, y: 0, duration: 100 },\n {x: 3, y: 0, duration: 100 },\n {x: 4, y: 0, duration: 100 },\n {x: 0, y: 1, duration: 100 },\n {x: 1, y: 1, duration: 100 },\n {x: 2, y: 1, duration: 100 },\n ]\n})\n\nexport const Smoke = Resources.SmokeSheet.toSprite();\n\nexport const Title = Resources.TitleImage.toSprite();\n\nexport const loader = new ex.Loader();\n\nfor (let res of Object.values(Resources)) {\n loader.addResource(res);\n}","module.exports = new __parcel__URL__(\"title.46943752.png\").toString();","module.exports = new __parcel__URL__(\"KnightSheet.2897b254.png\").toString();","module.exports = new __parcel__URL__(\"SpiderSheet.597e1dd4.png\").toString();","module.exports = new __parcel__URL__(\"HeartSheet.54a99443.png\").toString();","module.exports = new __parcel__URL__(\"UISheet.2837e64f.png\").toString();","module.exports = new __parcel__URL__(\"TerrainSheet.e61d651c.png\").toString();","module.exports = new __parcel__URL__(\"HighlightSheet.fff21fa0.png\").toString();","module.exports = new __parcel__URL__(\"RedHighlightSheet.4a69e4d5.png\").toString();","module.exports = new __parcel__URL__(\"Cloud.e0b572a9.png\").toString();","module.exports = new __parcel__URL__(\"Smoke.7bc6cfe7.png\").toString();","module.exports = new __parcel__URL__(\"hit.cc332530.wav\").toString();","module.exports = new __parcel__URL__(\"move.8e8aee5f.wav\").toString();","module.exports = new __parcel__URL__(\"unitselect.d85b2a99.wav\").toString();","module.exports = new __parcel__URL__(\"targetselect.05425c18.wav\").toString();","module.exports = new __parcel__URL__(\"tutorial-text.d113bd93.png\").toString();","module.exports = new __parcel__URL__(\"Juhani Junkala [Retro Game Music Pack] Level 3.af273cb2.wav\").toString();","module.exports = new __parcel__URL__(\"gba1complete.c6e75e6f.mp3\").toString();","module.exports = new __parcel__URL__(\"explosion.cd6dbdc9.png\").toString();","module.exports = new __parcel__URL__(\"explosion.fcafad1f.wav\").toString();","module.exports = new __parcel__URL__(\"two_left_socks.7d2f267c.ogg\").toString();","import * as ex from 'excalibur';\nimport { Board } from '../board';\nimport { Terrain } from '../cell';\nimport { UnitType } from '../config';\nimport { Unit } from '../unit';\nimport { Player } from '../player';\nimport { HumanPlayer } from '../human-player';\nimport { SelectionManager } from '../selection-manager';\nimport { UIManager } from '../ui-manager';\nimport { TurnManager } from '../turn-manager';\nimport { ComputerPlayer } from '../computer-player';\nimport { Cloud } from '../cloud';\nimport { DustParticles } from '../dust-particles';\nimport { Resources } from '../resources';\n\nexport interface LevelData {\n name: string;\n displayName: string;\n nextLevel: string;\n width: number;\n height: number;\n maxTurns: number;\n /**\n * By convention the first player is human\n */\n players: string[];\n data: string[];\n}\n\n// export const TestLevelData: LevelData = {\n// name: 'Gentle Plains',\n// nextLevel: 'level2',\n// width: 6,\n// height: 6,\n// maxTurns: 100,\n// players: ['human', 'computer'],\n// data: [\n// 'GK1', 'G', 'G', 'G', 'G', 'GK1',\n// 'G', 'G', 'G', 'G', 'G', 'G',\n// 'G', 'G', 'W', 'W', 'G', 'G',\n// 'G', 'G', 'W', 'W', 'G', 'G',\n// 'G', 'G', 'W', 'W', 'G', 'G',\n// 'GS2', 'GS2', 'GS2', 'GS2', 'GS2', 'GS2'\n// ]\n// }\n\nexport class LevelBase extends ex.Scene {\n\n board!: Board;\n selectionManager!: SelectionManager;\n uiManager!: UIManager;\n engine!: ex.Engine;\n players!: Player[];\n turnManager!: TurnManager;\n constructor(public levelData: LevelData, public name: string) {\n super();\n }\n\n override onInitialize(engine: ex.Engine): void {\n this.engine = engine;\n }\n\n resetAndLoad() {\n const entities = this.entities;\n for (let i = entities.length - 1; i >= 0; i--) {\n this.world.remove(entities[i], false);\n }\n\n Resources.LevelMusic2.stop();\n\n this.add(new Cloud(ex.vec(800, 0)));\n this.add(new Cloud(ex.vec(400, 300)));\n this.add(new Cloud(ex.vec(700, 700)));\n\n\n this.board = this.parse(this.levelData);\n\n this.add(DustParticles);\n\n this.camera.pos = this.board.getCenter();\n }\n\n override onActivate(): void {\n this.resetAndLoad();\n this.turnManager.start();\n Resources.LevelMusic2.loop = true;\n Resources.LevelMusic2.play();\n\n this.engine.input.keyboard.on('press', (evt) => {\n // DELETEME for debugging\n if (evt.key === ex.Keys.W) {\n (this.players[1] as ComputerPlayer).lose();\n }\n if (evt.key === ex.Keys.L) {\n (this.players[0] as HumanPlayer).lose();\n }\n });\n\n }\n\n override onDeactivate(): void {\n // TODO deactivate event handlers on types that have them!!\n Resources.LevelMusic2.instances.forEach(i => i.stop());\n Resources.LevelMusic2.stop();\n }\n\n parse(levelData: LevelData): Board {\n const board = new Board(levelData.height, levelData.width, this);\n this.selectionManager = new SelectionManager(board);\n this.selectionManager.showCursor(0, 0);\n this.uiManager = new UIManager(this.engine);\n // TODO support arbitrary players\n this.players = [\n new HumanPlayer(levelData.players[0], this.engine, this.selectionManager, this.uiManager, board),\n new ComputerPlayer(levelData.players[1], this.selectionManager, board)\n ];\n\n this.turnManager = new TurnManager(this.engine, this, this.players, this.selectionManager, 10);\n\n for (let y = 0; y < levelData.height; y++) {\n for (let x = 0; x < levelData.width; x++) {\n const data = levelData.data[x + y * levelData.width];\n const terrain = data.charAt(0) as Terrain;\n let unit: Unit | null = null;\n if (data.length === 3) {\n const unitType: UnitType = data.charAt(1) === 'K' ? 'Knight' : 'Spider';\n const playerIndex = (+data.charAt(2)) - 1;\n\n unit = new Unit(x, y, unitType, board, this.players[playerIndex]);\n this.add(unit);\n }\n const cell = board.getCell(x, y);\n if (cell) {\n cell.terrain = terrain;\n if (unit) {\n cell.addUnit(unit);\n }\n }\n }\n }\n\n return board;\n }\n}","import * as ex from 'excalibur';\nimport { Cell } from \"./cell\";\nimport { BOARD_OFFSET, SCALE } from './config';\nimport { PathFinder } from './path-finding/path-finding-system';\nimport { Unit } from './unit';\n\nexport class Board {\n tileWidth: number = 32;\n tileHeight: number = 32;\n margin: number = 2;\n rows: number;\n cols: number;\n\n cells: Cell[] = [];\n\n pathFinder: PathFinder\n\n constructor(rows: number, cols: number, scene: ex.Scene) {\n this.rows = rows;\n this.cols = cols;\n for (let i = 0; i < this.rows * this.cols; i++) {\n const cell = new Cell(i % this.cols, Math.floor(i / this.cols), this);\n this.cells.push(cell);\n scene.add(cell);\n }\n\n // setup neighbors connections\n for (let cell of this.cells) {\n cell.pathNode.connections = cell.getNeighbors().map(c => c.pathNode);\n }\n\n this.pathFinder = new PathFinder(scene);\n }\n\n getCenter() {\n return ex.vec(\n this.cols * ((this.tileWidth + this.margin) * SCALE.x),\n this.rows * ((this.tileHeight + this.margin) * SCALE.y)\n ).scale(.5);\n }\n\n getUnits() {\n let result: Unit[] = [];\n for (let cell of this.cells) {\n if (cell.unit && cell.unit.active) {\n result.push(cell.unit);\n }\n }\n return result;\n }\n\n getEmptyCells(): Cell[] {\n return this.cells.filter(cell => !cell.unit);\n }\n\n getCellByWorldPos(pos: ex.Vector): Cell | null {\n return this.getCell(\n Math.floor((pos.x /*- BOARD_OFFSET.x*/) / ((this.tileWidth+this.margin) * SCALE.x)),\n Math.floor((pos.y /*- BOARD_OFFSET.y*/) / ((this.tileHeight+this.margin) * SCALE.y))\n );\n }\n\n getCell(x: number, y: number): Cell | null {\n if(x < 0 || x >= this.cols) return null;\n if(y < 0 || y >= this.rows) return null;\n return this.cells[x + y * this.cols];\n }\n}","import * as ex from \"excalibur\";\nimport { Board } from \"./board\";\nimport { CursorAnimation, HighlightAnimation, RedHighlightAnimation, TerrainSpriteSheet } from \"./resources\";\nimport { BOARD_OFFSET, SCALE } from \"./config\";\nimport { PathNodeComponent } from \"./path-finding/path-node-component\";\nimport { Unit } from \"./unit\";\n\nconst RangeHighlightAnimation = HighlightAnimation.clone();\nconst PathHighlightAnimation = HighlightAnimation.clone();\nconst AttackHighlightAnimation = RedHighlightAnimation.clone();\n\nexport enum Terrain {\n Grass = 'G',\n Water = 'W',\n Sand = 'S',\n Stone = 'T'\n}\n\nexport class Cell extends ex.Actor {\n sprite!: ex.Sprite;\n pathNode: PathNodeComponent;\n unit: Unit | null = null;\n private _terrain: Terrain = Terrain.Grass;\n\n /**\n * Individual cells on the board\n * \n * @param x integer coordinate\n * @param y integer coordinate\n * @param board \n */\n constructor(public x: number, public y: number, public board: Board) {\n super({\n name: `cell(${x}, ${y})`,\n pos: ex.vec(\n x * (board.tileWidth + board.margin) * SCALE.x,\n y * (board.tileHeight + board.margin) * SCALE.y\n ),\n anchor: ex.Vector.Zero\n });\n this.pathNode = new PathNodeComponent(this.pos);\n this.addComponent(this.pathNode);\n\n this.terrain = Terrain.Grass;\n\n RangeHighlightAnimation.scale = SCALE;\n RangeHighlightAnimation.opacity = 0.75;\n PathHighlightAnimation.scale = SCALE;\n PathHighlightAnimation.opacity = 0.75;\n PathHighlightAnimation.tint = ex.Color.Green;\n AttackHighlightAnimation.scale = SCALE;\n AttackHighlightAnimation.opacity = 0.75;\n CursorAnimation.scale = SCALE;\n this.graphics.add('range', RangeHighlightAnimation);\n this.graphics.add('path', PathHighlightAnimation);\n this.graphics.add('attack', AttackHighlightAnimation);\n this.graphics.add('cursor', CursorAnimation);\n }\n\n get terrain() {\n return this._terrain;\n }\n\n set terrain(terrain: Terrain) {\n this._terrain = terrain;\n switch(this.terrain) {\n case Terrain.Grass:\n this.sprite = TerrainSpriteSheet.sprites[ex.randomIntInRange(0, 1)];\n break;\n case Terrain.Sand:\n this.sprite = TerrainSpriteSheet.sprites[ex.randomIntInRange(2, 3)];\n // TODO slower to move through sand\n break;\n case Terrain.Water:\n this.sprite = TerrainSpriteSheet.sprites[4];\n this.pathNode.isWalkable = false;\n break;\n case Terrain.Stone:\n this.sprite = TerrainSpriteSheet.sprites[5];\n break;\n }\n this.sprite.scale = SCALE;\n this.graphics.use(this.sprite.clone());\n }\n\n addUnit(unit: Unit) {\n this.unit = unit;\n this.unit.cell = this;\n this.pathNode.walkableMask = unit.player.mask;\n }\n\n removeUnit(unit: Unit) {\n this.pathNode.walkableMask = -1;\n this.unit = null;\n unit.cell = null;\n }\n\n toggleHighlight(show: boolean, type: 'range' | 'path' | 'attack') {\n // reset highlight\n this.graphics.hide('range');\n this.graphics.hide('path');\n this.graphics.hide('attack');\n\n if (show) {\n this.graphics.show(type);\n } else {\n this.graphics.hide(type);\n }\n }\n\n toggleCursor(show: boolean) {\n if (show) {\n this.graphics.show('cursor');\n } else {\n this.graphics.hide('cursor');\n }\n }\n\n getDistance(other: Cell) {\n return Math.abs(this.pos.x - other.pos.x) + Math.abs(this.pos.y - other.pos.y);\n }\n\n /**\n * Returns the orthogonal neighbors (up, down, left, right)\n * @returns \n */\n getNeighbors(): Cell[] {\n return [\n this.board.getCell(this.x, this.y - 1),\n this.board.getCell(this.x, this.y + 1),\n this.board.getCell(this.x + 1, this.y),\n this.board.getCell(this.x - 1, this.y),\n ].filter(function (cell) {\n return cell !== null;\n }) as Cell[];\n }\n\n}","import * as ex from \"excalibur\";\n\nimport { KnightIdle, SpiderIdle } from \"./resources\";\nconst seed = Date.now();\nconsole.log(\"Random seed:\", seed);\nexport const RANDOM = new ex.Random(seed);\n\nexport const SCALE = ex.vec(3, 3);\nexport const BOARD_OFFSET = ex.vec(32 * 3, 32 * 4);\nexport const ENEMY_SPEED = 200;\n\nexport type UnitType = \"Knight\" | \"Spider\";\nexport interface UnitConfig {\n graphics: {\n offset: ex.Vector,\n idle: ex.Animation\n }\n health: number;\n movement: number;\n attack: number;\n range: number;\n}\nexport const UNIT_CONFIG: Record = {\n Knight: {\n graphics: {\n offset: ex.vec(0, 12 * SCALE.y),\n idle: KnightIdle\n },\n health: 5,\n movement: 4,\n attack: 2,\n range: 1\n },\n Spider: {\n graphics: {\n offset: ex.vec(0, 8 * SCALE.y),\n idle: SpiderIdle\n },\n health: 3,\n movement: 3,\n attack: 1,\n range: 1\n }\n} as const;\n\n","import * as ex from \"excalibur\";\n\nexport class PathNodeComponent extends ex.Component {\n static type = 'path-node' as const;\n readonly type = 'path-node' as const;\n pos = ex.vec(0, 0);\n /**\n * Is this path node traversable by anything at all?\n */\n isWalkable = true;\n /**\n * Is this path node traversable by certain things\n */\n walkableMask: number = -1; // 32-bit mask\n constructor(pos: ex.Vector) {\n super();\n this.pos = pos;\n }\n\n gScore = Infinity;\n hScore = Infinity;\n weight = 1;\n data?: T;\n direction: ex.Vector = ex.Vector.Zero;\n\n connections: PathNodeComponent[] = [];\n\n previousNode: PathNodeComponent | null = null;\n}","import * as ex from 'excalibur';\nimport { PathNodeComponent } from \"./path-node-component\";\n\n\nexport class PathFinder {\n query: ex.Query;\n\n constructor(scene: ex.Scene) {\n this.query = scene.world.queryManager.createQuery([PathNodeComponent.type]);\n }\n\n heuristicWeight = 1;\n heuristic: (start: PathNodeComponent, end: PathNodeComponent) => number = (start: PathNodeComponent, end: PathNodeComponent) => {\n // manhattan distance\n return Math.abs(start.pos.x - end.pos.x) + Math.abs(end.pos.y - end.pos.y);\n\n // euclidean distance\n // return start.pos.distance(end.pos);\n }\n\n private _buildPath(currentNode: PathNodeComponent) {\n const path: PathNodeComponent[] = [];\n while (currentNode.previousNode) {\n path.unshift(currentNode);\n currentNode = currentNode.previousNode;\n }\n path.unshift(currentNode);\n return path;\n }\n\n private _getRangeHelper(cell: PathNodeComponent, accum: PathNodeComponent[], mask: number, range: number) {\n if (range >= 0) {\n accum.push(cell);\n cell.connections\n .filter(node => node.isWalkable && !!(node.walkableMask & mask))\n .forEach(cell => this._getRangeHelper(cell, accum, mask, range - 1))\n }\n }\n\n getRange(start: PathNodeComponent, mask: number, range: number): PathNodeComponent[] {\n let result: PathNodeComponent[] = [];\n this._getRangeHelper(start, result, mask, range);\n // dedup results\n result = result.filter((node, index, nodeArray) => nodeArray.indexOf(node) === index);\n result = result.filter(node => node.isWalkable);\n return result;\n }\n\n /**\n * \n * @param start start node for the path\n * @param end end node for the path\n * @param mask bit mask to test against the node's walkability mask, same bit position means walkable (0b111 & 0b001) = walkable, (0b010 & 0b001) = not walkable\n * @param range \n * @returns \n */\n findPath(start: PathNodeComponent, end: PathNodeComponent, mask: number, range?: PathNodeComponent[]): PathNodeComponent[] {\n const nodes = this.query.getEntities().map(n => n.get(PathNodeComponent)) as PathNodeComponent[];\n nodes.forEach(node => {\n node.gScore = 0;\n node.hScore = 0;\n node.previousNode = null;\n });\n\n start.gScore = 0;\n start.hScore = start.gScore + this.heuristic(start, end) * this.heuristicWeight;\n start.direction = ex.Vector.Down;\n\n const openNodes: PathNodeComponent[] = [start];\n const closedNodes: PathNodeComponent[] = [];\n\n while (openNodes.length > 0) {\n // priority queue, evaluate nodes with the lowest cost\n const priorityNodes = openNodes.sort((a, b) => {\n // tie breaking for aesthetics\n // if (a.hScore === b.hScore) {\n // // console.log(b.direction.normalize());\n // // console.log(a.direction.normalize());\n // console.log(b.direction.dot(ex.Vector.Down) - a.direction.dot(ex.Vector.Down));\n // return b.direction.dot(ex.Vector.Down) - a.direction.dot(ex.Vector.Down);\n // // return b.pos.y - a.pos.y;\n // }\n return a.hScore - b.hScore;\n });\n\n // tie breaking for aesthetics\n const current = priorityNodes[0];\n\n // Done!\n if (current === end) {\n return this._buildPath(current);\n }\n\n // Remove current from the open node set\n const index = openNodes.indexOf(current);\n openNodes.splice(index, 1);\n closedNodes.push(current);\n\n\n // Find the neighbors that haven't been explored\n let neighbors = current.connections.filter(node => {\n return node.isWalkable && !!(node.walkableMask & mask);\n }).filter(node => {\n return closedNodes.indexOf(node) === -1;\n });\n\n // If a range is supplied only look for nodes in there\n if (range) {\n neighbors = neighbors.filter(node => range.indexOf(node) > -1);\n }\n\n // Current direction!\n let currentDirection = current.direction;\n\n neighbors.forEach((node) => {\n if (openNodes.indexOf(node) === -1) {\n node.previousNode = current;\n node.gScore = node.weight + current.gScore;\n node.hScore = node.gScore + this.heuristic(node, end) * this.heuristicWeight;\n\n // Turn penalty if direction is not straight\n const newDirection = node.pos.sub(current.pos).normalize();\n node.direction = newDirection;\n const inline = currentDirection.dot(newDirection);\n if (inline === 0.0) {\n node.hScore += 130.0;\n }\n\n openNodes.push(node);\n }\n });\n }\n\n // error case\n return [];\n }\n}","import * as ex from \"excalibur\";\nimport { Board } from \"./board\";\nimport { Explosion, HeartSpriteSheet, Resources, Smoke, SpiderSpriteSheet } from \"./resources\";\nimport { SCALE, UNIT_CONFIG, UnitConfig, UnitType } from \"./config\";\nimport { Cell } from \"./cell\";\nimport { PathNodeComponent } from \"./path-finding/path-node-component\";\nimport { Player } from \"./player\";\nimport { DustParticles } from \"./dust-particles\";\nimport { DamageManager } from \"./damage-manager\";\nimport { AnimationManager } from \"./animation-manager\";\n\n\n\nexport class Unit extends ex.Actor {\n cell: Cell | null = null;\n unitConfig: UnitConfig;\n moved = false;\n attacked = false;\n anim: ex.Animation;\n health: number;\n damageManager!: DamageManager;\n animationManger!: AnimationManager;\n constructor(x: number, y: number, unitType: UnitType, board: Board, public player: Player) {\n super({\n name: unitType,\n anchor: ex.vec(0, 0),\n z: 2\n });\n this.unitConfig = {...UNIT_CONFIG[unitType]};\n\n this.health = this.unitConfig.health;\n\n this.anim = this.unitConfig.graphics.idle.clone();\n this.anim.scale = SCALE;\n this.graphics.use(this.anim);\n this.graphics.onPostDraw = this.onPostDraw.bind(this);\n\n const cell = board.getCell(x, y);\n if (cell) {\n this.pos = cell.pos.sub(this.unitConfig.graphics.offset);\n cell.addUnit(this);\n }\n }\n\n onInitialize(engine: ex.Engine): void {\n this.damageManager = new DamageManager(engine.currentScene);\n this.animationManger = new AnimationManager(engine.currentScene);\n }\n\n onPostUpdate(): void {\n if (!this.hasActions()) {\n this.anim.tint = ex.Color.Gray;\n } else {\n this.anim.tint = ex.Color.White;\n }\n\n if (this.health <= 0) {\n this.cell?.removeUnit(this);\n this.actions.delay(500).callMethod(() => {\n this.animationManger.playExplosion(this.pos);\n Resources.ExplosionSound.play();\n }).callMethod(() => {\n this.kill();\n });\n }\n }\n\n onPostDraw(ctx: ex.ExcaliburGraphicsContext) {\n if (this.health > 0) {\n const heart = HeartSpriteSheet.getSprite(ex.clamp(this.health, 0, 5), 0);\n if (heart) {\n heart.scale = SCALE;\n heart.draw(ctx, \n 10 * SCALE.x + this.unitConfig.graphics.offset.x,\n 10 * SCALE.y + this.unitConfig.graphics.offset.y\n );\n }\n }\n }\n\n async move(path: PathNodeComponent[]) {\n if (this.cell) {\n this.cell.removeUnit(this);\n }\n let currentCell: Cell | null = null;\n let pathMinusFirst = path.slice(1, path.length);\n for (let node of pathMinusFirst) {\n currentCell = node.owner as Cell;\n const sound = new ex.ActionSequence(this, (ctx) => {\n ctx.delay(200);\n ctx.callMethod(() => {\n Resources.MoveSound.play();\n });\n });\n\n const move = new ex.ActionSequence(this, (ctx) => {\n ctx.easeTo(currentCell!.pos.sub(this.unitConfig.graphics.offset), 300, ex.EasingFunctions.EaseInOutCubic);\n ctx.callMethod(() => {\n DustParticles.pos = this.pos.add(SCALE.scale(16));\n DustParticles.emitParticles(5);\n })\n });\n\n const parallel = new ex.ParallelActions([\n sound,\n move\n ])\n await this.actions.runAction(parallel).toPromise();\n }\n if (currentCell) {\n currentCell.addUnit(this);\n }\n this.moved = true;\n }\n\n reset() {\n this.moved = false;\n this.attacked = false;\n }\n\n canAttack() {\n return this.getPossibleTargets()?.length !== 0 && !this.attacked;\n }\n\n canMove() {\n return !this.moved;\n }\n\n hasActions() {\n return this.canMove() || this.canAttack();\n }\n\n availableActions() {\n let available: ('move' | 'attack')[] = [];\n if (this.canMove()) {\n available.push('move');\n }\n if (this.canAttack()) {\n available.push('attack');\n }\n return available;\n }\n\n pass() {\n this.moved = true;\n this.attacked = true;\n }\n\n getPossibleTargets() {\n if (this.cell) {\n const range = this.cell.board.pathFinder.getRange(this.cell.pathNode, ~this.player.mask, this.unitConfig.range);\n const cellsWithEnemies = range.map(node => node.owner as Cell).filter(cell => {\n if (cell.unit?.player) {\n return cell.unit.player !== this.player;\n }\n return false;\n } );\n return cellsWithEnemies;\n }\n }\n\n async attack(other: Unit) {\n other.health -= this.unitConfig.attack;\n Resources.HitSound.play();\n\n this.damageManager.spawnDamageNumber(other.pos.add(other.unitConfig.graphics.offset).add(ex.vec(16 * SCALE.x, 0)), this.unitConfig.attack);\n await other.actions.blink(200, 200, 5).toPromise();\n this.attacked = true;\n }\n}","import * as ex from 'excalibur';\nimport { Smoke } from './resources';\n\nexport const DustParticles = new ex.ParticleEmitter({\n emitterType: ex.EmitterType.Circle,\n radius: 16,\n minVel: 0,\n maxVel: 20,\n minAngle: 0,\n maxAngle: 6.2,\n isEmitting: false,\n emitRate: 8,\n opacity: 0.75,\n fadeFlag: true,\n particleLife: 1500,\n maxSize: 20,\n minSize: 1,\n startSize: 10,\n endSize: .01,\n acceleration: ex.vec(0, -32),\n particleSprite: Smoke,\n randomRotation: true,\n particleRotationalVelocity: Math.PI,\n});","import * as ex from 'excalibur';\nimport { SCALE } from './config';\n\nexport class Damage extends ex.Actor {\n constructor(pos: ex.Vector, damage: number) {\n super({\n name: 'damage',\n pos,\n z: 10\n });\n\n const font = new ex.Font({\n family: 'notjamslab14',\n size: 16 * SCALE.x,\n unit: ex.FontUnit.Px,\n color: ex.Color.Yellow,\n baseAlign: ex.BaseAlign.Top,\n quality: 4,\n shadow: {\n offset: ex.vec(2, 2).scale(SCALE),\n color: ex.Color.Black\n }\n });\n\n const text = new ex.Text({\n text: damage.toFixed(0),\n font\n });\n this.graphics.add(text);\n }\n}\n\nexport class DamageManager {\n\n constructor(public scene: ex.Scene) {}\n\n spawnDamageNumber(pos: ex.Vector, damage: number) {\n const damageNumber = new Damage(pos, damage);\n damageNumber.actions.easeBy(ex.vec(0, -100), 1000, ex.EasingFunctions.EaseOutCubic).die();\n this.scene.add(damageNumber);\n }\n} ","import * as ex from 'excalibur';\nimport { Explosion } from './resources';\nimport { SCALE } from './config';\n\nexport class AnimationManager {\n constructor(public scene: ex.Scene) {}\n playExplosion(pos: ex.Vector) {\n const explosionActor = new ex.Actor({\n name: 'explosion',\n pos: pos.add(ex.vec(16, 16).scale(SCALE)),\n });\n Explosion.reset();\n Explosion.strategy = ex.AnimationStrategy.End;\n Explosion.scale = SCALE;\n const sub = Explosion.events.on('frame', data => {\n if (data.frameIndex === 7) {\n explosionActor.kill();\n sub.close();\n }\n });\n\n explosionActor.graphics.use(Explosion);\n this.scene.add(explosionActor);\n }\n}","import * as ex from \"excalibur\";\nimport { Board } from \"./board\";\nimport { Player } from \"./player\";\nimport { SelectionManager } from \"./selection-manager\";\nimport { UIManager } from \"./ui-manager\";\nimport { Cell } from \"./cell\";\nimport { Unit } from \"./unit\";\nimport { Resources } from \"./resources\";\n\n\nexport class HumanPlayer extends Player {\n public passed = false;\n private humanMove = new ex.Future();\n\n constructor(name: string, private engine: ex.Engine, private selectionManager: SelectionManager, public uiManger: UIManager, board: Board) {\n super(name, board);\n engine.input.pointers.on('down', this.pointerClick.bind(this));\n engine.input.pointers.on('move', this.pointerMove.bind(this));\n engine.input.keyboard.on('press', this.keyboardDown.bind(this));\n document.body.oncontextmenu = () => false;\n }\n\n keyboardDown(event: ex.KeyEvent) {\n if (!this.active) return;\n this.selectionManager.resetHighlight();\n const currentCursor = this.selectionManager.currentCursor;\n switch(event.key) {\n case ex.Keys.ArrowRight:\n case ex.Keys.D:\n this.selectionManager.showCursor(currentCursor.x + 1, currentCursor.y);\n break;\n case ex.Keys.Left:\n case ex.Keys.A:\n this.selectionManager.showCursor(currentCursor.x - 1, currentCursor.y);\n break;\n case ex.Keys.Up:\n case ex.Keys.W:\n this.selectionManager.showCursor(currentCursor.x, currentCursor.y - 1);\n break;\n case ex.Keys.Down:\n case ex.Keys.D:\n this.selectionManager.showCursor(currentCursor.x, currentCursor.y + 1);\n break;\n case ex.Keys.Enter:\n case ex.Keys.NumpadEnter:\n const cell = this.board.getCell(currentCursor.x, currentCursor.y);\n this.maybeSelectUnit(cell);\n }\n }\n\n async pointerClick(pointer: ex.PointerEvent) {\n if (!this.active) return;\n this.selectionManager.resetHighlight();\n const maybeClickedCell = this.board.getCellByWorldPos(pointer.worldPos);\n\n if (pointer.button === ex.PointerButton.Left) {\n // a unit is currently selected\n if (this.selectionManager.currentUnitSelection) {\n const unit = this.selectionManager.currentUnitSelection;\n if (this.selectionManager.currentSelectionMode === 'move') {\n await this.maybeMove(unit, maybeClickedCell);\n await this.maybeSelectUnit(unit.cell);\n } else {\n await this.maybeAttack(unit, maybeClickedCell);\n await this.maybeSelectUnit(unit.cell);\n }\n // no unit selected, make a selection\n } else {\n this.maybeSelectUnit(maybeClickedCell);\n }\n }\n\n if (pointer.button === ex.PointerButton.Right) {\n this.highlightUnitRange(maybeClickedCell);\n }\n }\n\n pointerMove(pointer: ex.PointerEvent) {\n if (!this.active) return;\n\n const cellBelowPointer = this.board.getCellByWorldPos(pointer.worldPos);\n if (cellBelowPointer) {\n this.selectionManager.showCursor(cellBelowPointer.x, cellBelowPointer.y);\n }\n\n if (!this.selectionManager.currentUnitSelection) return;\n\n this.selectionManager.resetHighlight();\n\n // move\n if (this.selectionManager.currentSelectionMode === 'move') {\n const currentRange = this.selectionManager.findMovementRange(this.selectionManager.currentUnitSelection);\n this.selectionManager.showHighlight(currentRange, 'range');\n\n const destination = this.board.getCellByWorldPos(pointer.worldPos);\n if (destination) {\n const currentPath = this.selectionManager.findPath(destination, currentRange);\n this.selectionManager.showHighlight(currentPath, 'path');\n }\n // attack\n } else {\n const currentRange = this.selectionManager.findAttackRange(this.selectionManager.currentUnitSelection);\n this.selectionManager.showHighlight(currentRange, 'attack');\n\n const destination = this.board.getCellByWorldPos(pointer.worldPos);\n if (destination && this.hasNonPlayerUnit(destination)) {\n this.selectionManager.showHighlight([destination.pathNode], \"path\");\n }\n }\n }\n\n async maybeMove(unit: Unit, destination: Cell | null) {\n if (destination && unit.canMove()) {\n this.active = false;\n Resources.TargetSelectSound.play();\n await this.selectionManager.selectDestinationAndMove(unit, destination);\n this.humanMove.resolve();\n } else {\n this.selectionManager.reset();\n }\n }\n\n async maybeAttack(attacker: Unit, destination: Cell | null) {\n if (destination && attacker.canAttack() && this.hasNonPlayerUnit(destination)) {\n this.active = false;\n const enemyUnit = destination.unit as Unit;\n this.selectionManager.reset();\n await attacker.attack(enemyUnit);\n this.humanMove.resolve();\n } else {\n this.selectionManager.reset();\n }\n }\n\n /**\n * Highlight the range of any unit friendly or not\n * @param cell \n */\n async highlightUnitRange(cell: Cell | null) {\n if (cell?.unit) {\n const unit = cell.unit;\n const rangePlusAttack = this.board.pathFinder.getRange(\n cell.pathNode,\n unit.player.mask,\n unit.unitConfig.movement + 1);\n this.selectionManager.showHighlight(rangePlusAttack, 'attack');\n\n const attack = this.board.pathFinder.getRange(\n cell.pathNode,\n ~unit.player.mask, // don't attack friends!\n unit.unitConfig.range);\n this.selectionManager.showHighlight(attack, 'attack');\n\n const currentRange = this.selectionManager.findMovementRange(unit);\n this.selectionManager.showHighlight(currentRange, 'range');\n } else {\n this.selectionManager.reset();\n }\n }\n\n async maybeSelectUnit(cell: Cell | null) {\n // check if the cell clicked has a unit, then select it\n if (cell?.unit && this.hasPlayerUnitWithActions(cell)) {\n Resources.SelectSound.play();\n\n this.uiManger.showUnitMenu(cell.unit, {\n move: () => {\n this.selectionManager.selectUnit(cell.unit!, 'move');\n },\n attack: () => {\n this.selectionManager.selectUnit(cell.unit!, 'attack');\n },\n pass: () => {\n cell.unit?.pass();\n this.selectionManager.reset();\n this.humanMove.resolve();\n }\n });\n // otherwise clear selection\n } else {\n this.selectionManager.reset();\n }\n }\n\n hasNonPlayerUnit(maybeClickedCell: Cell) {\n return maybeClickedCell && maybeClickedCell.unit && maybeClickedCell.unit.player !== this;\n }\n\n hasPlayerUnitWithActions(maybeClickedCell: Cell) {\n return maybeClickedCell?.unit && maybeClickedCell?.unit?.hasActions() && maybeClickedCell.unit.player === this;\n }\n\n async waitForHumanMove() {\n this.active = true;\n await this.humanMove.promise;\n this.humanMove = new ex.Future();\n\n }\n\n hasMoves() {\n const units = this.board.getUnits()\n .filter(u => u.player === this)\n .filter(u => u.hasActions());\n return units.length > 0 && !this.passed;\n }\n\n override async makeMove(): Promise {\n while(this.hasMoves()) {\n await this.waitForHumanMove();\n }\n return true;\n }\n\n lose() {\n this.active = false;\n const playerUnits = this.board.getUnits().filter(u => u.player instanceof HumanPlayer);\n playerUnits.forEach(u => { \n u.health = 0\n u.cell?.removeUnit(u);\n });\n this.humanMove.resolve();\n }\n}","import { Board } from \"./board\";\n\nexport abstract class Player {\n private static _STARTING_BIT = 0b1 | 0;\n private static _CURRENT_GROUP = Player._STARTING_BIT;\n\n public readonly mask: number;\n public active: boolean = false;\n constructor(public name: string, public board: Board) {\n this.mask = Player._CURRENT_GROUP = (Player._CURRENT_GROUP << 1) | 0;\n }\n\n async turnStart(): Promise {\n this.active = true;\n const units = this.board.getUnits()\n .filter(u => u.player === this);\n units.forEach(u => u.reset());\n }\n\n hasLost() {\n const units = this.board.getUnits()\n .filter(u => u.player === this);\n\n return units.length === 0;\n }\n\n async turnEnd(): Promise {\n this.active = false;\n }\n\n /**\n * \n * @returns true if done with turn, false if more moves to make\n */\n abstract makeMove(): Promise;\n}","import * as ex from 'excalibur';\nimport { Unit } from \"./unit\";\nimport { Board } from \"./board\";\nimport { Cell } from './cell';\nimport { PathNodeComponent } from './path-finding/path-node-component';\nimport { Player } from './player';\n\n\n/**\n * Manages current unit selection\n */\nexport class SelectionManager {\n\n currentPlayer: Player | null = null;\n currentSelectionMode: 'move' | 'attack' = 'move';\n currentUnitSelection: Unit | null = null;\n currentRange: PathNodeComponent[] = [];\n currentPath: PathNodeComponent[] = [];\n\n currentCursor: {x: number, y: number } = {x: 0, y: 0};\n\n constructor(private board: Board) {}\n\n reset() {\n this.resetHighlight();\n this.currentUnitSelection = null;\n this.currentPath = [];\n this.currentRange = [];\n }\n\n showCursor(x: number, y: number) {\n const cell = this.board.getCell(x, y);\n if (cell) {\n this.board.cells.forEach(c => c.toggleCursor(false));\n cell.toggleCursor(true);\n this.currentCursor = { x, y };\n }\n }\n\n selectPlayer(player: Player) {\n this.currentPlayer = player;\n }\n\n selectUnit(unit: Unit, type: 'move' | 'attack') {\n if (unit.player !== this.currentPlayer) return;\n this.currentUnitSelection = unit;\n this.currentSelectionMode = type;\n if (type === 'move') {\n this.currentRange = this.findMovementRange(this.currentUnitSelection);\n this.showHighlight(this.currentRange, 'range');\n } else {\n this.currentRange = this.findAttackRange(this.currentUnitSelection);\n this.showHighlight(this.currentRange, 'attack');\n }\n }\n\n async selectDestinationAndMove(unit: Unit, destination: Cell) {\n if (unit.player !== this.currentPlayer) return;\n const range = this.findMovementRange(unit);\n // select a destination if there is no path\n if (this.currentPath.length === 0) {\n this.currentPath = this.findPath(destination, range);\n }\n // if a valid path was found move!\n if (this.currentPath.length > 1) {\n await unit.move(this.currentPath);\n }\n this.reset();\n }\n\n findAttackRange(unit: Unit): PathNodeComponent[] {\n if (!this.currentUnitSelection) return [];\n if (!unit.cell) return [];\n let range = this.board.pathFinder.getRange(\n unit.cell.pathNode,\n ~unit.player.mask, // don't attack friends!\n this.currentUnitSelection.unitConfig.range);\n return range;\n }\n\n findMovementRange(unit: Unit): PathNodeComponent[] {\n // if (!this.currentUnitSelection) return [];\n if (!unit.cell) return [];\n let range = this.board.pathFinder.getRange(\n unit.cell.pathNode,\n unit.player.mask,\n unit.unitConfig.movement);\n range = range.filter(node => node.isWalkable && !!(node.walkableMask & unit.player.mask))\n return range;\n }\n\n resetHighlight() {\n this.board.cells.forEach(cell => {\n cell.toggleHighlight(false, 'range');\n cell.toggleHighlight(false, 'path');\n cell.toggleHighlight(false, 'attack');\n });\n }\n\n showHighlight(path: PathNodeComponent[], type: 'path' | 'range' | 'attack'): void {\n path.forEach(node => {\n const cell = node.owner as Cell;\n cell.toggleHighlight(true, type);\n });\n }\n\n findPath(destination: Cell, currentRange: PathNodeComponent[]): PathNodeComponent[] {\n if (!this.currentUnitSelection) return [];\n const start = this.currentUnitSelection.cell?.pathNode;\n\n if (destination && !destination.unit && currentRange.includes(destination.pathNode)) {\n const path = this.board.pathFinder.findPath(start!, destination?.pathNode!, this.currentUnitSelection.player.mask, currentRange);\n return path;\n }\n return [];\n }\n}","import * as ex from 'excalibur';\n\nimport './ui-components/unit-menu';\nimport { UnitMenu } from \"./ui-components/unit-menu\";\nimport { SCALE } from \"./config\";\nimport { Unit } from \"./unit\";\nimport { LitElement } from 'lit';\n\nexport interface MenuOptions {\n move: () => any;\n attack: () => any;\n pass: () => any;\n}\n\n/**\n * UI manager create html elements for game UI\n */\nexport class UIManager {\n uiToWorldPos = new Map();\n\n unitMenu: UnitMenu;\n constructor(private engine: ex.Engine) {\n this.unitMenu = new UnitMenu();\n document.body.appendChild(this.unitMenu);\n document.documentElement.style.setProperty('--pixel-conversion', this.worldDistanceToPage(1).toString());\n window.addEventListener('resize', () => {\n document.documentElement.style.setProperty('--pixel-conversion', this.worldDistanceToPage(1).toString());\n\n const menuPos = this.uiToWorldPos.get(this.unitMenu)\n if (menuPos) {\n const pagePos = this.engine.screen.worldToPageCoordinates(menuPos);\n this.unitMenu.left = pagePos.x + this.worldDistanceToPage(32);\n this.unitMenu.top = pagePos.y;\n }\n });\n \n }\n\n worldDistanceToPage(distance: number) {\n const pageOrigin = this.engine.screen.worldToPageCoordinates(ex.Vector.Zero);\n const pageDistance = this.engine.screen.worldToPageCoordinates(ex.vec(distance * SCALE.x, 0)).sub(pageOrigin);\n return pageDistance.x;\n }\n\n showUnitMenu(unit: Unit, options: MenuOptions): UnitMenu {\n const menu = this.unitMenu;\n const pagePos = this.engine.screen.worldToPageCoordinates(unit.pos);\n menu.left = pagePos.x + this.worldDistanceToPage(32);\n menu.top = pagePos.y;\n menu.unit = unit;\n\n const move = () => {\n options.move();\n clearEvents();\n }\n const attack = () => {\n options.attack();\n clearEvents();\n }\n const pass = () => {\n options.pass();\n clearEvents();\n }\n\n menu.addEventListener('move', move);\n menu.addEventListener('attack', attack);\n menu.addEventListener('pass', pass);\n\n const clearEvents = () => {\n menu.removeEventListener('move', move);\n menu.removeEventListener('attack', attack);\n menu.removeEventListener('pass', pass);\n }\n\n menu.clearEvents = clearEvents;\n menu.show();\n menu.focus();\n\n this.uiToWorldPos.set(menu, unit.pos);\n\n return menu;\n }\n\n showNextMission(pos: ex.Vector) {\n\n }\n}","import * as ex from 'excalibur';\n\nimport { LitElement, css, html, nothing } from 'lit';\nimport { customElement, property, query, state } from 'lit/decorators'\nimport {styleMap} from 'lit/directives/style-map'\nimport {classMap} from 'lit/directives/class-map'\nimport { Unit } from '../unit';\n\n@customElement('unit-menu')\nexport class UnitMenu extends LitElement {\n static override styles = css`\n @keyframes fadeIn {\n from {\n opacity: 0;\n transform: translateY(50%);\n }\n to {\n opacity: 1;\n transform: translateY(0%);\n }\n }\n\n @keyframes fadeOut {\n from {\n opacity: 1;\n transform: translateY(0%);\n }\n to {\n opacity: 0;\n transform: translateY(50%);\n }\n }\n\n .menu {\n position: absolute;\n top: 0;\n left: 0;\n width: calc(64px * var(--pixel-conversion));\n display: none;\n opacity: 0;\n flex-direction: column;\n font-size: calc(8px * var(--pixel-conversion));\n background-color: rgba(240, 220, 220, 1);\n\n border: black calc(1px * var(--pixel-conversion)) solid;\n z-index: 1;\n }\n\n .overlay {\n position: fixed;\n left: 0;\n top: 0;\n right: 0;\n bottom: 0;\n }\n\n .show {\n display: flex;\n opacity: 1;\n animation: fadeIn 140ms ease normal;\n }\n\n .hide {\n animation: fadeOut 140ms ease normal;\n }\n\n .options {\n display: flex;\n flex-direction: column;\n }\n\n .title-bar {\n background-color: red;\n width: 100%;\n height: calc(7px * var(--pixel-conversion));\n }\n\n button {\n all: unset;\n padding: calc(2px * var(--pixel-conversion));\n padding-left: calc(4px * var(--pixel-conversion));\n cursor: pointer;\n }\n\n button:focus, button:hover, .focus {\n background-color: rgba(220, 200, 200, 1);\n }\n\n button:active, .active {\n background-color: rgba(250, 240, 240, 1);\n }\n `\n\n @property({type: Number})\n left: number = 0;\n\n @property({type: Number})\n top: number = 0;\n\n @property({type: Number})\n fontSize: number = 0;\n\n @property({type: Number})\n width: number = 0;\n\n @property({attribute: false})\n unit: Unit | null = null;\n\n @property({type: Number})\n pixelConversion: number = 1;\n\n @state()\n private _show: boolean = false;\n\n @query('.menu')\n menuHtml?: HTMLDivElement;\n\n clearEvents: () => any = () => {};\n\n override firstUpdated(): void {\n this.menuHtml?.addEventListener('animationend', evt => {\n if (evt.animationName === 'fadeOut') {\n this._show = false;\n this.menuHtml?.classList.remove('hide');\n this.requestUpdate();\n }\n })\n }\n\n sendEvent(type: string) {\n return () => {\n this.dispatchEvent(new Event(type))\n this.hide();\n this.requestUpdate();\n }\n }\n\n // Debounce needed for mobile for some reason\n // Overlay is also receiving the event\n private _debounce: number = 0;\n show() {\n this._show = true;\n this._debounce = Date.now();\n }\n\n hide() {\n const now = Date.now();\n if (now - this._debounce > 200) {\n this.menuHtml?.classList.add('hide');\n this.clearEvents();\n }\n }\n\n override render() {\n const dismissOverlayHtml = this._show ? html`
` : nothing;\n\n return html`\n ${dismissOverlayHtml}\n
\n
\n
\n \n \n \n
\n
\n `\n }\n}","/******************************************************************************\r\nCopyright (c) Microsoft Corporation.\r\n\r\nPermission to use, copy, modify, and/or distribute this software for any\r\npurpose with or without fee is hereby granted.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH\r\nREGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY\r\nAND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,\r\nINDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM\r\nLOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR\r\nOTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR\r\nPERFORMANCE OF THIS SOFTWARE.\r\n***************************************************************************** */\r\n/* global Reflect, Promise, SuppressedError, Symbol */\r\n\r\nvar extendStatics = function(d, b) {\r\n extendStatics = Object.setPrototypeOf ||\r\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\r\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\r\n return extendStatics(d, b);\r\n};\r\n\r\nexport function __extends(d, b) {\r\n if (typeof b !== \"function\" && b !== null)\r\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\r\n extendStatics(d, b);\r\n function __() { this.constructor = d; }\r\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\r\n}\r\n\r\nexport var __assign = function() {\r\n __assign = Object.assign || function __assign(t) {\r\n for (var s, i = 1, n = arguments.length; i < n; i++) {\r\n s = arguments[i];\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];\r\n }\r\n return t;\r\n }\r\n return __assign.apply(this, arguments);\r\n}\r\n\r\nexport function __rest(s, e) {\r\n var t = {};\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)\r\n t[p] = s[p];\r\n if (s != null && typeof Object.getOwnPropertySymbols === \"function\")\r\n for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {\r\n if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))\r\n t[p[i]] = s[p[i]];\r\n }\r\n return t;\r\n}\r\n\r\nexport function __decorate(decorators, target, key, desc) {\r\n var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;\r\n if (typeof Reflect === \"object\" && typeof Reflect.decorate === \"function\") r = Reflect.decorate(decorators, target, key, desc);\r\n else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;\r\n return c > 3 && r && Object.defineProperty(target, key, r), r;\r\n}\r\n\r\nexport function __param(paramIndex, decorator) {\r\n return function (target, key) { decorator(target, key, paramIndex); }\r\n}\r\n\r\nexport function __esDecorate(ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {\r\n function accept(f) { if (f !== void 0 && typeof f !== \"function\") throw new TypeError(\"Function expected\"); return f; }\r\n var kind = contextIn.kind, key = kind === \"getter\" ? \"get\" : kind === \"setter\" ? \"set\" : \"value\";\r\n var target = !descriptorIn && ctor ? contextIn[\"static\"] ? ctor : ctor.prototype : null;\r\n var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});\r\n var _, done = false;\r\n for (var i = decorators.length - 1; i >= 0; i--) {\r\n var context = {};\r\n for (var p in contextIn) context[p] = p === \"access\" ? {} : contextIn[p];\r\n for (var p in contextIn.access) context.access[p] = contextIn.access[p];\r\n context.addInitializer = function (f) { if (done) throw new TypeError(\"Cannot add initializers after decoration has completed\"); extraInitializers.push(accept(f || null)); };\r\n var result = (0, decorators[i])(kind === \"accessor\" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);\r\n if (kind === \"accessor\") {\r\n if (result === void 0) continue;\r\n if (result === null || typeof result !== \"object\") throw new TypeError(\"Object expected\");\r\n if (_ = accept(result.get)) descriptor.get = _;\r\n if (_ = accept(result.set)) descriptor.set = _;\r\n if (_ = accept(result.init)) initializers.unshift(_);\r\n }\r\n else if (_ = accept(result)) {\r\n if (kind === \"field\") initializers.unshift(_);\r\n else descriptor[key] = _;\r\n }\r\n }\r\n if (target) Object.defineProperty(target, contextIn.name, descriptor);\r\n done = true;\r\n};\r\n\r\nexport function __runInitializers(thisArg, initializers, value) {\r\n var useValue = arguments.length > 2;\r\n for (var i = 0; i < initializers.length; i++) {\r\n value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);\r\n }\r\n return useValue ? value : void 0;\r\n};\r\n\r\nexport function __propKey(x) {\r\n return typeof x === \"symbol\" ? x : \"\".concat(x);\r\n};\r\n\r\nexport function __setFunctionName(f, name, prefix) {\r\n if (typeof name === \"symbol\") name = name.description ? \"[\".concat(name.description, \"]\") : \"\";\r\n return Object.defineProperty(f, \"name\", { configurable: true, value: prefix ? \"\".concat(prefix, \" \", name) : name });\r\n};\r\n\r\nexport function __metadata(metadataKey, metadataValue) {\r\n if (typeof Reflect === \"object\" && typeof Reflect.metadata === \"function\") return Reflect.metadata(metadataKey, metadataValue);\r\n}\r\n\r\nexport function __awaiter(thisArg, _arguments, P, generator) {\r\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\r\n return new (P || (P = Promise))(function (resolve, reject) {\r\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\r\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\r\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\r\n step((generator = generator.apply(thisArg, _arguments || [])).next());\r\n });\r\n}\r\n\r\nexport function __generator(thisArg, body) {\r\n var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;\r\n return g = { next: verb(0), \"throw\": verb(1), \"return\": verb(2) }, typeof Symbol === \"function\" && (g[Symbol.iterator] = function() { return this; }), g;\r\n function verb(n) { return function (v) { return step([n, v]); }; }\r\n function step(op) {\r\n if (f) throw new TypeError(\"Generator is already executing.\");\r\n while (g && (g = 0, op[0] && (_ = 0)), _) try {\r\n if (f = 1, y && (t = op[0] & 2 ? y[\"return\"] : op[0] ? y[\"throw\"] || ((t = y[\"return\"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;\r\n if (y = 0, t) op = [op[0] & 2, t.value];\r\n switch (op[0]) {\r\n case 0: case 1: t = op; break;\r\n case 4: _.label++; return { value: op[1], done: false };\r\n case 5: _.label++; y = op[1]; op = [0]; continue;\r\n case 7: op = _.ops.pop(); _.trys.pop(); continue;\r\n default:\r\n if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }\r\n if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }\r\n if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }\r\n if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }\r\n if (t[2]) _.ops.pop();\r\n _.trys.pop(); continue;\r\n }\r\n op = body.call(thisArg, _);\r\n } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }\r\n if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };\r\n }\r\n}\r\n\r\nexport var __createBinding = Object.create ? (function(o, m, k, k2) {\r\n if (k2 === undefined) k2 = k;\r\n var desc = Object.getOwnPropertyDescriptor(m, k);\r\n if (!desc || (\"get\" in desc ? !m.__esModule : desc.writable || desc.configurable)) {\r\n desc = { enumerable: true, get: function() { return m[k]; } };\r\n }\r\n Object.defineProperty(o, k2, desc);\r\n}) : (function(o, m, k, k2) {\r\n if (k2 === undefined) k2 = k;\r\n o[k2] = m[k];\r\n});\r\n\r\nexport function __exportStar(m, o) {\r\n for (var p in m) if (p !== \"default\" && !Object.prototype.hasOwnProperty.call(o, p)) __createBinding(o, m, p);\r\n}\r\n\r\nexport function __values(o) {\r\n var s = typeof Symbol === \"function\" && Symbol.iterator, m = s && o[s], i = 0;\r\n if (m) return m.call(o);\r\n if (o && typeof o.length === \"number\") return {\r\n next: function () {\r\n if (o && i >= o.length) o = void 0;\r\n return { value: o && o[i++], done: !o };\r\n }\r\n };\r\n throw new TypeError(s ? \"Object is not iterable.\" : \"Symbol.iterator is not defined.\");\r\n}\r\n\r\nexport function __read(o, n) {\r\n var m = typeof Symbol === \"function\" && o[Symbol.iterator];\r\n if (!m) return o;\r\n var i = m.call(o), r, ar = [], e;\r\n try {\r\n while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);\r\n }\r\n catch (error) { e = { error: error }; }\r\n finally {\r\n try {\r\n if (r && !r.done && (m = i[\"return\"])) m.call(i);\r\n }\r\n finally { if (e) throw e.error; }\r\n }\r\n return ar;\r\n}\r\n\r\n/** @deprecated */\r\nexport function __spread() {\r\n for (var ar = [], i = 0; i < arguments.length; i++)\r\n ar = ar.concat(__read(arguments[i]));\r\n return ar;\r\n}\r\n\r\n/** @deprecated */\r\nexport function __spreadArrays() {\r\n for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;\r\n for (var r = Array(s), k = 0, i = 0; i < il; i++)\r\n for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)\r\n r[k] = a[j];\r\n return r;\r\n}\r\n\r\nexport function __spreadArray(to, from, pack) {\r\n if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {\r\n if (ar || !(i in from)) {\r\n if (!ar) ar = Array.prototype.slice.call(from, 0, i);\r\n ar[i] = from[i];\r\n }\r\n }\r\n return to.concat(ar || Array.prototype.slice.call(from));\r\n}\r\n\r\nexport function __await(v) {\r\n return this instanceof __await ? (this.v = v, this) : new __await(v);\r\n}\r\n\r\nexport function __asyncGenerator(thisArg, _arguments, generator) {\r\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n var g = generator.apply(thisArg, _arguments || []), i, q = [];\r\n return i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i;\r\n function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; }\r\n function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }\r\n function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }\r\n function fulfill(value) { resume(\"next\", value); }\r\n function reject(value) { resume(\"throw\", value); }\r\n function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }\r\n}\r\n\r\nexport function __asyncDelegator(o) {\r\n var i, p;\r\n return i = {}, verb(\"next\"), verb(\"throw\", function (e) { throw e; }), verb(\"return\"), i[Symbol.iterator] = function () { return this; }, i;\r\n function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: false } : f ? f(v) : v; } : f; }\r\n}\r\n\r\nexport function __asyncValues(o) {\r\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n var m = o[Symbol.asyncIterator], i;\r\n return m ? m.call(o) : (o = typeof __values === \"function\" ? __values(o) : o[Symbol.iterator](), i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i);\r\n function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }\r\n function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }\r\n}\r\n\r\nexport function __makeTemplateObject(cooked, raw) {\r\n if (Object.defineProperty) { Object.defineProperty(cooked, \"raw\", { value: raw }); } else { cooked.raw = raw; }\r\n return cooked;\r\n};\r\n\r\nvar __setModuleDefault = Object.create ? (function(o, v) {\r\n Object.defineProperty(o, \"default\", { enumerable: true, value: v });\r\n}) : function(o, v) {\r\n o[\"default\"] = v;\r\n};\r\n\r\nexport function __importStar(mod) {\r\n if (mod && mod.__esModule) return mod;\r\n var result = {};\r\n if (mod != null) for (var k in mod) if (k !== \"default\" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);\r\n __setModuleDefault(result, mod);\r\n return result;\r\n}\r\n\r\nexport function __importDefault(mod) {\r\n return (mod && mod.__esModule) ? mod : { default: mod };\r\n}\r\n\r\nexport function __classPrivateFieldGet(receiver, state, kind, f) {\r\n if (kind === \"a\" && !f) throw new TypeError(\"Private accessor was defined without a getter\");\r\n if (typeof state === \"function\" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError(\"Cannot read private member from an object whose class did not declare it\");\r\n return kind === \"m\" ? f : kind === \"a\" ? f.call(receiver) : f ? f.value : state.get(receiver);\r\n}\r\n\r\nexport function __classPrivateFieldSet(receiver, state, value, kind, f) {\r\n if (kind === \"m\") throw new TypeError(\"Private method is not writable\");\r\n if (kind === \"a\" && !f) throw new TypeError(\"Private accessor was defined without a setter\");\r\n if (typeof state === \"function\" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError(\"Cannot write private member to an object whose class did not declare it\");\r\n return (kind === \"a\" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;\r\n}\r\n\r\nexport function __classPrivateFieldIn(state, receiver) {\r\n if (receiver === null || (typeof receiver !== \"object\" && typeof receiver !== \"function\")) throw new TypeError(\"Cannot use 'in' operator on non-object\");\r\n return typeof state === \"function\" ? receiver === state : state.has(receiver);\r\n}\r\n\r\nexport function __addDisposableResource(env, value, async) {\r\n if (value !== null && value !== void 0) {\r\n if (typeof value !== \"object\" && typeof value !== \"function\") throw new TypeError(\"Object expected.\");\r\n var dispose;\r\n if (async) {\r\n if (!Symbol.asyncDispose) throw new TypeError(\"Symbol.asyncDispose is not defined.\");\r\n dispose = value[Symbol.asyncDispose];\r\n }\r\n if (dispose === void 0) {\r\n if (!Symbol.dispose) throw new TypeError(\"Symbol.dispose is not defined.\");\r\n dispose = value[Symbol.dispose];\r\n }\r\n if (typeof dispose !== \"function\") throw new TypeError(\"Object not disposable.\");\r\n env.stack.push({ value: value, dispose: dispose, async: async });\r\n }\r\n else if (async) {\r\n env.stack.push({ async: true });\r\n }\r\n return value;\r\n}\r\n\r\nvar _SuppressedError = typeof SuppressedError === \"function\" ? SuppressedError : function (error, suppressed, message) {\r\n var e = new Error(message);\r\n return e.name = \"SuppressedError\", e.error = error, e.suppressed = suppressed, e;\r\n};\r\n\r\nexport function __disposeResources(env) {\r\n function fail(e) {\r\n env.error = env.hasError ? new _SuppressedError(e, env.error, \"An error was suppressed during disposal.\") : e;\r\n env.hasError = true;\r\n }\r\n function next() {\r\n while (env.stack.length) {\r\n var rec = env.stack.pop();\r\n try {\r\n var result = rec.dispose && rec.dispose.call(rec.value);\r\n if (rec.async) return Promise.resolve(result).then(next, function(e) { fail(e); return next(); });\r\n }\r\n catch (e) {\r\n fail(e);\r\n }\r\n }\r\n if (env.hasError) throw env.error;\r\n }\r\n return next();\r\n}\r\n\r\nexport default {\r\n __extends: __extends,\r\n __assign: __assign,\r\n __rest: __rest,\r\n __decorate: __decorate,\r\n __param: __param,\r\n __metadata: __metadata,\r\n __awaiter: __awaiter,\r\n __generator: __generator,\r\n __createBinding: __createBinding,\r\n __exportStar: __exportStar,\r\n __values: __values,\r\n __read: __read,\r\n __spread: __spread,\r\n __spreadArrays: __spreadArrays,\r\n __spreadArray: __spreadArray,\r\n __await: __await,\r\n __asyncGenerator: __asyncGenerator,\r\n __asyncDelegator: __asyncDelegator,\r\n __asyncValues: __asyncValues,\r\n __makeTemplateObject: __makeTemplateObject,\r\n __importStar: __importStar,\r\n __importDefault: __importDefault,\r\n __classPrivateFieldGet: __classPrivateFieldGet,\r\n __classPrivateFieldSet: __classPrivateFieldSet,\r\n __classPrivateFieldIn: __classPrivateFieldIn,\r\n __addDisposableResource: __addDisposableResource,\r\n __disposeResources: __disposeResources,\r\n};\r\n","import{getCompatibleStyle as t,adoptStyles as s}from\"./css-tag.js\";export{CSSResult,adoptStyles,css,getCompatibleStyle,supportsAdoptingStyleSheets,unsafeCSS}from\"./css-tag.js\";\n/**\n * @license\n * Copyright 2017 Google LLC\n * SPDX-License-Identifier: BSD-3-Clause\n */const{is:i,defineProperty:e,getOwnPropertyDescriptor:r,getOwnPropertyNames:h,getOwnPropertySymbols:o,getPrototypeOf:n}=Object,a=globalThis,c=a.trustedTypes,l=c?c.emptyScript:\"\",p=a.reactiveElementPolyfillSupport,d=(t,s)=>t,u={toAttribute(t,s){switch(s){case Boolean:t=t?l:null;break;case Object:case Array:t=null==t?t:JSON.stringify(t)}return t},fromAttribute(t,s){let i=t;switch(s){case Boolean:i=null!==t;break;case Number:i=null===t?null:Number(t);break;case Object:case Array:try{i=JSON.parse(t)}catch(t){i=null}}return i}},f=(t,s)=>!i(t,s),y={attribute:!0,type:String,converter:u,reflect:!1,hasChanged:f};Symbol.metadata??=Symbol(\"metadata\"),a.litPropertyMetadata??=new WeakMap;class b extends HTMLElement{static addInitializer(t){this._$Ei(),(this.l??=[]).push(t)}static get observedAttributes(){return this.finalize(),this._$Eh&&[...this._$Eh.keys()]}static createProperty(t,s=y){if(s.state&&(s.attribute=!1),this._$Ei(),this.elementProperties.set(t,s),!s.noAccessor){const i=Symbol(),r=this.getPropertyDescriptor(t,i,s);void 0!==r&&e(this.prototype,t,r)}}static getPropertyDescriptor(t,s,i){const{get:e,set:h}=r(this.prototype,t)??{get(){return this[s]},set(t){this[s]=t}};return{get(){return e?.call(this)},set(s){const r=e?.call(this);h.call(this,s),this.requestUpdate(t,r,i)},configurable:!0,enumerable:!0}}static getPropertyOptions(t){return this.elementProperties.get(t)??y}static _$Ei(){if(this.hasOwnProperty(d(\"elementProperties\")))return;const t=n(this);t.finalize(),void 0!==t.l&&(this.l=[...t.l]),this.elementProperties=new Map(t.elementProperties)}static finalize(){if(this.hasOwnProperty(d(\"finalized\")))return;if(this.finalized=!0,this._$Ei(),this.hasOwnProperty(d(\"properties\"))){const t=this.properties,s=[...h(t),...o(t)];for(const i of s)this.createProperty(i,t[i])}const t=this[Symbol.metadata];if(null!==t){const s=litPropertyMetadata.get(t);if(void 0!==s)for(const[t,i]of s)this.elementProperties.set(t,i)}this._$Eh=new Map;for(const[t,s]of this.elementProperties){const i=this._$Eu(t,s);void 0!==i&&this._$Eh.set(i,t)}this.elementStyles=this.finalizeStyles(this.styles)}static finalizeStyles(s){const i=[];if(Array.isArray(s)){const e=new Set(s.flat(1/0).reverse());for(const s of e)i.unshift(t(s))}else void 0!==s&&i.push(t(s));return i}static _$Eu(t,s){const i=s.attribute;return!1===i?void 0:\"string\"==typeof i?i:\"string\"==typeof t?t.toLowerCase():void 0}constructor(){super(),this._$Ep=void 0,this.isUpdatePending=!1,this.hasUpdated=!1,this._$Em=null,this._$Ev()}_$Ev(){this._$Eg=new Promise((t=>this.enableUpdating=t)),this._$AL=new Map,this._$ES(),this.requestUpdate(),this.constructor.l?.forEach((t=>t(this)))}addController(t){(this._$E_??=new Set).add(t),void 0!==this.renderRoot&&this.isConnected&&t.hostConnected?.()}removeController(t){this._$E_?.delete(t)}_$ES(){const t=new Map,s=this.constructor.elementProperties;for(const i of s.keys())this.hasOwnProperty(i)&&(t.set(i,this[i]),delete this[i]);t.size>0&&(this._$Ep=t)}createRenderRoot(){const t=this.shadowRoot??this.attachShadow(this.constructor.shadowRootOptions);return s(t,this.constructor.elementStyles),t}connectedCallback(){this.renderRoot??=this.createRenderRoot(),this.enableUpdating(!0),this._$E_?.forEach((t=>t.hostConnected?.()))}enableUpdating(t){}disconnectedCallback(){this._$E_?.forEach((t=>t.hostDisconnected?.()))}attributeChangedCallback(t,s,i){this._$AK(t,i)}_$EO(t,s){const i=this.constructor.elementProperties.get(t),e=this.constructor._$Eu(t,i);if(void 0!==e&&!0===i.reflect){const r=(void 0!==i.converter?.toAttribute?i.converter:u).toAttribute(s,i.type);this._$Em=t,null==r?this.removeAttribute(e):this.setAttribute(e,r),this._$Em=null}}_$AK(t,s){const i=this.constructor,e=i._$Eh.get(t);if(void 0!==e&&this._$Em!==e){const t=i.getPropertyOptions(e),r=\"function\"==typeof t.converter?{fromAttribute:t.converter}:void 0!==t.converter?.fromAttribute?t.converter:u;this._$Em=e,this[e]=r.fromAttribute(s,t.type),this._$Em=null}}requestUpdate(t,s,i,e=!1,r){if(void 0!==t){if(i??=this.constructor.getPropertyOptions(t),!(i.hasChanged??f)(e?r:this[t],s))return;this.C(t,s,i)}!1===this.isUpdatePending&&(this._$Eg=this._$EP())}C(t,s,i){this._$AL.has(t)||this._$AL.set(t,s),!0===i.reflect&&this._$Em!==t&&(this._$Ej??=new Set).add(t)}async _$EP(){this.isUpdatePending=!0;try{await this._$Eg}catch(t){Promise.reject(t)}const t=this.scheduleUpdate();return null!=t&&await t,!this.isUpdatePending}scheduleUpdate(){return this.performUpdate()}performUpdate(){if(!this.isUpdatePending)return;if(!this.hasUpdated){if(this.renderRoot??=this.createRenderRoot(),this._$Ep){for(const[t,s]of this._$Ep)this[t]=s;this._$Ep=void 0}const t=this.constructor.elementProperties;if(t.size>0)for(const[s,i]of t)!0!==i.wrapped||this._$AL.has(s)||void 0===this[s]||this.C(s,this[s],i)}let t=!1;const s=this._$AL;try{t=this.shouldUpdate(s),t?(this.willUpdate(s),this._$E_?.forEach((t=>t.hostUpdate?.())),this.update(s)):this._$ET()}catch(s){throw t=!1,this._$ET(),s}t&&this._$AE(s)}willUpdate(t){}_$AE(t){this._$E_?.forEach((t=>t.hostUpdated?.())),this.hasUpdated||(this.hasUpdated=!0,this.firstUpdated(t)),this.updated(t)}_$ET(){this._$AL=new Map,this.isUpdatePending=!1}get updateComplete(){return this.getUpdateComplete()}getUpdateComplete(){return this._$Eg}shouldUpdate(t){return!0}update(t){this._$Ej&&=this._$Ej.forEach((t=>this._$EO(t,this[t]))),this._$ET()}updated(t){}firstUpdated(t){}}b.elementStyles=[],b.shadowRootOptions={mode:\"open\"},b[d(\"elementProperties\")]=new Map,b[d(\"finalized\")]=new Map,p?.({ReactiveElement:b}),(a.reactiveElementVersions??=[]).push(\"2.0.2\");export{b as ReactiveElement,u as defaultConverter,f as notEqual};\n//# sourceMappingURL=reactive-element.js.map\n","/**\n * @license\n * Copyright 2017 Google LLC\n * SPDX-License-Identifier: BSD-3-Clause\n */\n\n/**\n * Use this module if you want to create your own base class extending\n * {@link ReactiveElement}.\n * @packageDocumentation\n */\n\nimport {\n getCompatibleStyle,\n adoptStyles,\n CSSResultGroup,\n CSSResultOrNative,\n} from './css-tag.js';\nimport type {\n ReactiveController,\n ReactiveControllerHost,\n} from './reactive-controller.js';\n\n// In the Node build, this import will be injected by Rollup:\n// import {HTMLElement, customElements} from '@lit-labs/ssr-dom-shim';\n\nexport * from './css-tag.js';\nexport type {\n ReactiveController,\n ReactiveControllerHost,\n} from './reactive-controller.js';\n\n/**\n * Removes the `readonly` modifier from properties in the union K.\n *\n * This is a safer way to cast a value to a type with a mutable version of a\n * readonly field, than casting to an interface with the field re-declared\n * because it preserves the type of all the fields and warns on typos.\n */\ntype Mutable = Omit & {\n -readonly [P in keyof Pick]: P extends K ? T[P] : never;\n};\n\n// TODO (justinfagnani): Add `hasOwn` here when we ship ES2022\nconst {\n is,\n defineProperty,\n getOwnPropertyDescriptor,\n getOwnPropertyNames,\n getOwnPropertySymbols,\n getPrototypeOf,\n} = Object;\n\nconst NODE_MODE = false;\n\n// Lets a minifier replace globalThis references with a minified name\nconst global = globalThis;\n\nif (NODE_MODE) {\n global.customElements ??= customElements;\n}\n\nconst DEV_MODE = true;\n\nlet issueWarning: (code: string, warning: string) => void;\n\nconst trustedTypes = (global as unknown as {trustedTypes?: {emptyScript: ''}})\n .trustedTypes;\n\n// Temporary workaround for https://crbug.com/993268\n// Currently, any attribute starting with \"on\" is considered to be a\n// TrustedScript source. Such boolean attributes must be set to the equivalent\n// trusted emptyScript value.\nconst emptyStringForBooleanAttribute = trustedTypes\n ? (trustedTypes.emptyScript as unknown as '')\n : '';\n\nconst polyfillSupport = DEV_MODE\n ? global.reactiveElementPolyfillSupportDevMode\n : global.reactiveElementPolyfillSupport;\n\nif (DEV_MODE) {\n // Ensure warnings are issued only 1x, even if multiple versions of Lit\n // are loaded.\n const issuedWarnings: Set = (global.litIssuedWarnings ??=\n new Set());\n\n // Issue a warning, if we haven't already.\n issueWarning = (code: string, warning: string) => {\n warning += ` See https://lit.dev/msg/${code} for more information.`;\n if (!issuedWarnings.has(warning)) {\n console.warn(warning);\n issuedWarnings.add(warning);\n }\n };\n\n issueWarning(\n 'dev-mode',\n `Lit is in dev mode. Not recommended for production!`\n );\n\n // Issue polyfill support warning.\n if (global.ShadyDOM?.inUse && polyfillSupport === undefined) {\n issueWarning(\n 'polyfill-support-missing',\n `Shadow DOM is being polyfilled via \\`ShadyDOM\\` but ` +\n `the \\`polyfill-support\\` module has not been loaded.`\n );\n }\n}\n\n/**\n * Contains types that are part of the unstable debug API.\n *\n * Everything in this API is not stable and may change or be removed in the future,\n * even on patch releases.\n */\n// eslint-disable-next-line @typescript-eslint/no-namespace\nexport namespace ReactiveUnstable {\n /**\n * When Lit is running in dev mode and `window.emitLitDebugLogEvents` is true,\n * we will emit 'lit-debug' events to window, with live details about the update and render\n * lifecycle. These can be useful for writing debug tooling and visualizations.\n *\n * Please be aware that running with window.emitLitDebugLogEvents has performance overhead,\n * making certain operations that are normally very cheap (like a no-op render) much slower,\n * because we must copy data and dispatch events.\n */\n // eslint-disable-next-line @typescript-eslint/no-namespace\n export namespace DebugLog {\n export type Entry = Update;\n export interface Update {\n kind: 'update';\n }\n }\n}\n\ninterface DebugLoggingWindow {\n // Even in dev mode, we generally don't want to emit these events, as that's\n // another level of cost, so only emit them when DEV_MODE is true _and_ when\n // window.emitLitDebugEvents is true.\n emitLitDebugLogEvents?: boolean;\n}\n\n/**\n * Useful for visualizing and logging insights into what the Lit template system is doing.\n *\n * Compiled out of prod mode builds.\n */\nconst debugLogEvent = DEV_MODE\n ? (event: ReactiveUnstable.DebugLog.Entry) => {\n const shouldEmit = (global as unknown as DebugLoggingWindow)\n .emitLitDebugLogEvents;\n if (!shouldEmit) {\n return;\n }\n global.dispatchEvent(\n new CustomEvent('lit-debug', {\n detail: event,\n })\n );\n }\n : undefined;\n\n/*\n * When using Closure Compiler, JSCompiler_renameProperty(property, object) is\n * replaced at compile time by the munged name for object[property]. We cannot\n * alias this function, so we have to use a small shim that has the same\n * behavior when not compiling.\n */\n/*@__INLINE__*/\nconst JSCompiler_renameProperty =

(\n prop: P,\n _obj: unknown\n): P => prop;\n\n/**\n * Converts property values to and from attribute values.\n */\nexport interface ComplexAttributeConverter {\n /**\n * Called to convert an attribute value to a property\n * value.\n */\n fromAttribute?(value: string | null, type?: TypeHint): Type;\n\n /**\n * Called to convert a property value to an attribute\n * value.\n *\n * It returns unknown instead of string, to be compatible with\n * https://github.com/WICG/trusted-types (and similar efforts).\n */\n toAttribute?(value: Type, type?: TypeHint): unknown;\n}\n\ntype AttributeConverter =\n | ComplexAttributeConverter\n | ((value: string | null, type?: TypeHint) => Type);\n\n/**\n * Defines options for a property accessor.\n */\nexport interface PropertyDeclaration {\n /**\n * When set to `true`, indicates the property is internal private state. The\n * property should not be set by users. When using TypeScript, this property\n * should be marked as `private` or `protected`, and it is also a common\n * practice to use a leading `_` in the name. The property is not added to\n * `observedAttributes`.\n */\n readonly state?: boolean;\n\n /**\n * Indicates how and whether the property becomes an observed attribute.\n * If the value is `false`, the property is not added to `observedAttributes`.\n * If true or absent, the lowercased property name is observed (e.g. `fooBar`\n * becomes `foobar`). If a string, the string value is observed (e.g\n * `attribute: 'foo-bar'`).\n */\n readonly attribute?: boolean | string;\n\n /**\n * Indicates the type of the property. This is used only as a hint for the\n * `converter` to determine how to convert the attribute\n * to/from a property.\n */\n readonly type?: TypeHint;\n\n /**\n * Indicates how to convert the attribute to/from a property. If this value\n * is a function, it is used to convert the attribute value a the property\n * value. If it's an object, it can have keys for `fromAttribute` and\n * `toAttribute`. If no `toAttribute` function is provided and\n * `reflect` is set to `true`, the property value is set directly to the\n * attribute. A default `converter` is used if none is provided; it supports\n * `Boolean`, `String`, `Number`, `Object`, and `Array`. Note,\n * when a property changes and the converter is used to update the attribute,\n * the property is never updated again as a result of the attribute changing,\n * and vice versa.\n */\n readonly converter?: AttributeConverter;\n\n /**\n * Indicates if the property should reflect to an attribute.\n * If `true`, when the property is set, the attribute is set using the\n * attribute name determined according to the rules for the `attribute`\n * property option and the value of the property converted using the rules\n * from the `converter` property option.\n */\n readonly reflect?: boolean;\n\n /**\n * A function that indicates if a property should be considered changed when\n * it is set. The function should take the `newValue` and `oldValue` and\n * return `true` if an update should be requested.\n */\n hasChanged?(value: Type, oldValue: Type): boolean;\n\n /**\n * Indicates whether an accessor will be created for this property. By\n * default, an accessor will be generated for this property that requests an\n * update when set. If this flag is `true`, no accessor will be created, and\n * it will be the user's responsibility to call\n * `this.requestUpdate(propertyName, oldValue)` to request an update when\n * the property changes.\n */\n readonly noAccessor?: boolean;\n\n /**\n * Whether this property is wrapping accessors. This is set by `@property`\n * to control the initial value change and reflection logic.\n *\n * @internal\n */\n wrapped?: boolean;\n}\n\n/**\n * Map of properties to PropertyDeclaration options. For each property an\n * accessor is made, and the property is processed according to the\n * PropertyDeclaration options.\n */\nexport interface PropertyDeclarations {\n readonly [key: string]: PropertyDeclaration;\n}\n\ntype PropertyDeclarationMap = Map;\n\ntype AttributeMap = Map;\n\n/**\n * A Map of property keys to values.\n *\n * Takes an optional type parameter T, which when specified as a non-any,\n * non-unknown type, will make the Map more strongly-typed, associating the map\n * keys with their corresponding value type on T.\n *\n * Use `PropertyValues` when overriding ReactiveElement.update() and\n * other lifecycle methods in order to get stronger type-checking on keys\n * and values.\n */\n// This type is conditional so that if the parameter T is not specified, or\n// is `any`, the type will include `Map`. Since T is not\n// given in the uses of PropertyValues in this file, all uses here fallback to\n// meaning `Map`, but if a developer uses\n// `PropertyValues` (or any other value for T) they will get a\n// strongly-typed Map type.\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type PropertyValues = T extends object\n ? PropertyValueMap\n : Map;\n\n/**\n * Do not use, instead prefer {@linkcode PropertyValues}.\n */\n// This type must be exported such that JavaScript generated by the Google\n// Closure Compiler can import a type reference.\nexport interface PropertyValueMap extends Map {\n get(k: K): T[K] | undefined;\n set(key: K, value: T[K]): this;\n has(k: K): boolean;\n delete(k: K): boolean;\n}\n\nexport const defaultConverter: ComplexAttributeConverter = {\n toAttribute(value: unknown, type?: unknown): unknown {\n switch (type) {\n case Boolean:\n value = value ? emptyStringForBooleanAttribute : null;\n break;\n case Object:\n case Array:\n // if the value is `null` or `undefined` pass this through\n // to allow removing/no change behavior.\n value = value == null ? value : JSON.stringify(value);\n break;\n }\n return value;\n },\n\n fromAttribute(value: string | null, type?: unknown) {\n let fromValue: unknown = value;\n switch (type) {\n case Boolean:\n fromValue = value !== null;\n break;\n case Number:\n fromValue = value === null ? null : Number(value);\n break;\n case Object:\n case Array:\n // Do *not* generate exception when invalid JSON is set as elements\n // don't normally complain on being mis-configured.\n // TODO(sorvell): Do generate exception in *dev mode*.\n try {\n // Assert to adhere to Bazel's \"must type assert JSON parse\" rule.\n fromValue = JSON.parse(value!) as unknown;\n } catch (e) {\n fromValue = null;\n }\n break;\n }\n return fromValue;\n },\n};\n\nexport interface HasChanged {\n (value: unknown, old: unknown): boolean;\n}\n\n/**\n * Change function that returns true if `value` is different from `oldValue`.\n * This method is used as the default for a property's `hasChanged` function.\n */\nexport const notEqual: HasChanged = (value: unknown, old: unknown): boolean =>\n !is(value, old);\n\nconst defaultPropertyDeclaration: PropertyDeclaration = {\n attribute: true,\n type: String,\n converter: defaultConverter,\n reflect: false,\n hasChanged: notEqual,\n};\n\n/**\n * A string representing one of the supported dev mode warning categories.\n */\nexport type WarningKind =\n | 'change-in-update'\n | 'migration'\n | 'async-perform-update';\n\nexport type Initializer = (element: ReactiveElement) => void;\n\n// Temporary, until google3 is on TypeScript 5.2\ndeclare global {\n interface SymbolConstructor {\n readonly metadata: unique symbol;\n }\n}\n\n// Ensure metadata is enabled. TypeScript does not polyfill\n// Symbol.metadata, so we must ensure that it exists.\n(Symbol as {metadata: symbol}).metadata ??= Symbol('metadata');\n\ndeclare global {\n // This is public global API, do not change!\n // eslint-disable-next-line no-var\n var litPropertyMetadata: WeakMap<\n object,\n Map\n >;\n}\n\n// Map from a class's metadata object to property options\n// Note that we must use nullish-coalescing assignment so that we only use one\n// map even if we load multiple version of this module.\nglobal.litPropertyMetadata ??= new WeakMap<\n object,\n Map\n>();\n\n/**\n * Base element class which manages element properties and attributes. When\n * properties change, the `update` method is asynchronously called. This method\n * should be supplied by subclasses to render updates as desired.\n * @noInheritDoc\n */\nexport abstract class ReactiveElement\n // In the Node build, this `extends` clause will be substituted with\n // `(globalThis.HTMLElement ?? HTMLElement)`.\n //\n // This way, we will first prefer any global `HTMLElement` polyfill that the\n // user has assigned, and then fall back to the `HTMLElement` shim which has\n // been imported (see note at the top of this file about how this import is\n // generated by Rollup). Note that the `HTMLElement` variable has been\n // shadowed by this import, so it no longer refers to the global.\n extends HTMLElement\n implements ReactiveControllerHost\n{\n // Note: these are patched in only in DEV_MODE.\n /**\n * Read or set all the enabled warning categories for this class.\n *\n * This property is only used in development builds.\n *\n * @nocollapse\n * @category dev-mode\n */\n static enabledWarnings?: WarningKind[];\n\n /**\n * Enable the given warning category for this class.\n *\n * This method only exists in development builds, so it should be accessed\n * with a guard like:\n *\n * ```ts\n * // Enable for all ReactiveElement subclasses\n * ReactiveElement.enableWarning?.('migration');\n *\n * // Enable for only MyElement and subclasses\n * MyElement.enableWarning?.('migration');\n * ```\n *\n * @nocollapse\n * @category dev-mode\n */\n static enableWarning?: (warningKind: WarningKind) => void;\n\n /**\n * Disable the given warning category for this class.\n *\n * This method only exists in development builds, so it should be accessed\n * with a guard like:\n *\n * ```ts\n * // Disable for all ReactiveElement subclasses\n * ReactiveElement.disableWarning?.('migration');\n *\n * // Disable for only MyElement and subclasses\n * MyElement.disableWarning?.('migration');\n * ```\n *\n * @nocollapse\n * @category dev-mode\n */\n static disableWarning?: (warningKind: WarningKind) => void;\n\n /**\n * Adds an initializer function to the class that is called during instance\n * construction.\n *\n * This is useful for code that runs against a `ReactiveElement`\n * subclass, such as a decorator, that needs to do work for each\n * instance, such as setting up a `ReactiveController`.\n *\n * ```ts\n * const myDecorator = (target: typeof ReactiveElement, key: string) => {\n * target.addInitializer((instance: ReactiveElement) => {\n * // This is run during construction of the element\n * new MyController(instance);\n * });\n * }\n * ```\n *\n * Decorating a field will then cause each instance to run an initializer\n * that adds a controller:\n *\n * ```ts\n * class MyElement extends LitElement {\n * @myDecorator foo;\n * }\n * ```\n *\n * Initializers are stored per-constructor. Adding an initializer to a\n * subclass does not add it to a superclass. Since initializers are run in\n * constructors, initializers will run in order of the class hierarchy,\n * starting with superclasses and progressing to the instance's class.\n *\n * @nocollapse\n */\n static addInitializer(initializer: Initializer) {\n this.__prepare();\n (this._initializers ??= []).push(initializer);\n }\n\n static _initializers?: Initializer[];\n\n /*\n * Due to closure compiler ES6 compilation bugs, @nocollapse is required on\n * all static methods and properties with initializers. Reference:\n * - https://github.com/google/closure-compiler/issues/1776\n */\n\n /**\n * Maps attribute names to properties; for example `foobar` attribute to\n * `fooBar` property. Created lazily on user subclasses when finalizing the\n * class.\n * @nocollapse\n */\n private static __attributeToPropertyMap: AttributeMap;\n\n /**\n * Marks class as having been finalized, which includes creating properties\n * from `static properties`, but does *not* include all properties created\n * from decorators.\n * @nocollapse\n */\n protected static finalized: true | undefined;\n\n /**\n * Memoized list of all element properties, including any superclass\n * properties. Created lazily on user subclasses when finalizing the class.\n *\n * @nocollapse\n * @category properties\n */\n static elementProperties: PropertyDeclarationMap;\n\n /**\n * User-supplied object that maps property names to `PropertyDeclaration`\n * objects containing options for configuring reactive properties. When\n * a reactive property is set the element will update and render.\n *\n * By default properties are public fields, and as such, they should be\n * considered as primarily settable by element users, either via attribute or\n * the property itself.\n *\n * Generally, properties that are changed by the element should be private or\n * protected fields and should use the `state: true` option. Properties\n * marked as `state` do not reflect from the corresponding attribute\n *\n * However, sometimes element code does need to set a public property. This\n * should typically only be done in response to user interaction, and an event\n * should be fired informing the user; for example, a checkbox sets its\n * `checked` property when clicked and fires a `changed` event. Mutating\n * public properties should typically not be done for non-primitive (object or\n * array) properties. In other cases when an element needs to manage state, a\n * private property set with the `state: true` option should be used. When\n * needed, state properties can be initialized via public properties to\n * facilitate complex interactions.\n * @nocollapse\n * @category properties\n */\n static properties: PropertyDeclarations;\n\n /**\n * Memoized list of all element styles.\n * Created lazily on user subclasses when finalizing the class.\n * @nocollapse\n * @category styles\n */\n static elementStyles: Array = [];\n\n /**\n * Array of styles to apply to the element. The styles should be defined\n * using the {@linkcode css} tag function, via constructible stylesheets, or\n * imported from native CSS module scripts.\n *\n * Note on Content Security Policy:\n *\n * Element styles are implemented with `