diff --git a/src/Game/NPC/NPCController/NPCController.js b/src/Game/NPC/NPCController/NPCController.js index 2d2c0ac..5a3783b 100644 --- a/src/Game/NPC/NPCController/NPCController.js +++ b/src/Game/NPC/NPCController/NPCController.js @@ -35,20 +35,22 @@ export class NPCController extends GameObject { let pf = new PathFinder(); let nPath = pf.search(new PointInt2D(this.controlledNPC.worldPosition.getX(), this.controlledNPC.worldPosition.getY()), position); - if(!nPath) + if(nPath.error) { console.log("failed"); callback("failed"); + console.log(nPath); return; } - else if (nPath.path.length < 2) + else if (nPath.result.path.length < 2) { console.log("success"); callback("success"); + console.log(nPath); return; } - for (let i = nPath.path.length-1; i > 0; i--) { - this.navigationPathQueue.push(nPath.path[i]); + for (let i = nPath.result.path.length-1; i > 0; i--) { + this.navigationPathQueue.push(nPath.result.path[i]); } this.navigationCallback = callback; this.navigationInProgress = true; diff --git a/src/Game/NPC/NPCObserver/NPCObserver.js b/src/Game/NPC/NPCObserver/NPCObserver.js new file mode 100644 index 0000000..533a050 --- /dev/null +++ b/src/Game/NPC/NPCObserver/NPCObserver.js @@ -0,0 +1,2 @@ + +// export class NPCObserver \ No newline at end of file diff --git a/src/Game/Utils/PathFinding.util.js b/src/Game/Utils/PathFinding.util.js index f81d6b7..8d124b5 100644 --- a/src/Game/Utils/PathFinding.util.js +++ b/src/Game/Utils/PathFinding.util.js @@ -38,6 +38,29 @@ export class NavigationPath { } }; +export class NavigationResult +{ + /** + * @type Boolean + */ + error; + /** + * @type String + */ + errorText; + /** + * @type NavigationPath | undefined + */ + result; + + constructor(error, errorText, result) + { + this.error = error; + this.errorText = errorText; + this.result = result; + } +}; + export class PathFinder { /** * @type Array @@ -90,30 +113,31 @@ export class PathFinder { //find node with min f score //better to rewrite it to priority queue for (let i = 0; i < this._openSet.length; i++) { - if(!this._openSet[i]){ - return undefined; - } + // if(!this._openSet[i] || !this._openSet[minFScoreNodeIndex]){ + // return new NavigationResult(true, "Failed to access element in openSet", undefined); + // } if (this._openSet[i].fScore < this._openSet[minFScoreNodeIndex].fScore) minFScoreNodeIndex = i; } //wow! node is found and set!! currentNode = this._openSet[minFScoreNodeIndex]; + minFScoreNodeIndex = 0; if (PointInt2D.isEqual(currentNode.position, this._goal)) { //wow!!! we have found an end of the path!!! this is so cool!!! // console.log(cameFrom); - return new NavigationPath(this._reconstructPath(cameFrom, currentNode)); //return something weird stuff + return new NavigationResult(false, "", new NavigationPath(this._reconstructPath(cameFrom, currentNode))); //return something weird stuff } //and now we must delete this node... what a sad situation... this._openSet.splice(minFScoreNodeIndex, 1); - //but wait! we add it to closed set! nice!!! (why we are doing this??? idk... okay) + //but wait! we add it to closed set! nice!!! this._closedSet.push(currentNode); /** * @type Array */ let currentNeighbors = this._getNeighbors(currentNode.position); - if(!currentNeighbors) return undefined; + // if(!currentNeighbors) return undefined; // console.log(currentNeighbors); for (const neighbor of currentNeighbors) { this._closedSet.push(neighbor); @@ -136,7 +160,7 @@ export class PathFinder { } } - return undefined; + return new NavigationResult(false, "", new NavigationPath()); } /** @@ -167,37 +191,46 @@ export class PathFinder { /** * @type SceneObject */ - let currentTile = getTileAt(root.getX(), root.getY() + BC_TERRAIN_SETTINGS.totalSize, ChunkStorageTypes.TYPE_TERRAIN); - if(!currentTile) return undefined; - // currentTile.drawObject.tint = 0xff0000; - let node = new PathFinderNode(new PointInt2D(currentTile.worldPosition.getX(), currentTile.worldPosition.getY()), 1e16, 1e16, currentTile.props.navigationCost); //north - if (!this._existsInClosedSet(node)) { - neighbors.push(node); + let currentTile = getTileAt(root.getX(), root.getY() + BC_TERRAIN_SETTINGS.totalSize, ChunkStorageTypes.TYPE_TERRAIN); + let node; + if(currentTile) + { + // currentTile.drawObject.tint = 0xff0000; + node = new PathFinderNode(new PointInt2D(currentTile.worldPosition.getX(), currentTile.worldPosition.getY()), 1e16, 1e16, currentTile.props.navigationCost); + if (!this._existsInClosedSet(node)) { + neighbors.push(node); + } } //south currentTile = getTileAt(root.getX(), root.getY() - BC_TERRAIN_SETTINGS.totalSize, ChunkStorageTypes.TYPE_TERRAIN); - if(!currentTile) return undefined; - // currentTile.drawObject.tint = 0xff0000; - node = new PathFinderNode(new PointInt2D(currentTile.worldPosition.getX(), currentTile.worldPosition.getY()), 1e16, 1e16, currentTile.props.navigationCost); - if (!this._existsInClosedSet(node)) { - neighbors.push(node); + if(currentTile) + { + // currentTile.drawObject.tint = 0xff0000; + node = new PathFinderNode(new PointInt2D(currentTile.worldPosition.getX(), currentTile.worldPosition.getY()), 1e16, 1e16, currentTile.props.navigationCost); + if (!this._existsInClosedSet(node)) { + neighbors.push(node); + } } //east currentTile = getTileAt(root.getX() + BC_TERRAIN_SETTINGS.totalSize, root.getY(), ChunkStorageTypes.TYPE_TERRAIN); - if(!currentTile) return undefined; - // currentTile.drawObject.tint = 0xff0000; - node = new PathFinderNode(new PointInt2D(currentTile.worldPosition.getX(), currentTile.worldPosition.getY()), 1e16, 1e16, currentTile.props.navigationCost); - if (!this._existsInClosedSet(node)) { - neighbors.push(node); + if(currentTile) + { + // currentTile.drawObject.tint = 0xff0000; + node = new PathFinderNode(new PointInt2D(currentTile.worldPosition.getX(), currentTile.worldPosition.getY()), 1e16, 1e16, currentTile.props.navigationCost); + if (!this._existsInClosedSet(node)) { + neighbors.push(node); + } } //west currentTile = getTileAt(root.getX() - BC_TERRAIN_SETTINGS.totalSize, root.getY(), ChunkStorageTypes.TYPE_TERRAIN); - if(!currentTile) return undefined; - // currentTile.drawObject.tint = 0xff0000; - node = new PathFinderNode(new PointInt2D(currentTile.worldPosition.getX(), currentTile.worldPosition.getY()), 1e16, 1e16, currentTile.props.navigationCost); - if (!this._existsInClosedSet(node)) { - neighbors.push(node); + if(currentTile) + { + // currentTile.drawObject.tint = 0xff0000; + node = new PathFinderNode(new PointInt2D(currentTile.worldPosition.getX(), currentTile.worldPosition.getY()), 1e16, 1e16, currentTile.props.navigationCost); + if (!this._existsInClosedSet(node)) { + neighbors.push(node); + } } return neighbors; diff --git a/src/pixi/pixi.mjs b/src/pixi/pixi.mjs index df8f568..82d55af 100644 --- a/src/pixi/pixi.mjs +++ b/src/pixi/pixi.mjs @@ -1,49 +1,21935 @@ /*! - * PixiJS - v8.0.5 - * Compiled Tue, 02 Apr 2024 16:14:29 UTC + * PixiJS - v8.1.0 + * Compiled Tue, 09 Apr 2024 13:40:17 UTC * * PixiJS is licensed under the MIT License. * http://www.opensource.org/licenses/mit-license - */var Yx=Object.defineProperty,Kx=Object.defineProperties,qx=Object.getOwnPropertyDescriptors,sl=Object.getOwnPropertySymbols,Zx=Object.prototype.hasOwnProperty,Qx=Object.prototype.propertyIsEnumerable,il=(r,t,e)=>t in r?Yx(r,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):r[t]=e,nl=(r,t)=>{for(var e in t||(t={}))Zx.call(t,e)&&il(r,e,t[e]);if(sl)for(var e of sl(t))Qx.call(t,e)&&il(r,e,t[e]);return r},Jx=(r,t)=>Kx(r,qx(t)),v=(r=>(r.Application="application",r.WebGLPipes="webgl-pipes",r.WebGLPipesAdaptor="webgl-pipes-adaptor",r.WebGLSystem="webgl-system",r.WebGPUPipes="webgpu-pipes",r.WebGPUPipesAdaptor="webgpu-pipes-adaptor",r.WebGPUSystem="webgpu-system",r.CanvasSystem="canvas-system",r.CanvasPipesAdaptor="canvas-pipes-adaptor",r.CanvasPipes="canvas-pipes",r.Asset="asset",r.LoadParser="load-parser",r.ResolveParser="resolve-parser",r.CacheParser="cache-parser",r.DetectionParser="detection-parser",r.MaskEffect="mask-effect",r.BlendMode="blend-mode",r.TextureSource="texture-source",r.Environment="environment",r))(v||{});const Ui=r=>{if(typeof r=="function"||typeof r=="object"&&r.extension){const t=typeof r.extension!="object"?{type:r.extension}:r.extension;r=Jx(nl({},t),{ref:r})}if(typeof r=="object")r=nl({},r);else throw new Error("Invalid extension type");return typeof r.type=="string"&&(r.type=[r.type]),r},rr=(r,t)=>{var e;return(e=Ui(r).priority)!=null?e:t},D={_addHandlers:{},_removeHandlers:{},_queue:{},remove(...r){return r.map(Ui).forEach(t=>{t.type.forEach(e=>{var s,i;return(i=(s=this._removeHandlers)[e])==null?void 0:i.call(s,t)})}),this},add(...r){return r.map(Ui).forEach(t=>{t.type.forEach(e=>{var s,i;const n=this._addHandlers,o=this._queue;n[e]?(i=n[e])==null||i.call(n,t):(o[e]=o[e]||[],(s=o[e])==null||s.push(t))})}),this},handle(r,t,e){var s;const i=this._addHandlers,n=this._removeHandlers;i[r]=t,n[r]=e;const o=this._queue;return o[r]&&((s=o[r])==null||s.forEach(a=>t(a)),delete o[r]),this},handleByMap(r,t){return this.handle(r,e=>{e.name&&(t[e.name]=e.ref)},e=>{e.name&&delete t[e.name]})},handleByNamedList(r,t,e=-1){return this.handle(r,s=>{t.findIndex(i=>i.name===s.name)>=0||(t.push({name:s.name,value:s.ref}),t.sort((i,n)=>rr(n.value,e)-rr(i.value,e)))},s=>{const i=t.findIndex(n=>n.name===s.name);i!==-1&&t.splice(i,1)})},handleByList(r,t,e=-1){return this.handle(r,s=>{t.includes(s.ref)||(t.push(s.ref),t.sort((i,n)=>rr(n,e)-rr(i,e)))},s=>{const i=t.indexOf(s.ref);i!==-1&&t.splice(i,1)})}};var NA=typeof globalThis!="undefined"?globalThis:typeof window!="undefined"?window:typeof global!="undefined"?global:typeof self!="undefined"?self:{};function ki(r){return r&&r.__esModule&&Object.prototype.hasOwnProperty.call(r,"default")?r.default:r}function HA(r){return r&&Object.prototype.hasOwnProperty.call(r,"default")?r.default:r}function XA(r){return r&&Object.prototype.hasOwnProperty.call(r,"default")&&Object.keys(r).length===1?r.default:r}function zA(r){if(r.__esModule)return r;var t=r.default;if(typeof t=="function"){var e=function s(){return this instanceof s?Reflect.construct(t,arguments,this.constructor):t.apply(this,arguments)};e.prototype=t.prototype}else e={};return Object.defineProperty(e,"__esModule",{value:!0}),Object.keys(r).forEach(function(s){var i=Object.getOwnPropertyDescriptor(r,s);Object.defineProperty(e,s,i.get?i:{enumerable:!0,get:function(){return r[s]}})}),e}var Li={exports:{}},jA=Li.exports;(function(r){"use strict";var t=Object.prototype.hasOwnProperty,e="~";function s(){}Object.create&&(s.prototype=Object.create(null),new s().__proto__||(e=!1));function i(u,l,h){this.fn=u,this.context=l,this.once=h||!1}function n(u,l,h,c,d){if(typeof h!="function")throw new TypeError("The listener must be a function");var p=new i(h,c||u,d),f=e?e+l:l;return u._events[f]?u._events[f].fn?u._events[f]=[u._events[f],p]:u._events[f].push(p):(u._events[f]=p,u._eventsCount++),u}function o(u,l){--u._eventsCount===0?u._events=new s:delete u._events[l]}function a(){this._events=new s,this._eventsCount=0}a.prototype.eventNames=function(){var l=[],h,c;if(this._eventsCount===0)return l;for(c in h=this._events)t.call(h,c)&&l.push(e?c.slice(1):c);return Object.getOwnPropertySymbols?l.concat(Object.getOwnPropertySymbols(h)):l},a.prototype.listeners=function(l){var h=e?e+l:l,c=this._events[h];if(!c)return[];if(c.fn)return[c.fn];for(var d=0,p=c.length,f=new Array(p);d0:typeof r=="number"},nt=function(r,t,e){return t===void 0&&(t=0),e===void 0&&(e=Math.pow(10,t)),Math.round(e*r)/e+0},Et=function(r,t,e){return t===void 0&&(t=0),e===void 0&&(e=1),r>e?e:r>t?r:t},ol=function(r){return(r=isFinite(r)?r%360:0)>0?r:r+360},al=function(r){return{r:Et(r.r,0,255),g:Et(r.g,0,255),b:Et(r.b,0,255),a:Et(r.a)}},$i=function(r){return{r:nt(r.r),g:nt(r.g),b:nt(r.b),a:nt(r.a,3)}},rb=/^#([0-9a-f]{3,8})$/i,Qr=function(r){var t=r.toString(16);return t.length<2?"0"+t:t},ul=function(r){var t=r.r,e=r.g,s=r.b,i=r.a,n=Math.max(t,e,s),o=n-Math.min(t,e,s),a=o?n===t?(e-s)/o:n===e?2+(s-t)/o:4+(t-e)/o:0;return{h:60*(a<0?a+6:a),s:n?o/n*100:0,v:n/255*100,a:i}},ll=function(r){var t=r.h,e=r.s,s=r.v,i=r.a;t=t/360*6,e/=100,s/=100;var n=Math.floor(t),o=s*(1-e),a=s*(1-(t-n)*e),u=s*(1-(1-t+n)*e),l=n%6;return{r:255*[s,a,o,o,u,s][l],g:255*[u,s,s,a,o,o][l],b:255*[o,o,u,s,s,a][l],a:i}},hl=function(r){return{h:ol(r.h),s:Et(r.s,0,100),l:Et(r.l,0,100),a:Et(r.a)}},cl=function(r){return{h:nt(r.h),s:nt(r.s),l:nt(r.l),a:nt(r.a,3)}},dl=function(r){return ll((e=(t=r).s,{h:t.h,s:(e*=((s=t.l)<50?s:100-s)/100)>0?2*e/(s+e)*100:0,v:s+e,a:t.a}));var t,e,s},sr=function(r){return{h:(t=ul(r)).h,s:(i=(200-(e=t.s))*(s=t.v)/100)>0&&i<200?e*s/100/(i<=100?i:200-i)*100:0,l:i/2,a:t.a};var t,e,s,i},sb=/^hsla?\(\s*([+-]?\d*\.?\d+)(deg|rad|grad|turn)?\s*,\s*([+-]?\d*\.?\d+)%\s*,\s*([+-]?\d*\.?\d+)%\s*(?:,\s*([+-]?\d*\.?\d+)(%)?\s*)?\)$/i,ib=/^hsla?\(\s*([+-]?\d*\.?\d+)(deg|rad|grad|turn)?\s+([+-]?\d*\.?\d+)%\s+([+-]?\d*\.?\d+)%\s*(?:\/\s*([+-]?\d*\.?\d+)(%)?\s*)?\)$/i,nb=/^rgba?\(\s*([+-]?\d*\.?\d+)(%)?\s*,\s*([+-]?\d*\.?\d+)(%)?\s*,\s*([+-]?\d*\.?\d+)(%)?\s*(?:,\s*([+-]?\d*\.?\d+)(%)?\s*)?\)$/i,ob=/^rgba?\(\s*([+-]?\d*\.?\d+)(%)?\s+([+-]?\d*\.?\d+)(%)?\s+([+-]?\d*\.?\d+)(%)?\s*(?:\/\s*([+-]?\d*\.?\d+)(%)?\s*)?\)$/i,Ni={string:[[function(r){var t=rb.exec(r);return t?(r=t[1]).length<=4?{r:parseInt(r[0]+r[0],16),g:parseInt(r[1]+r[1],16),b:parseInt(r[2]+r[2],16),a:r.length===4?nt(parseInt(r[3]+r[3],16)/255,2):1}:r.length===6||r.length===8?{r:parseInt(r.substr(0,2),16),g:parseInt(r.substr(2,2),16),b:parseInt(r.substr(4,2),16),a:r.length===8?nt(parseInt(r.substr(6,2),16)/255,2):1}:null:null},"hex"],[function(r){var t=nb.exec(r)||ob.exec(r);return t?t[2]!==t[4]||t[4]!==t[6]?null:al({r:Number(t[1])/(t[2]?100/255:1),g:Number(t[3])/(t[4]?100/255:1),b:Number(t[5])/(t[6]?100/255:1),a:t[7]===void 0?1:Number(t[7])/(t[8]?100:1)}):null},"rgb"],[function(r){var t=sb.exec(r)||ib.exec(r);if(!t)return null;var e,s,i=hl({h:(e=t[1],s=t[2],s===void 0&&(s="deg"),Number(e)*(eb[s]||1)),s:Number(t[3]),l:Number(t[4]),a:t[5]===void 0?1:Number(t[5])/(t[6]?100:1)});return dl(i)},"hsl"]],object:[[function(r){var t=r.r,e=r.g,s=r.b,i=r.a,n=i===void 0?1:i;return Nt(t)&&Nt(e)&&Nt(s)?al({r:Number(t),g:Number(e),b:Number(s),a:Number(n)}):null},"rgb"],[function(r){var t=r.h,e=r.s,s=r.l,i=r.a,n=i===void 0?1:i;if(!Nt(t)||!Nt(e)||!Nt(s))return null;var o=hl({h:Number(t),s:Number(e),l:Number(s),a:Number(n)});return dl(o)},"hsl"],[function(r){var t=r.h,e=r.s,s=r.v,i=r.a,n=i===void 0?1:i;if(!Nt(t)||!Nt(e)||!Nt(s))return null;var o=function(a){return{h:ol(a.h),s:Et(a.s,0,100),v:Et(a.v,0,100),a:Et(a.a)}}({h:Number(t),s:Number(e),v:Number(s),a:Number(n)});return ll(o)},"hsv"]]},pl=function(r,t){for(var e=0;e=.5},r.prototype.toHex=function(){return t=$i(this.rgba),e=t.r,s=t.g,i=t.b,o=(n=t.a)<1?Qr(nt(255*n)):"","#"+Qr(e)+Qr(s)+Qr(i)+o;var t,e,s,i,n,o},r.prototype.toRgb=function(){return $i(this.rgba)},r.prototype.toRgbString=function(){return t=$i(this.rgba),e=t.r,s=t.g,i=t.b,(n=t.a)<1?"rgba("+e+", "+s+", "+i+", "+n+")":"rgb("+e+", "+s+", "+i+")";var t,e,s,i,n},r.prototype.toHsl=function(){return cl(sr(this.rgba))},r.prototype.toHslString=function(){return t=cl(sr(this.rgba)),e=t.h,s=t.s,i=t.l,(n=t.a)<1?"hsla("+e+", "+s+"%, "+i+"%, "+n+")":"hsl("+e+", "+s+"%, "+i+"%)";var t,e,s,i,n},r.prototype.toHsv=function(){return t=ul(this.rgba),{h:nt(t.h),s:nt(t.s),v:nt(t.v),a:nt(t.a,3)};var t},r.prototype.invert=function(){return Dt({r:255-(t=this.rgba).r,g:255-t.g,b:255-t.b,a:t.a});var t},r.prototype.saturate=function(t){return t===void 0&&(t=.1),Dt(Hi(this.rgba,t))},r.prototype.desaturate=function(t){return t===void 0&&(t=.1),Dt(Hi(this.rgba,-t))},r.prototype.grayscale=function(){return Dt(Hi(this.rgba,-1))},r.prototype.lighten=function(t){return t===void 0&&(t=.1),Dt(ml(this.rgba,t))},r.prototype.darken=function(t){return t===void 0&&(t=.1),Dt(ml(this.rgba,-t))},r.prototype.rotate=function(t){return t===void 0&&(t=15),this.hue(this.hue()+t)},r.prototype.alpha=function(t){return typeof t=="number"?Dt({r:(e=this.rgba).r,g:e.g,b:e.b,a:t}):nt(this.rgba.a,3);var e},r.prototype.hue=function(t){var e=sr(this.rgba);return typeof t=="number"?Dt({h:t,s:e.s,l:e.l,a:e.a}):nt(e.h)},r.prototype.isEqual=function(t){return this.toHex()===Dt(t).toHex()},r}(),Dt=function(r){return r instanceof Jr?r:new Jr(r)},gl=[],ab=function(r){r.forEach(function(t){gl.indexOf(t)<0&&(t(Jr,Ni),gl.push(t))})},WA=function(){return new Jr({r:255*Math.random(),g:255*Math.random(),b:255*Math.random()})};function ub(r,t){var e={white:"#ffffff",bisque:"#ffe4c4",blue:"#0000ff",cadetblue:"#5f9ea0",chartreuse:"#7fff00",chocolate:"#d2691e",coral:"#ff7f50",antiquewhite:"#faebd7",aqua:"#00ffff",azure:"#f0ffff",whitesmoke:"#f5f5f5",papayawhip:"#ffefd5",plum:"#dda0dd",blanchedalmond:"#ffebcd",black:"#000000",gold:"#ffd700",goldenrod:"#daa520",gainsboro:"#dcdcdc",cornsilk:"#fff8dc",cornflowerblue:"#6495ed",burlywood:"#deb887",aquamarine:"#7fffd4",beige:"#f5f5dc",crimson:"#dc143c",cyan:"#00ffff",darkblue:"#00008b",darkcyan:"#008b8b",darkgoldenrod:"#b8860b",darkkhaki:"#bdb76b",darkgray:"#a9a9a9",darkgreen:"#006400",darkgrey:"#a9a9a9",peachpuff:"#ffdab9",darkmagenta:"#8b008b",darkred:"#8b0000",darkorchid:"#9932cc",darkorange:"#ff8c00",darkslateblue:"#483d8b",gray:"#808080",darkslategray:"#2f4f4f",darkslategrey:"#2f4f4f",deeppink:"#ff1493",deepskyblue:"#00bfff",wheat:"#f5deb3",firebrick:"#b22222",floralwhite:"#fffaf0",ghostwhite:"#f8f8ff",darkviolet:"#9400d3",magenta:"#ff00ff",green:"#008000",dodgerblue:"#1e90ff",grey:"#808080",honeydew:"#f0fff0",hotpink:"#ff69b4",blueviolet:"#8a2be2",forestgreen:"#228b22",lawngreen:"#7cfc00",indianred:"#cd5c5c",indigo:"#4b0082",fuchsia:"#ff00ff",brown:"#a52a2a",maroon:"#800000",mediumblue:"#0000cd",lightcoral:"#f08080",darkturquoise:"#00ced1",lightcyan:"#e0ffff",ivory:"#fffff0",lightyellow:"#ffffe0",lightsalmon:"#ffa07a",lightseagreen:"#20b2aa",linen:"#faf0e6",mediumaquamarine:"#66cdaa",lemonchiffon:"#fffacd",lime:"#00ff00",khaki:"#f0e68c",mediumseagreen:"#3cb371",limegreen:"#32cd32",mediumspringgreen:"#00fa9a",lightskyblue:"#87cefa",lightblue:"#add8e6",midnightblue:"#191970",lightpink:"#ffb6c1",mistyrose:"#ffe4e1",moccasin:"#ffe4b5",mintcream:"#f5fffa",lightslategray:"#778899",lightslategrey:"#778899",navajowhite:"#ffdead",navy:"#000080",mediumvioletred:"#c71585",powderblue:"#b0e0e6",palegoldenrod:"#eee8aa",oldlace:"#fdf5e6",paleturquoise:"#afeeee",mediumturquoise:"#48d1cc",mediumorchid:"#ba55d3",rebeccapurple:"#663399",lightsteelblue:"#b0c4de",mediumslateblue:"#7b68ee",thistle:"#d8bfd8",tan:"#d2b48c",orchid:"#da70d6",mediumpurple:"#9370db",purple:"#800080",pink:"#ffc0cb",skyblue:"#87ceeb",springgreen:"#00ff7f",palegreen:"#98fb98",red:"#ff0000",yellow:"#ffff00",slateblue:"#6a5acd",lavenderblush:"#fff0f5",peru:"#cd853f",palevioletred:"#db7093",violet:"#ee82ee",teal:"#008080",slategray:"#708090",slategrey:"#708090",aliceblue:"#f0f8ff",darkseagreen:"#8fbc8f",darkolivegreen:"#556b2f",greenyellow:"#adff2f",seagreen:"#2e8b57",seashell:"#fff5ee",tomato:"#ff6347",silver:"#c0c0c0",sienna:"#a0522d",lavender:"#e6e6fa",lightgreen:"#90ee90",orange:"#ffa500",orangered:"#ff4500",steelblue:"#4682b4",royalblue:"#4169e1",turquoise:"#40e0d0",yellowgreen:"#9acd32",salmon:"#fa8072",saddlebrown:"#8b4513",sandybrown:"#f4a460",rosybrown:"#bc8f8f",darksalmon:"#e9967a",lightgoldenrodyellow:"#fafad2",snow:"#fffafa",lightgrey:"#d3d3d3",lightgray:"#d3d3d3",dimgray:"#696969",dimgrey:"#696969",olivedrab:"#6b8e23",olive:"#808000"},s={};for(var i in e)s[e[i]]=i;var n={};r.prototype.toName=function(o){if(!(this.rgba.a||this.rgba.r||this.rgba.g||this.rgba.b))return"transparent";var a,u,l=s[this.toHex()];if(l)return l;if(o!=null&&o.closest){var h=this.toRgb(),c=1/0,d="black";if(!n.length)for(var p in e)n[p]=new r(e[p]).toRgb();for(var f in e){var g=(a=h,u=n[f],Math.pow(a.r-u.r,2)+Math.pow(a.g-u.g,2)+Math.pow(a.b-u.b,2));gt in r?lb(r,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):r[t]=e,db=(r,t)=>{for(var e in t||(t={}))hb.call(t,e)&&xl(r,e,t[e]);if(_l)for(var e of _l(t))cb.call(t,e)&&xl(r,e,t[e]);return r};ab([ub]);const we=class Vr{constructor(t=16777215){this._value=null,this._components=new Float32Array(4),this._components.fill(1),this._int=16777215,this.value=t}get red(){return this._components[0]}get green(){return this._components[1]}get blue(){return this._components[2]}get alpha(){return this._components[3]}setValue(t){return this.value=t,this}set value(t){if(t instanceof Vr)this._value=this._cloneSource(t._value),this._int=t._int,this._components.set(t._components);else{if(t===null)throw new Error("Cannot set Color#value to null");(this._value===null||!this._isSourceEqual(this._value,t))&&(this._normalize(t),this._value=this._cloneSource(t))}}get value(){return this._value}_cloneSource(t){return typeof t=="string"||typeof t=="number"||t instanceof Number||t===null?t:Array.isArray(t)||ArrayBuffer.isView(t)?t.slice(0):typeof t=="object"&&t!==null?db({},t):t}_isSourceEqual(t,e){const s=typeof t;if(s!==typeof e)return!1;if(s==="number"||s==="string"||t instanceof Number)return t===e;if(Array.isArray(t)&&Array.isArray(e)||ArrayBuffer.isView(t)&&ArrayBuffer.isView(e))return t.length!==e.length?!1:t.every((i,n)=>i===e[n]);if(t!==null&&e!==null){const i=Object.keys(t),n=Object.keys(e);return i.length!==n.length?!1:i.every(o=>t[o]===e[o])}return t===e}toRgba(){const[t,e,s,i]=this._components;return{r:t,g:e,b:s,a:i}}toRgb(){const[t,e,s]=this._components;return{r:t,g:e,b:s}}toRgbaString(){const[t,e,s]=this.toUint8RgbArray();return`rgba(${t},${e},${s},${this.alpha})`}toUint8RgbArray(t){const[e,s,i]=this._components;return this._arrayRgb||(this._arrayRgb=[]),t=t||this._arrayRgb,t[0]=Math.round(e*255),t[1]=Math.round(s*255),t[2]=Math.round(i*255),t}toArray(t){this._arrayRgba||(this._arrayRgba=[]),t=t||this._arrayRgba;const[e,s,i,n]=this._components;return t[0]=e,t[1]=s,t[2]=i,t[3]=n,t}toRgbArray(t){this._arrayRgb||(this._arrayRgb=[]),t=t||this._arrayRgb;const[e,s,i]=this._components;return t[0]=e,t[1]=s,t[2]=i,t}toNumber(){return this._int}toBgrNumber(){const[t,e,s]=this.toUint8RgbArray();return(s<<16)+(e<<8)+t}toLittleEndianNumber(){const t=this._int;return(t>>16)+(t&65280)+((t&255)<<16)}multiply(t){const[e,s,i,n]=Vr._temp.setValue(t)._components;return this._components[0]*=e,this._components[1]*=s,this._components[2]*=i,this._components[3]*=n,this._refreshInt(),this._value=null,this}premultiply(t,e=!0){return e&&(this._components[0]*=t,this._components[1]*=t,this._components[2]*=t),this._components[3]=t,this._refreshInt(),this._value=null,this}toPremultiplied(t,e=!0){if(t===1)return(255<<24)+this._int;if(t===0)return e?0:this._int;let s=this._int>>16&255,i=this._int>>8&255,n=this._int&255;return e&&(s=s*t+.5|0,i=i*t+.5|0,n=n*t+.5|0),(t*255<<24)+(s<<16)+(i<<8)+n}toHex(){const t=this._int.toString(16);return`#${"000000".substring(0,6-t.length)+t}`}toHexa(){const t=Math.round(this._components[3]*255).toString(16);return this.toHex()+"00".substring(0,2-t.length)+t}setAlpha(t){return this._components[3]=this._clamp(t),this}_normalize(t){let e,s,i,n;if((typeof t=="number"||t instanceof Number)&&t>=0&&t<=16777215){const o=t;e=(o>>16&255)/255,s=(o>>8&255)/255,i=(o&255)/255,n=1}else if((Array.isArray(t)||t instanceof Float32Array)&&t.length>=3&&t.length<=4)t=this._clamp(t),[e,s,i,n=1]=t;else if((t instanceof Uint8Array||t instanceof Uint8ClampedArray)&&t.length>=3&&t.length<=4)t=this._clamp(t,0,255),[e,s,i,n=255]=t,e/=255,s/=255,i/=255,n/=255;else if(typeof t=="string"||typeof t=="object"){if(typeof t=="string"){const a=Vr.HEX_PATTERN.exec(t);a&&(t=`#${a[2]}`)}const o=Dt(t);o.isValid()&&({r:e,g:s,b:i,a:n}=o.rgba,e/=255,s/=255,i/=255)}if(e!==void 0)this._components[0]=e,this._components[1]=s,this._components[2]=i,this._components[3]=n,this._refreshInt();else throw new Error(`Unable to convert color ${t}`)}_refreshInt(){this._clamp(this._components);const[t,e,s]=this._components;this._int=(t*255<<16)+(e*255<<8)+(s*255|0)}_clamp(t,e=0,s=1){return typeof t=="number"?Math.min(Math.max(t,e),s):(t.forEach((i,n)=>{t[n]=Math.min(Math.max(i,e),s)}),t)}static isColorLike(t){return typeof t=="number"||typeof t=="string"||t instanceof Number||t instanceof Vr||Array.isArray(t)||t instanceof Uint8Array||t instanceof Uint8ClampedArray||t instanceof Float32Array||t.r!==void 0&&t.g!==void 0&&t.b!==void 0||t.r!==void 0&&t.g!==void 0&&t.b!==void 0&&t.a!==void 0||t.h!==void 0&&t.s!==void 0&&t.l!==void 0||t.h!==void 0&&t.s!==void 0&&t.l!==void 0&&t.a!==void 0||t.h!==void 0&&t.s!==void 0&&t.v!==void 0||t.h!==void 0&&t.s!==void 0&&t.v!==void 0&&t.a!==void 0}};we.shared=new we,we._temp=new we,we.HEX_PATTERN=/^(#|0x)?(([a-f0-9]{3}){1,2}([a-f0-9]{2})?)$/i;let W=we;const bl={cullArea:null,cullable:!1,cullableChildren:!0},vl=Math.PI*2,yl=180/Math.PI,Tl=Math.PI/180;class j{constructor(t=0,e=0){this.x=0,this.y=0,this.x=t,this.y=e}clone(){return new j(this.x,this.y)}copyFrom(t){return this.set(t.x,t.y),this}copyTo(t){return t.set(this.x,this.y),t}equals(t){return t.x===this.x&&t.y===this.y}set(t=0,e=t){return this.x=t,this.y=e,this}static get shared(){return zi.x=0,zi.y=0,zi}}const zi=new j;class G{constructor(t=1,e=0,s=0,i=1,n=0,o=0){this.array=null,this.a=t,this.b=e,this.c=s,this.d=i,this.tx=n,this.ty=o}fromArray(t){this.a=t[0],this.b=t[1],this.c=t[3],this.d=t[4],this.tx=t[2],this.ty=t[5]}set(t,e,s,i,n,o){return this.a=t,this.b=e,this.c=s,this.d=i,this.tx=n,this.ty=o,this}toArray(t,e){this.array||(this.array=new Float32Array(9));const s=e||this.array;return t?(s[0]=this.a,s[1]=this.b,s[2]=0,s[3]=this.c,s[4]=this.d,s[5]=0,s[6]=this.tx,s[7]=this.ty,s[8]=1):(s[0]=this.a,s[1]=this.c,s[2]=this.tx,s[3]=this.b,s[4]=this.d,s[5]=this.ty,s[6]=0,s[7]=0,s[8]=1),s}apply(t,e){e=e||new j;const s=t.x,i=t.y;return e.x=this.a*s+this.c*i+this.tx,e.y=this.b*s+this.d*i+this.ty,e}applyInverse(t,e){e=e||new j;const s=this.a,i=this.b,n=this.c,o=this.d,a=this.tx,u=this.ty,l=1/(s*o+n*-i),h=t.x,c=t.y;return e.x=o*l*h+-n*l*c+(u*n-a*o)*l,e.y=s*l*c+-i*l*h+(-u*s+a*i)*l,e}translate(t,e){return this.tx+=t,this.ty+=e,this}scale(t,e){return this.a*=t,this.d*=e,this.c*=t,this.b*=e,this.tx*=t,this.ty*=e,this}rotate(t){const e=Math.cos(t),s=Math.sin(t),i=this.a,n=this.c,o=this.tx;return this.a=i*e-this.b*s,this.b=i*s+this.b*e,this.c=n*e-this.d*s,this.d=n*s+this.d*e,this.tx=o*e-this.ty*s,this.ty=o*s+this.ty*e,this}append(t){const e=this.a,s=this.b,i=this.c,n=this.d;return this.a=t.a*e+t.b*i,this.b=t.a*s+t.b*n,this.c=t.c*e+t.d*i,this.d=t.c*s+t.d*n,this.tx=t.tx*e+t.ty*i+this.tx,this.ty=t.tx*s+t.ty*n+this.ty,this}appendFrom(t,e){const s=t.a,i=t.b,n=t.c,o=t.d,a=t.tx,u=t.ty,l=e.a,h=e.b,c=e.c,d=e.d;return this.a=s*l+i*c,this.b=s*h+i*d,this.c=n*l+o*c,this.d=n*h+o*d,this.tx=a*l+u*c+e.tx,this.ty=a*h+u*d+e.ty,this}setTransform(t,e,s,i,n,o,a,u,l){return this.a=Math.cos(a+l)*n,this.b=Math.sin(a+l)*n,this.c=-Math.sin(a-u)*o,this.d=Math.cos(a-u)*o,this.tx=t-(s*this.a+i*this.c),this.ty=e-(s*this.b+i*this.d),this}prepend(t){const e=this.tx;if(t.a!==1||t.b!==0||t.c!==0||t.d!==1){const s=this.a,i=this.c;this.a=s*t.a+this.b*t.c,this.b=s*t.b+this.b*t.d,this.c=i*t.a+this.d*t.c,this.d=i*t.b+this.d*t.d}return this.tx=e*t.a+this.ty*t.c+t.tx,this.ty=e*t.b+this.ty*t.d+t.ty,this}decompose(t){const e=this.a,s=this.b,i=this.c,n=this.d,o=t.pivot,a=-Math.atan2(-i,n),u=Math.atan2(s,e),l=Math.abs(a+u);return l<1e-5||Math.abs(vl-l)<1e-5?(t.rotation=u,t.skew.x=t.skew.y=0):(t.rotation=0,t.skew.x=a,t.skew.y=u),t.scale.x=Math.sqrt(e*e+s*s),t.scale.y=Math.sqrt(i*i+n*n),t.position.x=this.tx+(o.x*e+o.y*i),t.position.y=this.ty+(o.x*s+o.y*n),t}invert(){const t=this.a,e=this.b,s=this.c,i=this.d,n=this.tx,o=t*i-e*s;return this.a=i/o,this.b=-e/o,this.c=-s/o,this.d=t/o,this.tx=(s*this.ty-i*n)/o,this.ty=-(t*this.ty-e*n)/o,this}isIdentity(){return this.a===1&&this.b===0&&this.c===0&&this.d===1&&this.tx===0&&this.ty===0}identity(){return this.a=1,this.b=0,this.c=0,this.d=1,this.tx=0,this.ty=0,this}clone(){const t=new G;return t.a=this.a,t.b=this.b,t.c=this.c,t.d=this.d,t.tx=this.tx,t.ty=this.ty,t}copyTo(t){return t.a=this.a,t.b=this.b,t.c=this.c,t.d=this.d,t.tx=this.tx,t.ty=this.ty,t}copyFrom(t){return this.a=t.a,this.b=t.b,this.c=t.c,this.d=t.d,this.tx=t.tx,this.ty=t.ty,this}equals(t){return t.a===this.a&&t.b===this.b&&t.c===this.c&&t.d===this.d&&t.tx===this.tx&&t.ty===this.ty}static get IDENTITY(){return fb.identity()}static get shared(){return pb.identity()}}const pb=new G,fb=new G;class rt{constructor(t,e,s){this._x=e||0,this._y=s||0,this._observer=t}clone(t){return new rt(t!=null?t:this._observer,this._x,this._y)}set(t=0,e=t){return(this._x!==t||this._y!==e)&&(this._x=t,this._y=e,this._observer._onUpdate(this)),this}copyFrom(t){return(this._x!==t.x||this._y!==t.y)&&(this._x=t.x,this._y=t.y,this._observer._onUpdate(this)),this}copyTo(t){return t.set(this._x,this._y),t}equals(t){return t.x===this._x&&t.y===this._y}get x(){return this._x}set x(t){this._x!==t&&(this._x=t,this._observer._onUpdate(this))}get y(){return this._y}set y(t){this._y!==t&&(this._y=t,this._observer._onUpdate(this))}}const ir={default:-1};function Z(r="default"){return ir[r]===void 0&&(ir[r]=-1),++ir[r]}function mb(){for(const r in ir)delete ir[r]}function ji(r,t,e){const s=r.length;let i;if(t>=s||e===0)return;e=t+e>s?s-t:e;const n=s-e;for(i=t;i0&&s<=e){for(let n=e-1;n>=r;n--){const o=this.children[n];o&&(this.renderGroup&&this.renderGroup.removeChild(o),i.push(o),o.parent=null)}ji(this.children,r,e);for(let n=0;n=this.children.length)throw new Error(`getChildAt: Index (${r}) does not exist.`);return this.children[r]},setChildIndex(r,t){if(t<0||t>=this.children.length)throw new Error(`The index ${t} supplied is out of bounds ${this.children.length}`);this.getChildIndex(r),this.addChildAt(r,t)},getChildIndex(r){const t=this.children.indexOf(r);if(t===-1)throw new Error("The supplied Container must be a child of the caller");return t},addChildAt(r,t){const{children:e}=this;if(t<0||t>e.length)throw new Error(`${r}addChildAt: The index ${t} supplied is out of bounds ${e.length}`);if(r.parent){const s=r.parent.children.indexOf(r);if(r.parent===this&&s===t)return r;s!==-1&&r.parent.children.splice(s,1)}return t===e.length?e.push(r):e.splice(t,0,r),r.parent=this,r.didChange=!0,r.didViewUpdate=!1,r._updateFlags=15,this.renderGroup&&this.renderGroup.addChild(r),this.sortableChildren&&(this.sortDirty=!0),this.emit("childAdded",r,this,t),r.emit("added",this),r},swapChildren(r,t){if(r===t)return;const e=this.getChildIndex(r),s=this.getChildIndex(t);this.children[e]=t,this.children[s]=r},removeFromParent(){var r;(r=this.parent)==null||r.removeChild(this)}};class ts{constructor(t){this.pipe="filter",this.priority=1,this.filters=t==null?void 0:t.filters,this.filterArea=t==null?void 0:t.filterArea}destroy(){for(let t=0;t0?s=this._pool[--this._index]:s=new this._classType,(e=s.init)==null||e.call(s,t),s}return(t){var e;(e=t.reset)==null||e.call(t),this._pool[this._index++]=t}get totalSize(){return this._count}get totalFree(){return this._index}get totalUsed(){return this._count-this._index}}class El{constructor(){this._poolsByClass=new Map}prepopulate(t,e){this.getPool(t).prepopulate(e)}get(t,e){return this.getPool(t).get(e)}return(t){this.getPool(t.constructor).return(t)}getPool(t){return this._poolsByClass.has(t)||this._poolsByClass.set(t,new es(t)),this._poolsByClass.get(t)}stats(){const t={};return this._poolsByClass.forEach(e=>{const s=t[e._classType.name]?e._classType.name+e._classType.ID:e._classType.name;t[s]={free:e.totalFree,used:e.totalUsed,size:e.totalSize}}),t}}const H=new El;class Al{constructor(){this._effectClasses=[],this._tests=[],this._initialized=!1}init(){this._initialized||(this._initialized=!0,this._effectClasses.forEach(t=>{this.add({test:t.test,maskClass:t})}))}add(t){this._tests.push(t)}getMaskEffect(t){this._initialized||this.init();for(let e=0;et.priority-e.priority),this.renderGroup&&(this.renderGroup.structureDidChange=!0),this._updateIsSimple())},removeEffect(r){const t=this.effects.indexOf(r);t!==-1&&(this.effects.splice(t,1),!this.isRenderGroupRoot&&this.renderGroup&&(this.renderGroup.structureDidChange=!0),this._updateIsSimple())},set mask(r){if(this._mask||(this._mask={mask:null,effect:null}),this._mask.mask===r||(this._mask.effect&&(this.removeEffect(this._mask.effect),rs.returnMaskEffect(this._mask.effect),this._mask.effect=null),this._mask.mask=r,r==null))return;const t=rs.getMaskEffect(r);this._mask.effect=t,this.addEffect(t)},get mask(){var r;return(r=this._mask)==null?void 0:r.mask},set filters(r){!Array.isArray(r)&&r&&(r=[r]),r=r,this._filters||(this._filters={filters:null,effect:null,filterArea:null});const t=(r==null?void 0:r.length)>0,e=this._filters.effect&&!t||!this._filters.effect&&t;if(r=Array.isArray(r)?r.slice(0):r,this._filters.filters=Object.freeze(r),e)if(t){const s=H.get(ts);this._filters.effect=s,this.addEffect(s)}else{const s=this._filters.effect;this.removeEffect(s),s.filterArea=null,s.filters=null,this._filters.effect=null,H.return(s)}t&&(this._filters.effect.filters=r,this._filters.effect.filterArea=this.filterArea)},get filters(){var r;return(r=this._filters)==null?void 0:r.filters},set filterArea(r){this._filters||(this._filters={filters:null,effect:null,filterArea:null}),this._filters.filterArea=r},get filterArea(){var r;return(r=this._filters)==null?void 0:r.filterArea}},wl={label:null,get name(){return this.label},set name(r){this.label=r},getChildByName(r,t=!1){return this.getChildByLabel(r,t)},getChildByLabel(r,t=!1){const e=this.children;for(let s=0;s=this.x&&t=this.y&&e=u&&t<=l&&e>=h&&e<=c&&!(t>d&&tf&&et.right?t.right:this.right)<=w)return!1;const T=this.yt.bottom?t.bottom:this.bottom)>T}const s=this.left,i=this.right,n=this.top,o=this.bottom;if(i<=s||o<=n)return!1;const a=ss[0].set(t.left,t.top),u=ss[1].set(t.left,t.bottom),l=ss[2].set(t.right,t.top),h=ss[3].set(t.right,t.bottom);if(l.x<=a.x||u.y<=a.y)return!1;const c=Math.sign(e.a*e.d-e.b*e.c);if(c===0||(e.apply(a,a),e.apply(u,u),e.apply(l,l),e.apply(h,h),Math.max(a.x,u.x,l.x,h.x)<=s||Math.min(a.x,u.x,l.x,h.x)>=i||Math.max(a.y,u.y,l.y,h.y)<=n||Math.min(a.y,u.y,l.y,h.y)>=o))return!1;const d=c*(u.y-a.y),p=c*(a.x-u.x),f=d*s+p*n,g=d*i+p*n,m=d*s+p*o,_=d*i+p*o;if(Math.max(f,g,m,_)<=d*a.x+p*a.y||Math.min(f,g,m,_)>=d*h.x+p*h.y)return!1;const x=c*(a.y-l.y),b=c*(l.x-a.x),y=x*s+b*n,S=x*i+b*n,P=x*s+b*o,R=x*i+b*o;return!(Math.max(y,S,P,R)<=x*a.x+b*a.y||Math.min(y,S,P,R)>=x*h.x+b*h.y)}pad(t=0,e=t){return this.x-=t,this.y-=e,this.width+=t*2,this.height+=e*2,this}fit(t){const e=Math.max(this.x,t.x),s=Math.min(this.x+this.width,t.x+t.width),i=Math.max(this.y,t.y),n=Math.min(this.y+this.height,t.y+t.height);return this.x=e,this.width=Math.max(s-e,0),this.y=i,this.height=Math.max(n-i,0),this}ceil(t=1,e=.001){const s=Math.ceil((this.x+this.width-e)*t)/t,i=Math.ceil((this.y+this.height-e)*t)/t;return this.x=Math.floor((this.x+e)*t)/t,this.y=Math.floor((this.y+e)*t)/t,this.width=s-this.x,this.height=i-this.y,this}enlarge(t){const e=Math.min(this.x,t.x),s=Math.max(this.x+this.width,t.x+t.width),i=Math.min(this.y,t.y),n=Math.max(this.y+this.height,t.y+t.height);return this.x=e,this.width=s-e,this.y=i,this.height=n-i,this}getBounds(t){return t=t||new z,t.copyFrom(this),t}}const Rl=new G;class lt{constructor(t=1/0,e=1/0,s=-1/0,i=-1/0){this.minX=1/0,this.minY=1/0,this.maxX=-1/0,this.maxY=-1/0,this.matrix=Rl,this.minX=t,this.minY=e,this.maxX=s,this.maxY=i}isEmpty(){return this.minX>this.maxX||this.minY>this.maxY}get rectangle(){this._rectangle||(this._rectangle=new z);const t=this._rectangle;return this.minX>this.maxX||this.minY>this.maxY?(t.x=0,t.y=0,t.width=0,t.height=0):t.copyFromBounds(this),t}clear(){return this.minX=1/0,this.minY=1/0,this.maxX=-1/0,this.maxY=-1/0,this.matrix=Rl,this}set(t,e,s,i){this.minX=t,this.minY=e,this.maxX=s,this.maxY=i}addFrame(t,e,s,i,n){n||(n=this.matrix);const o=n.a,a=n.b,u=n.c,l=n.d,h=n.tx,c=n.ty;let d=this.minX,p=this.minY,f=this.maxX,g=this.maxY,m=o*t+u*e+h,_=a*t+l*e+c;mf&&(f=m),_>g&&(g=_),m=o*s+u*e+h,_=a*s+l*e+c,mf&&(f=m),_>g&&(g=_),m=o*t+u*i+h,_=a*t+l*i+c,mf&&(f=m),_>g&&(g=_),m=o*s+u*i+h,_=a*s+l*i+c,mf&&(f=m),_>g&&(g=_),this.minX=d,this.minY=p,this.maxX=f,this.maxY=g}addRect(t,e){this.addFrame(t.x,t.y,t.x+t.width,t.y+t.height,e)}addBounds(t,e){this.addFrame(t.minX,t.minY,t.maxX,t.maxY,e)}addBoundsMask(t){this.minX=this.minX>t.minX?this.minX:t.minX,this.minY=this.minY>t.minY?this.minY:t.minY,this.maxX=this.maxXthis.maxX?d:this.maxX,this.maxY=p>this.maxY?p:this.maxY,d=o*e+u*n+h,p=a*e+l*n+c,this.minX=dthis.maxX?d:this.maxX,this.maxY=p>this.maxY?p:this.maxY,d=o*i+u*n+h,p=a*i+l*n+c,this.minX=dthis.maxX?d:this.maxX,this.maxY=p>this.maxY?p:this.maxY}fit(t){return this.minXt.right&&(this.maxX=t.right),this.minYt.bottom&&(this.maxY=t.bottom),this}fitBounds(t,e,s,i){return this.minXe&&(this.maxX=e),this.minYi&&(this.maxY=i),this}pad(t,e=t){return this.minX-=t,this.maxX+=t,this.minY-=e,this.maxY+=e,this}ceil(){return this.minX=Math.floor(this.minX),this.minY=Math.floor(this.minY),this.maxX=Math.ceil(this.maxX),this.maxY=Math.ceil(this.maxY),this}clone(){return new lt(this.minX,this.minY,this.maxX,this.maxY)}scale(t,e=t){return this.minX*=t,this.minY*=e,this.maxX*=t,this.maxY*=e,this}get x(){return this.minX}set x(t){const e=this.maxX-this.minX;this.minX=t,this.maxX=t+e}get y(){return this.minY}set y(t){const e=this.maxY-this.minY;this.minY=t,this.maxY=t+e}get width(){return this.maxX-this.minX}set width(t){this.maxX=this.minX+t}get height(){return this.maxY-this.minY}set height(t){this.maxY=this.minY+t}get left(){return this.minX}get right(){return this.maxX}get top(){return this.minY}get bottom(){return this.maxY}get isPositive(){return this.maxX-this.minX>0&&this.maxY-this.minY>0}get isValid(){return this.minX+this.minY!==1/0}addVertexData(t,e,s,i){let n=this.minX,o=this.minY,a=this.maxX,u=this.maxY;i||(i=this.matrix);const l=i.a,h=i.b,c=i.c,d=i.d,p=i.tx,f=i.ty;for(let g=e;ga?x:a,u=b>u?b:u}this.minX=n,this.minY=o,this.maxX=a,this.maxY=u}containsPoint(t,e){return this.minX<=t&&this.minY<=e&&this.maxX>=t&&this.maxY>=e}toString(){return`[pixi.js:Bounds minX=${this.minX} minY=${this.minY} maxX=${this.maxX} maxY=${this.maxY} width=${this.width} height=${this.height}]`}}const Ut=new es(G),kt=new es(lt);function nr(r,t,e){e.clear();let s,i;return r.parent?t?s=r.parent.worldTransform:(i=Ut.get().identity(),s=or(r,i)):s=G.IDENTITY,Vi(r,e,s,t),i&&Ut.return(i),e.isValid||e.set(0,0,0,0),e}function Vi(r,t,e,s){var i,n;if(!r.visible||!r.measurable)return;let o;s?o=r.worldTransform:(r.updateLocalTransform(),o=Ut.get(),o.appendFrom(r.localTransform,e));const a=t,u=!!r.effects.length;if(u&&(t=kt.get().clear()),r.boundsArea)t.addRect(r.boundsArea,o);else{r.addBounds&&(t.matrix=o,r.addBounds(t));for(let l=0;l>12&&(r.didChange=!0,r.data[0]=this._didChangeId>>12),Wi(this,r),r.didChange&&is(this,r.localBounds,gb),r.localBounds},getBounds(r,t){return nr(this,r,t||new lt)}},Gl={_onRender:null,set onRender(r){const t=this.renderGroup;if(!r){this._onRender&&(t==null||t.removeOnRender(this)),this._onRender=null;return}this._onRender||t==null||t.addOnRender(this),this._onRender=r},get onRender(){return this._onRender}},Il={_zIndex:0,sortDirty:!1,sortableChildren:!1,get zIndex(){return this._zIndex},set zIndex(r){this._zIndex!==r&&(this._zIndex=r,this.depthOfChildModified())},depthOfChildModified(){this.parent&&(this.parent.sortableChildren=!0,this.parent.sortDirty=!0),this.renderGroup&&!this.isRenderGroupRoot&&(this.renderGroup.structureDidChange=!0)},sortChildren(){this.sortDirty&&(this.sortDirty=!1,this.children.sort(_b))}};function _b(r,t){return r._zIndex-t._zIndex}const Bl={getGlobalPosition(r=new j,t=!1){return this.parent?this.parent.toGlobal(this._position,r,t):(r.x=this._position.x,r.y=this._position.y),r},toGlobal(r,t,e=!1){if(!e){this.updateLocalTransform();const s=or(this,new G);return s.append(this.localTransform),s.apply(r,t)}return this.worldTransform.apply(r,t)},toLocal(r,t,e,s){if(t&&(r=t.toGlobal(r,e,s)),!s){this.updateLocalTransform();const i=or(this,new G);return i.append(this.localTransform),i.applyInverse(r,e)}return this.worldTransform.applyInverse(r,e)}};class Yi{constructor(){this.uid=Z("instructionSet"),this.instructions=[],this.instructionSize=0}reset(){this.instructionSize=0}add(t){this.instructions[this.instructionSize++]=t}log(){this.instructions.length=this.instructionSize,console.table(this.instructions,["type","action"])}}class Fl{constructor(t){this.renderPipeId="renderGroup",this.root=null,this.canBundle=!1,this.renderGroupParent=null,this.renderGroupChildren=[],this._children=[],this.worldTransform=new G,this.worldColorAlpha=4294967295,this.worldColor=16777215,this.worldAlpha=1,this.childrenToUpdate=Object.create(null),this.updateTick=0,this.childrenRenderablesToUpdate={list:[],index:0},this.structureDidChange=!0,this.instructionSet=new Yi,this._onRenderContainers=[],this.root=t,this.addChild(t)}get localTransform(){return this.root.localTransform}addRenderGroupChild(t){t.renderGroupParent&&t.renderGroupParent._removeRenderGroupChild(t),t.renderGroupParent=this,this.onChildUpdate(t.root),this.renderGroupChildren.push(t)}_removeRenderGroupChild(t){t.root.didChange&&this._removeChildFromUpdate(t.root);const e=this.renderGroupChildren.indexOf(t);e>-1&&this.renderGroupChildren.splice(e,1),t.renderGroupParent=null}addChild(t){if(this.structureDidChange=!0,t!==this.root&&(this._children.push(t),t.updateTick=-1,t.parent===this.root?t.relativeRenderGroupDepth=1:t.relativeRenderGroupDepth=t.parent.relativeRenderGroupDepth+1,t._onRender&&this.addOnRender(t)),t.renderGroup){if(t.renderGroup.root===t){this.addRenderGroupChild(t.renderGroup);return}}else t.renderGroup=this,t.didChange=!0;const e=t.children;t.isRenderGroupRoot||this.onChildUpdate(t);for(let s=0;s-1&&this._children.splice(e,1)}onChildUpdate(t){let e=this.childrenToUpdate[t.relativeRenderGroupDepth];e||(e=this.childrenToUpdate[t.relativeRenderGroupDepth]={index:0,list:[]}),e.list[e.index++]=t}updateRenderable(t){t.globalDisplayStatus<7||(t.didViewUpdate=!1,this.instructionSet.renderPipes[t.renderPipeId].updateRenderable(t))}onChildViewUpdate(t){this.childrenRenderablesToUpdate.list[this.childrenRenderablesToUpdate.index++]=t}_removeChildFromUpdate(t){const e=this.childrenToUpdate[t.relativeRenderGroupDepth];if(!e)return;const s=e.list.indexOf(t);s>-1&&e.list.splice(s,1),e.index--}get isRenderable(){return this.root.localDisplayStatus===7&&this.worldAlpha>0}addOnRender(t){this._onRenderContainers.push(t)}removeOnRender(t){this._onRenderContainers.splice(this._onRenderContainers.indexOf(t),1)}runOnRender(){for(let t=0;tthis.addChild(i)),this.effects=[],(s=t.parent)==null||s.addChild(this)}static mixin(t){Object.defineProperties(V.prototype,Object.getOwnPropertyDescriptors(t))}addChild(...t){if(t.length>1){for(let s=0;s1){for(let i=0;i-1&&(this.children.splice(s,1),this.renderGroup&&this.renderGroup.removeChild(e),e.parent=null,this.emit("childRemoved",e,this,s),e.emit("removed",this)),e}_onUpdate(t){if(t&&t===this._skew&&this._updateSkew(),this._didChangeId++,!this.didChange)if(this.didChange=!0,this.isRenderGroupRoot){const e=this.renderGroup.renderGroupParent;e&&e.onChildUpdate(this)}else this.renderGroup&&this.renderGroup.onChildUpdate(this)}set isRenderGroup(t){if(this.isRenderGroupRoot&&t===!1)throw new Error("[Pixi] cannot undo a render group just yet");t&&this.enableRenderGroup()}get isRenderGroup(){return this.isRenderGroupRoot}enableRenderGroup(){if(this.renderGroup&&this.renderGroup.root===this)return;this.isRenderGroupRoot=!0;const t=this.renderGroup;if(t&&t.removeChild(this),this.renderGroup=new Fl(this),t){for(let e=0;e>16&255)}set blendMode(t){this.localBlendMode!==t&&(this.renderGroup&&!this.isRenderGroupRoot&&(this.renderGroup.structureDidChange=!0),this._updateFlags|=Qi,this.localBlendMode=t,this._onUpdate())}get blendMode(){return this.localBlendMode}get visible(){return!!(this.localDisplayStatus&2)}set visible(t){const e=t?1:0;(this.localDisplayStatus&2)>>1!==e&&(this.renderGroup&&!this.isRenderGroupRoot&&(this.renderGroup.structureDidChange=!0),this._updateFlags|=ar,this.localDisplayStatus^=2,this._onUpdate())}get culled(){return!(this.localDisplayStatus&4)}set culled(t){const e=t?1:0;(this.localDisplayStatus&4)>>2!==e&&(this.renderGroup&&!this.isRenderGroupRoot&&(this.renderGroup.structureDidChange=!0),this._updateFlags|=ar,this.localDisplayStatus^=4,this._onUpdate())}get renderable(){return!!(this.localDisplayStatus&1)}set renderable(t){const e=t?1:0;(this.localDisplayStatus&1)!==e&&(this._updateFlags|=ar,this.localDisplayStatus^=1,this.renderGroup&&!this.isRenderGroupRoot&&(this.renderGroup.structureDidChange=!0),this._onUpdate())}get isRenderable(){return this.localDisplayStatus===7&&this.groupAlpha>0}destroy(t=!1){if(this.destroyed)return;this.destroyed=!0,this.removeFromParent(),this.parent=null,this._mask=null,this._filters=null,this.effects=null,this._position=null,this._scale=null,this._pivot=null,this._skew=null,this.emit("destroyed",this),this.removeAllListeners();const e=typeof t=="boolean"?t:t==null?void 0:t.children,s=this.removeChildren(0,this.children.length);if(e)for(let i=0;i1&&typeof MSStream=="undefined"};function bb(r){return function(t){return t.test(r)}}function Yl(r){var t={userAgent:"",platform:"",maxTouchPoints:0};!r&&typeof navigator!="undefined"?t={userAgent:navigator.userAgent,platform:navigator.platform,maxTouchPoints:navigator.maxTouchPoints||0}:typeof r=="string"?t.userAgent=r:r&&r.userAgent&&(t={userAgent:r.userAgent,platform:r.platform,maxTouchPoints:r.maxTouchPoints||0});var e=t.userAgent,s=e.split("[FBAN");typeof s[1]!="undefined"&&(e=s[0]),s=e.split("Twitter"),typeof s[1]!="undefined"&&(e=s[0]);var i=bb(e),n={apple:{phone:i(Ji)&&!i(Ht),ipod:i(Ul),tablet:!i(Ji)&&(i(kl)||Wl(t))&&!i(Ht),universal:i(Ll),device:(i(Ji)||i(Ul)||i(kl)||i(Ll)||Wl(t))&&!i(Ht)},amazon:{phone:i(Re),tablet:!i(Re)&&i(os),device:i(Re)||i(os)},android:{phone:!i(Ht)&&i(Re)||!i(Ht)&&i(tn),tablet:!i(Ht)&&!i(Re)&&!i(tn)&&(i(os)||i($l)),device:!i(Ht)&&(i(Re)||i(os)||i(tn)||i($l))||i(/\bokhttp\b/i)},windows:{phone:i(Ht),tablet:i(Nl),device:i(Ht)||i(Nl)},other:{blackberry:i(Hl),blackberry10:i(Xl),opera:i(zl),firefox:i(Vl),chrome:i(jl),device:i(Hl)||i(Xl)||i(zl)||i(Vl)||i(jl)},any:!1,phone:!1,tablet:!1};return n.any=n.apple.device||n.android.device||n.windows.device||n.other.device,n.phone=n.apple.phone||n.android.phone||n.windows.phone,n.tablet=n.apple.tablet||n.android.tablet||n.windows.tablet,n}var Kl;const vb=(Kl=Yl.default)!=null?Kl:Yl,ql=vb(globalThis.navigator),yb=9,as=100,Tb=0,Sb=0,Zl=2,Ql=1,Eb=-1e3,Ab=-1e3,Pb=2;class en{constructor(t,e=ql){this._mobileInfo=e,this.debug=!1,this._isActive=!1,this._isMobileAccessibility=!1,this._pool=[],this._renderId=0,this._children=[],this._androidUpdateCount=0,this._androidUpdateFrequency=500,this._hookDiv=null,(e.tablet||e.phone)&&this._createTouchHook();const s=document.createElement("div");s.style.width=`${as}px`,s.style.height=`${as}px`,s.style.position="absolute",s.style.top=`${Tb}px`,s.style.left=`${Sb}px`,s.style.zIndex=Zl.toString(),this._div=s,this._renderer=t,this._onKeyDown=this._onKeyDown.bind(this),this._onMouseMove=this._onMouseMove.bind(this),globalThis.addEventListener("keydown",this._onKeyDown,!1)}get isActive(){return this._isActive}get isMobileAccessibility(){return this._isMobileAccessibility}get hookDiv(){return this._hookDiv}_createTouchHook(){const t=document.createElement("button");t.style.width=`${Ql}px`,t.style.height=`${Ql}px`,t.style.position="absolute",t.style.top=`${Eb}px`,t.style.left=`${Ab}px`,t.style.zIndex=Pb.toString(),t.style.backgroundColor="#FF0000",t.title="select to enable accessibility for this content",t.addEventListener("focus",()=>{this._isMobileAccessibility=!0,this._activate(),this._destroyTouchHook()}),document.body.appendChild(t),this._hookDiv=t}_destroyTouchHook(){this._hookDiv&&(document.body.removeChild(this._hookDiv),this._hookDiv=null)}_activate(){var t;this._isActive||(this._isActive=!0,globalThis.document.addEventListener("mousemove",this._onMouseMove,!0),globalThis.removeEventListener("keydown",this._onKeyDown,!1),this._renderer.runners.postrender.add(this),(t=this._renderer.view.canvas.parentNode)==null||t.appendChild(this._div))}_deactivate(){var t;!this._isActive||this._isMobileAccessibility||(this._isActive=!1,globalThis.document.removeEventListener("mousemove",this._onMouseMove,!0),globalThis.addEventListener("keydown",this._onKeyDown,!1),this._renderer.runners.postrender.remove(this),(t=this._div.parentNode)==null||t.removeChild(this._div))}_updateAccessibleObjects(t){if(!t.visible||!t.accessibleChildren)return;t.accessible&&t.isInteractive()&&(t._accessibleActive||this._addChild(t),t._renderId=this._renderId);const e=t.children;if(e)for(let s=0;s title : ${t.title}
tabIndex: ${t.tabIndex}`}_capHitArea(t){t.x<0&&(t.width+=t.x,t.x=0),t.y<0&&(t.height+=t.y,t.y=0);const{width:e,height:s}=this._renderer;t.x+t.width>e&&(t.width=e-t.x),t.y+t.height>s&&(t.height=s-t.y)}_addChild(t){let e=this._pool.pop();e||(e=document.createElement("button"),e.style.width=`${as}px`,e.style.height=`${as}px`,e.style.backgroundColor=this.debug?"rgba(255,255,255,0.5)":"transparent",e.style.position="absolute",e.style.zIndex=Zl.toString(),e.style.borderStyle="none",navigator.userAgent.toLowerCase().includes("chrome")?e.setAttribute("aria-live","off"):e.setAttribute("aria-live","polite"),navigator.userAgent.match(/rv:.*Gecko\//)?e.setAttribute("aria-relevant","additions"):e.setAttribute("aria-relevant","text"),e.addEventListener("click",this._onClick.bind(this)),e.addEventListener("focus",this._onFocus.bind(this)),e.addEventListener("focusout",this._onFocusOut.bind(this))),e.style.pointerEvents=t.accessiblePointerEvents,e.type=t.accessibleType,t.accessibleTitle&&t.accessibleTitle!==null?e.title=t.accessibleTitle:(!t.accessibleHint||t.accessibleHint===null)&&(e.title=`container ${t.tabIndex}`),t.accessibleHint&&t.accessibleHint!==null&&e.setAttribute("aria-label",t.accessibleHint),this.debug&&this._updateDebugHTML(e),t._accessibleActive=!0,t._accessibleDiv=e,e.container=t,this._children.push(t),this._div.appendChild(t._accessibleDiv),t._accessibleDiv.tabIndex=t.tabIndex}_dispatchEvent(t,e){const{container:s}=t.target,i=this._renderer.events.rootBoundary,n=Object.assign(new Ke(i),{target:s});i.rootTarget=this._renderer.lastObjectRendered,e.forEach(o=>i.dispatchEvent(n,o))}_onClick(t){this._dispatchEvent(t,["click","pointertap","tap"])}_onFocus(t){t.target.getAttribute("aria-live")||t.target.setAttribute("aria-live","assertive"),this._dispatchEvent(t,["mouseover"])}_onFocusOut(t){t.target.getAttribute("aria-live")||t.target.setAttribute("aria-live","polite"),this._dispatchEvent(t,["mouseout"])}_onKeyDown(t){t.keyCode===yb&&this._activate()}_onMouseMove(t){t.movementX===0&&t.movementY===0||this._deactivate()}destroy(){this._destroyTouchHook(),this._div=null,globalThis.document.removeEventListener("mousemove",this._onMouseMove,!0),globalThis.removeEventListener("keydown",this._onKeyDown),this._pool=null,this._children=null,this._renderer=null}}en.extension={type:[v.WebGLSystem,v.WebGPUSystem],name:"accessibility"};const Jl={accessible:!1,accessibleTitle:null,accessibleHint:null,tabIndex:0,_accessibleActive:!1,_accessibleDiv:null,accessibleType:"button",accessiblePointerEvents:"auto",accessibleChildren:!0,_renderId:-1};D.add(en),V.mixin(Jl);class rn{static init(t){Object.defineProperty(this,"resizeTo",{set(e){globalThis.removeEventListener("resize",this.queueResize),this._resizeTo=e,e&&(globalThis.addEventListener("resize",this.queueResize),this.resize())},get(){return this._resizeTo}}),this.queueResize=()=>{this._resizeTo&&(this._cancelResize(),this._resizeId=requestAnimationFrame(()=>this.resize()))},this._cancelResize=()=>{this._resizeId&&(cancelAnimationFrame(this._resizeId),this._resizeId=null)},this.resize=()=>{if(!this._resizeTo)return;this._cancelResize();let e,s;if(this._resizeTo===globalThis.window)e=globalThis.innerWidth,s=globalThis.innerHeight;else{const{clientWidth:i,clientHeight:n}=this._resizeTo;e=i,s=n}this.renderer.resize(e,s),this.render()},this._resizeId=null,this._resizeTo=null,this.resizeTo=t.resizeTo||null}static destroy(){globalThis.removeEventListener("resize",this.queueResize),this._cancelResize(),this._cancelResize=null,this.queueResize=null,this.resizeTo=null,this.resize=null}}rn.extension=v.Application;var Xt=(r=>(r[r.INTERACTION=50]="INTERACTION",r[r.HIGH=25]="HIGH",r[r.NORMAL=0]="NORMAL",r[r.LOW=-25]="LOW",r[r.UTILITY=-50]="UTILITY",r))(Xt||{});class us{constructor(t,e=null,s=0,i=!1){this.next=null,this.previous=null,this._destroyed=!1,this._fn=t,this._context=e,this.priority=s,this._once=i}match(t,e=null){return this._fn===t&&this._context===e}emit(t){this._fn&&(this._context?this._fn.call(this._context,t):this._fn(t));const e=this.next;return this._once&&this.destroy(!0),this._destroyed&&(this.next=null),e}connect(t){this.previous=t,t.next&&(t.next.previous=this),this.next=t.next,t.next=this}destroy(t=!1){this._destroyed=!0,this._fn=null,this._context=null,this.previous&&(this.previous.next=this.next),this.next&&(this.next.previous=this.previous);const e=this.next;return this.next=t?null:e,this.previous=null,e}}const th=class yt{constructor(){this.autoStart=!1,this.deltaTime=1,this.lastTime=-1,this.speed=1,this.started=!1,this._requestId=null,this._maxElapsedMS=100,this._minElapsedMS=0,this._protected=!1,this._lastFrame=-1,this._head=new us(null,null,1/0),this.deltaMS=1/yt.targetFPMS,this.elapsedMS=1/yt.targetFPMS,this._tick=t=>{this._requestId=null,this.started&&(this.update(t),this.started&&this._requestId===null&&this._head.next&&(this._requestId=requestAnimationFrame(this._tick)))}}_requestIfNeeded(){this._requestId===null&&this._head.next&&(this.lastTime=performance.now(),this._lastFrame=this.lastTime,this._requestId=requestAnimationFrame(this._tick))}_cancelIfNeeded(){this._requestId!==null&&(cancelAnimationFrame(this._requestId),this._requestId=null)}_startIfPossible(){this.started?this._requestIfNeeded():this.autoStart&&this.start()}add(t,e,s=Xt.NORMAL){return this._addListener(new us(t,e,s))}addOnce(t,e,s=Xt.NORMAL){return this._addListener(new us(t,e,s,!0))}_addListener(t){let e=this._head.next,s=this._head;if(!e)t.connect(s);else{for(;e;){if(t.priority>e.priority){t.connect(s);break}s=e,e=e.next}t.previous||t.connect(s)}return this._startIfPossible(),this}remove(t,e){let s=this._head.next;for(;s;)s.match(t,e)?s=s.destroy():s=s.next;return this._head.next||this._cancelIfNeeded(),this}get count(){if(!this._head)return 0;let t=0,e=this._head;for(;e=e.next;)t++;return t}start(){this.started||(this.started=!0,this._requestIfNeeded())}stop(){this.started&&(this.started=!1,this._cancelIfNeeded())}destroy(){if(!this._protected){this.stop();let t=this._head.next;for(;t;)t=t.destroy(!0);this._head.destroy(),this._head=null}}update(t=performance.now()){let e;if(t>this.lastTime){if(e=this.elapsedMS=t-this.lastTime,e>this._maxElapsedMS&&(e=this._maxElapsedMS),e*=this.speed,this._minElapsedMS){const n=t-this._lastFrame|0;if(n{this._ticker.stop()},this.start=()=>{this._ticker.start()},this._ticker=null,this.ticker=t.sharedTicker?ht.shared:new ht,t.autoStart&&this.start()}static destroy(){if(this._ticker){const t=this._ticker;this.ticker=null,t.destroy()}}}sn.extension=v.Application,D.add(rn),D.add(sn);let wb=class{constructor(){this.interactionFrequency=10,this._deltaTime=0,this._didMove=!1,this._tickerAdded=!1,this._pauseUpdate=!0}init(t){this.removeTickerListener(),this.events=t,this.interactionFrequency=10,this._deltaTime=0,this._didMove=!1,this._tickerAdded=!1,this._pauseUpdate=!0}get pauseUpdate(){return this._pauseUpdate}set pauseUpdate(t){this._pauseUpdate=t}addTickerListener(){this._tickerAdded||!this.domElement||(ht.system.add(this._tickerUpdate,this,Xt.INTERACTION),this._tickerAdded=!0)}removeTickerListener(){this._tickerAdded&&(ht.system.remove(this._tickerUpdate,this),this._tickerAdded=!1)}pointerMoved(){this._didMove=!0}_update(){if(!this.domElement||this._pauseUpdate)return;if(this._didMove){this._didMove=!1;return}const t=this.events._rootPointerEvent;this.events.supportsTouchEvents&&t.pointerType==="touch"||globalThis.document.dispatchEvent(new PointerEvent("pointermove",{clientX:t.clientX,clientY:t.clientY}))}_tickerUpdate(t){this._deltaTime+=t.deltaTime,!(this._deltaTimes.priority-i.priority)}dispatchEvent(t,e){t.propagationStopped=!1,t.propagationImmediatelyStopped=!1,this.propagate(t,e),this.dispatch.emit(e||t.type,t)}mapEvent(t){if(!this.rootTarget)return;const e=this.mappingTable[t.type];if(e)for(let s=0,i=e.length;s=0;i--)if(t.currentTarget=s[i],this.notifyTarget(t,e),t.propagationStopped||t.propagationImmediatelyStopped)return}}all(t,e,s=this._allInteractiveElements){if(s.length===0)return;t.eventPhase=t.BUBBLING_PHASE;const i=Array.isArray(e)?e:[e];for(let n=s.length-1;n>=0;n--)i.forEach(o=>{t.currentTarget=s[n],this.notifyTarget(t,o)})}propagationPath(t){const e=[t];for(let s=0;s=0;c--){const d=h[c],p=this.hitTestMoveRecursive(d,this._isInteractive(e)?e:d.eventMode,s,i,n,o||n(t,s));if(p){if(p.length>0&&!p[p.length-1].parent)continue;const f=t.isInteractive();(p.length>0||f)&&(f&&this._allInteractiveElements.push(t),p.push(t)),this._hitElements.length===0&&(this._hitElements=p),a=!0}}}const u=this._isInteractive(e),l=t.isInteractive();return l&&l&&this._allInteractiveElements.push(t),o||this._hitElements.length>0?null:a?this._hitElements:u&&!n(t,s)&&i(t,s)?l?[t]:[]:null}hitTestRecursive(t,e,s,i,n){if(this._interactivePrune(t)||n(t,s))return null;if((t.eventMode==="dynamic"||e==="dynamic")&&(zt.pauseUpdate=!1),t.interactiveChildren&&t.children){const u=t.children,l=s;for(let h=u.length-1;h>=0;h--){const c=u[h],d=this.hitTestRecursive(c,this._isInteractive(e)?e:c.eventMode,l,i,n);if(d){if(d.length>0&&!d[d.length-1].parent)continue;const p=t.isInteractive();return(d.length>0||p)&&d.push(t),d}}}const o=this._isInteractive(e),a=t.isInteractive();return o&&i(t,s)?a?[t]:[]:null}_isInteractive(t){return t==="static"||t==="dynamic"}_interactivePrune(t){return!t||!t.visible||!t.renderable||t.eventMode==="none"||t.eventMode==="passive"&&!t.interactiveChildren}hitPruneFn(t,e){if(t.hitArea&&(t.worldTransform.applyInverse(e,lr),!t.hitArea.contains(lr.x,lr.y)))return!0;if(t.effects&&t.effects.length)for(let s=0;s0&&u!==n.target){const c=t.type==="mousemove"?"mouseout":"pointerout",d=this.createPointerEvent(t,c,u);if(this.dispatchEvent(d,"pointerout"),o&&this.dispatchEvent(d,"mouseout"),!n.composedPath().includes(u)){const p=this.createPointerEvent(t,"pointerleave",u);for(p.eventPhase=p.AT_TARGET;p.target&&!n.composedPath().includes(p.target);)p.currentTarget=p.target,this.notifyTarget(p),o&&this.notifyTarget(p,"mouseleave"),p.target=p.target.parent;this.freeEvent(p)}this.freeEvent(d)}if(u!==n.target){const c=t.type==="mousemove"?"mouseover":"pointerover",d=this.clonePointerEvent(n,c);this.dispatchEvent(d,"pointerover"),o&&this.dispatchEvent(d,"mouseover");let p=u==null?void 0:u.parent;for(;p&&p!==this.rootTarget.parent&&p!==n.target;)p=p.parent;if(!p||p===this.rootTarget.parent){const f=this.clonePointerEvent(n,"pointerenter");for(f.eventPhase=f.AT_TARGET;f.target&&f.target!==u&&f.target!==this.rootTarget.parent;)f.currentTarget=f.target,this.notifyTarget(f),o&&this.notifyTarget(f,"mouseenter"),f.target=f.target.parent;this.freeEvent(f)}this.freeEvent(d)}const l=[],h=(s=this.enableGlobalMoveEvents)!=null?s:!0;this.moveOnAll?l.push("pointermove"):this.dispatchEvent(n,"pointermove"),h&&l.push("globalpointermove"),n.pointerType==="touch"&&(this.moveOnAll?l.splice(1,0,"touchmove"):this.dispatchEvent(n,"touchmove"),h&&l.push("globaltouchmove")),o&&(this.moveOnAll?l.splice(1,0,"mousemove"):this.dispatchEvent(n,"mousemove"),h&&l.push("globalmousemove"),this.cursor=(i=n.target)==null?void 0:i.cursor),l.length>0&&this.all(n,l),this._allInteractiveElements.length=0,this._hitElements.length=0,a.overTargets=n.composedPath(),this.freeEvent(n)}mapPointerOver(t){var e;if(!(t instanceof At))return;const s=this.trackingData(t.pointerId),i=this.createPointerEvent(t),n=i.pointerType==="mouse"||i.pointerType==="pen";this.dispatchEvent(i,"pointerover"),n&&this.dispatchEvent(i,"mouseover"),i.pointerType==="mouse"&&(this.cursor=(e=i.target)==null?void 0:e.cursor);const o=this.clonePointerEvent(i,"pointerenter");for(o.eventPhase=o.AT_TARGET;o.target&&o.target!==this.rootTarget.parent;)o.currentTarget=o.target,this.notifyTarget(o),n&&this.notifyTarget(o,"mouseenter"),o.target=o.target.parent;s.overTargets=i.composedPath(),this.freeEvent(i),this.freeEvent(o)}mapPointerOut(t){if(!(t instanceof At))return;const e=this.trackingData(t.pointerId);if(e.overTargets){const s=t.pointerType==="mouse"||t.pointerType==="pen",i=this.findMountedTarget(e.overTargets),n=this.createPointerEvent(t,"pointerout",i);this.dispatchEvent(n),s&&this.dispatchEvent(n,"mouseout");const o=this.createPointerEvent(t,"pointerleave",i);for(o.eventPhase=o.AT_TARGET;o.target&&o.target!==this.rootTarget.parent;)o.currentTarget=o.target,this.notifyTarget(o),s&&this.notifyTarget(o,"mouseleave"),o.target=o.target.parent;e.overTargets=null,this.freeEvent(n),this.freeEvent(o)}this.cursor=null}mapPointerUp(t){if(!(t instanceof At))return;const e=performance.now(),s=this.createPointerEvent(t);if(this.dispatchEvent(s,"pointerup"),s.pointerType==="touch")this.dispatchEvent(s,"touchend");else if(s.pointerType==="mouse"||s.pointerType==="pen"){const a=s.button===2;this.dispatchEvent(s,a?"rightup":"mouseup")}const i=this.trackingData(t.pointerId),n=this.findMountedTarget(i.pressTargetsByButton[t.button]);let o=n;if(n&&!s.composedPath().includes(n)){let a=n;for(;a&&!s.composedPath().includes(a);){if(s.currentTarget=a,this.notifyTarget(s,"pointerupoutside"),s.pointerType==="touch")this.notifyTarget(s,"touchendoutside");else if(s.pointerType==="mouse"||s.pointerType==="pen"){const u=s.button===2;this.notifyTarget(s,u?"rightupoutside":"mouseupoutside")}a=a.parent}delete i.pressTargetsByButton[t.button],o=a}if(o){const a=this.clonePointerEvent(s,"click");a.target=o,a.path=null,i.clicksByButton[t.button]||(i.clicksByButton[t.button]={clickCount:0,target:a.target,timeStamp:e});const u=i.clicksByButton[t.button];if(u.target===a.target&&e-u.timeStamp<200?++u.clickCount:u.clickCount=1,u.target=a.target,u.timeStamp=e,a.detail=u.clickCount,a.pointerType==="mouse"){const l=a.button===2;this.dispatchEvent(a,l?"rightclick":"click")}else a.pointerType==="touch"&&this.dispatchEvent(a,"tap");this.dispatchEvent(a,"pointertap"),this.freeEvent(a)}this.freeEvent(s)}mapPointerUpOutside(t){if(!(t instanceof At))return;const e=this.trackingData(t.pointerId),s=this.findMountedTarget(e.pressTargetsByButton[t.button]),i=this.createPointerEvent(t);if(s){let n=s;for(;n;)i.currentTarget=n,this.notifyTarget(i,"pointerupoutside"),i.pointerType==="touch"?this.notifyTarget(i,"touchendoutside"):(i.pointerType==="mouse"||i.pointerType==="pen")&&this.notifyTarget(i,i.button===2?"rightupoutside":"mouseupoutside"),n=n.parent;delete e.pressTargetsByButton[t.button]}this.freeEvent(i)}mapWheel(t){if(!(t instanceof he))return;const e=this.createWheelEvent(t);this.dispatchEvent(e),this.freeEvent(e)}findMountedTarget(t){if(!t)return null;let e=t[0];for(let s=1;st in r?Ob(r,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):r[t]=e,Ib=(r,t)=>{for(var e in t||(t={}))Cb.call(t,e)&&sh(r,e,t[e]);if(rh)for(var e of rh(t))Gb.call(t,e)&&sh(r,e,t[e]);return r};const Bb=1,Fb={touchstart:"pointerdown",touchend:"pointerup",touchendoutside:"pointerupoutside",touchmove:"pointermove",touchcancel:"pointercancel"},nn=class ju{constructor(t){this.supportsTouchEvents="ontouchstart"in globalThis,this.supportsPointerEvents=!!globalThis.PointerEvent,this.domElement=null,this.resolution=1,this.renderer=t,this.rootBoundary=new eh(null),zt.init(this),this.autoPreventDefault=!0,this._eventsAdded=!1,this._rootPointerEvent=new At(null),this._rootWheelEvent=new he(null),this.cursorStyles={default:"inherit",pointer:"pointer"},this.features=new Proxy(Ib({},ju.defaultEventFeatures),{set:(e,s,i)=>(s==="globalMove"&&(this.rootBoundary.enableGlobalMoveEvents=i),e[s]=i,!0)}),this._onPointerDown=this._onPointerDown.bind(this),this._onPointerMove=this._onPointerMove.bind(this),this._onPointerUp=this._onPointerUp.bind(this),this._onPointerOverOut=this._onPointerOverOut.bind(this),this.onWheel=this.onWheel.bind(this)}static get defaultEventMode(){return this._defaultEventMode}init(t){var e,s;const{canvas:i,resolution:n}=this.renderer;this.setTargetElement(i),this.resolution=n,ju._defaultEventMode=(e=t.eventMode)!=null?e:"passive",Object.assign(this.features,(s=t.eventFeatures)!=null?s:{}),this.rootBoundary.enableGlobalMoveEvents=this.features.globalMove}resolutionChange(t){this.resolution=t}destroy(){this.setTargetElement(null),this.renderer=null,this._currentCursor=null}setCursor(t){t=t||"default";let e=!0;if(globalThis.OffscreenCanvas&&this.domElement instanceof OffscreenCanvas&&(e=!1),this._currentCursor===t)return;this._currentCursor=t;const s=this.cursorStyles[t];if(s)switch(typeof s){case"string":e&&(this.domElement.style.cursor=s);break;case"function":s(t);break;case"object":e&&Object.assign(this.domElement.style,s);break}else e&&typeof t=="string"&&!Object.prototype.hasOwnProperty.call(this.cursorStyles,t)&&(this.domElement.style.cursor=t)}get pointer(){return this._rootPointerEvent}_onPointerDown(t){if(!this.features.click)return;this.rootBoundary.rootTarget=this.renderer.lastObjectRendered;const e=this._normalizeToPointerData(t);this.autoPreventDefault&&e[0].isNormalized&&(t.cancelable||!("cancelable"in t))&&t.preventDefault();for(let s=0,i=e.length;s0&&(e=t.composedPath()[0]);const s=e!==this.domElement?"outside":"",i=this._normalizeToPointerData(t);for(let n=0,o=i.length;n{u.off(r,a,o)}),n?u.once(r,a,o):u.on(r,a,o)},removeEventListener(r,t,e){const s=typeof e=="boolean"&&e||typeof e=="object"&&e.capture,i=typeof t=="function"?void 0:t;r=s?`${r}capture`:r,t=typeof t=="function"?t:t.handleEvent,this.off(r,t,i)},dispatchEvent(r){if(!(r instanceof Ke))throw new Error("Container cannot propagate events outside of the Federated Events API");return r.defaultPrevented=!1,r.path=null,r.target=this,r.manager.dispatchEvent(r),!r.defaultPrevented}};D.add(on),V.mixin(ih);var gt=(r=>(r[r.Low=0]="Low",r[r.Normal=1]="Normal",r[r.High=2]="High",r))(gt||{});const nh={createCanvas:(r,t)=>{const e=document.createElement("canvas");return e.width=r,e.height=t,e},getCanvasRenderingContext2D:()=>CanvasRenderingContext2D,getWebGLRenderingContext:()=>WebGLRenderingContext,getWebGL2RenderingContext:()=>WebGL2RenderingContext,getNavigator:()=>navigator,getBaseUrl:()=>{var r;return(r=document.baseURI)!=null?r:window.location.href},getFontFaceSet:()=>document.fonts,fetch:(r,t)=>fetch(r,t),parseXML:r=>new DOMParser().parseFromString(r,"text/xml")};let oh=nh;const X={get(){return oh},set(r){oh=r}};function Ot(r){if(typeof r!="string")throw new TypeError(`Path must be a string. Received ${JSON.stringify(r)}`)}function hr(r){return r.split("?")[0].split("#")[0]}function Db(r){return r.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function Ub(r,t,e){return r.replace(new RegExp(Db(t),"g"),e)}function kb(r,t){let e="",s=0,i=-1,n=0,o=-1;for(let a=0;a<=r.length;++a){if(a2){const u=e.lastIndexOf("/");if(u!==e.length-1){u===-1?(e="",s=0):(e=e.slice(0,u),s=e.length-1-e.lastIndexOf("/")),i=a,n=0;continue}}else if(e.length===2||e.length===1){e="",s=0,i=a,n=0;continue}}t&&(e.length>0?e+="/..":e="..",s=2)}else e.length>0?e+=`/${r.slice(i+1,a)}`:e=r.slice(i+1,a),s=a-i-1;i=a,n=0}else o===46&&n!==-1?++n:n=-1}return e}const dt={toPosix(r){return Ub(r,"\\","/")},isUrl(r){return/^https?:/.test(this.toPosix(r))},isDataUrl(r){return/^data:([a-z]+\/[a-z0-9-+.]+(;[a-z0-9-.!#$%*+.{}|~`]+=[a-z0-9-.!#$%*+.{}()_|~`]+)*)?(;base64)?,([a-z0-9!$&',()*+;=\-._~:@\/?%\s<>]*?)$/i.test(r)},isBlobUrl(r){return r.startsWith("blob:")},hasProtocol(r){return/^[^/:]+:/.test(this.toPosix(r))},getProtocol(r){Ot(r),r=this.toPosix(r);const t=/^file:\/\/\//.exec(r);if(t)return t[0];const e=/^[^/:]+:\/{0,2}/.exec(r);return e?e[0]:""},toAbsolute(r,t,e){if(Ot(r),this.isDataUrl(r)||this.isBlobUrl(r))return r;const s=hr(this.toPosix(t!=null?t:X.get().getBaseUrl())),i=hr(this.toPosix(e!=null?e:this.rootname(s)));return r=this.toPosix(r),r.startsWith("/")?dt.join(i,r.slice(1)):this.isAbsolute(r)?r:this.join(s,r)},normalize(r){if(Ot(r),r.length===0)return".";if(this.isDataUrl(r)||this.isBlobUrl(r))return r;r=this.toPosix(r);let t="";const e=r.startsWith("/");this.hasProtocol(r)&&(t=this.rootname(r),r=r.slice(t.length));const s=r.endsWith("/");return r=kb(r,!1),r.length>0&&s&&(r+="/"),e?`/${r}`:t+r},isAbsolute(r){return Ot(r),r=this.toPosix(r),this.hasProtocol(r)?!0:r.startsWith("/")},join(...r){var t;if(r.length===0)return".";let e;for(let s=0;s0)if(e===void 0)e=i;else{const n=(t=r[s-1])!=null?t:"";this.joinExtensions.includes(this.extname(n).toLowerCase())?e+=`/../${i}`:e+=`/${i}`}}return e===void 0?".":this.normalize(e)},dirname(r){if(Ot(r),r.length===0)return".";r=this.toPosix(r);let t=r.charCodeAt(0);const e=t===47;let s=-1,i=!0;const n=this.getProtocol(r),o=r;r=r.slice(n.length);for(let a=r.length-1;a>=1;--a)if(t=r.charCodeAt(a),t===47){if(!i){s=a;break}}else i=!1;return s===-1?e?"/":this.isUrl(o)?n+r:n:e&&s===1?"//":n+r.slice(0,s)},rootname(r){Ot(r),r=this.toPosix(r);let t="";if(r.startsWith("/")?t="/":t=this.getProtocol(r),this.isUrl(r)){const e=r.indexOf("/",t.length);e!==-1?t=r.slice(0,e):t=r,t.endsWith("/")||(t+="/")}return t},basename(r,t){Ot(r),t&&Ot(t),r=hr(this.toPosix(r));let e=0,s=-1,i=!0,n;if(t!==void 0&&t.length>0&&t.length<=r.length){if(t.length===r.length&&t===r)return"";let o=t.length-1,a=-1;for(n=r.length-1;n>=0;--n){const u=r.charCodeAt(n);if(u===47){if(!i){e=n+1;break}}else a===-1&&(i=!1,a=n+1),o>=0&&(u===t.charCodeAt(o)?--o===-1&&(s=n):(o=-1,s=a))}return e===s?s=a:s===-1&&(s=r.length),r.slice(e,s)}for(n=r.length-1;n>=0;--n)if(r.charCodeAt(n)===47){if(!i){e=n+1;break}}else s===-1&&(i=!1,s=n+1);return s===-1?"":r.slice(e,s)},extname(r){Ot(r),r=hr(this.toPosix(r));let t=-1,e=0,s=-1,i=!0,n=0;for(let o=r.length-1;o>=0;--o){const a=r.charCodeAt(o);if(a===47){if(!i){e=o+1;break}continue}s===-1&&(i=!1,s=o+1),a===46?t===-1?t=o:n!==1&&(n=1):t!==-1&&(n=-1)}return t===-1||s===-1||n===0||n===1&&t===s-1&&t===e+1?"":r.slice(t,s)},parse(r){Ot(r);const t={root:"",dir:"",base:"",ext:"",name:""};if(r.length===0)return t;r=hr(this.toPosix(r));let e=r.charCodeAt(0);const s=this.isAbsolute(r);let i;const n="";t.root=this.rootname(r),s||this.hasProtocol(r)?i=1:i=0;let o=-1,a=0,u=-1,l=!0,h=r.length-1,c=0;for(;h>=i;--h){if(e=r.charCodeAt(h),e===47){if(!l){a=h+1;break}continue}u===-1&&(l=!1,u=h+1),e===46?o===-1?o=h:c!==1&&(c=1):o!==-1&&(c=-1)}return o===-1||u===-1||c===0||c===1&&o===u-1&&o===a+1?u!==-1&&(a===0&&s?t.base=t.name=r.slice(1,u):t.base=t.name=r.slice(a,u)):(a===0&&s?(t.name=r.slice(1,o),t.base=r.slice(1,u)):(t.name=r.slice(a,o),t.base=r.slice(a,u)),t.ext=r.slice(o,u)),t.dir=this.dirname(r),n&&(t.dir=n+t.dir),t},sep:"/",delimiter:":",joinExtensions:[".html"]},Pt=(r,t,e=!1)=>(Array.isArray(r)||(r=[r]),t?r.map(s=>typeof s=="string"||e?t(s):s):r);function ah(r,t,e,s,i){const n=t[e];for(let o=0;o{const o=n.substring(1,n.length-1).split(",");i.push(o)}),ah(r,i,0,e,s)}else s.push(r);return s}const cr=r=>!Array.isArray(r);var Lb=Object.defineProperty,$b=Object.defineProperties,Nb=Object.getOwnPropertyDescriptors,lh=Object.getOwnPropertySymbols,Hb=Object.prototype.hasOwnProperty,Xb=Object.prototype.propertyIsEnumerable,hh=(r,t,e)=>t in r?Lb(r,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):r[t]=e,Me=(r,t)=>{for(var e in t||(t={}))Hb.call(t,e)&&hh(r,e,t[e]);if(lh)for(var e of lh(t))Xb.call(t,e)&&hh(r,e,t[e]);return r},zb=(r,t)=>$b(r,Nb(t));class qt{constructor(){this._defaultBundleIdentifierOptions={connector:"-",createBundleAssetId:(t,e)=>`${t}${this._bundleIdConnector}${e}`,extractAssetIdFromBundle:(t,e)=>e.replace(`${t}${this._bundleIdConnector}`,"")},this._bundleIdConnector=this._defaultBundleIdentifierOptions.connector,this._createBundleAssetId=this._defaultBundleIdentifierOptions.createBundleAssetId,this._extractAssetIdFromBundle=this._defaultBundleIdentifierOptions.extractAssetIdFromBundle,this._assetMap={},this._preferredOrder=[],this._parsers=[],this._resolverHash={},this._bundles={}}setBundleIdentifier(t){var e,s,i;if(this._bundleIdConnector=(e=t.connector)!=null?e:this._bundleIdConnector,this._createBundleAssetId=(s=t.createBundleAssetId)!=null?s:this._createBundleAssetId,this._extractAssetIdFromBundle=(i=t.extractAssetIdFromBundle)!=null?i:this._extractAssetIdFromBundle,this._extractAssetIdFromBundle("foo",this._createBundleAssetId("foo","bar"))!=="bar")throw new Error("[Resolver] GenerateBundleAssetId are not working correctly")}prefer(...t){t.forEach(e=>{this._preferredOrder.push(e),e.priority||(e.priority=Object.keys(e.params))}),this._resolverHash={}}set basePath(t){this._basePath=t}get basePath(){return this._basePath}set rootPath(t){this._rootPath=t}get rootPath(){return this._rootPath}get parsers(){return this._parsers}reset(){this.setBundleIdentifier(this._defaultBundleIdentifierOptions),this._assetMap={},this._preferredOrder=[],this._resolverHash={},this._rootPath=null,this._basePath=null,this._manifest=null,this._bundles={},this._defaultSearchParams=null}setDefaultSearchParams(t){if(typeof t=="string")this._defaultSearchParams=t;else{const e=t;this._defaultSearchParams=Object.keys(e).map(s=>`${encodeURIComponent(s)}=${encodeURIComponent(e[s])}`).join("&")}}getAlias(t){const{alias:e,src:s}=t;return Pt(e||s,i=>typeof i=="string"?i:Array.isArray(i)?i.map(n=>{var o;return(o=n==null?void 0:n.src)!=null?o:n}):i!=null&&i.src?i.src:i,!0)}addManifest(t){this._manifest,this._manifest=t,t.bundles.forEach(e=>{this.addBundle(e.name,e.assets)})}addBundle(t,e){const s=[];let i=e;Array.isArray(e)||(i=Object.entries(e).map(([n,o])=>typeof o=="string"||Array.isArray(o)?{alias:n,src:o}:Me({alias:n},o))),i.forEach(n=>{const o=n.src,a=n.alias;let u;if(typeof a=="string"){const l=this._createBundleAssetId(t,a);s.push(l),u=[a,l]}else{const l=a.map(h=>this._createBundleAssetId(t,h));s.push(...l),u=[...a,...l]}this.add(zb(Me({},n),{alias:u,src:o}))}),this._bundles[t]=s}add(t){const e=[];Array.isArray(t)?e.push(...t):e.push(t);let s;Pt(e).forEach(i=>{const{src:n}=i;let{data:o,format:a,loadParser:u}=i;const l=Pt(n).map(d=>typeof d=="string"?uh(d):Array.isArray(d)?d:[d]),h=this.getAlias(i),c=[];l.forEach(d=>{d.forEach(p=>{var f,g,m;let _={};if(typeof p!="object"){_.src=p;for(let x=0;x{this._assetMap[d]=c})})}resolveBundle(t){const e=cr(t);t=Pt(t);const s={};return t.forEach(i=>{const n=this._bundles[i];if(n){const o=this.resolve(n),a={};for(const u in o){const l=o[u];a[this._extractAssetIdFromBundle(i,u)]=l}s[i]=a}}),e?s[t[0]]:s}resolveUrl(t){const e=this.resolve(t);if(typeof t!="string"){const s={};for(const i in e)s[i]=e[i].src;return s}return e.src}resolve(t){const e=cr(t);t=Pt(t);const s={};return t.forEach(i=>{if(!this._resolverHash[i])if(this._assetMap[i]){let n=this._assetMap[i];const o=this._getPreferredOrder(n);o==null||o.priority.forEach(a=>{o.params[a].forEach(u=>{const l=n.filter(h=>h[a]?h[a]===u:!1);l.length&&(n=l)})}),this._resolverHash[i]=n[0]}else this._resolverHash[i]=this._buildResolvedAsset({alias:[i],src:i},{});s[i]=this._resolverHash[i]}),e?s[t[0]]:s}hasKey(t){return!!this._assetMap[t]}hasBundle(t){return!!this._bundles[t]}_getPreferredOrder(t){for(let e=0;en.params.format.includes(s.format));if(i)return i}return this._preferredOrder[0]}_appendDefaultSearchParams(t){if(!this._defaultSearchParams)return t;const e=/\?/.test(t)?"&":"?";return`${t}${e}${this._defaultSearchParams}`}_buildResolvedAsset(t,e){var s,i;const{aliases:n,data:o,loadParser:a,format:u}=e;return(this._basePath||this._rootPath)&&(t.src=dt.toAbsolute(t.src,this._basePath,this._rootPath)),t.alias=(s=n!=null?n:t.alias)!=null?s:[t.src],t.src=this._appendDefaultSearchParams(t.src),t.data=Me(Me({},o||{}),t.data),t.loadParser=a!=null?a:t.loadParser,t.format=(i=u!=null?u:t.format)!=null?i:ch(t.src),t}}qt.RETINA_PREFIX=/@([0-9\.]+)x/;function ch(r){return r.split(".").pop().split("?").shift().split("#").shift()}const ls=(r,t)=>{const e=t.split("?")[1];return e&&(r+=`?${e}`),r},ce=[1,1,0,-1,-1,-1,0,1,1,1,0,-1,-1,-1,0,1],de=[0,1,1,1,0,-1,-1,-1,0,1,1,1,0,-1,-1,-1],pe=[0,-1,-1,-1,0,1,1,1,0,1,1,1,0,-1,-1,-1],fe=[1,1,0,-1,-1,-1,0,1,-1,-1,0,1,1,1,0,-1],an=[],dh=[],hs=Math.sign;function jb(){for(let r=0;r<16;r++){const t=[];an.push(t);for(let e=0;e<16;e++){const s=hs(ce[r]*ce[e]+pe[r]*de[e]),i=hs(de[r]*ce[e]+fe[r]*de[e]),n=hs(ce[r]*pe[e]+pe[r]*fe[e]),o=hs(de[r]*pe[e]+fe[r]*fe[e]);for(let a=0;a<16;a++)if(ce[a]===s&&de[a]===i&&pe[a]===n&&fe[a]===o){t.push(a);break}}}for(let r=0;r<16;r++){const t=new G;t.set(ce[r],de[r],pe[r],fe[r],0,0),dh.push(t)}}jb();const U={E:0,SE:1,S:2,SW:3,W:4,NW:5,N:6,NE:7,MIRROR_VERTICAL:8,MAIN_DIAGONAL:10,MIRROR_HORIZONTAL:12,REVERSE_DIAGONAL:14,uX:r=>ce[r],uY:r=>de[r],vX:r=>pe[r],vY:r=>fe[r],inv:r=>r&8?r&15:-r&7,add:(r,t)=>an[r][t],sub:(r,t)=>an[r][U.inv(t)],rotate180:r=>r^4,isVertical:r=>(r&3)===2,byDirection:(r,t)=>Math.abs(r)*2<=Math.abs(t)?t>=0?U.S:U.N:Math.abs(t)*2<=Math.abs(r)?r>0?U.E:U.W:t>0?r>0?U.SE:U.SW:r>0?U.NE:U.NW,matrixAppendRotationInv:(r,t,e=0,s=0)=>{const i=dh[U.inv(t)];i.tx=e,i.ty=s,r.append(i)}},un=()=>{};function me(r){return r+=r===0?1:0,--r,r|=r>>>1,r|=r>>>2,r|=r>>>4,r|=r>>>8,r|=r>>>16,r+1}function ln(r){return!(r&r-1)&&!!r}function Vb(r){let t=(r>65535?1:0)<<4;r>>>=t;let e=(r>255?1:0)<<3;return r>>>=e,t|=e,e=(r>15?1:0)<<2,r>>>=e,t|=e,e=(r>3?1:0)<<1,r>>>=e,t|=e,t|r>>1}function Zt(r){const t={};for(const e in r)r[e]!==void 0&&(t[e]=r[e]);return t}var Wb=Object.defineProperty,ph=Object.getOwnPropertySymbols,Yb=Object.prototype.hasOwnProperty,Kb=Object.prototype.propertyIsEnumerable,fh=(r,t,e)=>t in r?Wb(r,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):r[t]=e,mh=(r,t)=>{for(var e in t||(t={}))Yb.call(t,e)&&fh(r,e,t[e]);if(ph)for(var e of ph(t))Kb.call(t,e)&&fh(r,e,t[e]);return r};const gh=Object.create(null);function qb(r){const t=gh[r];return t===void 0&&(gh[r]=Z("resource")),t}const _h=class yx extends ct{constructor(t={}){var e,s,i,n,o,a,u;super(),this._resourceType="textureSampler",this._touched=0,this._maxAnisotropy=1,t=mh(mh({},yx.defaultOptions),t),this.addressMode=t.addressMode,this.addressModeU=(e=t.addressModeU)!=null?e:this.addressModeU,this.addressModeV=(s=t.addressModeV)!=null?s:this.addressModeV,this.addressModeW=(i=t.addressModeW)!=null?i:this.addressModeW,this.scaleMode=t.scaleMode,this.magFilter=(n=t.magFilter)!=null?n:this.magFilter,this.minFilter=(o=t.minFilter)!=null?o:this.minFilter,this.mipmapFilter=(a=t.mipmapFilter)!=null?a:this.mipmapFilter,this.lodMinClamp=t.lodMinClamp,this.lodMaxClamp=t.lodMaxClamp,this.compare=t.compare,this.maxAnisotropy=(u=t.maxAnisotropy)!=null?u:1}set addressMode(t){this.addressModeU=t,this.addressModeV=t,this.addressModeW=t}get addressMode(){return this.addressModeU}set wrapMode(t){this.addressMode=t}get wrapMode(){return this.addressMode}set scaleMode(t){this.magFilter=t,this.minFilter=t,this.mipmapFilter=t}get scaleMode(){return this.magFilter}set maxAnisotropy(t){this._maxAnisotropy=Math.min(t,16),this._maxAnisotropy>1&&(this.scaleMode="linear")}get maxAnisotropy(){return this._maxAnisotropy}get _resourceId(){return this._sharedResourceId||this._generateResourceId()}update(){this.emit("change",this),this._sharedResourceId=null}_generateResourceId(){const t=`${this.addressModeU}-${this.addressModeV}-${this.addressModeW}-${this.magFilter}-${this.minFilter}-${this.mipmapFilter}-${this.lodMinClamp}-${this.lodMaxClamp}-${this.compare}-${this._maxAnisotropy}`;return this._sharedResourceId=qb(t),this._resourceId}destroy(){this.emit("destroy",this),this.removeAllListeners()}};_h.defaultOptions={addressMode:"clamp-to-edge",scaleMode:"linear"};let xh=_h;var Zb=Object.defineProperty,bh=Object.getOwnPropertySymbols,Qb=Object.prototype.hasOwnProperty,Jb=Object.prototype.propertyIsEnumerable,vh=(r,t,e)=>t in r?Zb(r,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):r[t]=e,yh=(r,t)=>{for(var e in t||(t={}))Qb.call(t,e)&&vh(r,e,t[e]);if(bh)for(var e of bh(t))Jb.call(t,e)&&vh(r,e,t[e]);return r};const Th=class Tx extends ct{constructor(t={}){var e,s,i;super(),this.options=t,this.uid=Z("textureSource"),this._resourceType="textureSource",this._resourceId=Z("resource"),this.uploadMethodId="unknown",this._resolution=1,this.pixelWidth=1,this.pixelHeight=1,this.width=1,this.height=1,this.sampleCount=1,this.mipLevelCount=1,this.autoGenerateMipmaps=!1,this.format="rgba8unorm",this.dimension="2d",this.antialias=!1,this._touched=0,this._batchTick=-1,this._textureBindLocation=-1,t=yh(yh({},Tx.defaultOptions),t),this.label=(e=t.label)!=null?e:"",this.resource=t.resource,this.autoGarbageCollect=t.autoGarbageCollect,this._resolution=t.resolution,t.width?this.pixelWidth=t.width*this._resolution:this.pixelWidth=this.resource&&(s=this.resourceWidth)!=null?s:1,t.height?this.pixelHeight=t.height*this._resolution:this.pixelHeight=this.resource&&(i=this.resourceHeight)!=null?i:1,this.width=this.pixelWidth/this._resolution,this.height=this.pixelHeight/this._resolution,this.format=t.format,this.dimension=t.dimensions,this.mipLevelCount=t.mipLevelCount,this.autoGenerateMipmaps=t.autoGenerateMipmaps,this.sampleCount=t.sampleCount,this.antialias=t.antialias,this.alphaMode=t.alphaMode,this.style=new xh(Zt(t)),this.destroyed=!1,this._refreshPOT()}get source(){return this}get style(){return this._style}set style(t){var e,s;this.style!==t&&((e=this._style)==null||e.off("change",this._onStyleChange,this),this._style=t,(s=this._style)==null||s.on("change",this._onStyleChange,this),this._onStyleChange())}get addressMode(){return this._style.addressMode}set addressMode(t){this._style.addressMode=t}get repeatMode(){return this._style.addressMode}set repeatMode(t){this._style.addressMode=t}get magFilter(){return this._style.magFilter}set magFilter(t){this._style.magFilter=t}get minFilter(){return this._style.minFilter}set minFilter(t){this._style.minFilter=t}get mipmapFilter(){return this._style.mipmapFilter}set mipmapFilter(t){this._style.mipmapFilter=t}get lodMinClamp(){return this._style.lodMinClamp}set lodMinClamp(t){this._style.lodMinClamp=t}get lodMaxClamp(){return this._style.lodMaxClamp}set lodMaxClamp(t){this._style.lodMaxClamp=t}_onStyleChange(){this.emit("styleChange",this)}update(){if(this.resource){const t=this._resolution;if(this.resize(this.resourceWidth/t,this.resourceHeight/t))return}this.emit("update",this)}destroy(){this.destroyed=!0,this.emit("destroy",this),this._style&&(this._style.destroy(),this._style=null),this.uploadMethodId=null,this.resource=null,this.removeAllListeners()}unload(){this._resourceId=Z("resource"),this.emit("change",this),this.emit("unload",this)}get resourceWidth(){const{resource:t}=this;return t.naturalWidth||t.videoWidth||t.displayWidth||t.width}get resourceHeight(){const{resource:t}=this;return t.naturalHeight||t.videoHeight||t.displayHeight||t.height}get resolution(){return this._resolution}set resolution(t){this._resolution!==t&&(this._resolution=t,this.width=this.pixelWidth/t,this.height=this.pixelHeight/t)}resize(t,e,s){s=s||this._resolution,t=t||this.width,e=e||this.height;const i=Math.round(t*s),n=Math.round(e*s);return this.width=i/s,this.height=n/s,this._resolution=s,this.pixelWidth===i&&this.pixelHeight===n?!1:(this._refreshPOT(),this.pixelWidth=i,this.pixelHeight=n,this.emit("resize",this),this._resourceId=Z("resource"),this.emit("change",this),!0)}updateMipmaps(){this.autoGenerateMipmaps&&this.mipLevelCount>1&&this.emit("updateMipmaps",this)}set wrapMode(t){this._style.wrapMode=t}get wrapMode(){return this._style.wrapMode}set scaleMode(t){this._style.scaleMode=t}get scaleMode(){return this._style.scaleMode}_refreshPOT(){this.isPowerOfTwo=ln(this.pixelWidth)&&ln(this.pixelHeight)}static test(t){throw new Error("Unimplemented")}};Th.defaultOptions={resolution:1,format:"bgra8unorm",alphaMode:"premultiply-alpha-on-upload",dimensions:"2d",mipLevelCount:1,autoGenerateMipmaps:!1,sampleCount:1,antialias:!1,autoGarbageCollect:!1};let et=Th;var tv=Object.defineProperty,ev=Object.defineProperties,rv=Object.getOwnPropertyDescriptors,Sh=Object.getOwnPropertySymbols,sv=Object.prototype.hasOwnProperty,iv=Object.prototype.propertyIsEnumerable,Eh=(r,t,e)=>t in r?tv(r,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):r[t]=e,nv=(r,t)=>{for(var e in t||(t={}))sv.call(t,e)&&Eh(r,e,t[e]);if(Sh)for(var e of Sh(t))iv.call(t,e)&&Eh(r,e,t[e]);return r},ov=(r,t)=>ev(r,rv(t));class cs extends et{constructor(t){const e=t.resource||new Float32Array(t.width*t.height*4);let s=t.format;s||(e instanceof Float32Array?s="rgba32float":e instanceof Int32Array||e instanceof Uint32Array?s="rgba32uint":e instanceof Int16Array||e instanceof Uint16Array?s="rgba16uint":(e instanceof Int8Array,s="bgra8unorm")),super(ov(nv({},t),{resource:e,format:s})),this.uploadMethodId="buffer"}static test(t){return t instanceof Int8Array||t instanceof Uint8Array||t instanceof Uint8ClampedArray||t instanceof Int16Array||t instanceof Uint16Array||t instanceof Int32Array||t instanceof Uint32Array||t instanceof Float32Array}}cs.extension=v.TextureSource;const Ah=new G;class hn{constructor(t,e){this.mapCoord=new G,this.uClampFrame=new Float32Array(4),this.uClampOffset=new Float32Array(2),this._textureID=-1,this._updateID=0,this.clampOffset=0,typeof e=="undefined"?this.clampMargin=t.width<10?0:.5:this.clampMargin=e,this.isSimple=!1,this.texture=t}get texture(){return this._texture}set texture(t){var e;this.texture!==t&&((e=this._texture)==null||e.removeListener("update",this.update,this),this._texture=t,this._texture.addListener("update",this.update,this),this.update())}multiplyUvs(t,e){e===void 0&&(e=t);const s=this.mapCoord;for(let i=0;i{this._callback=t,this._batchIndex=0,this._frameKeys.length<=Wr.BATCH_SIZE?(this._processFrames(0),this._processAnimations(),this._parseComplete()):this._nextBatch()})}_processFrames(t){let e=t;const s=Wr.BATCH_SIZE;for(;e-t{this._batchIndex*Wr.BATCH_SIZE{s[i]=t}),Object.keys(t.textures).forEach(i=>{s[i]=t.textures[i]}),!e){const i=dt.dirname(r[0]);t.linkedSheets.forEach((n,o)=>{const a=wh([`${i}/${t.data.meta.related_multi_packs[o]}`],n,!0);Object.assign(s,a)})}return s}const Rh={extension:v.Asset,cache:{test:r=>r instanceof cn,getCacheableAssets:(r,t)=>wh(r,t,!1)},resolver:{test:r=>{const t=r.split("?")[0].split("."),e=t.pop(),s=t.pop();return e==="json"&&av.includes(s)},parse:r=>{var t,e;const s=r.split(".");return{resolution:parseFloat((e=(t=qt.RETINA_PREFIX.exec(r))==null?void 0:t[1])!=null?e:"1"),format:s[s.length-2],src:r}}},loader:{name:"spritesheetLoader",extension:{type:v.LoadParser,priority:gt.Normal},async testParse(r,t){return dt.extname(t.src).toLowerCase()===".json"&&!!r.frames},async parse(r,t,e){var s,i,n;const{texture:o,imageFilename:a}=(s=t==null?void 0:t.data)!=null?s:{};let u=dt.dirname(t.src);u&&u.lastIndexOf("/")!==u.length-1&&(u+="/");let l;if(o instanceof A)l=o;else{const d=ls(u+(a!=null?a:r.meta.image),t.src);l=(await e.load([d]))[d]}const h=new cn(l.source,r);await h.parse();const c=(i=r==null?void 0:r.meta)==null?void 0:i.related_multi_packs;if(Array.isArray(c)){const d=[];for(const f of c){if(typeof f!="string")continue;let g=u+f;(n=t.data)!=null&&n.ignoreMultiPack||(g=ls(g,t.src),d.push(e.load({src:g,data:{ignoreMultiPack:!0}})))}const p=await Promise.all(d);h.linkedSheets=p,p.forEach(f=>{f.linkedSheets=[h].concat(h.linkedSheets.filter(g=>g!==f))})}return h},async unload(r,t,e){await e.unload(r.textureSource._sourceOrigin),r.destroy(!1)}}};D.add(Rh);function dr(r,t,e,s){const{width:i,height:n}=e.orig,o=e.trim;if(o){const a=o.width,u=o.height;r.minX=o.x-t._x*i-s,r.maxX=r.minX+a,r.minY=o.y-t._y*n-s,r.maxY=r.minY+u}else r.minX=-t._x*i-s,r.maxX=r.minX+i,r.minY=-t._y*n-s,r.maxY=r.minY+n}var uv=Object.defineProperty,ds=Object.getOwnPropertySymbols,Mh=Object.prototype.hasOwnProperty,Oh=Object.prototype.propertyIsEnumerable,Ch=(r,t,e)=>t in r?uv(r,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):r[t]=e,lv=(r,t)=>{for(var e in t||(t={}))Mh.call(t,e)&&Ch(r,e,t[e]);if(ds)for(var e of ds(t))Oh.call(t,e)&&Ch(r,e,t[e]);return r},hv=(r,t)=>{var e={};for(var s in r)Mh.call(r,s)&&t.indexOf(s)<0&&(e[s]=r[s]);if(r!=null&&ds)for(var s of ds(r))t.indexOf(s)<0&&Oh.call(r,s)&&(e[s]=r[s]);return e};class Ft extends V{constructor(t=A.EMPTY){t instanceof A&&(t={texture:t});const e=t,{texture:s,anchor:i,roundPixels:n,width:o,height:a}=e,u=hv(e,["texture","anchor","roundPixels","width","height"]);super(lv({label:"Sprite"},u)),this.renderPipeId="sprite",this.batched=!0,this._didSpriteUpdate=!1,this._bounds={minX:0,maxX:1,minY:0,maxY:0},this._sourceBounds={minX:0,maxX:1,minY:0,maxY:0},this._boundsDirty=!0,this._sourceBoundsDirty=!0,this._roundPixels=0,this._anchor=new rt({_onUpdate:()=>{this.onViewUpdate()}}),i&&(this.anchor=i),this.texture=s,this.allowChildren=!1,this.roundPixels=n!=null?n:!1,o&&(this.width=o),a&&(this.height=a)}static from(t,e=!1){return t instanceof A?new Ft(t):new Ft(A.from(t,e))}set texture(t){t||(t=A.EMPTY);const e=this._texture;e!==t&&(e&&e.dynamic&&e.off("update",this.onViewUpdate,this),t.dynamic&&t.on("update",this.onViewUpdate,this),this._texture=t,this.onViewUpdate())}get texture(){return this._texture}get bounds(){return this._boundsDirty&&(this._updateBounds(),this._boundsDirty=!1),this._bounds}get sourceBounds(){return this._sourceBoundsDirty&&(this._updateSourceBounds(),this._sourceBoundsDirty=!1),this._sourceBounds}containsPoint(t){const e=this.sourceBounds;return t.x>=e.maxX&&t.x<=e.minX&&t.y>=e.maxY&&t.y<=e.minY}addBounds(t){const e=this._texture.trim?this.sourceBounds:this.bounds;t.addFrame(e.minX,e.minY,e.maxX,e.maxY)}onViewUpdate(){this._didChangeId+=4096,this._didSpriteUpdate=!0,this._sourceBoundsDirty=this._boundsDirty=!0,!this.didViewUpdate&&(this.didViewUpdate=!0,this.renderGroup&&this.renderGroup.onChildViewUpdate(this))}_updateBounds(){dr(this._bounds,this._anchor,this._texture,0)}_updateSourceBounds(){const t=this._anchor,e=this._texture,s=this._sourceBounds,{width:i,height:n}=e.orig;s.maxX=-t._x*i,s.minX=s.maxX+i,s.maxY=-t._y*n,s.minY=s.maxY+n}destroy(t=!1){if(super.destroy(t),typeof t=="boolean"?t:t==null?void 0:t.texture){const e=typeof t=="boolean"?t:t==null?void 0:t.textureSource;this._texture.destroy(e)}this._texture=null,this._bounds=null,this._sourceBounds=null,this._anchor=null}get anchor(){return this._anchor}set anchor(t){typeof t=="number"?this._anchor.set(t):this._anchor.copyFrom(t)}get roundPixels(){return!!this._roundPixels}set roundPixels(t){this._roundPixels=t?1:0}get width(){return Math.abs(this.scale.x)*this._texture.orig.width}set width(t){this._setWidth(t,this._texture.orig.width)}get height(){return Math.abs(this.scale.y)*this._texture.orig.height}set height(t){this._setHeight(t,this._texture.orig.height)}getSize(t){return t||(t={}),t.width=Math.abs(this.scale.x)*this._texture.orig.width,t.height=Math.abs(this.scale.y)*this._texture.orig.height,t}setSize(t,e){var s;let i,n;typeof t!="object"?(i=t,n=e!=null?e:t):(i=t.width,n=(s=t.height)!=null?s:t.width),i!==void 0&&this._setWidth(i,this._texture.orig.width),n!==void 0&&this._setHeight(n,this._texture.orig.height)}}const cv=new lt;function ps(r,t,e){const s=cv;r.measurable=!0,nr(r,e,s),t.addBoundsMask(s),r.measurable=!1}function fs(r,t,e){const s=kt.get();r.measurable=!0;const i=Ut.get().identity(),n=dn(r,e,i);is(r,s,n),r.measurable=!1,t.addBoundsMask(s),Ut.return(i),kt.return(s)}function dn(r,t,e){return r&&r!==t&&(dn(r.parent,t,e),r.updateLocalTransform(),e.append(r.localTransform)),e}class pn{constructor(t){this.priority=0,this.pipe="alphaMask",t!=null&&t.mask&&this.init(t.mask)}init(t){this.mask=t,this.renderMaskToTexture=!(t instanceof Ft),this.mask.renderable=this.renderMaskToTexture,this.mask.includeInBuild=!this.renderMaskToTexture,this.mask.measurable=!1}reset(){this.mask.measurable=!0,this.mask=null}addBounds(t,e){ps(this.mask,t,e)}addLocalBounds(t,e){fs(this.mask,t,e)}containsPoint(t,e){const s=this.mask;return e(s,t)}destroy(){this.reset()}static test(t){return t instanceof Ft}}pn.extension=v.MaskEffect;class fn{constructor(t){this.priority=0,this.pipe="colorMask",t!=null&&t.mask&&this.init(t.mask)}init(t){this.mask=t}destroy(){}static test(t){return typeof t=="number"}}fn.extension=v.MaskEffect;class mn{constructor(t){this.priority=0,this.pipe="stencilMask",t!=null&&t.mask&&this.init(t.mask)}init(t){this.mask=t,this.mask.includeInBuild=!1,this.mask.measurable=!1}reset(){this.mask.measurable=!0,this.mask.includeInBuild=!0,this.mask=null}addBounds(t,e){ps(this.mask,t,e)}addLocalBounds(t,e){fs(this.mask,t,e)}containsPoint(t,e){const s=this.mask;return e(s,t)}destroy(){this.reset()}static test(t){return t instanceof V}}mn.extension=v.MaskEffect;class Qt extends et{constructor(t){t.resource||(t.resource=X.get().createCanvas()),t.width||(t.width=t.resource.width,t.autoDensity||(t.width/=t.resolution)),t.height||(t.height=t.resource.height,t.autoDensity||(t.height/=t.resolution)),super(t),this.uploadMethodId="image",this.autoDensity=t.autoDensity;const e=t.resource;(this.pixelWidth!==e.width||this.pixelWidth!==e.height)&&this.resizeCanvas(),this.transparent=!!t.transparent}resizeCanvas(){this.autoDensity&&(this.resource.style.width=`${this.width}px`,this.resource.style.height=`${this.height}px`),(this.resource.width!==this.pixelWidth||this.resource.height!==this.pixelHeight)&&(this.resource.width=this.pixelWidth,this.resource.height=this.pixelHeight)}resize(t=this.width,e=this.height,s=this._resolution){const i=super.resize(t,e,s);return i&&this.resizeCanvas(),i}static test(t){return globalThis.HTMLCanvasElement&&t instanceof HTMLCanvasElement||globalThis.OffscreenCanvas&&t instanceof OffscreenCanvas}}Qt.extension=v.TextureSource;class ge extends et{constructor(t){if(t.resource&&globalThis.HTMLImageElement&&t.resource instanceof HTMLImageElement){const e=X.get().createCanvas(t.resource.width,t.resource.height);e.getContext("2d").drawImage(t.resource,0,0),t.resource=e}super(t),this.uploadMethodId="image",this.autoGarbageCollect=!0}static test(t){return globalThis.HTMLImageElement&&t instanceof HTMLImageElement||typeof ImageBitmap!="undefined"&&t instanceof ImageBitmap}}ge.extension=v.TextureSource;let gn;async function _n(){return gn!=null||(gn=(async()=>{var r;const t=document.createElement("canvas").getContext("webgl");if(!t)return"premultiply-alpha-on-upload";const e=await new Promise(o=>{const a=document.createElement("video");a.onloadeddata=()=>o(a),a.onerror=()=>o(null),a.autoplay=!1,a.crossOrigin="anonymous",a.preload="auto",a.src="data:video/webm;base64,GkXfo59ChoEBQveBAULygQRC84EIQoKEd2VibUKHgQJChYECGFOAZwEAAAAAAAHTEU2bdLpNu4tTq4QVSalmU6yBoU27i1OrhBZUrmtTrIHGTbuMU6uEElTDZ1OsggEXTbuMU6uEHFO7a1OsggG97AEAAAAAAABZAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVSalmoCrXsYMPQkBNgIRMYXZmV0GETGF2ZkSJiEBEAAAAAAAAFlSua8yuAQAAAAAAAEPXgQFzxYgAAAAAAAAAAZyBACK1nIN1bmSIgQCGhVZfVlA5g4EBI+ODhAJiWgDglLCBArqBApqBAlPAgQFVsIRVuYEBElTDZ9Vzc9JjwItjxYgAAAAAAAAAAWfInEWjh0VOQ09ERVJEh49MYXZjIGxpYnZweC12cDlnyKJFo4hEVVJBVElPTkSHlDAwOjAwOjAwLjA0MDAwMDAwMAAAH0O2dcfngQCgwqGggQAAAIJJg0IAABAAFgA4JBwYSgAAICAAEb///4r+AAB1oZ2mm+6BAaWWgkmDQgAAEAAWADgkHBhKAAAgIABIQBxTu2uRu4+zgQC3iveBAfGCAXHwgQM=",a.load()});if(!e)return"premultiply-alpha-on-upload";const s=t.createTexture();t.bindTexture(t.TEXTURE_2D,s);const i=t.createFramebuffer();t.bindFramebuffer(t.FRAMEBUFFER,i),t.framebufferTexture2D(t.FRAMEBUFFER,t.COLOR_ATTACHMENT0,t.TEXTURE_2D,s,0),t.pixelStorei(t.UNPACK_PREMULTIPLY_ALPHA_WEBGL,!1),t.pixelStorei(t.UNPACK_COLORSPACE_CONVERSION_WEBGL,t.NONE),t.texImage2D(t.TEXTURE_2D,0,t.RGBA,t.RGBA,t.UNSIGNED_BYTE,e);const n=new Uint8Array(4);return t.readPixels(0,0,1,1,t.RGBA,t.UNSIGNED_BYTE,n),t.deleteFramebuffer(i),t.deleteTexture(s),(r=t.getExtension("WEBGL_lose_context"))==null||r.loseContext(),n[0]<=n[3]?"premultiplied-alpha":"premultiply-alpha-on-upload"})()),gn}var dv=Object.defineProperty,pv=Object.defineProperties,fv=Object.getOwnPropertyDescriptors,Gh=Object.getOwnPropertySymbols,mv=Object.prototype.hasOwnProperty,gv=Object.prototype.propertyIsEnumerable,Ih=(r,t,e)=>t in r?dv(r,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):r[t]=e,xn=(r,t)=>{for(var e in t||(t={}))mv.call(t,e)&&Ih(r,e,t[e]);if(Gh)for(var e of Gh(t))gv.call(t,e)&&Ih(r,e,t[e]);return r},_v=(r,t)=>pv(r,fv(t));const ms=class Sx extends et{constructor(t){var e;super(t),this.isReady=!1,this.uploadMethodId="video",t=xn(xn({},Sx.defaultOptions),t),this._autoUpdate=!0,this._isConnectedToTicker=!1,this._updateFPS=t.updateFPS||0,this._msToNextUpdate=0,this.autoPlay=t.autoPlay!==!1,this.alphaMode=(e=t.alphaMode)!=null?e:"premultiply-alpha-on-upload",this._videoFrameRequestCallback=this._videoFrameRequestCallback.bind(this),this._videoFrameRequestCallbackHandle=null,this._load=null,this._resolve=null,this._reject=null,this._onCanPlay=this._onCanPlay.bind(this),this._onCanPlayThrough=this._onCanPlayThrough.bind(this),this._onError=this._onError.bind(this),this._onPlayStart=this._onPlayStart.bind(this),this._onPlayStop=this._onPlayStop.bind(this),this._onSeeked=this._onSeeked.bind(this),t.autoLoad!==!1&&this.load()}updateFrame(){if(!this.destroyed){if(this._updateFPS){const t=ht.shared.elapsedMS*this.resource.playbackRate;this._msToNextUpdate=Math.floor(this._msToNextUpdate-t)}(!this._updateFPS||this._msToNextUpdate<=0)&&(this._msToNextUpdate=this._updateFPS?Math.floor(1e3/this._updateFPS):0),this.isValid&&this.update()}}_videoFrameRequestCallback(){this.updateFrame(),this.destroyed?this._videoFrameRequestCallbackHandle=null:this._videoFrameRequestCallbackHandle=this.source.requestVideoFrameCallback(this._videoFrameRequestCallback)}get isValid(){return!!this.resource.videoWidth&&!!this.resource.videoHeight}async load(){if(this._load)return this._load;const t=this.resource,e=this.options;return(t.readyState===t.HAVE_ENOUGH_DATA||t.readyState===t.HAVE_FUTURE_DATA)&&t.width&&t.height&&(t.complete=!0),t.addEventListener("play",this._onPlayStart),t.addEventListener("pause",this._onPlayStop),t.addEventListener("seeked",this._onSeeked),this._isSourceReady()?this._mediaReady():(e.preload||t.addEventListener("canplay",this._onCanPlay),t.addEventListener("canplaythrough",this._onCanPlayThrough),t.addEventListener("error",this._onError,!0)),this.alphaMode=await _n(),this._load=new Promise((s,i)=>{this.isValid?s(this):(this._resolve=s,this._reject=i,e.preloadTimeoutMs!==void 0&&(this._preloadTimeout=setTimeout(()=>{this._onError(new ErrorEvent(`Preload exceeded timeout of ${e.preloadTimeoutMs}ms`))})),t.load())}),this._load}_onError(t){this.resource.removeEventListener("error",this._onError,!0),this.emit("error",t),this._reject&&(this._reject(t),this._reject=null,this._resolve=null)}_isSourcePlaying(){const t=this.resource;return!t.paused&&!t.ended}_isSourceReady(){return this.resource.readyState>2}_onPlayStart(){this.isValid||this._mediaReady(),this._configureAutoUpdate()}_onPlayStop(){this._configureAutoUpdate()}_onSeeked(){this._autoUpdate&&!this._isSourcePlaying()&&(this._msToNextUpdate=0,this.updateFrame(),this._msToNextUpdate=0)}_onCanPlay(){this.resource.removeEventListener("canplay",this._onCanPlay),this._mediaReady()}_onCanPlayThrough(){this.resource.removeEventListener("canplaythrough",this._onCanPlay),this._preloadTimeout&&(clearTimeout(this._preloadTimeout),this._preloadTimeout=void 0),this._mediaReady()}_mediaReady(){const t=this.resource;this.isValid&&(this.isReady=!0,this.resize(t.videoWidth,t.videoHeight)),this._msToNextUpdate=0,this.updateFrame(),this._msToNextUpdate=0,this._resolve&&(this._resolve(this),this._resolve=null,this._reject=null),this._isSourcePlaying()?this._onPlayStart():this.autoPlay&&this.resource.play()}destroy(){this._configureAutoUpdate();const t=this.resource;t&&(t.removeEventListener("play",this._onPlayStart),t.removeEventListener("pause",this._onPlayStop),t.removeEventListener("seeked",this._onSeeked),t.removeEventListener("canplay",this._onCanPlay),t.removeEventListener("canplaythrough",this._onCanPlayThrough),t.removeEventListener("error",this._onError,!0),t.pause(),t.src="",t.load()),super.destroy()}get autoUpdate(){return this._autoUpdate}set autoUpdate(t){t!==this._autoUpdate&&(this._autoUpdate=t,this._configureAutoUpdate())}get updateFPS(){return this._updateFPS}set updateFPS(t){t!==this._updateFPS&&(this._updateFPS=t,this._configureAutoUpdate())}_configureAutoUpdate(){this._autoUpdate&&this._isSourcePlaying()?!this._updateFPS&&this.source.requestVideoFrameCallback?(this._isConnectedToTicker&&(ht.shared.remove(this.updateFrame,this),this._isConnectedToTicker=!1,this._msToNextUpdate=0),this._videoFrameRequestCallbackHandle===null&&(this._videoFrameRequestCallbackHandle=this.source.requestVideoFrameCallback(this._videoFrameRequestCallback))):(this._videoFrameRequestCallbackHandle!==null&&(this.source.cancelVideoFrameCallback(this._videoFrameRequestCallbackHandle),this._videoFrameRequestCallbackHandle=null),this._isConnectedToTicker||(ht.shared.add(this.updateFrame,this),this._isConnectedToTicker=!0,this._msToNextUpdate=0)):(this._videoFrameRequestCallbackHandle!==null&&(this.source.cancelVideoFrameCallback(this._videoFrameRequestCallbackHandle),this._videoFrameRequestCallbackHandle=null),this._isConnectedToTicker&&(ht.shared.remove(this.updateFrame,this),this._isConnectedToTicker=!1,this._msToNextUpdate=0))}static test(t){return globalThis.HTMLVideoElement&&t instanceof HTMLVideoElement||globalThis.VideoFrame&&t instanceof VideoFrame}};ms.extension=v.TextureSource,ms.defaultOptions=_v(xn({},et.defaultOptions),{autoLoad:!0,autoPlay:!0,updateFPS:0,crossorigin:!0,loop:!1,muted:!0,playsinline:!0,preload:!1}),ms.MIME_TYPES={ogv:"video/ogg",mov:"video/quicktime",m4v:"video/mp4"};let pr=ms,xv=class{constructor(){this._parsers=[],this._cache=new Map,this._cacheMap=new Map}reset(){this._cacheMap.clear(),this._cache.clear()}has(t){return this._cache.has(t)}get(t){return this._cache.get(t)}set(t,e){const s=Pt(t);let i;for(let u=0;u{n.set(u,e)});const o=[...n.keys()],a={cacheKeys:o,keys:s};s.forEach(u=>{this._cacheMap.set(u,a)}),o.forEach(u=>{const l=i?i[u]:e;this._cache.has(u)&&this._cache.get(u),this._cache.set(u,n.get(u))})}remove(t){if(!this._cacheMap.has(t))return;const e=this._cacheMap.get(t);e.cacheKeys.forEach(s=>{this._cache.delete(s)}),e.keys.forEach(s=>{this._cacheMap.delete(s)})}get parsers(){return this._parsers}};const Y=new xv,bn=[];D.handleByList(v.TextureSource,bn);function Bh(r={}){const t=r&&r.resource,e=t?r.resource:r,s=t?r:{resource:r};for(let i=0;i{Y.has(s)&&Y.remove(s)}),t||Y.set(s,n),n}function Dh(r,t=!1){return typeof r=="string"?Y.get(r):r instanceof et?new A({source:r}):Fh(r,t)}A.from=Dh,D.add(pn,fn,mn,pr,ge,Qt,cs);var $=(r=>(r[r.MAP_READ=1]="MAP_READ",r[r.MAP_WRITE=2]="MAP_WRITE",r[r.COPY_SRC=4]="COPY_SRC",r[r.COPY_DST=8]="COPY_DST",r[r.INDEX=16]="INDEX",r[r.VERTEX=32]="VERTEX",r[r.UNIFORM=64]="UNIFORM",r[r.STORAGE=128]="STORAGE",r[r.INDIRECT=256]="INDIRECT",r[r.QUERY_RESOLVE=512]="QUERY_RESOLVE",r[r.STATIC=1024]="STATIC",r))($||{});class _t extends ct{constructor(t){let{data:e,size:s}=t;const{usage:i,label:n,shrinkToFit:o}=t;super(),this.uid=Z("buffer"),this._resourceType="buffer",this._resourceId=Z("resource"),this._touched=0,this._updateID=1,this.shrinkToFit=!0,e instanceof Array&&(e=new Float32Array(e)),this._data=e,s=s!=null?s:e==null?void 0:e.byteLength;const a=!!e;this.descriptor={size:s,usage:i,mappedAtCreation:a,label:n},this.shrinkToFit=o!=null?o:!0}get data(){return this._data}set data(t){this.setDataWithSize(t,t.length,!0)}get static(){return!!(this.descriptor.usage&$.STATIC)}set static(t){t?this.descriptor.usage|=$.STATIC:this.descriptor.usage&=~$.STATIC}setDataWithSize(t,e,s){if(this._updateID++,this._updateSize=e*t.BYTES_PER_ELEMENT,this._data===t){s&&this.emit("update",this);return}const i=this._data;if(this._data=t,i.length!==t.length){!this.shrinkToFit&&t.byteLengtha&&(a=p),f>u&&(u=f),pe.destroy()),this.attributes=null,this.buffers=null,this.indexBuffer=null,this._bounds=null}}const vv=new Float32Array(1),yv=new Uint32Array(1);class yn extends Oe{constructor(){const t=new _t({data:vv,label:"attribute-batch-buffer",usage:$.VERTEX|$.COPY_DST,shrinkToFit:!1}),e=new _t({data:yv,label:"index-batch-buffer",usage:$.INDEX|$.COPY_DST,shrinkToFit:!1}),s=6*4;super({attributes:{aPosition:{buffer:t,format:"float32x2",stride:s,offset:0,location:1},aUV:{buffer:t,format:"float32x2",stride:s,offset:2*4,location:3},aColor:{buffer:t,format:"unorm8x4",stride:s,offset:4*4,location:0},aTextureIdAndRound:{buffer:t,format:"uint16x2",stride:s,offset:5*4,location:2}},indexBuffer:e})}}class Lt{constructor(t){this.resources=Object.create(null),this._dirty=!0;let e=0;for(const s in t){const i=t[s];this.setResource(i,e++)}this._updateKey()}_updateKey(){if(!this._dirty)return;this._dirty=!1;const t=[];let e=0;for(const s in this.resources)t[e++]=this.resources[s]._resourceId;this._key=t.join("|")}setResource(t,e){var s,i;const n=this.resources[e];t!==n&&(n&&((s=t.off)==null||s.call(t,"change",this.onResourceChange,this)),(i=t.on)==null||i.call(t,"change",this.onResourceChange,this),this.resources[e]=t,this._dirty=!0)}getResource(t){return this.resources[t]}_touch(t){const e=this.resources;for(const s in e)e[s]._touched=t}destroy(){var t;const e=this.resources;for(const s in e){const i=e[s];(t=i.off)==null||t.call(i,"change",this.onResourceChange,this)}this.resources=null}onResourceChange(){this._dirty=!0,this._updateKey()}}const wt=16,kh={};function gs(r,t){let e=0;for(let s=0;s>>0;return kh[e]||Tv(r,e)}function Tv(r,t){const e={};let s=0;for(let n=0;n0){const n=new Uint8Array(r,e*8,i);new Uint8Array(t,e*8,i).set(n)}}const Lh={normal:"normal-npm",add:"add-npm",screen:"screen-npm"};var st=(r=>(r[r.DISABLED=0]="DISABLED",r[r.RENDERING_MASK_ADD=1]="RENDERING_MASK_ADD",r[r.MASK_ACTIVE=2]="MASK_ACTIVE",r[r.RENDERING_MASK_REMOVE=3]="RENDERING_MASK_REMOVE",r[r.NONE=4]="NONE",r))(st||{});function Sn(r,t){return t.alphaMode==="no-premultiply-alpha"&&Lh[r]||r}class En{constructor(){this.ids=Object.create(null),this.textures=[],this.count=0}clear(){for(let t=0;tt in r?Sv(r,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):r[t]=e,Hh=(r,t)=>{for(var e in t||(t={}))Ev.call(t,e)&&Nh(r,e,t[e]);if($h)for(var e of $h(t))Av.call(t,e)&&Nh(r,e,t[e]);return r};class An{constructor(){this.renderPipeId="batch",this.action="startBatch",this.start=0,this.size=0,this.blendMode="normal",this.canBundle=!0}destroy(){this.textures=null,this.gpuBindGroup=null,this.bindGroup=null,this.batcher=null}}let fr=0;const Xh=class Ex{constructor(t={}){this.uid=Z("batcher"),this.dirty=!0,this.batchIndex=0,this.batches=[],this._vertexSize=6,this._elements=[],this._batchPool=[],this._batchPoolIndex=0,this._textureBatchPool=[],this._textureBatchPoolIndex=0,t=Hh(Hh({},Ex.defaultOptions),t);const{vertexSize:e,indexSize:s}=t;this.attributeBuffer=new Tn(e*this._vertexSize*4),this.indexBuffer=new Uint16Array(s)}begin(){this.batchIndex=0,this.elementSize=0,this.elementStart=0,this.indexSize=0,this.attributeSize=0,this._batchPoolIndex=0,this._textureBatchPoolIndex=0,this._batchIndexStart=0,this._batchIndexSize=0,this.dirty=!0}add(t){this._elements[this.elementSize++]=t,t.indexStart=this.indexSize,t.location=this.attributeSize,t.batcher=this,this.indexSize+=t.indexSize,this.attributeSize+=t.vertexSize*this._vertexSize}checkAndUpdateTexture(t,e){const s=t.batch.textures.ids[e._source.uid];return!s&&s!==0?!1:(t.textureId=s,t.texture=e,!0)}updateElement(t){this.dirty=!0,t.packAttributes(this.attributeBuffer.float32View,this.attributeBuffer.uint32View,t.location,t.textureId)}break(t){const e=this._elements;let s=this._textureBatchPool[this._textureBatchPoolIndex++]||new En;if(s.clear(),!e[this.elementStart])return;const i=e[this.elementStart];let n=Sn(i.blendMode,i.texture._source);this.attributeSize*4>this.attributeBuffer.size&&this._resizeAttributeBuffer(this.attributeSize*4),this.indexSize>this.indexBuffer.length&&this._resizeIndexBuffer(this.indexSize);const o=this.attributeBuffer.float32View,a=this.attributeBuffer.uint32View,u=this.indexBuffer;let l=this._batchIndexSize,h=this._batchIndexStart,c="startBatch",d=this._batchPool[this._batchPoolIndex++]||new An;for(let p=this.elementStart;p=wt||_)&&(this._finishBatch(d,h,l-h,s,n,t,c),c="renderBatch",h=l,n=m,s=this._textureBatchPool[this._textureBatchPoolIndex++]||new En,s.clear(),d=this._batchPool[this._batchPoolIndex++]||new An,++fr),f.textureId=g._textureBindLocation=s.count,s.ids[g.uid]=s.count,s.textures[s.count++]=g,f.batch=d,l+=f.indexSize,f.packAttributes(o,a,f.location,f.textureId),f.packIndex(u,f.indexStart,f.location/this._vertexSize)}s.count>0&&(this._finishBatch(d,h,l-h,s,n,t,c),h=l,++fr),this.elementStart=this.elementSize,this._batchIndexStart=h,this._batchIndexSize=l}_finishBatch(t,e,s,i,n,o,a){t.gpuBindGroup=null,t.action=a,t.batcher=this,t.textures=i,t.blendMode=n,t.start=e,t.size=s,++fr,o.add(t)}finish(t){this.break(t)}ensureAttributeBuffer(t){t*4<=this.attributeBuffer.size||this._resizeAttributeBuffer(t*4)}ensureIndexBuffer(t){t<=this.indexBuffer.length||this._resizeIndexBuffer(t)}_resizeAttributeBuffer(t){const e=Math.max(t,this.attributeBuffer.size*2),s=new Tn(e);_s(this.attributeBuffer.rawBinaryData,s.rawBinaryData),this.attributeBuffer=s}_resizeIndexBuffer(t){const e=this.indexBuffer;let s=Math.max(t,e.length*1.5);s+=s%2;const i=s>65535?new Uint32Array(s):new Uint16Array(s);if(i.BYTES_PER_ELEMENT!==e.BYTES_PER_ELEMENT)for(let n=0;n>16&255,i=r>>8&255,n=r&255,o=t>>16&255,a=t>>8&255,u=t&255,l=s+(o-s)*e,h=i+(a-i)*e,c=n+(u-n)*e;return(l<<16)+(h<<8)+c}const Ce=16777215;function bs(r,t){return r===Ce||t===Ce?r+t-Ce:Mn(r,t,.5)}function Pv(r,t,e){const s=(e>>24&255)/255,i=t*s*255,n=((r&255)<<16)+(r&65280)+(r>>16&255),o=e&16777215;let a;return n===Ce||o===Ce?a=n+o-Ce:a=Mn(n,o,.5),a+(i<<24)}class vs{constructor(){this.batcher=null,this.batch=null,this.applyTransform=!0,this.roundPixels=0}get blendMode(){return this.applyTransform?this.renderable.groupBlendMode:"normal"}packIndex(t,e,s){const i=this.geometryData.indices;for(let n=0;n>16|c&65280|(c&255)<<16;if(this.applyTransform){const p=bs(d,o.groupColor)+(this.alpha*o.groupAlpha*255<<24),f=o.groupTransform,g=i<<16|this.roundPixels&65535,m=f.a,_=f.b,x=f.c,b=f.d,y=f.tx,S=f.ty;for(let P=l;P=0&&a>=0&&i>=0&&n>=0))return t;const u=Math.ceil(2.3*Math.sqrt(o+a)),l=u*8+(i?4:0)+(n?4:0);if(l===0)return t;if(u===0)return t[0]=t[6]=e+i,t[1]=t[3]=s+n,t[2]=t[4]=e-i,t[5]=t[7]=s-n,t;let h=0,c=u*4+(i?2:0)+2,d=c,p=l,f=i+o,g=n,m=e+f,_=e-f,x=s+g;if(t[h++]=m,t[h++]=x,t[--c]=x,t[--c]=_,n){const y=s-g;t[d++]=_,t[d++]=y,t[--p]=y,t[--p]=m}for(let y=1;y0&&(i[n++]=u,i[n++]=l,i[n++]=u-1),u++;i[n++]=l+1,i[n++]=l,i[n++]=u-1}},zh=1e-4,On=1e-4;function jh(r){const t=r.length;if(t<6)return 1;let e=0;for(let s=0,i=r[t-2],n=r[t-1];sc&&(c+=Math.PI*2);let d=h;const p=c-h,f=Math.abs(p),g=Math.sqrt(u*u+l*l),m=(15*f*Math.sqrt(g)/Math.PI>>0)+1,_=p/m;if(d+=_,a){o.push(r,t),o.push(e,s);for(let x=1,b=d;x=0&&(h.join==="round"?x+=xe(T,E,T-C*B,E-M*B,T-q*B,E-J*B,m,!1)+4:x+=2,m.push(T-q*F,E-J*F),m.push(T+q*B,E+J*B));continue}const tl=(-C+R)*(-M+E)-(-C+T)*(-M+w),el=(-q+L)*(-J+E)-(-q+T)*(-J+k),qr=(Kt*el-Je*tl)/Kr,Zr=(tr*tl-Qe*el)/Kr,Di=(qr-T)*(qr-T)+(Zr-E)*(Zr-E),oe=T+(qr-T)*B,ae=E+(Zr-E)*B,ue=T-(qr-T)*F,le=E-(Zr-E)*F,Vx=Math.min(Kt*Kt+Qe*Qe,Je*Je+tr*tr),rl=er?B:F,Wx=Vx+rl*rl*S;Di<=Wx?h.join==="bevel"||Di/S>P?(er?(m.push(oe,ae),m.push(T+C*F,E+M*F),m.push(oe,ae),m.push(T+q*F,E+J*F)):(m.push(T-C*B,E-M*B),m.push(ue,le),m.push(T-q*B,E-J*B),m.push(ue,le)),x+=2):h.join==="round"?er?(m.push(oe,ae),m.push(T+C*F,E+M*F),x+=xe(T,E,T+C*F,E+M*F,T+q*F,E+J*F,m,!0)+4,m.push(oe,ae),m.push(T+q*F,E+J*F)):(m.push(T-C*B,E-M*B),m.push(ue,le),x+=xe(T,E,T-C*B,E-M*B,T-q*B,E-J*B,m,!1)+4,m.push(T-q*B,E-J*B),m.push(ue,le)):(m.push(oe,ae),m.push(ue,le)):(m.push(T-C*B,E-M*B),m.push(T+C*F,E+M*F),h.join==="round"?er?x+=xe(T,E,T+C*F,E+M*F,T+q*F,E+J*F,m,!0)+2:x+=xe(T,E,T-C*B,E-M*B,T-q*B,E-J*B,m,!1)+2:h.join==="miter"&&Di/S<=P&&(er?(m.push(ue,le),m.push(ue,le)):(m.push(oe,ae),m.push(oe,ae)),x+=2),m.push(T-q*B,E-J*B),m.push(T+q*F,E+J*F),x+=2)}R=r[(_-2)*2],w=r[(_-2)*2+1],T=r[(_-1)*2],E=r[(_-1)*2+1],C=-(w-E),M=R-T,mt=Math.sqrt(C*C+M*M),C/=mt,M/=mt,C*=y,M*=y,m.push(T-C*B,E-M*B),m.push(T+C*F,E+M*F),f||(h.cap==="round"?x+=xe(T-C*(B-F)*.5,E-M*(B-F)*.5,T-C*B,E-M*B,T+C*F,E+M*F,m,!1)+2:h.cap==="square"&&(x+=Vh(T,E,C,M,B,F,!1,m)));const jx=On*On;for(let K=b;K80*e){a=l=r[0],u=h=r[1];for(var f=e;fl&&(l=c),d>h&&(h=d);p=Math.max(l-a,h-u),p=p!==0?32767/p:0}return mr(n,o,e,a,u,p,0),o}function Yh(r,t,e,s,i){var n,o;if(i===In(r,t,e,s)>0)for(n=t;n=t;n-=s)o=Zh(n,r[n],r[n+1],o);return o&&Ss(o,o.next)&&(_r(o),o=o.next),o}function be(r,t){if(!r)return r;t||(t=r);var e=r,s;do if(s=!1,!e.steiner&&(Ss(e,e.next)||Q(e.prev,e,e.next)===0)){if(_r(e),e=t=e.prev,e===e.next)break;s=!0}else e=e.next;while(s||e!==t);return t}function mr(r,t,e,s,i,n,o){if(r){!o&&n&&Dv(r,s,i,n);for(var a=r,u,l;r.prev!==r.next;){if(u=r.prev,l=r.next,n?Rv(r,s,i,n):wv(r)){t.push(u.i/e|0),t.push(r.i/e|0),t.push(l.i/e|0),_r(r),r=l.next,a=l.next;continue}if(r=l,r===a){o?o===1?(r=Mv(be(r),t,e),mr(r,t,e,s,i,n,2)):o===2&&Ov(r,t,e,s,i,n):mr(be(r),t,e,s,i,n,1);break}}}}function wv(r){var t=r.prev,e=r,s=r.next;if(Q(t,e,s)>=0)return!1;for(var i=t.x,n=e.x,o=s.x,a=t.y,u=e.y,l=s.y,h=in?i>o?i:o:n>o?n:o,p=a>u?a>l?a:l:u>l?u:l,f=s.next;f!==t;){if(f.x>=h&&f.x<=d&&f.y>=c&&f.y<=p&&Ge(i,a,n,u,o,l,f.x,f.y)&&Q(f.prev,f,f.next)>=0)return!1;f=f.next}return!0}function Rv(r,t,e,s){var i=r.prev,n=r,o=r.next;if(Q(i,n,o)>=0)return!1;for(var a=i.x,u=n.x,l=o.x,h=i.y,c=n.y,d=o.y,p=au?a>l?a:l:u>l?u:l,m=h>c?h>d?h:d:c>d?c:d,_=Cn(p,f,t,e,s),x=Cn(g,m,t,e,s),b=r.prevZ,y=r.nextZ;b&&b.z>=_&&y&&y.z<=x;){if(b.x>=p&&b.x<=g&&b.y>=f&&b.y<=m&&b!==i&&b!==o&&Ge(a,h,u,c,l,d,b.x,b.y)&&Q(b.prev,b,b.next)>=0||(b=b.prevZ,y.x>=p&&y.x<=g&&y.y>=f&&y.y<=m&&y!==i&&y!==o&&Ge(a,h,u,c,l,d,y.x,y.y)&&Q(y.prev,y,y.next)>=0))return!1;y=y.nextZ}for(;b&&b.z>=_;){if(b.x>=p&&b.x<=g&&b.y>=f&&b.y<=m&&b!==i&&b!==o&&Ge(a,h,u,c,l,d,b.x,b.y)&&Q(b.prev,b,b.next)>=0)return!1;b=b.prevZ}for(;y&&y.z<=x;){if(y.x>=p&&y.x<=g&&y.y>=f&&y.y<=m&&y!==i&&y!==o&&Ge(a,h,u,c,l,d,y.x,y.y)&&Q(y.prev,y,y.next)>=0)return!1;y=y.nextZ}return!0}function Mv(r,t,e){var s=r;do{var i=s.prev,n=s.next.next;!Ss(i,n)&&Kh(i,s,s.next,n)&&gr(i,n)&&gr(n,i)&&(t.push(i.i/e|0),t.push(s.i/e|0),t.push(n.i/e|0),_r(s),_r(s.next),s=r=n),s=s.next}while(s!==r);return be(s)}function Ov(r,t,e,s,i,n){var o=r;do{for(var a=o.next.next;a!==o.prev;){if(o.i!==a.i&&Lv(o,a)){var u=qh(o,a);o=be(o,o.next),u=be(u,u.next),mr(o,t,e,s,i,n,0),mr(u,t,e,s,i,n,0);return}a=a.next}o=o.next}while(o!==r)}function Cv(r,t,e,s){var i=[],n,o,a,u,l;for(n=0,o=t.length;n=e.next.y&&e.next.y!==e.y){var a=e.x+(i-e.y)*(e.next.x-e.x)/(e.next.y-e.y);if(a<=s&&a>n&&(n=a,o=e.x=e.x&&e.x>=l&&s!==e.x&&Ge(io.x||e.x===o.x&&Fv(o,e)))&&(o=e,c=d)),e=e.next;while(e!==u);return o}function Fv(r,t){return Q(r.prev,r,t.prev)<0&&Q(t.next,r,r.next)<0}function Dv(r,t,e,s){var i=r;do i.z===0&&(i.z=Cn(i.x,i.y,t,e,s)),i.prevZ=i.prev,i.nextZ=i.next,i=i.next;while(i!==r);i.prevZ.nextZ=null,i.prevZ=null,Uv(i)}function Uv(r){var t,e,s,i,n,o,a,u,l=1;do{for(e=r,r=null,n=null,o=0;e;){for(o++,s=e,a=0,t=0;t0||u>0&&s;)a!==0&&(u===0||!s||e.z<=s.z)?(i=e,e=e.nextZ,a--):(i=s,s=s.nextZ,u--),n?n.nextZ=i:r=i,i.prevZ=n,n=i;e=s}n.nextZ=null,l*=2}while(o>1);return r}function Cn(r,t,e,s,i){return r=(r-e)*i|0,t=(t-s)*i|0,r=(r|r<<8)&16711935,r=(r|r<<4)&252645135,r=(r|r<<2)&858993459,r=(r|r<<1)&1431655765,t=(t|t<<8)&16711935,t=(t|t<<4)&252645135,t=(t|t<<2)&858993459,t=(t|t<<1)&1431655765,r|t<<1}function kv(r){var t=r,e=r;do(t.x=(r-o)*(n-a)&&(r-o)*(s-a)>=(e-o)*(t-a)&&(e-o)*(n-a)>=(i-o)*(s-a)}function Lv(r,t){return r.next.i!==t.i&&r.prev.i!==t.i&&!$v(r,t)&&(gr(r,t)&&gr(t,r)&&Nv(r,t)&&(Q(r.prev,r,t.prev)||Q(r,t.prev,t))||Ss(r,t)&&Q(r.prev,r,r.next)>0&&Q(t.prev,t,t.next)>0)}function Q(r,t,e){return(t.y-r.y)*(e.x-t.x)-(t.x-r.x)*(e.y-t.y)}function Ss(r,t){return r.x===t.x&&r.y===t.y}function Kh(r,t,e,s){var i=As(Q(r,t,e)),n=As(Q(r,t,s)),o=As(Q(e,s,r)),a=As(Q(e,s,t));return!!(i!==n&&o!==a||i===0&&Es(r,e,t)||n===0&&Es(r,s,t)||o===0&&Es(e,r,s)||a===0&&Es(e,t,s))}function Es(r,t,e){return t.x<=Math.max(r.x,e.x)&&t.x>=Math.min(r.x,e.x)&&t.y<=Math.max(r.y,e.y)&&t.y>=Math.min(r.y,e.y)}function As(r){return r>0?1:r<0?-1:0}function $v(r,t){var e=r;do{if(e.i!==r.i&&e.next.i!==r.i&&e.i!==t.i&&e.next.i!==t.i&&Kh(e,e.next,r,t))return!0;e=e.next}while(e!==r);return!1}function gr(r,t){return Q(r.prev,r,r.next)<0?Q(r,t,r.next)>=0&&Q(r,r.prev,t)>=0:Q(r,t,r.prev)<0||Q(r,r.next,t)<0}function Nv(r,t){var e=r,s=!1,i=(r.x+t.x)/2,n=(r.y+t.y)/2;do e.y>n!=e.next.y>n&&e.next.y!==e.y&&i<(e.next.x-e.x)*(n-e.y)/(e.next.y-e.y)+e.x&&(s=!s),e=e.next;while(e!==r);return s}function qh(r,t){var e=new Gn(r.i,r.x,r.y),s=new Gn(t.i,t.x,t.y),i=r.next,n=t.prev;return r.next=t,t.prev=r,e.next=i,i.prev=e,s.next=e,e.prev=s,n.next=s,s.prev=n,s}function Zh(r,t,e,s){var i=new Gn(r,t,e);return s?(i.next=s.next,i.prev=s,s.next.prev=i,s.next=i):(i.prev=i,i.next=i),i}function _r(r){r.next.prev=r.prev,r.prev.next=r.next,r.prevZ&&(r.prevZ.nextZ=r.nextZ),r.nextZ&&(r.nextZ.prevZ=r.prevZ)}function Gn(r,t,e){this.i=r,this.x=t,this.y=e,this.prev=null,this.next=null,this.z=0,this.prevZ=null,this.nextZ=null,this.steiner=!1}Ts.deviation=function(r,t,e,s){var i=t&&t.length,n=i?t[0]*e:r.length,o=Math.abs(In(r,0,n,e));if(i)for(var a=0,u=t.length;a0&&(s+=r[i-1].length,e.holes.push(s))}return e};var Hv=ys.exports,Qh=ki(Hv);function Bn(r,t,e,s,i,n,o){const a=Qh(r,t,2);if(!a)return;for(let l=0;l=0&&o>=0&&(t[0]=s,t[1]=i,t[2]=s+n,t[3]=i,t[4]=s+n,t[5]=i+o,t[6]=s,t[7]=i+o),t},triangulate(r,t,e,s,i,n){let o=0;s*=e,t[s+o]=r[0],t[s+o+1]=r[1],o+=e,t[s+o]=r[2],t[s+o+1]=r[3],o+=e,t[s+o]=r[6],t[s+o+1]=r[7],o+=e,t[s+o]=r[4],t[s+o+1]=r[5],o+=e;const a=s/e;i[n++]=a,i[n++]=a+1,i[n++]=a+2,i[n++]=a+1,i[n++]=a+3,i[n++]=a+2}},Un={build(r,t){return t[0]=r.x,t[1]=r.y,t[2]=r.x2,t[3]=r.y2,t[4]=r.x3,t[5]=r.y3,t},triangulate(r,t,e,s,i,n){let o=0;s*=e,t[s+o]=r[0],t[s+o+1]=r[1],o+=e,t[s+o]=r[2],t[s+o+1]=r[3],o+=e,t[s+o]=r[4],t[s+o+1]=r[5];const a=s/e;i[n++]=a,i[n++]=a+1,i[n++]=a+2}},kn={rectangle:Dn,polygon:Fn,triangle:Un,circle:_e,ellipse:_e,roundedRectangle:_e},zv=new z;function Jh(r,t){const{geometryData:e,batches:s}=t;s.length=0,e.indices.length=0,e.vertices.length=0,e.uvs.length=0;for(let i=0;i{var p;const f=u.length,g=o.length/2,m=[],_=kn[h.type];if(_.build(h,m),c&&xs(m,c),s){const S=(p=h.closePath)!=null?p:!0;Wh(m,t,!1,S,o,2,g,u,f)}else if(e&&l===d){l!==0&&console.warn("[Pixi Graphics] only the last shape have be cut out");const S=[],P=m.slice();Vv(e.shapePath).forEach(R=>{S.push(P.length/2),P.push(...R)}),Bn(P,S,o,2,g,u,f)}else _.triangulate(m,o,2,g,u,f);const x=a.length/2,b=t.texture;if(b!==A.WHITE){const S=t.matrix;c&&S.append(c.clone().invert()),wn(o,2,g,a,x,2,o.length/2-g,S)}else Rn(a,x,2,o.length/2-g);const y=H.get(vs);y.indexOffset=f,y.indexSize=u.length-f,y.vertexOffset=g,y.vertexSize=o.length/2-g,y.color=t.color,y.alpha=t.alpha,y.texture=b,y.geometryData=n,i.push(y)})}function Vv(r){if(!r)return[];const t=r.shapePrimitives,e=[];for(let s=0;s{H.return(s)})}destroy(){for(const t of this._needsContextNeedsRebuild)this._gpuContextHash[t.uid]&&this.onGraphicsContextDestroy(t);this._needsContextNeedsRebuild.length=0}};Ln.extension={type:[v.WebGLSystem,v.WebGPUSystem,v.CanvasSystem],name:"graphicsContext"},Ln.defaultOptions={bezierSmoothness:.5};let Ps=Ln;const Wv={normal:0,add:1,multiply:2,screen:3,overlay:4,erase:5,"normal-npm":6,"add-npm":7,"screen-npm":8},$n=0,Nn=1,Hn=2,Xn=3,zn=4,jn=5,Vn=class Ax{constructor(){this.data=0,this.blendMode="normal",this.polygonOffset=0,this.blend=!0,this.depthMask=!0}get blend(){return!!(this.data&1<<$n)}set blend(t){!!(this.data&1<<$n)!==t&&(this.data^=1<<$n)}get offsets(){return!!(this.data&1<>16&255)/255,e[s++]=(r>>8&255)/255,e[s++]=(r&255)/255,e[s++]=t}function xr(r,t,e){const s=(r>>24&255)/255;t[e++]=(r&255)/255*s,t[e++]=(r>>8&255)/255*s,t[e++]=(r>>16&255)/255*s,t[e++]=s}class Wn{constructor(t,e){this.state=Ct.for2d(),this._graphicsBatchesHash=Object.create(null),this.renderer=t,this._adaptor=e,this._adaptor.init()}validateRenderable(t){const e=t.context,s=!!this._graphicsBatchesHash[t.uid],i=this.renderer.graphicsContext.updateGpuContext(e);return!!(i.isBatchable||s!==i.isBatchable)}addRenderable(t,e){const s=this.renderer.graphicsContext.updateGpuContext(t.context);t._didGraphicsUpdate&&(t._didGraphicsUpdate=!1,this._rebuild(t)),s.isBatchable?this._addToBatcher(t,e):(this.renderer.renderPipes.batch.break(e),e.add(t))}updateRenderable(t){const e=this._graphicsBatchesHash[t.uid];if(e)for(let s=0;s{const a=H.get(vs);return o.copyTo(a),a.renderable=t,a.roundPixels=i,a});return this._graphicsBatchesHash[t.uid]=n,t.on("destroyed",()=>{this.destroyRenderable(t)}),n}_removeBatchForRenderable(t){this._graphicsBatchesHash[t].forEach(e=>{H.return(e)}),this._graphicsBatchesHash[t]=null}destroy(){this.renderer=null,this._adaptor.destroy(),this._adaptor=null,this.state=null;for(const t in this._graphicsBatchesHash)this._removeBatchForRenderable(t);this._graphicsBatchesHash=null}}Wn.extension={type:[v.WebGLPipes,v.WebGPUPipes,v.CanvasPipes],name:"graphics"},D.add(Wn),D.add(Ps);const Yn=Object.create(null),sc=Object.create(null);function br(r,t){let e=sc[r];return e===void 0&&(Yn[t]===void 0&&(Yn[t]=1),sc[r]=e=Yn[t]++),e}function ic(r,t){switch(r){case"f32":return 0;case"vec2":return new Float32Array(2*t);case"vec3":return new Float32Array(3*t);case"vec4":return new Float32Array(4*t);case"mat2x2":return new Float32Array([1,0,0,1]);case"mat3x3":return new Float32Array([1,0,0,0,1,0,0,0,1]);case"mat4x4":return new Float32Array([1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1])}return null}var Kv=Object.defineProperty,nc=Object.getOwnPropertySymbols,qv=Object.prototype.hasOwnProperty,Zv=Object.prototype.propertyIsEnumerable,oc=(r,t,e)=>t in r?Kv(r,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):r[t]=e,ac=(r,t)=>{for(var e in t||(t={}))qv.call(t,e)&&oc(r,e,t[e]);if(nc)for(var e of nc(t))Zv.call(t,e)&&oc(r,e,t[e]);return r};const uc=class Px{constructor(t,e){this._touched=0,this.uid=Z("uniform"),this._resourceType="uniformGroup",this._resourceId=Z("resource"),this.isUniformGroup=!0,this._dirtyId=0;var s,i;e=ac(ac({},Px.defaultOptions),e),this.uniformStructures=t;const n={};for(const o in t){const a=t[o];a.name=o,a.size=(s=a.size)!=null?s:1,(i=a.value)!=null||(a.value=ic(a.type,a.size)),n[o]=a.value}this.uniforms=n,this._dirtyId=1,this.ubo=e.ubo,this.isStatic=e.isStatic,this._signature=br(Object.keys(n).map(o=>`${o}-${t[o].type}`).join("-"),"uniform-group")}update(){this._dirtyId++}};uc.defaultOptions={ubo:!1,isStatic:!1};let it=uc;class ws{constructor(){this.batcher=null,this.batch=null,this.roundPixels=0,this._uvUpdateId=-1,this._textureMatrixUpdateId=-1}get blendMode(){return this.mesh.groupBlendMode}reset(){this.mesh=null,this.texture=null,this.batcher=null,this.batch=null}packIndex(t,e,s){const i=this.geometry.indices;for(let n=0;n"},uColor:{value:new Float32Array([1,1,1,1]),type:"vec4"},uRound:{value:0,type:"f32"}}),this.localUniformsBindGroup=new Lt({0:this.localUniforms}),this._meshDataHash=Object.create(null),this._gpuBatchableMeshHash=Object.create(null),this.renderer=t,this._adaptor=e,this._adaptor.init()}validateRenderable(t){const e=this._getMeshData(t),s=e.batched,i=t.batched;if(e.batched=i,s!==i)return!0;if(i){const n=t._geometry;if(n.indices.length!==e.indexSize||n.positions.length!==e.vertexSize)return e.indexSize=n.indices.length,e.vertexSize=n.positions.length,!0;const o=this._getBatchableMesh(t),a=t.texture;if(o.texture._source!==a._source&&o.texture._source!==a._source)return!o.batcher.checkAndUpdateTexture(o,a)}return!1}addRenderable(t,e){const s=this.renderer.renderPipes.batch,{batched:i}=this._getMeshData(t);if(i){const n=this._getBatchableMesh(t);n.texture=t._texture,n.geometry=t._geometry,s.addToBatch(n)}else s.break(e),e.add({renderPipeId:"mesh",mesh:t})}updateRenderable(t){if(t.batched){const e=this._gpuBatchableMeshHash[t.uid];e.texture=t._texture,e.geometry=t._geometry,e.batcher.updateElement(e)}}destroyRenderable(t){this._meshDataHash[t.uid]=null;const e=this._gpuBatchableMeshHash[t.uid];e&&(H.return(e),this._gpuBatchableMeshHash[t.uid]=null)}execute({mesh:t}){if(!t.isRenderable)return;t.state.blendMode=t.groupBlendMode;const e=this.localUniforms;e.uniforms.uTransformMatrix=t.groupTransform,e.uniforms.uRound=this.renderer._roundPixels|t._roundPixels,e.update(),xr(t.groupColorAlpha,e.uniforms.uColor,0),this._adaptor.execute(this,t)}_getMeshData(t){return this._meshDataHash[t.uid]||this._initMeshData(t)}_initMeshData(t){var e,s;return this._meshDataHash[t.uid]={batched:t.batched,indexSize:(e=t._geometry.indices)==null?void 0:e.length,vertexSize:(s=t._geometry.positions)==null?void 0:s.length},t.on("destroyed",()=>{this.destroyRenderable(t)}),this._meshDataHash[t.uid]}_getBatchableMesh(t){return this._gpuBatchableMeshHash[t.uid]||this._initBatchableMesh(t)}_initBatchableMesh(t){const e=H.get(ws);return e.mesh=t,e.texture=t._texture,e.roundPixels=this.renderer._roundPixels|t._roundPixels,this._gpuBatchableMeshHash[t.uid]=e,e.mesh=t,e}destroy(){for(const t in this._gpuBatchableMeshHash)this._gpuBatchableMeshHash[t]&&H.return(this._gpuBatchableMeshHash[t]);this._gpuBatchableMeshHash=null,this._meshDataHash=null,this.localUniforms=null,this.localUniformsBindGroup=null,this._adaptor.destroy(),this._adaptor=null,this.renderer=null}}Kn.extension={type:[v.WebGLPipes,v.WebGPUPipes,v.CanvasPipes],name:"mesh"},D.add(Kn);class Rs{constructor(){this.vertexSize=4,this.indexSize=6,this.location=0,this.batcher=null,this.batch=null,this.roundPixels=0}get blendMode(){return this.renderable.groupBlendMode}packAttributes(t,e,s,i){const n=this.renderable,o=this.texture,a=n.groupTransform,u=a.a,l=a.b,h=a.c,c=a.d,d=a.tx,p=a.ty,f=this.bounds,g=f.maxX,m=f.minX,_=f.maxY,x=f.minY,b=o.uvs,y=n.groupColorAlpha,S=i<<16|this.roundPixels&65535;t[s+0]=u*m+h*x+d,t[s+1]=c*x+l*m+p,t[s+2]=b.x0,t[s+3]=b.y0,e[s+4]=y,e[s+5]=S,t[s+6]=u*g+h*x+d,t[s+7]=c*x+l*g+p,t[s+8]=b.x1,t[s+9]=b.y1,e[s+10]=y,e[s+11]=S,t[s+12]=u*g+h*_+d,t[s+13]=c*_+l*g+p,t[s+14]=b.x2,t[s+15]=b.y2,e[s+16]=y,e[s+17]=S,t[s+18]=u*m+h*_+d,t[s+19]=c*_+l*m+p,t[s+20]=b.x3,t[s+21]=b.y3,e[s+22]=y,e[s+23]=S}packIndex(t,e,s){t[e]=s+0,t[e+1]=s+1,t[e+2]=s+2,t[e+3]=s+0,t[e+4]=s+2,t[e+5]=s+3}reset(){this.renderable=null,this.texture=null,this.batcher=null,this.batch=null,this.bounds=null}}class qn{constructor(t){this._gpuText=Object.create(null),this._renderer=t}validateRenderable(t){var e;const s=this._getGpuText(t),i=t._getKey();if(s.currentKey!==i){const n=(e=t.resolution)!=null?e:this._renderer.resolution,{width:o,height:a}=this._renderer.canvasText.getTextureSize(t.text,n,t._style);return!(this._renderer.canvasText.getReferenceCount(s.currentKey)===1&&o===s.texture._source.width&&a===s.texture._source.height)}return!1}addRenderable(t,e){const s=this._getGpuText(t).batchableSprite;t._didTextUpdate&&this._updateText(t),this._renderer.renderPipes.batch.addToBatch(s)}updateRenderable(t){const e=this._getGpuText(t).batchableSprite;t._didTextUpdate&&this._updateText(t),e.batcher.updateElement(e)}destroyRenderable(t){this._destroyRenderableById(t.uid)}_destroyRenderableById(t){const e=this._gpuText[t];this._renderer.canvasText.decreaseReferenceCount(e.currentKey),H.return(e.batchableSprite),this._gpuText[t]=null}_updateText(t){const e=t._getKey(),s=this._getGpuText(t),i=s.batchableSprite;s.currentKey!==e&&this._updateGpuText(t),t._didTextUpdate=!1;const n=t._style.padding;dr(i.bounds,t._anchor,i.texture,n)}_updateGpuText(t){var e;const s=this._getGpuText(t),i=s.batchableSprite;s.texture&&this._renderer.canvasText.decreaseReferenceCount(s.currentKey);const n=(e=t.resolution)!=null?e:this._renderer.resolution;s.texture=i.texture=this._renderer.canvasText.getTexture(t.text,n,t._style,t._getKey()),s.currentKey=t._getKey(),i.texture=s.texture}_getGpuText(t){return this._gpuText[t.uid]||this.initGpuText(t)}initGpuText(t){const e={texture:null,currentKey:"--",batchableSprite:H.get(Rs)};return e.batchableSprite.renderable=t,e.batchableSprite.bounds={minX:0,maxX:1,minY:0,maxY:0},e.batchableSprite.roundPixels=this._renderer._roundPixels|t._roundPixels,this._gpuText[t.uid]=e,this._updateText(t),t.on("destroyed",()=>{this.destroyRenderable(t)}),e}destroy(){for(const t in this._gpuText)this._destroyRenderableById(t);this._gpuText=null,this._renderer=null}}qn.extension={type:[v.WebGLPipes,v.WebGPUPipes,v.CanvasPipes],name:"text"};class lc{constructor(t){this._canvasPool=Object.create(null),this.canvasOptions=t||{},this.enableFullScreen=!1}_createCanvasAndContext(t,e){const s=X.get().createCanvas();s.width=t,s.height=e;const i=s.getContext("2d");return{canvas:s,context:i}}getOptimalCanvasAndContext(t,e,s=1){t=Math.ceil(t*s-1e-6),e=Math.ceil(e*s-1e-6),t=me(t),e=me(e);const i=(t<<17)+(e<<1);this._canvasPool[i]||(this._canvasPool[i]=[]);let n=this._canvasPool[i].pop();return n||(n=this._createCanvasAndContext(t,e)),n}returnCanvasAndContext(t){const{width:e,height:s}=t.canvas,i=(e<<17)+(s<<1);this._canvasPool[i].push(t)}clear(){this._canvasPool={}}}const jt=new lc;var Qv=Object.defineProperty,Jv=Object.defineProperties,t0=Object.getOwnPropertyDescriptors,hc=Object.getOwnPropertySymbols,e0=Object.prototype.hasOwnProperty,r0=Object.prototype.propertyIsEnumerable,cc=(r,t,e)=>t in r?Qv(r,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):r[t]=e,s0=(r,t)=>{for(var e in t||(t={}))e0.call(t,e)&&cc(r,e,t[e]);if(hc)for(var e of hc(t))r0.call(t,e)&&cc(r,e,t[e]);return r},i0=(r,t)=>Jv(r,t0(t));let n0=0;class dc{constructor(t){this._poolKeyHash=Object.create(null),this._texturePool={},this.textureOptions=t||{},this.enableFullScreen=!1}createTexture(t,e,s){const i=new et(i0(s0({},this.textureOptions),{width:t,height:e,resolution:1,antialias:s,autoGarbageCollect:!0}));return new A({source:i,label:`texturePool_${n0++}`})}getOptimalTexture(t,e,s=1,i){let n=Math.ceil(t*s-1e-6),o=Math.ceil(e*s-1e-6);n=me(n),o=me(o);const a=(n<<17)+(o<<1)+(i?1:0);this._texturePool[a]||(this._texturePool[a]=[]);let u=this._texturePool[a].pop();return u||(u=this.createTexture(n,o,i)),u.source._resolution=s,u.source.width=n/s,u.source.height=o/s,u.source.pixelWidth=n,u.source.pixelHeight=o,u.frame.x=0,u.frame.y=0,u.frame.width=t,u.frame.height=e,u.updateUvs(),this._poolKeyHash[u.uid]=a,u}getSameSizeTexture(t,e=!1){const s=t.source;return this.getOptimalTexture(t.width,t.height,s._resolution,e)}returnTexture(t){const e=this._poolKeyHash[t.uid];this._texturePool[e].push(t)}clear(t){if(t=t!==!1,t)for(const e in this._texturePool){const s=this._texturePool[e];if(s)for(let i=0;i=0;s--){let i=e[s].trim();!/([\"\'])[^\'\"]+\1/.test(i)&&!a0.includes(i)&&(i=`"${i}"`),e[s]=i}return`${r.fontStyle} ${r.fontVariant} ${r.fontWeight} ${t} ${e.join(",")}`}const Qn={willReadFrequently:!0},Gt=class O{static get experimentalLetterSpacingSupported(){let t=O._experimentalLetterSpacingSupported;if(t!==void 0){const e=X.get().getCanvasRenderingContext2D().prototype;t=O._experimentalLetterSpacingSupported="letterSpacing"in e||"textLetterSpacing"in e}return t}constructor(t,e,s,i,n,o,a,u,l){this.text=t,this.style=e,this.width=s,this.height=i,this.lines=n,this.lineWidths=o,this.lineHeight=a,this.maxLineWidth=u,this.fontProperties=l}static measureText(t=" ",e,s=O._canvas,i=e.wordWrap){var n;const o=`${t}:${e.styleKey}`;if(O._measurementCache[o])return O._measurementCache[o];const a=vr(e),u=O.measureFont(a);u.fontSize===0&&(u.fontSize=e.fontSize,u.ascent=e.fontSize);const l=O.__context;l.font=a;const h=(i?O._wordWrap(t,e,s):t).split(/(?:\r\n|\r|\n)/),c=new Array(h.length);let d=0;for(let _=0;_0&&(i?n-=e:n+=(O.graphemeSegmenter(t).length-1)*e),n}static _wordWrap(t,e,s=O._canvas){const i=s.getContext("2d",Qn);let n=0,o="",a="";const u=Object.create(null),{letterSpacing:l,whiteSpace:h}=e,c=O._collapseSpaces(h),d=O._collapseNewlines(h);let p=!c;const f=e.wordWrapWidth+l,g=O._tokenize(t);for(let m=0;mf)if(o!==""&&(a+=O._addLine(o),o="",n=0),O.canBreakWords(_,e.breakWords)){const b=O.wordWrapSplit(_);for(let y=0;yf&&(a+=O._addLine(o),p=!1,o="",n=0),o+=S,n+=w}}else{o.length>0&&(a+=O._addLine(o),o="",n=0);const b=m===g.length-1;a+=O._addLine(_,!b),p=!1,o="",n=0}else x+n>f&&(p=!1,a+=O._addLine(o),o="",n=0),(o.length>0||!O.isBreakingSpace(_)||p)&&(o+=_,n+=x)}return a+=O._addLine(o,!1),a}static _addLine(t,e=!0){return t=O._trimRight(t),t=e?`${t} -`:t,t}static _getFromCache(t,e,s,i){let n=s[t];return typeof n!="number"&&(n=O._measureText(t,e,i)+e,s[t]=n),n}static _collapseSpaces(t){return t==="normal"||t==="pre-line"}static _collapseNewlines(t){return t==="normal"}static _trimRight(t){if(typeof t!="string")return"";for(let e=t.length-1;e>=0;e--){const s=t[e];if(!O.isBreakingSpace(s))break;t=t.slice(0,-1)}return t}static _isNewline(t){return typeof t!="string"?!1:O._newlines.includes(t.charCodeAt(0))}static isBreakingSpace(t,e){return typeof t!="string"?!1:O._breakingSpaces.includes(t.charCodeAt(0))}static _tokenize(t){const e=[];let s="";if(typeof t!="string")return e;for(let i=0;i{if(typeof(Intl==null?void 0:Intl.Segmenter)=="function"){const r=new Intl.Segmenter;return t=>[...r.segment(t)].map(e=>e.segment)}return r=>[...r]})(),Gt.experimentalLetterSpacing=!1,Gt._fonts={},Gt._newlines=[10,13],Gt._breakingSpaces=[9,32,8192,8193,8194,8195,8196,8197,8198,8200,8201,8202,8287,12288],Gt._measurementCache={};let It=Gt;const gc=class Wu{constructor(t,e,s,i){this.uid=Z("fillGradient"),this.type="linear",this.gradientStops=[],this.x0=t,this.y0=e,this.x1=s,this.y1=i}addColorStop(t,e){return this.gradientStops.push({offset:t,color:W.shared.setValue(e).toHex()}),this}buildLinearGradient(){const t=Wu.defaultTextureSize,{gradientStops:e}=this,s=X.get().createCanvas();s.width=t,s.height=t;const i=s.getContext("2d"),n=i.createLinearGradient(0,0,Wu.defaultTextureSize,1);for(let g=0;g{s.addColorStop(i.offset,W.shared.setValue(i.color).toHex())}),s}}}else{const e=t.createPattern(r.texture.source.resource,"repeat"),s=r.matrix.copyTo(G.shared);return s.scale(r.texture.frame.width,r.texture.frame.height),e.setTransform(s),e}return"red"}class to{constructor(){this._activeTextures={}}getTextureSize(t,e,s){const i=It.measureText(t||" ",s);let n=Math.ceil(Math.ceil(Math.max(1,i.width)+s.padding*2)*e),o=Math.ceil(Math.ceil(Math.max(1,i.height)+s.padding*2)*e);return n=Math.ceil(n-1e-6),o=Math.ceil(o-1e-6),n=me(n),o=me(o),{width:n,height:o}}getTexture(t,e,s,i){if(this._activeTextures[i])return this._increaseReferenceCount(i),this._activeTextures[i].texture;const n=It.measureText(t||" ",s),o=Math.ceil(Math.ceil(Math.max(1,n.width)+s.padding*2)*e),a=Math.ceil(Math.ceil(Math.max(1,n.height)+s.padding*2)*e),u=jt.getOptimalCanvasAndContext(o,a),{canvas:l}=u;this.renderTextToCanvas(t,s,e,u);const h=Zn(l,o,a,e);if(s.trim){const c=mc(l,e);h.frame.copyFrom(c),h.updateUvs()}return this._activeTextures[i]={canvasAndContext:u,texture:h,usageCount:1},h}_increaseReferenceCount(t){this._activeTextures[t].usageCount++}decreaseReferenceCount(t){const e=this._activeTextures[t];if(e.usageCount--,e.usageCount===0){jt.returnCanvasAndContext(e.canvasAndContext),ut.returnTexture(e.texture);const s=e.texture.source;s.resource=null,s.uploadMethodId="unknown",s.alphaMode="no-premultiply-alpha",this._activeTextures[t]=null}}getReferenceCount(t){return this._activeTextures[t].usageCount}renderTextToCanvas(t,e,s,i){var n,o,a,u,l,h;const{canvas:c,context:d}=i,p=vr(e),f=It.measureText(t||" ",e),g=f.lines,m=f.lineHeight,_=f.lineWidths,x=f.maxLineWidth,b=f.fontProperties,y=c.height;if(d.resetTransform(),d.scale(s,s),d.clearRect(0,0,f.width+4,f.height+4),(n=e._stroke)!=null&&n.width){const w=e._stroke;d.lineWidth=w.width,d.miterLimit=w.miterLimit,d.lineJoin=w.join,d.lineCap=w.cap}d.font=p;let S,P;const R=e.dropShadow?2:1;for(let w=0;we.texture.destroy(!0)),this.pages=null)}}var u0=h0,ro={a:7,c:6,h:1,l:2,m:2,q:4,s:4,t:2,v:1,z:0},l0=/([astvzqmhlc])([^astvzqmhlc]*)/ig;function h0(r){var t=[];return r.replace(l0,function(e,s,i){var n=s.toLowerCase();for(i=d0(i),n=="m"&&i.length>2&&(t.push([s].concat(i.splice(0,2))),n="l",s=s=="m"?"l":"L");;){if(i.length==ro[n])return i.unshift(s),t.push(i);if(i.length0&&(i=s.pop(),i?(n=i.startX,o=i.startY):(n=0,o=0)),i=null;break;default:}l!=="Z"&&l!=="z"&&i===null&&(i={startX:n,startY:o},s.push(i))}return t}class Ii{constructor(t=0,e=0,s=0){this.type="circle",this.x=t,this.y=e,this.radius=s}clone(){return new Ii(this.x,this.y,this.radius)}contains(t,e){if(this.radius<=0)return!1;const s=this.radius*this.radius;let i=this.x-t,n=this.y-e;return i*=i,n*=n,i+n<=s}strokeContains(t,e,s){if(this.radius===0)return!1;const i=this.x-t,n=this.y-e,o=this.radius,a=s/2,u=Math.sqrt(i*i+n*n);return uo-a}getBounds(t){return t=t||new z,t.x=this.x-this.radius,t.y=this.y-this.radius,t.width=this.radius*2,t.height=this.radius*2,t}copyFrom(t){return this.x=t.x,this.y=t.y,this.radius=t.radius,this}copyTo(t){return t.copyFrom(this),t}}class Bi{constructor(t=0,e=0,s=0,i=0){this.type="ellipse",this.x=t,this.y=e,this.halfWidth=s,this.halfHeight=i}clone(){return new Bi(this.x,this.y,this.halfWidth,this.halfHeight)}contains(t,e){if(this.halfWidth<=0||this.halfHeight<=0)return!1;let s=(t-this.x)/this.halfWidth,i=(e-this.y)/this.halfHeight;return s*=s,i*=i,s+i<=1}strokeContains(t,e,s){const{halfWidth:i,halfHeight:n}=this;if(i<=0||n<=0)return!1;const o=s/2,a=i-o,u=n-o,l=i+o,h=n+o,c=t-this.x,d=e-this.y,p=c*c/(a*a)+d*d/(u*u),f=c*c/(l*l)+d*d/(h*h);return p>1&&f<=1}getBounds(){return new z(this.x-this.halfWidth,this.y-this.halfHeight,this.halfWidth*2,this.halfHeight*2)}copyFrom(t){return this.x=t.x,this.y=t.y,this.halfWidth=t.halfWidth,this.halfHeight=t.halfHeight,this}copyTo(t){return t.copyFrom(this),t}}function Tr(r,t,e,s,i,n){const o=r-e,a=t-s,u=i-e,l=n-s,h=o*u+a*l,c=u*u+l*l;let d=-1;c!==0&&(d=h/c);let p,f;d<0?(p=e,f=s):d>1?(p=i,f=n):(p=e+d*u,f=s+d*l);const g=r-p,m=t-f;return g*g+m*m}class Ae{constructor(...t){this.type="polygon";let e=Array.isArray(t[0])?t[0]:t;if(typeof e[0]!="number"){const s=[];for(let i=0,n=e.length;ie!=h>e&&t<(l-a)*((e-u)/(h-u))+a&&(s=!s)}return s}strokeContains(t,e,s){const i=s/2,n=i*i,{points:o}=this;for(let a=0;ai?l:i,n=ho?h:o}return t.x=s,t.width=i-s,t.y=n,t.height=o-n,t}copyFrom(t){return this.points=t.points.slice(),this.closePath=t.closePath,this}copyTo(t){return t.copyFrom(this),t}get lastX(){return this.points[this.points.length-2]}get lastY(){return this.points[this.points.length-1]}get x(){return this.points[this.points.length-2]}get y(){return this.points[this.points.length-1]}}const Os=(r,t,e,s,i,n)=>{const o=r-e,a=t-s,u=Math.sqrt(o*o+a*a);return u>=i-n&&u<=i+n};class Fi{constructor(t=0,e=0,s=0,i=0,n=20){this.type="roundedRectangle",this.x=t,this.y=e,this.width=s,this.height=i,this.radius=n}getBounds(t){return t=t||new z,t.x=this.x,t.y=this.y,t.width=this.width,t.height=this.height,t}clone(){return new Fi(this.x,this.y,this.width,this.height,this.radius)}copyFrom(t){return this.x=t.x,this.y=t.y,this.width=t.width,this.height=t.height,this}copyTo(t){return t.copyFrom(this),t}contains(t,e){if(this.width<=0||this.height<=0)return!1;if(t>=this.x&&t<=this.x+this.width&&e>=this.y&&e<=this.y+this.height){const s=Math.max(0,Math.min(this.radius,Math.min(this.width,this.height)/2));if(e>=this.y+s&&e<=this.y+this.height-s||t>=this.x+s&&t<=this.x+this.width-s)return!0;let i=t-(this.x+s),n=e-(this.y+s);const o=s*s;if(i*i+n*n<=o||(i=t-(this.x+this.width-s),i*i+n*n<=o)||(n=e-(this.y+this.height-s),i*i+n*n<=o)||(i=t-(this.x+s),i*i+n*n<=o))return!0}return!1}strokeContains(t,e,s){const{x:i,y:n,width:o,height:a,radius:u}=this,l=s/2,h=i+u,c=n+u,d=o-u*2,p=a-u*2,f=i+o,g=n+a;return(t>=i-l&&t<=i+l||t>=f-l&&t<=f+l)&&e>=c&&e<=c+p||(e>=n-l&&e<=n+l||e>=g-l&&e<=g+l)&&t>=h&&t<=h+d?!0:tf-u&&ef-u&&e>g-u&&Os(t,e,f-u,g-u,u,l)||tg-u&&Os(t,e,h,g-u,u,l)}}const f0=8,Cs=11920929e-14,m0=1,so=.01,Ie=0,ve=0;function io(r,t,e,s,i,n,o,a,u,l){const h=Math.min(.99,Math.max(0,l!=null?l:Ps.defaultOptions.bezierSmoothness));let c=(m0-h)/1;return c*=c,g0(t,e,s,i,n,o,a,u,r,c),r}function g0(r,t,e,s,i,n,o,a,u,l){no(r,t,e,s,i,n,o,a,u,l,0),u.push(o,a)}function no(r,t,e,s,i,n,o,a,u,l,h){if(h>f0)return;const c=Math.PI,d=(r+e)/2,p=(t+s)/2,f=(e+i)/2,g=(s+n)/2,m=(i+o)/2,_=(n+a)/2,x=(d+f)/2,b=(p+g)/2,y=(f+m)/2,S=(g+_)/2,P=(x+y)/2,R=(b+S)/2;if(h>0){let w=o-r,T=a-t;const E=Math.abs((e-o)*T-(s-a)*w),L=Math.abs((i-o)*T-(n-a)*w);let k,C;if(E>Cs&&L>Cs){if((E+L)*(E+L)<=l*(w*w+T*T)){if(Ie=c&&(k=2*c-k),C>=c&&(C=2*c-C),k+Cve){u.push(e,s);return}if(C>ve){u.push(i,n);return}}}}else if(E>Cs){if(E*E<=l*(w*w+T*T)){if(Ie=c&&(k=2*c-k),kve){u.push(e,s);return}}}else if(L>Cs){if(L*L<=l*(w*w+T*T)){if(Ie=c&&(k=2*c-k),kve){u.push(i,n);return}}}else if(w=P-(r+o)/2,T=R-(t+a)/2,w*w+T*T<=l){u.push(P,R);return}}no(r,t,d,p,x,b,P,R,u,l,h+1),no(P,R,y,S,m,_,o,a,u,l,h+1)}const _0=8,x0=11920929e-14,b0=1,v0=.01,bc=0;function vc(r,t,e,s,i,n,o,a){const u=Math.min(.99,Math.max(0,a!=null?a:Ps.defaultOptions.bezierSmoothness));let l=(b0-u)/1;return l*=l,y0(t,e,s,i,n,o,r,l),r}function y0(r,t,e,s,i,n,o,a){oo(o,r,t,e,s,i,n,a,0),o.push(i,n)}function oo(r,t,e,s,i,n,o,a,u){if(u>_0)return;const l=Math.PI,h=(t+s)/2,c=(e+i)/2,d=(s+n)/2,p=(i+o)/2,f=(h+d)/2,g=(c+p)/2;let m=n-t,_=o-e;const x=Math.abs((s-n)*_-(i-o)*m);if(x>x0){if(x*x<=a*(m*m+_*_)){if(bc=l&&(b=2*l-b),bn||o&&n>i)&&(u=2*Math.PI-u),a=a||Math.max(6,Math.floor(6*Math.pow(s,1/3)*(u/Math.PI))),a=Math.max(a,3);let l=u/a,h=i;l*=o?-1:1;for(let c=0;ch*a)}const Sr=Math.PI*2,uo={centerX:0,centerY:0,ang1:0,ang2:0},lo=({x:r,y:t},e,s,i,n,o,a,u)=>{r*=e,t*=s;const l=i*r-n*t,h=n*r+i*t;return u.x=l+o,u.y=h+a,u};function T0(r,t){const e=t===-1.5707963267948966?-.551915024494:1.3333333333333333*Math.tan(t/4),s=t===1.5707963267948966?.551915024494:e,i=Math.cos(r),n=Math.sin(r),o=Math.cos(r+t),a=Math.sin(r+t);return[{x:i-n*s,y:n+i*s},{x:o+a*s,y:a-o*s},{x:o,y:a}]}const Tc=(r,t,e,s)=>{const i=r*s-t*e<0?-1:1;let n=r*e+t*s;return n>1&&(n=1),n<-1&&(n=-1),i*Math.acos(n)},S0=(r,t,e,s,i,n,o,a,u,l,h,c,d)=>{const p=Math.pow(i,2),f=Math.pow(n,2),g=Math.pow(h,2),m=Math.pow(c,2);let _=p*f-p*m-f*g;_<0&&(_=0),_/=p*m+f*g,_=Math.sqrt(_)*(o===a?-1:1);const x=_*i/n*c,b=_*-n/i*h,y=l*x-u*b+(r+e)/2,S=u*x+l*b+(t+s)/2,P=(h-x)/i,R=(c-b)/n,w=(-h-x)/i,T=(-c-b)/n,E=Tc(1,0,P,R);let L=Tc(P,R,w,T);a===0&&L>0&&(L-=Sr),a===1&&L<0&&(L+=Sr),d.centerX=y,d.centerY=S,d.ang1=E,d.ang2=L};function Sc(r,t,e,s,i,n,o,a=0,u=0,l=0){if(n===0||o===0)return;const h=Math.sin(a*Sr/360),c=Math.cos(a*Sr/360),d=c*(t-s)/2+h*(e-i)/2,p=-h*(t-s)/2+c*(e-i)/2;if(d===0&&p===0)return;n=Math.abs(n),o=Math.abs(o);const f=Math.pow(d,2)/Math.pow(n,2)+Math.pow(p,2)/Math.pow(o,2);f>1&&(n*=Math.sqrt(f),o*=Math.sqrt(f)),S0(t,e,s,i,n,o,u,l,h,c,d,p,uo);let{ang1:g,ang2:m}=uo;const{centerX:_,centerY:x}=uo;let b=Math.abs(m)/(Sr/4);Math.abs(1-b)<1e-7&&(b=1);const y=Math.max(Math.ceil(b),1);m/=y;let S=r[r.length-2],P=r[r.length-1];const R={x:0,y:0};for(let w=0;w{const l=u.x-a.x,h=u.y-a.y,c=Math.sqrt(l*l+h*h),d=l/c,p=h/c;return{len:c,nx:d,ny:p}},n=(a,u)=>{a===0?r.moveTo(u.x,u.y):r.lineTo(u.x,u.y)};let o=t[t.length-1];for(let a=0;a0&&(f=-1,g=!0);const m=p/2;let _,x=Math.abs(Math.cos(m)*l/Math.sin(m));x>Math.min(c.len/2,d.len/2)?(x=Math.min(c.len/2,d.len/2),_=Math.abs(x*Math.sin(m)/Math.cos(m))):_=l;const b=u.x+d.nx*x+-d.ny*_*f,y=u.y+d.ny*x+d.nx*_*f,S=Math.atan2(c.ny,c.nx)+Math.PI/2*f,P=Math.atan2(d.ny,d.nx)-Math.PI/2*f;a===0&&r.moveTo(b+Math.cos(S)*_,y+Math.sin(S)*_),r.arc(b,y,_,S,P,g),o=u}}function Ac(r,t,e,s){var i;const n=(u,l)=>Math.sqrt((u.x-l.x)**2+(u.y-l.y)**2),o=(u,l,h)=>({x:u.x+(l.x-u.x)*h,y:u.y+(l.y-u.y)*h}),a=t.length;for(let u=0;u=2;c-=2)h[c]===h[c-2]&&h[c-1]===h[c-3]&&h.splice(c-1,2);return this.poly(h,!0,o)}ellipse(t,e,s,i,n){return this.drawShape(new Bi(t,e,s,i),n),this}roundRect(t,e,s,i,n,o){return this.drawShape(new Fi(t,e,s,i,n),o),this}drawShape(t,e){return this.endPoly(),this.shapePrimitives.push({shape:t,transform:e}),this}startPoly(t,e){let s=this._currentPoly;return s&&this.endPoly(),s=new Ae,s.points.push(t,e),this._currentPoly=s,this}endPoly(t=!1){const e=this._currentPoly;return e&&e.points.length>2&&(e.closePath=t,this.shapePrimitives.push({shape:e})),this._currentPoly=null,this}_ensurePoly(t=!0){if(!this._currentPoly&&(this._currentPoly=new Ae,t)){const e=this.shapePrimitives[this.shapePrimitives.length-1];if(e){let s=e.shape.x,i=e.shape.y;if(!e.transform.isIdentity()){const n=e.transform,o=s;s=n.a*s+n.c*i+n.tx,i=n.b*o+n.d*i+n.ty}this._currentPoly.points.push(s,i)}else this._currentPoly.points.push(0,0)}}buildPath(){const t=this._graphicsPath2D;this.shapePrimitives.length=0,this._currentPoly=null;for(let e=0;et in r?A0(r,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):r[t]=e,Gs=(r,t)=>{for(var e in t||(t={}))P0.call(t,e)&&Rc(r,e,t[e]);if(wc)for(var e of wc(t))w0.call(t,e)&&Rc(r,e,t[e]);return r};function Mc(r,t){if(typeof r=="string"){const s=document.createElement("div");s.innerHTML=r.trim(),r=s.querySelector("svg")}const e={context:t,path:new ne};return Oc(r,e,null,null),t}function Oc(r,t,e,s){const i=r.children,{fillStyle:n,strokeStyle:o}=R0(r);n&&e?e=Gs(Gs({},e),n):n&&(e=n),o&&s?s=Gs(Gs({},s),o):o&&(s=o),t.context.fillStyle=e,t.context.strokeStyle=s;let a,u,l,h,c,d,p,f,g,m,_,x,b,y,S,P,R;switch(r.nodeName.toLowerCase()){case"path":y=r.getAttribute("d"),S=new ne(y),t.context.path(S),e&&t.context.fill(),s&&t.context.stroke();break;case"circle":p=ot(r,"cx",0),f=ot(r,"cy",0),g=ot(r,"r",0),t.context.ellipse(p,f,g,g),e&&t.context.fill(),s&&t.context.stroke();break;case"rect":a=ot(r,"x",0),u=ot(r,"y",0),P=ot(r,"width",0),R=ot(r,"height",0),m=ot(r,"rx",0),_=ot(r,"ry",0),m||_?t.context.roundRect(a,u,P,R,m||_):t.context.rect(a,u,P,R),e&&t.context.fill(),s&&t.context.stroke();break;case"ellipse":p=ot(r,"cx",0),f=ot(r,"cy",0),m=ot(r,"rx",0),_=ot(r,"ry",0),t.context.beginPath(),t.context.ellipse(p,f,m,_),e&&t.context.fill(),s&&t.context.stroke();break;case"line":l=ot(r,"x1",0),h=ot(r,"y1",0),c=ot(r,"x2",0),d=ot(r,"y2",0),t.context.beginPath(),t.context.moveTo(l,h),t.context.lineTo(c,d),s&&t.context.stroke();break;case"polygon":b=r.getAttribute("points"),x=b.match(/\d+/g).map(w=>parseInt(w,10)),t.context.poly(x,!0),e&&t.context.fill(),s&&t.context.stroke();break;case"polyline":b=r.getAttribute("points"),x=b.match(/\d+/g).map(w=>parseInt(w,10)),t.context.poly(x,!1),s&&t.context.stroke();break;case"g":case"svg":break;default:{console.info(`[SVG parser] <${r.nodeName}> elements unsupported`);break}}for(let w=0;wt in r?M0(r,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):r[t]=e,ye=(r,t)=>{for(var e in t||(t={}))G0.call(t,e)&&Gc(r,e,t[e]);if(Cc)for(var e of Cc(t))I0.call(t,e)&&Gc(r,e,t[e]);return r},ho=(r,t)=>O0(r,C0(t));function Vt(r,t){var e,s;if(r==null)return null;let i,n;if(r!=null&&r.fill?(n=r.fill,i=ye(ye({},t),r)):(n=r,i=t),W.isColorLike(n)){const u=W.shared.setValue(n!=null?n:0);return ho(ye({},i),{color:u.toNumber(),alpha:u.alpha===1?i.alpha:u.alpha,texture:A.WHITE})}else if(n instanceof Jn){const u=n;return ho(ye({},i),{color:16777215,texture:u.texture,matrix:u.transform,fill:(e=i.fill)!=null?e:null})}else if(n instanceof Ms){const u=n;return u.buildLinearGradient(),ho(ye({},i),{color:16777215,texture:u.texture,matrix:u.transform})}const o=ye(ye({},t),r);if(o.texture){if(o.texture!==A.WHITE){const l=((s=o.matrix)==null?void 0:s.invert())||new G;l.scale(1/o.texture.frame.width,1/o.texture.frame.height),o.matrix=l}const u=o.texture.source.style;u.addressMode==="clamp-to-edge"&&(u.addressMode="repeat")}const a=W.shared.setValue(o.color);return o.alpha*=a.alpha,o.color=a.toNumber(),o.matrix=o.matrix?o.matrix.clone():null,o}var B0=Object.defineProperty,Ic=Object.getOwnPropertySymbols,F0=Object.prototype.hasOwnProperty,D0=Object.prototype.propertyIsEnumerable,Bc=(r,t,e)=>t in r?B0(r,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):r[t]=e,Be=(r,t)=>{for(var e in t||(t={}))F0.call(t,e)&&Bc(r,e,t[e]);if(Ic)for(var e of Ic(t))D0.call(t,e)&&Bc(r,e,t[e]);return r};const U0=new j,Fc=new G,co=class $t extends ct{constructor(){super(...arguments),this.uid=Z("graphicsContext"),this.dirty=!0,this.batchMode="auto",this.instructions=[],this._activePath=new ne,this._transform=new G,this._fillStyle=Be({},$t.defaultFillStyle),this._strokeStyle=Be({},$t.defaultStrokeStyle),this._stateStack=[],this._tick=0,this._bounds=new lt,this._boundsDirty=!0}clone(){const t=new $t;return t.batchMode=this.batchMode,t.instructions=this.instructions.slice(),t._activePath=this._activePath.clone(),t._transform=this._transform.clone(),t._fillStyle=Be({},this._fillStyle),t._strokeStyle=Be({},this._strokeStyle),t._stateStack=this._stateStack.slice(),t._bounds=this._bounds.clone(),t._boundsDirty=!0,t}get fillStyle(){return this._fillStyle}set fillStyle(t){this._fillStyle=Vt(t,$t.defaultFillStyle)}get strokeStyle(){return this._strokeStyle}set strokeStyle(t){this._strokeStyle=Vt(t,$t.defaultStrokeStyle)}setFillStyle(t){return this._fillStyle=Vt(t,$t.defaultFillStyle),this}setStrokeStyle(t){return this._strokeStyle=Vt(t,$t.defaultStrokeStyle),this}texture(t,e,s,i,n,o){return this.instructions.push({action:"texture",data:{image:t,dx:s||0,dy:i||0,dw:n||t.frame.width,dh:o||t.frame.height,transform:this._transform.clone(),alpha:this._fillStyle.alpha,style:e?W.shared.setValue(e).toNumber():16777215}}),this.onUpdate(),this}beginPath(){return this._activePath=new ne,this}fill(t,e){let s;const i=this.instructions[this.instructions.length-1];return this._tick===0&&i&&i.action==="stroke"?s=i.data.path:s=this._activePath.clone(),s?(t!=null&&(e!==void 0&&typeof t=="number"&&(t={color:t,alpha:e}),this._fillStyle=Vt(t,$t.defaultFillStyle)),this.instructions.push({action:"fill",data:{style:this.fillStyle,path:s}}),this.onUpdate(),this._initNextPathLocation(),this._tick=0,this):this}_initNextPathLocation(){const{x:t,y:e}=this._activePath.getLastPoint(j.shared);this._activePath.clear(),this._activePath.moveTo(t,e)}stroke(t){let e;const s=this.instructions[this.instructions.length-1];return this._tick===0&&s&&s.action==="fill"?e=s.data.path:e=this._activePath.clone(),e?(t!=null&&(this._strokeStyle=Vt(t,$t.defaultStrokeStyle)),this.instructions.push({action:"stroke",data:{style:this.strokeStyle,path:e}}),this.onUpdate(),this._initNextPathLocation(),this._tick=0,this):this}cut(){for(let t=0;t<2;t++){const e=this.instructions[this.instructions.length-1-t],s=this._activePath.clone();if(e&&(e.action==="stroke"||e.action==="fill"))if(e.data.hole)e.data.hole.addPath(s);else{e.data.hole=s;break}}return this._initNextPathLocation(),this}arc(t,e,s,i,n,o){this._tick++;const a=this._transform;return this._activePath.arc(a.a*t+a.c*e+a.tx,a.b*t+a.d*e+a.ty,s,i,n,o),this}arcTo(t,e,s,i,n){this._tick++;const o=this._transform;return this._activePath.arcTo(o.a*t+o.c*e+o.tx,o.b*t+o.d*e+o.ty,o.a*s+o.c*i+o.tx,o.b*s+o.d*i+o.ty,n),this}arcToSvg(t,e,s,i,n,o,a){this._tick++;const u=this._transform;return this._activePath.arcToSvg(t,e,s,i,n,u.a*o+u.c*a+u.tx,u.b*o+u.d*a+u.ty),this}bezierCurveTo(t,e,s,i,n,o,a){this._tick++;const u=this._transform;return this._activePath.bezierCurveTo(u.a*t+u.c*e+u.tx,u.b*t+u.d*e+u.ty,u.a*s+u.c*i+u.tx,u.b*s+u.d*i+u.ty,u.a*n+u.c*o+u.tx,u.b*n+u.d*o+u.ty,a),this}closePath(){var t;return this._tick++,(t=this._activePath)==null||t.closePath(),this}ellipse(t,e,s,i){return this._tick++,this._activePath.ellipse(t,e,s,i,this._transform.clone()),this}circle(t,e,s){return this._tick++,this._activePath.circle(t,e,s,this._transform.clone()),this}path(t){return this._tick++,this._activePath.addPath(t,this._transform.clone()),this}lineTo(t,e){this._tick++;const s=this._transform;return this._activePath.lineTo(s.a*t+s.c*e+s.tx,s.b*t+s.d*e+s.ty),this}moveTo(t,e){this._tick++;const s=this._transform,i=this._activePath.instructions,n=s.a*t+s.c*e+s.tx,o=s.b*t+s.d*e+s.ty;return i.length===1&&i[0].action==="moveTo"?(i[0].data[0]=n,i[0].data[1]=o,this):(this._activePath.moveTo(n,o),this)}quadraticCurveTo(t,e,s,i,n){this._tick++;const o=this._transform;return this._activePath.quadraticCurveTo(o.a*t+o.c*e+o.tx,o.b*t+o.d*e+o.ty,o.a*s+o.c*i+o.tx,o.b*s+o.d*i+o.ty,n),this}rect(t,e,s,i){return this._tick++,this._activePath.rect(t,e,s,i,this._transform.clone()),this}roundRect(t,e,s,i,n){return this._tick++,this._activePath.roundRect(t,e,s,i,n,this._transform.clone()),this}poly(t,e){return this._tick++,this._activePath.poly(t,e,this._transform.clone()),this}regularPoly(t,e,s,i,n=0,o){return this._tick++,this._activePath.regularPoly(t,e,s,i,n,o),this}roundPoly(t,e,s,i,n,o){return this._tick++,this._activePath.roundPoly(t,e,s,i,n,o),this}roundShape(t,e,s,i){return this._tick++,this._activePath.roundShape(t,e,s,i),this}filletRect(t,e,s,i,n){return this._tick++,this._activePath.filletRect(t,e,s,i,n),this}chamferRect(t,e,s,i,n,o){return this._tick++,this._activePath.chamferRect(t,e,s,i,n,o),this}star(t,e,s,i,n=0,o=0){return this._tick++,this._activePath.star(t,e,s,i,n,o,this._transform.clone()),this}svg(t){return this._tick++,Mc(t,this),this}restore(){const t=this._stateStack.pop();return t&&(this._transform=t.transform,this._fillStyle=t.fillStyle,this._strokeStyle=t.strokeStyle),this}save(){return this._stateStack.push({transform:this._transform.clone(),fillStyle:Be({},this._fillStyle),strokeStyle:Be({},this._strokeStyle)}),this}getTransform(){return this._transform}resetTransform(){return this._transform.identity(),this}rotate(t){return this._transform.rotate(t),this}scale(t,e=t){return this._transform.scale(t,e),this}setTransform(t,e,s,i,n,o){return t instanceof G?(this._transform.set(t.a,t.b,t.c,t.d,t.tx,t.ty),this):(this._transform.set(t,e,s,i,n,o),this)}transform(t,e,s,i,n,o){return t instanceof G?(this._transform.append(t),this):(Fc.set(t,e,s,i,n,o),this._transform.append(Fc),this)}translate(t,e=t){return this._transform.translate(t,e),this}clear(){return this.instructions.length=0,this.resetTransform(),this.onUpdate(),this}onUpdate(){this.dirty||(this.emit("update",this,16),this.dirty=!0,this._boundsDirty=!0)}get bounds(){if(!this._boundsDirty)return this._bounds;const t=this._bounds;t.clear();for(let e=0;et in r?L0(r,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):r[t]=e,Ar=(r,t)=>{for(var e in t||(t={}))$0.call(t,e)&&Lc(r,e,t[e]);if(kc)for(var e of kc(t))N0.call(t,e)&&Lc(r,e,t[e]);return r};const fo=class Ye extends ct{constructor(t={}){super(),H0(t);const e=Ar(Ar({},Ye.defaultTextStyle),t);for(const s in e){const i=s;this[i]=e[s]}this.update()}get align(){return this._align}set align(t){this._align=t,this.update()}get breakWords(){return this._breakWords}set breakWords(t){this._breakWords=t,this.update()}get dropShadow(){return this._dropShadow}set dropShadow(t){t!==null&&typeof t=="object"?this._dropShadow=Ar(Ar({},Ye.defaultDropShadow),t):this._dropShadow=t?Ar({},Ye.defaultDropShadow):null,this.update()}get fontFamily(){return this._fontFamily}set fontFamily(t){this._fontFamily=t,this.update()}get fontSize(){return this._fontSize}set fontSize(t){typeof t=="string"?this._fontSize=parseInt(t,10):this._fontSize=t,this.update()}get fontStyle(){return this._fontStyle}set fontStyle(t){this._fontStyle=t,this.update()}get fontVariant(){return this._fontVariant}set fontVariant(t){this._fontVariant=t,this.update()}get fontWeight(){return this._fontWeight}set fontWeight(t){this._fontWeight=t,this.update()}get leading(){return this._leading}set leading(t){this._leading=t,this.update()}get letterSpacing(){return this._letterSpacing}set letterSpacing(t){this._letterSpacing=t,this.update()}get lineHeight(){return this._lineHeight}set lineHeight(t){this._lineHeight=t,this.update()}get padding(){return this._padding}set padding(t){this._padding=t,this.update()}get trim(){return this._trim}set trim(t){this._trim=t,this.update()}get textBaseline(){return this._textBaseline}set textBaseline(t){this._textBaseline=t,this.update()}get whiteSpace(){return this._whiteSpace}set whiteSpace(t){this._whiteSpace=t,this.update()}get wordWrap(){return this._wordWrap}set wordWrap(t){this._wordWrap=t,this.update()}get wordWrapWidth(){return this._wordWrapWidth}set wordWrapWidth(t){this._wordWrapWidth=t,this.update()}get fill(){return this._originalFill}set fill(t){t!==this._originalFill&&(this._originalFill=t,this._fill=Vt(t===0?"black":t,Bt.defaultFillStyle),this.update())}get stroke(){return this._originalStroke}set stroke(t){t!==this._originalStroke&&(this._originalStroke=t,this._stroke=Vt(t,Bt.defaultStrokeStyle),this.update())}_generateKey(){return this._styleKey=po(this),this._styleKey}update(){this._styleKey=null,this.emit("update",this)}reset(){const t=Ye.defaultTextStyle;for(const e in t)this[e]=t[e]}get styleKey(){return this._styleKey||this._generateKey()}clone(){return new Ye({align:this.align,breakWords:this.breakWords,dropShadow:this.dropShadow,fill:this._fill,fontFamily:this.fontFamily,fontSize:this.fontSize,fontStyle:this.fontStyle,fontVariant:this.fontVariant,fontWeight:this.fontWeight,leading:this.leading,letterSpacing:this.letterSpacing,lineHeight:this.lineHeight,padding:this.padding,stroke:this._stroke,textBaseline:this.textBaseline,whiteSpace:this.whiteSpace,wordWrap:this.wordWrap,wordWrapWidth:this.wordWrapWidth})}destroy(t=!1){var e,s,i,n;if(this.removeAllListeners(),typeof t=="boolean"?t:t==null?void 0:t.texture){const o=typeof t=="boolean"?t:t==null?void 0:t.textureSource;(e=this._fill)!=null&&e.texture&&this._fill.texture.destroy(o),(s=this._originalFill)!=null&&s.texture&&this._originalFill.texture.destroy(o),(i=this._stroke)!=null&&i.texture&&this._stroke.texture.destroy(o),(n=this._originalStroke)!=null&&n.texture&&this._originalStroke.texture.destroy(o)}this._fill=null,this._stroke=null,this.dropShadow=null,this._originalStroke=null,this._originalFill=null}};fo.defaultDropShadow={alpha:1,angle:Math.PI/6,blur:0,color:"black",distance:5},fo.defaultTextStyle={align:"left",breakWords:!1,dropShadow:null,fill:"black",fontFamily:"Arial",fontSize:26,fontStyle:"normal",fontVariant:"normal",fontWeight:"normal",leading:0,letterSpacing:0,lineHeight:0,padding:0,stroke:null,textBaseline:"alphabetic",trim:!1,whiteSpace:"pre",wordWrap:!1,wordWrapWidth:100};let Wt=fo;function H0(r){var t,e,s,i,n;const o=r;if(typeof o.dropShadow=="boolean"&&o.dropShadow){const a=Wt.defaultDropShadow;r.dropShadow={alpha:(t=o.dropShadowAlpha)!=null?t:a.alpha,angle:(e=o.dropShadowAngle)!=null?e:a.angle,blur:(s=o.dropShadowBlur)!=null?s:a.blur,color:(i=o.dropShadowColor)!=null?i:a.color,distance:(n=o.dropShadowDistance)!=null?n:a.distance}}if(o.strokeThickness){const a=o.stroke;r.stroke={color:a,width:o.strokeThickness}}if(Array.isArray(o.fill)){const a=new Ms(0,0,0,r.fontSize*1.7),u=o.fill.map(l=>W.shared.setValue(l).toNumber());u.forEach((l,h)=>{var c;const d=(c=o.fillGradientStops[h])!=null?c:h/u.length;a.addColorStop(d,l)}),r.fill={fill:a}}}function mo(r){if(r==="")return[];typeof r=="string"&&(r=[r]);const t=[];for(let e=0,s=r.length;e!this._currentChars.includes(b)).filter((b,y,S)=>S.indexOf(b)===y);if(!o.length)return;this._currentChars=[...this._currentChars,...o];let a;this._currentPageIndex===-1?a=this._nextPage():a=this.pages[this._currentPageIndex];let{canvas:u,context:l}=a.canvasAndContext,h=a.texture.source;const c=this._style;let d=this._currentX,p=this._currentY;const f=this.baseRenderedFontSize/this.baseMeasurementFontSize,g=this._padding*f,m=c.fontStyle==="italic"?2:1;let _=0,x=!1;for(let b=0;b512&&(p+=_,_=T,d=0,p+_>512)){h.update();const L=this._nextPage();u=L.canvasAndContext.canvas,l=L.canvasAndContext.context,h=L.texture.source,p=0}const E=P/f-((s=(e=c.dropShadow)==null?void 0:e.distance)!=null?s:0)-((n=(i=c._stroke)==null?void 0:i.width)!=null?n:0);if(this.chars[y]={id:y.codePointAt(0),xOffset:-this._padding,yOffset:-this._padding,xAdvance:E,kerning:{}},x){this._drawGlyph(l,S,d+g,p+g,f,c);const L=h.width*f,k=h.height*f,C=new z(d/L*h.width,p/k*h.height,w/L*h.width,T/k*h.height);this.chars[y].texture=new A({source:h,frame:C}),d+=Math.ceil(w)}}h.update(),this._currentX=d,this._currentY=p,this._skipKerning&&this._applyKerning(o,l)}get pageTextures(){return this.pages}_applyKerning(t,e){const s=this._measureCache;for(let i=0;i{const f=i.width;for(let g=0;g{let p=i.chars.length-1,f=i.chars[p];for(;f===" ";)i.width-=e.chars[f].xAdvance,f=i.chars[--p];s.width=Math.max(s.width,i.width),i={width:0,charPositions:[],chars:[],spaceWidth:0,spacesIndex:[]},o=!0,s.lines.push(i),s.height+=e.lineHeight},h=e.baseMeasurementFontSize/t.fontSize,c=t.letterSpacing*h,d=t.wordWrapWidth*h;for(let p=0;pd?(l(),u(a),g||i.charPositions.push(0)):(a.start=i.width,u(a),g||i.charPositions.push(0)),f==="\r"||f===` -`)i.width!==0&&l();else if(!g){const _=m.xAdvance+(m.kerning[n]||0)+c;i.width+=_,i.spaceWidth=_,i.spacesIndex.push(i.charPositions.length),i.chars.push(f)}}else{const _=m.kerning[n]||0,x=m.xAdvance+_+c;a.positions[a.index++]=a.width+_,a.chars.push(f),a.width+=x}n=f}return l(),t.align==="center"?X0(s):t.align==="right"?z0(s):t.align==="justify"&&j0(s),s}function X0(r){for(let t=0;tt in r?V0(r,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):r[t]=e,xo=(r,t)=>{for(var e in t||(t={}))W0.call(t,e)&&Nc(r,e,t[e]);if($c)for(var e of $c(t))Y0.call(t,e)&&Nc(r,e,t[e]);return r};let K0=class{constructor(){this.ALPHA=[["a","z"],["A","Z"]," "],this.NUMERIC=[["0","9"]],this.ALPHANUMERIC=[["a","z"],["A","Z"],["0","9"]," "],this.ASCII=[[" ","~"]],this.defaultOptions={chars:this.ALPHANUMERIC,resolution:1,padding:4,skipKerning:!1}}getFont(t,e){var s;let i=`${e.fontFamily}-bitmap`,n=!0;if(e._fill.fill&&(i+=e._fill.fill.uid,n=!1),!Y.has(i)){const a=new go(xo({style:e,overrideFill:n,overrideSize:!0},this.defaultOptions));a.once("destroy",()=>Y.remove(i)),Y.set(i,a)}const o=Y.get(i);return(s=o.ensureCharacters)==null||s.call(o,t),o}getLayout(t,e){const s=this.getFont(t,e);return _o(t.split(""),e,s)}measureText(t,e){return this.getLayout(t,e)}install(...t){var e,s,i,n;let o=t[0];typeof o=="string"&&(o={name:o,style:t[1],chars:(e=t[2])==null?void 0:e.chars,resolution:(s=t[2])==null?void 0:s.resolution,padding:(i=t[2])==null?void 0:i.padding,skipKerning:(n=t[2])==null?void 0:n.skipKerning});const a=o==null?void 0:o.name;if(!a)throw new Error("[BitmapFontManager] Property `name` is required.");o=xo(xo({},this.defaultOptions),o);const u=o.style,l=u instanceof Wt?u:new Wt(u),h=l._fill.fill!==null&&l._fill.fill!==void 0,c=new go({style:l,overrideFill:h,skipKerning:o.skipKerning,padding:o.padding,resolution:o.resolution,overrideSize:!1}),d=mo(o.chars);return c.ensureCharacters(d.join("")),Y.set(`${a}-bitmap`,c),c.once("destroy",()=>Y.remove(`${a}-bitmap`)),c}uninstall(t){const e=`${t}-bitmap`,s=Y.get(e);s&&(Y.remove(e),s.destroy())}};const Pr=new K0;class bo extends eo{constructor(t,e){var s;super();const{textures:i,data:n}=t;Object.keys(n.pages).forEach(o=>{const a=n.pages[parseInt(o,10)],u=i[a.id];this.pages.push({texture:u})}),Object.keys(n.chars).forEach(o=>{var a;const u=n.chars[o],l=i[u.page].source,h=new z(u.x,u.y,u.width,u.height),c=new A({source:l,frame:h});this.chars[o]={id:o.codePointAt(0),xOffset:u.xOffset,yOffset:u.yOffset,xAdvance:u.xAdvance,kerning:(a=u.kerning)!=null?a:{},texture:c}}),this.baseRenderedFontSize=n.fontSize,this.baseMeasurementFontSize=n.fontSize,this.fontMetrics={ascent:0,descent:0,fontSize:n.fontSize},this.baseLineOffset=n.baseLineOffset,this.lineHeight=n.lineHeight,this.fontFamily=n.fontFamily,this.distanceField=(s=n.distanceField)!=null?s:{type:"none",range:0},this.url=e}destroy(){super.destroy();for(let t=0;t")?vo.test(X.get().parseXML(r)):!1},parse(r){return vo.parse(X.get().parseXML(r))}},q0=[".xml",".fnt"],Hc={extension:v.CacheParser,test:r=>r instanceof bo,getCacheableAssets(r,t){const e={};return r.forEach(s=>{e[s]=t}),e[`${t.fontFamily}-bitmap`]=t,e}},Xc={extension:{type:v.LoadParser,priority:gt.Normal},test(r){return q0.includes(dt.extname(r).toLowerCase())},async testParse(r){return Is.test(r)||yo.test(r)},async parse(r,t,e){const s=Is.test(r)?Is.parse(r):yo.parse(r),{src:i}=t,{pages:n}=s,o=[];for(let l=0;la[l]);return new bo({data:s,textures:u},i)},async load(r,t){return await(await X.get().fetch(r)).text()},async unload(r,t,e){await Promise.all(r.pages.map(s=>e.unload(s.texture.source._sourceOrigin))),r.destroy()}};var Z0=Object.defineProperty,Bs=Object.getOwnPropertySymbols,zc=Object.prototype.hasOwnProperty,jc=Object.prototype.propertyIsEnumerable,Vc=(r,t,e)=>t in r?Z0(r,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):r[t]=e,Q0=(r,t)=>{for(var e in t||(t={}))zc.call(t,e)&&Vc(r,e,t[e]);if(Bs)for(var e of Bs(t))jc.call(t,e)&&Vc(r,e,t[e]);return r},J0=(r,t)=>{var e={};for(var s in r)zc.call(r,s)&&t.indexOf(s)<0&&(e[s]=r[s]);if(r!=null&&Bs)for(var s of Bs(r))t.indexOf(s)<0&&jc.call(r,s)&&(e[s]=r[s]);return e};class qe extends V{constructor(t){t instanceof Bt&&(t={context:t});const e=t||{},{context:s,roundPixels:i}=e,n=J0(e,["context","roundPixels"]);super(Q0({label:"Graphics"},n)),this.canBundle=!0,this.renderPipeId="graphics",this._roundPixels=0,s?this._context=s:this._context=this._ownedContext=new Bt,this._context.on("update",this.onViewUpdate,this),this.allowChildren=!1,this.roundPixels=i!=null?i:!1}set context(t){t!==this._context&&(this._context.off("update",this.onViewUpdate,this),this._context=t,this._context.on("update",this.onViewUpdate,this),this.onViewUpdate())}get context(){return this._context}get bounds(){return this._context.bounds}addBounds(t){t.addBounds(this._context.bounds)}containsPoint(t){return this._context.containsPoint(t)}get roundPixels(){return!!this._roundPixels}set roundPixels(t){this._roundPixels=t?1:0}onViewUpdate(){this._didChangeId+=4096,this._didGraphicsUpdate=!0,!this.didViewUpdate&&(this.didViewUpdate=!0,this.renderGroup&&this.renderGroup.onChildViewUpdate(this))}destroy(t){this._ownedContext&&!t?this._ownedContext.destroy(t):(t===!0||(t==null?void 0:t.context)===!0)&&this._context.destroy(t),this._ownedContext=null,this._context=null,super.destroy(t)}_callContextMethod(t,e){return this.context[t](...e),this}setFillStyle(...t){return this._callContextMethod("setFillStyle",t)}setStrokeStyle(...t){return this._callContextMethod("setStrokeStyle",t)}fill(...t){return this._callContextMethod("fill",t)}stroke(...t){return this._callContextMethod("stroke",t)}texture(...t){return this._callContextMethod("texture",t)}beginPath(){return this._callContextMethod("beginPath",[])}cut(){return this._callContextMethod("cut",[])}arc(...t){return this._callContextMethod("arc",t)}arcTo(...t){return this._callContextMethod("arcTo",t)}arcToSvg(...t){return this._callContextMethod("arcToSvg",t)}bezierCurveTo(...t){return this._callContextMethod("bezierCurveTo",t)}closePath(){return this._callContextMethod("closePath",[])}ellipse(...t){return this._callContextMethod("ellipse",t)}circle(...t){return this._callContextMethod("circle",t)}path(...t){return this._callContextMethod("path",t)}lineTo(...t){return this._callContextMethod("lineTo",t)}moveTo(...t){return this._callContextMethod("moveTo",t)}quadraticCurveTo(...t){return this._callContextMethod("quadraticCurveTo",t)}rect(...t){return this._callContextMethod("rect",t)}roundRect(...t){return this._callContextMethod("roundRect",t)}poly(...t){return this._callContextMethod("poly",t)}regularPoly(...t){return this._callContextMethod("regularPoly",t)}roundPoly(...t){return this._callContextMethod("roundPoly",t)}roundShape(...t){return this._callContextMethod("roundShape",t)}filletRect(...t){return this._callContextMethod("filletRect",t)}chamferRect(...t){return this._callContextMethod("chamferRect",t)}star(...t){return this._callContextMethod("star",t)}svg(...t){return this._callContextMethod("svg",t)}restore(...t){return this._callContextMethod("restore",t)}save(){return this._callContextMethod("save",[])}getTransform(){return this.context.getTransform()}resetTransform(){return this._callContextMethod("resetTransform",[])}rotateTransform(...t){return this._callContextMethod("rotate",t)}scaleTransform(...t){return this._callContextMethod("scale",t)}setTransform(...t){return this._callContextMethod("setTransform",t)}transform(...t){return this._callContextMethod("transform",t)}translateTransform(...t){return this._callContextMethod("translate",t)}clear(){return this._callContextMethod("clear",[])}get fillStyle(){return this._context.fillStyle}set fillStyle(t){this._context.fillStyle=t}get strokeStyle(){return this._context.strokeStyle}set strokeStyle(t){this._context.strokeStyle=t}clone(t=!1){return t?new qe(this._context.clone()):(this._ownedContext=null,new qe(this._context))}lineStyle(t,e,s){const i={};return t&&(i.width=t),e&&(i.color=e),s&&(i.alpha=s),this.context.strokeStyle=i,this}beginFill(t,e){const s={};return t&&(s.color=t),e&&(s.alpha=e),this.context.fillStyle=s,this}endFill(){this.context.fill();const t=this.context.strokeStyle;return(t.width!==Bt.defaultStrokeStyle.width||t.color!==Bt.defaultStrokeStyle.color||t.alpha!==Bt.defaultStrokeStyle.alpha)&&this.context.stroke(),this}drawCircle(...t){return this._callContextMethod("circle",t)}drawEllipse(...t){return this._callContextMethod("ellipse",t)}drawPolygon(...t){return this._callContextMethod("poly",t)}drawRect(...t){return this._callContextMethod("rect",t)}drawRoundedRect(...t){return this._callContextMethod("roundRect",t)}drawStar(...t){return this._callContextMethod("star",t)}}let wr;function Wc(){return(!wr||wr!=null&&wr.isContextLost())&&(wr=X.get().createCanvas().getContext("webgl",{})),wr}let Fs;function Yc(){if(!Fs){Fs="mediump";const r=Wc();r&&r.getShaderPrecisionFormat&&(Fs=r.getShaderPrecisionFormat(r.FRAGMENT_SHADER,r.HIGH_FLOAT).precision?"highp":"mediump")}return Fs}function Kc(r,t,e){return t?r:e?(r=r.replace("out vec4 finalColor;",""),` + */ +"use strict"; +var __defProp$10 = Object.defineProperty; +var __defProps$n = Object.defineProperties; +var __getOwnPropDescs$n = Object.getOwnPropertyDescriptors; +var __getOwnPropSymbols$10 = Object.getOwnPropertySymbols; +var __hasOwnProp$10 = Object.prototype.hasOwnProperty; +var __propIsEnum$10 = Object.prototype.propertyIsEnumerable; +var __defNormalProp$10 = (obj, key, value) => key in obj ? __defProp$10(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; +var __spreadValues$10 = (a, b) => { + for (var prop in b || (b = {})) + if (__hasOwnProp$10.call(b, prop)) + __defNormalProp$10(a, prop, b[prop]); + if (__getOwnPropSymbols$10) + for (var prop of __getOwnPropSymbols$10(b)) { + if (__propIsEnum$10.call(b, prop)) + __defNormalProp$10(a, prop, b[prop]); + } + return a; +}; +var __spreadProps$n = (a, b) => __defProps$n(a, __getOwnPropDescs$n(b)); +var ExtensionType = /* @__PURE__ */ ((ExtensionType2) => { + ExtensionType2["Application"] = "application"; + ExtensionType2["WebGLPipes"] = "webgl-pipes"; + ExtensionType2["WebGLPipesAdaptor"] = "webgl-pipes-adaptor"; + ExtensionType2["WebGLSystem"] = "webgl-system"; + ExtensionType2["WebGPUPipes"] = "webgpu-pipes"; + ExtensionType2["WebGPUPipesAdaptor"] = "webgpu-pipes-adaptor"; + ExtensionType2["WebGPUSystem"] = "webgpu-system"; + ExtensionType2["CanvasSystem"] = "canvas-system"; + ExtensionType2["CanvasPipesAdaptor"] = "canvas-pipes-adaptor"; + ExtensionType2["CanvasPipes"] = "canvas-pipes"; + ExtensionType2["Asset"] = "asset"; + ExtensionType2["LoadParser"] = "load-parser"; + ExtensionType2["ResolveParser"] = "resolve-parser"; + ExtensionType2["CacheParser"] = "cache-parser"; + ExtensionType2["DetectionParser"] = "detection-parser"; + ExtensionType2["MaskEffect"] = "mask-effect"; + ExtensionType2["BlendMode"] = "blend-mode"; + ExtensionType2["TextureSource"] = "texture-source"; + ExtensionType2["Environment"] = "environment"; + return ExtensionType2; +})(ExtensionType || {}); +const normalizeExtension = (ext) => { + if (typeof ext === "function" || typeof ext === "object" && ext.extension) { + if (!ext.extension) { + throw new Error("Extension class must have an extension object"); + } + const metadata = typeof ext.extension !== "object" ? { type: ext.extension } : ext.extension; + ext = __spreadProps$n(__spreadValues$10({}, metadata), { ref: ext }); + } + if (typeof ext === "object") { + ext = __spreadValues$10({}, ext); + } else { + throw new Error("Invalid extension type"); + } + if (typeof ext.type === "string") { + ext.type = [ext.type]; + } + return ext; +}; +const normalizeExtensionPriority = (ext, defaultPriority) => { + var _a; + return (_a = normalizeExtension(ext).priority) != null ? _a : defaultPriority; +}; +const extensions = { + /** @ignore */ + _addHandlers: {}, + /** @ignore */ + _removeHandlers: {}, + /** @ignore */ + _queue: {}, + /** + * Remove extensions from PixiJS. + * @param extensions - Extensions to be removed. + * @returns {extensions} For chaining. + */ + remove(...extensions2) { + extensions2.map(normalizeExtension).forEach((ext) => { + ext.type.forEach((type) => { + var _a, _b; + return (_b = (_a = this._removeHandlers)[type]) == null ? void 0 : _b.call(_a, ext); + }); + }); + return this; + }, + /** + * Register new extensions with PixiJS. + * @param extensions - The spread of extensions to add to PixiJS. + * @returns {extensions} For chaining. + */ + add(...extensions2) { + extensions2.map(normalizeExtension).forEach((ext) => { + ext.type.forEach((type) => { + var _a, _b; + const handlers = this._addHandlers; + const queue = this._queue; + if (!handlers[type]) { + queue[type] = queue[type] || []; + (_a = queue[type]) == null ? void 0 : _a.push(ext); + } else { + (_b = handlers[type]) == null ? void 0 : _b.call(handlers, ext); + } + }); + }); + return this; + }, + /** + * Internal method to handle extensions by name. + * @param type - The extension type. + * @param onAdd - Function handler when extensions are added/registered {@link StrictExtensionFormat}. + * @param onRemove - Function handler when extensions are removed/unregistered {@link StrictExtensionFormat}. + * @returns {extensions} For chaining. + */ + handle(type, onAdd, onRemove) { + var _a; + const addHandlers = this._addHandlers; + const removeHandlers = this._removeHandlers; + if (addHandlers[type] || removeHandlers[type]) { + throw new Error(`Extension type ${type} already has a handler`); + } + addHandlers[type] = onAdd; + removeHandlers[type] = onRemove; + const queue = this._queue; + if (queue[type]) { + (_a = queue[type]) == null ? void 0 : _a.forEach((ext) => onAdd(ext)); + delete queue[type]; + } + return this; + }, + /** + * Handle a type, but using a map by `name` property. + * @param type - Type of extension to handle. + * @param map - The object map of named extensions. + * @returns {extensions} For chaining. + */ + handleByMap(type, map) { + return this.handle( + type, + (extension) => { + if (extension.name) { + map[extension.name] = extension.ref; + } + }, + (extension) => { + if (extension.name) { + delete map[extension.name]; + } + } + ); + }, + /** + * Handle a type, but using a list of extensions with a `name` property. + * @param type - Type of extension to handle. + * @param map - The array of named extensions. + * @param defaultPriority - Fallback priority if none is defined. + * @returns {extensions} For chaining. + */ + handleByNamedList(type, map, defaultPriority = -1) { + return this.handle( + type, + (extension) => { + const index = map.findIndex((item) => item.name === extension.name); + if (index >= 0) + return; + map.push({ name: extension.name, value: extension.ref }); + map.sort((a, b) => normalizeExtensionPriority(b.value, defaultPriority) - normalizeExtensionPriority(a.value, defaultPriority)); + }, + (extension) => { + const index = map.findIndex((item) => item.name === extension.name); + if (index !== -1) { + map.splice(index, 1); + } + } + ); + }, + /** + * Handle a type, but using a list of extensions. + * @param type - Type of extension to handle. + * @param list - The list of extensions. + * @param defaultPriority - The default priority to use if none is specified. + * @returns {extensions} For chaining. + */ + handleByList(type, list, defaultPriority = -1) { + return this.handle( + type, + (extension) => { + if (list.includes(extension.ref)) { + return; + } + list.push(extension.ref); + list.sort((a, b) => normalizeExtensionPriority(b, defaultPriority) - normalizeExtensionPriority(a, defaultPriority)); + }, + (extension) => { + const index = list.indexOf(extension.ref); + if (index !== -1) { + list.splice(index, 1); + } + } + ); + } +}; + +var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {}; + +function getDefaultExportFromCjs (x) { + return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x; +} + +function getDefaultExportFromNamespaceIfPresent (n) { + return n && Object.prototype.hasOwnProperty.call(n, 'default') ? n['default'] : n; +} + +function getDefaultExportFromNamespaceIfNotNamed (n) { + return n && Object.prototype.hasOwnProperty.call(n, 'default') && Object.keys(n).length === 1 ? n['default'] : n; +} + +function getAugmentedNamespace(n) { + if (n.__esModule) return n; + var f = n.default; + if (typeof f == "function") { + var a = function a () { + if (this instanceof a) { + return Reflect.construct(f, arguments, this.constructor); + } + return f.apply(this, arguments); + }; + a.prototype = f.prototype; + } else a = {}; + Object.defineProperty(a, '__esModule', {value: true}); + Object.keys(n).forEach(function (k) { + var d = Object.getOwnPropertyDescriptor(n, k); + Object.defineProperty(a, k, d.get ? d : { + enumerable: true, + get: function () { + return n[k]; + } + }); + }); + return a; +} + +var eventemitter3$1 = {exports: {}}; + +var eventemitter3 = eventemitter3$1.exports; + +(function (module) { + 'use strict'; + + var has = Object.prototype.hasOwnProperty + , prefix = '~'; + + /** + * Constructor to create a storage for our `EE` objects. + * An `Events` instance is a plain object whose properties are event names. + * + * @constructor + * @private + */ + function Events() {} + + // + // We try to not inherit from `Object.prototype`. In some engines creating an + // instance in this way is faster than calling `Object.create(null)` directly. + // If `Object.create(null)` is not supported we prefix the event names with a + // character to make sure that the built-in object properties are not + // overridden or used as an attack vector. + // + if (Object.create) { + Events.prototype = Object.create(null); + + // + // This hack is needed because the `__proto__` property is still inherited in + // some old browsers like Android 4, iPhone 5.1, Opera 11 and Safari 5. + // + if (!new Events().__proto__) prefix = false; + } + + /** + * Representation of a single event listener. + * + * @param {Function} fn The listener function. + * @param {*} context The context to invoke the listener with. + * @param {Boolean} [once=false] Specify if the listener is a one-time listener. + * @constructor + * @private + */ + function EE(fn, context, once) { + this.fn = fn; + this.context = context; + this.once = once || false; + } + + /** + * Add a listener for a given event. + * + * @param {EventEmitter} emitter Reference to the `EventEmitter` instance. + * @param {(String|Symbol)} event The event name. + * @param {Function} fn The listener function. + * @param {*} context The context to invoke the listener with. + * @param {Boolean} once Specify if the listener is a one-time listener. + * @returns {EventEmitter} + * @private + */ + function addListener(emitter, event, fn, context, once) { + if (typeof fn !== 'function') { + throw new TypeError('The listener must be a function'); + } + + var listener = new EE(fn, context || emitter, once) + , evt = prefix ? prefix + event : event; + + if (!emitter._events[evt]) emitter._events[evt] = listener, emitter._eventsCount++; + else if (!emitter._events[evt].fn) emitter._events[evt].push(listener); + else emitter._events[evt] = [emitter._events[evt], listener]; + + return emitter; + } + + /** + * Clear event by name. + * + * @param {EventEmitter} emitter Reference to the `EventEmitter` instance. + * @param {(String|Symbol)} evt The Event name. + * @private + */ + function clearEvent(emitter, evt) { + if (--emitter._eventsCount === 0) emitter._events = new Events(); + else delete emitter._events[evt]; + } + + /** + * Minimal `EventEmitter` interface that is molded against the Node.js + * `EventEmitter` interface. + * + * @constructor + * @public + */ + function EventEmitter() { + this._events = new Events(); + this._eventsCount = 0; + } + + /** + * Return an array listing the events for which the emitter has registered + * listeners. + * + * @returns {Array} + * @public + */ + EventEmitter.prototype.eventNames = function eventNames() { + var names = [] + , events + , name; + + if (this._eventsCount === 0) return names; + + for (name in (events = this._events)) { + if (has.call(events, name)) names.push(prefix ? name.slice(1) : name); + } + + if (Object.getOwnPropertySymbols) { + return names.concat(Object.getOwnPropertySymbols(events)); + } + + return names; + }; + + /** + * Return the listeners registered for a given event. + * + * @param {(String|Symbol)} event The event name. + * @returns {Array} The registered listeners. + * @public + */ + EventEmitter.prototype.listeners = function listeners(event) { + var evt = prefix ? prefix + event : event + , handlers = this._events[evt]; + + if (!handlers) return []; + if (handlers.fn) return [handlers.fn]; + + for (var i = 0, l = handlers.length, ee = new Array(l); i < l; i++) { + ee[i] = handlers[i].fn; + } + + return ee; + }; + + /** + * Return the number of listeners listening to a given event. + * + * @param {(String|Symbol)} event The event name. + * @returns {Number} The number of listeners. + * @public + */ + EventEmitter.prototype.listenerCount = function listenerCount(event) { + var evt = prefix ? prefix + event : event + , listeners = this._events[evt]; + + if (!listeners) return 0; + if (listeners.fn) return 1; + return listeners.length; + }; + + /** + * Calls each of the listeners registered for a given event. + * + * @param {(String|Symbol)} event The event name. + * @returns {Boolean} `true` if the event had listeners, else `false`. + * @public + */ + EventEmitter.prototype.emit = function emit(event, a1, a2, a3, a4, a5) { + var evt = prefix ? prefix + event : event; + + if (!this._events[evt]) return false; + + var listeners = this._events[evt] + , len = arguments.length + , args + , i; + + if (listeners.fn) { + if (listeners.once) this.removeListener(event, listeners.fn, undefined, true); + + switch (len) { + case 1: return listeners.fn.call(listeners.context), true; + case 2: return listeners.fn.call(listeners.context, a1), true; + case 3: return listeners.fn.call(listeners.context, a1, a2), true; + case 4: return listeners.fn.call(listeners.context, a1, a2, a3), true; + case 5: return listeners.fn.call(listeners.context, a1, a2, a3, a4), true; + case 6: return listeners.fn.call(listeners.context, a1, a2, a3, a4, a5), true; + } + + for (i = 1, args = new Array(len -1); i < len; i++) { + args[i - 1] = arguments[i]; + } + + listeners.fn.apply(listeners.context, args); + } else { + var length = listeners.length + , j; + + for (i = 0; i < length; i++) { + if (listeners[i].once) this.removeListener(event, listeners[i].fn, undefined, true); + + switch (len) { + case 1: listeners[i].fn.call(listeners[i].context); break; + case 2: listeners[i].fn.call(listeners[i].context, a1); break; + case 3: listeners[i].fn.call(listeners[i].context, a1, a2); break; + case 4: listeners[i].fn.call(listeners[i].context, a1, a2, a3); break; + default: + if (!args) for (j = 1, args = new Array(len -1); j < len; j++) { + args[j - 1] = arguments[j]; + } + + listeners[i].fn.apply(listeners[i].context, args); + } + } + } + + return true; + }; + + /** + * Add a listener for a given event. + * + * @param {(String|Symbol)} event The event name. + * @param {Function} fn The listener function. + * @param {*} [context=this] The context to invoke the listener with. + * @returns {EventEmitter} `this`. + * @public + */ + EventEmitter.prototype.on = function on(event, fn, context) { + return addListener(this, event, fn, context, false); + }; + + /** + * Add a one-time listener for a given event. + * + * @param {(String|Symbol)} event The event name. + * @param {Function} fn The listener function. + * @param {*} [context=this] The context to invoke the listener with. + * @returns {EventEmitter} `this`. + * @public + */ + EventEmitter.prototype.once = function once(event, fn, context) { + return addListener(this, event, fn, context, true); + }; + + /** + * Remove the listeners of a given event. + * + * @param {(String|Symbol)} event The event name. + * @param {Function} fn Only remove the listeners that match this function. + * @param {*} context Only remove the listeners that have this context. + * @param {Boolean} once Only remove one-time listeners. + * @returns {EventEmitter} `this`. + * @public + */ + EventEmitter.prototype.removeListener = function removeListener(event, fn, context, once) { + var evt = prefix ? prefix + event : event; + + if (!this._events[evt]) return this; + if (!fn) { + clearEvent(this, evt); + return this; + } + + var listeners = this._events[evt]; + + if (listeners.fn) { + if ( + listeners.fn === fn && + (!once || listeners.once) && + (!context || listeners.context === context) + ) { + clearEvent(this, evt); + } + } else { + for (var i = 0, events = [], length = listeners.length; i < length; i++) { + if ( + listeners[i].fn !== fn || + (once && !listeners[i].once) || + (context && listeners[i].context !== context) + ) { + events.push(listeners[i]); + } + } + + // + // Reset the array, or remove it completely if we have no more listeners. + // + if (events.length) this._events[evt] = events.length === 1 ? events[0] : events; + else clearEvent(this, evt); + } + + return this; + }; + + /** + * Remove all listeners, or those of the specified event. + * + * @param {(String|Symbol)} [event] The event name. + * @returns {EventEmitter} `this`. + * @public + */ + EventEmitter.prototype.removeAllListeners = function removeAllListeners(event) { + var evt; + + if (event) { + evt = prefix ? prefix + event : event; + if (this._events[evt]) clearEvent(this, evt); + } else { + this._events = new Events(); + this._eventsCount = 0; + } + + return this; + }; + + // + // Alias methods names because people roll like that. + // + EventEmitter.prototype.off = EventEmitter.prototype.removeListener; + EventEmitter.prototype.addListener = EventEmitter.prototype.on; + + // + // Expose the prefix. + // + EventEmitter.prefixed = prefix; + + // + // Allow `EventEmitter` to be imported as module namespace. + // + EventEmitter.EventEmitter = EventEmitter; + + // + // Expose the module. + // + if ('undefined' !== 'object') { + module.exports = EventEmitter; + } +} (eventemitter3$1)); + +var eventemitter3Exports = eventemitter3$1.exports; +var EventEmitter = /*@__PURE__*/getDefaultExportFromCjs(eventemitter3Exports); + +var r={grad:.9,turn:360,rad:360/(2*Math.PI)},t=function(r){return "string"==typeof r?r.length>0:"number"==typeof r},n=function(r,t,n){return void 0===t&&(t=0),void 0===n&&(n=Math.pow(10,t)),Math.round(n*r)/n+0},e=function(r,t,n){return void 0===t&&(t=0),void 0===n&&(n=1),r>n?n:r>t?r:t},u=function(r){return (r=isFinite(r)?r%360:0)>0?r:r+360},a=function(r){return {r:e(r.r,0,255),g:e(r.g,0,255),b:e(r.b,0,255),a:e(r.a)}},o=function(r){return {r:n(r.r),g:n(r.g),b:n(r.b),a:n(r.a,3)}},i=/^#([0-9a-f]{3,8})$/i,s=function(r){var t=r.toString(16);return t.length<2?"0"+t:t},h=function(r){var t=r.r,n=r.g,e=r.b,u=r.a,a=Math.max(t,n,e),o=a-Math.min(t,n,e),i=o?a===t?(n-e)/o:a===n?2+(e-t)/o:4+(t-n)/o:0;return {h:60*(i<0?i+6:i),s:a?o/a*100:0,v:a/255*100,a:u}},b=function(r){var t=r.h,n=r.s,e=r.v,u=r.a;t=t/360*6,n/=100,e/=100;var a=Math.floor(t),o=e*(1-n),i=e*(1-(t-a)*n),s=e*(1-(1-t+a)*n),h=a%6;return {r:255*[e,i,o,o,s,e][h],g:255*[s,e,e,i,o,o][h],b:255*[o,o,s,e,e,i][h],a:u}},g=function(r){return {h:u(r.h),s:e(r.s,0,100),l:e(r.l,0,100),a:e(r.a)}},d=function(r){return {h:n(r.h),s:n(r.s),l:n(r.l),a:n(r.a,3)}},f=function(r){return b((n=(t=r).s,{h:t.h,s:(n*=((e=t.l)<50?e:100-e)/100)>0?2*n/(e+n)*100:0,v:e+n,a:t.a}));var t,n,e;},c=function(r){return {h:(t=h(r)).h,s:(u=(200-(n=t.s))*(e=t.v)/100)>0&&u<200?n*e/100/(u<=100?u:200-u)*100:0,l:u/2,a:t.a};var t,n,e,u;},l=/^hsla?\(\s*([+-]?\d*\.?\d+)(deg|rad|grad|turn)?\s*,\s*([+-]?\d*\.?\d+)%\s*,\s*([+-]?\d*\.?\d+)%\s*(?:,\s*([+-]?\d*\.?\d+)(%)?\s*)?\)$/i,p=/^hsla?\(\s*([+-]?\d*\.?\d+)(deg|rad|grad|turn)?\s+([+-]?\d*\.?\d+)%\s+([+-]?\d*\.?\d+)%\s*(?:\/\s*([+-]?\d*\.?\d+)(%)?\s*)?\)$/i,v=/^rgba?\(\s*([+-]?\d*\.?\d+)(%)?\s*,\s*([+-]?\d*\.?\d+)(%)?\s*,\s*([+-]?\d*\.?\d+)(%)?\s*(?:,\s*([+-]?\d*\.?\d+)(%)?\s*)?\)$/i,m=/^rgba?\(\s*([+-]?\d*\.?\d+)(%)?\s+([+-]?\d*\.?\d+)(%)?\s+([+-]?\d*\.?\d+)(%)?\s*(?:\/\s*([+-]?\d*\.?\d+)(%)?\s*)?\)$/i,y={string:[[function(r){var t=i.exec(r);return t?(r=t[1]).length<=4?{r:parseInt(r[0]+r[0],16),g:parseInt(r[1]+r[1],16),b:parseInt(r[2]+r[2],16),a:4===r.length?n(parseInt(r[3]+r[3],16)/255,2):1}:6===r.length||8===r.length?{r:parseInt(r.substr(0,2),16),g:parseInt(r.substr(2,2),16),b:parseInt(r.substr(4,2),16),a:8===r.length?n(parseInt(r.substr(6,2),16)/255,2):1}:null:null},"hex"],[function(r){var t=v.exec(r)||m.exec(r);return t?t[2]!==t[4]||t[4]!==t[6]?null:a({r:Number(t[1])/(t[2]?100/255:1),g:Number(t[3])/(t[4]?100/255:1),b:Number(t[5])/(t[6]?100/255:1),a:void 0===t[7]?1:Number(t[7])/(t[8]?100:1)}):null},"rgb"],[function(t){var n=l.exec(t)||p.exec(t);if(!n)return null;var e,u,a=g({h:(e=n[1],u=n[2],void 0===u&&(u="deg"),Number(e)*(r[u]||1)),s:Number(n[3]),l:Number(n[4]),a:void 0===n[5]?1:Number(n[5])/(n[6]?100:1)});return f(a)},"hsl"]],object:[[function(r){var n=r.r,e=r.g,u=r.b,o=r.a,i=void 0===o?1:o;return t(n)&&t(e)&&t(u)?a({r:Number(n),g:Number(e),b:Number(u),a:Number(i)}):null},"rgb"],[function(r){var n=r.h,e=r.s,u=r.l,a=r.a,o=void 0===a?1:a;if(!t(n)||!t(e)||!t(u))return null;var i=g({h:Number(n),s:Number(e),l:Number(u),a:Number(o)});return f(i)},"hsl"],[function(r){var n=r.h,a=r.s,o=r.v,i=r.a,s=void 0===i?1:i;if(!t(n)||!t(a)||!t(o))return null;var h=function(r){return {h:u(r.h),s:e(r.s,0,100),v:e(r.v,0,100),a:e(r.a)}}({h:Number(n),s:Number(a),v:Number(o),a:Number(s)});return b(h)},"hsv"]]},N=function(r,t){for(var n=0;n=.5},r.prototype.toHex=function(){return r=o(this.rgba),t=r.r,e=r.g,u=r.b,i=(a=r.a)<1?s(n(255*a)):"","#"+s(t)+s(e)+s(u)+i;var r,t,e,u,a,i;},r.prototype.toRgb=function(){return o(this.rgba)},r.prototype.toRgbString=function(){return r=o(this.rgba),t=r.r,n=r.g,e=r.b,(u=r.a)<1?"rgba("+t+", "+n+", "+e+", "+u+")":"rgb("+t+", "+n+", "+e+")";var r,t,n,e,u;},r.prototype.toHsl=function(){return d(c(this.rgba))},r.prototype.toHslString=function(){return r=d(c(this.rgba)),t=r.h,n=r.s,e=r.l,(u=r.a)<1?"hsla("+t+", "+n+"%, "+e+"%, "+u+")":"hsl("+t+", "+n+"%, "+e+"%)";var r,t,n,e,u;},r.prototype.toHsv=function(){return r=h(this.rgba),{h:n(r.h),s:n(r.s),v:n(r.v),a:n(r.a,3)};var r;},r.prototype.invert=function(){return w({r:255-(r=this.rgba).r,g:255-r.g,b:255-r.b,a:r.a});var r;},r.prototype.saturate=function(r){return void 0===r&&(r=.1),w(M(this.rgba,r))},r.prototype.desaturate=function(r){return void 0===r&&(r=.1),w(M(this.rgba,-r))},r.prototype.grayscale=function(){return w(M(this.rgba,-1))},r.prototype.lighten=function(r){return void 0===r&&(r=.1),w($(this.rgba,r))},r.prototype.darken=function(r){return void 0===r&&(r=.1),w($(this.rgba,-r))},r.prototype.rotate=function(r){return void 0===r&&(r=15),this.hue(this.hue()+r)},r.prototype.alpha=function(r){return "number"==typeof r?w({r:(t=this.rgba).r,g:t.g,b:t.b,a:r}):n(this.rgba.a,3);var t;},r.prototype.hue=function(r){var t=c(this.rgba);return "number"==typeof r?w({h:r,s:t.s,l:t.l,a:t.a}):n(t.h)},r.prototype.isEqual=function(r){return this.toHex()===w(r).toHex()},r}(),w=function(r){return r instanceof j?r:new j(r)},S=[],k=function(r){r.forEach(function(r){S.indexOf(r)<0&&(r(j,y),S.push(r));});},E=function(){return new j({r:255*Math.random(),g:255*Math.random(),b:255*Math.random()})}; + +function namesPlugin(e,f){var a={white:"#ffffff",bisque:"#ffe4c4",blue:"#0000ff",cadetblue:"#5f9ea0",chartreuse:"#7fff00",chocolate:"#d2691e",coral:"#ff7f50",antiquewhite:"#faebd7",aqua:"#00ffff",azure:"#f0ffff",whitesmoke:"#f5f5f5",papayawhip:"#ffefd5",plum:"#dda0dd",blanchedalmond:"#ffebcd",black:"#000000",gold:"#ffd700",goldenrod:"#daa520",gainsboro:"#dcdcdc",cornsilk:"#fff8dc",cornflowerblue:"#6495ed",burlywood:"#deb887",aquamarine:"#7fffd4",beige:"#f5f5dc",crimson:"#dc143c",cyan:"#00ffff",darkblue:"#00008b",darkcyan:"#008b8b",darkgoldenrod:"#b8860b",darkkhaki:"#bdb76b",darkgray:"#a9a9a9",darkgreen:"#006400",darkgrey:"#a9a9a9",peachpuff:"#ffdab9",darkmagenta:"#8b008b",darkred:"#8b0000",darkorchid:"#9932cc",darkorange:"#ff8c00",darkslateblue:"#483d8b",gray:"#808080",darkslategray:"#2f4f4f",darkslategrey:"#2f4f4f",deeppink:"#ff1493",deepskyblue:"#00bfff",wheat:"#f5deb3",firebrick:"#b22222",floralwhite:"#fffaf0",ghostwhite:"#f8f8ff",darkviolet:"#9400d3",magenta:"#ff00ff",green:"#008000",dodgerblue:"#1e90ff",grey:"#808080",honeydew:"#f0fff0",hotpink:"#ff69b4",blueviolet:"#8a2be2",forestgreen:"#228b22",lawngreen:"#7cfc00",indianred:"#cd5c5c",indigo:"#4b0082",fuchsia:"#ff00ff",brown:"#a52a2a",maroon:"#800000",mediumblue:"#0000cd",lightcoral:"#f08080",darkturquoise:"#00ced1",lightcyan:"#e0ffff",ivory:"#fffff0",lightyellow:"#ffffe0",lightsalmon:"#ffa07a",lightseagreen:"#20b2aa",linen:"#faf0e6",mediumaquamarine:"#66cdaa",lemonchiffon:"#fffacd",lime:"#00ff00",khaki:"#f0e68c",mediumseagreen:"#3cb371",limegreen:"#32cd32",mediumspringgreen:"#00fa9a",lightskyblue:"#87cefa",lightblue:"#add8e6",midnightblue:"#191970",lightpink:"#ffb6c1",mistyrose:"#ffe4e1",moccasin:"#ffe4b5",mintcream:"#f5fffa",lightslategray:"#778899",lightslategrey:"#778899",navajowhite:"#ffdead",navy:"#000080",mediumvioletred:"#c71585",powderblue:"#b0e0e6",palegoldenrod:"#eee8aa",oldlace:"#fdf5e6",paleturquoise:"#afeeee",mediumturquoise:"#48d1cc",mediumorchid:"#ba55d3",rebeccapurple:"#663399",lightsteelblue:"#b0c4de",mediumslateblue:"#7b68ee",thistle:"#d8bfd8",tan:"#d2b48c",orchid:"#da70d6",mediumpurple:"#9370db",purple:"#800080",pink:"#ffc0cb",skyblue:"#87ceeb",springgreen:"#00ff7f",palegreen:"#98fb98",red:"#ff0000",yellow:"#ffff00",slateblue:"#6a5acd",lavenderblush:"#fff0f5",peru:"#cd853f",palevioletred:"#db7093",violet:"#ee82ee",teal:"#008080",slategray:"#708090",slategrey:"#708090",aliceblue:"#f0f8ff",darkseagreen:"#8fbc8f",darkolivegreen:"#556b2f",greenyellow:"#adff2f",seagreen:"#2e8b57",seashell:"#fff5ee",tomato:"#ff6347",silver:"#c0c0c0",sienna:"#a0522d",lavender:"#e6e6fa",lightgreen:"#90ee90",orange:"#ffa500",orangered:"#ff4500",steelblue:"#4682b4",royalblue:"#4169e1",turquoise:"#40e0d0",yellowgreen:"#9acd32",salmon:"#fa8072",saddlebrown:"#8b4513",sandybrown:"#f4a460",rosybrown:"#bc8f8f",darksalmon:"#e9967a",lightgoldenrodyellow:"#fafad2",snow:"#fffafa",lightgrey:"#d3d3d3",lightgray:"#d3d3d3",dimgray:"#696969",dimgrey:"#696969",olivedrab:"#6b8e23",olive:"#808000"},r={};for(var d in a)r[a[d]]=d;var l={};e.prototype.toName=function(f){if(!(this.rgba.a||this.rgba.r||this.rgba.g||this.rgba.b))return "transparent";var d,i,n=r[this.toHex()];if(n)return n;if(null==f?void 0:f.closest){var o=this.toRgb(),t=1/0,b="black";if(!l.length)for(var c in a)l[c]=new e(a[c]).toRgb();for(var g in a){var u=(d=o,i=l[g],Math.pow(d.r-i.r,2)+Math.pow(d.g-i.g,2)+Math.pow(d.b-i.b,2));u key in obj ? __defProp$$(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; +var __spreadValues$$ = (a, b) => { + for (var prop in b || (b = {})) + if (__hasOwnProp$$.call(b, prop)) + __defNormalProp$$(a, prop, b[prop]); + if (__getOwnPropSymbols$$) + for (var prop of __getOwnPropSymbols$$(b)) { + if (__propIsEnum$$.call(b, prop)) + __defNormalProp$$(a, prop, b[prop]); + } + return a; +}; +k([namesPlugin]); +const _Color = class _Color { + /** + * @param {ColorSource} value - Optional value to use, if not provided, white is used. + */ + constructor(value = 16777215) { + this._value = null; + this._components = new Float32Array(4); + this._components.fill(1); + this._int = 16777215; + this.value = value; + } + /** Get red component (0 - 1) */ + get red() { + return this._components[0]; + } + /** Get green component (0 - 1) */ + get green() { + return this._components[1]; + } + /** Get blue component (0 - 1) */ + get blue() { + return this._components[2]; + } + /** Get alpha component (0 - 1) */ + get alpha() { + return this._components[3]; + } + /** + * Set the value, suitable for chaining + * @param value + * @see Color.value + */ + setValue(value) { + this.value = value; + return this; + } + /** + * The current color source. + * + * When setting: + * - Setting to an instance of `Color` will copy its color source and components. + * - Otherwise, `Color` will try to normalize the color source and set the components. + * If the color source is invalid, an `Error` will be thrown and the `Color` will left unchanged. + * + * Note: The `null` in the setter's parameter type is added to match the TypeScript rule: return type of getter + * must be assignable to its setter's parameter type. Setting `value` to `null` will throw an `Error`. + * + * When getting: + * - A return value of `null` means the previous value was overridden (e.g., {@link Color.multiply multiply}, + * {@link Color.premultiply premultiply} or {@link Color.round round}). + * - Otherwise, the color source used when setting is returned. + */ + set value(value) { + if (value instanceof _Color) { + this._value = this._cloneSource(value._value); + this._int = value._int; + this._components.set(value._components); + } else if (value === null) { + throw new Error("Cannot set Color#value to null"); + } else if (this._value === null || !this._isSourceEqual(this._value, value)) { + this._normalize(value); + this._value = this._cloneSource(value); + } + } + get value() { + return this._value; + } + /** + * Copy a color source internally. + * @param value - Color source + */ + _cloneSource(value) { + if (typeof value === "string" || typeof value === "number" || value instanceof Number || value === null) { + return value; + } else if (Array.isArray(value) || ArrayBuffer.isView(value)) { + return value.slice(0); + } else if (typeof value === "object" && value !== null) { + return __spreadValues$$({}, value); + } + return value; + } + /** + * Equality check for color sources. + * @param value1 - First color source + * @param value2 - Second color source + * @returns `true` if the color sources are equal, `false` otherwise. + */ + _isSourceEqual(value1, value2) { + const type1 = typeof value1; + const type2 = typeof value2; + if (type1 !== type2) { + return false; + } else if (type1 === "number" || type1 === "string" || value1 instanceof Number) { + return value1 === value2; + } else if (Array.isArray(value1) && Array.isArray(value2) || ArrayBuffer.isView(value1) && ArrayBuffer.isView(value2)) { + if (value1.length !== value2.length) { + return false; + } + return value1.every((v, i) => v === value2[i]); + } else if (value1 !== null && value2 !== null) { + const keys1 = Object.keys(value1); + const keys2 = Object.keys(value2); + if (keys1.length !== keys2.length) { + return false; + } + return keys1.every((key) => value1[key] === value2[key]); + } + return value1 === value2; + } + /** + * Convert to a RGBA color object. + * @example + * import { Color } from 'pixi.js'; + * new Color('white').toRgb(); // returns { r: 1, g: 1, b: 1, a: 1 } + */ + toRgba() { + const [r, g, b, a] = this._components; + return { r, g, b, a }; + } + /** + * Convert to a RGB color object. + * @example + * import { Color } from 'pixi.js'; + * new Color('white').toRgb(); // returns { r: 1, g: 1, b: 1 } + */ + toRgb() { + const [r, g, b] = this._components; + return { r, g, b }; + } + /** Convert to a CSS-style rgba string: `rgba(255,255,255,1.0)`. */ + toRgbaString() { + const [r, g, b] = this.toUint8RgbArray(); + return `rgba(${r},${g},${b},${this.alpha})`; + } + toUint8RgbArray(out) { + const [r, g, b] = this._components; + if (!this._arrayRgb) { + this._arrayRgb = []; + } + out = out || this._arrayRgb; + out[0] = Math.round(r * 255); + out[1] = Math.round(g * 255); + out[2] = Math.round(b * 255); + return out; + } + toArray(out) { + if (!this._arrayRgba) { + this._arrayRgba = []; + } + out = out || this._arrayRgba; + const [r, g, b, a] = this._components; + out[0] = r; + out[1] = g; + out[2] = b; + out[3] = a; + return out; + } + toRgbArray(out) { + if (!this._arrayRgb) { + this._arrayRgb = []; + } + out = out || this._arrayRgb; + const [r, g, b] = this._components; + out[0] = r; + out[1] = g; + out[2] = b; + return out; + } + /** + * Convert to a hexadecimal number. + * @example + * import { Color } from 'pixi.js'; + * new Color('white').toNumber(); // returns 16777215 + */ + toNumber() { + return this._int; + } + /** + * Convert to a BGR number + * @example + * import { Color } from 'pixi.js'; + * new Color(0xffcc99).toBgrNumber(); // returns 0x99ccff + */ + toBgrNumber() { + const [r, g, b] = this.toUint8RgbArray(); + return (b << 16) + (g << 8) + r; + } + /** + * Convert to a hexadecimal number in little endian format (e.g., BBGGRR). + * @example + * import { Color } from 'pixi.js'; + * new Color(0xffcc99).toLittleEndianNumber(); // returns 0x99ccff + * @returns {number} - The color as a number in little endian format. + */ + toLittleEndianNumber() { + const value = this._int; + return (value >> 16) + (value & 65280) + ((value & 255) << 16); + } + /** + * Multiply with another color. This action is destructive, and will + * override the previous `value` property to be `null`. + * @param {ColorSource} value - The color to multiply by. + */ + multiply(value) { + const [r, g, b, a] = _Color._temp.setValue(value)._components; + this._components[0] *= r; + this._components[1] *= g; + this._components[2] *= b; + this._components[3] *= a; + this._refreshInt(); + this._value = null; + return this; + } + /** + * Converts color to a premultiplied alpha format. This action is destructive, and will + * override the previous `value` property to be `null`. + * @param alpha - The alpha to multiply by. + * @param {boolean} [applyToRGB=true] - Whether to premultiply RGB channels. + * @returns {Color} - Itself. + */ + premultiply(alpha, applyToRGB = true) { + if (applyToRGB) { + this._components[0] *= alpha; + this._components[1] *= alpha; + this._components[2] *= alpha; + } + this._components[3] = alpha; + this._refreshInt(); + this._value = null; + return this; + } + /** + * Premultiplies alpha with current color. + * @param {number} alpha - The alpha to multiply by. + * @param {boolean} [applyToRGB=true] - Whether to premultiply RGB channels. + * @returns {number} tint multiplied by alpha + */ + toPremultiplied(alpha, applyToRGB = true) { + if (alpha === 1) { + return (255 << 24) + this._int; + } + if (alpha === 0) { + return applyToRGB ? 0 : this._int; + } + let r = this._int >> 16 & 255; + let g = this._int >> 8 & 255; + let b = this._int & 255; + if (applyToRGB) { + r = r * alpha + 0.5 | 0; + g = g * alpha + 0.5 | 0; + b = b * alpha + 0.5 | 0; + } + return (alpha * 255 << 24) + (r << 16) + (g << 8) + b; + } + /** + * Convert to a hexidecimal string. + * @example + * import { Color } from 'pixi.js'; + * new Color('white').toHex(); // returns "#ffffff" + */ + toHex() { + const hexString = this._int.toString(16); + return `#${"000000".substring(0, 6 - hexString.length) + hexString}`; + } + /** + * Convert to a hexidecimal string with alpha. + * @example + * import { Color } from 'pixi.js'; + * new Color('white').toHexa(); // returns "#ffffffff" + */ + toHexa() { + const alphaValue = Math.round(this._components[3] * 255); + const alphaString = alphaValue.toString(16); + return this.toHex() + "00".substring(0, 2 - alphaString.length) + alphaString; + } + /** + * Set alpha, suitable for chaining. + * @param alpha + */ + setAlpha(alpha) { + this._components[3] = this._clamp(alpha); + return this; + } + /** + * Normalize the input value into rgba + * @param value - Input value + */ + _normalize(value) { + let r; + let g; + let b; + let a; + if ((typeof value === "number" || value instanceof Number) && value >= 0 && value <= 16777215) { + const int = value; + r = (int >> 16 & 255) / 255; + g = (int >> 8 & 255) / 255; + b = (int & 255) / 255; + a = 1; + } else if ((Array.isArray(value) || value instanceof Float32Array) && value.length >= 3 && value.length <= 4) { + value = this._clamp(value); + [r, g, b, a = 1] = value; + } else if ((value instanceof Uint8Array || value instanceof Uint8ClampedArray) && value.length >= 3 && value.length <= 4) { + value = this._clamp(value, 0, 255); + [r, g, b, a = 255] = value; + r /= 255; + g /= 255; + b /= 255; + a /= 255; + } else if (typeof value === "string" || typeof value === "object") { + if (typeof value === "string") { + const match = _Color.HEX_PATTERN.exec(value); + if (match) { + value = `#${match[2]}`; + } + } + const color = w(value); + if (color.isValid()) { + ({ r, g, b, a } = color.rgba); + r /= 255; + g /= 255; + b /= 255; + } + } + if (r !== void 0) { + this._components[0] = r; + this._components[1] = g; + this._components[2] = b; + this._components[3] = a; + this._refreshInt(); + } else { + throw new Error(`Unable to convert color ${value}`); + } + } + /** Refresh the internal color rgb number */ + _refreshInt() { + this._clamp(this._components); + const [r, g, b] = this._components; + this._int = (r * 255 << 16) + (g * 255 << 8) + (b * 255 | 0); + } + /** + * Clamps values to a range. Will override original values + * @param value - Value(s) to clamp + * @param min - Minimum value + * @param max - Maximum value + */ + _clamp(value, min = 0, max = 1) { + if (typeof value === "number") { + return Math.min(Math.max(value, min), max); + } + value.forEach((v, i) => { + value[i] = Math.min(Math.max(v, min), max); + }); + return value; + } + /** + * Check if the value is a color-like object + * @param value - Value to check + * @returns True if the value is a color-like object + * @static + * @example + * import { Color } from 'pixi.js'; + * Color.isColorLike('white'); // returns true + * Color.isColorLike(0xffffff); // returns true + * Color.isColorLike([1, 1, 1]); // returns true + */ + static isColorLike(value) { + return typeof value === "number" || typeof value === "string" || value instanceof Number || value instanceof _Color || Array.isArray(value) || value instanceof Uint8Array || value instanceof Uint8ClampedArray || value instanceof Float32Array || value.r !== void 0 && value.g !== void 0 && value.b !== void 0 || value.r !== void 0 && value.g !== void 0 && value.b !== void 0 && value.a !== void 0 || value.h !== void 0 && value.s !== void 0 && value.l !== void 0 || value.h !== void 0 && value.s !== void 0 && value.l !== void 0 && value.a !== void 0 || value.h !== void 0 && value.s !== void 0 && value.v !== void 0 || value.h !== void 0 && value.s !== void 0 && value.v !== void 0 && value.a !== void 0; + } +}; +/** + * Default Color object for static uses + * @example + * import { Color } from 'pixi.js'; + * Color.shared.setValue(0xffffff).toHex(); // '#ffffff' + */ +_Color.shared = new _Color(); +/** + * Temporary Color object for static uses internally. + * As to not conflict with Color.shared. + * @ignore + */ +_Color._temp = new _Color(); +/** Pattern for hex strings */ +// eslint-disable-next-line @typescript-eslint/naming-convention +_Color.HEX_PATTERN = /^(#|0x)?(([a-f0-9]{3}){1,2}([a-f0-9]{2})?)$/i; +let Color = _Color; + +"use strict"; +const cullingMixin = { + cullArea: null, + cullable: false, + cullableChildren: true +}; + +"use strict"; +const PI_2 = Math.PI * 2; +const RAD_TO_DEG = 180 / Math.PI; +const DEG_TO_RAD = Math.PI / 180; + +"use strict"; +class Point { + /** + * Creates a new `Point` + * @param {number} [x=0] - position of the point on the x axis + * @param {number} [y=0] - position of the point on the y axis + */ + constructor(x = 0, y = 0) { + /** Position of the point on the x axis */ + this.x = 0; + /** Position of the point on the y axis */ + this.y = 0; + this.x = x; + this.y = y; + } + /** + * Creates a clone of this point + * @returns A clone of this point + */ + clone() { + return new Point(this.x, this.y); + } + /** + * Copies `x` and `y` from the given point into this point + * @param p - The point to copy from + * @returns The point instance itself + */ + copyFrom(p) { + this.set(p.x, p.y); + return this; + } + /** + * Copies this point's x and y into the given point (`p`). + * @param p - The point to copy to. Can be any of type that is or extends `PointData` + * @returns The point (`p`) with values updated + */ + copyTo(p) { + p.set(this.x, this.y); + return p; + } + /** + * Accepts another point (`p`) and returns `true` if the given point is equal to this point + * @param p - The point to check + * @returns Returns `true` if both `x` and `y` are equal + */ + equals(p) { + return p.x === this.x && p.y === this.y; + } + /** + * Sets the point to a new `x` and `y` position. + * If `y` is omitted, both `x` and `y` will be set to `x`. + * @param {number} [x=0] - position of the point on the `x` axis + * @param {number} [y=x] - position of the point on the `y` axis + * @returns The point instance itself + */ + set(x = 0, y = x) { + this.x = x; + this.y = y; + return this; + } + toString() { + return `[pixi.js/math:Point x=${this.x} y=${this.y}]`; + } + /** + * A static Point object with `x` and `y` values of `0`. Can be used to avoid creating new objects multiple times. + * @readonly + */ + static get shared() { + tempPoint.x = 0; + tempPoint.y = 0; + return tempPoint; + } +} +const tempPoint = new Point(); + +"use strict"; +class Matrix { + /** + * @param a - x scale + * @param b - y skew + * @param c - x skew + * @param d - y scale + * @param tx - x translation + * @param ty - y translation + */ + constructor(a = 1, b = 0, c = 0, d = 1, tx = 0, ty = 0) { + /** An array of the current matrix. Only populated when `toArray` is called */ + this.array = null; + this.a = a; + this.b = b; + this.c = c; + this.d = d; + this.tx = tx; + this.ty = ty; + } + /** + * Creates a Matrix object based on the given array. The Element to Matrix mapping order is as follows: + * + * a = array[0] + * b = array[1] + * c = array[3] + * d = array[4] + * tx = array[2] + * ty = array[5] + * @param array - The array that the matrix will be populated from. + */ + fromArray(array) { + this.a = array[0]; + this.b = array[1]; + this.c = array[3]; + this.d = array[4]; + this.tx = array[2]; + this.ty = array[5]; + } + /** + * Sets the matrix properties. + * @param a - Matrix component + * @param b - Matrix component + * @param c - Matrix component + * @param d - Matrix component + * @param tx - Matrix component + * @param ty - Matrix component + * @returns This matrix. Good for chaining method calls. + */ + set(a, b, c, d, tx, ty) { + this.a = a; + this.b = b; + this.c = c; + this.d = d; + this.tx = tx; + this.ty = ty; + return this; + } + /** + * Creates an array from the current Matrix object. + * @param transpose - Whether we need to transpose the matrix or not + * @param [out=new Float32Array(9)] - If provided the array will be assigned to out + * @returns The newly created array which contains the matrix + */ + toArray(transpose, out) { + if (!this.array) { + this.array = new Float32Array(9); + } + const array = out || this.array; + if (transpose) { + array[0] = this.a; + array[1] = this.b; + array[2] = 0; + array[3] = this.c; + array[4] = this.d; + array[5] = 0; + array[6] = this.tx; + array[7] = this.ty; + array[8] = 1; + } else { + array[0] = this.a; + array[1] = this.c; + array[2] = this.tx; + array[3] = this.b; + array[4] = this.d; + array[5] = this.ty; + array[6] = 0; + array[7] = 0; + array[8] = 1; + } + return array; + } + /** + * Get a new position with the current transformation applied. + * Can be used to go from a child's coordinate space to the world coordinate space. (e.g. rendering) + * @param pos - The origin + * @param {Point} [newPos] - The point that the new position is assigned to (allowed to be same as input) + * @returns {Point} The new point, transformed through this matrix + */ + apply(pos, newPos) { + newPos = newPos || new Point(); + const x = pos.x; + const y = pos.y; + newPos.x = this.a * x + this.c * y + this.tx; + newPos.y = this.b * x + this.d * y + this.ty; + return newPos; + } + /** + * Get a new position with the inverse of the current transformation applied. + * Can be used to go from the world coordinate space to a child's coordinate space. (e.g. input) + * @param pos - The origin + * @param {Point} [newPos] - The point that the new position is assigned to (allowed to be same as input) + * @returns {Point} The new point, inverse-transformed through this matrix + */ + applyInverse(pos, newPos) { + newPos = newPos || new Point(); + const a = this.a; + const b = this.b; + const c = this.c; + const d = this.d; + const tx = this.tx; + const ty = this.ty; + const id = 1 / (a * d + c * -b); + const x = pos.x; + const y = pos.y; + newPos.x = d * id * x + -c * id * y + (ty * c - tx * d) * id; + newPos.y = a * id * y + -b * id * x + (-ty * a + tx * b) * id; + return newPos; + } + /** + * Translates the matrix on the x and y. + * @param x - How much to translate x by + * @param y - How much to translate y by + * @returns This matrix. Good for chaining method calls. + */ + translate(x, y) { + this.tx += x; + this.ty += y; + return this; + } + /** + * Applies a scale transformation to the matrix. + * @param x - The amount to scale horizontally + * @param y - The amount to scale vertically + * @returns This matrix. Good for chaining method calls. + */ + scale(x, y) { + this.a *= x; + this.d *= y; + this.c *= x; + this.b *= y; + this.tx *= x; + this.ty *= y; + return this; + } + /** + * Applies a rotation transformation to the matrix. + * @param angle - The angle in radians. + * @returns This matrix. Good for chaining method calls. + */ + rotate(angle) { + const cos = Math.cos(angle); + const sin = Math.sin(angle); + const a1 = this.a; + const c1 = this.c; + const tx1 = this.tx; + this.a = a1 * cos - this.b * sin; + this.b = a1 * sin + this.b * cos; + this.c = c1 * cos - this.d * sin; + this.d = c1 * sin + this.d * cos; + this.tx = tx1 * cos - this.ty * sin; + this.ty = tx1 * sin + this.ty * cos; + return this; + } + /** + * Appends the given Matrix to this Matrix. + * @param matrix - The matrix to append. + * @returns This matrix. Good for chaining method calls. + */ + append(matrix) { + const a1 = this.a; + const b1 = this.b; + const c1 = this.c; + const d1 = this.d; + this.a = matrix.a * a1 + matrix.b * c1; + this.b = matrix.a * b1 + matrix.b * d1; + this.c = matrix.c * a1 + matrix.d * c1; + this.d = matrix.c * b1 + matrix.d * d1; + this.tx = matrix.tx * a1 + matrix.ty * c1 + this.tx; + this.ty = matrix.tx * b1 + matrix.ty * d1 + this.ty; + return this; + } + /** + * Appends two matrix's and sets the result to this matrix. AB = A * B + * @param a - The matrix to append. + * @param b - The matrix to append. + * @returns This matrix. Good for chaining method calls. + */ + appendFrom(a, b) { + const a1 = a.a; + const b1 = a.b; + const c1 = a.c; + const d1 = a.d; + const tx = a.tx; + const ty = a.ty; + const a2 = b.a; + const b2 = b.b; + const c2 = b.c; + const d2 = b.d; + this.a = a1 * a2 + b1 * c2; + this.b = a1 * b2 + b1 * d2; + this.c = c1 * a2 + d1 * c2; + this.d = c1 * b2 + d1 * d2; + this.tx = tx * a2 + ty * c2 + b.tx; + this.ty = tx * b2 + ty * d2 + b.ty; + return this; + } + /** + * Sets the matrix based on all the available properties + * @param x - Position on the x axis + * @param y - Position on the y axis + * @param pivotX - Pivot on the x axis + * @param pivotY - Pivot on the y axis + * @param scaleX - Scale on the x axis + * @param scaleY - Scale on the y axis + * @param rotation - Rotation in radians + * @param skewX - Skew on the x axis + * @param skewY - Skew on the y axis + * @returns This matrix. Good for chaining method calls. + */ + setTransform(x, y, pivotX, pivotY, scaleX, scaleY, rotation, skewX, skewY) { + this.a = Math.cos(rotation + skewY) * scaleX; + this.b = Math.sin(rotation + skewY) * scaleX; + this.c = -Math.sin(rotation - skewX) * scaleY; + this.d = Math.cos(rotation - skewX) * scaleY; + this.tx = x - (pivotX * this.a + pivotY * this.c); + this.ty = y - (pivotX * this.b + pivotY * this.d); + return this; + } + /** + * Prepends the given Matrix to this Matrix. + * @param matrix - The matrix to prepend + * @returns This matrix. Good for chaining method calls. + */ + prepend(matrix) { + const tx1 = this.tx; + if (matrix.a !== 1 || matrix.b !== 0 || matrix.c !== 0 || matrix.d !== 1) { + const a1 = this.a; + const c1 = this.c; + this.a = a1 * matrix.a + this.b * matrix.c; + this.b = a1 * matrix.b + this.b * matrix.d; + this.c = c1 * matrix.a + this.d * matrix.c; + this.d = c1 * matrix.b + this.d * matrix.d; + } + this.tx = tx1 * matrix.a + this.ty * matrix.c + matrix.tx; + this.ty = tx1 * matrix.b + this.ty * matrix.d + matrix.ty; + return this; + } + /** + * Decomposes the matrix (x, y, scaleX, scaleY, and rotation) and sets the properties on to a transform. + * @param transform - The transform to apply the properties to. + * @returns The transform with the newly applied properties + */ + decompose(transform) { + const a = this.a; + const b = this.b; + const c = this.c; + const d = this.d; + const pivot = transform.pivot; + const skewX = -Math.atan2(-c, d); + const skewY = Math.atan2(b, a); + const delta = Math.abs(skewX + skewY); + if (delta < 1e-5 || Math.abs(PI_2 - delta) < 1e-5) { + transform.rotation = skewY; + transform.skew.x = transform.skew.y = 0; + } else { + transform.rotation = 0; + transform.skew.x = skewX; + transform.skew.y = skewY; + } + transform.scale.x = Math.sqrt(a * a + b * b); + transform.scale.y = Math.sqrt(c * c + d * d); + transform.position.x = this.tx + (pivot.x * a + pivot.y * c); + transform.position.y = this.ty + (pivot.x * b + pivot.y * d); + return transform; + } + /** + * Inverts this matrix + * @returns This matrix. Good for chaining method calls. + */ + invert() { + const a1 = this.a; + const b1 = this.b; + const c1 = this.c; + const d1 = this.d; + const tx1 = this.tx; + const n = a1 * d1 - b1 * c1; + this.a = d1 / n; + this.b = -b1 / n; + this.c = -c1 / n; + this.d = a1 / n; + this.tx = (c1 * this.ty - d1 * tx1) / n; + this.ty = -(a1 * this.ty - b1 * tx1) / n; + return this; + } + /** Checks if this matrix is an identity matrix */ + isIdentity() { + return this.a === 1 && this.b === 0 && this.c === 0 && this.d === 1 && this.tx === 0 && this.ty === 0; + } + /** + * Resets this Matrix to an identity (default) matrix. + * @returns This matrix. Good for chaining method calls. + */ + identity() { + this.a = 1; + this.b = 0; + this.c = 0; + this.d = 1; + this.tx = 0; + this.ty = 0; + return this; + } + /** + * Creates a new Matrix object with the same values as this one. + * @returns A copy of this matrix. Good for chaining method calls. + */ + clone() { + const matrix = new Matrix(); + matrix.a = this.a; + matrix.b = this.b; + matrix.c = this.c; + matrix.d = this.d; + matrix.tx = this.tx; + matrix.ty = this.ty; + return matrix; + } + /** + * Changes the values of the given matrix to be the same as the ones in this matrix + * @param matrix - The matrix to copy to. + * @returns The matrix given in parameter with its values updated. + */ + copyTo(matrix) { + matrix.a = this.a; + matrix.b = this.b; + matrix.c = this.c; + matrix.d = this.d; + matrix.tx = this.tx; + matrix.ty = this.ty; + return matrix; + } + /** + * Changes the values of the matrix to be the same as the ones in given matrix + * @param matrix - The matrix to copy from. + * @returns this + */ + copyFrom(matrix) { + this.a = matrix.a; + this.b = matrix.b; + this.c = matrix.c; + this.d = matrix.d; + this.tx = matrix.tx; + this.ty = matrix.ty; + return this; + } + /** + * check to see if two matrices are the same + * @param matrix - The matrix to compare to. + */ + equals(matrix) { + return matrix.a === this.a && matrix.b === this.b && matrix.c === this.c && matrix.d === this.d && matrix.tx === this.tx && matrix.ty === this.ty; + } + toString() { + return `[pixi.js:Matrix a=${this.a} b=${this.b} c=${this.c} d=${this.d} tx=${this.tx} ty=${this.ty}]`; + } + /** + * A default (identity) matrix. + * + * This is a shared object, if you want to modify it consider creating a new `Matrix` + * @readonly + */ + static get IDENTITY() { + return identityMatrix.identity(); + } + /** + * A static Matrix that can be used to avoid creating new objects. + * Will always ensure the matrix is reset to identity when requested. + * Use this object for fast but temporary calculations, as it may be mutated later on. + * This is a different object to the `IDENTITY` object and so can be modified without changing `IDENTITY`. + * @readonly + */ + static get shared() { + return tempMatrix$4.identity(); + } +} +const tempMatrix$4 = new Matrix(); +const identityMatrix = new Matrix(); + +"use strict"; +class ObservablePoint { + /** + * Creates a new `ObservablePoint` + * @param observer - Observer to pass to listen for change events. + * @param {number} [x=0] - position of the point on the x axis + * @param {number} [y=0] - position of the point on the y axis + */ + constructor(observer, x, y) { + this._x = x || 0; + this._y = y || 0; + this._observer = observer; + } + /** + * Creates a clone of this point. + * @param observer - Optional observer to pass to the new observable point. + * @returns a copy of this observable point + */ + clone(observer) { + return new ObservablePoint(observer != null ? observer : this._observer, this._x, this._y); + } + /** + * Sets the point to a new `x` and `y` position. + * If `y` is omitted, both `x` and `y` will be set to `x`. + * @param {number} [x=0] - position of the point on the x axis + * @param {number} [y=x] - position of the point on the y axis + * @returns The observable point instance itself + */ + set(x = 0, y = x) { + if (this._x !== x || this._y !== y) { + this._x = x; + this._y = y; + this._observer._onUpdate(this); + } + return this; + } + /** + * Copies x and y from the given point (`p`) + * @param p - The point to copy from. Can be any of type that is or extends `PointData` + * @returns The observable point instance itself + */ + copyFrom(p) { + if (this._x !== p.x || this._y !== p.y) { + this._x = p.x; + this._y = p.y; + this._observer._onUpdate(this); + } + return this; + } + /** + * Copies this point's x and y into that of the given point (`p`) + * @param p - The point to copy to. Can be any of type that is or extends `PointData` + * @returns The point (`p`) with values updated + */ + copyTo(p) { + p.set(this._x, this._y); + return p; + } + /** + * Accepts another point (`p`) and returns `true` if the given point is equal to this point + * @param p - The point to check + * @returns Returns `true` if both `x` and `y` are equal + */ + equals(p) { + return p.x === this._x && p.y === this._y; + } + toString() { + return `[pixi.js/math:ObservablePoint x=${0} y=${0} scope=${this._observer}]`; + } + /** Position of the observable point on the x axis. */ + get x() { + return this._x; + } + set x(value) { + if (this._x !== value) { + this._x = value; + this._observer._onUpdate(this); + } + } + /** Position of the observable point on the y axis. */ + get y() { + return this._y; + } + set y(value) { + if (this._y !== value) { + this._y = value; + this._observer._onUpdate(this); + } + } +} + +"use strict"; +const uidCache = { + default: -1 +}; +function uid(name = "default") { + if (uidCache[name] === void 0) { + uidCache[name] = -1; + } + return ++uidCache[name]; +} +function resetUids() { + for (const key in uidCache) { + delete uidCache[key]; + } +} + +"use strict"; +const warnings = {}; +const v8_0_0 = "8.0.0"; +function deprecation(version, message, ignoreDepth = 3) { + if (warnings[message]) { + return; + } + let stack = new Error().stack; + if (typeof stack === "undefined") { + console.warn("PixiJS Deprecation Warning: ", `${message} +Deprecated since v${version}`); + } else { + stack = stack.split("\n").splice(ignoreDepth).join("\n"); + if (console.groupCollapsed) { + console.groupCollapsed( + "%cPixiJS Deprecation Warning: %c%s", + "color:#614108;background:#fffbe6", + "font-weight:normal;color:#614108;background:#fffbe6", + `${message} +Deprecated since v${version}` + ); + console.warn(stack); + console.groupEnd(); + } else { + console.warn("PixiJS Deprecation Warning: ", `${message} +Deprecated since v${version}`); + console.warn(stack); + } + } + warnings[message] = true; +} + +"use strict"; +function removeItems(arr, startIdx, removeCount) { + const length = arr.length; + let i; + if (startIdx >= length || removeCount === 0) { + return; + } + removeCount = startIdx + removeCount > length ? length - startIdx : removeCount; + const len = length - removeCount; + for (i = startIdx; i < len; ++i) { + arr[i] = arr[i + removeCount]; + } + arr.length = len; +} + +"use strict"; +const childrenHelperMixin = { + allowChildren: true, + /** + * Removes all children from this container that are within the begin and end indexes. + * @param beginIndex - The beginning position. + * @param endIndex - The ending position. Default value is size of the container. + * @returns - List of removed children + * @memberof scene.Container# + */ + removeChildren(beginIndex = 0, endIndex) { + const end = endIndex != null ? endIndex : this.children.length; + const range = end - beginIndex; + const removed = []; + if (range > 0 && range <= end) { + for (let i = end - 1; i >= beginIndex; i--) { + const child = this.children[i]; + if (!child) + continue; + if (this.renderGroup) { + this.renderGroup.removeChild(child); + } + removed.push(child); + child.parent = null; + } + removeItems(this.children, beginIndex, end); + for (let i = 0; i < removed.length; ++i) { + this.emit("childRemoved", removed[i], this, i); + removed[i].emit("removed", this); + } + return removed; + } else if (range === 0 && this.children.length === 0) { + return removed; + } + throw new RangeError("removeChildren: numeric values are outside the acceptable range."); + }, + /** + * Removes a child from the specified index position. + * @param index - The index to get the child from + * @returns The child that was removed. + * @memberof scene.Container# + */ + removeChildAt(index) { + const child = this.getChildAt(index); + return this.removeChild(child); + }, + /** + * Returns the child at the specified index + * @param index - The index to get the child at + * @returns - The child at the given index, if any. + * @memberof scene.Container# + */ + getChildAt(index) { + if (index < 0 || index >= this.children.length) { + throw new Error(`getChildAt: Index (${index}) does not exist.`); + } + return this.children[index]; + }, + /** + * Changes the position of an existing child in the container container + * @param child - The child Container instance for which you want to change the index number + * @param index - The resulting index number for the child container + * @memberof scene.Container# + */ + setChildIndex(child, index) { + if (index < 0 || index >= this.children.length) { + throw new Error(`The index ${index} supplied is out of bounds ${this.children.length}`); + } + this.getChildIndex(child); + this.addChildAt(child, index); + }, + /** + * Returns the index position of a child Container instance + * @param child - The Container instance to identify + * @returns - The index position of the child container to identify + * @memberof scene.Container# + */ + getChildIndex(child) { + const index = this.children.indexOf(child); + if (index === -1) { + throw new Error("The supplied Container must be a child of the caller"); + } + return index; + }, + /** + * Adds a child to the container at a specified index. If the index is out of bounds an error will be thrown. + * If the child is already in this container, it will be moved to the specified index. + * @param {Container} child - The child to add. + * @param {number} index - The absolute index where the child will be positioned at the end of the operation. + * @returns {Container} The child that was added. + * @memberof scene.Container# + */ + addChildAt(child, index) { + if (!this.allowChildren) { + deprecation(v8_0_0, "addChildAt: Only Containers will be allowed to add children in v8.0.0"); + } + const { children } = this; + if (index < 0 || index > children.length) { + throw new Error(`${child}addChildAt: The index ${index} supplied is out of bounds ${children.length}`); + } + if (child.parent) { + const currentIndex = child.parent.children.indexOf(child); + if (child.parent === this && currentIndex === index) { + return child; + } + if (currentIndex !== -1) { + child.parent.children.splice(currentIndex, 1); + } + } + if (index === children.length) { + children.push(child); + } else { + children.splice(index, 0, child); + } + child.parent = this; + child.didChange = true; + child.didViewUpdate = false; + child._updateFlags = 15; + if (this.renderGroup) { + this.renderGroup.addChild(child); + } + if (this.sortableChildren) + this.sortDirty = true; + this.emit("childAdded", child, this, index); + child.emit("added", this); + return child; + }, + /** + * Swaps the position of 2 Containers within this container. + * @param child - First container to swap + * @param child2 - Second container to swap + */ + swapChildren(child, child2) { + if (child === child2) { + return; + } + const index1 = this.getChildIndex(child); + const index2 = this.getChildIndex(child2); + this.children[index1] = child2; + this.children[index2] = child; + }, + /** + * Remove the Container from its parent Container. If the Container has no parent, do nothing. + * @memberof scene.Container# + */ + removeFromParent() { + var _a; + (_a = this.parent) == null ? void 0 : _a.removeChild(this); + } +}; + +"use strict"; +class FilterEffect { + constructor(options) { + this.pipe = "filter"; + this.priority = 1; + this.filters = options == null ? void 0 : options.filters; + this.filterArea = options == null ? void 0 : options.filterArea; + } + destroy() { + for (let i = 0; i < this.filters.length; i++) { + this.filters[i].destroy(); + } + this.filters = null; + this.filterArea = null; + } +} + +"use strict"; +class Pool { + /** + * Constructs a new Pool. + * @param ClassType - The constructor of the items in the pool. + * @param {number} [initialSize] - The initial size of the pool. + */ + constructor(ClassType, initialSize) { + this._pool = []; + this._count = 0; + this._index = 0; + this._classType = ClassType; + if (initialSize) { + this.prepopulate(initialSize); + } + } + /** + * Prepopulates the pool with a given number of items. + * @param total - The number of items to add to the pool. + */ + prepopulate(total) { + for (let i = 0; i < total; i++) { + this._pool[this._index++] = new this._classType(); + } + this._count += total; + } + /** + * Gets an item from the pool. Calls the item's `init` method if it exists. + * If there are no items left in the pool, a new one will be created. + * @param {unknown} [data] - Optional data to pass to the item's constructor. + * @returns {T} The item from the pool. + */ + get(data) { + var _a; + let item; + if (this._index > 0) { + item = this._pool[--this._index]; + } else { + item = new this._classType(); + } + (_a = item.init) == null ? void 0 : _a.call(item, data); + return item; + } + /** + * Returns an item to the pool. Calls the item's `reset` method if it exists. + * @param {T} item - The item to return to the pool. + */ + return(item) { + var _a; + (_a = item.reset) == null ? void 0 : _a.call(item); + this._pool[this._index++] = item; + } + /** + * Gets the number of items in the pool. + * @readonly + * @member {number} + */ + get totalSize() { + return this._count; + } + /** + * Gets the number of items in the pool that are free to use without needing to create more. + * @readonly + * @member {number} + */ + get totalFree() { + return this._index; + } + /** + * Gets the number of items in the pool that are currently in use. + * @readonly + * @member {number} + */ + get totalUsed() { + return this._count - this._index; + } +} + +"use strict"; +class PoolGroupClass { + constructor() { + /** + * A map to store the pools by their class type. + * @private + */ + this._poolsByClass = /* @__PURE__ */ new Map(); + } + /** + * Prepopulates a specific pool with a given number of items. + * @template T The type of items in the pool. Must extend PoolItem. + * @param {PoolItemConstructor} Class - The constructor of the items in the pool. + * @param {number} total - The number of items to add to the pool. + */ + prepopulate(Class, total) { + const classPool = this.getPool(Class); + classPool.prepopulate(total); + } + /** + * Gets an item from a specific pool. + * @template T The type of items in the pool. Must extend PoolItem. + * @param {PoolItemConstructor} Class - The constructor of the items in the pool. + * @param {unknown} [data] - Optional data to pass to the item's constructor. + * @returns {T} The item from the pool. + */ + get(Class, data) { + const pool = this.getPool(Class); + return pool.get(data); + } + /** + * Returns an item to its respective pool. + * @param {PoolItem} item - The item to return to the pool. + */ + return(item) { + const pool = this.getPool(item.constructor); + pool.return(item); + } + /** + * Gets a specific pool based on the class type. + * @template T The type of items in the pool. Must extend PoolItem. + * @param {PoolItemConstructor} ClassType - The constructor of the items in the pool. + * @returns {Pool} The pool of the given class type. + */ + getPool(ClassType) { + if (!this._poolsByClass.has(ClassType)) { + this._poolsByClass.set(ClassType, new Pool(ClassType)); + } + return this._poolsByClass.get(ClassType); + } + /** gets the usage stats of each pool in the system */ + stats() { + const stats = {}; + this._poolsByClass.forEach((pool) => { + const name = stats[pool._classType.name] ? pool._classType.name + pool._classType.ID : pool._classType.name; + stats[name] = { + free: pool.totalFree, + used: pool.totalUsed, + size: pool.totalSize + }; + }); + return stats; + } +} +const BigPool = new PoolGroupClass(); + +"use strict"; +class MaskEffectManagerClass { + constructor() { + /** + * @private + */ + this._effectClasses = []; + this._tests = []; + this._initialized = false; + } + init() { + if (this._initialized) + return; + this._initialized = true; + this._effectClasses.forEach((test) => { + this.add({ + test: test.test, + maskClass: test + }); + }); + } + add(test) { + this._tests.push(test); + } + getMaskEffect(item) { + if (!this._initialized) + this.init(); + for (let i = 0; i < this._tests.length; i++) { + const test = this._tests[i]; + if (test.test(item)) { + return BigPool.get(test.maskClass, item); + } + } + return item; + } + returnMaskEffect(effect) { + BigPool.return(effect); + } +} +const MaskEffectManager = new MaskEffectManagerClass(); +extensions.handleByList(ExtensionType.MaskEffect, MaskEffectManager._effectClasses); + +"use strict"; +const effectsMixin = { + _mask: null, + _filters: null, + /** + * @todo Needs docs. + * @memberof scene.Container# + * @type {Array} + */ + effects: [], + /** + * @todo Needs docs. + * @param effect - The effect to add. + * @memberof scene.Container# + * @ignore + */ + addEffect(effect) { + const index = this.effects.indexOf(effect); + if (index !== -1) + return; + this.effects.push(effect); + this.effects.sort((a, b) => a.priority - b.priority); + if (this.renderGroup) { + this.renderGroup.structureDidChange = true; + } + this._updateIsSimple(); + }, + /** + * @todo Needs docs. + * @param effect - The effect to remove. + * @memberof scene.Container# + * @ignore + */ + removeEffect(effect) { + const index = this.effects.indexOf(effect); + if (index === -1) + return; + this.effects.splice(index, 1); + if (!this.isRenderGroupRoot && this.renderGroup) { + this.renderGroup.structureDidChange = true; + } + this._updateIsSimple(); + }, + set mask(value) { + this._mask || (this._mask = { mask: null, effect: null }); + if (this._mask.mask === value) + return; + if (this._mask.effect) { + this.removeEffect(this._mask.effect); + MaskEffectManager.returnMaskEffect(this._mask.effect); + this._mask.effect = null; + } + this._mask.mask = value; + if (value === null || value === void 0) + return; + const effect = MaskEffectManager.getMaskEffect(value); + this._mask.effect = effect; + this.addEffect(effect); + }, + /** + * Sets a mask for the displayObject. A mask is an object that limits the visibility of an + * object to the shape of the mask applied to it. In PixiJS a regular mask must be a + * {@link Graphics} or a {@link Sprite} object. This allows for much faster masking in canvas as it + * utilities shape clipping. Furthermore, a mask of an object must be in the subtree of its parent. + * Otherwise, `getLocalBounds` may calculate incorrect bounds, which makes the container's width and height wrong. + * To remove a mask, set this property to `null`. + * + * For sprite mask both alpha and red channel are used. Black mask is the same as transparent mask. + * @example + * import { Graphics, Sprite } from 'pixi.js'; + * + * const graphics = new Graphics(); + * graphics.beginFill(0xFF3300); + * graphics.drawRect(50, 250, 100, 100); + * graphics.endFill(); + * + * const sprite = new Sprite(texture); + * sprite.mask = graphics; + * @memberof scene.Container# + */ + get mask() { + var _a; + return (_a = this._mask) == null ? void 0 : _a.mask; + }, + set filters(value) { + if (!Array.isArray(value) && value) + value = [value]; + value = value; + this._filters || (this._filters = { filters: null, effect: null, filterArea: null }); + const hasFilters = (value == null ? void 0 : value.length) > 0; + const didChange = this._filters.effect && !hasFilters || !this._filters.effect && hasFilters; + value = Array.isArray(value) ? value.slice(0) : value; + this._filters.filters = Object.freeze(value); + if (didChange) { + if (hasFilters) { + const effect = BigPool.get(FilterEffect); + this._filters.effect = effect; + this.addEffect(effect); + } else { + const effect = this._filters.effect; + this.removeEffect(effect); + effect.filterArea = null; + effect.filters = null; + this._filters.effect = null; + BigPool.return(effect); + } + } + if (hasFilters) { + this._filters.effect.filters = value; + this._filters.effect.filterArea = this.filterArea; + } + }, + /** + * Sets the filters for the displayObject. + * IMPORTANT: This is a WebGL only feature and will be ignored by the canvas renderer. + * To remove filters simply set this property to `'null'`. + * @memberof scene.Container# + */ + get filters() { + var _a; + return (_a = this._filters) == null ? void 0 : _a.filters; + }, + set filterArea(value) { + this._filters || (this._filters = { filters: null, effect: null, filterArea: null }); + this._filters.filterArea = value; + }, + /** + * The area the filter is applied to. This is used as more of an optimization + * rather than figuring out the dimensions of the displayObject each frame you can set this rectangle. + * + * Also works as an interaction mask. + * @memberof scene.Container# + */ + get filterArea() { + var _a; + return (_a = this._filters) == null ? void 0 : _a.filterArea; + } +}; + +"use strict"; +const findMixin = { + /** + * The instance label of the object. + * @memberof scene.Container# + * @member {string} label + */ + label: null, + /** + * The instance name of the object. + * @deprecated since 8.0.0 + * @see scene.Container#label + * @member {string} name + * @memberof scene.Container# + */ + get name() { + deprecation(v8_0_0, "Container.name property has been removed, use Container.label instead"); + return this.label; + }, + set name(value) { + deprecation(v8_0_0, "Container.name property has been removed, use Container.label instead"); + this.label = value; + }, + /** + * @method getChildByName + * @deprecated since 8.0.0 + * @param {string} name - Instance name. + * @param {boolean}[deep=false] - Whether to search recursively + * @returns {Container} The child with the specified name. + * @see scene.Container#getChildByLabel + * @memberof scene.Container# + */ + getChildByName(name, deep = false) { + return this.getChildByLabel(name, deep); + }, + /** + * Returns the first child in the container with the specified label. + * + * Recursive searches are done in a pre-order traversal. + * @memberof scene.Container# + * @param {string|RegExp} label - Instance label. + * @param {boolean}[deep=false] - Whether to search recursively + * @returns {Container} The child with the specified label. + */ + getChildByLabel(label, deep = false) { + const children = this.children; + for (let i = 0; i < children.length; i++) { + const child = children[i]; + if (child.label === label || label instanceof RegExp && label.test(child.label)) + return child; + } + if (deep) { + for (let i = 0; i < children.length; i++) { + const child = children[i]; + const found = child.getChildByLabel(label, true); + if (found) { + return found; + } + } + } + return null; + }, + /** + * Returns all children in the container with the specified label. + * @memberof scene.Container# + * @param {string|RegExp} label - Instance label. + * @param {boolean}[deep=false] - Whether to search recursively + * @param {Container[]} [out=[]] - The array to store matching children in. + * @returns {Container[]} An array of children with the specified label. + */ + getChildrenByLabel(label, deep = false, out = []) { + const children = this.children; + for (let i = 0; i < children.length; i++) { + const child = children[i]; + if (child.label === label || label instanceof RegExp && label.test(child.label)) { + out.push(child); + } + } + if (deep) { + for (let i = 0; i < children.length; i++) { + children[i].getChildrenByLabel(label, true, out); + } + } + return out; + } +}; + +"use strict"; +const tempPoints = [new Point(), new Point(), new Point(), new Point()]; +class Rectangle { + /** + * @param x - The X coordinate of the upper-left corner of the rectangle + * @param y - The Y coordinate of the upper-left corner of the rectangle + * @param width - The overall width of the rectangle + * @param height - The overall height of the rectangle + */ + constructor(x = 0, y = 0, width = 0, height = 0) { + /** + * The type of the object, mainly used to avoid `instanceof` checks + * @default 'rectangle' + */ + this.type = "rectangle"; + this.x = Number(x); + this.y = Number(y); + this.width = Number(width); + this.height = Number(height); + } + /** Returns the left edge of the rectangle. */ + get left() { + return this.x; + } + /** Returns the right edge of the rectangle. */ + get right() { + return this.x + this.width; + } + /** Returns the top edge of the rectangle. */ + get top() { + return this.y; + } + /** Returns the bottom edge of the rectangle. */ + get bottom() { + return this.y + this.height; + } + /** Determines whether the Rectangle is empty. */ + isEmpty() { + return this.left === this.right || this.top === this.bottom; + } + /** A constant empty rectangle. This is a new object every time the property is accessed */ + static get EMPTY() { + return new Rectangle(0, 0, 0, 0); + } + /** + * Creates a clone of this Rectangle + * @returns a copy of the rectangle + */ + clone() { + return new Rectangle(this.x, this.y, this.width, this.height); + } + /** + * Converts a Bounds object to a Rectangle object. + * @param bounds - The bounds to copy and convert to a rectangle. + * @returns Returns itself. + */ + copyFromBounds(bounds) { + this.x = bounds.minX; + this.y = bounds.minY; + this.width = bounds.maxX - bounds.minX; + this.height = bounds.maxY - bounds.minY; + return this; + } + /** + * Copies another rectangle to this one. + * @param rectangle - The rectangle to copy from. + * @returns Returns itself. + */ + copyFrom(rectangle) { + this.x = rectangle.x; + this.y = rectangle.y; + this.width = rectangle.width; + this.height = rectangle.height; + return this; + } + /** + * Copies this rectangle to another one. + * @param rectangle - The rectangle to copy to. + * @returns Returns given parameter. + */ + copyTo(rectangle) { + rectangle.copyFrom(this); + return rectangle; + } + /** + * Checks whether the x and y coordinates given are contained within this Rectangle + * @param x - The X coordinate of the point to test + * @param y - The Y coordinate of the point to test + * @returns Whether the x/y coordinates are within this Rectangle + */ + contains(x, y) { + if (this.width <= 0 || this.height <= 0) { + return false; + } + if (x >= this.x && x < this.x + this.width) { + if (y >= this.y && y < this.y + this.height) { + return true; + } + } + return false; + } + /** + * Checks whether the x and y coordinates given are contained within this rectangle including the stroke. + * @param x - The X coordinate of the point to test + * @param y - The Y coordinate of the point to test + * @param strokeWidth - The width of the line to check + * @returns Whether the x/y coordinates are within this rectangle + */ + strokeContains(x, y, strokeWidth) { + const { width, height } = this; + if (width <= 0 || height <= 0) + return false; + const _x = this.x; + const _y = this.y; + const outerLeft = _x - strokeWidth / 2; + const outerRight = _x + width + strokeWidth / 2; + const outerTop = _y - strokeWidth / 2; + const outerBottom = _y + height + strokeWidth / 2; + const innerLeft = _x + strokeWidth / 2; + const innerRight = _x + width - strokeWidth / 2; + const innerTop = _y + strokeWidth / 2; + const innerBottom = _y + height - strokeWidth / 2; + return x >= outerLeft && x <= outerRight && y >= outerTop && y <= outerBottom && !(x > innerLeft && x < innerRight && y > innerTop && y < innerBottom); + } + /** + * Determines whether the `other` Rectangle transformed by `transform` intersects with `this` Rectangle object. + * Returns true only if the area of the intersection is >0, this means that Rectangles + * sharing a side are not overlapping. Another side effect is that an arealess rectangle + * (width or height equal to zero) can't intersect any other rectangle. + * @param {Rectangle} other - The Rectangle to intersect with `this`. + * @param {Matrix} transform - The transformation matrix of `other`. + * @returns {boolean} A value of `true` if the transformed `other` Rectangle intersects with `this`; otherwise `false`. + */ + intersects(other, transform) { + if (!transform) { + const x02 = this.x < other.x ? other.x : this.x; + const x12 = this.right > other.right ? other.right : this.right; + if (x12 <= x02) { + return false; + } + const y02 = this.y < other.y ? other.y : this.y; + const y12 = this.bottom > other.bottom ? other.bottom : this.bottom; + return y12 > y02; + } + const x0 = this.left; + const x1 = this.right; + const y0 = this.top; + const y1 = this.bottom; + if (x1 <= x0 || y1 <= y0) { + return false; + } + const lt = tempPoints[0].set(other.left, other.top); + const lb = tempPoints[1].set(other.left, other.bottom); + const rt = tempPoints[2].set(other.right, other.top); + const rb = tempPoints[3].set(other.right, other.bottom); + if (rt.x <= lt.x || lb.y <= lt.y) { + return false; + } + const s = Math.sign(transform.a * transform.d - transform.b * transform.c); + if (s === 0) { + return false; + } + transform.apply(lt, lt); + transform.apply(lb, lb); + transform.apply(rt, rt); + transform.apply(rb, rb); + if (Math.max(lt.x, lb.x, rt.x, rb.x) <= x0 || Math.min(lt.x, lb.x, rt.x, rb.x) >= x1 || Math.max(lt.y, lb.y, rt.y, rb.y) <= y0 || Math.min(lt.y, lb.y, rt.y, rb.y) >= y1) { + return false; + } + const nx = s * (lb.y - lt.y); + const ny = s * (lt.x - lb.x); + const n00 = nx * x0 + ny * y0; + const n10 = nx * x1 + ny * y0; + const n01 = nx * x0 + ny * y1; + const n11 = nx * x1 + ny * y1; + if (Math.max(n00, n10, n01, n11) <= nx * lt.x + ny * lt.y || Math.min(n00, n10, n01, n11) >= nx * rb.x + ny * rb.y) { + return false; + } + const mx = s * (lt.y - rt.y); + const my = s * (rt.x - lt.x); + const m00 = mx * x0 + my * y0; + const m10 = mx * x1 + my * y0; + const m01 = mx * x0 + my * y1; + const m11 = mx * x1 + my * y1; + if (Math.max(m00, m10, m01, m11) <= mx * lt.x + my * lt.y || Math.min(m00, m10, m01, m11) >= mx * rb.x + my * rb.y) { + return false; + } + return true; + } + /** + * Pads the rectangle making it grow in all directions. + * If paddingY is omitted, both paddingX and paddingY will be set to paddingX. + * @param paddingX - The horizontal padding amount. + * @param paddingY - The vertical padding amount. + * @returns Returns itself. + */ + pad(paddingX = 0, paddingY = paddingX) { + this.x -= paddingX; + this.y -= paddingY; + this.width += paddingX * 2; + this.height += paddingY * 2; + return this; + } + /** + * Fits this rectangle around the passed one. + * @param rectangle - The rectangle to fit. + * @returns Returns itself. + */ + fit(rectangle) { + const x1 = Math.max(this.x, rectangle.x); + const x2 = Math.min(this.x + this.width, rectangle.x + rectangle.width); + const y1 = Math.max(this.y, rectangle.y); + const y2 = Math.min(this.y + this.height, rectangle.y + rectangle.height); + this.x = x1; + this.width = Math.max(x2 - x1, 0); + this.y = y1; + this.height = Math.max(y2 - y1, 0); + return this; + } + /** + * Enlarges rectangle that way its corners lie on grid + * @param resolution - resolution + * @param eps - precision + * @returns Returns itself. + */ + ceil(resolution = 1, eps = 1e-3) { + const x2 = Math.ceil((this.x + this.width - eps) * resolution) / resolution; + const y2 = Math.ceil((this.y + this.height - eps) * resolution) / resolution; + this.x = Math.floor((this.x + eps) * resolution) / resolution; + this.y = Math.floor((this.y + eps) * resolution) / resolution; + this.width = x2 - this.x; + this.height = y2 - this.y; + return this; + } + /** + * Enlarges this rectangle to include the passed rectangle. + * @param rectangle - The rectangle to include. + * @returns Returns itself. + */ + enlarge(rectangle) { + const x1 = Math.min(this.x, rectangle.x); + const x2 = Math.max(this.x + this.width, rectangle.x + rectangle.width); + const y1 = Math.min(this.y, rectangle.y); + const y2 = Math.max(this.y + this.height, rectangle.y + rectangle.height); + this.x = x1; + this.width = x2 - x1; + this.y = y1; + this.height = y2 - y1; + return this; + } + /** + * Returns the framing rectangle of the rectangle as a Rectangle object + * @param out - optional rectangle to store the result + * @returns The framing rectangle + */ + getBounds(out) { + out = out || new Rectangle(); + out.copyFrom(this); + return out; + } + toString() { + return `[pixi.js/math:Rectangle x=${this.x} y=${this.y} width=${this.width} height=${this.height}]`; + } +} + +"use strict"; +const defaultMatrix = new Matrix(); +class Bounds { + constructor(minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity) { + /** @default Infinity */ + this.minX = Infinity; + /** @default Infinity */ + this.minY = Infinity; + /** @default -Infinity */ + this.maxX = -Infinity; + /** @default -Infinity */ + this.maxY = -Infinity; + this.matrix = defaultMatrix; + this.minX = minX; + this.minY = minY; + this.maxX = maxX; + this.maxY = maxY; + } + /** + * Checks if bounds are empty. + * @returns - True if empty. + */ + isEmpty() { + return this.minX > this.maxX || this.minY > this.maxY; + } + /** The bounding rectangle of the bounds. */ + get rectangle() { + if (!this._rectangle) { + this._rectangle = new Rectangle(); + } + const rectangle = this._rectangle; + if (this.minX > this.maxX || this.minY > this.maxY) { + rectangle.x = 0; + rectangle.y = 0; + rectangle.width = 0; + rectangle.height = 0; + } else { + rectangle.copyFromBounds(this); + } + return rectangle; + } + /** Clears the bounds and resets. */ + clear() { + this.minX = Infinity; + this.minY = Infinity; + this.maxX = -Infinity; + this.maxY = -Infinity; + this.matrix = defaultMatrix; + return this; + } + /** + * Sets the bounds. + * @param x0 - left X of frame + * @param y0 - top Y of frame + * @param x1 - right X of frame + * @param y1 - bottom Y of frame + */ + set(x0, y0, x1, y1) { + this.minX = x0; + this.minY = y0; + this.maxX = x1; + this.maxY = y1; + } + /** + * Adds sprite frame + * @param x0 - left X of frame + * @param y0 - top Y of frame + * @param x1 - right X of frame + * @param y1 - bottom Y of frame + * @param matrix + */ + addFrame(x0, y0, x1, y1, matrix) { + matrix || (matrix = this.matrix); + const a = matrix.a; + const b = matrix.b; + const c = matrix.c; + const d = matrix.d; + const tx = matrix.tx; + const ty = matrix.ty; + let minX = this.minX; + let minY = this.minY; + let maxX = this.maxX; + let maxY = this.maxY; + let x = a * x0 + c * y0 + tx; + let y = b * x0 + d * y0 + ty; + if (x < minX) + minX = x; + if (y < minY) + minY = y; + if (x > maxX) + maxX = x; + if (y > maxY) + maxY = y; + x = a * x1 + c * y0 + tx; + y = b * x1 + d * y0 + ty; + if (x < minX) + minX = x; + if (y < minY) + minY = y; + if (x > maxX) + maxX = x; + if (y > maxY) + maxY = y; + x = a * x0 + c * y1 + tx; + y = b * x0 + d * y1 + ty; + if (x < minX) + minX = x; + if (y < minY) + minY = y; + if (x > maxX) + maxX = x; + if (y > maxY) + maxY = y; + x = a * x1 + c * y1 + tx; + y = b * x1 + d * y1 + ty; + if (x < minX) + minX = x; + if (y < minY) + minY = y; + if (x > maxX) + maxX = x; + if (y > maxY) + maxY = y; + this.minX = minX; + this.minY = minY; + this.maxX = maxX; + this.maxY = maxY; + } + /** + * Adds a rectangle to the bounds. + * @param rect - The rectangle to be added. + * @param matrix - The matrix to apply to the bounds. + */ + addRect(rect, matrix) { + this.addFrame(rect.x, rect.y, rect.x + rect.width, rect.y + rect.height, matrix); + } + /** + * Adds other {@link Bounds}. + * @param bounds - The Bounds to be added + * @param matrix + */ + addBounds(bounds, matrix) { + this.addFrame(bounds.minX, bounds.minY, bounds.maxX, bounds.maxY, matrix); + } + /** + * Adds other Bounds, masked with Bounds. + * @param mask - The Bounds to be added. + */ + addBoundsMask(mask) { + this.minX = this.minX > mask.minX ? this.minX : mask.minX; + this.minY = this.minY > mask.minY ? this.minY : mask.minY; + this.maxX = this.maxX < mask.maxX ? this.maxX : mask.maxX; + this.maxY = this.maxY < mask.maxY ? this.maxY : mask.maxY; + } + /** + * Adds other Bounds, multiplied with matrix. + * @param matrix - The matrix to apply to the bounds. + */ + applyMatrix(matrix) { + const minX = this.minX; + const minY = this.minY; + const maxX = this.maxX; + const maxY = this.maxY; + const { a, b, c, d, tx, ty } = matrix; + let x = a * minX + c * minY + tx; + let y = b * minX + d * minY + ty; + this.minX = x; + this.minY = y; + this.maxX = x; + this.maxY = y; + x = a * maxX + c * minY + tx; + y = b * maxX + d * minY + ty; + this.minX = x < this.minX ? x : this.minX; + this.minY = y < this.minY ? y : this.minY; + this.maxX = x > this.maxX ? x : this.maxX; + this.maxY = y > this.maxY ? y : this.maxY; + x = a * minX + c * maxY + tx; + y = b * minX + d * maxY + ty; + this.minX = x < this.minX ? x : this.minX; + this.minY = y < this.minY ? y : this.minY; + this.maxX = x > this.maxX ? x : this.maxX; + this.maxY = y > this.maxY ? y : this.maxY; + x = a * maxX + c * maxY + tx; + y = b * maxX + d * maxY + ty; + this.minX = x < this.minX ? x : this.minX; + this.minY = y < this.minY ? y : this.minY; + this.maxX = x > this.maxX ? x : this.maxX; + this.maxY = y > this.maxY ? y : this.maxY; + } + /** + * Resizes the bounds object to include the given rectangle. + * @param rect - The rectangle to be included. + */ + fit(rect) { + if (this.minX < rect.left) + this.minX = rect.left; + if (this.maxX > rect.right) + this.maxX = rect.right; + if (this.minY < rect.top) + this.minY = rect.top; + if (this.maxY > rect.bottom) + this.maxY = rect.bottom; + return this; + } + /** + * Resizes the bounds object to include the given bounds. + * @param left - The left value of the bounds. + * @param right - The right value of the bounds. + * @param top - The top value of the bounds. + * @param bottom - The bottom value of the bounds. + */ + fitBounds(left, right, top, bottom) { + if (this.minX < left) + this.minX = left; + if (this.maxX > right) + this.maxX = right; + if (this.minY < top) + this.minY = top; + if (this.maxY > bottom) + this.maxY = bottom; + return this; + } + /** + * Pads bounds object, making it grow in all directions. + * If paddingY is omitted, both paddingX and paddingY will be set to paddingX. + * @param paddingX - The horizontal padding amount. + * @param paddingY - The vertical padding amount. + */ + pad(paddingX, paddingY = paddingX) { + this.minX -= paddingX; + this.maxX += paddingX; + this.minY -= paddingY; + this.maxY += paddingY; + return this; + } + /** Ceils the bounds. */ + ceil() { + this.minX = Math.floor(this.minX); + this.minY = Math.floor(this.minY); + this.maxX = Math.ceil(this.maxX); + this.maxY = Math.ceil(this.maxY); + return this; + } + /** Clones the bounds. */ + clone() { + return new Bounds(this.minX, this.minY, this.maxX, this.maxY); + } + /** + * Scales the bounds by the given values + * @param x - The X value to scale by. + * @param y - The Y value to scale by. + */ + scale(x, y = x) { + this.minX *= x; + this.minY *= y; + this.maxX *= x; + this.maxY *= y; + return this; + } + /** the x value of the bounds. */ + get x() { + return this.minX; + } + set x(value) { + const width = this.maxX - this.minX; + this.minX = value; + this.maxX = value + width; + } + /** the y value of the bounds. */ + get y() { + return this.minY; + } + set y(value) { + const height = this.maxY - this.minY; + this.minY = value; + this.maxY = value + height; + } + /** the width value of the bounds. */ + get width() { + return this.maxX - this.minX; + } + set width(value) { + this.maxX = this.minX + value; + } + /** the height value of the bounds. */ + get height() { + return this.maxY - this.minY; + } + set height(value) { + this.maxY = this.minY + value; + } + /** the left value of the bounds. */ + get left() { + return this.minX; + } + /** the right value of the bounds. */ + get right() { + return this.maxX; + } + /** the top value of the bounds. */ + get top() { + return this.minY; + } + /** the bottom value of the bounds. */ + get bottom() { + return this.maxY; + } + /** Is the bounds positive. */ + get isPositive() { + return this.maxX - this.minX > 0 && this.maxY - this.minY > 0; + } + get isValid() { + return this.minX + this.minY !== Infinity; + } + /** + * Adds screen vertices from array + * @param vertexData - calculated vertices + * @param beginOffset - begin offset + * @param endOffset - end offset, excluded + * @param matrix + */ + addVertexData(vertexData, beginOffset, endOffset, matrix) { + let minX = this.minX; + let minY = this.minY; + let maxX = this.maxX; + let maxY = this.maxY; + matrix || (matrix = this.matrix); + const a = matrix.a; + const b = matrix.b; + const c = matrix.c; + const d = matrix.d; + const tx = matrix.tx; + const ty = matrix.ty; + for (let i = beginOffset; i < endOffset; i += 2) { + const localX = vertexData[i]; + const localY = vertexData[i + 1]; + const x = a * localX + c * localY + tx; + const y = b * localX + d * localY + ty; + minX = x < minX ? x : minX; + minY = y < minY ? y : minY; + maxX = x > maxX ? x : maxX; + maxY = y > maxY ? y : maxY; + } + this.minX = minX; + this.minY = minY; + this.maxX = maxX; + this.maxY = maxY; + } + /** + * Checks if the point is contained within the bounds. + * @param x - x coordinate + * @param y - y coordinate + */ + containsPoint(x, y) { + if (this.minX <= x && this.minY <= y && this.maxX >= x && this.maxY >= y) { + return true; + } + return false; + } + toString() { + return `[pixi.js:Bounds minX=${this.minX} minY=${this.minY} maxX=${this.maxX} maxY=${this.maxY} width=${this.width} height=${this.height}]`; + } +} + +"use strict"; +const matrixPool = new Pool(Matrix); +const boundsPool = new Pool(Bounds); + +"use strict"; +function getGlobalBounds(target, skipUpdateTransform, bounds) { + bounds.clear(); + let parentTransform; + let pooledMatrix; + if (target.parent) { + if (!skipUpdateTransform) { + pooledMatrix = matrixPool.get().identity(); + parentTransform = updateTransformBackwards(target, pooledMatrix); + } else { + parentTransform = target.parent.worldTransform; + } + } else { + parentTransform = Matrix.IDENTITY; + } + _getGlobalBounds(target, bounds, parentTransform, skipUpdateTransform); + if (pooledMatrix) { + matrixPool.return(pooledMatrix); + } + if (!bounds.isValid) { + bounds.set(0, 0, 0, 0); + } + return bounds; +} +function _getGlobalBounds(target, bounds, parentTransform, skipUpdateTransform) { + var _a, _b; + if (!target.visible || !target.measurable) + return; + let worldTransform; + if (!skipUpdateTransform) { + target.updateLocalTransform(); + worldTransform = matrixPool.get(); + worldTransform.appendFrom(target.localTransform, parentTransform); + } else { + worldTransform = target.worldTransform; + } + const parentBounds = bounds; + const preserveBounds = !!target.effects.length; + if (preserveBounds) { + bounds = boundsPool.get().clear(); + } + if (target.boundsArea) { + bounds.addRect(target.boundsArea, worldTransform); + } else { + if (target.addBounds) { + bounds.matrix = worldTransform; + target.addBounds(bounds); + } + for (let i = 0; i < target.children.length; i++) { + _getGlobalBounds(target.children[i], bounds, worldTransform, skipUpdateTransform); + } + } + if (preserveBounds) { + for (let i = 0; i < target.effects.length; i++) { + (_b = (_a = target.effects[i]).addBounds) == null ? void 0 : _b.call(_a, bounds); + } + parentBounds.addBounds(bounds, Matrix.IDENTITY); + boundsPool.return(bounds); + } + if (!skipUpdateTransform) { + matrixPool.return(worldTransform); + } +} +function updateTransformBackwards(target, parentTransform) { + const parent = target.parent; + if (parent) { + updateTransformBackwards(parent, parentTransform); + parent.updateLocalTransform(); + parentTransform.append(parent.localTransform); + } + return parentTransform; +} + +"use strict"; +let warnCount = 0; +const maxWarnings = 500; +function warn(...args) { + if (warnCount === maxWarnings) + return; + warnCount++; + if (warnCount === maxWarnings) { + console.warn("PixiJS Warning: too many warnings, no more warnings will be reported to the console by PixiJS."); + } else { + console.warn("PixiJS Warning: ", ...args); + } +} + +"use strict"; +function getLocalBounds(target, bounds, relativeMatrix) { + bounds.clear(); + relativeMatrix || (relativeMatrix = Matrix.IDENTITY); + _getLocalBounds(target, bounds, relativeMatrix, target, true); + if (!bounds.isValid) { + bounds.set(0, 0, 0, 0); + } + return bounds; +} +function _getLocalBounds(target, bounds, parentTransform, rootContainer, isRoot) { + var _a, _b; + let relativeTransform; + if (!isRoot) { + if (!target.visible || !target.measurable) + return; + target.updateLocalTransform(); + const localTransform = target.localTransform; + relativeTransform = matrixPool.get(); + relativeTransform.appendFrom(localTransform, parentTransform); + } else { + relativeTransform = matrixPool.get(); + relativeTransform = parentTransform.copyTo(relativeTransform); + } + const parentBounds = bounds; + const preserveBounds = !!target.effects.length; + if (preserveBounds) { + bounds = boundsPool.get().clear(); + } + if (target.boundsArea) { + bounds.addRect(target.boundsArea, relativeTransform); + } else { + if (target.renderPipeId) { + bounds.matrix = relativeTransform; + target.addBounds(bounds); + } + const children = target.children; + for (let i = 0; i < children.length; i++) { + _getLocalBounds(children[i], bounds, relativeTransform, rootContainer, false); + } + } + if (preserveBounds) { + for (let i = 0; i < target.effects.length; i++) { + (_b = (_a = target.effects[i]).addLocalBounds) == null ? void 0 : _b.call(_a, bounds, rootContainer); + } + parentBounds.addBounds(bounds, Matrix.IDENTITY); + boundsPool.return(bounds); + } + matrixPool.return(relativeTransform); +} +function getParent(target, root, matrix) { + const parent = target.parent; + if (!parent) { + warn("Item is not inside the root container"); + return; + } + if (parent !== root) { + getParent(parent, root, matrix); + parent.updateLocalTransform(); + matrix.append(parent.localTransform); + } +} + +"use strict"; +function checkChildrenDidChange(container, previousData) { + const children = container.children; + for (let i = 0; i < children.length; i++) { + const child = children[i]; + const changeId = (child.uid & 255) << 24 | child._didChangeId & 16777215; + if (previousData.data[previousData.index] !== changeId) { + previousData.data[previousData.index] = changeId; + previousData.didChange = true; + } + previousData.index++; + if (child.children.length) { + checkChildrenDidChange(child, previousData); + } + } + return previousData.didChange; +} + +"use strict"; +const tempMatrix$3 = new Matrix(); +const measureMixin = { + _localBoundsCacheId: -1, + _localBoundsCacheData: null, + _setWidth(value, localWidth) { + const sign = Math.sign(this.scale.x) || 1; + if (localWidth !== 0) { + this.scale.x = value / localWidth * sign; + } else { + this.scale.x = sign; + } + }, + _setHeight(value, localHeight) { + const sign = Math.sign(this.scale.y) || 1; + if (localHeight !== 0) { + this.scale.y = value / localHeight * sign; + } else { + this.scale.y = sign; + } + }, + /** + * Retrieves the local bounds of the container as a Bounds object. + * @returns - The bounding area. + * @memberof scene.Container# + */ + getLocalBounds() { + if (!this._localBoundsCacheData) { + this._localBoundsCacheData = { + data: [], + index: 1, + didChange: false, + localBounds: new Bounds() + }; + } + const localBoundsCacheData = this._localBoundsCacheData; + localBoundsCacheData.index = 1; + localBoundsCacheData.didChange = false; + if (localBoundsCacheData.data[0] !== this._didChangeId >> 12) { + localBoundsCacheData.didChange = true; + localBoundsCacheData.data[0] = this._didChangeId >> 12; + } + checkChildrenDidChange(this, localBoundsCacheData); + if (localBoundsCacheData.didChange) { + getLocalBounds(this, localBoundsCacheData.localBounds, tempMatrix$3); + } + return localBoundsCacheData.localBounds; + }, + /** + * Calculates and returns the (world) bounds of the display object as a [Rectangle]{@link Rectangle}. + * @param skipUpdate - Setting to `true` will stop the transforms of the scene graph from + * being updated. This means the calculation returned MAY be out of date BUT will give you a + * nice performance boost. + * @param bounds - Optional bounds to store the result of the bounds calculation. + * @returns - The minimum axis-aligned rectangle in world space that fits around this object. + * @memberof scene.Container# + */ + getBounds(skipUpdate, bounds) { + return getGlobalBounds(this, skipUpdate, bounds || new Bounds()); + } +}; + +"use strict"; +const onRenderMixin = { + _onRender: null, + set onRender(func) { + const renderGroup = this.renderGroup; + if (!func) { + if (this._onRender) { + renderGroup == null ? void 0 : renderGroup.removeOnRender(this); + } + this._onRender = null; + return; + } + if (!this._onRender) { + renderGroup == null ? void 0 : renderGroup.addOnRender(this); + } + this._onRender = func; + }, + /** + * This callback is used when the container is rendered. This is where you should add your custom + * logic that is needed to be run every frame. + * + * In v7 many users used `updateTransform` for this, however the way v8 renders objects is different + * and "updateTransform" is no longer called every frame + * @example + * const container = new Container(); + * container.onRender = () => { + * container.rotation += 0.01; + * }; + * @memberof scene.Container# + */ + get onRender() { + return this._onRender; + } +}; + +"use strict"; +const sortMixin = { + _zIndex: 0, + /** + * Should children be sorted by zIndex at the next render call. + * + * Will get automatically set to true if a new child is added, or if a child's zIndex changes. + * @type {boolean} + * @memberof scene.Container# + */ + sortDirty: false, + /** + * If set to true, the container will sort its children by `zIndex` value + * when the next render is called, or manually if `sortChildren()` is called. + * + * This actually changes the order of elements in the array, so should be treated + * as a basic solution that is not performant compared to other solutions, + * such as {@link https://github.com/pixijs/layers PixiJS Layers} + * + * Also be aware of that this may not work nicely with the `addChildAt()` function, + * as the `zIndex` sorting may cause the child to automatically sorted to another position. + * @type {boolean} + * @memberof scene.Container# + */ + sortableChildren: false, + /** + * The zIndex of the container. + * + * Setting this value, will automatically set the parent to be sortable. Children will be automatically + * sorted by zIndex value; a higher value will mean it will be moved towards the end of the array, + * and thus rendered on top of other display objects within the same container. + * @see scene.Container#sortableChildren + * @memberof scene.Container# + */ + get zIndex() { + return this._zIndex; + }, + set zIndex(value) { + if (this._zIndex === value) + return; + this._zIndex = value; + this.depthOfChildModified(); + }, + depthOfChildModified() { + if (this.parent) { + this.parent.sortableChildren = true; + this.parent.sortDirty = true; + } + if (this.renderGroup && !this.isRenderGroupRoot) { + this.renderGroup.structureDidChange = true; + } + }, + /** + * Sorts children by zIndex. + * @memberof scene.Container# + */ + sortChildren() { + if (!this.sortDirty) + return; + this.sortDirty = false; + this.children.sort(sortChildren); + } +}; +function sortChildren(a, b) { + return a._zIndex - b._zIndex; +} + +"use strict"; +const toLocalGlobalMixin = { + /** + * Returns the global position of the container. + * @param point - The optional point to write the global value to. + * @param skipUpdate - Should we skip the update transform. + * @returns - The updated point. + * @memberof scene.Container# + */ + getGlobalPosition(point = new Point(), skipUpdate = false) { + if (this.parent) { + this.parent.toGlobal(this._position, point, skipUpdate); + } else { + point.x = this._position.x; + point.y = this._position.y; + } + return point; + }, + /** + * Calculates the global position of the container. + * @param position - The world origin to calculate from. + * @param point - A Point object in which to store the value, optional + * (otherwise will create a new Point). + * @param skipUpdate - Should we skip the update transform. + * @returns - A point object representing the position of this object. + * @memberof scene.Container# + */ + toGlobal(position, point, skipUpdate = false) { + if (!skipUpdate) { + this.updateLocalTransform(); + const globalMatrix = updateTransformBackwards(this, new Matrix()); + globalMatrix.append(this.localTransform); + return globalMatrix.apply(position, point); + } + return this.worldTransform.apply(position, point); + }, + /** + * Calculates the local position of the container relative to another point. + * @param position - The world origin to calculate from. + * @param from - The Container to calculate the global position from. + * @param point - A Point object in which to store the value, optional + * (otherwise will create a new Point). + * @param skipUpdate - Should we skip the update transform + * @returns - A point object representing the position of this object + * @memberof scene.Container# + */ + toLocal(position, from, point, skipUpdate) { + if (from) { + position = from.toGlobal(position, point, skipUpdate); + } + if (!skipUpdate) { + this.updateLocalTransform(); + const globalMatrix = updateTransformBackwards(this, new Matrix()); + globalMatrix.append(this.localTransform); + return globalMatrix.applyInverse(position, point); + } + return this.worldTransform.applyInverse(position, point); + } +}; + +"use strict"; +class InstructionSet { + constructor() { + /** a unique id for this instruction set used through the renderer */ + this.uid = uid("instructionSet"); + /** the array of instructions */ + this.instructions = []; + /** the actual size of the array (any instructions passed this should be ignored) */ + this.instructionSize = 0; + } + /** reset the instruction set so it can be reused set size back to 0 */ + reset() { + this.instructionSize = 0; + } + /** + * Add an instruction to the set + * @param instruction - add an instruction to the set + */ + add(instruction) { + this.instructions[this.instructionSize++] = instruction; + } + /** + * Log the instructions to the console (for debugging) + * @internal + * @ignore + */ + log() { + this.instructions.length = this.instructionSize; + console.table(this.instructions, ["type", "action"]); + } +} + +"use strict"; +class RenderGroup { + constructor(root) { + this.renderPipeId = "renderGroup"; + this.root = null; + this.canBundle = false; + this.renderGroupParent = null; + this.renderGroupChildren = []; + this._children = []; + this.worldTransform = new Matrix(); + this.worldColorAlpha = 4294967295; + this.worldColor = 16777215; + this.worldAlpha = 1; + // these updates are transform changes.. + this.childrenToUpdate = /* @__PURE__ */ Object.create(null); + this.updateTick = 0; + // these update are renderable changes.. + this.childrenRenderablesToUpdate = { list: [], index: 0 }; + // other + this.structureDidChange = true; + this.instructionSet = new InstructionSet(); + this._onRenderContainers = []; + this.root = root; + this.addChild(root); + } + get localTransform() { + return this.root.localTransform; + } + addRenderGroupChild(renderGroupChild) { + if (renderGroupChild.renderGroupParent) { + renderGroupChild.renderGroupParent._removeRenderGroupChild(renderGroupChild); + } + renderGroupChild.renderGroupParent = this; + this.onChildUpdate(renderGroupChild.root); + this.renderGroupChildren.push(renderGroupChild); + } + _removeRenderGroupChild(renderGroupChild) { + if (renderGroupChild.root.didChange) { + this._removeChildFromUpdate(renderGroupChild.root); + } + const index = this.renderGroupChildren.indexOf(renderGroupChild); + if (index > -1) { + this.renderGroupChildren.splice(index, 1); + } + renderGroupChild.renderGroupParent = null; + } + addChild(child) { + this.structureDidChange = true; + if (child !== this.root) { + this._children.push(child); + child.updateTick = -1; + if (child.parent === this.root) { + child.relativeRenderGroupDepth = 1; + } else { + child.relativeRenderGroupDepth = child.parent.relativeRenderGroupDepth + 1; + } + if (child._onRender) { + this.addOnRender(child); + } + } + if (child.renderGroup) { + if (child.renderGroup.root === child) { + this.addRenderGroupChild(child.renderGroup); + return; + } + } else { + child.renderGroup = this; + child.didChange = true; + } + const children = child.children; + if (!child.isRenderGroupRoot) { + this.onChildUpdate(child); + } + for (let i = 0; i < children.length; i++) { + this.addChild(children[i]); + } + } + removeChild(child) { + this.structureDidChange = true; + if (child._onRender) { + this.removeOnRender(child); + } + if (child.renderGroup.root !== child) { + const children = child.children; + for (let i = 0; i < children.length; i++) { + this.removeChild(children[i]); + } + if (child.didChange) { + child.renderGroup._removeChildFromUpdate(child); + } + child.renderGroup = null; + } else { + this._removeRenderGroupChild(child.renderGroup); + } + const index = this._children.indexOf(child); + if (index > -1) { + this._children.splice(index, 1); + } + } + onChildUpdate(child) { + let childrenToUpdate = this.childrenToUpdate[child.relativeRenderGroupDepth]; + if (!childrenToUpdate) { + childrenToUpdate = this.childrenToUpdate[child.relativeRenderGroupDepth] = { + index: 0, + list: [] + }; + } + childrenToUpdate.list[childrenToUpdate.index++] = child; + } + // SHOULD THIS BE HERE? + updateRenderable(container) { + if (container.globalDisplayStatus < 7) + return; + container.didViewUpdate = false; + this.instructionSet.renderPipes[container.renderPipeId].updateRenderable(container); + } + onChildViewUpdate(child) { + this.childrenRenderablesToUpdate.list[this.childrenRenderablesToUpdate.index++] = child; + } + _removeChildFromUpdate(child) { + const childrenToUpdate = this.childrenToUpdate[child.relativeRenderGroupDepth]; + if (!childrenToUpdate) { + return; + } + const index = childrenToUpdate.list.indexOf(child); + if (index > -1) { + childrenToUpdate.list.splice(index, 1); + } + childrenToUpdate.index--; + } + get isRenderable() { + return this.root.localDisplayStatus === 7 && this.worldAlpha > 0; + } + /** + * adding a container to the onRender list will make sure the user function + * passed in to the user defined 'onRender` callBack + * @param container - the container to add to the onRender list + */ + addOnRender(container) { + this._onRenderContainers.push(container); + } + removeOnRender(container) { + this._onRenderContainers.splice(this._onRenderContainers.indexOf(container), 1); + } + runOnRender() { + for (let i = 0; i < this._onRenderContainers.length; i++) { + this._onRenderContainers[i]._onRender(); + } + } +} + +"use strict"; +function assignWithIgnore(target, options, ignore = {}) { + for (const key in options) { + if (!ignore[key] && options[key] !== void 0) { + target[key] = options[key]; + } + } +} + +"use strict"; +const defaultSkew = new ObservablePoint(null); +const defaultPivot = new ObservablePoint(null); +const defaultScale = new ObservablePoint(null, 1, 1); +const UPDATE_COLOR = 1; +const UPDATE_BLEND = 2; +const UPDATE_VISIBLE = 4; +const UPDATE_TRANSFORM = 8; +class Container extends EventEmitter { + constructor(options = {}) { + var _a, _b; + super(); + /** @private */ + this.uid = uid("renderable"); + /** @private */ + this._updateFlags = 15; + // is this container the root of a renderGroup? + // TODO implement this in a few more places + /** @private */ + this.isRenderGroupRoot = false; + // the render group this container belongs to OR owns + /** @private */ + this.renderGroup = null; + // set to true if the container has changed. It is reset once the changes have been applied + // by the transform system + // its here to stop ensure that when things change, only one update gets registers with the transform system + /** @private */ + this.didChange = false; + // same as above, but for the renderable + /** @private */ + this.didViewUpdate = false; + // how deep is the container relative to its render group.. + // unless the element is the root render group - it will be relative to its parent + /** @private */ + this.relativeRenderGroupDepth = 0; + /** + * The array of children of this container. + * @readonly + */ + this.children = []; + /** The display object container that contains this display object. */ + this.parent = null; + // used internally for changing up the render order.. mainly for masks and filters + // TODO setting this should cause a rebuild?? + /** @private */ + this.includeInBuild = true; + /** @private */ + this.measurable = true; + /** @private */ + this.isSimple = true; + // / /////////////Transform related props////////////// + // used by the transform system to check if a container needs to be updated that frame + // if the tick matches the current transform system tick, it is not updated again + /** + * @internal + * @ignore + */ + this.updateTick = -1; + /** + * Current transform of the object based on local factors: position, scale, other stuff. + * @readonly + */ + this.localTransform = new Matrix(); + /** + * The relative group transform is a transform relative to the render group it belongs too. It will include all parent + * transforms and up to the render group (think of it as kind of like a stage - but the stage can be nested). + * If this container is is self a render group matrix will be relative to its parent render group + * @readonly + */ + this.relativeGroupTransform = new Matrix(); + /** + * The group transform is a transform relative to the render group it belongs too. + * If this container is render group then this will be an identity matrix. other wise it + * will be the same as the relativeGroupTransform. + * Use this value when actually rendering things to the screen + * @readonly + */ + this.groupTransform = this.relativeGroupTransform; + /** If the object has been destroyed via destroy(). If true, it should not be used. */ + this.destroyed = false; + // transform data.. + /** + * The coordinate of the object relative to the local coordinates of the parent. + * @internal + * @ignore + */ + this._position = new ObservablePoint(this, 0, 0); + /** + * The scale factor of the object. + * @internal + * @ignore + */ + this._scale = defaultScale; + /** + * The pivot point of the container that it rotates around. + * @internal + * @ignore + */ + this._pivot = defaultPivot; + /** + * The skew amount, on the x and y axis. + * @internal + * @ignore + */ + this._skew = defaultSkew; + /** + * The X-coordinate value of the normalized local X axis, + * the first column of the local transformation matrix without a scale. + * @internal + * @ignore + */ + this._cx = 1; + /** + * The Y-coordinate value of the normalized local X axis, + * the first column of the local transformation matrix without a scale. + * @internal + * @ignore + */ + this._sx = 0; + /** + * The X-coordinate value of the normalized local Y axis, + * the second column of the local transformation matrix without a scale. + * @internal + * @ignore + */ + this._cy = 0; + /** + * The Y-coordinate value of the normalized local Y axis, + * the second column of the local transformation matrix without a scale. + * @internal + * @ignore + */ + this._sy = 1; + /** + * The rotation amount. + * @internal + * @ignore + */ + this._rotation = 0; + // / COLOR related props ////////////// + // color stored as ABGR + this.localColor = 16777215; + this.localAlpha = 1; + this.groupAlpha = 1; + // A + this.groupColor = 16777215; + // BGR + this.groupColorAlpha = 4294967295; + // ABGR + // / BLEND related props ////////////// + /** + * @internal + * @ignore + */ + this.localBlendMode = "inherit"; + /** + * @internal + * @ignore + */ + this.groupBlendMode = "normal"; + // / VISIBILITY related props ////////////// + // visibility + // 0b11 + // first bit is visible, second bit is renderable + /** + * This property holds three bits: culled, visible, renderable + * the third bit represents culling (0 = culled, 1 = not culled) 0b100 + * the second bit represents visibility (0 = not visible, 1 = visible) 0b010 + * the first bit represents renderable (0 = renderable, 1 = not renderable) 0b001 + * @internal + * @ignore + */ + this.localDisplayStatus = 7; + // 0b11 | 0b10 | 0b01 | 0b00 + /** + * @internal + * @ignore + */ + this.globalDisplayStatus = 7; + /** + * A value that increments each time the container is modified + * the first 12 bits represent the container changes (eg transform, alpha, visible etc) + * the second 12 bits represent the view changes (eg texture swap, geometry change etc) + * + * view container + * [000000000000][00000000000] + * @ignore + */ + this._didChangeId = 0; + /** + * property that tracks if the container transform has changed + * @ignore + */ + this._didLocalTransformChangeId = -1; + assignWithIgnore(this, options, { + children: true, + parent: true, + effects: true + }); + (_a = options.children) == null ? void 0 : _a.forEach((child) => this.addChild(child)); + this.effects = []; + (_b = options.parent) == null ? void 0 : _b.addChild(this); + } + /** + * Mixes all enumerable properties and methods from a source object to Container. + * @param source - The source of properties and methods to mix in. + */ + static mixin(source) { + Object.defineProperties(Container.prototype, Object.getOwnPropertyDescriptors(source)); + } + /** + * Adds one or more children to the container. + * + * Multiple items can be added like so: `myContainer.addChild(thingOne, thingTwo, thingThree)` + * @param {...Container} children - The Container(s) to add to the container + * @returns {Container} - The first child that was added. + */ + addChild(...children) { + if (!this.allowChildren) { + deprecation(v8_0_0, "addChild: Only Containers will be allowed to add children in v8.0.0"); + } + if (children.length > 1) { + for (let i = 0; i < children.length; i++) { + this.addChild(children[i]); + } + return children[0]; + } + const child = children[0]; + if (child.parent === this) { + this.children.splice(this.children.indexOf(child), 1); + this.children.push(child); + if (this.renderGroup && !this.isRenderGroupRoot) { + this.renderGroup.structureDidChange = true; + } + return child; + } + if (child.parent) { + child.parent.removeChild(child); + } + this.children.push(child); + if (this.sortableChildren) + this.sortDirty = true; + child.parent = this; + child.didChange = true; + child.didViewUpdate = false; + child._updateFlags = 15; + if (this.renderGroup) { + this.renderGroup.addChild(child); + } + this.emit("childAdded", child, this, this.children.length - 1); + child.emit("added", this); + if (child._zIndex !== 0) { + child.depthOfChildModified(); + } + return child; + } + /** + * Removes one or more children from the container. + * @param {...Container} children - The Container(s) to remove + * @returns {Container} The first child that was removed. + */ + removeChild(...children) { + if (children.length > 1) { + for (let i = 0; i < children.length; i++) { + this.removeChild(children[i]); + } + return children[0]; + } + const child = children[0]; + const index = this.children.indexOf(child); + if (index > -1) { + this.children.splice(index, 1); + if (this.renderGroup) { + this.renderGroup.removeChild(child); + } + child.parent = null; + this.emit("childRemoved", child, this, index); + child.emit("removed", this); + } + return child; + } + /** @ignore */ + _onUpdate(point) { + if (point) { + if (point === this._skew) { + this._updateSkew(); + } + } + this._didChangeId++; + if (this.didChange) + return; + this.didChange = true; + if (this.isRenderGroupRoot) { + const renderGroupParent = this.renderGroup.renderGroupParent; + if (renderGroupParent) { + renderGroupParent.onChildUpdate(this); + } + } else if (this.renderGroup) { + this.renderGroup.onChildUpdate(this); + } + } + set isRenderGroup(value) { + if (this.isRenderGroupRoot && value === false) { + throw new Error("[Pixi] cannot undo a render group just yet"); + } + if (value) { + this.enableRenderGroup(); + } + } + /** + * Returns true if this container is a render group. + * This means that it will be rendered as a separate pass, with its own set of instructions + */ + get isRenderGroup() { + return this.isRenderGroupRoot; + } + /** This enables the container to be rendered as a render group. */ + enableRenderGroup() { + if (this.renderGroup && this.renderGroup.root === this) + return; + this.isRenderGroupRoot = true; + const parentRenderGroup = this.renderGroup; + if (parentRenderGroup) { + parentRenderGroup.removeChild(this); + } + this.renderGroup = new RenderGroup(this); + if (parentRenderGroup) { + for (let i = 0; i < parentRenderGroup.renderGroupChildren.length; i++) { + const childRenderGroup = parentRenderGroup.renderGroupChildren[i]; + let parent = childRenderGroup.root; + while (parent) { + if (parent === this) { + this.renderGroup.addRenderGroupChild(childRenderGroup); + break; + } + parent = parent.parent; + } + } + parentRenderGroup.addRenderGroupChild(this.renderGroup); + } + this._updateIsSimple(); + this.groupTransform = Matrix.IDENTITY; + } + /** @ignore */ + _updateIsSimple() { + this.isSimple = !this.isRenderGroupRoot && this.effects.length === 0; + } + /** + * Current transform of the object based on world (parent) factors. + * @readonly + */ + get worldTransform() { + this._worldTransform || (this._worldTransform = new Matrix()); + if (this.renderGroup) { + if (this.isRenderGroupRoot) { + this._worldTransform.copyFrom(this.renderGroup.worldTransform); + } else { + this._worldTransform.appendFrom(this.relativeGroupTransform, this.renderGroup.worldTransform); + } + } + return this._worldTransform; + } + // / ////// transform related stuff + /** + * The position of the container on the x axis relative to the local coordinates of the parent. + * An alias to position.x + */ + get x() { + return this._position.x; + } + set x(value) { + this._position.x = value; + } + /** + * The position of the container on the y axis relative to the local coordinates of the parent. + * An alias to position.y + */ + get y() { + return this._position.y; + } + set y(value) { + this._position.y = value; + } + /** + * The coordinate of the object relative to the local coordinates of the parent. + * @since 4.0.0 + */ + get position() { + return this._position; + } + set position(value) { + this._position.copyFrom(value); + } + /** + * The rotation of the object in radians. + * 'rotation' and 'angle' have the same effect on a display object; rotation is in radians, angle is in degrees. + */ + get rotation() { + return this._rotation; + } + set rotation(value) { + if (this._rotation !== value) { + this._rotation = value; + this._onUpdate(this._skew); + } + } + /** + * The angle of the object in degrees. + * 'rotation' and 'angle' have the same effect on a display object; rotation is in radians, angle is in degrees. + */ + get angle() { + return this.rotation * RAD_TO_DEG; + } + set angle(value) { + this.rotation = value * DEG_TO_RAD; + } + /** + * The center of rotation, scaling, and skewing for this display object in its local space. The `position` + * is the projection of `pivot` in the parent's local space. + * + * By default, the pivot is the origin (0, 0). + * @since 4.0.0 + */ + get pivot() { + if (this._pivot === defaultPivot) { + this._pivot = new ObservablePoint(this, 0, 0); + } + return this._pivot; + } + set pivot(value) { + if (this._pivot === defaultPivot) { + this._pivot = new ObservablePoint(this, 0, 0); + } + typeof value === "number" ? this._pivot.set(value) : this._pivot.copyFrom(value); + } + /** + * The skew factor for the object in radians. + * @since 4.0.0 + */ + get skew() { + if (this._skew === defaultSkew) { + this._skew = new ObservablePoint(this, 0, 0); + } + return this._skew; + } + set skew(value) { + if (this._skew === defaultSkew) { + this._skew = new ObservablePoint(this, 0, 0); + } + this._skew.copyFrom(value); + } + /** + * The scale factors of this object along the local coordinate axes. + * + * The default scale is (1, 1). + * @since 4.0.0 + */ + get scale() { + if (this._scale === defaultScale) { + this._scale = new ObservablePoint(this, 1, 1); + } + return this._scale; + } + set scale(value) { + if (this._scale === defaultScale) { + this._scale = new ObservablePoint(this, 0, 0); + } + typeof value === "number" ? this._scale.set(value) : this._scale.copyFrom(value); + } + /** + * The width of the Container, setting this will actually modify the scale to achieve the value set. + * @memberof scene.Container# + */ + get width() { + return Math.abs(this.scale.x * this.getLocalBounds().width); + } + set width(value) { + const localWidth = this.getLocalBounds().width; + this._setWidth(value, localWidth); + } + /** + * The height of the Container, setting this will actually modify the scale to achieve the value set. + * @memberof scene.Container# + */ + get height() { + return Math.abs(this.scale.y * this.getLocalBounds().height); + } + set height(value) { + const localHeight = this.getLocalBounds().height; + this._setHeight(value, localHeight); + } + /** + * Retrieves the size of the container as a [Size]{@link Size} object. + * This is faster than get the width and height separately. + * @param out - Optional object to store the size in. + * @returns - The size of the container. + * @memberof scene.Container# + */ + getSize(out) { + if (!out) { + out = {}; + } + const bounds = this.getLocalBounds(); + out.width = Math.abs(this.scale.x * bounds.width); + out.height = Math.abs(this.scale.y * bounds.height); + return out; + } + /** + * Sets the size of the container to the specified width and height. + * This is faster than setting the width and height separately. + * @param value - This can be either a number or a [Size]{@link Size} object. + * @param height - The height to set. Defaults to the value of `width` if not provided. + * @memberof scene.Container# + */ + setSize(value, height) { + var _a; + const size = this.getLocalBounds(); + let convertedWidth; + let convertedHeight; + if (typeof value !== "object") { + convertedWidth = value; + convertedHeight = height != null ? height : value; + } else { + convertedWidth = value.width; + convertedHeight = (_a = value.height) != null ? _a : value.width; + } + if (convertedWidth !== void 0) { + this._setWidth(convertedWidth, size.width); + } + if (convertedHeight !== void 0) { + this._setHeight(convertedHeight, size.height); + } + } + /** Called when the skew or the rotation changes. */ + _updateSkew() { + const rotation = this._rotation; + const skew = this._skew; + this._cx = Math.cos(rotation + skew._y); + this._sx = Math.sin(rotation + skew._y); + this._cy = -Math.sin(rotation - skew._x); + this._sy = Math.cos(rotation - skew._x); + } + /** + * Updates the transform properties of the container (accepts partial values). + * @param {object} opts - The options for updating the transform. + * @param {number} opts.x - The x position of the container. + * @param {number} opts.y - The y position of the container. + * @param {number} opts.scaleX - The scale factor on the x-axis. + * @param {number} opts.scaleY - The scale factor on the y-axis. + * @param {number} opts.rotation - The rotation of the container, in radians. + * @param {number} opts.skewX - The skew factor on the x-axis. + * @param {number} opts.skewY - The skew factor on the y-axis. + * @param {number} opts.pivotX - The x coordinate of the pivot point. + * @param {number} opts.pivotY - The y coordinate of the pivot point. + */ + updateTransform(opts) { + this.position.set( + typeof opts.x === "number" ? opts.x : this.position.x, + typeof opts.y === "number" ? opts.y : this.position.y + ); + this.scale.set( + typeof opts.scaleX === "number" ? opts.scaleX || 1 : this.scale.x, + typeof opts.scaleY === "number" ? opts.scaleY || 1 : this.scale.y + ); + this.rotation = typeof opts.rotation === "number" ? opts.rotation : this.rotation; + this.skew.set( + typeof opts.skewX === "number" ? opts.skewX : this.skew.x, + typeof opts.skewY === "number" ? opts.skewY : this.skew.y + ); + this.pivot.set( + typeof opts.pivotX === "number" ? opts.pivotX : this.pivot.x, + typeof opts.pivotY === "number" ? opts.pivotY : this.pivot.y + ); + return this; + } + /** + * Updates the local transform using the given matrix. + * @param matrix - The matrix to use for updating the transform. + */ + setFromMatrix(matrix) { + matrix.decompose(this); + } + /** Updates the local transform. */ + updateLocalTransform() { + if ((this._didLocalTransformChangeId & 15) === this._didChangeId) + return; + this._didLocalTransformChangeId = this._didChangeId; + const lt = this.localTransform; + const scale = this._scale; + const pivot = this._pivot; + const position = this._position; + const sx = scale._x; + const sy = scale._y; + const px = pivot._x; + const py = pivot._y; + lt.a = this._cx * sx; + lt.b = this._sx * sx; + lt.c = this._cy * sy; + lt.d = this._sy * sy; + lt.tx = position._x - (px * lt.a + py * lt.c); + lt.ty = position._y - (px * lt.b + py * lt.d); + } + // / ///// color related stuff + set alpha(value) { + if (value === this.localAlpha) + return; + this.localAlpha = value; + this._updateFlags |= UPDATE_COLOR; + this._onUpdate(); + } + /** The opacity of the object. */ + get alpha() { + return this.localAlpha; + } + set tint(value) { + const tempColor = Color.shared.setValue(value != null ? value : 16777215); + const bgr = tempColor.toBgrNumber(); + if (bgr === this.localColor) + return; + this.localColor = bgr; + this._updateFlags |= UPDATE_COLOR; + this._onUpdate(); + } + /** + * The tint applied to the sprite. This is a hex value. + * + * A value of 0xFFFFFF will remove any tint effect. + * @default 0xFFFFFF + */ + get tint() { + const bgr = this.localColor; + return ((bgr & 255) << 16) + (bgr & 65280) + (bgr >> 16 & 255); + } + // / //////////////// blend related stuff + set blendMode(value) { + if (this.localBlendMode === value) + return; + if (this.renderGroup && !this.isRenderGroupRoot) { + this.renderGroup.structureDidChange = true; + } + this._updateFlags |= UPDATE_BLEND; + this.localBlendMode = value; + this._onUpdate(); + } + /** + * The blend mode to be applied to the sprite. Apply a value of `'normal'` to reset the blend mode. + * @default 'normal' + */ + get blendMode() { + return this.localBlendMode; + } + // / ///////// VISIBILITY / RENDERABLE ///////////////// + /** The visibility of the object. If false the object will not be drawn, and the transform will not be updated. */ + get visible() { + return !!(this.localDisplayStatus & 2); + } + set visible(value) { + const valueNumber = value ? 1 : 0; + if ((this.localDisplayStatus & 2) >> 1 === valueNumber) + return; + if (this.renderGroup && !this.isRenderGroupRoot) { + this.renderGroup.structureDidChange = true; + } + this._updateFlags |= UPDATE_VISIBLE; + this.localDisplayStatus ^= 2; + this._onUpdate(); + } + /** @ignore */ + get culled() { + return !(this.localDisplayStatus & 4); + } + /** @ignore */ + set culled(value) { + const valueNumber = value ? 1 : 0; + if ((this.localDisplayStatus & 4) >> 2 === valueNumber) + return; + if (this.renderGroup && !this.isRenderGroupRoot) { + this.renderGroup.structureDidChange = true; + } + this._updateFlags |= UPDATE_VISIBLE; + this.localDisplayStatus ^= 4; + this._onUpdate(); + } + /** Can this object be rendered, if false the object will not be drawn but the transform will still be updated. */ + get renderable() { + return !!(this.localDisplayStatus & 1); + } + set renderable(value) { + const valueNumber = value ? 1 : 0; + if ((this.localDisplayStatus & 1) === valueNumber) + return; + this._updateFlags |= UPDATE_VISIBLE; + this.localDisplayStatus ^= 1; + if (this.renderGroup && !this.isRenderGroupRoot) { + this.renderGroup.structureDidChange = true; + } + this._onUpdate(); + } + /** Whether or not the object should be rendered. */ + get isRenderable() { + return this.localDisplayStatus === 7 && this.groupAlpha > 0; + } + /** + * Removes all internal references and listeners as well as removes children from the display list. + * Do not use a Container after calling `destroy`. + * @param options - Options parameter. A boolean will act as if all options + * have been set to that value + * @param {boolean} [options.children=false] - if set to true, all the children will have their destroy + * method called as well. 'options' will be passed on to those calls. + * @param {boolean} [options.texture=false] - Only used for children with textures e.g. Sprites. If options.children + * is set to true it should destroy the texture of the child sprite + * @param {boolean} [options.textureSource=false] - Only used for children with textures e.g. Sprites. + * If options.children is set to true it should destroy the texture source of the child sprite + * @param {boolean} [options.context=false] - Only used for children with graphicsContexts e.g. Graphics. + * If options.children is set to true it should destroy the context of the child graphics + */ + destroy(options = false) { + if (this.destroyed) + return; + this.destroyed = true; + this.removeFromParent(); + this.parent = null; + this._mask = null; + this._filters = null; + this.effects = null; + this._position = null; + this._scale = null; + this._pivot = null; + this._skew = null; + this.emit("destroyed", this); + this.removeAllListeners(); + const destroyChildren = typeof options === "boolean" ? options : options == null ? void 0 : options.children; + const oldChildren = this.removeChildren(0, this.children.length); + if (destroyChildren) { + for (let i = 0; i < oldChildren.length; ++i) { + oldChildren[i].destroy(options); + } + } + } +} +Container.mixin(childrenHelperMixin); +Container.mixin(toLocalGlobalMixin); +Container.mixin(onRenderMixin); +Container.mixin(measureMixin); +Container.mixin(effectsMixin); +Container.mixin(findMixin); +Container.mixin(sortMixin); +Container.mixin(cullingMixin); + +"use strict"; +class FederatedEvent { + /** + * @param manager - The event boundary which manages this event. Propagation can only occur + * within the boundary's jurisdiction. + */ + constructor(manager) { + /** Flags whether this event bubbles. This will take effect only if it is set before propagation. */ + this.bubbles = true; + /** @deprecated since 7.0.0 */ + this.cancelBubble = true; + /** + * Flags whether this event can be canceled using {@link FederatedEvent.preventDefault}. This is always + * false (for now). + */ + this.cancelable = false; + /** + * Flag added for compatibility with DOM {@code Event}. It is not used in the Federated Events + * API. + * @see https://dom.spec.whatwg.org/#dom-event-composed + */ + this.composed = false; + /** Flags whether the default response of the user agent was prevent through this event. */ + this.defaultPrevented = false; + /** + * The propagation phase. + * @default {@link FederatedEvent.NONE} + */ + this.eventPhase = FederatedEvent.prototype.NONE; + /** Flags whether propagation was stopped. */ + this.propagationStopped = false; + /** Flags whether propagation was immediately stopped. */ + this.propagationImmediatelyStopped = false; + /** The coordinates of the event relative to the nearest DOM layer. This is a non-standard property. */ + this.layer = new Point(); + /** The coordinates of the event relative to the DOM document. This is a non-standard property. */ + this.page = new Point(); + this.NONE = 0; + this.CAPTURING_PHASE = 1; + this.AT_TARGET = 2; + this.BUBBLING_PHASE = 3; + this.manager = manager; + } + /** @readonly */ + get layerX() { + return this.layer.x; + } + /** @readonly */ + get layerY() { + return this.layer.y; + } + /** @readonly */ + get pageX() { + return this.page.x; + } + /** @readonly */ + get pageY() { + return this.page.y; + } + /** + * Fallback for the deprecated @code{InteractionEvent.data}. + * @deprecated since 7.0.0 + */ + get data() { + return this; + } + /** The propagation path for this event. Alias for {@link EventBoundary.propagationPath}. */ + composedPath() { + if (this.manager && (!this.path || this.path[this.path.length - 1] !== this.target)) { + this.path = this.target ? this.manager.propagationPath(this.target) : []; + } + return this.path; + } + /** + * Unimplemented method included for implementing the DOM interface {@code Event}. It will throw an {@code Error}. + * @deprecated + * @param _type + * @param _bubbles + * @param _cancelable + */ + initEvent(_type, _bubbles, _cancelable) { + throw new Error("initEvent() is a legacy DOM API. It is not implemented in the Federated Events API."); + } + /** + * Unimplemented method included for implementing the DOM interface {@code UIEvent}. It will throw an {@code Error}. + * @deprecated + * @param _typeArg + * @param _bubblesArg + * @param _cancelableArg + * @param _viewArg + * @param _detailArg + */ + initUIEvent(_typeArg, _bubblesArg, _cancelableArg, _viewArg, _detailArg) { + throw new Error("initUIEvent() is a legacy DOM API. It is not implemented in the Federated Events API."); + } + /** Prevent default behavior of PixiJS and the user agent. */ + preventDefault() { + if (this.nativeEvent instanceof Event && this.nativeEvent.cancelable) { + this.nativeEvent.preventDefault(); + } + this.defaultPrevented = true; + } + /** + * Stop this event from propagating to any addition listeners, including on the + * {@link FederatedEventTarget.currentTarget currentTarget} and also the following + * event targets on the propagation path. + */ + stopImmediatePropagation() { + this.propagationImmediatelyStopped = true; + } + /** + * Stop this event from propagating to the next {@link FederatedEventTarget}. The rest of the listeners + * on the {@link FederatedEventTarget.currentTarget currentTarget} will still be notified. + */ + stopPropagation() { + this.propagationStopped = true; + } +} + +var appleIphone = /iPhone/i; +var appleIpod = /iPod/i; +var appleTablet = /iPad/i; +var appleUniversal = /\biOS-universal(?:.+)Mac\b/i; +var androidPhone = /\bAndroid(?:.+)Mobile\b/i; +var androidTablet = /Android/i; +var amazonPhone = /(?:SD4930UR|\bSilk(?:.+)Mobile\b)/i; +var amazonTablet = /Silk/i; +var windowsPhone = /Windows Phone/i; +var windowsTablet = /\bWindows(?:.+)ARM\b/i; +var otherBlackBerry = /BlackBerry/i; +var otherBlackBerry10 = /BB10/i; +var otherOpera = /Opera Mini/i; +var otherChrome = /\b(CriOS|Chrome)(?:.+)Mobile/i; +var otherFirefox = /Mobile(?:.+)Firefox\b/i; +var isAppleTabletOnIos13 = function (navigator) { + return (typeof navigator !== 'undefined' && + navigator.platform === 'MacIntel' && + typeof navigator.maxTouchPoints === 'number' && + navigator.maxTouchPoints > 1 && + typeof MSStream === 'undefined'); +}; +function createMatch(userAgent) { + return function (regex) { return regex.test(userAgent); }; +} +function isMobile$1(param) { + var nav = { + userAgent: '', + platform: '', + maxTouchPoints: 0 + }; + if (!param && typeof navigator !== 'undefined') { + nav = { + userAgent: navigator.userAgent, + platform: navigator.platform, + maxTouchPoints: navigator.maxTouchPoints || 0 + }; + } + else if (typeof param === 'string') { + nav.userAgent = param; + } + else if (param && param.userAgent) { + nav = { + userAgent: param.userAgent, + platform: param.platform, + maxTouchPoints: param.maxTouchPoints || 0 + }; + } + var userAgent = nav.userAgent; + var tmp = userAgent.split('[FBAN'); + if (typeof tmp[1] !== 'undefined') { + userAgent = tmp[0]; + } + tmp = userAgent.split('Twitter'); + if (typeof tmp[1] !== 'undefined') { + userAgent = tmp[0]; + } + var match = createMatch(userAgent); + var result = { + apple: { + phone: match(appleIphone) && !match(windowsPhone), + ipod: match(appleIpod), + tablet: !match(appleIphone) && + (match(appleTablet) || isAppleTabletOnIos13(nav)) && + !match(windowsPhone), + universal: match(appleUniversal), + device: (match(appleIphone) || + match(appleIpod) || + match(appleTablet) || + match(appleUniversal) || + isAppleTabletOnIos13(nav)) && + !match(windowsPhone) + }, + amazon: { + phone: match(amazonPhone), + tablet: !match(amazonPhone) && match(amazonTablet), + device: match(amazonPhone) || match(amazonTablet) + }, + android: { + phone: (!match(windowsPhone) && match(amazonPhone)) || + (!match(windowsPhone) && match(androidPhone)), + tablet: !match(windowsPhone) && + !match(amazonPhone) && + !match(androidPhone) && + (match(amazonTablet) || match(androidTablet)), + device: (!match(windowsPhone) && + (match(amazonPhone) || + match(amazonTablet) || + match(androidPhone) || + match(androidTablet))) || + match(/\bokhttp\b/i) + }, + windows: { + phone: match(windowsPhone), + tablet: match(windowsTablet), + device: match(windowsPhone) || match(windowsTablet) + }, + other: { + blackberry: match(otherBlackBerry), + blackberry10: match(otherBlackBerry10), + opera: match(otherOpera), + firefox: match(otherFirefox), + chrome: match(otherChrome), + device: match(otherBlackBerry) || + match(otherBlackBerry10) || + match(otherOpera) || + match(otherFirefox) || + match(otherChrome) + }, + any: false, + phone: false, + tablet: false + }; + result.any = + result.apple.device || + result.android.device || + result.windows.device || + result.other.device; + result.phone = + result.apple.phone || result.android.phone || result.windows.phone; + result.tablet = + result.apple.tablet || result.android.tablet || result.windows.tablet; + return result; +} + +"use strict"; +var _a; +const isMobileCall = (_a = isMobile$1.default) != null ? _a : isMobile$1; +const isMobile = isMobileCall(globalThis.navigator); + +"use strict"; +const KEY_CODE_TAB = 9; +const DIV_TOUCH_SIZE = 100; +const DIV_TOUCH_POS_X = 0; +const DIV_TOUCH_POS_Y = 0; +const DIV_TOUCH_ZINDEX = 2; +const DIV_HOOK_SIZE = 1; +const DIV_HOOK_POS_X = -1e3; +const DIV_HOOK_POS_Y = -1e3; +const DIV_HOOK_ZINDEX = 2; +class AccessibilitySystem { + // 2fps + // eslint-disable-next-line jsdoc/require-param + /** + * @param {WebGLRenderer|WebGPURenderer} renderer - A reference to the current renderer + */ + constructor(renderer, _mobileInfo = isMobile) { + this._mobileInfo = _mobileInfo; + /** Setting this to true will visually show the divs. */ + this.debug = false; + /** Internal variable, see isActive getter. */ + this._isActive = false; + /** Internal variable, see isMobileAccessibility getter. */ + this._isMobileAccessibility = false; + /** A simple pool for storing divs. */ + this._pool = []; + /** This is a tick used to check if an object is no longer being rendered. */ + this._renderId = 0; + /** The array of currently active accessible items. */ + this._children = []; + /** Count to throttle div updates on android devices. */ + this._androidUpdateCount = 0; + /** The frequency to update the div elements. */ + this._androidUpdateFrequency = 500; + this._hookDiv = null; + if (_mobileInfo.tablet || _mobileInfo.phone) { + this._createTouchHook(); + } + const div = document.createElement("div"); + div.style.width = `${DIV_TOUCH_SIZE}px`; + div.style.height = `${DIV_TOUCH_SIZE}px`; + div.style.position = "absolute"; + div.style.top = `${DIV_TOUCH_POS_X}px`; + div.style.left = `${DIV_TOUCH_POS_Y}px`; + div.style.zIndex = DIV_TOUCH_ZINDEX.toString(); + this._div = div; + this._renderer = renderer; + this._onKeyDown = this._onKeyDown.bind(this); + this._onMouseMove = this._onMouseMove.bind(this); + globalThis.addEventListener("keydown", this._onKeyDown, false); + } + /** + * Value of `true` if accessibility is currently active and accessibility layers are showing. + * @member {boolean} + * @readonly + */ + get isActive() { + return this._isActive; + } + /** + * Value of `true` if accessibility is enabled for touch devices. + * @member {boolean} + * @readonly + */ + get isMobileAccessibility() { + return this._isMobileAccessibility; + } + get hookDiv() { + return this._hookDiv; + } + /** + * Creates the touch hooks. + * @private + */ + _createTouchHook() { + const hookDiv = document.createElement("button"); + hookDiv.style.width = `${DIV_HOOK_SIZE}px`; + hookDiv.style.height = `${DIV_HOOK_SIZE}px`; + hookDiv.style.position = "absolute"; + hookDiv.style.top = `${DIV_HOOK_POS_X}px`; + hookDiv.style.left = `${DIV_HOOK_POS_Y}px`; + hookDiv.style.zIndex = DIV_HOOK_ZINDEX.toString(); + hookDiv.style.backgroundColor = "#FF0000"; + hookDiv.title = "select to enable accessibility for this content"; + hookDiv.addEventListener("focus", () => { + this._isMobileAccessibility = true; + this._activate(); + this._destroyTouchHook(); + }); + document.body.appendChild(hookDiv); + this._hookDiv = hookDiv; + } + /** + * Destroys the touch hooks. + * @private + */ + _destroyTouchHook() { + if (!this._hookDiv) { + return; + } + document.body.removeChild(this._hookDiv); + this._hookDiv = null; + } + /** + * Activating will cause the Accessibility layer to be shown. + * This is called when a user presses the tab key. + * @private + */ + _activate() { + var _a; + if (this._isActive) { + return; + } + this._isActive = true; + globalThis.document.addEventListener("mousemove", this._onMouseMove, true); + globalThis.removeEventListener("keydown", this._onKeyDown, false); + this._renderer.runners.postrender.add(this); + (_a = this._renderer.view.canvas.parentNode) == null ? void 0 : _a.appendChild(this._div); + } + /** + * Deactivating will cause the Accessibility layer to be hidden. + * This is called when a user moves the mouse. + * @private + */ + _deactivate() { + var _a; + if (!this._isActive || this._isMobileAccessibility) { + return; + } + this._isActive = false; + globalThis.document.removeEventListener("mousemove", this._onMouseMove, true); + globalThis.addEventListener("keydown", this._onKeyDown, false); + this._renderer.runners.postrender.remove(this); + (_a = this._div.parentNode) == null ? void 0 : _a.removeChild(this._div); + } + /** + * This recursive function will run through the scene graph and add any new accessible objects to the DOM layer. + * @private + * @param {Container} container - The Container to check. + */ + _updateAccessibleObjects(container) { + if (!container.visible || !container.accessibleChildren) { + return; + } + if (container.accessible && container.isInteractive()) { + if (!container._accessibleActive) { + this._addChild(container); + } + container._renderId = this._renderId; + } + const children = container.children; + if (children) { + for (let i = 0; i < children.length; i++) { + this._updateAccessibleObjects(children[i]); + } + } + } + /** + * Runner init called, view is available at this point. + * @ignore + */ + init(options) { + var _a; + this.debug = (_a = options == null ? void 0 : options.debug) != null ? _a : this.debug; + this._renderer.runners.postrender.remove(this); + } + /** + * Runner postrender was called, ensure that all divs are mapped correctly to their Containers. + * Only fires while active. + * @ignore + */ + postrender() { + const now = performance.now(); + if (this._mobileInfo.android.device && now < this._androidUpdateCount) { + return; + } + this._androidUpdateCount = now + this._androidUpdateFrequency; + if (!this._renderer.renderingToScreen || !this._renderer.view.canvas) { + return; + } + if (this._renderer.lastObjectRendered) { + this._updateAccessibleObjects(this._renderer.lastObjectRendered); + } + const { x, y, width, height } = this._renderer.view.canvas.getBoundingClientRect(); + const { width: viewWidth, height: viewHeight, resolution } = this._renderer; + const sx = width / viewWidth * resolution; + const sy = height / viewHeight * resolution; + let div = this._div; + div.style.left = `${x}px`; + div.style.top = `${y}px`; + div.style.width = `${viewWidth}px`; + div.style.height = `${viewHeight}px`; + for (let i = 0; i < this._children.length; i++) { + const child = this._children[i]; + if (child._renderId !== this._renderId) { + child._accessibleActive = false; + removeItems(this._children, i, 1); + this._div.removeChild(child._accessibleDiv); + this._pool.push(child._accessibleDiv); + child._accessibleDiv = null; + i--; + } else { + div = child._accessibleDiv; + let hitArea = child.hitArea; + const wt = child.worldTransform; + if (child.hitArea) { + div.style.left = `${(wt.tx + hitArea.x * wt.a) * sx}px`; + div.style.top = `${(wt.ty + hitArea.y * wt.d) * sy}px`; + div.style.width = `${hitArea.width * wt.a * sx}px`; + div.style.height = `${hitArea.height * wt.d * sy}px`; + } else { + hitArea = child.getBounds().rectangle; + this._capHitArea(hitArea); + div.style.left = `${hitArea.x * sx}px`; + div.style.top = `${hitArea.y * sy}px`; + div.style.width = `${hitArea.width * sx}px`; + div.style.height = `${hitArea.height * sy}px`; + if (div.title !== child.accessibleTitle && child.accessibleTitle !== null) { + div.title = child.accessibleTitle || ""; + } + if (div.getAttribute("aria-label") !== child.accessibleHint && child.accessibleHint !== null) { + div.setAttribute("aria-label", child.accessibleHint || ""); + } + } + if (child.accessibleTitle !== div.title || child.tabIndex !== div.tabIndex) { + div.title = child.accessibleTitle || ""; + div.tabIndex = child.tabIndex; + if (this.debug) { + this._updateDebugHTML(div); + } + } + } + } + this._renderId++; + } + /** + * private function that will visually add the information to the + * accessibility div + * @param {HTMLElement} div - + */ + _updateDebugHTML(div) { + div.innerHTML = `type: ${div.type}
title : ${div.title}
tabIndex: ${div.tabIndex}`; + } + /** + * Adjust the hit area based on the bounds of a display object + * @param {Rectangle} hitArea - Bounds of the child + */ + _capHitArea(hitArea) { + if (hitArea.x < 0) { + hitArea.width += hitArea.x; + hitArea.x = 0; + } + if (hitArea.y < 0) { + hitArea.height += hitArea.y; + hitArea.y = 0; + } + const { width: viewWidth, height: viewHeight } = this._renderer; + if (hitArea.x + hitArea.width > viewWidth) { + hitArea.width = viewWidth - hitArea.x; + } + if (hitArea.y + hitArea.height > viewHeight) { + hitArea.height = viewHeight - hitArea.y; + } + } + /** + * Adds a Container to the accessibility manager + * @private + * @param {Container} container - The child to make accessible. + */ + _addChild(container) { + let div = this._pool.pop(); + if (!div) { + div = document.createElement("button"); + div.style.width = `${DIV_TOUCH_SIZE}px`; + div.style.height = `${DIV_TOUCH_SIZE}px`; + div.style.backgroundColor = this.debug ? "rgba(255,255,255,0.5)" : "transparent"; + div.style.position = "absolute"; + div.style.zIndex = DIV_TOUCH_ZINDEX.toString(); + div.style.borderStyle = "none"; + if (navigator.userAgent.toLowerCase().includes("chrome")) { + div.setAttribute("aria-live", "off"); + } else { + div.setAttribute("aria-live", "polite"); + } + if (navigator.userAgent.match(/rv:.*Gecko\//)) { + div.setAttribute("aria-relevant", "additions"); + } else { + div.setAttribute("aria-relevant", "text"); + } + div.addEventListener("click", this._onClick.bind(this)); + div.addEventListener("focus", this._onFocus.bind(this)); + div.addEventListener("focusout", this._onFocusOut.bind(this)); + } + div.style.pointerEvents = container.accessiblePointerEvents; + div.type = container.accessibleType; + if (container.accessibleTitle && container.accessibleTitle !== null) { + div.title = container.accessibleTitle; + } else if (!container.accessibleHint || container.accessibleHint === null) { + div.title = `container ${container.tabIndex}`; + } + if (container.accessibleHint && container.accessibleHint !== null) { + div.setAttribute("aria-label", container.accessibleHint); + } + if (this.debug) { + this._updateDebugHTML(div); + } + container._accessibleActive = true; + container._accessibleDiv = div; + div.container = container; + this._children.push(container); + this._div.appendChild(container._accessibleDiv); + container._accessibleDiv.tabIndex = container.tabIndex; + } + /** + * Dispatch events with the EventSystem. + * @param e + * @param type + * @private + */ + _dispatchEvent(e, type) { + const { container: target } = e.target; + const boundary = this._renderer.events.rootBoundary; + const event = Object.assign(new FederatedEvent(boundary), { target }); + boundary.rootTarget = this._renderer.lastObjectRendered; + type.forEach((type2) => boundary.dispatchEvent(event, type2)); + } + /** + * Maps the div button press to pixi's EventSystem (click) + * @private + * @param {MouseEvent} e - The click event. + */ + _onClick(e) { + this._dispatchEvent(e, ["click", "pointertap", "tap"]); + } + /** + * Maps the div focus events to pixi's EventSystem (mouseover) + * @private + * @param {FocusEvent} e - The focus event. + */ + _onFocus(e) { + if (!e.target.getAttribute("aria-live")) { + e.target.setAttribute("aria-live", "assertive"); + } + this._dispatchEvent(e, ["mouseover"]); + } + /** + * Maps the div focus events to pixi's EventSystem (mouseout) + * @private + * @param {FocusEvent} e - The focusout event. + */ + _onFocusOut(e) { + if (!e.target.getAttribute("aria-live")) { + e.target.setAttribute("aria-live", "polite"); + } + this._dispatchEvent(e, ["mouseout"]); + } + /** + * Is called when a key is pressed + * @private + * @param {KeyboardEvent} e - The keydown event. + */ + _onKeyDown(e) { + if (e.keyCode !== KEY_CODE_TAB) { + return; + } + this._activate(); + } + /** + * Is called when the mouse moves across the renderer element + * @private + * @param {MouseEvent} e - The mouse event. + */ + _onMouseMove(e) { + if (e.movementX === 0 && e.movementY === 0) { + return; + } + this._deactivate(); + } + /** Destroys the accessibility manager */ + destroy() { + this._destroyTouchHook(); + this._div = null; + globalThis.document.removeEventListener("mousemove", this._onMouseMove, true); + globalThis.removeEventListener("keydown", this._onKeyDown); + this._pool = null; + this._children = null; + this._renderer = null; + } +} +/** @ignore */ +AccessibilitySystem.extension = { + type: [ + ExtensionType.WebGLSystem, + ExtensionType.WebGPUSystem + ], + name: "accessibility" +}; + +"use strict"; +const accessibilityTarget = { + /** + * Flag for if the object is accessible. If true AccessibilityManager will overlay a + * shadow div with attributes set + * @member {boolean} + * @memberof scene.Container# + */ + accessible: false, + /** + * Sets the title attribute of the shadow div + * If accessibleTitle AND accessibleHint has not been this will default to 'container [tabIndex]' + * @member {string} + * @memberof scene.Container# + */ + accessibleTitle: null, + /** + * Sets the aria-label attribute of the shadow div + * @member {string} + * @memberof scene.Container# + */ + accessibleHint: null, + /** + * @member {number} + * @memberof scene.Container# + * @todo Needs docs. + */ + tabIndex: 0, + /** + * @member {boolean} + * @memberof scene.Container# + * @private + */ + _accessibleActive: false, + /** + * @memberof scene.Container# + * @private + */ + _accessibleDiv: null, + /** + * Specify the type of div the accessible layer is. Screen readers treat the element differently + * depending on this type. Defaults to button. + * @member {string} + * @memberof scene.Container# + * @default 'button' + */ + accessibleType: "button", + /** + * Specify the pointer-events the accessible div will use + * Defaults to auto. + * @type {PointerEvents} + * @memberof scene.Container# + * @default 'auto' + */ + accessiblePointerEvents: "auto", + /** + * Setting to false will prevent any children inside this container to + * be accessible. Defaults to true. + * @member {boolean} + * @memberof scene.Container# + * @default true + */ + accessibleChildren: true, + /** + * @member {number} + * @memberof scene.Container# + * @private + */ + _renderId: -1 +}; + +"use strict"; +extensions.add(AccessibilitySystem); +Container.mixin(accessibilityTarget); + +"use strict"; +class ResizePlugin { + /** + * Initialize the plugin with scope of application instance + * @static + * @private + * @param {object} [options] - See application options + */ + static init(options) { + Object.defineProperty( + this, + "resizeTo", + /** + * The HTML element or window to automatically resize the + * renderer's view element to match width and height. + * @member {Window|HTMLElement} + * @name resizeTo + * @memberof app.Application# + */ + { + set(dom) { + globalThis.removeEventListener("resize", this.queueResize); + this._resizeTo = dom; + if (dom) { + globalThis.addEventListener("resize", this.queueResize); + this.resize(); + } + }, + get() { + return this._resizeTo; + } + } + ); + this.queueResize = () => { + if (!this._resizeTo) { + return; + } + this._cancelResize(); + this._resizeId = requestAnimationFrame(() => this.resize()); + }; + this._cancelResize = () => { + if (this._resizeId) { + cancelAnimationFrame(this._resizeId); + this._resizeId = null; + } + }; + this.resize = () => { + if (!this._resizeTo) { + return; + } + this._cancelResize(); + let width; + let height; + if (this._resizeTo === globalThis.window) { + width = globalThis.innerWidth; + height = globalThis.innerHeight; + } else { + const { clientWidth, clientHeight } = this._resizeTo; + width = clientWidth; + height = clientHeight; + } + this.renderer.resize(width, height); + this.render(); + }; + this._resizeId = null; + this._resizeTo = null; + this.resizeTo = options.resizeTo || null; + } + /** + * Clean up the ticker, scoped to application + * @static + * @private + */ + static destroy() { + globalThis.removeEventListener("resize", this.queueResize); + this._cancelResize(); + this._cancelResize = null; + this.queueResize = null; + this.resizeTo = null; + this.resize = null; + } +} +/** @ignore */ +ResizePlugin.extension = ExtensionType.Application; + +"use strict"; +var UPDATE_PRIORITY = /* @__PURE__ */ ((UPDATE_PRIORITY2) => { + UPDATE_PRIORITY2[UPDATE_PRIORITY2["INTERACTION"] = 50] = "INTERACTION"; + UPDATE_PRIORITY2[UPDATE_PRIORITY2["HIGH"] = 25] = "HIGH"; + UPDATE_PRIORITY2[UPDATE_PRIORITY2["NORMAL"] = 0] = "NORMAL"; + UPDATE_PRIORITY2[UPDATE_PRIORITY2["LOW"] = -25] = "LOW"; + UPDATE_PRIORITY2[UPDATE_PRIORITY2["UTILITY"] = -50] = "UTILITY"; + return UPDATE_PRIORITY2; +})(UPDATE_PRIORITY || {}); + +"use strict"; +class TickerListener { + /** + * Constructor + * @private + * @param fn - The listener function to be added for one update + * @param context - The listener context + * @param priority - The priority for emitting + * @param once - If the handler should fire once + */ + constructor(fn, context = null, priority = 0, once = false) { + /** The next item in chain. */ + this.next = null; + /** The previous item in chain. */ + this.previous = null; + /** `true` if this listener has been destroyed already. */ + this._destroyed = false; + this._fn = fn; + this._context = context; + this.priority = priority; + this._once = once; + } + /** + * Simple compare function to figure out if a function and context match. + * @param fn - The listener function to be added for one update + * @param context - The listener context + * @returns `true` if the listener match the arguments + */ + match(fn, context = null) { + return this._fn === fn && this._context === context; + } + /** + * Emit by calling the current function. + * @param ticker - The ticker emitting. + * @returns Next ticker + */ + emit(ticker) { + if (this._fn) { + if (this._context) { + this._fn.call(this._context, ticker); + } else { + this._fn(ticker); + } + } + const redirect = this.next; + if (this._once) { + this.destroy(true); + } + if (this._destroyed) { + this.next = null; + } + return redirect; + } + /** + * Connect to the list. + * @param previous - Input node, previous listener + */ + connect(previous) { + this.previous = previous; + if (previous.next) { + previous.next.previous = this; + } + this.next = previous.next; + previous.next = this; + } + /** + * Destroy and don't use after this. + * @param hard - `true` to remove the `next` reference, this + * is considered a hard destroy. Soft destroy maintains the next reference. + * @returns The listener to redirect while emitting or removing. + */ + destroy(hard = false) { + this._destroyed = true; + this._fn = null; + this._context = null; + if (this.previous) { + this.previous.next = this.next; + } + if (this.next) { + this.next.previous = this.previous; + } + const redirect = this.next; + this.next = hard ? null : redirect; + this.previous = null; + return redirect; + } +} + +"use strict"; +const _Ticker = class _Ticker { + constructor() { + /** + * Whether or not this ticker should invoke the method + * {@link ticker.Ticker#start|start} automatically when a listener is added. + */ + this.autoStart = false; + /** + * Scalar time value from last frame to this frame. + * This value is capped by setting {@link ticker.Ticker#minFPS|minFPS} + * and is scaled with {@link ticker.Ticker#speed|speed}. + * **Note:** The cap may be exceeded by scaling. + */ + this.deltaTime = 1; + /** + * The last time {@link ticker.Ticker#update|update} was invoked. + * This value is also reset internally outside of invoking + * update, but only when a new animation frame is requested. + * If the platform supports DOMHighResTimeStamp, + * this value will have a precision of 1 µs. + */ + this.lastTime = -1; + /** + * Factor of current {@link ticker.Ticker#deltaTime|deltaTime}. + * @example + * // Scales ticker.deltaTime to what would be + * // the equivalent of approximately 120 FPS + * ticker.speed = 2; + */ + this.speed = 1; + /** + * Whether or not this ticker has been started. + * `true` if {@link ticker.Ticker#start|start} has been called. + * `false` if {@link ticker.Ticker#stop|Stop} has been called. + * While `false`, this value may change to `true` in the + * event of {@link ticker.Ticker#autoStart|autoStart} being `true` + * and a listener is added. + */ + this.started = false; + /** Internal current frame request ID */ + this._requestId = null; + /** + * Internal value managed by minFPS property setter and getter. + * This is the maximum allowed milliseconds between updates. + */ + this._maxElapsedMS = 100; + /** + * Internal value managed by minFPS property setter and getter. + * This is the minimum allowed milliseconds between updates. + */ + this._minElapsedMS = 0; + /** If enabled, deleting is disabled.*/ + this._protected = false; + /** The last time keyframe was executed. Maintains a relatively fixed interval with the previous value. */ + this._lastFrame = -1; + this._head = new TickerListener(null, null, Infinity); + this.deltaMS = 1 / _Ticker.targetFPMS; + this.elapsedMS = 1 / _Ticker.targetFPMS; + this._tick = (time) => { + this._requestId = null; + if (this.started) { + this.update(time); + if (this.started && this._requestId === null && this._head.next) { + this._requestId = requestAnimationFrame(this._tick); + } + } + }; + } + /** + * Conditionally requests a new animation frame. + * If a frame has not already been requested, and if the internal + * emitter has listeners, a new frame is requested. + * @private + */ + _requestIfNeeded() { + if (this._requestId === null && this._head.next) { + this.lastTime = performance.now(); + this._lastFrame = this.lastTime; + this._requestId = requestAnimationFrame(this._tick); + } + } + /** + * Conditionally cancels a pending animation frame. + * @private + */ + _cancelIfNeeded() { + if (this._requestId !== null) { + cancelAnimationFrame(this._requestId); + this._requestId = null; + } + } + /** + * Conditionally requests a new animation frame. + * If the ticker has been started it checks if a frame has not already + * been requested, and if the internal emitter has listeners. If these + * conditions are met, a new frame is requested. If the ticker has not + * been started, but autoStart is `true`, then the ticker starts now, + * and continues with the previous conditions to request a new frame. + * @private + */ + _startIfPossible() { + if (this.started) { + this._requestIfNeeded(); + } else if (this.autoStart) { + this.start(); + } + } + /** + * Register a handler for tick events. Calls continuously unless + * it is removed or the ticker is stopped. + * @param fn - The listener function to be added for updates + * @param context - The listener context + * @param {number} [priority=UPDATE_PRIORITY.NORMAL] - The priority for emitting + * @returns This instance of a ticker + */ + add(fn, context, priority = UPDATE_PRIORITY.NORMAL) { + return this._addListener(new TickerListener(fn, context, priority)); + } + /** + * Add a handler for the tick event which is only execute once. + * @param fn - The listener function to be added for one update + * @param context - The listener context + * @param {number} [priority=UPDATE_PRIORITY.NORMAL] - The priority for emitting + * @returns This instance of a ticker + */ + addOnce(fn, context, priority = UPDATE_PRIORITY.NORMAL) { + return this._addListener(new TickerListener(fn, context, priority, true)); + } + /** + * Internally adds the event handler so that it can be sorted by priority. + * Priority allows certain handler (user, AnimatedSprite, Interaction) to be run + * before the rendering. + * @private + * @param listener - Current listener being added. + * @returns This instance of a ticker + */ + _addListener(listener) { + let current = this._head.next; + let previous = this._head; + if (!current) { + listener.connect(previous); + } else { + while (current) { + if (listener.priority > current.priority) { + listener.connect(previous); + break; + } + previous = current; + current = current.next; + } + if (!listener.previous) { + listener.connect(previous); + } + } + this._startIfPossible(); + return this; + } + /** + * Removes any handlers matching the function and context parameters. + * If no handlers are left after removing, then it cancels the animation frame. + * @param fn - The listener function to be removed + * @param context - The listener context to be removed + * @returns This instance of a ticker + */ + remove(fn, context) { + let listener = this._head.next; + while (listener) { + if (listener.match(fn, context)) { + listener = listener.destroy(); + } else { + listener = listener.next; + } + } + if (!this._head.next) { + this._cancelIfNeeded(); + } + return this; + } + /** + * The number of listeners on this ticker, calculated by walking through linked list + * @readonly + * @member {number} + */ + get count() { + if (!this._head) { + return 0; + } + let count = 0; + let current = this._head; + while (current = current.next) { + count++; + } + return count; + } + /** Starts the ticker. If the ticker has listeners a new animation frame is requested at this point. */ + start() { + if (!this.started) { + this.started = true; + this._requestIfNeeded(); + } + } + /** Stops the ticker. If the ticker has requested an animation frame it is canceled at this point. */ + stop() { + if (this.started) { + this.started = false; + this._cancelIfNeeded(); + } + } + /** Destroy the ticker and don't use after this. Calling this method removes all references to internal events. */ + destroy() { + if (!this._protected) { + this.stop(); + let listener = this._head.next; + while (listener) { + listener = listener.destroy(true); + } + this._head.destroy(); + this._head = null; + } + } + /** + * Triggers an update. An update entails setting the + * current {@link ticker.Ticker#elapsedMS|elapsedMS}, + * the current {@link ticker.Ticker#deltaTime|deltaTime}, + * invoking all listeners with current deltaTime, + * and then finally setting {@link ticker.Ticker#lastTime|lastTime} + * with the value of currentTime that was provided. + * This method will be called automatically by animation + * frame callbacks if the ticker instance has been started + * and listeners are added. + * @param {number} [currentTime=performance.now()] - the current time of execution + */ + update(currentTime = performance.now()) { + let elapsedMS; + if (currentTime > this.lastTime) { + elapsedMS = this.elapsedMS = currentTime - this.lastTime; + if (elapsedMS > this._maxElapsedMS) { + elapsedMS = this._maxElapsedMS; + } + elapsedMS *= this.speed; + if (this._minElapsedMS) { + const delta = currentTime - this._lastFrame | 0; + if (delta < this._minElapsedMS) { + return; + } + this._lastFrame = currentTime - delta % this._minElapsedMS; + } + this.deltaMS = elapsedMS; + this.deltaTime = this.deltaMS * _Ticker.targetFPMS; + const head = this._head; + let listener = head.next; + while (listener) { + listener = listener.emit(this); + } + if (!head.next) { + this._cancelIfNeeded(); + } + } else { + this.deltaTime = this.deltaMS = this.elapsedMS = 0; + } + this.lastTime = currentTime; + } + /** + * The frames per second at which this ticker is running. + * The default is approximately 60 in most modern browsers. + * **Note:** This does not factor in the value of + * {@link ticker.Ticker#speed|speed}, which is specific + * to scaling {@link ticker.Ticker#deltaTime|deltaTime}. + * @member {number} + * @readonly + */ + get FPS() { + return 1e3 / this.elapsedMS; + } + /** + * Manages the maximum amount of milliseconds allowed to + * elapse between invoking {@link ticker.Ticker#update|update}. + * This value is used to cap {@link ticker.Ticker#deltaTime|deltaTime}, + * but does not effect the measured value of {@link ticker.Ticker#FPS|FPS}. + * When setting this property it is clamped to a value between + * `0` and `Ticker.targetFPMS * 1000`. + * @member {number} + * @default 10 + */ + get minFPS() { + return 1e3 / this._maxElapsedMS; + } + set minFPS(fps) { + const minFPS = Math.min(this.maxFPS, fps); + const minFPMS = Math.min(Math.max(0, minFPS) / 1e3, _Ticker.targetFPMS); + this._maxElapsedMS = 1 / minFPMS; + } + /** + * Manages the minimum amount of milliseconds required to + * elapse between invoking {@link ticker.Ticker#update|update}. + * This will effect the measured value of {@link ticker.Ticker#FPS|FPS}. + * If it is set to `0`, then there is no limit; PixiJS will render as many frames as it can. + * Otherwise it will be at least `minFPS` + * @member {number} + * @default 0 + */ + get maxFPS() { + if (this._minElapsedMS) { + return Math.round(1e3 / this._minElapsedMS); + } + return 0; + } + set maxFPS(fps) { + if (fps === 0) { + this._minElapsedMS = 0; + } else { + const maxFPS = Math.max(this.minFPS, fps); + this._minElapsedMS = 1 / (maxFPS / 1e3); + } + } + /** + * The shared ticker instance used by {@link AnimatedSprite} and by + * {@link VideoResource} to update animation frames / video textures. + * + * It may also be used by {@link Application} if created with the `sharedTicker` option property set to true. + * + * The property {@link ticker.Ticker#autoStart|autoStart} is set to `true` for this instance. + * Please follow the examples for usage, including how to opt-out of auto-starting the shared ticker. + * @example + * import { Ticker } from 'pixi.js'; + * + * const ticker = Ticker.shared; + * // Set this to prevent starting this ticker when listeners are added. + * // By default this is true only for the Ticker.shared instance. + * ticker.autoStart = false; + * + * // FYI, call this to ensure the ticker is stopped. It should be stopped + * // if you have not attempted to render anything yet. + * ticker.stop(); + * + * // Call this when you are ready for a running shared ticker. + * ticker.start(); + * @example + * import { autoDetectRenderer, Container } from 'pixi.js'; + * + * // You may use the shared ticker to render... + * const renderer = autoDetectRenderer(); + * const stage = new Container(); + * document.body.appendChild(renderer.view); + * ticker.add((time) => renderer.render(stage)); + * + * // Or you can just update it manually. + * ticker.autoStart = false; + * ticker.stop(); + * const animate = (time) => { + * ticker.update(time); + * renderer.render(stage); + * requestAnimationFrame(animate); + * }; + * animate(performance.now()); + * @member {ticker.Ticker} + * @readonly + * @static + */ + static get shared() { + if (!_Ticker._shared) { + const shared = _Ticker._shared = new _Ticker(); + shared.autoStart = true; + shared._protected = true; + } + return _Ticker._shared; + } + /** + * The system ticker instance used by {@link BasePrepare} for core timing + * functionality that shouldn't usually need to be paused, unlike the `shared` + * ticker which drives visual animations and rendering which may want to be paused. + * + * The property {@link ticker.Ticker#autoStart|autoStart} is set to `true` for this instance. + * @member {ticker.Ticker} + * @readonly + * @static + */ + static get system() { + if (!_Ticker._system) { + const system = _Ticker._system = new _Ticker(); + system.autoStart = true; + system._protected = true; + } + return _Ticker._system; + } +}; +/** + * Target frames per millisecond. + * @static + */ +_Ticker.targetFPMS = 0.06; +let Ticker = _Ticker; + +"use strict"; +class TickerPlugin { + /** + * Initialize the plugin with scope of application instance + * @static + * @private + * @param {object} [options] - See application options + */ + static init(options) { + options = Object.assign({ + autoStart: true, + sharedTicker: false + }, options); + Object.defineProperty( + this, + "ticker", + { + set(ticker) { + if (this._ticker) { + this._ticker.remove(this.render, this); + } + this._ticker = ticker; + if (ticker) { + ticker.add(this.render, this, UPDATE_PRIORITY.LOW); + } + }, + get() { + return this._ticker; + } + } + ); + this.stop = () => { + this._ticker.stop(); + }; + this.start = () => { + this._ticker.start(); + }; + this._ticker = null; + this.ticker = options.sharedTicker ? Ticker.shared : new Ticker(); + if (options.autoStart) { + this.start(); + } + } + /** + * Clean up the ticker, scoped to application. + * @static + * @private + */ + static destroy() { + if (this._ticker) { + const oldTicker = this._ticker; + this.ticker = null; + oldTicker.destroy(); + } + } +} +/** @ignore */ +TickerPlugin.extension = ExtensionType.Application; + +"use strict"; +extensions.add(ResizePlugin); +extensions.add(TickerPlugin); + +"use strict"; +class EventsTickerClass { + constructor() { + /** The frequency that fake events will be fired. */ + this.interactionFrequency = 10; + this._deltaTime = 0; + this._didMove = false; + this._tickerAdded = false; + this._pauseUpdate = true; + } + /** + * Initializes the event ticker. + * @param events - The event system. + */ + init(events) { + this.removeTickerListener(); + this.events = events; + this.interactionFrequency = 10; + this._deltaTime = 0; + this._didMove = false; + this._tickerAdded = false; + this._pauseUpdate = true; + } + /** Whether to pause the update checks or not. */ + get pauseUpdate() { + return this._pauseUpdate; + } + set pauseUpdate(paused) { + this._pauseUpdate = paused; + } + /** Adds the ticker listener. */ + addTickerListener() { + if (this._tickerAdded || !this.domElement) { + return; + } + Ticker.system.add(this._tickerUpdate, this, UPDATE_PRIORITY.INTERACTION); + this._tickerAdded = true; + } + /** Removes the ticker listener. */ + removeTickerListener() { + if (!this._tickerAdded) { + return; + } + Ticker.system.remove(this._tickerUpdate, this); + this._tickerAdded = false; + } + /** Sets flag to not fire extra events when the user has already moved there mouse */ + pointerMoved() { + this._didMove = true; + } + /** Updates the state of interactive objects. */ + _update() { + if (!this.domElement || this._pauseUpdate) { + return; + } + if (this._didMove) { + this._didMove = false; + return; + } + const rootPointerEvent = this.events["_rootPointerEvent"]; + if (this.events.supportsTouchEvents && rootPointerEvent.pointerType === "touch") { + return; + } + globalThis.document.dispatchEvent(new PointerEvent("pointermove", { + clientX: rootPointerEvent.clientX, + clientY: rootPointerEvent.clientY + })); + } + /** + * Updates the state of interactive objects if at least {@link interactionFrequency} + * milliseconds have passed since the last invocation. + * + * Invoked by a throttled ticker update from {@link Ticker.system}. + * @param ticker - The throttled ticker. + */ + _tickerUpdate(ticker) { + this._deltaTime += ticker.deltaTime; + if (this._deltaTime < this.interactionFrequency) { + return; + } + this._deltaTime = 0; + this._update(); + } +} +const EventsTicker = new EventsTickerClass(); + +"use strict"; +class FederatedMouseEvent extends FederatedEvent { + constructor() { + super(...arguments); + /** The coordinates of the mouse event relative to the canvas. */ + this.client = new Point(); + /** The movement in this pointer relative to the last `mousemove` event. */ + this.movement = new Point(); + /** The offset of the pointer coordinates w.r.t. target Container in world space. This is not supported at the moment. */ + this.offset = new Point(); + /** The pointer coordinates in world space. */ + this.global = new Point(); + /** + * The pointer coordinates in the renderer's {@link Renderer.screen screen}. This has slightly + * different semantics than native PointerEvent screenX/screenY. + */ + this.screen = new Point(); + } + /** @readonly */ + get clientX() { + return this.client.x; + } + /** @readonly */ + get clientY() { + return this.client.y; + } + /** + * Alias for {@link FederatedMouseEvent.clientX this.clientX}. + * @readonly + */ + get x() { + return this.clientX; + } + /** + * Alias for {@link FederatedMouseEvent.clientY this.clientY}. + * @readonly + */ + get y() { + return this.clientY; + } + /** @readonly */ + get movementX() { + return this.movement.x; + } + /** @readonly */ + get movementY() { + return this.movement.y; + } + /** @readonly */ + get offsetX() { + return this.offset.x; + } + /** @readonly */ + get offsetY() { + return this.offset.y; + } + /** @readonly */ + get globalX() { + return this.global.x; + } + /** @readonly */ + get globalY() { + return this.global.y; + } + /** + * The pointer coordinates in the renderer's screen. Alias for {@code screen.x}. + * @readonly + */ + get screenX() { + return this.screen.x; + } + /** + * The pointer coordinates in the renderer's screen. Alias for {@code screen.y}. + * @readonly + */ + get screenY() { + return this.screen.y; + } + /** + * This will return the local coordinates of the specified container for this InteractionData + * @param {Container} container - The Container that you would like the local + * coords off + * @param {PointData} point - A Point object in which to store the value, optional (otherwise + * will create a new point) + * @param {PointData} globalPos - A Point object containing your custom global coords, optional + * (otherwise will use the current global coords) + * @returns - A point containing the coordinates of the InteractionData position relative + * to the Container + */ + getLocalPosition(container, point, globalPos) { + return container.worldTransform.applyInverse(globalPos || this.global, point); + } + /** + * Whether the modifier key was pressed when this event natively occurred. + * @param key - The modifier key. + */ + getModifierState(key) { + return "getModifierState" in this.nativeEvent && this.nativeEvent.getModifierState(key); + } + /** + * Not supported. + * @param _typeArg + * @param _canBubbleArg + * @param _cancelableArg + * @param _viewArg + * @param _detailArg + * @param _screenXArg + * @param _screenYArg + * @param _clientXArg + * @param _clientYArg + * @param _ctrlKeyArg + * @param _altKeyArg + * @param _shiftKeyArg + * @param _metaKeyArg + * @param _buttonArg + * @param _relatedTargetArg + * @deprecated since 7.0.0 + */ + // eslint-disable-next-line max-params + initMouseEvent(_typeArg, _canBubbleArg, _cancelableArg, _viewArg, _detailArg, _screenXArg, _screenYArg, _clientXArg, _clientYArg, _ctrlKeyArg, _altKeyArg, _shiftKeyArg, _metaKeyArg, _buttonArg, _relatedTargetArg) { + throw new Error("Method not implemented."); + } +} + +"use strict"; +class FederatedPointerEvent extends FederatedMouseEvent { + constructor() { + super(...arguments); + /** + * The width of the pointer's contact along the x-axis, measured in CSS pixels. + * radiusX of TouchEvents will be represented by this value. + * @see https://developer.mozilla.org/en-US/docs/Web/API/PointerEvent/width + */ + this.width = 0; + /** + * The height of the pointer's contact along the y-axis, measured in CSS pixels. + * radiusY of TouchEvents will be represented by this value. + * @see https://developer.mozilla.org/en-US/docs/Web/API/PointerEvent/height + */ + this.height = 0; + /** + * Indicates whether or not the pointer device that created the event is the primary pointer. + * @see https://developer.mozilla.org/en-US/docs/Web/API/PointerEvent/isPrimary + */ + this.isPrimary = false; + } + // Only included for completeness for now + getCoalescedEvents() { + if (this.type === "pointermove" || this.type === "mousemove" || this.type === "touchmove") { + return [this]; + } + return []; + } + // Only included for completeness for now + getPredictedEvents() { + throw new Error("getPredictedEvents is not supported!"); + } +} + +"use strict"; +class FederatedWheelEvent extends FederatedMouseEvent { + constructor() { + super(...arguments); + /** Units specified in pixels. */ + this.DOM_DELTA_PIXEL = 0; + /** Units specified in lines. */ + this.DOM_DELTA_LINE = 1; + /** Units specified in pages. */ + this.DOM_DELTA_PAGE = 2; + } +} +/** Units specified in pixels. */ +FederatedWheelEvent.DOM_DELTA_PIXEL = 0; +/** Units specified in lines. */ +FederatedWheelEvent.DOM_DELTA_LINE = 1; +/** Units specified in pages. */ +FederatedWheelEvent.DOM_DELTA_PAGE = 2; + +"use strict"; +const PROPAGATION_LIMIT = 2048; +const tempHitLocation = new Point(); +const tempLocalMapping = new Point(); +class EventBoundary { + /** + * @param rootTarget - The holder of the event boundary. + */ + constructor(rootTarget) { + /** + * Emits events after they were dispatched into the scene graph. + * + * This can be used for global events listening, regardless of the scene graph being used. It should + * not be used by interactive libraries for normal use. + * + * Special events that do not bubble all the way to the root target are not emitted from here, + * e.g. pointerenter, pointerleave, click. + */ + this.dispatch = new EventEmitter(); + /** + * This flag would emit `pointermove`, `touchmove`, and `mousemove` events on all Containers. + * + * The `moveOnAll` semantics mirror those of earlier versions of PixiJS. This was disabled in favor of + * the Pointer Event API's approach. + */ + this.moveOnAll = false; + /** Enables the global move events. `globalpointermove`, `globaltouchmove`, and `globalmousemove` */ + this.enableGlobalMoveEvents = true; + /** + * State object for mapping methods. + * @see EventBoundary#trackingData + */ + this.mappingState = { + trackingData: {} + }; + /** + * The event pool maps event constructors to an free pool of instances of those specific events. + * @see EventBoundary#allocateEvent + * @see EventBoundary#freeEvent + */ + this.eventPool = /* @__PURE__ */ new Map(); + /** Every interactive element gathered from the scene. Only used in `pointermove` */ + this._allInteractiveElements = []; + /** Every element that passed the hit test. Only used in `pointermove` */ + this._hitElements = []; + /** Whether or not to collect all the interactive elements from the scene. Enabled in `pointermove` */ + this._isPointerMoveEvent = false; + this.rootTarget = rootTarget; + this.hitPruneFn = this.hitPruneFn.bind(this); + this.hitTestFn = this.hitTestFn.bind(this); + this.mapPointerDown = this.mapPointerDown.bind(this); + this.mapPointerMove = this.mapPointerMove.bind(this); + this.mapPointerOut = this.mapPointerOut.bind(this); + this.mapPointerOver = this.mapPointerOver.bind(this); + this.mapPointerUp = this.mapPointerUp.bind(this); + this.mapPointerUpOutside = this.mapPointerUpOutside.bind(this); + this.mapWheel = this.mapWheel.bind(this); + this.mappingTable = {}; + this.addEventMapping("pointerdown", this.mapPointerDown); + this.addEventMapping("pointermove", this.mapPointerMove); + this.addEventMapping("pointerout", this.mapPointerOut); + this.addEventMapping("pointerleave", this.mapPointerOut); + this.addEventMapping("pointerover", this.mapPointerOver); + this.addEventMapping("pointerup", this.mapPointerUp); + this.addEventMapping("pointerupoutside", this.mapPointerUpOutside); + this.addEventMapping("wheel", this.mapWheel); + } + /** + * Adds an event mapping for the event `type` handled by `fn`. + * + * Event mappings can be used to implement additional or custom events. They take an event + * coming from the upstream scene (or directly from the {@link EventSystem}) and dispatch new downstream events + * generally trickling down and bubbling up to {@link EventBoundary.rootTarget this.rootTarget}. + * + * To modify the semantics of existing events, the built-in mapping methods of EventBoundary should be overridden + * instead. + * @param type - The type of upstream event to map. + * @param fn - The mapping method. The context of this function must be bound manually, if desired. + */ + addEventMapping(type, fn) { + if (!this.mappingTable[type]) { + this.mappingTable[type] = []; + } + this.mappingTable[type].push({ + fn, + priority: 0 + }); + this.mappingTable[type].sort((a, b) => a.priority - b.priority); + } + /** + * Dispatches the given event + * @param e - The event to dispatch. + * @param type - The type of event to dispatch. Defaults to `e.type`. + */ + dispatchEvent(e, type) { + e.propagationStopped = false; + e.propagationImmediatelyStopped = false; + this.propagate(e, type); + this.dispatch.emit(type || e.type, e); + } + /** + * Maps the given upstream event through the event boundary and propagates it downstream. + * @param e - The event to map. + */ + mapEvent(e) { + if (!this.rootTarget) { + return; + } + const mappers = this.mappingTable[e.type]; + if (mappers) { + for (let i = 0, j = mappers.length; i < j; i++) { + mappers[i].fn(e); + } + } else { + warn(`[EventBoundary]: Event mapping not defined for ${e.type}`); + } + } + /** + * Finds the Container that is the target of a event at the given coordinates. + * + * The passed (x,y) coordinates are in the world space above this event boundary. + * @param x - The x coordinate of the event. + * @param y - The y coordinate of the event. + */ + hitTest(x, y) { + EventsTicker.pauseUpdate = true; + const useMove = this._isPointerMoveEvent && this.enableGlobalMoveEvents; + const fn = useMove ? "hitTestMoveRecursive" : "hitTestRecursive"; + const invertedPath = this[fn]( + this.rootTarget, + this.rootTarget.eventMode, + tempHitLocation.set(x, y), + this.hitTestFn, + this.hitPruneFn + ); + return invertedPath && invertedPath[0]; + } + /** + * Propagate the passed event from from {@link EventBoundary.rootTarget this.rootTarget} to its + * target {@code e.target}. + * @param e - The event to propagate. + * @param type - The type of event to propagate. Defaults to `e.type`. + */ + propagate(e, type) { + if (!e.target) { + return; + } + const composedPath = e.composedPath(); + e.eventPhase = e.CAPTURING_PHASE; + for (let i = 0, j = composedPath.length - 1; i < j; i++) { + e.currentTarget = composedPath[i]; + this.notifyTarget(e, type); + if (e.propagationStopped || e.propagationImmediatelyStopped) + return; + } + e.eventPhase = e.AT_TARGET; + e.currentTarget = e.target; + this.notifyTarget(e, type); + if (e.propagationStopped || e.propagationImmediatelyStopped) + return; + e.eventPhase = e.BUBBLING_PHASE; + for (let i = composedPath.length - 2; i >= 0; i--) { + e.currentTarget = composedPath[i]; + this.notifyTarget(e, type); + if (e.propagationStopped || e.propagationImmediatelyStopped) + return; + } + } + /** + * Emits the event {@code e} to all interactive containers. The event is propagated in the bubbling phase always. + * + * This is used in the `globalpointermove` event. + * @param e - The emitted event. + * @param type - The listeners to notify. + * @param targets - The targets to notify. + */ + all(e, type, targets = this._allInteractiveElements) { + if (targets.length === 0) + return; + e.eventPhase = e.BUBBLING_PHASE; + const events = Array.isArray(type) ? type : [type]; + for (let i = targets.length - 1; i >= 0; i--) { + events.forEach((event) => { + e.currentTarget = targets[i]; + this.notifyTarget(e, event); + }); + } + } + /** + * Finds the propagation path from {@link EventBoundary.rootTarget rootTarget} to the passed + * {@code target}. The last element in the path is {@code target}. + * @param target - The target to find the propagation path to. + */ + propagationPath(target) { + const propagationPath = [target]; + for (let i = 0; i < PROPAGATION_LIMIT && (target !== this.rootTarget && target.parent); i++) { + if (!target.parent) { + throw new Error("Cannot find propagation path to disconnected target"); + } + propagationPath.push(target.parent); + target = target.parent; + } + propagationPath.reverse(); + return propagationPath; + } + hitTestMoveRecursive(currentTarget, eventMode, location, testFn, pruneFn, ignore = false) { + let shouldReturn = false; + if (this._interactivePrune(currentTarget)) + return null; + if (currentTarget.eventMode === "dynamic" || eventMode === "dynamic") { + EventsTicker.pauseUpdate = false; + } + if (currentTarget.interactiveChildren && currentTarget.children) { + const children = currentTarget.children; + for (let i = children.length - 1; i >= 0; i--) { + const child = children[i]; + const nestedHit = this.hitTestMoveRecursive( + child, + this._isInteractive(eventMode) ? eventMode : child.eventMode, + location, + testFn, + pruneFn, + ignore || pruneFn(currentTarget, location) + ); + if (nestedHit) { + if (nestedHit.length > 0 && !nestedHit[nestedHit.length - 1].parent) { + continue; + } + const isInteractive = currentTarget.isInteractive(); + if (nestedHit.length > 0 || isInteractive) { + if (isInteractive) + this._allInteractiveElements.push(currentTarget); + nestedHit.push(currentTarget); + } + if (this._hitElements.length === 0) + this._hitElements = nestedHit; + shouldReturn = true; + } + } + } + const isInteractiveMode = this._isInteractive(eventMode); + const isInteractiveTarget = currentTarget.isInteractive(); + if (isInteractiveTarget && isInteractiveTarget) + this._allInteractiveElements.push(currentTarget); + if (ignore || this._hitElements.length > 0) + return null; + if (shouldReturn) + return this._hitElements; + if (isInteractiveMode && (!pruneFn(currentTarget, location) && testFn(currentTarget, location))) { + return isInteractiveTarget ? [currentTarget] : []; + } + return null; + } + /** + * Recursive implementation for {@link EventBoundary.hitTest hitTest}. + * @param currentTarget - The Container that is to be hit tested. + * @param eventMode - The event mode for the `currentTarget` or one of its parents. + * @param location - The location that is being tested for overlap. + * @param testFn - Callback that determines whether the target passes hit testing. This callback + * can assume that `pruneFn` failed to prune the container. + * @param pruneFn - Callback that determiness whether the target and all of its children + * cannot pass the hit test. It is used as a preliminary optimization to prune entire subtrees + * of the scene graph. + * @returns An array holding the hit testing target and all its ancestors in order. The first element + * is the target itself and the last is {@link EventBoundary.rootTarget rootTarget}. This is the opposite + * order w.r.t. the propagation path. If no hit testing target is found, null is returned. + */ + hitTestRecursive(currentTarget, eventMode, location, testFn, pruneFn) { + if (this._interactivePrune(currentTarget) || pruneFn(currentTarget, location)) { + return null; + } + if (currentTarget.eventMode === "dynamic" || eventMode === "dynamic") { + EventsTicker.pauseUpdate = false; + } + if (currentTarget.interactiveChildren && currentTarget.children) { + const children = currentTarget.children; + const relativeLocation = location; + for (let i = children.length - 1; i >= 0; i--) { + const child = children[i]; + const nestedHit = this.hitTestRecursive( + child, + this._isInteractive(eventMode) ? eventMode : child.eventMode, + relativeLocation, + testFn, + pruneFn + ); + if (nestedHit) { + if (nestedHit.length > 0 && !nestedHit[nestedHit.length - 1].parent) { + continue; + } + const isInteractive = currentTarget.isInteractive(); + if (nestedHit.length > 0 || isInteractive) + nestedHit.push(currentTarget); + return nestedHit; + } + } + } + const isInteractiveMode = this._isInteractive(eventMode); + const isInteractiveTarget = currentTarget.isInteractive(); + if (isInteractiveMode && testFn(currentTarget, location)) { + return isInteractiveTarget ? [currentTarget] : []; + } + return null; + } + _isInteractive(int) { + return int === "static" || int === "dynamic"; + } + _interactivePrune(container) { + if (!container || !container.visible || !container.renderable) { + return true; + } + if (container.eventMode === "none") { + return true; + } + if (container.eventMode === "passive" && !container.interactiveChildren) { + return true; + } + return false; + } + /** + * Checks whether the container or any of its children cannot pass the hit test at all. + * + * {@link EventBoundary}'s implementation uses the {@link Container.hitArea hitArea} + * and {@link Container._mask} for pruning. + * @param container - The container to prune. + * @param location - The location to test for overlap. + */ + hitPruneFn(container, location) { + if (container.hitArea) { + container.worldTransform.applyInverse(location, tempLocalMapping); + if (!container.hitArea.contains(tempLocalMapping.x, tempLocalMapping.y)) { + return true; + } + } + if (container.effects && container.effects.length) { + for (let i = 0; i < container.effects.length; i++) { + const effect = container.effects[i]; + if (effect.containsPoint) { + const effectContainsPoint = effect.containsPoint(location, this.hitTestFn); + if (!effectContainsPoint) { + return true; + } + } + } + } + return false; + } + /** + * Checks whether the container passes hit testing for the given location. + * @param container - The container to test. + * @param location - The location to test for overlap. + * @returns - Whether `container` passes hit testing for `location`. + */ + hitTestFn(container, location) { + if (container.hitArea) { + return true; + } + if (container == null ? void 0 : container.containsPoint) { + container.worldTransform.applyInverse(location, tempLocalMapping); + return container.containsPoint(tempLocalMapping); + } + return false; + } + /** + * Notify all the listeners to the event's `currentTarget`. + * + * If the `currentTarget` contains the property `on`, then it is called here, + * simulating the behavior from version 6.x and prior. + * @param e - The event passed to the target. + * @param type - The type of event to notify. Defaults to `e.type`. + */ + notifyTarget(e, type) { + var _a, _b; + type = type != null ? type : e.type; + const handlerKey = `on${type}`; + (_b = (_a = e.currentTarget)[handlerKey]) == null ? void 0 : _b.call(_a, e); + const key = e.eventPhase === e.CAPTURING_PHASE || e.eventPhase === e.AT_TARGET ? `${type}capture` : type; + this._notifyListeners(e, key); + if (e.eventPhase === e.AT_TARGET) { + this._notifyListeners(e, type); + } + } + /** + * Maps the upstream `pointerdown` events to a downstream `pointerdown` event. + * + * `touchstart`, `rightdown`, `mousedown` events are also dispatched for specific pointer types. + * @param from - The upstream `pointerdown` event. + */ + mapPointerDown(from) { + if (!(from instanceof FederatedPointerEvent)) { + warn("EventBoundary cannot map a non-pointer event as a pointer event"); + return; + } + const e = this.createPointerEvent(from); + this.dispatchEvent(e, "pointerdown"); + if (e.pointerType === "touch") { + this.dispatchEvent(e, "touchstart"); + } else if (e.pointerType === "mouse" || e.pointerType === "pen") { + const isRightButton = e.button === 2; + this.dispatchEvent(e, isRightButton ? "rightdown" : "mousedown"); + } + const trackingData = this.trackingData(from.pointerId); + trackingData.pressTargetsByButton[from.button] = e.composedPath(); + this.freeEvent(e); + } + /** + * Maps the upstream `pointermove` to downstream `pointerout`, `pointerover`, and `pointermove` events, in that order. + * + * The tracking data for the specific pointer has an updated `overTarget`. `mouseout`, `mouseover`, + * `mousemove`, and `touchmove` events are fired as well for specific pointer types. + * @param from - The upstream `pointermove` event. + */ + mapPointerMove(from) { + var _a, _b, _c; + if (!(from instanceof FederatedPointerEvent)) { + warn("EventBoundary cannot map a non-pointer event as a pointer event"); + return; + } + this._allInteractiveElements.length = 0; + this._hitElements.length = 0; + this._isPointerMoveEvent = true; + const e = this.createPointerEvent(from); + this._isPointerMoveEvent = false; + const isMouse = e.pointerType === "mouse" || e.pointerType === "pen"; + const trackingData = this.trackingData(from.pointerId); + const outTarget = this.findMountedTarget(trackingData.overTargets); + if (((_a = trackingData.overTargets) == null ? void 0 : _a.length) > 0 && outTarget !== e.target) { + const outType = from.type === "mousemove" ? "mouseout" : "pointerout"; + const outEvent = this.createPointerEvent(from, outType, outTarget); + this.dispatchEvent(outEvent, "pointerout"); + if (isMouse) + this.dispatchEvent(outEvent, "mouseout"); + if (!e.composedPath().includes(outTarget)) { + const leaveEvent = this.createPointerEvent(from, "pointerleave", outTarget); + leaveEvent.eventPhase = leaveEvent.AT_TARGET; + while (leaveEvent.target && !e.composedPath().includes(leaveEvent.target)) { + leaveEvent.currentTarget = leaveEvent.target; + this.notifyTarget(leaveEvent); + if (isMouse) + this.notifyTarget(leaveEvent, "mouseleave"); + leaveEvent.target = leaveEvent.target.parent; + } + this.freeEvent(leaveEvent); + } + this.freeEvent(outEvent); + } + if (outTarget !== e.target) { + const overType = from.type === "mousemove" ? "mouseover" : "pointerover"; + const overEvent = this.clonePointerEvent(e, overType); + this.dispatchEvent(overEvent, "pointerover"); + if (isMouse) + this.dispatchEvent(overEvent, "mouseover"); + let overTargetAncestor = outTarget == null ? void 0 : outTarget.parent; + while (overTargetAncestor && overTargetAncestor !== this.rootTarget.parent) { + if (overTargetAncestor === e.target) + break; + overTargetAncestor = overTargetAncestor.parent; + } + const didPointerEnter = !overTargetAncestor || overTargetAncestor === this.rootTarget.parent; + if (didPointerEnter) { + const enterEvent = this.clonePointerEvent(e, "pointerenter"); + enterEvent.eventPhase = enterEvent.AT_TARGET; + while (enterEvent.target && enterEvent.target !== outTarget && enterEvent.target !== this.rootTarget.parent) { + enterEvent.currentTarget = enterEvent.target; + this.notifyTarget(enterEvent); + if (isMouse) + this.notifyTarget(enterEvent, "mouseenter"); + enterEvent.target = enterEvent.target.parent; + } + this.freeEvent(enterEvent); + } + this.freeEvent(overEvent); + } + const allMethods = []; + const allowGlobalPointerEvents = (_b = this.enableGlobalMoveEvents) != null ? _b : true; + this.moveOnAll ? allMethods.push("pointermove") : this.dispatchEvent(e, "pointermove"); + allowGlobalPointerEvents && allMethods.push("globalpointermove"); + if (e.pointerType === "touch") { + this.moveOnAll ? allMethods.splice(1, 0, "touchmove") : this.dispatchEvent(e, "touchmove"); + allowGlobalPointerEvents && allMethods.push("globaltouchmove"); + } + if (isMouse) { + this.moveOnAll ? allMethods.splice(1, 0, "mousemove") : this.dispatchEvent(e, "mousemove"); + allowGlobalPointerEvents && allMethods.push("globalmousemove"); + this.cursor = (_c = e.target) == null ? void 0 : _c.cursor; + } + if (allMethods.length > 0) { + this.all(e, allMethods); + } + this._allInteractiveElements.length = 0; + this._hitElements.length = 0; + trackingData.overTargets = e.composedPath(); + this.freeEvent(e); + } + /** + * Maps the upstream `pointerover` to downstream `pointerover` and `pointerenter` events, in that order. + * + * The tracking data for the specific pointer gets a new `overTarget`. + * @param from - The upstream `pointerover` event. + */ + mapPointerOver(from) { + var _a; + if (!(from instanceof FederatedPointerEvent)) { + warn("EventBoundary cannot map a non-pointer event as a pointer event"); + return; + } + const trackingData = this.trackingData(from.pointerId); + const e = this.createPointerEvent(from); + const isMouse = e.pointerType === "mouse" || e.pointerType === "pen"; + this.dispatchEvent(e, "pointerover"); + if (isMouse) + this.dispatchEvent(e, "mouseover"); + if (e.pointerType === "mouse") + this.cursor = (_a = e.target) == null ? void 0 : _a.cursor; + const enterEvent = this.clonePointerEvent(e, "pointerenter"); + enterEvent.eventPhase = enterEvent.AT_TARGET; + while (enterEvent.target && enterEvent.target !== this.rootTarget.parent) { + enterEvent.currentTarget = enterEvent.target; + this.notifyTarget(enterEvent); + if (isMouse) + this.notifyTarget(enterEvent, "mouseenter"); + enterEvent.target = enterEvent.target.parent; + } + trackingData.overTargets = e.composedPath(); + this.freeEvent(e); + this.freeEvent(enterEvent); + } + /** + * Maps the upstream `pointerout` to downstream `pointerout`, `pointerleave` events, in that order. + * + * The tracking data for the specific pointer is cleared of a `overTarget`. + * @param from - The upstream `pointerout` event. + */ + mapPointerOut(from) { + if (!(from instanceof FederatedPointerEvent)) { + warn("EventBoundary cannot map a non-pointer event as a pointer event"); + return; + } + const trackingData = this.trackingData(from.pointerId); + if (trackingData.overTargets) { + const isMouse = from.pointerType === "mouse" || from.pointerType === "pen"; + const outTarget = this.findMountedTarget(trackingData.overTargets); + const outEvent = this.createPointerEvent(from, "pointerout", outTarget); + this.dispatchEvent(outEvent); + if (isMouse) + this.dispatchEvent(outEvent, "mouseout"); + const leaveEvent = this.createPointerEvent(from, "pointerleave", outTarget); + leaveEvent.eventPhase = leaveEvent.AT_TARGET; + while (leaveEvent.target && leaveEvent.target !== this.rootTarget.parent) { + leaveEvent.currentTarget = leaveEvent.target; + this.notifyTarget(leaveEvent); + if (isMouse) + this.notifyTarget(leaveEvent, "mouseleave"); + leaveEvent.target = leaveEvent.target.parent; + } + trackingData.overTargets = null; + this.freeEvent(outEvent); + this.freeEvent(leaveEvent); + } + this.cursor = null; + } + /** + * Maps the upstream `pointerup` event to downstream `pointerup`, `pointerupoutside`, + * and `click`/`rightclick`/`pointertap` events, in that order. + * + * The `pointerupoutside` event bubbles from the original `pointerdown` target to the most specific + * ancestor of the `pointerdown` and `pointerup` targets, which is also the `click` event's target. `touchend`, + * `rightup`, `mouseup`, `touchendoutside`, `rightupoutside`, `mouseupoutside`, and `tap` are fired as well for + * specific pointer types. + * @param from - The upstream `pointerup` event. + */ + mapPointerUp(from) { + if (!(from instanceof FederatedPointerEvent)) { + warn("EventBoundary cannot map a non-pointer event as a pointer event"); + return; + } + const now = performance.now(); + const e = this.createPointerEvent(from); + this.dispatchEvent(e, "pointerup"); + if (e.pointerType === "touch") { + this.dispatchEvent(e, "touchend"); + } else if (e.pointerType === "mouse" || e.pointerType === "pen") { + const isRightButton = e.button === 2; + this.dispatchEvent(e, isRightButton ? "rightup" : "mouseup"); + } + const trackingData = this.trackingData(from.pointerId); + const pressTarget = this.findMountedTarget(trackingData.pressTargetsByButton[from.button]); + let clickTarget = pressTarget; + if (pressTarget && !e.composedPath().includes(pressTarget)) { + let currentTarget = pressTarget; + while (currentTarget && !e.composedPath().includes(currentTarget)) { + e.currentTarget = currentTarget; + this.notifyTarget(e, "pointerupoutside"); + if (e.pointerType === "touch") { + this.notifyTarget(e, "touchendoutside"); + } else if (e.pointerType === "mouse" || e.pointerType === "pen") { + const isRightButton = e.button === 2; + this.notifyTarget(e, isRightButton ? "rightupoutside" : "mouseupoutside"); + } + currentTarget = currentTarget.parent; + } + delete trackingData.pressTargetsByButton[from.button]; + clickTarget = currentTarget; + } + if (clickTarget) { + const clickEvent = this.clonePointerEvent(e, "click"); + clickEvent.target = clickTarget; + clickEvent.path = null; + if (!trackingData.clicksByButton[from.button]) { + trackingData.clicksByButton[from.button] = { + clickCount: 0, + target: clickEvent.target, + timeStamp: now + }; + } + const clickHistory = trackingData.clicksByButton[from.button]; + if (clickHistory.target === clickEvent.target && now - clickHistory.timeStamp < 200) { + ++clickHistory.clickCount; + } else { + clickHistory.clickCount = 1; + } + clickHistory.target = clickEvent.target; + clickHistory.timeStamp = now; + clickEvent.detail = clickHistory.clickCount; + if (clickEvent.pointerType === "mouse") { + const isRightButton = clickEvent.button === 2; + this.dispatchEvent(clickEvent, isRightButton ? "rightclick" : "click"); + } else if (clickEvent.pointerType === "touch") { + this.dispatchEvent(clickEvent, "tap"); + } + this.dispatchEvent(clickEvent, "pointertap"); + this.freeEvent(clickEvent); + } + this.freeEvent(e); + } + /** + * Maps the upstream `pointerupoutside` event to a downstream `pointerupoutside` event, bubbling from the original + * `pointerdown` target to `rootTarget`. + * + * (The most specific ancestor of the `pointerdown` event and the `pointerup` event must the + * `{@link EventBoundary}'s root because the `pointerup` event occurred outside of the boundary.) + * + * `touchendoutside`, `mouseupoutside`, and `rightupoutside` events are fired as well for specific pointer + * types. The tracking data for the specific pointer is cleared of a `pressTarget`. + * @param from - The upstream `pointerupoutside` event. + */ + mapPointerUpOutside(from) { + if (!(from instanceof FederatedPointerEvent)) { + warn("EventBoundary cannot map a non-pointer event as a pointer event"); + return; + } + const trackingData = this.trackingData(from.pointerId); + const pressTarget = this.findMountedTarget(trackingData.pressTargetsByButton[from.button]); + const e = this.createPointerEvent(from); + if (pressTarget) { + let currentTarget = pressTarget; + while (currentTarget) { + e.currentTarget = currentTarget; + this.notifyTarget(e, "pointerupoutside"); + if (e.pointerType === "touch") { + this.notifyTarget(e, "touchendoutside"); + } else if (e.pointerType === "mouse" || e.pointerType === "pen") { + this.notifyTarget(e, e.button === 2 ? "rightupoutside" : "mouseupoutside"); + } + currentTarget = currentTarget.parent; + } + delete trackingData.pressTargetsByButton[from.button]; + } + this.freeEvent(e); + } + /** + * Maps the upstream `wheel` event to a downstream `wheel` event. + * @param from - The upstream `wheel` event. + */ + mapWheel(from) { + if (!(from instanceof FederatedWheelEvent)) { + warn("EventBoundary cannot map a non-wheel event as a wheel event"); + return; + } + const wheelEvent = this.createWheelEvent(from); + this.dispatchEvent(wheelEvent); + this.freeEvent(wheelEvent); + } + /** + * Finds the most specific event-target in the given propagation path that is still mounted in the scene graph. + * + * This is used to find the correct `pointerup` and `pointerout` target in the case that the original `pointerdown` + * or `pointerover` target was unmounted from the scene graph. + * @param propagationPath - The propagation path was valid in the past. + * @returns - The most specific event-target still mounted at the same location in the scene graph. + */ + findMountedTarget(propagationPath) { + if (!propagationPath) { + return null; + } + let currentTarget = propagationPath[0]; + for (let i = 1; i < propagationPath.length; i++) { + if (propagationPath[i].parent === currentTarget) { + currentTarget = propagationPath[i]; + } else { + break; + } + } + return currentTarget; + } + /** + * Creates an event whose {@code originalEvent} is {@code from}, with an optional `type` and `target` override. + * + * The event is allocated using {@link EventBoundary#allocateEvent this.allocateEvent}. + * @param from - The {@code originalEvent} for the returned event. + * @param [type=from.type] - The type of the returned event. + * @param target - The target of the returned event. + */ + createPointerEvent(from, type, target) { + var _a; + const event = this.allocateEvent(FederatedPointerEvent); + this.copyPointerData(from, event); + this.copyMouseData(from, event); + this.copyData(from, event); + event.nativeEvent = from.nativeEvent; + event.originalEvent = from; + event.target = (_a = target != null ? target : this.hitTest(event.global.x, event.global.y)) != null ? _a : this._hitElements[0]; + if (typeof type === "string") { + event.type = type; + } + return event; + } + /** + * Creates a wheel event whose {@code originalEvent} is {@code from}. + * + * The event is allocated using {@link EventBoundary#allocateEvent this.allocateEvent}. + * @param from - The upstream wheel event. + */ + createWheelEvent(from) { + const event = this.allocateEvent(FederatedWheelEvent); + this.copyWheelData(from, event); + this.copyMouseData(from, event); + this.copyData(from, event); + event.nativeEvent = from.nativeEvent; + event.originalEvent = from; + event.target = this.hitTest(event.global.x, event.global.y); + return event; + } + /** + * Clones the event {@code from}, with an optional {@code type} override. + * + * The event is allocated using {@link EventBoundary#allocateEvent this.allocateEvent}. + * @param from - The event to clone. + * @param [type=from.type] - The type of the returned event. + */ + clonePointerEvent(from, type) { + const event = this.allocateEvent(FederatedPointerEvent); + event.nativeEvent = from.nativeEvent; + event.originalEvent = from.originalEvent; + this.copyPointerData(from, event); + this.copyMouseData(from, event); + this.copyData(from, event); + event.target = from.target; + event.path = from.composedPath().slice(); + event.type = type != null ? type : event.type; + return event; + } + /** + * Copies wheel {@link FederatedWheelEvent} data from {@code from} into {@code to}. + * + * The following properties are copied: + * + deltaMode + * + deltaX + * + deltaY + * + deltaZ + * @param from - The event to copy data from. + * @param to - The event to copy data into. + */ + copyWheelData(from, to) { + to.deltaMode = from.deltaMode; + to.deltaX = from.deltaX; + to.deltaY = from.deltaY; + to.deltaZ = from.deltaZ; + } + /** + * Copies pointer {@link FederatedPointerEvent} data from {@code from} into {@code to}. + * + * The following properties are copied: + * + pointerId + * + width + * + height + * + isPrimary + * + pointerType + * + pressure + * + tangentialPressure + * + tiltX + * + tiltY + * @param from - The event to copy data from. + * @param to - The event to copy data into. + */ + copyPointerData(from, to) { + if (!(from instanceof FederatedPointerEvent && to instanceof FederatedPointerEvent)) + return; + to.pointerId = from.pointerId; + to.width = from.width; + to.height = from.height; + to.isPrimary = from.isPrimary; + to.pointerType = from.pointerType; + to.pressure = from.pressure; + to.tangentialPressure = from.tangentialPressure; + to.tiltX = from.tiltX; + to.tiltY = from.tiltY; + to.twist = from.twist; + } + /** + * Copies mouse {@link FederatedMouseEvent} data from {@code from} to {@code to}. + * + * The following properties are copied: + * + altKey + * + button + * + buttons + * + clientX + * + clientY + * + metaKey + * + movementX + * + movementY + * + pageX + * + pageY + * + x + * + y + * + screen + * + shiftKey + * + global + * @param from - The event to copy data from. + * @param to - The event to copy data into. + */ + copyMouseData(from, to) { + if (!(from instanceof FederatedMouseEvent && to instanceof FederatedMouseEvent)) + return; + to.altKey = from.altKey; + to.button = from.button; + to.buttons = from.buttons; + to.client.copyFrom(from.client); + to.ctrlKey = from.ctrlKey; + to.metaKey = from.metaKey; + to.movement.copyFrom(from.movement); + to.screen.copyFrom(from.screen); + to.shiftKey = from.shiftKey; + to.global.copyFrom(from.global); + } + /** + * Copies base {@link FederatedEvent} data from {@code from} into {@code to}. + * + * The following properties are copied: + * + isTrusted + * + srcElement + * + timeStamp + * + type + * @param from - The event to copy data from. + * @param to - The event to copy data into. + */ + copyData(from, to) { + to.isTrusted = from.isTrusted; + to.srcElement = from.srcElement; + to.timeStamp = performance.now(); + to.type = from.type; + to.detail = from.detail; + to.view = from.view; + to.which = from.which; + to.layer.copyFrom(from.layer); + to.page.copyFrom(from.page); + } + /** + * @param id - The pointer ID. + * @returns The tracking data stored for the given pointer. If no data exists, a blank + * state will be created. + */ + trackingData(id) { + if (!this.mappingState.trackingData[id]) { + this.mappingState.trackingData[id] = { + pressTargetsByButton: {}, + clicksByButton: {}, + overTarget: null + }; + } + return this.mappingState.trackingData[id]; + } + /** + * Allocate a specific type of event from {@link EventBoundary#eventPool this.eventPool}. + * + * This allocation is constructor-agnostic, as long as it only takes one argument - this event + * boundary. + * @param constructor - The event's constructor. + */ + allocateEvent(constructor) { + if (!this.eventPool.has(constructor)) { + this.eventPool.set(constructor, []); + } + const event = this.eventPool.get(constructor).pop() || new constructor(this); + event.eventPhase = event.NONE; + event.currentTarget = null; + event.path = null; + event.target = null; + return event; + } + /** + * Frees the event and puts it back into the event pool. + * + * It is illegal to reuse the event until it is allocated again, using `this.allocateEvent`. + * + * It is also advised that events not allocated from {@link EventBoundary#allocateEvent this.allocateEvent} + * not be freed. This is because of the possibility that the same event is freed twice, which can cause + * it to be allocated twice & result in overwriting. + * @param event - The event to be freed. + * @throws Error if the event is managed by another event boundary. + */ + freeEvent(event) { + if (event.manager !== this) + throw new Error("It is illegal to free an event not managed by this EventBoundary!"); + const constructor = event.constructor; + if (!this.eventPool.has(constructor)) { + this.eventPool.set(constructor, []); + } + this.eventPool.get(constructor).push(event); + } + /** + * Similar to {@link EventEmitter.emit}, except it stops if the `propagationImmediatelyStopped` flag + * is set on the event. + * @param e - The event to call each listener with. + * @param type - The event key. + */ + _notifyListeners(e, type) { + const listeners = e.currentTarget._events[type]; + if (!listeners) + return; + if (!e.currentTarget.isInteractive()) + return; + if ("fn" in listeners) { + if (listeners.once) + e.currentTarget.removeListener(type, listeners.fn, void 0, true); + listeners.fn.call(listeners.context, e); + } else { + for (let i = 0, j = listeners.length; i < j && !e.propagationImmediatelyStopped; i++) { + if (listeners[i].once) + e.currentTarget.removeListener(type, listeners[i].fn, void 0, true); + listeners[i].fn.call(listeners[i].context, e); + } + } + } +} + +"use strict"; +var __defProp$_ = Object.defineProperty; +var __getOwnPropSymbols$_ = Object.getOwnPropertySymbols; +var __hasOwnProp$_ = Object.prototype.hasOwnProperty; +var __propIsEnum$_ = Object.prototype.propertyIsEnumerable; +var __defNormalProp$_ = (obj, key, value) => key in obj ? __defProp$_(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; +var __spreadValues$_ = (a, b) => { + for (var prop in b || (b = {})) + if (__hasOwnProp$_.call(b, prop)) + __defNormalProp$_(a, prop, b[prop]); + if (__getOwnPropSymbols$_) + for (var prop of __getOwnPropSymbols$_(b)) { + if (__propIsEnum$_.call(b, prop)) + __defNormalProp$_(a, prop, b[prop]); + } + return a; +}; +const MOUSE_POINTER_ID = 1; +const TOUCH_TO_POINTER = { + touchstart: "pointerdown", + touchend: "pointerup", + touchendoutside: "pointerupoutside", + touchmove: "pointermove", + touchcancel: "pointercancel" +}; +const _EventSystem = class _EventSystem { + /** + * @param {Renderer} renderer + */ + constructor(renderer) { + /** Does the device support touch events https://www.w3.org/TR/touch-events/ */ + this.supportsTouchEvents = "ontouchstart" in globalThis; + /** Does the device support pointer events https://www.w3.org/Submission/pointer-events/ */ + this.supportsPointerEvents = !!globalThis.PointerEvent; + /** + * The DOM element to which the root event listeners are bound. This is automatically set to + * the renderer's {@link Renderer#view view}. + */ + this.domElement = null; + /** The resolution used to convert between the DOM client space into world space. */ + this.resolution = 1; + this.renderer = renderer; + this.rootBoundary = new EventBoundary(null); + EventsTicker.init(this); + this.autoPreventDefault = true; + this._eventsAdded = false; + this._rootPointerEvent = new FederatedPointerEvent(null); + this._rootWheelEvent = new FederatedWheelEvent(null); + this.cursorStyles = { + default: "inherit", + pointer: "pointer" + }; + this.features = new Proxy(__spreadValues$_({}, _EventSystem.defaultEventFeatures), { + set: (target, key, value) => { + if (key === "globalMove") { + this.rootBoundary.enableGlobalMoveEvents = value; + } + target[key] = value; + return true; + } + }); + this._onPointerDown = this._onPointerDown.bind(this); + this._onPointerMove = this._onPointerMove.bind(this); + this._onPointerUp = this._onPointerUp.bind(this); + this._onPointerOverOut = this._onPointerOverOut.bind(this); + this.onWheel = this.onWheel.bind(this); + } + /** + * The default interaction mode for all display objects. + * @see Container.eventMode + * @type {EventMode} + * @readonly + * @since 7.2.0 + */ + static get defaultEventMode() { + return this._defaultEventMode; + } + /** + * Runner init called, view is available at this point. + * @ignore + */ + init(options) { + var _a, _b; + const { canvas, resolution } = this.renderer; + this.setTargetElement(canvas); + this.resolution = resolution; + _EventSystem._defaultEventMode = (_a = options.eventMode) != null ? _a : "passive"; + Object.assign(this.features, (_b = options.eventFeatures) != null ? _b : {}); + this.rootBoundary.enableGlobalMoveEvents = this.features.globalMove; + } + /** + * Handle changing resolution. + * @ignore + */ + resolutionChange(resolution) { + this.resolution = resolution; + } + /** Destroys all event listeners and detaches the renderer. */ + destroy() { + this.setTargetElement(null); + this.renderer = null; + this._currentCursor = null; + } + /** + * Sets the current cursor mode, handling any callbacks or CSS style changes. + * @param mode - cursor mode, a key from the cursorStyles dictionary + */ + setCursor(mode) { + mode = mode || "default"; + let applyStyles = true; + if (globalThis.OffscreenCanvas && this.domElement instanceof OffscreenCanvas) { + applyStyles = false; + } + if (this._currentCursor === mode) { + return; + } + this._currentCursor = mode; + const style = this.cursorStyles[mode]; + if (style) { + switch (typeof style) { + case "string": + if (applyStyles) { + this.domElement.style.cursor = style; + } + break; + case "function": + style(mode); + break; + case "object": + if (applyStyles) { + Object.assign(this.domElement.style, style); + } + break; + } + } else if (applyStyles && typeof mode === "string" && !Object.prototype.hasOwnProperty.call(this.cursorStyles, mode)) { + this.domElement.style.cursor = mode; + } + } + /** + * The global pointer event. + * Useful for getting the pointer position without listening to events. + * @since 7.2.0 + */ + get pointer() { + return this._rootPointerEvent; + } + /** + * Event handler for pointer down events on {@link EventSystem#domElement this.domElement}. + * @param nativeEvent - The native mouse/pointer/touch event. + */ + _onPointerDown(nativeEvent) { + if (!this.features.click) + return; + this.rootBoundary.rootTarget = this.renderer.lastObjectRendered; + const events = this._normalizeToPointerData(nativeEvent); + if (this.autoPreventDefault && events[0].isNormalized) { + const cancelable = nativeEvent.cancelable || !("cancelable" in nativeEvent); + if (cancelable) { + nativeEvent.preventDefault(); + } + } + for (let i = 0, j = events.length; i < j; i++) { + const nativeEvent2 = events[i]; + const federatedEvent = this._bootstrapEvent(this._rootPointerEvent, nativeEvent2); + this.rootBoundary.mapEvent(federatedEvent); + } + this.setCursor(this.rootBoundary.cursor); + } + /** + * Event handler for pointer move events on on {@link EventSystem#domElement this.domElement}. + * @param nativeEvent - The native mouse/pointer/touch events. + */ + _onPointerMove(nativeEvent) { + if (!this.features.move) + return; + this.rootBoundary.rootTarget = this.renderer.lastObjectRendered; + EventsTicker.pointerMoved(); + const normalizedEvents = this._normalizeToPointerData(nativeEvent); + for (let i = 0, j = normalizedEvents.length; i < j; i++) { + const event = this._bootstrapEvent(this._rootPointerEvent, normalizedEvents[i]); + this.rootBoundary.mapEvent(event); + } + this.setCursor(this.rootBoundary.cursor); + } + /** + * Event handler for pointer up events on {@link EventSystem#domElement this.domElement}. + * @param nativeEvent - The native mouse/pointer/touch event. + */ + _onPointerUp(nativeEvent) { + if (!this.features.click) + return; + this.rootBoundary.rootTarget = this.renderer.lastObjectRendered; + let target = nativeEvent.target; + if (nativeEvent.composedPath && nativeEvent.composedPath().length > 0) { + target = nativeEvent.composedPath()[0]; + } + const outside = target !== this.domElement ? "outside" : ""; + const normalizedEvents = this._normalizeToPointerData(nativeEvent); + for (let i = 0, j = normalizedEvents.length; i < j; i++) { + const event = this._bootstrapEvent(this._rootPointerEvent, normalizedEvents[i]); + event.type += outside; + this.rootBoundary.mapEvent(event); + } + this.setCursor(this.rootBoundary.cursor); + } + /** + * Event handler for pointer over & out events on {@link EventSystem#domElement this.domElement}. + * @param nativeEvent - The native mouse/pointer/touch event. + */ + _onPointerOverOut(nativeEvent) { + if (!this.features.click) + return; + this.rootBoundary.rootTarget = this.renderer.lastObjectRendered; + const normalizedEvents = this._normalizeToPointerData(nativeEvent); + for (let i = 0, j = normalizedEvents.length; i < j; i++) { + const event = this._bootstrapEvent(this._rootPointerEvent, normalizedEvents[i]); + this.rootBoundary.mapEvent(event); + } + this.setCursor(this.rootBoundary.cursor); + } + /** + * Passive handler for `wheel` events on {@link EventSystem.domElement this.domElement}. + * @param nativeEvent - The native wheel event. + */ + onWheel(nativeEvent) { + if (!this.features.wheel) + return; + const wheelEvent = this.normalizeWheelEvent(nativeEvent); + this.rootBoundary.rootTarget = this.renderer.lastObjectRendered; + this.rootBoundary.mapEvent(wheelEvent); + } + /** + * Sets the {@link EventSystem#domElement domElement} and binds event listeners. + * + * To deregister the current DOM element without setting a new one, pass {@code null}. + * @param element - The new DOM element. + */ + setTargetElement(element) { + this._removeEvents(); + this.domElement = element; + EventsTicker.domElement = element; + this._addEvents(); + } + /** Register event listeners on {@link Renderer#domElement this.domElement}. */ + _addEvents() { + if (this._eventsAdded || !this.domElement) { + return; + } + EventsTicker.addTickerListener(); + const style = this.domElement.style; + if (style) { + if (globalThis.navigator.msPointerEnabled) { + style.msContentZooming = "none"; + style.msTouchAction = "none"; + } else if (this.supportsPointerEvents) { + style.touchAction = "none"; + } + } + if (this.supportsPointerEvents) { + globalThis.document.addEventListener("pointermove", this._onPointerMove, true); + this.domElement.addEventListener("pointerdown", this._onPointerDown, true); + this.domElement.addEventListener("pointerleave", this._onPointerOverOut, true); + this.domElement.addEventListener("pointerover", this._onPointerOverOut, true); + globalThis.addEventListener("pointerup", this._onPointerUp, true); + } else { + globalThis.document.addEventListener("mousemove", this._onPointerMove, true); + this.domElement.addEventListener("mousedown", this._onPointerDown, true); + this.domElement.addEventListener("mouseout", this._onPointerOverOut, true); + this.domElement.addEventListener("mouseover", this._onPointerOverOut, true); + globalThis.addEventListener("mouseup", this._onPointerUp, true); + if (this.supportsTouchEvents) { + this.domElement.addEventListener("touchstart", this._onPointerDown, true); + this.domElement.addEventListener("touchend", this._onPointerUp, true); + this.domElement.addEventListener("touchmove", this._onPointerMove, true); + } + } + this.domElement.addEventListener("wheel", this.onWheel, { + passive: true, + capture: true + }); + this._eventsAdded = true; + } + /** Unregister event listeners on {@link EventSystem#domElement this.domElement}. */ + _removeEvents() { + if (!this._eventsAdded || !this.domElement) { + return; + } + EventsTicker.removeTickerListener(); + const style = this.domElement.style; + if (style) { + if (globalThis.navigator.msPointerEnabled) { + style.msContentZooming = ""; + style.msTouchAction = ""; + } else if (this.supportsPointerEvents) { + style.touchAction = ""; + } + } + if (this.supportsPointerEvents) { + globalThis.document.removeEventListener("pointermove", this._onPointerMove, true); + this.domElement.removeEventListener("pointerdown", this._onPointerDown, true); + this.domElement.removeEventListener("pointerleave", this._onPointerOverOut, true); + this.domElement.removeEventListener("pointerover", this._onPointerOverOut, true); + globalThis.removeEventListener("pointerup", this._onPointerUp, true); + } else { + globalThis.document.removeEventListener("mousemove", this._onPointerMove, true); + this.domElement.removeEventListener("mousedown", this._onPointerDown, true); + this.domElement.removeEventListener("mouseout", this._onPointerOverOut, true); + this.domElement.removeEventListener("mouseover", this._onPointerOverOut, true); + globalThis.removeEventListener("mouseup", this._onPointerUp, true); + if (this.supportsTouchEvents) { + this.domElement.removeEventListener("touchstart", this._onPointerDown, true); + this.domElement.removeEventListener("touchend", this._onPointerUp, true); + this.domElement.removeEventListener("touchmove", this._onPointerMove, true); + } + } + this.domElement.removeEventListener("wheel", this.onWheel, true); + this.domElement = null; + this._eventsAdded = false; + } + /** + * Maps x and y coords from a DOM object and maps them correctly to the PixiJS view. The + * resulting value is stored in the point. This takes into account the fact that the DOM + * element could be scaled and positioned anywhere on the screen. + * @param {PointData} point - the point that the result will be stored in + * @param {number} x - the x coord of the position to map + * @param {number} y - the y coord of the position to map + */ + mapPositionToPoint(point, x, y) { + const rect = this.domElement.isConnected ? this.domElement.getBoundingClientRect() : { + x: 0, + y: 0, + width: this.domElement.width, + height: this.domElement.height, + left: 0, + top: 0 + }; + const resolutionMultiplier = 1 / this.resolution; + point.x = (x - rect.left) * (this.domElement.width / rect.width) * resolutionMultiplier; + point.y = (y - rect.top) * (this.domElement.height / rect.height) * resolutionMultiplier; + } + /** + * Ensures that the original event object contains all data that a regular pointer event would have + * @param event - The original event data from a touch or mouse event + * @returns An array containing a single normalized pointer event, in the case of a pointer + * or mouse event, or a multiple normalized pointer events if there are multiple changed touches + */ + _normalizeToPointerData(event) { + const normalizedEvents = []; + if (this.supportsTouchEvents && event instanceof TouchEvent) { + for (let i = 0, li = event.changedTouches.length; i < li; i++) { + const touch = event.changedTouches[i]; + if (typeof touch.button === "undefined") + touch.button = 0; + if (typeof touch.buttons === "undefined") + touch.buttons = 1; + if (typeof touch.isPrimary === "undefined") { + touch.isPrimary = event.touches.length === 1 && event.type === "touchstart"; + } + if (typeof touch.width === "undefined") + touch.width = touch.radiusX || 1; + if (typeof touch.height === "undefined") + touch.height = touch.radiusY || 1; + if (typeof touch.tiltX === "undefined") + touch.tiltX = 0; + if (typeof touch.tiltY === "undefined") + touch.tiltY = 0; + if (typeof touch.pointerType === "undefined") + touch.pointerType = "touch"; + if (typeof touch.pointerId === "undefined") + touch.pointerId = touch.identifier || 0; + if (typeof touch.pressure === "undefined") + touch.pressure = touch.force || 0.5; + if (typeof touch.twist === "undefined") + touch.twist = 0; + if (typeof touch.tangentialPressure === "undefined") + touch.tangentialPressure = 0; + if (typeof touch.layerX === "undefined") + touch.layerX = touch.offsetX = touch.clientX; + if (typeof touch.layerY === "undefined") + touch.layerY = touch.offsetY = touch.clientY; + touch.isNormalized = true; + touch.type = event.type; + normalizedEvents.push(touch); + } + } else if (!globalThis.MouseEvent || event instanceof MouseEvent && (!this.supportsPointerEvents || !(event instanceof globalThis.PointerEvent))) { + const tempEvent = event; + if (typeof tempEvent.isPrimary === "undefined") + tempEvent.isPrimary = true; + if (typeof tempEvent.width === "undefined") + tempEvent.width = 1; + if (typeof tempEvent.height === "undefined") + tempEvent.height = 1; + if (typeof tempEvent.tiltX === "undefined") + tempEvent.tiltX = 0; + if (typeof tempEvent.tiltY === "undefined") + tempEvent.tiltY = 0; + if (typeof tempEvent.pointerType === "undefined") + tempEvent.pointerType = "mouse"; + if (typeof tempEvent.pointerId === "undefined") + tempEvent.pointerId = MOUSE_POINTER_ID; + if (typeof tempEvent.pressure === "undefined") + tempEvent.pressure = 0.5; + if (typeof tempEvent.twist === "undefined") + tempEvent.twist = 0; + if (typeof tempEvent.tangentialPressure === "undefined") + tempEvent.tangentialPressure = 0; + tempEvent.isNormalized = true; + normalizedEvents.push(tempEvent); + } else { + normalizedEvents.push(event); + } + return normalizedEvents; + } + /** + * Normalizes the native {@link https://w3c.github.io/uievents/#interface-wheelevent WheelEvent}. + * + * The returned {@link FederatedWheelEvent} is a shared instance. It will not persist across + * multiple native wheel events. + * @param nativeEvent - The native wheel event that occurred on the canvas. + * @returns A federated wheel event. + */ + normalizeWheelEvent(nativeEvent) { + const event = this._rootWheelEvent; + this._transferMouseData(event, nativeEvent); + event.deltaX = nativeEvent.deltaX; + event.deltaY = nativeEvent.deltaY; + event.deltaZ = nativeEvent.deltaZ; + event.deltaMode = nativeEvent.deltaMode; + this.mapPositionToPoint(event.screen, nativeEvent.clientX, nativeEvent.clientY); + event.global.copyFrom(event.screen); + event.offset.copyFrom(event.screen); + event.nativeEvent = nativeEvent; + event.type = nativeEvent.type; + return event; + } + /** + * Normalizes the `nativeEvent` into a federateed {@link FederatedPointerEvent}. + * @param event + * @param nativeEvent + */ + _bootstrapEvent(event, nativeEvent) { + event.originalEvent = null; + event.nativeEvent = nativeEvent; + event.pointerId = nativeEvent.pointerId; + event.width = nativeEvent.width; + event.height = nativeEvent.height; + event.isPrimary = nativeEvent.isPrimary; + event.pointerType = nativeEvent.pointerType; + event.pressure = nativeEvent.pressure; + event.tangentialPressure = nativeEvent.tangentialPressure; + event.tiltX = nativeEvent.tiltX; + event.tiltY = nativeEvent.tiltY; + event.twist = nativeEvent.twist; + this._transferMouseData(event, nativeEvent); + this.mapPositionToPoint(event.screen, nativeEvent.clientX, nativeEvent.clientY); + event.global.copyFrom(event.screen); + event.offset.copyFrom(event.screen); + event.isTrusted = nativeEvent.isTrusted; + if (event.type === "pointerleave") { + event.type = "pointerout"; + } + if (event.type.startsWith("mouse")) { + event.type = event.type.replace("mouse", "pointer"); + } + if (event.type.startsWith("touch")) { + event.type = TOUCH_TO_POINTER[event.type] || event.type; + } + return event; + } + /** + * Transfers base & mouse event data from the {@code nativeEvent} to the federated event. + * @param event + * @param nativeEvent + */ + _transferMouseData(event, nativeEvent) { + event.isTrusted = nativeEvent.isTrusted; + event.srcElement = nativeEvent.srcElement; + event.timeStamp = performance.now(); + event.type = nativeEvent.type; + event.altKey = nativeEvent.altKey; + event.button = nativeEvent.button; + event.buttons = nativeEvent.buttons; + event.client.x = nativeEvent.clientX; + event.client.y = nativeEvent.clientY; + event.ctrlKey = nativeEvent.ctrlKey; + event.metaKey = nativeEvent.metaKey; + event.movement.x = nativeEvent.movementX; + event.movement.y = nativeEvent.movementY; + event.page.x = nativeEvent.pageX; + event.page.y = nativeEvent.pageY; + event.relatedTarget = null; + event.shiftKey = nativeEvent.shiftKey; + } +}; +/** @ignore */ +_EventSystem.extension = { + name: "events", + type: [ + ExtensionType.WebGLSystem, + ExtensionType.CanvasSystem, + ExtensionType.WebGPUSystem + ], + priority: -1 +}; +/** + * The event features that are enabled by the EventSystem + * (included in the **pixi.js** and **pixi.js-legacy** bundle), otherwise it will be ignored. + * @since 7.2.0 + */ +_EventSystem.defaultEventFeatures = { + /** Enables pointer events associated with pointer movement. */ + move: true, + /** Enables global pointer move events. */ + globalMove: true, + /** Enables pointer events associated with clicking. */ + click: true, + /** Enables wheel events. */ + wheel: true +}; +let EventSystem = _EventSystem; + +"use strict"; +const FederatedContainer = { + /** + * Property-based event handler for the `click` event. + * @memberof scene.Container# + * @default null + * @example + * this.onclick = (event) => { + * //some function here that happens on click + * } + */ + onclick: null, + /** + * Property-based event handler for the `mousedown` event. + * @memberof scene.Container# + * @default null + * @example + * this.onmousedown = (event) => { + * //some function here that happens on mousedown + * } + */ + onmousedown: null, + /** + * Property-based event handler for the `mouseenter` event. + * @memberof scene.Container# + * @default null + * @example + * this.onmouseenter = (event) => { + * //some function here that happens on mouseenter + * } + */ + onmouseenter: null, + /** + * Property-based event handler for the `mouseleave` event. + * @memberof scene.Container# + * @default null + * @example + * this.onmouseleave = (event) => { + * //some function here that happens on mouseleave + * } + */ + onmouseleave: null, + /** + * Property-based event handler for the `mousemove` event. + * @memberof scene.Container# + * @default null + * @example + * this.onmousemove = (event) => { + * //some function here that happens on mousemove + * } + */ + onmousemove: null, + /** + * Property-based event handler for the `globalmousemove` event. + * @memberof scene.Container# + * @default null + * @example + * this.onglobalmousemove = (event) => { + * //some function here that happens on globalmousemove + * } + */ + onglobalmousemove: null, + /** + * Property-based event handler for the `mouseout` event. + * @memberof scene.Container# + * @default null + * @example + * this.onmouseout = (event) => { + * //some function here that happens on mouseout + * } + */ + onmouseout: null, + /** + * Property-based event handler for the `mouseover` event. + * @memberof scene.Container# + * @default null + * @example + * this.onmouseover = (event) => { + * //some function here that happens on mouseover + * } + */ + onmouseover: null, + /** + * Property-based event handler for the `mouseup` event. + * @memberof scene.Container# + * @default null + * @example + * this.onmouseup = (event) => { + * //some function here that happens on mouseup + * } + */ + onmouseup: null, + /** + * Property-based event handler for the `mouseupoutside` event. + * @memberof scene.Container# + * @default null + * @example + * this.onmouseupoutside = (event) => { + * //some function here that happens on mouseupoutside + * } + */ + onmouseupoutside: null, + /** + * Property-based event handler for the `pointercancel` event. + * @memberof scene.Container# + * @default null + * @example + * this.onpointercancel = (event) => { + * //some function here that happens on pointercancel + * } + */ + onpointercancel: null, + /** + * Property-based event handler for the `pointerdown` event. + * @memberof scene.Container# + * @default null + * @example + * this.onpointerdown = (event) => { + * //some function here that happens on pointerdown + * } + */ + onpointerdown: null, + /** + * Property-based event handler for the `pointerenter` event. + * @memberof scene.Container# + * @default null + * @example + * this.onpointerenter = (event) => { + * //some function here that happens on pointerenter + * } + */ + onpointerenter: null, + /** + * Property-based event handler for the `pointerleave` event. + * @memberof scene.Container# + * @default null + * @example + * this.onpointerleave = (event) => { + * //some function here that happens on pointerleave + * } + */ + onpointerleave: null, + /** + * Property-based event handler for the `pointermove` event. + * @memberof scene.Container# + * @default null + * @example + * this.onpointermove = (event) => { + * //some function here that happens on pointermove + * } + */ + onpointermove: null, + /** + * Property-based event handler for the `globalpointermove` event. + * @memberof scene.Container# + * @default null + * @example + * this.onglobalpointermove = (event) => { + * //some function here that happens on globalpointermove + * } + */ + onglobalpointermove: null, + /** + * Property-based event handler for the `pointerout` event. + * @memberof scene.Container# + * @default null + * @example + * this.onpointerout = (event) => { + * //some function here that happens on pointerout + * } + */ + onpointerout: null, + /** + * Property-based event handler for the `pointerover` event. + * @memberof scene.Container# + * @default null + * @example + * this.onpointerover = (event) => { + * //some function here that happens on pointerover + * } + */ + onpointerover: null, + /** + * Property-based event handler for the `pointertap` event. + * @memberof scene.Container# + * @default null + * @example + * this.onpointertap = (event) => { + * //some function here that happens on pointertap + * } + */ + onpointertap: null, + /** + * Property-based event handler for the `pointerup` event. + * @memberof scene.Container# + * @default null + * @example + * this.onpointerup = (event) => { + * //some function here that happens on pointerup + * } + */ + onpointerup: null, + /** + * Property-based event handler for the `pointerupoutside` event. + * @memberof scene.Container# + * @default null + * @example + * this.onpointerupoutside = (event) => { + * //some function here that happens on pointerupoutside + * } + */ + onpointerupoutside: null, + /** + * Property-based event handler for the `rightclick` event. + * @memberof scene.Container# + * @default null + * @example + * this.onrightclick = (event) => { + * //some function here that happens on rightclick + * } + */ + onrightclick: null, + /** + * Property-based event handler for the `rightdown` event. + * @memberof scene.Container# + * @default null + * @example + * this.onrightdown = (event) => { + * //some function here that happens on rightdown + * } + */ + onrightdown: null, + /** + * Property-based event handler for the `rightup` event. + * @memberof scene.Container# + * @default null + * @example + * this.onrightup = (event) => { + * //some function here that happens on rightup + * } + */ + onrightup: null, + /** + * Property-based event handler for the `rightupoutside` event. + * @memberof scene.Container# + * @default null + * @example + * this.onrightupoutside = (event) => { + * //some function here that happens on rightupoutside + * } + */ + onrightupoutside: null, + /** + * Property-based event handler for the `tap` event. + * @memberof scene.Container# + * @default null + * @example + * this.ontap = (event) => { + * //some function here that happens on tap + * } + */ + ontap: null, + /** + * Property-based event handler for the `touchcancel` event. + * @memberof scene.Container# + * @default null + * @example + * this.ontouchcancel = (event) => { + * //some function here that happens on touchcancel + * } + */ + ontouchcancel: null, + /** + * Property-based event handler for the `touchend` event. + * @memberof scene.Container# + * @default null + * @example + * this.ontouchend = (event) => { + * //some function here that happens on touchend + * } + */ + ontouchend: null, + /** + * Property-based event handler for the `touchendoutside` event. + * @memberof scene.Container# + * @default null + * @example + * this.ontouchendoutside = (event) => { + * //some function here that happens on touchendoutside + * } + */ + ontouchendoutside: null, + /** + * Property-based event handler for the `touchmove` event. + * @memberof scene.Container# + * @default null + * @example + * this.ontouchmove = (event) => { + * //some function here that happens on touchmove + * } + */ + ontouchmove: null, + /** + * Property-based event handler for the `globaltouchmove` event. + * @memberof scene.Container# + * @default null + * @example + * this.onglobaltouchmove = (event) => { + * //some function here that happens on globaltouchmove + * } + */ + onglobaltouchmove: null, + /** + * Property-based event handler for the `touchstart` event. + * @memberof scene.Container# + * @default null + * @example + * this.ontouchstart = (event) => { + * //some function here that happens on touchstart + * } + */ + ontouchstart: null, + /** + * Property-based event handler for the `wheel` event. + * @memberof scene.Container# + * @default null + * @example + * this.onwheel = (event) => { + * //some function here that happens on wheel + * } + */ + onwheel: null, + /** + * Enable interaction events for the Container. Touch, pointer and mouse + * @memberof scene.Container# + */ + get interactive() { + return this.eventMode === "dynamic" || this.eventMode === "static"; + }, + set interactive(value) { + this.eventMode = value ? "static" : "passive"; + }, + /** + * @ignore + */ + _internalEventMode: void 0, + /** + * Enable interaction events for the Container. Touch, pointer and mouse. + * There are 5 types of interaction settings: + * - `'none'`: Ignores all interaction events, even on its children. + * - `'passive'`: **(default)** Does not emit events and ignores all hit testing on itself and non-interactive children. + * Interactive children will still emit events. + * - `'auto'`: Does not emit events but is hit tested if parent is interactive. Same as `interactive = false` in v7 + * - `'static'`: Emit events and is hit tested. Same as `interaction = true` in v7 + * - `'dynamic'`: Emits events and is hit tested but will also receive mock interaction events fired from a ticker to + * allow for interaction when the mouse isn't moving + * @example + * import { Sprite } from 'pixi.js'; + * + * const sprite = new Sprite(texture); + * sprite.eventMode = 'static'; + * sprite.on('tap', (event) => { + * // Handle event + * }); + * @memberof scene.Container# + * @since 7.2.0 + */ + get eventMode() { + var _a; + return (_a = this._internalEventMode) != null ? _a : EventSystem.defaultEventMode; + }, + set eventMode(value) { + this._internalEventMode = value; + }, + /** + * Determines if the container is interactive or not + * @returns {boolean} Whether the container is interactive or not + * @memberof scene.Container# + * @since 7.2.0 + * @example + * import { Sprite } from 'pixi.js'; + * + * const sprite = new Sprite(texture); + * sprite.eventMode = 'static'; + * sprite.isInteractive(); // true + * + * sprite.eventMode = 'dynamic'; + * sprite.isInteractive(); // true + * + * sprite.eventMode = 'none'; + * sprite.isInteractive(); // false + * + * sprite.eventMode = 'passive'; + * sprite.isInteractive(); // false + * + * sprite.eventMode = 'auto'; + * sprite.isInteractive(); // false + */ + isInteractive() { + return this.eventMode === "static" || this.eventMode === "dynamic"; + }, + /** + * Determines if the children to the container can be clicked/touched + * Setting this to false allows PixiJS to bypass a recursive `hitTest` function + * @memberof scene.Container# + */ + interactiveChildren: true, + /** + * Interaction shape. Children will be hit first, then this shape will be checked. + * Setting this will cause this shape to be checked in hit tests rather than the container's bounds. + * @example + * import { Rectangle, Sprite } from 'pixi.js'; + * + * const sprite = new Sprite(texture); + * sprite.interactive = true; + * sprite.hitArea = new Rectangle(0, 0, 100, 100); + * @member {IHitArea} + * @memberof scene.Container# + */ + hitArea: null, + /** + * Unlike `on` or `addListener` which are methods from EventEmitter, `addEventListener` + * seeks to be compatible with the DOM's `addEventListener` with support for options. + * @memberof scene.Container + * @param type - The type of event to listen to. + * @param listener - The listener callback or object. + * @param options - Listener options, used for capture phase. + * @example + * // Tell the user whether they did a single, double, triple, or nth click. + * button.addEventListener('click', { + * handleEvent(e): { + * let prefix; + * + * switch (e.detail) { + * case 1: prefix = 'single'; break; + * case 2: prefix = 'double'; break; + * case 3: prefix = 'triple'; break; + * default: prefix = e.detail + 'th'; break; + * } + * + * console.log('That was a ' + prefix + 'click'); + * } + * }); + * + * // But skip the first click! + * button.parent.addEventListener('click', function blockClickOnce(e) { + * e.stopImmediatePropagation(); + * button.parent.removeEventListener('click', blockClickOnce, true); + * }, { + * capture: true, + * }); + */ + addEventListener(type, listener, options) { + const capture = typeof options === "boolean" && options || typeof options === "object" && options.capture; + const signal = typeof options === "object" ? options.signal : void 0; + const once = typeof options === "object" ? options.once === true : false; + const context = typeof listener === "function" ? void 0 : listener; + type = capture ? `${type}capture` : type; + const listenerFn = typeof listener === "function" ? listener : listener.handleEvent; + const emitter = this; + if (signal) { + signal.addEventListener("abort", () => { + emitter.off(type, listenerFn, context); + }); + } + if (once) { + emitter.once(type, listenerFn, context); + } else { + emitter.on(type, listenerFn, context); + } + }, + /** + * Unlike `off` or `removeListener` which are methods from EventEmitter, `removeEventListener` + * seeks to be compatible with the DOM's `removeEventListener` with support for options. + * @memberof scene.Container + * @param type - The type of event the listener is bound to. + * @param listener - The listener callback or object. + * @param options - The original listener options. This is required to deregister a capture phase listener. + */ + removeEventListener(type, listener, options) { + const capture = typeof options === "boolean" && options || typeof options === "object" && options.capture; + const context = typeof listener === "function" ? void 0 : listener; + type = capture ? `${type}capture` : type; + listener = typeof listener === "function" ? listener : listener.handleEvent; + this.off(type, listener, context); + }, + /** + * Dispatch the event on this {@link Container} using the event's {@link EventBoundary}. + * + * The target of the event is set to `this` and the `defaultPrevented` flag is cleared before dispatch. + * @memberof scene.Container + * @param e - The event to dispatch. + * @returns Whether the {@link FederatedEvent.preventDefault preventDefault}() method was not invoked. + * @example + * // Reuse a click event! + * button.dispatchEvent(clickEvent); + */ + dispatchEvent(e) { + if (!(e instanceof FederatedEvent)) { + throw new Error("Container cannot propagate events outside of the Federated Events API"); + } + e.defaultPrevented = false; + e.path = null; + e.target = this; + e.manager.dispatchEvent(e); + return !e.defaultPrevented; + } +}; + +"use strict"; +extensions.add(EventSystem); +Container.mixin(FederatedContainer); + +"use strict"; +var LoaderParserPriority = /* @__PURE__ */ ((LoaderParserPriority2) => { + LoaderParserPriority2[LoaderParserPriority2["Low"] = 0] = "Low"; + LoaderParserPriority2[LoaderParserPriority2["Normal"] = 1] = "Normal"; + LoaderParserPriority2[LoaderParserPriority2["High"] = 2] = "High"; + return LoaderParserPriority2; +})(LoaderParserPriority || {}); + +"use strict"; +const BrowserAdapter = { + createCanvas: (width, height) => { + const canvas = document.createElement("canvas"); + canvas.width = width; + canvas.height = height; + return canvas; + }, + getCanvasRenderingContext2D: () => CanvasRenderingContext2D, + getWebGLRenderingContext: () => WebGLRenderingContext, + getNavigator: () => navigator, + getBaseUrl: () => { + var _a; + return (_a = document.baseURI) != null ? _a : window.location.href; + }, + getFontFaceSet: () => document.fonts, + fetch: (url, options) => fetch(url, options), + parseXML: (xml) => { + const parser = new DOMParser(); + return parser.parseFromString(xml, "text/xml"); + } +}; + +"use strict"; +let currentAdapter = BrowserAdapter; +const DOMAdapter = { + /** + * Returns the current adapter. + * @returns {environment.Adapter} The current adapter. + */ + get() { + return currentAdapter; + }, + /** + * Sets the current adapter. + * @param adapter - The new adapter. + */ + set(adapter) { + currentAdapter = adapter; + } +}; + +"use strict"; +function assertPath(path2) { + if (typeof path2 !== "string") { + throw new TypeError(`Path must be a string. Received ${JSON.stringify(path2)}`); + } +} +function removeUrlParams(url) { + const re = url.split("?")[0]; + return re.split("#")[0]; +} +function escapeRegExp(string) { + return string.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); +} +function replaceAll(str, find, replace) { + return str.replace(new RegExp(escapeRegExp(find), "g"), replace); +} +function normalizeStringPosix(path2, allowAboveRoot) { + let res = ""; + let lastSegmentLength = 0; + let lastSlash = -1; + let dots = 0; + let code = -1; + for (let i = 0; i <= path2.length; ++i) { + if (i < path2.length) { + code = path2.charCodeAt(i); + } else if (code === 47) { + break; + } else { + code = 47; + } + if (code === 47) { + if (lastSlash === i - 1 || dots === 1) { + } else if (lastSlash !== i - 1 && dots === 2) { + if (res.length < 2 || lastSegmentLength !== 2 || res.charCodeAt(res.length - 1) !== 46 || res.charCodeAt(res.length - 2) !== 46) { + if (res.length > 2) { + const lastSlashIndex = res.lastIndexOf("/"); + if (lastSlashIndex !== res.length - 1) { + if (lastSlashIndex === -1) { + res = ""; + lastSegmentLength = 0; + } else { + res = res.slice(0, lastSlashIndex); + lastSegmentLength = res.length - 1 - res.lastIndexOf("/"); + } + lastSlash = i; + dots = 0; + continue; + } + } else if (res.length === 2 || res.length === 1) { + res = ""; + lastSegmentLength = 0; + lastSlash = i; + dots = 0; + continue; + } + } + if (allowAboveRoot) { + if (res.length > 0) { + res += "/.."; + } else { + res = ".."; + } + lastSegmentLength = 2; + } + } else { + if (res.length > 0) { + res += `/${path2.slice(lastSlash + 1, i)}`; + } else { + res = path2.slice(lastSlash + 1, i); + } + lastSegmentLength = i - lastSlash - 1; + } + lastSlash = i; + dots = 0; + } else if (code === 46 && dots !== -1) { + ++dots; + } else { + dots = -1; + } + } + return res; +} +const path = { + /** + * Converts a path to posix format. + * @param path - The path to convert to posix + */ + toPosix(path2) { + return replaceAll(path2, "\\", "/"); + }, + /** + * Checks if the path is a URL e.g. http://, https:// + * @param path - The path to check + */ + isUrl(path2) { + return /^https?:/.test(this.toPosix(path2)); + }, + /** + * Checks if the path is a data URL + * @param path - The path to check + */ + isDataUrl(path2) { + return /^data:([a-z]+\/[a-z0-9-+.]+(;[a-z0-9-.!#$%*+.{}|~`]+=[a-z0-9-.!#$%*+.{}()_|~`]+)*)?(;base64)?,([a-z0-9!$&',()*+;=\-._~:@\/?%\s<>]*?)$/i.test(path2); + }, + /** + * Checks if the path is a blob URL + * @param path - The path to check + */ + isBlobUrl(path2) { + return path2.startsWith("blob:"); + }, + /** + * Checks if the path has a protocol e.g. http://, https://, file:///, data:, blob:, C:/ + * This will return true for windows file paths + * @param path - The path to check + */ + hasProtocol(path2) { + return /^[^/:]+:/.test(this.toPosix(path2)); + }, + /** + * Returns the protocol of the path e.g. http://, https://, file:///, data:, blob:, C:/ + * @param path - The path to get the protocol from + */ + getProtocol(path2) { + assertPath(path2); + path2 = this.toPosix(path2); + const matchFile = /^file:\/\/\//.exec(path2); + if (matchFile) { + return matchFile[0]; + } + const matchProtocol = /^[^/:]+:\/{0,2}/.exec(path2); + if (matchProtocol) { + return matchProtocol[0]; + } + return ""; + }, + /** + * Converts URL to an absolute path. + * When loading from a Web Worker, we must use absolute paths. + * If the URL is already absolute we return it as is + * If it's not, we convert it + * @param url - The URL to test + * @param customBaseUrl - The base URL to use + * @param customRootUrl - The root URL to use + */ + toAbsolute(url, customBaseUrl, customRootUrl) { + assertPath(url); + if (this.isDataUrl(url) || this.isBlobUrl(url)) + return url; + const baseUrl = removeUrlParams(this.toPosix(customBaseUrl != null ? customBaseUrl : DOMAdapter.get().getBaseUrl())); + const rootUrl = removeUrlParams(this.toPosix(customRootUrl != null ? customRootUrl : this.rootname(baseUrl))); + url = this.toPosix(url); + if (url.startsWith("/")) { + return path.join(rootUrl, url.slice(1)); + } + const absolutePath = this.isAbsolute(url) ? url : this.join(baseUrl, url); + return absolutePath; + }, + /** + * Normalizes the given path, resolving '..' and '.' segments + * @param path - The path to normalize + */ + normalize(path2) { + assertPath(path2); + if (path2.length === 0) + return "."; + if (this.isDataUrl(path2) || this.isBlobUrl(path2)) + return path2; + path2 = this.toPosix(path2); + let protocol = ""; + const isAbsolute = path2.startsWith("/"); + if (this.hasProtocol(path2)) { + protocol = this.rootname(path2); + path2 = path2.slice(protocol.length); + } + const trailingSeparator = path2.endsWith("/"); + path2 = normalizeStringPosix(path2, false); + if (path2.length > 0 && trailingSeparator) + path2 += "/"; + if (isAbsolute) + return `/${path2}`; + return protocol + path2; + }, + /** + * Determines if path is an absolute path. + * Absolute paths can be urls, data urls, or paths on disk + * @param path - The path to test + */ + isAbsolute(path2) { + assertPath(path2); + path2 = this.toPosix(path2); + if (this.hasProtocol(path2)) + return true; + return path2.startsWith("/"); + }, + /** + * Joins all given path segments together using the platform-specific separator as a delimiter, + * then normalizes the resulting path + * @param segments - The segments of the path to join + */ + join(...segments) { + var _a; + if (segments.length === 0) { + return "."; + } + let joined; + for (let i = 0; i < segments.length; ++i) { + const arg = segments[i]; + assertPath(arg); + if (arg.length > 0) { + if (joined === void 0) + joined = arg; + else { + const prevArg = (_a = segments[i - 1]) != null ? _a : ""; + if (this.joinExtensions.includes(this.extname(prevArg).toLowerCase())) { + joined += `/../${arg}`; + } else { + joined += `/${arg}`; + } + } + } + } + if (joined === void 0) { + return "."; + } + return this.normalize(joined); + }, + /** + * Returns the directory name of a path + * @param path - The path to parse + */ + dirname(path2) { + assertPath(path2); + if (path2.length === 0) + return "."; + path2 = this.toPosix(path2); + let code = path2.charCodeAt(0); + const hasRoot = code === 47; + let end = -1; + let matchedSlash = true; + const proto = this.getProtocol(path2); + const origpath = path2; + path2 = path2.slice(proto.length); + for (let i = path2.length - 1; i >= 1; --i) { + code = path2.charCodeAt(i); + if (code === 47) { + if (!matchedSlash) { + end = i; + break; + } + } else { + matchedSlash = false; + } + } + if (end === -1) + return hasRoot ? "/" : this.isUrl(origpath) ? proto + path2 : proto; + if (hasRoot && end === 1) + return "//"; + return proto + path2.slice(0, end); + }, + /** + * Returns the root of the path e.g. /, C:/, file:///, http://domain.com/ + * @param path - The path to parse + */ + rootname(path2) { + assertPath(path2); + path2 = this.toPosix(path2); + let root = ""; + if (path2.startsWith("/")) + root = "/"; + else { + root = this.getProtocol(path2); + } + if (this.isUrl(path2)) { + const index = path2.indexOf("/", root.length); + if (index !== -1) { + root = path2.slice(0, index); + } else + root = path2; + if (!root.endsWith("/")) + root += "/"; + } + return root; + }, + /** + * Returns the last portion of a path + * @param path - The path to test + * @param ext - Optional extension to remove + */ + basename(path2, ext) { + assertPath(path2); + if (ext) + assertPath(ext); + path2 = removeUrlParams(this.toPosix(path2)); + let start = 0; + let end = -1; + let matchedSlash = true; + let i; + if (ext !== void 0 && ext.length > 0 && ext.length <= path2.length) { + if (ext.length === path2.length && ext === path2) + return ""; + let extIdx = ext.length - 1; + let firstNonSlashEnd = -1; + for (i = path2.length - 1; i >= 0; --i) { + const code = path2.charCodeAt(i); + if (code === 47) { + if (!matchedSlash) { + start = i + 1; + break; + } + } else { + if (firstNonSlashEnd === -1) { + matchedSlash = false; + firstNonSlashEnd = i + 1; + } + if (extIdx >= 0) { + if (code === ext.charCodeAt(extIdx)) { + if (--extIdx === -1) { + end = i; + } + } else { + extIdx = -1; + end = firstNonSlashEnd; + } + } + } + } + if (start === end) + end = firstNonSlashEnd; + else if (end === -1) + end = path2.length; + return path2.slice(start, end); + } + for (i = path2.length - 1; i >= 0; --i) { + if (path2.charCodeAt(i) === 47) { + if (!matchedSlash) { + start = i + 1; + break; + } + } else if (end === -1) { + matchedSlash = false; + end = i + 1; + } + } + if (end === -1) + return ""; + return path2.slice(start, end); + }, + /** + * Returns the extension of the path, from the last occurrence of the . (period) character to end of string in the last + * portion of the path. If there is no . in the last portion of the path, or if there are no . characters other than + * the first character of the basename of path, an empty string is returned. + * @param path - The path to parse + */ + extname(path2) { + assertPath(path2); + path2 = removeUrlParams(this.toPosix(path2)); + let startDot = -1; + let startPart = 0; + let end = -1; + let matchedSlash = true; + let preDotState = 0; + for (let i = path2.length - 1; i >= 0; --i) { + const code = path2.charCodeAt(i); + if (code === 47) { + if (!matchedSlash) { + startPart = i + 1; + break; + } + continue; + } + if (end === -1) { + matchedSlash = false; + end = i + 1; + } + if (code === 46) { + if (startDot === -1) + startDot = i; + else if (preDotState !== 1) + preDotState = 1; + } else if (startDot !== -1) { + preDotState = -1; + } + } + if (startDot === -1 || end === -1 || preDotState === 0 || preDotState === 1 && startDot === end - 1 && startDot === startPart + 1) { + return ""; + } + return path2.slice(startDot, end); + }, + /** + * Parses a path into an object containing the 'root', `dir`, `base`, `ext`, and `name` properties. + * @param path - The path to parse + */ + parse(path2) { + assertPath(path2); + const ret = { root: "", dir: "", base: "", ext: "", name: "" }; + if (path2.length === 0) + return ret; + path2 = removeUrlParams(this.toPosix(path2)); + let code = path2.charCodeAt(0); + const isAbsolute = this.isAbsolute(path2); + let start; + const protocol = ""; + ret.root = this.rootname(path2); + if (isAbsolute || this.hasProtocol(path2)) { + start = 1; + } else { + start = 0; + } + let startDot = -1; + let startPart = 0; + let end = -1; + let matchedSlash = true; + let i = path2.length - 1; + let preDotState = 0; + for (; i >= start; --i) { + code = path2.charCodeAt(i); + if (code === 47) { + if (!matchedSlash) { + startPart = i + 1; + break; + } + continue; + } + if (end === -1) { + matchedSlash = false; + end = i + 1; + } + if (code === 46) { + if (startDot === -1) + startDot = i; + else if (preDotState !== 1) + preDotState = 1; + } else if (startDot !== -1) { + preDotState = -1; + } + } + if (startDot === -1 || end === -1 || preDotState === 0 || preDotState === 1 && startDot === end - 1 && startDot === startPart + 1) { + if (end !== -1) { + if (startPart === 0 && isAbsolute) + ret.base = ret.name = path2.slice(1, end); + else + ret.base = ret.name = path2.slice(startPart, end); + } + } else { + if (startPart === 0 && isAbsolute) { + ret.name = path2.slice(1, startDot); + ret.base = path2.slice(1, end); + } else { + ret.name = path2.slice(startPart, startDot); + ret.base = path2.slice(startPart, end); + } + ret.ext = path2.slice(startDot, end); + } + ret.dir = this.dirname(path2); + if (protocol) + ret.dir = protocol + ret.dir; + return ret; + }, + sep: "/", + delimiter: ":", + joinExtensions: [".html"] +}; + +"use strict"; +const convertToList = (input, transform, forceTransform = false) => { + if (!Array.isArray(input)) { + input = [input]; + } + if (!transform) { + return input; + } + return input.map((item) => { + if (typeof item === "string" || forceTransform) { + return transform(item); + } + return item; + }); +}; + +"use strict"; +function processX(base, ids, depth, result, tags) { + const id = ids[depth]; + for (let i = 0; i < id.length; i++) { + const value = id[i]; + if (depth < ids.length - 1) { + processX(base.replace(result[depth], value), ids, depth + 1, result, tags); + } else { + tags.push(base.replace(result[depth], value)); + } + } +} +function createStringVariations(string) { + const regex = /\{(.*?)\}/g; + const result = string.match(regex); + const tags = []; + if (result) { + const ids = []; + result.forEach((vars) => { + const split = vars.substring(1, vars.length - 1).split(","); + ids.push(split); + }); + processX(string, ids, 0, result, tags); + } else { + tags.push(string); + } + return tags; +} + +"use strict"; +const isSingleItem = (item) => !Array.isArray(item); + +"use strict"; +var __defProp$Z = Object.defineProperty; +var __getOwnPropSymbols$Z = Object.getOwnPropertySymbols; +var __hasOwnProp$Z = Object.prototype.hasOwnProperty; +var __propIsEnum$Z = Object.prototype.propertyIsEnumerable; +var __defNormalProp$Z = (obj, key, value) => key in obj ? __defProp$Z(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; +var __spreadValues$Z = (a, b) => { + for (var prop in b || (b = {})) + if (__hasOwnProp$Z.call(b, prop)) + __defNormalProp$Z(a, prop, b[prop]); + if (__getOwnPropSymbols$Z) + for (var prop of __getOwnPropSymbols$Z(b)) { + if (__propIsEnum$Z.call(b, prop)) + __defNormalProp$Z(a, prop, b[prop]); + } + return a; +}; +class Resolver { + constructor() { + this._defaultBundleIdentifierOptions = { + connector: "-", + createBundleAssetId: (bundleId, assetId) => `${bundleId}${this._bundleIdConnector}${assetId}`, + extractAssetIdFromBundle: (bundleId, assetBundleId) => assetBundleId.replace(`${bundleId}${this._bundleIdConnector}`, "") + }; + /** The character that is used to connect the bundleId and the assetId when generating a bundle asset id key */ + this._bundleIdConnector = this._defaultBundleIdentifierOptions.connector; + /** + * A function that generates a bundle asset id key from a bundleId and an assetId + * @param bundleId - the bundleId + * @param assetId - the assetId + * @returns the bundle asset id key + */ + this._createBundleAssetId = this._defaultBundleIdentifierOptions.createBundleAssetId; + /** + * A function that generates an assetId from a bundle asset id key. This is the reverse of generateBundleAssetId + * @param bundleId - the bundleId + * @param assetBundleId - the bundle asset id key + * @returns the assetId + */ + this._extractAssetIdFromBundle = this._defaultBundleIdentifierOptions.extractAssetIdFromBundle; + this._assetMap = {}; + this._preferredOrder = []; + this._parsers = []; + this._resolverHash = {}; + this._bundles = {}; + } + /** + * Override how the resolver deals with generating bundle ids. + * must be called before any bundles are added + * @param bundleIdentifier - the bundle identifier options + */ + setBundleIdentifier(bundleIdentifier) { + var _a, _b, _c; + this._bundleIdConnector = (_a = bundleIdentifier.connector) != null ? _a : this._bundleIdConnector; + this._createBundleAssetId = (_b = bundleIdentifier.createBundleAssetId) != null ? _b : this._createBundleAssetId; + this._extractAssetIdFromBundle = (_c = bundleIdentifier.extractAssetIdFromBundle) != null ? _c : this._extractAssetIdFromBundle; + if (this._extractAssetIdFromBundle("foo", this._createBundleAssetId("foo", "bar")) !== "bar") { + throw new Error("[Resolver] GenerateBundleAssetId are not working correctly"); + } + } + /** + * Let the resolver know which assets you prefer to use when resolving assets. + * Multiple prefer user defined rules can be added. + * @example + * resolver.prefer({ + * // first look for something with the correct format, and then then correct resolution + * priority: ['format', 'resolution'], + * params:{ + * format:'webp', // prefer webp images + * resolution: 2, // prefer a resolution of 2 + * } + * }) + * resolver.add('foo', ['bar@2x.webp', 'bar@2x.png', 'bar.webp', 'bar.png']); + * resolver.resolveUrl('foo') // => 'bar@2x.webp' + * @param preferOrders - the prefer options + */ + prefer(...preferOrders) { + preferOrders.forEach((prefer) => { + this._preferredOrder.push(prefer); + if (!prefer.priority) { + prefer.priority = Object.keys(prefer.params); + } + }); + this._resolverHash = {}; + } + /** + * Set the base path to prepend to all urls when resolving + * @example + * resolver.basePath = 'https://home.com/'; + * resolver.add('foo', 'bar.ong'); + * resolver.resolveUrl('foo', 'bar.png'); // => 'https://home.com/bar.png' + * @param basePath - the base path to use + */ + set basePath(basePath) { + this._basePath = basePath; + } + get basePath() { + return this._basePath; + } + /** + * Set the root path for root-relative URLs. By default the `basePath`'s root is used. If no `basePath` is set, then the + * default value for browsers is `window.location.origin` + * @example + * // Application hosted on https://home.com/some-path/index.html + * resolver.basePath = 'https://home.com/some-path/'; + * resolver.rootPath = 'https://home.com/'; + * resolver.add('foo', '/bar.png'); + * resolver.resolveUrl('foo', '/bar.png'); // => 'https://home.com/bar.png' + * @param rootPath - the root path to use + */ + set rootPath(rootPath) { + this._rootPath = rootPath; + } + get rootPath() { + return this._rootPath; + } + /** + * All the active URL parsers that help the parser to extract information and create + * an asset object-based on parsing the URL itself. + * + * Can be added using the extensions API + * @example + * resolver.add('foo', [ + * { + * resolution: 2, + * format: 'png', + * src: 'image@2x.png', + * }, + * { + * resolution:1, + * format:'png', + * src: 'image.png', + * }, + * ]); + * + * // With a url parser the information such as resolution and file format could extracted from the url itself: + * extensions.add({ + * extension: ExtensionType.ResolveParser, + * test: loadTextures.test, // test if url ends in an image + * parse: (value: string) => + * ({ + * resolution: parseFloat(Resolver.RETINA_PREFIX.exec(value)?.[1] ?? '1'), + * format: value.split('.').pop(), + * src: value, + * }), + * }); + * + * // Now resolution and format can be extracted from the url + * resolver.add('foo', [ + * 'image@2x.png', + * 'image.png', + * ]); + */ + get parsers() { + return this._parsers; + } + /** Used for testing, this resets the resolver to its initial state */ + reset() { + this.setBundleIdentifier(this._defaultBundleIdentifierOptions); + this._assetMap = {}; + this._preferredOrder = []; + this._resolverHash = {}; + this._rootPath = null; + this._basePath = null; + this._manifest = null; + this._bundles = {}; + this._defaultSearchParams = null; + } + /** + * Sets the default URL search parameters for the URL resolver. The urls can be specified as a string or an object. + * @param searchParams - the default url parameters to append when resolving urls + */ + setDefaultSearchParams(searchParams) { + if (typeof searchParams === "string") { + this._defaultSearchParams = searchParams; + } else { + const queryValues = searchParams; + this._defaultSearchParams = Object.keys(queryValues).map((key) => `${encodeURIComponent(key)}=${encodeURIComponent(queryValues[key])}`).join("&"); + } + } + /** + * Returns the aliases for a given asset + * @param asset - the asset to get the aliases for + */ + getAlias(asset) { + const { alias, src } = asset; + const aliasesToUse = convertToList( + alias || src, + (value) => { + if (typeof value === "string") + return value; + if (Array.isArray(value)) + return value.map((v) => { + var _a; + return (_a = v == null ? void 0 : v.src) != null ? _a : v; + }); + if (value == null ? void 0 : value.src) + return value.src; + return value; + }, + true + ); + return aliasesToUse; + } + /** + * Add a manifest to the asset resolver. This is a nice way to add all the asset information in one go. + * generally a manifest would be built using a tool. + * @param manifest - the manifest to add to the resolver + */ + addManifest(manifest) { + if (this._manifest) { + warn("[Resolver] Manifest already exists, this will be overwritten"); + } + this._manifest = manifest; + manifest.bundles.forEach((bundle) => { + this.addBundle(bundle.name, bundle.assets); + }); + } + /** + * This adds a bundle of assets in one go so that you can resolve them as a group. + * For example you could add a bundle for each screen in you pixi app + * @example + * resolver.addBundle('animals', [ + * { alias: 'bunny', src: 'bunny.png' }, + * { alias: 'chicken', src: 'chicken.png' }, + * { alias: 'thumper', src: 'thumper.png' }, + * ]); + * // or + * resolver.addBundle('animals', { + * bunny: 'bunny.png', + * chicken: 'chicken.png', + * thumper: 'thumper.png', + * }); + * + * const resolvedAssets = await resolver.resolveBundle('animals'); + * @param bundleId - The id of the bundle to add + * @param assets - A record of the asset or assets that will be chosen from when loading via the specified key + */ + addBundle(bundleId, assets) { + const assetNames = []; + let convertedAssets = assets; + if (!Array.isArray(assets)) { + convertedAssets = Object.entries(assets).map(([alias, src]) => { + if (typeof src === "string" || Array.isArray(src)) { + return { alias, src }; + } + return __spreadValues$Z({ alias }, src); + }); + } + convertedAssets.forEach((asset) => { + const srcs = asset.src; + const aliases = asset.alias; + let ids; + if (typeof aliases === "string") { + const bundleAssetId = this._createBundleAssetId(bundleId, aliases); + assetNames.push(bundleAssetId); + ids = [aliases, bundleAssetId]; + } else { + const bundleIds = aliases.map((name) => this._createBundleAssetId(bundleId, name)); + assetNames.push(...bundleIds); + ids = [...aliases, ...bundleIds]; + } + this.add(__spreadValues$Z(__spreadValues$Z({}, asset), { + alias: ids, + src: srcs + })); + }); + this._bundles[bundleId] = assetNames; + } + /** + * Tells the resolver what keys are associated with witch asset. + * The most important thing the resolver does + * @example + * // Single key, single asset: + * resolver.add({alias: 'foo', src: 'bar.png'); + * resolver.resolveUrl('foo') // => 'bar.png' + * + * // Multiple keys, single asset: + * resolver.add({alias: ['foo', 'boo'], src: 'bar.png'}); + * resolver.resolveUrl('foo') // => 'bar.png' + * resolver.resolveUrl('boo') // => 'bar.png' + * + * // Multiple keys, multiple assets: + * resolver.add({alias: ['foo', 'boo'], src: ['bar.png', 'bar.webp']}); + * resolver.resolveUrl('foo') // => 'bar.png' + * + * // Add custom data attached to the resolver + * Resolver.add({ + * alias: 'bunnyBooBooSmooth', + * src: 'bunny{png,webp}', + * data: { scaleMode:SCALE_MODES.NEAREST }, // Base texture options + * }); + * + * resolver.resolve('bunnyBooBooSmooth') // => { src: 'bunny.png', data: { scaleMode: SCALE_MODES.NEAREST } } + * @param aliases - the UnresolvedAsset or array of UnresolvedAssets to add to the resolver + */ + add(aliases) { + const assets = []; + if (Array.isArray(aliases)) { + assets.push(...aliases); + } else { + assets.push(aliases); + } + let keyCheck; + keyCheck = (key) => { + if (this.hasKey(key)) { + warn(`[Resolver] already has key: ${key} overwriting`); + } + }; + const assetArray = convertToList(assets); + assetArray.forEach((asset) => { + const { src } = asset; + let { data, format, loadParser } = asset; + const srcsToUse = convertToList(src).map((src2) => { + if (typeof src2 === "string") { + return createStringVariations(src2); + } + return Array.isArray(src2) ? src2 : [src2]; + }); + const aliasesToUse = this.getAlias(asset); + Array.isArray(aliasesToUse) ? aliasesToUse.forEach(keyCheck) : keyCheck(aliasesToUse); + const resolvedAssets = []; + srcsToUse.forEach((srcs) => { + srcs.forEach((src2) => { + var _a, _b, _c; + let formattedAsset = {}; + if (typeof src2 !== "object") { + formattedAsset.src = src2; + for (let i = 0; i < this._parsers.length; i++) { + const parser = this._parsers[i]; + if (parser.test(src2)) { + formattedAsset = parser.parse(src2); + break; + } + } + } else { + data = (_a = src2.data) != null ? _a : data; + format = (_b = src2.format) != null ? _b : format; + loadParser = (_c = src2.loadParser) != null ? _c : loadParser; + formattedAsset = __spreadValues$Z(__spreadValues$Z({}, formattedAsset), src2); + } + if (!aliasesToUse) { + throw new Error(`[Resolver] alias is undefined for this asset: ${formattedAsset.src}`); + } + formattedAsset = this._buildResolvedAsset(formattedAsset, { + aliases: aliasesToUse, + data, + format, + loadParser + }); + resolvedAssets.push(formattedAsset); + }); + }); + aliasesToUse.forEach((alias) => { + this._assetMap[alias] = resolvedAssets; + }); + }); + } + // TODO: this needs an overload like load did in Assets + /** + * If the resolver has had a manifest set via setManifest, this will return the assets urls for + * a given bundleId or bundleIds. + * @example + * // Manifest Example + * const manifest = { + * bundles: [ + * { + * name: 'load-screen', + * assets: [ + * { + * alias: 'background', + * src: 'sunset.png', + * }, + * { + * alias: 'bar', + * src: 'load-bar.{png,webp}', + * }, + * ], + * }, + * { + * name: 'game-screen', + * assets: [ + * { + * alias: 'character', + * src: 'robot.png', + * }, + * { + * alias: 'enemy', + * src: 'bad-guy.png', + * }, + * ], + * }, + * ] + * }; + * + * resolver.setManifest(manifest); + * const resolved = resolver.resolveBundle('load-screen'); + * @param bundleIds - The bundle ids to resolve + * @returns All the bundles assets or a hash of assets for each bundle specified + */ + resolveBundle(bundleIds) { + const singleAsset = isSingleItem(bundleIds); + bundleIds = convertToList(bundleIds); + const out = {}; + bundleIds.forEach((bundleId) => { + const assetNames = this._bundles[bundleId]; + if (assetNames) { + const results = this.resolve(assetNames); + const assets = {}; + for (const key in results) { + const asset = results[key]; + assets[this._extractAssetIdFromBundle(bundleId, key)] = asset; + } + out[bundleId] = assets; + } + }); + return singleAsset ? out[bundleIds[0]] : out; + } + /** + * Does exactly what resolve does, but returns just the URL rather than the whole asset object + * @param key - The key or keys to resolve + * @returns - The URLs associated with the key(s) + */ + resolveUrl(key) { + const result = this.resolve(key); + if (typeof key !== "string") { + const out = {}; + for (const i in result) { + out[i] = result[i].src; + } + return out; + } + return result.src; + } + resolve(keys) { + const singleAsset = isSingleItem(keys); + keys = convertToList(keys); + const result = {}; + keys.forEach((key) => { + if (!this._resolverHash[key]) { + if (this._assetMap[key]) { + let assets = this._assetMap[key]; + const preferredOrder = this._getPreferredOrder(assets); + preferredOrder == null ? void 0 : preferredOrder.priority.forEach((priorityKey) => { + preferredOrder.params[priorityKey].forEach((value) => { + const filteredAssets = assets.filter((asset) => { + if (asset[priorityKey]) { + return asset[priorityKey] === value; + } + return false; + }); + if (filteredAssets.length) { + assets = filteredAssets; + } + }); + }); + this._resolverHash[key] = assets[0]; + } else { + this._resolverHash[key] = this._buildResolvedAsset({ + alias: [key], + src: key + }, {}); + } + } + result[key] = this._resolverHash[key]; + }); + return singleAsset ? result[keys[0]] : result; + } + /** + * Checks if an asset with a given key exists in the resolver + * @param key - The key of the asset + */ + hasKey(key) { + return !!this._assetMap[key]; + } + /** + * Checks if a bundle with the given key exists in the resolver + * @param key - The key of the bundle + */ + hasBundle(key) { + return !!this._bundles[key]; + } + /** + * Internal function for figuring out what prefer criteria an asset should use. + * @param assets + */ + _getPreferredOrder(assets) { + for (let i = 0; i < assets.length; i++) { + const asset = assets[0]; + const preferred = this._preferredOrder.find((preference) => preference.params.format.includes(asset.format)); + if (preferred) { + return preferred; + } + } + return this._preferredOrder[0]; + } + /** + * Appends the default url parameters to the url + * @param url - The url to append the default parameters to + * @returns - The url with the default parameters appended + */ + _appendDefaultSearchParams(url) { + if (!this._defaultSearchParams) + return url; + const paramConnector = /\?/.test(url) ? "&" : "?"; + return `${url}${paramConnector}${this._defaultSearchParams}`; + } + _buildResolvedAsset(formattedAsset, data) { + var _a, _b; + const { aliases, data: assetData, loadParser, format } = data; + if (this._basePath || this._rootPath) { + formattedAsset.src = path.toAbsolute(formattedAsset.src, this._basePath, this._rootPath); + } + formattedAsset.alias = (_a = aliases != null ? aliases : formattedAsset.alias) != null ? _a : [formattedAsset.src]; + formattedAsset.src = this._appendDefaultSearchParams(formattedAsset.src); + formattedAsset.data = __spreadValues$Z(__spreadValues$Z({}, assetData || {}), formattedAsset.data); + formattedAsset.loadParser = loadParser != null ? loadParser : formattedAsset.loadParser; + formattedAsset.format = (_b = format != null ? format : formattedAsset.format) != null ? _b : getUrlExtension(formattedAsset.src); + return formattedAsset; + } +} +/** + * The prefix that denotes a URL is for a retina asset. + * @static + * @name RETINA_PREFIX + * @type {RegExp} + * @default /@([0-9\.]+)x/ + * @example `@2x` + */ +Resolver.RETINA_PREFIX = /@([0-9\.]+)x/; +function getUrlExtension(url) { + return url.split(".").pop().split("?").shift().split("#").shift(); +} + +"use strict"; +const copySearchParams = (targetUrl, sourceUrl) => { + const searchParams = sourceUrl.split("?")[1]; + if (searchParams) { + targetUrl += `?${searchParams}`; + } + return targetUrl; +}; + +"use strict"; +const ux = [1, 1, 0, -1, -1, -1, 0, 1, 1, 1, 0, -1, -1, -1, 0, 1]; +const uy = [0, 1, 1, 1, 0, -1, -1, -1, 0, 1, 1, 1, 0, -1, -1, -1]; +const vx = [0, -1, -1, -1, 0, 1, 1, 1, 0, 1, 1, 1, 0, -1, -1, -1]; +const vy = [1, 1, 0, -1, -1, -1, 0, 1, -1, -1, 0, 1, 1, 1, 0, -1]; +const rotationCayley = []; +const rotationMatrices = []; +const signum = Math.sign; +function init() { + for (let i = 0; i < 16; i++) { + const row = []; + rotationCayley.push(row); + for (let j = 0; j < 16; j++) { + const _ux = signum(ux[i] * ux[j] + vx[i] * uy[j]); + const _uy = signum(uy[i] * ux[j] + vy[i] * uy[j]); + const _vx = signum(ux[i] * vx[j] + vx[i] * vy[j]); + const _vy = signum(uy[i] * vx[j] + vy[i] * vy[j]); + for (let k = 0; k < 16; k++) { + if (ux[k] === _ux && uy[k] === _uy && vx[k] === _vx && vy[k] === _vy) { + row.push(k); + break; + } + } + } + } + for (let i = 0; i < 16; i++) { + const mat = new Matrix(); + mat.set(ux[i], uy[i], vx[i], vy[i], 0, 0); + rotationMatrices.push(mat); + } +} +init(); +const groupD8 = { + /** + * | Rotation | Direction | + * |----------|-----------| + * | 0° | East | + * @memberof maths.groupD8 + * @constant {GD8Symmetry} + */ + E: 0, + /** + * | Rotation | Direction | + * |----------|-----------| + * | 45°↻ | Southeast | + * @memberof maths.groupD8 + * @constant {GD8Symmetry} + */ + SE: 1, + /** + * | Rotation | Direction | + * |----------|-----------| + * | 90°↻ | South | + * @memberof maths.groupD8 + * @constant {GD8Symmetry} + */ + S: 2, + /** + * | Rotation | Direction | + * |----------|-----------| + * | 135°↻ | Southwest | + * @memberof maths.groupD8 + * @constant {GD8Symmetry} + */ + SW: 3, + /** + * | Rotation | Direction | + * |----------|-----------| + * | 180° | West | + * @memberof maths.groupD8 + * @constant {GD8Symmetry} + */ + W: 4, + /** + * | Rotation | Direction | + * |-------------|--------------| + * | -135°/225°↻ | Northwest | + * @memberof maths.groupD8 + * @constant {GD8Symmetry} + */ + NW: 5, + /** + * | Rotation | Direction | + * |-------------|--------------| + * | -90°/270°↻ | North | + * @memberof maths.groupD8 + * @constant {GD8Symmetry} + */ + N: 6, + /** + * | Rotation | Direction | + * |-------------|--------------| + * | -45°/315°↻ | Northeast | + * @memberof maths.groupD8 + * @constant {GD8Symmetry} + */ + NE: 7, + /** + * Reflection about Y-axis. + * @memberof maths.groupD8 + * @constant {GD8Symmetry} + */ + MIRROR_VERTICAL: 8, + /** + * Reflection about the main diagonal. + * @memberof maths.groupD8 + * @constant {GD8Symmetry} + */ + MAIN_DIAGONAL: 10, + /** + * Reflection about X-axis. + * @memberof maths.groupD8 + * @constant {GD8Symmetry} + */ + MIRROR_HORIZONTAL: 12, + /** + * Reflection about reverse diagonal. + * @memberof maths.groupD8 + * @constant {GD8Symmetry} + */ + REVERSE_DIAGONAL: 14, + /** + * @memberof maths.groupD8 + * @param {GD8Symmetry} ind - sprite rotation angle. + * @returns {GD8Symmetry} The X-component of the U-axis + * after rotating the axes. + */ + uX: (ind) => ux[ind], + /** + * @memberof maths.groupD8 + * @param {GD8Symmetry} ind - sprite rotation angle. + * @returns {GD8Symmetry} The Y-component of the U-axis + * after rotating the axes. + */ + uY: (ind) => uy[ind], + /** + * @memberof maths.groupD8 + * @param {GD8Symmetry} ind - sprite rotation angle. + * @returns {GD8Symmetry} The X-component of the V-axis + * after rotating the axes. + */ + vX: (ind) => vx[ind], + /** + * @memberof maths.groupD8 + * @param {GD8Symmetry} ind - sprite rotation angle. + * @returns {GD8Symmetry} The Y-component of the V-axis + * after rotating the axes. + */ + vY: (ind) => vy[ind], + /** + * @memberof maths.groupD8 + * @param {GD8Symmetry} rotation - symmetry whose opposite + * is needed. Only rotations have opposite symmetries while + * reflections don't. + * @returns {GD8Symmetry} The opposite symmetry of `rotation` + */ + inv: (rotation) => { + if (rotation & 8) { + return rotation & 15; + } + return -rotation & 7; + }, + /** + * Composes the two D8 operations. + * + * Taking `^` as reflection: + * + * | | E=0 | S=2 | W=4 | N=6 | E^=8 | S^=10 | W^=12 | N^=14 | + * |-------|-----|-----|-----|-----|------|-------|-------|-------| + * | E=0 | E | S | W | N | E^ | S^ | W^ | N^ | + * | S=2 | S | W | N | E | S^ | W^ | N^ | E^ | + * | W=4 | W | N | E | S | W^ | N^ | E^ | S^ | + * | N=6 | N | E | S | W | N^ | E^ | S^ | W^ | + * | E^=8 | E^ | N^ | W^ | S^ | E | N | W | S | + * | S^=10 | S^ | E^ | N^ | W^ | S | E | N | W | + * | W^=12 | W^ | S^ | E^ | N^ | W | S | E | N | + * | N^=14 | N^ | W^ | S^ | E^ | N | W | S | E | + * + * [This is a Cayley table]{@link https://en.wikipedia.org/wiki/Cayley_table} + * @memberof maths.groupD8 + * @param {GD8Symmetry} rotationSecond - Second operation, which + * is the row in the above cayley table. + * @param {GD8Symmetry} rotationFirst - First operation, which + * is the column in the above cayley table. + * @returns {GD8Symmetry} Composed operation + */ + add: (rotationSecond, rotationFirst) => rotationCayley[rotationSecond][rotationFirst], + /** + * Reverse of `add`. + * @memberof maths.groupD8 + * @param {GD8Symmetry} rotationSecond - Second operation + * @param {GD8Symmetry} rotationFirst - First operation + * @returns {GD8Symmetry} Result + */ + sub: (rotationSecond, rotationFirst) => rotationCayley[rotationSecond][groupD8.inv(rotationFirst)], + /** + * Adds 180 degrees to rotation, which is a commutative + * operation. + * @memberof maths.groupD8 + * @param {number} rotation - The number to rotate. + * @returns {number} Rotated number + */ + rotate180: (rotation) => rotation ^ 4, + /** + * Checks if the rotation angle is vertical, i.e. south + * or north. It doesn't work for reflections. + * @memberof maths.groupD8 + * @param {GD8Symmetry} rotation - The number to check. + * @returns {boolean} Whether or not the direction is vertical + */ + isVertical: (rotation) => (rotation & 3) === 2, + // rotation % 4 === 2 + /** + * Approximates the vector `V(dx,dy)` into one of the + * eight directions provided by `groupD8`. + * @memberof maths.groupD8 + * @param {number} dx - X-component of the vector + * @param {number} dy - Y-component of the vector + * @returns {GD8Symmetry} Approximation of the vector into + * one of the eight symmetries. + */ + byDirection: (dx, dy) => { + if (Math.abs(dx) * 2 <= Math.abs(dy)) { + if (dy >= 0) { + return groupD8.S; + } + return groupD8.N; + } else if (Math.abs(dy) * 2 <= Math.abs(dx)) { + if (dx > 0) { + return groupD8.E; + } + return groupD8.W; + } else if (dy > 0) { + if (dx > 0) { + return groupD8.SE; + } + return groupD8.SW; + } else if (dx > 0) { + return groupD8.NE; + } + return groupD8.NW; + }, + /** + * Helps sprite to compensate texture packer rotation. + * @memberof maths.groupD8 + * @param {Matrix} matrix - sprite world matrix + * @param {GD8Symmetry} rotation - The rotation factor to use. + * @param {number} tx - sprite anchoring + * @param {number} ty - sprite anchoring + */ + matrixAppendRotationInv: (matrix, rotation, tx = 0, ty = 0) => { + const mat = rotationMatrices[groupD8.inv(rotation)]; + mat.tx = tx; + mat.ty = ty; + matrix.append(mat); + } +}; + +"use strict"; +const NOOP = () => { +}; + +"use strict"; +function nextPow2(v) { + v += v === 0 ? 1 : 0; + --v; + v |= v >>> 1; + v |= v >>> 2; + v |= v >>> 4; + v |= v >>> 8; + v |= v >>> 16; + return v + 1; +} +function isPow2(v) { + return !(v & v - 1) && !!v; +} +function log2(v) { + let r = (v > 65535 ? 1 : 0) << 4; + v >>>= r; + let shift = (v > 255 ? 1 : 0) << 3; + v >>>= shift; + r |= shift; + shift = (v > 15 ? 1 : 0) << 2; + v >>>= shift; + r |= shift; + shift = (v > 3 ? 1 : 0) << 1; + v >>>= shift; + r |= shift; + return r | v >> 1; +} + +"use strict"; +function definedProps(obj) { + const result = {}; + for (const key in obj) { + if (obj[key] !== void 0) { + result[key] = obj[key]; + } + } + return result; +} + +"use strict"; +var __defProp$Y = Object.defineProperty; +var __getOwnPropSymbols$Y = Object.getOwnPropertySymbols; +var __hasOwnProp$Y = Object.prototype.hasOwnProperty; +var __propIsEnum$Y = Object.prototype.propertyIsEnumerable; +var __defNormalProp$Y = (obj, key, value) => key in obj ? __defProp$Y(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; +var __spreadValues$Y = (a, b) => { + for (var prop in b || (b = {})) + if (__hasOwnProp$Y.call(b, prop)) + __defNormalProp$Y(a, prop, b[prop]); + if (__getOwnPropSymbols$Y) + for (var prop of __getOwnPropSymbols$Y(b)) { + if (__propIsEnum$Y.call(b, prop)) + __defNormalProp$Y(a, prop, b[prop]); + } + return a; +}; +const idHash$1 = /* @__PURE__ */ Object.create(null); +function createResourceIdFromString(value) { + const id = idHash$1[value]; + if (id === void 0) { + idHash$1[value] = uid("resource"); + } + return id; +} +const _TextureStyle = class _TextureStyle extends EventEmitter { + /** + * @param options - options for the style + */ + constructor(options = {}) { + var _a, _b, _c, _d, _e, _f, _g; + super(); + this._resourceType = "textureSampler"; + this._touched = 0; + /** + * Specifies the maximum anisotropy value clamp used by the sampler. + * Note: Most implementations support {@link GPUSamplerDescriptor#maxAnisotropy} values in range + * between 1 and 16, inclusive. The used value of {@link GPUSamplerDescriptor#maxAnisotropy} will + * be clamped to the maximum value that the platform supports. + * @internal + * @ignore + */ + this._maxAnisotropy = 1; + /** + * Has the style been destroyed? + * @readonly + */ + this.destroyed = false; + options = __spreadValues$Y(__spreadValues$Y({}, _TextureStyle.defaultOptions), options); + this.addressMode = options.addressMode; + this.addressModeU = (_a = options.addressModeU) != null ? _a : this.addressModeU; + this.addressModeV = (_b = options.addressModeV) != null ? _b : this.addressModeV; + this.addressModeW = (_c = options.addressModeW) != null ? _c : this.addressModeW; + this.scaleMode = options.scaleMode; + this.magFilter = (_d = options.magFilter) != null ? _d : this.magFilter; + this.minFilter = (_e = options.minFilter) != null ? _e : this.minFilter; + this.mipmapFilter = (_f = options.mipmapFilter) != null ? _f : this.mipmapFilter; + this.lodMinClamp = options.lodMinClamp; + this.lodMaxClamp = options.lodMaxClamp; + this.compare = options.compare; + this.maxAnisotropy = (_g = options.maxAnisotropy) != null ? _g : 1; + } + set addressMode(value) { + this.addressModeU = value; + this.addressModeV = value; + this.addressModeW = value; + } + /** setting this will set wrapModeU,wrapModeV and wrapModeW all at once! */ + get addressMode() { + return this.addressModeU; + } + set wrapMode(value) { + deprecation(v8_0_0, "TextureStyle.wrapMode is now TextureStyle.addressMode"); + this.addressMode = value; + } + get wrapMode() { + return this.addressMode; + } + set scaleMode(value) { + this.magFilter = value; + this.minFilter = value; + this.mipmapFilter = value; + } + /** setting this will set magFilter,minFilter and mipmapFilter all at once! */ + get scaleMode() { + return this.magFilter; + } + /** Specifies the maximum anisotropy value clamp used by the sampler. */ + set maxAnisotropy(value) { + this._maxAnisotropy = Math.min(value, 16); + if (this._maxAnisotropy > 1) { + this.scaleMode = "linear"; + } + } + get maxAnisotropy() { + return this._maxAnisotropy; + } + // TODO - move this to WebGL? + get _resourceId() { + return this._sharedResourceId || this._generateResourceId(); + } + update() { + this.emit("change", this); + this._sharedResourceId = null; + } + _generateResourceId() { + const bigKey = `${this.addressModeU}-${this.addressModeV}-${this.addressModeW}-${this.magFilter}-${this.minFilter}-${this.mipmapFilter}-${this.lodMinClamp}-${this.lodMaxClamp}-${this.compare}-${this._maxAnisotropy}`; + this._sharedResourceId = createResourceIdFromString(bigKey); + return this._resourceId; + } + /** Destroys the style */ + destroy() { + this.destroyed = true; + this.emit("destroy", this); + this.emit("change", this); + this.removeAllListeners(); + } +}; +/** default options for the style */ +_TextureStyle.defaultOptions = { + addressMode: "clamp-to-edge", + scaleMode: "linear" +}; +let TextureStyle = _TextureStyle; + +"use strict"; +var __defProp$X = Object.defineProperty; +var __getOwnPropSymbols$X = Object.getOwnPropertySymbols; +var __hasOwnProp$X = Object.prototype.hasOwnProperty; +var __propIsEnum$X = Object.prototype.propertyIsEnumerable; +var __defNormalProp$X = (obj, key, value) => key in obj ? __defProp$X(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; +var __spreadValues$X = (a, b) => { + for (var prop in b || (b = {})) + if (__hasOwnProp$X.call(b, prop)) + __defNormalProp$X(a, prop, b[prop]); + if (__getOwnPropSymbols$X) + for (var prop of __getOwnPropSymbols$X(b)) { + if (__propIsEnum$X.call(b, prop)) + __defNormalProp$X(a, prop, b[prop]); + } + return a; +}; +const _TextureSource = class _TextureSource extends EventEmitter { + /** + * @param options - options for creating a new TextureSource + */ + constructor(options = {}) { + var _a, _b, _c; + super(); + this.options = options; + /** unique id for this Texture source */ + this.uid = uid("textureSource"); + /** + * The resource type used by this TextureSource. This is used by the bind groups to determine + * how to handle this resource. + * @ignore + * @internal + */ + this._resourceType = "textureSource"; + /** + * i unique resource id, used by the bind group systems. + * This can change if the texture is resized or its resource changes + */ + this._resourceId = uid("resource"); + /** + * this is how the backends know how to upload this texture to the GPU + * It changes depending on the resource type. Classes that extend TextureSource + * should override this property. + * @ignore + * @internal + */ + this.uploadMethodId = "unknown"; + // dimensions + this._resolution = 1; + /** the pixel width of this texture source. This is the REAL pure number, not accounting resolution */ + this.pixelWidth = 1; + /** the pixel height of this texture source. This is the REAL pure number, not accounting resolution */ + this.pixelHeight = 1; + /** + * the width of this texture source, accounting for resolution + * eg pixelWidth 200, resolution 2, then width will be 100 + */ + this.width = 1; + /** + * the height of this texture source, accounting for resolution + * eg pixelHeight 200, resolution 2, then height will be 100 + */ + this.height = 1; + /** + * The number of samples of a multisample texture. This is always 1 for non-multisample textures. + * To enable multisample for a texture, set antialias to true + * @internal + * @ignore + */ + this.sampleCount = 1; + /** The number of mip levels to generate for this texture. this is overridden if autoGenerateMipmaps is true */ + this.mipLevelCount = 1; + /** + * Should we auto generate mipmaps for this texture? This will automatically generate mipmaps + * for this texture when uploading to the GPU. Mipmapped textures take up more memory, but + * can look better when scaled down. + * + * For performance reasons, it is recommended to NOT use this with RenderTextures, as they are often updated every frame. + * If you do, make sure to call `updateMipmaps` after you update the texture. + */ + this.autoGenerateMipmaps = false; + /** the format that the texture data has */ + this.format = "rgba8unorm"; + /** how many dimensions does this texture have? currently v8 only supports 2d */ + this.dimension = "2d"; + /** + * Only really affects RenderTextures. + * Should we use antialiasing for this texture. It will look better, but may impact performance as a + * Blit operation will be required to resolve the texture. + */ + this.antialias = false; + /** + * Used by automatic texture Garbage Collection, stores last GC tick when it was bound + * @protected + */ + this._touched = 0; + /** + * Used by the batcher to build texture batches. faster to have the variable here! + * @protected + */ + this._batchTick = -1; + /** + * A temporary batch location for the texture batching. Here for performance reasons only! + * @protected + */ + this._textureBindLocation = -1; + options = __spreadValues$X(__spreadValues$X({}, _TextureSource.defaultOptions), options); + this.label = (_a = options.label) != null ? _a : ""; + this.resource = options.resource; + this.autoGarbageCollect = options.autoGarbageCollect; + this._resolution = options.resolution; + if (options.width) { + this.pixelWidth = options.width * this._resolution; + } else { + this.pixelWidth = this.resource ? (_b = this.resourceWidth) != null ? _b : 1 : 1; + } + if (options.height) { + this.pixelHeight = options.height * this._resolution; + } else { + this.pixelHeight = this.resource ? (_c = this.resourceHeight) != null ? _c : 1 : 1; + } + this.width = this.pixelWidth / this._resolution; + this.height = this.pixelHeight / this._resolution; + this.format = options.format; + this.dimension = options.dimensions; + this.mipLevelCount = options.mipLevelCount; + this.autoGenerateMipmaps = options.autoGenerateMipmaps; + this.sampleCount = options.sampleCount; + this.antialias = options.antialias; + this.alphaMode = options.alphaMode; + this.style = new TextureStyle(definedProps(options)); + this.destroyed = false; + this._refreshPOT(); + } + /** returns itself */ + get source() { + return this; + } + /** the style of the texture */ + get style() { + return this._style; + } + set style(value) { + var _a, _b; + if (this.style === value) + return; + (_a = this._style) == null ? void 0 : _a.off("change", this._onStyleChange, this); + this._style = value; + (_b = this._style) == null ? void 0 : _b.on("change", this._onStyleChange, this); + this._onStyleChange(); + } + /** setting this will set wrapModeU,wrapModeV and wrapModeW all at once! */ + get addressMode() { + return this._style.addressMode; + } + set addressMode(value) { + this._style.addressMode = value; + } + /** setting this will set wrapModeU,wrapModeV and wrapModeW all at once! */ + get repeatMode() { + return this._style.addressMode; + } + set repeatMode(value) { + this._style.addressMode = value; + } + /** Specifies the sampling behavior when the sample footprint is smaller than or equal to one texel. */ + get magFilter() { + return this._style.magFilter; + } + set magFilter(value) { + this._style.magFilter = value; + } + /** Specifies the sampling behavior when the sample footprint is larger than one texel. */ + get minFilter() { + return this._style.minFilter; + } + set minFilter(value) { + this._style.minFilter = value; + } + /** Specifies behavior for sampling between mipmap levels. */ + get mipmapFilter() { + return this._style.mipmapFilter; + } + set mipmapFilter(value) { + this._style.mipmapFilter = value; + } + /** Specifies the minimum and maximum levels of detail, respectively, used internally when sampling a texture. */ + get lodMinClamp() { + return this._style.lodMinClamp; + } + set lodMinClamp(value) { + this._style.lodMinClamp = value; + } + /** Specifies the minimum and maximum levels of detail, respectively, used internally when sampling a texture. */ + get lodMaxClamp() { + return this._style.lodMaxClamp; + } + set lodMaxClamp(value) { + this._style.lodMaxClamp = value; + } + _onStyleChange() { + this.emit("styleChange", this); + } + /** call this if you have modified the texture outside of the constructor */ + update() { + if (this.resource) { + const resolution = this._resolution; + const didResize = this.resize(this.resourceWidth / resolution, this.resourceHeight / resolution); + if (didResize) + return; + } + this.emit("update", this); + } + /** Destroys this texture source */ + destroy() { + this.destroyed = true; + this.emit("destroy", this); + this.emit("change", this); + if (this._style) { + this._style.destroy(); + this._style = null; + } + this.uploadMethodId = null; + this.resource = null; + this.removeAllListeners(); + } + /** + * This will unload the Texture source from the GPU. This will free up the GPU memory + * As soon as it is required fore rendering, it will be re-uploaded. + */ + unload() { + this._resourceId = uid("resource"); + this.emit("change", this); + this.emit("unload", this); + } + /** the width of the resource. This is the REAL pure number, not accounting resolution */ + get resourceWidth() { + const { resource } = this; + return resource.naturalWidth || resource.videoWidth || resource.displayWidth || resource.width; + } + /** the height of the resource. This is the REAL pure number, not accounting resolution */ + get resourceHeight() { + const { resource } = this; + return resource.naturalHeight || resource.videoHeight || resource.displayHeight || resource.height; + } + /** + * the resolution of the texture. Changing this number, will not change the number of pixels in the actual texture + * but will the size of the texture when rendered. + * + * changing the resolution of this texture to 2 for example will make it appear twice as small when rendered (as pixel + * density will have increased) + */ + get resolution() { + return this._resolution; + } + set resolution(resolution) { + if (this._resolution === resolution) + return; + this._resolution = resolution; + this.width = this.pixelWidth / resolution; + this.height = this.pixelHeight / resolution; + } + /** + * Resize the texture, this is handy if you want to use the texture as a render texture + * @param width - the new width of the texture + * @param height - the new height of the texture + * @param resolution - the new resolution of the texture + * @returns - if the texture was resized + */ + resize(width, height, resolution) { + resolution = resolution || this._resolution; + width = width || this.width; + height = height || this.height; + const newPixelWidth = Math.round(width * resolution); + const newPixelHeight = Math.round(height * resolution); + this.width = newPixelWidth / resolution; + this.height = newPixelHeight / resolution; + this._resolution = resolution; + if (this.pixelWidth === newPixelWidth && this.pixelHeight === newPixelHeight) { + return false; + } + this._refreshPOT(); + this.pixelWidth = newPixelWidth; + this.pixelHeight = newPixelHeight; + this.emit("resize", this); + this._resourceId = uid("resource"); + this.emit("change", this); + return true; + } + /** + * Lets the renderer know that this texture has been updated and its mipmaps should be re-generated. + * This is only important for RenderTexture instances, as standard Texture instances will have their + * mipmaps generated on upload. You should call this method after you make any change to the texture + * + * The reason for this is is can be quite expensive to update mipmaps for a texture. So by default, + * We want you, the developer to specify when this action should happen. + * + * Generally you don't want to have mipmaps generated on Render targets that are changed every frame, + */ + updateMipmaps() { + if (this.autoGenerateMipmaps && this.mipLevelCount > 1) { + this.emit("updateMipmaps", this); + } + } + set wrapMode(value) { + this._style.wrapMode = value; + } + get wrapMode() { + return this._style.wrapMode; + } + set scaleMode(value) { + this._style.scaleMode = value; + } + /** setting this will set magFilter,minFilter and mipmapFilter all at once! */ + get scaleMode() { + return this._style.scaleMode; + } + /** + * Refresh check for isPowerOfTwo texture based on size + * @private + */ + _refreshPOT() { + this.isPowerOfTwo = isPow2(this.pixelWidth) && isPow2(this.pixelHeight); + } + static test(_resource) { + throw new Error("Unimplemented"); + } +}; +/** The default options used when creating a new TextureSource. override these to add your own defaults */ +_TextureSource.defaultOptions = { + resolution: 1, + format: "bgra8unorm", + alphaMode: "premultiply-alpha-on-upload", + dimensions: "2d", + mipLevelCount: 1, + autoGenerateMipmaps: false, + sampleCount: 1, + antialias: false, + autoGarbageCollect: false +}; +let TextureSource = _TextureSource; + +"use strict"; +var __defProp$W = Object.defineProperty; +var __defProps$m = Object.defineProperties; +var __getOwnPropDescs$m = Object.getOwnPropertyDescriptors; +var __getOwnPropSymbols$W = Object.getOwnPropertySymbols; +var __hasOwnProp$W = Object.prototype.hasOwnProperty; +var __propIsEnum$W = Object.prototype.propertyIsEnumerable; +var __defNormalProp$W = (obj, key, value) => key in obj ? __defProp$W(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; +var __spreadValues$W = (a, b) => { + for (var prop in b || (b = {})) + if (__hasOwnProp$W.call(b, prop)) + __defNormalProp$W(a, prop, b[prop]); + if (__getOwnPropSymbols$W) + for (var prop of __getOwnPropSymbols$W(b)) { + if (__propIsEnum$W.call(b, prop)) + __defNormalProp$W(a, prop, b[prop]); + } + return a; +}; +var __spreadProps$m = (a, b) => __defProps$m(a, __getOwnPropDescs$m(b)); +class BufferImageSource extends TextureSource { + constructor(options) { + const buffer = options.resource || new Float32Array(options.width * options.height * 4); + let format = options.format; + if (!format) { + if (buffer instanceof Float32Array) { + format = "rgba32float"; + } else if (buffer instanceof Int32Array) { + format = "rgba32uint"; + } else if (buffer instanceof Uint32Array) { + format = "rgba32uint"; + } else if (buffer instanceof Int16Array) { + format = "rgba16uint"; + } else if (buffer instanceof Uint16Array) { + format = "rgba16uint"; + } else if (buffer instanceof Int8Array) { + format = "bgra8unorm"; + } else { + format = "bgra8unorm"; + } + } + super(__spreadProps$m(__spreadValues$W({}, options), { + resource: buffer, + format + })); + this.uploadMethodId = "buffer"; + } + static test(resource) { + return resource instanceof Int8Array || resource instanceof Uint8Array || resource instanceof Uint8ClampedArray || resource instanceof Int16Array || resource instanceof Uint16Array || resource instanceof Int32Array || resource instanceof Uint32Array || resource instanceof Float32Array; + } +} +BufferImageSource.extension = ExtensionType.TextureSource; + +"use strict"; +const tempMat = new Matrix(); +class TextureMatrix { + /** + * @param texture - observed texture + * @param clampMargin - Changes frame clamping, 0.5 by default. Use -0.5 for extra border. + */ + constructor(texture, clampMargin) { + this.mapCoord = new Matrix(); + this.uClampFrame = new Float32Array(4); + this.uClampOffset = new Float32Array(2); + this._textureID = -1; + this._updateID = 0; + this.clampOffset = 0; + if (typeof clampMargin === "undefined") { + this.clampMargin = texture.width < 10 ? 0 : 0.5; + } else { + this.clampMargin = clampMargin; + } + this.isSimple = false; + this.texture = texture; + } + /** Texture property. */ + get texture() { + return this._texture; + } + set texture(value) { + var _a; + if (this.texture === value) + return; + (_a = this._texture) == null ? void 0 : _a.removeListener("update", this.update, this); + this._texture = value; + this._texture.addListener("update", this.update, this); + this.update(); + } + /** + * Multiplies uvs array to transform + * @param uvs - mesh uvs + * @param [out=uvs] - output + * @returns - output + */ + multiplyUvs(uvs, out) { + if (out === void 0) { + out = uvs; + } + const mat = this.mapCoord; + for (let i = 0; i < uvs.length; i += 2) { + const x = uvs[i]; + const y = uvs[i + 1]; + out[i] = x * mat.a + y * mat.c + mat.tx; + out[i + 1] = x * mat.b + y * mat.d + mat.ty; + } + return out; + } + /** + * Updates matrices if texture was changed + * @returns - whether or not it was updated + */ + update() { + const tex = this._texture; + this._updateID++; + const uvs = tex.uvs; + this.mapCoord.set(uvs.x1 - uvs.x0, uvs.y1 - uvs.y0, uvs.x3 - uvs.x0, uvs.y3 - uvs.y0, uvs.x0, uvs.y0); + const orig = tex.orig; + const trim = tex.trim; + if (trim) { + tempMat.set( + orig.width / trim.width, + 0, + 0, + orig.height / trim.height, + -trim.x / trim.width, + -trim.y / trim.height + ); + this.mapCoord.append(tempMat); + } + const texBase = tex.source; + const frame = this.uClampFrame; + const margin = this.clampMargin / texBase._resolution; + const offset = this.clampOffset; + frame[0] = (tex.frame.x + margin + offset) / texBase.width; + frame[1] = (tex.frame.y + margin + offset) / texBase.height; + frame[2] = (tex.frame.x + tex.frame.width - margin + offset) / texBase.width; + frame[3] = (tex.frame.y + tex.frame.height - margin + offset) / texBase.height; + this.uClampOffset[0] = offset / texBase.pixelWidth; + this.uClampOffset[1] = offset / texBase.pixelHeight; + this.isSimple = tex.frame.width === texBase.width && tex.frame.height === texBase.height && tex.rotate === 0; + return true; + } +} + +"use strict"; +class Texture extends EventEmitter { + /** + * @param {TextureOptions} param0 - Options for the texture + */ + constructor({ + source, + label, + frame, + orig, + trim, + defaultAnchor, + defaultBorders, + rotate, + dynamic + } = {}) { + var _a; + super(); + /** unique id for this texture */ + this.uid = uid("texture"); + /** A uvs object based on the given frame and the texture source */ + this.uvs = { x0: 0, y0: 0, x1: 0, y1: 0, x2: 0, y2: 0, x3: 0, y3: 0 }; + /** + * This is the area of the BaseTexture image to actually copy to the Canvas / WebGL when rendering, + * irrespective of the actual frame size or placement (which can be influenced by trimmed texture atlases) + */ + this.frame = new Rectangle(); + /** + * Does this Texture have any frame data assigned to it? + * + * This mode is enabled automatically if no frame was passed inside constructor. + * + * In this mode texture is subscribed to baseTexture events, and fires `update` on any change. + * + * Beware, after loading or resize of baseTexture event can fired two times! + * If you want more control, subscribe on baseTexture itself. + * @example + * texture.on('update', () => {}); + */ + this.noFrame = false; + /** + * Set to true if you plan on modifying the uvs of this texture. + * When this is the case, sprites and other objects using the texture will + * make sure to listen for changes to the uvs and update their vertices accordingly. + */ + this.dynamic = false; + /** is it a texture? yes! used for type checking */ + this.isTexture = true; + this.label = label; + this.source = (_a = source == null ? void 0 : source.source) != null ? _a : new TextureSource(); + this.noFrame = !frame; + if (frame) { + this.frame.copyFrom(frame); + } else { + const { width, height } = this._source; + this.frame.width = width; + this.frame.height = height; + } + this.orig = orig || this.frame; + this.trim = trim; + this.rotate = rotate != null ? rotate : 0; + this.defaultAnchor = defaultAnchor; + this.defaultBorders = defaultBorders; + this.destroyed = false; + this.dynamic = dynamic || false; + this.updateUvs(); + } + set source(value) { + if (this._source) { + this._source.off("resize", this.update, this); + } + this._source = value; + value.on("resize", this.update, this); + this.emit("update", this); + } + /** the underlying source of the texture (equivalent of baseTexture in v7) */ + get source() { + return this._source; + } + /** returns a TextureMatrix instance for this texture. By default, that object is not created because its heavy. */ + get textureMatrix() { + if (!this._textureMatrix) { + this._textureMatrix = new TextureMatrix(this); + } + return this._textureMatrix; + } + /** The width of the Texture in pixels. */ + get width() { + return this.orig.width; + } + /** The height of the Texture in pixels. */ + get height() { + return this.orig.height; + } + /** Call this function when you have modified the frame of this texture. */ + updateUvs() { + const { uvs, frame } = this; + const { width, height } = this._source; + const nX = frame.x / width; + const nY = frame.y / height; + const nW = frame.width / width; + const nH = frame.height / height; + let rotate = this.rotate; + if (rotate) { + const w2 = nW / 2; + const h2 = nH / 2; + const cX = nX + w2; + const cY = nY + h2; + rotate = groupD8.add(rotate, groupD8.NW); + uvs.x0 = cX + w2 * groupD8.uX(rotate); + uvs.y0 = cY + h2 * groupD8.uY(rotate); + rotate = groupD8.add(rotate, 2); + uvs.x1 = cX + w2 * groupD8.uX(rotate); + uvs.y1 = cY + h2 * groupD8.uY(rotate); + rotate = groupD8.add(rotate, 2); + uvs.x2 = cX + w2 * groupD8.uX(rotate); + uvs.y2 = cY + h2 * groupD8.uY(rotate); + rotate = groupD8.add(rotate, 2); + uvs.x3 = cX + w2 * groupD8.uX(rotate); + uvs.y3 = cY + h2 * groupD8.uY(rotate); + } else { + uvs.x0 = nX; + uvs.y0 = nY; + uvs.x1 = nX + nW; + uvs.y1 = nY; + uvs.x2 = nX + nW; + uvs.y2 = nY + nH; + uvs.x3 = nX; + uvs.y3 = nY + nH; + } + } + /** + * Destroys this texture + * @param destroySource - Destroy the source when the texture is destroyed. + */ + destroy(destroySource = false) { + if (this._source) { + if (destroySource) { + this._source.destroy(); + this._source = null; + } + } + this._textureMatrix = null; + this.destroyed = true; + this.emit("destroy", this); + this.removeAllListeners(); + } + /** call this if you have modified the `texture outside` of the constructor */ + update() { + if (this.noFrame) { + this.frame.width = this._source.width; + this.frame.height = this._source.height; + } + this.updateUvs(); + this.emit("update", this); + } + /** @deprecated since 8.0.0 */ + get baseTexture() { + deprecation(v8_0_0, "Texture.baseTexture is now Texture.source"); + return this._source; + } +} +Texture.EMPTY = new Texture({ + label: "EMPTY", + source: new TextureSource({ + label: "EMPTY" + }) +}); +Texture.EMPTY.destroy = NOOP; +Texture.WHITE = new Texture({ + source: new BufferImageSource({ + resource: new Uint8Array([255, 255, 255, 255]), + width: 1, + height: 1, + alphaMode: "premultiply-alpha-on-upload", + label: "WHITE" + }), + label: "WHITE" +}); +Texture.WHITE.destroy = NOOP; + +"use strict"; +const _Spritesheet = class _Spritesheet { + /** + * @param texture - Reference to the source BaseTexture object. + * @param {object} data - Spritesheet image data. + */ + constructor(texture, data) { + /** For multi-packed spritesheets, this contains a reference to all the other spritesheets it depends on. */ + this.linkedSheets = []; + this._texture = texture instanceof Texture ? texture : null; + this.textureSource = texture.source; + this.textures = {}; + this.animations = {}; + this.data = data; + const metaResolution = parseFloat(data.meta.scale); + if (metaResolution) { + this.resolution = metaResolution; + texture.source.resolution = this.resolution; + } else { + this.resolution = texture.source._resolution; + } + this._frames = this.data.frames; + this._frameKeys = Object.keys(this._frames); + this._batchIndex = 0; + this._callback = null; + } + /** + * Parser spritesheet from loaded data. This is done asynchronously + * to prevent creating too many Texture within a single process. + */ + parse() { + return new Promise((resolve) => { + this._callback = resolve; + this._batchIndex = 0; + if (this._frameKeys.length <= _Spritesheet.BATCH_SIZE) { + this._processFrames(0); + this._processAnimations(); + this._parseComplete(); + } else { + this._nextBatch(); + } + }); + } + /** + * Process a batch of frames + * @param initialFrameIndex - The index of frame to start. + */ + _processFrames(initialFrameIndex) { + let frameIndex = initialFrameIndex; + const maxFrames = _Spritesheet.BATCH_SIZE; + while (frameIndex - initialFrameIndex < maxFrames && frameIndex < this._frameKeys.length) { + const i = this._frameKeys[frameIndex]; + const data = this._frames[i]; + const rect = data.frame; + if (rect) { + let frame = null; + let trim = null; + const sourceSize = data.trimmed !== false && data.sourceSize ? data.sourceSize : data.frame; + const orig = new Rectangle( + 0, + 0, + Math.floor(sourceSize.w) / this.resolution, + Math.floor(sourceSize.h) / this.resolution + ); + if (data.rotated) { + frame = new Rectangle( + Math.floor(rect.x) / this.resolution, + Math.floor(rect.y) / this.resolution, + Math.floor(rect.h) / this.resolution, + Math.floor(rect.w) / this.resolution + ); + } else { + frame = new Rectangle( + Math.floor(rect.x) / this.resolution, + Math.floor(rect.y) / this.resolution, + Math.floor(rect.w) / this.resolution, + Math.floor(rect.h) / this.resolution + ); + } + if (data.trimmed !== false && data.spriteSourceSize) { + trim = new Rectangle( + Math.floor(data.spriteSourceSize.x) / this.resolution, + Math.floor(data.spriteSourceSize.y) / this.resolution, + Math.floor(rect.w) / this.resolution, + Math.floor(rect.h) / this.resolution + ); + } + this.textures[i] = new Texture({ + source: this.textureSource, + frame, + orig, + trim, + rotate: data.rotated ? 2 : 0, + defaultAnchor: data.anchor, + defaultBorders: data.borders, + label: i.toString() + }); + } + frameIndex++; + } + } + /** Parse animations config. */ + _processAnimations() { + const animations = this.data.animations || {}; + for (const animName in animations) { + this.animations[animName] = []; + for (let i = 0; i < animations[animName].length; i++) { + const frameName = animations[animName][i]; + this.animations[animName].push(this.textures[frameName]); + } + } + } + /** The parse has completed. */ + _parseComplete() { + const callback = this._callback; + this._callback = null; + this._batchIndex = 0; + callback.call(this, this.textures); + } + /** Begin the next batch of textures. */ + _nextBatch() { + this._processFrames(this._batchIndex * _Spritesheet.BATCH_SIZE); + this._batchIndex++; + setTimeout(() => { + if (this._batchIndex * _Spritesheet.BATCH_SIZE < this._frameKeys.length) { + this._nextBatch(); + } else { + this._processAnimations(); + this._parseComplete(); + } + }, 0); + } + /** + * Destroy Spritesheet and don't use after this. + * @param {boolean} [destroyBase=false] - Whether to destroy the base texture as well + */ + destroy(destroyBase = false) { + var _a; + for (const i in this.textures) { + this.textures[i].destroy(); + } + this._frames = null; + this._frameKeys = null; + this.data = null; + this.textures = null; + if (destroyBase) { + (_a = this._texture) == null ? void 0 : _a.destroy(); + this.textureSource.destroy(); + } + this._texture = null; + this.textureSource = null; + this.linkedSheets = []; + } +}; +/** The maximum number of Textures to build per process. */ +_Spritesheet.BATCH_SIZE = 1e3; +let Spritesheet = _Spritesheet; + +"use strict"; +const validImages = [ + "jpg", + "png", + "jpeg", + "avif", + "webp", + "basis", + "etc2", + "bc7", + "bc6h", + "bc5", + "bc4", + "bc3", + "bc2", + "bc1", + "eac", + "astc" +]; +function getCacheableAssets(keys, asset, ignoreMultiPack) { + const out = {}; + keys.forEach((key) => { + out[key] = asset; + }); + Object.keys(asset.textures).forEach((key) => { + out[key] = asset.textures[key]; + }); + if (!ignoreMultiPack) { + const basePath = path.dirname(keys[0]); + asset.linkedSheets.forEach((item, i) => { + const out2 = getCacheableAssets([`${basePath}/${asset.data.meta.related_multi_packs[i]}`], item, true); + Object.assign(out, out2); + }); + } + return out; +} +const spritesheetAsset = { + extension: ExtensionType.Asset, + /** Handle the caching of the related Spritesheet Textures */ + cache: { + test: (asset) => asset instanceof Spritesheet, + getCacheableAssets: (keys, asset) => getCacheableAssets(keys, asset, false) + }, + /** Resolve the resolution of the asset. */ + resolver: { + test: (value) => { + const tempURL = value.split("?")[0]; + const split = tempURL.split("."); + const extension = split.pop(); + const format = split.pop(); + return extension === "json" && validImages.includes(format); + }, + parse: (value) => { + var _a, _b; + const split = value.split("."); + return { + resolution: parseFloat((_b = (_a = Resolver.RETINA_PREFIX.exec(value)) == null ? void 0 : _a[1]) != null ? _b : "1"), + format: split[split.length - 2], + src: value + }; + } + }, + /** + * Loader plugin that parses sprite sheets! + * once the JSON has been loaded this checks to see if the JSON is spritesheet data. + * If it is, we load the spritesheets image and parse the data into Spritesheet + * All textures in the sprite sheet are then added to the cache + */ + loader: { + name: "spritesheetLoader", + extension: { + type: ExtensionType.LoadParser, + priority: LoaderParserPriority.Normal + }, + async testParse(asset, options) { + return path.extname(options.src).toLowerCase() === ".json" && !!asset.frames; + }, + async parse(asset, options, loader) { + var _a, _b, _c; + const { + texture: imageTexture, + // if user need to use preloaded texture + imageFilename + // if user need to use custom filename (not from jsonFile.meta.image) + } = (_a = options == null ? void 0 : options.data) != null ? _a : {}; + let basePath = path.dirname(options.src); + if (basePath && basePath.lastIndexOf("/") !== basePath.length - 1) { + basePath += "/"; + } + let texture; + if (imageTexture instanceof Texture) { + texture = imageTexture; + } else { + const imagePath = copySearchParams(basePath + (imageFilename != null ? imageFilename : asset.meta.image), options.src); + const assets = await loader.load([imagePath]); + texture = assets[imagePath]; + } + const spritesheet = new Spritesheet( + texture.source, + asset + ); + await spritesheet.parse(); + const multiPacks = (_b = asset == null ? void 0 : asset.meta) == null ? void 0 : _b.related_multi_packs; + if (Array.isArray(multiPacks)) { + const promises = []; + for (const item of multiPacks) { + if (typeof item !== "string") { + continue; + } + let itemUrl = basePath + item; + if ((_c = options.data) == null ? void 0 : _c.ignoreMultiPack) { + continue; + } + itemUrl = copySearchParams(itemUrl, options.src); + promises.push(loader.load({ + src: itemUrl, + data: { + ignoreMultiPack: true + } + })); + } + const res = await Promise.all(promises); + spritesheet.linkedSheets = res; + res.forEach((item) => { + item.linkedSheets = [spritesheet].concat(spritesheet.linkedSheets.filter((sp) => sp !== item)); + }); + } + return spritesheet; + }, + async unload(spritesheet, _resolvedAsset, loader) { + await loader.unload(spritesheet.textureSource._sourceOrigin); + spritesheet.destroy(false); + } + } +}; + +"use strict"; +extensions.add(spritesheetAsset); + +"use strict"; +function updateQuadBounds(bounds, anchor, texture, padding) { + const { width, height } = texture.orig; + const trim = texture.trim; + if (trim) { + const sourceWidth = trim.width; + const sourceHeight = trim.height; + bounds.minX = trim.x - anchor._x * width - padding; + bounds.maxX = bounds.minX + sourceWidth; + bounds.minY = trim.y - anchor._y * height - padding; + bounds.maxY = bounds.minY + sourceHeight; + } else { + bounds.minX = -anchor._x * width - padding; + bounds.maxX = bounds.minX + width; + bounds.minY = -anchor._y * height - padding; + bounds.maxY = bounds.minY + height; + } + return; +} + +"use strict"; +var __defProp$V = Object.defineProperty; +var __getOwnPropSymbols$V = Object.getOwnPropertySymbols; +var __hasOwnProp$V = Object.prototype.hasOwnProperty; +var __propIsEnum$V = Object.prototype.propertyIsEnumerable; +var __defNormalProp$V = (obj, key, value) => key in obj ? __defProp$V(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; +var __spreadValues$V = (a, b) => { + for (var prop in b || (b = {})) + if (__hasOwnProp$V.call(b, prop)) + __defNormalProp$V(a, prop, b[prop]); + if (__getOwnPropSymbols$V) + for (var prop of __getOwnPropSymbols$V(b)) { + if (__propIsEnum$V.call(b, prop)) + __defNormalProp$V(a, prop, b[prop]); + } + return a; +}; +var __objRest$h = (source, exclude) => { + var target = {}; + for (var prop in source) + if (__hasOwnProp$V.call(source, prop) && exclude.indexOf(prop) < 0) + target[prop] = source[prop]; + if (source != null && __getOwnPropSymbols$V) + for (var prop of __getOwnPropSymbols$V(source)) { + if (exclude.indexOf(prop) < 0 && __propIsEnum$V.call(source, prop)) + target[prop] = source[prop]; + } + return target; +}; +class Sprite extends Container { + /** + * @param options - The options for creating the sprite. + */ + constructor(options = Texture.EMPTY) { + if (options instanceof Texture) { + options = { texture: options }; + } + const _a = options, { texture, anchor, roundPixels, width, height } = _a, rest = __objRest$h(_a, ["texture", "anchor", "roundPixels", "width", "height"]); + super(__spreadValues$V({ + label: "Sprite" + }, rest)); + this.renderPipeId = "sprite"; + this.batched = true; + this._didSpriteUpdate = false; + this._bounds = { minX: 0, maxX: 1, minY: 0, maxY: 0 }; + this._sourceBounds = { minX: 0, maxX: 1, minY: 0, maxY: 0 }; + this._boundsDirty = true; + this._sourceBoundsDirty = true; + this._roundPixels = 0; + this._anchor = new ObservablePoint( + { + _onUpdate: () => { + this.onViewUpdate(); + } + } + ); + if (anchor) { + this.anchor = anchor; + } else if (texture.defaultAnchor) { + this.anchor = texture.defaultAnchor; + } + this.texture = texture; + this.allowChildren = false; + this.roundPixels = roundPixels != null ? roundPixels : false; + if (width) + this.width = width; + if (height) + this.height = height; + } + /** + * Helper function that creates a new sprite based on the source you provide. + * The source can be - frame id, image, video, canvas element, video element, texture + * @param source - Source to create texture from + * @param [skipCache] - Whether to skip the cache or not + * @returns The newly created sprite + */ + static from(source, skipCache = false) { + if (source instanceof Texture) { + return new Sprite(source); + } + return new Sprite(Texture.from(source, skipCache)); + } + set texture(value) { + value || (value = Texture.EMPTY); + const currentTexture = this._texture; + if (currentTexture === value) + return; + if (currentTexture && currentTexture.dynamic) + currentTexture.off("update", this.onViewUpdate, this); + if (value.dynamic) + value.on("update", this.onViewUpdate, this); + this._texture = value; + this.onViewUpdate(); + } + /** The texture that the sprite is using. */ + get texture() { + return this._texture; + } + /** + * The local bounds of the sprite. + * @type {rendering.Bounds} + */ + get bounds() { + if (this._boundsDirty) { + this._updateBounds(); + this._boundsDirty = false; + } + return this._bounds; + } + /** + * The bounds of the sprite, taking the texture's trim into account. + * @type {rendering.Bounds} + */ + get sourceBounds() { + if (this._sourceBoundsDirty) { + this._updateSourceBounds(); + this._sourceBoundsDirty = false; + } + return this._sourceBounds; + } + /** + * Checks if the object contains the given point. + * @param point - The point to check + */ + containsPoint(point) { + const bounds = this.sourceBounds; + if (point.x >= bounds.maxX && point.x <= bounds.minX) { + if (point.y >= bounds.maxY && point.y <= bounds.minY) { + return true; + } + } + return false; + } + /** + * Adds the bounds of this object to the bounds object. + * @param bounds - The output bounds object. + */ + addBounds(bounds) { + const _bounds = this._texture.trim ? this.sourceBounds : this.bounds; + bounds.addFrame(_bounds.minX, _bounds.minY, _bounds.maxX, _bounds.maxY); + } + onViewUpdate() { + this._didChangeId += 1 << 12; + this._didSpriteUpdate = true; + this._sourceBoundsDirty = this._boundsDirty = true; + if (this.didViewUpdate) + return; + this.didViewUpdate = true; + if (this.renderGroup) { + this.renderGroup.onChildViewUpdate(this); + } + } + _updateBounds() { + updateQuadBounds(this._bounds, this._anchor, this._texture, 0); + } + _updateSourceBounds() { + const anchor = this._anchor; + const texture = this._texture; + const sourceBounds = this._sourceBounds; + const { width, height } = texture.orig; + sourceBounds.maxX = -anchor._x * width; + sourceBounds.minX = sourceBounds.maxX + width; + sourceBounds.maxY = -anchor._y * height; + sourceBounds.minY = sourceBounds.maxY + height; + } + /** + * Destroys this sprite renderable and optionally its texture. + * @param options - Options parameter. A boolean will act as if all options + * have been set to that value + * @param {boolean} [options.texture=false] - Should it destroy the current texture of the renderable as well + * @param {boolean} [options.textureSource=false] - Should it destroy the textureSource of the renderable as well + */ + destroy(options = false) { + super.destroy(options); + const destroyTexture = typeof options === "boolean" ? options : options == null ? void 0 : options.texture; + if (destroyTexture) { + const destroyTextureSource = typeof options === "boolean" ? options : options == null ? void 0 : options.textureSource; + this._texture.destroy(destroyTextureSource); + } + this._texture = null; + this._bounds = null; + this._sourceBounds = null; + this._anchor = null; + } + /** + * The anchor sets the origin point of the sprite. The default value is taken from the {@link Texture} + * and passed to the constructor. + * + * The default is `(0,0)`, this means the sprite's origin is the top left. + * + * Setting the anchor to `(0.5,0.5)` means the sprite's origin is centered. + * + * Setting the anchor to `(1,1)` would mean the sprite's origin point will be the bottom right corner. + * + * If you pass only single parameter, it will set both x and y to the same value as shown in the example below. + * @example + * import { Sprite } from 'pixi.js'; + * + * const sprite = new Sprite({texture: Texture.WHITE}); + * sprite.anchor.set(0.5); // This will set the origin to center. (0.5) is same as (0.5, 0.5). + */ + get anchor() { + return this._anchor; + } + set anchor(value) { + typeof value === "number" ? this._anchor.set(value) : this._anchor.copyFrom(value); + } + /** + * Whether or not to round the x/y position of the sprite. + * @type {boolean} + */ + get roundPixels() { + return !!this._roundPixels; + } + set roundPixels(value) { + this._roundPixels = value ? 1 : 0; + } + /** The width of the sprite, setting this will actually modify the scale to achieve the value set. */ + get width() { + return Math.abs(this.scale.x) * this._texture.orig.width; + } + set width(value) { + this._setWidth(value, this._texture.orig.width); + } + /** The height of the sprite, setting this will actually modify the scale to achieve the value set. */ + get height() { + return Math.abs(this.scale.y) * this._texture.orig.height; + } + set height(value) { + this._setHeight(value, this._texture.orig.height); + } + /** + * Retrieves the size of the Sprite as a [Size]{@link Size} object. + * This is faster than get the width and height separately. + * @param out - Optional object to store the size in. + * @returns - The size of the Sprite. + */ + getSize(out) { + if (!out) { + out = {}; + } + out.width = Math.abs(this.scale.x) * this._texture.orig.width; + out.height = Math.abs(this.scale.y) * this._texture.orig.height; + return out; + } + /** + * Sets the size of the Sprite to the specified width and height. + * This is faster than setting the width and height separately. + * @param value - This can be either a number or a [Size]{@link Size} object. + * @param height - The height to set. Defaults to the value of `width` if not provided. + */ + setSize(value, height) { + var _a; + let convertedWidth; + let convertedHeight; + if (typeof value !== "object") { + convertedWidth = value; + convertedHeight = height != null ? height : value; + } else { + convertedWidth = value.width; + convertedHeight = (_a = value.height) != null ? _a : value.width; + } + if (convertedWidth !== void 0) { + this._setWidth(convertedWidth, this._texture.orig.width); + } + if (convertedHeight !== void 0) { + this._setHeight(convertedHeight, this._texture.orig.height); + } + } +} + +"use strict"; +const tempBounds$4 = new Bounds(); +function addMaskBounds(mask, bounds, skipUpdateTransform) { + const boundsToMask = tempBounds$4; + mask.measurable = true; + getGlobalBounds(mask, skipUpdateTransform, boundsToMask); + bounds.addBoundsMask(boundsToMask); + mask.measurable = false; +} + +"use strict"; +function addMaskLocalBounds(mask, bounds, localRoot) { + const boundsToMask = boundsPool.get(); + mask.measurable = true; + const tempMatrix = matrixPool.get().identity(); + const relativeMask = getMatrixRelativeToParent(mask, localRoot, tempMatrix); + getLocalBounds(mask, boundsToMask, relativeMask); + mask.measurable = false; + bounds.addBoundsMask(boundsToMask); + matrixPool.return(tempMatrix); + boundsPool.return(boundsToMask); +} +function getMatrixRelativeToParent(target, root, matrix) { + if (!target) { + warn("Mask bounds, renderable is not inside the root container"); + return matrix; + } + if (target !== root) { + getMatrixRelativeToParent(target.parent, root, matrix); + target.updateLocalTransform(); + matrix.append(target.localTransform); + } + return matrix; +} + +"use strict"; +class AlphaMask { + constructor(options) { + this.priority = 0; + this.pipe = "alphaMask"; + if (options == null ? void 0 : options.mask) { + this.init(options.mask); + } + } + init(mask) { + this.mask = mask; + this.renderMaskToTexture = !(mask instanceof Sprite); + this.mask.renderable = this.renderMaskToTexture; + this.mask.includeInBuild = !this.renderMaskToTexture; + this.mask.measurable = false; + } + reset() { + this.mask.measurable = true; + this.mask = null; + } + addBounds(bounds, skipUpdateTransform) { + addMaskBounds(this.mask, bounds, skipUpdateTransform); + } + addLocalBounds(bounds, localRoot) { + addMaskLocalBounds(this.mask, bounds, localRoot); + } + containsPoint(point, hitTestFn) { + const mask = this.mask; + return hitTestFn(mask, point); + } + destroy() { + this.reset(); + } + static test(mask) { + return mask instanceof Sprite; + } +} +AlphaMask.extension = ExtensionType.MaskEffect; + +"use strict"; +class ColorMask { + constructor(options) { + this.priority = 0; + this.pipe = "colorMask"; + if (options == null ? void 0 : options.mask) { + this.init(options.mask); + } + } + init(mask) { + this.mask = mask; + } + destroy() { + } + static test(mask) { + return typeof mask === "number"; + } +} +ColorMask.extension = ExtensionType.MaskEffect; + +"use strict"; +class StencilMask { + constructor(options) { + this.priority = 0; + this.pipe = "stencilMask"; + if (options == null ? void 0 : options.mask) { + this.init(options.mask); + } + } + init(mask) { + this.mask = mask; + this.mask.includeInBuild = false; + this.mask.measurable = false; + } + reset() { + this.mask.measurable = true; + this.mask.includeInBuild = true; + this.mask = null; + } + addBounds(bounds, skipUpdateTransform) { + addMaskBounds(this.mask, bounds, skipUpdateTransform); + } + addLocalBounds(bounds, localRoot) { + addMaskLocalBounds(this.mask, bounds, localRoot); + } + containsPoint(point, hitTestFn) { + const mask = this.mask; + return hitTestFn(mask, point); + } + destroy() { + this.reset(); + } + static test(mask) { + return mask instanceof Container; + } +} +StencilMask.extension = ExtensionType.MaskEffect; + +"use strict"; +class CanvasSource extends TextureSource { + constructor(options) { + if (!options.resource) { + options.resource = DOMAdapter.get().createCanvas(); + } + if (!options.width) { + options.width = options.resource.width; + if (!options.autoDensity) { + options.width /= options.resolution; + } + } + if (!options.height) { + options.height = options.resource.height; + if (!options.autoDensity) { + options.height /= options.resolution; + } + } + super(options); + this.uploadMethodId = "image"; + this.autoDensity = options.autoDensity; + const canvas = options.resource; + if (this.pixelWidth !== canvas.width || this.pixelWidth !== canvas.height) { + this.resizeCanvas(); + } + this.transparent = !!options.transparent; + } + resizeCanvas() { + if (this.autoDensity) { + this.resource.style.width = `${this.width}px`; + this.resource.style.height = `${this.height}px`; + } + if (this.resource.width !== this.pixelWidth || this.resource.height !== this.pixelHeight) { + this.resource.width = this.pixelWidth; + this.resource.height = this.pixelHeight; + } + } + resize(width = this.width, height = this.height, resolution = this._resolution) { + const didResize = super.resize(width, height, resolution); + if (didResize) { + this.resizeCanvas(); + } + return didResize; + } + static test(resource) { + return globalThis.HTMLCanvasElement && resource instanceof HTMLCanvasElement || globalThis.OffscreenCanvas && resource instanceof OffscreenCanvas; + } +} +CanvasSource.extension = ExtensionType.TextureSource; + +"use strict"; +class ImageSource extends TextureSource { + constructor(options) { + if (options.resource && (globalThis.HTMLImageElement && options.resource instanceof HTMLImageElement)) { + const canvas = DOMAdapter.get().createCanvas(options.resource.width, options.resource.height); + const context = canvas.getContext("2d"); + context.drawImage(options.resource, 0, 0); + options.resource = canvas; + warn("ImageSource: Image element passed, converting to canvas. Use CanvasSource instead."); + } + super(options); + this.uploadMethodId = "image"; + this.autoGarbageCollect = true; + } + static test(resource) { + return globalThis.HTMLImageElement && resource instanceof HTMLImageElement || typeof ImageBitmap !== "undefined" && resource instanceof ImageBitmap; + } +} +ImageSource.extension = ExtensionType.TextureSource; + +"use strict"; +let promise; +async function detectVideoAlphaMode() { + promise != null ? promise : promise = (async () => { + var _a; + const canvas = document.createElement("canvas"); + const gl = canvas.getContext("webgl"); + if (!gl) { + return "premultiply-alpha-on-upload"; + } + const video = await new Promise((resolve) => { + const video2 = document.createElement("video"); + video2.onloadeddata = () => resolve(video2); + video2.onerror = () => resolve(null); + video2.autoplay = false; + video2.crossOrigin = "anonymous"; + video2.preload = "auto"; + video2.src = "data:video/webm;base64,GkXfo59ChoEBQveBAULygQRC84EIQoKEd2VibUKHgQJChYECGFOAZwEAAAAAAAHTEU2bdLpNu4tTq4QVSalmU6yBoU27i1OrhBZUrmtTrIHGTbuMU6uEElTDZ1OsggEXTbuMU6uEHFO7a1OsggG97AEAAAAAAABZAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVSalmoCrXsYMPQkBNgIRMYXZmV0GETGF2ZkSJiEBEAAAAAAAAFlSua8yuAQAAAAAAAEPXgQFzxYgAAAAAAAAAAZyBACK1nIN1bmSIgQCGhVZfVlA5g4EBI+ODhAJiWgDglLCBArqBApqBAlPAgQFVsIRVuYEBElTDZ9Vzc9JjwItjxYgAAAAAAAAAAWfInEWjh0VOQ09ERVJEh49MYXZjIGxpYnZweC12cDlnyKJFo4hEVVJBVElPTkSHlDAwOjAwOjAwLjA0MDAwMDAwMAAAH0O2dcfngQCgwqGggQAAAIJJg0IAABAAFgA4JBwYSgAAICAAEb///4r+AAB1oZ2mm+6BAaWWgkmDQgAAEAAWADgkHBhKAAAgIABIQBxTu2uRu4+zgQC3iveBAfGCAXHwgQM="; + video2.load(); + }); + if (!video) { + return "premultiply-alpha-on-upload"; + } + const texture = gl.createTexture(); + gl.bindTexture(gl.TEXTURE_2D, texture); + const framebuffer = gl.createFramebuffer(); + gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer); + gl.framebufferTexture2D( + gl.FRAMEBUFFER, + gl.COLOR_ATTACHMENT0, + gl.TEXTURE_2D, + texture, + 0 + ); + gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, false); + gl.pixelStorei(gl.UNPACK_COLORSPACE_CONVERSION_WEBGL, gl.NONE); + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, video); + const pixel = new Uint8Array(4); + gl.readPixels(0, 0, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, pixel); + gl.deleteFramebuffer(framebuffer); + gl.deleteTexture(texture); + (_a = gl.getExtension("WEBGL_lose_context")) == null ? void 0 : _a.loseContext(); + return pixel[0] <= pixel[3] ? "premultiplied-alpha" : "premultiply-alpha-on-upload"; + })(); + return promise; +} + +"use strict"; +var __defProp$U = Object.defineProperty; +var __defProps$l = Object.defineProperties; +var __getOwnPropDescs$l = Object.getOwnPropertyDescriptors; +var __getOwnPropSymbols$U = Object.getOwnPropertySymbols; +var __hasOwnProp$U = Object.prototype.hasOwnProperty; +var __propIsEnum$U = Object.prototype.propertyIsEnumerable; +var __defNormalProp$U = (obj, key, value) => key in obj ? __defProp$U(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; +var __spreadValues$U = (a, b) => { + for (var prop in b || (b = {})) + if (__hasOwnProp$U.call(b, prop)) + __defNormalProp$U(a, prop, b[prop]); + if (__getOwnPropSymbols$U) + for (var prop of __getOwnPropSymbols$U(b)) { + if (__propIsEnum$U.call(b, prop)) + __defNormalProp$U(a, prop, b[prop]); + } + return a; +}; +var __spreadProps$l = (a, b) => __defProps$l(a, __getOwnPropDescs$l(b)); +const _VideoSource = class _VideoSource extends TextureSource { + constructor(options) { + var _a; + super(options); + // Public + /** Whether or not the video is ready to play. */ + this.isReady = false; + /** The upload method for this texture. */ + this.uploadMethodId = "video"; + options = __spreadValues$U(__spreadValues$U({}, _VideoSource.defaultOptions), options); + this._autoUpdate = true; + this._isConnectedToTicker = false; + this._updateFPS = options.updateFPS || 0; + this._msToNextUpdate = 0; + this.autoPlay = options.autoPlay !== false; + this.alphaMode = (_a = options.alphaMode) != null ? _a : "premultiply-alpha-on-upload"; + this._videoFrameRequestCallback = this._videoFrameRequestCallback.bind(this); + this._videoFrameRequestCallbackHandle = null; + this._load = null; + this._resolve = null; + this._reject = null; + this._onCanPlay = this._onCanPlay.bind(this); + this._onCanPlayThrough = this._onCanPlayThrough.bind(this); + this._onError = this._onError.bind(this); + this._onPlayStart = this._onPlayStart.bind(this); + this._onPlayStop = this._onPlayStop.bind(this); + this._onSeeked = this._onSeeked.bind(this); + if (options.autoLoad !== false) { + void this.load(); + } + } + /** Update the video frame if the source is not destroyed and meets certain conditions. */ + updateFrame() { + if (this.destroyed) { + return; + } + if (this._updateFPS) { + const elapsedMS = Ticker.shared.elapsedMS * this.resource.playbackRate; + this._msToNextUpdate = Math.floor(this._msToNextUpdate - elapsedMS); + } + if (!this._updateFPS || this._msToNextUpdate <= 0) { + this._msToNextUpdate = this._updateFPS ? Math.floor(1e3 / this._updateFPS) : 0; + } + if (this.isValid) { + this.update(); + } + } + /** Callback to update the video frame and potentially request the next frame update. */ + _videoFrameRequestCallback() { + this.updateFrame(); + if (this.destroyed) { + this._videoFrameRequestCallbackHandle = null; + } else { + this._videoFrameRequestCallbackHandle = this.resource.requestVideoFrameCallback( + this._videoFrameRequestCallback + ); + } + } + /** + * Checks if the resource has valid dimensions. + * @returns {boolean} True if width and height are set, otherwise false. + */ + get isValid() { + return !!this.resource.videoWidth && !!this.resource.videoHeight; + } + /** + * Start preloading the video resource. + * @returns {Promise} Handle the validate event + */ + async load() { + if (this._load) { + return this._load; + } + const source = this.resource; + const options = this.options; + if ((source.readyState === source.HAVE_ENOUGH_DATA || source.readyState === source.HAVE_FUTURE_DATA) && source.width && source.height) { + source.complete = true; + } + source.addEventListener("play", this._onPlayStart); + source.addEventListener("pause", this._onPlayStop); + source.addEventListener("seeked", this._onSeeked); + if (!this._isSourceReady()) { + if (!options.preload) { + source.addEventListener("canplay", this._onCanPlay); + } + source.addEventListener("canplaythrough", this._onCanPlayThrough); + source.addEventListener("error", this._onError, true); + } else { + this._mediaReady(); + } + this.alphaMode = await detectVideoAlphaMode(); + this._load = new Promise((resolve, reject) => { + if (this.isValid) { + resolve(this); + } else { + this._resolve = resolve; + this._reject = reject; + if (options.preloadTimeoutMs !== void 0) { + this._preloadTimeout = setTimeout(() => { + this._onError(new ErrorEvent(`Preload exceeded timeout of ${options.preloadTimeoutMs}ms`)); + }); + } + source.load(); + } + }); + return this._load; + } + /** + * Handle video error events. + * @param event - The error event + */ + _onError(event) { + this.resource.removeEventListener("error", this._onError, true); + this.emit("error", event); + if (this._reject) { + this._reject(event); + this._reject = null; + this._resolve = null; + } + } + /** + * Checks if the underlying source is playing. + * @returns True if playing. + */ + _isSourcePlaying() { + const source = this.resource; + return !source.paused && !source.ended; + } + /** + * Checks if the underlying source is ready for playing. + * @returns True if ready. + */ + _isSourceReady() { + const source = this.resource; + return source.readyState > 2; + } + /** Runs the update loop when the video is ready to play. */ + _onPlayStart() { + if (!this.isValid) { + this._mediaReady(); + } + this._configureAutoUpdate(); + } + /** Stops the update loop when a pause event is triggered. */ + _onPlayStop() { + this._configureAutoUpdate(); + } + /** Handles behavior when the video completes seeking to the current playback position. */ + _onSeeked() { + if (this._autoUpdate && !this._isSourcePlaying()) { + this._msToNextUpdate = 0; + this.updateFrame(); + this._msToNextUpdate = 0; + } + } + _onCanPlay() { + const source = this.resource; + source.removeEventListener("canplay", this._onCanPlay); + this._mediaReady(); + } + _onCanPlayThrough() { + const source = this.resource; + source.removeEventListener("canplaythrough", this._onCanPlay); + if (this._preloadTimeout) { + clearTimeout(this._preloadTimeout); + this._preloadTimeout = void 0; + } + this._mediaReady(); + } + /** Fired when the video is loaded and ready to play. */ + _mediaReady() { + const source = this.resource; + if (this.isValid) { + this.isReady = true; + this.resize(source.videoWidth, source.videoHeight); + } + this._msToNextUpdate = 0; + this.updateFrame(); + this._msToNextUpdate = 0; + if (this._resolve) { + this._resolve(this); + this._resolve = null; + this._reject = null; + } + if (this._isSourcePlaying()) { + this._onPlayStart(); + } else if (this.autoPlay) { + void this.resource.play(); + } + } + /** Cleans up resources and event listeners associated with this texture. */ + destroy() { + this._configureAutoUpdate(); + const source = this.resource; + if (source) { + source.removeEventListener("play", this._onPlayStart); + source.removeEventListener("pause", this._onPlayStop); + source.removeEventListener("seeked", this._onSeeked); + source.removeEventListener("canplay", this._onCanPlay); + source.removeEventListener("canplaythrough", this._onCanPlayThrough); + source.removeEventListener("error", this._onError, true); + source.pause(); + source.src = ""; + source.load(); + } + super.destroy(); + } + /** Should the base texture automatically update itself, set to true by default. */ + get autoUpdate() { + return this._autoUpdate; + } + set autoUpdate(value) { + if (value !== this._autoUpdate) { + this._autoUpdate = value; + this._configureAutoUpdate(); + } + } + /** + * How many times a second to update the texture from the video. + * Leave at 0 to update at every render. + * A lower fps can help performance, as updating the texture at 60fps on a 30ps video may not be efficient. + */ + get updateFPS() { + return this._updateFPS; + } + set updateFPS(value) { + if (value !== this._updateFPS) { + this._updateFPS = value; + this._configureAutoUpdate(); + } + } + /** + * Configures the updating mechanism based on the current state and settings. + * + * This method decides between using the browser's native video frame callback or a custom ticker + * for updating the video frame. It ensures optimal performance and responsiveness + * based on the video's state, playback status, and the desired frames-per-second setting. + * + * - If `_autoUpdate` is enabled and the video source is playing: + * - It will prefer the native video frame callback if available and no specific FPS is set. + * - Otherwise, it will use a custom ticker for manual updates. + * - If `_autoUpdate` is disabled or the video isn't playing, any active update mechanisms are halted. + */ + _configureAutoUpdate() { + if (this._autoUpdate && this._isSourcePlaying()) { + if (!this._updateFPS && this.resource.requestVideoFrameCallback) { + if (this._isConnectedToTicker) { + Ticker.shared.remove(this.updateFrame, this); + this._isConnectedToTicker = false; + this._msToNextUpdate = 0; + } + if (this._videoFrameRequestCallbackHandle === null) { + this._videoFrameRequestCallbackHandle = this.resource.requestVideoFrameCallback( + this._videoFrameRequestCallback + ); + } + } else { + if (this._videoFrameRequestCallbackHandle !== null) { + this.resource.cancelVideoFrameCallback(this._videoFrameRequestCallbackHandle); + this._videoFrameRequestCallbackHandle = null; + } + if (!this._isConnectedToTicker) { + Ticker.shared.add(this.updateFrame, this); + this._isConnectedToTicker = true; + this._msToNextUpdate = 0; + } + } + } else { + if (this._videoFrameRequestCallbackHandle !== null) { + this.resource.cancelVideoFrameCallback(this._videoFrameRequestCallbackHandle); + this._videoFrameRequestCallbackHandle = null; + } + if (this._isConnectedToTicker) { + Ticker.shared.remove(this.updateFrame, this); + this._isConnectedToTicker = false; + this._msToNextUpdate = 0; + } + } + } + static test(resource) { + return globalThis.HTMLVideoElement && resource instanceof HTMLVideoElement || globalThis.VideoFrame && resource instanceof VideoFrame; + } +}; +_VideoSource.extension = ExtensionType.TextureSource; +/** The default options for video sources. */ +_VideoSource.defaultOptions = __spreadProps$l(__spreadValues$U({}, TextureSource.defaultOptions), { + /** If true, the video will start loading immediately. */ + autoLoad: true, + /** If true, the video will start playing as soon as it is loaded. */ + autoPlay: true, + /** The number of times a second to update the texture from the video. Leave at 0 to update at every render. */ + updateFPS: 0, + /** If true, the video will be loaded with the `crossorigin` attribute. */ + crossorigin: true, + /** If true, the video will loop when it ends. */ + loop: false, + /** If true, the video will be muted. */ + muted: true, + /** If true, the video will play inline. */ + playsinline: true, + /** If true, the video will be preloaded. */ + preload: false +}); +/** + * Map of video MIME types that can't be directly derived from file extensions. + * @readonly + */ +_VideoSource.MIME_TYPES = { + ogv: "video/ogg", + mov: "video/quicktime", + m4v: "video/mp4" +}; +let VideoSource = _VideoSource; + +"use strict"; +class CacheClass { + constructor() { + this._parsers = []; + this._cache = /* @__PURE__ */ new Map(); + this._cacheMap = /* @__PURE__ */ new Map(); + } + /** Clear all entries. */ + reset() { + this._cacheMap.clear(); + this._cache.clear(); + } + /** + * Check if the key exists + * @param key - The key to check + */ + has(key) { + return this._cache.has(key); + } + /** + * Fetch entry by key + * @param key - The key of the entry to get + */ + get(key) { + const result = this._cache.get(key); + if (!result) { + warn(`[Assets] Asset id ${key} was not found in the Cache`); + } + return result; + } + /** + * Set a value by key or keys name + * @param key - The key or keys to set + * @param value - The value to store in the cache or from which cacheable assets will be derived. + */ + set(key, value) { + const keys = convertToList(key); + let cacheableAssets; + for (let i = 0; i < this.parsers.length; i++) { + const parser = this.parsers[i]; + if (parser.test(value)) { + cacheableAssets = parser.getCacheableAssets(keys, value); + break; + } + } + const cacheableMap = new Map(Object.entries(cacheableAssets || {})); + if (!cacheableAssets) { + keys.forEach((key2) => { + cacheableMap.set(key2, value); + }); + } + const cacheKeys = [...cacheableMap.keys()]; + const cachedAssets = { + cacheKeys, + keys + }; + keys.forEach((key2) => { + this._cacheMap.set(key2, cachedAssets); + }); + cacheKeys.forEach((key2) => { + const val = cacheableAssets ? cacheableAssets[key2] : value; + if (this._cache.has(key2) && this._cache.get(key2) !== val) { + warn("[Cache] already has key:", key2); + } + this._cache.set(key2, cacheableMap.get(key2)); + }); + } + /** + * Remove entry by key + * + * This function will also remove any associated alias from the cache also. + * @param key - The key of the entry to remove + */ + remove(key) { + if (!this._cacheMap.has(key)) { + warn(`[Assets] Asset id ${key} was not found in the Cache`); + return; + } + const cacheMap = this._cacheMap.get(key); + const cacheKeys = cacheMap.cacheKeys; + cacheKeys.forEach((key2) => { + this._cache.delete(key2); + }); + cacheMap.keys.forEach((key2) => { + this._cacheMap.delete(key2); + }); + } + /** All loader parsers registered */ + get parsers() { + return this._parsers; + } +} +const Cache = new CacheClass(); + +"use strict"; +const sources = []; +extensions.handleByList(ExtensionType.TextureSource, sources); +function autoDetectSource(options = {}) { + const hasResource = options && options.resource; + const res = hasResource ? options.resource : options; + const opts = hasResource ? options : { resource: options }; + for (let i = 0; i < sources.length; i++) { + const Source = sources[i]; + if (Source.test(res)) { + return new Source(opts); + } + } + throw new Error(`Could not find a source type for resource: ${opts.resource}`); +} +function resourceToTexture(options = {}, skipCache = false) { + const hasResource = options && options.resource; + const resource = hasResource ? options.resource : options; + const opts = hasResource ? options : { resource: options }; + if (!skipCache && Cache.has(resource)) { + return Cache.get(resource); + } + const texture = new Texture({ source: autoDetectSource(opts) }); + texture.on("destroy", () => { + if (Cache.has(resource)) { + Cache.remove(resource); + } + }); + if (!skipCache) { + Cache.set(resource, texture); + } + return texture; +} +function textureFrom(id, skipCache = false) { + if (typeof id === "string") { + return Cache.get(id); + } else if (id instanceof TextureSource) { + return new Texture({ source: id }); + } + return resourceToTexture(id, skipCache); +} +Texture.from = textureFrom; + +"use strict"; +extensions.add(AlphaMask, ColorMask, StencilMask, VideoSource, ImageSource, CanvasSource, BufferImageSource); + +"use strict"; +var BufferUsage = /* @__PURE__ */ ((BufferUsage2) => { + BufferUsage2[BufferUsage2["MAP_READ"] = 1] = "MAP_READ"; + BufferUsage2[BufferUsage2["MAP_WRITE"] = 2] = "MAP_WRITE"; + BufferUsage2[BufferUsage2["COPY_SRC"] = 4] = "COPY_SRC"; + BufferUsage2[BufferUsage2["COPY_DST"] = 8] = "COPY_DST"; + BufferUsage2[BufferUsage2["INDEX"] = 16] = "INDEX"; + BufferUsage2[BufferUsage2["VERTEX"] = 32] = "VERTEX"; + BufferUsage2[BufferUsage2["UNIFORM"] = 64] = "UNIFORM"; + BufferUsage2[BufferUsage2["STORAGE"] = 128] = "STORAGE"; + BufferUsage2[BufferUsage2["INDIRECT"] = 256] = "INDIRECT"; + BufferUsage2[BufferUsage2["QUERY_RESOLVE"] = 512] = "QUERY_RESOLVE"; + BufferUsage2[BufferUsage2["STATIC"] = 1024] = "STATIC"; + return BufferUsage2; +})(BufferUsage || {}); + +"use strict"; +class Buffer extends EventEmitter { + /** + * Creates a new Buffer with the given options + * @param options - the options for the buffer + */ + constructor(options) { + let { data, size } = options; + const { usage, label, shrinkToFit } = options; + super(); + /** + * emits when the underlying buffer has changed shape (i.e. resized) + * letting the renderer know that it needs to discard the old buffer on the GPU and create a new one + * @event change + */ + /** + * emits when the underlying buffer data has been updated. letting the renderer know + * that it needs to update the buffer on the GPU + * @event update + */ + /** + * emits when the buffer is destroyed. letting the renderer know that it needs to destroy the buffer on the GPU + * @event destroy + */ + /** + * a unique id for this uniform group used through the renderer + * @internal + * @ignore + */ + this.uid = uid("buffer"); + /** + * a resource type, used to identify how to handle it when its in a bind group / shader resource + * @internal + * @ignore + */ + this._resourceType = "buffer"; + /** + * the resource id used internally by the renderer to build bind group keys + * @internal + * @ignore + */ + this._resourceId = uid("resource"); + /** + * used internally to know if a uniform group was used in the last render pass + * @internal + * @ignore + */ + this._touched = 0; + /** + * @internal + * @ignore + */ + this._updateID = 1; + /** + * should the GPU buffer be shrunk when the data becomes smaller? + * changing this will cause the buffer to be destroyed and a new one created on the GPU + * this can be expensive, especially if the buffer is already big enough! + * setting this to false will prevent the buffer from being shrunk. This will yield better performance + * if you are constantly setting data that is changing size often. + * @default true + */ + this.shrinkToFit = true; + /** + * Has the buffer been destroyed? + * @readonly + */ + this.destroyed = false; + if (data instanceof Array) { + data = new Float32Array(data); + } + this._data = data; + size = size != null ? size : data == null ? void 0 : data.byteLength; + const mappedAtCreation = !!data; + this.descriptor = { + size, + usage, + mappedAtCreation, + label + }; + this.shrinkToFit = shrinkToFit != null ? shrinkToFit : true; + } + /** the data in the buffer */ + get data() { + return this._data; + } + set data(value) { + this.setDataWithSize(value, value.length, true); + } + /** whether the buffer is static or not */ + get static() { + return !!(this.descriptor.usage & BufferUsage.STATIC); + } + set static(value) { + if (value) { + this.descriptor.usage |= BufferUsage.STATIC; + } else { + this.descriptor.usage &= ~BufferUsage.STATIC; + } + } + /** + * Sets the data in the buffer to the given value. This will immediately update the buffer on the GPU. + * If you only want to update a subset of the buffer, you can pass in the size of the data. + * @param value - the data to set + * @param size - the size of the data in bytes + * @param syncGPU - should the buffer be updated on the GPU immediately? + */ + setDataWithSize(value, size, syncGPU) { + this._updateID++; + this._updateSize = size * value.BYTES_PER_ELEMENT; + if (this._data === value) { + if (syncGPU) + this.emit("update", this); + return; + } + const oldData = this._data; + this._data = value; + if (oldData.length !== value.length) { + if (!this.shrinkToFit && value.byteLength < oldData.byteLength) { + if (syncGPU) + this.emit("update", this); + } else { + this.descriptor.size = value.byteLength; + this._resourceId = uid("resource"); + this.emit("change", this); + } + return; + } + if (syncGPU) + this.emit("update", this); + } + /** + * updates the buffer on the GPU to reflect the data in the buffer. + * By default it will update the entire buffer. If you only want to update a subset of the buffer, + * you can pass in the size of the buffer to update. + * @param sizeInBytes - the new size of the buffer in bytes + */ + update(sizeInBytes) { + this._updateSize = sizeInBytes != null ? sizeInBytes : this._updateSize; + this._updateID++; + this.emit("update", this); + } + /** Destroys the buffer */ + destroy() { + this.destroyed = true; + this.emit("destroy", this); + this.emit("change", this); + this._data = null; + this.descriptor = null; + this.removeAllListeners(); + } +} + +"use strict"; +function ensureIsBuffer(buffer, index) { + if (!(buffer instanceof Buffer)) { + let usage = index ? BufferUsage.INDEX : BufferUsage.VERTEX; + if (buffer instanceof Array) { + if (index) { + buffer = new Uint32Array(buffer); + usage = BufferUsage.INDEX | BufferUsage.COPY_DST; + } else { + buffer = new Float32Array(buffer); + usage = BufferUsage.VERTEX | BufferUsage.COPY_DST; + } + } + buffer = new Buffer({ + data: buffer, + label: index ? "index-mesh-buffer" : "vertex-mesh-buffer", + usage + }); + } + return buffer; +} + +"use strict"; +function getGeometryBounds(geometry, attributeId, bounds) { + const attribute = geometry.getAttribute(attributeId); + if (!attribute) { + bounds.minX = 0; + bounds.minY = 0; + bounds.maxX = 0; + bounds.maxY = 0; + return bounds; + } + const data = attribute.buffer.data; + let minX = Infinity; + let minY = Infinity; + let maxX = -Infinity; + let maxY = -Infinity; + const byteSize = data.BYTES_PER_ELEMENT; + const offset = (attribute.offset || 0) / byteSize; + const stride = (attribute.stride || 2 * 4) / byteSize; + for (let i = offset; i < data.length; i += stride) { + const x = data[i]; + const y = data[i + 1]; + if (x > maxX) + maxX = x; + if (y > maxY) + maxY = y; + if (x < minX) + minX = x; + if (y < minY) + minY = y; + } + bounds.minX = minX; + bounds.minY = minY; + bounds.maxX = maxX; + bounds.maxY = maxY; + return bounds; +} + +"use strict"; +function ensureIsAttribute(attribute) { + if (attribute instanceof Buffer || Array.isArray(attribute) || attribute.BYTES_PER_ELEMENT) { + attribute = { + buffer: attribute + }; + } + attribute.buffer = ensureIsBuffer(attribute.buffer, false); + return attribute; +} +class Geometry extends EventEmitter { + /** + * Create a new instance of a geometry + * @param options - The options for the geometry. + */ + constructor(options) { + const { attributes, indexBuffer, topology } = options; + super(); + /** The unique id of the geometry. */ + this.uid = uid("geometry"); + /** + * the layout key will be generated by WebGPU all geometries that have the same structure + * will have the same layout key. This is used to cache the pipeline layout + * @internal + * @ignore + */ + this._layoutKey = 0; + /** the instance count of the geometry to draw */ + this.instanceCount = 1; + this._bounds = new Bounds(); + this._boundsDirty = true; + this.attributes = attributes; + this.buffers = []; + this.instanceCount = options.instanceCount || 1; + for (const i in attributes) { + const attribute = attributes[i] = ensureIsAttribute(attributes[i]); + const bufferIndex = this.buffers.indexOf(attribute.buffer); + if (bufferIndex === -1) { + this.buffers.push(attribute.buffer); + attribute.buffer.on("update", this.onBufferUpdate, this); + attribute.buffer.on("change", this.onBufferUpdate, this); + } + } + if (indexBuffer) { + this.indexBuffer = ensureIsBuffer(indexBuffer, true); + this.buffers.push(this.indexBuffer); + } + this.topology = topology || "triangle-list"; + } + onBufferUpdate() { + this._boundsDirty = true; + this.emit("update", this); + } + /** + * Returns the requested attribute. + * @param id - The name of the attribute required + * @returns - The attribute requested. + */ + getAttribute(id) { + return this.attributes[id]; + } + /** + * Returns the index buffer + * @returns - The index buffer. + */ + getIndex() { + return this.indexBuffer; + } + /** + * Returns the requested buffer. + * @param id - The name of the buffer required. + * @returns - The buffer requested. + */ + getBuffer(id) { + return this.getAttribute(id).buffer; + } + /** + * Used to figure out how many vertices there are in this geometry + * @returns the number of vertices in the geometry + */ + getSize() { + for (const i in this.attributes) { + const attribute = this.attributes[i]; + const buffer = attribute.buffer; + return buffer.data.length / (attribute.stride / 4 || attribute.size); + } + return 0; + } + /** Returns the bounds of the geometry. */ + get bounds() { + if (!this._boundsDirty) + return this._bounds; + this._boundsDirty = false; + return getGeometryBounds(this, "aPosition", this._bounds); + } + /** + * destroys the geometry. + * @param destroyBuffers - destroy the buffers associated with this geometry + */ + destroy(destroyBuffers = false) { + this.emit("destroy", this); + this.removeAllListeners(); + if (destroyBuffers) { + this.buffers.forEach((buffer) => buffer.destroy()); + } + this.attributes = null; + this.buffers = null; + this.indexBuffer = null; + this._bounds = null; + } +} + +"use strict"; +const placeHolderBufferData = new Float32Array(1); +const placeHolderIndexData = new Uint32Array(1); +class BatchGeometry extends Geometry { + constructor() { + const vertexSize = 6; + const attributeBuffer = new Buffer({ + data: placeHolderBufferData, + label: "attribute-batch-buffer", + usage: BufferUsage.VERTEX | BufferUsage.COPY_DST, + shrinkToFit: false + }); + const indexBuffer = new Buffer({ + data: placeHolderIndexData, + label: "index-batch-buffer", + usage: BufferUsage.INDEX | BufferUsage.COPY_DST, + // | BufferUsage.STATIC, + shrinkToFit: false + }); + const stride = vertexSize * 4; + super({ + attributes: { + aPosition: { + buffer: attributeBuffer, + format: "float32x2", + stride, + offset: 0, + location: 1 + }, + aUV: { + buffer: attributeBuffer, + format: "float32x2", + stride, + offset: 2 * 4, + location: 3 + }, + aColor: { + buffer: attributeBuffer, + format: "unorm8x4", + stride, + offset: 4 * 4, + location: 0 + }, + aTextureIdAndRound: { + buffer: attributeBuffer, + format: "uint16x2", + stride, + offset: 5 * 4, + location: 2 + } + }, + indexBuffer + }); + } +} + +"use strict"; +class BindGroup { + /** + * Create a new instance eof the Bind Group. + * @param resources - The resources that are bound together for use by a shader. + */ + constructor(resources) { + /** The resources that are bound together for use by a shader. */ + this.resources = /* @__PURE__ */ Object.create(null); + this._dirty = true; + let index = 0; + for (const i in resources) { + const resource = resources[i]; + this.setResource(resource, index++); + } + this._updateKey(); + } + /** + * Updates the key if its flagged as dirty. This is used internally to + * match this bind group to a WebGPU BindGroup. + * @internal + * @ignore + */ + _updateKey() { + if (!this._dirty) + return; + this._dirty = false; + const keyParts = []; + let index = 0; + for (const i in this.resources) { + keyParts[index++] = this.resources[i]._resourceId; + } + this._key = keyParts.join("|"); + } + /** + * Set a resource at a given index. this function will + * ensure that listeners will be removed from the current resource + * and added to the new resource. + * @param resource - The resource to set. + * @param index - The index to set the resource at. + */ + setResource(resource, index) { + var _a, _b; + const currentResource = this.resources[index]; + if (resource === currentResource) + return; + if (currentResource) { + (_a = resource.off) == null ? void 0 : _a.call(resource, "change", this.onResourceChange, this); + } + (_b = resource.on) == null ? void 0 : _b.call(resource, "change", this.onResourceChange, this); + this.resources[index] = resource; + this._dirty = true; + } + /** + * Returns the resource at the current specified index. + * @param index - The index of the resource to get. + * @returns - The resource at the specified index. + */ + getResource(index) { + return this.resources[index]; + } + /** + * Used internally to 'touch' each resource, to ensure that the GC + * knows that all resources in this bind group are still being used. + * @param tick - The current tick. + * @internal + * @ignore + */ + _touch(tick) { + const resources = this.resources; + for (const i in resources) { + resources[i]._touched = tick; + } + } + /** Destroys this bind group and removes all listeners. */ + destroy() { + var _a; + const resources = this.resources; + for (const i in resources) { + const resource = resources[i]; + (_a = resource.off) == null ? void 0 : _a.call(resource, "change", this.onResourceChange, this); + } + this.resources = null; + } + onResourceChange(resource) { + this._dirty = true; + if (resource.destroyed) { + const resources = this.resources; + for (const i in resources) { + if (resources[i] === resource) { + resources[i] = null; + } + } + } else { + this._updateKey(); + } + } +} + +"use strict"; +const MAX_TEXTURES = 16; + +"use strict"; +const cachedGroups = {}; +function getTextureBatchBindGroup(textures, size) { + let uid = 0; + for (let i = 0; i < size; i++) { + uid = uid * 31 + textures[i].uid >>> 0; + } + return cachedGroups[uid] || generateTextureBatchBindGroup(textures, uid); +} +function generateTextureBatchBindGroup(textures, key) { + const bindGroupResources = {}; + let bindIndex = 0; + for (let i = 0; i < MAX_TEXTURES; i++) { + const texture = i < textures.length ? textures[i] : Texture.EMPTY.source; + bindGroupResources[bindIndex++] = texture.source; + bindGroupResources[bindIndex++] = texture.style; + } + const bindGroup = new BindGroup(bindGroupResources); + cachedGroups[key] = bindGroup; + return bindGroup; +} + +"use strict"; +class ViewableBuffer { + constructor(sizeOrBuffer) { + if (typeof sizeOrBuffer === "number") { + this.rawBinaryData = new ArrayBuffer(sizeOrBuffer); + } else if (sizeOrBuffer instanceof Uint8Array) { + this.rawBinaryData = sizeOrBuffer.buffer; + } else { + this.rawBinaryData = sizeOrBuffer; + } + this.uint32View = new Uint32Array(this.rawBinaryData); + this.float32View = new Float32Array(this.rawBinaryData); + this.size = this.rawBinaryData.byteLength; + } + /** View on the raw binary data as a `Int8Array`. */ + get int8View() { + if (!this._int8View) { + this._int8View = new Int8Array(this.rawBinaryData); + } + return this._int8View; + } + /** View on the raw binary data as a `Uint8Array`. */ + get uint8View() { + if (!this._uint8View) { + this._uint8View = new Uint8Array(this.rawBinaryData); + } + return this._uint8View; + } + /** View on the raw binary data as a `Int16Array`. */ + get int16View() { + if (!this._int16View) { + this._int16View = new Int16Array(this.rawBinaryData); + } + return this._int16View; + } + /** View on the raw binary data as a `Int32Array`. */ + get int32View() { + if (!this._int32View) { + this._int32View = new Int32Array(this.rawBinaryData); + } + return this._int32View; + } + /** View on the raw binary data as a `Float64Array`. */ + get float64View() { + if (!this._float64Array) { + this._float64Array = new Float64Array(this.rawBinaryData); + } + return this._float64Array; + } + /** View on the raw binary data as a `BigUint64Array`. */ + get bigUint64View() { + if (!this._bigUint64Array) { + this._bigUint64Array = new BigUint64Array(this.rawBinaryData); + } + return this._bigUint64Array; + } + /** + * Returns the view of the given type. + * @param type - One of `int8`, `uint8`, `int16`, + * `uint16`, `int32`, `uint32`, and `float32`. + * @returns - typed array of given type + */ + view(type) { + return this[`${type}View`]; + } + /** Destroys all buffer references. Do not use after calling this. */ + destroy() { + this.rawBinaryData = null; + this._int8View = null; + this._uint8View = null; + this._int16View = null; + this.uint16View = null; + this._int32View = null; + this.uint32View = null; + this.float32View = null; + } + /** + * Returns the size of the given type in bytes. + * @param type - One of `int8`, `uint8`, `int16`, + * `uint16`, `int32`, `uint32`, and `float32`. + * @returns - size of the type in bytes + */ + static sizeOf(type) { + switch (type) { + case "int8": + case "uint8": + return 1; + case "int16": + case "uint16": + return 2; + case "int32": + case "uint32": + case "float32": + return 4; + default: + throw new Error(`${type} isn't a valid view type`); + } + } +} + +"use strict"; +function fastCopy(sourceBuffer, destinationBuffer) { + const lengthDouble = sourceBuffer.byteLength / 8 | 0; + const sourceFloat64View = new Float64Array(sourceBuffer, 0, lengthDouble); + const destinationFloat64View = new Float64Array(destinationBuffer, 0, lengthDouble); + destinationFloat64View.set(sourceFloat64View); + const remainingBytes = sourceBuffer.byteLength - lengthDouble * 8; + if (remainingBytes > 0) { + const sourceUint8View = new Uint8Array(sourceBuffer, lengthDouble * 8, remainingBytes); + const destinationUint8View = new Uint8Array(destinationBuffer, lengthDouble * 8, remainingBytes); + destinationUint8View.set(sourceUint8View); + } +} + +"use strict"; +const BLEND_TO_NPM = { + normal: "normal-npm", + add: "add-npm", + screen: "screen-npm" +}; +var STENCIL_MODES = /* @__PURE__ */ ((STENCIL_MODES2) => { + STENCIL_MODES2[STENCIL_MODES2["DISABLED"] = 0] = "DISABLED"; + STENCIL_MODES2[STENCIL_MODES2["RENDERING_MASK_ADD"] = 1] = "RENDERING_MASK_ADD"; + STENCIL_MODES2[STENCIL_MODES2["MASK_ACTIVE"] = 2] = "MASK_ACTIVE"; + STENCIL_MODES2[STENCIL_MODES2["RENDERING_MASK_REMOVE"] = 3] = "RENDERING_MASK_REMOVE"; + STENCIL_MODES2[STENCIL_MODES2["NONE"] = 4] = "NONE"; + return STENCIL_MODES2; +})(STENCIL_MODES || {}); + +"use strict"; +function getAdjustedBlendModeBlend(blendMode, textureSource) { + if (textureSource.alphaMode === "no-premultiply-alpha") { + return BLEND_TO_NPM[blendMode] || blendMode; + } + return blendMode; +} + +"use strict"; +class BatchTextureArray { + constructor() { + /** Respective locations for textures. */ + this.ids = /* @__PURE__ */ Object.create(null); + this.textures = []; + this.count = 0; + } + /** Clear the textures and their locations. */ + clear() { + for (let i = 0; i < this.count; i++) { + const t = this.textures[i]; + this.textures[i] = null; + this.ids[t.uid] = null; + } + this.count = 0; + } +} + +"use strict"; +var __defProp$T = Object.defineProperty; +var __getOwnPropSymbols$T = Object.getOwnPropertySymbols; +var __hasOwnProp$T = Object.prototype.hasOwnProperty; +var __propIsEnum$T = Object.prototype.propertyIsEnumerable; +var __defNormalProp$T = (obj, key, value) => key in obj ? __defProp$T(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; +var __spreadValues$T = (a, b) => { + for (var prop in b || (b = {})) + if (__hasOwnProp$T.call(b, prop)) + __defNormalProp$T(a, prop, b[prop]); + if (__getOwnPropSymbols$T) + for (var prop of __getOwnPropSymbols$T(b)) { + if (__propIsEnum$T.call(b, prop)) + __defNormalProp$T(a, prop, b[prop]); + } + return a; +}; +class Batch { + constructor() { + this.renderPipeId = "batch"; + this.action = "startBatch"; + // TODO - eventually this could be useful for flagging batches as dirty and then only rebuilding those ones + // public elementStart = 0; + // public elementSize = 0; + // for drawing.. + this.start = 0; + this.size = 0; + this.blendMode = "normal"; + this.canBundle = true; + } + destroy() { + this.textures = null; + this.gpuBindGroup = null; + this.bindGroup = null; + this.batcher = null; + } +} +let BATCH_TICK = 0; +const _Batcher = class _Batcher { + constructor(options = {}) { + this.uid = uid("batcher"); + this.dirty = true; + this.batchIndex = 0; + this.batches = []; + // specifics. + this._vertexSize = 6; + this._elements = []; + this._batchPool = []; + this._batchPoolIndex = 0; + this._textureBatchPool = []; + this._textureBatchPoolIndex = 0; + options = __spreadValues$T(__spreadValues$T({}, _Batcher.defaultOptions), options); + const { vertexSize, indexSize } = options; + this.attributeBuffer = new ViewableBuffer(vertexSize * this._vertexSize * 4); + this.indexBuffer = new Uint16Array(indexSize); + } + begin() { + this.batchIndex = 0; + this.elementSize = 0; + this.elementStart = 0; + this.indexSize = 0; + this.attributeSize = 0; + this._batchPoolIndex = 0; + this._textureBatchPoolIndex = 0; + this._batchIndexStart = 0; + this._batchIndexSize = 0; + this.dirty = true; + } + add(batchableObject) { + this._elements[this.elementSize++] = batchableObject; + batchableObject.indexStart = this.indexSize; + batchableObject.location = this.attributeSize; + batchableObject.batcher = this; + this.indexSize += batchableObject.indexSize; + this.attributeSize += batchableObject.vertexSize * this._vertexSize; + } + checkAndUpdateTexture(batchableObject, texture) { + const textureId = batchableObject.batch.textures.ids[texture._source.uid]; + if (!textureId && textureId !== 0) + return false; + batchableObject.textureId = textureId; + batchableObject.texture = texture; + return true; + } + updateElement(batchableObject) { + this.dirty = true; + batchableObject.packAttributes( + this.attributeBuffer.float32View, + this.attributeBuffer.uint32View, + batchableObject.location, + batchableObject.textureId + ); + } + /** + * breaks the batcher. This happens when a batch gets too big, + * or we need to switch to a different type of rendering (a filter for example) + * @param instructionSet + */ + break(instructionSet) { + const elements = this._elements; + let textureBatch = this._textureBatchPool[this._textureBatchPoolIndex++] || new BatchTextureArray(); + textureBatch.clear(); + if (!elements[this.elementStart]) + return; + const firstElement = elements[this.elementStart]; + let blendMode = getAdjustedBlendModeBlend(firstElement.blendMode, firstElement.texture._source); + if (this.attributeSize * 4 > this.attributeBuffer.size) { + this._resizeAttributeBuffer(this.attributeSize * 4); + } + if (this.indexSize > this.indexBuffer.length) { + this._resizeIndexBuffer(this.indexSize); + } + const f32 = this.attributeBuffer.float32View; + const u32 = this.attributeBuffer.uint32View; + const iBuffer = this.indexBuffer; + let size = this._batchIndexSize; + let start = this._batchIndexStart; + let action = "startBatch"; + let batch = this._batchPool[this._batchPoolIndex++] || new Batch(); + for (let i = this.elementStart; i < this.elementSize; ++i) { + const element = elements[i]; + elements[i] = null; + const texture = element.texture; + const source = texture._source; + const adjustedBlendMode = getAdjustedBlendModeBlend(element.blendMode, source); + const blendModeChange = blendMode !== adjustedBlendMode; + if (source._batchTick === BATCH_TICK && !blendModeChange) { + element.textureId = source._textureBindLocation; + size += element.indexSize; + element.packAttributes(f32, u32, element.location, element.textureId); + element.packIndex(iBuffer, element.indexStart, element.location / this._vertexSize); + element.batch = batch; + continue; + } + source._batchTick = BATCH_TICK; + if (textureBatch.count >= MAX_TEXTURES || blendModeChange) { + this._finishBatch( + batch, + start, + size - start, + textureBatch, + blendMode, + instructionSet, + action + ); + action = "renderBatch"; + start = size; + blendMode = adjustedBlendMode; + textureBatch = this._textureBatchPool[this._textureBatchPoolIndex++] || new BatchTextureArray(); + textureBatch.clear(); + batch = this._batchPool[this._batchPoolIndex++] || new Batch(); + ++BATCH_TICK; + } + element.textureId = source._textureBindLocation = textureBatch.count; + textureBatch.ids[source.uid] = textureBatch.count; + textureBatch.textures[textureBatch.count++] = source; + element.batch = batch; + size += element.indexSize; + element.packAttributes(f32, u32, element.location, element.textureId); + element.packIndex(iBuffer, element.indexStart, element.location / this._vertexSize); + } + if (textureBatch.count > 0) { + this._finishBatch( + batch, + start, + size - start, + textureBatch, + blendMode, + instructionSet, + action + ); + start = size; + ++BATCH_TICK; + } + this.elementStart = this.elementSize; + this._batchIndexStart = start; + this._batchIndexSize = size; + } + _finishBatch(batch, indexStart, indexSize, textureBatch, blendMode, instructionSet, action) { + batch.gpuBindGroup = null; + batch.action = action; + batch.batcher = this; + batch.textures = textureBatch; + batch.blendMode = blendMode; + batch.start = indexStart; + batch.size = indexSize; + ++BATCH_TICK; + instructionSet.add(batch); + } + finish(instructionSet) { + this.break(instructionSet); + } + /** + * Resizes the attribute buffer to the given size (1 = 1 float32) + * @param size - the size in vertices to ensure (not bytes!) + */ + ensureAttributeBuffer(size) { + if (size * 4 <= this.attributeBuffer.size) + return; + this._resizeAttributeBuffer(size * 4); + } + /** + * Resizes the index buffer to the given size (1 = 1 float32) + * @param size - the size in vertices to ensure (not bytes!) + */ + ensureIndexBuffer(size) { + if (size <= this.indexBuffer.length) + return; + this._resizeIndexBuffer(size); + } + _resizeAttributeBuffer(size) { + const newSize = Math.max(size, this.attributeBuffer.size * 2); + const newArrayBuffer = new ViewableBuffer(newSize); + fastCopy(this.attributeBuffer.rawBinaryData, newArrayBuffer.rawBinaryData); + this.attributeBuffer = newArrayBuffer; + } + _resizeIndexBuffer(size) { + const indexBuffer = this.indexBuffer; + let newSize = Math.max(size, indexBuffer.length * 1.5); + newSize += newSize % 2; + const newIndexBuffer = newSize > 65535 ? new Uint32Array(newSize) : new Uint16Array(newSize); + if (newIndexBuffer.BYTES_PER_ELEMENT !== indexBuffer.BYTES_PER_ELEMENT) { + for (let i = 0; i < indexBuffer.length; i++) { + newIndexBuffer[i] = indexBuffer[i]; + } + } else { + fastCopy(indexBuffer.buffer, newIndexBuffer.buffer); + } + this.indexBuffer = newIndexBuffer; + } + destroy() { + for (let i = 0; i < this.batches.length; i++) { + this.batches[i].destroy(); + } + this.batches = null; + for (let i = 0; i < this._elements.length; i++) { + this._elements[i].batch = null; + } + this._elements = null; + this.indexBuffer = null; + this.attributeBuffer.destroy(); + this.attributeBuffer = null; + } +}; +_Batcher.defaultOptions = { + vertexSize: 4, + indexSize: 6 +}; +let Batcher = _Batcher; + +"use strict"; +function buildUvs(vertices, verticesStride, verticesOffset, uvs, uvsOffset, uvsStride, size, matrix = null) { + let index = 0; + verticesOffset *= verticesStride; + uvsOffset *= uvsStride; + const a = matrix.a; + const b = matrix.b; + const c = matrix.c; + const d = matrix.d; + const tx = matrix.tx; + const ty = matrix.ty; + while (index < size) { + const x = vertices[verticesOffset]; + const y = vertices[verticesOffset + 1]; + uvs[uvsOffset] = a * x + c * y + tx; + uvs[uvsOffset + 1] = b * x + d * y + ty; + uvsOffset += uvsStride; + verticesOffset += verticesStride; + index++; + } +} +function buildSimpleUvs(uvs, uvsOffset, uvsStride, size) { + let index = 0; + uvsOffset *= uvsStride; + while (index < size) { + uvs[uvsOffset] = 0; + uvs[uvsOffset + 1] = 0; + uvsOffset += uvsStride; + index++; + } +} + +"use strict"; +function transformVertices(vertices, m, offset, stride, size) { + const a = m.a; + const b = m.b; + const c = m.c; + const d = m.d; + const tx = m.tx; + const ty = m.ty; + offset = offset || 0; + stride = stride || 2; + size = size || vertices.length / stride - offset; + let index = offset * stride; + for (let i = 0; i < size; i++) { + const x = vertices[index]; + const y = vertices[index + 1]; + vertices[index] = a * x + c * y + tx; + vertices[index + 1] = b * x + d * y + ty; + index += stride; + } +} + +"use strict"; +function mixHexColors(color1, color2, ratio) { + const r1 = color1 >> 16 & 255; + const g1 = color1 >> 8 & 255; + const b1 = color1 & 255; + const r2 = color2 >> 16 & 255; + const g2 = color2 >> 8 & 255; + const b2 = color2 & 255; + const r = r1 + (r2 - r1) * ratio; + const g = g1 + (g2 - g1) * ratio; + const b = b1 + (b2 - b1) * ratio; + return (r << 16) + (g << 8) + b; +} + +"use strict"; +const WHITE_BGR = 16777215; +function mixColors(localBGRColor, parentBGRColor) { + if (localBGRColor === WHITE_BGR || parentBGRColor === WHITE_BGR) { + return localBGRColor + parentBGRColor - WHITE_BGR; + } + return mixHexColors(localBGRColor, parentBGRColor, 0.5); +} +function mixStandardAnd32BitColors(localColorRGB, localAlpha, parentColor) { + const parentAlpha = (parentColor >> 24 & 255) / 255; + const globalAlpha = localAlpha * parentAlpha * 255; + const localBGRColor = ((localColorRGB & 255) << 16) + (localColorRGB & 65280) + (localColorRGB >> 16 & 255); + const parentBGRColor = parentColor & 16777215; + let sharedBGRColor; + if (localBGRColor === WHITE_BGR || parentBGRColor === WHITE_BGR) { + sharedBGRColor = localBGRColor + parentBGRColor - WHITE_BGR; + } else { + sharedBGRColor = mixHexColors(localBGRColor, parentBGRColor, 0.5); + } + return sharedBGRColor + (globalAlpha << 24); +} + +"use strict"; +class BatchableGraphics { + constructor() { + this.batcher = null; + this.batch = null; + this.applyTransform = true; + this.roundPixels = 0; + } + get blendMode() { + if (this.applyTransform) { + return this.renderable.groupBlendMode; + } + return "normal"; + } + packIndex(indexBuffer, index, indicesOffset) { + const indices = this.geometryData.indices; + for (let i = 0; i < this.indexSize; i++) { + indexBuffer[index++] = indices[i + this.indexOffset] + indicesOffset - this.vertexOffset; + } + } + packAttributes(float32View, uint32View, index, textureId) { + const geometry = this.geometryData; + const graphics = this.renderable; + const positions = geometry.vertices; + const uvs = geometry.uvs; + const offset = this.vertexOffset * 2; + const vertSize = (this.vertexOffset + this.vertexSize) * 2; + const rgb = this.color; + const bgr = rgb >> 16 | rgb & 65280 | (rgb & 255) << 16; + if (this.applyTransform) { + const argb = mixColors(bgr, graphics.groupColor) + (this.alpha * graphics.groupAlpha * 255 << 24); + const wt = graphics.groupTransform; + const textureIdAndRound = textureId << 16 | this.roundPixels & 65535; + const a = wt.a; + const b = wt.b; + const c = wt.c; + const d = wt.d; + const tx = wt.tx; + const ty = wt.ty; + for (let i = offset; i < vertSize; i += 2) { + const x = positions[i]; + const y = positions[i + 1]; + float32View[index] = a * x + c * y + tx; + float32View[index + 1] = b * x + d * y + ty; + float32View[index + 2] = uvs[i]; + float32View[index + 3] = uvs[i + 1]; + uint32View[index + 4] = argb; + uint32View[index + 5] = textureIdAndRound; + index += 6; + } + } else { + const argb = bgr + (this.alpha * 255 << 24); + for (let i = offset; i < vertSize; i += 2) { + float32View[index] = positions[i]; + float32View[index + 1] = positions[i + 1]; + float32View[index + 2] = uvs[i]; + float32View[index + 3] = uvs[i + 1]; + uint32View[index + 4] = argb; + uint32View[index + 5] = textureId << 16; + index += 6; + } + } + } + // TODO rename to vertexSize + get vertSize() { + return this.vertexSize; + } + copyTo(gpuBuffer) { + gpuBuffer.indexOffset = this.indexOffset; + gpuBuffer.indexSize = this.indexSize; + gpuBuffer.vertexOffset = this.vertexOffset; + gpuBuffer.vertexSize = this.vertexSize; + gpuBuffer.color = this.color; + gpuBuffer.alpha = this.alpha; + gpuBuffer.texture = this.texture; + gpuBuffer.geometryData = this.geometryData; + } + reset() { + this.applyTransform = true; + } +} + +"use strict"; +const buildCircle = { + build(shape, points) { + let x; + let y; + let dx; + let dy; + let rx; + let ry; + if (shape.type === "circle") { + const circle = shape; + x = circle.x; + y = circle.y; + rx = ry = circle.radius; + dx = dy = 0; + } else if (shape.type === "ellipse") { + const ellipse = shape; + x = ellipse.x; + y = ellipse.y; + rx = ellipse.halfWidth; + ry = ellipse.halfHeight; + dx = dy = 0; + } else { + const roundedRect = shape; + const halfWidth = roundedRect.width / 2; + const halfHeight = roundedRect.height / 2; + x = roundedRect.x + halfWidth; + y = roundedRect.y + halfHeight; + rx = ry = Math.max(0, Math.min(roundedRect.radius, Math.min(halfWidth, halfHeight))); + dx = halfWidth - rx; + dy = halfHeight - ry; + } + if (!(rx >= 0 && ry >= 0 && dx >= 0 && dy >= 0)) { + return points; + } + const n = Math.ceil(2.3 * Math.sqrt(rx + ry)); + const m = n * 8 + (dx ? 4 : 0) + (dy ? 4 : 0); + if (m === 0) { + return points; + } + if (n === 0) { + points[0] = points[6] = x + dx; + points[1] = points[3] = y + dy; + points[2] = points[4] = x - dx; + points[5] = points[7] = y - dy; + return points; + } + let j1 = 0; + let j2 = n * 4 + (dx ? 2 : 0) + 2; + let j3 = j2; + let j4 = m; + let x0 = dx + rx; + let y0 = dy; + let x1 = x + x0; + let x2 = x - x0; + let y1 = y + y0; + points[j1++] = x1; + points[j1++] = y1; + points[--j2] = y1; + points[--j2] = x2; + if (dy) { + const y22 = y - y0; + points[j3++] = x2; + points[j3++] = y22; + points[--j4] = y22; + points[--j4] = x1; + } + for (let i = 1; i < n; i++) { + const a = Math.PI / 2 * (i / n); + const x02 = dx + Math.cos(a) * rx; + const y02 = dy + Math.sin(a) * ry; + const x12 = x + x02; + const x22 = x - x02; + const y12 = y + y02; + const y22 = y - y02; + points[j1++] = x12; + points[j1++] = y12; + points[--j2] = y12; + points[--j2] = x22; + points[j3++] = x22; + points[j3++] = y22; + points[--j4] = y22; + points[--j4] = x12; + } + x0 = dx; + y0 = dy + ry; + x1 = x + x0; + x2 = x - x0; + y1 = y + y0; + const y2 = y - y0; + points[j1++] = x1; + points[j1++] = y1; + points[--j4] = y2; + points[--j4] = x1; + if (dx) { + points[j1++] = x2; + points[j1++] = y1; + points[--j4] = y2; + points[--j4] = x2; + } + return points; + }, + triangulate(points, vertices, verticesStride, verticesOffset, indices, indicesOffset) { + if (points.length === 0) { + return; + } + let centerX = 0; + let centerY = 0; + for (let i = 0; i < points.length; i += 2) { + centerX += points[i]; + centerY += points[i + 1]; + } + centerX /= points.length / 2; + centerY /= points.length / 2; + let count = verticesOffset; + vertices[count * verticesStride] = centerX; + vertices[count * verticesStride + 1] = centerY; + const centerIndex = count++; + for (let i = 0; i < points.length; i += 2) { + vertices[count * verticesStride] = points[i]; + vertices[count * verticesStride + 1] = points[i + 1]; + if (i > 0) { + indices[indicesOffset++] = count; + indices[indicesOffset++] = centerIndex; + indices[indicesOffset++] = count - 1; + } + count++; + } + indices[indicesOffset++] = centerIndex + 1; + indices[indicesOffset++] = centerIndex; + indices[indicesOffset++] = count - 1; + } +}; + +"use strict"; +const closePointEps = 1e-4; +const curveEps = 1e-4; + +"use strict"; +function getOrientationOfPoints(points) { + const m = points.length; + if (m < 6) { + return 1; + } + let area = 0; + for (let i = 0, x1 = points[m - 2], y1 = points[m - 1]; i < m; i += 2) { + const x2 = points[i]; + const y2 = points[i + 1]; + area += (x2 - x1) * (y2 + y1); + x1 = x2; + y1 = y2; + } + if (area < 0) { + return -1; + } + return 1; +} + +"use strict"; +function square(x, y, nx, ny, innerWeight, outerWeight, clockwise, verts) { + const ix = x - nx * innerWeight; + const iy = y - ny * innerWeight; + const ox = x + nx * outerWeight; + const oy = y + ny * outerWeight; + let exx; + let eyy; + if (clockwise) { + exx = ny; + eyy = -nx; + } else { + exx = -ny; + eyy = nx; + } + const eix = ix + exx; + const eiy = iy + eyy; + const eox = ox + exx; + const eoy = oy + eyy; + verts.push(eix, eiy); + verts.push(eox, eoy); + return 2; +} +function round(cx, cy, sx, sy, ex, ey, verts, clockwise) { + const cx2p0x = sx - cx; + const cy2p0y = sy - cy; + let angle0 = Math.atan2(cx2p0x, cy2p0y); + let angle1 = Math.atan2(ex - cx, ey - cy); + if (clockwise && angle0 < angle1) { + angle0 += Math.PI * 2; + } else if (!clockwise && angle0 > angle1) { + angle1 += Math.PI * 2; + } + let startAngle = angle0; + const angleDiff = angle1 - angle0; + const absAngleDiff = Math.abs(angleDiff); + const radius = Math.sqrt(cx2p0x * cx2p0x + cy2p0y * cy2p0y); + const segCount = (15 * absAngleDiff * Math.sqrt(radius) / Math.PI >> 0) + 1; + const angleInc = angleDiff / segCount; + startAngle += angleInc; + if (clockwise) { + verts.push(cx, cy); + verts.push(sx, sy); + for (let i = 1, angle = startAngle; i < segCount; i++, angle += angleInc) { + verts.push(cx, cy); + verts.push( + cx + Math.sin(angle) * radius, + cy + Math.cos(angle) * radius + ); + } + verts.push(cx, cy); + verts.push(ex, ey); + } else { + verts.push(sx, sy); + verts.push(cx, cy); + for (let i = 1, angle = startAngle; i < segCount; i++, angle += angleInc) { + verts.push( + cx + Math.sin(angle) * radius, + cy + Math.cos(angle) * radius + ); + verts.push(cx, cy); + } + verts.push(ex, ey); + verts.push(cx, cy); + } + return segCount * 2; +} +function buildLine(points, lineStyle, flipAlignment, closed, vertices, _verticesStride, _verticesOffset, indices, _indicesOffset) { + const eps = closePointEps; + if (points.length === 0) { + return; + } + const style = lineStyle; + let alignment = style.alignment; + if (lineStyle.alignment !== 0.5) { + let orientation = getOrientationOfPoints(points); + if (flipAlignment) + orientation *= -1; + alignment = (alignment - 0.5) * orientation + 0.5; + } + const firstPoint = new Point(points[0], points[1]); + const lastPoint = new Point(points[points.length - 2], points[points.length - 1]); + const closedShape = closed; + const closedPath = Math.abs(firstPoint.x - lastPoint.x) < eps && Math.abs(firstPoint.y - lastPoint.y) < eps; + if (closedShape) { + points = points.slice(); + if (closedPath) { + points.pop(); + points.pop(); + lastPoint.set(points[points.length - 2], points[points.length - 1]); + } + const midPointX = (firstPoint.x + lastPoint.x) * 0.5; + const midPointY = (lastPoint.y + firstPoint.y) * 0.5; + points.unshift(midPointX, midPointY); + points.push(midPointX, midPointY); + } + const verts = vertices; + const length = points.length / 2; + let indexCount = points.length; + const indexStart = verts.length / 2; + const width = style.width / 2; + const widthSquared = width * width; + const miterLimitSquared = style.miterLimit * style.miterLimit; + let x0 = points[0]; + let y0 = points[1]; + let x1 = points[2]; + let y1 = points[3]; + let x2 = 0; + let y2 = 0; + let perpX = -(y0 - y1); + let perpY = x0 - x1; + let perp1x = 0; + let perp1y = 0; + let dist = Math.sqrt(perpX * perpX + perpY * perpY); + perpX /= dist; + perpY /= dist; + perpX *= width; + perpY *= width; + const ratio = alignment; + const innerWeight = (1 - ratio) * 2; + const outerWeight = ratio * 2; + if (!closedShape) { + if (style.cap === "round") { + indexCount += round( + x0 - perpX * (innerWeight - outerWeight) * 0.5, + y0 - perpY * (innerWeight - outerWeight) * 0.5, + x0 - perpX * innerWeight, + y0 - perpY * innerWeight, + x0 + perpX * outerWeight, + y0 + perpY * outerWeight, + verts, + true + ) + 2; + } else if (style.cap === "square") { + indexCount += square(x0, y0, perpX, perpY, innerWeight, outerWeight, true, verts); + } + } + verts.push( + x0 - perpX * innerWeight, + y0 - perpY * innerWeight + ); + verts.push( + x0 + perpX * outerWeight, + y0 + perpY * outerWeight + ); + for (let i = 1; i < length - 1; ++i) { + x0 = points[(i - 1) * 2]; + y0 = points[(i - 1) * 2 + 1]; + x1 = points[i * 2]; + y1 = points[i * 2 + 1]; + x2 = points[(i + 1) * 2]; + y2 = points[(i + 1) * 2 + 1]; + perpX = -(y0 - y1); + perpY = x0 - x1; + dist = Math.sqrt(perpX * perpX + perpY * perpY); + perpX /= dist; + perpY /= dist; + perpX *= width; + perpY *= width; + perp1x = -(y1 - y2); + perp1y = x1 - x2; + dist = Math.sqrt(perp1x * perp1x + perp1y * perp1y); + perp1x /= dist; + perp1y /= dist; + perp1x *= width; + perp1y *= width; + const dx0 = x1 - x0; + const dy0 = y0 - y1; + const dx1 = x1 - x2; + const dy1 = y2 - y1; + const dot = dx0 * dx1 + dy0 * dy1; + const cross = dy0 * dx1 - dy1 * dx0; + const clockwise = cross < 0; + if (Math.abs(cross) < 1e-3 * Math.abs(dot)) { + verts.push( + x1 - perpX * innerWeight, + y1 - perpY * innerWeight + ); + verts.push( + x1 + perpX * outerWeight, + y1 + perpY * outerWeight + ); + if (dot >= 0) { + if (style.join === "round") { + indexCount += round( + x1, + y1, + x1 - perpX * innerWeight, + y1 - perpY * innerWeight, + x1 - perp1x * innerWeight, + y1 - perp1y * innerWeight, + verts, + false + ) + 4; + } else { + indexCount += 2; + } + verts.push( + x1 - perp1x * outerWeight, + y1 - perp1y * outerWeight + ); + verts.push( + x1 + perp1x * innerWeight, + y1 + perp1y * innerWeight + ); + } + continue; + } + const c1 = (-perpX + x0) * (-perpY + y1) - (-perpX + x1) * (-perpY + y0); + const c2 = (-perp1x + x2) * (-perp1y + y1) - (-perp1x + x1) * (-perp1y + y2); + const px = (dx0 * c2 - dx1 * c1) / cross; + const py = (dy1 * c1 - dy0 * c2) / cross; + const pDist = (px - x1) * (px - x1) + (py - y1) * (py - y1); + const imx = x1 + (px - x1) * innerWeight; + const imy = y1 + (py - y1) * innerWeight; + const omx = x1 - (px - x1) * outerWeight; + const omy = y1 - (py - y1) * outerWeight; + const smallerInsideSegmentSq = Math.min(dx0 * dx0 + dy0 * dy0, dx1 * dx1 + dy1 * dy1); + const insideWeight = clockwise ? innerWeight : outerWeight; + const smallerInsideDiagonalSq = smallerInsideSegmentSq + insideWeight * insideWeight * widthSquared; + const insideMiterOk = pDist <= smallerInsideDiagonalSq; + if (insideMiterOk) { + if (style.join === "bevel" || pDist / widthSquared > miterLimitSquared) { + if (clockwise) { + verts.push(imx, imy); + verts.push(x1 + perpX * outerWeight, y1 + perpY * outerWeight); + verts.push(imx, imy); + verts.push(x1 + perp1x * outerWeight, y1 + perp1y * outerWeight); + } else { + verts.push(x1 - perpX * innerWeight, y1 - perpY * innerWeight); + verts.push(omx, omy); + verts.push(x1 - perp1x * innerWeight, y1 - perp1y * innerWeight); + verts.push(omx, omy); + } + indexCount += 2; + } else if (style.join === "round") { + if (clockwise) { + verts.push(imx, imy); + verts.push(x1 + perpX * outerWeight, y1 + perpY * outerWeight); + indexCount += round( + x1, + y1, + x1 + perpX * outerWeight, + y1 + perpY * outerWeight, + x1 + perp1x * outerWeight, + y1 + perp1y * outerWeight, + verts, + true + ) + 4; + verts.push(imx, imy); + verts.push(x1 + perp1x * outerWeight, y1 + perp1y * outerWeight); + } else { + verts.push(x1 - perpX * innerWeight, y1 - perpY * innerWeight); + verts.push(omx, omy); + indexCount += round( + x1, + y1, + x1 - perpX * innerWeight, + y1 - perpY * innerWeight, + x1 - perp1x * innerWeight, + y1 - perp1y * innerWeight, + verts, + false + ) + 4; + verts.push(x1 - perp1x * innerWeight, y1 - perp1y * innerWeight); + verts.push(omx, omy); + } + } else { + verts.push(imx, imy); + verts.push(omx, omy); + } + } else { + verts.push(x1 - perpX * innerWeight, y1 - perpY * innerWeight); + verts.push(x1 + perpX * outerWeight, y1 + perpY * outerWeight); + if (style.join === "round") { + if (clockwise) { + indexCount += round( + x1, + y1, + x1 + perpX * outerWeight, + y1 + perpY * outerWeight, + x1 + perp1x * outerWeight, + y1 + perp1y * outerWeight, + verts, + true + ) + 2; + } else { + indexCount += round( + x1, + y1, + x1 - perpX * innerWeight, + y1 - perpY * innerWeight, + x1 - perp1x * innerWeight, + y1 - perp1y * innerWeight, + verts, + false + ) + 2; + } + } else if (style.join === "miter" && pDist / widthSquared <= miterLimitSquared) { + if (clockwise) { + verts.push(omx, omy); + verts.push(omx, omy); + } else { + verts.push(imx, imy); + verts.push(imx, imy); + } + indexCount += 2; + } + verts.push(x1 - perp1x * innerWeight, y1 - perp1y * innerWeight); + verts.push(x1 + perp1x * outerWeight, y1 + perp1y * outerWeight); + indexCount += 2; + } + } + x0 = points[(length - 2) * 2]; + y0 = points[(length - 2) * 2 + 1]; + x1 = points[(length - 1) * 2]; + y1 = points[(length - 1) * 2 + 1]; + perpX = -(y0 - y1); + perpY = x0 - x1; + dist = Math.sqrt(perpX * perpX + perpY * perpY); + perpX /= dist; + perpY /= dist; + perpX *= width; + perpY *= width; + verts.push(x1 - perpX * innerWeight, y1 - perpY * innerWeight); + verts.push(x1 + perpX * outerWeight, y1 + perpY * outerWeight); + if (!closedShape) { + if (style.cap === "round") { + indexCount += round( + x1 - perpX * (innerWeight - outerWeight) * 0.5, + y1 - perpY * (innerWeight - outerWeight) * 0.5, + x1 - perpX * innerWeight, + y1 - perpY * innerWeight, + x1 + perpX * outerWeight, + y1 + perpY * outerWeight, + verts, + false + ) + 2; + } else if (style.cap === "square") { + indexCount += square(x1, y1, perpX, perpY, innerWeight, outerWeight, false, verts); + } + } + const eps2 = curveEps * curveEps; + for (let i = indexStart; i < indexCount + indexStart - 2; ++i) { + x0 = verts[i * 2]; + y0 = verts[i * 2 + 1]; + x1 = verts[(i + 1) * 2]; + y1 = verts[(i + 1) * 2 + 1]; + x2 = verts[(i + 2) * 2]; + y2 = verts[(i + 2) * 2 + 1]; + if (Math.abs(x0 * (y1 - y2) + x1 * (y2 - y0) + x2 * (y0 - y1)) < eps2) { + continue; + } + indices.push(i, i + 1, i + 2); + } +} + +var earcut$2 = {exports: {}}; + +var earcut_1 = earcut$2.exports; + +'use strict'; + +earcut$2.exports = earcut; +var _default = earcut$2.exports.default = earcut; + +function earcut(data, holeIndices, dim) { + + dim = dim || 2; + + var hasHoles = holeIndices && holeIndices.length, + outerLen = hasHoles ? holeIndices[0] * dim : data.length, + outerNode = linkedList(data, 0, outerLen, dim, true), + triangles = []; + + if (!outerNode || outerNode.next === outerNode.prev) return triangles; + + var minX, minY, maxX, maxY, x, y, invSize; + + if (hasHoles) outerNode = eliminateHoles(data, holeIndices, outerNode, dim); + + // if the shape is not too simple, we'll use z-order curve hash later; calculate polygon bbox + if (data.length > 80 * dim) { + minX = maxX = data[0]; + minY = maxY = data[1]; + + for (var i = dim; i < outerLen; i += dim) { + x = data[i]; + y = data[i + 1]; + if (x < minX) minX = x; + if (y < minY) minY = y; + if (x > maxX) maxX = x; + if (y > maxY) maxY = y; + } + + // minX, minY and invSize are later used to transform coords into integers for z-order calculation + invSize = Math.max(maxX - minX, maxY - minY); + invSize = invSize !== 0 ? 32767 / invSize : 0; + } + + earcutLinked(outerNode, triangles, dim, minX, minY, invSize, 0); + + return triangles; +} + +// create a circular doubly linked list from polygon points in the specified winding order +function linkedList(data, start, end, dim, clockwise) { + var i, last; + + if (clockwise === (signedArea(data, start, end, dim) > 0)) { + for (i = start; i < end; i += dim) last = insertNode(i, data[i], data[i + 1], last); + } else { + for (i = end - dim; i >= start; i -= dim) last = insertNode(i, data[i], data[i + 1], last); + } + + if (last && equals(last, last.next)) { + removeNode(last); + last = last.next; + } + + return last; +} + +// eliminate colinear or duplicate points +function filterPoints(start, end) { + if (!start) return start; + if (!end) end = start; + + var p = start, + again; + do { + again = false; + + if (!p.steiner && (equals(p, p.next) || area(p.prev, p, p.next) === 0)) { + removeNode(p); + p = end = p.prev; + if (p === p.next) break; + again = true; + + } else { + p = p.next; + } + } while (again || p !== end); + + return end; +} + +// main ear slicing loop which triangulates a polygon (given as a linked list) +function earcutLinked(ear, triangles, dim, minX, minY, invSize, pass) { + if (!ear) return; + + // interlink polygon nodes in z-order + if (!pass && invSize) indexCurve(ear, minX, minY, invSize); + + var stop = ear, + prev, next; + + // iterate through ears, slicing them one by one + while (ear.prev !== ear.next) { + prev = ear.prev; + next = ear.next; + + if (invSize ? isEarHashed(ear, minX, minY, invSize) : isEar(ear)) { + // cut off the triangle + triangles.push(prev.i / dim | 0); + triangles.push(ear.i / dim | 0); + triangles.push(next.i / dim | 0); + + removeNode(ear); + + // skipping the next vertex leads to less sliver triangles + ear = next.next; + stop = next.next; + + continue; + } + + ear = next; + + // if we looped through the whole remaining polygon and can't find any more ears + if (ear === stop) { + // try filtering points and slicing again + if (!pass) { + earcutLinked(filterPoints(ear), triangles, dim, minX, minY, invSize, 1); + + // if this didn't work, try curing all small self-intersections locally + } else if (pass === 1) { + ear = cureLocalIntersections(filterPoints(ear), triangles, dim); + earcutLinked(ear, triangles, dim, minX, minY, invSize, 2); + + // as a last resort, try splitting the remaining polygon into two + } else if (pass === 2) { + splitEarcut(ear, triangles, dim, minX, minY, invSize); + } + + break; + } + } +} + +// check whether a polygon node forms a valid ear with adjacent nodes +function isEar(ear) { + var a = ear.prev, + b = ear, + c = ear.next; + + if (area(a, b, c) >= 0) return false; // reflex, can't be an ear + + // now make sure we don't have other points inside the potential ear + var ax = a.x, bx = b.x, cx = c.x, ay = a.y, by = b.y, cy = c.y; + + // triangle bbox; min & max are calculated like this for speed + var x0 = ax < bx ? (ax < cx ? ax : cx) : (bx < cx ? bx : cx), + y0 = ay < by ? (ay < cy ? ay : cy) : (by < cy ? by : cy), + x1 = ax > bx ? (ax > cx ? ax : cx) : (bx > cx ? bx : cx), + y1 = ay > by ? (ay > cy ? ay : cy) : (by > cy ? by : cy); + + var p = c.next; + while (p !== a) { + if (p.x >= x0 && p.x <= x1 && p.y >= y0 && p.y <= y1 && + pointInTriangle(ax, ay, bx, by, cx, cy, p.x, p.y) && + area(p.prev, p, p.next) >= 0) return false; + p = p.next; + } + + return true; +} + +function isEarHashed(ear, minX, minY, invSize) { + var a = ear.prev, + b = ear, + c = ear.next; + + if (area(a, b, c) >= 0) return false; // reflex, can't be an ear + + var ax = a.x, bx = b.x, cx = c.x, ay = a.y, by = b.y, cy = c.y; + + // triangle bbox; min & max are calculated like this for speed + var x0 = ax < bx ? (ax < cx ? ax : cx) : (bx < cx ? bx : cx), + y0 = ay < by ? (ay < cy ? ay : cy) : (by < cy ? by : cy), + x1 = ax > bx ? (ax > cx ? ax : cx) : (bx > cx ? bx : cx), + y1 = ay > by ? (ay > cy ? ay : cy) : (by > cy ? by : cy); + + // z-order range for the current triangle bbox; + var minZ = zOrder(x0, y0, minX, minY, invSize), + maxZ = zOrder(x1, y1, minX, minY, invSize); + + var p = ear.prevZ, + n = ear.nextZ; + + // look for points inside the triangle in both directions + while (p && p.z >= minZ && n && n.z <= maxZ) { + if (p.x >= x0 && p.x <= x1 && p.y >= y0 && p.y <= y1 && p !== a && p !== c && + pointInTriangle(ax, ay, bx, by, cx, cy, p.x, p.y) && area(p.prev, p, p.next) >= 0) return false; + p = p.prevZ; + + if (n.x >= x0 && n.x <= x1 && n.y >= y0 && n.y <= y1 && n !== a && n !== c && + pointInTriangle(ax, ay, bx, by, cx, cy, n.x, n.y) && area(n.prev, n, n.next) >= 0) return false; + n = n.nextZ; + } + + // look for remaining points in decreasing z-order + while (p && p.z >= minZ) { + if (p.x >= x0 && p.x <= x1 && p.y >= y0 && p.y <= y1 && p !== a && p !== c && + pointInTriangle(ax, ay, bx, by, cx, cy, p.x, p.y) && area(p.prev, p, p.next) >= 0) return false; + p = p.prevZ; + } + + // look for remaining points in increasing z-order + while (n && n.z <= maxZ) { + if (n.x >= x0 && n.x <= x1 && n.y >= y0 && n.y <= y1 && n !== a && n !== c && + pointInTriangle(ax, ay, bx, by, cx, cy, n.x, n.y) && area(n.prev, n, n.next) >= 0) return false; + n = n.nextZ; + } + + return true; +} + +// go through all polygon nodes and cure small local self-intersections +function cureLocalIntersections(start, triangles, dim) { + var p = start; + do { + var a = p.prev, + b = p.next.next; + + if (!equals(a, b) && intersects(a, p, p.next, b) && locallyInside(a, b) && locallyInside(b, a)) { + + triangles.push(a.i / dim | 0); + triangles.push(p.i / dim | 0); + triangles.push(b.i / dim | 0); + + // remove two nodes involved + removeNode(p); + removeNode(p.next); + + p = start = b; + } + p = p.next; + } while (p !== start); + + return filterPoints(p); +} + +// try splitting polygon into two and triangulate them independently +function splitEarcut(start, triangles, dim, minX, minY, invSize) { + // look for a valid diagonal that divides the polygon into two + var a = start; + do { + var b = a.next.next; + while (b !== a.prev) { + if (a.i !== b.i && isValidDiagonal(a, b)) { + // split the polygon in two by the diagonal + var c = splitPolygon(a, b); + + // filter colinear points around the cuts + a = filterPoints(a, a.next); + c = filterPoints(c, c.next); + + // run earcut on each half + earcutLinked(a, triangles, dim, minX, minY, invSize, 0); + earcutLinked(c, triangles, dim, minX, minY, invSize, 0); + return; + } + b = b.next; + } + a = a.next; + } while (a !== start); +} + +// link every hole into the outer loop, producing a single-ring polygon without holes +function eliminateHoles(data, holeIndices, outerNode, dim) { + var queue = [], + i, len, start, end, list; + + for (i = 0, len = holeIndices.length; i < len; i++) { + start = holeIndices[i] * dim; + end = i < len - 1 ? holeIndices[i + 1] * dim : data.length; + list = linkedList(data, start, end, dim, false); + if (list === list.next) list.steiner = true; + queue.push(getLeftmost(list)); + } + + queue.sort(compareX); + + // process holes from left to right + for (i = 0; i < queue.length; i++) { + outerNode = eliminateHole(queue[i], outerNode); + } + + return outerNode; +} + +function compareX(a, b) { + return a.x - b.x; +} + +// find a bridge between vertices that connects hole with an outer ring and and link it +function eliminateHole(hole, outerNode) { + var bridge = findHoleBridge(hole, outerNode); + if (!bridge) { + return outerNode; + } + + var bridgeReverse = splitPolygon(bridge, hole); + + // filter collinear points around the cuts + filterPoints(bridgeReverse, bridgeReverse.next); + return filterPoints(bridge, bridge.next); +} + +// David Eberly's algorithm for finding a bridge between hole and outer polygon +function findHoleBridge(hole, outerNode) { + var p = outerNode, + hx = hole.x, + hy = hole.y, + qx = -Infinity, + m; + + // find a segment intersected by a ray from the hole's leftmost point to the left; + // segment's endpoint with lesser x will be potential connection point + do { + if (hy <= p.y && hy >= p.next.y && p.next.y !== p.y) { + var x = p.x + (hy - p.y) * (p.next.x - p.x) / (p.next.y - p.y); + if (x <= hx && x > qx) { + qx = x; + m = p.x < p.next.x ? p : p.next; + if (x === hx) return m; // hole touches outer segment; pick leftmost endpoint + } + } + p = p.next; + } while (p !== outerNode); + + if (!m) return null; + + // look for points inside the triangle of hole point, segment intersection and endpoint; + // if there are no points found, we have a valid connection; + // otherwise choose the point of the minimum angle with the ray as connection point + + var stop = m, + mx = m.x, + my = m.y, + tanMin = Infinity, + tan; + + p = m; + + do { + if (hx >= p.x && p.x >= mx && hx !== p.x && + pointInTriangle(hy < my ? hx : qx, hy, mx, my, hy < my ? qx : hx, hy, p.x, p.y)) { + + tan = Math.abs(hy - p.y) / (hx - p.x); // tangential + + if (locallyInside(p, hole) && + (tan < tanMin || (tan === tanMin && (p.x > m.x || (p.x === m.x && sectorContainsSector(m, p)))))) { + m = p; + tanMin = tan; + } + } + + p = p.next; + } while (p !== stop); + + return m; +} + +// whether sector in vertex m contains sector in vertex p in the same coordinates +function sectorContainsSector(m, p) { + return area(m.prev, m, p.prev) < 0 && area(p.next, m, m.next) < 0; +} + +// interlink polygon nodes in z-order +function indexCurve(start, minX, minY, invSize) { + var p = start; + do { + if (p.z === 0) p.z = zOrder(p.x, p.y, minX, minY, invSize); + p.prevZ = p.prev; + p.nextZ = p.next; + p = p.next; + } while (p !== start); + + p.prevZ.nextZ = null; + p.prevZ = null; + + sortLinked(p); +} + +// Simon Tatham's linked list merge sort algorithm +// http://www.chiark.greenend.org.uk/~sgtatham/algorithms/listsort.html +function sortLinked(list) { + var i, p, q, e, tail, numMerges, pSize, qSize, + inSize = 1; + + do { + p = list; + list = null; + tail = null; + numMerges = 0; + + while (p) { + numMerges++; + q = p; + pSize = 0; + for (i = 0; i < inSize; i++) { + pSize++; + q = q.nextZ; + if (!q) break; + } + qSize = inSize; + + while (pSize > 0 || (qSize > 0 && q)) { + + if (pSize !== 0 && (qSize === 0 || !q || p.z <= q.z)) { + e = p; + p = p.nextZ; + pSize--; + } else { + e = q; + q = q.nextZ; + qSize--; + } + + if (tail) tail.nextZ = e; + else list = e; + + e.prevZ = tail; + tail = e; + } + + p = q; + } + + tail.nextZ = null; + inSize *= 2; + + } while (numMerges > 1); + + return list; +} + +// z-order of a point given coords and inverse of the longer side of data bbox +function zOrder(x, y, minX, minY, invSize) { + // coords are transformed into non-negative 15-bit integer range + x = (x - minX) * invSize | 0; + y = (y - minY) * invSize | 0; + + x = (x | (x << 8)) & 0x00FF00FF; + x = (x | (x << 4)) & 0x0F0F0F0F; + x = (x | (x << 2)) & 0x33333333; + x = (x | (x << 1)) & 0x55555555; + + y = (y | (y << 8)) & 0x00FF00FF; + y = (y | (y << 4)) & 0x0F0F0F0F; + y = (y | (y << 2)) & 0x33333333; + y = (y | (y << 1)) & 0x55555555; + + return x | (y << 1); +} + +// find the leftmost node of a polygon ring +function getLeftmost(start) { + var p = start, + leftmost = start; + do { + if (p.x < leftmost.x || (p.x === leftmost.x && p.y < leftmost.y)) leftmost = p; + p = p.next; + } while (p !== start); + + return leftmost; +} + +// check if a point lies within a convex triangle +function pointInTriangle(ax, ay, bx, by, cx, cy, px, py) { + return (cx - px) * (ay - py) >= (ax - px) * (cy - py) && + (ax - px) * (by - py) >= (bx - px) * (ay - py) && + (bx - px) * (cy - py) >= (cx - px) * (by - py); +} + +// check if a diagonal between two polygon nodes is valid (lies in polygon interior) +function isValidDiagonal(a, b) { + return a.next.i !== b.i && a.prev.i !== b.i && !intersectsPolygon(a, b) && // dones't intersect other edges + (locallyInside(a, b) && locallyInside(b, a) && middleInside(a, b) && // locally visible + (area(a.prev, a, b.prev) || area(a, b.prev, b)) || // does not create opposite-facing sectors + equals(a, b) && area(a.prev, a, a.next) > 0 && area(b.prev, b, b.next) > 0); // special zero-length case +} + +// signed area of a triangle +function area(p, q, r) { + return (q.y - p.y) * (r.x - q.x) - (q.x - p.x) * (r.y - q.y); +} + +// check if two points are equal +function equals(p1, p2) { + return p1.x === p2.x && p1.y === p2.y; +} + +// check if two segments intersect +function intersects(p1, q1, p2, q2) { + var o1 = sign(area(p1, q1, p2)); + var o2 = sign(area(p1, q1, q2)); + var o3 = sign(area(p2, q2, p1)); + var o4 = sign(area(p2, q2, q1)); + + if (o1 !== o2 && o3 !== o4) return true; // general case + + if (o1 === 0 && onSegment(p1, p2, q1)) return true; // p1, q1 and p2 are collinear and p2 lies on p1q1 + if (o2 === 0 && onSegment(p1, q2, q1)) return true; // p1, q1 and q2 are collinear and q2 lies on p1q1 + if (o3 === 0 && onSegment(p2, p1, q2)) return true; // p2, q2 and p1 are collinear and p1 lies on p2q2 + if (o4 === 0 && onSegment(p2, q1, q2)) return true; // p2, q2 and q1 are collinear and q1 lies on p2q2 + + return false; +} + +// for collinear points p, q, r, check if point q lies on segment pr +function onSegment(p, q, r) { + return q.x <= Math.max(p.x, r.x) && q.x >= Math.min(p.x, r.x) && q.y <= Math.max(p.y, r.y) && q.y >= Math.min(p.y, r.y); +} + +function sign(num) { + return num > 0 ? 1 : num < 0 ? -1 : 0; +} + +// check if a polygon diagonal intersects any polygon segments +function intersectsPolygon(a, b) { + var p = a; + do { + if (p.i !== a.i && p.next.i !== a.i && p.i !== b.i && p.next.i !== b.i && + intersects(p, p.next, a, b)) return true; + p = p.next; + } while (p !== a); + + return false; +} + +// check if a polygon diagonal is locally inside the polygon +function locallyInside(a, b) { + return area(a.prev, a, a.next) < 0 ? + area(a, b, a.next) >= 0 && area(a, a.prev, b) >= 0 : + area(a, b, a.prev) < 0 || area(a, a.next, b) < 0; +} + +// check if the middle point of a polygon diagonal is inside the polygon +function middleInside(a, b) { + var p = a, + inside = false, + px = (a.x + b.x) / 2, + py = (a.y + b.y) / 2; + do { + if (((p.y > py) !== (p.next.y > py)) && p.next.y !== p.y && + (px < (p.next.x - p.x) * (py - p.y) / (p.next.y - p.y) + p.x)) + inside = !inside; + p = p.next; + } while (p !== a); + + return inside; +} + +// link two polygon vertices with a bridge; if the vertices belong to the same ring, it splits polygon into two; +// if one belongs to the outer ring and another to a hole, it merges it into a single ring +function splitPolygon(a, b) { + var a2 = new Node(a.i, a.x, a.y), + b2 = new Node(b.i, b.x, b.y), + an = a.next, + bp = b.prev; + + a.next = b; + b.prev = a; + + a2.next = an; + an.prev = a2; + + b2.next = a2; + a2.prev = b2; + + bp.next = b2; + b2.prev = bp; + + return b2; +} + +// create a node and optionally link it with previous one (in a circular doubly linked list) +function insertNode(i, x, y, last) { + var p = new Node(i, x, y); + + if (!last) { + p.prev = p; + p.next = p; + + } else { + p.next = last.next; + p.prev = last; + last.next.prev = p; + last.next = p; + } + return p; +} + +function removeNode(p) { + p.next.prev = p.prev; + p.prev.next = p.next; + + if (p.prevZ) p.prevZ.nextZ = p.nextZ; + if (p.nextZ) p.nextZ.prevZ = p.prevZ; +} + +function Node(i, x, y) { + // vertex index in coordinates array + this.i = i; + + // vertex coordinates + this.x = x; + this.y = y; + + // previous and next vertex nodes in a polygon ring + this.prev = null; + this.next = null; + + // z-order curve value + this.z = 0; + + // previous and next nodes in z-order + this.prevZ = null; + this.nextZ = null; + + // indicates whether this is a steiner point + this.steiner = false; +} + +// return a percentage difference between the polygon area and its triangulation area; +// used to verify correctness of triangulation +earcut.deviation = function (data, holeIndices, dim, triangles) { + var hasHoles = holeIndices && holeIndices.length; + var outerLen = hasHoles ? holeIndices[0] * dim : data.length; + + var polygonArea = Math.abs(signedArea(data, 0, outerLen, dim)); + if (hasHoles) { + for (var i = 0, len = holeIndices.length; i < len; i++) { + var start = holeIndices[i] * dim; + var end = i < len - 1 ? holeIndices[i + 1] * dim : data.length; + polygonArea -= Math.abs(signedArea(data, start, end, dim)); + } + } + + var trianglesArea = 0; + for (i = 0; i < triangles.length; i += 3) { + var a = triangles[i] * dim; + var b = triangles[i + 1] * dim; + var c = triangles[i + 2] * dim; + trianglesArea += Math.abs( + (data[a] - data[c]) * (data[b + 1] - data[a + 1]) - + (data[a] - data[b]) * (data[c + 1] - data[a + 1])); + } + + return polygonArea === 0 && trianglesArea === 0 ? 0 : + Math.abs((trianglesArea - polygonArea) / polygonArea); +}; + +function signedArea(data, start, end, dim) { + var sum = 0; + for (var i = start, j = end - dim; i < end; i += dim) { + sum += (data[j] - data[i]) * (data[i + 1] + data[j + 1]); + j = i; + } + return sum; +} + +// turn a polygon in a multi-dimensional array form (e.g. as in GeoJSON) into a form Earcut accepts +earcut.flatten = function (data) { + var dim = data[0][0].length, + result = {vertices: [], holes: [], dimensions: dim}, + holeIndex = 0; + + for (var i = 0; i < data.length; i++) { + for (var j = 0; j < data[i].length; j++) { + for (var d = 0; d < dim; d++) result.vertices.push(data[i][j][d]); + } + if (i > 0) { + holeIndex += data[i - 1].length; + result.holes.push(holeIndex); + } + } + return result; +}; + +var earcutExports = earcut$2.exports; +var earcut$1 = /*@__PURE__*/getDefaultExportFromCjs(earcutExports); + +"use strict"; +function triangulateWithHoles(points, holes, vertices, verticesStride, verticesOffset, indices, indicesOffset) { + const triangles = earcut$1(points, holes, 2); + if (!triangles) { + return; + } + for (let i = 0; i < triangles.length; i += 3) { + indices[indicesOffset++] = triangles[i] + verticesOffset; + indices[indicesOffset++] = triangles[i + 1] + verticesOffset; + indices[indicesOffset++] = triangles[i + 2] + verticesOffset; + } + let index = verticesOffset * verticesStride; + for (let i = 0; i < points.length; i += 2) { + vertices[index] = points[i]; + vertices[index + 1] = points[i + 1]; + index += verticesStride; + } +} + +"use strict"; +const emptyArray = []; +const buildPolygon = { + build(shape, points) { + for (let i = 0; i < shape.points.length; i++) { + points[i] = shape.points[i]; + } + return points; + }, + triangulate(points, vertices, verticesStride, verticesOffset, indices, indicesOffset) { + triangulateWithHoles(points, emptyArray, vertices, verticesStride, verticesOffset, indices, indicesOffset); + } +}; + +"use strict"; +const buildRectangle = { + build(shape, points) { + const rectData = shape; + const x = rectData.x; + const y = rectData.y; + const width = rectData.width; + const height = rectData.height; + if (!(width >= 0 && height >= 0)) { + return points; + } + points[0] = x; + points[1] = y; + points[2] = x + width; + points[3] = y; + points[4] = x + width; + points[5] = y + height; + points[6] = x; + points[7] = y + height; + return points; + }, + triangulate(points, vertices, verticesStride, verticesOffset, indices, indicesOffset) { + let count = 0; + verticesOffset *= verticesStride; + vertices[verticesOffset + count] = points[0]; + vertices[verticesOffset + count + 1] = points[1]; + count += verticesStride; + vertices[verticesOffset + count] = points[2]; + vertices[verticesOffset + count + 1] = points[3]; + count += verticesStride; + vertices[verticesOffset + count] = points[6]; + vertices[verticesOffset + count + 1] = points[7]; + count += verticesStride; + vertices[verticesOffset + count] = points[4]; + vertices[verticesOffset + count + 1] = points[5]; + count += verticesStride; + const verticesIndex = verticesOffset / verticesStride; + indices[indicesOffset++] = verticesIndex; + indices[indicesOffset++] = verticesIndex + 1; + indices[indicesOffset++] = verticesIndex + 2; + indices[indicesOffset++] = verticesIndex + 1; + indices[indicesOffset++] = verticesIndex + 3; + indices[indicesOffset++] = verticesIndex + 2; + } +}; + +"use strict"; +const buildTriangle = { + build(shape, points) { + points[0] = shape.x; + points[1] = shape.y; + points[2] = shape.x2; + points[3] = shape.y2; + points[4] = shape.x3; + points[5] = shape.y3; + return points; + }, + triangulate(points, vertices, verticesStride, verticesOffset, indices, indicesOffset) { + let count = 0; + verticesOffset *= verticesStride; + vertices[verticesOffset + count] = points[0]; + vertices[verticesOffset + count + 1] = points[1]; + count += verticesStride; + vertices[verticesOffset + count] = points[2]; + vertices[verticesOffset + count + 1] = points[3]; + count += verticesStride; + vertices[verticesOffset + count] = points[4]; + vertices[verticesOffset + count + 1] = points[5]; + const verticesIndex = verticesOffset / verticesStride; + indices[indicesOffset++] = verticesIndex; + indices[indicesOffset++] = verticesIndex + 1; + indices[indicesOffset++] = verticesIndex + 2; + } +}; + +"use strict"; +const buildMap$1 = { + rectangle: buildRectangle, + polygon: buildPolygon, + triangle: buildTriangle, + circle: buildCircle, + ellipse: buildCircle, + roundedRectangle: buildCircle +}; +const tempRect$1 = new Rectangle(); +function buildContextBatches(context, gpuContext) { + const { geometryData, batches } = gpuContext; + batches.length = 0; + geometryData.indices.length = 0; + geometryData.vertices.length = 0; + geometryData.uvs.length = 0; + for (let i = 0; i < context.instructions.length; i++) { + const instruction = context.instructions[i]; + if (instruction.action === "texture") { + addTextureToGeometryData(instruction.data, batches, geometryData); + } else if (instruction.action === "fill" || instruction.action === "stroke") { + const isStroke = instruction.action === "stroke"; + const shapePath = instruction.data.path.shapePath; + const style = instruction.data.style; + const hole = instruction.data.hole; + if (isStroke && hole) { + addShapePathToGeometryData(hole.shapePath, style, null, true, batches, geometryData); + } + addShapePathToGeometryData(shapePath, style, hole, isStroke, batches, geometryData); + } + } +} +function addTextureToGeometryData(data, batches, geometryData) { + const { vertices, uvs, indices } = geometryData; + const indexOffset = indices.length; + const vertOffset = vertices.length / 2; + const points = []; + const build = buildMap$1.rectangle; + const rect = tempRect$1; + const texture = data.image; + rect.x = data.dx; + rect.y = data.dy; + rect.width = data.dw; + rect.height = data.dh; + const matrix = data.transform; + build.build(rect, points); + if (matrix) { + transformVertices(points, matrix); + } + build.triangulate(points, vertices, 2, vertOffset, indices, indexOffset); + const textureUvs = texture.uvs; + uvs.push( + textureUvs.x0, + textureUvs.y0, + textureUvs.x1, + textureUvs.y1, + textureUvs.x3, + textureUvs.y3, + textureUvs.x2, + textureUvs.y2 + ); + const graphicsBatch = BigPool.get(BatchableGraphics); + graphicsBatch.indexOffset = indexOffset; + graphicsBatch.indexSize = indices.length - indexOffset; + graphicsBatch.vertexOffset = vertOffset; + graphicsBatch.vertexSize = vertices.length / 2 - vertOffset; + graphicsBatch.color = data.style; + graphicsBatch.alpha = data.alpha; + graphicsBatch.texture = texture; + graphicsBatch.geometryData = geometryData; + batches.push(graphicsBatch); +} +function addShapePathToGeometryData(shapePath, style, hole, isStroke, batches, geometryData) { + const { vertices, uvs, indices } = geometryData; + const lastIndex = shapePath.shapePrimitives.length - 1; + shapePath.shapePrimitives.forEach(({ shape, transform: matrix }, i) => { + var _a; + const indexOffset = indices.length; + const vertOffset = vertices.length / 2; + const points = []; + const build = buildMap$1[shape.type]; + build.build(shape, points); + if (matrix) { + transformVertices(points, matrix); + } + if (!isStroke) { + if (hole && lastIndex === i) { + if (lastIndex !== 0) { + console.warn("[Pixi Graphics] only the last shape have be cut out"); + } + const holeIndices = []; + const otherPoints = points.slice(); + const holeArrays = getHoleArrays(hole.shapePath); + holeArrays.forEach((holePoints) => { + holeIndices.push(otherPoints.length / 2); + otherPoints.push(...holePoints); + }); + triangulateWithHoles(otherPoints, holeIndices, vertices, 2, vertOffset, indices, indexOffset); + } else { + build.triangulate(points, vertices, 2, vertOffset, indices, indexOffset); + } + } else { + const close = (_a = shape.closePath) != null ? _a : true; + const lineStyle = style; + buildLine(points, lineStyle, false, close, vertices, 2, vertOffset, indices, indexOffset); + } + const uvsOffset = uvs.length / 2; + const texture = style.texture; + if (texture !== Texture.WHITE) { + const textureMatrix = style.matrix; + if (matrix) { + textureMatrix.append(matrix.clone().invert()); + } + buildUvs(vertices, 2, vertOffset, uvs, uvsOffset, 2, vertices.length / 2 - vertOffset, textureMatrix); + } else { + buildSimpleUvs(uvs, uvsOffset, 2, vertices.length / 2 - vertOffset); + } + const graphicsBatch = BigPool.get(BatchableGraphics); + graphicsBatch.indexOffset = indexOffset; + graphicsBatch.indexSize = indices.length - indexOffset; + graphicsBatch.vertexOffset = vertOffset; + graphicsBatch.vertexSize = vertices.length / 2 - vertOffset; + graphicsBatch.color = style.color; + graphicsBatch.alpha = style.alpha; + graphicsBatch.texture = texture; + graphicsBatch.geometryData = geometryData; + batches.push(graphicsBatch); + }); +} +function getHoleArrays(shape) { + if (!shape) + return []; + const holePrimitives = shape.shapePrimitives; + const holeArrays = []; + for (let k = 0; k < holePrimitives.length; k++) { + const holePrimitive = holePrimitives[k].shape; + const holePoints = []; + const holeBuilder = buildMap$1[holePrimitive.type]; + holeBuilder.build(holePrimitive, holePoints); + holeArrays.push(holePoints); + } + return holeArrays; +} + +"use strict"; +class GpuGraphicsContext { + constructor() { + this.batches = []; + this.geometryData = { + vertices: [], + uvs: [], + indices: [] + }; + } +} +class GraphicsContextRenderData { + constructor() { + this.geometry = new BatchGeometry(); + this.instructions = new InstructionSet(); + } + init() { + this.instructions.reset(); + } +} +const _GraphicsContextSystem = class _GraphicsContextSystem { + constructor() { + // the root context batches, used to either make a batch or geometry + // all graphics use this as a base + this._activeBatchers = []; + this._gpuContextHash = {}; + // used for non-batchable graphics + this._graphicsDataContextHash = /* @__PURE__ */ Object.create(null); + this._needsContextNeedsRebuild = []; + } + /** + * Runner init called, update the default options + * @ignore + */ + init(options) { + var _a; + _GraphicsContextSystem.defaultOptions.bezierSmoothness = (_a = options == null ? void 0 : options.bezierSmoothness) != null ? _a : _GraphicsContextSystem.defaultOptions.bezierSmoothness; + } + prerender() { + this._returnActiveBatchers(); + } + getContextRenderData(context) { + return this._graphicsDataContextHash[context.uid] || this._initContextRenderData(context); + } + // Context management functions + updateGpuContext(context) { + let gpuContext = this._gpuContextHash[context.uid] || this._initContext(context); + if (context.dirty) { + if (gpuContext) { + this._cleanGraphicsContextData(context); + } else { + gpuContext = this._initContext(context); + } + buildContextBatches(context, gpuContext); + const batchMode = context.batchMode; + if (context.customShader || batchMode === "no-batch") { + gpuContext.isBatchable = false; + } else if (batchMode === "auto") { + gpuContext.isBatchable = gpuContext.geometryData.vertices.length < 400; + } + context.dirty = false; + } + return gpuContext; + } + getGpuContext(context) { + return this._gpuContextHash[context.uid] || this._initContext(context); + } + _returnActiveBatchers() { + for (let i = 0; i < this._activeBatchers.length; i++) { + BigPool.return(this._activeBatchers[i]); + } + this._activeBatchers.length = 0; + } + _initContextRenderData(context) { + const graphicsData = BigPool.get(GraphicsContextRenderData); + const { batches, geometryData } = this._gpuContextHash[context.uid]; + const vertexSize = geometryData.vertices.length; + const indexSize = geometryData.indices.length; + for (let i = 0; i < batches.length; i++) { + batches[i].applyTransform = false; + } + const batcher = BigPool.get(Batcher); + this._activeBatchers.push(batcher); + batcher.ensureAttributeBuffer(vertexSize); + batcher.ensureIndexBuffer(indexSize); + batcher.begin(); + for (let i = 0; i < batches.length; i++) { + const batch = batches[i]; + batcher.add(batch); + } + batcher.finish(graphicsData.instructions); + const geometry = graphicsData.geometry; + geometry.indexBuffer.setDataWithSize(batcher.indexBuffer, batcher.indexSize, true); + geometry.buffers[0].setDataWithSize(batcher.attributeBuffer.float32View, batcher.attributeSize, true); + const drawBatches = batcher.batches; + for (let i = 0; i < drawBatches.length; i++) { + const batch = drawBatches[i]; + batch.bindGroup = getTextureBatchBindGroup(batch.textures.textures, batch.textures.count); + } + this._graphicsDataContextHash[context.uid] = graphicsData; + return graphicsData; + } + _initContext(context) { + const gpuContext = new GpuGraphicsContext(); + this._gpuContextHash[context.uid] = gpuContext; + context.on("update", this.onGraphicsContextUpdate, this); + context.on("destroy", this.onGraphicsContextDestroy, this); + return this._gpuContextHash[context.uid]; + } + onGraphicsContextUpdate(context) { + this._needsContextNeedsRebuild.push(context); + } + onGraphicsContextDestroy(context) { + this._cleanGraphicsContextData(context); + context.off("update", this.onGraphicsContextUpdate, this); + context.off("destroy", this.onGraphicsContextDestroy, this); + this._gpuContextHash[context.uid] = null; + } + _cleanGraphicsContextData(context) { + const gpuContext = this._gpuContextHash[context.uid]; + if (!gpuContext.isBatchable) { + if (this._graphicsDataContextHash[context.uid]) { + BigPool.return(this.getContextRenderData(context)); + this._graphicsDataContextHash[context.uid] = null; + } + } + if (gpuContext.batches) { + gpuContext.batches.forEach((batch) => { + BigPool.return(batch); + }); + } + } + destroy() { + for (const context of this._needsContextNeedsRebuild) { + if (this._gpuContextHash[context.uid]) { + this.onGraphicsContextDestroy(context); + } + } + this._needsContextNeedsRebuild.length = 0; + } +}; +/** @ignore */ +_GraphicsContextSystem.extension = { + type: [ + ExtensionType.WebGLSystem, + ExtensionType.WebGPUSystem, + ExtensionType.CanvasSystem + ], + name: "graphicsContext" +}; +/** The default options for the GraphicsContextSystem. */ +_GraphicsContextSystem.defaultOptions = { + /** + * A value from 0 to 1 that controls the smoothness of bezier curves (the higher the smoother) + * @default 0.5 + */ + bezierSmoothness: 0.5 +}; +let GraphicsContextSystem = _GraphicsContextSystem; + +"use strict"; +const blendModeIds = { + normal: 0, + add: 1, + multiply: 2, + screen: 3, + overlay: 4, + erase: 5, + "normal-npm": 6, + "add-npm": 7, + "screen-npm": 8 +}; +const BLEND$1 = 0; +const OFFSET$1 = 1; +const CULLING$1 = 2; +const DEPTH_TEST$1 = 3; +const WINDING$1 = 4; +const DEPTH_MASK$1 = 5; +const _State = class _State { + constructor() { + this.data = 0; + this.blendMode = "normal"; + this.polygonOffset = 0; + this.blend = true; + this.depthMask = true; + } + /** + * Activates blending of the computed fragment color values. + * @default true + */ + get blend() { + return !!(this.data & 1 << BLEND$1); + } + set blend(value) { + if (!!(this.data & 1 << BLEND$1) !== value) { + this.data ^= 1 << BLEND$1; + } + } + /** + * Activates adding an offset to depth values of polygon's fragments + * @default false + */ + get offsets() { + return !!(this.data & 1 << OFFSET$1); + } + set offsets(value) { + if (!!(this.data & 1 << OFFSET$1) !== value) { + this.data ^= 1 << OFFSET$1; + } + } + /** The culling settings for this state none - No culling back - Back face culling front - Front face culling */ + set cullMode(value) { + if (value === "none") { + this.culling = false; + return; + } + this.culling = true; + this.clockwiseFrontFace = value === "front"; + } + get cullMode() { + if (!this.culling) { + return "none"; + } + return this.clockwiseFrontFace ? "front" : "back"; + } + /** + * Activates culling of polygons. + * @default false + */ + get culling() { + return !!(this.data & 1 << CULLING$1); + } + set culling(value) { + if (!!(this.data & 1 << CULLING$1) !== value) { + this.data ^= 1 << CULLING$1; + } + } + /** + * Activates depth comparisons and updates to the depth buffer. + * @default false + */ + get depthTest() { + return !!(this.data & 1 << DEPTH_TEST$1); + } + set depthTest(value) { + if (!!(this.data & 1 << DEPTH_TEST$1) !== value) { + this.data ^= 1 << DEPTH_TEST$1; + } + } + /** + * Enables or disables writing to the depth buffer. + * @default true + */ + get depthMask() { + return !!(this.data & 1 << DEPTH_MASK$1); + } + set depthMask(value) { + if (!!(this.data & 1 << DEPTH_MASK$1) !== value) { + this.data ^= 1 << DEPTH_MASK$1; + } + } + /** + * Specifies whether or not front or back-facing polygons can be culled. + * @default false + */ + get clockwiseFrontFace() { + return !!(this.data & 1 << WINDING$1); + } + set clockwiseFrontFace(value) { + if (!!(this.data & 1 << WINDING$1) !== value) { + this.data ^= 1 << WINDING$1; + } + } + /** + * The blend mode to be applied when this state is set. Apply a value of `normal` to reset the blend mode. + * Setting this mode to anything other than NO_BLEND will automatically switch blending on. + * @default 'normal' + */ + get blendMode() { + return this._blendMode; + } + set blendMode(value) { + this.blend = value !== "none"; + this._blendMode = value; + this._blendModeId = blendModeIds[value] || 0; + } + /** + * The polygon offset. Setting this property to anything other than 0 will automatically enable polygon offset fill. + * @default 0 + */ + get polygonOffset() { + return this._polygonOffset; + } + set polygonOffset(value) { + this.offsets = !!value; + this._polygonOffset = value; + } + toString() { + return `[pixi.js/core:State blendMode=${this.blendMode} clockwiseFrontFace=${this.clockwiseFrontFace} culling=${this.culling} depthMask=${this.depthMask} polygonOffset=${this.polygonOffset}]`; + } + /** + * A quickly getting an instance of a State that is configured for 2d rendering. + * @returns a new State with values set for 2d rendering + */ + static for2d() { + const state = new _State(); + state.depthTest = false; + state.blend = true; + return state; + } +}; +_State.default2d = _State.for2d(); +let State = _State; + +"use strict"; +function colorToUniform(rgb, alpha, out, offset) { + out[offset++] = (rgb >> 16 & 255) / 255; + out[offset++] = (rgb >> 8 & 255) / 255; + out[offset++] = (rgb & 255) / 255; + out[offset++] = alpha; +} +function color32BitToUniform(abgr, out, offset) { + const alpha = (abgr >> 24 & 255) / 255; + out[offset++] = (abgr & 255) / 255 * alpha; + out[offset++] = (abgr >> 8 & 255) / 255 * alpha; + out[offset++] = (abgr >> 16 & 255) / 255 * alpha; + out[offset++] = alpha; +} + +"use strict"; +class GraphicsPipe { + constructor(renderer, adaptor) { + this.state = State.for2d(); + // batchable graphics list, used to render batches + this._graphicsBatchesHash = /* @__PURE__ */ Object.create(null); + this.renderer = renderer; + this._adaptor = adaptor; + this._adaptor.init(); + } + validateRenderable(graphics) { + const context = graphics.context; + const wasBatched = !!this._graphicsBatchesHash[graphics.uid]; + const gpuContext = this.renderer.graphicsContext.updateGpuContext(context); + if (gpuContext.isBatchable || wasBatched !== gpuContext.isBatchable) { + return true; + } + return false; + } + addRenderable(graphics, instructionSet) { + const gpuContext = this.renderer.graphicsContext.updateGpuContext(graphics.context); + if (graphics._didGraphicsUpdate) { + graphics._didGraphicsUpdate = false; + this._rebuild(graphics); + } + if (gpuContext.isBatchable) { + this._addToBatcher(graphics, instructionSet); + } else { + this.renderer.renderPipes.batch.break(instructionSet); + instructionSet.add(graphics); + } + } + updateRenderable(graphics) { + const batches = this._graphicsBatchesHash[graphics.uid]; + if (batches) { + for (let i = 0; i < batches.length; i++) { + const batch = batches[i]; + batch.batcher.updateElement(batch); + } + } + } + destroyRenderable(graphics) { + if (this._graphicsBatchesHash[graphics.uid]) { + this._removeBatchForRenderable(graphics.uid); + } + } + execute(graphics) { + if (!graphics.isRenderable) + return; + const renderer = this.renderer; + const context = graphics.context; + const contextSystem = renderer.graphicsContext; + if (!contextSystem.getGpuContext(context).batches.length) { + return; + } + const shader = context.customShader || this._adaptor.shader; + this.state.blendMode = graphics.groupBlendMode; + const localUniforms = shader.resources.localUniforms.uniforms; + localUniforms.uTransformMatrix = graphics.groupTransform; + localUniforms.uRound = renderer._roundPixels | graphics._roundPixels; + color32BitToUniform( + graphics.groupColorAlpha, + localUniforms.uColor, + 0 + ); + this._adaptor.execute(this, graphics); + } + _rebuild(graphics) { + const wasBatched = !!this._graphicsBatchesHash[graphics.uid]; + const gpuContext = this.renderer.graphicsContext.updateGpuContext(graphics.context); + if (wasBatched) { + this._removeBatchForRenderable(graphics.uid); + } + if (gpuContext.isBatchable) { + this._initBatchesForRenderable(graphics); + } + graphics.batched = gpuContext.isBatchable; + } + _addToBatcher(graphics, instructionSet) { + const batchPipe = this.renderer.renderPipes.batch; + const batches = this._getBatchesForRenderable(graphics); + for (let i = 0; i < batches.length; i++) { + const batch = batches[i]; + batchPipe.addToBatch(batch, instructionSet); + } + } + _getBatchesForRenderable(graphics) { + return this._graphicsBatchesHash[graphics.uid] || this._initBatchesForRenderable(graphics); + } + _initBatchesForRenderable(graphics) { + const context = graphics.context; + const gpuContext = this.renderer.graphicsContext.getGpuContext(context); + const roundPixels = this.renderer._roundPixels | graphics._roundPixels; + const batches = gpuContext.batches.map((batch) => { + const batchClone = BigPool.get(BatchableGraphics); + batch.copyTo(batchClone); + batchClone.renderable = graphics; + batchClone.roundPixels = roundPixels; + return batchClone; + }); + this._graphicsBatchesHash[graphics.uid] = batches; + graphics.on("destroyed", () => { + this.destroyRenderable(graphics); + }); + return batches; + } + _removeBatchForRenderable(graphicsUid) { + this._graphicsBatchesHash[graphicsUid].forEach((batch) => { + BigPool.return(batch); + }); + this._graphicsBatchesHash[graphicsUid] = null; + } + destroy() { + this.renderer = null; + this._adaptor.destroy(); + this._adaptor = null; + this.state = null; + for (const i in this._graphicsBatchesHash) { + this._removeBatchForRenderable(i); + } + this._graphicsBatchesHash = null; + } +} +/** @ignore */ +GraphicsPipe.extension = { + type: [ + ExtensionType.WebGLPipes, + ExtensionType.WebGPUPipes, + ExtensionType.CanvasPipes + ], + name: "graphics" +}; + +"use strict"; +extensions.add(GraphicsPipe); +extensions.add(GraphicsContextSystem); + +"use strict"; +const idCounts = /* @__PURE__ */ Object.create(null); +const idHash = /* @__PURE__ */ Object.create(null); +function createIdFromString(value, groupId) { + let id = idHash[value]; + if (id === void 0) { + if (idCounts[groupId] === void 0) { + idCounts[groupId] = 1; + } + idHash[value] = id = idCounts[groupId]++; + } + return id; +} + +"use strict"; +function getDefaultUniformValue(type, size) { + switch (type) { + case "f32": + return 0; + case "vec2": + return new Float32Array(2 * size); + case "vec3": + return new Float32Array(3 * size); + case "vec4": + return new Float32Array(4 * size); + case "mat2x2": + return new Float32Array([ + 1, + 0, + 0, + 1 + ]); + case "mat3x3": + return new Float32Array([ + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1 + ]); + case "mat4x4": + return new Float32Array([ + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1 + ]); + } + return null; +} + +"use strict"; +var __defProp$S = Object.defineProperty; +var __getOwnPropSymbols$S = Object.getOwnPropertySymbols; +var __hasOwnProp$S = Object.prototype.hasOwnProperty; +var __propIsEnum$S = Object.prototype.propertyIsEnumerable; +var __defNormalProp$S = (obj, key, value) => key in obj ? __defProp$S(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; +var __spreadValues$S = (a, b) => { + for (var prop in b || (b = {})) + if (__hasOwnProp$S.call(b, prop)) + __defNormalProp$S(a, prop, b[prop]); + if (__getOwnPropSymbols$S) + for (var prop of __getOwnPropSymbols$S(b)) { + if (__propIsEnum$S.call(b, prop)) + __defNormalProp$S(a, prop, b[prop]); + } + return a; +}; +const _UniformGroup = class _UniformGroup { + /** + * Create a new Uniform group + * @param uniformStructures - The structures of the uniform group + * @param options - The optional parameters of this uniform group + */ + constructor(uniformStructures, options) { + /** used internally to know if a uniform group was used in the last render pass */ + this._touched = 0; + /** a unique id for this uniform group used through the renderer */ + this.uid = uid("uniform"); + /** a resource type, used to identify how to handle it when its in a bind group / shader resource */ + this._resourceType = "uniformGroup"; + /** the resource id used internally by the renderer to build bind group keys */ + this._resourceId = uid("resource"); + /** used ito identify if this is a uniform group */ + this.isUniformGroup = true; + /** + * used to flag if this Uniform groups data is different from what it has stored in its buffer / on the GPU + * @internal + * @ignore + */ + this._dirtyId = 0; + // implementing the interface - UniformGroup are not destroyed + this.destroyed = false; + var _a, _b; + options = __spreadValues$S(__spreadValues$S({}, _UniformGroup.defaultOptions), options); + this.uniformStructures = uniformStructures; + const uniforms = {}; + for (const i in uniformStructures) { + const uniformData = uniformStructures[i]; + uniformData.name = i; + uniformData.size = (_a = uniformData.size) != null ? _a : 1; + (_b = uniformData.value) != null ? _b : uniformData.value = getDefaultUniformValue(uniformData.type, uniformData.size); + uniforms[i] = uniformData.value; + } + this.uniforms = uniforms; + this._dirtyId = 1; + this.ubo = options.ubo; + this.isStatic = options.isStatic; + this._signature = createIdFromString(Object.keys(uniforms).map( + (i) => `${i}-${uniformStructures[i].type}` + ).join("-"), "uniform-group"); + } + /** Call this if you want the uniform groups data to be uploaded to the GPU only useful if `isStatic` is true. */ + update() { + this._dirtyId++; + } +}; +/** The default options used by the uniform group. */ +_UniformGroup.defaultOptions = { + /** if true the UniformGroup is handled as an Uniform buffer object. */ + ubo: false, + /** if true, then you are responsible for when the data is uploaded to the GPU by calling `update()` */ + isStatic: false +}; +let UniformGroup = _UniformGroup; + +"use strict"; +class BatchableMesh { + constructor() { + this.batcher = null; + this.batch = null; + this.roundPixels = 0; + this._uvUpdateId = -1; + this._textureMatrixUpdateId = -1; + } + get blendMode() { + return this.mesh.groupBlendMode; + } + reset() { + this.mesh = null; + this.texture = null; + this.batcher = null; + this.batch = null; + } + packIndex(indexBuffer, index, indicesOffset) { + const indices = this.geometry.indices; + for (let i = 0; i < indices.length; i++) { + indexBuffer[index++] = indices[i] + indicesOffset; + } + } + packAttributes(float32View, uint32View, index, textureId) { + const mesh = this.mesh; + const geometry = this.geometry; + const wt = mesh.groupTransform; + const textureIdAndRound = textureId << 16 | this.roundPixels & 65535; + const a = wt.a; + const b = wt.b; + const c = wt.c; + const d = wt.d; + const tx = wt.tx; + const ty = wt.ty; + const positions = geometry.positions; + const uvBuffer = geometry.getBuffer("aUV"); + const uvs = uvBuffer.data; + let transformedUvs = uvs; + const textureMatrix = this.texture.textureMatrix; + if (!textureMatrix.isSimple) { + transformedUvs = this._transformedUvs; + if (this._textureMatrixUpdateId !== textureMatrix._updateID || this._uvUpdateId !== uvBuffer._updateID) { + if (!transformedUvs || transformedUvs.length < uvs.length) { + transformedUvs = this._transformedUvs = new Float32Array(uvs.length); + } + this._textureMatrixUpdateId = textureMatrix._updateID; + this._uvUpdateId = uvBuffer._updateID; + textureMatrix.multiplyUvs(uvs, transformedUvs); + } + } + const abgr = mesh.groupColorAlpha; + for (let i = 0; i < positions.length; i += 2) { + const x = positions[i]; + const y = positions[i + 1]; + float32View[index] = a * x + c * y + tx; + float32View[index + 1] = b * x + d * y + ty; + float32View[index + 2] = transformedUvs[i]; + float32View[index + 3] = transformedUvs[i + 1]; + uint32View[index + 4] = abgr; + uint32View[index + 5] = textureIdAndRound; + index += 6; + } + } + get vertexSize() { + return this.geometry.positions.length / 2; + } + get indexSize() { + return this.geometry.indices.length; + } +} + +"use strict"; +class MeshPipe { + constructor(renderer, adaptor) { + this.localUniforms = new UniformGroup({ + uTransformMatrix: { value: new Matrix(), type: "mat3x3" }, + uColor: { value: new Float32Array([1, 1, 1, 1]), type: "vec4" }, + uRound: { value: 0, type: "f32" } + }); + this.localUniformsBindGroup = new BindGroup({ + 0: this.localUniforms + }); + this._meshDataHash = /* @__PURE__ */ Object.create(null); + this._gpuBatchableMeshHash = /* @__PURE__ */ Object.create(null); + this.renderer = renderer; + this._adaptor = adaptor; + this._adaptor.init(); + } + validateRenderable(mesh) { + const meshData = this._getMeshData(mesh); + const wasBatched = meshData.batched; + const isBatched = mesh.batched; + meshData.batched = isBatched; + if (wasBatched !== isBatched) { + return true; + } else if (isBatched) { + const geometry = mesh._geometry; + if (geometry.indices.length !== meshData.indexSize || geometry.positions.length !== meshData.vertexSize) { + meshData.indexSize = geometry.indices.length; + meshData.vertexSize = geometry.positions.length; + return true; + } + const batchableMesh = this._getBatchableMesh(mesh); + const texture = mesh.texture; + if (batchableMesh.texture._source !== texture._source) { + if (batchableMesh.texture._source !== texture._source) { + return !batchableMesh.batcher.checkAndUpdateTexture(batchableMesh, texture); + } + } + } + return false; + } + addRenderable(mesh, instructionSet) { + const batcher = this.renderer.renderPipes.batch; + const { batched } = this._getMeshData(mesh); + if (batched) { + const gpuBatchableMesh = this._getBatchableMesh(mesh); + gpuBatchableMesh.texture = mesh._texture; + gpuBatchableMesh.geometry = mesh._geometry; + batcher.addToBatch(gpuBatchableMesh); + } else { + batcher.break(instructionSet); + instructionSet.add({ + renderPipeId: "mesh", + mesh + }); + } + } + updateRenderable(mesh) { + if (mesh.batched) { + const gpuBatchableMesh = this._gpuBatchableMeshHash[mesh.uid]; + gpuBatchableMesh.texture = mesh._texture; + gpuBatchableMesh.geometry = mesh._geometry; + gpuBatchableMesh.batcher.updateElement(gpuBatchableMesh); + } + } + destroyRenderable(mesh) { + this._meshDataHash[mesh.uid] = null; + const gpuMesh = this._gpuBatchableMeshHash[mesh.uid]; + if (gpuMesh) { + BigPool.return(gpuMesh); + this._gpuBatchableMeshHash[mesh.uid] = null; + } + } + execute({ mesh }) { + if (!mesh.isRenderable) + return; + mesh.state.blendMode = mesh.groupBlendMode; + const localUniforms = this.localUniforms; + localUniforms.uniforms.uTransformMatrix = mesh.groupTransform; + localUniforms.uniforms.uRound = this.renderer._roundPixels | mesh._roundPixels; + localUniforms.update(); + color32BitToUniform( + mesh.groupColorAlpha, + localUniforms.uniforms.uColor, + 0 + ); + this._adaptor.execute(this, mesh); + } + _getMeshData(mesh) { + return this._meshDataHash[mesh.uid] || this._initMeshData(mesh); + } + _initMeshData(mesh) { + var _a, _b; + this._meshDataHash[mesh.uid] = { + batched: mesh.batched, + indexSize: (_a = mesh._geometry.indices) == null ? void 0 : _a.length, + vertexSize: (_b = mesh._geometry.positions) == null ? void 0 : _b.length + }; + mesh.on("destroyed", () => { + this.destroyRenderable(mesh); + }); + return this._meshDataHash[mesh.uid]; + } + _getBatchableMesh(mesh) { + return this._gpuBatchableMeshHash[mesh.uid] || this._initBatchableMesh(mesh); + } + _initBatchableMesh(mesh) { + const gpuMesh = BigPool.get(BatchableMesh); + gpuMesh.mesh = mesh; + gpuMesh.texture = mesh._texture; + gpuMesh.roundPixels = this.renderer._roundPixels | mesh._roundPixels; + this._gpuBatchableMeshHash[mesh.uid] = gpuMesh; + gpuMesh.mesh = mesh; + return gpuMesh; + } + destroy() { + for (const i in this._gpuBatchableMeshHash) { + if (this._gpuBatchableMeshHash[i]) { + BigPool.return(this._gpuBatchableMeshHash[i]); + } + } + this._gpuBatchableMeshHash = null; + this._meshDataHash = null; + this.localUniforms = null; + this.localUniformsBindGroup = null; + this._adaptor.destroy(); + this._adaptor = null; + this.renderer = null; + } +} +/** @ignore */ +MeshPipe.extension = { + type: [ + ExtensionType.WebGLPipes, + ExtensionType.WebGPUPipes, + ExtensionType.CanvasPipes + ], + name: "mesh" +}; + +"use strict"; +extensions.add(MeshPipe); + +"use strict"; +class BatchableSprite { + constructor() { + // batch specific.. + this.vertexSize = 4; + this.indexSize = 6; + this.location = 0; + // location in the buffer + this.batcher = null; + this.batch = null; + this.roundPixels = 0; + } + get blendMode() { + return this.renderable.groupBlendMode; + } + packAttributes(float32View, uint32View, index, textureId) { + const sprite = this.renderable; + const texture = this.texture; + const wt = sprite.groupTransform; + const a = wt.a; + const b = wt.b; + const c = wt.c; + const d = wt.d; + const tx = wt.tx; + const ty = wt.ty; + const bounds = this.bounds; + const w0 = bounds.maxX; + const w1 = bounds.minX; + const h0 = bounds.maxY; + const h1 = bounds.minY; + const uvs = texture.uvs; + const argb = sprite.groupColorAlpha; + const textureIdAndRound = textureId << 16 | this.roundPixels & 65535; + float32View[index + 0] = a * w1 + c * h1 + tx; + float32View[index + 1] = d * h1 + b * w1 + ty; + float32View[index + 2] = uvs.x0; + float32View[index + 3] = uvs.y0; + uint32View[index + 4] = argb; + uint32View[index + 5] = textureIdAndRound; + float32View[index + 6] = a * w0 + c * h1 + tx; + float32View[index + 7] = d * h1 + b * w0 + ty; + float32View[index + 8] = uvs.x1; + float32View[index + 9] = uvs.y1; + uint32View[index + 10] = argb; + uint32View[index + 11] = textureIdAndRound; + float32View[index + 12] = a * w0 + c * h0 + tx; + float32View[index + 13] = d * h0 + b * w0 + ty; + float32View[index + 14] = uvs.x2; + float32View[index + 15] = uvs.y2; + uint32View[index + 16] = argb; + uint32View[index + 17] = textureIdAndRound; + float32View[index + 18] = a * w1 + c * h0 + tx; + float32View[index + 19] = d * h0 + b * w1 + ty; + float32View[index + 20] = uvs.x3; + float32View[index + 21] = uvs.y3; + uint32View[index + 22] = argb; + uint32View[index + 23] = textureIdAndRound; + } + packIndex(indexBuffer, index, indicesOffset) { + indexBuffer[index] = indicesOffset + 0; + indexBuffer[index + 1] = indicesOffset + 1; + indexBuffer[index + 2] = indicesOffset + 2; + indexBuffer[index + 3] = indicesOffset + 0; + indexBuffer[index + 4] = indicesOffset + 2; + indexBuffer[index + 5] = indicesOffset + 3; + } + reset() { + this.renderable = null; + this.texture = null; + this.batcher = null; + this.batch = null; + this.bounds = null; + } +} + +"use strict"; +class CanvasTextPipe { + constructor(renderer) { + this._gpuText = /* @__PURE__ */ Object.create(null); + this._renderer = renderer; + } + validateRenderable(text) { + var _a; + const gpuText = this._getGpuText(text); + const newKey = text._getKey(); + if (gpuText.currentKey !== newKey) { + const resolution = (_a = text.resolution) != null ? _a : this._renderer.resolution; + const { width, height } = this._renderer.canvasText.getTextureSize( + text.text, + resolution, + text._style + ); + if ( + // is only being used by this text: + this._renderer.canvasText.getReferenceCount(gpuText.currentKey) === 1 && width === gpuText.texture._source.width && height === gpuText.texture._source.height + ) { + return false; + } + return true; + } + return false; + } + addRenderable(text, _instructionSet) { + const gpuText = this._getGpuText(text); + const batchableSprite = gpuText.batchableSprite; + if (text._didTextUpdate) { + this._updateText(text); + } + this._renderer.renderPipes.batch.addToBatch(batchableSprite); + } + updateRenderable(text) { + const gpuText = this._getGpuText(text); + const batchableSprite = gpuText.batchableSprite; + if (text._didTextUpdate) { + this._updateText(text); + } + batchableSprite.batcher.updateElement(batchableSprite); + } + destroyRenderable(text) { + this._destroyRenderableById(text.uid); + } + _destroyRenderableById(textUid) { + const gpuText = this._gpuText[textUid]; + this._renderer.canvasText.decreaseReferenceCount(gpuText.currentKey); + BigPool.return(gpuText.batchableSprite); + this._gpuText[textUid] = null; + } + _updateText(text) { + const newKey = text._getKey(); + const gpuText = this._getGpuText(text); + const batchableSprite = gpuText.batchableSprite; + if (gpuText.currentKey !== newKey) { + this._updateGpuText(text); + } + text._didTextUpdate = false; + const padding = text._style.padding; + updateQuadBounds(batchableSprite.bounds, text._anchor, batchableSprite.texture, padding); + } + _updateGpuText(text) { + var _a; + const gpuText = this._getGpuText(text); + const batchableSprite = gpuText.batchableSprite; + if (gpuText.texture) { + this._renderer.canvasText.decreaseReferenceCount(gpuText.currentKey); + } + const resolution = (_a = text.resolution) != null ? _a : this._renderer.resolution; + gpuText.texture = batchableSprite.texture = this._renderer.canvasText.getTexture( + text.text, + resolution, + text._style, + text._getKey() + ); + gpuText.currentKey = text._getKey(); + batchableSprite.texture = gpuText.texture; + } + _getGpuText(text) { + return this._gpuText[text.uid] || this.initGpuText(text); + } + initGpuText(text) { + const gpuTextData = { + texture: null, + currentKey: "--", + batchableSprite: BigPool.get(BatchableSprite) + }; + gpuTextData.batchableSprite.renderable = text; + gpuTextData.batchableSprite.bounds = { minX: 0, maxX: 1, minY: 0, maxY: 0 }; + gpuTextData.batchableSprite.roundPixels = this._renderer._roundPixels | text._roundPixels; + this._gpuText[text.uid] = gpuTextData; + this._updateText(text); + text.on("destroyed", () => { + this.destroyRenderable(text); + }); + return gpuTextData; + } + destroy() { + for (const i in this._gpuText) { + this._destroyRenderableById(i); + } + this._gpuText = null; + this._renderer = null; + } +} +/** @ignore */ +CanvasTextPipe.extension = { + type: [ + ExtensionType.WebGLPipes, + ExtensionType.WebGPUPipes, + ExtensionType.CanvasPipes + ], + name: "text" +}; + +"use strict"; +class CanvasPoolClass { + constructor(canvasOptions) { + this._canvasPool = /* @__PURE__ */ Object.create(null); + this.canvasOptions = canvasOptions || {}; + this.enableFullScreen = false; + } + /** + * Creates texture with params that were specified in pool constructor. + * @param pixelWidth - Width of texture in pixels. + * @param pixelHeight - Height of texture in pixels. + */ + _createCanvasAndContext(pixelWidth, pixelHeight) { + const canvas = DOMAdapter.get().createCanvas(); + canvas.width = pixelWidth; + canvas.height = pixelHeight; + const context = canvas.getContext("2d"); + return { canvas, context }; + } + /** + * Gets a Power-of-Two render texture or fullScreen texture + * @param minWidth - The minimum width of the render texture. + * @param minHeight - The minimum height of the render texture. + * @param resolution - The resolution of the render texture. + * @returns The new render texture. + */ + getOptimalCanvasAndContext(minWidth, minHeight, resolution = 1) { + minWidth = Math.ceil(minWidth * resolution - 1e-6); + minHeight = Math.ceil(minHeight * resolution - 1e-6); + minWidth = nextPow2(minWidth); + minHeight = nextPow2(minHeight); + const key = (minWidth << 17) + (minHeight << 1); + if (!this._canvasPool[key]) { + this._canvasPool[key] = []; + } + let canvasAndContext = this._canvasPool[key].pop(); + if (!canvasAndContext) { + canvasAndContext = this._createCanvasAndContext(minWidth, minHeight); + } + return canvasAndContext; + } + /** + * Place a render texture back into the pool. + * @param canvasAndContext + */ + returnCanvasAndContext(canvasAndContext) { + const { width, height } = canvasAndContext.canvas; + const key = (width << 17) + (height << 1); + this._canvasPool[key].push(canvasAndContext); + } + clear() { + this._canvasPool = {}; + } +} +const CanvasPool = new CanvasPoolClass(); + +"use strict"; +var __defProp$R = Object.defineProperty; +var __defProps$k = Object.defineProperties; +var __getOwnPropDescs$k = Object.getOwnPropertyDescriptors; +var __getOwnPropSymbols$R = Object.getOwnPropertySymbols; +var __hasOwnProp$R = Object.prototype.hasOwnProperty; +var __propIsEnum$R = Object.prototype.propertyIsEnumerable; +var __defNormalProp$R = (obj, key, value) => key in obj ? __defProp$R(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; +var __spreadValues$R = (a, b) => { + for (var prop in b || (b = {})) + if (__hasOwnProp$R.call(b, prop)) + __defNormalProp$R(a, prop, b[prop]); + if (__getOwnPropSymbols$R) + for (var prop of __getOwnPropSymbols$R(b)) { + if (__propIsEnum$R.call(b, prop)) + __defNormalProp$R(a, prop, b[prop]); + } + return a; +}; +var __spreadProps$k = (a, b) => __defProps$k(a, __getOwnPropDescs$k(b)); +let count = 0; +class TexturePoolClass { + /** + * @param textureOptions - options that will be passed to BaseRenderTexture constructor + * @param {SCALE_MODE} [textureOptions.scaleMode] - See {@link SCALE_MODE} for possible values. + */ + constructor(textureOptions) { + this._poolKeyHash = /* @__PURE__ */ Object.create(null); + this._texturePool = {}; + this.textureOptions = textureOptions || {}; + this.enableFullScreen = false; + } + /** + * Creates texture with params that were specified in pool constructor. + * @param pixelWidth - Width of texture in pixels. + * @param pixelHeight - Height of texture in pixels. + * @param antialias + */ + createTexture(pixelWidth, pixelHeight, antialias) { + const textureSource = new TextureSource(__spreadProps$k(__spreadValues$R({}, this.textureOptions), { + width: pixelWidth, + height: pixelHeight, + resolution: 1, + antialias, + autoGarbageCollect: true + })); + return new Texture({ + source: textureSource, + label: `texturePool_${count++}` + }); + } + /** + * Gets a Power-of-Two render texture or fullScreen texture + * @param frameWidth - The minimum width of the render texture. + * @param frameHeight - The minimum height of the render texture. + * @param resolution - The resolution of the render texture. + * @param antialias + * @returns The new render texture. + */ + getOptimalTexture(frameWidth, frameHeight, resolution = 1, antialias) { + let po2Width = Math.ceil(frameWidth * resolution - 1e-6); + let po2Height = Math.ceil(frameHeight * resolution - 1e-6); + po2Width = nextPow2(po2Width); + po2Height = nextPow2(po2Height); + const key = (po2Width << 17) + (po2Height << 1) + (antialias ? 1 : 0); + if (!this._texturePool[key]) { + this._texturePool[key] = []; + } + let texture = this._texturePool[key].pop(); + if (!texture) { + texture = this.createTexture(po2Width, po2Height, antialias); + } + texture.source._resolution = resolution; + texture.source.width = po2Width / resolution; + texture.source.height = po2Height / resolution; + texture.source.pixelWidth = po2Width; + texture.source.pixelHeight = po2Height; + texture.frame.x = 0; + texture.frame.y = 0; + texture.frame.width = frameWidth; + texture.frame.height = frameHeight; + texture.updateUvs(); + this._poolKeyHash[texture.uid] = key; + return texture; + } + /** + * Gets extra texture of the same size as input renderTexture + * @param texture - The texture to check what size it is. + * @param antialias - Whether to use antialias. + * @returns A texture that is a power of two + */ + getSameSizeTexture(texture, antialias = false) { + const source = texture.source; + return this.getOptimalTexture(texture.width, texture.height, source._resolution, antialias); + } + /** + * Place a render texture back into the pool. + * @param renderTexture - The renderTexture to free + */ + returnTexture(renderTexture) { + const key = this._poolKeyHash[renderTexture.uid]; + this._texturePool[key].push(renderTexture); + } + /** + * Clears the pool. + * @param destroyTextures - Destroy all stored textures. + */ + clear(destroyTextures) { + destroyTextures = destroyTextures !== false; + if (destroyTextures) { + for (const i in this._texturePool) { + const textures = this._texturePool[i]; + if (textures) { + for (let j = 0; j < textures.length; j++) { + textures[j].destroy(true); + } + } + } + } + this._texturePool = {}; + } +} +const TexturePool = new TexturePoolClass(); + +"use strict"; +function checkRow(data, width, y) { + for (let x = 0, index = 4 * y * width; x < width; ++x, index += 4) { + if (data[index + 3] !== 0) + return false; + } + return true; +} +function checkColumn(data, width, x, top, bottom) { + const stride = 4 * width; + for (let y = top, index = top * stride + 4 * x; y <= bottom; ++y, index += stride) { + if (data[index + 3] !== 0) + return false; + } + return true; +} +function getCanvasBoundingBox(canvas, resolution = 1) { + const { width, height } = canvas; + const context = canvas.getContext("2d", { + willReadFrequently: true + }); + if (context === null) { + throw new TypeError("Failed to get canvas 2D context"); + } + const imageData = context.getImageData(0, 0, width, height); + const data = imageData.data; + let left = 0; + let top = 0; + let right = width - 1; + let bottom = height - 1; + while (top < height && checkRow(data, width, top)) + ++top; + if (top === height) + return Rectangle.EMPTY; + while (checkRow(data, width, bottom)) + --bottom; + while (checkColumn(data, width, left, top, bottom)) + ++left; + while (checkColumn(data, width, right, top, bottom)) + --right; + ++right; + ++bottom; + return new Rectangle(left / resolution, top / resolution, (right - left) / resolution, (bottom - top) / resolution); +} + +"use strict"; +const tempBounds$3 = new Bounds(); +function getPo2TextureFromSource(image, width, height, resolution) { + const bounds = tempBounds$3; + bounds.minX = 0; + bounds.minY = 0; + bounds.maxX = image.width / resolution | 0; + bounds.maxY = image.height / resolution | 0; + const texture = TexturePool.getOptimalTexture( + bounds.width, + bounds.height, + resolution, + false + ); + texture.source.uploadMethodId = "image"; + texture.source.resource = image; + texture.source.alphaMode = "premultiply-alpha-on-upload"; + texture.frame.width = width / resolution; + texture.frame.height = height / resolution; + texture.source.emit("update", texture.source); + texture.updateUvs(); + return texture; +} + +"use strict"; +const genericFontFamilies = [ + "serif", + "sans-serif", + "monospace", + "cursive", + "fantasy", + "system-ui" +]; +function fontStringFromTextStyle(style) { + const fontSizeString = typeof style.fontSize === "number" ? `${style.fontSize}px` : style.fontSize; + let fontFamilies = style.fontFamily; + if (!Array.isArray(style.fontFamily)) { + fontFamilies = style.fontFamily.split(","); + } + for (let i = fontFamilies.length - 1; i >= 0; i--) { + let fontFamily = fontFamilies[i].trim(); + if (!/([\"\'])[^\'\"]+\1/.test(fontFamily) && !genericFontFamilies.includes(fontFamily)) { + fontFamily = `"${fontFamily}"`; + } + fontFamilies[i] = fontFamily; + } + return `${style.fontStyle} ${style.fontVariant} ${style.fontWeight} ${fontSizeString} ${fontFamilies.join(",")}`; +} + +"use strict"; +const contextSettings = { + // TextMetrics requires getImageData readback for measuring fonts. + willReadFrequently: true +}; +const _CanvasTextMetrics = class _CanvasTextMetrics { + /** + * Checking that we can use modern canvas 2D API. + * + * Note: This is an unstable API, Chrome < 94 use `textLetterSpacing`, later versions use `letterSpacing`. + * @see TextMetrics.experimentalLetterSpacing + * @see https://developer.mozilla.org/en-US/docs/Web/API/ICanvasRenderingContext2D/letterSpacing + * @see https://developer.chrome.com/origintrials/#/view_trial/3585991203293757441 + */ + static get experimentalLetterSpacingSupported() { + let result = _CanvasTextMetrics._experimentalLetterSpacingSupported; + if (result !== void 0) { + const proto = DOMAdapter.get().getCanvasRenderingContext2D().prototype; + result = _CanvasTextMetrics._experimentalLetterSpacingSupported = "letterSpacing" in proto || "textLetterSpacing" in proto; + } + return result; + } + /** + * @param text - the text that was measured + * @param style - the style that was measured + * @param width - the measured width of the text + * @param height - the measured height of the text + * @param lines - an array of the lines of text broken by new lines and wrapping if specified in style + * @param lineWidths - an array of the line widths for each line matched to `lines` + * @param lineHeight - the measured line height for this style + * @param maxLineWidth - the maximum line width for all measured lines + * @param {FontMetrics} fontProperties - the font properties object from TextMetrics.measureFont + */ + constructor(text, style, width, height, lines, lineWidths, lineHeight, maxLineWidth, fontProperties) { + this.text = text; + this.style = style; + this.width = width; + this.height = height; + this.lines = lines; + this.lineWidths = lineWidths; + this.lineHeight = lineHeight; + this.maxLineWidth = maxLineWidth; + this.fontProperties = fontProperties; + } + /** + * Measures the supplied string of text and returns a Rectangle. + * @param text - The text to measure. + * @param style - The text style to use for measuring + * @param canvas - optional specification of the canvas to use for measuring. + * @param wordWrap + * @returns Measured width and height of the text. + */ + static measureText(text = " ", style, canvas = _CanvasTextMetrics._canvas, wordWrap = style.wordWrap) { + var _a; + const textKey = `${text}:${style.styleKey}`; + if (_CanvasTextMetrics._measurementCache[textKey]) + return _CanvasTextMetrics._measurementCache[textKey]; + const font = fontStringFromTextStyle(style); + const fontProperties = _CanvasTextMetrics.measureFont(font); + if (fontProperties.fontSize === 0) { + fontProperties.fontSize = style.fontSize; + fontProperties.ascent = style.fontSize; + } + const context = _CanvasTextMetrics.__context; + context.font = font; + const outputText = wordWrap ? _CanvasTextMetrics._wordWrap(text, style, canvas) : text; + const lines = outputText.split(/(?:\r\n|\r|\n)/); + const lineWidths = new Array(lines.length); + let maxLineWidth = 0; + for (let i = 0; i < lines.length; i++) { + const lineWidth = _CanvasTextMetrics._measureText(lines[i], style.letterSpacing, context); + lineWidths[i] = lineWidth; + maxLineWidth = Math.max(maxLineWidth, lineWidth); + } + const strokeWidth = ((_a = style._stroke) == null ? void 0 : _a.width) || 0; + let width = maxLineWidth + strokeWidth; + if (style.dropShadow) { + width += style.dropShadow.distance; + } + const lineHeight = style.lineHeight || fontProperties.fontSize + strokeWidth; + let height = Math.max(lineHeight, fontProperties.fontSize + strokeWidth * 2) + (lines.length - 1) * (lineHeight + style.leading); + if (style.dropShadow) { + height += style.dropShadow.distance; + } + const measurements = new _CanvasTextMetrics( + text, + style, + width, + height, + lines, + lineWidths, + lineHeight + style.leading, + maxLineWidth, + fontProperties + ); + return measurements; + } + static _measureText(text, letterSpacing, context) { + let useExperimentalLetterSpacing = false; + if (_CanvasTextMetrics.experimentalLetterSpacingSupported) { + if (_CanvasTextMetrics.experimentalLetterSpacing) { + context.letterSpacing = `${letterSpacing}px`; + context.textLetterSpacing = `${letterSpacing}px`; + useExperimentalLetterSpacing = true; + } else { + context.letterSpacing = "0px"; + context.textLetterSpacing = "0px"; + } + } + let width = context.measureText(text).width; + if (width > 0) { + if (useExperimentalLetterSpacing) { + width -= letterSpacing; + } else { + width += (_CanvasTextMetrics.graphemeSegmenter(text).length - 1) * letterSpacing; + } + } + return width; + } + /** + * Applies newlines to a string to have it optimally fit into the horizontal + * bounds set by the Text object's wordWrapWidth property. + * @param text - String to apply word wrapping to + * @param style - the style to use when wrapping + * @param canvas - optional specification of the canvas to use for measuring. + * @returns New string with new lines applied where required + */ + static _wordWrap(text, style, canvas = _CanvasTextMetrics._canvas) { + const context = canvas.getContext("2d", contextSettings); + let width = 0; + let line = ""; + let lines = ""; + const cache = /* @__PURE__ */ Object.create(null); + const { letterSpacing, whiteSpace } = style; + const collapseSpaces = _CanvasTextMetrics._collapseSpaces(whiteSpace); + const collapseNewlines = _CanvasTextMetrics._collapseNewlines(whiteSpace); + let canPrependSpaces = !collapseSpaces; + const wordWrapWidth = style.wordWrapWidth + letterSpacing; + const tokens = _CanvasTextMetrics._tokenize(text); + for (let i = 0; i < tokens.length; i++) { + let token = tokens[i]; + if (_CanvasTextMetrics._isNewline(token)) { + if (!collapseNewlines) { + lines += _CanvasTextMetrics._addLine(line); + canPrependSpaces = !collapseSpaces; + line = ""; + width = 0; + continue; + } + token = " "; + } + if (collapseSpaces) { + const currIsBreakingSpace = _CanvasTextMetrics.isBreakingSpace(token); + const lastIsBreakingSpace = _CanvasTextMetrics.isBreakingSpace(line[line.length - 1]); + if (currIsBreakingSpace && lastIsBreakingSpace) { + continue; + } + } + const tokenWidth = _CanvasTextMetrics._getFromCache(token, letterSpacing, cache, context); + if (tokenWidth > wordWrapWidth) { + if (line !== "") { + lines += _CanvasTextMetrics._addLine(line); + line = ""; + width = 0; + } + if (_CanvasTextMetrics.canBreakWords(token, style.breakWords)) { + const characters = _CanvasTextMetrics.wordWrapSplit(token); + for (let j = 0; j < characters.length; j++) { + let char = characters[j]; + let lastChar = char; + let k = 1; + while (characters[j + k]) { + const nextChar = characters[j + k]; + if (!_CanvasTextMetrics.canBreakChars(lastChar, nextChar, token, j, style.breakWords)) { + char += nextChar; + } else { + break; + } + lastChar = nextChar; + k++; + } + j += k - 1; + const characterWidth = _CanvasTextMetrics._getFromCache(char, letterSpacing, cache, context); + if (characterWidth + width > wordWrapWidth) { + lines += _CanvasTextMetrics._addLine(line); + canPrependSpaces = false; + line = ""; + width = 0; + } + line += char; + width += characterWidth; + } + } else { + if (line.length > 0) { + lines += _CanvasTextMetrics._addLine(line); + line = ""; + width = 0; + } + const isLastToken = i === tokens.length - 1; + lines += _CanvasTextMetrics._addLine(token, !isLastToken); + canPrependSpaces = false; + line = ""; + width = 0; + } + } else { + if (tokenWidth + width > wordWrapWidth) { + canPrependSpaces = false; + lines += _CanvasTextMetrics._addLine(line); + line = ""; + width = 0; + } + if (line.length > 0 || !_CanvasTextMetrics.isBreakingSpace(token) || canPrependSpaces) { + line += token; + width += tokenWidth; + } + } + } + lines += _CanvasTextMetrics._addLine(line, false); + return lines; + } + /** + * Convienience function for logging each line added during the wordWrap method. + * @param line - The line of text to add + * @param newLine - Add new line character to end + * @returns A formatted line + */ + static _addLine(line, newLine = true) { + line = _CanvasTextMetrics._trimRight(line); + line = newLine ? `${line} +` : line; + return line; + } + /** + * Gets & sets the widths of calculated characters in a cache object + * @param key - The key + * @param letterSpacing - The letter spacing + * @param cache - The cache + * @param context - The canvas context + * @returns The from cache. + */ + static _getFromCache(key, letterSpacing, cache, context) { + let width = cache[key]; + if (typeof width !== "number") { + width = _CanvasTextMetrics._measureText(key, letterSpacing, context) + letterSpacing; + cache[key] = width; + } + return width; + } + /** + * Determines whether we should collapse breaking spaces. + * @param whiteSpace - The TextStyle property whiteSpace + * @returns Should collapse + */ + static _collapseSpaces(whiteSpace) { + return whiteSpace === "normal" || whiteSpace === "pre-line"; + } + /** + * Determines whether we should collapse newLine chars. + * @param whiteSpace - The white space + * @returns should collapse + */ + static _collapseNewlines(whiteSpace) { + return whiteSpace === "normal"; + } + /** + * Trims breaking whitespaces from string. + * @param text - The text + * @returns Trimmed string + */ + static _trimRight(text) { + if (typeof text !== "string") { + return ""; + } + for (let i = text.length - 1; i >= 0; i--) { + const char = text[i]; + if (!_CanvasTextMetrics.isBreakingSpace(char)) { + break; + } + text = text.slice(0, -1); + } + return text; + } + /** + * Determines if char is a newline. + * @param char - The character + * @returns True if newline, False otherwise. + */ + static _isNewline(char) { + if (typeof char !== "string") { + return false; + } + return _CanvasTextMetrics._newlines.includes(char.charCodeAt(0)); + } + /** + * Determines if char is a breaking whitespace. + * + * It allows one to determine whether char should be a breaking whitespace + * For example certain characters in CJK langs or numbers. + * It must return a boolean. + * @param char - The character + * @param [_nextChar] - The next character + * @returns True if whitespace, False otherwise. + */ + static isBreakingSpace(char, _nextChar) { + if (typeof char !== "string") { + return false; + } + return _CanvasTextMetrics._breakingSpaces.includes(char.charCodeAt(0)); + } + /** + * Splits a string into words, breaking-spaces and newLine characters + * @param text - The text + * @returns A tokenized array + */ + static _tokenize(text) { + const tokens = []; + let token = ""; + if (typeof text !== "string") { + return tokens; + } + for (let i = 0; i < text.length; i++) { + const char = text[i]; + const nextChar = text[i + 1]; + if (_CanvasTextMetrics.isBreakingSpace(char, nextChar) || _CanvasTextMetrics._isNewline(char)) { + if (token !== "") { + tokens.push(token); + token = ""; + } + tokens.push(char); + continue; + } + token += char; + } + if (token !== "") { + tokens.push(token); + } + return tokens; + } + /** + * Overridable helper method used internally by TextMetrics, exposed to allow customizing the class's behavior. + * + * It allows one to customise which words should break + * Examples are if the token is CJK or numbers. + * It must return a boolean. + * @param _token - The token + * @param breakWords - The style attr break words + * @returns Whether to break word or not + */ + static canBreakWords(_token, breakWords) { + return breakWords; + } + /** + * Overridable helper method used internally by TextMetrics, exposed to allow customizing the class's behavior. + * + * It allows one to determine whether a pair of characters + * should be broken by newlines + * For example certain characters in CJK langs or numbers. + * It must return a boolean. + * @param _char - The character + * @param _nextChar - The next character + * @param _token - The token/word the characters are from + * @param _index - The index in the token of the char + * @param _breakWords - The style attr break words + * @returns whether to break word or not + */ + static canBreakChars(_char, _nextChar, _token, _index, _breakWords) { + return true; + } + /** + * Overridable helper method used internally by TextMetrics, exposed to allow customizing the class's behavior. + * + * It is called when a token (usually a word) has to be split into separate pieces + * in order to determine the point to break a word. + * It must return an array of characters. + * @param token - The token to split + * @returns The characters of the token + * @see CanvasTextMetrics.graphemeSegmenter + */ + static wordWrapSplit(token) { + return _CanvasTextMetrics.graphemeSegmenter(token); + } + /** + * Calculates the ascent, descent and fontSize of a given font-style + * @param font - String representing the style of the font + * @returns Font properties object + */ + static measureFont(font) { + if (_CanvasTextMetrics._fonts[font]) { + return _CanvasTextMetrics._fonts[font]; + } + const context = _CanvasTextMetrics._context; + context.font = font; + const metrics = context.measureText(_CanvasTextMetrics.METRICS_STRING + _CanvasTextMetrics.BASELINE_SYMBOL); + const properties = { + ascent: metrics.actualBoundingBoxAscent, + descent: metrics.actualBoundingBoxDescent, + fontSize: metrics.actualBoundingBoxAscent + metrics.actualBoundingBoxDescent + }; + _CanvasTextMetrics._fonts[font] = properties; + return properties; + } + /** + * Clear font metrics in metrics cache. + * @param {string} [font] - font name. If font name not set then clear cache for all fonts. + */ + static clearMetrics(font = "") { + if (font) { + delete _CanvasTextMetrics._fonts[font]; + } else { + _CanvasTextMetrics._fonts = {}; + } + } + /** + * Cached canvas element for measuring text + * TODO: this should be private, but isn't because of backward compat, will fix later. + * @ignore + */ + static get _canvas() { + if (!_CanvasTextMetrics.__canvas) { + let canvas; + try { + const c = new OffscreenCanvas(0, 0); + const context = c.getContext("2d", contextSettings); + if (context == null ? void 0 : context.measureText) { + _CanvasTextMetrics.__canvas = c; + return c; + } + canvas = DOMAdapter.get().createCanvas(); + } catch (ex) { + canvas = DOMAdapter.get().createCanvas(); + } + canvas.width = canvas.height = 10; + _CanvasTextMetrics.__canvas = canvas; + } + return _CanvasTextMetrics.__canvas; + } + /** + * TODO: this should be private, but isn't because of backward compat, will fix later. + * @ignore + */ + static get _context() { + if (!_CanvasTextMetrics.__context) { + _CanvasTextMetrics.__context = _CanvasTextMetrics._canvas.getContext("2d", contextSettings); + } + return _CanvasTextMetrics.__context; + } +}; +/** + * String used for calculate font metrics. + * These characters are all tall to help calculate the height required for text. + */ +_CanvasTextMetrics.METRICS_STRING = "|\xC9q\xC5"; +/** Baseline symbol for calculate font metrics. */ +_CanvasTextMetrics.BASELINE_SYMBOL = "M"; +/** Baseline multiplier for calculate font metrics. */ +_CanvasTextMetrics.BASELINE_MULTIPLIER = 1.4; +/** Height multiplier for setting height of canvas to calculate font metrics. */ +_CanvasTextMetrics.HEIGHT_MULTIPLIER = 2; +/** + * A Unicode "character", or "grapheme cluster", can be composed of multiple Unicode code points, + * such as letters with diacritical marks (e.g. `'\u0065\u0301'`, letter e with acute) + * or emojis with modifiers (e.g. `'\uD83E\uDDD1\u200D\uD83D\uDCBB'`, technologist). + * The new `Intl.Segmenter` API in ES2022 can split the string into grapheme clusters correctly. If it is not available, + * PixiJS will fallback to use the iterator of String, which can only spilt the string into code points. + * If you want to get full functionality in environments that don't support `Intl.Segmenter` (such as Firefox), + * you can use other libraries such as [grapheme-splitter]{@link https://www.npmjs.com/package/grapheme-splitter} + * or [graphemer]{@link https://www.npmjs.com/package/graphemer} to create a polyfill. Since these libraries can be + * relatively large in size to handle various Unicode grapheme clusters properly, PixiJS won't use them directly. + */ +_CanvasTextMetrics.graphemeSegmenter = (() => { + if (typeof (Intl == null ? void 0 : Intl.Segmenter) === "function") { + const segmenter = new Intl.Segmenter(); + return (s) => [...segmenter.segment(s)].map((x) => x.segment); + } + return (s) => [...s]; +})(); +/** + * New rendering behavior for letter-spacing which uses Chrome's new native API. This will + * lead to more accurate letter-spacing results because it does not try to manually draw + * each character. However, this Chrome API is experimental and may not serve all cases yet. + * @see TextMetrics.experimentalLetterSpacingSupported + */ +_CanvasTextMetrics.experimentalLetterSpacing = false; +/** Cache of {@see TextMetrics.FontMetrics} objects. */ +_CanvasTextMetrics._fonts = {}; +/** Cache of new line chars. */ +_CanvasTextMetrics._newlines = [ + 10, + // line feed + 13 + // carriage return +]; +/** Cache of breaking spaces. */ +_CanvasTextMetrics._breakingSpaces = [ + 9, + // character tabulation + 32, + // space + 8192, + // en quad + 8193, + // em quad + 8194, + // en space + 8195, + // em space + 8196, + // three-per-em space + 8197, + // four-per-em space + 8198, + // six-per-em space + 8200, + // punctuation space + 8201, + // thin space + 8202, + // hair space + 8287, + // medium mathematical space + 12288 + // ideographic space +]; +_CanvasTextMetrics._measurementCache = {}; +let CanvasTextMetrics = _CanvasTextMetrics; + +"use strict"; +const _FillGradient = class _FillGradient { + constructor(x0, y0, x1, y1) { + this.uid = uid("fillGradient"); + this.type = "linear"; + this.gradientStops = []; + this.x0 = x0; + this.y0 = y0; + this.x1 = x1; + this.y1 = y1; + } + addColorStop(offset, color) { + this.gradientStops.push({ offset, color: Color.shared.setValue(color).toHex() }); + return this; + } + // TODO move to the system! + buildLinearGradient() { + const defaultSize = _FillGradient.defaultTextureSize; + const { gradientStops } = this; + const canvas = DOMAdapter.get().createCanvas(); + canvas.width = defaultSize; + canvas.height = defaultSize; + const ctx = canvas.getContext("2d"); + const gradient = ctx.createLinearGradient(0, 0, _FillGradient.defaultTextureSize, 1); + for (let i = 0; i < gradientStops.length; i++) { + const stop = gradientStops[i]; + gradient.addColorStop(stop.offset, stop.color); + } + ctx.fillStyle = gradient; + ctx.fillRect(0, 0, defaultSize, defaultSize); + this.texture = new Texture({ + source: new ImageSource({ + resource: canvas, + addressModeU: "clamp-to-edge", + addressModeV: "repeat" + }) + }); + const { x0, y0, x1, y1 } = this; + const m = new Matrix(); + const dx = x1 - x0; + const dy = y1 - y0; + const dist = Math.sqrt(dx * dx + dy * dy); + const angle = Math.atan2(dy, dx); + m.translate(-x0, -y0); + m.scale(1 / defaultSize, 1 / defaultSize); + m.rotate(-angle); + m.scale(256 / dist, 1); + this.transform = m; + } +}; +_FillGradient.defaultTextureSize = 256; +let FillGradient = _FillGradient; + +"use strict"; +const repetitionMap = { + repeat: { + addressModeU: "repeat", + addressModeV: "repeat" + }, + "repeat-x": { + addressModeU: "repeat", + addressModeV: "clamp-to-edge" + }, + "repeat-y": { + addressModeU: "clamp-to-edge", + addressModeV: "repeat" + }, + "no-repeat": { + addressModeU: "clamp-to-edge", + addressModeV: "clamp-to-edge" + } +}; +class FillPattern { + constructor(texture, repetition) { + this.uid = uid("fillPattern"); + this.transform = new Matrix(); + this.texture = texture; + this.transform.scale( + 1 / texture.frame.width, + 1 / texture.frame.height + ); + if (repetition) { + texture.source.style.addressModeU = repetitionMap[repetition].addressModeU; + texture.source.style.addressModeV = repetitionMap[repetition].addressModeV; + } + } + setTransform(transform) { + const texture = this.texture; + this.transform.copyFrom(transform); + this.transform.invert(); + this.transform.scale( + 1 / texture.frame.width, + 1 / texture.frame.height + ); + } +} + +"use strict"; +function getCanvasFillStyle(fillStyle, context) { + if (fillStyle.texture === Texture.WHITE && !fillStyle.fill) { + return Color.shared.setValue(fillStyle.color).toHex(); + } else if (!fillStyle.fill) { + const pattern = context.createPattern(fillStyle.texture.source.resource, "repeat"); + const tempMatrix = fillStyle.matrix.copyTo(Matrix.shared); + tempMatrix.scale(fillStyle.texture.frame.width, fillStyle.texture.frame.height); + pattern.setTransform(tempMatrix); + return pattern; + } else if (fillStyle.fill instanceof FillPattern) { + const fillPattern = fillStyle.fill; + const pattern = context.createPattern(fillPattern.texture.source.resource, "repeat"); + const tempMatrix = fillPattern.transform.copyTo(Matrix.shared); + tempMatrix.scale( + fillPattern.texture.frame.width, + fillPattern.texture.frame.height + ); + pattern.setTransform(tempMatrix); + return pattern; + } else if (fillStyle.fill instanceof FillGradient) { + const fillGradient = fillStyle.fill; + if (fillGradient.type === "linear") { + const gradient = context.createLinearGradient( + fillGradient.x0, + fillGradient.y0, + fillGradient.x1, + fillGradient.y1 + ); + fillGradient.gradientStops.forEach((stop) => { + gradient.addColorStop(stop.offset, Color.shared.setValue(stop.color).toHex()); + }); + return gradient; + } + } + warn("FillStyle not recognised", fillStyle); + return "red"; +} + +"use strict"; +class CanvasTextSystem { + constructor() { + this._activeTextures = {}; + } + getTextureSize(text, resolution, style) { + const measured = CanvasTextMetrics.measureText(text || " ", style); + let width = Math.ceil(Math.ceil(Math.max(1, measured.width) + style.padding * 2) * resolution); + let height = Math.ceil(Math.ceil(Math.max(1, measured.height) + style.padding * 2) * resolution); + width = Math.ceil(width - 1e-6); + height = Math.ceil(height - 1e-6); + width = nextPow2(width); + height = nextPow2(height); + return { width, height }; + } + getTexture(text, resolution, style, textKey) { + if (this._activeTextures[textKey]) { + this._increaseReferenceCount(textKey); + return this._activeTextures[textKey].texture; + } + const measured = CanvasTextMetrics.measureText(text || " ", style); + const width = Math.ceil(Math.ceil(Math.max(1, measured.width) + style.padding * 2) * resolution); + const height = Math.ceil(Math.ceil(Math.max(1, measured.height) + style.padding * 2) * resolution); + const canvasAndContext = CanvasPool.getOptimalCanvasAndContext(width, height); + const { canvas } = canvasAndContext; + this.renderTextToCanvas(text, style, resolution, canvasAndContext); + const texture = getPo2TextureFromSource(canvas, width, height, resolution); + if (style.trim) { + const trimmed = getCanvasBoundingBox(canvas, resolution); + texture.frame.copyFrom(trimmed); + texture.updateUvs(); + } + this._activeTextures[textKey] = { + canvasAndContext, + texture, + usageCount: 1 + }; + return texture; + } + _increaseReferenceCount(textKey) { + this._activeTextures[textKey].usageCount++; + } + decreaseReferenceCount(textKey) { + const activeTexture = this._activeTextures[textKey]; + activeTexture.usageCount--; + if (activeTexture.usageCount === 0) { + CanvasPool.returnCanvasAndContext(activeTexture.canvasAndContext); + TexturePool.returnTexture(activeTexture.texture); + const source = activeTexture.texture.source; + source.resource = null; + source.uploadMethodId = "unknown"; + source.alphaMode = "no-premultiply-alpha"; + this._activeTextures[textKey] = null; + } + } + getReferenceCount(textKey) { + return this._activeTextures[textKey].usageCount; + } + /** + * Renders text to its canvas, and updates its texture. + * + * By default this is used internally to ensure the texture is correct before rendering, + * but it can be used called externally, for example from this class to 'pre-generate' the texture from a piece of text, + * and then shared across multiple Sprites. + * @param text + * @param style + * @param resolution + * @param canvasAndContext + */ + renderTextToCanvas(text, style, resolution, canvasAndContext) { + var _a, _b, _c, _d, _e, _f; + const { canvas, context } = canvasAndContext; + const font = fontStringFromTextStyle(style); + const measured = CanvasTextMetrics.measureText(text || " ", style); + const lines = measured.lines; + const lineHeight = measured.lineHeight; + const lineWidths = measured.lineWidths; + const maxLineWidth = measured.maxLineWidth; + const fontProperties = measured.fontProperties; + const height = canvas.height; + context.resetTransform(); + context.scale(resolution, resolution); + context.clearRect(0, 0, measured.width + 4, measured.height + 4); + if ((_a = style._stroke) == null ? void 0 : _a.width) { + const strokeStyle = style._stroke; + context.lineWidth = strokeStyle.width; + context.miterLimit = strokeStyle.miterLimit; + context.lineJoin = strokeStyle.join; + context.lineCap = strokeStyle.cap; + } + context.font = font; + let linePositionX; + let linePositionY; + const passesCount = style.dropShadow ? 2 : 1; + for (let i = 0; i < passesCount; ++i) { + const isShadowPass = style.dropShadow && i === 0; + const dsOffsetText = isShadowPass ? Math.ceil(Math.max(1, height) + style.padding * 2) : 0; + const dsOffsetShadow = dsOffsetText * resolution; + if (isShadowPass) { + context.fillStyle = "black"; + context.strokeStyle = "black"; + const shadowOptions = style.dropShadow; + const dropShadowColor = shadowOptions.color; + const dropShadowAlpha = shadowOptions.alpha; + context.shadowColor = Color.shared.setValue(dropShadowColor).setAlpha(dropShadowAlpha).toRgbaString(); + const dropShadowBlur = shadowOptions.blur * resolution; + const dropShadowDistance = shadowOptions.distance * resolution; + context.shadowBlur = dropShadowBlur; + context.shadowOffsetX = Math.cos(shadowOptions.angle) * dropShadowDistance; + context.shadowOffsetY = Math.sin(shadowOptions.angle) * dropShadowDistance + dsOffsetShadow; + } else { + context.globalAlpha = (_c = (_b = style._fill) == null ? void 0 : _b.alpha) != null ? _c : 1; + context.fillStyle = style._fill ? getCanvasFillStyle(style._fill, context) : null; + if ((_d = style._stroke) == null ? void 0 : _d.width) { + context.strokeStyle = getCanvasFillStyle(style._stroke, context); + } + context.shadowColor = "black"; + } + let linePositionYShift = (lineHeight - fontProperties.fontSize) / 2; + if (lineHeight - fontProperties.fontSize < 0) { + linePositionYShift = 0; + } + const strokeWidth = (_f = (_e = style._stroke) == null ? void 0 : _e.width) != null ? _f : 0; + for (let i2 = 0; i2 < lines.length; i2++) { + linePositionX = strokeWidth / 2; + linePositionY = strokeWidth / 2 + i2 * lineHeight + fontProperties.ascent + linePositionYShift; + if (style.align === "right") { + linePositionX += maxLineWidth - lineWidths[i2]; + } else if (style.align === "center") { + linePositionX += (maxLineWidth - lineWidths[i2]) / 2; + } + if (style._stroke) { + this._drawLetterSpacing( + lines[i2], + style, + canvasAndContext, + linePositionX + style.padding, + linePositionY + style.padding - dsOffsetText, + true + ); + } + if (style._fill !== void 0) { + this._drawLetterSpacing( + lines[i2], + style, + canvasAndContext, + linePositionX + style.padding, + linePositionY + style.padding - dsOffsetText + ); + } + } + } + } + /** + * Render the text with letter-spacing. + * @param text - The text to draw + * @param style + * @param canvasAndContext + * @param x - Horizontal position to draw the text + * @param y - Vertical position to draw the text + * @param isStroke - Is this drawing for the outside stroke of the + * text? If not, it's for the inside fill + */ + _drawLetterSpacing(text, style, canvasAndContext, x, y, isStroke = false) { + const { context } = canvasAndContext; + const letterSpacing = style.letterSpacing; + let useExperimentalLetterSpacing = false; + if (CanvasTextMetrics.experimentalLetterSpacingSupported) { + if (CanvasTextMetrics.experimentalLetterSpacing) { + context.letterSpacing = `${letterSpacing}px`; + context.textLetterSpacing = `${letterSpacing}px`; + useExperimentalLetterSpacing = true; + } else { + context.letterSpacing = "0px"; + context.textLetterSpacing = "0px"; + } + } + if (letterSpacing === 0 || useExperimentalLetterSpacing) { + if (isStroke) { + context.strokeText(text, x, y); + } else { + context.fillText(text, x, y); + } + return; + } + let currentPosition = x; + const stringArray = CanvasTextMetrics.graphemeSegmenter(text); + let previousWidth = context.measureText(text).width; + let currentWidth = 0; + for (let i = 0; i < stringArray.length; ++i) { + const currentChar = stringArray[i]; + if (isStroke) { + context.strokeText(currentChar, currentPosition, y); + } else { + context.fillText(currentChar, currentPosition, y); + } + let textStr = ""; + for (let j = i + 1; j < stringArray.length; ++j) { + textStr += stringArray[j]; + } + currentWidth = context.measureText(textStr).width; + currentPosition += previousWidth - currentWidth + letterSpacing; + previousWidth = currentWidth; + } + } + destroy() { + this._activeTextures = null; + } +} +/** @ignore */ +CanvasTextSystem.extension = { + type: [ + ExtensionType.WebGLSystem, + ExtensionType.WebGPUSystem, + ExtensionType.CanvasSystem + ], + name: "canvasText" +}; + +"use strict"; +extensions.add(CanvasTextSystem); +extensions.add(CanvasTextPipe); + +"use strict"; +class AbstractBitmapFont extends EventEmitter { + constructor() { + super(...arguments); + /** The map of characters by character code. */ + this.chars = /* @__PURE__ */ Object.create(null); + /** + * The line-height of the font face in pixels. + * @type {number} + */ + this.lineHeight = 0; + /** + * The name of the font face + * @type {string} + */ + this.fontFamily = ""; + /** The metrics of the font face. */ + this.fontMetrics = { fontSize: 0, ascent: 0, descent: 0 }; + /** + * The offset of the font face from the baseline. + * @type {number} + */ + this.baseLineOffset = 0; + /** The range and type of the distance field for this font. */ + this.distanceField = { type: "none", range: 0 }; + /** The map of base page textures (i.e., sheets of glyphs). */ + this.pages = []; + /** The size of the font face in pixels. */ + this.baseMeasurementFontSize = 100; + this.baseRenderedFontSize = 100; + } + /** + * The name of the font face. + * @deprecated since 8.0.0 Use `fontFamily` instead. + */ + get font() { + deprecation(v8_0_0, "BitmapFont.font is deprecated, please use BitmapFont.fontFamily instead."); + return this.fontFamily; + } + /** + * The map of base page textures (i.e., sheets of glyphs). + * @deprecated since 8.0.0 Use `pages` instead. + */ + get pageTextures() { + deprecation(v8_0_0, "BitmapFont.pageTextures is deprecated, please use BitmapFont.pages instead."); + return this.pages; + } + /** + * The size of the font face in pixels. + * @deprecated since 8.0.0 Use `fontMetrics.fontSize` instead. + */ + get size() { + deprecation(v8_0_0, "BitmapFont.size is deprecated, please use BitmapFont.fontMetrics.fontSize instead."); + return this.fontMetrics.fontSize; + } + /** + * The kind of distance field for this font or "none". + * @deprecated since 8.0.0 Use `distanceField.type` instead. + */ + get distanceFieldRange() { + deprecation(v8_0_0, "BitmapFont.distanceFieldRange is deprecated, please use BitmapFont.distanceField.range instead."); + return this.distanceField.range; + } + /** + * The range of the distance field in pixels. + * @deprecated since 8.0.0 Use `distanceField.range` instead. + */ + get distanceFieldType() { + deprecation(v8_0_0, "BitmapFont.distanceFieldType is deprecated, please use BitmapFont.distanceField.type instead."); + return this.distanceField.type; + } + destroy(destroyTextures = false) { + this.emit("destroy", this); + this.removeAllListeners(); + for (const i in this.chars) { + this.chars[i].texture.destroy(); + } + this.chars = null; + if (destroyTextures) { + this.pages.forEach((page) => page.texture.destroy(true)); + this.pages = null; + } + } +} + +var parseSvgPath = parse; + +/** + * expected argument lengths + * @type {Object} + */ + +var length = {a: 7, c: 6, h: 1, l: 2, m: 2, q: 4, s: 4, t: 2, v: 1, z: 0}; + +/** + * segment pattern + * @type {RegExp} + */ + +var segment = /([astvzqmhlc])([^astvzqmhlc]*)/ig; + +/** + * parse an svg path data string. Generates an Array + * of commands where each command is an Array of the + * form `[command, arg1, arg2, ...]` + * + * @param {String} path + * @return {Array} + */ + +function parse(path) { + var data = []; + path.replace(segment, function(_, command, args){ + var type = command.toLowerCase(); + args = parseValues(args); + + // overloaded moveTo + if (type == 'm' && args.length > 2) { + data.push([command].concat(args.splice(0, 2))); + type = 'l'; + command = command == 'm' ? 'l' : 'L'; + } + + while (true) { + if (args.length == length[type]) { + args.unshift(command); + return data.push(args) + } + if (args.length < length[type]) throw new Error('malformed path data') + data.push([command].concat(args.splice(0, length[type]))); + } + }); + return data +} + +var number = /-?[0-9]*\.?[0-9]+(?:e[-+]?\d+)?/ig; + +function parseValues(args) { + var numbers = args.match(number); + return numbers ? numbers.map(Number) : [] +} + +var parse$1 = /*@__PURE__*/getDefaultExportFromCjs(parseSvgPath); + +"use strict"; +function SVGToGraphicsPath(svgPath, path) { + const commands = parse$1(svgPath); + const subpaths = []; + let currentSubPath = null; + let lastX = 0; + let lastY = 0; + for (let i = 0; i < commands.length; i++) { + const command = commands[i]; + const type = command[0]; + const data = command; + switch (type) { + case "M": + lastX = data[1]; + lastY = data[2]; + path.moveTo(lastX, lastY); + break; + case "m": + lastX += data[1]; + lastY += data[2]; + path.moveTo(lastX, lastY); + break; + case "H": + lastX = data[1]; + path.lineTo(lastX, lastY); + break; + case "h": + lastX += data[1]; + path.lineTo(lastX, lastY); + break; + case "V": + lastY = data[1]; + path.lineTo(lastX, lastY); + break; + case "v": + lastY += data[1]; + path.lineTo(lastX, lastY); + break; + case "L": + lastX = data[1]; + lastY = data[2]; + path.lineTo(lastX, lastY); + break; + case "l": + lastX += data[1]; + lastY += data[2]; + path.lineTo(lastX, lastY); + break; + case "C": + lastX = data[5]; + lastY = data[6]; + path.bezierCurveTo( + data[1], + data[2], + data[3], + data[4], + lastX, + lastY + ); + break; + case "c": + path.bezierCurveTo( + lastX + data[1], + lastY + data[2], + lastX + data[3], + lastY + data[4], + lastX + data[5], + lastY + data[6] + ); + lastX += data[5]; + lastY += data[6]; + break; + case "S": + lastX = data[3]; + lastY = data[4]; + path.bezierCurveToShort( + data[1], + data[2], + lastX, + lastY + ); + break; + case "s": + path.bezierCurveToShort( + lastX + data[1], + lastY + data[2], + lastX + data[3], + lastY + data[4] + ); + lastX += data[3]; + lastY += data[4]; + break; + case "Q": + lastX = data[3]; + lastY = data[4]; + path.quadraticCurveTo( + data[1], + data[2], + lastX, + lastY + ); + break; + case "q": + path.quadraticCurveTo( + lastX + data[1], + lastY + data[2], + lastX + data[3], + lastY + data[4] + ); + lastX += data[3]; + lastY += data[4]; + break; + case "T": + lastX = data[1]; + lastY = data[2]; + path.quadraticCurveToShort( + lastX, + lastY + ); + break; + case "t": + lastX += data[1]; + lastY += data[2]; + path.quadraticCurveToShort( + lastX, + lastY + ); + break; + case "A": + lastX = data[6]; + lastY = data[7]; + path.arcToSvg( + data[1], + data[2], + data[3], + data[4], + data[5], + lastX, + lastY + ); + break; + case "a": + lastX += data[6]; + lastY += data[7]; + path.arcToSvg( + data[1], + data[2], + data[3], + data[4], + data[5], + lastX, + lastY + ); + break; + case "Z": + case "z": + path.closePath(); + if (subpaths.length > 0) { + currentSubPath = subpaths.pop(); + if (currentSubPath) { + lastX = currentSubPath.startX; + lastY = currentSubPath.startY; + } else { + lastX = 0; + lastY = 0; + } + } + currentSubPath = null; + break; + default: + warn(`Unknown SVG path command: ${type}`); + } + if (type !== "Z" && type !== "z") { + if (currentSubPath === null) { + currentSubPath = { startX: lastX, startY: lastY }; + subpaths.push(currentSubPath); + } + } + } + return path; +} + +"use strict"; +class Circle { + /** + * @param x - The X coordinate of the center of this circle + * @param y - The Y coordinate of the center of this circle + * @param radius - The radius of the circle + */ + constructor(x = 0, y = 0, radius = 0) { + /** + * The type of the object, mainly used to avoid `instanceof` checks + * @default 'circle' + */ + this.type = "circle"; + this.x = x; + this.y = y; + this.radius = radius; + } + /** + * Creates a clone of this Circle instance + * @returns A copy of the Circle + */ + clone() { + return new Circle(this.x, this.y, this.radius); + } + /** + * Checks whether the x and y coordinates given are contained within this circle + * @param x - The X coordinate of the point to test + * @param y - The Y coordinate of the point to test + * @returns Whether the x/y coordinates are within this Circle + */ + contains(x, y) { + if (this.radius <= 0) + return false; + const r2 = this.radius * this.radius; + let dx = this.x - x; + let dy = this.y - y; + dx *= dx; + dy *= dy; + return dx + dy <= r2; + } + /** + * Checks whether the x and y coordinates given are contained within this circle including the stroke. + * @param x - The X coordinate of the point to test + * @param y - The Y coordinate of the point to test + * @param width - The width of the line to check + * @returns Whether the x/y coordinates are within this Circle + */ + strokeContains(x, y, width) { + if (this.radius === 0) + return false; + const dx = this.x - x; + const dy = this.y - y; + const r = this.radius; + const w2 = width / 2; + const distance = Math.sqrt(dx * dx + dy * dy); + return distance < r + w2 && distance > r - w2; + } + /** + * Returns the framing rectangle of the circle as a Rectangle object + * @param out + * @returns The framing rectangle + */ + getBounds(out) { + out = out || new Rectangle(); + out.x = this.x - this.radius; + out.y = this.y - this.radius; + out.width = this.radius * 2; + out.height = this.radius * 2; + return out; + } + /** + * Copies another circle to this one. + * @param circle - The circle to copy from. + * @returns Returns itself. + */ + copyFrom(circle) { + this.x = circle.x; + this.y = circle.y; + this.radius = circle.radius; + return this; + } + /** + * Copies this circle to another one. + * @param circle - The circle to copy to. + * @returns Returns given parameter. + */ + copyTo(circle) { + circle.copyFrom(this); + return circle; + } + toString() { + return `[pixi.js/math:Circle x=${this.x} y=${this.y} radius=${this.radius}]`; + } +} + +"use strict"; +class Ellipse { + /** + * @param x - The X coordinate of the center of this ellipse + * @param y - The Y coordinate of the center of this ellipse + * @param halfWidth - The half width of this ellipse + * @param halfHeight - The half height of this ellipse + */ + constructor(x = 0, y = 0, halfWidth = 0, halfHeight = 0) { + /** + * The type of the object, mainly used to avoid `instanceof` checks + * @default 'ellipse' + */ + this.type = "ellipse"; + this.x = x; + this.y = y; + this.halfWidth = halfWidth; + this.halfHeight = halfHeight; + } + /** + * Creates a clone of this Ellipse instance + * @returns {Ellipse} A copy of the ellipse + */ + clone() { + return new Ellipse(this.x, this.y, this.halfWidth, this.halfHeight); + } + /** + * Checks whether the x and y coordinates given are contained within this ellipse + * @param x - The X coordinate of the point to test + * @param y - The Y coordinate of the point to test + * @returns Whether the x/y coords are within this ellipse + */ + contains(x, y) { + if (this.halfWidth <= 0 || this.halfHeight <= 0) { + return false; + } + let normx = (x - this.x) / this.halfWidth; + let normy = (y - this.y) / this.halfHeight; + normx *= normx; + normy *= normy; + return normx + normy <= 1; + } + /** + * Checks whether the x and y coordinates given are contained within this ellipse including stroke + * @param x - The X coordinate of the point to test + * @param y - The Y coordinate of the point to test + * @param width + * @returns Whether the x/y coords are within this ellipse + */ + strokeContains(x, y, width) { + const { halfWidth, halfHeight } = this; + if (halfWidth <= 0 || halfHeight <= 0) { + return false; + } + const halfStrokeWidth = width / 2; + const innerA = halfWidth - halfStrokeWidth; + const innerB = halfHeight - halfStrokeWidth; + const outerA = halfWidth + halfStrokeWidth; + const outerB = halfHeight + halfStrokeWidth; + const normalizedX = x - this.x; + const normalizedY = y - this.y; + const innerEllipse = normalizedX * normalizedX / (innerA * innerA) + normalizedY * normalizedY / (innerB * innerB); + const outerEllipse = normalizedX * normalizedX / (outerA * outerA) + normalizedY * normalizedY / (outerB * outerB); + return innerEllipse > 1 && outerEllipse <= 1; + } + /** + * Returns the framing rectangle of the ellipse as a Rectangle object + * @returns The framing rectangle + */ + getBounds() { + return new Rectangle(this.x - this.halfWidth, this.y - this.halfHeight, this.halfWidth * 2, this.halfHeight * 2); + } + /** + * Copies another ellipse to this one. + * @param ellipse - The ellipse to copy from. + * @returns Returns itself. + */ + copyFrom(ellipse) { + this.x = ellipse.x; + this.y = ellipse.y; + this.halfWidth = ellipse.halfWidth; + this.halfHeight = ellipse.halfHeight; + return this; + } + /** + * Copies this ellipse to another one. + * @param ellipse - The ellipse to copy to. + * @returns Returns given parameter. + */ + copyTo(ellipse) { + ellipse.copyFrom(this); + return ellipse; + } + toString() { + return `[pixi.js/math:Ellipse x=${this.x} y=${this.y} halfWidth=${this.halfWidth} halfHeight=${this.halfHeight}]`; + } +} + +"use strict"; +function squaredDistanceToLineSegment(x, y, x1, y1, x2, y2) { + const a = x - x1; + const b = y - y1; + const c = x2 - x1; + const d = y2 - y1; + const dot = a * c + b * d; + const lenSq = c * c + d * d; + let param = -1; + if (lenSq !== 0) { + param = dot / lenSq; + } + let xx; + let yy; + if (param < 0) { + xx = x1; + yy = y1; + } else if (param > 1) { + xx = x2; + yy = y2; + } else { + xx = x1 + param * c; + yy = y1 + param * d; + } + const dx = x - xx; + const dy = y - yy; + return dx * dx + dy * dy; +} + +"use strict"; +class Polygon { + /** + * @param points - This can be an array of Points + * that form the polygon, a flat array of numbers that will be interpreted as [x,y, x,y, ...], or + * the arguments passed can be all the points of the polygon e.g. + * `new Polygon(new Point(), new Point(), ...)`, or the arguments passed can be flat + * x,y values e.g. `new Polygon(x,y, x,y, x,y, ...)` where `x` and `y` are Numbers. + */ + constructor(...points) { + /** + * The type of the object, mainly used to avoid `instanceof` checks + * @default 'polygon' + */ + this.type = "polygon"; + let flat = Array.isArray(points[0]) ? points[0] : points; + if (typeof flat[0] !== "number") { + const p = []; + for (let i = 0, il = flat.length; i < il; i++) { + p.push(flat[i].x, flat[i].y); + } + flat = p; + } + this.points = flat; + this.closePath = true; + } + /** + * Creates a clone of this polygon. + * @returns - A copy of the polygon. + */ + clone() { + const points = this.points.slice(); + const polygon = new Polygon(points); + polygon.closePath = this.closePath; + return polygon; + } + /** + * Checks whether the x and y coordinates passed to this function are contained within this polygon. + * @param x - The X coordinate of the point to test. + * @param y - The Y coordinate of the point to test. + * @returns - Whether the x/y coordinates are within this polygon. + */ + contains(x, y) { + let inside = false; + const length = this.points.length / 2; + for (let i = 0, j = length - 1; i < length; j = i++) { + const xi = this.points[i * 2]; + const yi = this.points[i * 2 + 1]; + const xj = this.points[j * 2]; + const yj = this.points[j * 2 + 1]; + const intersect = yi > y !== yj > y && x < (xj - xi) * ((y - yi) / (yj - yi)) + xi; + if (intersect) { + inside = !inside; + } + } + return inside; + } + /** + * Checks whether the x and y coordinates given are contained within this polygon including the stroke. + * @param x - The X coordinate of the point to test + * @param y - The Y coordinate of the point to test + * @param strokeWidth - The width of the line to check + * @returns Whether the x/y coordinates are within this polygon + */ + strokeContains(x, y, strokeWidth) { + const halfStrokeWidth = strokeWidth / 2; + const halfStrokeWidthSqrd = halfStrokeWidth * halfStrokeWidth; + const { points } = this; + const iterationLength = points.length - (this.closePath ? 0 : 2); + for (let i = 0; i < iterationLength; i += 2) { + const x1 = points[i]; + const y1 = points[i + 1]; + const x2 = points[(i + 2) % points.length]; + const y2 = points[(i + 3) % points.length]; + const distanceSqrd = squaredDistanceToLineSegment(x, y, x1, y1, x2, y2); + if (distanceSqrd <= halfStrokeWidthSqrd) { + return true; + } + } + return false; + } + /** + * Returns the framing rectangle of the polygon as a Rectangle object + * @param out - optional rectangle to store the result + * @returns The framing rectangle + */ + getBounds(out) { + out = out || new Rectangle(); + const points = this.points; + let minX = Infinity; + let maxX = -Infinity; + let minY = Infinity; + let maxY = -Infinity; + for (let i = 0, n = points.length; i < n; i += 2) { + const x = points[i]; + const y = points[i + 1]; + minX = x < minX ? x : minX; + maxX = x > maxX ? x : maxX; + minY = y < minY ? y : minY; + maxY = y > maxY ? y : maxY; + } + out.x = minX; + out.width = maxX - minX; + out.y = minY; + out.height = maxY - minY; + return out; + } + /** + * Copies another polygon to this one. + * @param polygon - The polygon to copy from. + * @returns Returns itself. + */ + copyFrom(polygon) { + this.points = polygon.points.slice(); + this.closePath = polygon.closePath; + return this; + } + /** + * Copies this polygon to another one. + * @param polygon - The polygon to copy to. + * @returns Returns given parameter. + */ + copyTo(polygon) { + polygon.copyFrom(this); + return polygon; + } + toString() { + return `[pixi.js/math:PolygoncloseStroke=${this.closePath}points=${this.points.reduce((pointsDesc, currentPoint) => `${pointsDesc}, ${currentPoint}`, "")}]`; + } + /** + * Get the last X coordinate of the polygon + * @readonly + */ + get lastX() { + return this.points[this.points.length - 2]; + } + /** + * Get the last Y coordinate of the polygon + * @readonly + */ + get lastY() { + return this.points[this.points.length - 1]; + } + /** + * Get the first X coordinate of the polygon + * @readonly + */ + get x() { + return this.points[this.points.length - 2]; + } + /** + * Get the first Y coordinate of the polygon + * @readonly + */ + get y() { + return this.points[this.points.length - 1]; + } +} + +"use strict"; +const isCornerWithinStroke = (pX, pY, cornerX, cornerY, radius, halfStrokeWidth) => { + const dx = pX - cornerX; + const dy = pY - cornerY; + const distance = Math.sqrt(dx * dx + dy * dy); + return distance >= radius - halfStrokeWidth && distance <= radius + halfStrokeWidth; +}; +class RoundedRectangle { + /** + * @param x - The X coordinate of the upper-left corner of the rounded rectangle + * @param y - The Y coordinate of the upper-left corner of the rounded rectangle + * @param width - The overall width of this rounded rectangle + * @param height - The overall height of this rounded rectangle + * @param radius - Controls the radius of the rounded corners + */ + constructor(x = 0, y = 0, width = 0, height = 0, radius = 20) { + /** + * The type of the object, mainly used to avoid `instanceof` checks + * @default 'roundedRectangle' + */ + this.type = "roundedRectangle"; + this.x = x; + this.y = y; + this.width = width; + this.height = height; + this.radius = radius; + } + /** + * Returns the framing rectangle of the rounded rectangle as a Rectangle object + * @param out - optional rectangle to store the result + * @returns The framing rectangle + */ + getBounds(out) { + out = out || new Rectangle(); + out.x = this.x; + out.y = this.y; + out.width = this.width; + out.height = this.height; + return out; + } + /** + * Creates a clone of this Rounded Rectangle. + * @returns - A copy of the rounded rectangle. + */ + clone() { + return new RoundedRectangle(this.x, this.y, this.width, this.height, this.radius); + } + /** + * Copies another rectangle to this one. + * @param rectangle - The rectangle to copy from. + * @returns Returns itself. + */ + copyFrom(rectangle) { + this.x = rectangle.x; + this.y = rectangle.y; + this.width = rectangle.width; + this.height = rectangle.height; + return this; + } + /** + * Copies this rectangle to another one. + * @param rectangle - The rectangle to copy to. + * @returns Returns given parameter. + */ + copyTo(rectangle) { + rectangle.copyFrom(this); + return rectangle; + } + /** + * Checks whether the x and y coordinates given are contained within this Rounded Rectangle + * @param x - The X coordinate of the point to test. + * @param y - The Y coordinate of the point to test. + * @returns - Whether the x/y coordinates are within this Rounded Rectangle. + */ + contains(x, y) { + if (this.width <= 0 || this.height <= 0) { + return false; + } + if (x >= this.x && x <= this.x + this.width) { + if (y >= this.y && y <= this.y + this.height) { + const radius = Math.max(0, Math.min(this.radius, Math.min(this.width, this.height) / 2)); + if (y >= this.y + radius && y <= this.y + this.height - radius || x >= this.x + radius && x <= this.x + this.width - radius) { + return true; + } + let dx = x - (this.x + radius); + let dy = y - (this.y + radius); + const radius2 = radius * radius; + if (dx * dx + dy * dy <= radius2) { + return true; + } + dx = x - (this.x + this.width - radius); + if (dx * dx + dy * dy <= radius2) { + return true; + } + dy = y - (this.y + this.height - radius); + if (dx * dx + dy * dy <= radius2) { + return true; + } + dx = x - (this.x + radius); + if (dx * dx + dy * dy <= radius2) { + return true; + } + } + } + return false; + } + /** + * Checks whether the x and y coordinates given are contained within this rectangle including the stroke. + * @param pX - The X coordinate of the point to test + * @param pY - The Y coordinate of the point to test + * @param strokeWidth - The width of the line to check + * @returns Whether the x/y coordinates are within this rectangle + */ + strokeContains(pX, pY, strokeWidth) { + const { x, y, width, height, radius } = this; + const halfStrokeWidth = strokeWidth / 2; + const innerX = x + radius; + const innerY = y + radius; + const innerWidth = width - radius * 2; + const innerHeight = height - radius * 2; + const rightBound = x + width; + const bottomBound = y + height; + if ((pX >= x - halfStrokeWidth && pX <= x + halfStrokeWidth || pX >= rightBound - halfStrokeWidth && pX <= rightBound + halfStrokeWidth) && pY >= innerY && pY <= innerY + innerHeight) { + return true; + } + if ((pY >= y - halfStrokeWidth && pY <= y + halfStrokeWidth || pY >= bottomBound - halfStrokeWidth && pY <= bottomBound + halfStrokeWidth) && pX >= innerX && pX <= innerX + innerWidth) { + return true; + } + return ( + // Top-left + pX < innerX && pY < innerY && isCornerWithinStroke(pX, pY, innerX, innerY, radius, halfStrokeWidth) || pX > rightBound - radius && pY < innerY && isCornerWithinStroke(pX, pY, rightBound - radius, innerY, radius, halfStrokeWidth) || pX > rightBound - radius && pY > bottomBound - radius && isCornerWithinStroke(pX, pY, rightBound - radius, bottomBound - radius, radius, halfStrokeWidth) || pX < innerX && pY > bottomBound - radius && isCornerWithinStroke(pX, pY, innerX, bottomBound - radius, radius, halfStrokeWidth) + ); + } + toString() { + return `[pixi.js/math:RoundedRectangle x=${this.x} y=${this.y}width=${this.width} height=${this.height} radius=${this.radius}]`; + } +} + +"use strict"; +const RECURSION_LIMIT$1 = 8; +const FLT_EPSILON$1 = 11920929e-14; +const PATH_DISTANCE_EPSILON$1 = 1; +const curveAngleToleranceEpsilon$1 = 0.01; +const mAngleTolerance$1 = 0; +const mCuspLimit = 0; +function buildAdaptiveBezier(points, sX, sY, cp1x, cp1y, cp2x, cp2y, eX, eY, smoothness) { + const scale = 1; + const smoothing = Math.min( + 0.99, + // a value of 1.0 actually inverts smoothing, so we cap it at 0.99 + Math.max(0, smoothness != null ? smoothness : GraphicsContextSystem.defaultOptions.bezierSmoothness) + ); + let distanceTolerance = (PATH_DISTANCE_EPSILON$1 - smoothing) / scale; + distanceTolerance *= distanceTolerance; + begin$1(sX, sY, cp1x, cp1y, cp2x, cp2y, eX, eY, points, distanceTolerance); + return points; +} +function begin$1(sX, sY, cp1x, cp1y, cp2x, cp2y, eX, eY, points, distanceTolerance) { + recursive$1(sX, sY, cp1x, cp1y, cp2x, cp2y, eX, eY, points, distanceTolerance, 0); + points.push(eX, eY); +} +function recursive$1(x1, y1, x2, y2, x3, y3, x4, y4, points, distanceTolerance, level) { + if (level > RECURSION_LIMIT$1) { + return; + } + const pi = Math.PI; + const x12 = (x1 + x2) / 2; + const y12 = (y1 + y2) / 2; + const x23 = (x2 + x3) / 2; + const y23 = (y2 + y3) / 2; + const x34 = (x3 + x4) / 2; + const y34 = (y3 + y4) / 2; + const x123 = (x12 + x23) / 2; + const y123 = (y12 + y23) / 2; + const x234 = (x23 + x34) / 2; + const y234 = (y23 + y34) / 2; + const x1234 = (x123 + x234) / 2; + const y1234 = (y123 + y234) / 2; + if (level > 0) { + let dx = x4 - x1; + let dy = y4 - y1; + const d2 = Math.abs((x2 - x4) * dy - (y2 - y4) * dx); + const d3 = Math.abs((x3 - x4) * dy - (y3 - y4) * dx); + let da1; + let da2; + if (d2 > FLT_EPSILON$1 && d3 > FLT_EPSILON$1) { + if ((d2 + d3) * (d2 + d3) <= distanceTolerance * (dx * dx + dy * dy)) { + if (mAngleTolerance$1 < curveAngleToleranceEpsilon$1) { + points.push(x1234, y1234); + return; + } + const a23 = Math.atan2(y3 - y2, x3 - x2); + da1 = Math.abs(a23 - Math.atan2(y2 - y1, x2 - x1)); + da2 = Math.abs(Math.atan2(y4 - y3, x4 - x3) - a23); + if (da1 >= pi) + da1 = 2 * pi - da1; + if (da2 >= pi) + da2 = 2 * pi - da2; + if (da1 + da2 < mAngleTolerance$1) { + points.push(x1234, y1234); + return; + } + if (mCuspLimit !== 0) { + if (da1 > mCuspLimit) { + points.push(x2, y2); + return; + } + if (da2 > mCuspLimit) { + points.push(x3, y3); + return; + } + } + } + } else if (d2 > FLT_EPSILON$1) { + if (d2 * d2 <= distanceTolerance * (dx * dx + dy * dy)) { + if (mAngleTolerance$1 < curveAngleToleranceEpsilon$1) { + points.push(x1234, y1234); + return; + } + da1 = Math.abs(Math.atan2(y3 - y2, x3 - x2) - Math.atan2(y2 - y1, x2 - x1)); + if (da1 >= pi) + da1 = 2 * pi - da1; + if (da1 < mAngleTolerance$1) { + points.push(x2, y2); + points.push(x3, y3); + return; + } + if (mCuspLimit !== 0) { + if (da1 > mCuspLimit) { + points.push(x2, y2); + return; + } + } + } + } else if (d3 > FLT_EPSILON$1) { + if (d3 * d3 <= distanceTolerance * (dx * dx + dy * dy)) { + if (mAngleTolerance$1 < curveAngleToleranceEpsilon$1) { + points.push(x1234, y1234); + return; + } + da1 = Math.abs(Math.atan2(y4 - y3, x4 - x3) - Math.atan2(y3 - y2, x3 - x2)); + if (da1 >= pi) + da1 = 2 * pi - da1; + if (da1 < mAngleTolerance$1) { + points.push(x2, y2); + points.push(x3, y3); + return; + } + if (mCuspLimit !== 0) { + if (da1 > mCuspLimit) { + points.push(x3, y3); + return; + } + } + } + } else { + dx = x1234 - (x1 + x4) / 2; + dy = y1234 - (y1 + y4) / 2; + if (dx * dx + dy * dy <= distanceTolerance) { + points.push(x1234, y1234); + return; + } + } + } + recursive$1(x1, y1, x12, y12, x123, y123, x1234, y1234, points, distanceTolerance, level + 1); + recursive$1(x1234, y1234, x234, y234, x34, y34, x4, y4, points, distanceTolerance, level + 1); +} + +"use strict"; +const RECURSION_LIMIT = 8; +const FLT_EPSILON = 11920929e-14; +const PATH_DISTANCE_EPSILON = 1; +const curveAngleToleranceEpsilon = 0.01; +const mAngleTolerance = 0; +function buildAdaptiveQuadratic(points, sX, sY, cp1x, cp1y, eX, eY, smoothness) { + const scale = 1; + const smoothing = Math.min( + 0.99, + // a value of 1.0 actually inverts smoothing, so we cap it at 0.99 + Math.max(0, smoothness != null ? smoothness : GraphicsContextSystem.defaultOptions.bezierSmoothness) + ); + let distanceTolerance = (PATH_DISTANCE_EPSILON - smoothing) / scale; + distanceTolerance *= distanceTolerance; + begin(sX, sY, cp1x, cp1y, eX, eY, points, distanceTolerance); + return points; +} +function begin(sX, sY, cp1x, cp1y, eX, eY, points, distanceTolerance) { + recursive(points, sX, sY, cp1x, cp1y, eX, eY, distanceTolerance, 0); + points.push(eX, eY); +} +function recursive(points, x1, y1, x2, y2, x3, y3, distanceTolerance, level) { + if (level > RECURSION_LIMIT) { + return; + } + const pi = Math.PI; + const x12 = (x1 + x2) / 2; + const y12 = (y1 + y2) / 2; + const x23 = (x2 + x3) / 2; + const y23 = (y2 + y3) / 2; + const x123 = (x12 + x23) / 2; + const y123 = (y12 + y23) / 2; + let dx = x3 - x1; + let dy = y3 - y1; + const d = Math.abs((x2 - x3) * dy - (y2 - y3) * dx); + if (d > FLT_EPSILON) { + if (d * d <= distanceTolerance * (dx * dx + dy * dy)) { + if (mAngleTolerance < curveAngleToleranceEpsilon) { + points.push(x123, y123); + return; + } + let da = Math.abs(Math.atan2(y3 - y2, x3 - x2) - Math.atan2(y2 - y1, x2 - x1)); + if (da >= pi) + da = 2 * pi - da; + if (da < mAngleTolerance) { + points.push(x123, y123); + return; + } + } + } else { + dx = x123 - (x1 + x3) / 2; + dy = y123 - (y1 + y3) / 2; + if (dx * dx + dy * dy <= distanceTolerance) { + points.push(x123, y123); + return; + } + } + recursive(points, x1, y1, x12, y12, x123, y123, distanceTolerance, level + 1); + recursive(points, x123, y123, x23, y23, x3, y3, distanceTolerance, level + 1); +} + +"use strict"; +function buildArc(points, x, y, radius, start, end, clockwise, steps) { + let dist = Math.abs(start - end); + if (!clockwise && start > end) { + dist = 2 * Math.PI - dist; + } else if (clockwise && end > start) { + dist = 2 * Math.PI - dist; + } + steps = steps || Math.max(6, Math.floor(6 * Math.pow(radius, 1 / 3) * (dist / Math.PI))); + steps = Math.max(steps, 3); + let f = dist / steps; + let t = start; + f *= clockwise ? -1 : 1; + for (let i = 0; i < steps + 1; i++) { + const cs = Math.cos(t); + const sn = Math.sin(t); + const nx = x + cs * radius; + const ny = y + sn * radius; + points.push(nx, ny); + t += f; + } +} + +"use strict"; +function buildArcTo(points, x1, y1, x2, y2, radius) { + const fromX = points[points.length - 2]; + const fromY = points[points.length - 1]; + const a1 = fromY - y1; + const b1 = fromX - x1; + const a2 = y2 - y1; + const b2 = x2 - x1; + const mm = Math.abs(a1 * b2 - b1 * a2); + if (mm < 1e-8 || radius === 0) { + if (points[points.length - 2] !== x1 || points[points.length - 1] !== y1) { + points.push(x1, y1); + } + return; + } + const dd = a1 * a1 + b1 * b1; + const cc = a2 * a2 + b2 * b2; + const tt = a1 * a2 + b1 * b2; + const k1 = radius * Math.sqrt(dd) / mm; + const k2 = radius * Math.sqrt(cc) / mm; + const j1 = k1 * tt / dd; + const j2 = k2 * tt / cc; + const cx = k1 * b2 + k2 * b1; + const cy = k1 * a2 + k2 * a1; + const px = b1 * (k2 + j1); + const py = a1 * (k2 + j1); + const qx = b2 * (k1 + j2); + const qy = a2 * (k1 + j2); + const startAngle = Math.atan2(py - cy, px - cx); + const endAngle = Math.atan2(qy - cy, qx - cx); + buildArc( + points, + cx + x1, + cy + y1, + radius, + startAngle, + endAngle, + b1 * a2 > b2 * a1 + ); +} + +"use strict"; +const TAU = Math.PI * 2; +const out = { + centerX: 0, + centerY: 0, + ang1: 0, + ang2: 0 +}; +const mapToEllipse = ({ x, y }, rx, ry, cosPhi, sinPhi, centerX, centerY, out2) => { + x *= rx; + y *= ry; + const xp = cosPhi * x - sinPhi * y; + const yp = sinPhi * x + cosPhi * y; + out2.x = xp + centerX; + out2.y = yp + centerY; + return out2; +}; +function approxUnitArc(ang1, ang2) { + const a1 = ang2 === -1.5707963267948966 ? -0.551915024494 : 4 / 3 * Math.tan(ang2 / 4); + const a = ang2 === 1.5707963267948966 ? 0.551915024494 : a1; + const x1 = Math.cos(ang1); + const y1 = Math.sin(ang1); + const x2 = Math.cos(ang1 + ang2); + const y2 = Math.sin(ang1 + ang2); + return [ + { + x: x1 - y1 * a, + y: y1 + x1 * a + }, + { + x: x2 + y2 * a, + y: y2 - x2 * a + }, + { + x: x2, + y: y2 + } + ]; +} +const vectorAngle = (ux, uy, vx, vy) => { + const sign = ux * vy - uy * vx < 0 ? -1 : 1; + let dot = ux * vx + uy * vy; + if (dot > 1) { + dot = 1; + } + if (dot < -1) { + dot = -1; + } + return sign * Math.acos(dot); +}; +const getArcCenter = (px, py, cx, cy, rx, ry, largeArcFlag, sweepFlag, sinPhi, cosPhi, pxp, pyp, out2) => { + const rxSq = Math.pow(rx, 2); + const rySq = Math.pow(ry, 2); + const pxpSq = Math.pow(pxp, 2); + const pypSq = Math.pow(pyp, 2); + let radicant = rxSq * rySq - rxSq * pypSq - rySq * pxpSq; + if (radicant < 0) { + radicant = 0; + } + radicant /= rxSq * pypSq + rySq * pxpSq; + radicant = Math.sqrt(radicant) * (largeArcFlag === sweepFlag ? -1 : 1); + const centerXp = radicant * rx / ry * pyp; + const centerYp = radicant * -ry / rx * pxp; + const centerX = cosPhi * centerXp - sinPhi * centerYp + (px + cx) / 2; + const centerY = sinPhi * centerXp + cosPhi * centerYp + (py + cy) / 2; + const vx1 = (pxp - centerXp) / rx; + const vy1 = (pyp - centerYp) / ry; + const vx2 = (-pxp - centerXp) / rx; + const vy2 = (-pyp - centerYp) / ry; + const ang1 = vectorAngle(1, 0, vx1, vy1); + let ang2 = vectorAngle(vx1, vy1, vx2, vy2); + if (sweepFlag === 0 && ang2 > 0) { + ang2 -= TAU; + } + if (sweepFlag === 1 && ang2 < 0) { + ang2 += TAU; + } + out2.centerX = centerX; + out2.centerY = centerY; + out2.ang1 = ang1; + out2.ang2 = ang2; +}; +function buildArcToSvg(points, px, py, cx, cy, rx, ry, xAxisRotation = 0, largeArcFlag = 0, sweepFlag = 0) { + if (rx === 0 || ry === 0) { + return; + } + const sinPhi = Math.sin(xAxisRotation * TAU / 360); + const cosPhi = Math.cos(xAxisRotation * TAU / 360); + const pxp = cosPhi * (px - cx) / 2 + sinPhi * (py - cy) / 2; + const pyp = -sinPhi * (px - cx) / 2 + cosPhi * (py - cy) / 2; + if (pxp === 0 && pyp === 0) { + return; + } + rx = Math.abs(rx); + ry = Math.abs(ry); + const lambda = Math.pow(pxp, 2) / Math.pow(rx, 2) + Math.pow(pyp, 2) / Math.pow(ry, 2); + if (lambda > 1) { + rx *= Math.sqrt(lambda); + ry *= Math.sqrt(lambda); + } + getArcCenter( + px, + py, + cx, + cy, + rx, + ry, + largeArcFlag, + sweepFlag, + sinPhi, + cosPhi, + pxp, + pyp, + out + ); + let { ang1, ang2 } = out; + const { centerX, centerY } = out; + let ratio = Math.abs(ang2) / (TAU / 4); + if (Math.abs(1 - ratio) < 1e-7) { + ratio = 1; + } + const segments = Math.max(Math.ceil(ratio), 1); + ang2 /= segments; + let lastX = points[points.length - 2]; + let lastY = points[points.length - 1]; + const outCurvePoint = { x: 0, y: 0 }; + for (let i = 0; i < segments; i++) { + const curve = approxUnitArc(ang1, ang2); + const { x: x1, y: y1 } = mapToEllipse(curve[0], rx, ry, cosPhi, sinPhi, centerX, centerY, outCurvePoint); + const { x: x2, y: y2 } = mapToEllipse(curve[1], rx, ry, cosPhi, sinPhi, centerX, centerY, outCurvePoint); + const { x, y } = mapToEllipse(curve[2], rx, ry, cosPhi, sinPhi, centerX, centerY, outCurvePoint); + buildAdaptiveBezier( + points, + lastX, + lastY, + x1, + y1, + x2, + y2, + x, + y + ); + lastX = x; + lastY = y; + ang1 += ang2; + } +} + +"use strict"; +function roundedShapeArc(g, points, radius) { + var _a; + const vecFrom = (p, pp) => { + const x = pp.x - p.x; + const y = pp.y - p.y; + const len = Math.sqrt(x * x + y * y); + const nx = x / len; + const ny = y / len; + return { len, nx, ny }; + }; + const sharpCorner = (i, p) => { + if (i === 0) { + g.moveTo(p.x, p.y); + } else { + g.lineTo(p.x, p.y); + } + }; + let p1 = points[points.length - 1]; + for (let i = 0; i < points.length; i++) { + const p2 = points[i % points.length]; + const pRadius = (_a = p2.radius) != null ? _a : radius; + if (pRadius <= 0) { + sharpCorner(i, p2); + p1 = p2; + continue; + } + const p3 = points[(i + 1) % points.length]; + const v1 = vecFrom(p2, p1); + const v2 = vecFrom(p2, p3); + if (v1.len < 1e-4 || v2.len < 1e-4) { + sharpCorner(i, p2); + p1 = p2; + continue; + } + let angle = Math.asin(v1.nx * v2.ny - v1.ny * v2.nx); + let radDirection = 1; + let drawDirection = false; + if (v1.nx * v2.nx - v1.ny * -v2.ny < 0) { + if (angle < 0) { + angle = Math.PI + angle; + } else { + angle = Math.PI - angle; + radDirection = -1; + drawDirection = true; + } + } else if (angle > 0) { + radDirection = -1; + drawDirection = true; + } + const halfAngle = angle / 2; + let cRadius; + let lenOut = Math.abs( + Math.cos(halfAngle) * pRadius / Math.sin(halfAngle) + ); + if (lenOut > Math.min(v1.len / 2, v2.len / 2)) { + lenOut = Math.min(v1.len / 2, v2.len / 2); + cRadius = Math.abs(lenOut * Math.sin(halfAngle) / Math.cos(halfAngle)); + } else { + cRadius = pRadius; + } + const cX = p2.x + v2.nx * lenOut + -v2.ny * cRadius * radDirection; + const cY = p2.y + v2.ny * lenOut + v2.nx * cRadius * radDirection; + const startAngle = Math.atan2(v1.ny, v1.nx) + Math.PI / 2 * radDirection; + const endAngle = Math.atan2(v2.ny, v2.nx) - Math.PI / 2 * radDirection; + if (i === 0) { + g.moveTo( + cX + Math.cos(startAngle) * cRadius, + cY + Math.sin(startAngle) * cRadius + ); + } + g.arc(cX, cY, cRadius, startAngle, endAngle, drawDirection); + p1 = p2; + } +} +function roundedShapeQuadraticCurve(g, points, radius, smoothness) { + var _a; + const distance = (p1, p2) => Math.sqrt((p1.x - p2.x) ** 2 + (p1.y - p2.y) ** 2); + const pointLerp = (p1, p2, t) => ({ + x: p1.x + (p2.x - p1.x) * t, + y: p1.y + (p2.y - p1.y) * t + }); + const numPoints = points.length; + for (let i = 0; i < numPoints; i++) { + const thisPoint = points[(i + 1) % numPoints]; + const pRadius = (_a = thisPoint.radius) != null ? _a : radius; + if (pRadius <= 0) { + if (i === 0) { + g.moveTo(thisPoint.x, thisPoint.y); + } else { + g.lineTo(thisPoint.x, thisPoint.y); + } + continue; + } + const lastPoint = points[i]; + const nextPoint = points[(i + 2) % numPoints]; + const lastEdgeLength = distance(lastPoint, thisPoint); + let start; + if (lastEdgeLength < 1e-4) { + start = thisPoint; + } else { + const lastOffsetDistance = Math.min(lastEdgeLength / 2, pRadius); + start = pointLerp( + thisPoint, + lastPoint, + lastOffsetDistance / lastEdgeLength + ); + } + const nextEdgeLength = distance(nextPoint, thisPoint); + let end; + if (nextEdgeLength < 1e-4) { + end = thisPoint; + } else { + const nextOffsetDistance = Math.min(nextEdgeLength / 2, pRadius); + end = pointLerp( + thisPoint, + nextPoint, + nextOffsetDistance / nextEdgeLength + ); + } + if (i === 0) { + g.moveTo(start.x, start.y); + } else { + g.lineTo(start.x, start.y); + } + g.quadraticCurveTo(thisPoint.x, thisPoint.y, end.x, end.y, smoothness); + } +} + +"use strict"; +const tempRectangle = new Rectangle(); +class ShapePath { + constructor(graphicsPath2D) { + /** The list of shape primitives that make up the path. */ + this.shapePrimitives = []; + this._currentPoly = null; + this._bounds = new Bounds(); + this._graphicsPath2D = graphicsPath2D; + } + /** + * Sets the starting point for a new sub-path. Any subsequent drawing commands are considered part of this path. + * @param x - The x-coordinate for the starting point. + * @param y - The y-coordinate for the starting point. + * @returns The instance of the current object for chaining. + */ + moveTo(x, y) { + this.startPoly(x, y); + return this; + } + /** + * Connects the current point to a new point with a straight line. This method updates the current path. + * @param x - The x-coordinate of the new point to connect to. + * @param y - The y-coordinate of the new point to connect to. + * @returns The instance of the current object for chaining. + */ + lineTo(x, y) { + this._ensurePoly(); + const points = this._currentPoly.points; + const fromX = points[points.length - 2]; + const fromY = points[points.length - 1]; + if (fromX !== x || fromY !== y) { + points.push(x, y); + } + return this; + } + /** + * Adds an arc to the path. The arc is centered at (x, y) + * position with radius `radius` starting at `startAngle` and ending at `endAngle`. + * @param x - The x-coordinate of the arc's center. + * @param y - The y-coordinate of the arc's center. + * @param radius - The radius of the arc. + * @param startAngle - The starting angle of the arc, in radians. + * @param endAngle - The ending angle of the arc, in radians. + * @param counterclockwise - Specifies whether the arc should be drawn in the anticlockwise direction. False by default. + * @returns The instance of the current object for chaining. + */ + arc(x, y, radius, startAngle, endAngle, counterclockwise) { + this._ensurePoly(false); + const points = this._currentPoly.points; + buildArc(points, x, y, radius, startAngle, endAngle, counterclockwise); + return this; + } + /** + * Adds an arc to the path with the arc tangent to the line joining two specified points. + * The arc radius is specified by `radius`. + * @param x1 - The x-coordinate of the first point. + * @param y1 - The y-coordinate of the first point. + * @param x2 - The x-coordinate of the second point. + * @param y2 - The y-coordinate of the second point. + * @param radius - The radius of the arc. + * @returns The instance of the current object for chaining. + */ + arcTo(x1, y1, x2, y2, radius) { + this._ensurePoly(); + const points = this._currentPoly.points; + buildArcTo(points, x1, y1, x2, y2, radius); + return this; + } + /** + * Adds an SVG-style arc to the path, allowing for elliptical arcs based on the SVG spec. + * @param rx - The x-radius of the ellipse. + * @param ry - The y-radius of the ellipse. + * @param xAxisRotation - The rotation of the ellipse's x-axis relative + * to the x-axis of the coordinate system, in degrees. + * @param largeArcFlag - Determines if the arc should be greater than or less than 180 degrees. + * @param sweepFlag - Determines if the arc should be swept in a positive angle direction. + * @param x - The x-coordinate of the arc's end point. + * @param y - The y-coordinate of the arc's end point. + * @returns The instance of the current object for chaining. + */ + arcToSvg(rx, ry, xAxisRotation, largeArcFlag, sweepFlag, x, y) { + const points = this._currentPoly.points; + buildArcToSvg( + points, + this._currentPoly.lastX, + this._currentPoly.lastY, + x, + y, + rx, + ry, + xAxisRotation, + largeArcFlag, + sweepFlag + ); + return this; + } + /** + * Adds a cubic Bezier curve to the path. + * It requires three points: the first two are control points and the third one is the end point. + * The starting point is the last point in the current path. + * @param cp1x - The x-coordinate of the first control point. + * @param cp1y - The y-coordinate of the first control point. + * @param cp2x - The x-coordinate of the second control point. + * @param cp2y - The y-coordinate of the second control point. + * @param x - The x-coordinate of the end point. + * @param y - The y-coordinate of the end point. + * @param smoothness - Optional parameter to adjust the smoothness of the curve. + * @returns The instance of the current object for chaining. + */ + bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y, smoothness) { + this._ensurePoly(); + const currentPoly = this._currentPoly; + buildAdaptiveBezier( + this._currentPoly.points, + currentPoly.lastX, + currentPoly.lastY, + cp1x, + cp1y, + cp2x, + cp2y, + x, + y, + smoothness + ); + return this; + } + /** + * Adds a quadratic curve to the path. It requires two points: the control point and the end point. + * The starting point is the last point in the current path. + * @param cp1x - The x-coordinate of the control point. + * @param cp1y - The y-coordinate of the control point. + * @param x - The x-coordinate of the end point. + * @param y - The y-coordinate of the end point. + * @param smoothing - Optional parameter to adjust the smoothness of the curve. + * @returns The instance of the current object for chaining. + */ + quadraticCurveTo(cp1x, cp1y, x, y, smoothing) { + this._ensurePoly(); + const currentPoly = this._currentPoly; + buildAdaptiveQuadratic( + this._currentPoly.points, + currentPoly.lastX, + currentPoly.lastY, + cp1x, + cp1y, + x, + y, + smoothing + ); + return this; + } + /** + * Closes the current path by drawing a straight line back to the start. + * If the shape is already closed or there are no points in the path, this method does nothing. + * @returns The instance of the current object for chaining. + */ + closePath() { + this.endPoly(true); + return this; + } + /** + * Adds another path to the current path. This method allows for the combination of multiple paths into one. + * @param path - The `GraphicsPath` object representing the path to add. + * @param transform - An optional `Matrix` object to apply a transformation to the path before adding it. + * @returns The instance of the current object for chaining. + */ + addPath(path, transform) { + this.endPoly(); + if (transform && !transform.isIdentity()) { + path = path.clone(true); + path.transform(transform); + } + for (let i = 0; i < path.instructions.length; i++) { + const instruction = path.instructions[i]; + this[instruction.action](...instruction.data); + } + return this; + } + /** + * Finalizes the drawing of the current path. Optionally, it can close the path. + * @param closePath - A boolean indicating whether to close the path after finishing. False by default. + */ + finish(closePath = false) { + this.endPoly(closePath); + } + /** + * Draws a rectangle shape. This method adds a new rectangle path to the current drawing. + * @param x - The x-coordinate of the top-left corner of the rectangle. + * @param y - The y-coordinate of the top-left corner of the rectangle. + * @param w - The width of the rectangle. + * @param h - The height of the rectangle. + * @param transform - An optional `Matrix` object to apply a transformation to the rectangle. + * @returns The instance of the current object for chaining. + */ + rect(x, y, w, h, transform) { + this.drawShape(new Rectangle(x, y, w, h), transform); + return this; + } + /** + * Draws a circle shape. This method adds a new circle path to the current drawing. + * @param x - The x-coordinate of the center of the circle. + * @param y - The y-coordinate of the center of the circle. + * @param radius - The radius of the circle. + * @param transform - An optional `Matrix` object to apply a transformation to the circle. + * @returns The instance of the current object for chaining. + */ + circle(x, y, radius, transform) { + this.drawShape(new Circle(x, y, radius), transform); + return this; + } + /** + * Draws a polygon shape. This method allows for the creation of complex polygons by specifying a sequence of points. + * @param points - An array of numbers, or or an array of PointData objects eg [{x,y}, {x,y}, {x,y}] + * representing the x and y coordinates of the polygon's vertices, in sequence. + * @param close - A boolean indicating whether to close the polygon path. True by default. + * @param transform - An optional `Matrix` object to apply a transformation to the polygon. + * @returns The instance of the current object for chaining. + */ + poly(points, close, transform) { + const polygon = new Polygon(points); + polygon.closePath = close; + this.drawShape(polygon, transform); + return this; + } + /** + * Draws a regular polygon with a specified number of sides. All sides and angles are equal. + * @param x - The x-coordinate of the center of the polygon. + * @param y - The y-coordinate of the center of the polygon. + * @param radius - The radius of the circumscribed circle of the polygon. + * @param sides - The number of sides of the polygon. Must be 3 or more. + * @param rotation - The rotation angle of the polygon, in radians. Zero by default. + * @param transform - An optional `Matrix` object to apply a transformation to the polygon. + * @returns The instance of the current object for chaining. + */ + regularPoly(x, y, radius, sides, rotation = 0, transform) { + sides = Math.max(sides | 0, 3); + const startAngle = -1 * Math.PI / 2 + rotation; + const delta = Math.PI * 2 / sides; + const polygon = []; + for (let i = 0; i < sides; i++) { + const angle = i * delta + startAngle; + polygon.push( + x + radius * Math.cos(angle), + y + radius * Math.sin(angle) + ); + } + this.poly(polygon, true, transform); + return this; + } + /** + * Draws a polygon with rounded corners. + * Similar to `regularPoly` but with the ability to round the corners of the polygon. + * @param x - The x-coordinate of the center of the polygon. + * @param y - The y-coordinate of the center of the polygon. + * @param radius - The radius of the circumscribed circle of the polygon. + * @param sides - The number of sides of the polygon. Must be 3 or more. + * @param corner - The radius of the rounding of the corners. + * @param rotation - The rotation angle of the polygon, in radians. Zero by default. + * @param smoothness - Optional parameter to adjust the smoothness of the rounding. + * @returns The instance of the current object for chaining. + */ + roundPoly(x, y, radius, sides, corner, rotation = 0, smoothness) { + sides = Math.max(sides | 0, 3); + if (corner <= 0) { + return this.regularPoly(x, y, radius, sides, rotation); + } + const sideLength = radius * Math.sin(Math.PI / sides) - 1e-3; + corner = Math.min(corner, sideLength); + const startAngle = -1 * Math.PI / 2 + rotation; + const delta = Math.PI * 2 / sides; + const internalAngle = (sides - 2) * Math.PI / sides / 2; + for (let i = 0; i < sides; i++) { + const angle = i * delta + startAngle; + const x0 = x + radius * Math.cos(angle); + const y0 = y + radius * Math.sin(angle); + const a1 = angle + Math.PI + internalAngle; + const a2 = angle - Math.PI - internalAngle; + const x1 = x0 + corner * Math.cos(a1); + const y1 = y0 + corner * Math.sin(a1); + const x3 = x0 + corner * Math.cos(a2); + const y3 = y0 + corner * Math.sin(a2); + if (i === 0) { + this.moveTo(x1, y1); + } else { + this.lineTo(x1, y1); + } + this.quadraticCurveTo(x0, y0, x3, y3, smoothness); + } + return this.closePath(); + } + /** + * Draws a shape with rounded corners. This function supports custom radius for each corner of the shape. + * Optionally, corners can be rounded using a quadratic curve instead of an arc, providing a different aesthetic. + * @param points - An array of `RoundedPoint` representing the corners of the shape to draw. + * A minimum of 3 points is required. + * @param radius - The default radius for the corners. + * This radius is applied to all corners unless overridden in `points`. + * @param useQuadratic - If set to true, rounded corners are drawn using a quadraticCurve + * method instead of an arc method. Defaults to false. + * @param smoothness - Specifies the smoothness of the curve when `useQuadratic` is true. + * Higher values make the curve smoother. + * @returns The instance of the current object for chaining. + */ + roundShape(points, radius, useQuadratic = false, smoothness) { + if (points.length < 3) { + return this; + } + if (useQuadratic) { + roundedShapeQuadraticCurve(this, points, radius, smoothness); + } else { + roundedShapeArc(this, points, radius); + } + return this.closePath(); + } + /** + * Draw Rectangle with fillet corners. This is much like rounded rectangle + * however it support negative numbers as well for the corner radius. + * @param x - Upper left corner of rect + * @param y - Upper right corner of rect + * @param width - Width of rect + * @param height - Height of rect + * @param fillet - accept negative or positive values + */ + filletRect(x, y, width, height, fillet) { + if (fillet === 0) { + return this.rect(x, y, width, height); + } + const maxFillet = Math.min(width, height) / 2; + const inset = Math.min(maxFillet, Math.max(-maxFillet, fillet)); + const right = x + width; + const bottom = y + height; + const dir = inset < 0 ? -inset : 0; + const size = Math.abs(inset); + return this.moveTo(x, y + size).arcTo(x + dir, y + dir, x + size, y, size).lineTo(right - size, y).arcTo(right - dir, y + dir, right, y + size, size).lineTo(right, bottom - size).arcTo(right - dir, bottom - dir, x + width - size, bottom, size).lineTo(x + size, bottom).arcTo(x + dir, bottom - dir, x, bottom - size, size).closePath(); + } + /** + * Draw Rectangle with chamfer corners. These are angled corners. + * @param x - Upper left corner of rect + * @param y - Upper right corner of rect + * @param width - Width of rect + * @param height - Height of rect + * @param chamfer - non-zero real number, size of corner cutout + * @param transform + */ + chamferRect(x, y, width, height, chamfer, transform) { + if (chamfer <= 0) { + return this.rect(x, y, width, height); + } + const inset = Math.min(chamfer, Math.min(width, height) / 2); + const right = x + width; + const bottom = y + height; + const points = [ + x + inset, + y, + right - inset, + y, + right, + y + inset, + right, + bottom - inset, + right - inset, + bottom, + x + inset, + bottom, + x, + bottom - inset, + x, + y + inset + ]; + for (let i = points.length - 1; i >= 2; i -= 2) { + if (points[i] === points[i - 2] && points[i - 1] === points[i - 3]) { + points.splice(i - 1, 2); + } + } + return this.poly(points, true, transform); + } + /** + * Draws an ellipse at the specified location and with the given x and y radii. + * An optional transformation can be applied, allowing for rotation, scaling, and translation. + * @param x - The x-coordinate of the center of the ellipse. + * @param y - The y-coordinate of the center of the ellipse. + * @param radiusX - The horizontal radius of the ellipse. + * @param radiusY - The vertical radius of the ellipse. + * @param transform - An optional `Matrix` object to apply a transformation to the ellipse. This can include rotations. + * @returns The instance of the current object for chaining. + */ + ellipse(x, y, radiusX, radiusY, transform) { + this.drawShape(new Ellipse(x, y, radiusX, radiusY), transform); + return this; + } + /** + * Draws a rectangle with rounded corners. + * The corner radius can be specified to determine how rounded the corners should be. + * An optional transformation can be applied, which allows for rotation, scaling, and translation of the rectangle. + * @param x - The x-coordinate of the top-left corner of the rectangle. + * @param y - The y-coordinate of the top-left corner of the rectangle. + * @param w - The width of the rectangle. + * @param h - The height of the rectangle. + * @param radius - The radius of the rectangle's corners. If not specified, corners will be sharp. + * @param transform - An optional `Matrix` object to apply a transformation to the rectangle. + * @returns The instance of the current object for chaining. + */ + roundRect(x, y, w, h, radius, transform) { + this.drawShape(new RoundedRectangle(x, y, w, h, radius), transform); + return this; + } + /** + * Draws a given shape on the canvas. + * This is a generic method that can draw any type of shape specified by the `ShapePrimitive` parameter. + * An optional transformation matrix can be applied to the shape, allowing for complex transformations. + * @param shape - The shape to draw, defined as a `ShapePrimitive` object. + * @param matrix - An optional `Matrix` for transforming the shape. This can include rotations, + * scaling, and translations. + * @returns The instance of the current object for chaining. + */ + drawShape(shape, matrix) { + this.endPoly(); + this.shapePrimitives.push({ shape, transform: matrix }); + return this; + } + /** + * Starts a new polygon path from the specified starting point. + * This method initializes a new polygon or ends the current one if it exists. + * @param x - The x-coordinate of the starting point of the new polygon. + * @param y - The y-coordinate of the starting point of the new polygon. + * @returns The instance of the current object for chaining. + */ + startPoly(x, y) { + let currentPoly = this._currentPoly; + if (currentPoly) { + this.endPoly(); + } + currentPoly = new Polygon(); + currentPoly.points.push(x, y); + this._currentPoly = currentPoly; + return this; + } + /** + * Ends the current polygon path. If `closePath` is set to true, + * the path is closed by connecting the last point to the first one. + * This method finalizes the current polygon and prepares it for drawing or adding to the shape primitives. + * @param closePath - A boolean indicating whether to close the polygon by connecting the last point + * back to the starting point. False by default. + * @returns The instance of the current object for chaining. + */ + endPoly(closePath = false) { + const shape = this._currentPoly; + if (shape && shape.points.length > 2) { + shape.closePath = closePath; + this.shapePrimitives.push({ shape }); + } + this._currentPoly = null; + return this; + } + _ensurePoly(start = true) { + if (this._currentPoly) + return; + this._currentPoly = new Polygon(); + if (start) { + const lastShape = this.shapePrimitives[this.shapePrimitives.length - 1]; + if (lastShape) { + let lx = lastShape.shape.x; + let ly = lastShape.shape.y; + if (!lastShape.transform.isIdentity()) { + const t = lastShape.transform; + const tempX = lx; + lx = t.a * lx + t.c * ly + t.tx; + ly = t.b * tempX + t.d * ly + t.ty; + } + this._currentPoly.points.push(lx, ly); + } else { + this._currentPoly.points.push(0, 0); + } + } + } + /** Builds the path. */ + buildPath() { + const path = this._graphicsPath2D; + this.shapePrimitives.length = 0; + this._currentPoly = null; + for (let i = 0; i < path.instructions.length; i++) { + const instruction = path.instructions[i]; + this[instruction.action](...instruction.data); + } + this.finish(); + } + /** Gets the bounds of the path. */ + get bounds() { + const bounds = this._bounds; + bounds.clear(); + const shapePrimitives = this.shapePrimitives; + for (let i = 0; i < shapePrimitives.length; i++) { + const shapePrimitive = shapePrimitives[i]; + const boundsRect = shapePrimitive.shape.getBounds(tempRectangle); + if (shapePrimitive.transform) { + bounds.addRect(boundsRect, shapePrimitive.transform); + } else { + bounds.addRect(boundsRect); + } + } + return bounds; + } +} + +"use strict"; +class GraphicsPath { + /** + * Creates a `GraphicsPath` instance optionally from an SVG path string or an array of `PathInstruction`. + * @param instructions - An SVG path string or an array of `PathInstruction` objects. + */ + constructor(instructions) { + this.instructions = []; + this.uid = uid("graphicsPath"); + this._dirty = true; + var _a; + if (typeof instructions === "string") { + SVGToGraphicsPath(instructions, this); + } else { + this.instructions = (_a = instructions == null ? void 0 : instructions.slice()) != null ? _a : []; + } + } + /** + * Provides access to the internal shape path, ensuring it is up-to-date with the current instructions. + * @returns The `ShapePath` instance associated with this `GraphicsPath`. + */ + get shapePath() { + if (!this._shapePath) { + this._shapePath = new ShapePath(this); + } + if (this._dirty) { + this._dirty = false; + this._shapePath.buildPath(); + } + return this._shapePath; + } + /** + * Adds another `GraphicsPath` to this path, optionally applying a transformation. + * @param path - The `GraphicsPath` to add. + * @param transform - An optional transformation to apply to the added path. + * @returns The instance of the current object for chaining. + */ + addPath(path, transform) { + path = path.clone(); + this.instructions.push({ action: "addPath", data: [path, transform] }); + this._dirty = true; + return this; + } + arc(...args) { + this.instructions.push({ action: "arc", data: args }); + this._dirty = true; + return this; + } + arcTo(...args) { + this.instructions.push({ action: "arcTo", data: args }); + this._dirty = true; + return this; + } + arcToSvg(...args) { + this.instructions.push({ action: "arcToSvg", data: args }); + this._dirty = true; + return this; + } + bezierCurveTo(...args) { + this.instructions.push({ action: "bezierCurveTo", data: args }); + this._dirty = true; + return this; + } + /** + * Adds a cubic Bezier curve to the path. + * It requires two points: the second control point and the end point. The first control point is assumed to be + * The starting point is the last point in the current path. + * @param cp2x - The x-coordinate of the second control point. + * @param cp2y - The y-coordinate of the second control point. + * @param x - The x-coordinate of the end point. + * @param y - The y-coordinate of the end point. + * @param smoothness - Optional parameter to adjust the smoothness of the curve. + * @returns The instance of the current object for chaining. + */ + bezierCurveToShort(cp2x, cp2y, x, y, smoothness) { + const last = this.instructions[this.instructions.length - 1]; + const lastPoint = this.getLastPoint(Point.shared); + let cp1x = 0; + let cp1y = 0; + if (!last || last.action !== "bezierCurveTo") { + cp1x = lastPoint.x; + cp1y = lastPoint.y; + } else { + cp1x = last.data[2]; + cp1y = last.data[3]; + const currentX = lastPoint.x; + const currentY = lastPoint.y; + cp1x = currentX + (currentX - cp1x); + cp1y = currentY + (currentY - cp1y); + } + this.instructions.push({ action: "bezierCurveTo", data: [cp1x, cp1y, cp2x, cp2y, x, y, smoothness] }); + this._dirty = true; + return this; + } + /** + * Closes the current path by drawing a straight line back to the start. + * If the shape is already closed or there are no points in the path, this method does nothing. + * @returns The instance of the current object for chaining. + */ + closePath() { + this.instructions.push({ action: "closePath", data: [] }); + this._dirty = true; + return this; + } + ellipse(...args) { + this.instructions.push({ action: "ellipse", data: args }); + this._dirty = true; + return this; + } + lineTo(...args) { + this.instructions.push({ action: "lineTo", data: args }); + this._dirty = true; + return this; + } + moveTo(...args) { + this.instructions.push({ action: "moveTo", data: args }); + return this; + } + quadraticCurveTo(...args) { + this.instructions.push({ action: "quadraticCurveTo", data: args }); + this._dirty = true; + return this; + } + /** + * Adds a quadratic curve to the path. It uses the previous point as the control point. + * @param x - The x-coordinate of the end point. + * @param y - The y-coordinate of the end point. + * @param smoothness - Optional parameter to adjust the smoothness of the curve. + * @returns The instance of the current object for chaining. + */ + quadraticCurveToShort(x, y, smoothness) { + const last = this.instructions[this.instructions.length - 1]; + const lastPoint = this.getLastPoint(Point.shared); + let cpx1 = 0; + let cpy1 = 0; + if (!last || last.action !== "quadraticCurveTo") { + cpx1 = lastPoint.x; + cpy1 = lastPoint.y; + } else { + cpx1 = last.data[0]; + cpy1 = last.data[1]; + const currentX = lastPoint.x; + const currentY = lastPoint.y; + cpx1 = currentX + (currentX - cpx1); + cpy1 = currentY + (currentY - cpy1); + } + this.instructions.push({ action: "quadraticCurveTo", data: [cpx1, cpy1, x, y, smoothness] }); + this._dirty = true; + return this; + } + /** + * Draws a rectangle shape. This method adds a new rectangle path to the current drawing. + * @param x - The x-coordinate of the top-left corner of the rectangle. + * @param y - The y-coordinate of the top-left corner of the rectangle. + * @param w - The width of the rectangle. + * @param h - The height of the rectangle. + * @param transform - An optional `Matrix` object to apply a transformation to the rectangle. + * @returns The instance of the current object for chaining. + */ + rect(x, y, w, h, transform) { + this.instructions.push({ action: "rect", data: [x, y, w, h, transform] }); + this._dirty = true; + return this; + } + /** + * Draws a circle shape. This method adds a new circle path to the current drawing. + * @param x - The x-coordinate of the center of the circle. + * @param y - The y-coordinate of the center of the circle. + * @param radius - The radius of the circle. + * @param transform - An optional `Matrix` object to apply a transformation to the circle. + * @returns The instance of the current object for chaining. + */ + circle(x, y, radius, transform) { + this.instructions.push({ action: "circle", data: [x, y, radius, transform] }); + this._dirty = true; + return this; + } + roundRect(...args) { + this.instructions.push({ action: "roundRect", data: args }); + this._dirty = true; + return this; + } + poly(...args) { + this.instructions.push({ action: "poly", data: args }); + this._dirty = true; + return this; + } + regularPoly(...args) { + this.instructions.push({ action: "regularPoly", data: args }); + this._dirty = true; + return this; + } + roundPoly(...args) { + this.instructions.push({ action: "roundPoly", data: args }); + this._dirty = true; + return this; + } + roundShape(...args) { + this.instructions.push({ action: "roundShape", data: args }); + this._dirty = true; + return this; + } + filletRect(...args) { + this.instructions.push({ action: "filletRect", data: args }); + this._dirty = true; + return this; + } + chamferRect(...args) { + this.instructions.push({ action: "chamferRect", data: args }); + this._dirty = true; + return this; + } + /** + * Draws a star shape centered at a specified location. This method allows for the creation + * of stars with a variable number of points, outer radius, optional inner radius, and rotation. + * The star is drawn as a closed polygon with alternating outer and inner vertices to create the star's points. + * An optional transformation can be applied to scale, rotate, or translate the star as needed. + * @param x - The x-coordinate of the center of the star. + * @param y - The y-coordinate of the center of the star. + * @param points - The number of points of the star. + * @param radius - The outer radius of the star (distance from the center to the outer points). + * @param innerRadius - Optional. The inner radius of the star + * (distance from the center to the inner points between the outer points). + * If not provided, defaults to half of the `radius`. + * @param rotation - Optional. The rotation of the star in radians, where 0 is aligned with the y-axis. + * Defaults to 0, meaning one point is directly upward. + * @param transform - An optional `Matrix` object to apply a transformation to the star. + * This can include rotations, scaling, and translations. + * @returns The instance of the current object for chaining further drawing commands. + */ + // eslint-disable-next-line max-len + star(x, y, points, radius, innerRadius, rotation, transform) { + innerRadius = innerRadius || radius / 2; + const startAngle = -1 * Math.PI / 2 + rotation; + const len = points * 2; + const delta = Math.PI * 2 / len; + const polygon = []; + for (let i = 0; i < len; i++) { + const r = i % 2 ? innerRadius : radius; + const angle = i * delta + startAngle; + polygon.push( + x + r * Math.cos(angle), + y + r * Math.sin(angle) + ); + } + this.poly(polygon, true, transform); + return this; + } + /** + * Creates a copy of the current `GraphicsPath` instance. This method supports both shallow and deep cloning. + * A shallow clone copies the reference of the instructions array, while a deep clone creates a new array and + * copies each instruction individually, ensuring that modifications to the instructions of the cloned `GraphicsPath` + * do not affect the original `GraphicsPath` and vice versa. + * @param deep - A boolean flag indicating whether the clone should be deep. + * @returns A new `GraphicsPath` instance that is a clone of the current instance. + */ + clone(deep = false) { + const newGraphicsPath2D = new GraphicsPath(); + if (!deep) { + newGraphicsPath2D.instructions = this.instructions.slice(); + } else { + for (let i = 0; i < this.instructions.length; i++) { + const instruction = this.instructions[i]; + newGraphicsPath2D.instructions.push({ action: instruction.action, data: instruction.data.slice() }); + } + } + return newGraphicsPath2D; + } + clear() { + this.instructions.length = 0; + this._dirty = true; + return this; + } + /** + * Applies a transformation matrix to all drawing instructions within the `GraphicsPath`. + * This method enables the modification of the path's geometry according to the provided + * transformation matrix, which can include translations, rotations, scaling, and skewing. + * + * Each drawing instruction in the path is updated to reflect the transformation, + * ensuring the visual representation of the path is consistent with the applied matrix. + * + * Note: The transformation is applied directly to the coordinates and control points of the drawing instructions, + * not to the path as a whole. This means the transformation's effects are baked into the individual instructions, + * allowing for fine-grained control over the path's appearance. + * @param matrix - A `Matrix` object representing the transformation to apply. + * @returns The instance of the current object for chaining further operations. + */ + transform(matrix) { + if (matrix.isIdentity()) + return this; + const a = matrix.a; + const b = matrix.b; + const c = matrix.c; + const d = matrix.d; + const tx = matrix.tx; + const ty = matrix.ty; + let x = 0; + let y = 0; + let cpx1 = 0; + let cpy1 = 0; + let cpx2 = 0; + let cpy2 = 0; + let rx = 0; + let ry = 0; + for (let i = 0; i < this.instructions.length; i++) { + const instruction = this.instructions[i]; + const data = instruction.data; + switch (instruction.action) { + case "moveTo": + case "lineTo": + x = data[0]; + y = data[1]; + data[0] = a * x + c * y + tx; + data[1] = b * x + d * y + ty; + break; + case "bezierCurveTo": + cpx1 = data[0]; + cpy1 = data[1]; + cpx2 = data[2]; + cpy2 = data[3]; + x = data[4]; + y = data[5]; + data[0] = a * cpx1 + c * cpy1 + tx; + data[1] = b * cpx1 + d * cpy1 + ty; + data[2] = a * cpx2 + c * cpy2 + tx; + data[3] = b * cpx2 + d * cpy2 + ty; + data[4] = a * x + c * y + tx; + data[5] = b * x + d * y + ty; + break; + case "quadraticCurveTo": + cpx1 = data[0]; + cpy1 = data[1]; + x = data[2]; + y = data[3]; + data[0] = a * cpx1 + c * cpy1 + tx; + data[1] = b * cpx1 + d * cpy1 + ty; + data[2] = a * x + c * y + tx; + data[3] = b * x + d * y + ty; + break; + case "arcToSvg": + x = data[5]; + y = data[6]; + rx = data[0]; + ry = data[1]; + data[0] = a * rx + c * ry; + data[1] = b * rx + d * ry; + data[5] = a * x + c * y + tx; + data[6] = b * x + d * y + ty; + break; + case "circle": + data[4] = adjustTransform(data[3], matrix); + break; + case "rect": + data[4] = adjustTransform(data[4], matrix); + break; + case "ellipse": + data[8] = adjustTransform(data[8], matrix); + break; + case "roundRect": + data[5] = adjustTransform(data[5], matrix); + break; + case "addPath": + data[0].transform(matrix); + break; + case "poly": + data[2] = adjustTransform(data[2], matrix); + break; + default: + warn("unknown transform action", instruction.action); + break; + } + } + this._dirty = true; + return this; + } + get bounds() { + return this.shapePath.bounds; + } + /** + * Retrieves the last point from the current drawing instructions in the `GraphicsPath`. + * This method is useful for operations that depend on the path's current endpoint, + * such as connecting subsequent shapes or paths. It supports various drawing instructions, + * ensuring the last point's position is accurately determined regardless of the path's complexity. + * + * If the last instruction is a `closePath`, the method iterates backward through the instructions + * until it finds an actionable instruction that defines a point (e.g., `moveTo`, `lineTo`, + * `quadraticCurveTo`, etc.). For compound paths added via `addPath`, it recursively retrieves + * the last point from the nested path. + * @param out - A `Point` object where the last point's coordinates will be stored. + * This object is modified directly to contain the result. + * @returns The `Point` object containing the last point's coordinates. + */ + getLastPoint(out) { + let index = this.instructions.length - 1; + let lastInstruction = this.instructions[index]; + if (!lastInstruction) { + out.x = 0; + out.y = 0; + return out; + } + while (lastInstruction.action === "closePath") { + index--; + if (index < 0) { + out.x = 0; + out.y = 0; + return out; + } + lastInstruction = this.instructions[index]; + } + switch (lastInstruction.action) { + case "moveTo": + case "lineTo": + out.x = lastInstruction.data[0]; + out.y = lastInstruction.data[1]; + break; + case "quadraticCurveTo": + out.x = lastInstruction.data[2]; + out.y = lastInstruction.data[3]; + break; + case "bezierCurveTo": + out.x = lastInstruction.data[4]; + out.y = lastInstruction.data[5]; + break; + case "arc": + case "arcToSvg": + out.x = lastInstruction.data[5]; + out.y = lastInstruction.data[6]; + break; + case "addPath": + lastInstruction.data[0].getLastPoint(out); + break; + } + return out; + } +} +function adjustTransform(currentMatrix, transform) { + if (currentMatrix) { + return currentMatrix.prepend(transform); + } + return transform.clone(); +} + +"use strict"; +var __defProp$Q = Object.defineProperty; +var __getOwnPropSymbols$Q = Object.getOwnPropertySymbols; +var __hasOwnProp$Q = Object.prototype.hasOwnProperty; +var __propIsEnum$Q = Object.prototype.propertyIsEnumerable; +var __defNormalProp$Q = (obj, key, value) => key in obj ? __defProp$Q(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; +var __spreadValues$Q = (a, b) => { + for (var prop in b || (b = {})) + if (__hasOwnProp$Q.call(b, prop)) + __defNormalProp$Q(a, prop, b[prop]); + if (__getOwnPropSymbols$Q) + for (var prop of __getOwnPropSymbols$Q(b)) { + if (__propIsEnum$Q.call(b, prop)) + __defNormalProp$Q(a, prop, b[prop]); + } + return a; +}; +function SVGParser(svg, graphicsContext) { + if (typeof svg === "string") { + const div = document.createElement("div"); + div.innerHTML = svg.trim(); + svg = div.querySelector("svg"); + } + const session = { + context: graphicsContext, + path: new GraphicsPath() + }; + renderChildren(svg, session, null, null); + return graphicsContext; +} +function renderChildren(svg, session, fillStyle, strokeStyle) { + const children = svg.children; + const { fillStyle: f1, strokeStyle: s1 } = parseStyle(svg); + if (f1 && fillStyle) { + fillStyle = __spreadValues$Q(__spreadValues$Q({}, fillStyle), f1); + } else if (f1) { + fillStyle = f1; + } + if (s1 && strokeStyle) { + strokeStyle = __spreadValues$Q(__spreadValues$Q({}, strokeStyle), s1); + } else if (s1) { + strokeStyle = s1; + } + session.context.fillStyle = fillStyle; + session.context.strokeStyle = strokeStyle; + let x; + let y; + let x1; + let y1; + let x2; + let y2; + let cx; + let cy; + let r; + let rx; + let ry; + let points; + let pointsString; + let d; + let graphicsPath; + let width; + let height; + switch (svg.nodeName.toLowerCase()) { + case "path": + d = svg.getAttribute("d"); + graphicsPath = new GraphicsPath(d); + session.context.path(graphicsPath); + if (fillStyle) + session.context.fill(); + if (strokeStyle) + session.context.stroke(); + break; + case "circle": + cx = parseFloatAttribute(svg, "cx", 0); + cy = parseFloatAttribute(svg, "cy", 0); + r = parseFloatAttribute(svg, "r", 0); + session.context.ellipse(cx, cy, r, r); + if (fillStyle) + session.context.fill(); + if (strokeStyle) + session.context.stroke(); + break; + case "rect": + x = parseFloatAttribute(svg, "x", 0); + y = parseFloatAttribute(svg, "y", 0); + width = parseFloatAttribute(svg, "width", 0); + height = parseFloatAttribute(svg, "height", 0); + rx = parseFloatAttribute(svg, "rx", 0); + ry = parseFloatAttribute(svg, "ry", 0); + if (rx || ry) { + session.context.roundRect(x, y, width, height, rx || ry); + } else { + session.context.rect(x, y, width, height); + } + if (fillStyle) + session.context.fill(); + if (strokeStyle) + session.context.stroke(); + break; + case "ellipse": + cx = parseFloatAttribute(svg, "cx", 0); + cy = parseFloatAttribute(svg, "cy", 0); + rx = parseFloatAttribute(svg, "rx", 0); + ry = parseFloatAttribute(svg, "ry", 0); + session.context.beginPath(); + session.context.ellipse(cx, cy, rx, ry); + if (fillStyle) + session.context.fill(); + if (strokeStyle) + session.context.stroke(); + break; + case "line": + x1 = parseFloatAttribute(svg, "x1", 0); + y1 = parseFloatAttribute(svg, "y1", 0); + x2 = parseFloatAttribute(svg, "x2", 0); + y2 = parseFloatAttribute(svg, "y2", 0); + session.context.beginPath(); + session.context.moveTo(x1, y1); + session.context.lineTo(x2, y2); + if (strokeStyle) + session.context.stroke(); + break; + case "polygon": + pointsString = svg.getAttribute("points"); + points = pointsString.match(/\d+/g).map((n) => parseInt(n, 10)); + session.context.poly(points, true); + if (fillStyle) + session.context.fill(); + if (strokeStyle) + session.context.stroke(); + break; + case "polyline": + pointsString = svg.getAttribute("points"); + points = pointsString.match(/\d+/g).map((n) => parseInt(n, 10)); + session.context.poly(points, false); + if (strokeStyle) + session.context.stroke(); + break; + case "g": + case "svg": + break; + default: { + console.info(`[SVG parser] <${svg.nodeName}> elements unsupported`); + break; + } + } + for (let i = 0; i < children.length; i++) { + renderChildren(children[i], session, fillStyle, strokeStyle); + } +} +function parseFloatAttribute(svg, id, defaultValue) { + const value = svg.getAttribute(id); + return value ? Number(value) : defaultValue; +} +function parseStyle(svg) { + const style = svg.getAttribute("style"); + const strokeStyle = {}; + const fillStyle = {}; + let useFill = false; + let useStroke = false; + if (style) { + const styleParts = style.split(";"); + for (let i = 0; i < styleParts.length; i++) { + const stylePart = styleParts[i]; + const [key, value] = stylePart.split(":"); + switch (key) { + case "stroke": + if (value !== "none") { + strokeStyle.color = Color.shared.setValue(value).toNumber(); + useStroke = true; + } + break; + case "stroke-width": + strokeStyle.width = Number(value); + break; + case "fill": + if (value !== "none") { + useFill = true; + fillStyle.color = Color.shared.setValue(value).toNumber(); + } + break; + case "fill-opacity": + fillStyle.alpha = Number(value); + break; + case "stroke-opacity": + strokeStyle.alpha = Number(value); + break; + case "opacity": + fillStyle.alpha = Number(value); + strokeStyle.alpha = Number(value); + break; + } + } + } else { + const stroke = svg.getAttribute("stroke"); + if (stroke && stroke !== "none") { + useStroke = true; + strokeStyle.color = Color.shared.setValue(stroke).toNumber(); + strokeStyle.width = parseFloatAttribute(svg, "stroke-width", 1); + } + const fill = svg.getAttribute("fill"); + if (fill && fill !== "none") { + useFill = true; + fillStyle.color = Color.shared.setValue(fill).toNumber(); + } + } + return { + strokeStyle: useStroke ? strokeStyle : null, + fillStyle: useFill ? fillStyle : null + }; +} + +"use strict"; +var __defProp$P = Object.defineProperty; +var __defProps$j = Object.defineProperties; +var __getOwnPropDescs$j = Object.getOwnPropertyDescriptors; +var __getOwnPropSymbols$P = Object.getOwnPropertySymbols; +var __hasOwnProp$P = Object.prototype.hasOwnProperty; +var __propIsEnum$P = Object.prototype.propertyIsEnumerable; +var __defNormalProp$P = (obj, key, value) => key in obj ? __defProp$P(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; +var __spreadValues$P = (a, b) => { + for (var prop in b || (b = {})) + if (__hasOwnProp$P.call(b, prop)) + __defNormalProp$P(a, prop, b[prop]); + if (__getOwnPropSymbols$P) + for (var prop of __getOwnPropSymbols$P(b)) { + if (__propIsEnum$P.call(b, prop)) + __defNormalProp$P(a, prop, b[prop]); + } + return a; +}; +var __spreadProps$j = (a, b) => __defProps$j(a, __getOwnPropDescs$j(b)); +function convertFillInputToFillStyle(value, defaultStyle) { + var _a, _b; + if (value === void 0 || value === null) { + return null; + } + let fillStyleToParse; + let styleToMerge; + if (value == null ? void 0 : value.fill) { + styleToMerge = value.fill; + fillStyleToParse = __spreadValues$P(__spreadValues$P({}, defaultStyle), value); + } else { + styleToMerge = value; + fillStyleToParse = defaultStyle; + } + if (Color.isColorLike(styleToMerge)) { + const temp = Color.shared.setValue(styleToMerge != null ? styleToMerge : 0); + const opts = __spreadProps$j(__spreadValues$P({}, fillStyleToParse), { + color: temp.toNumber(), + alpha: temp.alpha === 1 ? fillStyleToParse.alpha : temp.alpha, + texture: Texture.WHITE + }); + return opts; + } else if (styleToMerge instanceof FillPattern) { + const pattern = styleToMerge; + return __spreadProps$j(__spreadValues$P({}, fillStyleToParse), { + color: 16777215, + texture: pattern.texture, + matrix: pattern.transform, + fill: (_a = fillStyleToParse.fill) != null ? _a : null + }); + } else if (styleToMerge instanceof FillGradient) { + const gradient = styleToMerge; + gradient.buildLinearGradient(); + return __spreadProps$j(__spreadValues$P({}, fillStyleToParse), { + color: 16777215, + texture: gradient.texture, + matrix: gradient.transform + }); + } + const style = __spreadValues$P(__spreadValues$P({}, defaultStyle), value); + if (style.texture) { + if (style.texture !== Texture.WHITE) { + const m = ((_b = style.matrix) == null ? void 0 : _b.invert()) || new Matrix(); + m.scale( + 1 / style.texture.frame.width, + 1 / style.texture.frame.height + ); + style.matrix = m; + } + const sourceStyle = style.texture.source.style; + if (sourceStyle.addressMode === "clamp-to-edge") { + sourceStyle.addressMode = "repeat"; + } + } + const color = Color.shared.setValue(style.color); + style.alpha *= color.alpha; + style.color = color.toNumber(); + style.matrix = style.matrix ? style.matrix.clone() : null; + return style; +} + +"use strict"; +var __defProp$O = Object.defineProperty; +var __getOwnPropSymbols$O = Object.getOwnPropertySymbols; +var __hasOwnProp$O = Object.prototype.hasOwnProperty; +var __propIsEnum$O = Object.prototype.propertyIsEnumerable; +var __defNormalProp$O = (obj, key, value) => key in obj ? __defProp$O(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; +var __spreadValues$O = (a, b) => { + for (var prop in b || (b = {})) + if (__hasOwnProp$O.call(b, prop)) + __defNormalProp$O(a, prop, b[prop]); + if (__getOwnPropSymbols$O) + for (var prop of __getOwnPropSymbols$O(b)) { + if (__propIsEnum$O.call(b, prop)) + __defNormalProp$O(a, prop, b[prop]); + } + return a; +}; +const tmpPoint = new Point(); +const tempMatrix$2 = new Matrix(); +const _GraphicsContext = class _GraphicsContext extends EventEmitter { + constructor() { + super(...arguments); + this.uid = uid("graphicsContext"); + this.dirty = true; + this.batchMode = "auto"; + this.instructions = []; + this._activePath = new GraphicsPath(); + this._transform = new Matrix(); + this._fillStyle = __spreadValues$O({}, _GraphicsContext.defaultFillStyle); + this._strokeStyle = __spreadValues$O({}, _GraphicsContext.defaultStrokeStyle); + this._stateStack = []; + this._tick = 0; + this._bounds = new Bounds(); + this._boundsDirty = true; + } + /** + * Creates a new GraphicsContext object that is a clone of this instance, copying all properties, + * including the current drawing state, transformations, styles, and instructions. + * @returns A new GraphicsContext instance with the same properties and state as this one. + */ + clone() { + const clone = new _GraphicsContext(); + clone.batchMode = this.batchMode; + clone.instructions = this.instructions.slice(); + clone._activePath = this._activePath.clone(); + clone._transform = this._transform.clone(); + clone._fillStyle = __spreadValues$O({}, this._fillStyle); + clone._strokeStyle = __spreadValues$O({}, this._strokeStyle); + clone._stateStack = this._stateStack.slice(); + clone._bounds = this._bounds.clone(); + clone._boundsDirty = true; + return clone; + } + /** + * The current fill style of the graphics context. This can be a color, gradient, pattern, or a more complex style defined by a FillStyle object. + */ + get fillStyle() { + return this._fillStyle; + } + set fillStyle(value) { + this._fillStyle = convertFillInputToFillStyle(value, _GraphicsContext.defaultFillStyle); + } + /** + * The current stroke style of the graphics context. Similar to fill styles, stroke styles can encompass colors, gradients, patterns, or more detailed configurations via a StrokeStyle object. + */ + get strokeStyle() { + return this._strokeStyle; + } + set strokeStyle(value) { + this._strokeStyle = convertFillInputToFillStyle(value, _GraphicsContext.defaultStrokeStyle); + } + /** + * Sets the current fill style of the graphics context. The fill style can be a color, gradient, + * pattern, or a more complex style defined by a FillStyle object. + * @param style - The fill style to apply. This can be a simple color, a gradient or pattern object, + * or a FillStyle or ConvertedFillStyle object. + * @returns The instance of the current GraphicsContext for method chaining. + */ + setFillStyle(style) { + this._fillStyle = convertFillInputToFillStyle(style, _GraphicsContext.defaultFillStyle); + return this; + } + /** + * Sets the current stroke style of the graphics context. Similar to fill styles, stroke styles can + * encompass colors, gradients, patterns, or more detailed configurations via a StrokeStyle object. + * @param style - The stroke style to apply. Can be defined as a color, a gradient or pattern, + * or a StrokeStyle or ConvertedStrokeStyle object. + * @returns The instance of the current GraphicsContext for method chaining. + */ + setStrokeStyle(style) { + this._strokeStyle = convertFillInputToFillStyle(style, _GraphicsContext.defaultStrokeStyle); + return this; + } + texture(texture, tint, dx, dy, dw, dh) { + this.instructions.push({ + action: "texture", + data: { + image: texture, + dx: dx || 0, + dy: dy || 0, + dw: dw || texture.frame.width, + dh: dh || texture.frame.height, + transform: this._transform.clone(), + alpha: this._fillStyle.alpha, + style: tint ? Color.shared.setValue(tint).toNumber() : 16777215 + } + }); + this.onUpdate(); + return this; + } + /** + * Resets the current path. Any previous path and its commands are discarded and a new path is + * started. This is typically called before beginning a new shape or series of drawing commands. + * @returns The instance of the current GraphicsContext for method chaining. + */ + beginPath() { + this._activePath = new GraphicsPath(); + return this; + } + fill(style, alpha) { + let path; + const lastInstruction = this.instructions[this.instructions.length - 1]; + if (this._tick === 0 && lastInstruction && lastInstruction.action === "stroke") { + path = lastInstruction.data.path; + } else { + path = this._activePath.clone(); + } + if (!path) + return this; + if (style != null) { + if (alpha !== void 0 && typeof style === "number") { + deprecation(v8_0_0, "GraphicsContext.fill(color, alpha) is deprecated, use GraphicsContext.fill({ color, alpha }) instead"); + style = { color: style, alpha }; + } + this._fillStyle = convertFillInputToFillStyle(style, _GraphicsContext.defaultFillStyle); + } + this.instructions.push({ + action: "fill", + // TODO copy fill style! + data: { style: this.fillStyle, path } + }); + this.onUpdate(); + this._initNextPathLocation(); + this._tick = 0; + return this; + } + _initNextPathLocation() { + const { x, y } = this._activePath.getLastPoint(Point.shared); + this._activePath.clear(); + this._activePath.moveTo(x, y); + } + /** + * Strokes the current path with the current stroke style. This method can take an optional + * FillStyleInputs parameter to define the stroke's appearance, including its color, width, and other properties. + * @param style - (Optional) The stroke style to apply. Can be defined as a simple color or a more complex style object. If omitted, uses the current stroke style. + * @returns The instance of the current GraphicsContext for method chaining. + */ + stroke(style) { + let path; + const lastInstruction = this.instructions[this.instructions.length - 1]; + if (this._tick === 0 && lastInstruction && lastInstruction.action === "fill") { + path = lastInstruction.data.path; + } else { + path = this._activePath.clone(); + } + if (!path) + return this; + if (style != null) { + this._strokeStyle = convertFillInputToFillStyle(style, _GraphicsContext.defaultStrokeStyle); + } + this.instructions.push({ + action: "stroke", + // TODO copy fill style! + data: { style: this.strokeStyle, path } + }); + this.onUpdate(); + this._initNextPathLocation(); + this._tick = 0; + return this; + } + /** + * Applies a cutout to the last drawn shape. This is used to create holes or complex shapes by + * subtracting a path from the previously drawn path. If a hole is not completely in a shape, it will + * fail to cut correctly! + * @returns The instance of the current GraphicsContext for method chaining. + */ + cut() { + for (let i = 0; i < 2; i++) { + const lastInstruction = this.instructions[this.instructions.length - 1 - i]; + const holePath = this._activePath.clone(); + if (lastInstruction) { + if (lastInstruction.action === "stroke" || lastInstruction.action === "fill") { + if (lastInstruction.data.hole) { + lastInstruction.data.hole.addPath(holePath); + } else { + lastInstruction.data.hole = holePath; + break; + } + } + } + } + this._initNextPathLocation(); + return this; + } + /** + * Adds an arc to the current path, which is centered at (x, y) with the specified radius, + * starting and ending angles, and direction. + * @param x - The x-coordinate of the arc's center. + * @param y - The y-coordinate of the arc's center. + * @param radius - The arc's radius. + * @param startAngle - The starting angle, in radians. + * @param endAngle - The ending angle, in radians. + * @param counterclockwise - (Optional) Specifies whether the arc is drawn counterclockwise (true) or clockwise (false). Defaults to false. + * @returns The instance of the current GraphicsContext for method chaining. + */ + arc(x, y, radius, startAngle, endAngle, counterclockwise) { + this._tick++; + const t = this._transform; + this._activePath.arc( + t.a * x + t.c * y + t.tx, + t.b * x + t.d * y + t.ty, + radius, + startAngle, + endAngle, + counterclockwise + ); + return this; + } + /** + * Adds an arc to the current path with the given control points and radius, connected to the previous point + * by a straight line if necessary. + * @param x1 - The x-coordinate of the first control point. + * @param y1 - The y-coordinate of the first control point. + * @param x2 - The x-coordinate of the second control point. + * @param y2 - The y-coordinate of the second control point. + * @param radius - The arc's radius. + * @returns The instance of the current GraphicsContext for method chaining. + */ + arcTo(x1, y1, x2, y2, radius) { + this._tick++; + const t = this._transform; + this._activePath.arcTo( + t.a * x1 + t.c * y1 + t.tx, + t.b * x1 + t.d * y1 + t.ty, + t.a * x2 + t.c * y2 + t.tx, + t.b * x2 + t.d * y2 + t.ty, + radius + ); + return this; + } + /** + * Adds an SVG-style arc to the path, allowing for elliptical arcs based on the SVG spec. + * @param rx - The x-radius of the ellipse. + * @param ry - The y-radius of the ellipse. + * @param xAxisRotation - The rotation of the ellipse's x-axis relative + * to the x-axis of the coordinate system, in degrees. + * @param largeArcFlag - Determines if the arc should be greater than or less than 180 degrees. + * @param sweepFlag - Determines if the arc should be swept in a positive angle direction. + * @param x - The x-coordinate of the arc's end point. + * @param y - The y-coordinate of the arc's end point. + * @returns The instance of the current object for chaining. + */ + arcToSvg(rx, ry, xAxisRotation, largeArcFlag, sweepFlag, x, y) { + this._tick++; + const t = this._transform; + this._activePath.arcToSvg( + rx, + ry, + xAxisRotation, + // should we rotate this with transform?? + largeArcFlag, + sweepFlag, + t.a * x + t.c * y + t.tx, + t.b * x + t.d * y + t.ty + ); + return this; + } + /** + * Adds a cubic Bezier curve to the path. + * It requires three points: the first two are control points and the third one is the end point. + * The starting point is the last point in the current path. + * @param cp1x - The x-coordinate of the first control point. + * @param cp1y - The y-coordinate of the first control point. + * @param cp2x - The x-coordinate of the second control point. + * @param cp2y - The y-coordinate of the second control point. + * @param x - The x-coordinate of the end point. + * @param y - The y-coordinate of the end point. + * @param smoothness - Optional parameter to adjust the smoothness of the curve. + * @returns The instance of the current object for chaining. + */ + bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y, smoothness) { + this._tick++; + const t = this._transform; + this._activePath.bezierCurveTo( + t.a * cp1x + t.c * cp1y + t.tx, + t.b * cp1x + t.d * cp1y + t.ty, + t.a * cp2x + t.c * cp2y + t.tx, + t.b * cp2x + t.d * cp2y + t.ty, + t.a * x + t.c * y + t.tx, + t.b * x + t.d * y + t.ty, + smoothness + ); + return this; + } + /** + * Closes the current path by drawing a straight line back to the start. + * If the shape is already closed or there are no points in the path, this method does nothing. + * @returns The instance of the current object for chaining. + */ + closePath() { + var _a; + this._tick++; + (_a = this._activePath) == null ? void 0 : _a.closePath(); + return this; + } + /** + * Draws an ellipse at the specified location and with the given x and y radii. + * An optional transformation can be applied, allowing for rotation, scaling, and translation. + * @param x - The x-coordinate of the center of the ellipse. + * @param y - The y-coordinate of the center of the ellipse. + * @param radiusX - The horizontal radius of the ellipse. + * @param radiusY - The vertical radius of the ellipse. + * @returns The instance of the current object for chaining. + */ + ellipse(x, y, radiusX, radiusY) { + this._tick++; + this._activePath.ellipse(x, y, radiusX, radiusY, this._transform.clone()); + return this; + } + /** + * Draws a circle shape. This method adds a new circle path to the current drawing. + * @param x - The x-coordinate of the center of the circle. + * @param y - The y-coordinate of the center of the circle. + * @param radius - The radius of the circle. + * @returns The instance of the current object for chaining. + */ + circle(x, y, radius) { + this._tick++; + this._activePath.circle(x, y, radius, this._transform.clone()); + return this; + } + /** + * Adds another `GraphicsPath` to this path, optionally applying a transformation. + * @param path - The `GraphicsPath` to add. + * @returns The instance of the current object for chaining. + */ + path(path) { + this._tick++; + this._activePath.addPath(path, this._transform.clone()); + return this; + } + /** + * Connects the current point to a new point with a straight line. This method updates the current path. + * @param x - The x-coordinate of the new point to connect to. + * @param y - The y-coordinate of the new point to connect to. + * @returns The instance of the current object for chaining. + */ + lineTo(x, y) { + this._tick++; + const t = this._transform; + this._activePath.lineTo( + t.a * x + t.c * y + t.tx, + t.b * x + t.d * y + t.ty + ); + return this; + } + /** + * Sets the starting point for a new sub-path. Any subsequent drawing commands are considered part of this path. + * @param x - The x-coordinate for the starting point. + * @param y - The y-coordinate for the starting point. + * @returns The instance of the current object for chaining. + */ + moveTo(x, y) { + this._tick++; + const t = this._transform; + const instructions = this._activePath.instructions; + const transformedX = t.a * x + t.c * y + t.tx; + const transformedY = t.b * x + t.d * y + t.ty; + if (instructions.length === 1 && instructions[0].action === "moveTo") { + instructions[0].data[0] = transformedX; + instructions[0].data[1] = transformedY; + return this; + } + this._activePath.moveTo( + transformedX, + transformedY + ); + return this; + } + /** + * Adds a quadratic curve to the path. It requires two points: the control point and the end point. + * The starting point is the last point in the current path. + * @param cpx - The x-coordinate of the control point. + * @param cpy - The y-coordinate of the control point. + * @param x - The x-coordinate of the end point. + * @param y - The y-coordinate of the end point. + * @param smoothness - Optional parameter to adjust the smoothness of the curve. + * @returns The instance of the current object for chaining. + */ + quadraticCurveTo(cpx, cpy, x, y, smoothness) { + this._tick++; + const t = this._transform; + this._activePath.quadraticCurveTo( + t.a * cpx + t.c * cpy + t.tx, + t.b * cpx + t.d * cpy + t.ty, + t.a * x + t.c * y + t.tx, + t.b * x + t.d * y + t.ty, + smoothness + ); + return this; + } + /** + * Draws a rectangle shape. This method adds a new rectangle path to the current drawing. + * @param x - The x-coordinate of the top-left corner of the rectangle. + * @param y - The y-coordinate of the top-left corner of the rectangle. + * @param w - The width of the rectangle. + * @param h - The height of the rectangle. + * @returns The instance of the current object for chaining. + */ + rect(x, y, w, h) { + this._tick++; + this._activePath.rect(x, y, w, h, this._transform.clone()); + return this; + } + /** + * Draws a rectangle with rounded corners. + * The corner radius can be specified to determine how rounded the corners should be. + * An optional transformation can be applied, which allows for rotation, scaling, and translation of the rectangle. + * @param x - The x-coordinate of the top-left corner of the rectangle. + * @param y - The y-coordinate of the top-left corner of the rectangle. + * @param w - The width of the rectangle. + * @param h - The height of the rectangle. + * @param radius - The radius of the rectangle's corners. If not specified, corners will be sharp. + * @returns The instance of the current object for chaining. + */ + roundRect(x, y, w, h, radius) { + this._tick++; + this._activePath.roundRect(x, y, w, h, radius, this._transform.clone()); + return this; + } + /** + * Draws a polygon shape by specifying a sequence of points. This method allows for the creation of complex polygons, + * which can be both open and closed. An optional transformation can be applied, enabling the polygon to be scaled, + * rotated, or translated as needed. + * @param points - An array of numbers, or an array of PointData objects eg [{x,y}, {x,y}, {x,y}] + * representing the x and y coordinates, of the polygon's vertices, in sequence. + * @param close - A boolean indicating whether to close the polygon path. True by default. + */ + poly(points, close) { + this._tick++; + this._activePath.poly(points, close, this._transform.clone()); + return this; + } + /** + * Draws a regular polygon with a specified number of sides. All sides and angles are equal. + * @param x - The x-coordinate of the center of the polygon. + * @param y - The y-coordinate of the center of the polygon. + * @param radius - The radius of the circumscribed circle of the polygon. + * @param sides - The number of sides of the polygon. Must be 3 or more. + * @param rotation - The rotation angle of the polygon, in radians. Zero by default. + * @param transform - An optional `Matrix` object to apply a transformation to the polygon. + * @returns The instance of the current object for chaining. + */ + regularPoly(x, y, radius, sides, rotation = 0, transform) { + this._tick++; + this._activePath.regularPoly(x, y, radius, sides, rotation, transform); + return this; + } + /** + * Draws a polygon with rounded corners. + * Similar to `regularPoly` but with the ability to round the corners of the polygon. + * @param x - The x-coordinate of the center of the polygon. + * @param y - The y-coordinate of the center of the polygon. + * @param radius - The radius of the circumscribed circle of the polygon. + * @param sides - The number of sides of the polygon. Must be 3 or more. + * @param corner - The radius of the rounding of the corners. + * @param rotation - The rotation angle of the polygon, in radians. Zero by default. + * @returns The instance of the current object for chaining. + */ + roundPoly(x, y, radius, sides, corner, rotation) { + this._tick++; + this._activePath.roundPoly(x, y, radius, sides, corner, rotation); + return this; + } + /** + * Draws a shape with rounded corners. This function supports custom radius for each corner of the shape. + * Optionally, corners can be rounded using a quadratic curve instead of an arc, providing a different aesthetic. + * @param points - An array of `RoundedPoint` representing the corners of the shape to draw. + * A minimum of 3 points is required. + * @param radius - The default radius for the corners. + * This radius is applied to all corners unless overridden in `points`. + * @param useQuadratic - If set to true, rounded corners are drawn using a quadraticCurve + * method instead of an arc method. Defaults to false. + * @param smoothness - Specifies the smoothness of the curve when `useQuadratic` is true. + * Higher values make the curve smoother. + * @returns The instance of the current object for chaining. + */ + roundShape(points, radius, useQuadratic, smoothness) { + this._tick++; + this._activePath.roundShape(points, radius, useQuadratic, smoothness); + return this; + } + /** + * Draw Rectangle with fillet corners. This is much like rounded rectangle + * however it support negative numbers as well for the corner radius. + * @param x - Upper left corner of rect + * @param y - Upper right corner of rect + * @param width - Width of rect + * @param height - Height of rect + * @param fillet - accept negative or positive values + */ + filletRect(x, y, width, height, fillet) { + this._tick++; + this._activePath.filletRect(x, y, width, height, fillet); + return this; + } + /** + * Draw Rectangle with chamfer corners. These are angled corners. + * @param x - Upper left corner of rect + * @param y - Upper right corner of rect + * @param width - Width of rect + * @param height - Height of rect + * @param chamfer - non-zero real number, size of corner cutout + * @param transform + */ + chamferRect(x, y, width, height, chamfer, transform) { + this._tick++; + this._activePath.chamferRect(x, y, width, height, chamfer, transform); + return this; + } + /** + * Draws a star shape centered at a specified location. This method allows for the creation + * of stars with a variable number of points, outer radius, optional inner radius, and rotation. + * The star is drawn as a closed polygon with alternating outer and inner vertices to create the star's points. + * An optional transformation can be applied to scale, rotate, or translate the star as needed. + * @param x - The x-coordinate of the center of the star. + * @param y - The y-coordinate of the center of the star. + * @param points - The number of points of the star. + * @param radius - The outer radius of the star (distance from the center to the outer points). + * @param innerRadius - Optional. The inner radius of the star + * (distance from the center to the inner points between the outer points). + * If not provided, defaults to half of the `radius`. + * @param rotation - Optional. The rotation of the star in radians, where 0 is aligned with the y-axis. + * Defaults to 0, meaning one point is directly upward. + * @returns The instance of the current object for chaining further drawing commands. + */ + star(x, y, points, radius, innerRadius = 0, rotation = 0) { + this._tick++; + this._activePath.star(x, y, points, radius, innerRadius, rotation, this._transform.clone()); + return this; + } + /** + * Parses and renders an SVG string into the graphics context. This allows for complex shapes and paths + * defined in SVG format to be drawn within the graphics context. + * @param svg - The SVG string to be parsed and rendered. + */ + svg(svg) { + this._tick++; + SVGParser(svg, this); + return this; + } + /** + * Restores the most recently saved graphics state by popping the top of the graphics state stack. + * This includes transformations, fill styles, and stroke styles. + */ + restore() { + const state = this._stateStack.pop(); + if (state) { + this._transform = state.transform; + this._fillStyle = state.fillStyle; + this._strokeStyle = state.strokeStyle; + } + return this; + } + /** Saves the current graphics state, including transformations, fill styles, and stroke styles, onto a stack. */ + save() { + this._stateStack.push({ + transform: this._transform.clone(), + fillStyle: __spreadValues$O({}, this._fillStyle), + strokeStyle: __spreadValues$O({}, this._strokeStyle) + }); + return this; + } + /** + * Returns the current transformation matrix of the graphics context. + * @returns The current transformation matrix. + */ + getTransform() { + return this._transform; + } + /** + * Resets the current transformation matrix to the identity matrix, effectively removing any transformations (rotation, scaling, translation) previously applied. + * @returns The instance of the current GraphicsContext for method chaining. + */ + resetTransform() { + this._transform.identity(); + return this; + } + /** + * Applies a rotation transformation to the graphics context around the current origin. + * @param angle - The angle of rotation in radians. + * @returns The instance of the current GraphicsContext for method chaining. + */ + rotate(angle) { + this._transform.rotate(angle); + return this; + } + /** + * Applies a scaling transformation to the graphics context, scaling drawings by x horizontally and by y vertically. + * @param x - The scale factor in the horizontal direction. + * @param y - (Optional) The scale factor in the vertical direction. If not specified, the x value is used for both directions. + * @returns The instance of the current GraphicsContext for method chaining. + */ + scale(x, y = x) { + this._transform.scale(x, y); + return this; + } + setTransform(a, b, c, d, dx, dy) { + if (a instanceof Matrix) { + this._transform.set(a.a, a.b, a.c, a.d, a.tx, a.ty); + return this; + } + this._transform.set(a, b, c, d, dx, dy); + return this; + } + transform(a, b, c, d, dx, dy) { + if (a instanceof Matrix) { + this._transform.append(a); + return this; + } + tempMatrix$2.set(a, b, c, d, dx, dy); + this._transform.append(tempMatrix$2); + return this; + } + /** + * Applies a translation transformation to the graphics context, moving the origin by the specified amounts. + * @param x - The amount to translate in the horizontal direction. + * @param y - (Optional) The amount to translate in the vertical direction. If not specified, the x value is used for both directions. + * @returns The instance of the current GraphicsContext for method chaining. + */ + translate(x, y = x) { + this._transform.translate(x, y); + return this; + } + /** + * Clears all drawing commands from the graphics context, effectively resetting it. This includes clearing the path, + * and optionally resetting transformations to the identity matrix. + * @returns The instance of the current GraphicsContext for method chaining. + */ + clear() { + this.instructions.length = 0; + this.resetTransform(); + this.onUpdate(); + return this; + } + onUpdate() { + if (this.dirty) + return; + this.emit("update", this, 16); + this.dirty = true; + this._boundsDirty = true; + } + /** The bounds of the graphic shape. */ + get bounds() { + if (!this._boundsDirty) + return this._bounds; + const bounds = this._bounds; + bounds.clear(); + for (let i = 0; i < this.instructions.length; i++) { + const instruction = this.instructions[i]; + const action = instruction.action; + if (action === "fill") { + const data = instruction.data; + bounds.addBounds(data.path.bounds); + } else if (action === "texture") { + const data = instruction.data; + bounds.addFrame(data.dx, data.dy, data.dx + data.dw, data.dy + data.dh, data.transform); + } + if (action === "stroke") { + const data = instruction.data; + const padding = data.style.width / 2; + const _bounds = data.path.bounds; + bounds.addFrame( + _bounds.minX - padding, + _bounds.minY - padding, + _bounds.maxX + padding, + _bounds.maxY + padding + ); + } + } + return bounds; + } + /** + * Check to see if a point is contained within this geometry. + * @param point - Point to check if it's contained. + * @returns {boolean} `true` if the point is contained within geometry. + */ + containsPoint(point) { + var _a; + if (!this.bounds.containsPoint(point.x, point.y)) + return false; + const instructions = this.instructions; + let hasHit = false; + for (let k = 0; k < instructions.length; k++) { + const instruction = instructions[k]; + const data = instruction.data; + const path = data.path; + if (!instruction.action || !path) + continue; + const style = data.style; + const shapes = path.shapePath.shapePrimitives; + for (let i = 0; i < shapes.length; i++) { + const shape = shapes[i].shape; + if (!style || !shape) + continue; + const transform = shapes[i].transform; + const transformedPoint = transform ? transform.applyInverse(point, tmpPoint) : point; + if (instruction.action === "fill") { + hasHit = shape.contains(transformedPoint.x, transformedPoint.y); + } else { + hasHit = shape.strokeContains(transformedPoint.x, transformedPoint.y, style.width); + } + const holes = data.hole; + if (holes) { + const holeShapes = (_a = holes.shapePath) == null ? void 0 : _a.shapePrimitives; + if (holeShapes) { + for (let j = 0; j < holeShapes.length; j++) { + if (holeShapes[j].shape.contains(transformedPoint.x, transformedPoint.y)) { + hasHit = false; + } + } + } + } + if (hasHit) { + return true; + } + } + } + return hasHit; + } + /** + * Destroys the GraphicsData object. + * @param options - Options parameter. A boolean will act as if all options + * have been set to that value + * @param {boolean} [options.texture=false] - Should it destroy the current texture of the fill/stroke style? + * @param {boolean} [options.textureSource=false] - Should it destroy the texture source of the fill/stroke style? + */ + destroy(options = false) { + this._stateStack.length = 0; + this._transform = null; + this.emit("destroy", this); + this.removeAllListeners(); + const destroyTexture = typeof options === "boolean" ? options : options == null ? void 0 : options.texture; + if (destroyTexture) { + const destroyTextureSource = typeof options === "boolean" ? options : options == null ? void 0 : options.textureSource; + if (this._fillStyle.texture) { + this._fillStyle.texture.destroy(destroyTextureSource); + } + if (this._strokeStyle.texture) { + this._strokeStyle.texture.destroy(destroyTextureSource); + } + } + this._fillStyle = null; + this._strokeStyle = null; + this.instructions = null; + this._activePath = null; + this._bounds = null; + this._stateStack = null; + this.customShader = null; + this._transform = null; + } +}; +/** The default fill style to use when none is provided. */ +_GraphicsContext.defaultFillStyle = { + /** The color to use for the fill. */ + color: 16777215, + /** The alpha value to use for the fill. */ + alpha: 1, + /** The texture to use for the fill. */ + texture: Texture.WHITE, + /** The matrix to apply. */ + matrix: null, + /** The fill pattern to use. */ + fill: null +}; +/** The default stroke style to use when none is provided. */ +_GraphicsContext.defaultStrokeStyle = { + /** The width of the stroke. */ + width: 1, + /** The color to use for the stroke. */ + color: 16777215, + /** The alpha value to use for the stroke. */ + alpha: 1, + /** The alignment of the stroke. */ + alignment: 0.5, + /** The miter limit to use. */ + miterLimit: 10, + /** The line cap style to use. */ + cap: "butt", + /** The line join style to use. */ + join: "miter", + /** The texture to use for the fill. */ + texture: Texture.WHITE, + /** The matrix to apply. */ + matrix: null, + /** The fill pattern to use. */ + fill: null +}; +let GraphicsContext = _GraphicsContext; + +"use strict"; +const valuesToIterateForKeys = [ + "_fontFamily", + "_fontStyle", + "_fontSize", + "_fontVariant", + "_fontWeight", + "_breakWords", + "_align", + "_leading", + "_letterSpacing", + "_lineHeight", + "_textBaseline", + "_whiteSpace", + "_wordWrap", + "_wordWrapWidth", + "_padding", + "_cssOverrides", + "_trim" +]; +function generateTextStyleKey(style) { + const key = []; + let index = 0; + for (let i = 0; i < valuesToIterateForKeys.length; i++) { + const prop = valuesToIterateForKeys[i]; + key[index++] = style[prop]; + } + index = addFillStyleKey(style._fill, key, index); + index = addStokeStyleKey(style._stroke, key, index); + return key.join("-"); +} +function addFillStyleKey(fillStyle, key, index) { + var _a; + if (!fillStyle) + return index; + key[index++] = fillStyle.color; + key[index++] = fillStyle.alpha; + key[index++] = (_a = fillStyle.fill) == null ? void 0 : _a.uid; + return index; +} +function addStokeStyleKey(strokeStyle, key, index) { + if (!strokeStyle) + return index; + index = addFillStyleKey(strokeStyle, key, index); + key[index++] = strokeStyle.width; + key[index++] = strokeStyle.alignment; + key[index++] = strokeStyle.cap; + key[index++] = strokeStyle.join; + key[index++] = strokeStyle.miterLimit; + return index; +} + +"use strict"; +var __defProp$N = Object.defineProperty; +var __getOwnPropSymbols$N = Object.getOwnPropertySymbols; +var __hasOwnProp$N = Object.prototype.hasOwnProperty; +var __propIsEnum$N = Object.prototype.propertyIsEnumerable; +var __defNormalProp$N = (obj, key, value) => key in obj ? __defProp$N(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; +var __spreadValues$N = (a, b) => { + for (var prop in b || (b = {})) + if (__hasOwnProp$N.call(b, prop)) + __defNormalProp$N(a, prop, b[prop]); + if (__getOwnPropSymbols$N) + for (var prop of __getOwnPropSymbols$N(b)) { + if (__propIsEnum$N.call(b, prop)) + __defNormalProp$N(a, prop, b[prop]); + } + return a; +}; +const _TextStyle = class _TextStyle extends EventEmitter { + constructor(style = {}) { + super(); + convertV7Tov8Style(style); + const fullStyle = __spreadValues$N(__spreadValues$N({}, _TextStyle.defaultTextStyle), style); + for (const key in fullStyle) { + const thisKey = key; + this[thisKey] = fullStyle[key]; + } + this.update(); + } + /** + * Alignment for multiline text, does not affect single line text. + * @member {'left'|'center'|'right'|'justify'} + */ + get align() { + return this._align; + } + set align(value) { + this._align = value; + this.update(); + } + /** Indicates if lines can be wrapped within words, it needs wordWrap to be set to true. */ + get breakWords() { + return this._breakWords; + } + set breakWords(value) { + this._breakWords = value; + this.update(); + } + /** Set a drop shadow for the text. */ + get dropShadow() { + return this._dropShadow; + } + set dropShadow(value) { + if (value !== null && typeof value === "object") { + this._dropShadow = __spreadValues$N(__spreadValues$N({}, _TextStyle.defaultDropShadow), value); + } else { + this._dropShadow = value ? __spreadValues$N({}, _TextStyle.defaultDropShadow) : null; + } + this.update(); + } + /** The font family, can be a single font name, or a list of names where the first is the preferred font. */ + get fontFamily() { + return this._fontFamily; + } + set fontFamily(value) { + this._fontFamily = value; + this.update(); + } + /** The font size (as a number it converts to px, but as a string, equivalents are '26px','20pt','160%' or '1.6em') */ + get fontSize() { + return this._fontSize; + } + set fontSize(value) { + if (typeof value === "string") { + this._fontSize = parseInt(value, 10); + } else { + this._fontSize = value; + } + this.update(); + } + /** + * The font style. + * @member {'normal'|'italic'|'oblique'} + */ + get fontStyle() { + return this._fontStyle; + } + set fontStyle(value) { + this._fontStyle = value; + this.update(); + } + /** + * The font variant. + * @member {'normal'|'small-caps'} + */ + get fontVariant() { + return this._fontVariant; + } + set fontVariant(value) { + this._fontVariant = value; + this.update(); + } + /** + * The font weight. + * @member {'normal'|'bold'|'bolder'|'lighter'|'100'|'200'|'300'|'400'|'500'|'600'|'700'|'800'|'900'} + */ + get fontWeight() { + return this._fontWeight; + } + set fontWeight(value) { + this._fontWeight = value; + this.update(); + } + /** The space between lines. */ + get leading() { + return this._leading; + } + set leading(value) { + this._leading = value; + this.update(); + } + /** The amount of spacing between letters, default is 0. */ + get letterSpacing() { + return this._letterSpacing; + } + set letterSpacing(value) { + this._letterSpacing = value; + this.update(); + } + /** The line height, a number that represents the vertical space that a letter uses. */ + get lineHeight() { + return this._lineHeight; + } + set lineHeight(value) { + this._lineHeight = value; + this.update(); + } + /** + * Occasionally some fonts are cropped. Adding some padding will prevent this from happening + * by adding padding to all sides of the text. + */ + get padding() { + return this._padding; + } + set padding(value) { + this._padding = value; + this.update(); + } + /** Trim transparent borders. This is an expensive operation so only use this if you have to! */ + get trim() { + return this._trim; + } + set trim(value) { + this._trim = value; + this.update(); + } + /** + * The baseline of the text that is rendered. + * @member {'alphabetic'|'top'|'hanging'|'middle'|'ideographic'|'bottom'} + */ + get textBaseline() { + return this._textBaseline; + } + set textBaseline(value) { + this._textBaseline = value; + this.update(); + } + /** + * How newlines and spaces should be handled. + * Default is 'pre' (preserve, preserve). + * + * value | New lines | Spaces + * --- | --- | --- + * 'normal' | Collapse | Collapse + * 'pre' | Preserve | Preserve + * 'pre-line' | Preserve | Collapse + * @member {'normal'|'pre'|'pre-line'} + */ + get whiteSpace() { + return this._whiteSpace; + } + set whiteSpace(value) { + this._whiteSpace = value; + this.update(); + } + /** Indicates if word wrap should be used. */ + get wordWrap() { + return this._wordWrap; + } + set wordWrap(value) { + this._wordWrap = value; + this.update(); + } + /** The width at which text will wrap, it needs wordWrap to be set to true. */ + get wordWrapWidth() { + return this._wordWrapWidth; + } + set wordWrapWidth(value) { + this._wordWrapWidth = value; + this.update(); + } + /** A fillstyle that will be used on the text e.g., 'red', '#00FF00'. */ + get fill() { + return this._originalFill; + } + set fill(value) { + if (value === this._originalFill) + return; + this._originalFill = value; + this._fill = convertFillInputToFillStyle( + value === 0 ? "black" : value, + GraphicsContext.defaultFillStyle + ); + this.update(); + } + /** A fillstyle that will be used on the text stroke, e.g., 'blue', '#FCFF00'. */ + get stroke() { + return this._originalStroke; + } + set stroke(value) { + if (value === this._originalStroke) + return; + this._originalStroke = value; + this._stroke = convertFillInputToFillStyle(value, GraphicsContext.defaultStrokeStyle); + this.update(); + } + _generateKey() { + this._styleKey = generateTextStyleKey(this); + return this._styleKey; + } + update() { + this._styleKey = null; + this.emit("update", this); + } + /** Resets all properties to the default values */ + reset() { + const defaultStyle = _TextStyle.defaultTextStyle; + for (const key in defaultStyle) { + this[key] = defaultStyle[key]; + } + } + get styleKey() { + return this._styleKey || this._generateKey(); + } + /** + * Creates a new TextStyle object with the same values as this one. + * @returns New cloned TextStyle object + */ + clone() { + return new _TextStyle({ + align: this.align, + breakWords: this.breakWords, + dropShadow: this.dropShadow, + fill: this._fill, + fontFamily: this.fontFamily, + fontSize: this.fontSize, + fontStyle: this.fontStyle, + fontVariant: this.fontVariant, + fontWeight: this.fontWeight, + leading: this.leading, + letterSpacing: this.letterSpacing, + lineHeight: this.lineHeight, + padding: this.padding, + stroke: this._stroke, + textBaseline: this.textBaseline, + whiteSpace: this.whiteSpace, + wordWrap: this.wordWrap, + wordWrapWidth: this.wordWrapWidth + }); + } + /** + * Destroys this text style. + * @param options - Options parameter. A boolean will act as if all options + * have been set to that value + * @param {boolean} [options.texture=false] - Should it destroy the texture of the this style + * @param {boolean} [options.textureSource=false] - Should it destroy the textureSource of the this style + */ + destroy(options = false) { + var _a, _b, _c, _d; + this.removeAllListeners(); + const destroyTexture = typeof options === "boolean" ? options : options == null ? void 0 : options.texture; + if (destroyTexture) { + const destroyTextureSource = typeof options === "boolean" ? options : options == null ? void 0 : options.textureSource; + if ((_a = this._fill) == null ? void 0 : _a.texture) { + this._fill.texture.destroy(destroyTextureSource); + } + if ((_b = this._originalFill) == null ? void 0 : _b.texture) { + this._originalFill.texture.destroy(destroyTextureSource); + } + if ((_c = this._stroke) == null ? void 0 : _c.texture) { + this._stroke.texture.destroy(destroyTextureSource); + } + if ((_d = this._originalStroke) == null ? void 0 : _d.texture) { + this._originalStroke.texture.destroy(destroyTextureSource); + } + } + this._fill = null; + this._stroke = null; + this.dropShadow = null; + this._originalStroke = null; + this._originalFill = null; + } +}; +/** The default drop shadow settings */ +_TextStyle.defaultDropShadow = { + /** Set alpha for the drop shadow */ + alpha: 1, + /** Set a angle of the drop shadow */ + angle: Math.PI / 6, + /** Set a shadow blur radius */ + blur: 0, + /** A fill style to be used on the e.g., 'red', '#00FF00' */ + color: "black", + /** Set a distance of the drop shadow */ + distance: 5 +}; +/** The default text style settings */ +_TextStyle.defaultTextStyle = { + /** + * See {@link TextStyle.align} + * @type {'left'|'center'|'right'|'justify'} + */ + align: "left", + /** See {@link TextStyle.breakWords} */ + breakWords: false, + /** See {@link TextStyle.dropShadow} */ + dropShadow: null, + /** + * See {@link TextStyle.fill} + * @type {string|string[]|number|number[]|CanvasGradient|CanvasPattern} + */ + fill: "black", + /** + * See {@link TextStyle.fontFamily} + * @type {string|string[]} + */ + fontFamily: "Arial", + /** + * See {@link TextStyle.fontSize} + * @type {number|string} + */ + fontSize: 26, + /** + * See {@link TextStyle.fontStyle} + * @type {'normal'|'italic'|'oblique'} + */ + fontStyle: "normal", + /** + * See {@link TextStyle.fontVariant} + * @type {'normal'|'small-caps'} + */ + fontVariant: "normal", + /** + * See {@link TextStyle.fontWeight} + * @type {'normal'|'bold'|'bolder'|'lighter'|'100'|'200'|'300'|'400'|'500'|'600'|'700'|'800'|'900'} + */ + fontWeight: "normal", + /** See {@link TextStyle.leading} */ + leading: 0, + /** See {@link TextStyle.letterSpacing} */ + letterSpacing: 0, + /** See {@link TextStyle.lineHeight} */ + lineHeight: 0, + /** See {@link TextStyle.padding} */ + padding: 0, + /** + * See {@link TextStyle.stroke} + * @type {string|number} + */ + stroke: null, + /** + * See {@link TextStyle.textBaseline} + * @type {'alphabetic'|'top'|'hanging'|'middle'|'ideographic'|'bottom'} + */ + textBaseline: "alphabetic", + /** See {@link TextStyle.trim} */ + trim: false, + /** + * See {@link TextStyle.whiteSpace} + * @type {'normal'|'pre'|'pre-line'} + */ + whiteSpace: "pre", + /** See {@link TextStyle.wordWrap} */ + wordWrap: false, + /** See {@link TextStyle.wordWrapWidth} */ + wordWrapWidth: 100 +}; +let TextStyle = _TextStyle; +function convertV7Tov8Style(style) { + var _a, _b, _c, _d, _e; + const oldStyle = style; + if (typeof oldStyle.dropShadow === "boolean" && oldStyle.dropShadow) { + const defaults = TextStyle.defaultDropShadow; + style.dropShadow = { + alpha: (_a = oldStyle.dropShadowAlpha) != null ? _a : defaults.alpha, + angle: (_b = oldStyle.dropShadowAngle) != null ? _b : defaults.angle, + blur: (_c = oldStyle.dropShadowBlur) != null ? _c : defaults.blur, + color: (_d = oldStyle.dropShadowColor) != null ? _d : defaults.color, + distance: (_e = oldStyle.dropShadowDistance) != null ? _e : defaults.distance + }; + } + if (oldStyle.strokeThickness) { + deprecation(v8_0_0, "strokeThickness is now a part of stroke"); + const color = oldStyle.stroke; + style.stroke = { + color, + width: oldStyle.strokeThickness + }; + } + if (Array.isArray(oldStyle.fill)) { + deprecation(v8_0_0, "gradient fill is now a fill pattern: `new FillGradient(...)`"); + const gradientFill = new FillGradient(0, 0, 0, style.fontSize * 1.7); + const fills = oldStyle.fill.map((color) => Color.shared.setValue(color).toNumber()); + fills.forEach((number, index) => { + var _a2; + const ratio = (_a2 = oldStyle.fillGradientStops[index]) != null ? _a2 : index / fills.length; + gradientFill.addColorStop(ratio, number); + }); + style.fill = { + fill: gradientFill + }; + } +} + +"use strict"; +function resolveCharacters(chars) { + if (chars === "") { + return []; + } + if (typeof chars === "string") { + chars = [chars]; + } + const result = []; + for (let i = 0, j = chars.length; i < j; i++) { + const item = chars[i]; + if (Array.isArray(item)) { + if (item.length !== 2) { + throw new Error(`[BitmapFont]: Invalid character range length, expecting 2 got ${item.length}.`); + } + if (item[0].length === 0 || item[1].length === 0) { + throw new Error("[BitmapFont]: Invalid character delimiter."); + } + const startCode = item[0].charCodeAt(0); + const endCode = item[1].charCodeAt(0); + if (endCode < startCode) { + throw new Error("[BitmapFont]: Invalid character range."); + } + for (let i2 = startCode, j2 = endCode; i2 <= j2; i2++) { + result.push(String.fromCharCode(i2)); + } + } else { + result.push(...Array.from(item)); + } + } + if (result.length === 0) { + throw new Error("[BitmapFont]: Empty set when resolving characters."); + } + return result; +} + +"use strict"; +class DynamicBitmapFont extends AbstractBitmapFont { + /** + * @param options - The options for the dynamic bitmap font. + */ + constructor(options) { + var _a, _b, _c; + super(); + /** + * this is a resolution modifier for the font size.. + * texture resolution will also be used to scale texture according to its font size also + */ + this.resolution = 1; + /** The pages of the font. */ + this.pages = []; + this._padding = 4; + this._measureCache = /* @__PURE__ */ Object.create(null); + this._currentChars = []; + this._currentX = 0; + this._currentY = 0; + this._currentPageIndex = -1; + this._skipKerning = false; + const dynamicOptions = options; + const style = dynamicOptions.style.clone(); + if (dynamicOptions.overrideFill) { + style._fill.color = 16777215; + style._fill.alpha = 1; + style._fill.texture = Texture.WHITE; + style._fill.fill = null; + } + const requestedFontSize = style.fontSize; + style.fontSize = this.baseMeasurementFontSize; + const font = fontStringFromTextStyle(style); + if (dynamicOptions.overrideSize) { + if (style._stroke) { + style._stroke.width *= this.baseRenderedFontSize / requestedFontSize; + } + } else { + style.fontSize = this.baseRenderedFontSize = requestedFontSize; + } + this._style = style; + this._skipKerning = (_a = dynamicOptions.skipKerning) != null ? _a : false; + this.resolution = (_b = dynamicOptions.resolution) != null ? _b : 1; + this._padding = (_c = dynamicOptions.padding) != null ? _c : 4; + this.fontMetrics = CanvasTextMetrics.measureFont(font); + this.lineHeight = style.lineHeight || this.fontMetrics.fontSize || style.fontSize; + } + ensureCharacters(chars) { + var _a, _b, _c, _d; + const charList = resolveCharacters(chars).filter((char) => !this._currentChars.includes(char)).filter((char, index, self) => self.indexOf(char) === index); + if (!charList.length) + return; + this._currentChars = [...this._currentChars, ...charList]; + let pageData; + if (this._currentPageIndex === -1) { + pageData = this._nextPage(); + } else { + pageData = this.pages[this._currentPageIndex]; + } + let { canvas, context } = pageData.canvasAndContext; + let textureSource = pageData.texture.source; + const style = this._style; + let currentX = this._currentX; + let currentY = this._currentY; + const fontScale = this.baseRenderedFontSize / this.baseMeasurementFontSize; + const padding = this._padding * fontScale; + const widthScale = style.fontStyle === "italic" ? 2 : 1; + let maxCharHeight = 0; + let skipTexture = false; + for (let i = 0; i < charList.length; i++) { + const char = charList[i]; + const metrics = CanvasTextMetrics.measureText(char, style, canvas, false); + metrics.lineHeight = metrics.height; + const width = widthScale * metrics.width * fontScale; + const height = metrics.height * fontScale; + const paddedWidth = width + padding * 2; + const paddedHeight = height + padding * 2; + skipTexture = false; + if (char !== "\n" && char !== "\r" && char !== " " && char !== " ") { + skipTexture = true; + maxCharHeight = Math.ceil(Math.max(paddedHeight, maxCharHeight)); + } + if (currentX + paddedWidth > 512) { + currentY += maxCharHeight; + maxCharHeight = paddedHeight; + currentX = 0; + if (currentY + maxCharHeight > 512) { + textureSource.update(); + const pageData2 = this._nextPage(); + canvas = pageData2.canvasAndContext.canvas; + context = pageData2.canvasAndContext.context; + textureSource = pageData2.texture.source; + currentY = 0; + } + } + const xAdvance = width / fontScale - ((_b = (_a = style.dropShadow) == null ? void 0 : _a.distance) != null ? _b : 0) - ((_d = (_c = style._stroke) == null ? void 0 : _c.width) != null ? _d : 0); + this.chars[char] = { + id: char.codePointAt(0), + xOffset: -this._padding, + yOffset: -this._padding, + xAdvance, + kerning: {} + }; + if (skipTexture) { + this._drawGlyph( + context, + metrics, + currentX + padding, + currentY + padding, + fontScale, + style + ); + const px = textureSource.width * fontScale; + const py = textureSource.height * fontScale; + const frame = new Rectangle( + currentX / px * textureSource.width, + currentY / py * textureSource.height, + paddedWidth / px * textureSource.width, + paddedHeight / py * textureSource.height + ); + this.chars[char].texture = new Texture({ + source: textureSource, + frame + }); + currentX += Math.ceil(paddedWidth); + } + } + textureSource.update(); + this._currentX = currentX; + this._currentY = currentY; + this._skipKerning && this._applyKerning(charList, context); + } + /** + * @deprecated since 8.0.0 + * The map of base page textures (i.e., sheets of glyphs). + */ + get pageTextures() { + deprecation(v8_0_0, "BitmapFont.pageTextures is deprecated, please use BitmapFont.pages instead."); + return this.pages; + } + _applyKerning(newChars, context) { + const measureCache = this._measureCache; + for (let i = 0; i < newChars.length; i++) { + const first = newChars[i]; + for (let j = 0; j < this._currentChars.length; j++) { + const second = this._currentChars[j]; + let c1 = measureCache[first]; + if (!c1) + c1 = measureCache[first] = context.measureText(first).width; + let c2 = measureCache[second]; + if (!c2) + c2 = measureCache[second] = context.measureText(second).width; + let total = context.measureText(first + second).width; + let amount = total - (c1 + c2); + if (amount) { + this.chars[first].kerning[second] = amount; + } + total = context.measureText(first + second).width; + amount = total - (c1 + c2); + if (amount) { + this.chars[second].kerning[first] = amount; + } + } + } + } + _nextPage() { + this._currentPageIndex++; + const textureResolution = this.resolution; + const canvasAndContext = CanvasPool.getOptimalCanvasAndContext(512, 512, textureResolution); + this._setupContext(canvasAndContext.context, this._style, textureResolution); + const resolution = textureResolution * (this.baseRenderedFontSize / this.baseMeasurementFontSize); + const texture = new Texture({ + source: new ImageSource({ + resource: canvasAndContext.canvas, + resolution, + alphaMode: "premultiply-alpha-on-upload" + }) + }); + const pageData = { + canvasAndContext, + texture + }; + this.pages[this._currentPageIndex] = pageData; + return pageData; + } + // canvas style! + _setupContext(context, style, resolution) { + var _a; + style.fontSize = this.baseRenderedFontSize; + context.scale(resolution, resolution); + context.font = fontStringFromTextStyle(style); + style.fontSize = this.baseMeasurementFontSize; + context.textBaseline = style.textBaseline; + const stroke = style._stroke; + const strokeThickness = (_a = stroke == null ? void 0 : stroke.width) != null ? _a : 0; + if (stroke) { + context.lineWidth = strokeThickness; + context.lineJoin = stroke.join; + context.miterLimit = stroke.miterLimit; + context.strokeStyle = getCanvasFillStyle(stroke, context); + } + if (style._fill) { + context.fillStyle = getCanvasFillStyle(style._fill, context); + } + if (style.dropShadow) { + const shadowOptions = style.dropShadow; + const rgb = Color.shared.setValue(shadowOptions.color).toArray(); + const dropShadowBlur = shadowOptions.blur * resolution; + const dropShadowDistance = shadowOptions.distance * resolution; + context.shadowColor = `rgba(${rgb[0] * 255},${rgb[1] * 255},${rgb[2] * 255},${shadowOptions.alpha})`; + context.shadowBlur = dropShadowBlur; + context.shadowOffsetX = Math.cos(shadowOptions.angle) * dropShadowDistance; + context.shadowOffsetY = Math.sin(shadowOptions.angle) * dropShadowDistance; + } else { + context.shadowColor = "black"; + context.shadowBlur = 0; + context.shadowOffsetX = 0; + context.shadowOffsetY = 0; + } + } + _drawGlyph(context, metrics, x, y, fontScale, style) { + var _a; + const char = metrics.text; + const fontProperties = metrics.fontProperties; + const stroke = style._stroke; + const strokeThickness = ((_a = stroke == null ? void 0 : stroke.width) != null ? _a : 0) * fontScale; + const tx = x + strokeThickness / 2; + const ty = y - strokeThickness / 2; + const descent = fontProperties.descent * fontScale; + const lineHeight = metrics.lineHeight * fontScale; + if (style.stroke && strokeThickness) { + context.strokeText(char, tx, ty + lineHeight - descent); + } + if (style._fill) { + context.fillText(char, tx, ty + lineHeight - descent); + } + } + destroy() { + super.destroy(); + for (let i = 0; i < this.pages.length; i++) { + const { canvasAndContext, texture } = this.pages[i]; + CanvasPool.returnCanvasAndContext(canvasAndContext); + texture.destroy(true); + } + this.pages = null; + } +} + +"use strict"; +function getBitmapTextLayout(chars, style, font) { + const layoutData = { + width: 0, + height: 0, + offsetY: 0, + scale: style.fontSize / font.baseMeasurementFontSize, + lines: [{ + width: 0, + charPositions: [], + spaceWidth: 0, + spacesIndex: [], + chars: [] + }] + }; + layoutData.offsetY = font.baseLineOffset; + let currentLine = layoutData.lines[0]; + let previousChar = null; + let firstWord = true; + const currentWord = { + spaceWord: false, + width: 0, + start: 0, + index: 0, + // use index to not modify the array as we use it a lot! + positions: [], + chars: [] + }; + const nextWord = (word) => { + const start = currentLine.width; + for (let j = 0; j < currentWord.index; j++) { + const position = word.positions[j]; + currentLine.chars.push(word.chars[j]); + currentLine.charPositions.push(position + start); + } + currentLine.width += word.width; + firstWord = false; + currentWord.width = 0; + currentWord.index = 0; + currentWord.chars.length = 0; + }; + const nextLine = () => { + let index = currentLine.chars.length - 1; + let lastChar = currentLine.chars[index]; + while (lastChar === " ") { + currentLine.width -= font.chars[lastChar].xAdvance; + lastChar = currentLine.chars[--index]; + } + layoutData.width = Math.max(layoutData.width, currentLine.width); + currentLine = { + width: 0, + charPositions: [], + chars: [], + spaceWidth: 0, + spacesIndex: [] + }; + firstWord = true; + layoutData.lines.push(currentLine); + layoutData.height += font.lineHeight; + }; + const scale = font.baseMeasurementFontSize / style.fontSize; + const adjustedLetterSpacing = style.letterSpacing * scale; + const adjustedWordWrapWidth = style.wordWrapWidth * scale; + for (let i = 0; i < chars.length + 1; i++) { + let char; + const isEnd = i === chars.length; + if (!isEnd) { + char = chars[i]; + } + const charData = font.chars[char] || font.chars[" "]; + const isSpace = /(?:\s)/.test(char); + const isWordBreak = isSpace || char === "\r" || char === "\n" || isEnd; + if (isWordBreak) { + const addWordToNextLine = !firstWord && style.wordWrap && currentLine.width + currentWord.width - adjustedLetterSpacing > adjustedWordWrapWidth; + if (addWordToNextLine) { + nextLine(); + nextWord(currentWord); + if (!isEnd) { + currentLine.charPositions.push(0); + } + } else { + currentWord.start = currentLine.width; + nextWord(currentWord); + if (!isEnd) { + currentLine.charPositions.push(0); + } + } + if (char === "\r" || char === "\n") { + if (currentLine.width !== 0) { + nextLine(); + } + } else if (!isEnd) { + const spaceWidth = charData.xAdvance + (charData.kerning[previousChar] || 0) + adjustedLetterSpacing; + currentLine.width += spaceWidth; + currentLine.spaceWidth = spaceWidth; + currentLine.spacesIndex.push(currentLine.charPositions.length); + currentLine.chars.push(char); + } + } else { + const kerning = charData.kerning[previousChar] || 0; + const nextCharWidth = charData.xAdvance + kerning + adjustedLetterSpacing; + currentWord.positions[currentWord.index++] = currentWord.width + kerning; + currentWord.chars.push(char); + currentWord.width += nextCharWidth; + } + previousChar = char; + } + nextLine(); + if (style.align === "center") { + alignCenter(layoutData); + } else if (style.align === "right") { + alignRight(layoutData); + } else if (style.align === "justify") { + alignJustify(layoutData); + } + return layoutData; +} +function alignCenter(measurementData) { + for (let i = 0; i < measurementData.lines.length; i++) { + const line = measurementData.lines[i]; + const offset = measurementData.width / 2 - line.width / 2; + for (let j = 0; j < line.charPositions.length; j++) { + line.charPositions[j] += offset; + } + } +} +function alignRight(measurementData) { + for (let i = 0; i < measurementData.lines.length; i++) { + const line = measurementData.lines[i]; + const offset = measurementData.width - line.width; + for (let j = 0; j < line.charPositions.length; j++) { + line.charPositions[j] += offset; + } + } +} +function alignJustify(measurementData) { + const width = measurementData.width; + for (let i = 0; i < measurementData.lines.length; i++) { + const line = measurementData.lines[i]; + let indy = 0; + let spaceIndex = line.spacesIndex[indy++]; + let offset = 0; + const totalSpaces = line.spacesIndex.length; + const newSpaceWidth = (width - line.width) / totalSpaces; + const spaceWidth = newSpaceWidth; + for (let j = 0; j < line.charPositions.length; j++) { + if (j === spaceIndex) { + spaceIndex = line.spacesIndex[indy++]; + offset += spaceWidth; + } + line.charPositions[j] += offset; + } + } +} + +"use strict"; +var __defProp$M = Object.defineProperty; +var __getOwnPropSymbols$M = Object.getOwnPropertySymbols; +var __hasOwnProp$M = Object.prototype.hasOwnProperty; +var __propIsEnum$M = Object.prototype.propertyIsEnumerable; +var __defNormalProp$M = (obj, key, value) => key in obj ? __defProp$M(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; +var __spreadValues$M = (a, b) => { + for (var prop in b || (b = {})) + if (__hasOwnProp$M.call(b, prop)) + __defNormalProp$M(a, prop, b[prop]); + if (__getOwnPropSymbols$M) + for (var prop of __getOwnPropSymbols$M(b)) { + if (__propIsEnum$M.call(b, prop)) + __defNormalProp$M(a, prop, b[prop]); + } + return a; +}; +class BitmapFontManagerClass { + constructor() { + /** + * This character set includes all the letters in the alphabet (both lower- and upper- case). + * @type {string[][]} + * @example + * BitmapFont.from('ExampleFont', style, { chars: BitmapFont.ALPHA }) + */ + this.ALPHA = [["a", "z"], ["A", "Z"], " "]; + /** + * This character set includes all decimal digits (from 0 to 9). + * @type {string[][]} + * @example + * BitmapFont.from('ExampleFont', style, { chars: BitmapFont.NUMERIC }) + */ + this.NUMERIC = [["0", "9"]]; + /** + * This character set is the union of `BitmapFont.ALPHA` and `BitmapFont.NUMERIC`. + * @type {string[][]} + */ + this.ALPHANUMERIC = [["a", "z"], ["A", "Z"], ["0", "9"], " "]; + /** + * This character set consists of all the ASCII table. + * @member {string[][]} + * @see http://www.asciitable.com/ + */ + this.ASCII = [[" ", "~"]]; + /** Default options for installing a new BitmapFont. */ + this.defaultOptions = { + chars: this.ALPHANUMERIC, + resolution: 1, + padding: 4, + skipKerning: false + }; + } + /** + * Get a font for the specified text and style. + * @param text - The text to get the font for + * @param style - The style to use + */ + getFont(text, style) { + var _a; + let fontFamilyKey = `${style.fontFamily}-bitmap`; + let overrideFill = true; + if (style._fill.fill) { + fontFamilyKey += style._fill.fill.uid; + overrideFill = false; + } + if (!Cache.has(fontFamilyKey)) { + const fnt = new DynamicBitmapFont(__spreadValues$M({ + style, + overrideFill, + overrideSize: true + }, this.defaultOptions)); + fnt.once("destroy", () => Cache.remove(fontFamilyKey)); + Cache.set( + fontFamilyKey, + fnt + ); + } + const dynamicFont = Cache.get(fontFamilyKey); + (_a = dynamicFont.ensureCharacters) == null ? void 0 : _a.call(dynamicFont, text); + return dynamicFont; + } + /** + * Get the layout of a text for the specified style. + * @param text - The text to get the layout for + * @param style - The style to use + */ + getLayout(text, style) { + const bitmapFont = this.getFont(text, style); + return getBitmapTextLayout(text.split(""), style, bitmapFont); + } + /** + * Measure the text using the specified style. + * @param text - The text to measure + * @param style - The style to use + */ + measureText(text, style) { + return this.getLayout(text, style); + } + // eslint-disable-next-line max-len + install(...args) { + var _a, _b, _c, _d; + let options = args[0]; + if (typeof options === "string") { + options = { + name: options, + style: args[1], + chars: (_a = args[2]) == null ? void 0 : _a.chars, + resolution: (_b = args[2]) == null ? void 0 : _b.resolution, + padding: (_c = args[2]) == null ? void 0 : _c.padding, + skipKerning: (_d = args[2]) == null ? void 0 : _d.skipKerning + }; + deprecation(v8_0_0, "BitmapFontManager.install(name, style, options) is deprecated, use BitmapFontManager.install({name, style, ...options})"); + } + const name = options == null ? void 0 : options.name; + if (!name) { + throw new Error("[BitmapFontManager] Property `name` is required."); + } + options = __spreadValues$M(__spreadValues$M({}, this.defaultOptions), options); + const textStyle = options.style; + const style = textStyle instanceof TextStyle ? textStyle : new TextStyle(textStyle); + const overrideFill = style._fill.fill !== null && style._fill.fill !== void 0; + const font = new DynamicBitmapFont({ + style, + overrideFill, + skipKerning: options.skipKerning, + padding: options.padding, + resolution: options.resolution, + overrideSize: false + }); + const flatChars = resolveCharacters(options.chars); + font.ensureCharacters(flatChars.join("")); + Cache.set(`${name}-bitmap`, font); + font.once("destroy", () => Cache.remove(`${name}-bitmap`)); + return font; + } + /** + * Uninstalls a bitmap font from the cache. + * @param {string} name - The name of the bitmap font to uninstall. + */ + uninstall(name) { + const cacheKey = `${name}-bitmap`; + const font = Cache.get(cacheKey); + if (font) { + Cache.remove(cacheKey); + font.destroy(); + } + } +} +const BitmapFontManager = new BitmapFontManagerClass(); + +"use strict"; +class BitmapFont extends AbstractBitmapFont { + constructor(options, url) { + var _a; + super(); + const { textures, data } = options; + Object.keys(data.pages).forEach((key) => { + const pageData = data.pages[parseInt(key, 10)]; + const texture = textures[pageData.id]; + this.pages.push({ texture }); + }); + Object.keys(data.chars).forEach((key) => { + var _a2; + const charData = data.chars[key]; + const textureSource = textures[charData.page].source; + const frameReal = new Rectangle( + charData.x, + charData.y, + charData.width, + charData.height + ); + const texture = new Texture({ + source: textureSource, + frame: frameReal + }); + this.chars[key] = { + id: key.codePointAt(0), + xOffset: charData.xOffset, + yOffset: charData.yOffset, + xAdvance: charData.xAdvance, + kerning: (_a2 = charData.kerning) != null ? _a2 : {}, + texture + }; + }); + this.baseRenderedFontSize = data.fontSize; + this.baseMeasurementFontSize = data.fontSize; + this.fontMetrics = { + ascent: 0, + descent: 0, + fontSize: data.fontSize + }; + this.baseLineOffset = data.baseLineOffset; + this.lineHeight = data.lineHeight; + this.fontFamily = data.fontFamily; + this.distanceField = (_a = data.distanceField) != null ? _a : { + type: "none", + range: 0 + }; + this.url = url; + } + /** Destroys the BitmapFont object. */ + destroy() { + super.destroy(); + for (let i = 0; i < this.pages.length; i++) { + const { texture } = this.pages[i]; + texture.destroy(true); + } + this.pages = null; + } + /** + * Generates a bitmap-font for the given style and character set + * @param options - Setup options for font generation. + * @returns Font generated by style options. + * @example + * import { BitmapFont, BitmapText } from 'pixi.js'; + * + * BitmapFont.install('TitleFont', { + * fontFamily: 'Arial', + * fontSize: 12, + * strokeThickness: 2, + * fill: 'purple', + * }); + * + * const title = new BitmapText({ text: 'This is the title', fontFamily: 'TitleFont' }); + */ + static install(options) { + BitmapFontManager.install(options); + } + /** + * Uninstalls a bitmap font from the cache. + * @param {string} name - The name of the bitmap font to uninstall. + */ + static uninstall(name) { + BitmapFontManager.uninstall(name); + } +} + +"use strict"; +const bitmapFontTextParser = { + test(data) { + return typeof data === "string" && data.startsWith("info face="); + }, + parse(txt) { + var _a, _b, _c; + const items = txt.match(/^[a-z]+\s+.+$/gm); + const rawData = { + info: [], + common: [], + page: [], + char: [], + chars: [], + kerning: [], + kernings: [], + distanceField: [] + }; + for (const i in items) { + const name = items[i].match(/^[a-z]+/gm)[0]; + const attributeList = items[i].match(/[a-zA-Z]+=([^\s"']+|"([^"]*)")/gm); + const itemData = {}; + for (const i2 in attributeList) { + const split = attributeList[i2].split("="); + const key = split[0]; + const strValue = split[1].replace(/"/gm, ""); + const floatValue = parseFloat(strValue); + const value = isNaN(floatValue) ? strValue : floatValue; + itemData[key] = value; + } + rawData[name].push(itemData); + } + const font = { + chars: {}, + pages: [], + lineHeight: 0, + fontSize: 0, + fontFamily: "", + distanceField: null, + baseLineOffset: 0 + }; + const [info] = rawData.info; + const [common] = rawData.common; + const [distanceField] = (_a = rawData.distanceField) != null ? _a : []; + if (distanceField) { + font.distanceField = { + range: parseInt(distanceField.distanceRange, 10), + type: distanceField.fieldType + }; + } + font.fontSize = parseInt(info.size, 10); + font.fontFamily = info.face; + font.lineHeight = parseInt(common.lineHeight, 10); + const page = rawData.page; + for (let i = 0; i < page.length; i++) { + font.pages.push({ + id: parseInt(page[i].id, 10) || 0, + file: page[i].file + }); + } + const map = {}; + font.baseLineOffset = font.lineHeight - parseInt(common.base, 10); + const char = rawData.char; + for (let i = 0; i < char.length; i++) { + const charNode = char[i]; + const id = parseInt(charNode.id, 10); + let letter = (_c = (_b = charNode.letter) != null ? _b : charNode.char) != null ? _c : String.fromCharCode(id); + if (letter === "space") + letter = " "; + map[id] = letter; + font.chars[letter] = { + id, + // texture deets.. + page: parseInt(charNode.page, 10) || 0, + x: parseInt(charNode.x, 10), + y: parseInt(charNode.y, 10), + width: parseInt(charNode.width, 10), + height: parseInt(charNode.height, 10), + xOffset: parseInt(charNode.xoffset, 10), + yOffset: parseInt(charNode.yoffset, 10), + xAdvance: parseInt(charNode.xadvance, 10), + kerning: {} + }; + } + const kerning = rawData.kerning || []; + for (let i = 0; i < kerning.length; i++) { + const first = parseInt(kerning[i].first, 10); + const second = parseInt(kerning[i].second, 10); + const amount = parseInt(kerning[i].amount, 10); + font.chars[map[second]].kerning[map[first]] = amount; + } + return font; + } +}; + +"use strict"; +const bitmapFontXMLParser = { + test(data) { + const xml = data; + return typeof xml !== "string" && "getElementsByTagName" in xml && xml.getElementsByTagName("page").length && xml.getElementsByTagName("info")[0].getAttribute("face") !== null; + }, + parse(xml) { + var _a, _b; + const data = { + chars: {}, + pages: [], + lineHeight: 0, + fontSize: 0, + fontFamily: "", + distanceField: null, + baseLineOffset: 0 + }; + const info = xml.getElementsByTagName("info")[0]; + const common = xml.getElementsByTagName("common")[0]; + const distanceField = xml.getElementsByTagName("distanceField")[0]; + if (distanceField) { + data.distanceField = { + type: distanceField.getAttribute("fieldType"), + range: parseInt(distanceField.getAttribute("distanceRange"), 10) + }; + } + const page = xml.getElementsByTagName("page"); + const char = xml.getElementsByTagName("char"); + const kerning = xml.getElementsByTagName("kerning"); + data.fontSize = parseInt(info.getAttribute("size"), 10); + data.fontFamily = info.getAttribute("face"); + data.lineHeight = parseInt(common.getAttribute("lineHeight"), 10); + for (let i = 0; i < page.length; i++) { + data.pages.push({ + id: parseInt(page[i].getAttribute("id"), 10) || 0, + file: page[i].getAttribute("file") + }); + } + const map = {}; + data.baseLineOffset = data.lineHeight - parseInt(common.getAttribute("base"), 10); + for (let i = 0; i < char.length; i++) { + const charNode = char[i]; + const id = parseInt(charNode.getAttribute("id"), 10); + let letter = (_b = (_a = charNode.getAttribute("letter")) != null ? _a : charNode.getAttribute("char")) != null ? _b : String.fromCharCode(id); + if (letter === "space") + letter = " "; + map[id] = letter; + data.chars[letter] = { + id, + // texture deets.. + page: parseInt(charNode.getAttribute("page"), 10) || 0, + x: parseInt(charNode.getAttribute("x"), 10), + y: parseInt(charNode.getAttribute("y"), 10), + width: parseInt(charNode.getAttribute("width"), 10), + height: parseInt(charNode.getAttribute("height"), 10), + // render deets.. + xOffset: parseInt(charNode.getAttribute("xoffset"), 10), + yOffset: parseInt(charNode.getAttribute("yoffset"), 10), + // + baseLineOffset, + xAdvance: parseInt(charNode.getAttribute("xadvance"), 10), + kerning: {} + }; + } + for (let i = 0; i < kerning.length; i++) { + const first = parseInt(kerning[i].getAttribute("first"), 10); + const second = parseInt(kerning[i].getAttribute("second"), 10); + const amount = parseInt(kerning[i].getAttribute("amount"), 10); + data.chars[map[second]].kerning[map[first]] = amount; + } + return data; + } +}; + +"use strict"; +const bitmapFontXMLStringParser = { + test(data) { + if (typeof data === "string" && data.includes("")) { + return bitmapFontXMLParser.test(DOMAdapter.get().parseXML(data)); + } + return false; + }, + parse(data) { + return bitmapFontXMLParser.parse(DOMAdapter.get().parseXML(data)); + } +}; + +"use strict"; +const validExtensions = [".xml", ".fnt"]; +const bitmapFontCachePlugin = { + extension: ExtensionType.CacheParser, + test: (asset) => asset instanceof BitmapFont, + getCacheableAssets(keys, asset) { + const out = {}; + keys.forEach((key) => { + out[key] = asset; + }); + out[`${asset.fontFamily}-bitmap`] = asset; + return out; + } +}; +const loadBitmapFont = { + extension: { + type: ExtensionType.LoadParser, + priority: LoaderParserPriority.Normal + }, + test(url) { + return validExtensions.includes(path.extname(url).toLowerCase()); + }, + async testParse(data) { + return bitmapFontTextParser.test(data) || bitmapFontXMLStringParser.test(data); + }, + async parse(asset, data, loader) { + const bitmapFontData = bitmapFontTextParser.test(asset) ? bitmapFontTextParser.parse(asset) : bitmapFontXMLStringParser.parse(asset); + const { src } = data; + const { pages } = bitmapFontData; + const textureUrls = []; + for (let i = 0; i < pages.length; ++i) { + const pageFile = pages[i].file; + let imagePath = path.join(path.dirname(src), pageFile); + imagePath = copySearchParams(imagePath, src); + textureUrls.push(imagePath); + } + const loadedTextures = await loader.load(textureUrls); + const textures = textureUrls.map((url) => loadedTextures[url]); + const bitmapFont = new BitmapFont({ + data: bitmapFontData, + textures + }, src); + return bitmapFont; + }, + async load(url, _options) { + const response = await DOMAdapter.get().fetch(url); + return await response.text(); + }, + async unload(bitmapFont, _resolvedAsset, loader) { + await Promise.all(bitmapFont.pages.map((page) => loader.unload(page.texture.source._sourceOrigin))); + bitmapFont.destroy(); + } +}; + +"use strict"; +var __defProp$L = Object.defineProperty; +var __getOwnPropSymbols$L = Object.getOwnPropertySymbols; +var __hasOwnProp$L = Object.prototype.hasOwnProperty; +var __propIsEnum$L = Object.prototype.propertyIsEnumerable; +var __defNormalProp$L = (obj, key, value) => key in obj ? __defProp$L(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; +var __spreadValues$L = (a, b) => { + for (var prop in b || (b = {})) + if (__hasOwnProp$L.call(b, prop)) + __defNormalProp$L(a, prop, b[prop]); + if (__getOwnPropSymbols$L) + for (var prop of __getOwnPropSymbols$L(b)) { + if (__propIsEnum$L.call(b, prop)) + __defNormalProp$L(a, prop, b[prop]); + } + return a; +}; +var __objRest$g = (source, exclude) => { + var target = {}; + for (var prop in source) + if (__hasOwnProp$L.call(source, prop) && exclude.indexOf(prop) < 0) + target[prop] = source[prop]; + if (source != null && __getOwnPropSymbols$L) + for (var prop of __getOwnPropSymbols$L(source)) { + if (exclude.indexOf(prop) < 0 && __propIsEnum$L.call(source, prop)) + target[prop] = source[prop]; + } + return target; +}; +class Graphics extends Container { + /** + * @param options - Options for the Graphics. + */ + constructor(options) { + if (options instanceof GraphicsContext) { + options = { context: options }; + } + const _a = options || {}, { context, roundPixels } = _a, rest = __objRest$g(_a, ["context", "roundPixels"]); + super(__spreadValues$L({ + label: "Graphics" + }, rest)); + this.canBundle = true; + this.renderPipeId = "graphics"; + this._roundPixels = 0; + if (!context) { + this._context = this._ownedContext = new GraphicsContext(); + } else { + this._context = context; + } + this._context.on("update", this.onViewUpdate, this); + this.allowChildren = false; + this.roundPixels = roundPixels != null ? roundPixels : false; + } + set context(context) { + if (context === this._context) + return; + this._context.off("update", this.onViewUpdate, this); + this._context = context; + this._context.on("update", this.onViewUpdate, this); + this.onViewUpdate(); + } + get context() { + return this._context; + } + /** + * The local bounds of the graphic. + * @type {rendering.Bounds} + */ + get bounds() { + return this._context.bounds; + } + /** + * Adds the bounds of this object to the bounds object. + * @param bounds - The output bounds object. + */ + addBounds(bounds) { + bounds.addBounds(this._context.bounds); + } + /** + * Checks if the object contains the given point. + * @param point - The point to check + */ + containsPoint(point) { + return this._context.containsPoint(point); + } + /** + * Whether or not to round the x/y position of the graphic. + * @type {boolean} + */ + get roundPixels() { + return !!this._roundPixels; + } + set roundPixels(value) { + this._roundPixels = value ? 1 : 0; + } + onViewUpdate() { + this._didChangeId += 1 << 12; + this._didGraphicsUpdate = true; + if (this.didViewUpdate) + return; + this.didViewUpdate = true; + if (this.renderGroup) { + this.renderGroup.onChildViewUpdate(this); + } + } + /** + * Destroys this graphics renderable and optionally its context. + * @param options - Options parameter. A boolean will act as if all options + * + * If the context was created by this graphics and `destroy(false)` or `destroy()` is called + * then the context will still be destroyed. + * + * If you want to explicitly not destroy this context that this graphics created, + * then you should pass destroy({ context: false }) + * + * If the context was passed in as an argument to the constructor then it will not be destroyed + * @param {boolean} [options.texture=false] - Should destroy the texture of the graphics context + * @param {boolean} [options.textureSource=false] - Should destroy the texture source of the graphics context + * @param {boolean} [options.context=false] - Should destroy the context + */ + destroy(options) { + if (this._ownedContext && !options) { + this._ownedContext.destroy(options); + } else if (options === true || (options == null ? void 0 : options.context) === true) { + this._context.destroy(options); + } + this._ownedContext = null; + this._context = null; + super.destroy(options); + } + _callContextMethod(method, args) { + this.context[method](...args); + return this; + } + // --------------------------------------- GraphicsContext methods --------------------------------------- + /** + * Sets the current fill style of the graphics context. The fill style can be a color, gradient, + * pattern, or a more complex style defined by a FillStyle object. + * @param {FillStyleInputs} args - The fill style to apply. This can be a simple color, a gradient or + * pattern object, or a FillStyle or ConvertedFillStyle object. + * @returns The instance of the current GraphicsContext for method chaining. + */ + setFillStyle(...args) { + return this._callContextMethod("setFillStyle", args); + } + /** + * Sets the current stroke style of the graphics context. Similar to fill styles, stroke styles can + * encompass colors, gradients, patterns, or more detailed configurations via a StrokeStyle object. + * @param {FillStyleInputs} args - The stroke style to apply. Can be defined as a color, a gradient or pattern, + * or a StrokeStyle or ConvertedStrokeStyle object. + * @returns The instance of the current GraphicsContext for method chaining. + */ + setStrokeStyle(...args) { + return this._callContextMethod("setStrokeStyle", args); + } + fill(...args) { + return this._callContextMethod("fill", args); + } + /** + * Strokes the current path with the current stroke style. This method can take an optional + * FillStyleInputs parameter to define the stroke's appearance, including its color, width, and other properties. + * @param {FillStyleInputs} args - (Optional) The stroke style to apply. Can be defined as a simple color or a more + * complex style object. If omitted, uses the current stroke style. + * @returns The instance of the current GraphicsContext for method chaining. + */ + stroke(...args) { + return this._callContextMethod("stroke", args); + } + texture(...args) { + return this._callContextMethod("texture", args); + } + /** + * Resets the current path. Any previous path and its commands are discarded and a new path is + * started. This is typically called before beginning a new shape or series of drawing commands. + * @returns The instance of the current GraphicsContext for method chaining. + */ + beginPath() { + return this._callContextMethod("beginPath", []); + } + /** + * Applies a cutout to the last drawn shape. This is used to create holes or complex shapes by + * subtracting a path from the previously drawn path. If a hole is not completely in a shape, it will + * fail to cut correctly! + */ + cut() { + return this._callContextMethod("cut", []); + } + arc(...args) { + return this._callContextMethod("arc", args); + } + arcTo(...args) { + return this._callContextMethod("arcTo", args); + } + arcToSvg(...args) { + return this._callContextMethod("arcToSvg", args); + } + bezierCurveTo(...args) { + return this._callContextMethod("bezierCurveTo", args); + } + /** + * Closes the current path by drawing a straight line back to the start. + * If the shape is already closed or there are no points in the path, this method does nothing. + * @returns The instance of the current object for chaining. + */ + closePath() { + return this._callContextMethod("closePath", []); + } + ellipse(...args) { + return this._callContextMethod("ellipse", args); + } + circle(...args) { + return this._callContextMethod("circle", args); + } + path(...args) { + return this._callContextMethod("path", args); + } + lineTo(...args) { + return this._callContextMethod("lineTo", args); + } + moveTo(...args) { + return this._callContextMethod("moveTo", args); + } + quadraticCurveTo(...args) { + return this._callContextMethod("quadraticCurveTo", args); + } + rect(...args) { + return this._callContextMethod("rect", args); + } + roundRect(...args) { + return this._callContextMethod("roundRect", args); + } + poly(...args) { + return this._callContextMethod("poly", args); + } + regularPoly(...args) { + return this._callContextMethod("regularPoly", args); + } + roundPoly(...args) { + return this._callContextMethod("roundPoly", args); + } + roundShape(...args) { + return this._callContextMethod("roundShape", args); + } + filletRect(...args) { + return this._callContextMethod("filletRect", args); + } + chamferRect(...args) { + return this._callContextMethod("chamferRect", args); + } + star(...args) { + return this._callContextMethod("star", args); + } + svg(...args) { + return this._callContextMethod("svg", args); + } + restore(...args) { + return this._callContextMethod("restore", args); + } + /** Saves the current graphics state, including transformations, fill styles, and stroke styles, onto a stack. */ + save() { + return this._callContextMethod("save", []); + } + /** + * Returns the current transformation matrix of the graphics context. + * @returns The current transformation matrix. + */ + getTransform() { + return this.context.getTransform(); + } + /** + * Resets the current transformation matrix to the identity matrix, effectively removing + * any transformations (rotation, scaling, translation) previously applied. + * @returns The instance of the current GraphicsContext for method chaining. + */ + resetTransform() { + return this._callContextMethod("resetTransform", []); + } + rotateTransform(...args) { + return this._callContextMethod("rotate", args); + } + scaleTransform(...args) { + return this._callContextMethod("scale", args); + } + setTransform(...args) { + return this._callContextMethod("setTransform", args); + } + transform(...args) { + return this._callContextMethod("transform", args); + } + translateTransform(...args) { + return this._callContextMethod("translate", args); + } + /** + * Clears all drawing commands from the graphics context, effectively resetting it. This includes clearing the path, + * and optionally resetting transformations to the identity matrix. + * @returns The instance of the current GraphicsContext for method chaining. + */ + clear() { + return this._callContextMethod("clear", []); + } + /** + * The fill style to use. + * @type {ConvertedFillStyle} + */ + get fillStyle() { + return this._context.fillStyle; + } + set fillStyle(value) { + this._context.fillStyle = value; + } + /** + * The stroke style to use. + * @type {ConvertedStrokeStyle} + */ + get strokeStyle() { + return this._context.strokeStyle; + } + set strokeStyle(value) { + this._context.strokeStyle = value; + } + /** + * Creates a new Graphics object. + * Note that only the context of the object is cloned, not its transform (position,scale,etc) + * @param deep - Whether to create a deep clone of the graphics object. If false, the context + * will be shared between the two objects (default false). If true, the context will be + * cloned (recommended if you need to modify the context in any way). + * @returns - A clone of the graphics object + */ + clone(deep = false) { + if (deep) { + return new Graphics(this._context.clone()); + } + this._ownedContext = null; + const clone = new Graphics(this._context); + return clone; + } + // -------- v7 deprecations --------- + /** + * @param width + * @param color + * @param alpha + * @deprecated since 8.0.0 Use {@link Graphics#setStrokeStyle} instead + */ + lineStyle(width, color, alpha) { + deprecation(v8_0_0, "Graphics#lineStyle is no longer needed. Use Graphics#setStrokeStyle to set the stroke style."); + const strokeStyle = {}; + width && (strokeStyle.width = width); + color && (strokeStyle.color = color); + alpha && (strokeStyle.alpha = alpha); + this.context.strokeStyle = strokeStyle; + return this; + } + /** + * @param color + * @param alpha + * @deprecated since 8.0.0 Use {@link Graphics#fill} instead + */ + beginFill(color, alpha) { + deprecation(v8_0_0, "Graphics#beginFill is no longer needed. Use Graphics#fill to fill the shape with the desired style."); + const fillStyle = {}; + color && (fillStyle.color = color); + alpha && (fillStyle.alpha = alpha); + this.context.fillStyle = fillStyle; + return this; + } + /** + * @deprecated since 8.0.0 Use {@link Graphics#fill} instead + */ + endFill() { + deprecation(v8_0_0, "Graphics#endFill is no longer needed. Use Graphics#fill to fill the shape with the desired style."); + this.context.fill(); + const strokeStyle = this.context.strokeStyle; + if (strokeStyle.width !== GraphicsContext.defaultStrokeStyle.width || strokeStyle.color !== GraphicsContext.defaultStrokeStyle.color || strokeStyle.alpha !== GraphicsContext.defaultStrokeStyle.alpha) { + this.context.stroke(); + } + return this; + } + /** + * @param {...any} args + * @deprecated since 8.0.0 Use {@link Graphics#circle} instead + */ + drawCircle(...args) { + deprecation(v8_0_0, "Graphics#drawCircle has been renamed to Graphics#circle"); + return this._callContextMethod("circle", args); + } + /** + * @param {...any} args + * @deprecated since 8.0.0 Use {@link Graphics#ellipse} instead + */ + drawEllipse(...args) { + deprecation(v8_0_0, "Graphics#drawEllipse has been renamed to Graphics#ellipse"); + return this._callContextMethod("ellipse", args); + } + /** + * @param {...any} args + * @deprecated since 8.0.0 Use {@link Graphics#poly} instead + */ + drawPolygon(...args) { + deprecation(v8_0_0, "Graphics#drawPolygon has been renamed to Graphics#poly"); + return this._callContextMethod("poly", args); + } + /** + * @param {...any} args + * @deprecated since 8.0.0 Use {@link Graphics#rect} instead + */ + drawRect(...args) { + deprecation(v8_0_0, "Graphics#drawRect has been renamed to Graphics#rect"); + return this._callContextMethod("rect", args); + } + /** + * @param {...any} args + * @deprecated since 8.0.0 Use {@link Graphics#roundRect} instead + */ + drawRoundedRect(...args) { + deprecation(v8_0_0, "Graphics#drawRoundedRect has been renamed to Graphics#roundRect"); + return this._callContextMethod("roundRect", args); + } + /** + * @param {...any} args + * @deprecated since 8.0.0 Use {@link Graphics#star} instead + */ + drawStar(...args) { + deprecation(v8_0_0, "Graphics#drawStar has been renamed to Graphics#star"); + return this._callContextMethod("star", args); + } +} + +"use strict"; +let context; +function getTestContext() { + if (!context || (context == null ? void 0 : context.isContextLost())) { + const canvas = DOMAdapter.get().createCanvas(); + context = canvas.getContext("webgl", {}); + } + return context; +} + +"use strict"; +let maxFragmentPrecision; +function getMaxFragmentPrecision() { + if (!maxFragmentPrecision) { + maxFragmentPrecision = "mediump"; + const gl = getTestContext(); + if (gl) { + if (gl.getShaderPrecisionFormat) { + const shaderFragment = gl.getShaderPrecisionFormat(gl.FRAGMENT_SHADER, gl.HIGH_FLOAT); + maxFragmentPrecision = shaderFragment.precision ? "highp" : "mediump"; + } + } + } + return maxFragmentPrecision; +} + +"use strict"; +function addProgramDefines(src, isES300, isFragment) { + if (isES300) + return src; + if (isFragment) { + src = src.replace("out vec4 finalColor;", ""); + return ` #ifdef GL_ES // This checks if it is WebGL1 #define in varying #define finalColor gl_FragColor #define texture texture2D #endif - ${r} - `):` + ${src} + `; + } + return ` #ifdef GL_ES // This checks if it is WebGL1 #define in attribute #define out varying #endif - ${r} - `}function qc(r,t,e){const s=e?t.maxSupportedFragmentPrecision:t.maxSupportedVertexPrecision;if(r.substring(0,9)!=="precision"){let i=e?t.requestedFragmentPrecision:t.requestedVertexPrecision;return i==="highp"&&s!=="highp"&&(i="mediump"),`precision ${i} float; -${r}`}else if(s!=="highp"&&r.substring(0,15)==="precision highp")return r.replace("precision highp","precision mediump");return r}function Zc(r,t){return t?`#version 300 es -${r}`:r}const ty={},ey={};function Qc(r,{name:t="pixi-program"},e=!0){t=t.replace(/\s+/g,"-"),t+=e?"-fragment":"-vertex";const s=e?ty:ey;return s[t]?(s[t]++,t+=`-${s[t]}`):s[t]=1,r.indexOf("#define SHADER_NAME")!==-1?r:`${`#define SHADER_NAME ${t}`} -${r}`}function Jc(r,t){return t?r.replace("#version 300 es",""):r}var ry=Object.defineProperty,td=Object.getOwnPropertySymbols,sy=Object.prototype.hasOwnProperty,iy=Object.prototype.propertyIsEnumerable,ed=(r,t,e)=>t in r?ry(r,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):r[t]=e,rd=(r,t)=>{for(var e in t||(t={}))sy.call(t,e)&&ed(r,e,t[e]);if(td)for(var e of td(t))iy.call(t,e)&&ed(r,e,t[e]);return r};const To={stripVersion:Jc,ensurePrecision:qc,addProgramDefines:Kc,setProgramName:Qc,insertVersion:Zc},So=Object.create(null),sd=class Yu{constructor(t){t=rd(rd({},Yu.defaultOptions),t);const e=t.fragment.indexOf("#version 300 es")!==-1,s={stripVersion:e,ensurePrecision:{requestedFragmentPrecision:t.preferredFragmentPrecision,requestedVertexPrecision:t.preferredVertexPrecision,maxSupportedVertexPrecision:"highp",maxSupportedFragmentPrecision:Yc()},setProgramName:{name:t.name},addProgramDefines:e,insertVersion:e};let i=t.fragment,n=t.vertex;Object.keys(To).forEach(o=>{const a=s[o];i=To[o](i,a,!0),n=To[o](n,a,!1)}),this.fragment=i,this.vertex=n,this._key=br(`${this.vertex}:${this.fragment}`,"gl-program")}destroy(){this.fragment=null,this.vertex=null,this._attributeData=null,this._uniformData=null,this._uniformBlockData=null,this.transformFeedbackVaryings=null}static from(t){const e=`${t.vertex}:${t.fragment}`;return So[e]||(So[e]=new Yu(t)),So[e]}};sd.defaultOptions={preferredVertexPrecision:"highp",preferredFragmentPrecision:"mediump"};let Rt=sd;const id={uint8x2:{size:2,stride:2,normalised:!1},uint8x4:{size:4,stride:4,normalised:!1},sint8x2:{size:2,stride:2,normalised:!1},sint8x4:{size:4,stride:4,normalised:!1},unorm8x2:{size:2,stride:2,normalised:!0},unorm8x4:{size:4,stride:4,normalised:!0},snorm8x2:{size:2,stride:2,normalised:!0},snorm8x4:{size:4,stride:4,normalised:!0},uint16x2:{size:2,stride:4,normalised:!1},uint16x4:{size:4,stride:8,normalised:!1},sint16x2:{size:2,stride:4,normalised:!1},sint16x4:{size:4,stride:8,normalised:!1},unorm16x2:{size:2,stride:4,normalised:!0},unorm16x4:{size:4,stride:8,normalised:!0},snorm16x2:{size:2,stride:4,normalised:!0},snorm16x4:{size:4,stride:8,normalised:!0},float16x2:{size:2,stride:4,normalised:!1},float16x4:{size:4,stride:8,normalised:!1},float32:{size:1,stride:4,normalised:!1},float32x2:{size:2,stride:8,normalised:!1},float32x3:{size:3,stride:12,normalised:!1},float32x4:{size:4,stride:16,normalised:!1},uint32:{size:1,stride:4,normalised:!1},uint32x2:{size:2,stride:8,normalised:!1},uint32x3:{size:3,stride:12,normalised:!1},uint32x4:{size:4,stride:16,normalised:!1},sint32:{size:1,stride:4,normalised:!1},sint32x2:{size:2,stride:8,normalised:!1},sint32x3:{size:3,stride:12,normalised:!1},sint32x4:{size:4,stride:16,normalised:!1}};function Fe(r){var t;return(t=id[r])!=null?t:id.float32}const ny={f32:"float32","vec2":"float32x2","vec3":"float32x3","vec4":"float32x4",vec2f:"float32x2",vec3f:"float32x3",vec4f:"float32x4",i32:"sint32","vec2":"sint32x2","vec3":"sint32x3","vec4":"sint32x4",u32:"uint32","vec2":"uint32x2","vec3":"uint32x3","vec4":"uint32x4",bool:"uint32","vec2":"uint32x2","vec3":"uint32x3","vec4":"uint32x4"};function nd({source:r,entryPoint:t}){var e;const s={},i=r.indexOf(`fn ${t}`);if(i!==-1){const n=r.indexOf("->",i);if(n!==-1){const o=r.substring(i,n),a=/@location\((\d+)\)\s+([a-zA-Z0-9_]+)\s*:\s*([a-zA-Z0-9_<>]+)(?:,|\s|$)/g;let u;for(;(u=a.exec(o))!==null;){const l=(e=ny[u[3]])!=null?e:"float32";s[u[2]]={location:parseInt(u[1],10),format:l,stride:Fe(l).stride,offset:0,instance:!1,start:0}}}}return s}function Ds(r){var t,e,s;const i=/(^|[^/])@(group|binding)\(\d+\)[^;]+;/g,n=/@group\((\d+)\)/,o=/@binding\((\d+)\)/,a=/var(<[^>]+>)? (\w+)/,u=/:\s*(\w+)/,l=/struct\s+(\w+)\s*{([^}]+)}/g,h=/(\w+)\s*:\s*([\w\<\>]+)/g,c=/struct\s+(\w+)/,d=(t=r.match(i))==null?void 0:t.map(f=>({group:parseInt(f.match(n)[1],10),binding:parseInt(f.match(o)[1],10),name:f.match(a)[2],isUniform:f.match(a)[1]==="",type:f.match(u)[1]}));if(!d)return{groups:[],structs:[]};const p=(s=(e=r.match(l))==null?void 0:e.map(f=>{const g=f.match(c)[1],m=f.match(h).reduce((_,x)=>{const[b,y]=x.split(":");return _[b.trim()]=y.trim(),_},{});return m?{name:g,members:m}:null}).filter(({name:f})=>d.some(g=>g.type===f)))!=null?s:[];return{groups:d,structs:p}}var De=(r=>(r[r.VERTEX=1]="VERTEX",r[r.FRAGMENT=2]="FRAGMENT",r[r.COMPUTE=4]="COMPUTE",r))(De||{});function od({groups:r}){const t=[];for(let e=0;ee.has(o.name)?!1:(e.add(o.name),!0)),n=[...r.groups,...t.groups].filter(o=>{const a=`${o.name}-${o.binding}`;return s.has(a)?!1:(s.add(a),!0)});return{structs:i,groups:n}}const Eo=Object.create(null);class Tt{constructor(t){this._layoutKey=0;var e,s;const{fragment:i,vertex:n,layout:o,gpuLayout:a,name:u}=t;if(this.name=u,this.fragment=i,this.vertex=n,i.source===n.source){const l=Ds(i.source);this.structsAndGroups=l}else{const l=Ds(n.source),h=Ds(i.source);this.structsAndGroups=ud(l,h)}this.layout=o!=null?o:ad(this.structsAndGroups),this.gpuLayout=a!=null?a:od(this.structsAndGroups),this.autoAssignGlobalUniforms=((e=this.layout[0])==null?void 0:e.globalUniforms)!==void 0,this.autoAssignLocalUniforms=((s=this.layout[1])==null?void 0:s.localUniforms)!==void 0,this._generateProgramKey()}_generateProgramKey(){const{vertex:t,fragment:e}=this,s=t.source+e.source+t.entryPoint+e.entryPoint;this._layoutKey=br(s,"program")}get attributeData(){var t;return(t=this._attributeData)!=null||(this._attributeData=nd(this.vertex)),this._attributeData}destroy(){this.gpuLayout=null,this.layout=null,this.structsAndGroups=null,this.fragment=null,this.vertex=null}static from(t){const e=`${t.vertex.source}:${t.fragment.source}:${t.fragment.entryPoint}:${t.vertex.entryPoint}`;return Eo[e]||(Eo[e]=new Tt(t)),Eo[e]}}function Ao(r,t,e){if(r)for(const s in r){const i=s.toLocaleLowerCase(),n=t[i];if(n){let o=r[s];s==="header"&&(o=o.replace(/@in\s+[^;]+;\s*/g,"").replace(/@out\s+[^;]+;\s*/g,"")),e&&n.push(`//----${e}----//`),n.push(o)}}}const ld=/\{\{(.*?)\}\}/g;function Po(r){var t,e;const s={};return((e=(t=r.match(ld))==null?void 0:t.map(i=>i.replace(/[{()}]/g,"")))!=null?e:[]).forEach(i=>{s[i]=[]}),s}function hd(r,t){let e;const s=/@in\s+([^;]+);/g;for(;(e=s.exec(r))!==null;)t.push(e[1])}function wo(r,t,e=!1){const s=[];hd(t,s),r.forEach(a=>{a.header&&hd(a.header,s)});const i=s;e&&i.sort();const n=i.map((a,u)=>` @location(${u}) ${a},`).join(` -`);let o=t.replace(/@in\s+[^;]+;\s*/g,"");return o=o.replace("{{in}}",` -${n} -`),o}function cd(r,t){let e;const s=/@out\s+([^;]+);/g;for(;(e=s.exec(r))!==null;)t.push(e[1])}function oy(r){const t=/\b(\w+)\s*:/g.exec(r);return t?t[1]:""}function ay(r){const t=/@.*?\s+/g;return r.replace(t,"")}function dd(r,t){const e=[];cd(t,e),r.forEach(u=>{u.header&&cd(u.header,e)});let s=0;const i=e.sort().map(u=>u.indexOf("builtin")>-1?u:`@location(${s++}) ${u}`).join(`, -`),n=e.sort().map(u=>` var ${ay(u)};`).join(` -`),o=`return VSOutput( - ${e.sort().map(u=>` ${oy(u)}`).join(`, -`)});`;let a=t.replace(/@out\s+[^;]+;\s*/g,"");return a=a.replace("{{struct}}",` -${i} -`),a=a.replace("{{start}}",` -${n} -`),a=a.replace("{{return}}",` -${o} -`),a}function Ro(r,t){let e=r;for(const s in t){const i=t[s];i.join(` -`).length?e=e.replace(`{{${s}}}`,`//-----${s} START-----// -${i.join(` -`)} -//----${s} FINISH----//`):e=e.replace(`{{${s}}}`,"")}return e}const Te=Object.create(null),Mo=new Map;let uy=0;function pd({template:r,bits:t}){const e=md(r,t);if(Te[e])return Te[e];const{vertex:s,fragment:i}=ly(r,t);return Te[e]=gd(s,i,t),Te[e]}function fd({template:r,bits:t}){const e=md(r,t);return Te[e]||(Te[e]=gd(r.vertex,r.fragment,t)),Te[e]}function ly(r,t){const e=t.map(o=>o.vertex).filter(o=>!!o),s=t.map(o=>o.fragment).filter(o=>!!o);let i=wo(e,r.vertex,!0);i=dd(e,i);const n=wo(s,r.fragment,!0);return{vertex:i,fragment:n}}function md(r,t){return t.map(e=>(Mo.has(e)||Mo.set(e,uy++),Mo.get(e))).sort((e,s)=>e-s).join("-")+r.vertex+r.fragment}function gd(r,t,e){const s=Po(r),i=Po(t);return e.forEach(n=>{Ao(n.vertex,s,n.name),Ao(n.fragment,i,n.name)}),{vertex:Ro(r,s),fragment:Ro(t,i)}}const _d=` + ${src} + `; +} + +"use strict"; +function ensurePrecision(src, options, isFragment) { + const maxSupportedPrecision = isFragment ? options.maxSupportedFragmentPrecision : options.maxSupportedVertexPrecision; + if (src.substring(0, 9) !== "precision") { + let precision = isFragment ? options.requestedFragmentPrecision : options.requestedVertexPrecision; + if (precision === "highp" && maxSupportedPrecision !== "highp") { + precision = "mediump"; + } + return `precision ${precision} float; +${src}`; + } else if (maxSupportedPrecision !== "highp" && src.substring(0, 15) === "precision highp") { + return src.replace("precision highp", "precision mediump"); + } + return src; +} + +"use strict"; +function insertVersion(src, isES300) { + if (!isES300) + return src; + return `#version 300 es +${src}`; +} + +"use strict"; +const fragmentNameCache = {}; +const VertexNameCache = {}; +function setProgramName(src, { name = `pixi-program` }, isFragment = true) { + name = name.replace(/\s+/g, "-"); + name += isFragment ? "-fragment" : "-vertex"; + const nameCache = isFragment ? fragmentNameCache : VertexNameCache; + if (nameCache[name]) { + nameCache[name]++; + name += `-${nameCache[name]}`; + } else { + nameCache[name] = 1; + } + if (src.indexOf("#define SHADER_NAME") !== -1) + return src; + const shaderName = `#define SHADER_NAME ${name}`; + return `${shaderName} +${src}`; +} + +"use strict"; +function stripVersion(src, isES300) { + if (!isES300) + return src; + return src.replace("#version 300 es", ""); +} + +"use strict"; +var __defProp$K = Object.defineProperty; +var __getOwnPropSymbols$K = Object.getOwnPropertySymbols; +var __hasOwnProp$K = Object.prototype.hasOwnProperty; +var __propIsEnum$K = Object.prototype.propertyIsEnumerable; +var __defNormalProp$K = (obj, key, value) => key in obj ? __defProp$K(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; +var __spreadValues$K = (a, b) => { + for (var prop in b || (b = {})) + if (__hasOwnProp$K.call(b, prop)) + __defNormalProp$K(a, prop, b[prop]); + if (__getOwnPropSymbols$K) + for (var prop of __getOwnPropSymbols$K(b)) { + if (__propIsEnum$K.call(b, prop)) + __defNormalProp$K(a, prop, b[prop]); + } + return a; +}; +const processes = { + // strips any version headers.. + stripVersion, + // adds precision string if not already present + ensurePrecision, + // add some defines if WebGL1 to make it more compatible with WebGL2 shaders + addProgramDefines, + // add the program name to the shader + setProgramName, + // add the version string to the shader header + insertVersion +}; +const programCache$1 = /* @__PURE__ */ Object.create(null); +const _GlProgram = class _GlProgram { + /** + * Creates a shiny new GlProgram. Used by WebGL renderer. + * @param options - The options for the program. + */ + constructor(options) { + options = __spreadValues$K(__spreadValues$K({}, _GlProgram.defaultOptions), options); + const isES300 = options.fragment.indexOf("#version 300 es") !== -1; + const preprocessorOptions = { + stripVersion: isES300, + ensurePrecision: { + requestedFragmentPrecision: options.preferredFragmentPrecision, + requestedVertexPrecision: options.preferredVertexPrecision, + maxSupportedVertexPrecision: "highp", + maxSupportedFragmentPrecision: getMaxFragmentPrecision() + }, + setProgramName: { + name: options.name + }, + addProgramDefines: isES300, + insertVersion: isES300 + }; + let fragment = options.fragment; + let vertex = options.vertex; + Object.keys(processes).forEach((processKey) => { + const processOptions = preprocessorOptions[processKey]; + fragment = processes[processKey](fragment, processOptions, true); + vertex = processes[processKey](vertex, processOptions, false); + }); + this.fragment = fragment; + this.vertex = vertex; + this._key = createIdFromString(`${this.vertex}:${this.fragment}`, "gl-program"); + } + /** destroys the program */ + destroy() { + this.fragment = null; + this.vertex = null; + this._attributeData = null; + this._uniformData = null; + this._uniformBlockData = null; + this.transformFeedbackVaryings = null; + } + /** + * Helper function that creates a program for a given source. + * It will check the program cache if the program has already been created. + * If it has that one will be returned, if not a new one will be created and cached. + * @param options - The options for the program. + * @returns A program using the same source + */ + static from(options) { + const key = `${options.vertex}:${options.fragment}`; + if (!programCache$1[key]) { + programCache$1[key] = new _GlProgram(options); + } + return programCache$1[key]; + } +}; +/** The default options used by the program. */ +_GlProgram.defaultOptions = { + preferredVertexPrecision: "highp", + preferredFragmentPrecision: "mediump" +}; +let GlProgram = _GlProgram; + +"use strict"; +const attributeFormatData = { + uint8x2: { size: 2, stride: 2, normalised: false }, + uint8x4: { size: 4, stride: 4, normalised: false }, + sint8x2: { size: 2, stride: 2, normalised: false }, + sint8x4: { size: 4, stride: 4, normalised: false }, + unorm8x2: { size: 2, stride: 2, normalised: true }, + unorm8x4: { size: 4, stride: 4, normalised: true }, + snorm8x2: { size: 2, stride: 2, normalised: true }, + snorm8x4: { size: 4, stride: 4, normalised: true }, + uint16x2: { size: 2, stride: 4, normalised: false }, + uint16x4: { size: 4, stride: 8, normalised: false }, + sint16x2: { size: 2, stride: 4, normalised: false }, + sint16x4: { size: 4, stride: 8, normalised: false }, + unorm16x2: { size: 2, stride: 4, normalised: true }, + unorm16x4: { size: 4, stride: 8, normalised: true }, + snorm16x2: { size: 2, stride: 4, normalised: true }, + snorm16x4: { size: 4, stride: 8, normalised: true }, + float16x2: { size: 2, stride: 4, normalised: false }, + float16x4: { size: 4, stride: 8, normalised: false }, + float32: { size: 1, stride: 4, normalised: false }, + float32x2: { size: 2, stride: 8, normalised: false }, + float32x3: { size: 3, stride: 12, normalised: false }, + float32x4: { size: 4, stride: 16, normalised: false }, + uint32: { size: 1, stride: 4, normalised: false }, + uint32x2: { size: 2, stride: 8, normalised: false }, + uint32x3: { size: 3, stride: 12, normalised: false }, + uint32x4: { size: 4, stride: 16, normalised: false }, + sint32: { size: 1, stride: 4, normalised: false }, + sint32x2: { size: 2, stride: 8, normalised: false }, + sint32x3: { size: 3, stride: 12, normalised: false }, + sint32x4: { size: 4, stride: 16, normalised: false } +}; +function getAttributeInfoFromFormat(format) { + var _a; + return (_a = attributeFormatData[format]) != null ? _a : attributeFormatData.float32; +} + +"use strict"; +const WGSL_TO_VERTEX_TYPES = { + f32: "float32", + "vec2": "float32x2", + "vec3": "float32x3", + "vec4": "float32x4", + vec2f: "float32x2", + vec3f: "float32x3", + vec4f: "float32x4", + i32: "sint32", + "vec2": "sint32x2", + "vec3": "sint32x3", + "vec4": "sint32x4", + u32: "uint32", + "vec2": "uint32x2", + "vec3": "uint32x3", + "vec4": "uint32x4", + bool: "uint32", + "vec2": "uint32x2", + "vec3": "uint32x3", + "vec4": "uint32x4" +}; +function extractAttributesFromGpuProgram({ source, entryPoint }) { + var _a; + const results = {}; + const mainVertStart = source.indexOf(`fn ${entryPoint}`); + if (mainVertStart !== -1) { + const arrowFunctionStart = source.indexOf("->", mainVertStart); + if (arrowFunctionStart !== -1) { + const functionArgsSubstring = source.substring(mainVertStart, arrowFunctionStart); + const inputsRegex = /@location\((\d+)\)\s+([a-zA-Z0-9_]+)\s*:\s*([a-zA-Z0-9_<>]+)(?:,|\s|$)/g; + let match; + while ((match = inputsRegex.exec(functionArgsSubstring)) !== null) { + const format = (_a = WGSL_TO_VERTEX_TYPES[match[3]]) != null ? _a : "float32"; + results[match[2]] = { + location: parseInt(match[1], 10), + format, + stride: getAttributeInfoFromFormat(format).stride, + offset: 0, + instance: false, + start: 0 + }; + } + } + } + return results; +} + +"use strict"; +function extractStructAndGroups(wgsl) { + var _a, _b, _c; + const linePattern = /(^|[^/])@(group|binding)\(\d+\)[^;]+;/g; + const groupPattern = /@group\((\d+)\)/; + const bindingPattern = /@binding\((\d+)\)/; + const namePattern = /var(<[^>]+>)? (\w+)/; + const typePattern = /:\s*(\w+)/; + const structPattern = /struct\s+(\w+)\s*{([^}]+)}/g; + const structMemberPattern = /(\w+)\s*:\s*([\w\<\>]+)/g; + const structName = /struct\s+(\w+)/; + const groups = (_a = wgsl.match(linePattern)) == null ? void 0 : _a.map((item) => ({ + group: parseInt(item.match(groupPattern)[1], 10), + binding: parseInt(item.match(bindingPattern)[1], 10), + name: item.match(namePattern)[2], + isUniform: item.match(namePattern)[1] === "", + type: item.match(typePattern)[1] + })); + if (!groups) { + return { + groups: [], + structs: [] + }; + } + const structs = (_c = (_b = wgsl.match(structPattern)) == null ? void 0 : _b.map((struct) => { + const name = struct.match(structName)[1]; + const members = struct.match(structMemberPattern).reduce((acc, member) => { + const [name2, type] = member.split(":"); + acc[name2.trim()] = type.trim(); + return acc; + }, {}); + if (!members) { + return null; + } + return { name, members }; + }).filter(({ name }) => groups.some((group) => group.type === name))) != null ? _c : []; + return { + groups, + structs + }; +} + +"use strict"; +var ShaderStage = /* @__PURE__ */ ((ShaderStage2) => { + ShaderStage2[ShaderStage2["VERTEX"] = 1] = "VERTEX"; + ShaderStage2[ShaderStage2["FRAGMENT"] = 2] = "FRAGMENT"; + ShaderStage2[ShaderStage2["COMPUTE"] = 4] = "COMPUTE"; + return ShaderStage2; +})(ShaderStage || {}); + +"use strict"; +function generateGpuLayoutGroups({ groups }) { + const layout = []; + for (let i = 0; i < groups.length; i++) { + const group = groups[i]; + if (!layout[group.group]) { + layout[group.group] = []; + } + if (group.isUniform) { + layout[group.group].push({ + binding: group.binding, + visibility: ShaderStage.VERTEX | ShaderStage.FRAGMENT, + buffer: { + type: "uniform" + } + }); + } else if (group.type === "sampler") { + layout[group.group].push({ + binding: group.binding, + visibility: ShaderStage.FRAGMENT, + sampler: { + type: "filtering" + } + }); + } else if (group.type === "texture_2d") { + layout[group.group].push({ + binding: group.binding, + visibility: ShaderStage.FRAGMENT, + texture: { + sampleType: "float", + viewDimension: "2d", + multisampled: false + } + }); + } + } + return layout; +} + +"use strict"; +function generateLayoutHash({ groups }) { + const layout = []; + for (let i = 0; i < groups.length; i++) { + const group = groups[i]; + if (!layout[group.group]) { + layout[group.group] = {}; + } + layout[group.group][group.name] = group.binding; + } + return layout; +} + +"use strict"; +function removeStructAndGroupDuplicates(vertexStructsAndGroups, fragmentStructsAndGroups) { + const structNameSet = /* @__PURE__ */ new Set(); + const dupeGroupKeySet = /* @__PURE__ */ new Set(); + const structs = [...vertexStructsAndGroups.structs, ...fragmentStructsAndGroups.structs].filter((struct) => { + if (structNameSet.has(struct.name)) { + return false; + } + structNameSet.add(struct.name); + return true; + }); + const groups = [...vertexStructsAndGroups.groups, ...fragmentStructsAndGroups.groups].filter((group) => { + const key = `${group.name}-${group.binding}`; + if (dupeGroupKeySet.has(key)) { + return false; + } + dupeGroupKeySet.add(key); + return true; + }); + return { structs, groups }; +} + +"use strict"; +const programCache = /* @__PURE__ */ Object.create(null); +class GpuProgram { + /** + * Create a new GpuProgram + * @param options - The options for the gpu program + */ + constructor(options) { + /** + * @internal + * @ignore + */ + this._layoutKey = 0; + var _a, _b; + const { fragment, vertex, layout, gpuLayout, name } = options; + this.name = name; + this.fragment = fragment; + this.vertex = vertex; + if (fragment.source === vertex.source) { + const structsAndGroups = extractStructAndGroups(fragment.source); + this.structsAndGroups = structsAndGroups; + } else { + const vertexStructsAndGroups = extractStructAndGroups(vertex.source); + const fragmentStructsAndGroups = extractStructAndGroups(fragment.source); + this.structsAndGroups = removeStructAndGroupDuplicates(vertexStructsAndGroups, fragmentStructsAndGroups); + } + this.layout = layout != null ? layout : generateLayoutHash(this.structsAndGroups); + this.gpuLayout = gpuLayout != null ? gpuLayout : generateGpuLayoutGroups(this.structsAndGroups); + this.autoAssignGlobalUniforms = !!(((_a = this.layout[0]) == null ? void 0 : _a.globalUniforms) !== void 0); + this.autoAssignLocalUniforms = !!(((_b = this.layout[1]) == null ? void 0 : _b.localUniforms) !== void 0); + this._generateProgramKey(); + } + // TODO maker this pure + _generateProgramKey() { + const { vertex, fragment } = this; + const bigKey = vertex.source + fragment.source + vertex.entryPoint + fragment.entryPoint; + this._layoutKey = createIdFromString(bigKey, "program"); + } + get attributeData() { + var _a; + (_a = this._attributeData) != null ? _a : this._attributeData = extractAttributesFromGpuProgram(this.vertex); + return this._attributeData; + } + /** destroys the program */ + destroy() { + this.gpuLayout = null; + this.layout = null; + this.structsAndGroups = null; + this.fragment = null; + this.vertex = null; + } + /** + * Helper function that creates a program for a given source. + * It will check the program cache if the program has already been created. + * If it has that one will be returned, if not a new one will be created and cached. + * @param options - The options for the program. + * @returns A program using the same source + */ + static from(options) { + const key = `${options.vertex.source}:${options.fragment.source}:${options.fragment.entryPoint}:${options.vertex.entryPoint}`; + if (!programCache[key]) { + programCache[key] = new GpuProgram(options); + } + return programCache[key]; + } +} + +"use strict"; +function addBits(srcParts, parts, name) { + if (srcParts) { + for (const i in srcParts) { + const id = i.toLocaleLowerCase(); + const part = parts[id]; + if (part) { + let sanitisedPart = srcParts[i]; + if (i === "header") { + sanitisedPart = sanitisedPart.replace(/@in\s+[^;]+;\s*/g, "").replace(/@out\s+[^;]+;\s*/g, ""); + } + if (name) { + part.push(`//----${name}----//`); + } + part.push(sanitisedPart); + } else { + warn(`${i} placement hook does not exist in shader`); + } + } + } +} + +"use strict"; +const findHooksRx = /\{\{(.*?)\}\}/g; +function compileHooks(programSrc) { + var _a, _b; + const parts = {}; + const partMatches = (_b = (_a = programSrc.match(findHooksRx)) == null ? void 0 : _a.map((hook) => hook.replace(/[{()}]/g, ""))) != null ? _b : []; + partMatches.forEach((hook) => { + parts[hook] = []; + }); + return parts; +} + +"use strict"; +function extractInputs(fragmentSource, out) { + let match; + const regex = /@in\s+([^;]+);/g; + while ((match = regex.exec(fragmentSource)) !== null) { + out.push(match[1]); + } +} +function compileInputs(fragments, template, sort = false) { + const results = []; + extractInputs(template, results); + fragments.forEach((fragment) => { + if (fragment.header) { + extractInputs(fragment.header, results); + } + }); + const mainInput = results; + if (sort) { + mainInput.sort(); + } + const finalString = mainInput.map((inValue, i) => ` @location(${i}) ${inValue},`).join("\n"); + let cleanedString = template.replace(/@in\s+[^;]+;\s*/g, ""); + cleanedString = cleanedString.replace("{{in}}", ` +${finalString} +`); + return cleanedString; +} + +"use strict"; +function extractOutputs(fragmentSource, out) { + let match; + const regex = /@out\s+([^;]+);/g; + while ((match = regex.exec(fragmentSource)) !== null) { + out.push(match[1]); + } +} +function extractVariableName(value) { + const regex = /\b(\w+)\s*:/g; + const match = regex.exec(value); + return match ? match[1] : ""; +} +function stripVariable(value) { + const regex = /@.*?\s+/g; + return value.replace(regex, ""); +} +function compileOutputs(fragments, template) { + const results = []; + extractOutputs(template, results); + fragments.forEach((fragment) => { + if (fragment.header) { + extractOutputs(fragment.header, results); + } + }); + let index = 0; + const mainStruct = results.sort().map((inValue) => { + if (inValue.indexOf("builtin") > -1) { + return inValue; + } + return `@location(${index++}) ${inValue}`; + }).join(",\n"); + const mainStart = results.sort().map((inValue) => ` var ${stripVariable(inValue)};`).join("\n"); + const mainEnd = `return VSOutput( + ${results.sort().map((inValue) => ` ${extractVariableName(inValue)}`).join(",\n")});`; + let compiledCode = template.replace(/@out\s+[^;]+;\s*/g, ""); + compiledCode = compiledCode.replace("{{struct}}", ` +${mainStruct} +`); + compiledCode = compiledCode.replace("{{start}}", ` +${mainStart} +`); + compiledCode = compiledCode.replace("{{return}}", ` +${mainEnd} +`); + return compiledCode; +} + +"use strict"; +function injectBits(templateSrc, fragmentParts) { + let out = templateSrc; + for (const i in fragmentParts) { + const parts = fragmentParts[i]; + const toInject = parts.join("\n"); + if (toInject.length) { + out = out.replace(`{{${i}}}`, `//-----${i} START-----// +${parts.join("\n")} +//----${i} FINISH----//`); + } else { + out = out.replace(`{{${i}}}`, ""); + } + } + return out; +} + +"use strict"; +const cacheMap = /* @__PURE__ */ Object.create(null); +const bitCacheMap = /* @__PURE__ */ new Map(); +let CACHE_UID = 0; +function compileHighShader({ + template, + bits +}) { + const cacheId = generateCacheId(template, bits); + if (cacheMap[cacheId]) + return cacheMap[cacheId]; + const { vertex, fragment } = compileInputsAndOutputs(template, bits); + cacheMap[cacheId] = compileBits(vertex, fragment, bits); + return cacheMap[cacheId]; +} +function compileHighShaderGl({ + template, + bits +}) { + const cacheId = generateCacheId(template, bits); + if (cacheMap[cacheId]) + return cacheMap[cacheId]; + cacheMap[cacheId] = compileBits(template.vertex, template.fragment, bits); + return cacheMap[cacheId]; +} +function compileInputsAndOutputs(template, bits) { + const vertexFragments = bits.map((shaderBit) => shaderBit.vertex).filter((v) => !!v); + const fragmentFragments = bits.map((shaderBit) => shaderBit.fragment).filter((v) => !!v); + let compiledVertex = compileInputs(vertexFragments, template.vertex, true); + compiledVertex = compileOutputs(vertexFragments, compiledVertex); + const compiledFragment = compileInputs(fragmentFragments, template.fragment, true); + return { + vertex: compiledVertex, + fragment: compiledFragment + }; +} +function generateCacheId(template, bits) { + return bits.map((highFragment) => { + if (!bitCacheMap.has(highFragment)) { + bitCacheMap.set(highFragment, CACHE_UID++); + } + return bitCacheMap.get(highFragment); + }).sort((a, b) => a - b).join("-") + template.vertex + template.fragment; +} +function compileBits(vertex, fragment, bits) { + const vertexParts = compileHooks(vertex); + const fragmentParts = compileHooks(fragment); + bits.forEach((shaderBit) => { + addBits(shaderBit.vertex, vertexParts, shaderBit.name); + addBits(shaderBit.fragment, fragmentParts, shaderBit.name); + }); + return { + vertex: injectBits(vertex, vertexParts), + fragment: injectBits(fragment, fragmentParts) + }; +} + +"use strict"; +const vertexGPUTemplate = ( + /* wgsl */ + ` @in aPosition: vec2; @in aUV: vec2; @@ -87,7 +21973,11 @@ ${i.join(` {{return}} }; -`,xd=` +` +); +const fragmentGPUTemplate = ( + /* wgsl */ + ` @in vUV : vec2; @in vColor : vec4; @@ -106,7 +21996,11 @@ ${i.join(` return outColor * vColor; }; -`,bd=` +` +); +const vertexGlTemplate = ( + /* glsl */ + ` in vec2 aPosition; in vec2 aUV; @@ -142,7 +22036,11 @@ ${i.join(` {{end}} } -`,vd=` +` +); +const fragmentGlTemplate = ( + /* glsl */ + ` in vec4 vColor; in vec2 vUV; @@ -161,7 +22059,16 @@ ${i.join(` finalColor = outColor * vColor; } -`,yd={name:"global-uniforms-bit",vertex:{header:` +` +); + +"use strict"; +const globalUniformsBit = { + name: "global-uniforms-bit", + vertex: { + header: ( + /* wgsl */ + ` struct GlobalUniforms { uProjectionMatrix:mat3x3, uWorldTransformMatrix:mat3x3, @@ -170,78 +22077,511 @@ ${i.join(` } @group(0) @binding(0) var globalUniforms : GlobalUniforms; - `}},hy={name:"global-uniforms-ubo-bit",vertex:{header:` + ` + ) + } +}; +const globalUniformsUBOBitGl = { + name: "global-uniforms-ubo-bit", + vertex: { + header: ( + /* glsl */ + ` uniform globalUniforms { mat3 uProjectionMatrix; mat3 uWorldTransformMatrix; vec4 uWorldColorAlpha; vec2 uResolution; }; - `}},Td={name:"global-uniforms-bit",vertex:{header:` + ` + ) + } +}; +const globalUniformsBitGl = { + name: "global-uniforms-bit", + vertex: { + header: ( + /* glsl */ + ` uniform mat3 uProjectionMatrix; uniform mat3 uWorldTransformMatrix; uniform vec4 uWorldColorAlpha; uniform vec2 uResolution; - `}};var cy=Object.defineProperty,Sd=Object.getOwnPropertySymbols,dy=Object.prototype.hasOwnProperty,py=Object.prototype.propertyIsEnumerable,Ed=(r,t,e)=>t in r?cy(r,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):r[t]=e,fy=(r,t)=>{for(var e in t||(t={}))dy.call(t,e)&&Ed(r,e,t[e]);if(Sd)for(var e of Sd(t))py.call(t,e)&&Ed(r,e,t[e]);return r};function Ue({bits:r,name:t}){const e=pd({template:{fragment:xd,vertex:_d},bits:[yd,...r]});return Tt.from({name:t,vertex:{source:e.vertex,entryPoint:"main"},fragment:{source:e.fragment,entryPoint:"main"}})}function ke({bits:r,name:t}){return new Rt(fy({name:t},fd({template:{vertex:bd,fragment:vd},bits:[Td,...r]})))}const Us={name:"color-bit",vertex:{header:` + ` + ) + } +}; + +"use strict"; +var __defProp$J = Object.defineProperty; +var __getOwnPropSymbols$J = Object.getOwnPropertySymbols; +var __hasOwnProp$J = Object.prototype.hasOwnProperty; +var __propIsEnum$J = Object.prototype.propertyIsEnumerable; +var __defNormalProp$J = (obj, key, value) => key in obj ? __defProp$J(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; +var __spreadValues$J = (a, b) => { + for (var prop in b || (b = {})) + if (__hasOwnProp$J.call(b, prop)) + __defNormalProp$J(a, prop, b[prop]); + if (__getOwnPropSymbols$J) + for (var prop of __getOwnPropSymbols$J(b)) { + if (__propIsEnum$J.call(b, prop)) + __defNormalProp$J(a, prop, b[prop]); + } + return a; +}; +function compileHighShaderGpuProgram({ bits, name }) { + const source = compileHighShader({ + template: { + fragment: fragmentGPUTemplate, + vertex: vertexGPUTemplate + }, + bits: [ + globalUniformsBit, + ...bits + ] + }); + return GpuProgram.from({ + name, + vertex: { + source: source.vertex, + entryPoint: "main" + }, + fragment: { + source: source.fragment, + entryPoint: "main" + } + }); +} +function compileHighShaderGlProgram({ bits, name }) { + return new GlProgram(__spreadValues$J({ + name + }, compileHighShaderGl({ + template: { + vertex: vertexGlTemplate, + fragment: fragmentGlTemplate + }, + bits: [ + globalUniformsBitGl, + ...bits + ] + }))); +} + +"use strict"; +const colorBit = { + name: "color-bit", + vertex: { + header: ( + /* wgsl */ + ` @in aColor: vec4; - `,main:` + ` + ), + main: ( + /* wgsl */ + ` vColor *= vec4(aColor.rgb * aColor.a, aColor.a); - `}},ks={name:"color-bit",vertex:{header:` + ` + ) + } +}; +const colorBitGl = { + name: "color-bit", + vertex: { + header: ( + /* glsl */ + ` in vec4 aColor; - `,main:` + ` + ), + main: ( + /* glsl */ + ` vColor *= vec4(aColor.rgb * aColor.a, aColor.a); - `}},Oo={};function my(r){const t=[];if(r===1)t.push("@group(1) @binding(0) var textureSource1: texture_2d;"),t.push("@group(1) @binding(1) var textureSampler1: sampler;");else{let e=0;for(let s=0;s;`),t.push(`@group(1) @binding(${e++}) var textureSampler${s+1}: sampler;`)}return t.join(` -`)}function gy(r){const t=[];if(r===1)t.push("outColor = textureSampleGrad(textureSource1, textureSampler1, vUV, uvDx, uvDy);");else{t.push("switch vTextureId {");for(let e=0;e;"); + src.push("@group(1) @binding(1) var textureSampler1: sampler;"); + } else { + let bindingIndex = 0; + for (let i = 0; i < maxTextures; i++) { + src.push(`@group(1) @binding(${bindingIndex++}) var textureSource${i + 1}: texture_2d;`); + src.push(`@group(1) @binding(${bindingIndex++}) var textureSampler${i + 1}: sampler;`); + } + } + return src.join("\n"); +} +function generateSampleSrc(maxTextures) { + const src = []; + if (maxTextures === 1) { + src.push("outColor = textureSampleGrad(textureSource1, textureSampler1, vUV, uvDx, uvDy);"); + } else { + src.push("switch vTextureId {"); + for (let i = 0; i < maxTextures; i++) { + if (i === maxTextures - 1) { + src.push(` default:{`); + } else { + src.push(` case ${i}:{`); + } + src.push(` outColor = textureSampleGrad(textureSource${i + 1}, textureSampler${i + 1}, vUV, uvDx, uvDy);`); + src.push(` break;}`); + } + src.push(`}`); + } + return src.join("\n"); +} +function generateTextureBatchBit(maxTextures) { + if (!textureBatchBitGpuCache[maxTextures]) { + textureBatchBitGpuCache[maxTextures] = { + name: "texture-batch-bit", + vertex: { + header: ` @in aTextureIdAndRound: vec2; @out @interpolate(flat) vTextureId : u32; - `,main:` + `, + main: ` vTextureId = aTextureIdAndRound.y; - `,end:` + `, + end: ` if(aTextureIdAndRound.x == 1) { vPosition = vec4(roundPixels(vPosition.xy, globalUniforms.uResolution), vPosition.zw); } - `},fragment:{header:` + ` + }, + fragment: { + header: ` @in @interpolate(flat) vTextureId: u32; - ${my(16)} - `,main:` + ${generateBindingSrc(16)} + `, + main: ` var uvDx = dpdx(vUV); var uvDy = dpdy(vUV); - ${gy(16)} - `}}),Oo[r]}const Co={};function _y(r){const t=[];for(let e=0;e0&&t.push("else"),e 0) { + src.push("else"); + } + if (i < maxTextures - 1) { + src.push(`if(vTextureId < ${i}.5)`); + } + src.push("{"); + src.push(` outColor = texture(uTextures[${i}], vUV);`); + src.push("}"); + } + return src.join("\n"); +} +function generateTextureBatchBitGl(maxTextures) { + if (!textureBatchBitGlCache[maxTextures]) { + textureBatchBitGlCache[maxTextures] = { + name: "texture-batch-bit", + vertex: { + header: ` in vec2 aTextureIdAndRound; out float vTextureId; - `,main:` + `, + main: ` vTextureId = aTextureIdAndRound.y; - `,end:` + `, + end: ` if(aTextureIdAndRound.x == 1.) { gl_Position.xy = roundPixels(gl_Position.xy, uResolution); } - `},fragment:{header:` + ` + }, + fragment: { + header: ` in float vTextureId; - uniform sampler2D uTextures[${r}]; + uniform sampler2D uTextures[${maxTextures}]; - `,main:` + `, + main: ` - ${_y(16)} - `}}),Co[r]}const Le={name:"round-pixels-bit",vertex:{header:` + ${generateSampleGlSrc(16)} + ` + } + }; + } + return textureBatchBitGlCache[maxTextures]; +} + +"use strict"; +const roundPixelsBit = { + name: "round-pixels-bit", + vertex: { + header: ( + /* wgsl */ + ` fn roundPixels(position: vec2, targetSize: vec2) -> vec2 { - return (floor((position * 0.5 + 0.5) * targetSize) / targetSize) * 2.0 - 1.0; + return (floor(((position * 0.5 + 0.5) * targetSize) + 0.5) / targetSize) * 2.0 - 1.0; } - `}},$e={name:"round-pixels-bit",vertex:{header:` + ` + ) + } +}; +const roundPixelsBitGl = { + name: "round-pixels-bit", + vertex: { + header: ( + /* glsl */ + ` vec2 roundPixels(vec2 position, vec2 targetSize) { - return (floor((position * 0.5 + 0.5) * targetSize) / targetSize) * 2.0 - 1.0; + return (floor(((position * 0.5 + 0.5) * targetSize) + 0.5) / targetSize) * 2.0 - 1.0; } - `}},Ad=new Int32Array(wt);for(let r=0;r(r[r.WEBGL=1]="WEBGL",r[r.WEBGPU=2]="WEBGPU",r[r.BOTH=3]="BOTH",r))(xt||{}),xy=Object.defineProperty,Hs=Object.getOwnPropertySymbols,Pd=Object.prototype.hasOwnProperty,wd=Object.prototype.propertyIsEnumerable,Rd=(r,t,e)=>t in r?xy(r,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):r[t]=e,by=(r,t)=>{for(var e in t||(t={}))Pd.call(t,e)&&Rd(r,e,t[e]);if(Hs)for(var e of Hs(t))wd.call(t,e)&&Rd(r,e,t[e]);return r},vy=(r,t)=>{var e={};for(var s in r)Pd.call(r,s)&&t.indexOf(s)<0&&(e[s]=r[s]);if(r!=null&&Hs)for(var s of Hs(r))t.indexOf(s)<0&&wd.call(r,s)&&(e[s]=r[s]);return e};class St extends ct{constructor(t){super(),this._uniformBindMap=Object.create(null),this._ownedBindGroups=[];let{gpuProgram:e,glProgram:s,groups:i,resources:n,compatibleRenderers:o,groupMap:a}=t;this.gpuProgram=e,this.glProgram=s,o===void 0&&(o=0,e&&(o|=xt.WEBGPU),s&&(o|=xt.WEBGL)),this.compatibleRenderers=o;const u={};if(!n&&!i&&(n={}),n&&i)throw new Error("[Shader] Cannot have both resources and groups");if(!e&&i&&!a)throw new Error("[Shader] No group map or WebGPU shader provided - consider using resources instead.");if(!e&&i&&a)for(const l in a)for(const h in a[l]){const c=a[l][h];u[c]={group:l,binding:h,name:c}}else if(e&&i&&!a){const l=e.structsAndGroups.groups;a={},l.forEach(h=>{a[h.group]=a[h.group]||{},a[h.group][h.binding]=h.name,u[h.name]=h})}else if(n){if(e){const l=e.structsAndGroups.groups;a={},l.forEach(h=>{a[h.group]=a[h.group]||{},a[h.group][h.binding]=h.name,u[h.name]=h})}else{a={},i={99:new Lt},this._ownedBindGroups.push(i[99]);let l=0;for(const h in n)u[h]={group:99,binding:l,name:h},a[99]=a[99]||{},a[99][l]=h,l++}i={};for(const l in n){const h=l;let c=n[l];!c.source&&!c._resourceType&&(c=new it(c));const d=u[h];d&&(i[d.group]||(i[d.group]=new Lt,this._ownedBindGroups.push(i[d.group])),i[d.group].setResource(c,d.binding))}}this.groups=i,this._uniformBindMap=a,this.resources=this._buildResourceAccessor(i,u)}addResource(t,e,s){var i,n;(i=this._uniformBindMap)[e]||(i[e]={}),(n=this._uniformBindMap[e])[s]||(n[s]=t),this.groups[e]||(this.groups[e]=new Lt,this._ownedBindGroups.push(this.groups[e]))}_buildResourceAccessor(t,e){const s={};for(const i in e){const n=e[i];Object.defineProperty(s,n.name,{get(){return t[n.group].getResource(n.binding)},set(o){t[n.group].setResource(o,n.binding)}})}return s}destroy(t=!1){var e,s;this.emit("destroy",this),t&&((e=this.gpuProgram)==null||e.destroy(),(s=this.glProgram)==null||s.destroy()),this.gpuProgram=null,this.glProgram=null,this.removeAllListeners(),this._uniformBindMap=null,this._ownedBindGroups.forEach(i=>{i.destroy()}),this._ownedBindGroups=null,this.resources=null,this.groups=null}static from(t){const e=t,{gpu:s,gl:i}=e,n=vy(e,["gpu","gl"]);let o,a;return s&&(o=Tt.from(s)),i&&(a=Rt.from(i)),new St(by({gpuProgram:o,glProgram:a},n))}}const Md={name:"local-uniform-msdf-bit",vertex:{header:` + ` + ) + } +}; + +"use strict"; +const sampleValues = new Int32Array(MAX_TEXTURES); +for (let i = 0; i < MAX_TEXTURES; i++) { + sampleValues[i] = i; +} +const batchSamplersUniformGroup = new UniformGroup({ + uTextures: { value: sampleValues, type: `i32`, size: MAX_TEXTURES } +}, { isStatic: true }); + +"use strict"; +var RendererType = /* @__PURE__ */ ((RendererType2) => { + RendererType2[RendererType2["WEBGL"] = 1] = "WEBGL"; + RendererType2[RendererType2["WEBGPU"] = 2] = "WEBGPU"; + RendererType2[RendererType2["BOTH"] = 3] = "BOTH"; + return RendererType2; +})(RendererType || {}); + +"use strict"; +var __defProp$I = Object.defineProperty; +var __getOwnPropSymbols$I = Object.getOwnPropertySymbols; +var __hasOwnProp$I = Object.prototype.hasOwnProperty; +var __propIsEnum$I = Object.prototype.propertyIsEnumerable; +var __defNormalProp$I = (obj, key, value) => key in obj ? __defProp$I(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; +var __spreadValues$I = (a, b) => { + for (var prop in b || (b = {})) + if (__hasOwnProp$I.call(b, prop)) + __defNormalProp$I(a, prop, b[prop]); + if (__getOwnPropSymbols$I) + for (var prop of __getOwnPropSymbols$I(b)) { + if (__propIsEnum$I.call(b, prop)) + __defNormalProp$I(a, prop, b[prop]); + } + return a; +}; +var __objRest$f = (source, exclude) => { + var target = {}; + for (var prop in source) + if (__hasOwnProp$I.call(source, prop) && exclude.indexOf(prop) < 0) + target[prop] = source[prop]; + if (source != null && __getOwnPropSymbols$I) + for (var prop of __getOwnPropSymbols$I(source)) { + if (exclude.indexOf(prop) < 0 && __propIsEnum$I.call(source, prop)) + target[prop] = source[prop]; + } + return target; +}; +class Shader extends EventEmitter { + constructor(options) { + super(); + /** + * A record of the uniform groups and resources used by the shader. + * This is used by WebGL renderer to sync uniform data. + * @internal + * @ignore + */ + this._uniformBindMap = /* @__PURE__ */ Object.create(null); + this._ownedBindGroups = []; + let { + gpuProgram, + glProgram, + groups, + resources, + compatibleRenderers, + groupMap + } = options; + this.gpuProgram = gpuProgram; + this.glProgram = glProgram; + if (compatibleRenderers === void 0) { + compatibleRenderers = 0; + if (gpuProgram) + compatibleRenderers |= RendererType.WEBGPU; + if (glProgram) + compatibleRenderers |= RendererType.WEBGL; + } + this.compatibleRenderers = compatibleRenderers; + const nameHash = {}; + if (!resources && !groups) { + resources = {}; + } + if (resources && groups) { + throw new Error("[Shader] Cannot have both resources and groups"); + } else if (!gpuProgram && groups && !groupMap) { + throw new Error("[Shader] No group map or WebGPU shader provided - consider using resources instead."); + } else if (!gpuProgram && groups && groupMap) { + for (const i in groupMap) { + for (const j in groupMap[i]) { + const uniformName = groupMap[i][j]; + nameHash[uniformName] = { + group: i, + binding: j, + name: uniformName + }; + } + } + } else if (gpuProgram && groups && !groupMap) { + const groupData = gpuProgram.structsAndGroups.groups; + groupMap = {}; + groupData.forEach((data) => { + groupMap[data.group] = groupMap[data.group] || {}; + groupMap[data.group][data.binding] = data.name; + nameHash[data.name] = data; + }); + } else if (resources) { + if (!gpuProgram) { + groupMap = {}; + groups = { + 99: new BindGroup() + }; + this._ownedBindGroups.push(groups[99]); + let bindTick = 0; + for (const i in resources) { + nameHash[i] = { group: 99, binding: bindTick, name: i }; + groupMap[99] = groupMap[99] || {}; + groupMap[99][bindTick] = i; + bindTick++; + } + } else { + const groupData = gpuProgram.structsAndGroups.groups; + groupMap = {}; + groupData.forEach((data) => { + groupMap[data.group] = groupMap[data.group] || {}; + groupMap[data.group][data.binding] = data.name; + nameHash[data.name] = data; + }); + } + groups = {}; + for (const i in resources) { + const name = i; + let value = resources[i]; + if (!value.source && !value._resourceType) { + value = new UniformGroup(value); + } + const data = nameHash[name]; + if (data) { + if (!groups[data.group]) { + groups[data.group] = new BindGroup(); + this._ownedBindGroups.push(groups[data.group]); + } + groups[data.group].setResource(value, data.binding); + } + } + } + this.groups = groups; + this._uniformBindMap = groupMap; + this.resources = this._buildResourceAccessor(groups, nameHash); + } + /** + * Sometimes a resource group will be provided later (for example global uniforms) + * In such cases, this method can be used to let the shader know about the group. + * @param name - the name of the resource group + * @param groupIndex - the index of the group (should match the webGPU shader group location) + * @param bindIndex - the index of the bind point (should match the webGPU shader bind point) + */ + addResource(name, groupIndex, bindIndex) { + var _a, _b; + (_a = this._uniformBindMap)[groupIndex] || (_a[groupIndex] = {}); + (_b = this._uniformBindMap[groupIndex])[bindIndex] || (_b[bindIndex] = name); + if (!this.groups[groupIndex]) { + this.groups[groupIndex] = new BindGroup(); + this._ownedBindGroups.push(this.groups[groupIndex]); + } + } + _buildResourceAccessor(groups, nameHash) { + const uniformsOut = {}; + for (const i in nameHash) { + const data = nameHash[i]; + Object.defineProperty(uniformsOut, data.name, { + get() { + return groups[data.group].getResource(data.binding); + }, + set(value) { + groups[data.group].setResource(value, data.binding); + } + }); + } + return uniformsOut; + } + /** + * Use to destroy the shader when its not longer needed. + * It will destroy the resources and remove listeners. + * @param destroyPrograms - if the programs should be destroyed as well. + * Make sure its not being used by other shaders! + */ + destroy(destroyPrograms = false) { + var _a, _b; + this.emit("destroy", this); + if (destroyPrograms) { + (_a = this.gpuProgram) == null ? void 0 : _a.destroy(); + (_b = this.glProgram) == null ? void 0 : _b.destroy(); + } + this.gpuProgram = null; + this.glProgram = null; + this.removeAllListeners(); + this._uniformBindMap = null; + this._ownedBindGroups.forEach((bindGroup) => { + bindGroup.destroy(); + }); + this._ownedBindGroups = null; + this.resources = null; + this.groups = null; + } + static from(options) { + const _a = options, { gpu, gl } = _a, rest = __objRest$f(_a, ["gpu", "gl"]); + let gpuProgram; + let glProgram; + if (gpu) { + gpuProgram = GpuProgram.from(gpu); + } + if (gl) { + glProgram = GlProgram.from(gl); + } + return new Shader(__spreadValues$I({ + gpuProgram, + glProgram + }, rest)); + } +} + +"use strict"; +const localUniformMSDFBit = { + name: "local-uniform-msdf-bit", + vertex: { + header: ( + /* wgsl */ + ` struct LocalUniforms { uColor:vec4, uTransformMatrix:mat3x3, @@ -250,15 +22590,29 @@ ${i.join(` } @group(2) @binding(0) var localUniforms : LocalUniforms; - `,main:` + ` + ), + main: ( + /* wgsl */ + ` vColor *= localUniforms.uColor; modelMatrix *= localUniforms.uTransformMatrix; - `,end:` + ` + ), + end: ( + /* wgsl */ + ` if(localUniforms.uRound == 1) { vPosition = vec4(roundPixels(vPosition.xy, globalUniforms.uResolution), vPosition.zw); } - `},fragment:{header:` + ` + ) + }, + fragment: { + header: ( + /* wgsl */ + ` struct LocalUniforms { uColor:vec4, uTransformMatrix:mat3x3, @@ -266,25 +22620,67 @@ ${i.join(` } @group(2) @binding(0) var localUniforms : LocalUniforms; - `,main:` + ` + ), + main: ( + /* wgsl */ + ` outColor = vColor * calculateMSDFAlpha(outColor, localUniforms.uDistance); - `}},Od={name:"local-uniform-msdf-bit",vertex:{header:` + ` + ) + } +}; +const localUniformMSDFBitGl = { + name: "local-uniform-msdf-bit", + vertex: { + header: ( + /* glsl */ + ` uniform mat3 uTransformMatrix; uniform vec4 uColor; uniform float uRound; - `,main:` + ` + ), + main: ( + /* glsl */ + ` vColor *= uColor; modelMatrix *= uTransformMatrix; - `,end:` + ` + ), + end: ( + /* glsl */ + ` if(uRound == 1.) { gl_Position.xy = roundPixels(gl_Position.xy, uResolution); } - `},fragment:{header:` + ` + ) + }, + fragment: { + header: ( + /* glsl */ + ` uniform float uDistance; - `,main:` + ` + ), + main: ( + /* glsl */ + ` outColor = vColor * calculateMSDFAlpha(outColor, uDistance); - `}},Cd={name:"msdf-bit",fragment:{header:` + ` + ) + } +}; + +"use strict"; +const mSDFBit = { + name: "msdf-bit", + fragment: { + header: ( + /* wgsl */ + ` fn calculateMSDFAlpha(msdfColor:vec4, distance:f32) -> f32 { // MSDF @@ -305,7 +22701,16 @@ ${i.join(` return alpha; } - `}},Gd={name:"msdf-bit",fragment:{header:` + ` + ) + } +}; +const mSDFBitGl = { + name: "msdf-bit", + fragment: { + header: ( + /* glsl */ + ` float calculateMSDFAlpha(vec4 msdfColor, float distance) { // MSDF @@ -327,13 +22732,897 @@ ${i.join(` return alpha; } - `}};class Id extends St{constructor(){const t=new it({uColor:{value:new Float32Array([1,1,1,1]),type:"vec4"},uTransformMatrix:{value:new G,type:"mat3x3"},uDistance:{value:4,type:"f32"},uRound:{value:0,type:"f32"}}),e=Ue({name:"sdf-shader",bits:[Us,Ls(wt),Md,Cd,Le]}),s=ke({name:"sdf-shader",bits:[ks,$s(wt),Od,Gd,$e]});super({glProgram:s,gpuProgram:e,resources:{localUniforms:t,batchSamplers:Ns}})}}class Go{constructor(t){this._gpuBitmapText={},this._renderer=t}validateRenderable(t){const e=this._getGpuBitmapText(t);return t._didTextUpdate&&(t._didTextUpdate=!1,this._updateContext(t,e)),this._renderer.renderPipes.graphics.validateRenderable(e)}addRenderable(t,e){const s=this._getGpuBitmapText(t);Bd(t,s),t._didTextUpdate&&(t._didTextUpdate=!1,this._updateContext(t,s)),this._renderer.renderPipes.graphics.addRenderable(s,e),s.context.customShader&&this._updateDistanceField(t)}destroyRenderable(t){this._destroyRenderableByUid(t.uid)}_destroyRenderableByUid(t){H.return(this._gpuBitmapText[t]),this._gpuBitmapText[t]=null}updateRenderable(t){const e=this._getGpuBitmapText(t);Bd(t,e),this._renderer.renderPipes.graphics.updateRenderable(e),e.context.customShader&&this._updateDistanceField(t)}_updateContext(t,e){var s;const{context:i}=e,n=Pr.getFont(t.text,t._style);i.clear(),n.distanceField.type!=="none"&&(i.customShader||(this._sdfShader||(this._sdfShader=new Id),i.customShader=this._sdfShader));const o=Array.from(t.text),a=t._style;let u=(((s=a._stroke)==null?void 0:s.width)||0)/2;u+=n.baseLineOffset;const l=_o(o,a,n);let h=0;const c=a.padding,d=l.scale;i.translate(-t._anchor._x*l.width-c,-t._anchor._y*(l.height+l.offsetY)-c).scale(d,d);const p=a._fill.color;for(let f=0;f{this.destroyRenderable(t)}),this._gpuBitmapText[t.uid]}_updateDistanceField(t){var e;const s=this._getGpuBitmapText(t).context,i=t._style.fontFamily,n=Y.get(`${i}-bitmap`),{a:o,b:a,c:u,d:l}=t.groupTransform,h=Math.sqrt(o*o+a*a),c=Math.sqrt(u*u+l*l),d=(Math.abs(h)+Math.abs(c))/2,p=n.baseRenderedFontSize/t._style.fontSize,f=(e=t.resolution)!=null?e:this._renderer.resolution,g=d*n.distanceField.range*(1/p)*f;s.customShader.resources.localUniforms.uniforms.uDistance=g}destroy(){var t;for(const e in this._gpuBitmapText)this._destroyRenderableByUid(e);this._gpuBitmapText=null,(t=this._sdfShader)==null||t.destroy(!0),this._sdfShader=null,this._renderer=null}}Go.extension={type:[v.WebGLPipes,v.WebGPUPipes,v.CanvasPipes],name:"bitmapText"};function Bd(r,t){t.groupTransform=r.groupTransform,t.groupColorAlpha=r.groupColorAlpha,t.groupColor=r.groupColor,t.groupBlendMode=r.groupBlendMode,t.globalDisplayStatus=r.globalDisplayStatus,t.groupTransform=r.groupTransform,t.localDisplayStatus=r.localDisplayStatus,t.groupAlpha=r.groupAlpha,t._roundPixels=r._roundPixels}D.add(Go,Xc,Hc);class Io{constructor(t){this._gpuText=Object.create(null),this._renderer=t}validateRenderable(t){const e=this._getGpuText(t),s=t._getKey();return e.textureNeedsUploading?(e.textureNeedsUploading=!1,!0):e.currentKey!==s}addRenderable(t){const e=this._getGpuText(t).batchableSprite;t._didTextUpdate&&this._updateText(t),this._renderer.renderPipes.batch.addToBatch(e)}updateRenderable(t){const e=this._getGpuText(t).batchableSprite;t._didTextUpdate&&this._updateText(t),e.batcher.updateElement(e)}destroyRenderable(t){this._destroyRenderableById(t.uid)}_destroyRenderableById(t){const e=this._gpuText[t];this._renderer.htmlText.decreaseReferenceCount(e.currentKey),H.return(e.batchableSprite),this._gpuText[t]=null}_updateText(t){const e=t._getKey(),s=this._getGpuText(t),i=s.batchableSprite;s.currentKey!==e&&this._updateGpuText(t).catch(o=>{console.error(o)}),t._didTextUpdate=!1;const n=t._style.padding;dr(i.bounds,t._anchor,i.texture,n)}async _updateGpuText(t){var e;t._didTextUpdate=!1;const s=this._getGpuText(t);if(s.generatingTexture)return;const i=t._getKey();this._renderer.htmlText.decreaseReferenceCount(s.currentKey),s.generatingTexture=!0,s.currentKey=i;const n=(e=t.resolution)!=null?e:this._renderer.resolution,o=await this._renderer.htmlText.getManagedTexture(t.text,n,t._style,t._getKey()),a=s.batchableSprite;a.texture=s.texture=o,s.generatingTexture=!1,s.textureNeedsUploading=!0,t.onViewUpdate();const u=t._style.padding;dr(a.bounds,t._anchor,a.texture,u)}_getGpuText(t){return this._gpuText[t.uid]||this.initGpuText(t)}initGpuText(t){const e={texture:A.EMPTY,currentKey:"--",batchableSprite:H.get(Rs),textureNeedsUploading:!1,generatingTexture:!1},s=e.batchableSprite;return s.renderable=t,s.texture=A.EMPTY,s.bounds={minX:0,maxX:1,minY:0,maxY:0},s.roundPixels=this._renderer._roundPixels|t._roundPixels,this._gpuText[t.uid]=e,t.on("destroyed",()=>{this.destroyRenderable(t)}),e}destroy(){for(const t in this._gpuText)this._destroyRenderableById(t);this._gpuText=null,this._renderer=null}}Io.extension={type:[v.WebGLPipes,v.WebGPUPipes,v.CanvasPipes],name:"htmlText"};function Fd(){const{userAgent:r}=X.get().getNavigator();return/^((?!chrome|android).)*safari/i.test(r)}const Bo="http://www.w3.org/2000/svg",Fo="http://www.w3.org/1999/xhtml";class Do{constructor(){this.svgRoot=document.createElementNS(Bo,"svg"),this.foreignObject=document.createElementNS(Bo,"foreignObject"),this.domElement=document.createElementNS(Fo,"div"),this.styleElement=document.createElementNS(Fo,"style"),this.image=new Image;const{foreignObject:t,svgRoot:e,styleElement:s,domElement:i}=this;t.setAttribute("width","10000"),t.setAttribute("height","10000"),t.style.overflow="hidden",e.appendChild(t),t.appendChild(s),t.appendChild(i)}}function Dd(r){const t=r._stroke,e=r._fill,s=[`div { ${[`color: ${W.shared.setValue(e.color).toHex()}`,`font-size: ${r.fontSize}px`,`font-family: ${r.fontFamily}`,`font-weight: ${r.fontWeight}`,`font-style: ${r.fontStyle}`,`font-variant: ${r.fontVariant}`,`letter-spacing: ${r.letterSpacing}px`,`text-align: ${r.align}`,`padding: ${r.padding}px`,`white-space: ${r.whiteSpace==="pre"&&r.wordWrap?"pre-wrap":r.whiteSpace}`,...r.lineHeight?[`line-height: ${r.lineHeight}px`]:[],...r.wordWrap?[`word-wrap: ${r.breakWords?"break-all":"break-word"}`,`max-width: ${r.wordWrapWidth}px`]:[],...t?[kd(t)]:[],...r.dropShadow?[Ud(r.dropShadow)]:[],...r.cssOverrides].join(";")} }`];return yy(r.tagStyles,s),s.join(" ")}function Ud(r){const t=W.shared.setValue(r.color).setAlpha(r.alpha).toHexa(),e=Math.round(Math.cos(r.angle)*r.distance),s=Math.round(Math.sin(r.angle)*r.distance),i=`${e}px ${s}px`;return r.blur>0?`text-shadow: ${i} ${r.blur}px ${t}`:`text-shadow: ${i} ${t}`}function kd(r){return[`-webkit-text-stroke-width: ${r.width}px`,`-webkit-text-stroke-color: ${W.shared.setValue(r.color).toHex()}`,`text-stroke-width: ${r.width}px`,`text-stroke-color: ${W.shared.setValue(r.color).toHex()}`,"paint-order: stroke"].join(";")}const Ld={fontSize:"font-size: {{VALUE}}px",fontFamily:"font-family: {{VALUE}}",fontWeight:"font-weight: {{VALUE}}",fontStyle:"font-style: {{VALUE}}",fontVariant:"font-variant: {{VALUE}}",letterSpacing:"letter-spacing: {{VALUE}}px",align:"text-align: {{VALUE}}",padding:"padding: {{VALUE}}px",whiteSpace:"white-space: {{VALUE}}",lineHeight:"line-height: {{VALUE}}px",wordWrapWidth:"max-width: {{VALUE}}px"},$d={fill:r=>`color: ${W.shared.setValue(r).toHex()}`,breakWords:r=>`word-wrap: ${r?"break-all":"break-word"}`,stroke:kd,dropShadow:Ud};function yy(r,t){for(const e in r){const s=r[e],i=[];for(const n in s)$d[n]?i.push($d[n](s[n])):Ld[n]&&i.push(Ld[n].replace("{{VALUE}}",s[n]));t.push(`${e} { ${i.join(";")} }`)}}class Pe extends Wt{constructor(t={}){var e,s;super(t),this._cssOverrides=[],(e=this.cssOverrides)!=null||(this.cssOverrides=t.cssOverrides),this.tagStyles=(s=t.tagStyles)!=null?s:{}}set cssOverrides(t){this._cssOverrides=t instanceof Array?t:[t],this.update()}get cssOverrides(){return this._cssOverrides}_generateKey(){return this._styleKey=po(this)+this._cssOverrides.join("-"),this._styleKey}update(){this._cssStyle=null,super.update()}clone(){return new Pe({align:this.align,breakWords:this.breakWords,dropShadow:this.dropShadow,fill:this._fill,fontFamily:this.fontFamily,fontSize:this.fontSize,fontStyle:this.fontStyle,fontVariant:this.fontVariant,fontWeight:this.fontWeight,letterSpacing:this.letterSpacing,lineHeight:this.lineHeight,padding:this.padding,stroke:this._stroke,whiteSpace:this.whiteSpace,wordWrap:this.wordWrap,wordWrapWidth:this.wordWrapWidth,cssOverrides:this.cssOverrides})}get cssStyle(){return this._cssStyle||(this._cssStyle=Dd(this)),this._cssStyle}addOverride(...t){const e=t.filter(s=>!this.cssOverrides.includes(s));e.length>0&&(this.cssOverrides.push(...e),this.update())}removeOverride(...t){const e=t.filter(s=>this.cssOverrides.includes(s));e.length>0&&(this.cssOverrides=this.cssOverrides.filter(s=>!e.includes(s)),this.update())}set fill(t){super.fill=t}set stroke(t){super.stroke=t}}function Nd(r,t){const e=t.fontFamily,s=[],i={},n=/font-family:([^;"\s]+)/g,o=r.match(n);function a(u){i[u]||(s.push(u),i[u]=!0)}if(Array.isArray(e))for(let u=0;u{const l=u.split(":")[1].trim();a(l)});for(const u in t.tagStyles){const l=t.tagStyles[u].fontFamily;a(l)}return s}async function Hd(r){const t=await(await X.get().fetch(r)).blob(),e=new FileReader;return await new Promise((s,i)=>{e.onloadend=()=>s(e.result),e.onerror=i,e.readAsDataURL(t)})}async function Uo(r,t){const e=await Hd(t);return`@font-face { - font-family: "${r.fontFamily}"; - src: url('${e}'); - font-weight: ${r.fontWeight}; - font-style: ${r.fontStyle}; - }`}const Rr=new Map;async function Xd(r,t,e){const s=r.filter(i=>Y.has(`${i}-and-url`)).map((i,n)=>{if(!Rr.has(i)){const{url:o}=Y.get(`${i}-and-url`);n===0?Rr.set(i,Uo(t,o)):Rr.set(i,Uo({fontWeight:e.fontWeight,fontStyle:e.fontStyle,fontFamily:i},o))}return Rr.get(i)});return(await Promise.all(s)).join(` -`)}function zd(r,t,e,s,i){const{domElement:n,styleElement:o,svgRoot:a}=i;n.innerHTML=`
${r}
`,n.setAttribute("style",`transform: scale(${e});transform-origin: top left; display: inline-block`),o.textContent=s;const{width:u,height:l}=i.image;return a.setAttribute("width",u.toString()),a.setAttribute("height",l.toString()),new XMLSerializer().serializeToString(a)}function jd(r,t){const e=jt.getOptimalCanvasAndContext(r.width,r.height,t),{context:s}=e;return s.clearRect(0,0,r.width,r.height),s.drawImage(r,0,0),jt.returnCanvasAndContext(e),e.canvas}function Vd(r,t,e){return new Promise(async s=>{e&&await new Promise(i=>setTimeout(i,100)),r.onload=()=>{s()},r.src=`data:image/svg+xml;charset=utf8,${encodeURIComponent(t)}`,r.crossOrigin="anonymous"})}let Wd;function ko(r,t,e,s){s=s||Wd||(Wd=new Do);const{domElement:i,styleElement:n,svgRoot:o}=s;i.innerHTML=`
${r}
`,i.setAttribute("style","transform-origin: top left; display: inline-block"),e&&(n.textContent=e),document.body.appendChild(o);const a=i.getBoundingClientRect();o.remove();const u=It.measureFont(t.fontStyle).descent;return{width:a.width,height:a.height+u}}class Xs{constructor(t){this._activeTextures={},this._renderer=t,this._createCanvas=t.type===xt.WEBGPU}getTexture(t){return this._buildTexturePromise(t.text,t.resolution,t.style)}getManagedTexture(t,e,s,i){if(this._activeTextures[i])return this._increaseReferenceCount(i),this._activeTextures[i].promise;const n=this._buildTexturePromise(t,e,s).then(o=>(this._activeTextures[i].texture=o,o));return this._activeTextures[i]={texture:null,promise:n,usageCount:1},n}async _buildTexturePromise(t,e,s){const i=H.get(Do),n=Nd(t,s),o=await Xd(n,s,Pe.defaultTextStyle),a=ko(t,s,o,i),u=Math.ceil(Math.ceil(Math.max(1,a.width)+s.padding*2)*e),l=Math.ceil(Math.ceil(Math.max(1,a.height)+s.padding*2)*e),h=i.image;h.width=u|0,h.height=l|0;const c=zd(t,s,e,o,i);await Vd(h,c,Fd()&&n.length>0);let d=h;this._createCanvas&&(d=jd(h,e));const p=Zn(d,h.width,h.height,e);return this._createCanvas&&this._renderer.texture.initSource(p.source),H.return(i),p}_increaseReferenceCount(t){this._activeTextures[t].usageCount++}decreaseReferenceCount(t){const e=this._activeTextures[t];e&&(e.usageCount--,e.usageCount===0&&(e.texture?this._cleanUp(e):e.promise.then(s=>{e.texture=s,this._cleanUp(e)}).catch(()=>{}),this._activeTextures[t]=null))}_cleanUp(t){ut.returnTexture(t.texture),t.texture.source.resource=null,t.texture.source.uploadMethodId="unknown"}getReferenceCount(t){return this._activeTextures[t].usageCount}destroy(){this._activeTextures=null}}Xs.extension={type:[v.WebGLSystem,v.WebGPUSystem,v.CanvasSystem],name:"htmlText"},Xs.defaultFontOptions={fontFamily:"Arial",fontStyle:"normal",fontWeight:"normal"},D.add(Xs),D.add(Io);var Ty=Object.defineProperty,Yd=Object.getOwnPropertySymbols,Sy=Object.prototype.hasOwnProperty,Ey=Object.prototype.propertyIsEnumerable,Kd=(r,t,e)=>t in r?Ty(r,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):r[t]=e,qd=(r,t)=>{for(var e in t||(t={}))Sy.call(t,e)&&Kd(r,e,t[e]);if(Yd)for(var e of Yd(t))Ey.call(t,e)&&Kd(r,e,t[e]);return r};const Zd=class wx extends Oe{constructor(...t){var e;let s=(e=t[0])!=null?e:{};s instanceof Float32Array&&(s={positions:s,uvs:t[1],indices:t[2]}),s=qd(qd({},wx.defaultOptions),s);const i=s.positions||new Float32Array([0,0,1,0,1,1,0,1]),n=s.uvs||new Float32Array([0,0,1,0,1,1,0,1]),o=s.indices||new Uint32Array([0,1,2,0,2,3]),a=s.shrinkBuffersToFit,u=new _t({data:i,label:"attribute-mesh-positions",shrinkToFit:a,usage:$.VERTEX|$.COPY_DST}),l=new _t({data:n,label:"attribute-mesh-uvs",shrinkToFit:a,usage:$.VERTEX|$.COPY_DST}),h=new _t({data:o,label:"index-mesh-buffer",shrinkToFit:a,usage:$.INDEX|$.COPY_DST});super({attributes:{aPosition:{buffer:u,format:"float32x2",stride:2*4,offset:0},aUV:{buffer:l,format:"float32x2",stride:2*4,offset:0}},indexBuffer:h,topology:s.topology}),this.batchMode="auto"}get positions(){return this.attributes.aPosition.buffer.data}set positions(t){this.attributes.aPosition.buffer.data=t}get uvs(){return this.attributes.aUV.buffer.data}set uvs(t){this.attributes.aUV.buffer.data=t}get indices(){return this.indexBuffer.data}set indices(t){this.indexBuffer.data=t}};Zd.defaultOptions={topology:"triangle-list",shrinkBuffersToFit:!1};let Jt=Zd;var Ay=Object.defineProperty,Py=Object.defineProperties,wy=Object.getOwnPropertyDescriptors,Qd=Object.getOwnPropertySymbols,Ry=Object.prototype.hasOwnProperty,My=Object.prototype.propertyIsEnumerable,Jd=(r,t,e)=>t in r?Ay(r,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):r[t]=e,tp=(r,t)=>{for(var e in t||(t={}))Ry.call(t,e)&&Jd(r,e,t[e]);if(Qd)for(var e of Qd(t))My.call(t,e)&&Jd(r,e,t[e]);return r},ep=(r,t)=>Py(r,wy(t));const Ne={name:"local-uniform-bit",vertex:{header:` + ` + ) + } +}; + +"use strict"; +class SdfShader extends Shader { + constructor() { + const uniforms = new UniformGroup({ + uColor: { value: new Float32Array([1, 1, 1, 1]), type: "vec4" }, + uTransformMatrix: { value: new Matrix(), type: "mat3x3" }, + uDistance: { value: 4, type: "f32" }, + uRound: { value: 0, type: "f32" } + }); + const gpuProgram = compileHighShaderGpuProgram({ + name: "sdf-shader", + bits: [ + colorBit, + generateTextureBatchBit(MAX_TEXTURES), + localUniformMSDFBit, + mSDFBit, + roundPixelsBit + ] + }); + const glProgram = compileHighShaderGlProgram({ + name: "sdf-shader", + bits: [ + colorBitGl, + generateTextureBatchBitGl(MAX_TEXTURES), + localUniformMSDFBitGl, + mSDFBitGl, + roundPixelsBitGl + ] + }); + super({ + glProgram, + gpuProgram, + resources: { + localUniforms: uniforms, + batchSamplers: batchSamplersUniformGroup + } + }); + } +} + +"use strict"; +class BitmapTextPipe { + constructor(renderer) { + this._gpuBitmapText = {}; + this._renderer = renderer; + } + validateRenderable(bitmapText) { + const graphicsRenderable = this._getGpuBitmapText(bitmapText); + if (bitmapText._didTextUpdate) { + bitmapText._didTextUpdate = false; + this._updateContext(bitmapText, graphicsRenderable); + } + return this._renderer.renderPipes.graphics.validateRenderable(graphicsRenderable); + } + addRenderable(bitmapText, instructionSet) { + const graphicsRenderable = this._getGpuBitmapText(bitmapText); + syncWithProxy(bitmapText, graphicsRenderable); + if (bitmapText._didTextUpdate) { + bitmapText._didTextUpdate = false; + this._updateContext(bitmapText, graphicsRenderable); + } + this._renderer.renderPipes.graphics.addRenderable(graphicsRenderable, instructionSet); + if (graphicsRenderable.context.customShader) { + this._updateDistanceField(bitmapText); + } + } + destroyRenderable(bitmapText) { + this._destroyRenderableByUid(bitmapText.uid); + } + _destroyRenderableByUid(renderableUid) { + BigPool.return(this._gpuBitmapText[renderableUid]); + this._gpuBitmapText[renderableUid] = null; + } + updateRenderable(bitmapText) { + const graphicsRenderable = this._getGpuBitmapText(bitmapText); + syncWithProxy(bitmapText, graphicsRenderable); + this._renderer.renderPipes.graphics.updateRenderable(graphicsRenderable); + if (graphicsRenderable.context.customShader) { + this._updateDistanceField(bitmapText); + } + } + _updateContext(bitmapText, proxyGraphics) { + var _a; + const { context } = proxyGraphics; + const bitmapFont = BitmapFontManager.getFont(bitmapText.text, bitmapText._style); + context.clear(); + if (bitmapFont.distanceField.type !== "none") { + if (!context.customShader) { + if (!this._sdfShader) { + this._sdfShader = new SdfShader(); + } + context.customShader = this._sdfShader; + } + } + const chars = Array.from(bitmapText.text); + const style = bitmapText._style; + let currentY = (((_a = style._stroke) == null ? void 0 : _a.width) || 0) / 2; + currentY += bitmapFont.baseLineOffset; + const bitmapTextLayout = getBitmapTextLayout(chars, style, bitmapFont); + let index = 0; + const padding = style.padding; + const scale = bitmapTextLayout.scale; + context.translate( + -bitmapText._anchor._x * bitmapTextLayout.width - padding, + -bitmapText._anchor._y * (bitmapTextLayout.height + bitmapTextLayout.offsetY) - padding + ).scale(scale, scale); + const tint = style._fill.color; + for (let i = 0; i < bitmapTextLayout.lines.length; i++) { + const line = bitmapTextLayout.lines[i]; + for (let j = 0; j < line.charPositions.length; j++) { + const char = chars[index++]; + const charData = bitmapFont.chars[char]; + if (charData == null ? void 0 : charData.texture) { + context.texture( + charData.texture, + tint ? tint : "black", + Math.round(line.charPositions[j] + charData.xOffset), + Math.round(currentY + charData.yOffset) + ); + } + } + currentY += bitmapFont.lineHeight; + } + } + _getGpuBitmapText(bitmapText) { + return this._gpuBitmapText[bitmapText.uid] || this.initGpuText(bitmapText); + } + initGpuText(bitmapText) { + const proxyRenderable = BigPool.get(Graphics); + this._gpuBitmapText[bitmapText.uid] = proxyRenderable; + this._updateContext(bitmapText, proxyRenderable); + bitmapText.on("destroyed", () => { + this.destroyRenderable(bitmapText); + }); + return this._gpuBitmapText[bitmapText.uid]; + } + _updateDistanceField(bitmapText) { + var _a; + const context = this._getGpuBitmapText(bitmapText).context; + const fontFamily = bitmapText._style.fontFamily; + const dynamicFont = Cache.get(`${fontFamily}-bitmap`); + const { a, b, c, d } = bitmapText.groupTransform; + const dx = Math.sqrt(a * a + b * b); + const dy = Math.sqrt(c * c + d * d); + const worldScale = (Math.abs(dx) + Math.abs(dy)) / 2; + const fontScale = dynamicFont.baseRenderedFontSize / bitmapText._style.fontSize; + const resolution = (_a = bitmapText.resolution) != null ? _a : this._renderer.resolution; + const distance = worldScale * dynamicFont.distanceField.range * (1 / fontScale) * resolution; + context.customShader.resources.localUniforms.uniforms.uDistance = distance; + } + destroy() { + var _a; + for (const uid in this._gpuBitmapText) { + this._destroyRenderableByUid(uid); + } + this._gpuBitmapText = null; + (_a = this._sdfShader) == null ? void 0 : _a.destroy(true); + this._sdfShader = null; + this._renderer = null; + } +} +/** @ignore */ +BitmapTextPipe.extension = { + type: [ + ExtensionType.WebGLPipes, + ExtensionType.WebGPUPipes, + ExtensionType.CanvasPipes + ], + name: "bitmapText" +}; +function syncWithProxy(container, proxy) { + proxy.groupTransform = container.groupTransform; + proxy.groupColorAlpha = container.groupColorAlpha; + proxy.groupColor = container.groupColor; + proxy.groupBlendMode = container.groupBlendMode; + proxy.globalDisplayStatus = container.globalDisplayStatus; + proxy.groupTransform = container.groupTransform; + proxy.localDisplayStatus = container.localDisplayStatus; + proxy.groupAlpha = container.groupAlpha; + proxy._roundPixels = container._roundPixels; +} + +"use strict"; +extensions.add(BitmapTextPipe, loadBitmapFont, bitmapFontCachePlugin); + +"use strict"; +class HTMLTextPipe { + constructor(renderer) { + this._gpuText = /* @__PURE__ */ Object.create(null); + this._renderer = renderer; + } + validateRenderable(htmlText) { + const gpuText = this._getGpuText(htmlText); + const newKey = htmlText._getKey(); + if (gpuText.textureNeedsUploading) { + gpuText.textureNeedsUploading = false; + return true; + } + if (gpuText.currentKey !== newKey) { + return true; + } + return false; + } + addRenderable(htmlText) { + const gpuText = this._getGpuText(htmlText); + const batchableSprite = gpuText.batchableSprite; + if (htmlText._didTextUpdate) { + this._updateText(htmlText); + } + this._renderer.renderPipes.batch.addToBatch(batchableSprite); + } + updateRenderable(htmlText) { + const gpuText = this._getGpuText(htmlText); + const batchableSprite = gpuText.batchableSprite; + if (htmlText._didTextUpdate) { + this._updateText(htmlText); + } + batchableSprite.batcher.updateElement(batchableSprite); + } + destroyRenderable(htmlText) { + this._destroyRenderableById(htmlText.uid); + } + _destroyRenderableById(htmlTextUid) { + const gpuText = this._gpuText[htmlTextUid]; + this._renderer.htmlText.decreaseReferenceCount(gpuText.currentKey); + BigPool.return(gpuText.batchableSprite); + this._gpuText[htmlTextUid] = null; + } + _updateText(htmlText) { + const newKey = htmlText._getKey(); + const gpuText = this._getGpuText(htmlText); + const batchableSprite = gpuText.batchableSprite; + if (gpuText.currentKey !== newKey) { + this._updateGpuText(htmlText).catch((e) => { + console.error(e); + }); + } + htmlText._didTextUpdate = false; + const padding = htmlText._style.padding; + updateQuadBounds(batchableSprite.bounds, htmlText._anchor, batchableSprite.texture, padding); + } + async _updateGpuText(htmlText) { + var _a; + htmlText._didTextUpdate = false; + const gpuText = this._getGpuText(htmlText); + if (gpuText.generatingTexture) + return; + const newKey = htmlText._getKey(); + this._renderer.htmlText.decreaseReferenceCount(gpuText.currentKey); + gpuText.generatingTexture = true; + gpuText.currentKey = newKey; + const resolution = (_a = htmlText.resolution) != null ? _a : this._renderer.resolution; + const texture = await this._renderer.htmlText.getManagedTexture( + htmlText.text, + resolution, + htmlText._style, + htmlText._getKey() + ); + const batchableSprite = gpuText.batchableSprite; + batchableSprite.texture = gpuText.texture = texture; + gpuText.generatingTexture = false; + gpuText.textureNeedsUploading = true; + htmlText.onViewUpdate(); + const padding = htmlText._style.padding; + updateQuadBounds(batchableSprite.bounds, htmlText._anchor, batchableSprite.texture, padding); + } + _getGpuText(htmlText) { + return this._gpuText[htmlText.uid] || this.initGpuText(htmlText); + } + initGpuText(htmlText) { + const gpuTextData = { + texture: Texture.EMPTY, + currentKey: "--", + batchableSprite: BigPool.get(BatchableSprite), + textureNeedsUploading: false, + generatingTexture: false + }; + const batchableSprite = gpuTextData.batchableSprite; + batchableSprite.renderable = htmlText; + batchableSprite.texture = Texture.EMPTY; + batchableSprite.bounds = { minX: 0, maxX: 1, minY: 0, maxY: 0 }; + batchableSprite.roundPixels = this._renderer._roundPixels | htmlText._roundPixels; + this._gpuText[htmlText.uid] = gpuTextData; + htmlText.on("destroyed", () => { + this.destroyRenderable(htmlText); + }); + return gpuTextData; + } + destroy() { + for (const i in this._gpuText) { + this._destroyRenderableById(i); + } + this._gpuText = null; + this._renderer = null; + } +} +/** @ignore */ +HTMLTextPipe.extension = { + type: [ + ExtensionType.WebGLPipes, + ExtensionType.WebGPUPipes, + ExtensionType.CanvasPipes + ], + name: "htmlText" +}; + +"use strict"; +function isSafari() { + const { userAgent } = DOMAdapter.get().getNavigator(); + return /^((?!chrome|android).)*safari/i.test(userAgent); +} + +"use strict"; +const nssvg = "http://www.w3.org/2000/svg"; +const nsxhtml = "http://www.w3.org/1999/xhtml"; +class HTMLTextRenderData { + constructor() { + this.svgRoot = document.createElementNS(nssvg, "svg"); + this.foreignObject = document.createElementNS(nssvg, "foreignObject"); + this.domElement = document.createElementNS(nsxhtml, "div"); + this.styleElement = document.createElementNS(nsxhtml, "style"); + this.image = new Image(); + const { foreignObject, svgRoot, styleElement, domElement } = this; + foreignObject.setAttribute("width", "10000"); + foreignObject.setAttribute("height", "10000"); + foreignObject.style.overflow = "hidden"; + svgRoot.appendChild(foreignObject); + foreignObject.appendChild(styleElement); + foreignObject.appendChild(domElement); + } +} + +"use strict"; +function textStyleToCSS(style) { + const stroke = style._stroke; + const fill = style._fill; + const cssStyleString = [ + `color: ${Color.shared.setValue(fill.color).toHex()}`, + `font-size: ${style.fontSize}px`, + `font-family: ${style.fontFamily}`, + `font-weight: ${style.fontWeight}`, + `font-style: ${style.fontStyle}`, + `font-variant: ${style.fontVariant}`, + `letter-spacing: ${style.letterSpacing}px`, + `text-align: ${style.align}`, + `padding: ${style.padding}px`, + `white-space: ${style.whiteSpace === "pre" && style.wordWrap ? "pre-wrap" : style.whiteSpace}`, + ...style.lineHeight ? [`line-height: ${style.lineHeight}px`] : [], + ...style.wordWrap ? [ + `word-wrap: ${style.breakWords ? "break-all" : "break-word"}`, + `max-width: ${style.wordWrapWidth}px` + ] : [], + ...stroke ? [strokeToCSS(stroke)] : [], + ...style.dropShadow ? [dropShadowToCSS(style.dropShadow)] : [], + ...style.cssOverrides + ].join(";"); + const cssStyles = [`div { ${cssStyleString} }`]; + tagStyleToCSS(style.tagStyles, cssStyles); + return cssStyles.join(" "); +} +function dropShadowToCSS(dropShadowStyle) { + const color = Color.shared.setValue(dropShadowStyle.color).setAlpha(dropShadowStyle.alpha).toHexa(); + const x = Math.round(Math.cos(dropShadowStyle.angle) * dropShadowStyle.distance); + const y = Math.round(Math.sin(dropShadowStyle.angle) * dropShadowStyle.distance); + const position = `${x}px ${y}px`; + if (dropShadowStyle.blur > 0) { + return `text-shadow: ${position} ${dropShadowStyle.blur}px ${color}`; + } + return `text-shadow: ${position} ${color}`; +} +function strokeToCSS(stroke) { + return [ + `-webkit-text-stroke-width: ${stroke.width}px`, + `-webkit-text-stroke-color: ${Color.shared.setValue(stroke.color).toHex()}`, + `text-stroke-width: ${stroke.width}px`, + `text-stroke-color: ${Color.shared.setValue(stroke.color).toHex()}`, + "paint-order: stroke" + ].join(";"); +} +const templates = { + fontSize: `font-size: {{VALUE}}px`, + fontFamily: `font-family: {{VALUE}}`, + fontWeight: `font-weight: {{VALUE}}`, + fontStyle: `font-style: {{VALUE}}`, + fontVariant: `font-variant: {{VALUE}}`, + letterSpacing: `letter-spacing: {{VALUE}}px`, + align: `text-align: {{VALUE}}`, + padding: `padding: {{VALUE}}px`, + whiteSpace: `white-space: {{VALUE}}`, + lineHeight: `line-height: {{VALUE}}px`, + wordWrapWidth: `max-width: {{VALUE}}px` +}; +const transform = { + fill: (value) => `color: ${Color.shared.setValue(value).toHex()}`, + breakWords: (value) => `word-wrap: ${value ? "break-all" : "break-word"}`, + stroke: strokeToCSS, + dropShadow: dropShadowToCSS +}; +function tagStyleToCSS(tagStyles, out) { + for (const i in tagStyles) { + const tagStyle = tagStyles[i]; + const cssTagStyle = []; + for (const j in tagStyle) { + if (transform[j]) { + cssTagStyle.push(transform[j](tagStyle[j])); + } else if (templates[j]) { + cssTagStyle.push(templates[j].replace("{{VALUE}}", tagStyle[j])); + } + } + out.push(`${i} { ${cssTagStyle.join(";")} }`); + } +} + +"use strict"; +class HTMLTextStyle extends TextStyle { + constructor(options = {}) { + var _a, _b; + super(options); + this._cssOverrides = []; + (_a = this.cssOverrides) != null ? _a : this.cssOverrides = options.cssOverrides; + this.tagStyles = (_b = options.tagStyles) != null ? _b : {}; + } + /** List of style overrides that will be applied to the HTML text. */ + set cssOverrides(value) { + this._cssOverrides = value instanceof Array ? value : [value]; + this.update(); + } + get cssOverrides() { + return this._cssOverrides; + } + _generateKey() { + this._styleKey = generateTextStyleKey(this) + this._cssOverrides.join("-"); + return this._styleKey; + } + update() { + this._cssStyle = null; + super.update(); + } + /** + * Creates a new HTMLTextStyle object with the same values as this one. + * @returns New cloned HTMLTextStyle object + */ + clone() { + return new HTMLTextStyle({ + align: this.align, + breakWords: this.breakWords, + dropShadow: this.dropShadow, + fill: this._fill, + fontFamily: this.fontFamily, + fontSize: this.fontSize, + fontStyle: this.fontStyle, + fontVariant: this.fontVariant, + fontWeight: this.fontWeight, + letterSpacing: this.letterSpacing, + lineHeight: this.lineHeight, + padding: this.padding, + stroke: this._stroke, + whiteSpace: this.whiteSpace, + wordWrap: this.wordWrap, + wordWrapWidth: this.wordWrapWidth, + cssOverrides: this.cssOverrides + }); + } + get cssStyle() { + if (!this._cssStyle) { + this._cssStyle = textStyleToCSS(this); + } + return this._cssStyle; + } + /** + * Add a style override, this can be any CSS property + * it will override any built-in style. This is the + * property and the value as a string (e.g., `color: red`). + * This will override any other internal style. + * @param {string} value - CSS style(s) to add. + * @example + * style.addOverride('background-color: red'); + */ + addOverride(...value) { + const toAdd = value.filter((v) => !this.cssOverrides.includes(v)); + if (toAdd.length > 0) { + this.cssOverrides.push(...toAdd); + this.update(); + } + } + /** + * Remove any overrides that match the value. + * @param {string} value - CSS style to remove. + * @example + * style.removeOverride('background-color: red'); + */ + removeOverride(...value) { + const toRemove = value.filter((v) => this.cssOverrides.includes(v)); + if (toRemove.length > 0) { + this.cssOverrides = this.cssOverrides.filter((v) => !toRemove.includes(v)); + this.update(); + } + } + set fill(value) { + if (typeof value !== "string" && typeof value !== "number") { + warn("[HTMLTextStyle] only color fill is not supported by HTMLText"); + } + super.fill = value; + } + set stroke(value) { + if (value && typeof value !== "string" && typeof value !== "number") { + warn("[HTMLTextStyle] only color stroke is not supported by HTMLText"); + } + super.stroke = value; + } +} + +"use strict"; +function extractFontFamilies(text, style) { + const fontFamily = style.fontFamily; + const fontFamilies = []; + const dedupe = {}; + const regex = /font-family:([^;"\s]+)/g; + const matches = text.match(regex); + function addFontFamily(fontFamily2) { + if (!dedupe[fontFamily2]) { + fontFamilies.push(fontFamily2); + dedupe[fontFamily2] = true; + } + } + if (Array.isArray(fontFamily)) { + for (let i = 0; i < fontFamily.length; i++) { + addFontFamily(fontFamily[i]); + } + } else { + addFontFamily(fontFamily); + } + if (matches) { + matches.forEach((match) => { + const fontFamily2 = match.split(":")[1].trim(); + addFontFamily(fontFamily2); + }); + } + for (const i in style.tagStyles) { + const fontFamily2 = style.tagStyles[i].fontFamily; + addFontFamily(fontFamily2); + } + return fontFamilies; +} + +"use strict"; +async function loadFontAsBase64(url) { + const response = await DOMAdapter.get().fetch(url); + const blob = await response.blob(); + const reader = new FileReader(); + const dataSrc = await new Promise((resolve, reject) => { + reader.onloadend = () => resolve(reader.result); + reader.onerror = reject; + reader.readAsDataURL(blob); + }); + return dataSrc; +} + +"use strict"; +async function loadFontCSS(style, url) { + const dataSrc = await loadFontAsBase64(url); + return `@font-face { + font-family: "${style.fontFamily}"; + src: url('${dataSrc}'); + font-weight: ${style.fontWeight}; + font-style: ${style.fontStyle}; + }`; +} + +"use strict"; +const FontStylePromiseCache = /* @__PURE__ */ new Map(); +async function getFontCss(fontFamilies, style, defaultOptions) { + const fontPromises = fontFamilies.filter((fontFamily) => Cache.has(`${fontFamily}-and-url`)).map((fontFamily, i) => { + if (!FontStylePromiseCache.has(fontFamily)) { + const { url } = Cache.get(`${fontFamily}-and-url`); + if (i === 0) { + FontStylePromiseCache.set(fontFamily, loadFontCSS(style, url)); + } else { + FontStylePromiseCache.set(fontFamily, loadFontCSS({ + fontWeight: defaultOptions.fontWeight, + fontStyle: defaultOptions.fontStyle, + fontFamily + }, url)); + } + } + return FontStylePromiseCache.get(fontFamily); + }); + return (await Promise.all(fontPromises)).join("\n"); +} + +"use strict"; +function getSVGUrl(text, style, resolution, fontCSS, htmlTextData) { + const { domElement, styleElement, svgRoot } = htmlTextData; + domElement.innerHTML = `
${text}
`; + domElement.setAttribute("style", `transform: scale(${resolution});transform-origin: top left; display: inline-block`); + styleElement.textContent = fontCSS; + const { width, height } = htmlTextData.image; + svgRoot.setAttribute("width", width.toString()); + svgRoot.setAttribute("height", height.toString()); + return new XMLSerializer().serializeToString(svgRoot); +} + +"use strict"; +function getTemporaryCanvasFromImage(image, resolution) { + const canvasAndContext = CanvasPool.getOptimalCanvasAndContext( + image.width, + image.height, + resolution + ); + const { context } = canvasAndContext; + context.clearRect(0, 0, image.width, image.height); + context.drawImage(image, 0, 0); + CanvasPool.returnCanvasAndContext(canvasAndContext); + return canvasAndContext.canvas; +} + +"use strict"; +function loadSVGImage(image, url, delay) { + return new Promise(async (resolve) => { + if (delay) { + await new Promise((resolve2) => setTimeout(resolve2, 100)); + } + image.onload = () => { + resolve(); + }; + image.src = `data:image/svg+xml;charset=utf8,${encodeURIComponent(url)}`; + image.crossOrigin = "anonymous"; + }); +} + +"use strict"; +let tempHTMLTextRenderData; +function measureHtmlText(text, style, fontStyleCSS, htmlTextRenderData) { + htmlTextRenderData = htmlTextRenderData || tempHTMLTextRenderData || (tempHTMLTextRenderData = new HTMLTextRenderData()); + const { domElement, styleElement, svgRoot } = htmlTextRenderData; + domElement.innerHTML = `
${text}
`; + domElement.setAttribute("style", "transform-origin: top left; display: inline-block"); + if (fontStyleCSS) { + styleElement.textContent = fontStyleCSS; + } + document.body.appendChild(svgRoot); + const contentBounds = domElement.getBoundingClientRect(); + svgRoot.remove(); + const descenderPadding = CanvasTextMetrics.measureFont(style.fontStyle).descent; + return { + width: contentBounds.width, + height: contentBounds.height + descenderPadding + }; +} + +"use strict"; +class HTMLTextSystem { + constructor(renderer) { + this._activeTextures = {}; + this._renderer = renderer; + this._createCanvas = renderer.type === RendererType.WEBGPU; + } + getTexture(options) { + return this._buildTexturePromise( + options.text, + options.resolution, + options.style + ); + } + getManagedTexture(text, resolution, style, textKey) { + if (this._activeTextures[textKey]) { + this._increaseReferenceCount(textKey); + return this._activeTextures[textKey].promise; + } + const promise = this._buildTexturePromise(text, resolution, style).then((texture) => { + this._activeTextures[textKey].texture = texture; + return texture; + }); + this._activeTextures[textKey] = { + texture: null, + promise, + usageCount: 1 + }; + return promise; + } + async _buildTexturePromise(text, resolution, style) { + const htmlTextData = BigPool.get(HTMLTextRenderData); + const fontFamilies = extractFontFamilies(text, style); + const fontCSS = await getFontCss( + fontFamilies, + style, + HTMLTextStyle.defaultTextStyle + ); + const measured = measureHtmlText(text, style, fontCSS, htmlTextData); + const width = Math.ceil(Math.ceil(Math.max(1, measured.width) + style.padding * 2) * resolution); + const height = Math.ceil(Math.ceil(Math.max(1, measured.height) + style.padding * 2) * resolution); + const image = htmlTextData.image; + image.width = width | 0; + image.height = height | 0; + const svgURL = getSVGUrl(text, style, resolution, fontCSS, htmlTextData); + await loadSVGImage(image, svgURL, isSafari() && fontFamilies.length > 0); + let resource = image; + if (this._createCanvas) { + resource = getTemporaryCanvasFromImage(image, resolution); + } + const texture = getPo2TextureFromSource(resource, image.width, image.height, resolution); + if (this._createCanvas) { + this._renderer.texture.initSource(texture.source); + } + BigPool.return(htmlTextData); + return texture; + } + _increaseReferenceCount(textKey) { + this._activeTextures[textKey].usageCount++; + } + decreaseReferenceCount(textKey) { + const activeTexture = this._activeTextures[textKey]; + if (!activeTexture) + return; + activeTexture.usageCount--; + if (activeTexture.usageCount === 0) { + if (activeTexture.texture) { + this._cleanUp(activeTexture); + } else { + activeTexture.promise.then((texture) => { + activeTexture.texture = texture; + this._cleanUp(activeTexture); + }).catch(() => { + warn("HTMLTextSystem: Failed to clean texture"); + }); + } + this._activeTextures[textKey] = null; + } + } + _cleanUp(activeTexture) { + TexturePool.returnTexture(activeTexture.texture); + activeTexture.texture.source.resource = null; + activeTexture.texture.source.uploadMethodId = "unknown"; + } + getReferenceCount(textKey) { + return this._activeTextures[textKey].usageCount; + } + destroy() { + this._activeTextures = null; + } +} +/** @ignore */ +HTMLTextSystem.extension = { + type: [ + ExtensionType.WebGLSystem, + ExtensionType.WebGPUSystem, + ExtensionType.CanvasSystem + ], + name: "htmlText" +}; +HTMLTextSystem.defaultFontOptions = { + fontFamily: "Arial", + fontStyle: "normal", + fontWeight: "normal" +}; + +"use strict"; +extensions.add(HTMLTextSystem); +extensions.add(HTMLTextPipe); + +"use strict"; +var __defProp$H = Object.defineProperty; +var __getOwnPropSymbols$H = Object.getOwnPropertySymbols; +var __hasOwnProp$H = Object.prototype.hasOwnProperty; +var __propIsEnum$H = Object.prototype.propertyIsEnumerable; +var __defNormalProp$H = (obj, key, value) => key in obj ? __defProp$H(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; +var __spreadValues$H = (a, b) => { + for (var prop in b || (b = {})) + if (__hasOwnProp$H.call(b, prop)) + __defNormalProp$H(a, prop, b[prop]); + if (__getOwnPropSymbols$H) + for (var prop of __getOwnPropSymbols$H(b)) { + if (__propIsEnum$H.call(b, prop)) + __defNormalProp$H(a, prop, b[prop]); + } + return a; +}; +const _MeshGeometry = class _MeshGeometry extends Geometry { + constructor(...args) { + var _a; + let options = (_a = args[0]) != null ? _a : {}; + if (options instanceof Float32Array) { + deprecation(v8_0_0, "use new MeshGeometry({ positions, uvs, indices }) instead"); + options = { + positions: options, + uvs: args[1], + indices: args[2] + }; + } + options = __spreadValues$H(__spreadValues$H({}, _MeshGeometry.defaultOptions), options); + const positions = options.positions || new Float32Array([0, 0, 1, 0, 1, 1, 0, 1]); + const uvs = options.uvs || new Float32Array([0, 0, 1, 0, 1, 1, 0, 1]); + const indices = options.indices || new Uint32Array([0, 1, 2, 0, 2, 3]); + const shrinkToFit = options.shrinkBuffersToFit; + const positionBuffer = new Buffer({ + data: positions, + label: "attribute-mesh-positions", + shrinkToFit, + usage: BufferUsage.VERTEX | BufferUsage.COPY_DST + }); + const uvBuffer = new Buffer({ + data: uvs, + label: "attribute-mesh-uvs", + shrinkToFit, + usage: BufferUsage.VERTEX | BufferUsage.COPY_DST + }); + const indexBuffer = new Buffer({ + data: indices, + label: "index-mesh-buffer", + shrinkToFit, + usage: BufferUsage.INDEX | BufferUsage.COPY_DST + }); + super({ + attributes: { + aPosition: { + buffer: positionBuffer, + format: "float32x2", + stride: 2 * 4, + offset: 0 + }, + aUV: { + buffer: uvBuffer, + format: "float32x2", + stride: 2 * 4, + offset: 0 + } + }, + indexBuffer, + topology: options.topology + }); + this.batchMode = "auto"; + } + /** The positions of the mesh. */ + get positions() { + return this.attributes.aPosition.buffer.data; + } + set positions(value) { + this.attributes.aPosition.buffer.data = value; + } + /** The UVs of the mesh. */ + get uvs() { + return this.attributes.aUV.buffer.data; + } + set uvs(value) { + this.attributes.aUV.buffer.data = value; + } + /** The indices of the mesh. */ + get indices() { + return this.indexBuffer.data; + } + set indices(value) { + this.indexBuffer.data = value; + } +}; +_MeshGeometry.defaultOptions = { + topology: "triangle-list", + shrinkBuffersToFit: false +}; +let MeshGeometry = _MeshGeometry; + +"use strict"; +var __defProp$G = Object.defineProperty; +var __defProps$i = Object.defineProperties; +var __getOwnPropDescs$i = Object.getOwnPropertyDescriptors; +var __getOwnPropSymbols$G = Object.getOwnPropertySymbols; +var __hasOwnProp$G = Object.prototype.hasOwnProperty; +var __propIsEnum$G = Object.prototype.propertyIsEnumerable; +var __defNormalProp$G = (obj, key, value) => key in obj ? __defProp$G(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; +var __spreadValues$G = (a, b) => { + for (var prop in b || (b = {})) + if (__hasOwnProp$G.call(b, prop)) + __defNormalProp$G(a, prop, b[prop]); + if (__getOwnPropSymbols$G) + for (var prop of __getOwnPropSymbols$G(b)) { + if (__propIsEnum$G.call(b, prop)) + __defNormalProp$G(a, prop, b[prop]); + } + return a; +}; +var __spreadProps$i = (a, b) => __defProps$i(a, __getOwnPropDescs$i(b)); +const localUniformBit = { + name: "local-uniform-bit", + vertex: { + header: ( + /* wgsl */ + ` struct LocalUniforms { uTransformMatrix:mat3x3, @@ -342,28 +23631,70 @@ ${i.join(` } @group(1) @binding(0) var localUniforms : LocalUniforms; - `,main:` + ` + ), + main: ( + /* wgsl */ + ` vColor *= localUniforms.uColor; modelMatrix *= localUniforms.uTransformMatrix; - `,end:` + ` + ), + end: ( + /* wgsl */ + ` if(localUniforms.uRound == 1) { vPosition = vec4(roundPixels(vPosition.xy, globalUniforms.uResolution), vPosition.zw); } - `}},rp=ep(tp({},Ne),{vertex:ep(tp({},Ne.vertex),{header:Ne.vertex.header.replace("group(1)","group(2)")})}),zs={name:"local-uniform-bit",vertex:{header:` + ` + ) + } +}; +const localUniformBitGroup2 = __spreadProps$i(__spreadValues$G({}, localUniformBit), { + vertex: __spreadProps$i(__spreadValues$G({}, localUniformBit.vertex), { + // replace the group! + header: localUniformBit.vertex.header.replace("group(1)", "group(2)") + }) +}); +const localUniformBitGl = { + name: "local-uniform-bit", + vertex: { + header: ( + /* glsl */ + ` uniform mat3 uTransformMatrix; uniform vec4 uColor; uniform float uRound; - `,main:` + ` + ), + main: ( + /* glsl */ + ` vColor *= uColor; modelMatrix = uTransformMatrix; - `,end:` + ` + ), + end: ( + /* glsl */ + ` if(uRound == 1.) { gl_Position.xy = roundPixels(gl_Position.xy, uResolution); } - `}},sp={name:"tiling-bit",vertex:{header:` + ` + ) + } +}; + +"use strict"; +const tilingBit = { + name: "tiling-bit", + vertex: { + header: ( + /* wgsl */ + ` struct TilingUniforms { uMapCoord:mat3x3, uClampFrame:vec4, @@ -375,11 +23706,21 @@ ${i.join(` @group(2) @binding(0) var tilingUniforms: TilingUniforms; @group(2) @binding(1) var uTexture: texture_2d; @group(2) @binding(2) var uSampler: sampler; - `,main:` + ` + ), + main: ( + /* wgsl */ + ` uv = (tilingUniforms.uTextureTransform * vec3(uv, 1.0)).xy; position = (position - tilingUniforms.uSizeAnchor.zw) * tilingUniforms.uSizeAnchor.xy; - `},fragment:{header:` + ` + ) + }, + fragment: { + header: ( + /* wgsl */ + ` struct TilingUniforms { uMapCoord:mat3x3, uClampFrame:vec4, @@ -391,7 +23732,11 @@ ${i.join(` @group(2) @binding(0) var tilingUniforms: TilingUniforms; @group(2) @binding(1) var uTexture: texture_2d; @group(2) @binding(2) var uSampler: sampler; - `,main:` + ` + ), + main: ( + /* wgsl */ + ` var coord = vUV + ceil(tilingUniforms.uClampOffset - vUV); coord = (tilingUniforms.uMapCoord * vec3(coord, 1.0)).xy; @@ -406,20 +23751,43 @@ ${i.join(` } outColor = textureSampleBias(uTexture, uSampler, coord, bias); - `}},ip={name:"tiling-bit",vertex:{header:` + ` + ) + } +}; +const tilingBitGl = { + name: "tiling-bit", + vertex: { + header: ( + /* glsl */ + ` uniform mat3 uTextureTransform; uniform vec4 uSizeAnchor; - `,main:` + ` + ), + main: ( + /* glsl */ + ` uv = (uTextureTransform * vec3(aUV, 1.0)).xy; position = (position - uSizeAnchor.zw) * uSizeAnchor.xy; - `},fragment:{header:` + ` + ) + }, + fragment: { + header: ( + /* glsl */ + ` uniform sampler2D uTexture; uniform mat3 uMapCoord; uniform vec4 uClampFrame; uniform vec2 uClampOffset; - `,main:` + ` + ), + main: ( + /* glsl */ + ` vec2 coord = vUV + ceil(uClampOffset - vUV); coord = (uMapCoord * vec3(coord, 1.0)).xy; @@ -428,131 +23796,5120 @@ ${i.join(` outColor = texture(uTexture, coord, unclamped == coord ? 0.0 : -32.0);// lod-bias very negative to force lod 0 - `}};let Lo,$o;class np extends St{constructor(){Lo!=null||(Lo=Ue({name:"tiling-sprite-shader",bits:[Ne,sp,Le]})),$o!=null||($o=ke({name:"tiling-sprite-shader",bits:[zs,ip,$e]}));const t=new it({uMapCoord:{value:new G,type:"mat3x3"},uClampFrame:{value:new Float32Array([0,0,1,1]),type:"vec4"},uClampOffset:{value:new Float32Array([0,0]),type:"vec2"},uTextureTransform:{value:new G,type:"mat3x3"},uSizeAnchor:{value:new Float32Array([100,100,.5,.5]),type:"vec4"}});super({glProgram:$o,gpuProgram:Lo,resources:{localUniforms:new it({uTransformMatrix:{value:new G,type:"mat3x3"},uColor:{value:new Float32Array([1,1,1,1]),type:"vec4"},uRound:{value:0,type:"f32"}}),tilingUniforms:t,uTexture:A.EMPTY.source,uSampler:A.EMPTY.source.style}})}updateUniforms(t,e,s,i,n,o){const a=this.resources.tilingUniforms,u=o.width,l=o.height,h=o.textureMatrix,c=a.uniforms.uTextureTransform;c.set(s.a*u/t,s.b*u/e,s.c*l/t,s.d*l/e,s.tx/t,s.ty/e),c.invert(),a.uniforms.uMapCoord=h.mapCoord,a.uniforms.uClampFrame=h.uClampFrame,a.uniforms.uClampOffset=h.uClampOffset,a.uniforms.uTextureTransform=c,a.uniforms.uSizeAnchor[0]=t,a.uniforms.uSizeAnchor[1]=e,a.uniforms.uSizeAnchor[2]=i,a.uniforms.uSizeAnchor[3]=n,o&&(this.resources.uTexture=o.source,this.resources.uSampler=o.source.style)}}class op extends Jt{constructor(){super({positions:new Float32Array([0,0,1,0,1,1,0,1]),uvs:new Float32Array([0,0,1,0,1,1,0,1]),indices:new Uint32Array([0,1,2,0,2,3])})}}function ap(r,t){const e=r.anchor.x,s=r.anchor.y;t[0]=-e*r.width,t[1]=-s*r.height,t[2]=(1-e)*r.width,t[3]=-s*r.height,t[4]=(1-e)*r.width,t[5]=(1-s)*r.height,t[6]=-e*r.width,t[7]=(1-s)*r.height}function up(r,t,e,s){let i=0;const n=r.length/(t||2),o=s.a,a=s.b,u=s.c,l=s.d,h=s.tx,c=s.ty;for(e*=t;i{this.destroyRenderable(t)}),this._tilingSpriteDataHash[t.uid]}_updateBatchableMesh(t){const e=this._getTilingSpriteData(t),{geometry:s}=e,i=t.texture.source.style;i.addressMode!=="repeat"&&(i.addressMode="repeat",i.update()),lp(t,s.uvs),ap(t,s.positions)}destroy(){for(const t in this._tilingSpriteDataHash)this.destroyRenderable(this._tilingSpriteDataHash[t].renderable);this._tilingSpriteDataHash=null,this._renderer=null}_updateCanBatch(t){const e=this._getTilingSpriteData(t),s=t.texture;let i=!0;return this._renderer.type===xt.WEBGL&&(i=this._renderer.context.supports.nonPowOf2wrapping),e.canBatch=s.textureMatrix.isSimple&&(i||s.source.isPowerOfTwo),e.canBatch}}No.extension={type:[v.WebGLPipes,v.WebGPUPipes,v.CanvasPipes],name:"tilingSprite"},D.add(No);var Oy=Object.defineProperty,hp=Object.getOwnPropertySymbols,Cy=Object.prototype.hasOwnProperty,Gy=Object.prototype.propertyIsEnumerable,cp=(r,t,e)=>t in r?Oy(r,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):r[t]=e,dp=(r,t)=>{for(var e in t||(t={}))Cy.call(t,e)&&cp(r,e,t[e]);if(hp)for(var e of hp(t))Gy.call(t,e)&&cp(r,e,t[e]);return r};const pp=class Rx extends Jt{constructor(...t){var e;super({});let s=(e=t[0])!=null?e:{};typeof s=="number"&&(s={width:s,height:t[1],verticesX:t[2],verticesY:t[3]}),this.build(s)}build(t){var e,s,i,n;t=dp(dp({},Rx.defaultOptions),t),this.verticesX=(e=this.verticesX)!=null?e:t.verticesX,this.verticesY=(s=this.verticesY)!=null?s:t.verticesY,this.width=(i=this.width)!=null?i:t.width,this.height=(n=this.height)!=null?n:t.height;const o=this.verticesX*this.verticesY,a=[],u=[],l=[],h=this.verticesX-1,c=this.verticesY-1,d=this.width/h,p=this.height/c;for(let g=0;gt in r?Iy(r,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):r[t]=e,gp=(r,t)=>{for(var e in t||(t={}))By.call(t,e)&&mp(r,e,t[e]);if(fp)for(var e of fp(t))Fy.call(t,e)&&mp(r,e,t[e]);return r};const _p=class Mx extends Ho{constructor(t={}){t=gp(gp({},Mx.defaultOptions),t),super({width:t.width,height:t.height,verticesX:4,verticesY:4}),this.update(t)}update(t){var e,s,i,n,o,a,u,l;this.width=(e=t.width)!=null?e:this.width,this.height=(s=t.height)!=null?s:this.height,this._originalWidth=(i=t.originalWidth)!=null?i:this._originalWidth,this._originalHeight=(n=t.originalHeight)!=null?n:this._originalHeight,this._leftWidth=(o=t.leftWidth)!=null?o:this._leftWidth,this._rightWidth=(a=t.rightWidth)!=null?a:this._rightWidth,this._topHeight=(u=t.topHeight)!=null?u:this._topHeight,this._bottomHeight=(l=t.bottomHeight)!=null?l:this._bottomHeight,this.updateUvs(),this.updatePositions()}updatePositions(){const t=this.positions,e=this._leftWidth+this._rightWidth,s=this.width>e?1:this.width/e,i=this._topHeight+this._bottomHeight,n=this.height>i?1:this.height/i,o=Math.min(s,n);t[9]=t[11]=t[13]=t[15]=this._topHeight*o,t[17]=t[19]=t[21]=t[23]=this.height-this._bottomHeight*o,t[25]=t[27]=t[29]=t[31]=this.height,t[2]=t[10]=t[18]=t[26]=this._leftWidth*o,t[4]=t[12]=t[20]=t[28]=this.width-this._rightWidth*o,t[6]=t[14]=t[22]=t[30]=this.width,this.getBuffer("aPosition").update()}updateUvs(){const t=this.uvs;t[0]=t[8]=t[16]=t[24]=0,t[1]=t[3]=t[5]=t[7]=0,t[6]=t[14]=t[22]=t[30]=1,t[25]=t[27]=t[29]=t[31]=1;const e=1/this._originalWidth,s=1/this._originalHeight;t[2]=t[10]=t[18]=t[26]=e*this._leftWidth,t[9]=t[11]=t[13]=t[15]=s*this._topHeight,t[4]=t[12]=t[20]=t[28]=1-e*this._rightWidth,t[17]=t[19]=t[21]=t[23]=1-s*this._bottomHeight,this.getBuffer("aUV").update()}};_p.defaultOptions={width:100,height:100,leftWidth:10,topHeight:10,rightWidth:10,bottomHeight:10,originalWidth:100,originalHeight:100};let te=_p;class Xo{constructor(t){this._gpuSpriteHash=Object.create(null),this._renderer=t}addRenderable(t,e){const s=this._getGpuSprite(t);t._didSpriteUpdate&&this._updateBatchableSprite(t,s),this._renderer.renderPipes.batch.addToBatch(s)}updateRenderable(t){const e=this._gpuSpriteHash[t.uid];t._didSpriteUpdate&&this._updateBatchableSprite(t,e),e.batcher.updateElement(e)}validateRenderable(t){const e=t._texture,s=this._getGpuSprite(t);return s.texture._source!==e._source?!s.batcher.checkAndUpdateTexture(s,e):!1}destroyRenderable(t){const e=this._gpuSpriteHash[t.uid];H.return(e),this._gpuSpriteHash[t.uid]=null}_updateBatchableSprite(t,e){t._didSpriteUpdate=!1,e.geometry.update(t),e.texture=t._texture}_getGpuSprite(t){return this._gpuSpriteHash[t.uid]||this._initGPUSprite(t)}_initGPUSprite(t){const e=new ws;return e.geometry=new te,e.mesh=t,e.texture=t._texture,e.roundPixels=this._renderer._roundPixels|t._roundPixels,this._gpuSpriteHash[t.uid]=e,t.on("destroyed",()=>{this.destroyRenderable(t)}),e}destroy(){for(const t in this._gpuSpriteHash)this._gpuSpriteHash[t].geometry.destroy();this._gpuSpriteHash=null,this._renderer=null}}Xo.extension={type:[v.WebGLPipes,v.WebGPUPipes,v.CanvasPipes],name:"nineSliceSprite"},D.add(Xo);class zo{constructor(t){this._renderer=t}push(t,e,s){this._renderer.renderPipes.batch.break(s),s.add({renderPipeId:"filter",canBundle:!1,action:"pushFilter",container:e,filterEffect:t})}pop(t,e,s){this._renderer.renderPipes.batch.break(s),s.add({renderPipeId:"filter",action:"popFilter",canBundle:!1})}execute(t){t.action==="pushFilter"?this._renderer.filter.push(t):t.action==="popFilter"&&this._renderer.filter.pop()}destroy(){this._renderer=null}}zo.extension={type:[v.WebGLPipes,v.WebGPUPipes,v.CanvasPipes],name:"filter"};const Dy=new G;function xp(r,t){return t.clear(),jo(r,t),t.isValid||t.set(0,0,0,0),r.isRenderGroupRoot?t.applyMatrix(r.renderGroup.localTransform):t.applyMatrix(r.renderGroup.worldTransform),t}function jo(r,t){if(r.localDisplayStatus!==7||!r.measurable)return;const e=!!r.effects.length;let s=t;if((r.isRenderGroupRoot||e)&&(s=kt.get().clear()),r.boundsArea)t.addRect(r.boundsArea,r.worldTransform);else{if(r.renderPipeId){const n=r.bounds;s.addFrame(n.minX,n.minY,n.maxX,n.maxY,r.groupTransform)}const i=r.children;for(let n=0;n"},uInputPixel:{value:new Float32Array(4),type:"vec4"},uInputClamp:{value:new Float32Array(4),type:"vec4"},uOutputFrame:{value:new Float32Array(4),type:"vec4"},uGlobalFrame:{value:new Float32Array(4),type:"vec4"},uOutputTexture:{value:new Float32Array(4),type:"vec4"}}),this._globalFilterBindGroup=new Lt({}),this.renderer=t}get activeBackTexture(){var t;return(t=this._activeFilterData)==null?void 0:t.backTexture}push(t){var e,s;const i=this.renderer,n=t.filterEffect.filters;this._filterStack[this._filterStackIndex]||(this._filterStack[this._filterStackIndex]=this._getFilterData());const o=this._filterStack[this._filterStackIndex];if(this._filterStackIndex++,n.length===0){o.skip=!0;return}const a=o.bounds;t.renderables?bp(t.renderables,a):t.filterEffect.filterArea?(a.clear(),a.addRect(t.filterEffect.filterArea),a.applyMatrix(t.container.worldTransform)):xp(t.container,a);const u=i.renderTarget.rootRenderTarget.colorTexture.source;let l=u._resolution,h=0,c=u.antialias,d=!1,p=!1;for(let g=0;g0?this._filterStack[this._filterStackIndex-1].bounds:null,u=t.renderTarget.getRenderTarget(e.previousRenderSurface);n=this.getBackTexture(u,i,a)}e.backTexture=n;const o=e.filterEffect.filters;if(this._globalFilterBindGroup.setResource(s.source.style,2),this._globalFilterBindGroup.setResource(n.source,3),t.globalUniforms.pop(),o.length===1)o[0].apply(this,s,e.previousRenderSurface,!1),ut.returnTexture(s);else{let a=e.inputTexture,u=ut.getOptimalTexture(i.width,i.height,a.source._resolution,!1),l=0;for(l=0;l0&&this._filterStack[c].skip;)--c;c>0&&(h=this._filterStack[c].inputTexture.source._resolution);const d=this._filterGlobalUniforms,p=d.uniforms,f=p.uOutputFrame,g=p.uInputSize,m=p.uInputPixel,_=p.uInputClamp,x=p.uGlobalFrame,b=p.uOutputTexture;if(l){let P=this._filterStackIndex;for(;P>0;){P--;const R=this._filterStack[this._filterStackIndex-1];if(!R.skip){u.x=R.bounds.minX,u.y=R.bounds.minY;break}}f[0]=a.minX-u.x,f[1]=a.minY-u.y}else f[0]=0,f[1]=0;f[2]=e.frame.width,f[3]=e.frame.height,g[0]=e.source.width,g[1]=e.source.height,g[2]=1/g[0],g[3]=1/g[1],m[0]=e.source.pixelWidth,m[1]=e.source.pixelHeight,m[2]=1/m[0],m[3]=1/m[1],_[0]=.5*m[2],_[1]=.5*m[3],_[2]=e.frame.width*g[2]-.5*m[2],_[3]=e.frame.height*g[3]-.5*m[3];const y=this.renderer.renderTarget.rootRenderTarget.colorTexture;x[0]=u.x*h,x[1]=u.y*h,x[2]=y.source.width*h,x[3]=y.source.height*h;const S=this.renderer.renderTarget.getRenderTarget(s);if(n.renderTarget.bind(s,!!i),s instanceof A?(b[0]=s.frame.width,b[1]=s.frame.height):(b[0]=S.width,b[1]=S.height),b[2]=S.isRoot?-1:1,d.update(),n.renderPipes.uniformBatch){const P=n.renderPipes.uniformBatch.getUboResource(d);this._globalFilterBindGroup.setResource(P,0)}else this._globalFilterBindGroup.setResource(d,0);this._globalFilterBindGroup.setResource(e.source,1),this._globalFilterBindGroup.setResource(e.source.style,2),t.groups[0]=this._globalFilterBindGroup,n.encoder.draw({geometry:Uy,shader:t,state:t._state,topology:"triangle-list"}),n.type===xt.WEBGL&&n.renderTarget.finishRenderPass()}_getFilterData(){return{skip:!1,inputTexture:null,bounds:new lt,container:null,filterEffect:null,blendRequired:!1,previousRenderSurface:null}}calculateSpriteMatrix(t,e){const s=this._activeFilterData,i=t.set(s.inputTexture._source.width,0,0,s.inputTexture._source.height,s.bounds.minX,s.bounds.minY),n=e.worldTransform.copyTo(G.shared);return n.invert(),i.prepend(n),i.scale(1/e.texture.frame.width,1/e.texture.frame.height),i.translate(e.anchor.x,e.anchor.y),i}}Vo.extension={type:[v.WebGLSystem,v.WebGPUSystem],name:"filter"},D.add(Vo),D.add(zo);var ky={__proto__:null};const Wo=[];D.handleByNamedList(v.Environment,Wo);async function vp(r){if(r)for(let t=0;t(r[r.NONE=0]="NONE",r[r.COLOR=16384]="COLOR",r[r.STENCIL=1024]="STENCIL",r[r.DEPTH=256]="DEPTH",r[r.COLOR_DEPTH=16640]="COLOR_DEPTH",r[r.COLOR_STENCIL=17408]="COLOR_STENCIL",r[r.DEPTH_STENCIL=1280]="DEPTH_STENCIL",r[r.ALL=17664]="ALL",r))(pt||{});class Ko{constructor(t){this.items=[],this._name=t}emit(t,e,s,i,n,o,a,u){const{name:l,items:h}=this;for(let c=0,d=h.length;ct in r?Ly(r,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):r[t]=e,Vs=(r,t)=>{for(var e in t||(t={}))$y.call(t,e)&&Tp(r,e,t[e]);if(yp)for(var e of yp(t))Ny.call(t,e)&&Tp(r,e,t[e]);return r};const Hy=["init","destroy","contextChange","resolutionChange","reset","renderEnd","renderStart","render","update","postrender","prerender"],Sp=class Ox extends ct{constructor(t){var e;super(),this.runners=Object.create(null),this.renderPipes=Object.create(null),this._initOptions={},this._systemsHash=Object.create(null),this.type=t.type,this.name=t.name;const s=[...Hy,...(e=t.runners)!=null?e:[]];this._addRunners(...s),this._addSystems(t.systems),this._addPipes(t.renderPipes,t.renderPipeAdaptors),this._unsafeEvalCheck()}async init(t={}){for(const e in this._systemsHash){const s=this._systemsHash[e].constructor.defaultOptions;t=Vs(Vs({},s),t)}t=Vs(Vs({},Ox.defaultOptions),t),this._roundPixels=t.roundPixels?1:0;for(let e=0;e{this.runners[e]=new Ko(e)})}_addSystems(t){let e;for(e in t){const s=t[e];this._addSystem(s.value,s.name)}}_addSystem(t,e){const s=new t(this);if(this[e])throw new Error(`Whoops! The name "${e}" is already in use`);this[e]=s,this._systemsHash[e]=s;for(const i in this.runners)this.runners[i].add(s);return this}_addPipes(t,e){const s=e.reduce((i,n)=>(i[n.name]=n.value,i),{});t.forEach(i=>{const n=i.value,o=i.name,a=s[o];this.renderPipes[o]=new n(this,a?new a:null)})}destroy(t=!1){this.runners.destroy.items.reverse(),this.runners.destroy.emit(t),Object.values(this.runners).forEach(e=>{e.destroy()}),this._systemsHash=null,this.renderPipes=null}generateTexture(t){return this.textureGenerator.generateTexture(t)}get roundPixels(){return!!this._roundPixels}_unsafeEvalCheck(){if(!Yo())throw new Error("Current environment does not allow unsafe-eval, please use pixi.js/unsafe-eval module to enable support.")}};Sp.defaultOptions={resolution:1,failIfMajorPerformanceCaveat:!1,roundPixels:!1};let Or=Sp,qo;function Cr(r){return qo!==void 0||(qo=(()=>{var t;const e={stencil:!0,failIfMajorPerformanceCaveat:r!=null?r:Or.defaultOptions.failIfMajorPerformanceCaveat};try{if(!X.get().getWebGLRenderingContext())return!1;let s=X.get().createCanvas().getContext("webgl",e);const i=!!((t=s==null?void 0:s.getContextAttributes())!=null&&t.stencil);if(s){const n=s.getExtension("WEBGL_lose_context");n&&n.loseContext()}return s=null,i}catch(s){return!1}})()),qo}let Zo;async function Gr(r={}){return Zo!==void 0||(Zo=await(async()=>{if(!X.get().getNavigator().gpu)return!1;try{return await(await navigator.gpu.requestAdapter(r)).requestDevice(),!0}catch(t){return!1}})()),Zo}var Xy=Object.defineProperty,Ep=Object.getOwnPropertySymbols,zy=Object.prototype.hasOwnProperty,jy=Object.prototype.propertyIsEnumerable,Ap=(r,t,e)=>t in r?Xy(r,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):r[t]=e,Ir=(r,t)=>{for(var e in t||(t={}))zy.call(t,e)&&Ap(r,e,t[e]);if(Ep)for(var e of Ep(t))jy.call(t,e)&&Ap(r,e,t[e]);return r};const Pp=["webgpu","webgl","canvas"];async function wp(r){var t,e;let s=[];r.preference?(s.push(r.preference),Pp.forEach(a=>{a!==r.preference&&s.push(a)})):s=Pp.slice();let i;await vp((t=r.manageImports)!=null?t:!0);let n={};for(let a=0;at in r?Vy(r,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):r[t]=e,Ky=(r,t)=>{for(var e in t||(t={}))Wy.call(t,e)&&Mp(r,e,t[e]);if(Rp)for(var e of Rp(t))Yy.call(t,e)&&Mp(r,e,t[e]);return r};const Op=class Ku{constructor(...t){this.stage=new V}async init(t){t=Ky({},t),this.renderer=await wp(t),Ku._plugins.forEach(e=>{e.init.call(this,t)})}render(){this.renderer.render({container:this.stage})}get canvas(){return this.renderer.canvas}get view(){return this.renderer.canvas}get screen(){return this.renderer.screen}destroy(t=!1,e=!1){const s=Ku._plugins.slice(0);s.reverse(),s.forEach(i=>{i.destroy.call(this)}),this.stage.destroy(e),this.stage=null,this.renderer.destroy(t),this.renderer=null}};Op._plugins=[];let Cp=Op;D.handleByList(v.Application,Cp._plugins);class Gp{constructor(t,e=!1){this._loader=t,this._assetList=[],this._isLoading=!1,this._maxConcurrent=1,this.verbose=e}add(t){t.forEach(e=>{this._assetList.push(e)}),this.verbose&&console.log("[BackgroundLoader] assets: ",this._assetList),this._isActive&&!this._isLoading&&this._next()}async _next(){if(this._assetList.length&&this._isActive){this._isLoading=!0;const t=[],e=Math.min(this._assetList.length,this._maxConcurrent);for(let s=0;sArray.isArray(r)&&r.every(t=>t instanceof A),getCacheableAssets:(r,t)=>{const e={};return r.forEach(s=>{t.forEach((i,n)=>{e[s+(n===0?"":n+1)]=i})}),e}};async function Qo(r){if("Image"in globalThis)return new Promise(t=>{const e=new Image;e.onload=()=>{t(!0)},e.onerror=()=>{t(!1)},e.src=r});if("createImageBitmap"in globalThis&&"fetch"in globalThis){try{const t=await(await fetch(r)).blob();await createImageBitmap(t)}catch(t){return!1}return!0}return!1}const Bp={extension:{type:v.DetectionParser,priority:1},test:async()=>Qo("data:image/avif;base64,AAAAIGZ0eXBhdmlmAAAAAGF2aWZtaWYxbWlhZk1BMUIAAADybWV0YQAAAAAAAAAoaGRscgAAAAAAAAAAcGljdAAAAAAAAAAAAAAAAGxpYmF2aWYAAAAADnBpdG0AAAAAAAEAAAAeaWxvYwAAAABEAAABAAEAAAABAAABGgAAAB0AAAAoaWluZgAAAAAAAQAAABppbmZlAgAAAAABAABhdjAxQ29sb3IAAAAAamlwcnAAAABLaXBjbwAAABRpc3BlAAAAAAAAAAIAAAACAAAAEHBpeGkAAAAAAwgICAAAAAxhdjFDgQ0MAAAAABNjb2xybmNseAACAAIAAYAAAAAXaXBtYQAAAAAAAAABAAEEAQKDBAAAACVtZGF0EgAKCBgANogQEAwgMg8f8D///8WfhwB8+ErK42A="),add:async r=>[...r,"avif"],remove:async r=>r.filter(t=>t!=="avif")},Fp=["png","jpg","jpeg"],Dp={extension:{type:v.DetectionParser,priority:-1},test:()=>Promise.resolve(!0),add:async r=>[...r,...Fp],remove:async r=>r.filter(t=>!Fp.includes(t))},qy="WorkerGlobalScope"in globalThis&&globalThis instanceof globalThis.WorkerGlobalScope;function Ws(r){return qy?!1:document.createElement("video").canPlayType(r)!==""}const Up={extension:{type:v.DetectionParser,priority:0},test:async()=>Ws("video/mp4"),add:async r=>[...r,"mp4","m4v"],remove:async r=>r.filter(t=>t!=="mp4"&&t!=="m4v")},kp={extension:{type:v.DetectionParser,priority:0},test:async()=>Ws("video/ogg"),add:async r=>[...r,"ogv"],remove:async r=>r.filter(t=>t!=="ogv")},Lp={extension:{type:v.DetectionParser,priority:0},test:async()=>Ws("video/webm"),add:async r=>[...r,"webm"],remove:async r=>r.filter(t=>t!=="webm")},$p={extension:{type:v.DetectionParser,priority:0},test:async()=>Qo("data:image/webp;base64,UklGRh4AAABXRUJQVlA4TBEAAAAvAAAAAAfQ//73v/+BiOh/AAA="),add:async r=>[...r,"webp"],remove:async r=>r.filter(t=>t!=="webp")};var Zy=Object.defineProperty,Qy=Object.defineProperties,Jy=Object.getOwnPropertyDescriptors,Np=Object.getOwnPropertySymbols,t1=Object.prototype.hasOwnProperty,e1=Object.prototype.propertyIsEnumerable,Hp=(r,t,e)=>t in r?Zy(r,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):r[t]=e,r1=(r,t)=>{for(var e in t||(t={}))t1.call(t,e)&&Hp(r,e,t[e]);if(Np)for(var e of Np(t))e1.call(t,e)&&Hp(r,e,t[e]);return r},s1=(r,t)=>Qy(r,Jy(t));class Xp{constructor(){this._parsers=[],this._parsersValidated=!1,this.parsers=new Proxy(this._parsers,{set:(t,e,s)=>(this._parsersValidated=!1,t[e]=s,!0)}),this.promiseCache={}}reset(){this._parsersValidated=!1,this.promiseCache={}}_getLoadPromiseAndParser(t,e){const s={promise:null,parser:null};return s.promise=(async()=>{var i,n;let o=null,a=null;if(e.loadParser&&(a=this._parserHash[e.loadParser]),!a){for(let u=0;u({alias:[l],src:l})),a=o.length,u=o.map(async l=>{const h=dt.toAbsolute(l.src);if(!i[l.src])try{this.promiseCache[h]||(this.promiseCache[h]=this._getLoadPromiseAndParser(h,l)),i[l.src]=await this.promiseCache[h].promise,e&&e(++s/a)}catch(c){throw delete this.promiseCache[h],delete i[l.src],new Error(`[Loader.load] Failed to load ${h}. -${c}`)}});return await Promise.all(u),n?i[o[0].src]:i}async unload(t){const e=Pt(t,s=>({alias:[s],src:s})).map(async s=>{var i,n;const o=dt.toAbsolute(s.src),a=this.promiseCache[o];if(a){const u=await a.promise;delete this.promiseCache[o],await((n=(i=a.parser)==null?void 0:i.unload)==null?void 0:n.call(i,u,s,this))}});await Promise.all(e)}_validateParsers(){this._parsersValidated=!0,this._parserHash=this._parsers.filter(t=>t.name).reduce((t,e)=>(e.name&&t[e.name],s1(r1({},t),{[e.name]:e})),{})}}function Se(r,t){if(Array.isArray(t)){for(const e of t)if(r.startsWith(`data:${e}`))return!0;return!1}return r.startsWith(`data:${t}`)}function Mt(r,t){const e=r.split("?")[0],s=dt.extname(e).toLowerCase();return Array.isArray(t)?t.includes(s):s===t}const i1=".json",n1="application/json",zp={extension:{type:v.LoadParser,priority:gt.Low},name:"loadJson",test(r){return Se(r,n1)||Mt(r,i1)},async load(r){return await(await X.get().fetch(r)).json()}},o1=".txt",a1="text/plain",jp={name:"loadTxt",extension:{type:v.LoadParser,priority:gt.Low},test(r){return Se(r,a1)||Mt(r,o1)},async load(r){return await(await X.get().fetch(r)).text()}};var u1=Object.defineProperty,l1=Object.defineProperties,h1=Object.getOwnPropertyDescriptors,Vp=Object.getOwnPropertySymbols,c1=Object.prototype.hasOwnProperty,d1=Object.prototype.propertyIsEnumerable,Wp=(r,t,e)=>t in r?u1(r,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):r[t]=e,p1=(r,t)=>{for(var e in t||(t={}))c1.call(t,e)&&Wp(r,e,t[e]);if(Vp)for(var e of Vp(t))d1.call(t,e)&&Wp(r,e,t[e]);return r},f1=(r,t)=>l1(r,h1(t));const m1=["normal","bold","100","200","300","400","500","600","700","800","900"],g1=[".ttf",".otf",".woff",".woff2"],_1=["font/ttf","font/otf","font/woff","font/woff2"],x1=/^(--|-?[A-Z_])[0-9A-Z_-]*$/i;function Yp(r){const t=dt.extname(r),e=dt.basename(r,t).replace(/(-|_)/g," ").toLowerCase().split(" ").map(n=>n.charAt(0).toUpperCase()+n.slice(1));let s=e.length>0;for(const n of e)if(!n.match(x1)){s=!1;break}let i=e.join(" ");return s||(i=`"${i.replace(/[\\"]/g,"\\$&")}"`),i}const b1=/^[0-9A-Za-z%:/?#\[\]@!\$&'()\*\+,;=\-._~]*$/;function v1(r){return b1.test(r)?r:encodeURI(r)}const Kp={extension:{type:v.LoadParser,priority:gt.Low},name:"loadWebFont",test(r){return Se(r,_1)||Mt(r,g1)},async load(r,t){var e,s,i,n,o,a;const u=X.get().getFontFaceSet();if(u){const l=[],h=(s=(e=t.data)==null?void 0:e.family)!=null?s:Yp(r),c=(o=(n=(i=t.data)==null?void 0:i.weights)==null?void 0:n.filter(p=>m1.includes(p)))!=null?o:["normal"],d=(a=t.data)!=null?a:{};for(let p=0;p{Y.remove(t.family),X.get().getFontFaceSet().delete(t)})}};function Ys(r,t=1){var e;const s=(e=qt.RETINA_PREFIX)==null?void 0:e.exec(r);return s?parseFloat(s[1]):t}function ee(r,t,e){r.label=e,r._sourceOrigin=e;const s=new A({source:r,label:e}),i=()=>{delete t.promiseCache[e],Y.has(e)&&Y.remove(e)};return s.source.once("destroy",()=>{t.promiseCache[e]&&i()}),s.once("destroy",()=>{r.destroyed||i()}),s}var y1=Object.defineProperty,Ks=Object.getOwnPropertySymbols,qp=Object.prototype.hasOwnProperty,Zp=Object.prototype.propertyIsEnumerable,Qp=(r,t,e)=>t in r?y1(r,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):r[t]=e,T1=(r,t)=>{for(var e in t||(t={}))qp.call(t,e)&&Qp(r,e,t[e]);if(Ks)for(var e of Ks(t))Zp.call(t,e)&&Qp(r,e,t[e]);return r},S1=(r,t)=>{var e={};for(var s in r)qp.call(r,s)&&t.indexOf(s)<0&&(e[s]=r[s]);if(r!=null&&Ks)for(var s of Ks(r))t.indexOf(s)<0&&Zp.call(r,s)&&(e[s]=r[s]);return e};const E1=".svg",A1="image/svg+xml",Jp={extension:{type:v.LoadParser,priority:gt.Low},name:"loadSVG",config:{crossOrigin:"anonymous",parseAsGraphicsContext:!1},test(r){return Se(r,A1)||Mt(r,E1)},async load(r,t,e){var s;return((s=t.data.parseAsGraphicsContext)!=null?s:this.config.parseAsGraphicsContext)?w1(r):P1(r,t,e,this.config.crossOrigin)},unload(r){r.destroy(!0)}};async function P1(r,t,e,s){var i,n,o,a,u;const l=await(await X.get().fetch(r)).blob(),h=URL.createObjectURL(l),c=new Image;c.src=h,c.crossOrigin=s,await c.decode(),URL.revokeObjectURL(h);const d=document.createElement("canvas"),p=d.getContext("2d"),f=((i=t.data)==null?void 0:i.resolution)||Ys(r),g=(o=(n=t.data)==null?void 0:n.width)!=null?o:c.width,m=(u=(a=t.data)==null?void 0:a.height)!=null?u:c.height;d.width=g*f,d.height=m*f,p.drawImage(c,0,0,g*f,m*f);const _=t.data,{parseAsGraphicsContext:x}=_,b=S1(_,["parseAsGraphicsContext"]),y=new ge(T1({resource:d,alphaMode:"premultiply-alpha-on-upload",resolution:f},b));return ee(y,e,r)}async function w1(r){const t=await(await X.get().fetch(r)).text(),e=new Bt;return e.svg(t),e}const R1=`(function(){"use strict";const e="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mP8/x8AAwMCAO+ip1sAAAAASUVORK5CYII=";async function a(){try{if(typeof createImageBitmap!="function")return!1;const A=await(await fetch(e)).blob(),t=await createImageBitmap(A);return t.width===1&&t.height===1}catch(A){return!1}}a().then(A=>{self.postMessage(A)})})(); -`;let He=null,Jo=class{constructor(){He||(He=URL.createObjectURL(new Blob([R1],{type:"application/javascript"}))),this.worker=new Worker(He)}};Jo.revokeObjectURL=function(){He&&(URL.revokeObjectURL(He),He=null)};const M1='(function(){"use strict";async function e(t){const a=await fetch(t);if(!a.ok)throw new Error(`[WorkerManager.loadImageBitmap] Failed to fetch ${t}: ${a.status} ${a.statusText}`);const s=await a.blob();return await createImageBitmap(s)}self.onmessage=async t=>{try{const a=await e(t.data.data[0]);self.postMessage({data:a,uuid:t.data.uuid,id:t.data.id},[a])}catch(a){self.postMessage({error:a,uuid:t.data.uuid,id:t.data.id})}}})();\n';let Xe=null,tf=class{constructor(){Xe||(Xe=URL.createObjectURL(new Blob([M1],{type:"application/javascript"}))),this.worker=new Worker(Xe)}};tf.revokeObjectURL=function(){Xe&&(URL.revokeObjectURL(Xe),Xe=null)};let ef=0,ta,O1=class{constructor(){this._initialized=!1,this._createdWorkers=0,this._workerPool=[],this._queue=[],this._resolveHash={}}isImageBitmapSupported(){return this._isImageBitmapSupported!==void 0?this._isImageBitmapSupported:(this._isImageBitmapSupported=new Promise(t=>{const{worker:e}=new Jo;e.addEventListener("message",s=>{e.terminate(),Jo.revokeObjectURL(),t(s.data)})}),this._isImageBitmapSupported)}loadImageBitmap(t){return this._run("loadImageBitmap",[t])}async _initWorkers(){this._initialized||(this._initialized=!0)}_getWorker(){ta===void 0&&(ta=navigator.hardwareConcurrency||4);let t=this._workerPool.pop();return!t&&this._createdWorkers{this._complete(e.data),this._returnWorker(e.target),this._next()})),t}_returnWorker(t){this._workerPool.push(t)}_complete(t){t.error!==void 0?this._resolveHash[t.uuid].reject(t.error):this._resolveHash[t.uuid].resolve(t.data),this._resolveHash[t.uuid]=null}async _run(t,e){await this._initWorkers();const s=new Promise((i,n)=>{this._queue.push({id:t,arguments:e,resolve:i,reject:n})});return this._next(),s}_next(){if(!this._queue.length)return;const t=this._getWorker();if(!t)return;const e=this._queue.pop(),s=e.id;this._resolveHash[ef]={resolve:e.resolve,reject:e.reject},t.postMessage({data:e.arguments,uuid:ef++,id:s})}};const ea=new O1;var C1=Object.defineProperty,rf=Object.getOwnPropertySymbols,G1=Object.prototype.hasOwnProperty,I1=Object.prototype.propertyIsEnumerable,sf=(r,t,e)=>t in r?C1(r,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):r[t]=e,B1=(r,t)=>{for(var e in t||(t={}))G1.call(t,e)&&sf(r,e,t[e]);if(rf)for(var e of rf(t))I1.call(t,e)&&sf(r,e,t[e]);return r};const F1=[".jpeg",".jpg",".png",".webp",".avif"],D1=["image/jpeg","image/png","image/webp","image/avif"];async function nf(r){const t=await X.get().fetch(r);if(!t.ok)throw new Error(`[loadImageBitmap] Failed to fetch ${r}: ${t.status} ${t.statusText}`);const e=await t.blob();return await createImageBitmap(e)}const ra={name:"loadTextures",extension:{type:v.LoadParser,priority:gt.High},config:{preferWorkers:!0,preferCreateImageBitmap:!0,crossOrigin:"anonymous"},test(r){return Se(r,D1)||Mt(r,F1)},async load(r,t,e){var s;let i=null;globalThis.createImageBitmap&&this.config.preferCreateImageBitmap?this.config.preferWorkers&&await ea.isImageBitmapSupported()?i=await ea.loadImageBitmap(r):i=await nf(r):i=await new Promise(o=>{i=new Image,i.crossOrigin=this.config.crossOrigin,i.src=r,i.complete?o(i):i.onload=()=>{o(i)}});const n=new ge(B1({resource:i,alphaMode:"premultiply-alpha-on-upload",resolution:((s=t.data)==null?void 0:s.resolution)||Ys(r)},t.data));return ee(n,e,r)},unload(r){r.destroy(!0)}};var U1=Object.defineProperty,k1=Object.defineProperties,L1=Object.getOwnPropertyDescriptors,of=Object.getOwnPropertySymbols,$1=Object.prototype.hasOwnProperty,N1=Object.prototype.propertyIsEnumerable,af=(r,t,e)=>t in r?U1(r,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):r[t]=e,sa=(r,t)=>{for(var e in t||(t={}))$1.call(t,e)&&af(r,e,t[e]);if(of)for(var e of of(t))N1.call(t,e)&&af(r,e,t[e]);return r},uf=(r,t)=>k1(r,L1(t));const lf=[".mp4",".m4v",".webm",".ogg",".ogv",".h264",".avi",".mov"],H1=lf.map(r=>`video/${r.substring(1)}`);function hf(r,t,e){e===void 0&&!t.startsWith("data:")?r.crossOrigin=df(t):e!==!1&&(r.crossOrigin=typeof e=="string"?e:"anonymous")}function cf(r){return new Promise((t,e)=>{r.addEventListener("canplaythrough",s),r.addEventListener("error",i),r.load();function s(){n(),t()}function i(o){n(),e(o)}function n(){r.removeEventListener("canplaythrough",s),r.removeEventListener("error",i)}})}function df(r,t=globalThis.location){if(r.startsWith("data:"))return"";t=t||globalThis.location;const e=new URL(r,document.baseURI);return e.hostname!==t.hostname||e.port!==t.port||e.protocol!==t.protocol?"anonymous":""}const pf={name:"loadVideo",extension:{type:v.LoadParser},config:null,test(r){const t=Se(r,H1),e=Mt(r,lf);return t||e},async load(r,t,e){var s,i;const n=sa(uf(sa({},pr.defaultOptions),{resolution:((s=t.data)==null?void 0:s.resolution)||Ys(r),alphaMode:((i=t.data)==null?void 0:i.alphaMode)||await _n()}),t.data),o=document.createElement("video"),a={preload:n.autoLoad!==!1?"auto":void 0,"webkit-playsinline":n.playsinline!==!1?"":void 0,playsinline:n.playsinline!==!1?"":void 0,muted:n.muted===!0?"":void 0,loop:n.loop===!0?"":void 0,autoplay:n.autoPlay!==!1?"":void 0};Object.keys(a).forEach(h=>{const c=a[h];c!==void 0&&o.setAttribute(h,c)}),n.muted===!0&&(o.muted=!0),hf(o,r,n.crossorigin);const u=document.createElement("source");let l;if(r.startsWith("data:"))l=r.slice(5,r.indexOf(";"));else if(!r.startsWith("blob:")){const h=r.split("?")[0].slice(r.lastIndexOf(".")+1).toLowerCase();l=pr.MIME_TYPES[h]||`video/${h}`}return u.src=r,l&&(u.type=l),new Promise(h=>{const c=async()=>{const d=new pr(uf(sa({},n),{resource:o}));o.removeEventListener("canplay",c),t.data.preload&&await cf(o),h(ee(d,e,r))};o.addEventListener("canplay",c),o.appendChild(u)})},unload(r){r.destroy(!0)}},ia={extension:v.ResolveParser,test:ra.test,parse:r=>{var t,e;return{resolution:parseFloat((e=(t=qt.RETINA_PREFIX.exec(r))==null?void 0:t[1])!=null?e:"1"),format:r.split(".").pop(),src:r}}},ff={extension:v.ResolveParser,test:r=>qt.RETINA_PREFIX.test(r)&&r.endsWith(".json"),parse:ia.parse};class mf{constructor(){this._detections=[],this._initialized=!1,this.resolver=new qt,this.loader=new Xp,this.cache=Y,this._backgroundLoader=new Gp(this.loader),this._backgroundLoader.active=!0,this.reset()}async init(t={}){var e,s,i;if(this._initialized)return;if(this._initialized=!0,t.defaultSearchParams&&this.resolver.setDefaultSearchParams(t.defaultSearchParams),t.basePath&&(this.resolver.basePath=t.basePath),t.bundleIdentifier&&this.resolver.setBundleIdentifier(t.bundleIdentifier),t.manifest){let u=t.manifest;typeof u=="string"&&(u=await this.load(u)),this.resolver.addManifest(u)}const n=(s=(e=t.texturePreference)==null?void 0:e.resolution)!=null?s:1,o=typeof n=="number"?[n]:n,a=await this._detectFormats({preferredFormats:(i=t.texturePreference)==null?void 0:i.format,skipDetections:t.skipDetections,detections:this._detections});this.resolver.prefer({params:{format:a,resolution:o}}),t.preferences&&this.setPreferences(t.preferences)}add(t){this.resolver.add(t)}async load(t,e){this._initialized||await this.init();const s=cr(t),i=Pt(t).map(a=>{if(typeof a!="string"){const u=this.resolver.getAlias(a);return u.some(l=>!this.resolver.hasKey(l))&&this.add(a),Array.isArray(u)?u[0]:u}return this.resolver.hasKey(a)||this.add({alias:a,src:a}),a}),n=this.resolver.resolve(i),o=await this._mapLoadToResolve(n,e);return s?o[i[0]]:o}addBundle(t,e){this.resolver.addBundle(t,e)}async loadBundle(t,e){this._initialized||await this.init();let s=!1;typeof t=="string"&&(s=!0,t=[t]);const i=this.resolver.resolveBundle(t),n={},o=Object.keys(i);let a=0,u=0;const l=()=>{e==null||e(++a/u)},h=o.map(c=>{const d=i[c];return u+=Object.keys(d).length,this._mapLoadToResolve(d,l).then(p=>{n[c]=p})});return await Promise.all(h),s?n[t[0]]:n}async backgroundLoad(t){this._initialized||await this.init(),typeof t=="string"&&(t=[t]);const e=this.resolver.resolve(t);this._backgroundLoader.add(Object.values(e))}async backgroundLoadBundle(t){this._initialized||await this.init(),typeof t=="string"&&(t=[t]);const e=this.resolver.resolveBundle(t);Object.values(e).forEach(s=>{this._backgroundLoader.add(Object.values(s))})}reset(){this.resolver.reset(),this.loader.reset(),this.cache.reset(),this._initialized=!1}get(t){if(typeof t=="string")return Y.get(t);const e={};for(let s=0;s{const a=i[o.src],u=[o.src];o.alias&&u.push(...o.alias),u.forEach(l=>{n[l]=a}),Y.set(u,a)}),n}async unload(t){this._initialized||await this.init();const e=Pt(t).map(i=>typeof i!="string"?i.src:i),s=this.resolver.resolve(e);await this._unloadFromResolved(s)}async unloadBundle(t){this._initialized||await this.init(),t=Pt(t);const e=this.resolver.resolveBundle(t),s=Object.keys(e).map(i=>this._unloadFromResolved(e[i]));await Promise.all(s)}async _unloadFromResolved(t){const e=Object.values(t);e.forEach(s=>{Y.remove(s.src)}),await this.loader.unload(e)}async _detectFormats(t){let e=[];t.preferredFormats&&(e=Array.isArray(t.preferredFormats)?t.preferredFormats:[t.preferredFormats]);for(const s of t.detections)t.skipDetections||await s.test()?e=await s.add(e):t.skipDetections||(e=await s.remove(e));return e=e.filter((s,i)=>e.indexOf(s)===i),e}get detections(){return this._detections}setPreferences(t){this.loader.parsers.forEach(e=>{e.config&&Object.keys(e.config).filter(s=>s in t).forEach(s=>{e.config[s]=t[s]})})}}const Br=new mf;D.handleByList(v.LoadParser,Br.loader.parsers).handleByList(v.ResolveParser,Br.resolver.parsers).handleByList(v.CacheParser,Br.cache.parsers).handleByList(v.DetectionParser,Br.detections),D.add(Ip,Dp,Bp,$p,Up,kp,Lp,zp,jp,Kp,Jp,ra,pf,ia,ff);const gf={loader:v.LoadParser,resolver:v.ResolveParser,cache:v.CacheParser,detection:v.DetectionParser};D.handle(v.Asset,r=>{const t=r.ref;Object.entries(gf).filter(([e])=>!!t[e]).forEach(([e,s])=>{var i;return D.add(Object.assign(t[e],{extension:(i=t[e].extension)!=null?i:s}))})},r=>{const t=r.ref;Object.keys(gf).filter(e=>!!t[e]).forEach(e=>D.remove(t[e]))});const X1={extension:{type:v.DetectionParser,priority:3},test:async()=>!!(await Gr()||Cr()),add:async r=>[...r,"basis"],remove:async r=>r.filter(t=>t!=="basis")};class Fr extends et{constructor(t){super(t),this.uploadMethodId="compressed",this.resource=t.resource,this.mipLevelCount=this.resource.length}}let qs;function na(){if(qs)return qs;const r=document.createElement("canvas").getContext("webgl");return r?(qs=[...r.getExtension("EXT_texture_compression_bptc")?["bc6h-rgb-ufloat","bc6h-rgb-float","bc7-rgba-unorm","bc7-rgba-unorm-srgb"]:[],...r.getExtension("WEBGL_compressed_texture_s3tc")?["bc1-rgba-unorm","bc2-rgba-unorm","bc3-rgba-unorm"]:[],...r.getExtension("WEBGL_compressed_texture_s3tc_srgb")?["bc1-rgba-unorm-srgb","bc2-rgba-unorm-srgb","bc3-rgba-unorm-srgb"]:[],...r.getExtension("EXT_texture_compression_rgtc")?["bc4-r-unorm","bc4-r-snorm","bc5-rg-unorm","bc5-rg-snorm"]:[],...r.getExtension("WEBGL_compressed_texture_etc")?["etc2-rgb8unorm","etc2-rgb8unorm-srgb","etc2-rgba8unorm","etc2-rgba8unorm-srgb","etc2-rgb8a1unorm","etc2-rgb8a1unorm-srgb","eac-r11unorm","eac-rg11unorm"]:[],...r.getExtension("WEBGL_compressed_texture_astc")?["astc-4x4-unorm","astc-4x4-unorm-srgb","astc-5x4-unorm","astc-5x4-unorm-srgb","astc-5x5-unorm","astc-5x5-unorm-srgb","astc-6x5-unorm","astc-6x5-unorm-srgb","astc-6x6-unorm","astc-6x6-unorm-srgb","astc-8x5-unorm","astc-8x5-unorm-srgb","astc-8x6-unorm","astc-8x6-unorm-srgb","astc-8x8-unorm","astc-8x8-unorm-srgb","astc-10x5-unorm","astc-10x5-unorm-srgb","astc-10x6-unorm","astc-10x6-unorm-srgb","astc-10x8-unorm","astc-10x8-unorm-srgb","astc-10x10-unorm","astc-10x10-unorm-srgb","astc-12x10-unorm","astc-12x10-unorm-srgb","astc-12x12-unorm","astc-12x12-unorm-srgb"]:[]],qs):[]}let Zs;async function oa(){if(Zs)return Zs;const r=await navigator.gpu.requestAdapter();return Zs=[...r.features.has("texture-compression-bc")?["bc1-rgba-unorm","bc1-rgba-unorm-srgb","bc2-rgba-unorm","bc2-rgba-unorm-srgb","bc3-rgba-unorm","bc3-rgba-unorm-srgb","bc4-r-unorm","bc4-r-snorm","bc5-rg-unorm","bc5-rg-snorm","bc6h-rgb-ufloat","bc6h-rgb-float","bc7-rgba-unorm","bc7-rgba-unorm-srgb"]:[],...r.features.has("texture-compression-etc2")?["etc2-rgb8unorm","etc2-rgb8unorm-srgb","etc2-rgb8a1unorm","etc2-rgb8a1unorm-srgb","etc2-rgba8unorm","etc2-rgba8unorm-srgb","eac-r11unorm","eac-r11snorm","eac-rg11unorm","eac-rg11snorm"]:[],...r.features.has("texture-compression-astc")?["astc-4x4-unorm","astc-4x4-unorm-srgb","astc-5x4-unorm","astc-5x4-unorm-srgb","astc-5x5-unorm","astc-5x5-unorm-srgb","astc-6x5-unorm","astc-6x5-unorm-srgb","astc-6x6-unorm","astc-6x6-unorm-srgb","astc-8x5-unorm","astc-8x5-unorm-srgb","astc-8x6-unorm","astc-8x6-unorm-srgb","astc-8x8-unorm","astc-8x8-unorm-srgb","astc-10x5-unorm","astc-10x5-unorm-srgb","astc-10x6-unorm","astc-10x6-unorm-srgb","astc-10x8-unorm","astc-10x8-unorm-srgb","astc-10x10-unorm","astc-10x10-unorm-srgb","astc-12x10-unorm","astc-12x10-unorm-srgb","astc-12x12-unorm","astc-12x12-unorm-srgb"]:[]],Zs}let aa;async function ua(){return aa!==void 0||(aa=await(async()=>{const r=await Gr(),t=Cr();if(r&&t){const e=await oa(),s=na();return e.filter(i=>s.includes(i))}else{if(r)return await oa();if(t)return na()}return[]})()),aa}const _f=["r8unorm","r8snorm","r8uint","r8sint","r16uint","r16sint","r16float","rg8unorm","rg8snorm","rg8uint","rg8sint","r32uint","r32sint","r32float","rg16uint","rg16sint","rg16float","rgba8unorm","rgba8unorm-srgb","rgba8snorm","rgba8uint","rgba8sint","bgra8unorm","bgra8unorm-srgb","rgb9e5ufloat","rgb10a2unorm","rg11b10ufloat","rg32uint","rg32sint","rg32float","rgba16uint","rgba16sint","rgba16float","rgba32uint","rgba32sint","rgba32float","stencil8","depth16unorm","depth24plus","depth24plus-stencil8","depth32float","depth32float-stencil8"];let Qs;async function Dr(){if(Qs!==void 0)return Qs;const r=await ua();return Qs=[..._f,...r],Qs}const z1='(function(){"use strict";function g(r,a){const t=r.getNumImages(),s=r.getNumLevels(0);if(!r.startTranscoding())throw new Error("startTranscoding failed");const m=[];for(let e=0;e{BASIS({locateFile:s=>a}).then(s=>{s.initializeBasis(),t(s.BasisFile)})})}return c}async function b(r,a){const t=await fetch(r);if(t.ok){const s=await t.arrayBuffer();return new a(new Uint8Array(s))}throw new Error(`Failed to load Basis texture: ${r}`)}const h=["bc7-rgba-unorm","astc-4x4-unorm","etc2-rgba8unorm","bc3-rgba-unorm","rgba8unorm"];async function p(r){const a=await l(),t=await b(r,a),s=g(t,u);return{width:t.getImageWidth(0,0),height:t.getImageHeight(0,0),format:i,resource:s,alphaMode:"no-premultiply-alpha"}}async function y(r,a,t){r&&(n.jsUrl=r),a&&(n.wasmUrl=a),i=h.filter(s=>t.includes(s))[0],u=d(i),await l()}const U={init:async r=>{const{jsUrl:a,wasmUrl:t,supportedTextures:s}=r;await y(a,t,s)},load:async r=>{var a;try{const t=await p(r.url);return{type:"load",url:r.url,success:!0,textureOptions:t,transferables:(a=t.resource)==null?void 0:a.map(s=>s.buffer)}}catch(t){throw t}}};self.onmessage=async r=>{const a=r.data,t=await U[a.type](a);t&&self.postMessage(t,t.transferables)}})();\n';let ze=null,xf=class{constructor(){ze||(ze=URL.createObjectURL(new Blob([z1],{type:"application/javascript"}))),this.worker=new Worker(ze)}};xf.revokeObjectURL=function(){ze&&(URL.revokeObjectURL(ze),ze=null)};const Js={jsUrl:"https://files.pixijs.download/transcoders/basis/basis_transcoder.js",wasmUrl:"https://files.pixijs.download/transcoders/basis/basis_transcoder.wasm"};function j1(r){Object.assign(Js,r)}let Ur;const bf={};function V1(r){return Ur||(Ur=new xf().worker,Ur.onmessage=t=>{const{success:e,url:s,textureOptions:i}=t.data;e||console.warn("Failed to load Basis texture",s),bf[s](i)},Ur.postMessage({type:"init",jsUrl:Js.jsUrl,wasmUrl:Js.wasmUrl,supportedTextures:r})),Ur}function vf(r,t){const e=V1(t);return new Promise(s=>{bf[r]=s,e.postMessage({type:"load",url:r})})}const W1={extension:{type:v.LoadParser,priority:gt.High},name:"loadBasis",test(r){return Mt(r,[".basis"])},async load(r,t,e){const s=await Dr(),i=await vf(r,s),n=new Fr(i);return ee(n,e,r)},unload(r){Array.isArray(r)?r.forEach(t=>t.destroy(!0)):r.destroy(!0)}};function Y1(r,t){const e=r.getNumImages(),s=r.getNumLevels(0);if(!r.startTranscoding())throw new Error("startTranscoding failed");const i=[];for(let n=0;n(r[r.DXGI_FORMAT_UNKNOWN=0]="DXGI_FORMAT_UNKNOWN",r[r.DXGI_FORMAT_R32G32B32A32_TYPELESS=1]="DXGI_FORMAT_R32G32B32A32_TYPELESS",r[r.DXGI_FORMAT_R32G32B32A32_FLOAT=2]="DXGI_FORMAT_R32G32B32A32_FLOAT",r[r.DXGI_FORMAT_R32G32B32A32_UINT=3]="DXGI_FORMAT_R32G32B32A32_UINT",r[r.DXGI_FORMAT_R32G32B32A32_SINT=4]="DXGI_FORMAT_R32G32B32A32_SINT",r[r.DXGI_FORMAT_R32G32B32_TYPELESS=5]="DXGI_FORMAT_R32G32B32_TYPELESS",r[r.DXGI_FORMAT_R32G32B32_FLOAT=6]="DXGI_FORMAT_R32G32B32_FLOAT",r[r.DXGI_FORMAT_R32G32B32_UINT=7]="DXGI_FORMAT_R32G32B32_UINT",r[r.DXGI_FORMAT_R32G32B32_SINT=8]="DXGI_FORMAT_R32G32B32_SINT",r[r.DXGI_FORMAT_R16G16B16A16_TYPELESS=9]="DXGI_FORMAT_R16G16B16A16_TYPELESS",r[r.DXGI_FORMAT_R16G16B16A16_FLOAT=10]="DXGI_FORMAT_R16G16B16A16_FLOAT",r[r.DXGI_FORMAT_R16G16B16A16_UNORM=11]="DXGI_FORMAT_R16G16B16A16_UNORM",r[r.DXGI_FORMAT_R16G16B16A16_UINT=12]="DXGI_FORMAT_R16G16B16A16_UINT",r[r.DXGI_FORMAT_R16G16B16A16_SNORM=13]="DXGI_FORMAT_R16G16B16A16_SNORM",r[r.DXGI_FORMAT_R16G16B16A16_SINT=14]="DXGI_FORMAT_R16G16B16A16_SINT",r[r.DXGI_FORMAT_R32G32_TYPELESS=15]="DXGI_FORMAT_R32G32_TYPELESS",r[r.DXGI_FORMAT_R32G32_FLOAT=16]="DXGI_FORMAT_R32G32_FLOAT",r[r.DXGI_FORMAT_R32G32_UINT=17]="DXGI_FORMAT_R32G32_UINT",r[r.DXGI_FORMAT_R32G32_SINT=18]="DXGI_FORMAT_R32G32_SINT",r[r.DXGI_FORMAT_R32G8X24_TYPELESS=19]="DXGI_FORMAT_R32G8X24_TYPELESS",r[r.DXGI_FORMAT_D32_FLOAT_S8X24_UINT=20]="DXGI_FORMAT_D32_FLOAT_S8X24_UINT",r[r.DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS=21]="DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS",r[r.DXGI_FORMAT_X32_TYPELESS_G8X24_UINT=22]="DXGI_FORMAT_X32_TYPELESS_G8X24_UINT",r[r.DXGI_FORMAT_R10G10B10A2_TYPELESS=23]="DXGI_FORMAT_R10G10B10A2_TYPELESS",r[r.DXGI_FORMAT_R10G10B10A2_UNORM=24]="DXGI_FORMAT_R10G10B10A2_UNORM",r[r.DXGI_FORMAT_R10G10B10A2_UINT=25]="DXGI_FORMAT_R10G10B10A2_UINT",r[r.DXGI_FORMAT_R11G11B10_FLOAT=26]="DXGI_FORMAT_R11G11B10_FLOAT",r[r.DXGI_FORMAT_R8G8B8A8_TYPELESS=27]="DXGI_FORMAT_R8G8B8A8_TYPELESS",r[r.DXGI_FORMAT_R8G8B8A8_UNORM=28]="DXGI_FORMAT_R8G8B8A8_UNORM",r[r.DXGI_FORMAT_R8G8B8A8_UNORM_SRGB=29]="DXGI_FORMAT_R8G8B8A8_UNORM_SRGB",r[r.DXGI_FORMAT_R8G8B8A8_UINT=30]="DXGI_FORMAT_R8G8B8A8_UINT",r[r.DXGI_FORMAT_R8G8B8A8_SNORM=31]="DXGI_FORMAT_R8G8B8A8_SNORM",r[r.DXGI_FORMAT_R8G8B8A8_SINT=32]="DXGI_FORMAT_R8G8B8A8_SINT",r[r.DXGI_FORMAT_R16G16_TYPELESS=33]="DXGI_FORMAT_R16G16_TYPELESS",r[r.DXGI_FORMAT_R16G16_FLOAT=34]="DXGI_FORMAT_R16G16_FLOAT",r[r.DXGI_FORMAT_R16G16_UNORM=35]="DXGI_FORMAT_R16G16_UNORM",r[r.DXGI_FORMAT_R16G16_UINT=36]="DXGI_FORMAT_R16G16_UINT",r[r.DXGI_FORMAT_R16G16_SNORM=37]="DXGI_FORMAT_R16G16_SNORM",r[r.DXGI_FORMAT_R16G16_SINT=38]="DXGI_FORMAT_R16G16_SINT",r[r.DXGI_FORMAT_R32_TYPELESS=39]="DXGI_FORMAT_R32_TYPELESS",r[r.DXGI_FORMAT_D32_FLOAT=40]="DXGI_FORMAT_D32_FLOAT",r[r.DXGI_FORMAT_R32_FLOAT=41]="DXGI_FORMAT_R32_FLOAT",r[r.DXGI_FORMAT_R32_UINT=42]="DXGI_FORMAT_R32_UINT",r[r.DXGI_FORMAT_R32_SINT=43]="DXGI_FORMAT_R32_SINT",r[r.DXGI_FORMAT_R24G8_TYPELESS=44]="DXGI_FORMAT_R24G8_TYPELESS",r[r.DXGI_FORMAT_D24_UNORM_S8_UINT=45]="DXGI_FORMAT_D24_UNORM_S8_UINT",r[r.DXGI_FORMAT_R24_UNORM_X8_TYPELESS=46]="DXGI_FORMAT_R24_UNORM_X8_TYPELESS",r[r.DXGI_FORMAT_X24_TYPELESS_G8_UINT=47]="DXGI_FORMAT_X24_TYPELESS_G8_UINT",r[r.DXGI_FORMAT_R8G8_TYPELESS=48]="DXGI_FORMAT_R8G8_TYPELESS",r[r.DXGI_FORMAT_R8G8_UNORM=49]="DXGI_FORMAT_R8G8_UNORM",r[r.DXGI_FORMAT_R8G8_UINT=50]="DXGI_FORMAT_R8G8_UINT",r[r.DXGI_FORMAT_R8G8_SNORM=51]="DXGI_FORMAT_R8G8_SNORM",r[r.DXGI_FORMAT_R8G8_SINT=52]="DXGI_FORMAT_R8G8_SINT",r[r.DXGI_FORMAT_R16_TYPELESS=53]="DXGI_FORMAT_R16_TYPELESS",r[r.DXGI_FORMAT_R16_FLOAT=54]="DXGI_FORMAT_R16_FLOAT",r[r.DXGI_FORMAT_D16_UNORM=55]="DXGI_FORMAT_D16_UNORM",r[r.DXGI_FORMAT_R16_UNORM=56]="DXGI_FORMAT_R16_UNORM",r[r.DXGI_FORMAT_R16_UINT=57]="DXGI_FORMAT_R16_UINT",r[r.DXGI_FORMAT_R16_SNORM=58]="DXGI_FORMAT_R16_SNORM",r[r.DXGI_FORMAT_R16_SINT=59]="DXGI_FORMAT_R16_SINT",r[r.DXGI_FORMAT_R8_TYPELESS=60]="DXGI_FORMAT_R8_TYPELESS",r[r.DXGI_FORMAT_R8_UNORM=61]="DXGI_FORMAT_R8_UNORM",r[r.DXGI_FORMAT_R8_UINT=62]="DXGI_FORMAT_R8_UINT",r[r.DXGI_FORMAT_R8_SNORM=63]="DXGI_FORMAT_R8_SNORM",r[r.DXGI_FORMAT_R8_SINT=64]="DXGI_FORMAT_R8_SINT",r[r.DXGI_FORMAT_A8_UNORM=65]="DXGI_FORMAT_A8_UNORM",r[r.DXGI_FORMAT_R1_UNORM=66]="DXGI_FORMAT_R1_UNORM",r[r.DXGI_FORMAT_R9G9B9E5_SHAREDEXP=67]="DXGI_FORMAT_R9G9B9E5_SHAREDEXP",r[r.DXGI_FORMAT_R8G8_B8G8_UNORM=68]="DXGI_FORMAT_R8G8_B8G8_UNORM",r[r.DXGI_FORMAT_G8R8_G8B8_UNORM=69]="DXGI_FORMAT_G8R8_G8B8_UNORM",r[r.DXGI_FORMAT_BC1_TYPELESS=70]="DXGI_FORMAT_BC1_TYPELESS",r[r.DXGI_FORMAT_BC1_UNORM=71]="DXGI_FORMAT_BC1_UNORM",r[r.DXGI_FORMAT_BC1_UNORM_SRGB=72]="DXGI_FORMAT_BC1_UNORM_SRGB",r[r.DXGI_FORMAT_BC2_TYPELESS=73]="DXGI_FORMAT_BC2_TYPELESS",r[r.DXGI_FORMAT_BC2_UNORM=74]="DXGI_FORMAT_BC2_UNORM",r[r.DXGI_FORMAT_BC2_UNORM_SRGB=75]="DXGI_FORMAT_BC2_UNORM_SRGB",r[r.DXGI_FORMAT_BC3_TYPELESS=76]="DXGI_FORMAT_BC3_TYPELESS",r[r.DXGI_FORMAT_BC3_UNORM=77]="DXGI_FORMAT_BC3_UNORM",r[r.DXGI_FORMAT_BC3_UNORM_SRGB=78]="DXGI_FORMAT_BC3_UNORM_SRGB",r[r.DXGI_FORMAT_BC4_TYPELESS=79]="DXGI_FORMAT_BC4_TYPELESS",r[r.DXGI_FORMAT_BC4_UNORM=80]="DXGI_FORMAT_BC4_UNORM",r[r.DXGI_FORMAT_BC4_SNORM=81]="DXGI_FORMAT_BC4_SNORM",r[r.DXGI_FORMAT_BC5_TYPELESS=82]="DXGI_FORMAT_BC5_TYPELESS",r[r.DXGI_FORMAT_BC5_UNORM=83]="DXGI_FORMAT_BC5_UNORM",r[r.DXGI_FORMAT_BC5_SNORM=84]="DXGI_FORMAT_BC5_SNORM",r[r.DXGI_FORMAT_B5G6R5_UNORM=85]="DXGI_FORMAT_B5G6R5_UNORM",r[r.DXGI_FORMAT_B5G5R5A1_UNORM=86]="DXGI_FORMAT_B5G5R5A1_UNORM",r[r.DXGI_FORMAT_B8G8R8A8_UNORM=87]="DXGI_FORMAT_B8G8R8A8_UNORM",r[r.DXGI_FORMAT_B8G8R8X8_UNORM=88]="DXGI_FORMAT_B8G8R8X8_UNORM",r[r.DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM=89]="DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM",r[r.DXGI_FORMAT_B8G8R8A8_TYPELESS=90]="DXGI_FORMAT_B8G8R8A8_TYPELESS",r[r.DXGI_FORMAT_B8G8R8A8_UNORM_SRGB=91]="DXGI_FORMAT_B8G8R8A8_UNORM_SRGB",r[r.DXGI_FORMAT_B8G8R8X8_TYPELESS=92]="DXGI_FORMAT_B8G8R8X8_TYPELESS",r[r.DXGI_FORMAT_B8G8R8X8_UNORM_SRGB=93]="DXGI_FORMAT_B8G8R8X8_UNORM_SRGB",r[r.DXGI_FORMAT_BC6H_TYPELESS=94]="DXGI_FORMAT_BC6H_TYPELESS",r[r.DXGI_FORMAT_BC6H_UF16=95]="DXGI_FORMAT_BC6H_UF16",r[r.DXGI_FORMAT_BC6H_SF16=96]="DXGI_FORMAT_BC6H_SF16",r[r.DXGI_FORMAT_BC7_TYPELESS=97]="DXGI_FORMAT_BC7_TYPELESS",r[r.DXGI_FORMAT_BC7_UNORM=98]="DXGI_FORMAT_BC7_UNORM",r[r.DXGI_FORMAT_BC7_UNORM_SRGB=99]="DXGI_FORMAT_BC7_UNORM_SRGB",r[r.DXGI_FORMAT_AYUV=100]="DXGI_FORMAT_AYUV",r[r.DXGI_FORMAT_Y410=101]="DXGI_FORMAT_Y410",r[r.DXGI_FORMAT_Y416=102]="DXGI_FORMAT_Y416",r[r.DXGI_FORMAT_NV12=103]="DXGI_FORMAT_NV12",r[r.DXGI_FORMAT_P010=104]="DXGI_FORMAT_P010",r[r.DXGI_FORMAT_P016=105]="DXGI_FORMAT_P016",r[r.DXGI_FORMAT_420_OPAQUE=106]="DXGI_FORMAT_420_OPAQUE",r[r.DXGI_FORMAT_YUY2=107]="DXGI_FORMAT_YUY2",r[r.DXGI_FORMAT_Y210=108]="DXGI_FORMAT_Y210",r[r.DXGI_FORMAT_Y216=109]="DXGI_FORMAT_Y216",r[r.DXGI_FORMAT_NV11=110]="DXGI_FORMAT_NV11",r[r.DXGI_FORMAT_AI44=111]="DXGI_FORMAT_AI44",r[r.DXGI_FORMAT_IA44=112]="DXGI_FORMAT_IA44",r[r.DXGI_FORMAT_P8=113]="DXGI_FORMAT_P8",r[r.DXGI_FORMAT_A8P8=114]="DXGI_FORMAT_A8P8",r[r.DXGI_FORMAT_B4G4R4A4_UNORM=115]="DXGI_FORMAT_B4G4R4A4_UNORM",r[r.DXGI_FORMAT_P208=116]="DXGI_FORMAT_P208",r[r.DXGI_FORMAT_V208=117]="DXGI_FORMAT_V208",r[r.DXGI_FORMAT_V408=118]="DXGI_FORMAT_V408",r[r.DXGI_FORMAT_SAMPLER_FEEDBACK_MIN_MIP_OPAQUE=119]="DXGI_FORMAT_SAMPLER_FEEDBACK_MIN_MIP_OPAQUE",r[r.DXGI_FORMAT_SAMPLER_FEEDBACK_MIP_REGION_USED_OPAQUE=120]="DXGI_FORMAT_SAMPLER_FEEDBACK_MIP_REGION_USED_OPAQUE",r[r.DXGI_FORMAT_FORCE_UINT=121]="DXGI_FORMAT_FORCE_UINT",r))(yf||{}),Tf=(r=>(r[r.DDS_DIMENSION_TEXTURE1D=2]="DDS_DIMENSION_TEXTURE1D",r[r.DDS_DIMENSION_TEXTURE2D=3]="DDS_DIMENSION_TEXTURE2D",r[r.DDS_DIMENSION_TEXTURE3D=6]="DDS_DIMENSION_TEXTURE3D",r))(Tf||{});function at(r){return r.charCodeAt(0)+(r.charCodeAt(1)<<8)+(r.charCodeAt(2)<<16)+(r.charCodeAt(3)<<24)}var bt=(r=>(r[r.UNKNOWN=0]="UNKNOWN",r[r.R8G8B8=20]="R8G8B8",r[r.A8R8G8B8=21]="A8R8G8B8",r[r.X8R8G8B8=22]="X8R8G8B8",r[r.R5G6B5=23]="R5G6B5",r[r.X1R5G5B5=24]="X1R5G5B5",r[r.A1R5G5B5=25]="A1R5G5B5",r[r.A4R4G4B4=26]="A4R4G4B4",r[r.R3G3B2=27]="R3G3B2",r[r.A8=28]="A8",r[r.A8R3G3B2=29]="A8R3G3B2",r[r.X4R4G4B4=30]="X4R4G4B4",r[r.A2B10G10R10=31]="A2B10G10R10",r[r.A8B8G8R8=32]="A8B8G8R8",r[r.X8B8G8R8=33]="X8B8G8R8",r[r.G16R16=34]="G16R16",r[r.A2R10G10B10=35]="A2R10G10B10",r[r.A16B16G16R16=36]="A16B16G16R16",r[r.A8P8=40]="A8P8",r[r.P8=41]="P8",r[r.L8=50]="L8",r[r.A8L8=51]="A8L8",r[r.A4L4=52]="A4L4",r[r.V8U8=60]="V8U8",r[r.L6V5U5=61]="L6V5U5",r[r.X8L8V8U8=62]="X8L8V8U8",r[r.Q8W8V8U8=63]="Q8W8V8U8",r[r.V16U16=64]="V16U16",r[r.A2W10V10U10=67]="A2W10V10U10",r[r.Q16W16V16U16=110]="Q16W16V16U16",r[r.R16F=111]="R16F",r[r.G16R16F=112]="G16R16F",r[r.A16B16G16R16F=113]="A16B16G16R16F",r[r.R32F=114]="R32F",r[r.G32R32F=115]="G32R32F",r[r.A32B32G32R32F=116]="A32B32G32R32F",r[r.UYVY=at("UYVY")]="UYVY",r[r.R8G8_B8G8=at("RGBG")]="R8G8_B8G8",r[r.YUY2=at("YUY2")]="YUY2",r[r.D3DFMT_G8R8_G8B8=at("GRGB")]="D3DFMT_G8R8_G8B8",r[r.DXT1=at("DXT1")]="DXT1",r[r.DXT2=at("DXT2")]="DXT2",r[r.DXT3=at("DXT3")]="DXT3",r[r.DXT4=at("DXT4")]="DXT4",r[r.DXT5=at("DXT5")]="DXT5",r[r.ATI1=at("ATI1")]="ATI1",r[r.AT1N=at("AT1N")]="AT1N",r[r.ATI2=at("ATI2")]="ATI2",r[r.AT2N=at("AT2N")]="AT2N",r[r.BC4U=at("BC4U")]="BC4U",r[r.BC4S=at("BC4S")]="BC4S",r[r.BC5U=at("BC5U")]="BC5U",r[r.BC5S=at("BC5S")]="BC5S",r[r.DX10=at("DX10")]="DX10",r))(bt||{});const la={[bt.DXT1]:"bc1-rgba-unorm",[bt.DXT2]:"bc2-rgba-unorm",[bt.DXT3]:"bc2-rgba-unorm",[bt.DXT4]:"bc3-rgba-unorm",[bt.DXT5]:"bc3-rgba-unorm",[bt.ATI1]:"bc4-r-unorm",[bt.BC4U]:"bc4-r-unorm",[bt.BC4S]:"bc4-r-snorm",[bt.ATI2]:"bc5-rg-unorm",[bt.BC5U]:"bc5-rg-unorm",[bt.BC5S]:"bc5-rg-snorm",36:"rgba16uint",110:"rgba16sint",111:"r16float",112:"rg16float",113:"rgba16float",114:"r32float",115:"rg32float",116:"rgba32float"},ft={70:"bc1-rgba-unorm",71:"bc1-rgba-unorm",72:"bc1-rgba-unorm-srgb",73:"bc2-rgba-unorm",74:"bc2-rgba-unorm",75:"bc2-rgba-unorm-srgb",76:"bc3-rgba-unorm",77:"bc3-rgba-unorm",78:"bc3-rgba-unorm-srgb",79:"bc4-r-unorm",80:"bc4-r-unorm",81:"bc4-r-snorm",82:"bc5-rg-unorm",83:"bc5-rg-unorm",84:"bc5-rg-snorm",94:"bc6h-rgb-ufloat",95:"bc6h-rgb-ufloat",96:"bc6h-rgb-float",97:"bc7-rgba-unorm",98:"bc7-rgba-unorm",99:"bc7-rgba-unorm-srgb",28:"rgba8unorm",29:"rgba8unorm-srgb",87:"bgra8unorm",91:"bgra8unorm-srgb",41:"r32float",49:"rg8unorm",56:"r16uint",61:"r8unorm",24:"rgb10a2unorm",11:"rgba16uint",13:"rgba16sint",10:"rgba16float",54:"r16float",34:"rg16float",16:"rg32float",2:"rgba32float"},I={MAGIC_VALUE:542327876,MAGIC_SIZE:4,HEADER_SIZE:124,HEADER_DX10_SIZE:20,PIXEL_FORMAT_FLAGS:{ALPHAPIXELS:1,ALPHA:2,FOURCC:4,RGB:64,RGBA:65,YUV:512,LUMINANCE:131072,LUMINANCEA:131073},RESOURCE_MISC_TEXTURECUBE:4,HEADER_FIELDS:Z1,HEADER_DX10_FIELDS:Q1,DXGI_FORMAT:yf,D3D10_RESOURCE_DIMENSION:Tf,D3DFMT:bt},Sf={"bc1-rgba-unorm":8,"bc1-rgba-unorm-srgb":8,"bc2-rgba-unorm":16,"bc2-rgba-unorm-srgb":16,"bc3-rgba-unorm":16,"bc3-rgba-unorm-srgb":16,"bc4-r-unorm":8,"bc4-r-snorm":8,"bc5-rg-unorm":16,"bc5-rg-snorm":16,"bc6h-rgb-ufloat":16,"bc6h-rgb-float":16,"bc7-rgba-unorm":16,"bc7-rgba-unorm-srgb":16};function Ef(r,t){const{format:e,fourCC:s,width:i,height:n,dataOffset:o,mipmapCount:a}=tT(r);if(!t.includes(e))throw new Error(`Unsupported texture format: ${s} ${e}, supported: ${t}`);if(a<=1)return{format:e,width:i,height:n,resource:[new Uint8Array(r,o)],alphaMode:"no-premultiply-alpha"};const u=J1(e,i,n,o,a,r);return{format:e,width:i,height:n,resource:u,alphaMode:"no-premultiply-alpha"}}function J1(r,t,e,s,i,n){const o=[],a=Sf[r];let u=t,l=e,h=s;for(let c=0;c>1,1),l=Math.max(l>>1,1)}return o}function tT(r){const t=new Uint32Array(r,0,I.HEADER_SIZE/Uint32Array.BYTES_PER_ELEMENT);if(t[I.HEADER_FIELDS.MAGIC]!==I.MAGIC_VALUE)throw new Error("Invalid magic number in DDS header");const e=t[I.HEADER_FIELDS.HEIGHT],s=t[I.HEADER_FIELDS.WIDTH],i=Math.max(1,t[I.HEADER_FIELDS.MIPMAP_COUNT]),n=t[I.HEADER_FIELDS.PF_FLAGS],o=t[I.HEADER_FIELDS.FOURCC],a=eT(t,n,o,r),u=I.MAGIC_SIZE+I.HEADER_SIZE+(o===I.D3DFMT.DX10?I.HEADER_DX10_SIZE:0);return{format:a,fourCC:o,width:s,height:e,dataOffset:u,mipmapCount:i}}function eT(r,t,e,s){if(t&I.PIXEL_FORMAT_FLAGS.FOURCC){if(e===I.D3DFMT.DX10){const i=new Uint32Array(s,I.MAGIC_SIZE+I.HEADER_SIZE,I.HEADER_DX10_SIZE/Uint32Array.BYTES_PER_ELEMENT);if(i[I.HEADER_DX10_FIELDS.MISC_FLAG]===I.RESOURCE_MISC_TEXTURECUBE)throw new Error("DDSParser does not support cubemap textures");if(i[I.HEADER_DX10_FIELDS.RESOURCE_DIMENSION]===I.D3D10_RESOURCE_DIMENSION.DDS_DIMENSION_TEXTURE3D)throw new Error("DDSParser does not supported 3D texture data");const n=i[I.HEADER_DX10_FIELDS.DXGI_FORMAT];if(n in ft)return ft[n];throw new Error(`DDSParser cannot parse texture data with DXGI format ${n}`)}if(e in la)return la[e];throw new Error(`DDSParser cannot parse texture data with fourCC format ${e}`)}if(t&I.PIXEL_FORMAT_FLAGS.RGB||t&I.PIXEL_FORMAT_FLAGS.RGBA)return rT(r);throw t&I.PIXEL_FORMAT_FLAGS.YUV?new Error("DDSParser does not supported YUV uncompressed texture data."):t&I.PIXEL_FORMAT_FLAGS.LUMINANCE||t&I.PIXEL_FORMAT_FLAGS.LUMINANCEA?new Error("DDSParser does not support single-channel (lumninance) texture data!"):t&I.PIXEL_FORMAT_FLAGS.ALPHA||t&I.PIXEL_FORMAT_FLAGS.ALPHAPIXELS?new Error("DDSParser does not support single-channel (alpha) texture data!"):new Error("DDSParser failed to load a texture file due to an unknown reason!")}function rT(r){const t=r[I.HEADER_FIELDS.RGB_BITCOUNT],e=r[I.HEADER_FIELDS.R_BIT_MASK],s=r[I.HEADER_FIELDS.G_BIT_MASK],i=r[I.HEADER_FIELDS.B_BIT_MASK],n=r[I.HEADER_FIELDS.A_BIT_MASK];switch(t){case 32:if(e===255&&s===65280&&i===16711680&&n===4278190080)return ft[I.DXGI_FORMAT.DXGI_FORMAT_R8G8B8A8_UNORM];if(e===16711680&&s===65280&&i===255&&n===4278190080)return ft[I.DXGI_FORMAT.DXGI_FORMAT_B8G8R8A8_UNORM];if(e===1072693248&&s===1047552&&i===1023&&n===3221225472)return ft[I.DXGI_FORMAT.DXGI_FORMAT_R10G10B10A2_UNORM];if(e===65535&&s===4294901760&&i===0&&n===0)return ft[I.DXGI_FORMAT.DXGI_FORMAT_R16G16_UNORM];if(e===4294967295&&s===0&&i===0&&n===0)return ft[I.DXGI_FORMAT.DXGI_FORMAT_R32_FLOAT];break;case 24:break;case 16:if(e===31744&&s===992&&i===31&&n===32768)return ft[I.DXGI_FORMAT.DXGI_FORMAT_B5G5R5A1_UNORM];if(e===63488&&s===2016&&i===31&&n===0)return ft[I.DXGI_FORMAT.DXGI_FORMAT_B5G6R5_UNORM];if(e===3840&&s===240&&i===15&&n===61440)return ft[I.DXGI_FORMAT.DXGI_FORMAT_B4G4R4A4_UNORM];if(e===255&&s===0&&i===0&&n===65280)return ft[I.DXGI_FORMAT.DXGI_FORMAT_R8G8_UNORM];if(e===65535&&s===0&&i===0&&n===0)return ft[I.DXGI_FORMAT.DXGI_FORMAT_R16_UNORM];break;case 8:if(e===255&&s===0&&i===0&&n===0)return ft[I.DXGI_FORMAT.DXGI_FORMAT_R8_UNORM];break}throw new Error(`DDSParser does not support uncompressed texture with configuration: - bitCount = ${t}, rBitMask = ${e}, gBitMask = ${s}, aBitMask = ${n}`)}const sT={extension:{type:v.LoadParser,priority:gt.High},name:"loadDDS",test(r){return Mt(r,[".dds"])},async load(r,t,e){const s=await Dr(),i=await(await fetch(r)).arrayBuffer(),n=Ef(i,s),o=new Fr(n);return ee(o,e,r)},unload(r){Array.isArray(r)?r.forEach(t=>t.destroy(!0)):r.destroy(!0)}};var Af=(r=>(r[r.RGBA8_SNORM=36759]="RGBA8_SNORM",r[r.RGBA=6408]="RGBA",r[r.RGBA8UI=36220]="RGBA8UI",r[r.SRGB8_ALPHA8=35907]="SRGB8_ALPHA8",r[r.RGBA8I=36238]="RGBA8I",r[r.RGBA8=32856]="RGBA8",r[r.COMPRESSED_RGB_S3TC_DXT1_EXT=33776]="COMPRESSED_RGB_S3TC_DXT1_EXT",r[r.COMPRESSED_RGBA_S3TC_DXT1_EXT=33777]="COMPRESSED_RGBA_S3TC_DXT1_EXT",r[r.COMPRESSED_RGBA_S3TC_DXT3_EXT=33778]="COMPRESSED_RGBA_S3TC_DXT3_EXT",r[r.COMPRESSED_RGBA_S3TC_DXT5_EXT=33779]="COMPRESSED_RGBA_S3TC_DXT5_EXT",r[r.COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT=35917]="COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT",r[r.COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT=35918]="COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT",r[r.COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT=35919]="COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT",r[r.COMPRESSED_SRGB_S3TC_DXT1_EXT=35916]="COMPRESSED_SRGB_S3TC_DXT1_EXT",r[r.COMPRESSED_RED_RGTC1_EXT=36283]="COMPRESSED_RED_RGTC1_EXT",r[r.COMPRESSED_SIGNED_RED_RGTC1_EXT=36284]="COMPRESSED_SIGNED_RED_RGTC1_EXT",r[r.COMPRESSED_RED_GREEN_RGTC2_EXT=36285]="COMPRESSED_RED_GREEN_RGTC2_EXT",r[r.COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT=36286]="COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT",r[r.COMPRESSED_R11_EAC=37488]="COMPRESSED_R11_EAC",r[r.COMPRESSED_SIGNED_R11_EAC=37489]="COMPRESSED_SIGNED_R11_EAC",r[r.COMPRESSED_RG11_EAC=37490]="COMPRESSED_RG11_EAC",r[r.COMPRESSED_SIGNED_RG11_EAC=37491]="COMPRESSED_SIGNED_RG11_EAC",r[r.COMPRESSED_RGB8_ETC2=37492]="COMPRESSED_RGB8_ETC2",r[r.COMPRESSED_RGBA8_ETC2_EAC=37496]="COMPRESSED_RGBA8_ETC2_EAC",r[r.COMPRESSED_SRGB8_ETC2=37493]="COMPRESSED_SRGB8_ETC2",r[r.COMPRESSED_SRGB8_ALPHA8_ETC2_EAC=37497]="COMPRESSED_SRGB8_ALPHA8_ETC2_EAC",r[r.COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2=37494]="COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2",r[r.COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2=37495]="COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2",r[r.COMPRESSED_RGBA_ASTC_4x4_KHR=37808]="COMPRESSED_RGBA_ASTC_4x4_KHR",r[r.COMPRESSED_RGBA_ASTC_5x4_KHR=37809]="COMPRESSED_RGBA_ASTC_5x4_KHR",r[r.COMPRESSED_RGBA_ASTC_5x5_KHR=37810]="COMPRESSED_RGBA_ASTC_5x5_KHR",r[r.COMPRESSED_RGBA_ASTC_6x5_KHR=37811]="COMPRESSED_RGBA_ASTC_6x5_KHR",r[r.COMPRESSED_RGBA_ASTC_6x6_KHR=37812]="COMPRESSED_RGBA_ASTC_6x6_KHR",r[r.COMPRESSED_RGBA_ASTC_8x5_KHR=37813]="COMPRESSED_RGBA_ASTC_8x5_KHR",r[r.COMPRESSED_RGBA_ASTC_8x6_KHR=37814]="COMPRESSED_RGBA_ASTC_8x6_KHR",r[r.COMPRESSED_RGBA_ASTC_8x8_KHR=37815]="COMPRESSED_RGBA_ASTC_8x8_KHR",r[r.COMPRESSED_RGBA_ASTC_10x5_KHR=37816]="COMPRESSED_RGBA_ASTC_10x5_KHR",r[r.COMPRESSED_RGBA_ASTC_10x6_KHR=37817]="COMPRESSED_RGBA_ASTC_10x6_KHR",r[r.COMPRESSED_RGBA_ASTC_10x8_KHR=37818]="COMPRESSED_RGBA_ASTC_10x8_KHR",r[r.COMPRESSED_RGBA_ASTC_10x10_KHR=37819]="COMPRESSED_RGBA_ASTC_10x10_KHR",r[r.COMPRESSED_RGBA_ASTC_12x10_KHR=37820]="COMPRESSED_RGBA_ASTC_12x10_KHR",r[r.COMPRESSED_RGBA_ASTC_12x12_KHR=37821]="COMPRESSED_RGBA_ASTC_12x12_KHR",r[r.COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR=37840]="COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR",r[r.COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR=37841]="COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR",r[r.COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR=37842]="COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR",r[r.COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR=37843]="COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR",r[r.COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR=37844]="COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR",r[r.COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR=37845]="COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR",r[r.COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR=37846]="COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR",r[r.COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR=37847]="COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR",r[r.COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR=37848]="COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR",r[r.COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR=37849]="COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR",r[r.COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR=37850]="COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR",r[r.COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR=37851]="COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR",r[r.COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR=37852]="COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR",r[r.COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR=37853]="COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR",r[r.COMPRESSED_RGBA_BPTC_UNORM_EXT=36492]="COMPRESSED_RGBA_BPTC_UNORM_EXT",r[r.COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT=36493]="COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT",r[r.COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT=36494]="COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT",r[r.COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT=36495]="COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT",r))(Af||{}),iT=(r=>(r[r.RGBA=6408]="RGBA",r[r.RGB=6407]="RGB",r[r.RG=33319]="RG",r[r.RED=6403]="RED",r[r.RGBA_INTEGER=36249]="RGBA_INTEGER",r[r.RGB_INTEGER=36248]="RGB_INTEGER",r[r.RG_INTEGER=33320]="RG_INTEGER",r[r.RED_INTEGER=36244]="RED_INTEGER",r[r.ALPHA=6406]="ALPHA",r[r.LUMINANCE=6409]="LUMINANCE",r[r.LUMINANCE_ALPHA=6410]="LUMINANCE_ALPHA",r[r.DEPTH_COMPONENT=6402]="DEPTH_COMPONENT",r[r.DEPTH_STENCIL=34041]="DEPTH_STENCIL",r))(iT||{}),nT=(r=>(r[r.UNSIGNED_BYTE=5121]="UNSIGNED_BYTE",r[r.UNSIGNED_SHORT=5123]="UNSIGNED_SHORT",r[r.UNSIGNED_SHORT_5_6_5=33635]="UNSIGNED_SHORT_5_6_5",r[r.UNSIGNED_SHORT_4_4_4_4=32819]="UNSIGNED_SHORT_4_4_4_4",r[r.UNSIGNED_SHORT_5_5_5_1=32820]="UNSIGNED_SHORT_5_5_5_1",r[r.UNSIGNED_INT=5125]="UNSIGNED_INT",r[r.UNSIGNED_INT_10F_11F_11F_REV=35899]="UNSIGNED_INT_10F_11F_11F_REV",r[r.UNSIGNED_INT_2_10_10_10_REV=33640]="UNSIGNED_INT_2_10_10_10_REV",r[r.UNSIGNED_INT_24_8=34042]="UNSIGNED_INT_24_8",r[r.UNSIGNED_INT_5_9_9_9_REV=35902]="UNSIGNED_INT_5_9_9_9_REV",r[r.BYTE=5120]="BYTE",r[r.SHORT=5122]="SHORT",r[r.INT=5124]="INT",r[r.FLOAT=5126]="FLOAT",r[r.FLOAT_32_UNSIGNED_INT_24_8_REV=36269]="FLOAT_32_UNSIGNED_INT_24_8_REV",r[r.HALF_FLOAT=36193]="HALF_FLOAT",r))(nT||{});const oT={33776:"bc1-rgba-unorm",33777:"bc1-rgba-unorm",33778:"bc2-rgba-unorm",33779:"bc3-rgba-unorm",35916:"bc1-rgba-unorm-srgb",35917:"bc1-rgba-unorm-srgb",35918:"bc2-rgba-unorm-srgb",35919:"bc3-rgba-unorm-srgb",36283:"bc4-r-unorm",36284:"bc4-r-snorm",36285:"bc5-rg-unorm",36286:"bc5-rg-snorm",37488:"eac-r11unorm",37490:"eac-rg11snorm",37492:"etc2-rgb8unorm",37496:"etc2-rgba8unorm",37493:"etc2-rgb8unorm-srgb",37497:"etc2-rgba8unorm-srgb",37494:"etc2-rgb8a1unorm",37495:"etc2-rgb8a1unorm-srgb",37808:"astc-4x4-unorm",37840:"astc-4x4-unorm-srgb",37809:"astc-5x4-unorm",37841:"astc-5x4-unorm-srgb",37810:"astc-5x5-unorm",37842:"astc-5x5-unorm-srgb",37811:"astc-6x5-unorm",37843:"astc-6x5-unorm-srgb",37812:"astc-6x6-unorm",37844:"astc-6x6-unorm-srgb",37813:"astc-8x5-unorm",37845:"astc-8x5-unorm-srgb",37814:"astc-8x6-unorm",37846:"astc-8x6-unorm-srgb",37815:"astc-8x8-unorm",37847:"astc-8x8-unorm-srgb",37816:"astc-10x5-unorm",37848:"astc-10x5-unorm-srgb",37817:"astc-10x6-unorm",37849:"astc-10x6-unorm-srgb",37818:"astc-10x8-unorm",37850:"astc-10x8-unorm-srgb",37819:"astc-10x10-unorm",37851:"astc-10x10-unorm-srgb",37820:"astc-12x10-unorm",37852:"astc-12x10-unorm-srgb",37821:"astc-12x12-unorm",37853:"astc-12x12-unorm-srgb",36492:"bc7-rgba-unorm",36493:"bc7-rgba-unorm-srgb",36494:"bc6h-rgb-float",36495:"bc6h-rgb-ufloat",35907:"rgba8unorm-srgb",36759:"rgba8snorm",36220:"rgba8uint",36238:"rgba8sint",6408:"rgba8unorm"},aT=[171,75,84,88,32,49,49,187,13,10,26,10],uT={FILE_IDENTIFIER:0,ENDIANNESS:12,GL_TYPE:16,GL_TYPE_SIZE:20,GL_FORMAT:24,GL_INTERNAL_FORMAT:28,GL_BASE_INTERNAL_FORMAT:32,PIXEL_WIDTH:36,PIXEL_HEIGHT:40,PIXEL_DEPTH:44,NUMBER_OF_ARRAY_ELEMENTS:48,NUMBER_OF_FACES:52,NUMBER_OF_MIPMAP_LEVELS:56,BYTES_OF_KEY_VALUE_DATA:60},lT=64,hT=67305985,cT={5121:1,5123:2,5124:4,5125:4,5126:4,36193:8},dT={6408:4,6407:3,33319:2,6403:1,6409:1,6410:2,6406:1},pT={32819:2,32820:2,33635:2},fT={33776:.5,33777:.5,33778:1,33779:1,35916:.5,35917:.5,35918:1,35919:1,36283:.5,36284:.5,36285:1,36286:1,37488:.5,37489:.5,37490:1,37491:1,37492:.5,37496:1,37493:.5,37497:1,37494:.5,37495:.5,37808:1,37840:1,37809:.8,37841:.8,37810:.64,37842:.64,37811:.53375,37843:.53375,37812:.445,37844:.445,37813:.4,37845:.4,37814:.33375,37846:.33375,37815:.25,37847:.25,37816:.32,37848:.32,37817:.26625,37849:.26625,37818:.2,37850:.2,37819:.16,37851:.16,37820:.13375,37852:.13375,37821:.11125,37853:.11125,36492:1,36493:1,36494:1,36495:1},tt={FILE_HEADER_SIZE:lT,FILE_IDENTIFIER:aT,FORMATS_TO_COMPONENTS:dT,INTERNAL_FORMAT_TO_BYTES_PER_PIXEL:fT,INTERNAL_FORMAT_TO_TEXTURE_FORMATS:oT,FIELDS:uT,TYPES_TO_BYTES_PER_COMPONENT:cT,TYPES_TO_BYTES_PER_PIXEL:pT,ENDIANNESS:hT};function Pf(r,t){const e=new DataView(r);if(!xT(e))throw new Error("Invalid KTX identifier in header");const{littleEndian:s,glType:i,glFormat:n,glInternalFormat:o,pixelWidth:a,pixelHeight:u,numberOfMipmapLevels:l,offset:h}=_T(e),c=tt.INTERNAL_FORMAT_TO_TEXTURE_FORMATS[o];if(!c)throw new Error(`Unknown texture format ${o}`);if(!t.includes(c))throw new Error(`Unsupported texture format: ${c}, supportedFormats: ${t}`);const d=gT(i,n,o),p=mT(e,i,d,a,u,h,l,s);return{format:c,width:a,height:u,resource:p,alphaMode:"no-premultiply-alpha"}}function mT(r,t,e,s,i,n,o,a){const u=s+3&-4,l=i+3&-4;let h=s*i;t===0&&(h=u*l);let c=h*e,d=s,p=i,f=u,g=l,m=n;const _=new Array(o);for(let x=0;x>1||1,p=p>>1||1,f=d+4-1&-4,g=p+4-1&-4,c=f*g*e}return _}function gT(r,t,e){let s=tt.INTERNAL_FORMAT_TO_BYTES_PER_PIXEL[e];if(r!==0&&(tt.TYPES_TO_BYTES_PER_COMPONENT[r]?s=tt.TYPES_TO_BYTES_PER_COMPONENT[r]*tt.FORMATS_TO_COMPONENTS[t]:s=tt.TYPES_TO_BYTES_PER_PIXEL[r]),s===void 0)throw new Error("Unable to resolve the pixel format stored in the *.ktx file!");return s}function _T(r){const t=r.getUint32(tt.FIELDS.ENDIANNESS,!0)===tt.ENDIANNESS,e=r.getUint32(tt.FIELDS.GL_TYPE,t),s=r.getUint32(tt.FIELDS.GL_FORMAT,t),i=r.getUint32(tt.FIELDS.GL_INTERNAL_FORMAT,t),n=r.getUint32(tt.FIELDS.PIXEL_WIDTH,t),o=r.getUint32(tt.FIELDS.PIXEL_HEIGHT,t)||1,a=r.getUint32(tt.FIELDS.PIXEL_DEPTH,t)||1,u=r.getUint32(tt.FIELDS.NUMBER_OF_ARRAY_ELEMENTS,t)||1,l=r.getUint32(tt.FIELDS.NUMBER_OF_FACES,t),h=r.getUint32(tt.FIELDS.NUMBER_OF_MIPMAP_LEVELS,t),c=r.getUint32(tt.FIELDS.BYTES_OF_KEY_VALUE_DATA,t);if(o===0||a!==1)throw new Error("Only 2D textures are supported");if(l!==1)throw new Error("CubeTextures are not supported by KTXLoader yet!");if(u!==1)throw new Error("WebGL does not support array textures");return{littleEndian:t,glType:e,glFormat:s,glInternalFormat:i,pixelWidth:n,pixelHeight:o,numberOfMipmapLevels:h,offset:tt.FILE_HEADER_SIZE+c}}function xT(r){for(let t=0;tt.destroy(!0)):r.destroy(!0)}},vT='(function(){"use strict";const s={rgb8unorm:{convertedFormat:"rgba8unorm",convertFunction:i},"rgb8unorm-srgb":{convertedFormat:"rgba8unorm-srgb",convertFunction:i}};function f(r){const t=r.format;if(s[t]){const n=s[t].convertFunction,o=r.resource;for(let e=0;e{LIBKTX({locateFile:o=>t}).then(o=>{n(o)})})}return c}async function v(r,t){const n=await fetch(r);if(n.ok){const o=await n.arrayBuffer();return new t.ktxTexture(new Uint8Array(o))}throw new Error(`Failed to load KTX(2) texture: ${r}`)}const x=["bc7-rgba-unorm","astc-4x4-unorm","etc2-rgba8unorm","bc3-rgba-unorm","rgba8unorm"];async function B(r){const t=await g(),n=await v(r,t);let o;if(n.needsTranscoding){o=u;const R=t.TranscodeTarget[l];if(n.transcodeBasis(R,0)!==t.ErrorCode.SUCCESS)throw new Error("Unable to transcode basis texture.")}else o=U(n);const e=d(n),b={width:n.baseWidth,height:n.baseHeight,format:o,mipLevelCount:n.numLevels,resource:e,alphaMode:"no-premultiply-alpha"};return f(b),b}async function A(r,t,n){r&&(a.jsUrl=r),t&&(a.wasmUrl=t),u=x.filter(o=>n.includes(o))[0],l=y(u),await g()}const m={init:async r=>{const{jsUrl:t,wasmUrl:n,supportedTextures:o}=r;await A(t,n,o)},load:async r=>{var t;try{const n=await B(r.url);return{type:"load",url:r.url,success:!0,textureOptions:n,transferables:(t=n.resource)==null?void 0:t.map(o=>o.buffer)}}catch(n){throw n}}};self.onmessage=async r=>{var t;const n=r.data,o=await((t=m[n.type])==null?void 0:t.call(m,n));o&&self.postMessage(o,o.transferables)}})();\n';let je=null;class wf{constructor(){je||(je=URL.createObjectURL(new Blob([vT],{type:"application/javascript"}))),this.worker=new Worker(je)}}wf.revokeObjectURL=function(){je&&(URL.revokeObjectURL(je),je=null)};const ti={jsUrl:"https://files.pixijs.download/transcoders/ktx/libktx.js",wasmUrl:"https://files.pixijs.download/transcoders/ktx/libktx.wasm"};function yT(r){Object.assign(ti,r)}let kr;const Rf={};function TT(r){return kr||(kr=new wf().worker,kr.onmessage=t=>{const{success:e,url:s,textureOptions:i}=t.data;e||console.warn("Failed to load KTX texture",s),Rf[s](i)},kr.postMessage({type:"init",jsUrl:ti.jsUrl,wasmUrl:ti.wasmUrl,supportedTextures:r})),kr}function Mf(r,t){const e=TT(t);return new Promise(s=>{Rf[r]=s,e.postMessage({type:"load",url:r})})}const ST={extension:{type:v.LoadParser,priority:gt.High},name:"loadKTX2",test(r){return Mt(r,".ktx2")},async load(r,t,e){const s=await Dr(),i=await Mf(r,s),n=new Fr(i);return ee(n,e,r)},unload(r){Array.isArray(r)?r.forEach(t=>t.destroy(!0)):r.destroy(!0)}},ha={rgb8unorm:{convertedFormat:"rgba8unorm",convertFunction:Of},"rgb8unorm-srgb":{convertedFormat:"rgba8unorm-srgb",convertFunction:Of}};function ET(r){const t=r.format;if(ha[t]){const e=ha[t].convertFunction,s=r.resource;for(let i=0;iMt(r,[".ktx",".ktx2",".dds"]),parse:r=>{var t,e;let s;const i=r.split(".");if(i.length>2){const n=i[i.length-2];ei.includes(n)&&(s=n)}else s=i[i.length-1];return{resolution:parseFloat((e=(t=qt.RETINA_PREFIX.exec(r))==null?void 0:t[1])!=null?e:"1"),format:s,src:r}}};let ri;const GT={extension:{type:v.DetectionParser,priority:2},test:async()=>!!(await Gr()||Cr()),add:async r=>{const t=await ua();return ri=IT(t),[...ri,...r]},remove:async r=>ri?r.filter(t=>!(t in ri)):r};function IT(r){const t=["basis"],e={};return r.forEach(s=>{const i=s.split("-")[0];i&&!e[i]&&(e[i]=!0,t.push(i))}),t.sort((s,i)=>{const n=ei.indexOf(s),o=ei.indexOf(i);return n===-1?1:o===-1?-1:n-o}),t}const BT=new lt,ca=class{cull(t,e,s=!0){this._cullRecursive(t,e,s)}_cullRecursive(t,e,s=!0){var i;if(t.cullable&&t.measurable&&t.includeInBuild){const n=(i=t.cullArea)!=null?i:nr(t,s,BT);t.culled=!(n.x>=e.x+e.width||n.y>=e.y+e.height||n.x+n.width<=e.x||n.y+n.height<=e.y)}if(!(!t.cullableChildren||t.culled||!t.renderable||!t.measurable||!t.includeInBuild))for(let n=0;n{If.shared.cull(this.stage,this.renderer.screen),this.renderer.render({container:this.stage})}}static destroy(){this.render=this._renderRef}}Bf.extension={priority:10,type:v.Application,name:"culler"};const FT={extension:{type:v.Environment,name:"browser",priority:-1},test:()=>!0,load:async()=>{await Promise.resolve().then(function(){return ky})}};var DT=Object.defineProperty,si=Object.getOwnPropertySymbols,Ff=Object.prototype.hasOwnProperty,Df=Object.prototype.propertyIsEnumerable,Uf=(r,t,e)=>t in r?DT(r,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):r[t]=e,da=(r,t)=>{for(var e in t||(t={}))Ff.call(t,e)&&Uf(r,e,t[e]);if(si)for(var e of si(t))Df.call(t,e)&&Uf(r,e,t[e]);return r},UT=(r,t)=>{var e={};for(var s in r)Ff.call(r,s)&&t.indexOf(s)<0&&(e[s]=r[s]);if(r!=null&&si)for(var s of si(r))t.indexOf(s)<0&&Df.call(r,s)&&(e[s]=r[s]);return e};const kf=class qu extends St{constructor(t){t=da(da({},qu.defaultOptions),t),super(t),this.enabled=!0,this._state=Ct.for2d(),this.padding=t.padding,typeof t.antialias=="boolean"?this.antialias=t.antialias?"on":"off":this.antialias=t.antialias,this.resolution=t.resolution,this.blendRequired=t.blendRequired,this.addResource("uTexture",0,1)}apply(t,e,s,i){t.applyFilter(this,e,s,i)}get blendMode(){return this._state.blendMode}set blendMode(t){this._state.blendMode=t}static from(t){const e=t,{gpu:s,gl:i}=e,n=UT(e,["gpu","gl"]);let o,a;return s&&(o=Tt.from(s)),i&&(a=Rt.from(i)),new qu(da({gpuProgram:o,glProgram:a},n))}};kf.defaultOptions={blendMode:"normal",resolution:1,padding:0,antialias:"off",blendRequired:!1};let Yt=kf;var Lf=` -in vec2 vTextureCoord; -in vec4 vColor; - -out vec4 finalColor; - -uniform float uBlend; - -uniform sampler2D uTexture; -uniform sampler2D uBackTexture; - -{FUNCTIONS} - -void main() -{ - vec4 back = texture(uBackTexture, vTextureCoord); - vec4 front = texture(uTexture, vTextureCoord); - - {MAIN} -} -`,$f=`in vec2 aPosition; -out vec2 vTextureCoord; -out vec2 backgroundUv; - -uniform vec4 uInputSize; -uniform vec4 uOutputFrame; -uniform vec4 uOutputTexture; - -vec4 filterVertexPosition( void ) -{ - vec2 position = aPosition * uOutputFrame.zw + uOutputFrame.xy; - - position.x = position.x * (2.0 / uOutputTexture.x) - 1.0; - position.y = position.y * (2.0*uOutputTexture.z / uOutputTexture.y) - uOutputTexture.z; - - return vec4(position, 0.0, 1.0); -} - -vec2 filterTextureCoord( void ) -{ - return aPosition * (uOutputFrame.zw * uInputSize.zw); -} - -void main(void) -{ - gl_Position = filterVertexPosition(); - vTextureCoord = filterTextureCoord(); -} -`,Nf=` -struct GlobalFilterUniforms { - uInputSize:vec4, - uInputPixel:vec4, - uInputClamp:vec4, - uOutputFrame:vec4, - uGlobalFrame:vec4, - uOutputTexture:vec4, + ` + ) + } }; -struct BlendUniforms { - uBlend:f32, +"use strict"; +let gpuProgram; +let glProgram; +class TilingSpriteShader extends Shader { + constructor() { + gpuProgram != null ? gpuProgram : gpuProgram = compileHighShaderGpuProgram({ + name: "tiling-sprite-shader", + bits: [ + localUniformBit, + tilingBit, + roundPixelsBit + ] + }); + glProgram != null ? glProgram : glProgram = compileHighShaderGlProgram({ + name: "tiling-sprite-shader", + bits: [ + localUniformBitGl, + tilingBitGl, + roundPixelsBitGl + ] + }); + const tilingUniforms = new UniformGroup({ + uMapCoord: { value: new Matrix(), type: "mat3x3" }, + uClampFrame: { value: new Float32Array([0, 0, 1, 1]), type: "vec4" }, + uClampOffset: { value: new Float32Array([0, 0]), type: "vec2" }, + uTextureTransform: { value: new Matrix(), type: "mat3x3" }, + uSizeAnchor: { value: new Float32Array([100, 100, 0.5, 0.5]), type: "vec4" } + }); + super({ + glProgram, + gpuProgram, + resources: { + localUniforms: new UniformGroup({ + uTransformMatrix: { value: new Matrix(), type: "mat3x3" }, + uColor: { value: new Float32Array([1, 1, 1, 1]), type: "vec4" }, + uRound: { value: 0, type: "f32" } + }), + tilingUniforms, + uTexture: Texture.EMPTY.source, + uSampler: Texture.EMPTY.source.style + } + }); + } + updateUniforms(width, height, matrix, anchorX, anchorY, texture) { + const tilingUniforms = this.resources.tilingUniforms; + const textureWidth = texture.width; + const textureHeight = texture.height; + const textureMatrix = texture.textureMatrix; + const uTextureTransform = tilingUniforms.uniforms.uTextureTransform; + uTextureTransform.set( + matrix.a * textureWidth / width, + matrix.b * textureWidth / height, + matrix.c * textureHeight / width, + matrix.d * textureHeight / height, + matrix.tx / width, + matrix.ty / height + ); + uTextureTransform.invert(); + tilingUniforms.uniforms.uMapCoord = textureMatrix.mapCoord; + tilingUniforms.uniforms.uClampFrame = textureMatrix.uClampFrame; + tilingUniforms.uniforms.uClampOffset = textureMatrix.uClampOffset; + tilingUniforms.uniforms.uTextureTransform = uTextureTransform; + tilingUniforms.uniforms.uSizeAnchor[0] = width; + tilingUniforms.uniforms.uSizeAnchor[1] = height; + tilingUniforms.uniforms.uSizeAnchor[2] = anchorX; + tilingUniforms.uniforms.uSizeAnchor[3] = anchorY; + if (texture) { + this.resources.uTexture = texture.source; + this.resources.uSampler = texture.source.style; + } + } +} + +"use strict"; +class QuadGeometry extends MeshGeometry { + constructor() { + super({ + positions: new Float32Array([0, 0, 1, 0, 1, 1, 0, 1]), + uvs: new Float32Array([0, 0, 1, 0, 1, 1, 0, 1]), + indices: new Uint32Array([0, 1, 2, 0, 2, 3]) + }); + } +} + +"use strict"; +function setPositions(tilingSprite, positions) { + const anchorX = tilingSprite.anchor.x; + const anchorY = tilingSprite.anchor.y; + positions[0] = -anchorX * tilingSprite.width; + positions[1] = -anchorY * tilingSprite.height; + positions[2] = (1 - anchorX) * tilingSprite.width; + positions[3] = -anchorY * tilingSprite.height; + positions[4] = (1 - anchorX) * tilingSprite.width; + positions[5] = (1 - anchorY) * tilingSprite.height; + positions[6] = -anchorX * tilingSprite.width; + positions[7] = (1 - anchorY) * tilingSprite.height; +} + +"use strict"; +function applyMatrix(array, stride, offset, matrix) { + let index = 0; + const size = array.length / (stride || 2); + const a = matrix.a; + const b = matrix.b; + const c = matrix.c; + const d = matrix.d; + const tx = matrix.tx; + const ty = matrix.ty; + offset *= stride; + while (index < size) { + const x = array[offset]; + const y = array[offset + 1]; + array[offset] = a * x + c * y + tx; + array[offset + 1] = b * x + d * y + ty; + offset += stride; + index++; + } +} + +"use strict"; +function setUvs(tilingSprite, uvs) { + const texture = tilingSprite.texture; + const width = texture.frame.width; + const height = texture.frame.height; + let anchorX = 0; + let anchorY = 0; + if (tilingSprite._applyAnchorToTexture) { + anchorX = tilingSprite.anchor.x; + anchorY = tilingSprite.anchor.y; + } + uvs[0] = uvs[6] = -anchorX; + uvs[2] = uvs[4] = 1 - anchorX; + uvs[1] = uvs[3] = -anchorY; + uvs[5] = uvs[7] = 1 - anchorY; + const textureMatrix = Matrix.shared; + textureMatrix.copyFrom(tilingSprite._tileTransform.matrix); + textureMatrix.tx /= tilingSprite.width; + textureMatrix.ty /= tilingSprite.height; + textureMatrix.invert(); + textureMatrix.scale(tilingSprite.width / width, tilingSprite.height / height); + applyMatrix(uvs, 2, 0, textureMatrix); +} + +"use strict"; +const sharedQuad = new QuadGeometry(); +class TilingSpritePipe { + constructor(renderer) { + this._tilingSpriteDataHash = /* @__PURE__ */ Object.create(null); + this._renderer = renderer; + } + validateRenderable(renderable) { + const tilingSpriteData = this._getTilingSpriteData(renderable); + const couldBatch = tilingSpriteData.canBatch; + this._updateCanBatch(renderable); + const canBatch = tilingSpriteData.canBatch; + if (canBatch && canBatch === couldBatch) { + const { batchableMesh } = tilingSpriteData; + if (batchableMesh.texture._source !== renderable.texture._source) { + return !batchableMesh.batcher.checkAndUpdateTexture(batchableMesh, renderable.texture); + } + } + return couldBatch !== canBatch; + } + addRenderable(tilingSprite, instructionSet) { + const batcher = this._renderer.renderPipes.batch; + this._updateCanBatch(tilingSprite); + const tilingSpriteData = this._getTilingSpriteData(tilingSprite); + const { geometry, canBatch } = tilingSpriteData; + if (canBatch) { + tilingSpriteData.batchableMesh || (tilingSpriteData.batchableMesh = new BatchableMesh()); + const batchableMesh = tilingSpriteData.batchableMesh; + if (tilingSprite._didTilingSpriteUpdate) { + tilingSprite._didTilingSpriteUpdate = false; + this._updateBatchableMesh(tilingSprite); + batchableMesh.geometry = geometry; + batchableMesh.mesh = tilingSprite; + batchableMesh.texture = tilingSprite._texture; + } + batchableMesh.roundPixels = this._renderer._roundPixels | tilingSprite._roundPixels; + batcher.addToBatch(batchableMesh); + } else { + batcher.break(instructionSet); + tilingSpriteData.shader || (tilingSpriteData.shader = new TilingSpriteShader()); + this.updateRenderable(tilingSprite); + instructionSet.add(tilingSprite); + } + } + execute(tilingSprite) { + const { shader } = this._tilingSpriteDataHash[tilingSprite.uid]; + shader.groups[0] = this._renderer.globalUniforms.bindGroup; + const localUniforms = shader.resources.localUniforms.uniforms; + localUniforms.uTransformMatrix = tilingSprite.groupTransform; + localUniforms.uRound = this._renderer._roundPixels | tilingSprite._roundPixels; + color32BitToUniform( + tilingSprite.groupColorAlpha, + localUniforms.uColor, + 0 + ); + this._renderer.encoder.draw({ + geometry: sharedQuad, + shader, + state: State.default2d + }); + } + updateRenderable(tilingSprite) { + const tilingSpriteData = this._getTilingSpriteData(tilingSprite); + const { canBatch } = tilingSpriteData; + if (canBatch) { + const { batchableMesh } = tilingSpriteData; + if (tilingSprite._didTilingSpriteUpdate) + this._updateBatchableMesh(tilingSprite); + batchableMesh.batcher.updateElement(batchableMesh); + } else if (tilingSprite._didTilingSpriteUpdate) { + const { shader } = tilingSpriteData; + shader.updateUniforms( + tilingSprite.width, + tilingSprite.height, + tilingSprite._tileTransform.matrix, + tilingSprite.anchor.x, + tilingSprite.anchor.y, + tilingSprite.texture + ); + } + tilingSprite._didTilingSpriteUpdate = false; + } + destroyRenderable(tilingSprite) { + var _a; + const tilingSpriteData = this._getTilingSpriteData(tilingSprite); + tilingSpriteData.batchableMesh = null; + (_a = tilingSpriteData.shader) == null ? void 0 : _a.destroy(); + this._tilingSpriteDataHash[tilingSprite.uid] = null; + } + _getTilingSpriteData(renderable) { + return this._tilingSpriteDataHash[renderable.uid] || this._initTilingSpriteData(renderable); + } + _initTilingSpriteData(tilingSprite) { + const geometry = new MeshGeometry({ + indices: sharedQuad.indices, + positions: sharedQuad.positions.slice(), + uvs: sharedQuad.uvs.slice() + }); + this._tilingSpriteDataHash[tilingSprite.uid] = { + canBatch: true, + renderable: tilingSprite, + geometry + }; + tilingSprite.on("destroyed", () => { + this.destroyRenderable(tilingSprite); + }); + return this._tilingSpriteDataHash[tilingSprite.uid]; + } + _updateBatchableMesh(tilingSprite) { + const renderableData = this._getTilingSpriteData(tilingSprite); + const { geometry } = renderableData; + const style = tilingSprite.texture.source.style; + if (style.addressMode !== "repeat") { + style.addressMode = "repeat"; + style.update(); + } + setUvs(tilingSprite, geometry.uvs); + setPositions(tilingSprite, geometry.positions); + } + destroy() { + for (const i in this._tilingSpriteDataHash) { + this.destroyRenderable(this._tilingSpriteDataHash[i].renderable); + } + this._tilingSpriteDataHash = null; + this._renderer = null; + } + _updateCanBatch(tilingSprite) { + const renderableData = this._getTilingSpriteData(tilingSprite); + const texture = tilingSprite.texture; + let _nonPowOf2wrapping = true; + if (this._renderer.type === RendererType.WEBGL) { + _nonPowOf2wrapping = this._renderer.context.supports.nonPowOf2wrapping; + } + renderableData.canBatch = texture.textureMatrix.isSimple && (_nonPowOf2wrapping || texture.source.isPowerOfTwo); + return renderableData.canBatch; + } +} +/** @ignore */ +TilingSpritePipe.extension = { + type: [ + ExtensionType.WebGLPipes, + ExtensionType.WebGPUPipes, + ExtensionType.CanvasPipes + ], + name: "tilingSprite" }; -@group(0) @binding(0) var gfu: GlobalFilterUniforms; -@group(0) @binding(1) var uTexture: texture_2d; -@group(0) @binding(2) var uSampler : sampler; -@group(0) @binding(3) var uBackTexture: texture_2d; +"use strict"; +extensions.add(TilingSpritePipe); -@group(1) @binding(0) var blendUniforms : BlendUniforms; +"use strict"; +var __defProp$F = Object.defineProperty; +var __getOwnPropSymbols$F = Object.getOwnPropertySymbols; +var __hasOwnProp$F = Object.prototype.hasOwnProperty; +var __propIsEnum$F = Object.prototype.propertyIsEnumerable; +var __defNormalProp$F = (obj, key, value) => key in obj ? __defProp$F(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; +var __spreadValues$F = (a, b) => { + for (var prop in b || (b = {})) + if (__hasOwnProp$F.call(b, prop)) + __defNormalProp$F(a, prop, b[prop]); + if (__getOwnPropSymbols$F) + for (var prop of __getOwnPropSymbols$F(b)) { + if (__propIsEnum$F.call(b, prop)) + __defNormalProp$F(a, prop, b[prop]); + } + return a; +}; +const _PlaneGeometry = class _PlaneGeometry extends MeshGeometry { + constructor(...args) { + var _a; + super({}); + let options = (_a = args[0]) != null ? _a : {}; + if (typeof options === "number") { + deprecation(v8_0_0, "PlaneGeometry constructor changed please use { width, height, verticesX, verticesY } instead"); + options = { + width: options, + height: args[1], + verticesX: args[2], + verticesY: args[3] + }; + } + this.build(options); + } + /** + * Refreshes plane coordinates + * @param options - Options to be applied to plane geometry + */ + build(options) { + var _a, _b, _c, _d; + options = __spreadValues$F(__spreadValues$F({}, _PlaneGeometry.defaultOptions), options); + this.verticesX = (_a = this.verticesX) != null ? _a : options.verticesX; + this.verticesY = (_b = this.verticesY) != null ? _b : options.verticesY; + this.width = (_c = this.width) != null ? _c : options.width; + this.height = (_d = this.height) != null ? _d : options.height; + const total = this.verticesX * this.verticesY; + const verts = []; + const uvs = []; + const indices = []; + const verticesX = this.verticesX - 1; + const verticesY = this.verticesY - 1; + const sizeX = this.width / verticesX; + const sizeY = this.height / verticesY; + for (let i = 0; i < total; i++) { + const x = i % this.verticesX; + const y = i / this.verticesX | 0; + verts.push(x * sizeX, y * sizeY); + uvs.push(x / verticesX, y / verticesY); + } + const totalSub = verticesX * verticesY; + for (let i = 0; i < totalSub; i++) { + const xpos = i % verticesX; + const ypos = i / verticesX | 0; + const value = ypos * this.verticesX + xpos; + const value2 = ypos * this.verticesX + xpos + 1; + const value3 = (ypos + 1) * this.verticesX + xpos; + const value4 = (ypos + 1) * this.verticesX + xpos + 1; + indices.push( + value, + value2, + value3, + value2, + value4, + value3 + ); + } + this.buffers[0].data = new Float32Array(verts); + this.buffers[1].data = new Float32Array(uvs); + this.indexBuffer.data = new Uint32Array(indices); + this.buffers[0].update(); + this.buffers[1].update(); + this.indexBuffer.update(); + } +}; +_PlaneGeometry.defaultOptions = { + width: 100, + height: 100, + verticesX: 10, + verticesY: 10 +}; +let PlaneGeometry = _PlaneGeometry; +"use strict"; +var __defProp$E = Object.defineProperty; +var __getOwnPropSymbols$E = Object.getOwnPropertySymbols; +var __hasOwnProp$E = Object.prototype.hasOwnProperty; +var __propIsEnum$E = Object.prototype.propertyIsEnumerable; +var __defNormalProp$E = (obj, key, value) => key in obj ? __defProp$E(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; +var __spreadValues$E = (a, b) => { + for (var prop in b || (b = {})) + if (__hasOwnProp$E.call(b, prop)) + __defNormalProp$E(a, prop, b[prop]); + if (__getOwnPropSymbols$E) + for (var prop of __getOwnPropSymbols$E(b)) { + if (__propIsEnum$E.call(b, prop)) + __defNormalProp$E(a, prop, b[prop]); + } + return a; +}; +const _NineSliceGeometry = class _NineSliceGeometry extends PlaneGeometry { + constructor(options = {}) { + options = __spreadValues$E(__spreadValues$E({}, _NineSliceGeometry.defaultOptions), options); + super({ + width: options.width, + height: options.height, + verticesX: 4, + verticesY: 4 + }); + this.update(options); + } + /** + * Updates the NineSliceGeometry with the options. + * @param options - The options of the NineSliceGeometry. + */ + update(options) { + var _a, _b, _c, _d, _e, _f, _g, _h; + this.width = (_a = options.width) != null ? _a : this.width; + this.height = (_b = options.height) != null ? _b : this.height; + this._originalWidth = (_c = options.originalWidth) != null ? _c : this._originalWidth; + this._originalHeight = (_d = options.originalHeight) != null ? _d : this._originalHeight; + this._leftWidth = (_e = options.leftWidth) != null ? _e : this._leftWidth; + this._rightWidth = (_f = options.rightWidth) != null ? _f : this._rightWidth; + this._topHeight = (_g = options.topHeight) != null ? _g : this._topHeight; + this._bottomHeight = (_h = options.bottomHeight) != null ? _h : this._bottomHeight; + this.updateUvs(); + this.updatePositions(); + } + /** Updates the positions of the vertices. */ + updatePositions() { + const positions = this.positions; + const w = this._leftWidth + this._rightWidth; + const scaleW = this.width > w ? 1 : this.width / w; + const h = this._topHeight + this._bottomHeight; + const scaleH = this.height > h ? 1 : this.height / h; + const scale = Math.min(scaleW, scaleH); + positions[9] = positions[11] = positions[13] = positions[15] = this._topHeight * scale; + positions[17] = positions[19] = positions[21] = positions[23] = this.height - this._bottomHeight * scale; + positions[25] = positions[27] = positions[29] = positions[31] = this.height; + positions[2] = positions[10] = positions[18] = positions[26] = this._leftWidth * scale; + positions[4] = positions[12] = positions[20] = positions[28] = this.width - this._rightWidth * scale; + positions[6] = positions[14] = positions[22] = positions[30] = this.width; + this.getBuffer("aPosition").update(); + } + /** Updates the UVs of the vertices. */ + updateUvs() { + const uvs = this.uvs; + uvs[0] = uvs[8] = uvs[16] = uvs[24] = 0; + uvs[1] = uvs[3] = uvs[5] = uvs[7] = 0; + uvs[6] = uvs[14] = uvs[22] = uvs[30] = 1; + uvs[25] = uvs[27] = uvs[29] = uvs[31] = 1; + const _uvw = 1 / this._originalWidth; + const _uvh = 1 / this._originalHeight; + uvs[2] = uvs[10] = uvs[18] = uvs[26] = _uvw * this._leftWidth; + uvs[9] = uvs[11] = uvs[13] = uvs[15] = _uvh * this._topHeight; + uvs[4] = uvs[12] = uvs[20] = uvs[28] = 1 - _uvw * this._rightWidth; + uvs[17] = uvs[19] = uvs[21] = uvs[23] = 1 - _uvh * this._bottomHeight; + this.getBuffer("aUV").update(); + } +}; +/** The default options for the NineSliceGeometry. */ +_NineSliceGeometry.defaultOptions = { + /** The width of the NineSlicePlane, setting this will actually modify the vertices and UV's of this plane. */ + width: 100, + /** The height of the NineSlicePlane, setting this will actually modify the vertices and UV's of this plane. */ + height: 100, + /** The width of the left column. */ + leftWidth: 10, + /** The height of the top row. */ + topHeight: 10, + /** The width of the right column. */ + rightWidth: 10, + /** The height of the bottom row. */ + bottomHeight: 10, + /** The original width of the texture */ + originalWidth: 100, + /** The original height of the texture */ + originalHeight: 100 +}; +let NineSliceGeometry = _NineSliceGeometry; -struct VSOutput { - @builtin(position) position: vec4, - @location(0) uv : vec2 - }; +"use strict"; +class NineSliceSpritePipe { + constructor(renderer) { + this._gpuSpriteHash = /* @__PURE__ */ Object.create(null); + this._renderer = renderer; + } + addRenderable(sprite, _instructionSet) { + const gpuSprite = this._getGpuSprite(sprite); + if (sprite._didSpriteUpdate) + this._updateBatchableSprite(sprite, gpuSprite); + this._renderer.renderPipes.batch.addToBatch(gpuSprite); + } + updateRenderable(sprite) { + const gpuSprite = this._gpuSpriteHash[sprite.uid]; + if (sprite._didSpriteUpdate) + this._updateBatchableSprite(sprite, gpuSprite); + gpuSprite.batcher.updateElement(gpuSprite); + } + validateRenderable(sprite) { + const texture = sprite._texture; + const gpuSprite = this._getGpuSprite(sprite); + if (gpuSprite.texture._source !== texture._source) { + return !gpuSprite.batcher.checkAndUpdateTexture(gpuSprite, texture); + } + return false; + } + destroyRenderable(sprite) { + const batchableSprite = this._gpuSpriteHash[sprite.uid]; + BigPool.return(batchableSprite); + this._gpuSpriteHash[sprite.uid] = null; + } + _updateBatchableSprite(sprite, batchableSprite) { + sprite._didSpriteUpdate = false; + batchableSprite.geometry.update(sprite); + batchableSprite.texture = sprite._texture; + } + _getGpuSprite(sprite) { + return this._gpuSpriteHash[sprite.uid] || this._initGPUSprite(sprite); + } + _initGPUSprite(sprite) { + const batchableMesh = new BatchableMesh(); + batchableMesh.geometry = new NineSliceGeometry(); + batchableMesh.mesh = sprite; + batchableMesh.texture = sprite._texture; + batchableMesh.roundPixels = this._renderer._roundPixels | sprite._roundPixels; + this._gpuSpriteHash[sprite.uid] = batchableMesh; + sprite.on("destroyed", () => { + this.destroyRenderable(sprite); + }); + return batchableMesh; + } + destroy() { + for (const i in this._gpuSpriteHash) { + const batchableMesh = this._gpuSpriteHash[i]; + batchableMesh.geometry.destroy(); + } + this._gpuSpriteHash = null; + this._renderer = null; + } +} +/** @ignore */ +NineSliceSpritePipe.extension = { + type: [ + ExtensionType.WebGLPipes, + ExtensionType.WebGPUPipes, + ExtensionType.CanvasPipes + ], + name: "nineSliceSprite" +}; -fn filterVertexPosition(aPosition:vec2) -> vec4 -{ - var position = aPosition * gfu.uOutputFrame.zw + gfu.uOutputFrame.xy; +"use strict"; +extensions.add(NineSliceSpritePipe); - position.x = position.x * (2.0 / gfu.uOutputTexture.x) - 1.0; - position.y = position.y * (2.0*gfu.uOutputTexture.z / gfu.uOutputTexture.y) - gfu.uOutputTexture.z; +"use strict"; +class FilterPipe { + constructor(renderer) { + this._renderer = renderer; + } + push(filterEffect, container, instructionSet) { + const renderPipes = this._renderer.renderPipes; + renderPipes.batch.break(instructionSet); + instructionSet.add({ + renderPipeId: "filter", + canBundle: false, + action: "pushFilter", + container, + filterEffect + }); + } + pop(_filterEffect, _container, instructionSet) { + this._renderer.renderPipes.batch.break(instructionSet); + instructionSet.add({ + renderPipeId: "filter", + action: "popFilter", + canBundle: false + }); + } + execute(instruction) { + if (instruction.action === "pushFilter") { + this._renderer.filter.push(instruction); + } else if (instruction.action === "popFilter") { + this._renderer.filter.pop(); + } + } + destroy() { + this._renderer = null; + } +} +FilterPipe.extension = { + type: [ + ExtensionType.WebGLPipes, + ExtensionType.WebGPUPipes, + ExtensionType.CanvasPipes + ], + name: "filter" +}; - return vec4(position, 0.0, 1.0); +"use strict"; +const tempMatrix$1 = new Matrix(); +function getFastGlobalBounds(target, bounds) { + bounds.clear(); + _getGlobalBoundsRecursive(target, bounds); + if (!bounds.isValid) { + bounds.set(0, 0, 0, 0); + } + if (!target.isRenderGroupRoot) { + bounds.applyMatrix(target.renderGroup.worldTransform); + } else { + bounds.applyMatrix(target.renderGroup.localTransform); + } + return bounds; +} +function _getGlobalBoundsRecursive(target, bounds) { + if (target.localDisplayStatus !== 7 || !target.measurable) { + return; + } + const manageEffects = !!target.effects.length; + let localBounds = bounds; + if (target.isRenderGroupRoot || manageEffects) { + localBounds = boundsPool.get().clear(); + } + if (target.boundsArea) { + bounds.addRect(target.boundsArea, target.worldTransform); + } else { + if (target.renderPipeId) { + const viewBounds = target.bounds; + localBounds.addFrame( + viewBounds.minX, + viewBounds.minY, + viewBounds.maxX, + viewBounds.maxY, + target.groupTransform + ); + } + const children = target.children; + for (let i = 0; i < children.length; i++) { + _getGlobalBoundsRecursive(children[i], localBounds); + } + } + if (manageEffects) { + let advanced = false; + for (let i = 0; i < target.effects.length; i++) { + if (target.effects[i].addBounds) { + if (!advanced) { + advanced = true; + localBounds.applyMatrix(target.renderGroup.worldTransform); + } + target.effects[i].addBounds(localBounds, true); + } + } + if (advanced) { + localBounds.applyMatrix(target.renderGroup.worldTransform.copyTo(tempMatrix$1).invert()); + bounds.addBounds(localBounds, target.relativeGroupTransform); + } + bounds.addBounds(localBounds); + boundsPool.return(localBounds); + } else if (target.isRenderGroupRoot) { + bounds.addBounds(localBounds, target.relativeGroupTransform); + boundsPool.return(localBounds); + } } -fn filterTextureCoord( aPosition:vec2 ) -> vec2 -{ - return aPosition * (gfu.uOutputFrame.zw * gfu.uInputSize.zw); +"use strict"; +function getGlobalRenderableBounds(renderables, bounds) { + bounds.clear(); + const tempMatrix = bounds.matrix; + for (let i = 0; i < renderables.length; i++) { + const renderable = renderables[i]; + if (renderable.globalDisplayStatus < 7) { + continue; + } + bounds.matrix = renderable.worldTransform; + renderable.addBounds(bounds); + } + bounds.matrix = tempMatrix; + return bounds; } -fn globalTextureCoord( aPosition:vec2 ) -> vec2 -{ - return (aPosition.xy / gfu.uGlobalFrame.zw) + (gfu.uGlobalFrame.xy / gfu.uGlobalFrame.zw); +"use strict"; +const quadGeometry = new Geometry({ + attributes: { + aPosition: { + buffer: new Float32Array([0, 0, 1, 0, 1, 1, 0, 1]), + location: 0, + format: "float32x2", + stride: 2 * 4, + offset: 0 + } + }, + indexBuffer: new Uint32Array([0, 1, 2, 0, 2, 3]) +}); +class FilterSystem { + constructor(renderer) { + this._filterStackIndex = 0; + this._filterStack = []; + this._filterGlobalUniforms = new UniformGroup({ + uInputSize: { value: new Float32Array(4), type: "vec4" }, + uInputPixel: { value: new Float32Array(4), type: "vec4" }, + uInputClamp: { value: new Float32Array(4), type: "vec4" }, + uOutputFrame: { value: new Float32Array(4), type: "vec4" }, + uGlobalFrame: { value: new Float32Array(4), type: "vec4" }, + uOutputTexture: { value: new Float32Array(4), type: "vec4" } + }); + this._globalFilterBindGroup = new BindGroup({}); + this.renderer = renderer; + } + /** + * The back texture of the currently active filter. Requires the filter to have `blendRequired` set to true. + * @readonly + */ + get activeBackTexture() { + var _a; + return (_a = this._activeFilterData) == null ? void 0 : _a.backTexture; + } + push(instruction) { + var _a, _b; + const renderer = this.renderer; + const filters = instruction.filterEffect.filters; + if (!this._filterStack[this._filterStackIndex]) { + this._filterStack[this._filterStackIndex] = this._getFilterData(); + } + const filterData = this._filterStack[this._filterStackIndex]; + this._filterStackIndex++; + if (filters.length === 0) { + filterData.skip = true; + return; + } + const bounds = filterData.bounds; + if (instruction.renderables) { + getGlobalRenderableBounds(instruction.renderables, bounds); + } else if (instruction.filterEffect.filterArea) { + bounds.clear(); + bounds.addRect(instruction.filterEffect.filterArea); + bounds.applyMatrix(instruction.container.worldTransform); + } else { + getFastGlobalBounds(instruction.container, bounds); + } + const colorTextureSource = renderer.renderTarget.rootRenderTarget.colorTexture.source; + let resolution = colorTextureSource._resolution; + let padding = 0; + let antialias = colorTextureSource.antialias; + let blendRequired = false; + let enabled = false; + for (let i = 0; i < filters.length; i++) { + const filter = filters[i]; + resolution = Math.min(resolution, filter.resolution); + padding += filter.padding; + if (filter.antialias !== "inherit") { + if (filter.antialias === "on") { + antialias = true; + } else { + antialias = false; + } + } + const isCompatible = !!(filter.compatibleRenderers & renderer.type); + if (!isCompatible) { + enabled = false; + break; + } + if (filter.blendRequired && !((_b = (_a = renderer.backBuffer) == null ? void 0 : _a.useBackBuffer) != null ? _b : true)) { + warn("Blend filter requires backBuffer on WebGL renderer to be enabled. Set `useBackBuffer: true` in the renderer options."); + enabled = false; + break; + } + enabled = filter.enabled || enabled; + blendRequired = blendRequired || filter.blendRequired; + } + if (!enabled) { + filterData.skip = true; + return; + } + const viewPort = renderer.renderTarget.rootViewPort; + bounds.scale(resolution).fitBounds(0, viewPort.width, 0, viewPort.height).scale(1 / resolution).pad(padding).ceil(); + if (!bounds.isPositive) { + filterData.skip = true; + return; + } + filterData.skip = false; + filterData.bounds = bounds; + filterData.blendRequired = blendRequired; + filterData.container = instruction.container; + filterData.filterEffect = instruction.filterEffect; + filterData.previousRenderSurface = renderer.renderTarget.renderSurface; + filterData.inputTexture = TexturePool.getOptimalTexture( + bounds.width, + bounds.height, + resolution, + antialias + ); + renderer.renderTarget.bind(filterData.inputTexture, true); + renderer.globalUniforms.push({ + offset: bounds + }); + } + pop() { + const renderer = this.renderer; + this._filterStackIndex--; + const filterData = this._filterStack[this._filterStackIndex]; + if (filterData.skip) { + return; + } + this._activeFilterData = filterData; + const inputTexture = filterData.inputTexture; + const bounds = filterData.bounds; + let backTexture = Texture.EMPTY; + renderer.renderTarget.finishRenderPass(); + if (filterData.blendRequired) { + const previousBounds = this._filterStackIndex > 0 ? this._filterStack[this._filterStackIndex - 1].bounds : null; + const renderTarget = renderer.renderTarget.getRenderTarget(filterData.previousRenderSurface); + backTexture = this.getBackTexture(renderTarget, bounds, previousBounds); + } + filterData.backTexture = backTexture; + const filters = filterData.filterEffect.filters; + this._globalFilterBindGroup.setResource(inputTexture.source.style, 2); + this._globalFilterBindGroup.setResource(backTexture.source, 3); + renderer.globalUniforms.pop(); + if (filters.length === 1) { + filters[0].apply(this, inputTexture, filterData.previousRenderSurface, false); + TexturePool.returnTexture(inputTexture); + } else { + let flip = filterData.inputTexture; + let flop = TexturePool.getOptimalTexture( + bounds.width, + bounds.height, + flip.source._resolution, + false + ); + let i = 0; + for (i = 0; i < filters.length - 1; ++i) { + const filter = filters[i]; + filter.apply(this, flip, flop, true); + const t = flip; + flip = flop; + flop = t; + } + filters[i].apply(this, flip, filterData.previousRenderSurface, false); + TexturePool.returnTexture(flip); + TexturePool.returnTexture(flop); + } + if (filterData.blendRequired) { + TexturePool.returnTexture(backTexture); + } + } + getBackTexture(lastRenderSurface, bounds, previousBounds) { + const backgroundResolution = lastRenderSurface.colorTexture.source._resolution; + const backTexture = TexturePool.getOptimalTexture( + bounds.width, + bounds.height, + backgroundResolution, + false + ); + let x = bounds.minX; + let y = bounds.minY; + if (previousBounds) { + x -= previousBounds.minX; + y -= previousBounds.minY; + } + x = Math.floor(x * backgroundResolution); + y = Math.floor(y * backgroundResolution); + const width = Math.ceil(bounds.width * backgroundResolution); + const height = Math.ceil(bounds.height * backgroundResolution); + this.renderer.renderTarget.copyToTexture( + lastRenderSurface, + backTexture, + { x, y }, + { width, height }, + { x: 0, y: 0 } + ); + return backTexture; + } + applyFilter(filter, input, output, clear) { + const renderer = this.renderer; + const filterData = this._filterStack[this._filterStackIndex]; + const bounds = filterData.bounds; + const offset = Point.shared; + const previousRenderSurface = filterData.previousRenderSurface; + const isFinalTarget = previousRenderSurface === output; + let resolution = this.renderer.renderTarget.rootRenderTarget.colorTexture.source._resolution; + let currentIndex = this._filterStackIndex - 1; + while (currentIndex > 0 && this._filterStack[currentIndex].skip) { + --currentIndex; + } + if (currentIndex > 0) { + resolution = this._filterStack[currentIndex].inputTexture.source._resolution; + } + const filterUniforms = this._filterGlobalUniforms; + const uniforms = filterUniforms.uniforms; + const outputFrame = uniforms.uOutputFrame; + const inputSize = uniforms.uInputSize; + const inputPixel = uniforms.uInputPixel; + const inputClamp = uniforms.uInputClamp; + const globalFrame = uniforms.uGlobalFrame; + const outputTexture = uniforms.uOutputTexture; + if (isFinalTarget) { + let lastIndex = this._filterStackIndex; + while (lastIndex > 0) { + lastIndex--; + const filterData2 = this._filterStack[this._filterStackIndex - 1]; + if (!filterData2.skip) { + offset.x = filterData2.bounds.minX; + offset.y = filterData2.bounds.minY; + break; + } + } + outputFrame[0] = bounds.minX - offset.x; + outputFrame[1] = bounds.minY - offset.y; + } else { + outputFrame[0] = 0; + outputFrame[1] = 0; + } + outputFrame[2] = input.frame.width; + outputFrame[3] = input.frame.height; + inputSize[0] = input.source.width; + inputSize[1] = input.source.height; + inputSize[2] = 1 / inputSize[0]; + inputSize[3] = 1 / inputSize[1]; + inputPixel[0] = input.source.pixelWidth; + inputPixel[1] = input.source.pixelHeight; + inputPixel[2] = 1 / inputPixel[0]; + inputPixel[3] = 1 / inputPixel[1]; + inputClamp[0] = 0.5 * inputPixel[2]; + inputClamp[1] = 0.5 * inputPixel[3]; + inputClamp[2] = input.frame.width * inputSize[2] - 0.5 * inputPixel[2]; + inputClamp[3] = input.frame.height * inputSize[3] - 0.5 * inputPixel[3]; + const rootTexture = this.renderer.renderTarget.rootRenderTarget.colorTexture; + globalFrame[0] = offset.x * resolution; + globalFrame[1] = offset.y * resolution; + globalFrame[2] = rootTexture.source.width * resolution; + globalFrame[3] = rootTexture.source.height * resolution; + const renderTarget = this.renderer.renderTarget.getRenderTarget(output); + renderer.renderTarget.bind(output, !!clear); + if (output instanceof Texture) { + outputTexture[0] = output.frame.width; + outputTexture[1] = output.frame.height; + } else { + outputTexture[0] = renderTarget.width; + outputTexture[1] = renderTarget.height; + } + outputTexture[2] = renderTarget.isRoot ? -1 : 1; + filterUniforms.update(); + if (renderer.renderPipes.uniformBatch) { + const batchUniforms = renderer.renderPipes.uniformBatch.getUboResource(filterUniforms); + this._globalFilterBindGroup.setResource(batchUniforms, 0); + } else { + this._globalFilterBindGroup.setResource(filterUniforms, 0); + } + this._globalFilterBindGroup.setResource(input.source, 1); + this._globalFilterBindGroup.setResource(input.source.style, 2); + filter.groups[0] = this._globalFilterBindGroup; + renderer.encoder.draw({ + geometry: quadGeometry, + shader: filter, + state: filter._state, + topology: "triangle-list" + }); + if (renderer.type === RendererType.WEBGL) { + renderer.renderTarget.finishRenderPass(); + } + } + _getFilterData() { + return { + skip: false, + inputTexture: null, + bounds: new Bounds(), + container: null, + filterEffect: null, + blendRequired: false, + previousRenderSurface: null + }; + } + /** + * Multiply _input normalized coordinates_ to this matrix to get _sprite texture normalized coordinates_. + * + * Use `outputMatrix * vTextureCoord` in the shader. + * @param outputMatrix - The matrix to output to. + * @param {Sprite} sprite - The sprite to map to. + * @returns The mapped matrix. + */ + calculateSpriteMatrix(outputMatrix, sprite) { + const data = this._activeFilterData; + const mappedMatrix = outputMatrix.set( + data.inputTexture._source.width, + 0, + 0, + data.inputTexture._source.height, + data.bounds.minX, + data.bounds.minY + ); + const worldTransform = sprite.worldTransform.copyTo(Matrix.shared); + worldTransform.invert(); + mappedMatrix.prepend(worldTransform); + mappedMatrix.scale( + 1 / sprite.texture.frame.width, + 1 / sprite.texture.frame.height + ); + mappedMatrix.translate(sprite.anchor.x, sprite.anchor.y); + return mappedMatrix; + } } - -@vertex -fn mainVertex( - @location(0) aPosition : vec2, -) -> VSOutput { - return VSOutput( - filterVertexPosition(aPosition), - filterTextureCoord(aPosition) +/** @ignore */ +FilterSystem.extension = { + type: [ + ExtensionType.WebGLSystem, + ExtensionType.WebGPUSystem + ], + name: "filter" +}; + +"use strict"; +extensions.add(FilterSystem); +extensions.add(FilterPipe); + +"use strict"; + +var browserAll = { + __proto__: null +}; + +"use strict"; + +"use strict"; +const environments = []; +extensions.handleByNamedList(ExtensionType.Environment, environments); +async function autoDetectEnvironment(manageImports) { + if (!manageImports) + return; + for (let i = 0; i < environments.length; i++) { + const env = environments[i]; + if (env.value.test()) { + await env.value.load(); + return; + } + } +} + +"use strict"; +let unsafeEval; +function unsafeEvalSupported() { + if (typeof unsafeEval === "boolean") { + return unsafeEval; + } + try { + const func = new Function("param1", "param2", "param3", "return param1[param2] === param3;"); + unsafeEval = func({ a: "b" }, "a", "b") === true; + } catch (e) { + unsafeEval = false; + } + return unsafeEval; +} + +"use strict"; + +"use strict"; +var CLEAR = /* @__PURE__ */ ((CLEAR2) => { + CLEAR2[CLEAR2["NONE"] = 0] = "NONE"; + CLEAR2[CLEAR2["COLOR"] = 16384] = "COLOR"; + CLEAR2[CLEAR2["STENCIL"] = 1024] = "STENCIL"; + CLEAR2[CLEAR2["DEPTH"] = 256] = "DEPTH"; + CLEAR2[CLEAR2["COLOR_DEPTH"] = 16640] = "COLOR_DEPTH"; + CLEAR2[CLEAR2["COLOR_STENCIL"] = 17408] = "COLOR_STENCIL"; + CLEAR2[CLEAR2["DEPTH_STENCIL"] = 1280] = "DEPTH_STENCIL"; + CLEAR2[CLEAR2["ALL"] = 17664] = "ALL"; + return CLEAR2; +})(CLEAR || {}); + +"use strict"; +class SystemRunner { + /** + * @param name - The function name that will be executed on the listeners added to this Runner. + */ + constructor(name) { + this.items = []; + this._name = name; + } + /* eslint-disable jsdoc/require-param, jsdoc/check-param-names */ + /** + * Dispatch/Broadcast Runner to all listeners added to the queue. + * @param {...any} params - (optional) parameters to pass to each listener + */ + /* eslint-enable jsdoc/require-param, jsdoc/check-param-names */ + emit(a0, a1, a2, a3, a4, a5, a6, a7) { + const { name, items } = this; + for (let i = 0, len = items.length; i < len; i++) { + items[i][name](a0, a1, a2, a3, a4, a5, a6, a7); + } + return this; + } + /** + * Add a listener to the Runner + * + * Runners do not need to have scope or functions passed to them. + * All that is required is to pass the listening object and ensure that it has contains a function that has the same name + * as the name provided to the Runner when it was created. + * + * Eg A listener passed to this Runner will require a 'complete' function. + * + * ``` + * import { Runner } from 'pixi.js'; + * + * const complete = new Runner('complete'); + * ``` + * + * The scope used will be the object itself. + * @param {any} item - The object that will be listening. + */ + add(item) { + if (item[this._name]) { + this.remove(item); + this.items.push(item); + } + return this; + } + /** + * Remove a single listener from the dispatch queue. + * @param {any} item - The listener that you would like to remove. + */ + remove(item) { + const index = this.items.indexOf(item); + if (index !== -1) { + this.items.splice(index, 1); + } + return this; + } + /** + * Check to see if the listener is already in the Runner + * @param {any} item - The listener that you would like to check. + */ + contains(item) { + return this.items.indexOf(item) !== -1; + } + /** Remove all listeners from the Runner */ + removeAll() { + this.items.length = 0; + return this; + } + /** Remove all references, don't use after this. */ + destroy() { + this.removeAll(); + this.items = null; + this._name = null; + } + /** + * `true` if there are no this Runner contains no listeners + * @readonly + */ + get empty() { + return this.items.length === 0; + } + /** + * The name of the runner. + * @readonly + */ + get name() { + return this._name; + } +} + +"use strict"; +var __defProp$D = Object.defineProperty; +var __getOwnPropSymbols$D = Object.getOwnPropertySymbols; +var __hasOwnProp$D = Object.prototype.hasOwnProperty; +var __propIsEnum$D = Object.prototype.propertyIsEnumerable; +var __defNormalProp$D = (obj, key, value) => key in obj ? __defProp$D(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; +var __spreadValues$D = (a, b) => { + for (var prop in b || (b = {})) + if (__hasOwnProp$D.call(b, prop)) + __defNormalProp$D(a, prop, b[prop]); + if (__getOwnPropSymbols$D) + for (var prop of __getOwnPropSymbols$D(b)) { + if (__propIsEnum$D.call(b, prop)) + __defNormalProp$D(a, prop, b[prop]); + } + return a; +}; +const defaultRunners = [ + "init", + "destroy", + "contextChange", + "resolutionChange", + "reset", + "renderEnd", + "renderStart", + "render", + "update", + "postrender", + "prerender" +]; +const _AbstractRenderer = class _AbstractRenderer extends EventEmitter { + /** + * Set up a system with a collection of SystemClasses and runners. + * Systems are attached dynamically to this class when added. + * @param config - the config for the system manager + */ + constructor(config) { + var _a; + super(); + this.runners = /* @__PURE__ */ Object.create(null); + this.renderPipes = /* @__PURE__ */ Object.create(null); + this._initOptions = {}; + this._systemsHash = /* @__PURE__ */ Object.create(null); + this.type = config.type; + this.name = config.name; + const combinedRunners = [...defaultRunners, ...(_a = config.runners) != null ? _a : []]; + this._addRunners(...combinedRunners); + this._addSystems(config.systems); + this._addPipes(config.renderPipes, config.renderPipeAdaptors); + this._unsafeEvalCheck(); + } + /** + * Initialize the renderer. + * @param options - The options to use to create the renderer. + */ + async init(options = {}) { + for (const systemName in this._systemsHash) { + const system = this._systemsHash[systemName]; + const defaultSystemOptions = system.constructor.defaultOptions; + options = __spreadValues$D(__spreadValues$D({}, defaultSystemOptions), options); + } + options = __spreadValues$D(__spreadValues$D({}, _AbstractRenderer.defaultOptions), options); + this._roundPixels = options.roundPixels ? 1 : 0; + for (let i = 0; i < this.runners.init.items.length; i++) { + await this.runners.init.items[i].init(options); + } + this._initOptions = options; + } + render(args, deprecated) { + let options = args; + if (options instanceof Container) { + options = { container: options }; + if (deprecated) { + deprecation(v8_0_0, "passing a second argument is deprecated, please use render options instead"); + options.target = deprecated.renderTexture; + } + } + options.target || (options.target = this.view.renderTarget); + if (options.target === this.view.renderTarget) { + this._lastObjectRendered = options.container; + options.clearColor = this.background.colorRgba; + } + if (options.clearColor) { + const isRGBAArray = Array.isArray(options.clearColor) && options.clearColor.length === 4; + options.clearColor = isRGBAArray ? options.clearColor : Color.shared.setValue(options.clearColor).toArray(); + } + if (!options.transform) { + options.container.updateLocalTransform(); + options.transform = options.container.localTransform; + } + this.runners.prerender.emit(options); + this.runners.renderStart.emit(options); + this.runners.render.emit(options); + this.runners.renderEnd.emit(options); + this.runners.postrender.emit(options); + } + /** + * Resizes the WebGL view to the specified width and height. + * @param desiredScreenWidth - The desired width of the screen. + * @param desiredScreenHeight - The desired height of the screen. + * @param resolution - The resolution / device pixel ratio of the renderer. + */ + resize(desiredScreenWidth, desiredScreenHeight, resolution) { + this.view.resize(desiredScreenWidth, desiredScreenHeight, resolution); + this.emit("resize", this.view.screen.width, this.view.screen.height); + } + clear(options = {}) { + var _a; + const renderer = this; + options.target || (options.target = renderer.renderTarget.renderTarget); + options.clearColor || (options.clearColor = this.background.colorRgba); + (_a = options.clear) != null ? _a : options.clear = CLEAR.ALL; + const { clear, clearColor, target } = options; + Color.shared.setValue(clearColor != null ? clearColor : this.background.colorRgba); + renderer.renderTarget.clear(target, clear, Color.shared.toArray()); + } + /** The resolution / device pixel ratio of the renderer. */ + get resolution() { + return this.view.resolution; + } + set resolution(value) { + this.view.resolution = value; + this.runners.resolutionChange.emit(value); + } + /** + * Same as view.width, actual number of pixels in the canvas by horizontal. + * @member {number} + * @readonly + * @default 800 + */ + get width() { + return this.view.texture.frame.width; + } + /** + * Same as view.height, actual number of pixels in the canvas by vertical. + * @default 600 + */ + get height() { + return this.view.texture.frame.height; + } + // NOTE: this was `view` in v7 + /** + * The canvas element that everything is drawn to. + * @type {environment.ICanvas} + */ + get canvas() { + return this.view.canvas; + } + /** + * the last object rendered by the renderer. Useful for other plugins like interaction managers + * @readonly + */ + get lastObjectRendered() { + return this._lastObjectRendered; + } + /** + * Flag if we are rendering to the screen vs renderTexture + * @readonly + * @default true + */ + get renderingToScreen() { + const renderer = this; + return renderer.renderTarget.renderingToScreen; + } + /** + * Measurements of the screen. (0, 0, screenWidth, screenHeight). + * + * Its safe to use as filterArea or hitArea for the whole stage. + */ + get screen() { + return this.view.screen; + } + /** + * Create a bunch of runners based of a collection of ids + * @param runnerIds - the runner ids to add + */ + _addRunners(...runnerIds) { + runnerIds.forEach((runnerId) => { + this.runners[runnerId] = new SystemRunner(runnerId); + }); + } + _addSystems(systems) { + let i; + for (i in systems) { + const val = systems[i]; + this._addSystem(val.value, val.name); + } + } + /** + * Add a new system to the renderer. + * @param ClassRef - Class reference + * @param name - Property name for system, if not specified + * will use a static `name` property on the class itself. This + * name will be assigned as s property on the Renderer so make + * sure it doesn't collide with properties on Renderer. + * @returns Return instance of renderer + */ + _addSystem(ClassRef, name) { + const system = new ClassRef(this); + if (this[name]) { + throw new Error(`Whoops! The name "${name}" is already in use`); + } + this[name] = system; + this._systemsHash[name] = system; + for (const i in this.runners) { + this.runners[i].add(system); + } + return this; + } + _addPipes(pipes, pipeAdaptors) { + const adaptors = pipeAdaptors.reduce((acc, adaptor) => { + acc[adaptor.name] = adaptor.value; + return acc; + }, {}); + pipes.forEach((pipe) => { + const PipeClass = pipe.value; + const name = pipe.name; + const Adaptor = adaptors[name]; + this.renderPipes[name] = new PipeClass( + this, + Adaptor ? new Adaptor() : null + ); + }); + } + destroy(options = false) { + this.runners.destroy.items.reverse(); + this.runners.destroy.emit(options); + Object.values(this.runners).forEach((runner) => { + runner.destroy(); + }); + this._systemsHash = null; + this.renderPipes = null; + } + /** + * Generate a texture from a container. + * @param options - options or container target to use when generating the texture + * @returns a texture + */ + generateTexture(options) { + return this.textureGenerator.generateTexture(options); + } + /** + * Whether the renderer will round coordinates to whole pixels when rendering. + * Can be overridden on a per scene item basis. + */ + get roundPixels() { + return !!this._roundPixels; + } + /** + * Overrideable function by `pixi.js/unsafe-eval` to silence + * throwing an error if platform doesn't support unsafe-evals. + * @private + * @ignore + */ + _unsafeEvalCheck() { + if (!unsafeEvalSupported()) { + throw new Error("Current environment does not allow unsafe-eval, please use pixi.js/unsafe-eval module to enable support."); + } + } +}; +/** The default options for the renderer. */ +_AbstractRenderer.defaultOptions = { + /** + * Default resolution / device pixel ratio of the renderer. + * @default 1 + */ + resolution: 1, + /** + * Should the `failIfMajorPerformanceCaveat` flag be enabled as a context option used in the `isWebGLSupported` + * function. If set to true, a WebGL renderer can fail to be created if the browser thinks there could be + * performance issues when using WebGL. + * + * In PixiJS v6 this has changed from true to false by default, to allow WebGL to work in as many + * scenarios as possible. However, some users may have a poor experience, for example, if a user has a gpu or + * driver version blacklisted by the + * browser. + * + * If your application requires high performance rendering, you may wish to set this to false. + * We recommend one of two options if you decide to set this flag to false: + * + * 1: Use the Canvas renderer as a fallback in case high performance WebGL is + * not supported. + * + * 2: Call `isWebGLSupported` (which if found in the utils package) in your code before attempting to create a + * PixiJS renderer, and show an error message to the user if the function returns false, explaining that their + * device & browser combination does not support high performance WebGL. + * This is a much better strategy than trying to create a PixiJS renderer and finding it then fails. + * @default false + */ + failIfMajorPerformanceCaveat: false, + /** + * Should round pixels be forced when rendering? + * @default false + */ + roundPixels: false +}; +let AbstractRenderer = _AbstractRenderer; + +"use strict"; +let _isWebGLSupported; +function isWebGLSupported(failIfMajorPerformanceCaveat) { + if (_isWebGLSupported !== void 0) + return _isWebGLSupported; + _isWebGLSupported = (() => { + var _a; + const contextOptions = { + stencil: true, + failIfMajorPerformanceCaveat: failIfMajorPerformanceCaveat != null ? failIfMajorPerformanceCaveat : AbstractRenderer.defaultOptions.failIfMajorPerformanceCaveat + }; + try { + if (!DOMAdapter.get().getWebGLRenderingContext()) { + return false; + } + const canvas = DOMAdapter.get().createCanvas(); + let gl = canvas.getContext("webgl", contextOptions); + const success = !!((_a = gl == null ? void 0 : gl.getContextAttributes()) == null ? void 0 : _a.stencil); + if (gl) { + const loseContext = gl.getExtension("WEBGL_lose_context"); + if (loseContext) { + loseContext.loseContext(); + } + } + gl = null; + return success; + } catch (e) { + return false; + } + })(); + return _isWebGLSupported; +} + +"use strict"; +let _isWebGPUSupported; +async function isWebGPUSupported(options = {}) { + if (_isWebGPUSupported !== void 0) + return _isWebGPUSupported; + _isWebGPUSupported = await (async () => { + const gpu = DOMAdapter.get().getNavigator().gpu; + if (!gpu) { + return false; + } + try { + const adapter = await navigator.gpu.requestAdapter(options); + await adapter.requestDevice(); + return true; + } catch (e) { + return false; + } + })(); + return _isWebGPUSupported; +} + +"use strict"; +var __defProp$C = Object.defineProperty; +var __getOwnPropSymbols$C = Object.getOwnPropertySymbols; +var __hasOwnProp$C = Object.prototype.hasOwnProperty; +var __propIsEnum$C = Object.prototype.propertyIsEnumerable; +var __defNormalProp$C = (obj, key, value) => key in obj ? __defProp$C(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; +var __spreadValues$C = (a, b) => { + for (var prop in b || (b = {})) + if (__hasOwnProp$C.call(b, prop)) + __defNormalProp$C(a, prop, b[prop]); + if (__getOwnPropSymbols$C) + for (var prop of __getOwnPropSymbols$C(b)) { + if (__propIsEnum$C.call(b, prop)) + __defNormalProp$C(a, prop, b[prop]); + } + return a; +}; +const renderPriority = ["webgl", "webgpu", "canvas"]; +async function autoDetectRenderer(options) { + var _a, _b; + let preferredOrder = []; + if (options.preference) { + preferredOrder.push(options.preference); + renderPriority.forEach((item) => { + if (item !== options.preference) { + preferredOrder.push(item); + } + }); + } else { + preferredOrder = renderPriority.slice(); + } + let RendererClass; + await autoDetectEnvironment( + (_a = options.manageImports) != null ? _a : true ); + let finalOptions = {}; + for (let i = 0; i < preferredOrder.length; i++) { + const rendererType = preferredOrder[i]; + if (rendererType === "webgpu" && await isWebGPUSupported()) { + const { WebGPURenderer } = await Promise.resolve().then(function () { return WebGPURenderer$1; }); + RendererClass = WebGPURenderer; + finalOptions = __spreadValues$C(__spreadValues$C({}, options), options.webgpu); + break; + } else if (rendererType === "webgl" && isWebGLSupported( + (_b = options.failIfMajorPerformanceCaveat) != null ? _b : AbstractRenderer.defaultOptions.failIfMajorPerformanceCaveat + )) { + const { WebGLRenderer } = await Promise.resolve().then(function () { return WebGLRenderer$1; }); + RendererClass = WebGLRenderer; + finalOptions = __spreadValues$C(__spreadValues$C({}, options), options.webgl); + break; + } else if (rendererType === "canvas") { + finalOptions = __spreadValues$C({}, options); + break; + } + } + delete finalOptions.webgpu; + delete finalOptions.webgl; + const renderer = new RendererClass(); + await renderer.init(finalOptions); + return renderer; } -{FUNCTIONS} +"use strict"; +var __defProp$B = Object.defineProperty; +var __getOwnPropSymbols$B = Object.getOwnPropertySymbols; +var __hasOwnProp$B = Object.prototype.hasOwnProperty; +var __propIsEnum$B = Object.prototype.propertyIsEnumerable; +var __defNormalProp$B = (obj, key, value) => key in obj ? __defProp$B(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; +var __spreadValues$B = (a, b) => { + for (var prop in b || (b = {})) + if (__hasOwnProp$B.call(b, prop)) + __defNormalProp$B(a, prop, b[prop]); + if (__getOwnPropSymbols$B) + for (var prop of __getOwnPropSymbols$B(b)) { + if (__propIsEnum$B.call(b, prop)) + __defNormalProp$B(a, prop, b[prop]); + } + return a; +}; +const _Application = class _Application { + /** @ignore */ + constructor(...args) { + /** The root display container that's rendered. */ + this.stage = new Container(); + if (args[0] !== void 0) { + deprecation(v8_0_0, "Application constructor options are deprecated, please use Application.init() instead."); + } + } + /** + * @param options - The optional application and renderer parameters. + */ + async init(options) { + options = __spreadValues$B({}, options); + this.renderer = await autoDetectRenderer(options); + _Application._plugins.forEach((plugin) => { + plugin.init.call(this, options); + }); + } + /** Render the current stage. */ + render() { + this.renderer.render({ container: this.stage }); + } + /** + * Reference to the renderer's canvas element. + * @readonly + * @member {HTMLCanvasElement} + */ + get canvas() { + return this.renderer.canvas; + } + /** + * Reference to the renderer's canvas element. + * @member {HTMLCanvasElement} + * @deprecated since 8.0.0 + */ + get view() { + deprecation(v8_0_0, "Application.view is deprecated, please use Application.canvas instead."); + return this.renderer.canvas; + } + /** + * Reference to the renderer's screen rectangle. Its safe to use as `filterArea` or `hitArea` for the whole screen. + * @readonly + */ + get screen() { + return this.renderer.screen; + } + /** + * Destroys the application and all of its resources. + * @param {object|boolean}[rendererDestroyOptions=false] - The options for destroying the renderer. + * @param {boolean}[rendererDestroyOptions.removeView=false] - Removes the Canvas element from the DOM. + * @param {object|boolean} [options=false] - The options for destroying the stage. + * @param {boolean} [options.children=false] - If set to true, all the children will have their destroy method + * called as well. `options` will be passed on to those calls. + * @param {boolean} [options.texture=false] - Only used for children with textures e.g. Sprites. + * If options.children is set to true, + * it should destroy the texture of the child sprite. + * @param {boolean} [options.textureSource=false] - Only used for children with textures e.g. Sprites. + * If options.children is set to true, + * it should destroy the texture source of the child sprite. + * @param {boolean} [options.context=false] - Only used for children with graphicsContexts e.g. Graphics. + * If options.children is set to true, + * it should destroy the context of the child graphics. + */ + destroy(rendererDestroyOptions = false, options = false) { + const plugins = _Application._plugins.slice(0); + plugins.reverse(); + plugins.forEach((plugin) => { + plugin.destroy.call(this); + }); + this.stage.destroy(options); + this.stage = null; + this.renderer.destroy(rendererDestroyOptions); + this.renderer = null; + } +}; +/** + * Collection of installed plugins. + * @alias _plugins + */ +_Application._plugins = []; +let Application = _Application; +extensions.handleByList(ExtensionType.Application, Application._plugins); -@fragment -fn mainFragment( - @location(0) uv: vec2 -) -> @location(0) vec4 { +"use strict"; +"use strict"; - var back = textureSample(uBackTexture, uSampler, uv); - var front = textureSample(uTexture, uSampler, uv); - - var out = vec4(0.0,0.0,0.0,0.0); +"use strict"; +class BackgroundLoader { + /** + * @param loader + * @param verbose - should the loader log to the console + */ + constructor(loader, verbose = false) { + this._loader = loader; + this._assetList = []; + this._isLoading = false; + this._maxConcurrent = 1; + this.verbose = verbose; + } + /** + * Adds an array of assets to load. + * @param assetUrls - assets to load + */ + add(assetUrls) { + assetUrls.forEach((a) => { + this._assetList.push(a); + }); + if (this.verbose) { + console.log("[BackgroundLoader] assets: ", this._assetList); + } + if (this._isActive && !this._isLoading) { + void this._next(); + } + } + /** + * Loads the next set of assets. Will try to load as many assets as it can at the same time. + * + * The max assets it will try to load at one time will be 4. + */ + async _next() { + if (this._assetList.length && this._isActive) { + this._isLoading = true; + const toLoad = []; + const toLoadAmount = Math.min(this._assetList.length, this._maxConcurrent); + for (let i = 0; i < toLoadAmount; i++) { + toLoad.push(this._assetList.pop()); + } + await this._loader.load(toLoad); + this._isLoading = false; + void this._next(); + } + } + /** + * Activate/Deactivate the loading. If set to true then it will immediately continue to load the next asset. + * @returns whether the class is active + */ + get active() { + return this._isActive; + } + set active(value) { + if (this._isActive === value) + return; + this._isActive = value; + if (value && !this._isLoading) { + void this._next(); + } + } +} - {MAIN} +"use strict"; +const cacheTextureArray = { + extension: ExtensionType.CacheParser, + test: (asset) => Array.isArray(asset) && asset.every((t) => t instanceof Texture), + getCacheableAssets: (keys, asset) => { + const out = {}; + keys.forEach((key) => { + asset.forEach((item, i) => { + out[key + (i === 0 ? "" : i + 1)] = item; + }); + }); + return out; + } +}; - return out; -}`,kT=Object.defineProperty,Hf=Object.getOwnPropertySymbols,LT=Object.prototype.hasOwnProperty,$T=Object.prototype.propertyIsEnumerable,Xf=(r,t,e)=>t in r?kT(r,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):r[t]=e,zf=(r,t)=>{for(var e in t||(t={}))LT.call(t,e)&&Xf(r,e,t[e]);if(Hf)for(var e of Hf(t))$T.call(t,e)&&Xf(r,e,t[e]);return r};class NT extends Yt{constructor(t){const e=t.gpu,s=jf(zf({source:Nf},e)),i=Tt.from({vertex:{source:s,entryPoint:"mainVertex"},fragment:{source:s,entryPoint:"mainFragment"}}),n=t.gl,o=jf(zf({source:Lf},n)),a=Rt.from({vertex:$f,fragment:o}),u=new it({uBlend:{value:1,type:"f32"}});super({gpuProgram:i,glProgram:a,blendRequired:!0,resources:{blendUniforms:u,uBackTexture:A.EMPTY}})}}function jf(r){const{source:t,functions:e,main:s}=r;return t.replace("{FUNCTIONS}",e).replace("{MAIN}",s)}const HT=` +"use strict"; +async function testImageFormat(imageData) { + if ("Image" in globalThis) { + return new Promise((resolve) => { + const image = new Image(); + image.onload = () => { + resolve(true); + }; + image.onerror = () => { + resolve(false); + }; + image.src = imageData; + }); + } + if ("createImageBitmap" in globalThis && "fetch" in globalThis) { + try { + const blob = await (await fetch(imageData)).blob(); + await createImageBitmap(blob); + } catch (e) { + return false; + } + return true; + } + return false; +} + +"use strict"; +const detectAvif = { + extension: { + type: ExtensionType.DetectionParser, + priority: 1 + }, + test: async () => testImageFormat( + // eslint-disable-next-line max-len + "data:image/avif;base64,AAAAIGZ0eXBhdmlmAAAAAGF2aWZtaWYxbWlhZk1BMUIAAADybWV0YQAAAAAAAAAoaGRscgAAAAAAAAAAcGljdAAAAAAAAAAAAAAAAGxpYmF2aWYAAAAADnBpdG0AAAAAAAEAAAAeaWxvYwAAAABEAAABAAEAAAABAAABGgAAAB0AAAAoaWluZgAAAAAAAQAAABppbmZlAgAAAAABAABhdjAxQ29sb3IAAAAAamlwcnAAAABLaXBjbwAAABRpc3BlAAAAAAAAAAIAAAACAAAAEHBpeGkAAAAAAwgICAAAAAxhdjFDgQ0MAAAAABNjb2xybmNseAACAAIAAYAAAAAXaXBtYQAAAAAAAAABAAEEAQKDBAAAACVtZGF0EgAKCBgANogQEAwgMg8f8D///8WfhwB8+ErK42A=" + ), + add: async (formats) => [...formats, "avif"], + remove: async (formats) => formats.filter((f) => f !== "avif") +}; + +"use strict"; +const imageFormats = ["png", "jpg", "jpeg"]; +const detectDefaults = { + extension: { + type: ExtensionType.DetectionParser, + priority: -1 + }, + test: () => Promise.resolve(true), + add: async (formats) => [...formats, ...imageFormats], + remove: async (formats) => formats.filter((f) => !imageFormats.includes(f)) +}; + +"use strict"; +const inWorker = "WorkerGlobalScope" in globalThis && globalThis instanceof globalThis.WorkerGlobalScope; +function testVideoFormat(mimeType) { + if (inWorker) { + return false; + } + const video = document.createElement("video"); + return video.canPlayType(mimeType) !== ""; +} + +"use strict"; +const detectMp4 = { + extension: { + type: ExtensionType.DetectionParser, + priority: 0 + }, + test: async () => testVideoFormat("video/mp4"), + add: async (formats) => [...formats, "mp4", "m4v"], + remove: async (formats) => formats.filter((f) => f !== "mp4" && f !== "m4v") +}; + +"use strict"; +const detectOgv = { + extension: { + type: ExtensionType.DetectionParser, + priority: 0 + }, + test: async () => testVideoFormat("video/ogg"), + add: async (formats) => [...formats, "ogv"], + remove: async (formats) => formats.filter((f) => f !== "ogv") +}; + +"use strict"; +const detectWebm = { + extension: { + type: ExtensionType.DetectionParser, + priority: 0 + }, + test: async () => testVideoFormat("video/webm"), + add: async (formats) => [...formats, "webm"], + remove: async (formats) => formats.filter((f) => f !== "webm") +}; + +"use strict"; +const detectWebp = { + extension: { + type: ExtensionType.DetectionParser, + priority: 0 + }, + test: async () => testImageFormat( + "data:image/webp;base64,UklGRh4AAABXRUJQVlA4TBEAAAAvAAAAAAfQ//73v/+BiOh/AAA=" + ), + add: async (formats) => [...formats, "webp"], + remove: async (formats) => formats.filter((f) => f !== "webp") +}; + +"use strict"; +var __defProp$A = Object.defineProperty; +var __defProps$h = Object.defineProperties; +var __getOwnPropDescs$h = Object.getOwnPropertyDescriptors; +var __getOwnPropSymbols$A = Object.getOwnPropertySymbols; +var __hasOwnProp$A = Object.prototype.hasOwnProperty; +var __propIsEnum$A = Object.prototype.propertyIsEnumerable; +var __defNormalProp$A = (obj, key, value) => key in obj ? __defProp$A(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; +var __spreadValues$A = (a, b) => { + for (var prop in b || (b = {})) + if (__hasOwnProp$A.call(b, prop)) + __defNormalProp$A(a, prop, b[prop]); + if (__getOwnPropSymbols$A) + for (var prop of __getOwnPropSymbols$A(b)) { + if (__propIsEnum$A.call(b, prop)) + __defNormalProp$A(a, prop, b[prop]); + } + return a; +}; +var __spreadProps$h = (a, b) => __defProps$h(a, __getOwnPropDescs$h(b)); +class Loader { + constructor() { + this._parsers = []; + this._parsersValidated = false; + /** + * All loader parsers registered + * @type {assets.LoaderParser[]} + */ + this.parsers = new Proxy(this._parsers, { + set: (target, key, value) => { + this._parsersValidated = false; + target[key] = value; + return true; + } + }); + /** Cache loading promises that ae currently active */ + this.promiseCache = {}; + } + /** function used for testing */ + reset() { + this._parsersValidated = false; + this.promiseCache = {}; + } + /** + * Used internally to generate a promise for the asset to be loaded. + * @param url - The URL to be loaded + * @param data - any custom additional information relevant to the asset being loaded + * @returns - a promise that will resolve to an Asset for example a Texture of a JSON object + */ + _getLoadPromiseAndParser(url, data) { + const result = { + promise: null, + parser: null + }; + result.promise = (async () => { + var _a, _b; + let asset = null; + let parser = null; + if (data.loadParser) { + parser = this._parserHash[data.loadParser]; + if (!parser) { + warn(`[Assets] specified load parser "${data.loadParser}" not found while loading ${url}`); + } + } + if (!parser) { + for (let i = 0; i < this.parsers.length; i++) { + const parserX = this.parsers[i]; + if (parserX.load && ((_a = parserX.test) == null ? void 0 : _a.call(parserX, url, data, this))) { + parser = parserX; + break; + } + } + if (!parser) { + warn(`[Assets] ${url} could not be loaded as we don't know how to parse it, ensure the correct parser has been added`); + return null; + } + } + asset = await parser.load(url, data, this); + result.parser = parser; + for (let i = 0; i < this.parsers.length; i++) { + const parser2 = this.parsers[i]; + if (parser2.parse) { + if (parser2.parse && await ((_b = parser2.testParse) == null ? void 0 : _b.call(parser2, asset, data, this))) { + asset = await parser2.parse(asset, data, this) || asset; + result.parser = parser2; + } + } + } + return asset; + })(); + return result; + } + async load(assetsToLoadIn, onProgress) { + if (!this._parsersValidated) { + this._validateParsers(); + } + let count = 0; + const assets = {}; + const singleAsset = isSingleItem(assetsToLoadIn); + const assetsToLoad = convertToList(assetsToLoadIn, (item) => ({ + alias: [item], + src: item + })); + const total = assetsToLoad.length; + const promises = assetsToLoad.map(async (asset) => { + const url = path.toAbsolute(asset.src); + if (!assets[asset.src]) { + try { + if (!this.promiseCache[url]) { + this.promiseCache[url] = this._getLoadPromiseAndParser(url, asset); + } + assets[asset.src] = await this.promiseCache[url].promise; + if (onProgress) + onProgress(++count / total); + } catch (e) { + delete this.promiseCache[url]; + delete assets[asset.src]; + throw new Error(`[Loader.load] Failed to load ${url}. +${e}`); + } + } + }); + await Promise.all(promises); + return singleAsset ? assets[assetsToLoad[0].src] : assets; + } + /** + * Unloads one or more assets. Any unloaded assets will be destroyed, freeing up memory for your app. + * The parser that created the asset, will be the one that unloads it. + * @example + * // Single asset: + * const asset = await Loader.load('cool.png'); + * + * await Loader.unload('cool.png'); + * + * console.log(asset.destroyed); // true + * @param assetsToUnloadIn - urls that you want to unload, or a single one! + */ + async unload(assetsToUnloadIn) { + const assetsToUnload = convertToList(assetsToUnloadIn, (item) => ({ + alias: [item], + src: item + })); + const promises = assetsToUnload.map(async (asset) => { + var _a, _b; + const url = path.toAbsolute(asset.src); + const loadPromise = this.promiseCache[url]; + if (loadPromise) { + const loadedAsset = await loadPromise.promise; + delete this.promiseCache[url]; + await ((_b = (_a = loadPromise.parser) == null ? void 0 : _a.unload) == null ? void 0 : _b.call(_a, loadedAsset, asset, this)); + } + }); + await Promise.all(promises); + } + /** validates our parsers, right now it only checks for name conflicts but we can add more here as required! */ + _validateParsers() { + this._parsersValidated = true; + this._parserHash = this._parsers.filter((parser) => parser.name).reduce((hash, parser) => { + if (!parser.name) { + warn(`[Assets] loadParser should have a name`); + } else if (hash[parser.name]) { + warn(`[Assets] loadParser name conflict "${parser.name}"`); + } + return __spreadProps$h(__spreadValues$A({}, hash), { [parser.name]: parser }); + }, {}); + } +} + +"use strict"; +function checkDataUrl(url, mimes) { + if (Array.isArray(mimes)) { + for (const mime of mimes) { + if (url.startsWith(`data:${mime}`)) + return true; + } + return false; + } + return url.startsWith(`data:${mimes}`); +} + +"use strict"; +function checkExtension(url, extension) { + const tempURL = url.split("?")[0]; + const ext = path.extname(tempURL).toLowerCase(); + if (Array.isArray(extension)) { + return extension.includes(ext); + } + return ext === extension; +} + +"use strict"; +const validJSONExtension = ".json"; +const validJSONMIME = "application/json"; +const loadJson = { + extension: { + type: ExtensionType.LoadParser, + priority: LoaderParserPriority.Low + }, + name: "loadJson", + test(url) { + return checkDataUrl(url, validJSONMIME) || checkExtension(url, validJSONExtension); + }, + async load(url) { + const response = await DOMAdapter.get().fetch(url); + const json = await response.json(); + return json; + } +}; + +"use strict"; +const validTXTExtension = ".txt"; +const validTXTMIME = "text/plain"; +const loadTxt = { + name: "loadTxt", + extension: { + type: ExtensionType.LoadParser, + priority: LoaderParserPriority.Low + }, + test(url) { + return checkDataUrl(url, validTXTMIME) || checkExtension(url, validTXTExtension); + }, + async load(url) { + const response = await DOMAdapter.get().fetch(url); + const txt = await response.text(); + return txt; + } +}; + +"use strict"; +var __defProp$z = Object.defineProperty; +var __defProps$g = Object.defineProperties; +var __getOwnPropDescs$g = Object.getOwnPropertyDescriptors; +var __getOwnPropSymbols$z = Object.getOwnPropertySymbols; +var __hasOwnProp$z = Object.prototype.hasOwnProperty; +var __propIsEnum$z = Object.prototype.propertyIsEnumerable; +var __defNormalProp$z = (obj, key, value) => key in obj ? __defProp$z(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; +var __spreadValues$z = (a, b) => { + for (var prop in b || (b = {})) + if (__hasOwnProp$z.call(b, prop)) + __defNormalProp$z(a, prop, b[prop]); + if (__getOwnPropSymbols$z) + for (var prop of __getOwnPropSymbols$z(b)) { + if (__propIsEnum$z.call(b, prop)) + __defNormalProp$z(a, prop, b[prop]); + } + return a; +}; +var __spreadProps$g = (a, b) => __defProps$g(a, __getOwnPropDescs$g(b)); +const validWeights = [ + "normal", + "bold", + "100", + "200", + "300", + "400", + "500", + "600", + "700", + "800", + "900" +]; +const validFontExtensions = [".ttf", ".otf", ".woff", ".woff2"]; +const validFontMIMEs = [ + "font/ttf", + "font/otf", + "font/woff", + "font/woff2" +]; +const CSS_IDENT_TOKEN_REGEX = /^(--|-?[A-Z_])[0-9A-Z_-]*$/i; +function getFontFamilyName(url) { + const ext = path.extname(url); + const name = path.basename(url, ext); + const nameWithSpaces = name.replace(/(-|_)/g, " "); + const nameTokens = nameWithSpaces.toLowerCase().split(" ").map((word) => word.charAt(0).toUpperCase() + word.slice(1)); + let valid = nameTokens.length > 0; + for (const token of nameTokens) { + if (!token.match(CSS_IDENT_TOKEN_REGEX)) { + valid = false; + break; + } + } + let fontFamilyName = nameTokens.join(" "); + if (!valid) { + fontFamilyName = `"${fontFamilyName.replace(/[\\"]/g, "\\$&")}"`; + } + return fontFamilyName; +} +const validURICharactersRegex = /^[0-9A-Za-z%:/?#\[\]@!\$&'()\*\+,;=\-._~]*$/; +function encodeURIWhenNeeded(uri) { + if (validURICharactersRegex.test(uri)) { + return uri; + } + return encodeURI(uri); +} +const loadWebFont = { + extension: { + type: ExtensionType.LoadParser, + priority: LoaderParserPriority.Low + }, + name: "loadWebFont", + test(url) { + return checkDataUrl(url, validFontMIMEs) || checkExtension(url, validFontExtensions); + }, + async load(url, options) { + var _a, _b, _c, _d, _e, _f; + const fonts = DOMAdapter.get().getFontFaceSet(); + if (fonts) { + const fontFaces = []; + const name = (_b = (_a = options.data) == null ? void 0 : _a.family) != null ? _b : getFontFamilyName(url); + const weights = (_e = (_d = (_c = options.data) == null ? void 0 : _c.weights) == null ? void 0 : _d.filter((weight) => validWeights.includes(weight))) != null ? _e : ["normal"]; + const data = (_f = options.data) != null ? _f : {}; + for (let i = 0; i < weights.length; i++) { + const weight = weights[i]; + const font = new FontFace(name, `url(${encodeURIWhenNeeded(url)})`, __spreadProps$g(__spreadValues$z({}, data), { + weight + })); + await font.load(); + fonts.add(font); + fontFaces.push(font); + } + Cache.set(`${name}-and-url`, { + url, + fontFaces + }); + return fontFaces.length === 1 ? fontFaces[0] : fontFaces; + } + warn("[loadWebFont] FontFace API is not supported. Skipping loading font"); + return null; + }, + unload(font) { + (Array.isArray(font) ? font : [font]).forEach((t) => { + Cache.remove(t.family); + DOMAdapter.get().getFontFaceSet().delete(t); + }); + } +}; + +"use strict"; +function getResolutionOfUrl(url, defaultValue = 1) { + var _a; + const resolution = (_a = Resolver.RETINA_PREFIX) == null ? void 0 : _a.exec(url); + if (resolution) { + return parseFloat(resolution[1]); + } + return defaultValue; +} + +"use strict"; +function createTexture(source, loader, url) { + source.label = url; + source._sourceOrigin = url; + const texture = new Texture({ + source, + label: url + }); + const unload = () => { + delete loader.promiseCache[url]; + if (Cache.has(url)) { + Cache.remove(url); + } + }; + texture.source.once("destroy", () => { + if (loader.promiseCache[url]) { + warn("[Assets] A TextureSource managed by Assets was destroyed instead of unloaded! Use Assets.unload() instead of destroying the TextureSource."); + unload(); + } + }); + texture.once("destroy", () => { + if (!source.destroyed) { + warn("[Assets] A Texture managed by Assets was destroyed instead of unloaded! Use Assets.unload() instead of destroying the Texture."); + unload(); + } + }); + return texture; +} + +"use strict"; +var __defProp$y = Object.defineProperty; +var __getOwnPropSymbols$y = Object.getOwnPropertySymbols; +var __hasOwnProp$y = Object.prototype.hasOwnProperty; +var __propIsEnum$y = Object.prototype.propertyIsEnumerable; +var __defNormalProp$y = (obj, key, value) => key in obj ? __defProp$y(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; +var __spreadValues$y = (a, b) => { + for (var prop in b || (b = {})) + if (__hasOwnProp$y.call(b, prop)) + __defNormalProp$y(a, prop, b[prop]); + if (__getOwnPropSymbols$y) + for (var prop of __getOwnPropSymbols$y(b)) { + if (__propIsEnum$y.call(b, prop)) + __defNormalProp$y(a, prop, b[prop]); + } + return a; +}; +var __objRest$e = (source, exclude) => { + var target = {}; + for (var prop in source) + if (__hasOwnProp$y.call(source, prop) && exclude.indexOf(prop) < 0) + target[prop] = source[prop]; + if (source != null && __getOwnPropSymbols$y) + for (var prop of __getOwnPropSymbols$y(source)) { + if (exclude.indexOf(prop) < 0 && __propIsEnum$y.call(source, prop)) + target[prop] = source[prop]; + } + return target; +}; +const validSVGExtension = ".svg"; +const validSVGMIME = "image/svg+xml"; +const loadSvg = { + extension: { + type: ExtensionType.LoadParser, + priority: LoaderParserPriority.Low + }, + name: "loadSVG", + config: { + crossOrigin: "anonymous", + parseAsGraphicsContext: false + }, + test(url) { + return checkDataUrl(url, validSVGMIME) || checkExtension(url, validSVGExtension); + }, + async load(url, asset, loader) { + var _a; + if ((_a = asset.data.parseAsGraphicsContext) != null ? _a : this.config.parseAsGraphicsContext) { + return loadAsGraphics(url); + } + return loadAsTexture(url, asset, loader, this.config.crossOrigin); + }, + unload(asset) { + asset.destroy(true); + } +}; +async function loadAsTexture(url, asset, loader, crossOrigin) { + var _a, _b, _c, _d, _e; + const response = await DOMAdapter.get().fetch(url); + const blob = await response.blob(); + const blobUrl = URL.createObjectURL(blob); + const image = new Image(); + image.src = blobUrl; + image.crossOrigin = crossOrigin; + await image.decode(); + URL.revokeObjectURL(blobUrl); + const canvas = document.createElement("canvas"); + const context = canvas.getContext("2d"); + const resolution = ((_a = asset.data) == null ? void 0 : _a.resolution) || getResolutionOfUrl(url); + const width = (_c = (_b = asset.data) == null ? void 0 : _b.width) != null ? _c : image.width; + const height = (_e = (_d = asset.data) == null ? void 0 : _d.height) != null ? _e : image.height; + canvas.width = width * resolution; + canvas.height = height * resolution; + context.drawImage(image, 0, 0, width * resolution, height * resolution); + const _f = asset.data, { parseAsGraphicsContext: _p } = _f, rest = __objRest$e(_f, ["parseAsGraphicsContext"]); + const base = new ImageSource(__spreadValues$y({ + resource: canvas, + alphaMode: "premultiply-alpha-on-upload", + resolution + }, rest)); + return createTexture(base, loader, url); +} +async function loadAsGraphics(url) { + const response = await DOMAdapter.get().fetch(url); + const svgSource = await response.text(); + const context = new GraphicsContext(); + context.svg(svgSource); + return context; +} + +const WORKER_CODE$3 = "(function () {\n 'use strict';\n\n const WHITE_PNG = \"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mP8/x8AAwMCAO+ip1sAAAAASUVORK5CYII=\";\n async function checkImageBitmap() {\n try {\n if (typeof createImageBitmap !== \"function\")\n return false;\n const response = await fetch(WHITE_PNG);\n const imageBlob = await response.blob();\n const imageBitmap = await createImageBitmap(imageBlob);\n return imageBitmap.width === 1 && imageBitmap.height === 1;\n } catch (e) {\n return false;\n }\n }\n void checkImageBitmap().then((result) => {\n self.postMessage(result);\n });\n\n})();\n"; +let WORKER_URL$3 = null; +let WorkerInstance$3 = class WorkerInstance +{ + constructor() + { + if (!WORKER_URL$3) + { + WORKER_URL$3 = URL.createObjectURL(new Blob([WORKER_CODE$3], { type: 'application/javascript' })); + } + this.worker = new Worker(WORKER_URL$3); + } +}; +WorkerInstance$3.revokeObjectURL = function revokeObjectURL() +{ + if (WORKER_URL$3) + { + URL.revokeObjectURL(WORKER_URL$3); + WORKER_URL$3 = null; + } +}; + +const WORKER_CODE$2 = "(function () {\n 'use strict';\n\n async function loadImageBitmap(url) {\n const response = await fetch(url);\n if (!response.ok) {\n throw new Error(`[WorkerManager.loadImageBitmap] Failed to fetch ${url}: ${response.status} ${response.statusText}`);\n }\n const imageBlob = await response.blob();\n const imageBitmap = await createImageBitmap(imageBlob);\n return imageBitmap;\n }\n self.onmessage = async (event) => {\n try {\n const imageBitmap = await loadImageBitmap(event.data.data[0]);\n self.postMessage({\n data: imageBitmap,\n uuid: event.data.uuid,\n id: event.data.id\n }, [imageBitmap]);\n } catch (e) {\n self.postMessage({\n error: e,\n uuid: event.data.uuid,\n id: event.data.id\n });\n }\n };\n\n})();\n"; +let WORKER_URL$2 = null; +let WorkerInstance$2 = class WorkerInstance +{ + constructor() + { + if (!WORKER_URL$2) + { + WORKER_URL$2 = URL.createObjectURL(new Blob([WORKER_CODE$2], { type: 'application/javascript' })); + } + this.worker = new Worker(WORKER_URL$2); + } +}; +WorkerInstance$2.revokeObjectURL = function revokeObjectURL() +{ + if (WORKER_URL$2) + { + URL.revokeObjectURL(WORKER_URL$2); + WORKER_URL$2 = null; + } +}; + +"use strict"; +let UUID = 0; +let MAX_WORKERS; +class WorkerManagerClass { + constructor() { + this._initialized = false; + this._createdWorkers = 0; + this._workerPool = []; + this._queue = []; + this._resolveHash = {}; + } + isImageBitmapSupported() { + if (this._isImageBitmapSupported !== void 0) + return this._isImageBitmapSupported; + this._isImageBitmapSupported = new Promise((resolve) => { + const { worker } = new WorkerInstance$3(); + worker.addEventListener("message", (event) => { + worker.terminate(); + WorkerInstance$3.revokeObjectURL(); + resolve(event.data); + }); + }); + return this._isImageBitmapSupported; + } + loadImageBitmap(src) { + return this._run("loadImageBitmap", [src]); + } + async _initWorkers() { + if (this._initialized) + return; + this._initialized = true; + } + _getWorker() { + if (MAX_WORKERS === void 0) { + MAX_WORKERS = navigator.hardwareConcurrency || 4; + } + let worker = this._workerPool.pop(); + if (!worker && this._createdWorkers < MAX_WORKERS) { + this._createdWorkers++; + worker = new WorkerInstance$2().worker; + worker.addEventListener("message", (event) => { + this._complete(event.data); + this._returnWorker(event.target); + this._next(); + }); + } + return worker; + } + _returnWorker(worker) { + this._workerPool.push(worker); + } + _complete(data) { + if (data.error !== void 0) { + this._resolveHash[data.uuid].reject(data.error); + } else { + this._resolveHash[data.uuid].resolve(data.data); + } + this._resolveHash[data.uuid] = null; + } + async _run(id, args) { + await this._initWorkers(); + const promise = new Promise((resolve, reject) => { + this._queue.push({ id, arguments: args, resolve, reject }); + }); + this._next(); + return promise; + } + _next() { + if (!this._queue.length) + return; + const worker = this._getWorker(); + if (!worker) { + return; + } + const toDo = this._queue.pop(); + const id = toDo.id; + this._resolveHash[UUID] = { resolve: toDo.resolve, reject: toDo.reject }; + worker.postMessage({ + data: toDo.arguments, + uuid: UUID++, + id + }); + } +} +const WorkerManager = new WorkerManagerClass(); + +"use strict"; +var __defProp$x = Object.defineProperty; +var __getOwnPropSymbols$x = Object.getOwnPropertySymbols; +var __hasOwnProp$x = Object.prototype.hasOwnProperty; +var __propIsEnum$x = Object.prototype.propertyIsEnumerable; +var __defNormalProp$x = (obj, key, value) => key in obj ? __defProp$x(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; +var __spreadValues$x = (a, b) => { + for (var prop in b || (b = {})) + if (__hasOwnProp$x.call(b, prop)) + __defNormalProp$x(a, prop, b[prop]); + if (__getOwnPropSymbols$x) + for (var prop of __getOwnPropSymbols$x(b)) { + if (__propIsEnum$x.call(b, prop)) + __defNormalProp$x(a, prop, b[prop]); + } + return a; +}; +const validImageExtensions = [".jpeg", ".jpg", ".png", ".webp", ".avif"]; +const validImageMIMEs = [ + "image/jpeg", + "image/png", + "image/webp", + "image/avif" +]; +async function loadImageBitmap(url) { + const response = await DOMAdapter.get().fetch(url); + if (!response.ok) { + throw new Error(`[loadImageBitmap] Failed to fetch ${url}: ${response.status} ${response.statusText}`); + } + const imageBlob = await response.blob(); + const imageBitmap = await createImageBitmap(imageBlob); + return imageBitmap; +} +const loadTextures = { + name: "loadTextures", + extension: { + type: ExtensionType.LoadParser, + priority: LoaderParserPriority.High + }, + config: { + preferWorkers: true, + preferCreateImageBitmap: true, + crossOrigin: "anonymous" + }, + test(url) { + return checkDataUrl(url, validImageMIMEs) || checkExtension(url, validImageExtensions); + }, + async load(url, asset, loader) { + var _a; + let src = null; + if (globalThis.createImageBitmap && this.config.preferCreateImageBitmap) { + if (this.config.preferWorkers && await WorkerManager.isImageBitmapSupported()) { + src = await WorkerManager.loadImageBitmap(url); + } else { + src = await loadImageBitmap(url); + } + } else { + src = await new Promise((resolve) => { + src = new Image(); + src.crossOrigin = this.config.crossOrigin; + src.src = url; + if (src.complete) { + resolve(src); + } else { + src.onload = () => { + resolve(src); + }; + } + }); + } + const base = new ImageSource(__spreadValues$x({ + resource: src, + alphaMode: "premultiply-alpha-on-upload", + resolution: ((_a = asset.data) == null ? void 0 : _a.resolution) || getResolutionOfUrl(url) + }, asset.data)); + return createTexture(base, loader, url); + }, + unload(texture) { + texture.destroy(true); + } +}; + +"use strict"; +var __defProp$w = Object.defineProperty; +var __defProps$f = Object.defineProperties; +var __getOwnPropDescs$f = Object.getOwnPropertyDescriptors; +var __getOwnPropSymbols$w = Object.getOwnPropertySymbols; +var __hasOwnProp$w = Object.prototype.hasOwnProperty; +var __propIsEnum$w = Object.prototype.propertyIsEnumerable; +var __defNormalProp$w = (obj, key, value) => key in obj ? __defProp$w(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; +var __spreadValues$w = (a, b) => { + for (var prop in b || (b = {})) + if (__hasOwnProp$w.call(b, prop)) + __defNormalProp$w(a, prop, b[prop]); + if (__getOwnPropSymbols$w) + for (var prop of __getOwnPropSymbols$w(b)) { + if (__propIsEnum$w.call(b, prop)) + __defNormalProp$w(a, prop, b[prop]); + } + return a; +}; +var __spreadProps$f = (a, b) => __defProps$f(a, __getOwnPropDescs$f(b)); +const validVideoExtensions = [".mp4", ".m4v", ".webm", ".ogg", ".ogv", ".h264", ".avi", ".mov"]; +const validVideoMIMEs = validVideoExtensions.map((ext) => `video/${ext.substring(1)}`); +function crossOrigin(element, url, crossorigin) { + if (crossorigin === void 0 && !url.startsWith("data:")) { + element.crossOrigin = determineCrossOrigin(url); + } else if (crossorigin !== false) { + element.crossOrigin = typeof crossorigin === "string" ? crossorigin : "anonymous"; + } +} +function preloadVideo(element) { + return new Promise((resolve, reject) => { + element.addEventListener("canplaythrough", loaded); + element.addEventListener("error", error); + element.load(); + function loaded() { + cleanup(); + resolve(); + } + function error(err) { + cleanup(); + reject(err); + } + function cleanup() { + element.removeEventListener("canplaythrough", loaded); + element.removeEventListener("error", error); + } + }); +} +function determineCrossOrigin(url, loc = globalThis.location) { + if (url.startsWith("data:")) { + return ""; + } + loc = loc || globalThis.location; + const parsedUrl = new URL(url, document.baseURI); + if (parsedUrl.hostname !== loc.hostname || parsedUrl.port !== loc.port || parsedUrl.protocol !== loc.protocol) { + return "anonymous"; + } + return ""; +} +const loadVideoTextures = { + name: "loadVideo", + extension: { + type: ExtensionType.LoadParser + }, + config: null, + test(url) { + const isValidDataUrl = checkDataUrl(url, validVideoMIMEs); + const isValidExtension = checkExtension(url, validVideoExtensions); + return isValidDataUrl || isValidExtension; + }, + async load(url, asset, loader) { + var _a, _b; + const options = __spreadValues$w(__spreadProps$f(__spreadValues$w({}, VideoSource.defaultOptions), { + resolution: ((_a = asset.data) == null ? void 0 : _a.resolution) || getResolutionOfUrl(url), + alphaMode: ((_b = asset.data) == null ? void 0 : _b.alphaMode) || await detectVideoAlphaMode() + }), asset.data); + const videoElement = document.createElement("video"); + const attributeMap = { + preload: options.autoLoad !== false ? "auto" : void 0, + "webkit-playsinline": options.playsinline !== false ? "" : void 0, + playsinline: options.playsinline !== false ? "" : void 0, + muted: options.muted === true ? "" : void 0, + loop: options.loop === true ? "" : void 0, + autoplay: options.autoPlay !== false ? "" : void 0 + }; + Object.keys(attributeMap).forEach((key) => { + const value = attributeMap[key]; + if (value !== void 0) + videoElement.setAttribute(key, value); + }); + if (options.muted === true) { + videoElement.muted = true; + } + crossOrigin(videoElement, url, options.crossorigin); + const sourceElement = document.createElement("source"); + let mime; + if (url.startsWith("data:")) { + mime = url.slice(5, url.indexOf(";")); + } else if (!url.startsWith("blob:")) { + const ext = url.split("?")[0].slice(url.lastIndexOf(".") + 1).toLowerCase(); + mime = VideoSource.MIME_TYPES[ext] || `video/${ext}`; + } + sourceElement.src = url; + if (mime) { + sourceElement.type = mime; + } + return new Promise((resolve) => { + const onCanPlay = async () => { + const base = new VideoSource(__spreadProps$f(__spreadValues$w({}, options), { resource: videoElement })); + videoElement.removeEventListener("canplay", onCanPlay); + if (asset.data.preload) { + await preloadVideo(videoElement); + } + resolve(createTexture(base, loader, url)); + }; + videoElement.addEventListener("canplay", onCanPlay); + videoElement.appendChild(sourceElement); + }); + }, + unload(texture) { + texture.destroy(true); + } +}; + +"use strict"; +const resolveTextureUrl = { + extension: ExtensionType.ResolveParser, + test: loadTextures.test, + parse: (value) => { + var _a, _b; + return { + resolution: parseFloat((_b = (_a = Resolver.RETINA_PREFIX.exec(value)) == null ? void 0 : _a[1]) != null ? _b : "1"), + format: value.split(".").pop(), + src: value + }; + } +}; + +"use strict"; +const resolveJsonUrl = { + extension: ExtensionType.ResolveParser, + test: (value) => Resolver.RETINA_PREFIX.test(value) && value.endsWith(".json"), + parse: resolveTextureUrl.parse +}; + +"use strict"; +class AssetsClass { + constructor() { + this._detections = []; + this._initialized = false; + this.resolver = new Resolver(); + this.loader = new Loader(); + this.cache = Cache; + this._backgroundLoader = new BackgroundLoader(this.loader); + this._backgroundLoader.active = true; + this.reset(); + } + /** + * Best practice is to call this function before any loading commences + * Initiating is the best time to add any customization to the way things are loaded. + * + * you do not need to call this for the Assets class to work, only if you want to set any initial properties + * @param options - options to initialize the Assets manager with + */ + async init(options = {}) { + var _a, _b, _c; + if (this._initialized) { + warn("[Assets]AssetManager already initialized, did you load before calling this Assets.init()?"); + return; + } + this._initialized = true; + if (options.defaultSearchParams) { + this.resolver.setDefaultSearchParams(options.defaultSearchParams); + } + if (options.basePath) { + this.resolver.basePath = options.basePath; + } + if (options.bundleIdentifier) { + this.resolver.setBundleIdentifier(options.bundleIdentifier); + } + if (options.manifest) { + let manifest = options.manifest; + if (typeof manifest === "string") { + manifest = await this.load(manifest); + } + this.resolver.addManifest(manifest); + } + const resolutionPref = (_b = (_a = options.texturePreference) == null ? void 0 : _a.resolution) != null ? _b : 1; + const resolution = typeof resolutionPref === "number" ? [resolutionPref] : resolutionPref; + const formats = await this._detectFormats({ + preferredFormats: (_c = options.texturePreference) == null ? void 0 : _c.format, + skipDetections: options.skipDetections, + detections: this._detections + }); + this.resolver.prefer({ + params: { + format: formats, + resolution + } + }); + if (options.preferences) { + this.setPreferences(options.preferences); + } + } + /** + * Allows you to specify how to resolve any assets load requests. + * There are a few ways to add things here as shown below: + * @example + * import { Assets } from 'pixi.js'; + * + * // Simple + * Assets.add({alias: 'bunnyBooBoo', src: 'bunny.png'}); + * const bunny = await Assets.load('bunnyBooBoo'); + * + * // Multiple keys: + * Assets.add({alias: ['burger', 'chicken'], src: 'bunny.png'}); + * + * const bunny = await Assets.load('burger'); + * const bunny2 = await Assets.load('chicken'); + * + * // passing options to to the object + * Assets.add({ + * alias: 'bunnyBooBooSmooth', + * src: 'bunny{png,webp}', + * data: { scaleMode: SCALE_MODES.NEAREST }, // Base texture options + * }); + * + * // Multiple assets + * + * // The following all do the same thing: + * + * Assets.add({alias: 'bunnyBooBoo', src: 'bunny{png,webp}'}); + * + * Assets.add({ + * alias: 'bunnyBooBoo', + * src: [ + * 'bunny.png', + * 'bunny.webp', + * ], + * }); + * + * const bunny = await Assets.load('bunnyBooBoo'); // Will try to load WebP if available + * @param assets - the unresolved assets to add to the resolver + */ + add(assets) { + this.resolver.add(assets); + } + async load(urls, onProgress) { + if (!this._initialized) { + await this.init(); + } + const singleAsset = isSingleItem(urls); + const urlArray = convertToList(urls).map((url) => { + if (typeof url !== "string") { + const aliases = this.resolver.getAlias(url); + if (aliases.some((alias) => !this.resolver.hasKey(alias))) { + this.add(url); + } + return Array.isArray(aliases) ? aliases[0] : aliases; + } + if (!this.resolver.hasKey(url)) + this.add({ alias: url, src: url }); + return url; + }); + const resolveResults = this.resolver.resolve(urlArray); + const out = await this._mapLoadToResolve(resolveResults, onProgress); + return singleAsset ? out[urlArray[0]] : out; + } + /** + * This adds a bundle of assets in one go so that you can load them as a group. + * For example you could add a bundle for each screen in you pixi app + * @example + * import { Assets } from 'pixi.js'; + * + * Assets.addBundle('animals', [ + * { alias: 'bunny', src: 'bunny.png' }, + * { alias: 'chicken', src: 'chicken.png' }, + * { alias: 'thumper', src: 'thumper.png' }, + * ]); + * // or + * Assets.addBundle('animals', { + * bunny: 'bunny.png', + * chicken: 'chicken.png', + * thumper: 'thumper.png', + * }); + * + * const assets = await Assets.loadBundle('animals'); + * @param bundleId - the id of the bundle to add + * @param assets - a record of the asset or assets that will be chosen from when loading via the specified key + */ + addBundle(bundleId, assets) { + this.resolver.addBundle(bundleId, assets); + } + /** + * Bundles are a way to load multiple assets at once. + * If a manifest has been provided to the init function then you can load a bundle, or bundles. + * you can also add bundles via `addBundle` + * @example + * import { Assets } from 'pixi.js'; + * + * // Manifest Example + * const manifest = { + * bundles: [ + * { + * name: 'load-screen', + * assets: [ + * { + * alias: 'background', + * src: 'sunset.png', + * }, + * { + * alias: 'bar', + * src: 'load-bar.{png,webp}', + * }, + * ], + * }, + * { + * name: 'game-screen', + * assets: [ + * { + * alias: 'character', + * src: 'robot.png', + * }, + * { + * alias: 'enemy', + * src: 'bad-guy.png', + * }, + * ], + * }, + * ] + * }; + * + * await Assets.init({ manifest }); + * + * // Load a bundle... + * loadScreenAssets = await Assets.loadBundle('load-screen'); + * // Load another bundle... + * gameScreenAssets = await Assets.loadBundle('game-screen'); + * @param bundleIds - the bundle id or ids to load + * @param onProgress - Optional function that is called when progress on asset loading is made. + * The function is passed a single parameter, `progress`, which represents the percentage (0.0 - 1.0) + * of the assets loaded. Do not use this function to detect when assets are complete and available, + * instead use the Promise returned by this function. + * @returns all the bundles assets or a hash of assets for each bundle specified + */ + async loadBundle(bundleIds, onProgress) { + if (!this._initialized) { + await this.init(); + } + let singleAsset = false; + if (typeof bundleIds === "string") { + singleAsset = true; + bundleIds = [bundleIds]; + } + const resolveResults = this.resolver.resolveBundle(bundleIds); + const out = {}; + const keys = Object.keys(resolveResults); + let count = 0; + let total = 0; + const _onProgress = () => { + onProgress == null ? void 0 : onProgress(++count / total); + }; + const promises = keys.map((bundleId) => { + const resolveResult = resolveResults[bundleId]; + total += Object.keys(resolveResult).length; + return this._mapLoadToResolve(resolveResult, _onProgress).then((resolveResult2) => { + out[bundleId] = resolveResult2; + }); + }); + await Promise.all(promises); + return singleAsset ? out[bundleIds[0]] : out; + } + /** + * Initiate a background load of some assets. It will passively begin to load these assets in the background. + * So when you actually come to loading them you will get a promise that resolves to the loaded assets immediately + * + * An example of this might be that you would background load game assets after your inital load. + * then when you got to actually load your game screen assets when a player goes to the game - the loading + * would already have stared or may even be complete, saving you having to show an interim load bar. + * @example + * import { Assets } from 'pixi.js'; + * + * Assets.backgroundLoad('bunny.png'); + * + * // later on in your app... + * await Assets.loadBundle('bunny.png'); // Will resolve quicker as loading may have completed! + * @param urls - the url / urls you want to background load + */ + async backgroundLoad(urls) { + if (!this._initialized) { + await this.init(); + } + if (typeof urls === "string") { + urls = [urls]; + } + const resolveResults = this.resolver.resolve(urls); + this._backgroundLoader.add(Object.values(resolveResults)); + } + /** + * Initiate a background of a bundle, works exactly like backgroundLoad but for bundles. + * this can only be used if the loader has been initiated with a manifest + * @example + * import { Assets } from 'pixi.js'; + * + * await Assets.init({ + * manifest: { + * bundles: [ + * { + * name: 'load-screen', + * assets: [...], + * }, + * ... + * ], + * }, + * }); + * + * Assets.backgroundLoadBundle('load-screen'); + * + * // Later on in your app... + * await Assets.loadBundle('load-screen'); // Will resolve quicker as loading may have completed! + * @param bundleIds - the bundleId / bundleIds you want to background load + */ + async backgroundLoadBundle(bundleIds) { + if (!this._initialized) { + await this.init(); + } + if (typeof bundleIds === "string") { + bundleIds = [bundleIds]; + } + const resolveResults = this.resolver.resolveBundle(bundleIds); + Object.values(resolveResults).forEach((resolveResult) => { + this._backgroundLoader.add(Object.values(resolveResult)); + }); + } + /** + * Only intended for development purposes. + * This will wipe the resolver and caches. + * You will need to reinitialize the Asset + */ + reset() { + this.resolver.reset(); + this.loader.reset(); + this.cache.reset(); + this._initialized = false; + } + get(keys) { + if (typeof keys === "string") { + return Cache.get(keys); + } + const assets = {}; + for (let i = 0; i < keys.length; i++) { + assets[i] = Cache.get(keys[i]); + } + return assets; + } + /** + * helper function to map resolved assets back to loaded assets + * @param resolveResults - the resolve results from the resolver + * @param onProgress - the progress callback + */ + async _mapLoadToResolve(resolveResults, onProgress) { + const resolveArray = [...new Set(Object.values(resolveResults))]; + this._backgroundLoader.active = false; + const loadedAssets = await this.loader.load(resolveArray, onProgress); + this._backgroundLoader.active = true; + const out = {}; + resolveArray.forEach((resolveResult) => { + const asset = loadedAssets[resolveResult.src]; + const keys = [resolveResult.src]; + if (resolveResult.alias) { + keys.push(...resolveResult.alias); + } + keys.forEach((key) => { + out[key] = asset; + }); + Cache.set(keys, asset); + }); + return out; + } + /** + * Unload an asset or assets. As the Assets class is responsible for creating the assets via the `load` function + * this will make sure to destroy any assets and release them from memory. + * Once unloaded, you will need to load the asset again. + * + * Use this to help manage assets if you find that you have a large app and you want to free up memory. + * + * - it's up to you as the developer to make sure that textures are not actively being used when you unload them, + * Pixi won't break but you will end up with missing assets. Not a good look for the user! + * @example + * import { Assets } from 'pixi.js'; + * + * // Load a URL: + * const myImageTexture = await Assets.load('http://some.url.com/image.png'); // => returns a texture + * + * await Assets.unload('http://some.url.com/image.png') + * + * // myImageTexture will be destroyed now. + * + * // Unload multiple assets: + * const textures = await Assets.unload(['thumper', 'chicko']); + * @param urls - the urls to unload + */ + async unload(urls) { + if (!this._initialized) { + await this.init(); + } + const urlArray = convertToList(urls).map((url) => typeof url !== "string" ? url.src : url); + const resolveResults = this.resolver.resolve(urlArray); + await this._unloadFromResolved(resolveResults); + } + /** + * Bundles are a way to manage multiple assets at once. + * this will unload all files in a bundle. + * + * once a bundle has been unloaded, you need to load it again to have access to the assets. + * @example + * import { Assets } from 'pixi.js'; + * + * Assets.addBundle({ + * 'thumper': 'http://some.url.com/thumper.png', + * }) + * + * const assets = await Assets.loadBundle('thumper'); + * + * // Now to unload... + * + * await Assets.unloadBundle('thumper'); + * + * // All assets in the assets object will now have been destroyed and purged from the cache + * @param bundleIds - the bundle id or ids to unload + */ + async unloadBundle(bundleIds) { + if (!this._initialized) { + await this.init(); + } + bundleIds = convertToList(bundleIds); + const resolveResults = this.resolver.resolveBundle(bundleIds); + const promises = Object.keys(resolveResults).map((bundleId) => this._unloadFromResolved(resolveResults[bundleId])); + await Promise.all(promises); + } + async _unloadFromResolved(resolveResult) { + const resolveArray = Object.values(resolveResult); + resolveArray.forEach((resolveResult2) => { + Cache.remove(resolveResult2.src); + }); + await this.loader.unload(resolveArray); + } + /** + * Detects the supported formats for the browser, and returns an array of supported formats, respecting + * the users preferred formats order. + * @param options - the options to use when detecting formats + * @param options.preferredFormats - the preferred formats to use + * @param options.skipDetections - if we should skip the detections altogether + * @param options.detections - the detections to use + * @returns - the detected formats + */ + async _detectFormats(options) { + let formats = []; + if (options.preferredFormats) { + formats = Array.isArray(options.preferredFormats) ? options.preferredFormats : [options.preferredFormats]; + } + for (const detection of options.detections) { + if (options.skipDetections || await detection.test()) { + formats = await detection.add(formats); + } else if (!options.skipDetections) { + formats = await detection.remove(formats); + } + } + formats = formats.filter((format, index) => formats.indexOf(format) === index); + return formats; + } + /** All the detection parsers currently added to the Assets class. */ + get detections() { + return this._detections; + } + /** + * General setter for preferences. This is a helper function to set preferences on all parsers. + * @param preferences - the preferences to set + */ + setPreferences(preferences) { + this.loader.parsers.forEach((parser) => { + if (!parser.config) + return; + Object.keys(parser.config).filter((key) => key in preferences).forEach((key) => { + parser.config[key] = preferences[key]; + }); + }); + } +} +const Assets = new AssetsClass(); +extensions.handleByList(ExtensionType.LoadParser, Assets.loader.parsers).handleByList(ExtensionType.ResolveParser, Assets.resolver.parsers).handleByList(ExtensionType.CacheParser, Assets.cache.parsers).handleByList(ExtensionType.DetectionParser, Assets.detections); +extensions.add( + cacheTextureArray, + detectDefaults, + detectAvif, + detectWebp, + detectMp4, + detectOgv, + detectWebm, + loadJson, + loadTxt, + loadWebFont, + loadSvg, + loadTextures, + loadVideoTextures, + resolveTextureUrl, + resolveJsonUrl +); +const assetKeyMap = { + loader: ExtensionType.LoadParser, + resolver: ExtensionType.ResolveParser, + cache: ExtensionType.CacheParser, + detection: ExtensionType.DetectionParser +}; +extensions.handle(ExtensionType.Asset, (extension) => { + const ref = extension.ref; + Object.entries(assetKeyMap).filter(([key]) => !!ref[key]).forEach(([key, type]) => { + var _a; + return extensions.add(Object.assign( + ref[key], + // Allow the function to optionally define it's own + // ExtensionMetadata, the use cases here is priority for LoaderParsers + { extension: (_a = ref[key].extension) != null ? _a : type } + )); + }); +}, (extension) => { + const ref = extension.ref; + Object.keys(assetKeyMap).filter((key) => !!ref[key]).forEach((key) => extensions.remove(ref[key])); +}); + +"use strict"; + +"use strict"; + +"use strict"; + +"use strict"; + +"use strict"; + +"use strict"; + +"use strict"; + +"use strict"; +const detectBasis = { + extension: { + type: ExtensionType.DetectionParser, + priority: 3 + }, + test: async () => { + if (await isWebGPUSupported()) + return true; + if (isWebGLSupported()) + return true; + return false; + }, + add: async (formats) => [...formats, "basis"], + remove: async (formats) => formats.filter((f) => f !== "basis") +}; + +"use strict"; +class CompressedSource extends TextureSource { + constructor(options) { + super(options); + this.uploadMethodId = "compressed"; + this.resource = options.resource; + this.mipLevelCount = this.resource.length; + } +} + +"use strict"; +let supportedGLCompressedTextureFormats; +function getSupportedGlCompressedTextureFormats() { + if (supportedGLCompressedTextureFormats) + return supportedGLCompressedTextureFormats; + const canvas = document.createElement("canvas"); + const gl = canvas.getContext("webgl"); + if (!gl) { + return []; + } + supportedGLCompressedTextureFormats = [ + // BC compressed formats usable if "texture-compression-bc" is both + // supported by the device/user agent and enabled in requestDevice. + // 'bc6h-rgb-ufloat' + // 'bc6h-rgb-float' + // 'bc7-rgba-unorm', + // 'bc7-rgba-unorm-srgb', + ...gl.getExtension("EXT_texture_compression_bptc") ? [ + "bc6h-rgb-ufloat", + "bc6h-rgb-float", + "bc7-rgba-unorm", + "bc7-rgba-unorm-srgb" + ] : [], + // BC compressed formats usable if "texture-compression-bc" is both + // supported by the device/user agent and enabled in requestDevice. + // 'bc1-rgba-unorm', + // 'bc1-rgba-unorm-srgb', + // 'bc4-r-unorm' + // 'bc4-r-snorm' + // 'bc5-rg-unorm' + // 'bc5-rg-snorm' + ...gl.getExtension("WEBGL_compressed_texture_s3tc") ? [ + "bc1-rgba-unorm", + "bc2-rgba-unorm", + "bc3-rgba-unorm" + ] : [], + ...gl.getExtension("WEBGL_compressed_texture_s3tc_srgb") ? [ + "bc1-rgba-unorm-srgb", + "bc2-rgba-unorm-srgb", + "bc3-rgba-unorm-srgb" + ] : [], + ...gl.getExtension("EXT_texture_compression_rgtc") ? [ + "bc4-r-unorm", + "bc4-r-snorm", + "bc5-rg-unorm", + "bc5-rg-snorm" + ] : [], + // ETC2 compressed formats usable if "texture-compression-etc2" is both + // supported by the device/user agent and enabled in requestDevice. + ...gl.getExtension("WEBGL_compressed_texture_etc") ? [ + "etc2-rgb8unorm", + "etc2-rgb8unorm-srgb", + "etc2-rgba8unorm", + "etc2-rgba8unorm-srgb", + "etc2-rgb8a1unorm", + "etc2-rgb8a1unorm-srgb", + "eac-r11unorm", + "eac-rg11unorm" + ] : [], + // 'eac-r11snorm', + // 'eac-rg11snorm', + // ASTC compressed formats usable if "texture-compression-astc" is both + // supported by the device/user agent and enabled in requestDevice. + ...gl.getExtension("WEBGL_compressed_texture_astc") ? [ + "astc-4x4-unorm", + "astc-4x4-unorm-srgb", + "astc-5x4-unorm", + "astc-5x4-unorm-srgb", + "astc-5x5-unorm", + "astc-5x5-unorm-srgb", + "astc-6x5-unorm", + "astc-6x5-unorm-srgb", + "astc-6x6-unorm", + "astc-6x6-unorm-srgb", + "astc-8x5-unorm", + "astc-8x5-unorm-srgb", + "astc-8x6-unorm", + "astc-8x6-unorm-srgb", + "astc-8x8-unorm", + "astc-8x8-unorm-srgb", + "astc-10x5-unorm", + "astc-10x5-unorm-srgb", + "astc-10x6-unorm", + "astc-10x6-unorm-srgb", + "astc-10x8-unorm", + "astc-10x8-unorm-srgb", + "astc-10x10-unorm", + "astc-10x10-unorm-srgb", + "astc-12x10-unorm", + "astc-12x10-unorm-srgb", + "astc-12x12-unorm", + "astc-12x12-unorm-srgb" + ] : [] + ]; + return supportedGLCompressedTextureFormats; +} + +"use strict"; +let supportedGPUCompressedTextureFormats; +async function getSupportedGPUCompressedTextureFormats() { + if (supportedGPUCompressedTextureFormats) + return supportedGPUCompressedTextureFormats; + const adapter = await navigator.gpu.requestAdapter(); + supportedGPUCompressedTextureFormats = [ + ...adapter.features.has("texture-compression-bc") ? [ + // BC compressed formats usable if "texture-compression-bc" is both + // supported by the device/user agent and enabled in requestDevice. + "bc1-rgba-unorm", + "bc1-rgba-unorm-srgb", + "bc2-rgba-unorm", + "bc2-rgba-unorm-srgb", + "bc3-rgba-unorm", + "bc3-rgba-unorm-srgb", + "bc4-r-unorm", + "bc4-r-snorm", + "bc5-rg-unorm", + "bc5-rg-snorm", + "bc6h-rgb-ufloat", + "bc6h-rgb-float", + "bc7-rgba-unorm", + "bc7-rgba-unorm-srgb" + ] : [], + ...adapter.features.has("texture-compression-etc2") ? [ + // ETC2 compressed formats usable if "texture-compression-etc2" is both + // supported by the device/user agent and enabled in requestDevice. + "etc2-rgb8unorm", + "etc2-rgb8unorm-srgb", + "etc2-rgb8a1unorm", + "etc2-rgb8a1unorm-srgb", + "etc2-rgba8unorm", + "etc2-rgba8unorm-srgb", + "eac-r11unorm", + "eac-r11snorm", + "eac-rg11unorm", + "eac-rg11snorm" + ] : [], + ...adapter.features.has("texture-compression-astc") ? [ + // ASTC compressed formats usable if "texture-compression-astc" is both + // supported by the device/user agent and enabled in requestDevice. + "astc-4x4-unorm", + "astc-4x4-unorm-srgb", + "astc-5x4-unorm", + "astc-5x4-unorm-srgb", + "astc-5x5-unorm", + "astc-5x5-unorm-srgb", + "astc-6x5-unorm", + "astc-6x5-unorm-srgb", + "astc-6x6-unorm", + "astc-6x6-unorm-srgb", + "astc-8x5-unorm", + "astc-8x5-unorm-srgb", + "astc-8x6-unorm", + "astc-8x6-unorm-srgb", + "astc-8x8-unorm", + "astc-8x8-unorm-srgb", + "astc-10x5-unorm", + "astc-10x5-unorm-srgb", + "astc-10x6-unorm", + "astc-10x6-unorm-srgb", + "astc-10x8-unorm", + "astc-10x8-unorm-srgb", + "astc-10x10-unorm", + "astc-10x10-unorm-srgb", + "astc-12x10-unorm", + "astc-12x10-unorm-srgb", + "astc-12x12-unorm", + "astc-12x12-unorm-srgb" + ] : [] + ]; + return supportedGPUCompressedTextureFormats; +} + +"use strict"; +let supportedCompressedTextureFormats; +async function getSupportedCompressedTextureFormats() { + if (supportedCompressedTextureFormats !== void 0) + return supportedCompressedTextureFormats; + supportedCompressedTextureFormats = await (async () => { + const _isWebGPUSupported = await isWebGPUSupported(); + const _isWebGLSupported = isWebGLSupported(); + if (_isWebGPUSupported && _isWebGLSupported) { + const gpuTextureFormats = await getSupportedGPUCompressedTextureFormats(); + const glTextureFormats = getSupportedGlCompressedTextureFormats(); + return gpuTextureFormats.filter((format) => glTextureFormats.includes(format)); + } else if (_isWebGPUSupported) { + return await getSupportedGPUCompressedTextureFormats(); + } else if (_isWebGLSupported) { + return getSupportedGlCompressedTextureFormats(); + } + return []; + })(); + return supportedCompressedTextureFormats; +} + +"use strict"; +const nonCompressedFormats = [ + // 8-bit formats + "r8unorm", + "r8snorm", + "r8uint", + "r8sint", + // 16-bit formats + "r16uint", + "r16sint", + "r16float", + "rg8unorm", + "rg8snorm", + "rg8uint", + "rg8sint", + // 32-bit formats + "r32uint", + "r32sint", + "r32float", + "rg16uint", + "rg16sint", + "rg16float", + "rgba8unorm", + "rgba8unorm-srgb", + "rgba8snorm", + "rgba8uint", + "rgba8sint", + "bgra8unorm", + "bgra8unorm-srgb", + // Packed 32-bit formats + "rgb9e5ufloat", + "rgb10a2unorm", + "rg11b10ufloat", + // 64-bit formats + "rg32uint", + "rg32sint", + "rg32float", + "rgba16uint", + "rgba16sint", + "rgba16float", + // 128-bit formats + "rgba32uint", + "rgba32sint", + "rgba32float", + // Depth/stencil formats + "stencil8", + "depth16unorm", + "depth24plus", + "depth24plus-stencil8", + "depth32float", + // "depth32float-stencil8" feature + "depth32float-stencil8" +]; +let supportedTextureFormats; +async function getSupportedTextureFormats() { + if (supportedTextureFormats !== void 0) + return supportedTextureFormats; + const compressedTextureFormats = await getSupportedCompressedTextureFormats(); + supportedTextureFormats = [ + ...nonCompressedFormats, + ...compressedTextureFormats + ]; + return supportedTextureFormats; +} + +const WORKER_CODE$1 = "(function () {\n 'use strict';\n\n function createLevelBuffers(basisTexture, basisTranscoderFormat) {\n const images = basisTexture.getNumImages();\n const levels = basisTexture.getNumLevels(0);\n const success = basisTexture.startTranscoding();\n if (!success) {\n throw new Error(\"startTranscoding failed\");\n }\n const levelBuffers = [];\n for (let levelIndex = 0; levelIndex < levels; ++levelIndex) {\n for (let sliceIndex = 0; sliceIndex < images; ++sliceIndex) {\n const transcodeSize = basisTexture.getImageTranscodedSizeInBytes(sliceIndex, levelIndex, basisTranscoderFormat);\n const levelBuffer = new Uint8Array(transcodeSize);\n const success2 = basisTexture.transcodeImage(levelBuffer, sliceIndex, levelIndex, basisTranscoderFormat, 1, 0);\n if (!success2) {\n throw new Error(\"transcodeImage failed\");\n }\n levelBuffers.push(levelBuffer);\n }\n }\n return levelBuffers;\n }\n\n const gpuFormatToBasisTranscoderFormatMap = {\n \"bc3-rgba-unorm\": 3,\n // cTFBC3_RGBA\n \"bc7-rgba-unorm\": 6,\n // cTFBC7_RGBA,\n \"etc2-rgba8unorm\": 1,\n // cTFETC2_RGBA,\n \"astc-4x4-unorm\": 10,\n // cTFASTC_4x4_RGBA,\n // Uncompressed\n rgba8unorm: 13,\n // cTFRGBA32,\n rgba4unorm: 16\n // cTFRGBA4444,\n };\n function gpuFormatToBasisTranscoderFormat(transcoderFormat) {\n const format = gpuFormatToBasisTranscoderFormatMap[transcoderFormat];\n if (format) {\n return format;\n }\n throw new Error(`Unsupported transcoderFormat: ${transcoderFormat}`);\n }\n\n const settings = {\n jsUrl: \"basis/basis_transcoder.js\",\n wasmUrl: \"basis/basis_transcoder.wasm\"\n };\n let basisTranscoderFormat;\n let basisTranscodedTextureFormat;\n let basisPromise;\n async function getBasis() {\n if (!basisPromise) {\n const absoluteJsUrl = new URL(settings.jsUrl, location.origin).href;\n const absoluteWasmUrl = new URL(settings.wasmUrl, location.origin).href;\n importScripts(absoluteJsUrl);\n basisPromise = new Promise((resolve) => {\n BASIS({\n locateFile: (_file) => absoluteWasmUrl\n }).then((module) => {\n module.initializeBasis();\n resolve(module.BasisFile);\n });\n });\n }\n return basisPromise;\n }\n async function fetchBasisTexture(url, BasisTexture) {\n const basisResponse = await fetch(url);\n if (basisResponse.ok) {\n const basisArrayBuffer = await basisResponse.arrayBuffer();\n return new BasisTexture(new Uint8Array(basisArrayBuffer));\n }\n throw new Error(`Failed to load Basis texture: ${url}`);\n }\n const preferredTranscodedFormat = [\n \"bc7-rgba-unorm\",\n \"astc-4x4-unorm\",\n \"etc2-rgba8unorm\",\n \"bc3-rgba-unorm\",\n \"rgba8unorm\"\n ];\n async function load(url) {\n const BasisTexture = await getBasis();\n const basisTexture = await fetchBasisTexture(url, BasisTexture);\n const levelBuffers = createLevelBuffers(basisTexture, basisTranscoderFormat);\n return {\n width: basisTexture.getImageWidth(0, 0),\n height: basisTexture.getImageHeight(0, 0),\n format: basisTranscodedTextureFormat,\n resource: levelBuffers,\n alphaMode: \"no-premultiply-alpha\"\n };\n }\n async function init(jsUrl, wasmUrl, supportedTextures) {\n if (jsUrl)\n settings.jsUrl = jsUrl;\n if (wasmUrl)\n settings.wasmUrl = wasmUrl;\n basisTranscodedTextureFormat = preferredTranscodedFormat.filter((format) => supportedTextures.includes(format))[0];\n basisTranscoderFormat = gpuFormatToBasisTranscoderFormat(basisTranscodedTextureFormat);\n await getBasis();\n }\n const messageHandlers = {\n init: async (data) => {\n const { jsUrl, wasmUrl, supportedTextures } = data;\n await init(jsUrl, wasmUrl, supportedTextures);\n },\n load: async (data) => {\n var _a;\n try {\n const textureOptions = await load(data.url);\n return {\n type: \"load\",\n url: data.url,\n success: true,\n textureOptions,\n transferables: (_a = textureOptions.resource) == null ? void 0 : _a.map((arr) => arr.buffer)\n };\n } catch (e) {\n throw e;\n }\n }\n };\n self.onmessage = async (messageEvent) => {\n const message = messageEvent.data;\n const response = await messageHandlers[message.type](message);\n if (response) {\n self.postMessage(response, response.transferables);\n }\n };\n\n})();\n"; +let WORKER_URL$1 = null; +let WorkerInstance$1 = class WorkerInstance +{ + constructor() + { + if (!WORKER_URL$1) + { + WORKER_URL$1 = URL.createObjectURL(new Blob([WORKER_CODE$1], { type: 'application/javascript' })); + } + this.worker = new Worker(WORKER_URL$1); + } +}; +WorkerInstance$1.revokeObjectURL = function revokeObjectURL() +{ + if (WORKER_URL$1) + { + URL.revokeObjectURL(WORKER_URL$1); + WORKER_URL$1 = null; + } +}; + +"use strict"; +const basisTranscoderUrls = { + jsUrl: "https://files.pixijs.download/transcoders/basis/basis_transcoder.js", + wasmUrl: "https://files.pixijs.download/transcoders/basis/basis_transcoder.wasm" +}; +function setBasisTranscoderPath(config) { + Object.assign(basisTranscoderUrls, config); +} + +"use strict"; +let basisWorker; +const urlHash$1 = {}; +function getBasisWorker(supportedTextures) { + if (!basisWorker) { + basisWorker = new WorkerInstance$1().worker; + basisWorker.onmessage = (messageEvent) => { + const { success, url, textureOptions } = messageEvent.data; + if (!success) { + console.warn("Failed to load Basis texture", url); + } + urlHash$1[url](textureOptions); + }; + basisWorker.postMessage({ + type: "init", + jsUrl: basisTranscoderUrls.jsUrl, + wasmUrl: basisTranscoderUrls.wasmUrl, + supportedTextures + }); + } + return basisWorker; +} +function loadBasisOnWorker(url, supportedTextures) { + const ktxWorker = getBasisWorker(supportedTextures); + return new Promise((resolve) => { + urlHash$1[url] = resolve; + ktxWorker.postMessage({ type: "load", url }); + }); +} + +"use strict"; +const loadBasis = { + extension: { + type: ExtensionType.LoadParser, + priority: LoaderParserPriority.High + }, + name: "loadBasis", + test(url) { + return checkExtension(url, [".basis"]); + }, + async load(url, _asset, loader) { + const supportedTextures = await getSupportedTextureFormats(); + const textureOptions = await loadBasisOnWorker(url, supportedTextures); + const compressedTextureSource = new CompressedSource(textureOptions); + return createTexture(compressedTextureSource, loader, url); + }, + unload(texture) { + if (Array.isArray(texture)) { + texture.forEach((t) => t.destroy(true)); + } else { + texture.destroy(true); + } + } +}; + +"use strict"; + +"use strict"; +function createLevelBuffers(basisTexture, basisTranscoderFormat) { + const images = basisTexture.getNumImages(); + const levels = basisTexture.getNumLevels(0); + const success = basisTexture.startTranscoding(); + if (!success) { + throw new Error("startTranscoding failed"); + } + const levelBuffers = []; + for (let levelIndex = 0; levelIndex < levels; ++levelIndex) { + for (let sliceIndex = 0; sliceIndex < images; ++sliceIndex) { + const transcodeSize = basisTexture.getImageTranscodedSizeInBytes(sliceIndex, levelIndex, basisTranscoderFormat); + const levelBuffer = new Uint8Array(transcodeSize); + const success2 = basisTexture.transcodeImage(levelBuffer, sliceIndex, levelIndex, basisTranscoderFormat, 1, 0); + if (!success2) { + throw new Error("transcodeImage failed"); + } + levelBuffers.push(levelBuffer); + } + } + return levelBuffers; +} + +"use strict"; +const gpuFormatToBasisTranscoderFormatMap$1 = { + "bc3-rgba-unorm": 3, + // cTFBC3_RGBA + "bc7-rgba-unorm": 6, + // cTFBC7_RGBA, + "etc2-rgba8unorm": 1, + // cTFETC2_RGBA, + "astc-4x4-unorm": 10, + // cTFASTC_4x4_RGBA, + // Uncompressed + rgba8unorm: 13, + // cTFRGBA32, + rgba4unorm: 16 + // cTFRGBA4444, +}; +function gpuFormatToBasisTranscoderFormat(transcoderFormat) { + const format = gpuFormatToBasisTranscoderFormatMap$1[transcoderFormat]; + if (format) { + return format; + } + throw new Error(`Unsupported transcoderFormat: ${transcoderFormat}`); +} + +"use strict"; +const DDS_HEADER_FIELDS = { + MAGIC: 0, + SIZE: 1, + FLAGS: 2, + HEIGHT: 3, + WIDTH: 4, + MIPMAP_COUNT: 7, + PIXEL_FORMAT: 19, + PF_FLAGS: 20, + FOURCC: 21, + RGB_BITCOUNT: 22, + R_BIT_MASK: 23, + G_BIT_MASK: 24, + B_BIT_MASK: 25, + A_BIT_MASK: 26 +}; +const DDS_DX10_FIELDS = { + DXGI_FORMAT: 0, + RESOURCE_DIMENSION: 1, + MISC_FLAG: 2, + ARRAY_SIZE: 3, + MISC_FLAGS2: 4 +}; +var DXGI_FORMAT = /* @__PURE__ */ ((DXGI_FORMAT2) => { + DXGI_FORMAT2[DXGI_FORMAT2["DXGI_FORMAT_UNKNOWN"] = 0] = "DXGI_FORMAT_UNKNOWN"; + DXGI_FORMAT2[DXGI_FORMAT2["DXGI_FORMAT_R32G32B32A32_TYPELESS"] = 1] = "DXGI_FORMAT_R32G32B32A32_TYPELESS"; + DXGI_FORMAT2[DXGI_FORMAT2["DXGI_FORMAT_R32G32B32A32_FLOAT"] = 2] = "DXGI_FORMAT_R32G32B32A32_FLOAT"; + DXGI_FORMAT2[DXGI_FORMAT2["DXGI_FORMAT_R32G32B32A32_UINT"] = 3] = "DXGI_FORMAT_R32G32B32A32_UINT"; + DXGI_FORMAT2[DXGI_FORMAT2["DXGI_FORMAT_R32G32B32A32_SINT"] = 4] = "DXGI_FORMAT_R32G32B32A32_SINT"; + DXGI_FORMAT2[DXGI_FORMAT2["DXGI_FORMAT_R32G32B32_TYPELESS"] = 5] = "DXGI_FORMAT_R32G32B32_TYPELESS"; + DXGI_FORMAT2[DXGI_FORMAT2["DXGI_FORMAT_R32G32B32_FLOAT"] = 6] = "DXGI_FORMAT_R32G32B32_FLOAT"; + DXGI_FORMAT2[DXGI_FORMAT2["DXGI_FORMAT_R32G32B32_UINT"] = 7] = "DXGI_FORMAT_R32G32B32_UINT"; + DXGI_FORMAT2[DXGI_FORMAT2["DXGI_FORMAT_R32G32B32_SINT"] = 8] = "DXGI_FORMAT_R32G32B32_SINT"; + DXGI_FORMAT2[DXGI_FORMAT2["DXGI_FORMAT_R16G16B16A16_TYPELESS"] = 9] = "DXGI_FORMAT_R16G16B16A16_TYPELESS"; + DXGI_FORMAT2[DXGI_FORMAT2["DXGI_FORMAT_R16G16B16A16_FLOAT"] = 10] = "DXGI_FORMAT_R16G16B16A16_FLOAT"; + DXGI_FORMAT2[DXGI_FORMAT2["DXGI_FORMAT_R16G16B16A16_UNORM"] = 11] = "DXGI_FORMAT_R16G16B16A16_UNORM"; + DXGI_FORMAT2[DXGI_FORMAT2["DXGI_FORMAT_R16G16B16A16_UINT"] = 12] = "DXGI_FORMAT_R16G16B16A16_UINT"; + DXGI_FORMAT2[DXGI_FORMAT2["DXGI_FORMAT_R16G16B16A16_SNORM"] = 13] = "DXGI_FORMAT_R16G16B16A16_SNORM"; + DXGI_FORMAT2[DXGI_FORMAT2["DXGI_FORMAT_R16G16B16A16_SINT"] = 14] = "DXGI_FORMAT_R16G16B16A16_SINT"; + DXGI_FORMAT2[DXGI_FORMAT2["DXGI_FORMAT_R32G32_TYPELESS"] = 15] = "DXGI_FORMAT_R32G32_TYPELESS"; + DXGI_FORMAT2[DXGI_FORMAT2["DXGI_FORMAT_R32G32_FLOAT"] = 16] = "DXGI_FORMAT_R32G32_FLOAT"; + DXGI_FORMAT2[DXGI_FORMAT2["DXGI_FORMAT_R32G32_UINT"] = 17] = "DXGI_FORMAT_R32G32_UINT"; + DXGI_FORMAT2[DXGI_FORMAT2["DXGI_FORMAT_R32G32_SINT"] = 18] = "DXGI_FORMAT_R32G32_SINT"; + DXGI_FORMAT2[DXGI_FORMAT2["DXGI_FORMAT_R32G8X24_TYPELESS"] = 19] = "DXGI_FORMAT_R32G8X24_TYPELESS"; + DXGI_FORMAT2[DXGI_FORMAT2["DXGI_FORMAT_D32_FLOAT_S8X24_UINT"] = 20] = "DXGI_FORMAT_D32_FLOAT_S8X24_UINT"; + DXGI_FORMAT2[DXGI_FORMAT2["DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS"] = 21] = "DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS"; + DXGI_FORMAT2[DXGI_FORMAT2["DXGI_FORMAT_X32_TYPELESS_G8X24_UINT"] = 22] = "DXGI_FORMAT_X32_TYPELESS_G8X24_UINT"; + DXGI_FORMAT2[DXGI_FORMAT2["DXGI_FORMAT_R10G10B10A2_TYPELESS"] = 23] = "DXGI_FORMAT_R10G10B10A2_TYPELESS"; + DXGI_FORMAT2[DXGI_FORMAT2["DXGI_FORMAT_R10G10B10A2_UNORM"] = 24] = "DXGI_FORMAT_R10G10B10A2_UNORM"; + DXGI_FORMAT2[DXGI_FORMAT2["DXGI_FORMAT_R10G10B10A2_UINT"] = 25] = "DXGI_FORMAT_R10G10B10A2_UINT"; + DXGI_FORMAT2[DXGI_FORMAT2["DXGI_FORMAT_R11G11B10_FLOAT"] = 26] = "DXGI_FORMAT_R11G11B10_FLOAT"; + DXGI_FORMAT2[DXGI_FORMAT2["DXGI_FORMAT_R8G8B8A8_TYPELESS"] = 27] = "DXGI_FORMAT_R8G8B8A8_TYPELESS"; + DXGI_FORMAT2[DXGI_FORMAT2["DXGI_FORMAT_R8G8B8A8_UNORM"] = 28] = "DXGI_FORMAT_R8G8B8A8_UNORM"; + DXGI_FORMAT2[DXGI_FORMAT2["DXGI_FORMAT_R8G8B8A8_UNORM_SRGB"] = 29] = "DXGI_FORMAT_R8G8B8A8_UNORM_SRGB"; + DXGI_FORMAT2[DXGI_FORMAT2["DXGI_FORMAT_R8G8B8A8_UINT"] = 30] = "DXGI_FORMAT_R8G8B8A8_UINT"; + DXGI_FORMAT2[DXGI_FORMAT2["DXGI_FORMAT_R8G8B8A8_SNORM"] = 31] = "DXGI_FORMAT_R8G8B8A8_SNORM"; + DXGI_FORMAT2[DXGI_FORMAT2["DXGI_FORMAT_R8G8B8A8_SINT"] = 32] = "DXGI_FORMAT_R8G8B8A8_SINT"; + DXGI_FORMAT2[DXGI_FORMAT2["DXGI_FORMAT_R16G16_TYPELESS"] = 33] = "DXGI_FORMAT_R16G16_TYPELESS"; + DXGI_FORMAT2[DXGI_FORMAT2["DXGI_FORMAT_R16G16_FLOAT"] = 34] = "DXGI_FORMAT_R16G16_FLOAT"; + DXGI_FORMAT2[DXGI_FORMAT2["DXGI_FORMAT_R16G16_UNORM"] = 35] = "DXGI_FORMAT_R16G16_UNORM"; + DXGI_FORMAT2[DXGI_FORMAT2["DXGI_FORMAT_R16G16_UINT"] = 36] = "DXGI_FORMAT_R16G16_UINT"; + DXGI_FORMAT2[DXGI_FORMAT2["DXGI_FORMAT_R16G16_SNORM"] = 37] = "DXGI_FORMAT_R16G16_SNORM"; + DXGI_FORMAT2[DXGI_FORMAT2["DXGI_FORMAT_R16G16_SINT"] = 38] = "DXGI_FORMAT_R16G16_SINT"; + DXGI_FORMAT2[DXGI_FORMAT2["DXGI_FORMAT_R32_TYPELESS"] = 39] = "DXGI_FORMAT_R32_TYPELESS"; + DXGI_FORMAT2[DXGI_FORMAT2["DXGI_FORMAT_D32_FLOAT"] = 40] = "DXGI_FORMAT_D32_FLOAT"; + DXGI_FORMAT2[DXGI_FORMAT2["DXGI_FORMAT_R32_FLOAT"] = 41] = "DXGI_FORMAT_R32_FLOAT"; + DXGI_FORMAT2[DXGI_FORMAT2["DXGI_FORMAT_R32_UINT"] = 42] = "DXGI_FORMAT_R32_UINT"; + DXGI_FORMAT2[DXGI_FORMAT2["DXGI_FORMAT_R32_SINT"] = 43] = "DXGI_FORMAT_R32_SINT"; + DXGI_FORMAT2[DXGI_FORMAT2["DXGI_FORMAT_R24G8_TYPELESS"] = 44] = "DXGI_FORMAT_R24G8_TYPELESS"; + DXGI_FORMAT2[DXGI_FORMAT2["DXGI_FORMAT_D24_UNORM_S8_UINT"] = 45] = "DXGI_FORMAT_D24_UNORM_S8_UINT"; + DXGI_FORMAT2[DXGI_FORMAT2["DXGI_FORMAT_R24_UNORM_X8_TYPELESS"] = 46] = "DXGI_FORMAT_R24_UNORM_X8_TYPELESS"; + DXGI_FORMAT2[DXGI_FORMAT2["DXGI_FORMAT_X24_TYPELESS_G8_UINT"] = 47] = "DXGI_FORMAT_X24_TYPELESS_G8_UINT"; + DXGI_FORMAT2[DXGI_FORMAT2["DXGI_FORMAT_R8G8_TYPELESS"] = 48] = "DXGI_FORMAT_R8G8_TYPELESS"; + DXGI_FORMAT2[DXGI_FORMAT2["DXGI_FORMAT_R8G8_UNORM"] = 49] = "DXGI_FORMAT_R8G8_UNORM"; + DXGI_FORMAT2[DXGI_FORMAT2["DXGI_FORMAT_R8G8_UINT"] = 50] = "DXGI_FORMAT_R8G8_UINT"; + DXGI_FORMAT2[DXGI_FORMAT2["DXGI_FORMAT_R8G8_SNORM"] = 51] = "DXGI_FORMAT_R8G8_SNORM"; + DXGI_FORMAT2[DXGI_FORMAT2["DXGI_FORMAT_R8G8_SINT"] = 52] = "DXGI_FORMAT_R8G8_SINT"; + DXGI_FORMAT2[DXGI_FORMAT2["DXGI_FORMAT_R16_TYPELESS"] = 53] = "DXGI_FORMAT_R16_TYPELESS"; + DXGI_FORMAT2[DXGI_FORMAT2["DXGI_FORMAT_R16_FLOAT"] = 54] = "DXGI_FORMAT_R16_FLOAT"; + DXGI_FORMAT2[DXGI_FORMAT2["DXGI_FORMAT_D16_UNORM"] = 55] = "DXGI_FORMAT_D16_UNORM"; + DXGI_FORMAT2[DXGI_FORMAT2["DXGI_FORMAT_R16_UNORM"] = 56] = "DXGI_FORMAT_R16_UNORM"; + DXGI_FORMAT2[DXGI_FORMAT2["DXGI_FORMAT_R16_UINT"] = 57] = "DXGI_FORMAT_R16_UINT"; + DXGI_FORMAT2[DXGI_FORMAT2["DXGI_FORMAT_R16_SNORM"] = 58] = "DXGI_FORMAT_R16_SNORM"; + DXGI_FORMAT2[DXGI_FORMAT2["DXGI_FORMAT_R16_SINT"] = 59] = "DXGI_FORMAT_R16_SINT"; + DXGI_FORMAT2[DXGI_FORMAT2["DXGI_FORMAT_R8_TYPELESS"] = 60] = "DXGI_FORMAT_R8_TYPELESS"; + DXGI_FORMAT2[DXGI_FORMAT2["DXGI_FORMAT_R8_UNORM"] = 61] = "DXGI_FORMAT_R8_UNORM"; + DXGI_FORMAT2[DXGI_FORMAT2["DXGI_FORMAT_R8_UINT"] = 62] = "DXGI_FORMAT_R8_UINT"; + DXGI_FORMAT2[DXGI_FORMAT2["DXGI_FORMAT_R8_SNORM"] = 63] = "DXGI_FORMAT_R8_SNORM"; + DXGI_FORMAT2[DXGI_FORMAT2["DXGI_FORMAT_R8_SINT"] = 64] = "DXGI_FORMAT_R8_SINT"; + DXGI_FORMAT2[DXGI_FORMAT2["DXGI_FORMAT_A8_UNORM"] = 65] = "DXGI_FORMAT_A8_UNORM"; + DXGI_FORMAT2[DXGI_FORMAT2["DXGI_FORMAT_R1_UNORM"] = 66] = "DXGI_FORMAT_R1_UNORM"; + DXGI_FORMAT2[DXGI_FORMAT2["DXGI_FORMAT_R9G9B9E5_SHAREDEXP"] = 67] = "DXGI_FORMAT_R9G9B9E5_SHAREDEXP"; + DXGI_FORMAT2[DXGI_FORMAT2["DXGI_FORMAT_R8G8_B8G8_UNORM"] = 68] = "DXGI_FORMAT_R8G8_B8G8_UNORM"; + DXGI_FORMAT2[DXGI_FORMAT2["DXGI_FORMAT_G8R8_G8B8_UNORM"] = 69] = "DXGI_FORMAT_G8R8_G8B8_UNORM"; + DXGI_FORMAT2[DXGI_FORMAT2["DXGI_FORMAT_BC1_TYPELESS"] = 70] = "DXGI_FORMAT_BC1_TYPELESS"; + DXGI_FORMAT2[DXGI_FORMAT2["DXGI_FORMAT_BC1_UNORM"] = 71] = "DXGI_FORMAT_BC1_UNORM"; + DXGI_FORMAT2[DXGI_FORMAT2["DXGI_FORMAT_BC1_UNORM_SRGB"] = 72] = "DXGI_FORMAT_BC1_UNORM_SRGB"; + DXGI_FORMAT2[DXGI_FORMAT2["DXGI_FORMAT_BC2_TYPELESS"] = 73] = "DXGI_FORMAT_BC2_TYPELESS"; + DXGI_FORMAT2[DXGI_FORMAT2["DXGI_FORMAT_BC2_UNORM"] = 74] = "DXGI_FORMAT_BC2_UNORM"; + DXGI_FORMAT2[DXGI_FORMAT2["DXGI_FORMAT_BC2_UNORM_SRGB"] = 75] = "DXGI_FORMAT_BC2_UNORM_SRGB"; + DXGI_FORMAT2[DXGI_FORMAT2["DXGI_FORMAT_BC3_TYPELESS"] = 76] = "DXGI_FORMAT_BC3_TYPELESS"; + DXGI_FORMAT2[DXGI_FORMAT2["DXGI_FORMAT_BC3_UNORM"] = 77] = "DXGI_FORMAT_BC3_UNORM"; + DXGI_FORMAT2[DXGI_FORMAT2["DXGI_FORMAT_BC3_UNORM_SRGB"] = 78] = "DXGI_FORMAT_BC3_UNORM_SRGB"; + DXGI_FORMAT2[DXGI_FORMAT2["DXGI_FORMAT_BC4_TYPELESS"] = 79] = "DXGI_FORMAT_BC4_TYPELESS"; + DXGI_FORMAT2[DXGI_FORMAT2["DXGI_FORMAT_BC4_UNORM"] = 80] = "DXGI_FORMAT_BC4_UNORM"; + DXGI_FORMAT2[DXGI_FORMAT2["DXGI_FORMAT_BC4_SNORM"] = 81] = "DXGI_FORMAT_BC4_SNORM"; + DXGI_FORMAT2[DXGI_FORMAT2["DXGI_FORMAT_BC5_TYPELESS"] = 82] = "DXGI_FORMAT_BC5_TYPELESS"; + DXGI_FORMAT2[DXGI_FORMAT2["DXGI_FORMAT_BC5_UNORM"] = 83] = "DXGI_FORMAT_BC5_UNORM"; + DXGI_FORMAT2[DXGI_FORMAT2["DXGI_FORMAT_BC5_SNORM"] = 84] = "DXGI_FORMAT_BC5_SNORM"; + DXGI_FORMAT2[DXGI_FORMAT2["DXGI_FORMAT_B5G6R5_UNORM"] = 85] = "DXGI_FORMAT_B5G6R5_UNORM"; + DXGI_FORMAT2[DXGI_FORMAT2["DXGI_FORMAT_B5G5R5A1_UNORM"] = 86] = "DXGI_FORMAT_B5G5R5A1_UNORM"; + DXGI_FORMAT2[DXGI_FORMAT2["DXGI_FORMAT_B8G8R8A8_UNORM"] = 87] = "DXGI_FORMAT_B8G8R8A8_UNORM"; + DXGI_FORMAT2[DXGI_FORMAT2["DXGI_FORMAT_B8G8R8X8_UNORM"] = 88] = "DXGI_FORMAT_B8G8R8X8_UNORM"; + DXGI_FORMAT2[DXGI_FORMAT2["DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM"] = 89] = "DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM"; + DXGI_FORMAT2[DXGI_FORMAT2["DXGI_FORMAT_B8G8R8A8_TYPELESS"] = 90] = "DXGI_FORMAT_B8G8R8A8_TYPELESS"; + DXGI_FORMAT2[DXGI_FORMAT2["DXGI_FORMAT_B8G8R8A8_UNORM_SRGB"] = 91] = "DXGI_FORMAT_B8G8R8A8_UNORM_SRGB"; + DXGI_FORMAT2[DXGI_FORMAT2["DXGI_FORMAT_B8G8R8X8_TYPELESS"] = 92] = "DXGI_FORMAT_B8G8R8X8_TYPELESS"; + DXGI_FORMAT2[DXGI_FORMAT2["DXGI_FORMAT_B8G8R8X8_UNORM_SRGB"] = 93] = "DXGI_FORMAT_B8G8R8X8_UNORM_SRGB"; + DXGI_FORMAT2[DXGI_FORMAT2["DXGI_FORMAT_BC6H_TYPELESS"] = 94] = "DXGI_FORMAT_BC6H_TYPELESS"; + DXGI_FORMAT2[DXGI_FORMAT2["DXGI_FORMAT_BC6H_UF16"] = 95] = "DXGI_FORMAT_BC6H_UF16"; + DXGI_FORMAT2[DXGI_FORMAT2["DXGI_FORMAT_BC6H_SF16"] = 96] = "DXGI_FORMAT_BC6H_SF16"; + DXGI_FORMAT2[DXGI_FORMAT2["DXGI_FORMAT_BC7_TYPELESS"] = 97] = "DXGI_FORMAT_BC7_TYPELESS"; + DXGI_FORMAT2[DXGI_FORMAT2["DXGI_FORMAT_BC7_UNORM"] = 98] = "DXGI_FORMAT_BC7_UNORM"; + DXGI_FORMAT2[DXGI_FORMAT2["DXGI_FORMAT_BC7_UNORM_SRGB"] = 99] = "DXGI_FORMAT_BC7_UNORM_SRGB"; + DXGI_FORMAT2[DXGI_FORMAT2["DXGI_FORMAT_AYUV"] = 100] = "DXGI_FORMAT_AYUV"; + DXGI_FORMAT2[DXGI_FORMAT2["DXGI_FORMAT_Y410"] = 101] = "DXGI_FORMAT_Y410"; + DXGI_FORMAT2[DXGI_FORMAT2["DXGI_FORMAT_Y416"] = 102] = "DXGI_FORMAT_Y416"; + DXGI_FORMAT2[DXGI_FORMAT2["DXGI_FORMAT_NV12"] = 103] = "DXGI_FORMAT_NV12"; + DXGI_FORMAT2[DXGI_FORMAT2["DXGI_FORMAT_P010"] = 104] = "DXGI_FORMAT_P010"; + DXGI_FORMAT2[DXGI_FORMAT2["DXGI_FORMAT_P016"] = 105] = "DXGI_FORMAT_P016"; + DXGI_FORMAT2[DXGI_FORMAT2["DXGI_FORMAT_420_OPAQUE"] = 106] = "DXGI_FORMAT_420_OPAQUE"; + DXGI_FORMAT2[DXGI_FORMAT2["DXGI_FORMAT_YUY2"] = 107] = "DXGI_FORMAT_YUY2"; + DXGI_FORMAT2[DXGI_FORMAT2["DXGI_FORMAT_Y210"] = 108] = "DXGI_FORMAT_Y210"; + DXGI_FORMAT2[DXGI_FORMAT2["DXGI_FORMAT_Y216"] = 109] = "DXGI_FORMAT_Y216"; + DXGI_FORMAT2[DXGI_FORMAT2["DXGI_FORMAT_NV11"] = 110] = "DXGI_FORMAT_NV11"; + DXGI_FORMAT2[DXGI_FORMAT2["DXGI_FORMAT_AI44"] = 111] = "DXGI_FORMAT_AI44"; + DXGI_FORMAT2[DXGI_FORMAT2["DXGI_FORMAT_IA44"] = 112] = "DXGI_FORMAT_IA44"; + DXGI_FORMAT2[DXGI_FORMAT2["DXGI_FORMAT_P8"] = 113] = "DXGI_FORMAT_P8"; + DXGI_FORMAT2[DXGI_FORMAT2["DXGI_FORMAT_A8P8"] = 114] = "DXGI_FORMAT_A8P8"; + DXGI_FORMAT2[DXGI_FORMAT2["DXGI_FORMAT_B4G4R4A4_UNORM"] = 115] = "DXGI_FORMAT_B4G4R4A4_UNORM"; + DXGI_FORMAT2[DXGI_FORMAT2["DXGI_FORMAT_P208"] = 116] = "DXGI_FORMAT_P208"; + DXGI_FORMAT2[DXGI_FORMAT2["DXGI_FORMAT_V208"] = 117] = "DXGI_FORMAT_V208"; + DXGI_FORMAT2[DXGI_FORMAT2["DXGI_FORMAT_V408"] = 118] = "DXGI_FORMAT_V408"; + DXGI_FORMAT2[DXGI_FORMAT2["DXGI_FORMAT_SAMPLER_FEEDBACK_MIN_MIP_OPAQUE"] = 119] = "DXGI_FORMAT_SAMPLER_FEEDBACK_MIN_MIP_OPAQUE"; + DXGI_FORMAT2[DXGI_FORMAT2["DXGI_FORMAT_SAMPLER_FEEDBACK_MIP_REGION_USED_OPAQUE"] = 120] = "DXGI_FORMAT_SAMPLER_FEEDBACK_MIP_REGION_USED_OPAQUE"; + DXGI_FORMAT2[DXGI_FORMAT2["DXGI_FORMAT_FORCE_UINT"] = 121] = "DXGI_FORMAT_FORCE_UINT"; + return DXGI_FORMAT2; +})(DXGI_FORMAT || {}); +var D3D10_RESOURCE_DIMENSION = /* @__PURE__ */ ((D3D10_RESOURCE_DIMENSION2) => { + D3D10_RESOURCE_DIMENSION2[D3D10_RESOURCE_DIMENSION2["DDS_DIMENSION_TEXTURE1D"] = 2] = "DDS_DIMENSION_TEXTURE1D"; + D3D10_RESOURCE_DIMENSION2[D3D10_RESOURCE_DIMENSION2["DDS_DIMENSION_TEXTURE2D"] = 3] = "DDS_DIMENSION_TEXTURE2D"; + D3D10_RESOURCE_DIMENSION2[D3D10_RESOURCE_DIMENSION2["DDS_DIMENSION_TEXTURE3D"] = 6] = "DDS_DIMENSION_TEXTURE3D"; + return D3D10_RESOURCE_DIMENSION2; +})(D3D10_RESOURCE_DIMENSION || {}); +function fourCCToInt32(value) { + return value.charCodeAt(0) + (value.charCodeAt(1) << 8) + (value.charCodeAt(2) << 16) + (value.charCodeAt(3) << 24); +} +var D3DFMT = ((D3DFMT2) => { + D3DFMT2[D3DFMT2["UNKNOWN"] = 0] = "UNKNOWN"; + D3DFMT2[D3DFMT2["R8G8B8"] = 20] = "R8G8B8"; + D3DFMT2[D3DFMT2["A8R8G8B8"] = 21] = "A8R8G8B8"; + D3DFMT2[D3DFMT2["X8R8G8B8"] = 22] = "X8R8G8B8"; + D3DFMT2[D3DFMT2["R5G6B5"] = 23] = "R5G6B5"; + D3DFMT2[D3DFMT2["X1R5G5B5"] = 24] = "X1R5G5B5"; + D3DFMT2[D3DFMT2["A1R5G5B5"] = 25] = "A1R5G5B5"; + D3DFMT2[D3DFMT2["A4R4G4B4"] = 26] = "A4R4G4B4"; + D3DFMT2[D3DFMT2["R3G3B2"] = 27] = "R3G3B2"; + D3DFMT2[D3DFMT2["A8"] = 28] = "A8"; + D3DFMT2[D3DFMT2["A8R3G3B2"] = 29] = "A8R3G3B2"; + D3DFMT2[D3DFMT2["X4R4G4B4"] = 30] = "X4R4G4B4"; + D3DFMT2[D3DFMT2["A2B10G10R10"] = 31] = "A2B10G10R10"; + D3DFMT2[D3DFMT2["A8B8G8R8"] = 32] = "A8B8G8R8"; + D3DFMT2[D3DFMT2["X8B8G8R8"] = 33] = "X8B8G8R8"; + D3DFMT2[D3DFMT2["G16R16"] = 34] = "G16R16"; + D3DFMT2[D3DFMT2["A2R10G10B10"] = 35] = "A2R10G10B10"; + D3DFMT2[D3DFMT2["A16B16G16R16"] = 36] = "A16B16G16R16"; + D3DFMT2[D3DFMT2["A8P8"] = 40] = "A8P8"; + D3DFMT2[D3DFMT2["P8"] = 41] = "P8"; + D3DFMT2[D3DFMT2["L8"] = 50] = "L8"; + D3DFMT2[D3DFMT2["A8L8"] = 51] = "A8L8"; + D3DFMT2[D3DFMT2["A4L4"] = 52] = "A4L4"; + D3DFMT2[D3DFMT2["V8U8"] = 60] = "V8U8"; + D3DFMT2[D3DFMT2["L6V5U5"] = 61] = "L6V5U5"; + D3DFMT2[D3DFMT2["X8L8V8U8"] = 62] = "X8L8V8U8"; + D3DFMT2[D3DFMT2["Q8W8V8U8"] = 63] = "Q8W8V8U8"; + D3DFMT2[D3DFMT2["V16U16"] = 64] = "V16U16"; + D3DFMT2[D3DFMT2["A2W10V10U10"] = 67] = "A2W10V10U10"; + D3DFMT2[D3DFMT2["Q16W16V16U16"] = 110] = "Q16W16V16U16"; + D3DFMT2[D3DFMT2["R16F"] = 111] = "R16F"; + D3DFMT2[D3DFMT2["G16R16F"] = 112] = "G16R16F"; + D3DFMT2[D3DFMT2["A16B16G16R16F"] = 113] = "A16B16G16R16F"; + D3DFMT2[D3DFMT2["R32F"] = 114] = "R32F"; + D3DFMT2[D3DFMT2["G32R32F"] = 115] = "G32R32F"; + D3DFMT2[D3DFMT2["A32B32G32R32F"] = 116] = "A32B32G32R32F"; + D3DFMT2[D3DFMT2["UYVY"] = fourCCToInt32("UYVY")] = "UYVY"; + D3DFMT2[D3DFMT2["R8G8_B8G8"] = fourCCToInt32("RGBG")] = "R8G8_B8G8"; + D3DFMT2[D3DFMT2["YUY2"] = fourCCToInt32("YUY2")] = "YUY2"; + D3DFMT2[D3DFMT2["D3DFMT_G8R8_G8B8"] = fourCCToInt32("GRGB")] = "D3DFMT_G8R8_G8B8"; + D3DFMT2[D3DFMT2["DXT1"] = fourCCToInt32("DXT1")] = "DXT1"; + D3DFMT2[D3DFMT2["DXT2"] = fourCCToInt32("DXT2")] = "DXT2"; + D3DFMT2[D3DFMT2["DXT3"] = fourCCToInt32("DXT3")] = "DXT3"; + D3DFMT2[D3DFMT2["DXT4"] = fourCCToInt32("DXT4")] = "DXT4"; + D3DFMT2[D3DFMT2["DXT5"] = fourCCToInt32("DXT5")] = "DXT5"; + D3DFMT2[D3DFMT2["ATI1"] = fourCCToInt32("ATI1")] = "ATI1"; + D3DFMT2[D3DFMT2["AT1N"] = fourCCToInt32("AT1N")] = "AT1N"; + D3DFMT2[D3DFMT2["ATI2"] = fourCCToInt32("ATI2")] = "ATI2"; + D3DFMT2[D3DFMT2["AT2N"] = fourCCToInt32("AT2N")] = "AT2N"; + D3DFMT2[D3DFMT2["BC4U"] = fourCCToInt32("BC4U")] = "BC4U"; + D3DFMT2[D3DFMT2["BC4S"] = fourCCToInt32("BC4S")] = "BC4S"; + D3DFMT2[D3DFMT2["BC5U"] = fourCCToInt32("BC5U")] = "BC5U"; + D3DFMT2[D3DFMT2["BC5S"] = fourCCToInt32("BC5S")] = "BC5S"; + D3DFMT2[D3DFMT2["DX10"] = fourCCToInt32("DX10")] = "DX10"; + return D3DFMT2; +})(D3DFMT || {}); +const FOURCC_TO_TEXTURE_FORMAT = { + [D3DFMT.DXT1]: "bc1-rgba-unorm", + [D3DFMT.DXT2]: "bc2-rgba-unorm", + [D3DFMT.DXT3]: "bc2-rgba-unorm", + [D3DFMT.DXT4]: "bc3-rgba-unorm", + [D3DFMT.DXT5]: "bc3-rgba-unorm", + [D3DFMT.ATI1]: "bc4-r-unorm", + [D3DFMT.BC4U]: "bc4-r-unorm", + [D3DFMT.BC4S]: "bc4-r-snorm", + [D3DFMT.ATI2]: "bc5-rg-unorm", + [D3DFMT.BC5U]: "bc5-rg-unorm", + [D3DFMT.BC5S]: "bc5-rg-snorm", + [36 /* A16B16G16R16 */]: "rgba16uint", + [110 /* Q16W16V16U16 */]: "rgba16sint", + [111 /* R16F */]: "r16float", + [112 /* G16R16F */]: "rg16float", + [113 /* A16B16G16R16F */]: "rgba16float", + [114 /* R32F */]: "r32float", + [115 /* G32R32F */]: "rg32float", + [116 /* A32B32G32R32F */]: "rgba32float" +}; +const DXGI_TO_TEXTURE_FORMAT = { + [70 /* DXGI_FORMAT_BC1_TYPELESS */]: "bc1-rgba-unorm", + [71 /* DXGI_FORMAT_BC1_UNORM */]: "bc1-rgba-unorm", + [72 /* DXGI_FORMAT_BC1_UNORM_SRGB */]: "bc1-rgba-unorm-srgb", + [73 /* DXGI_FORMAT_BC2_TYPELESS */]: "bc2-rgba-unorm", + [74 /* DXGI_FORMAT_BC2_UNORM */]: "bc2-rgba-unorm", + [75 /* DXGI_FORMAT_BC2_UNORM_SRGB */]: "bc2-rgba-unorm-srgb", + [76 /* DXGI_FORMAT_BC3_TYPELESS */]: "bc3-rgba-unorm", + [77 /* DXGI_FORMAT_BC3_UNORM */]: "bc3-rgba-unorm", + [78 /* DXGI_FORMAT_BC3_UNORM_SRGB */]: "bc3-rgba-unorm-srgb", + [79 /* DXGI_FORMAT_BC4_TYPELESS */]: "bc4-r-unorm", + [80 /* DXGI_FORMAT_BC4_UNORM */]: "bc4-r-unorm", + [81 /* DXGI_FORMAT_BC4_SNORM */]: "bc4-r-snorm", + [82 /* DXGI_FORMAT_BC5_TYPELESS */]: "bc5-rg-unorm", + [83 /* DXGI_FORMAT_BC5_UNORM */]: "bc5-rg-unorm", + [84 /* DXGI_FORMAT_BC5_SNORM */]: "bc5-rg-snorm", + [94 /* DXGI_FORMAT_BC6H_TYPELESS */]: "bc6h-rgb-ufloat", + [95 /* DXGI_FORMAT_BC6H_UF16 */]: "bc6h-rgb-ufloat", + [96 /* DXGI_FORMAT_BC6H_SF16 */]: "bc6h-rgb-float", + [97 /* DXGI_FORMAT_BC7_TYPELESS */]: "bc7-rgba-unorm", + [98 /* DXGI_FORMAT_BC7_UNORM */]: "bc7-rgba-unorm", + [99 /* DXGI_FORMAT_BC7_UNORM_SRGB */]: "bc7-rgba-unorm-srgb", + [28 /* DXGI_FORMAT_R8G8B8A8_UNORM */]: "rgba8unorm", + [29 /* DXGI_FORMAT_R8G8B8A8_UNORM_SRGB */]: "rgba8unorm-srgb", + [87 /* DXGI_FORMAT_B8G8R8A8_UNORM */]: "bgra8unorm", + [91 /* DXGI_FORMAT_B8G8R8A8_UNORM_SRGB */]: "bgra8unorm-srgb", + [41 /* DXGI_FORMAT_R32_FLOAT */]: "r32float", + [49 /* DXGI_FORMAT_R8G8_UNORM */]: "rg8unorm", + [56 /* DXGI_FORMAT_R16_UNORM */]: "r16uint", + [61 /* DXGI_FORMAT_R8_UNORM */]: "r8unorm", + [24 /* DXGI_FORMAT_R10G10B10A2_UNORM */]: "rgb10a2unorm", + [11 /* DXGI_FORMAT_R16G16B16A16_UNORM */]: "rgba16uint", + [13 /* DXGI_FORMAT_R16G16B16A16_SNORM */]: "rgba16sint", + [10 /* DXGI_FORMAT_R16G16B16A16_FLOAT */]: "rgba16float", + [54 /* DXGI_FORMAT_R16_FLOAT */]: "r16float", + [34 /* DXGI_FORMAT_R16G16_FLOAT */]: "rg16float", + [16 /* DXGI_FORMAT_R32G32_FLOAT */]: "rg32float", + [2 /* DXGI_FORMAT_R32G32B32A32_FLOAT */]: "rgba32float" +}; +const DDS = { + MAGIC_VALUE: 542327876, + MAGIC_SIZE: 4, + HEADER_SIZE: 124, + HEADER_DX10_SIZE: 20, + PIXEL_FORMAT_FLAGS: { + // PIXEL_FORMAT flags + // https://github.com/Microsoft/DirectXTex/blob/main/DirectXTex/DDS.h + // https://learn.microsoft.com/en-us/windows/win32/direct3ddds/dds-pixelformat + ALPHAPIXELS: 1, + ALPHA: 2, + FOURCC: 4, + RGB: 64, + RGBA: 65, + YUV: 512, + LUMINANCE: 131072, + LUMINANCEA: 131073 + }, + RESOURCE_MISC_TEXTURECUBE: 4, + HEADER_FIELDS: DDS_HEADER_FIELDS, + HEADER_DX10_FIELDS: DDS_DX10_FIELDS, + DXGI_FORMAT, + D3D10_RESOURCE_DIMENSION, + D3DFMT +}; +const TEXTURE_FORMAT_BLOCK_SIZE = { + "bc1-rgba-unorm": 8, + "bc1-rgba-unorm-srgb": 8, + "bc2-rgba-unorm": 16, + "bc2-rgba-unorm-srgb": 16, + "bc3-rgba-unorm": 16, + "bc3-rgba-unorm-srgb": 16, + "bc4-r-unorm": 8, + "bc4-r-snorm": 8, + "bc5-rg-unorm": 16, + "bc5-rg-snorm": 16, + "bc6h-rgb-ufloat": 16, + "bc6h-rgb-float": 16, + "bc7-rgba-unorm": 16, + "bc7-rgba-unorm-srgb": 16 +}; + +"use strict"; +function parseDDS(arrayBuffer, supportedFormats) { + const { + format, + fourCC, + width, + height, + dataOffset, + mipmapCount + } = parseDDSHeader(arrayBuffer); + if (!supportedFormats.includes(format)) { + throw new Error(`Unsupported texture format: ${fourCC} ${format}, supported: ${supportedFormats}`); + } + if (mipmapCount <= 1) { + return { + format, + width, + height, + resource: [new Uint8Array(arrayBuffer, dataOffset)], + alphaMode: "no-premultiply-alpha" + }; + } + const levelBuffers = getMipmapLevelBuffers(format, width, height, dataOffset, mipmapCount, arrayBuffer); + const textureOptions = { + format, + width, + height, + resource: levelBuffers, + alphaMode: "no-premultiply-alpha" + }; + return textureOptions; +} +function getMipmapLevelBuffers(format, width, height, dataOffset, mipmapCount, arrayBuffer) { + const levelBuffers = []; + const blockBytes = TEXTURE_FORMAT_BLOCK_SIZE[format]; + let mipWidth = width; + let mipHeight = height; + let offset = dataOffset; + for (let level = 0; level < mipmapCount; ++level) { + const byteLength = blockBytes ? Math.max(4, mipWidth) / 4 * Math.max(4, mipHeight) / 4 * blockBytes : mipWidth * mipHeight * 4; + const levelBuffer = new Uint8Array(arrayBuffer, offset, byteLength); + levelBuffers.push(levelBuffer); + offset += byteLength; + mipWidth = Math.max(mipWidth >> 1, 1); + mipHeight = Math.max(mipHeight >> 1, 1); + } + return levelBuffers; +} +function parseDDSHeader(buffer) { + const header = new Uint32Array(buffer, 0, DDS.HEADER_SIZE / Uint32Array.BYTES_PER_ELEMENT); + if (header[DDS.HEADER_FIELDS.MAGIC] !== DDS.MAGIC_VALUE) { + throw new Error("Invalid magic number in DDS header"); + } + const height = header[DDS.HEADER_FIELDS.HEIGHT]; + const width = header[DDS.HEADER_FIELDS.WIDTH]; + const mipmapCount = Math.max(1, header[DDS.HEADER_FIELDS.MIPMAP_COUNT]); + const flags = header[DDS.HEADER_FIELDS.PF_FLAGS]; + const fourCC = header[DDS.HEADER_FIELDS.FOURCC]; + const format = getTextureFormat(header, flags, fourCC, buffer); + const dataOffset = DDS.MAGIC_SIZE + DDS.HEADER_SIZE + (fourCC === DDS.D3DFMT.DX10 ? DDS.HEADER_DX10_SIZE : 0); + return { + format, + fourCC, + width, + height, + dataOffset, + mipmapCount + }; +} +function getTextureFormat(header, flags, fourCC, buffer) { + if (flags & DDS.PIXEL_FORMAT_FLAGS.FOURCC) { + if (fourCC === DDS.D3DFMT.DX10) { + const dx10Header = new Uint32Array( + buffer, + DDS.MAGIC_SIZE + DDS.HEADER_SIZE, + // there is a 20-byte DDS_HEADER_DX10 after DDS_HEADER + DDS.HEADER_DX10_SIZE / Uint32Array.BYTES_PER_ELEMENT + ); + const miscFlag = dx10Header[DDS.HEADER_DX10_FIELDS.MISC_FLAG]; + if (miscFlag === DDS.RESOURCE_MISC_TEXTURECUBE) { + throw new Error("DDSParser does not support cubemap textures"); + } + const resourceDimension = dx10Header[DDS.HEADER_DX10_FIELDS.RESOURCE_DIMENSION]; + if (resourceDimension === DDS.D3D10_RESOURCE_DIMENSION.DDS_DIMENSION_TEXTURE3D) { + throw new Error("DDSParser does not supported 3D texture data"); + } + const dxgiFormat = dx10Header[DDS.HEADER_DX10_FIELDS.DXGI_FORMAT]; + if (dxgiFormat in DXGI_TO_TEXTURE_FORMAT) { + return DXGI_TO_TEXTURE_FORMAT[dxgiFormat]; + } + throw new Error(`DDSParser cannot parse texture data with DXGI format ${dxgiFormat}`); + } + if (fourCC in FOURCC_TO_TEXTURE_FORMAT) { + return FOURCC_TO_TEXTURE_FORMAT[fourCC]; + } + throw new Error(`DDSParser cannot parse texture data with fourCC format ${fourCC}`); + } + if (flags & DDS.PIXEL_FORMAT_FLAGS.RGB || flags & DDS.PIXEL_FORMAT_FLAGS.RGBA) { + return getUncompressedTextureFormat(header); + } + if (flags & DDS.PIXEL_FORMAT_FLAGS.YUV) { + throw new Error("DDSParser does not supported YUV uncompressed texture data."); + } + if (flags & DDS.PIXEL_FORMAT_FLAGS.LUMINANCE || flags & DDS.PIXEL_FORMAT_FLAGS.LUMINANCEA) { + throw new Error("DDSParser does not support single-channel (lumninance) texture data!"); + } + if (flags & DDS.PIXEL_FORMAT_FLAGS.ALPHA || flags & DDS.PIXEL_FORMAT_FLAGS.ALPHAPIXELS) { + throw new Error("DDSParser does not support single-channel (alpha) texture data!"); + } + throw new Error("DDSParser failed to load a texture file due to an unknown reason!"); +} +function getUncompressedTextureFormat(header) { + const bitCount = header[DDS.HEADER_FIELDS.RGB_BITCOUNT]; + const rBitMask = header[DDS.HEADER_FIELDS.R_BIT_MASK]; + const gBitMask = header[DDS.HEADER_FIELDS.G_BIT_MASK]; + const bBitMask = header[DDS.HEADER_FIELDS.B_BIT_MASK]; + const aBitMask = header[DDS.HEADER_FIELDS.A_BIT_MASK]; + switch (bitCount) { + case 32: + if (rBitMask === 255 && gBitMask === 65280 && bBitMask === 16711680 && aBitMask === 4278190080) { + return DXGI_TO_TEXTURE_FORMAT[DDS.DXGI_FORMAT.DXGI_FORMAT_R8G8B8A8_UNORM]; + } + if (rBitMask === 16711680 && gBitMask === 65280 && bBitMask === 255 && aBitMask === 4278190080) { + return DXGI_TO_TEXTURE_FORMAT[DDS.DXGI_FORMAT.DXGI_FORMAT_B8G8R8A8_UNORM]; + } + if (rBitMask === 1072693248 && gBitMask === 1047552 && bBitMask === 1023 && aBitMask === 3221225472) { + return DXGI_TO_TEXTURE_FORMAT[DDS.DXGI_FORMAT.DXGI_FORMAT_R10G10B10A2_UNORM]; + } + if (rBitMask === 65535 && gBitMask === 4294901760 && bBitMask === 0 && aBitMask === 0) { + return DXGI_TO_TEXTURE_FORMAT[DDS.DXGI_FORMAT.DXGI_FORMAT_R16G16_UNORM]; + } + if (rBitMask === 4294967295 && gBitMask === 0 && bBitMask === 0 && aBitMask === 0) { + return DXGI_TO_TEXTURE_FORMAT[DDS.DXGI_FORMAT.DXGI_FORMAT_R32_FLOAT]; + } + break; + case 24: + if (rBitMask === 16711680 && gBitMask === 65280 && bBitMask === 255 && aBitMask === 32768) { + } + break; + case 16: + if (rBitMask === 31744 && gBitMask === 992 && bBitMask === 31 && aBitMask === 32768) { + return DXGI_TO_TEXTURE_FORMAT[DDS.DXGI_FORMAT.DXGI_FORMAT_B5G5R5A1_UNORM]; + } + if (rBitMask === 63488 && gBitMask === 2016 && bBitMask === 31 && aBitMask === 0) { + return DXGI_TO_TEXTURE_FORMAT[DDS.DXGI_FORMAT.DXGI_FORMAT_B5G6R5_UNORM]; + } + if (rBitMask === 3840 && gBitMask === 240 && bBitMask === 15 && aBitMask === 61440) { + return DXGI_TO_TEXTURE_FORMAT[DDS.DXGI_FORMAT.DXGI_FORMAT_B4G4R4A4_UNORM]; + } + if (rBitMask === 255 && gBitMask === 0 && bBitMask === 0 && aBitMask === 65280) { + return DXGI_TO_TEXTURE_FORMAT[DDS.DXGI_FORMAT.DXGI_FORMAT_R8G8_UNORM]; + } + if (rBitMask === 65535 && gBitMask === 0 && bBitMask === 0 && aBitMask === 0) { + return DXGI_TO_TEXTURE_FORMAT[DDS.DXGI_FORMAT.DXGI_FORMAT_R16_UNORM]; + } + break; + case 8: + if (rBitMask === 255 && gBitMask === 0 && bBitMask === 0 && aBitMask === 0) { + return DXGI_TO_TEXTURE_FORMAT[DDS.DXGI_FORMAT.DXGI_FORMAT_R8_UNORM]; + } + break; + } + throw new Error(`DDSParser does not support uncompressed texture with configuration: + bitCount = ${bitCount}, rBitMask = ${rBitMask}, gBitMask = ${gBitMask}, aBitMask = ${aBitMask}`); +} + +"use strict"; +const loadDDS = { + extension: { + type: ExtensionType.LoadParser, + priority: LoaderParserPriority.High + }, + name: "loadDDS", + test(url) { + return checkExtension(url, [".dds"]); + }, + async load(url, _asset, loader) { + const supportedTextures = await getSupportedTextureFormats(); + const ddsResponse = await fetch(url); + const ddsArrayBuffer = await ddsResponse.arrayBuffer(); + const textureOptions = parseDDS(ddsArrayBuffer, supportedTextures); + const compressedTextureSource = new CompressedSource(textureOptions); + return createTexture(compressedTextureSource, loader, url); + }, + unload(texture) { + if (Array.isArray(texture)) { + texture.forEach((t) => t.destroy(true)); + } else { + texture.destroy(true); + } + } +}; + +"use strict"; +var GL_INTERNAL_FORMAT = /* @__PURE__ */ ((GL_INTERNAL_FORMAT2) => { + GL_INTERNAL_FORMAT2[GL_INTERNAL_FORMAT2["RGBA8_SNORM"] = 36759] = "RGBA8_SNORM"; + GL_INTERNAL_FORMAT2[GL_INTERNAL_FORMAT2["RGBA"] = 6408] = "RGBA"; + GL_INTERNAL_FORMAT2[GL_INTERNAL_FORMAT2["RGBA8UI"] = 36220] = "RGBA8UI"; + GL_INTERNAL_FORMAT2[GL_INTERNAL_FORMAT2["SRGB8_ALPHA8"] = 35907] = "SRGB8_ALPHA8"; + GL_INTERNAL_FORMAT2[GL_INTERNAL_FORMAT2["RGBA8I"] = 36238] = "RGBA8I"; + GL_INTERNAL_FORMAT2[GL_INTERNAL_FORMAT2["RGBA8"] = 32856] = "RGBA8"; + GL_INTERNAL_FORMAT2[GL_INTERNAL_FORMAT2["COMPRESSED_RGB_S3TC_DXT1_EXT"] = 33776] = "COMPRESSED_RGB_S3TC_DXT1_EXT"; + GL_INTERNAL_FORMAT2[GL_INTERNAL_FORMAT2["COMPRESSED_RGBA_S3TC_DXT1_EXT"] = 33777] = "COMPRESSED_RGBA_S3TC_DXT1_EXT"; + GL_INTERNAL_FORMAT2[GL_INTERNAL_FORMAT2["COMPRESSED_RGBA_S3TC_DXT3_EXT"] = 33778] = "COMPRESSED_RGBA_S3TC_DXT3_EXT"; + GL_INTERNAL_FORMAT2[GL_INTERNAL_FORMAT2["COMPRESSED_RGBA_S3TC_DXT5_EXT"] = 33779] = "COMPRESSED_RGBA_S3TC_DXT5_EXT"; + GL_INTERNAL_FORMAT2[GL_INTERNAL_FORMAT2["COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT"] = 35917] = "COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT"; + GL_INTERNAL_FORMAT2[GL_INTERNAL_FORMAT2["COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT"] = 35918] = "COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT"; + GL_INTERNAL_FORMAT2[GL_INTERNAL_FORMAT2["COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT"] = 35919] = "COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT"; + GL_INTERNAL_FORMAT2[GL_INTERNAL_FORMAT2["COMPRESSED_SRGB_S3TC_DXT1_EXT"] = 35916] = "COMPRESSED_SRGB_S3TC_DXT1_EXT"; + GL_INTERNAL_FORMAT2[GL_INTERNAL_FORMAT2["COMPRESSED_RED_RGTC1_EXT"] = 36283] = "COMPRESSED_RED_RGTC1_EXT"; + GL_INTERNAL_FORMAT2[GL_INTERNAL_FORMAT2["COMPRESSED_SIGNED_RED_RGTC1_EXT"] = 36284] = "COMPRESSED_SIGNED_RED_RGTC1_EXT"; + GL_INTERNAL_FORMAT2[GL_INTERNAL_FORMAT2["COMPRESSED_RED_GREEN_RGTC2_EXT"] = 36285] = "COMPRESSED_RED_GREEN_RGTC2_EXT"; + GL_INTERNAL_FORMAT2[GL_INTERNAL_FORMAT2["COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT"] = 36286] = "COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT"; + GL_INTERNAL_FORMAT2[GL_INTERNAL_FORMAT2["COMPRESSED_R11_EAC"] = 37488] = "COMPRESSED_R11_EAC"; + GL_INTERNAL_FORMAT2[GL_INTERNAL_FORMAT2["COMPRESSED_SIGNED_R11_EAC"] = 37489] = "COMPRESSED_SIGNED_R11_EAC"; + GL_INTERNAL_FORMAT2[GL_INTERNAL_FORMAT2["COMPRESSED_RG11_EAC"] = 37490] = "COMPRESSED_RG11_EAC"; + GL_INTERNAL_FORMAT2[GL_INTERNAL_FORMAT2["COMPRESSED_SIGNED_RG11_EAC"] = 37491] = "COMPRESSED_SIGNED_RG11_EAC"; + GL_INTERNAL_FORMAT2[GL_INTERNAL_FORMAT2["COMPRESSED_RGB8_ETC2"] = 37492] = "COMPRESSED_RGB8_ETC2"; + GL_INTERNAL_FORMAT2[GL_INTERNAL_FORMAT2["COMPRESSED_RGBA8_ETC2_EAC"] = 37496] = "COMPRESSED_RGBA8_ETC2_EAC"; + GL_INTERNAL_FORMAT2[GL_INTERNAL_FORMAT2["COMPRESSED_SRGB8_ETC2"] = 37493] = "COMPRESSED_SRGB8_ETC2"; + GL_INTERNAL_FORMAT2[GL_INTERNAL_FORMAT2["COMPRESSED_SRGB8_ALPHA8_ETC2_EAC"] = 37497] = "COMPRESSED_SRGB8_ALPHA8_ETC2_EAC"; + GL_INTERNAL_FORMAT2[GL_INTERNAL_FORMAT2["COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2"] = 37494] = "COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2"; + GL_INTERNAL_FORMAT2[GL_INTERNAL_FORMAT2["COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2"] = 37495] = "COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2"; + GL_INTERNAL_FORMAT2[GL_INTERNAL_FORMAT2["COMPRESSED_RGBA_ASTC_4x4_KHR"] = 37808] = "COMPRESSED_RGBA_ASTC_4x4_KHR"; + GL_INTERNAL_FORMAT2[GL_INTERNAL_FORMAT2["COMPRESSED_RGBA_ASTC_5x4_KHR"] = 37809] = "COMPRESSED_RGBA_ASTC_5x4_KHR"; + GL_INTERNAL_FORMAT2[GL_INTERNAL_FORMAT2["COMPRESSED_RGBA_ASTC_5x5_KHR"] = 37810] = "COMPRESSED_RGBA_ASTC_5x5_KHR"; + GL_INTERNAL_FORMAT2[GL_INTERNAL_FORMAT2["COMPRESSED_RGBA_ASTC_6x5_KHR"] = 37811] = "COMPRESSED_RGBA_ASTC_6x5_KHR"; + GL_INTERNAL_FORMAT2[GL_INTERNAL_FORMAT2["COMPRESSED_RGBA_ASTC_6x6_KHR"] = 37812] = "COMPRESSED_RGBA_ASTC_6x6_KHR"; + GL_INTERNAL_FORMAT2[GL_INTERNAL_FORMAT2["COMPRESSED_RGBA_ASTC_8x5_KHR"] = 37813] = "COMPRESSED_RGBA_ASTC_8x5_KHR"; + GL_INTERNAL_FORMAT2[GL_INTERNAL_FORMAT2["COMPRESSED_RGBA_ASTC_8x6_KHR"] = 37814] = "COMPRESSED_RGBA_ASTC_8x6_KHR"; + GL_INTERNAL_FORMAT2[GL_INTERNAL_FORMAT2["COMPRESSED_RGBA_ASTC_8x8_KHR"] = 37815] = "COMPRESSED_RGBA_ASTC_8x8_KHR"; + GL_INTERNAL_FORMAT2[GL_INTERNAL_FORMAT2["COMPRESSED_RGBA_ASTC_10x5_KHR"] = 37816] = "COMPRESSED_RGBA_ASTC_10x5_KHR"; + GL_INTERNAL_FORMAT2[GL_INTERNAL_FORMAT2["COMPRESSED_RGBA_ASTC_10x6_KHR"] = 37817] = "COMPRESSED_RGBA_ASTC_10x6_KHR"; + GL_INTERNAL_FORMAT2[GL_INTERNAL_FORMAT2["COMPRESSED_RGBA_ASTC_10x8_KHR"] = 37818] = "COMPRESSED_RGBA_ASTC_10x8_KHR"; + GL_INTERNAL_FORMAT2[GL_INTERNAL_FORMAT2["COMPRESSED_RGBA_ASTC_10x10_KHR"] = 37819] = "COMPRESSED_RGBA_ASTC_10x10_KHR"; + GL_INTERNAL_FORMAT2[GL_INTERNAL_FORMAT2["COMPRESSED_RGBA_ASTC_12x10_KHR"] = 37820] = "COMPRESSED_RGBA_ASTC_12x10_KHR"; + GL_INTERNAL_FORMAT2[GL_INTERNAL_FORMAT2["COMPRESSED_RGBA_ASTC_12x12_KHR"] = 37821] = "COMPRESSED_RGBA_ASTC_12x12_KHR"; + GL_INTERNAL_FORMAT2[GL_INTERNAL_FORMAT2["COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR"] = 37840] = "COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR"; + GL_INTERNAL_FORMAT2[GL_INTERNAL_FORMAT2["COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR"] = 37841] = "COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR"; + GL_INTERNAL_FORMAT2[GL_INTERNAL_FORMAT2["COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR"] = 37842] = "COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR"; + GL_INTERNAL_FORMAT2[GL_INTERNAL_FORMAT2["COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR"] = 37843] = "COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR"; + GL_INTERNAL_FORMAT2[GL_INTERNAL_FORMAT2["COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR"] = 37844] = "COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR"; + GL_INTERNAL_FORMAT2[GL_INTERNAL_FORMAT2["COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR"] = 37845] = "COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR"; + GL_INTERNAL_FORMAT2[GL_INTERNAL_FORMAT2["COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR"] = 37846] = "COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR"; + GL_INTERNAL_FORMAT2[GL_INTERNAL_FORMAT2["COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR"] = 37847] = "COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR"; + GL_INTERNAL_FORMAT2[GL_INTERNAL_FORMAT2["COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR"] = 37848] = "COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR"; + GL_INTERNAL_FORMAT2[GL_INTERNAL_FORMAT2["COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR"] = 37849] = "COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR"; + GL_INTERNAL_FORMAT2[GL_INTERNAL_FORMAT2["COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR"] = 37850] = "COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR"; + GL_INTERNAL_FORMAT2[GL_INTERNAL_FORMAT2["COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR"] = 37851] = "COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR"; + GL_INTERNAL_FORMAT2[GL_INTERNAL_FORMAT2["COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR"] = 37852] = "COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR"; + GL_INTERNAL_FORMAT2[GL_INTERNAL_FORMAT2["COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR"] = 37853] = "COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR"; + GL_INTERNAL_FORMAT2[GL_INTERNAL_FORMAT2["COMPRESSED_RGBA_BPTC_UNORM_EXT"] = 36492] = "COMPRESSED_RGBA_BPTC_UNORM_EXT"; + GL_INTERNAL_FORMAT2[GL_INTERNAL_FORMAT2["COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT"] = 36493] = "COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT"; + GL_INTERNAL_FORMAT2[GL_INTERNAL_FORMAT2["COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT"] = 36494] = "COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT"; + GL_INTERNAL_FORMAT2[GL_INTERNAL_FORMAT2["COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT"] = 36495] = "COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT"; + return GL_INTERNAL_FORMAT2; +})(GL_INTERNAL_FORMAT || {}); +var GL_FORMATS$1 = /* @__PURE__ */ ((GL_FORMATS2) => { + GL_FORMATS2[GL_FORMATS2["RGBA"] = 6408] = "RGBA"; + GL_FORMATS2[GL_FORMATS2["RGB"] = 6407] = "RGB"; + GL_FORMATS2[GL_FORMATS2["RG"] = 33319] = "RG"; + GL_FORMATS2[GL_FORMATS2["RED"] = 6403] = "RED"; + GL_FORMATS2[GL_FORMATS2["RGBA_INTEGER"] = 36249] = "RGBA_INTEGER"; + GL_FORMATS2[GL_FORMATS2["RGB_INTEGER"] = 36248] = "RGB_INTEGER"; + GL_FORMATS2[GL_FORMATS2["RG_INTEGER"] = 33320] = "RG_INTEGER"; + GL_FORMATS2[GL_FORMATS2["RED_INTEGER"] = 36244] = "RED_INTEGER"; + GL_FORMATS2[GL_FORMATS2["ALPHA"] = 6406] = "ALPHA"; + GL_FORMATS2[GL_FORMATS2["LUMINANCE"] = 6409] = "LUMINANCE"; + GL_FORMATS2[GL_FORMATS2["LUMINANCE_ALPHA"] = 6410] = "LUMINANCE_ALPHA"; + GL_FORMATS2[GL_FORMATS2["DEPTH_COMPONENT"] = 6402] = "DEPTH_COMPONENT"; + GL_FORMATS2[GL_FORMATS2["DEPTH_STENCIL"] = 34041] = "DEPTH_STENCIL"; + return GL_FORMATS2; +})(GL_FORMATS$1 || {}); +var GL_TYPES$1 = /* @__PURE__ */ ((GL_TYPES2) => { + GL_TYPES2[GL_TYPES2["UNSIGNED_BYTE"] = 5121] = "UNSIGNED_BYTE"; + GL_TYPES2[GL_TYPES2["UNSIGNED_SHORT"] = 5123] = "UNSIGNED_SHORT"; + GL_TYPES2[GL_TYPES2["UNSIGNED_SHORT_5_6_5"] = 33635] = "UNSIGNED_SHORT_5_6_5"; + GL_TYPES2[GL_TYPES2["UNSIGNED_SHORT_4_4_4_4"] = 32819] = "UNSIGNED_SHORT_4_4_4_4"; + GL_TYPES2[GL_TYPES2["UNSIGNED_SHORT_5_5_5_1"] = 32820] = "UNSIGNED_SHORT_5_5_5_1"; + GL_TYPES2[GL_TYPES2["UNSIGNED_INT"] = 5125] = "UNSIGNED_INT"; + GL_TYPES2[GL_TYPES2["UNSIGNED_INT_10F_11F_11F_REV"] = 35899] = "UNSIGNED_INT_10F_11F_11F_REV"; + GL_TYPES2[GL_TYPES2["UNSIGNED_INT_2_10_10_10_REV"] = 33640] = "UNSIGNED_INT_2_10_10_10_REV"; + GL_TYPES2[GL_TYPES2["UNSIGNED_INT_24_8"] = 34042] = "UNSIGNED_INT_24_8"; + GL_TYPES2[GL_TYPES2["UNSIGNED_INT_5_9_9_9_REV"] = 35902] = "UNSIGNED_INT_5_9_9_9_REV"; + GL_TYPES2[GL_TYPES2["BYTE"] = 5120] = "BYTE"; + GL_TYPES2[GL_TYPES2["SHORT"] = 5122] = "SHORT"; + GL_TYPES2[GL_TYPES2["INT"] = 5124] = "INT"; + GL_TYPES2[GL_TYPES2["FLOAT"] = 5126] = "FLOAT"; + GL_TYPES2[GL_TYPES2["FLOAT_32_UNSIGNED_INT_24_8_REV"] = 36269] = "FLOAT_32_UNSIGNED_INT_24_8_REV"; + GL_TYPES2[GL_TYPES2["HALF_FLOAT"] = 36193] = "HALF_FLOAT"; + return GL_TYPES2; +})(GL_TYPES$1 || {}); +const INTERNAL_FORMAT_TO_TEXTURE_FORMATS = { + [33776 /* COMPRESSED_RGB_S3TC_DXT1_EXT */]: "bc1-rgba-unorm", + // TODO: ??? + [33777 /* COMPRESSED_RGBA_S3TC_DXT1_EXT */]: "bc1-rgba-unorm", + [33778 /* COMPRESSED_RGBA_S3TC_DXT3_EXT */]: "bc2-rgba-unorm", + [33779 /* COMPRESSED_RGBA_S3TC_DXT5_EXT */]: "bc3-rgba-unorm", + [35916 /* COMPRESSED_SRGB_S3TC_DXT1_EXT */]: "bc1-rgba-unorm-srgb", + // TODO: ??? + [35917 /* COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT */]: "bc1-rgba-unorm-srgb", + [35918 /* COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT */]: "bc2-rgba-unorm-srgb", + [35919 /* COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT */]: "bc3-rgba-unorm-srgb", + [36283 /* COMPRESSED_RED_RGTC1_EXT */]: "bc4-r-unorm", + [36284 /* COMPRESSED_SIGNED_RED_RGTC1_EXT */]: "bc4-r-snorm", + [36285 /* COMPRESSED_RED_GREEN_RGTC2_EXT */]: "bc5-rg-unorm", + [36286 /* COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT */]: "bc5-rg-snorm", + [37488 /* COMPRESSED_R11_EAC */]: "eac-r11unorm", + // [GL_INTERNAL_FORMAT.COMPRESSED_SIGNED_R11_EAC]: 'eac-r11snorm', + [37490 /* COMPRESSED_RG11_EAC */]: "eac-rg11snorm", + // [GL_INTERNAL_FORMAT.COMPRESSED_SIGNED_RG11_EAC]: 'eac-rg11unorm', + [37492 /* COMPRESSED_RGB8_ETC2 */]: "etc2-rgb8unorm", + [37496 /* COMPRESSED_RGBA8_ETC2_EAC */]: "etc2-rgba8unorm", + [37493 /* COMPRESSED_SRGB8_ETC2 */]: "etc2-rgb8unorm-srgb", + [37497 /* COMPRESSED_SRGB8_ALPHA8_ETC2_EAC */]: "etc2-rgba8unorm-srgb", + [37494 /* COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 */]: "etc2-rgb8a1unorm", + [37495 /* COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2 */]: "etc2-rgb8a1unorm-srgb", + [37808 /* COMPRESSED_RGBA_ASTC_4x4_KHR */]: "astc-4x4-unorm", + [37840 /* COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR */]: "astc-4x4-unorm-srgb", + [37809 /* COMPRESSED_RGBA_ASTC_5x4_KHR */]: "astc-5x4-unorm", + [37841 /* COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR */]: "astc-5x4-unorm-srgb", + [37810 /* COMPRESSED_RGBA_ASTC_5x5_KHR */]: "astc-5x5-unorm", + [37842 /* COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR */]: "astc-5x5-unorm-srgb", + [37811 /* COMPRESSED_RGBA_ASTC_6x5_KHR */]: "astc-6x5-unorm", + [37843 /* COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR */]: "astc-6x5-unorm-srgb", + [37812 /* COMPRESSED_RGBA_ASTC_6x6_KHR */]: "astc-6x6-unorm", + [37844 /* COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR */]: "astc-6x6-unorm-srgb", + [37813 /* COMPRESSED_RGBA_ASTC_8x5_KHR */]: "astc-8x5-unorm", + [37845 /* COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR */]: "astc-8x5-unorm-srgb", + [37814 /* COMPRESSED_RGBA_ASTC_8x6_KHR */]: "astc-8x6-unorm", + [37846 /* COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR */]: "astc-8x6-unorm-srgb", + [37815 /* COMPRESSED_RGBA_ASTC_8x8_KHR */]: "astc-8x8-unorm", + [37847 /* COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR */]: "astc-8x8-unorm-srgb", + [37816 /* COMPRESSED_RGBA_ASTC_10x5_KHR */]: "astc-10x5-unorm", + [37848 /* COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR */]: "astc-10x5-unorm-srgb", + [37817 /* COMPRESSED_RGBA_ASTC_10x6_KHR */]: "astc-10x6-unorm", + [37849 /* COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR */]: "astc-10x6-unorm-srgb", + [37818 /* COMPRESSED_RGBA_ASTC_10x8_KHR */]: "astc-10x8-unorm", + [37850 /* COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR */]: "astc-10x8-unorm-srgb", + [37819 /* COMPRESSED_RGBA_ASTC_10x10_KHR */]: "astc-10x10-unorm", + [37851 /* COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR */]: "astc-10x10-unorm-srgb", + [37820 /* COMPRESSED_RGBA_ASTC_12x10_KHR */]: "astc-12x10-unorm", + [37852 /* COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR */]: "astc-12x10-unorm-srgb", + [37821 /* COMPRESSED_RGBA_ASTC_12x12_KHR */]: "astc-12x12-unorm", + [37853 /* COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR */]: "astc-12x12-unorm-srgb", + [36492 /* COMPRESSED_RGBA_BPTC_UNORM_EXT */]: "bc7-rgba-unorm", + [36493 /* COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT */]: "bc7-rgba-unorm-srgb", + [36494 /* COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT */]: "bc6h-rgb-float", + [36495 /* COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT */]: "bc6h-rgb-ufloat", + [35907 /* SRGB8_ALPHA8 */]: "rgba8unorm-srgb", + [36759 /* RGBA8_SNORM */]: "rgba8snorm", + [36220 /* RGBA8UI */]: "rgba8uint", + [36238 /* RGBA8I */]: "rgba8sint", + [6408 /* RGBA */]: "rgba8unorm" + // [GL_INTERNAL_FORMAT.RGBA8]: 'bgra8unorm' +}; +const FILE_IDENTIFIER = [171, 75, 84, 88, 32, 49, 49, 187, 13, 10, 26, 10]; +const FIELDS = { + FILE_IDENTIFIER: 0, + ENDIANNESS: 12, + GL_TYPE: 16, + GL_TYPE_SIZE: 20, + GL_FORMAT: 24, + GL_INTERNAL_FORMAT: 28, + GL_BASE_INTERNAL_FORMAT: 32, + PIXEL_WIDTH: 36, + PIXEL_HEIGHT: 40, + PIXEL_DEPTH: 44, + NUMBER_OF_ARRAY_ELEMENTS: 48, + NUMBER_OF_FACES: 52, + NUMBER_OF_MIPMAP_LEVELS: 56, + BYTES_OF_KEY_VALUE_DATA: 60 +}; +const FILE_HEADER_SIZE = 64; +const ENDIANNESS = 67305985; +const TYPES_TO_BYTES_PER_COMPONENT = { + [5121 /* UNSIGNED_BYTE */]: 1, + [5123 /* UNSIGNED_SHORT */]: 2, + [5124 /* INT */]: 4, + [5125 /* UNSIGNED_INT */]: 4, + [5126 /* FLOAT */]: 4, + [36193 /* HALF_FLOAT */]: 8 +}; +const FORMATS_TO_COMPONENTS = { + [6408 /* RGBA */]: 4, + [6407 /* RGB */]: 3, + [33319 /* RG */]: 2, + [6403 /* RED */]: 1, + [6409 /* LUMINANCE */]: 1, + [6410 /* LUMINANCE_ALPHA */]: 2, + [6406 /* ALPHA */]: 1 +}; +const TYPES_TO_BYTES_PER_PIXEL = { + [32819 /* UNSIGNED_SHORT_4_4_4_4 */]: 2, + [32820 /* UNSIGNED_SHORT_5_5_5_1 */]: 2, + [33635 /* UNSIGNED_SHORT_5_6_5 */]: 2 +}; +const INTERNAL_FORMAT_TO_BYTES_PER_PIXEL = { + [33776 /* COMPRESSED_RGB_S3TC_DXT1_EXT */]: 0.5, + [33777 /* COMPRESSED_RGBA_S3TC_DXT1_EXT */]: 0.5, + [33778 /* COMPRESSED_RGBA_S3TC_DXT3_EXT */]: 1, + [33779 /* COMPRESSED_RGBA_S3TC_DXT5_EXT */]: 1, + [35916 /* COMPRESSED_SRGB_S3TC_DXT1_EXT */]: 0.5, + [35917 /* COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT */]: 0.5, + [35918 /* COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT */]: 1, + [35919 /* COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT */]: 1, + [36283 /* COMPRESSED_RED_RGTC1_EXT */]: 0.5, + [36284 /* COMPRESSED_SIGNED_RED_RGTC1_EXT */]: 0.5, + [36285 /* COMPRESSED_RED_GREEN_RGTC2_EXT */]: 1, + [36286 /* COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT */]: 1, + [37488 /* COMPRESSED_R11_EAC */]: 0.5, + [37489 /* COMPRESSED_SIGNED_R11_EAC */]: 0.5, + [37490 /* COMPRESSED_RG11_EAC */]: 1, + [37491 /* COMPRESSED_SIGNED_RG11_EAC */]: 1, + [37492 /* COMPRESSED_RGB8_ETC2 */]: 0.5, + [37496 /* COMPRESSED_RGBA8_ETC2_EAC */]: 1, + [37493 /* COMPRESSED_SRGB8_ETC2 */]: 0.5, + [37497 /* COMPRESSED_SRGB8_ALPHA8_ETC2_EAC */]: 1, + [37494 /* COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 */]: 0.5, + [37495 /* COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2 */]: 0.5, + [37808 /* COMPRESSED_RGBA_ASTC_4x4_KHR */]: 1, + [37840 /* COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR */]: 1, + [37809 /* COMPRESSED_RGBA_ASTC_5x4_KHR */]: 0.8, + [37841 /* COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR */]: 0.8, + [37810 /* COMPRESSED_RGBA_ASTC_5x5_KHR */]: 0.64, + [37842 /* COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR */]: 0.64, + [37811 /* COMPRESSED_RGBA_ASTC_6x5_KHR */]: 0.53375, + [37843 /* COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR */]: 0.53375, + [37812 /* COMPRESSED_RGBA_ASTC_6x6_KHR */]: 0.445, + [37844 /* COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR */]: 0.445, + [37813 /* COMPRESSED_RGBA_ASTC_8x5_KHR */]: 0.4, + [37845 /* COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR */]: 0.4, + [37814 /* COMPRESSED_RGBA_ASTC_8x6_KHR */]: 0.33375, + [37846 /* COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR */]: 0.33375, + [37815 /* COMPRESSED_RGBA_ASTC_8x8_KHR */]: 0.25, + [37847 /* COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR */]: 0.25, + [37816 /* COMPRESSED_RGBA_ASTC_10x5_KHR */]: 0.32, + [37848 /* COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR */]: 0.32, + [37817 /* COMPRESSED_RGBA_ASTC_10x6_KHR */]: 0.26625, + [37849 /* COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR */]: 0.26625, + [37818 /* COMPRESSED_RGBA_ASTC_10x8_KHR */]: 0.2, + [37850 /* COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR */]: 0.2, + [37819 /* COMPRESSED_RGBA_ASTC_10x10_KHR */]: 0.16, + [37851 /* COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR */]: 0.16, + [37820 /* COMPRESSED_RGBA_ASTC_12x10_KHR */]: 0.13375, + [37852 /* COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR */]: 0.13375, + [37821 /* COMPRESSED_RGBA_ASTC_12x12_KHR */]: 0.11125, + [37853 /* COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR */]: 0.11125, + [36492 /* COMPRESSED_RGBA_BPTC_UNORM_EXT */]: 1, + [36493 /* COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT */]: 1, + [36494 /* COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT */]: 1, + [36495 /* COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT */]: 1 +}; +const KTX = { + FILE_HEADER_SIZE, + FILE_IDENTIFIER, + FORMATS_TO_COMPONENTS, + INTERNAL_FORMAT_TO_BYTES_PER_PIXEL, + INTERNAL_FORMAT_TO_TEXTURE_FORMATS, + FIELDS, + TYPES_TO_BYTES_PER_COMPONENT, + TYPES_TO_BYTES_PER_PIXEL, + ENDIANNESS +}; + +"use strict"; +function parseKTX(arrayBuffer, supportedFormats) { + const dataView = new DataView(arrayBuffer); + if (!validate(dataView)) { + throw new Error("Invalid KTX identifier in header"); + } + const { + littleEndian, + glType, + glFormat, + glInternalFormat, + pixelWidth, + pixelHeight, + numberOfMipmapLevels, + offset + } = parseKTXHeader(dataView); + const textureFormat = KTX.INTERNAL_FORMAT_TO_TEXTURE_FORMATS[glInternalFormat]; + if (!textureFormat) { + throw new Error(`Unknown texture format ${glInternalFormat}`); + } + if (!supportedFormats.includes(textureFormat)) { + throw new Error(`Unsupported texture format: ${textureFormat}, supportedFormats: ${supportedFormats}`); + } + const imagePixelByteSize = getImagePixelByteSize(glType, glFormat, glInternalFormat); + const imageBuffers = getImageBuffers( + dataView, + glType, + imagePixelByteSize, + pixelWidth, + pixelHeight, + offset, + numberOfMipmapLevels, + littleEndian + ); + return { + format: textureFormat, + width: pixelWidth, + height: pixelHeight, + resource: imageBuffers, + alphaMode: "no-premultiply-alpha" + }; +} +function getImageBuffers(dataView, glType, imagePixelByteSize, pixelWidth, pixelHeight, offset, numberOfMipmapLevels, littleEndian) { + const alignedWidth = pixelWidth + 3 & ~3; + const alignedHeight = pixelHeight + 3 & ~3; + let imagePixels = pixelWidth * pixelHeight; + if (glType === 0) { + imagePixels = alignedWidth * alignedHeight; + } + let mipByteSize = imagePixels * imagePixelByteSize; + let mipWidth = pixelWidth; + let mipHeight = pixelHeight; + let alignedMipWidth = alignedWidth; + let alignedMipHeight = alignedHeight; + let imageOffset = offset; + const imageBuffers = new Array(numberOfMipmapLevels); + for (let mipmapLevel = 0; mipmapLevel < numberOfMipmapLevels; mipmapLevel++) { + const imageSize = dataView.getUint32(imageOffset, littleEndian); + let elementOffset = imageOffset + 4; + imageBuffers[mipmapLevel] = new Uint8Array(dataView.buffer, elementOffset, mipByteSize); + elementOffset += mipByteSize; + imageOffset += imageSize + 4; + imageOffset = imageOffset % 4 !== 0 ? imageOffset + 4 - imageOffset % 4 : imageOffset; + mipWidth = mipWidth >> 1 || 1; + mipHeight = mipHeight >> 1 || 1; + alignedMipWidth = mipWidth + 4 - 1 & ~(4 - 1); + alignedMipHeight = mipHeight + 4 - 1 & ~(4 - 1); + mipByteSize = alignedMipWidth * alignedMipHeight * imagePixelByteSize; + } + return imageBuffers; +} +function getImagePixelByteSize(glType, glFormat, glInternalFormat) { + let imagePixelByteSize = KTX.INTERNAL_FORMAT_TO_BYTES_PER_PIXEL[glInternalFormat]; + if (glType !== 0) { + if (KTX.TYPES_TO_BYTES_PER_COMPONENT[glType]) { + imagePixelByteSize = KTX.TYPES_TO_BYTES_PER_COMPONENT[glType] * KTX.FORMATS_TO_COMPONENTS[glFormat]; + } else { + imagePixelByteSize = KTX.TYPES_TO_BYTES_PER_PIXEL[glType]; + } + } + if (imagePixelByteSize === void 0) { + throw new Error("Unable to resolve the pixel format stored in the *.ktx file!"); + } + return imagePixelByteSize; +} +function parseKTXHeader(dataView) { + const littleEndian = dataView.getUint32(KTX.FIELDS.ENDIANNESS, true) === KTX.ENDIANNESS; + const glType = dataView.getUint32(KTX.FIELDS.GL_TYPE, littleEndian); + const glFormat = dataView.getUint32(KTX.FIELDS.GL_FORMAT, littleEndian); + const glInternalFormat = dataView.getUint32(KTX.FIELDS.GL_INTERNAL_FORMAT, littleEndian); + const pixelWidth = dataView.getUint32(KTX.FIELDS.PIXEL_WIDTH, littleEndian); + const pixelHeight = dataView.getUint32(KTX.FIELDS.PIXEL_HEIGHT, littleEndian) || 1; + const pixelDepth = dataView.getUint32(KTX.FIELDS.PIXEL_DEPTH, littleEndian) || 1; + const numberOfArrayElements = dataView.getUint32(KTX.FIELDS.NUMBER_OF_ARRAY_ELEMENTS, littleEndian) || 1; + const numberOfFaces = dataView.getUint32(KTX.FIELDS.NUMBER_OF_FACES, littleEndian); + const numberOfMipmapLevels = dataView.getUint32(KTX.FIELDS.NUMBER_OF_MIPMAP_LEVELS, littleEndian); + const bytesOfKeyValueData = dataView.getUint32(KTX.FIELDS.BYTES_OF_KEY_VALUE_DATA, littleEndian); + if (pixelHeight === 0 || pixelDepth !== 1) { + throw new Error("Only 2D textures are supported"); + } + if (numberOfFaces !== 1) { + throw new Error("CubeTextures are not supported by KTXLoader yet!"); + } + if (numberOfArrayElements !== 1) { + throw new Error("WebGL does not support array textures"); + } + return { + littleEndian, + glType, + glFormat, + glInternalFormat, + pixelWidth, + pixelHeight, + numberOfMipmapLevels, + offset: KTX.FILE_HEADER_SIZE + bytesOfKeyValueData + }; +} +function validate(dataView) { + for (let i = 0; i < KTX.FILE_IDENTIFIER.length; i++) { + if (dataView.getUint8(i) !== KTX.FILE_IDENTIFIER[i]) { + return false; + } + } + return true; +} + +"use strict"; +const loadKTX = { + extension: { + type: ExtensionType.LoadParser, + priority: LoaderParserPriority.High + }, + name: "loadKTX", + test(url) { + return checkExtension(url, ".ktx"); + }, + async load(url, _asset, loader) { + const supportedTextures = await getSupportedTextureFormats(); + const ktxResponse = await fetch(url); + const ktxArrayBuffer = await ktxResponse.arrayBuffer(); + const textureOptions = parseKTX(ktxArrayBuffer, supportedTextures); + const compressedTextureSource = new CompressedSource(textureOptions); + return createTexture(compressedTextureSource, loader, url); + }, + unload(texture) { + if (Array.isArray(texture)) { + texture.forEach((t) => t.destroy(true)); + } else { + texture.destroy(true); + } + } +}; + +const WORKER_CODE = "(function () {\n 'use strict';\n\n const converters = {\n rgb8unorm: {\n convertedFormat: \"rgba8unorm\",\n convertFunction: convertRGBtoRGBA\n },\n \"rgb8unorm-srgb\": {\n convertedFormat: \"rgba8unorm-srgb\",\n convertFunction: convertRGBtoRGBA\n }\n };\n function convertFormatIfRequired(textureOptions) {\n const format = textureOptions.format;\n if (converters[format]) {\n const convertFunction = converters[format].convertFunction;\n const levelBuffers = textureOptions.resource;\n for (let i = 0; i < levelBuffers.length; i++) {\n levelBuffers[i] = convertFunction(levelBuffers[i]);\n }\n textureOptions.format = converters[format].convertedFormat;\n }\n }\n function convertRGBtoRGBA(levelBuffer) {\n const pixelCount = levelBuffer.byteLength / 3;\n const levelBufferWithAlpha = new Uint32Array(pixelCount);\n for (let i = 0; i < pixelCount; ++i) {\n levelBufferWithAlpha[i] = levelBuffer[i * 3] + (levelBuffer[i * 3 + 1] << 8) + (levelBuffer[i * 3 + 2] << 16) + 4278190080;\n }\n return new Uint8Array(levelBufferWithAlpha.buffer);\n }\n\n function createLevelBuffersFromKTX(ktxTexture) {\n const levelBuffers = [];\n for (let i = 0; i < ktxTexture.numLevels; i++) {\n const imageData = ktxTexture.getImageData(i, 0, 0);\n const levelBuffer = new Uint8Array(imageData.byteLength);\n levelBuffer.set(imageData);\n levelBuffers.push(levelBuffer);\n }\n return levelBuffers;\n }\n\n const glFormatToGPUFormatMap = {\n 6408: \"rgba8unorm\",\n 32856: \"bgra8unorm\",\n //\n 32857: \"rgb10a2unorm\",\n 33189: \"depth16unorm\",\n 33190: \"depth24plus\",\n 33321: \"r8unorm\",\n 33323: \"rg8unorm\",\n 33325: \"r16float\",\n 33326: \"r32float\",\n 33327: \"rg16float\",\n 33328: \"rg32float\",\n 33329: \"r8sint\",\n 33330: \"r8uint\",\n 33331: \"r16sint\",\n 33332: \"r16uint\",\n 33333: \"r32sint\",\n 33334: \"r32uint\",\n 33335: \"rg8sint\",\n 33336: \"rg8uint\",\n 33337: \"rg16sint\",\n 33338: \"rg16uint\",\n 33339: \"rg32sint\",\n 33340: \"rg32uint\",\n 33778: \"bc2-rgba-unorm\",\n 33779: \"bc3-rgba-unorm\",\n 34836: \"rgba32float\",\n 34842: \"rgba16float\",\n 35056: \"depth24plus-stencil8\",\n 35898: \"rg11b10ufloat\",\n 35901: \"rgb9e5ufloat\",\n 35907: \"rgba8unorm-srgb\",\n // bgra8unorm-srgb\n 36012: \"depth32float\",\n 36013: \"depth32float-stencil8\",\n 36168: \"stencil8\",\n 36208: \"rgba32uint\",\n 36214: \"rgba16uint\",\n 36220: \"rgba8uint\",\n 36226: \"rgba32sint\",\n 36232: \"rgba16sint\",\n 36238: \"rgba8sint\",\n 36492: \"bc7-rgba-unorm\",\n 36756: \"r8snorm\",\n 36757: \"rg8snorm\",\n 36759: \"rgba8snorm\",\n 37496: \"etc2-rgba8unorm\",\n 37808: \"astc-4x4-unorm\"\n };\n function glFormatToGPUFormat(glInternalFormat) {\n const format = glFormatToGPUFormatMap[glInternalFormat];\n if (format) {\n return format;\n }\n throw new Error(`Unsupported glInternalFormat: ${glInternalFormat}`);\n }\n\n const vkFormatToGPUFormatMap = {\n 23: \"rgb8unorm\",\n // VK_FORMAT_R8G8B8_UNORM\n 37: \"rgba8unorm\",\n // VK_FORMAT_R8G8B8A8_UNORM\n 43: \"rgba8unorm-srgb\"\n // VK_FORMAT_R8G8B8A8_SRGB\n // TODO add more!\n };\n function vkFormatToGPUFormat(vkFormat) {\n const format = vkFormatToGPUFormatMap[vkFormat];\n if (format) {\n return format;\n }\n throw new Error(`Unsupported VkFormat: ${vkFormat}`);\n }\n\n function getTextureFormatFromKTXTexture(ktxTexture) {\n if (ktxTexture.classId === 2) {\n return vkFormatToGPUFormat(ktxTexture.vkFormat);\n }\n return glFormatToGPUFormat(ktxTexture.glInternalformat);\n }\n\n const gpuFormatToBasisTranscoderFormatMap = {\n \"bc3-rgba-unorm\": \"BC3_RGBA\",\n \"bc7-rgba-unorm\": \"BC7_M5_RGBA\",\n \"etc2-rgba8unorm\": \"ETC2_RGBA\",\n \"astc-4x4-unorm\": \"ASTC_4x4_RGBA\",\n // Uncompressed\n rgba8unorm: \"RGBA32\",\n rg11b10ufloat: \"R11F_G11F_B10F\"\n };\n function gpuFormatToKTXBasisTranscoderFormat(transcoderFormat) {\n const format = gpuFormatToBasisTranscoderFormatMap[transcoderFormat];\n if (format) {\n return format;\n }\n throw new Error(`Unsupported transcoderFormat: ${transcoderFormat}`);\n }\n\n const settings = {\n jsUrl: \"\",\n wasmUrl: \"\"\n };\n let basisTranscoderFormat;\n let basisTranscodedTextureFormat;\n let ktxPromise;\n async function getKTX() {\n if (!ktxPromise) {\n const absoluteJsUrl = new URL(settings.jsUrl, location.origin).href;\n const absoluteWasmUrl = new URL(settings.wasmUrl, location.origin).href;\n importScripts(absoluteJsUrl);\n ktxPromise = new Promise((resolve) => {\n LIBKTX({\n locateFile: (_file) => absoluteWasmUrl\n }).then((libktx) => {\n resolve(libktx);\n });\n });\n }\n return ktxPromise;\n }\n async function fetchKTXTexture(url, ktx) {\n const ktx2Response = await fetch(url);\n if (ktx2Response.ok) {\n const ktx2ArrayBuffer = await ktx2Response.arrayBuffer();\n return new ktx.ktxTexture(new Uint8Array(ktx2ArrayBuffer));\n }\n throw new Error(`Failed to load KTX(2) texture: ${url}`);\n }\n const preferredTranscodedFormat = [\n \"bc7-rgba-unorm\",\n \"astc-4x4-unorm\",\n \"etc2-rgba8unorm\",\n \"bc3-rgba-unorm\",\n \"rgba8unorm\"\n ];\n async function load(url) {\n const ktx = await getKTX();\n const ktxTexture = await fetchKTXTexture(url, ktx);\n let format;\n if (ktxTexture.needsTranscoding) {\n format = basisTranscodedTextureFormat;\n const transcodeFormat = ktx.TranscodeTarget[basisTranscoderFormat];\n const result = ktxTexture.transcodeBasis(transcodeFormat, 0);\n if (result !== ktx.ErrorCode.SUCCESS) {\n throw new Error(\"Unable to transcode basis texture.\");\n }\n } else {\n format = getTextureFormatFromKTXTexture(ktxTexture);\n }\n const levelBuffers = createLevelBuffersFromKTX(ktxTexture);\n const textureOptions = {\n width: ktxTexture.baseWidth,\n height: ktxTexture.baseHeight,\n format,\n mipLevelCount: ktxTexture.numLevels,\n resource: levelBuffers,\n alphaMode: \"no-premultiply-alpha\"\n };\n convertFormatIfRequired(textureOptions);\n return textureOptions;\n }\n async function init(jsUrl, wasmUrl, supportedTextures) {\n if (jsUrl)\n settings.jsUrl = jsUrl;\n if (wasmUrl)\n settings.wasmUrl = wasmUrl;\n basisTranscodedTextureFormat = preferredTranscodedFormat.filter((format) => supportedTextures.includes(format))[0];\n basisTranscoderFormat = gpuFormatToKTXBasisTranscoderFormat(basisTranscodedTextureFormat);\n await getKTX();\n }\n const messageHandlers = {\n init: async (data) => {\n const { jsUrl, wasmUrl, supportedTextures } = data;\n await init(jsUrl, wasmUrl, supportedTextures);\n },\n load: async (data) => {\n var _a;\n try {\n const textureOptions = await load(data.url);\n return {\n type: \"load\",\n url: data.url,\n success: true,\n textureOptions,\n transferables: (_a = textureOptions.resource) == null ? void 0 : _a.map((arr) => arr.buffer)\n };\n } catch (e) {\n throw e;\n }\n }\n };\n self.onmessage = async (messageEvent) => {\n var _a;\n const message = messageEvent.data;\n const response = await ((_a = messageHandlers[message.type]) == null ? void 0 : _a.call(messageHandlers, message));\n if (response) {\n self.postMessage(response, response.transferables);\n }\n };\n\n})();\n"; +let WORKER_URL = null; +class WorkerInstance +{ + constructor() + { + if (!WORKER_URL) + { + WORKER_URL = URL.createObjectURL(new Blob([WORKER_CODE], { type: 'application/javascript' })); + } + this.worker = new Worker(WORKER_URL); + } +} +WorkerInstance.revokeObjectURL = function revokeObjectURL() +{ + if (WORKER_URL) + { + URL.revokeObjectURL(WORKER_URL); + WORKER_URL = null; + } +}; + +"use strict"; +const ktxTranscoderUrls = { + jsUrl: "https://files.pixijs.download/transcoders/ktx/libktx.js", + wasmUrl: "https://files.pixijs.download/transcoders/ktx/libktx.wasm" +}; +function setKTXTranscoderPath(config) { + Object.assign(ktxTranscoderUrls, config); +} + +"use strict"; +let ktxWorker; +const urlHash = {}; +function getKTX2Worker(supportedTextures) { + if (!ktxWorker) { + ktxWorker = new WorkerInstance().worker; + ktxWorker.onmessage = (messageEvent) => { + const { success, url, textureOptions } = messageEvent.data; + if (!success) { + console.warn("Failed to load KTX texture", url); + } + urlHash[url](textureOptions); + }; + ktxWorker.postMessage({ + type: "init", + jsUrl: ktxTranscoderUrls.jsUrl, + wasmUrl: ktxTranscoderUrls.wasmUrl, + supportedTextures + }); + } + return ktxWorker; +} +function loadKTX2onWorker(url, supportedTextures) { + const ktxWorker2 = getKTX2Worker(supportedTextures); + return new Promise((resolve) => { + urlHash[url] = resolve; + ktxWorker2.postMessage({ type: "load", url }); + }); +} + +"use strict"; +const loadKTX2 = { + extension: { + type: ExtensionType.LoadParser, + priority: LoaderParserPriority.High + }, + name: "loadKTX2", + test(url) { + return checkExtension(url, ".ktx2"); + }, + async load(url, _asset, loader) { + const supportedTextures = await getSupportedTextureFormats(); + const textureOptions = await loadKTX2onWorker(url, supportedTextures); + const compressedTextureSource = new CompressedSource(textureOptions); + return createTexture(compressedTextureSource, loader, url); + }, + unload(texture) { + if (Array.isArray(texture)) { + texture.forEach((t) => t.destroy(true)); + } else { + texture.destroy(true); + } + } +}; + +"use strict"; + +"use strict"; +const converters = { + rgb8unorm: { + convertedFormat: "rgba8unorm", + convertFunction: convertRGBtoRGBA + }, + "rgb8unorm-srgb": { + convertedFormat: "rgba8unorm-srgb", + convertFunction: convertRGBtoRGBA + } +}; +function convertFormatIfRequired(textureOptions) { + const format = textureOptions.format; + if (converters[format]) { + const convertFunction = converters[format].convertFunction; + const levelBuffers = textureOptions.resource; + for (let i = 0; i < levelBuffers.length; i++) { + levelBuffers[i] = convertFunction(levelBuffers[i]); + } + textureOptions.format = converters[format].convertedFormat; + } +} +function convertRGBtoRGBA(levelBuffer) { + const pixelCount = levelBuffer.byteLength / 3; + const levelBufferWithAlpha = new Uint32Array(pixelCount); + for (let i = 0; i < pixelCount; ++i) { + levelBufferWithAlpha[i] = levelBuffer[i * 3] + (levelBuffer[i * 3 + 1] << 8) + (levelBuffer[i * 3 + 2] << 16) + 4278190080; + } + return new Uint8Array(levelBufferWithAlpha.buffer); +} + +"use strict"; +function createLevelBuffersFromKTX(ktxTexture) { + const levelBuffers = []; + for (let i = 0; i < ktxTexture.numLevels; i++) { + const imageData = ktxTexture.getImageData(i, 0, 0); + const levelBuffer = new Uint8Array(imageData.byteLength); + levelBuffer.set(imageData); + levelBuffers.push(levelBuffer); + } + return levelBuffers; +} + +"use strict"; +const glFormatToGPUFormatMap = { + 6408: "rgba8unorm", + 32856: "bgra8unorm", + // + 32857: "rgb10a2unorm", + 33189: "depth16unorm", + 33190: "depth24plus", + 33321: "r8unorm", + 33323: "rg8unorm", + 33325: "r16float", + 33326: "r32float", + 33327: "rg16float", + 33328: "rg32float", + 33329: "r8sint", + 33330: "r8uint", + 33331: "r16sint", + 33332: "r16uint", + 33333: "r32sint", + 33334: "r32uint", + 33335: "rg8sint", + 33336: "rg8uint", + 33337: "rg16sint", + 33338: "rg16uint", + 33339: "rg32sint", + 33340: "rg32uint", + 33778: "bc2-rgba-unorm", + 33779: "bc3-rgba-unorm", + 34836: "rgba32float", + 34842: "rgba16float", + 35056: "depth24plus-stencil8", + 35898: "rg11b10ufloat", + 35901: "rgb9e5ufloat", + 35907: "rgba8unorm-srgb", + // bgra8unorm-srgb + 36012: "depth32float", + 36013: "depth32float-stencil8", + 36168: "stencil8", + 36208: "rgba32uint", + 36214: "rgba16uint", + 36220: "rgba8uint", + 36226: "rgba32sint", + 36232: "rgba16sint", + 36238: "rgba8sint", + 36492: "bc7-rgba-unorm", + 36756: "r8snorm", + 36757: "rg8snorm", + 36759: "rgba8snorm", + 37496: "etc2-rgba8unorm", + 37808: "astc-4x4-unorm" +}; +function glFormatToGPUFormat(glInternalFormat) { + const format = glFormatToGPUFormatMap[glInternalFormat]; + if (format) { + return format; + } + throw new Error(`Unsupported glInternalFormat: ${glInternalFormat}`); +} + +"use strict"; +const vkFormatToGPUFormatMap = { + 23: "rgb8unorm", + // VK_FORMAT_R8G8B8_UNORM + 37: "rgba8unorm", + // VK_FORMAT_R8G8B8A8_UNORM + 43: "rgba8unorm-srgb" + // VK_FORMAT_R8G8B8A8_SRGB + // TODO add more! +}; +function vkFormatToGPUFormat(vkFormat) { + const format = vkFormatToGPUFormatMap[vkFormat]; + if (format) { + return format; + } + throw new Error(`Unsupported VkFormat: ${vkFormat}`); +} + +"use strict"; +function getTextureFormatFromKTXTexture(ktxTexture) { + if (ktxTexture.classId === 2) { + return vkFormatToGPUFormat(ktxTexture.vkFormat); + } + return glFormatToGPUFormat(ktxTexture.glInternalformat); +} + +"use strict"; +const gpuFormatToBasisTranscoderFormatMap = { + "bc3-rgba-unorm": "BC3_RGBA", + "bc7-rgba-unorm": "BC7_M5_RGBA", + "etc2-rgba8unorm": "ETC2_RGBA", + "astc-4x4-unorm": "ASTC_4x4_RGBA", + // Uncompressed + rgba8unorm: "RGBA32", + rg11b10ufloat: "R11F_G11F_B10F" +}; +function gpuFormatToKTXBasisTranscoderFormat(transcoderFormat) { + const format = gpuFormatToBasisTranscoderFormatMap[transcoderFormat]; + if (format) { + return format; + } + throw new Error(`Unsupported transcoderFormat: ${transcoderFormat}`); +} + +"use strict"; +const validFormats = ["basis", "bc7", "bc6h", "astc", "etc2", "bc5", "bc4", "bc3", "bc2", "bc1", "eac"]; +const resolveCompressedTextureUrl = { + extension: ExtensionType.ResolveParser, + test: (value) => checkExtension(value, [".ktx", ".ktx2", ".dds"]), + parse: (value) => { + var _a, _b; + let format; + const splitValue = value.split("."); + if (splitValue.length > 2) { + const newFormat = splitValue[splitValue.length - 2]; + if (validFormats.includes(newFormat)) { + format = newFormat; + } + } else { + format = splitValue[splitValue.length - 1]; + } + return { + resolution: parseFloat((_b = (_a = Resolver.RETINA_PREFIX.exec(value)) == null ? void 0 : _a[1]) != null ? _b : "1"), + format, + src: value + }; + } +}; + +"use strict"; +let compressedTextureExtensions; +const detectCompressed = { + extension: { + type: ExtensionType.DetectionParser, + priority: 2 + }, + test: async () => { + if (await isWebGPUSupported()) + return true; + if (isWebGLSupported()) + return true; + return false; + }, + add: async (formats) => { + const supportedCompressedTextureFormats = await getSupportedCompressedTextureFormats(); + compressedTextureExtensions = extractExtensionsForCompressedTextureFormats(supportedCompressedTextureFormats); + return [...compressedTextureExtensions, ...formats]; + }, + remove: async (formats) => { + if (compressedTextureExtensions) { + return formats.filter((f) => !(f in compressedTextureExtensions)); + } + return formats; + } +}; +function extractExtensionsForCompressedTextureFormats(formats) { + const extensions = ["basis"]; + const dupeMap = {}; + formats.forEach((format) => { + const extension = format.split("-")[0]; + if (extension && !dupeMap[extension]) { + dupeMap[extension] = true; + extensions.push(extension); + } + }); + extensions.sort((a, b) => { + const aIndex = validFormats.indexOf(a); + const bIndex = validFormats.indexOf(b); + if (aIndex === -1) { + return 1; + } + if (bIndex === -1) { + return -1; + } + return aIndex - bIndex; + }); + return extensions; +} + +"use strict"; + +"use strict"; +const tempBounds$2 = new Bounds(); +const _Culler = class _Culler { + /** + * Culls the children of a specific container based on the given view. This will also cull items that are not + * being explicitly managed by the culler. + * @param container - The container to cull. + * @param view - The view rectangle. + * @param skipUpdateTransform - Whether to skip updating the transform. + */ + cull(container, view, skipUpdateTransform = true) { + this._cullRecursive(container, view, skipUpdateTransform); + } + _cullRecursive(container, view, skipUpdateTransform = true) { + var _a; + if (container.cullable && container.measurable && container.includeInBuild) { + const bounds = (_a = container.cullArea) != null ? _a : getGlobalBounds(container, skipUpdateTransform, tempBounds$2); + container.culled = !(bounds.x >= view.x + view.width || bounds.y >= view.y + view.height || bounds.x + bounds.width <= view.x || bounds.y + bounds.height <= view.y); + } + if (!container.cullableChildren || container.culled || !container.renderable || !container.measurable || !container.includeInBuild) + return; + for (let i = 0; i < container.children.length; i++) { + this._cullRecursive(container.children[i], view, skipUpdateTransform); + } + } +}; +/** A shared instance of the Culler class. */ +_Culler.shared = new _Culler(); +let Culler = _Culler; + +"use strict"; +class CullerPlugin { + static init() { + this._renderRef = this.render.bind(this); + this.render = () => { + Culler.shared.cull(this.stage, this.renderer.screen); + this.renderer.render({ container: this.stage }); + }; + } + static destroy() { + this.render = this._renderRef; + } +} +/** @ignore */ +CullerPlugin.extension = { + priority: 10, + type: ExtensionType.Application, + name: "culler" +}; + +"use strict"; + +"use strict"; + +"use strict"; + +"use strict"; + +"use strict"; +const browserExt = { + extension: { + type: ExtensionType.Environment, + name: "browser", + priority: -1 + }, + test: () => true, + load: async () => { + await Promise.resolve().then(function () { return browserAll; }); + } +}; + +"use strict"; + +"use strict"; + +"use strict"; + +"use strict"; + +"use strict"; + +"use strict"; +var __defProp$v = Object.defineProperty; +var __getOwnPropSymbols$v = Object.getOwnPropertySymbols; +var __hasOwnProp$v = Object.prototype.hasOwnProperty; +var __propIsEnum$v = Object.prototype.propertyIsEnumerable; +var __defNormalProp$v = (obj, key, value) => key in obj ? __defProp$v(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; +var __spreadValues$v = (a, b) => { + for (var prop in b || (b = {})) + if (__hasOwnProp$v.call(b, prop)) + __defNormalProp$v(a, prop, b[prop]); + if (__getOwnPropSymbols$v) + for (var prop of __getOwnPropSymbols$v(b)) { + if (__propIsEnum$v.call(b, prop)) + __defNormalProp$v(a, prop, b[prop]); + } + return a; +}; +var __objRest$d = (source, exclude) => { + var target = {}; + for (var prop in source) + if (__hasOwnProp$v.call(source, prop) && exclude.indexOf(prop) < 0) + target[prop] = source[prop]; + if (source != null && __getOwnPropSymbols$v) + for (var prop of __getOwnPropSymbols$v(source)) { + if (exclude.indexOf(prop) < 0 && __propIsEnum$v.call(source, prop)) + target[prop] = source[prop]; + } + return target; +}; +const _Filter = class _Filter extends Shader { + /** + * @param options - The optional parameters of this filter. + */ + constructor(options) { + options = __spreadValues$v(__spreadValues$v({}, _Filter.defaultOptions), options); + super(options); + /** If enabled is true the filter is applied, if false it will not. */ + this.enabled = true; + /** + * The gpu state the filter requires to render. + * @internal + * @ignore + */ + this._state = State.for2d(); + this.padding = options.padding; + if (typeof options.antialias === "boolean") { + this.antialias = options.antialias ? "on" : "off"; + } else { + this.antialias = options.antialias; + } + this.resolution = options.resolution; + this.blendRequired = options.blendRequired; + this.addResource("uTexture", 0, 1); + } + /** + * Applies the filter + * @param filterManager - The renderer to retrieve the filter from + * @param input - The input render target. + * @param output - The target to output to. + * @param clearMode - Should the output be cleared before rendering to it + */ + apply(filterManager, input, output, clearMode) { + filterManager.applyFilter(this, input, output, clearMode); + } + /** + * Get the blend mode of the filter. + * @default "normal" + */ + get blendMode() { + return this._state.blendMode; + } + /** Sets the blend mode of the filter. */ + set blendMode(value) { + this._state.blendMode = value; + } + /** + * A short hand function to create a filter based of a vertex and fragment shader src. + * @param options + * @returns A shiny new PixiJS filter! + */ + static from(options) { + const _a = options, { gpu, gl } = _a, rest = __objRest$d(_a, ["gpu", "gl"]); + let gpuProgram; + let glProgram; + if (gpu) { + gpuProgram = GpuProgram.from(gpu); + } + if (gl) { + glProgram = GlProgram.from(gl); + } + return new _Filter(__spreadValues$v({ + gpuProgram, + glProgram + }, rest)); + } +}; +/** + * The default filter settings + * @static + */ +_Filter.defaultOptions = { + blendMode: "normal", + resolution: 1, + padding: 0, + antialias: "off", + blendRequired: false +}; +let Filter = _Filter; + +var blendTemplateFrag = "\nin vec2 vTextureCoord;\nin vec4 vColor;\n\nout vec4 finalColor;\n\nuniform float uBlend;\n\nuniform sampler2D uTexture;\nuniform sampler2D uBackTexture;\n\n{FUNCTIONS}\n\nvoid main()\n{ \n vec4 back = texture(uBackTexture, vTextureCoord);\n vec4 front = texture(uTexture, vTextureCoord);\n\n {MAIN}\n}\n"; + +var blendTemplateVert = "in vec2 aPosition;\nout vec2 vTextureCoord;\nout vec2 backgroundUv;\n\nuniform vec4 uInputSize;\nuniform vec4 uOutputFrame;\nuniform vec4 uOutputTexture;\n\nvec4 filterVertexPosition( void )\n{\n vec2 position = aPosition * uOutputFrame.zw + uOutputFrame.xy;\n \n position.x = position.x * (2.0 / uOutputTexture.x) - 1.0;\n position.y = position.y * (2.0*uOutputTexture.z / uOutputTexture.y) - uOutputTexture.z;\n\n return vec4(position, 0.0, 1.0);\n}\n\nvec2 filterTextureCoord( void )\n{\n return aPosition * (uOutputFrame.zw * uInputSize.zw);\n}\n\nvoid main(void)\n{\n gl_Position = filterVertexPosition();\n vTextureCoord = filterTextureCoord();\n}\n"; + +var blendTemplate = "\nstruct GlobalFilterUniforms {\n uInputSize:vec4,\n uInputPixel:vec4,\n uInputClamp:vec4,\n uOutputFrame:vec4,\n uGlobalFrame:vec4,\n uOutputTexture:vec4,\n};\n\nstruct BlendUniforms {\n uBlend:f32,\n};\n\n@group(0) @binding(0) var gfu: GlobalFilterUniforms;\n@group(0) @binding(1) var uTexture: texture_2d;\n@group(0) @binding(2) var uSampler : sampler;\n@group(0) @binding(3) var uBackTexture: texture_2d;\n\n@group(1) @binding(0) var blendUniforms : BlendUniforms;\n\n\nstruct VSOutput {\n @builtin(position) position: vec4,\n @location(0) uv : vec2\n };\n\nfn filterVertexPosition(aPosition:vec2) -> vec4\n{\n var position = aPosition * gfu.uOutputFrame.zw + gfu.uOutputFrame.xy;\n\n position.x = position.x * (2.0 / gfu.uOutputTexture.x) - 1.0;\n position.y = position.y * (2.0*gfu.uOutputTexture.z / gfu.uOutputTexture.y) - gfu.uOutputTexture.z;\n\n return vec4(position, 0.0, 1.0);\n}\n\nfn filterTextureCoord( aPosition:vec2 ) -> vec2\n{\n return aPosition * (gfu.uOutputFrame.zw * gfu.uInputSize.zw);\n}\n\nfn globalTextureCoord( aPosition:vec2 ) -> vec2\n{\n return (aPosition.xy / gfu.uGlobalFrame.zw) + (gfu.uGlobalFrame.xy / gfu.uGlobalFrame.zw); \n}\n \n@vertex\nfn mainVertex(\n @location(0) aPosition : vec2, \n) -> VSOutput {\n return VSOutput(\n filterVertexPosition(aPosition),\n filterTextureCoord(aPosition)\n );\n}\n\n{FUNCTIONS}\n\n@fragment\nfn mainFragment(\n @location(0) uv: vec2\n) -> @location(0) vec4 {\n\n\n var back = textureSample(uBackTexture, uSampler, uv);\n var front = textureSample(uTexture, uSampler, uv);\n \n var out = vec4(0.0,0.0,0.0,0.0);\n\n {MAIN}\n\n return out;\n}"; + +"use strict"; +var __defProp$u = Object.defineProperty; +var __getOwnPropSymbols$u = Object.getOwnPropertySymbols; +var __hasOwnProp$u = Object.prototype.hasOwnProperty; +var __propIsEnum$u = Object.prototype.propertyIsEnumerable; +var __defNormalProp$u = (obj, key, value) => key in obj ? __defProp$u(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; +var __spreadValues$u = (a, b) => { + for (var prop in b || (b = {})) + if (__hasOwnProp$u.call(b, prop)) + __defNormalProp$u(a, prop, b[prop]); + if (__getOwnPropSymbols$u) + for (var prop of __getOwnPropSymbols$u(b)) { + if (__propIsEnum$u.call(b, prop)) + __defNormalProp$u(a, prop, b[prop]); + } + return a; +}; +class BlendModeFilter extends Filter { + constructor(options) { + const gpuOptions = options.gpu; + const gpuSource = compileBlendModeShader(__spreadValues$u({ source: blendTemplate }, gpuOptions)); + const gpuProgram = GpuProgram.from({ + vertex: { + source: gpuSource, + entryPoint: "mainVertex" + }, + fragment: { + source: gpuSource, + entryPoint: "mainFragment" + } + }); + const glOptions = options.gl; + const glSource = compileBlendModeShader(__spreadValues$u({ source: blendTemplateFrag }, glOptions)); + const glProgram = GlProgram.from({ + vertex: blendTemplateVert, + fragment: glSource + }); + const uniformGroup = new UniformGroup({ + uBlend: { + value: 1, + type: "f32" + } + }); + super({ + gpuProgram, + glProgram, + blendRequired: true, + resources: { + blendUniforms: uniformGroup, + uBackTexture: Texture.EMPTY + } + }); + } +} +function compileBlendModeShader(options) { + const { source, functions, main } = options; + return source.replace("{FUNCTIONS}", functions).replace("{MAIN}", main); +} + +"use strict"; +const hslgl = ` float getLuminosity(vec3 c) { return 0.3 * c.r + 0.59 * c.g + 0.11 * c.b; } @@ -631,7 +28988,10 @@ fn mainFragment( return color; } - `,XT=` + `; + +"use strict"; +const hslgpu = ` fn getLuminosity(c: vec3) -> f32 { return 0.3*c.r + 0.59*c.g + 0.11*c.b; @@ -728,116 +29088,139 @@ fn mainFragment( return color; } - `;var ii=`in vec2 aPosition; -out vec2 vTextureCoord; + `; -uniform vec4 uInputSize; -uniform vec4 uOutputFrame; -uniform vec4 uOutputTexture; +var vertex$2 = "in vec2 aPosition;\nout vec2 vTextureCoord;\n\nuniform vec4 uInputSize;\nuniform vec4 uOutputFrame;\nuniform vec4 uOutputTexture;\n\nvec4 filterVertexPosition( void )\n{\n vec2 position = aPosition * uOutputFrame.zw + uOutputFrame.xy;\n \n position.x = position.x * (2.0 / uOutputTexture.x) - 1.0;\n position.y = position.y * (2.0*uOutputTexture.z / uOutputTexture.y) - uOutputTexture.z;\n\n return vec4(position, 0.0, 1.0);\n}\n\nvec2 filterTextureCoord( void )\n{\n return aPosition * (uOutputFrame.zw * uInputSize.zw);\n}\n\nvoid main(void)\n{\n gl_Position = filterVertexPosition();\n vTextureCoord = filterTextureCoord();\n}\n"; -vec4 filterVertexPosition( void ) -{ - vec2 position = aPosition * uOutputFrame.zw + uOutputFrame.xy; - - position.x = position.x * (2.0 / uOutputTexture.x) - 1.0; - position.y = position.y * (2.0*uOutputTexture.z / uOutputTexture.y) - uOutputTexture.z; +var fragment$4 = "\nin vec2 vTextureCoord;\n\nout vec4 finalColor;\n\nuniform float uAlpha;\nuniform sampler2D uTexture;\n\nvoid main()\n{\n finalColor = texture(uTexture, vTextureCoord) * uAlpha;\n}\n"; - return vec4(position, 0.0, 1.0); -} +var source$5 = "struct GlobalFilterUniforms {\n uInputSize:vec4,\n uInputPixel:vec4,\n uInputClamp:vec4,\n uOutputFrame:vec4,\n uGlobalFrame:vec4,\n uOutputTexture:vec4,\n};\n\nstruct AlphaUniforms {\n uAlpha:f32,\n};\n\n@group(0) @binding(0) var gfu: GlobalFilterUniforms;\n@group(0) @binding(1) var uTexture: texture_2d;\n@group(0) @binding(2) var uSampler : sampler;\n\n@group(1) @binding(0) var alphaUniforms : AlphaUniforms;\n\nstruct VSOutput {\n @builtin(position) position: vec4,\n @location(0) uv : vec2\n };\n\nfn filterVertexPosition(aPosition:vec2) -> vec4\n{\n var position = aPosition * gfu.uOutputFrame.zw + gfu.uOutputFrame.xy;\n\n position.x = position.x * (2.0 / gfu.uOutputTexture.x) - 1.0;\n position.y = position.y * (2.0*gfu.uOutputTexture.z / gfu.uOutputTexture.y) - gfu.uOutputTexture.z;\n\n return vec4(position, 0.0, 1.0);\n}\n\nfn filterTextureCoord( aPosition:vec2 ) -> vec2\n{\n return aPosition * (gfu.uOutputFrame.zw * gfu.uInputSize.zw);\n}\n\nfn globalTextureCoord( aPosition:vec2 ) -> vec2\n{\n return (aPosition.xy / gfu.uGlobalFrame.zw) + (gfu.uGlobalFrame.xy / gfu.uGlobalFrame.zw); \n}\n\nfn getSize() -> vec2\n{\n return gfu.uGlobalFrame.zw;\n}\n \n@vertex\nfn mainVertex(\n @location(0) aPosition : vec2, \n) -> VSOutput {\n return VSOutput(\n filterVertexPosition(aPosition),\n filterTextureCoord(aPosition)\n );\n}\n\n@fragment\nfn mainFragment(\n @location(0) uv: vec2,\n @builtin(position) position: vec4\n) -> @location(0) vec4 {\n \n var sample = textureSample(uTexture, uSampler, uv);\n \n return sample * alphaUniforms.uAlpha;\n}"; -vec2 filterTextureCoord( void ) -{ - return aPosition * (uOutputFrame.zw * uInputSize.zw); -} +"use strict"; +var __defProp$t = Object.defineProperty; +var __defProps$e = Object.defineProperties; +var __getOwnPropDescs$e = Object.getOwnPropertyDescriptors; +var __getOwnPropSymbols$t = Object.getOwnPropertySymbols; +var __hasOwnProp$t = Object.prototype.hasOwnProperty; +var __propIsEnum$t = Object.prototype.propertyIsEnumerable; +var __defNormalProp$t = (obj, key, value) => key in obj ? __defProp$t(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; +var __spreadValues$t = (a, b) => { + for (var prop in b || (b = {})) + if (__hasOwnProp$t.call(b, prop)) + __defNormalProp$t(a, prop, b[prop]); + if (__getOwnPropSymbols$t) + for (var prop of __getOwnPropSymbols$t(b)) { + if (__propIsEnum$t.call(b, prop)) + __defNormalProp$t(a, prop, b[prop]); + } + return a; +}; +var __spreadProps$e = (a, b) => __defProps$e(a, __getOwnPropDescs$e(b)); +var __objRest$c = (source2, exclude) => { + var target = {}; + for (var prop in source2) + if (__hasOwnProp$t.call(source2, prop) && exclude.indexOf(prop) < 0) + target[prop] = source2[prop]; + if (source2 != null && __getOwnPropSymbols$t) + for (var prop of __getOwnPropSymbols$t(source2)) { + if (exclude.indexOf(prop) < 0 && __propIsEnum$t.call(source2, prop)) + target[prop] = source2[prop]; + } + return target; +}; +const _AlphaFilter = class _AlphaFilter extends Filter { + constructor(options) { + options = __spreadValues$t(__spreadValues$t({}, _AlphaFilter.defaultOptions), options); + const gpuProgram = GpuProgram.from({ + vertex: { + source: source$5, + entryPoint: "mainVertex" + }, + fragment: { + source: source$5, + entryPoint: "mainFragment" + } + }); + const glProgram = GlProgram.from({ + vertex: vertex$2, + fragment: fragment$4, + name: "alpha-filter" + }); + const _a = options, { alpha } = _a, rest = __objRest$c(_a, ["alpha"]); + const alphaUniforms = new UniformGroup({ + uAlpha: { value: alpha, type: "f32" } + }); + super(__spreadProps$e(__spreadValues$t({}, rest), { + gpuProgram, + glProgram, + resources: { + alphaUniforms + } + })); + } + /** + * Coefficient for alpha multiplication + * @default 1 + */ + get alpha() { + return this.resources.alphaUniforms.uniforms.uAlpha; + } + set alpha(value) { + this.resources.alphaUniforms.uniforms.uAlpha = value; + } +}; +/** Default filter options */ +_AlphaFilter.defaultOptions = { + /** Amount of alpha from 0 to 1, where 0 is transparent */ + alpha: 1 +}; +let AlphaFilter = _AlphaFilter; -void main(void) -{ - gl_Position = filterVertexPosition(); - vTextureCoord = filterTextureCoord(); -} -`,Vf=` -in vec2 vTextureCoord; - -out vec4 finalColor; - -uniform float uAlpha; -uniform sampler2D uTexture; - -void main() -{ - finalColor = texture(uTexture, vTextureCoord) * uAlpha; -} -`,pa=`struct GlobalFilterUniforms { - uInputSize:vec4, - uInputPixel:vec4, - uInputClamp:vec4, - uOutputFrame:vec4, - uGlobalFrame:vec4, - uOutputTexture:vec4, +"use strict"; +const GAUSSIAN_VALUES = { + 5: [0.153388, 0.221461, 0.250301], + 7: [0.071303, 0.131514, 0.189879, 0.214607], + 9: [0.028532, 0.067234, 0.124009, 0.179044, 0.20236], + 11: [93e-4, 0.028002, 0.065984, 0.121703, 0.175713, 0.198596], + 13: [2406e-6, 9255e-6, 0.027867, 0.065666, 0.121117, 0.174868, 0.197641], + 15: [489e-6, 2403e-6, 9246e-6, 0.02784, 0.065602, 0.120999, 0.174697, 0.197448] }; -struct AlphaUniforms { - uAlpha:f32, -}; - -@group(0) @binding(0) var gfu: GlobalFilterUniforms; -@group(0) @binding(1) var uTexture: texture_2d; -@group(0) @binding(2) var uSampler : sampler; - -@group(1) @binding(0) var alphaUniforms : AlphaUniforms; - -struct VSOutput { - @builtin(position) position: vec4, - @location(0) uv : vec2 - }; - -fn filterVertexPosition(aPosition:vec2) -> vec4 -{ - var position = aPosition * gfu.uOutputFrame.zw + gfu.uOutputFrame.xy; - - position.x = position.x * (2.0 / gfu.uOutputTexture.x) - 1.0; - position.y = position.y * (2.0*gfu.uOutputTexture.z / gfu.uOutputTexture.y) - gfu.uOutputTexture.z; - - return vec4(position, 0.0, 1.0); +"use strict"; +const fragTemplate = [ + "in vec2 vBlurTexCoords[%size%];", + "uniform sampler2D uTexture;", + "out vec4 finalColor;", + "void main(void)", + "{", + " finalColor = vec4(0.0);", + " %blur%", + "}" +].join("\n"); +function generateBlurFragSource(kernelSize) { + const kernel = GAUSSIAN_VALUES[kernelSize]; + const halfLength = kernel.length; + let fragSource = fragTemplate; + let blurLoop = ""; + const template = "finalColor += texture(uTexture, vBlurTexCoords[%index%]) * %value%;"; + let value; + for (let i = 0; i < kernelSize; i++) { + let blur = template.replace("%index%", i.toString()); + value = i; + if (i >= halfLength) { + value = kernelSize - i - 1; + } + blur = blur.replace("%value%", kernel[value].toString()); + blurLoop += blur; + blurLoop += "\n"; + } + fragSource = fragSource.replace("%blur%", blurLoop); + fragSource = fragSource.replace("%size%", kernelSize.toString()); + return fragSource; } -fn filterTextureCoord( aPosition:vec2 ) -> vec2 -{ - return aPosition * (gfu.uOutputFrame.zw * gfu.uInputSize.zw); -} - -fn globalTextureCoord( aPosition:vec2 ) -> vec2 -{ - return (aPosition.xy / gfu.uGlobalFrame.zw) + (gfu.uGlobalFrame.xy / gfu.uGlobalFrame.zw); -} - -fn getSize() -> vec2 -{ - return gfu.uGlobalFrame.zw; -} - -@vertex -fn mainVertex( - @location(0) aPosition : vec2, -) -> VSOutput { - return VSOutput( - filterVertexPosition(aPosition), - filterTextureCoord(aPosition) - ); -} - -@fragment -fn mainFragment( - @location(0) uv: vec2, - @builtin(position) position: vec4 -) -> @location(0) vec4 { - - var sample = textureSample(uTexture, uSampler, uv); - - return sample * alphaUniforms.uAlpha; -}`,zT=Object.defineProperty,jT=Object.defineProperties,VT=Object.getOwnPropertyDescriptors,ni=Object.getOwnPropertySymbols,Wf=Object.prototype.hasOwnProperty,Yf=Object.prototype.propertyIsEnumerable,Kf=(r,t,e)=>t in r?zT(r,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):r[t]=e,fa=(r,t)=>{for(var e in t||(t={}))Wf.call(t,e)&&Kf(r,e,t[e]);if(ni)for(var e of ni(t))Yf.call(t,e)&&Kf(r,e,t[e]);return r},WT=(r,t)=>jT(r,VT(t)),YT=(r,t)=>{var e={};for(var s in r)Wf.call(r,s)&&t.indexOf(s)<0&&(e[s]=r[s]);if(r!=null&&ni)for(var s of ni(r))t.indexOf(s)<0&&Yf.call(r,s)&&(e[s]=r[s]);return e};const qf=class Cx extends Yt{constructor(t){t=fa(fa({},Cx.defaultOptions),t);const e=Tt.from({vertex:{source:pa,entryPoint:"mainVertex"},fragment:{source:pa,entryPoint:"mainFragment"}}),s=Rt.from({vertex:ii,fragment:Vf,name:"alpha-filter"}),i=t,{alpha:n}=i,o=YT(i,["alpha"]),a=new it({uAlpha:{value:n,type:"f32"}});super(WT(fa({},o),{gpuProgram:e,glProgram:s,resources:{alphaUniforms:a}}))}get alpha(){return this.resources.alphaUniforms.uniforms.uAlpha}set alpha(t){this.resources.alphaUniforms.uniforms.uAlpha=t}};qf.defaultOptions={alpha:1};let KT=qf;const ma={5:[.153388,.221461,.250301],7:[.071303,.131514,.189879,.214607],9:[.028532,.067234,.124009,.179044,.20236],11:[.0093,.028002,.065984,.121703,.175713,.198596],13:[.002406,.009255,.027867,.065666,.121117,.174868,.197641],15:[489e-6,.002403,.009246,.02784,.065602,.120999,.174697,.197448]},qT=["in vec2 vBlurTexCoords[%size%];","uniform sampler2D uTexture;","out vec4 finalColor;","void main(void)","{"," finalColor = vec4(0.0);"," %blur%","}"].join(` -`);function Zf(r){const t=ma[r],e=t.length;let s=qT,i="";const n="finalColor += texture(uTexture, vBlurTexCoords[%index%]) * %value%;";let o;for(let a=0;a=e&&(o=r-a-1),u=u.replace("%value%",t[o].toString()),i+=u,i+=` -`}return s=s.replace("%blur%",i),s=s.replace("%size%",r.toString()),s}const ZT=` +"use strict"; +const vertTemplate = ` in vec2 aPosition; uniform float uStrength; @@ -871,804 +29254,4635 @@ fn mainFragment( vec2 textureCoord = filterTextureCoord(); %blur% - }`;function Qf(r,t){const e=Math.ceil(r/2);let s=ZT,i="",n;t?n="vBlurTexCoords[%index%] = textureCoord + vec2(%sampleIndex% * pixelStrength, 0.0);":n="vBlurTexCoords[%index%] = textureCoord + vec2(0.0, %sampleIndex% * pixelStrength);";for(let o=0;o, - uInputPixel:vec4, - uInputClamp:vec4, - uOutputFrame:vec4, - uGlobalFrame:vec4, - uOutputTexture:vec4, -}; - -struct BlurUniforms { - uStrength:f32, -}; - -@group(0) @binding(0) var gfu: GlobalFilterUniforms; -@group(0) @binding(1) var uTexture: texture_2d; -@group(0) @binding(2) var uSampler : sampler; - -@group(1) @binding(0) var blurUniforms : BlurUniforms; - - -struct VSOutput { - @builtin(position) position: vec4, - %blur-struct% - }; - -fn filterVertexPosition(aPosition:vec2) -> vec4 -{ - var position = aPosition * gfu.uOutputFrame.zw + gfu.uOutputFrame.xy; - - position.x = position.x * (2.0 / gfu.uOutputTexture.x) - 1.0; - position.y = position.y * (2.0*gfu.uOutputTexture.z / gfu.uOutputTexture.y) - gfu.uOutputTexture.z; - - return vec4(position, 0.0, 1.0); -} - -fn filterTextureCoord( aPosition:vec2 ) -> vec2 -{ - return aPosition * (gfu.uOutputFrame.zw * gfu.uInputSize.zw); -} - -fn globalTextureCoord( aPosition:vec2 ) -> vec2 -{ - return (aPosition.xy / gfu.uGlobalFrame.zw) + (gfu.uGlobalFrame.xy / gfu.uGlobalFrame.zw); -} - -fn getSize() -> vec2 -{ - return gfu.uGlobalFrame.zw; -} - - -@vertex -fn mainVertex( - @location(0) aPosition : vec2, -) -> VSOutput { - - let filteredCord = filterTextureCoord(aPosition); - - let strength = gfu.uInputSize.w * blurUniforms.uStrength; - - return VSOutput( - filterVertexPosition(aPosition), - %blur-vertex-out% - ); -} - -@fragment -fn mainFragment( - @builtin(position) position: vec4, - %blur-fragment-in% -) -> @location(0) vec4 { - - var finalColor = vec4(0.0); - - %blur-sampling% - - return finalColor; -}`;function em(r,t){const e=ma[t],s=e.length,i=[],n=[],o=[];for(let c=0;c,`,r?n[c]=`filteredCord + vec2(${c-s+1} * strength, 0.0),`:n[c]=`filteredCord + vec2(0.0, ${c-s+1} * strength),`;const d=ct in r?QT(r,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):r[t]=e,ga=(r,t)=>{for(var e in t||(t={}))JT.call(t,e)&&sm(r,e,t[e]);if(rm)for(var e of rm(t))tS.call(t,e)&&sm(r,e,t[e]);return r};const im=class Gx extends Yt{constructor(t){t=ga(ga({},Gx.defaultOptions),t);const e=Jf(t.horizontal,t.kernelSize),s=em(t.horizontal,t.kernelSize);super(ga({glProgram:e,gpuProgram:s,resources:{blurUniforms:{uStrength:{value:0,type:"f32"}}}},t)),this.horizontal=t.horizontal,this._quality=0,this.quality=t.quality,this.blur=t.strength,this._uniforms=this.resources.blurUniforms.uniforms}apply(t,e,s,i){if(this._uniforms.uStrength=this.strength/this.passes,this.passes===1)t.applyFilter(this,e,s,i);else{const n=ut.getSameSizeTexture(e);let o=e,a=n;this._state.blend=!1;for(let u=0;ut in r?eS(r,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):r[t]=e,Lr=(r,t)=>{for(var e in t||(t={}))nm.call(t,e)&&am(r,e,t[e]);if(ai)for(var e of ai(t))om.call(t,e)&&am(r,e,t[e]);return r},iS=(r,t)=>rS(r,sS(t)),nS=(r,t)=>{var e={};for(var s in r)nm.call(r,s)&&t.indexOf(s)<0&&(e[s]=r[s]);if(r!=null&&ai)for(var s of ai(r))t.indexOf(s)<0&&om.call(r,s)&&(e[s]=r[s]);return e};class um extends Yt{constructor(...t){var e;let s=(e=t[0])!=null?e:{};typeof s=="number"&&(s={strength:s},t[1]&&(s.quality=t[1]),t[2]&&(s.resolution=t[2]),t[3]&&(s.kernelSize=t[3])),s=Lr(Lr({},oi.defaultOptions),s);const i=s,{strength:n,quality:o}=i,a=nS(i,["strength","quality"]);super(iS(Lr({},a),{compatibleRenderers:xt.BOTH,resources:{}})),this._repeatEdgePixels=!1,this.blurXFilter=new oi(Lr({horizontal:!1},s)),this.blurYFilter=new oi(Lr({horizontal:!0},s)),this.quality=o,this.blur=n,this.repeatEdgePixels=!1}apply(t,e,s,i){const n=Math.abs(this.blurXFilter.strength),o=Math.abs(this.blurYFilter.strength);if(n&&o){const a=ut.getSameSizeTexture(e);this.blurXFilter.apply(t,e,a,!0),this.blurYFilter.apply(t,a,s,i),ut.returnTexture(a)}else o?this.blurYFilter.apply(t,e,s,i):this.blurXFilter.apply(t,e,s,i)}updatePadding(){this._repeatEdgePixels?this.padding=0:this.padding=Math.max(Math.abs(this.blurXFilter.blur),Math.abs(this.blurYFilter.blur))*2}get blur(){return this.blurXFilter.blur}set blur(t){this.blurXFilter.blur=this.blurYFilter.blur=t,this.updatePadding()}get quality(){return this.blurXFilter.quality}set quality(t){this.blurXFilter.quality=this.blurYFilter.quality=t}get blurX(){return this.blurXFilter.blur}set blurX(t){this.blurXFilter.blur=t,this.updatePadding()}get blurY(){return this.blurYFilter.blur}set blurY(t){this.blurYFilter.blur=t,this.updatePadding()}get blendMode(){return this.blurYFilter.blendMode}set blendMode(t){this.blurYFilter.blendMode=t}get repeatEdgePixels(){return this._repeatEdgePixels}set repeatEdgePixels(t){this._repeatEdgePixels=t,this.updatePadding()}}um.defaultOptions={strength:8,quality:4,kernelSize:5};var lm=` -in vec2 vTextureCoord; -in vec4 vColor; - -out vec4 finalColor; - -uniform float uColorMatrix[20]; -uniform float uAlpha; - -uniform sampler2D uTexture; - -float rand(vec2 co) -{ - return fract(sin(dot(co.xy, vec2(12.9898, 78.233))) * 43758.5453); -} - -void main() -{ - vec4 color = texture(uTexture, vTextureCoord); - float randomValue = rand(gl_FragCoord.xy * 0.2); - float diff = (randomValue - 0.5) * 0.5; - - if (uAlpha == 0.0) { - finalColor = color; - return; - } - - if (color.a > 0.0) { - color.rgb /= color.a; - } - - vec4 result; - - result.r = (uColorMatrix[0] * color.r); - result.r += (uColorMatrix[1] * color.g); - result.r += (uColorMatrix[2] * color.b); - result.r += (uColorMatrix[3] * color.a); - result.r += uColorMatrix[4]; - - result.g = (uColorMatrix[5] * color.r); - result.g += (uColorMatrix[6] * color.g); - result.g += (uColorMatrix[7] * color.b); - result.g += (uColorMatrix[8] * color.a); - result.g += uColorMatrix[9]; - - result.b = (uColorMatrix[10] * color.r); - result.b += (uColorMatrix[11] * color.g); - result.b += (uColorMatrix[12] * color.b); - result.b += (uColorMatrix[13] * color.a); - result.b += uColorMatrix[14]; - - result.a = (uColorMatrix[15] * color.r); - result.a += (uColorMatrix[16] * color.g); - result.a += (uColorMatrix[17] * color.b); - result.a += (uColorMatrix[18] * color.a); - result.a += uColorMatrix[19]; - - vec3 rgb = mix(color.rgb, result.rgb, uAlpha); - - // Premultiply alpha again. - rgb *= result.a; - - finalColor = vec4(rgb, result.a); -} -`,_a=`struct GlobalFilterUniforms { - uInputSize:vec4, - uInputPixel:vec4, - uInputClamp:vec4, - uOutputFrame:vec4, - uGlobalFrame:vec4, - uOutputTexture:vec4, -}; - -struct ColorMatrixUniforms { - uColorMatrix:array, 5>, - uAlpha:f32, -}; - - -@group(0) @binding(0) var gfu: GlobalFilterUniforms; -@group(0) @binding(1) var uTexture: texture_2d; -@group(0) @binding(2) var uSampler : sampler; -@group(1) @binding(0) var colorMatrixUniforms : ColorMatrixUniforms; - - -struct VSOutput { - @builtin(position) position: vec4, - @location(0) uv : vec2, - }; - -fn filterVertexPosition(aPosition:vec2) -> vec4 -{ - var position = aPosition * gfu.uOutputFrame.zw + gfu.uOutputFrame.xy; - - position.x = position.x * (2.0 / gfu.uOutputTexture.x) - 1.0; - position.y = position.y * (2.0*gfu.uOutputTexture.z / gfu.uOutputTexture.y) - gfu.uOutputTexture.z; - - return vec4(position, 0.0, 1.0); -} - -fn filterTextureCoord( aPosition:vec2 ) -> vec2 -{ - return aPosition * (gfu.uOutputFrame.zw * gfu.uInputSize.zw); -} - -@vertex -fn mainVertex( - @location(0) aPosition : vec2, -) -> VSOutput { - return VSOutput( - filterVertexPosition(aPosition), - filterTextureCoord(aPosition), - ); -} - - -@fragment -fn mainFragment( - @location(0) uv: vec2, -) -> @location(0) vec4 { - - - var c = textureSample(uTexture, uSampler, uv); - - if (colorMatrixUniforms.uAlpha == 0.0) { - return c; - } - - - // Un-premultiply alpha before applying the color matrix. See issue #3539. - if (c.a > 0.0) { - c.r /= c.a; - c.g /= c.a; - c.b /= c.a; - } - - var cm = colorMatrixUniforms.uColorMatrix; - - - var result = vec4(0.); - - result.r = (cm[0][0] * c.r); - result.r += (cm[0][1] * c.g); - result.r += (cm[0][2] * c.b); - result.r += (cm[0][3] * c.a); - result.r += cm[1][0]; - - result.g = (cm[1][1] * c.r); - result.g += (cm[1][2] * c.g); - result.g += (cm[1][3] * c.b); - result.g += (cm[2][0] * c.a); - result.g += cm[2][1]; - - result.b = (cm[2][2] * c.r); - result.b += (cm[2][3] * c.g); - result.b += (cm[3][0] * c.b); - result.b += (cm[3][1] * c.a); - result.b += cm[3][2]; - - result.a = (cm[3][3] * c.r); - result.a += (cm[4][0] * c.g); - result.a += (cm[4][1] * c.b); - result.a += (cm[4][2] * c.a); - result.a += cm[4][3]; - - var rgb = mix(c.rgb, result.rgb, colorMatrixUniforms.uAlpha); - - rgb.r *= result.a; - rgb.g *= result.a; - rgb.b *= result.a; - - return vec4(rgb, result.a); -}`,oS=Object.defineProperty,aS=Object.defineProperties,uS=Object.getOwnPropertyDescriptors,hm=Object.getOwnPropertySymbols,lS=Object.prototype.hasOwnProperty,hS=Object.prototype.propertyIsEnumerable,cm=(r,t,e)=>t in r?oS(r,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):r[t]=e,cS=(r,t)=>{for(var e in t||(t={}))lS.call(t,e)&&cm(r,e,t[e]);if(hm)for(var e of hm(t))hS.call(t,e)&&cm(r,e,t[e]);return r},dS=(r,t)=>aS(r,uS(t));class pS extends Yt{constructor(t={}){const e=new it({uColorMatrix:{value:[1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0],type:"f32",size:20},uAlpha:{value:1,type:"f32"}}),s=Tt.from({vertex:{source:_a,entryPoint:"mainVertex"},fragment:{source:_a,entryPoint:"mainFragment"}}),i=Rt.from({vertex:ii,fragment:lm,name:"color-matrix-filter"});super(dS(cS({},t),{gpuProgram:s,glProgram:i,resources:{colorMatrixUniforms:e}})),this.alpha=1}_loadMatrix(t,e=!1){let s=t;e&&(this._multiply(s,this.matrix,t),s=this._colorMatrix(s)),this.resources.colorMatrixUniforms.uniforms.uColorMatrix=s,this.resources.colorMatrixUniforms.update()}_multiply(t,e,s){return t[0]=e[0]*s[0]+e[1]*s[5]+e[2]*s[10]+e[3]*s[15],t[1]=e[0]*s[1]+e[1]*s[6]+e[2]*s[11]+e[3]*s[16],t[2]=e[0]*s[2]+e[1]*s[7]+e[2]*s[12]+e[3]*s[17],t[3]=e[0]*s[3]+e[1]*s[8]+e[2]*s[13]+e[3]*s[18],t[4]=e[0]*s[4]+e[1]*s[9]+e[2]*s[14]+e[3]*s[19]+e[4],t[5]=e[5]*s[0]+e[6]*s[5]+e[7]*s[10]+e[8]*s[15],t[6]=e[5]*s[1]+e[6]*s[6]+e[7]*s[11]+e[8]*s[16],t[7]=e[5]*s[2]+e[6]*s[7]+e[7]*s[12]+e[8]*s[17],t[8]=e[5]*s[3]+e[6]*s[8]+e[7]*s[13]+e[8]*s[18],t[9]=e[5]*s[4]+e[6]*s[9]+e[7]*s[14]+e[8]*s[19]+e[9],t[10]=e[10]*s[0]+e[11]*s[5]+e[12]*s[10]+e[13]*s[15],t[11]=e[10]*s[1]+e[11]*s[6]+e[12]*s[11]+e[13]*s[16],t[12]=e[10]*s[2]+e[11]*s[7]+e[12]*s[12]+e[13]*s[17],t[13]=e[10]*s[3]+e[11]*s[8]+e[12]*s[13]+e[13]*s[18],t[14]=e[10]*s[4]+e[11]*s[9]+e[12]*s[14]+e[13]*s[19]+e[14],t[15]=e[15]*s[0]+e[16]*s[5]+e[17]*s[10]+e[18]*s[15],t[16]=e[15]*s[1]+e[16]*s[6]+e[17]*s[11]+e[18]*s[16],t[17]=e[15]*s[2]+e[16]*s[7]+e[17]*s[12]+e[18]*s[17],t[18]=e[15]*s[3]+e[16]*s[8]+e[17]*s[13]+e[18]*s[18],t[19]=e[15]*s[4]+e[16]*s[9]+e[17]*s[14]+e[18]*s[19]+e[19],t}_colorMatrix(t){const e=new Float32Array(t);return e[4]/=255,e[9]/=255,e[14]/=255,e[19]/=255,e}brightness(t,e){const s=[t,0,0,0,0,0,t,0,0,0,0,0,t,0,0,0,0,0,1,0];this._loadMatrix(s,e)}tint(t,e){const[s,i,n]=W.shared.setValue(t).toArray(),o=[s,0,0,0,0,0,i,0,0,0,0,0,n,0,0,0,0,0,1,0];this._loadMatrix(o,e)}greyscale(t,e){const s=[t,t,t,0,0,t,t,t,0,0,t,t,t,0,0,0,0,0,1,0];this._loadMatrix(s,e)}grayscale(t,e){this.greyscale(t,e)}blackAndWhite(t){const e=[.3,.6,.1,0,0,.3,.6,.1,0,0,.3,.6,.1,0,0,0,0,0,1,0];this._loadMatrix(e,t)}hue(t,e){t=(t||0)/180*Math.PI;const s=Math.cos(t),i=Math.sin(t),n=Math.sqrt,o=1/3,a=n(o),u=s+(1-s)*o,l=o*(1-s)-a*i,h=o*(1-s)+a*i,c=o*(1-s)+a*i,d=s+o*(1-s),p=o*(1-s)-a*i,f=o*(1-s)-a*i,g=o*(1-s)+a*i,m=s+o*(1-s),_=[u,l,h,0,0,c,d,p,0,0,f,g,m,0,0,0,0,0,1,0];this._loadMatrix(_,e)}contrast(t,e){const s=(t||0)+1,i=-.5*(s-1),n=[s,0,0,0,i,0,s,0,0,i,0,0,s,0,i,0,0,0,1,0];this._loadMatrix(n,e)}saturate(t=0,e){const s=t*2/3+1,i=(s-1)*-.5,n=[s,i,i,0,0,i,s,i,0,0,i,i,s,0,0,0,0,0,1,0];this._loadMatrix(n,e)}desaturate(){this.saturate(-1)}negative(t){const e=[-1,0,0,1,0,0,-1,0,1,0,0,0,-1,1,0,0,0,0,1,0];this._loadMatrix(e,t)}sepia(t){const e=[.393,.7689999,.18899999,0,0,.349,.6859999,.16799999,0,0,.272,.5339999,.13099999,0,0,0,0,0,1,0];this._loadMatrix(e,t)}technicolor(t){const e=[1.9125277891456083,-.8545344976951645,-.09155508482755585,0,11.793603434377337,-.3087833385928097,1.7658908555458428,-.10601743074722245,0,-70.35205161461398,-.231103377548616,-.7501899197440212,1.847597816108189,0,30.950940869491138,0,0,0,1,0];this._loadMatrix(e,t)}polaroid(t){const e=[1.438,-.062,-.062,0,0,-.122,1.378,-.122,0,0,-.016,-.016,1.483,0,0,0,0,0,1,0];this._loadMatrix(e,t)}toBGR(t){const e=[0,0,1,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,1,0];this._loadMatrix(e,t)}kodachrome(t){const e=[1.1285582396593525,-.3967382283601348,-.03992559172921793,0,63.72958762196502,-.16404339962244616,1.0835251566291304,-.05498805115633132,0,24.732407896706203,-.16786010706155763,-.5603416277695248,1.6014850761964943,0,35.62982807460946,0,0,0,1,0];this._loadMatrix(e,t)}browni(t){const e=[.5997023498159715,.34553243048391263,-.2708298674538042,0,47.43192855600873,-.037703249837783157,.8609577587992641,.15059552388459913,0,-36.96841498319127,.24113635128153335,-.07441037908422492,.44972182064877153,0,-7.562075277591283,0,0,0,1,0];this._loadMatrix(e,t)}vintage(t){const e=[.6279345635605994,.3202183420819367,-.03965408211312453,0,9.651285835294123,.02578397704808868,.6441188644374771,.03259127616149294,0,7.462829176470591,.0466055556782719,-.0851232987247891,.5241648018700465,0,5.159190588235296,0,0,0,1,0];this._loadMatrix(e,t)}colorTone(t,e,s,i,n){t=t||.2,e=e||.15,s=s||16770432,i=i||3375104;const o=W.shared,[a,u,l]=o.setValue(s).toArray(),[h,c,d]=o.setValue(i).toArray(),p=[.3,.59,.11,0,0,a,u,l,t,0,h,c,d,e,0,a-h,u-c,l-d,0,0];this._loadMatrix(p,n)}night(t,e){t=t||.1;const s=[t*-2,-t,0,0,0,-t,0,t,0,0,0,t,t*2,0,0,0,0,0,1,0];this._loadMatrix(s,e)}predator(t,e){const s=[11.224130630493164*t,-4.794486999511719*t,-2.8746118545532227*t,0*t,.40342438220977783*t,-3.6330697536468506*t,9.193157196044922*t,-2.951810836791992*t,0*t,-1.316135048866272*t,-3.2184197902679443*t,-4.2375030517578125*t,7.476448059082031*t,0*t,.8044459223747253*t,0,0,0,1,0];this._loadMatrix(s,e)}lsd(t){const e=[2,-.4,.5,0,0,-.5,2,-.4,0,0,-.4,-.5,3,0,0,0,0,0,1,0];this._loadMatrix(e,t)}reset(){const t=[1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0];this._loadMatrix(t,!1)}get matrix(){return this.resources.colorMatrixUniforms.uniforms.uColorMatrix}set matrix(t){this.resources.colorMatrixUniforms.uniforms.uColorMatrix=t}get alpha(){return this.resources.colorMatrixUniforms.uniforms.uAlpha}set alpha(t){this.resources.colorMatrixUniforms.uniforms.uAlpha=t}}var dm=` -in vec2 vTextureCoord; -in vec2 vFilterUv; - -out vec4 finalColor; - -uniform sampler2D uTexture; -uniform sampler2D uMapTexture; - -uniform vec4 uInputClamp; -uniform highp vec4 uInputSize; -uniform mat2 uRotation; -uniform vec2 uScale; - -void main() -{ - vec4 map = texture(uMapTexture, vFilterUv); - - vec2 offset = uInputSize.zw * (uRotation * (map.xy - 0.5)) * uScale; - - finalColor = texture(uTexture, clamp(vTextureCoord + offset, uInputClamp.xy, uInputClamp.zw)); -} -`,pm=`in vec2 aPosition; -out vec2 vTextureCoord; -out vec2 vFilterUv; - - -uniform vec4 uInputSize; -uniform vec4 uOutputFrame; -uniform vec4 uOutputTexture; - -uniform mat3 uFilterMatrix; - -vec4 filterVertexPosition( void ) -{ - vec2 position = aPosition * uOutputFrame.zw + uOutputFrame.xy; - - position.x = position.x * (2.0 / uOutputTexture.x) - 1.0; - position.y = position.y * (2.0*uOutputTexture.z / uOutputTexture.y) - uOutputTexture.z; - - return vec4(position, 0.0, 1.0); -} - -vec2 filterTextureCoord( void ) -{ - return aPosition * (uOutputFrame.zw * uInputSize.zw); -} - -vec2 getFilterCoord( void ) -{ - return ( uFilterMatrix * vec3( filterTextureCoord(), 1.0) ).xy; -} - - -void main(void) -{ - gl_Position = filterVertexPosition(); - vTextureCoord = filterTextureCoord(); - vFilterUv = getFilterCoord(); -} -`,xa=` -struct GlobalFilterUniforms { - uInputSize:vec4, - uInputPixel:vec4, - uInputClamp:vec4, - uOutputFrame:vec4, - uGlobalFrame:vec4, - uOutputTexture:vec4, -}; - -struct DisplacementUniforms { - uFilterMatrix:mat3x3, - uScale:vec2, - uRotation:mat2x2 -}; - - - -@group(0) @binding(0) var gfu: GlobalFilterUniforms; -@group(0) @binding(1) var uTexture: texture_2d; -@group(0) @binding(2) var uSampler : sampler; - -@group(1) @binding(0) var filterUniforms : DisplacementUniforms; -@group(1) @binding(1) var uMapTexture: texture_2d; -@group(1) @binding(2) var uMapSampler : sampler; - -struct VSOutput { - @builtin(position) position: vec4, - @location(0) uv : vec2, - @location(1) filterUv : vec2, - }; - -fn filterVertexPosition(aPosition:vec2) -> vec4 -{ - var position = aPosition * gfu.uOutputFrame.zw + gfu.uOutputFrame.xy; - - position.x = position.x * (2.0 / gfu.uOutputTexture.x) - 1.0; - position.y = position.y * (2.0*gfu.uOutputTexture.z / gfu.uOutputTexture.y) - gfu.uOutputTexture.z; - - return vec4(position, 0.0, 1.0); -} - -fn filterTextureCoord( aPosition:vec2 ) -> vec2 -{ - return aPosition * (gfu.uOutputFrame.zw * gfu.uInputSize.zw); -} - -fn globalTextureCoord( aPosition:vec2 ) -> vec2 -{ - return (aPosition.xy / gfu.uGlobalFrame.zw) + (gfu.uGlobalFrame.xy / gfu.uGlobalFrame.zw); -} - -fn getFilterCoord(aPosition:vec2 ) -> vec2 -{ - return ( filterUniforms.uFilterMatrix * vec3( filterTextureCoord(aPosition), 1.0) ).xy; -} - -fn getSize() -> vec2 -{ - - - return gfu.uGlobalFrame.zw; -} - -@vertex -fn mainVertex( - @location(0) aPosition : vec2, -) -> VSOutput { - return VSOutput( - filterVertexPosition(aPosition), - filterTextureCoord(aPosition), - getFilterCoord(aPosition) - ); -} - -@fragment -fn mainFragment( - @location(0) uv: vec2, - @location(1) filterUv: vec2, - @builtin(position) position: vec4 -) -> @location(0) vec4 { - - var map = textureSample(uMapTexture, uMapSampler, filterUv); - - var offset = gfu.uInputSize.zw * (filterUniforms.uRotation * (map.xy - 0.5)) * filterUniforms.uScale; - - return textureSample(uTexture, uSampler, clamp(uv + offset, gfu.uInputClamp.xy, gfu.uInputClamp.zw)); -}`,fS=Object.defineProperty,mS=Object.defineProperties,gS=Object.getOwnPropertyDescriptors,ui=Object.getOwnPropertySymbols,fm=Object.prototype.hasOwnProperty,mm=Object.prototype.propertyIsEnumerable,gm=(r,t,e)=>t in r?fS(r,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):r[t]=e,_S=(r,t)=>{for(var e in t||(t={}))fm.call(t,e)&&gm(r,e,t[e]);if(ui)for(var e of ui(t))mm.call(t,e)&&gm(r,e,t[e]);return r},xS=(r,t)=>mS(r,gS(t)),bS=(r,t)=>{var e={};for(var s in r)fm.call(r,s)&&t.indexOf(s)<0&&(e[s]=r[s]);if(r!=null&&ui)for(var s of ui(r))t.indexOf(s)<0&&mm.call(r,s)&&(e[s]=r[s]);return e};class vS extends Yt{constructor(...t){let e=t[0];e instanceof Ft&&(e={sprite:e,scale:t[1]});const s=e,{sprite:i,scale:n}=s,o=bS(s,["sprite","scale"]);let a=n!=null?n:20;typeof a=="number"&&(a=new j(a,a));const u=new it({uFilterMatrix:{value:new G,type:"mat3x3"},uScale:{value:a,type:"vec2"},uRotation:{value:new Float32Array([0,0,0,0]),type:"mat2x2"}}),l=Rt.from({vertex:pm,fragment:dm,name:"displacement-filter"}),h=Tt.from({vertex:{source:xa,entryPoint:"mainVertex"},fragment:{source:xa,entryPoint:"mainFragment"}}),c=i.texture.source;super(xS(_S({},o),{gpuProgram:h,glProgram:l,resources:{filterUniforms:u,uMapTexture:c,uMapSampler:c.style}})),this._sprite=e.sprite,this._sprite.renderable=!1}apply(t,e,s,i){const n=this.resources.filterUniforms.uniforms;t.calculateSpriteMatrix(n.uFilterMatrix,this._sprite);const o=this._sprite.worldTransform,a=Math.sqrt(o.a*o.a+o.b*o.b),u=Math.sqrt(o.c*o.c+o.d*o.d);a!==0&&u!==0&&(n.uRotation[0]=o.a/a,n.uRotation[1]=o.b/a,n.uRotation[2]=o.c/u,n.uRotation[3]=o.d/u),this.resources.uMapTexture=this._sprite.texture.source,t.applyFilter(this,e,s,i)}get scale(){return this.resources.filterUniforms.uniforms.uScale}}var _m=` -in vec2 vTextureCoord; -in vec4 vColor; - -out vec4 finalColor; - -uniform float uNoise; -uniform float uSeed; -uniform sampler2D uTexture; - -float rand(vec2 co) -{ - return fract(sin(dot(co.xy, vec2(12.9898, 78.233))) * 43758.5453); -} - -void main() -{ - vec4 color = texture(uTexture, vTextureCoord); - float randomValue = rand(gl_FragCoord.xy * uSeed); - float diff = (randomValue - 0.5) * uNoise; - - // Un-premultiply alpha before applying the color matrix. See issue #3539. - if (color.a > 0.0) { - color.rgb /= color.a; - } - - color.r += diff; - color.g += diff; - color.b += diff; - - // Premultiply alpha again. - color.rgb *= color.a; - - finalColor = color; -} -`,ba=` - -struct GlobalFilterUniforms { - uInputSize:vec4, - uInputPixel:vec4, - uInputClamp:vec4, - uOutputFrame:vec4, - uGlobalFrame:vec4, - uOutputTexture:vec4, -}; - -struct NoiseUniforms { - uNoise:f32, - uSeed:f32, -}; - -@group(0) @binding(0) var gfu: GlobalFilterUniforms; -@group(0) @binding(1) var uTexture: texture_2d; -@group(0) @binding(2) var uSampler : sampler; - -@group(1) @binding(0) var noiseUniforms : NoiseUniforms; - -struct VSOutput { - @builtin(position) position: vec4, - @location(0) uv : vec2 - }; - -fn filterVertexPosition(aPosition:vec2) -> vec4 -{ - var position = aPosition * gfu.uOutputFrame.zw + gfu.uOutputFrame.xy; - - position.x = position.x * (2.0 / gfu.uOutputTexture.x) - 1.0; - position.y = position.y * (2.0*gfu.uOutputTexture.z / gfu.uOutputTexture.y) - gfu.uOutputTexture.z; - - return vec4(position, 0.0, 1.0); -} - -fn filterTextureCoord( aPosition:vec2 ) -> vec2 -{ - return aPosition * (gfu.uOutputFrame.zw * gfu.uInputSize.zw); -} - -fn globalTextureCoord( aPosition:vec2 ) -> vec2 -{ - return (aPosition.xy / gfu.uGlobalFrame.zw) + (gfu.uGlobalFrame.xy / gfu.uGlobalFrame.zw); -} - -fn getSize() -> vec2 -{ - return gfu.uGlobalFrame.zw; -} - -@vertex -fn mainVertex( - @location(0) aPosition : vec2, -) -> VSOutput { - return VSOutput( - filterVertexPosition(aPosition), - filterTextureCoord(aPosition) - ); -} - -fn rand(co:vec2) -> f32 -{ - return fract(sin(dot(co.xy, vec2(12.9898, 78.233))) * 43758.5453); -} - - - -@fragment -fn mainFragment( - @location(0) uv: vec2, - @builtin(position) position: vec4 -) -> @location(0) vec4 { - - var pixelPosition = globalTextureCoord(position.xy);// / (getSize());//- gfu.uOutputFrame.xy); - - - var sample = textureSample(uTexture, uSampler, uv); - var randomValue = rand(pixelPosition.xy * noiseUniforms.uSeed); - var diff = (randomValue - 0.5) * noiseUniforms.uNoise; - - // Un-premultiply alpha before applying the color matrix. See issue #3539. - if (sample.a > 0.0) { - sample.r /= sample.a; - sample.g /= sample.a; - sample.b /= sample.a; - } - - sample.r += diff; - sample.g += diff; - sample.b += diff; - - // Premultiply alpha again. - sample.r *= sample.a; - sample.g *= sample.a; - sample.b *= sample.a; - - return sample; -}`,yS=Object.defineProperty,TS=Object.defineProperties,SS=Object.getOwnPropertyDescriptors,li=Object.getOwnPropertySymbols,xm=Object.prototype.hasOwnProperty,bm=Object.prototype.propertyIsEnumerable,vm=(r,t,e)=>t in r?yS(r,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):r[t]=e,va=(r,t)=>{for(var e in t||(t={}))xm.call(t,e)&&vm(r,e,t[e]);if(li)for(var e of li(t))bm.call(t,e)&&vm(r,e,t[e]);return r},ES=(r,t)=>TS(r,SS(t)),AS=(r,t)=>{var e={};for(var s in r)xm.call(r,s)&&t.indexOf(s)<0&&(e[s]=r[s]);if(r!=null&&li)for(var s of li(r))t.indexOf(s)<0&&bm.call(r,s)&&(e[s]=r[s]);return e};const ym=class Ix extends Yt{constructor(t={}){t=va(va({},Ix.defaultOptions),t);const e=Tt.from({vertex:{source:ba,entryPoint:"mainVertex"},fragment:{source:ba,entryPoint:"mainFragment"}}),s=Rt.from({vertex:ii,fragment:_m,name:"noise-filter"}),i=t,{noise:n,seed:o}=i,a=AS(i,["noise","seed"]);super(ES(va({},a),{gpuProgram:e,glProgram:s,resources:{noiseUniforms:new it({uNoise:{value:1,type:"f32"},uSeed:{value:1,type:"f32"}})}})),this.noise=n,this.seed=o!=null?o:Math.random()}get noise(){return this.resources.noiseUniforms.uniforms.uNoise}set noise(t){this.resources.noiseUniforms.uniforms.uNoise=t}get seed(){return this.resources.noiseUniforms.uniforms.uSeed}set seed(t){this.resources.noiseUniforms.uniforms.uSeed=t}};ym.defaultOptions={noise:.5};let PS=ym;var Tm=`in vec2 vMaskCoord; -in vec2 vTextureCoord; - -uniform sampler2D uTexture; -uniform sampler2D uMaskTexture; - -uniform float uAlpha; -uniform vec4 uMaskClamp; - -out vec4 finalColor; - -void main(void) -{ - float clip = step(3.5, - step(uMaskClamp.x, vMaskCoord.x) + - step(uMaskClamp.y, vMaskCoord.y) + - step(vMaskCoord.x, uMaskClamp.z) + - step(vMaskCoord.y, uMaskClamp.w)); - - // TODO look into why this is needed - float npmAlpha = uAlpha; - vec4 original = texture(uTexture, vTextureCoord); - vec4 masky = texture(uMaskTexture, vMaskCoord); - float alphaMul = 1.0 - npmAlpha * (1.0 - masky.a); - - original *= (alphaMul * masky.r * uAlpha * clip); - - finalColor = original; -} -`,Sm=`in vec2 aPosition; - -out vec2 vTextureCoord; -out vec2 vMaskCoord; - - -uniform vec4 uInputSize; -uniform vec4 uOutputFrame; -uniform vec4 uOutputTexture; -uniform mat3 uFilterMatrix; - -vec4 filterVertexPosition( vec2 aPosition ) -{ - vec2 position = aPosition * uOutputFrame.zw + uOutputFrame.xy; - - position.x = position.x * (2.0 / uOutputTexture.x) - 1.0; - position.y = position.y * (2.0*uOutputTexture.z / uOutputTexture.y) - uOutputTexture.z; - - return vec4(position, 0.0, 1.0); -} - -vec2 filterTextureCoord( vec2 aPosition ) -{ - return aPosition * (uOutputFrame.zw * uInputSize.zw); -} - -vec2 getFilterCoord( vec2 aPosition ) -{ - return ( uFilterMatrix * vec3( filterTextureCoord(aPosition), 1.0) ).xy; -} - -void main(void) -{ - gl_Position = filterVertexPosition(aPosition); - vTextureCoord = filterTextureCoord(aPosition); - vMaskCoord = getFilterCoord(aPosition); -} -`,ya=`struct GlobalFilterUniforms { - uInputSize:vec4, - uInputPixel:vec4, - uInputClamp:vec4, - uOutputFrame:vec4, - uGlobalFrame:vec4, - uOutputTexture:vec4, -}; - -struct MaskUniforms { - uFilterMatrix:mat3x3, - uMaskClamp:vec4, - uAlpha:f32, -}; - - -@group(0) @binding(0) var gfu: GlobalFilterUniforms; -@group(0) @binding(1) var uTexture: texture_2d; -@group(0) @binding(2) var uSampler : sampler; - -@group(1) @binding(0) var filterUniforms : MaskUniforms; -@group(1) @binding(1) var uMaskTexture: texture_2d; - -struct VSOutput { - @builtin(position) position: vec4, - @location(0) uv : vec2, - @location(1) filterUv : vec2, - }; - -fn filterVertexPosition(aPosition:vec2) -> vec4 -{ - var position = aPosition * gfu.uOutputFrame.zw + gfu.uOutputFrame.xy; - - position.x = position.x * (2.0 / gfu.uOutputTexture.x) - 1.0; - position.y = position.y * (2.0*gfu.uOutputTexture.z / gfu.uOutputTexture.y) - gfu.uOutputTexture.z; - - return vec4(position, 0.0, 1.0); -} - -fn filterTextureCoord( aPosition:vec2 ) -> vec2 -{ - return aPosition * (gfu.uOutputFrame.zw * gfu.uInputSize.zw); -} - -fn globalTextureCoord( aPosition:vec2 ) -> vec2 -{ - return (aPosition.xy / gfu.uGlobalFrame.zw) + (gfu.uGlobalFrame.xy / gfu.uGlobalFrame.zw); -} - -fn getFilterCoord(aPosition:vec2 ) -> vec2 -{ - return ( filterUniforms.uFilterMatrix * vec3( filterTextureCoord(aPosition), 1.0) ).xy; -} - -fn getSize() -> vec2 -{ - - - return gfu.uGlobalFrame.zw; -} - -@vertex -fn mainVertex( - @location(0) aPosition : vec2, -) -> VSOutput { - return VSOutput( - filterVertexPosition(aPosition), - filterTextureCoord(aPosition), - getFilterCoord(aPosition) - ); -} - -@fragment -fn mainFragment( - @location(0) uv: vec2, - @location(1) filterUv: vec2, - @builtin(position) position: vec4 -) -> @location(0) vec4 { - - var maskClamp = filterUniforms.uMaskClamp; - - var clip = step(3.5, - step(maskClamp.x, filterUv.x) + - step(maskClamp.y, filterUv.y) + - step(filterUv.x, maskClamp.z) + - step(filterUv.y, maskClamp.w)); - - var mask = textureSample(uMaskTexture, uSampler, filterUv); - var source = textureSample(uTexture, uSampler, uv); - - var npmAlpha = 0.0; - - var alphaMul = 1.0 - npmAlpha * (1.0 - mask.a); - - var a = (alphaMul * mask.r) * clip; - - return vec4(source.rgb, source.a) * a; -}`,wS=Object.defineProperty,RS=Object.defineProperties,MS=Object.getOwnPropertyDescriptors,hi=Object.getOwnPropertySymbols,Em=Object.prototype.hasOwnProperty,Am=Object.prototype.propertyIsEnumerable,Pm=(r,t,e)=>t in r?wS(r,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):r[t]=e,OS=(r,t)=>{for(var e in t||(t={}))Em.call(t,e)&&Pm(r,e,t[e]);if(hi)for(var e of hi(t))Am.call(t,e)&&Pm(r,e,t[e]);return r},CS=(r,t)=>RS(r,MS(t)),GS=(r,t)=>{var e={};for(var s in r)Em.call(r,s)&&t.indexOf(s)<0&&(e[s]=r[s]);if(r!=null&&hi)for(var s of hi(r))t.indexOf(s)<0&&Am.call(r,s)&&(e[s]=r[s]);return e};class wm extends Yt{constructor(t){const e=t,{sprite:s}=e,i=GS(e,["sprite"]),n=new hn(s.texture),o=new it({uFilterMatrix:{value:new G,type:"mat3x3"},uMaskClamp:{value:n.uClampFrame,type:"vec4"},uAlpha:{value:1,type:"f32"}}),a=Tt.from({vertex:{source:ya,entryPoint:"mainVertex"},fragment:{source:ya,entryPoint:"mainFragment"}}),u=Rt.from({vertex:Sm,fragment:Tm,name:"mask-filter"});super(CS(OS({},i),{gpuProgram:a,glProgram:u,resources:{filterUniforms:o,uMaskTexture:s.texture.source}})),this.sprite=s,this._textureMatrix=n}apply(t,e,s,i){this._textureMatrix.texture=this.sprite.texture,t.calculateSpriteMatrix(this.resources.filterUniforms.uniforms.uFilterMatrix,this.sprite).prepend(this._textureMatrix.mapCoord),this.resources.uMaskTexture=this.sprite.texture.source,t.applyFilter(this,e,s,i)}}var IS=`fn getLuminosity(c: vec3) -> f32 { - return 0.3 * c.r + 0.59 * c.g + 0.11 * c.b; -} - -fn setLuminosity(c: vec3, lum: f32) -> vec3 { - let d: f32 = lum - getLuminosity(c); - let newColor: vec3 = c.rgb + vec3(d, d, d); - - // clip back into legal range - let newLum: f32 = getLuminosity(newColor); - let cMin: f32 = min(newColor.r, min(newColor.g, newColor.b)); - let cMax: f32 = max(newColor.r, max(newColor.g, newColor.b)); - - let t1: f32 = newLum / (newLum - cMin); - let t2: f32 = (1.0 - newLum) / (cMax - newLum); - - let finalColor = mix(vec3(newLum, newLum, newLum), newColor, select(select(1.0, t2, cMax > 1.0), t1, cMin < 0.0)); - - return finalColor; -} - -fn getSaturation(c: vec3) -> f32 { - return max(c.r, max(c.g, c.b)) - min(c.r, min(c.g, c.b)); -} - -// Set saturation if color components are sorted in ascending order. -fn setSaturationMinMidMax(cSorted: vec3, s: f32) -> vec3 { - var result: vec3; - if (cSorted.z > cSorted.x) { - let newY = (((cSorted.y - cSorted.x) * s) / (cSorted.z - cSorted.x)); - result = vec3(0.0, newY, s); + }`; +function generateBlurVertSource(kernelSize, x) { + const halfLength = Math.ceil(kernelSize / 2); + let vertSource = vertTemplate; + let blurLoop = ""; + let template; + if (x) { + template = "vBlurTexCoords[%index%] = textureCoord + vec2(%sampleIndex% * pixelStrength, 0.0);"; } else { - result = vec3(0.0, 0.0, 0.0); + template = "vBlurTexCoords[%index%] = textureCoord + vec2(0.0, %sampleIndex% * pixelStrength);"; } - return vec3(result.x, result.y, result.z); + for (let i = 0; i < kernelSize; i++) { + let blur = template.replace("%index%", i.toString()); + blur = blur.replace("%sampleIndex%", `${i - (halfLength - 1)}.0`); + blurLoop += blur; + blurLoop += "\n"; + } + vertSource = vertSource.replace("%blur%", blurLoop); + vertSource = vertSource.replace("%size%", kernelSize.toString()); + vertSource = vertSource.replace("%dimension%", x ? "z" : "w"); + return vertSource; } -fn setSaturation(c: vec3, s: f32) -> vec3 { - var result: vec3 = c; +"use strict"; +function generateBlurGlProgram(horizontal, kernelSize) { + const vertex = generateBlurVertSource(kernelSize, horizontal); + const fragment = generateBlurFragSource(kernelSize); + return GlProgram.from({ + vertex, + fragment, + name: `blur-${horizontal ? "horizontal" : "vertical"}-pass-filter` + }); +} - if (c.r <= c.g && c.r <= c.b) { - if (c.g <= c.b) { - result = setSaturationMinMidMax(result, s); - } else { - var temp: vec3 = vec3(result.r, result.b, result.g); - temp = setSaturationMinMidMax(temp, s); - result = vec3(temp.r, temp.b, temp.g); - } - } else if (c.g <= c.r && c.g <= c.b) { - if (c.r <= c.b) { - var temp: vec3 = vec3(result.g, result.r, result.b); - temp = setSaturationMinMidMax(temp, s); - result = vec3(temp.g, temp.r, temp.b); - } else { - var temp: vec3 = vec3(result.g, result.b, result.r); - temp = setSaturationMinMidMax(temp, s); - result = vec3(temp.g, temp.b, temp.r); - } +var source$4 = "\n\nstruct GlobalFilterUniforms {\n uInputSize:vec4,\n uInputPixel:vec4,\n uInputClamp:vec4,\n uOutputFrame:vec4,\n uGlobalFrame:vec4,\n uOutputTexture:vec4,\n};\n\nstruct BlurUniforms {\n uStrength:f32,\n};\n\n@group(0) @binding(0) var gfu: GlobalFilterUniforms;\n@group(0) @binding(1) var uTexture: texture_2d;\n@group(0) @binding(2) var uSampler : sampler;\n\n@group(1) @binding(0) var blurUniforms : BlurUniforms;\n\n\nstruct VSOutput {\n @builtin(position) position: vec4,\n %blur-struct%\n };\n\nfn filterVertexPosition(aPosition:vec2) -> vec4\n{\n var position = aPosition * gfu.uOutputFrame.zw + gfu.uOutputFrame.xy;\n\n position.x = position.x * (2.0 / gfu.uOutputTexture.x) - 1.0;\n position.y = position.y * (2.0*gfu.uOutputTexture.z / gfu.uOutputTexture.y) - gfu.uOutputTexture.z;\n\n return vec4(position, 0.0, 1.0);\n}\n\nfn filterTextureCoord( aPosition:vec2 ) -> vec2\n{\n return aPosition * (gfu.uOutputFrame.zw * gfu.uInputSize.zw);\n}\n\nfn globalTextureCoord( aPosition:vec2 ) -> vec2\n{\n return (aPosition.xy / gfu.uGlobalFrame.zw) + (gfu.uGlobalFrame.xy / gfu.uGlobalFrame.zw); \n}\n\nfn getSize() -> vec2\n{\n return gfu.uGlobalFrame.zw;\n}\n\n\n@vertex\nfn mainVertex(\n @location(0) aPosition : vec2, \n) -> VSOutput {\n\n let filteredCord = filterTextureCoord(aPosition);\n\n let strength = gfu.uInputSize.w * blurUniforms.uStrength;\n\n return VSOutput(\n filterVertexPosition(aPosition),\n %blur-vertex-out%\n );\n}\n\n@fragment\nfn mainFragment(\n @builtin(position) position: vec4,\n %blur-fragment-in%\n) -> @location(0) vec4 {\n\n var finalColor = vec4(0.0);\n\n %blur-sampling%\n\n return finalColor;\n}"; + +"use strict"; +function generateBlurProgram(horizontal, kernelSize) { + const kernel = GAUSSIAN_VALUES[kernelSize]; + const halfLength = kernel.length; + const blurStructSource = []; + const blurOutSource = []; + const blurSamplingSource = []; + for (let i = 0; i < kernelSize; i++) { + blurStructSource[i] = `@location(${i}) offset${i}: vec2,`; + if (horizontal) { + blurOutSource[i] = `filteredCord + vec2(${i - halfLength + 1} * strength, 0.0),`; } else { - if (c.r <= c.g) { - var temp: vec3 = vec3(result.b, result.r, result.g); - temp = setSaturationMinMidMax(temp, s); - result = vec3(temp.b, temp.r, temp.g); - } else { - var temp: vec3 = vec3(result.b, result.g, result.r); - temp = setSaturationMinMidMax(temp, s); - result = vec3(temp.b, temp.g, temp.r); - } + blurOutSource[i] = `filteredCord + vec2(0.0, ${i - halfLength + 1} * strength),`; } + const kernelIndex = i < halfLength ? i : kernelSize - i - 1; + const kernelValue = kernel[kernelIndex].toString(); + blurSamplingSource[i] = `finalColor += textureSample(uTexture, uSampler, offset${i}) * ${kernelValue};`; + } + const blurStruct = blurStructSource.join("\n"); + const blurOut = blurOutSource.join("\n"); + const blurSampling = blurSamplingSource.join("\n"); + const finalSource = source$4.replace("%blur-struct%", blurStruct).replace("%blur-vertex-out%", blurOut).replace("%blur-fragment-in%", blurStruct).replace("%blur-sampling%", blurSampling); + return GpuProgram.from({ + vertex: { + source: finalSource, + entryPoint: "mainVertex" + }, + fragment: { + source: finalSource, + entryPoint: "mainFragment" + } + }); +} - return result; -}`;class Qu{constructor(t=0,e=0,s=0,i=0,n=0,o=0){this.type="triangle",this.x=t,this.y=e,this.x2=s,this.y2=i,this.x3=n,this.y3=o}contains(t,e){const s=(this.x-this.x3)*(e-this.y3)-(this.y-this.y3)*(t-this.x3),i=(this.x2-this.x)*(e-this.y)-(this.y2-this.y)*(t-this.x);if(s<0!=i<0&&s!==0&&i!==0)return!1;const n=(this.x3-this.x2)*(e-this.y2)-(this.y3-this.y2)*(t-this.x2);return n===0||n<0==s+i<=0}strokeContains(t,e,s){const i=s/2,n=i*i,{x:o,x2:a,x3:u,y:l,y2:h,y3:c}=this;return Tr(t,e,o,l,a,c)<=n||Tr(t,e,a,h,u,c)<=n||Tr(t,e,u,c,o,l)<=n}clone(){return new Qu(this.x,this.y,this.x2,this.y2,this.x3,this.y3)}copyFrom(t){return this.x=t.x,this.y=t.y,this.x2=t.x2,this.y2=t.y2,this.x3=t.x3,this.y3=t.y3,this}copyTo(t){return t.copyFrom(this),t}getBounds(t){t=t||new z;const e=Math.min(this.x,this.x2,this.x3),s=Math.max(this.x,this.x2,this.x3),i=Math.min(this.y,this.y2,this.y3),n=Math.max(this.y,this.y2,this.y3);return t.x=e,t.y=i,t.width=s-e,t.height=n-i,t}}const Rm=class Bx{constructor(t){this._tick=()=>{this.timeout=setTimeout(this._processQueue,0)},this._processQueue=()=>{const{queue:e}=this;let s=0;for(;e.length&&s{this.queue.length?(this.resolves.push(e),this.dedupeQueue(),ht.system.addOnce(this._tick,this,Xt.UTILITY)):e()})}dedupeQueue(){const t=Object.create(null);let e=0;for(let s=0;st in r?BS(r,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):r[t]=e,FS=(r,t)=>{for(var e in t||(t={}))Om.call(t,e)&&Gm(r,e,t[e]);if(ci)for(var e of ci(t))Cm.call(t,e)&&Gm(r,e,t[e]);return r},DS=(r,t)=>{var e={};for(var s in r)Om.call(r,s)&&t.indexOf(s)<0&&(e[s]=r[s]);if(r!=null&&ci)for(var s of ci(r))t.indexOf(s)<0&&Cm.call(r,s)&&(e[s]=r[s]);return e};const Im=new Ae;class $r extends V{constructor(...t){var e;let s=t[0];s instanceof Oe&&(s={geometry:s,shader:t[1]},t[3]&&(s.geometry.topology=t[3]));const i=s,{geometry:n,shader:o,texture:a,roundPixels:u,state:l}=i,h=DS(i,["geometry","shader","texture","roundPixels","state"]);super(FS({label:"Mesh"},h)),this.renderPipeId="mesh",this.canBundle=!0,this._roundPixels=0,this.allowChildren=!1,this.shader=o,this.texture=(e=a!=null?a:o==null?void 0:o.texture)!=null?e:A.WHITE,this.state=l!=null?l:Ct.for2d(),this._geometry=n,this._geometry.on("update",this.onViewUpdate,this),this.roundPixels=u!=null?u:!1}get roundPixels(){return!!this._roundPixels}set roundPixels(t){this._roundPixels=t?1:0}get material(){return this._shader}set shader(t){this._shader!==t&&(this._shader=t,this.onViewUpdate())}get shader(){return this._shader}set geometry(t){var e;this._geometry!==t&&((e=this._geometry)==null||e.off("update",this.onViewUpdate,this),t.on("update",this.onViewUpdate,this),this._geometry=t,this.onViewUpdate())}get geometry(){return this._geometry}set texture(t){t||(t=A.EMPTY);const e=this._texture;e!==t&&(e&&e.dynamic&&e.off("update",this.onViewUpdate,this),t.dynamic&&t.on("update",this.onViewUpdate,this),this.shader&&(this.shader.texture=t),this._texture=t,this.onViewUpdate())}get texture(){return this._texture}get batched(){return this._shader?!1:this._geometry instanceof Jt?this._geometry.batchMode==="auto"?this._geometry.positions.length/2<=100:this._geometry.batchMode==="batch":!1}get bounds(){return this._geometry.bounds}addBounds(t){t.addBounds(this.geometry.bounds)}containsPoint(t){const{x:e,y:s}=t;if(!this.bounds.containsPoint(e,s))return!1;const i=this.geometry.getBuffer("aPosition").data,n=Im.points,o=this.geometry.getIndex().data,a=o.length,u=this.geometry.topology==="triangle-strip"?3:1;for(let l=0;l+2=this._durations[this.currentFrame];)n-=this._durations[this.currentFrame]*o,this._currentTime+=o;this._currentTime+=n/this._durations[this.currentFrame]}else this._currentTime+=s;this._currentTime<0&&!this.loop?(this.gotoAndStop(0),this.onComplete&&this.onComplete()):this._currentTime>=this._textures.length&&!this.loop?(this.gotoAndStop(this._textures.length-1),this.onComplete&&this.onComplete()):i!==this.currentFrame&&(this.loop&&this.onLoop&&(this.animationSpeed>0&&this.currentFramei)&&this.onLoop(),this._updateTexture())}_updateTexture(){const t=this.currentFrame;this._previousFrame!==t&&(this._previousFrame=t,this.texture=this._textures[t],this.updateAnchor&&this.anchor.copyFrom(this.texture.defaultAnchor),this.onFrameChange&&this.onFrameChange(this.currentFrame))}destroy(){this.stop(),super.destroy(),this.onComplete=null,this.onFrameChange=null,this.onLoop=null}static fromFrames(t){const e=[];for(let s=0;sthis.totalFrames-1)throw new Error(`[AnimatedSprite]: Invalid frame index value ${t}, expected to be between 0 and totalFrames ${this.totalFrames}.`);const e=this.currentFrame;this._currentTime=t,e!==this.currentFrame&&this._updateTexture()}get playing(){return this._playing}get autoUpdate(){return this._autoUpdate}set autoUpdate(t){t!==this._autoUpdate&&(this._autoUpdate=t,!this._autoUpdate&&this._isConnectedToTicker?(ht.shared.remove(this.update,this),this._isConnectedToTicker=!1):this._autoUpdate&&!this._isConnectedToTicker&&this._playing&&(ht.shared.add(this.update,this),this._isConnectedToTicker=!0))}}class Bm{constructor({matrix:t,observer:e}={}){this.dirty=!0,this._matrix=t!=null?t:new G,this.observer=e,this.position=new rt(this,0,0),this.scale=new rt(this,1,1),this.pivot=new rt(this,0,0),this.skew=new rt(this,0,0),this._rotation=0,this._cx=1,this._sx=0,this._cy=0,this._sy=1}get matrix(){const t=this._matrix;return this.dirty&&(t.a=this._cx*this.scale.x,t.b=this._sx*this.scale.x,t.c=this._cy*this.scale.y,t.d=this._sy*this.scale.y,t.tx=this.position.x-(this.pivot.x*t.a+this.pivot.y*t.c),t.ty=this.position.y-(this.pivot.x*t.b+this.pivot.y*t.d),this.dirty=!1),t}_onUpdate(t){var e;this.dirty=!0,t===this.skew&&this.updateSkew(),(e=this.observer)==null||e._onUpdate(this)}updateSkew(){this._cx=Math.cos(this._rotation+this.skew.y),this._sx=Math.sin(this._rotation+this.skew.y),this._cy=-Math.sin(this._rotation-this.skew.x),this._sy=Math.cos(this._rotation-this.skew.x),this.dirty=!0}setFromMatrix(t){t.decompose(this),this.dirty=!0}get rotation(){return this._rotation}set rotation(t){this._rotation!==t&&(this._rotation=t,this.updateSkew())}}var US=Object.defineProperty,di=Object.getOwnPropertySymbols,Fm=Object.prototype.hasOwnProperty,Dm=Object.prototype.propertyIsEnumerable,Um=(r,t,e)=>t in r?US(r,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):r[t]=e,Nr=(r,t)=>{for(var e in t||(t={}))Fm.call(t,e)&&Um(r,e,t[e]);if(di)for(var e of di(t))Dm.call(t,e)&&Um(r,e,t[e]);return r},kS=(r,t)=>{var e={};for(var s in r)Fm.call(r,s)&&t.indexOf(s)<0&&(e[s]=r[s]);if(r!=null&&di)for(var s of di(r))t.indexOf(s)<0&&Dm.call(r,s)&&(e[s]=r[s]);return e};const km=class Gi extends V{constructor(...t){let e=t[0]||{};e instanceof A&&(e={texture:e}),t.length>1&&(e.width=t[1],e.height=t[2]),e=Nr(Nr({},Gi.defaultOptions),e);const s=e!=null?e:{},{texture:i,anchor:n,tilePosition:o,tileScale:a,tileRotation:u,width:l,height:h,applyAnchorToTexture:c,roundPixels:d}=s,p=kS(s,["texture","anchor","tilePosition","tileScale","tileRotation","width","height","applyAnchorToTexture","roundPixels"]);super(Nr({label:"TilingSprite"},p)),this.renderPipeId="tilingSprite",this.canBundle=!0,this.batched=!0,this._roundPixels=0,this._bounds={minX:0,maxX:1,minY:0,maxY:0},this._boundsDirty=!0,this.allowChildren=!1,this._anchor=new rt(this),this._applyAnchorToTexture=c,this.texture=i,this._width=l!=null?l:i.width,this._height=h!=null?h:i.height,this._tileTransform=new Bm({observer:{_onUpdate:()=>this.onViewUpdate()}}),n&&(this.anchor=n),this.tilePosition=o,this.tileScale=a,this.tileRotation=u,this.roundPixels=d!=null?d:!1}static from(t,e={}){return typeof t=="string"?new Gi(Nr({texture:Y.get(t)},e)):new Gi(Nr({texture:t},e))}get clampMargin(){return this._texture.textureMatrix.clampMargin}set clampMargin(t){this._texture.textureMatrix.clampMargin=t}get anchor(){return this._anchor}set anchor(t){typeof t=="number"?this._anchor.set(t):this._anchor.copyFrom(t)}get tilePosition(){return this._tileTransform.position}set tilePosition(t){this._tileTransform.position.copyFrom(t)}get tileScale(){return this._tileTransform.scale}set tileScale(t){typeof t=="number"?this._tileTransform.scale.set(t):this._tileTransform.scale.copyFrom(t)}set tileRotation(t){this._tileTransform.rotation=t}get tileRotation(){return this._tileTransform.rotation}get tileTransform(){return this._tileTransform}get roundPixels(){return!!this._roundPixels}set roundPixels(t){this._roundPixels=t?1:0}get bounds(){return this._boundsDirty&&(this._updateBounds(),this._boundsDirty=!1),this._bounds}set texture(t){t||(t=A.EMPTY);const e=this._texture;e!==t&&(e&&e.dynamic&&e.off("update",this.onViewUpdate,this),t.dynamic&&t.on("update",this.onViewUpdate,this),this._texture=t,this.onViewUpdate())}get texture(){return this._texture}set width(t){this._width=t,this.onViewUpdate()}get width(){return this._width}set height(t){this._height=t,this.onViewUpdate()}get height(){return this._height}_updateBounds(){const t=this._bounds,e=this._anchor,s=this._width,i=this._height;t.maxX=-e._x*s,t.minX=t.maxX+s,t.maxY=-e._y*i,t.minY=t.maxY+i}addBounds(t){const e=this.bounds;t.addFrame(e.minX,e.minY,e.maxX,e.maxY)}containsPoint(t){const e=this.bounds.minX,s=this.bounds.minY,i=-e*this._anchor._x;let n=0;return t.x>=i&&t.x<=i+e&&(n=-s*this._anchor._y,t.y>=n&&t.y<=n+s)}onViewUpdate(){this._boundsDirty=!0,this._didTilingSpriteUpdate=!0,this._didChangeId+=4096,!this.didViewUpdate&&(this.didViewUpdate=!0,this.renderGroup&&this.renderGroup.onChildViewUpdate(this))}destroy(t=!1){if(super.destroy(t),this._anchor=null,this._tileTransform=null,this._bounds=null,typeof t=="boolean"?t:t==null?void 0:t.texture){const e=typeof t=="boolean"?t:t==null?void 0:t.textureSource;this._texture.destroy(e)}this._texture=null}};km.defaultOptions={texture:A.EMPTY,anchor:{x:0,y:0},tilePosition:{x:0,y:0},tileScale:{x:1,y:1},tileRotation:0,applyAnchorToTexture:!1};let Lm=km;var LS=Object.defineProperty,pi=Object.getOwnPropertySymbols,$m=Object.prototype.hasOwnProperty,Nm=Object.prototype.propertyIsEnumerable,Hm=(r,t,e)=>t in r?LS(r,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):r[t]=e,$S=(r,t)=>{for(var e in t||(t={}))$m.call(t,e)&&Hm(r,e,t[e]);if(pi)for(var e of pi(t))Nm.call(t,e)&&Hm(r,e,t[e]);return r},NS=(r,t)=>{var e={};for(var s in r)$m.call(r,s)&&t.indexOf(s)<0&&(e[s]=r[s]);if(r!=null&&pi)for(var s of pi(r))t.indexOf(s)<0&&Nm.call(r,s)&&(e[s]=r[s]);return e};class fi extends V{constructor(t,e){const s=t,{text:i,resolution:n,style:o,anchor:a,width:u,height:l,roundPixels:h}=s,c=NS(s,["text","resolution","style","anchor","width","height","roundPixels"]);super($S({},c)),this.batched=!0,this.resolution=null,this._didTextUpdate=!0,this._roundPixels=0,this._bounds=new lt,this._boundsDirty=!0,this._styleClass=e,this.text=i!=null?i:"",this.style=o,this.resolution=n!=null?n:null,this.allowChildren=!1,this._anchor=new rt({_onUpdate:()=>{this.onViewUpdate()}}),a&&(this.anchor=a),this.roundPixels=h!=null?h:!1,u&&(this.width=u),l&&(this.height=l)}get anchor(){return this._anchor}set anchor(t){typeof t=="number"?this._anchor.set(t):this._anchor.copyFrom(t)}get roundPixels(){return!!this._roundPixels}set roundPixels(t){this._roundPixels=t?1:0}set text(t){t=t.toString(),this._text!==t&&(this._text=t,this.onViewUpdate())}get text(){return this._text}get style(){return this._style}set style(t){var e;t=t||{},(e=this._style)==null||e.off("update",this.onViewUpdate,this),t instanceof this._styleClass?this._style=t:this._style=new this._styleClass(t),this._style.on("update",this.onViewUpdate,this),this.onViewUpdate()}get bounds(){return this._boundsDirty&&(this._updateBounds(),this._boundsDirty=!1),this._bounds}get width(){return Math.abs(this.scale.x)*this.bounds.width}set width(t){this._setWidth(t,this.bounds.width)}get height(){return Math.abs(this.scale.y)*this.bounds.height}set height(t){this._setHeight(t,this.bounds.height)}getSize(t){return t||(t={}),t.width=Math.abs(this.scale.x)*this.bounds.width,t.height=Math.abs(this.scale.y)*this.bounds.height,t}setSize(t,e){var s;let i,n;typeof t!="object"?(i=t,n=e!=null?e:t):(i=t.width,n=(s=t.height)!=null?s:t.width),i!==void 0&&this._setWidth(i,this.bounds.width),n!==void 0&&this._setHeight(n,this.bounds.height)}addBounds(t){const e=this.bounds;t.addFrame(e.minX,e.minY,e.maxX,e.maxY)}containsPoint(t){const e=this.bounds.maxX,s=this.bounds.maxY,i=-e*this.anchor.x;let n=0;return t.x>=i&&t.x<=i+e&&(n=-s*this.anchor.y,t.y>=n&&t.y<=n+s)}onViewUpdate(){this._didChangeId+=4096,this._boundsDirty=!0,!this.didViewUpdate&&(this.didViewUpdate=!0,this._didTextUpdate=!0,this.renderGroup&&this.renderGroup.onChildViewUpdate(this))}_getKey(){return`${this.text}:${this._style.styleKey}`}destroy(t=!1){super.destroy(t),this.owner=null,this._bounds=null,this._anchor=null,(typeof t=="boolean"?t:t!=null&&t.style)&&this._style.destroy(t),this._style=null,this._text=null}}function mi(r,t){var e;let s=(e=r[0])!=null?e:{};return(typeof s=="string"||r[1])&&(s={text:s,style:r[1]}),s}class Ta extends fi{constructor(...t){const e=mi(t,"Text");super(e,Wt),this.renderPipeId="text"}_updateBounds(){const t=this._bounds,e=this._style.padding,s=this._anchor,i=It.measureText(this._text,this._style),{width:n,height:o}=i;t.minX=-s._x*n-e,t.maxX=t.minX+n,t.minY=-s._y*o-e,t.maxY=t.minY+o}}class Xm extends Mm{resolveQueueItem(t,e){return t instanceof V?this.resolveContainerQueueItem(t,e):t instanceof et||t instanceof A?e.push(t.source):t instanceof Bt&&e.push(t),null}resolveContainerQueueItem(t,e){t instanceof Ft||t instanceof Lm||t instanceof $r?e.push(t.texture.source):t instanceof Ta?e.push(t):t instanceof qe?e.push(t.context):t instanceof Yr&&t.textures.forEach(s=>{s.source?e.push(s.source):e.push(s.texture.source)})}resolveGraphicsContextQueueItem(t){this.renderer.graphicsContext.getContextRenderData(t);const{instructions:e}=t;for(const s of e)if(s.action==="texture"){const{image:i}=s.data;return i.source}else if(s.action==="fill"){const{texture:i}=s.data.style;return i.source}return null}}class zm extends fi{constructor(...t){var e,s,i;const n=mi(t,"BitmapText");(e=n.style)!=null||(n.style=n.style||{}),(i=(s=n.style).fill)!=null||(s.fill=16777215),super(n,Wt),this.renderPipeId="bitmapText"}_updateBounds(){const t=this._bounds,e=this._style.padding,s=this._anchor,i=Pr.measureText(this.text,this._style),n=i.scale,o=i.offsetY*n,a=i.width*n,u=i.height*n;t.minX=-s._x*a-e,t.maxX=t.minX+a,t.minY=-s._y*(u+o)-e,t.maxY=t.minY+u}}class jm extends fi{constructor(...t){const e=mi(t,"HtmlText");super(e,Pe),this.renderPipeId="htmlText"}_updateBounds(){const t=this._bounds,e=this._style.padding,s=this._anchor,i=ko(this.text,this._style),{width:n,height:o}=i;t.minX=-s._x*n-e,t.maxX=t.minX+n,t.minY=-s._y*o-e,t.maxY=t.minY+o}}class Vm extends Xm{uploadQueueItem(t){t instanceof et?this.uploadTextureSource(t):t instanceof Ta?this.uploadText(t):t instanceof jm?this.uploadHTMLText(t):t instanceof zm?this.uploadBitmapText(t):t instanceof Bt&&this.uploadGraphicsContext(t)}uploadTextureSource(t){this.renderer.texture.initSource(t)}uploadText(t){this.renderer.renderPipes.text.initGpuText(t)}uploadBitmapText(t){this.renderer.renderPipes.bitmapText.initGpuText(t)}uploadHTMLText(t){this.renderer.renderPipes.htmlText.initGpuText(t)}uploadGraphicsContext(t){this.renderer.graphicsContext.getContextRenderData(t);const{instructions:e}=t;for(const s of e)if(s.action==="texture"){const{image:i}=s.data;this.uploadTextureSource(i.source)}else if(s.action==="fill"){const{texture:i}=s.data.style;this.uploadTextureSource(i.source)}return null}}class Wm extends Vm{destroy(){clearTimeout(this.timeout),this.renderer=null,this.queue=null,this.resolves=null}}Wm.extension={type:[v.WebGLSystem,v.WebGPUSystem],name:"prepare"};class Sa{constructor(){this._didUpload=!1,this._tempState=Ct.for2d()}init(t){const e=ke({name:"batch",bits:[ks,$s(wt),$e]});this._shader=new St({glProgram:e,resources:{batchSamplers:Ns}}),t.renderer.runners.contextChange.add(this)}contextChange(){this._didUpload=!1}start(t,e){const s=t.renderer;s.shader.bind(this._shader,this._didUpload),s.shader.updateUniformGroup(s.globalUniforms.uniformGroup),s.geometry.bind(e,this._shader.glProgram)}execute(t,e){const s=t.renderer;this._didUpload=!0,this._tempState.blendMode=e.blendMode,s.state.set(this._tempState);const i=e.textures.textures;for(let n=0;ns.trim()).filter(s=>s.length);let e="";return t.map(s=>{let i=e+s;return s==="{"?e+=" ":s==="}"&&(e=e.substr(0,e.length-4),i=e+s),i}).join(` -`)}const Ym={name:"texture-bit",vertex:{header:` +"use strict"; +var __defProp$s = Object.defineProperty; +var __getOwnPropSymbols$s = Object.getOwnPropertySymbols; +var __hasOwnProp$s = Object.prototype.hasOwnProperty; +var __propIsEnum$s = Object.prototype.propertyIsEnumerable; +var __defNormalProp$s = (obj, key, value) => key in obj ? __defProp$s(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; +var __spreadValues$s = (a, b) => { + for (var prop in b || (b = {})) + if (__hasOwnProp$s.call(b, prop)) + __defNormalProp$s(a, prop, b[prop]); + if (__getOwnPropSymbols$s) + for (var prop of __getOwnPropSymbols$s(b)) { + if (__propIsEnum$s.call(b, prop)) + __defNormalProp$s(a, prop, b[prop]); + } + return a; +}; +const _BlurFilterPass = class _BlurFilterPass extends Filter { + /** + * @param options + * @param options.horizontal - Do pass along the x-axis (`true`) or y-axis (`false`). + * @param options.strength - The strength of the blur filter. + * @param options.quality - The quality of the blur filter. + * @param options.kernelSize - The kernelSize of the blur filter.Options: 5, 7, 9, 11, 13, 15. + */ + constructor(options) { + options = __spreadValues$s(__spreadValues$s({}, _BlurFilterPass.defaultOptions), options); + const glProgram = generateBlurGlProgram(options.horizontal, options.kernelSize); + const gpuProgram = generateBlurProgram(options.horizontal, options.kernelSize); + super(__spreadValues$s({ + glProgram, + gpuProgram, + resources: { + blurUniforms: { + uStrength: { value: 0, type: "f32" } + } + } + }, options)); + this.horizontal = options.horizontal; + this._quality = 0; + this.quality = options.quality; + this.blur = options.strength; + this._uniforms = this.resources.blurUniforms.uniforms; + } + /** + * Applies the filter. + * @param filterManager - The manager. + * @param input - The input target. + * @param output - The output target. + * @param clearMode - How to clear + */ + apply(filterManager, input, output, clearMode) { + this._uniforms.uStrength = this.strength / this.passes; + if (this.passes === 1) { + filterManager.applyFilter(this, input, output, clearMode); + } else { + const tempTexture = TexturePool.getSameSizeTexture(input); + let flip = input; + let flop = tempTexture; + this._state.blend = false; + for (let i = 0; i < this.passes - 1; i++) { + filterManager.applyFilter(this, flip, flop, filterManager.renderer.type === RendererType.WEBGPU); + const temp = flop; + flop = flip; + flip = temp; + } + this._state.blend = true; + filterManager.applyFilter(this, flip, output, clearMode); + TexturePool.returnTexture(tempTexture); + } + } + /** + * Sets the strength of both the blur. + * @default 16 + */ + get blur() { + return this.strength; + } + set blur(value) { + this.padding = 1 + Math.abs(value) * 2; + this.strength = value; + } + /** + * Sets the quality of the blur by modifying the number of passes. More passes means higher + * quality blurring but the lower the performance. + * @default 4 + */ + get quality() { + return this._quality; + } + set quality(value) { + this._quality = value; + this.passes = value; + } +}; +/** Default blur filter pass options */ +_BlurFilterPass.defaultOptions = { + /** The strength of the blur filter. */ + strength: 8, + /** The quality of the blur filter. */ + quality: 4, + /** The kernelSize of the blur filter.Options: 5, 7, 9, 11, 13, 15. */ + kernelSize: 5 +}; +let BlurFilterPass = _BlurFilterPass; + +"use strict"; +var __defProp$r = Object.defineProperty; +var __defProps$d = Object.defineProperties; +var __getOwnPropDescs$d = Object.getOwnPropertyDescriptors; +var __getOwnPropSymbols$r = Object.getOwnPropertySymbols; +var __hasOwnProp$r = Object.prototype.hasOwnProperty; +var __propIsEnum$r = Object.prototype.propertyIsEnumerable; +var __defNormalProp$r = (obj, key, value) => key in obj ? __defProp$r(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; +var __spreadValues$r = (a, b) => { + for (var prop in b || (b = {})) + if (__hasOwnProp$r.call(b, prop)) + __defNormalProp$r(a, prop, b[prop]); + if (__getOwnPropSymbols$r) + for (var prop of __getOwnPropSymbols$r(b)) { + if (__propIsEnum$r.call(b, prop)) + __defNormalProp$r(a, prop, b[prop]); + } + return a; +}; +var __spreadProps$d = (a, b) => __defProps$d(a, __getOwnPropDescs$d(b)); +var __objRest$b = (source, exclude) => { + var target = {}; + for (var prop in source) + if (__hasOwnProp$r.call(source, prop) && exclude.indexOf(prop) < 0) + target[prop] = source[prop]; + if (source != null && __getOwnPropSymbols$r) + for (var prop of __getOwnPropSymbols$r(source)) { + if (exclude.indexOf(prop) < 0 && __propIsEnum$r.call(source, prop)) + target[prop] = source[prop]; + } + return target; +}; +class BlurFilter extends Filter { + constructor(...args) { + var _a; + let options = (_a = args[0]) != null ? _a : {}; + if (typeof options === "number") { + deprecation(v8_0_0, "BlurFilter constructor params are now options object. See params: { strength, quality, resolution, kernelSize }"); + options = { strength: options }; + if (args[1]) + options.quality = args[1]; + if (args[2]) + options.resolution = args[2]; + if (args[3]) + options.kernelSize = args[3]; + } + options = __spreadValues$r(__spreadValues$r({}, BlurFilterPass.defaultOptions), options); + const _b = options, { strength, quality } = _b, rest = __objRest$b(_b, ["strength", "quality"]); + super(__spreadProps$d(__spreadValues$r({}, rest), { + compatibleRenderers: RendererType.BOTH, + resources: {} + })); + this._repeatEdgePixels = false; + this.blurXFilter = new BlurFilterPass(__spreadValues$r({ horizontal: false }, options)); + this.blurYFilter = new BlurFilterPass(__spreadValues$r({ horizontal: true }, options)); + this.quality = quality; + this.blur = strength; + this.repeatEdgePixels = false; + } + /** + * Applies the filter. + * @param filterManager - The manager. + * @param input - The input target. + * @param output - The output target. + * @param clearMode - How to clear + */ + apply(filterManager, input, output, clearMode) { + const xStrength = Math.abs(this.blurXFilter.strength); + const yStrength = Math.abs(this.blurYFilter.strength); + if (xStrength && yStrength) { + const tempTexture = TexturePool.getSameSizeTexture(input); + this.blurXFilter.apply(filterManager, input, tempTexture, true); + this.blurYFilter.apply(filterManager, tempTexture, output, clearMode); + TexturePool.returnTexture(tempTexture); + } else if (yStrength) { + this.blurYFilter.apply(filterManager, input, output, clearMode); + } else { + this.blurXFilter.apply(filterManager, input, output, clearMode); + } + } + updatePadding() { + if (this._repeatEdgePixels) { + this.padding = 0; + } else { + this.padding = Math.max(Math.abs(this.blurXFilter.blur), Math.abs(this.blurYFilter.blur)) * 2; + } + } + /** + * Sets the strength of both the blurX and blurY properties simultaneously + * @default 2 + */ + get blur() { + return this.blurXFilter.blur; + } + set blur(value) { + this.blurXFilter.blur = this.blurYFilter.blur = value; + this.updatePadding(); + } + /** + * Sets the number of passes for blur. More passes means higher quality bluring. + * @default 1 + */ + get quality() { + return this.blurXFilter.quality; + } + set quality(value) { + this.blurXFilter.quality = this.blurYFilter.quality = value; + } + /** + * Sets the strength of the blurX property + * @default 2 + */ + get blurX() { + return this.blurXFilter.blur; + } + set blurX(value) { + this.blurXFilter.blur = value; + this.updatePadding(); + } + /** + * Sets the strength of the blurY property + * @default 2 + */ + get blurY() { + return this.blurYFilter.blur; + } + set blurY(value) { + this.blurYFilter.blur = value; + this.updatePadding(); + } + /** + * Sets the blendmode of the filter + * @default "normal" + */ + get blendMode() { + return this.blurYFilter.blendMode; + } + set blendMode(value) { + this.blurYFilter.blendMode = value; + } + /** + * If set to true the edge of the target will be clamped + * @default false + */ + get repeatEdgePixels() { + return this._repeatEdgePixels; + } + set repeatEdgePixels(value) { + this._repeatEdgePixels = value; + this.updatePadding(); + } +} +/** Default blur filter options */ +BlurFilter.defaultOptions = { + /** The strength of the blur filter. */ + strength: 8, + /** The quality of the blur filter. */ + quality: 4, + /** The kernelSize of the blur filter.Options: 5, 7, 9, 11, 13, 15. */ + kernelSize: 5 +}; + +var fragment$3 = "\nin vec2 vTextureCoord;\nin vec4 vColor;\n\nout vec4 finalColor;\n\nuniform float uColorMatrix[20];\nuniform float uAlpha;\n\nuniform sampler2D uTexture;\n\nfloat rand(vec2 co)\n{\n return fract(sin(dot(co.xy, vec2(12.9898, 78.233))) * 43758.5453);\n}\n\nvoid main()\n{\n vec4 color = texture(uTexture, vTextureCoord);\n float randomValue = rand(gl_FragCoord.xy * 0.2);\n float diff = (randomValue - 0.5) * 0.5;\n\n if (uAlpha == 0.0) {\n finalColor = color;\n return;\n }\n\n if (color.a > 0.0) {\n color.rgb /= color.a;\n }\n\n vec4 result;\n\n result.r = (uColorMatrix[0] * color.r);\n result.r += (uColorMatrix[1] * color.g);\n result.r += (uColorMatrix[2] * color.b);\n result.r += (uColorMatrix[3] * color.a);\n result.r += uColorMatrix[4];\n\n result.g = (uColorMatrix[5] * color.r);\n result.g += (uColorMatrix[6] * color.g);\n result.g += (uColorMatrix[7] * color.b);\n result.g += (uColorMatrix[8] * color.a);\n result.g += uColorMatrix[9];\n\n result.b = (uColorMatrix[10] * color.r);\n result.b += (uColorMatrix[11] * color.g);\n result.b += (uColorMatrix[12] * color.b);\n result.b += (uColorMatrix[13] * color.a);\n result.b += uColorMatrix[14];\n\n result.a = (uColorMatrix[15] * color.r);\n result.a += (uColorMatrix[16] * color.g);\n result.a += (uColorMatrix[17] * color.b);\n result.a += (uColorMatrix[18] * color.a);\n result.a += uColorMatrix[19];\n\n vec3 rgb = mix(color.rgb, result.rgb, uAlpha);\n\n // Premultiply alpha again.\n rgb *= result.a;\n\n finalColor = vec4(rgb, result.a);\n}\n"; + +var source$3 = "struct GlobalFilterUniforms {\n uInputSize:vec4,\n uInputPixel:vec4,\n uInputClamp:vec4,\n uOutputFrame:vec4,\n uGlobalFrame:vec4,\n uOutputTexture:vec4,\n};\n\nstruct ColorMatrixUniforms {\n uColorMatrix:array, 5>,\n uAlpha:f32,\n};\n\n\n@group(0) @binding(0) var gfu: GlobalFilterUniforms;\n@group(0) @binding(1) var uTexture: texture_2d;\n@group(0) @binding(2) var uSampler : sampler;\n@group(1) @binding(0) var colorMatrixUniforms : ColorMatrixUniforms;\n\n\nstruct VSOutput {\n @builtin(position) position: vec4,\n @location(0) uv : vec2,\n };\n \nfn filterVertexPosition(aPosition:vec2) -> vec4\n{\n var position = aPosition * gfu.uOutputFrame.zw + gfu.uOutputFrame.xy;\n\n position.x = position.x * (2.0 / gfu.uOutputTexture.x) - 1.0;\n position.y = position.y * (2.0*gfu.uOutputTexture.z / gfu.uOutputTexture.y) - gfu.uOutputTexture.z;\n\n return vec4(position, 0.0, 1.0);\n}\n\nfn filterTextureCoord( aPosition:vec2 ) -> vec2\n{\n return aPosition * (gfu.uOutputFrame.zw * gfu.uInputSize.zw);\n}\n\n@vertex\nfn mainVertex(\n @location(0) aPosition : vec2, \n) -> VSOutput {\n return VSOutput(\n filterVertexPosition(aPosition),\n filterTextureCoord(aPosition),\n );\n}\n\n\n@fragment\nfn mainFragment(\n @location(0) uv: vec2,\n) -> @location(0) vec4 {\n\n\n var c = textureSample(uTexture, uSampler, uv);\n \n if (colorMatrixUniforms.uAlpha == 0.0) {\n return c;\n }\n\n \n // Un-premultiply alpha before applying the color matrix. See issue #3539.\n if (c.a > 0.0) {\n c.r /= c.a;\n c.g /= c.a;\n c.b /= c.a;\n }\n\n var cm = colorMatrixUniforms.uColorMatrix;\n\n\n var result = vec4(0.);\n\n result.r = (cm[0][0] * c.r);\n result.r += (cm[0][1] * c.g);\n result.r += (cm[0][2] * c.b);\n result.r += (cm[0][3] * c.a);\n result.r += cm[1][0];\n\n result.g = (cm[1][1] * c.r);\n result.g += (cm[1][2] * c.g);\n result.g += (cm[1][3] * c.b);\n result.g += (cm[2][0] * c.a);\n result.g += cm[2][1];\n\n result.b = (cm[2][2] * c.r);\n result.b += (cm[2][3] * c.g);\n result.b += (cm[3][0] * c.b);\n result.b += (cm[3][1] * c.a);\n result.b += cm[3][2];\n\n result.a = (cm[3][3] * c.r);\n result.a += (cm[4][0] * c.g);\n result.a += (cm[4][1] * c.b);\n result.a += (cm[4][2] * c.a);\n result.a += cm[4][3];\n\n var rgb = mix(c.rgb, result.rgb, colorMatrixUniforms.uAlpha);\n\n rgb.r *= result.a;\n rgb.g *= result.a;\n rgb.b *= result.a;\n\n return vec4(rgb, result.a);\n}"; + +"use strict"; +var __defProp$q = Object.defineProperty; +var __defProps$c = Object.defineProperties; +var __getOwnPropDescs$c = Object.getOwnPropertyDescriptors; +var __getOwnPropSymbols$q = Object.getOwnPropertySymbols; +var __hasOwnProp$q = Object.prototype.hasOwnProperty; +var __propIsEnum$q = Object.prototype.propertyIsEnumerable; +var __defNormalProp$q = (obj, key, value) => key in obj ? __defProp$q(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; +var __spreadValues$q = (a, b) => { + for (var prop in b || (b = {})) + if (__hasOwnProp$q.call(b, prop)) + __defNormalProp$q(a, prop, b[prop]); + if (__getOwnPropSymbols$q) + for (var prop of __getOwnPropSymbols$q(b)) { + if (__propIsEnum$q.call(b, prop)) + __defNormalProp$q(a, prop, b[prop]); + } + return a; +}; +var __spreadProps$c = (a, b) => __defProps$c(a, __getOwnPropDescs$c(b)); +class ColorMatrixFilter extends Filter { + constructor(options = {}) { + const colorMatrixUniforms = new UniformGroup({ + uColorMatrix: { + value: [ + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0 + ], + type: "f32", + size: 20 + }, + uAlpha: { + value: 1, + type: "f32" + } + }); + const gpuProgram = GpuProgram.from({ + vertex: { + source: source$3, + entryPoint: "mainVertex" + }, + fragment: { + source: source$3, + entryPoint: "mainFragment" + } + }); + const glProgram = GlProgram.from({ + vertex: vertex$2, + fragment: fragment$3, + name: "color-matrix-filter" + }); + super(__spreadProps$c(__spreadValues$q({}, options), { + gpuProgram, + glProgram, + resources: { + colorMatrixUniforms + } + })); + this.alpha = 1; + } + /** + * Transforms current matrix and set the new one + * @param {number[]} matrix - 5x4 matrix + * @param multiply - if true, current matrix and matrix are multiplied. If false, + * just set the current matrix with @param matrix + */ + _loadMatrix(matrix, multiply = false) { + let newMatrix = matrix; + if (multiply) { + this._multiply(newMatrix, this.matrix, matrix); + newMatrix = this._colorMatrix(newMatrix); + } + this.resources.colorMatrixUniforms.uniforms.uColorMatrix = newMatrix; + this.resources.colorMatrixUniforms.update(); + } + /** + * Multiplies two mat5's + * @private + * @param out - 5x4 matrix the receiving matrix + * @param a - 5x4 matrix the first operand + * @param b - 5x4 matrix the second operand + * @returns {number[]} 5x4 matrix + */ + _multiply(out, a, b) { + out[0] = a[0] * b[0] + a[1] * b[5] + a[2] * b[10] + a[3] * b[15]; + out[1] = a[0] * b[1] + a[1] * b[6] + a[2] * b[11] + a[3] * b[16]; + out[2] = a[0] * b[2] + a[1] * b[7] + a[2] * b[12] + a[3] * b[17]; + out[3] = a[0] * b[3] + a[1] * b[8] + a[2] * b[13] + a[3] * b[18]; + out[4] = a[0] * b[4] + a[1] * b[9] + a[2] * b[14] + a[3] * b[19] + a[4]; + out[5] = a[5] * b[0] + a[6] * b[5] + a[7] * b[10] + a[8] * b[15]; + out[6] = a[5] * b[1] + a[6] * b[6] + a[7] * b[11] + a[8] * b[16]; + out[7] = a[5] * b[2] + a[6] * b[7] + a[7] * b[12] + a[8] * b[17]; + out[8] = a[5] * b[3] + a[6] * b[8] + a[7] * b[13] + a[8] * b[18]; + out[9] = a[5] * b[4] + a[6] * b[9] + a[7] * b[14] + a[8] * b[19] + a[9]; + out[10] = a[10] * b[0] + a[11] * b[5] + a[12] * b[10] + a[13] * b[15]; + out[11] = a[10] * b[1] + a[11] * b[6] + a[12] * b[11] + a[13] * b[16]; + out[12] = a[10] * b[2] + a[11] * b[7] + a[12] * b[12] + a[13] * b[17]; + out[13] = a[10] * b[3] + a[11] * b[8] + a[12] * b[13] + a[13] * b[18]; + out[14] = a[10] * b[4] + a[11] * b[9] + a[12] * b[14] + a[13] * b[19] + a[14]; + out[15] = a[15] * b[0] + a[16] * b[5] + a[17] * b[10] + a[18] * b[15]; + out[16] = a[15] * b[1] + a[16] * b[6] + a[17] * b[11] + a[18] * b[16]; + out[17] = a[15] * b[2] + a[16] * b[7] + a[17] * b[12] + a[18] * b[17]; + out[18] = a[15] * b[3] + a[16] * b[8] + a[17] * b[13] + a[18] * b[18]; + out[19] = a[15] * b[4] + a[16] * b[9] + a[17] * b[14] + a[18] * b[19] + a[19]; + return out; + } + /** + * Create a Float32 Array and normalize the offset component to 0-1 + * @param {number[]} matrix - 5x4 matrix + * @returns {number[]} 5x4 matrix with all values between 0-1 + */ + _colorMatrix(matrix) { + const m = new Float32Array(matrix); + m[4] /= 255; + m[9] /= 255; + m[14] /= 255; + m[19] /= 255; + return m; + } + /** + * Adjusts brightness + * @param b - value of the brigthness (0-1, where 0 is black) + * @param multiply - if true, current matrix and matrix are multiplied. If false, + * just set the current matrix with @param matrix + */ + brightness(b, multiply) { + const matrix = [ + b, + 0, + 0, + 0, + 0, + 0, + b, + 0, + 0, + 0, + 0, + 0, + b, + 0, + 0, + 0, + 0, + 0, + 1, + 0 + ]; + this._loadMatrix(matrix, multiply); + } + /** + * Sets each channel on the diagonal of the color matrix. + * This can be used to achieve a tinting effect on Containers similar to the tint field of some + * display objects like Sprite, Text, Graphics, and Mesh. + * @param color - Color of the tint. This is a hex value. + * @param multiply - if true, current matrix and matrix are multiplied. If false, + * just set the current matrix with @param matrix + */ + tint(color, multiply) { + const [r, g, b] = Color.shared.setValue(color).toArray(); + const matrix = [ + r, + 0, + 0, + 0, + 0, + 0, + g, + 0, + 0, + 0, + 0, + 0, + b, + 0, + 0, + 0, + 0, + 0, + 1, + 0 + ]; + this._loadMatrix(matrix, multiply); + } + /** + * Set the matrices in grey scales + * @param scale - value of the grey (0-1, where 0 is black) + * @param multiply - if true, current matrix and matrix are multiplied. If false, + * just set the current matrix with @param matrix + */ + greyscale(scale, multiply) { + const matrix = [ + scale, + scale, + scale, + 0, + 0, + scale, + scale, + scale, + 0, + 0, + scale, + scale, + scale, + 0, + 0, + 0, + 0, + 0, + 1, + 0 + ]; + this._loadMatrix(matrix, multiply); + } + /** + * for our american friends! + * @param scale + * @param multiply + */ + grayscale(scale, multiply) { + this.greyscale(scale, multiply); + } + /** + * Set the black and white matrice. + * @param multiply - if true, current matrix and matrix are multiplied. If false, + * just set the current matrix with @param matrix + */ + blackAndWhite(multiply) { + const matrix = [ + 0.3, + 0.6, + 0.1, + 0, + 0, + 0.3, + 0.6, + 0.1, + 0, + 0, + 0.3, + 0.6, + 0.1, + 0, + 0, + 0, + 0, + 0, + 1, + 0 + ]; + this._loadMatrix(matrix, multiply); + } + /** + * Set the hue property of the color + * @param rotation - in degrees + * @param multiply - if true, current matrix and matrix are multiplied. If false, + * just set the current matrix with @param matrix + */ + hue(rotation, multiply) { + rotation = (rotation || 0) / 180 * Math.PI; + const cosR = Math.cos(rotation); + const sinR = Math.sin(rotation); + const sqrt = Math.sqrt; + const w = 1 / 3; + const sqrW = sqrt(w); + const a00 = cosR + (1 - cosR) * w; + const a01 = w * (1 - cosR) - sqrW * sinR; + const a02 = w * (1 - cosR) + sqrW * sinR; + const a10 = w * (1 - cosR) + sqrW * sinR; + const a11 = cosR + w * (1 - cosR); + const a12 = w * (1 - cosR) - sqrW * sinR; + const a20 = w * (1 - cosR) - sqrW * sinR; + const a21 = w * (1 - cosR) + sqrW * sinR; + const a22 = cosR + w * (1 - cosR); + const matrix = [ + a00, + a01, + a02, + 0, + 0, + a10, + a11, + a12, + 0, + 0, + a20, + a21, + a22, + 0, + 0, + 0, + 0, + 0, + 1, + 0 + ]; + this._loadMatrix(matrix, multiply); + } + /** + * Set the contrast matrix, increase the separation between dark and bright + * Increase contrast : shadows darker and highlights brighter + * Decrease contrast : bring the shadows up and the highlights down + * @param amount - value of the contrast (0-1) + * @param multiply - if true, current matrix and matrix are multiplied. If false, + * just set the current matrix with @param matrix + */ + contrast(amount, multiply) { + const v = (amount || 0) + 1; + const o = -0.5 * (v - 1); + const matrix = [ + v, + 0, + 0, + 0, + o, + 0, + v, + 0, + 0, + o, + 0, + 0, + v, + 0, + o, + 0, + 0, + 0, + 1, + 0 + ]; + this._loadMatrix(matrix, multiply); + } + /** + * Set the saturation matrix, increase the separation between colors + * Increase saturation : increase contrast, brightness, and sharpness + * @param amount - The saturation amount (0-1) + * @param multiply - if true, current matrix and matrix are multiplied. If false, + * just set the current matrix with @param matrix + */ + saturate(amount = 0, multiply) { + const x = amount * 2 / 3 + 1; + const y = (x - 1) * -0.5; + const matrix = [ + x, + y, + y, + 0, + 0, + y, + x, + y, + 0, + 0, + y, + y, + x, + 0, + 0, + 0, + 0, + 0, + 1, + 0 + ]; + this._loadMatrix(matrix, multiply); + } + /** Desaturate image (remove color) Call the saturate function */ + desaturate() { + this.saturate(-1); + } + /** + * Negative image (inverse of classic rgb matrix) + * @param multiply - if true, current matrix and matrix are multiplied. If false, + * just set the current matrix with @param matrix + */ + negative(multiply) { + const matrix = [ + -1, + 0, + 0, + 1, + 0, + 0, + -1, + 0, + 1, + 0, + 0, + 0, + -1, + 1, + 0, + 0, + 0, + 0, + 1, + 0 + ]; + this._loadMatrix(matrix, multiply); + } + /** + * Sepia image + * @param multiply - if true, current matrix and matrix are multiplied. If false, + * just set the current matrix with @param matrix + */ + sepia(multiply) { + const matrix = [ + 0.393, + 0.7689999, + 0.18899999, + 0, + 0, + 0.349, + 0.6859999, + 0.16799999, + 0, + 0, + 0.272, + 0.5339999, + 0.13099999, + 0, + 0, + 0, + 0, + 0, + 1, + 0 + ]; + this._loadMatrix(matrix, multiply); + } + /** + * Color motion picture process invented in 1916 (thanks Dominic Szablewski) + * @param multiply - if true, current matrix and matrix are multiplied. If false, + * just set the current matrix with @param matrix + */ + technicolor(multiply) { + const matrix = [ + 1.9125277891456083, + -0.8545344976951645, + -0.09155508482755585, + 0, + 11.793603434377337, + -0.3087833385928097, + 1.7658908555458428, + -0.10601743074722245, + 0, + -70.35205161461398, + -0.231103377548616, + -0.7501899197440212, + 1.847597816108189, + 0, + 30.950940869491138, + 0, + 0, + 0, + 1, + 0 + ]; + this._loadMatrix(matrix, multiply); + } + /** + * Polaroid filter + * @param multiply - if true, current matrix and matrix are multiplied. If false, + * just set the current matrix with @param matrix + */ + polaroid(multiply) { + const matrix = [ + 1.438, + -0.062, + -0.062, + 0, + 0, + -0.122, + 1.378, + -0.122, + 0, + 0, + -0.016, + -0.016, + 1.483, + 0, + 0, + 0, + 0, + 0, + 1, + 0 + ]; + this._loadMatrix(matrix, multiply); + } + /** + * Filter who transforms : Red -> Blue and Blue -> Red + * @param multiply - if true, current matrix and matrix are multiplied. If false, + * just set the current matrix with @param matrix + */ + toBGR(multiply) { + const matrix = [ + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0 + ]; + this._loadMatrix(matrix, multiply); + } + /** + * Color reversal film introduced by Eastman Kodak in 1935. (thanks Dominic Szablewski) + * @param multiply - if true, current matrix and matrix are multiplied. If false, + * just set the current matrix with @param matrix + */ + kodachrome(multiply) { + const matrix = [ + 1.1285582396593525, + -0.3967382283601348, + -0.03992559172921793, + 0, + 63.72958762196502, + -0.16404339962244616, + 1.0835251566291304, + -0.05498805115633132, + 0, + 24.732407896706203, + -0.16786010706155763, + -0.5603416277695248, + 1.6014850761964943, + 0, + 35.62982807460946, + 0, + 0, + 0, + 1, + 0 + ]; + this._loadMatrix(matrix, multiply); + } + /** + * Brown delicious browni filter (thanks Dominic Szablewski) + * @param multiply - if true, current matrix and matrix are multiplied. If false, + * just set the current matrix with @param matrix + */ + browni(multiply) { + const matrix = [ + 0.5997023498159715, + 0.34553243048391263, + -0.2708298674538042, + 0, + 47.43192855600873, + -0.037703249837783157, + 0.8609577587992641, + 0.15059552388459913, + 0, + -36.96841498319127, + 0.24113635128153335, + -0.07441037908422492, + 0.44972182064877153, + 0, + -7.562075277591283, + 0, + 0, + 0, + 1, + 0 + ]; + this._loadMatrix(matrix, multiply); + } + /** + * Vintage filter (thanks Dominic Szablewski) + * @param multiply - if true, current matrix and matrix are multiplied. If false, + * just set the current matrix with @param matrix + */ + vintage(multiply) { + const matrix = [ + 0.6279345635605994, + 0.3202183420819367, + -0.03965408211312453, + 0, + 9.651285835294123, + 0.02578397704808868, + 0.6441188644374771, + 0.03259127616149294, + 0, + 7.462829176470591, + 0.0466055556782719, + -0.0851232987247891, + 0.5241648018700465, + 0, + 5.159190588235296, + 0, + 0, + 0, + 1, + 0 + ]; + this._loadMatrix(matrix, multiply); + } + /** + * We don't know exactly what it does, kind of gradient map, but funny to play with! + * @param desaturation - Tone values. + * @param toned - Tone values. + * @param lightColor - Tone values, example: `0xFFE580` + * @param darkColor - Tone values, example: `0xFFE580` + * @param multiply - if true, current matrix and matrix are multiplied. If false, + * just set the current matrix with @param matrix + */ + colorTone(desaturation, toned, lightColor, darkColor, multiply) { + desaturation = desaturation || 0.2; + toned = toned || 0.15; + lightColor = lightColor || 16770432; + darkColor = darkColor || 3375104; + const temp = Color.shared; + const [lR, lG, lB] = temp.setValue(lightColor).toArray(); + const [dR, dG, dB] = temp.setValue(darkColor).toArray(); + const matrix = [ + 0.3, + 0.59, + 0.11, + 0, + 0, + lR, + lG, + lB, + desaturation, + 0, + dR, + dG, + dB, + toned, + 0, + lR - dR, + lG - dG, + lB - dB, + 0, + 0 + ]; + this._loadMatrix(matrix, multiply); + } + /** + * Night effect + * @param intensity - The intensity of the night effect. + * @param multiply - if true, current matrix and matrix are multiplied. If false, + * just set the current matrix with @param matrix + */ + night(intensity, multiply) { + intensity = intensity || 0.1; + const matrix = [ + intensity * -2, + -intensity, + 0, + 0, + 0, + -intensity, + 0, + intensity, + 0, + 0, + 0, + intensity, + intensity * 2, + 0, + 0, + 0, + 0, + 0, + 1, + 0 + ]; + this._loadMatrix(matrix, multiply); + } + /** + * Predator effect + * + * Erase the current matrix by setting a new indepent one + * @param amount - how much the predator feels his future victim + * @param multiply - if true, current matrix and matrix are multiplied. If false, + * just set the current matrix with @param matrix + */ + predator(amount, multiply) { + const matrix = [ + // row 1 + 11.224130630493164 * amount, + -4.794486999511719 * amount, + -2.8746118545532227 * amount, + 0 * amount, + 0.40342438220977783 * amount, + // row 2 + -3.6330697536468506 * amount, + 9.193157196044922 * amount, + -2.951810836791992 * amount, + 0 * amount, + -1.316135048866272 * amount, + // row 3 + -3.2184197902679443 * amount, + -4.2375030517578125 * amount, + 7.476448059082031 * amount, + 0 * amount, + 0.8044459223747253 * amount, + // row 4 + 0, + 0, + 0, + 1, + 0 + ]; + this._loadMatrix(matrix, multiply); + } + /** + * LSD effect + * + * Multiply the current matrix + * @param multiply - if true, current matrix and matrix are multiplied. If false, + * just set the current matrix with @param matrix + */ + lsd(multiply) { + const matrix = [ + 2, + -0.4, + 0.5, + 0, + 0, + -0.5, + 2, + -0.4, + 0, + 0, + -0.4, + -0.5, + 3, + 0, + 0, + 0, + 0, + 0, + 1, + 0 + ]; + this._loadMatrix(matrix, multiply); + } + /** Erase the current matrix by setting the default one. */ + reset() { + const matrix = [ + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0 + ]; + this._loadMatrix(matrix, false); + } + /** + * The matrix of the color matrix filter + * @member {number[]} + * @default [1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0] + */ + get matrix() { + return this.resources.colorMatrixUniforms.uniforms.uColorMatrix; + } + set matrix(value) { + this.resources.colorMatrixUniforms.uniforms.uColorMatrix = value; + } + /** + * The opacity value to use when mixing the original and resultant colors. + * + * When the value is 0, the original color is used without modification. + * When the value is 1, the result color is used. + * When in the range (0, 1) the color is interpolated between the original and result by this amount. + * @default 1 + */ + get alpha() { + return this.resources.colorMatrixUniforms.uniforms.uAlpha; + } + set alpha(value) { + this.resources.colorMatrixUniforms.uniforms.uAlpha = value; + } +} + +var fragment$2 = "\nin vec2 vTextureCoord;\nin vec2 vFilterUv;\n\nout vec4 finalColor;\n\nuniform sampler2D uTexture;\nuniform sampler2D uMapTexture;\n\nuniform vec4 uInputClamp;\nuniform highp vec4 uInputSize;\nuniform mat2 uRotation;\nuniform vec2 uScale;\n\nvoid main()\n{\n vec4 map = texture(uMapTexture, vFilterUv);\n \n vec2 offset = uInputSize.zw * (uRotation * (map.xy - 0.5)) * uScale; \n\n finalColor = texture(uTexture, clamp(vTextureCoord + offset, uInputClamp.xy, uInputClamp.zw));\n}\n"; + +var vertex$1 = "in vec2 aPosition;\nout vec2 vTextureCoord;\nout vec2 vFilterUv;\n\n\nuniform vec4 uInputSize;\nuniform vec4 uOutputFrame;\nuniform vec4 uOutputTexture;\n\nuniform mat3 uFilterMatrix;\n\nvec4 filterVertexPosition( void )\n{\n vec2 position = aPosition * uOutputFrame.zw + uOutputFrame.xy;\n \n position.x = position.x * (2.0 / uOutputTexture.x) - 1.0;\n position.y = position.y * (2.0*uOutputTexture.z / uOutputTexture.y) - uOutputTexture.z;\n\n return vec4(position, 0.0, 1.0);\n}\n\nvec2 filterTextureCoord( void )\n{\n return aPosition * (uOutputFrame.zw * uInputSize.zw);\n}\n\nvec2 getFilterCoord( void )\n{\n return ( uFilterMatrix * vec3( filterTextureCoord(), 1.0) ).xy;\n}\n\n\nvoid main(void)\n{\n gl_Position = filterVertexPosition();\n vTextureCoord = filterTextureCoord();\n vFilterUv = getFilterCoord();\n}\n"; + +var source$2 = "\nstruct GlobalFilterUniforms {\n uInputSize:vec4,\n uInputPixel:vec4,\n uInputClamp:vec4,\n uOutputFrame:vec4,\n uGlobalFrame:vec4,\n uOutputTexture:vec4,\n};\n\nstruct DisplacementUniforms {\n uFilterMatrix:mat3x3,\n uScale:vec2,\n uRotation:mat2x2\n};\n\n\n\n@group(0) @binding(0) var gfu: GlobalFilterUniforms;\n@group(0) @binding(1) var uTexture: texture_2d;\n@group(0) @binding(2) var uSampler : sampler;\n\n@group(1) @binding(0) var filterUniforms : DisplacementUniforms;\n@group(1) @binding(1) var uMapTexture: texture_2d;\n@group(1) @binding(2) var uMapSampler : sampler;\n\nstruct VSOutput {\n @builtin(position) position: vec4,\n @location(0) uv : vec2,\n @location(1) filterUv : vec2,\n };\n\nfn filterVertexPosition(aPosition:vec2) -> vec4\n{\n var position = aPosition * gfu.uOutputFrame.zw + gfu.uOutputFrame.xy;\n\n position.x = position.x * (2.0 / gfu.uOutputTexture.x) - 1.0;\n position.y = position.y * (2.0*gfu.uOutputTexture.z / gfu.uOutputTexture.y) - gfu.uOutputTexture.z;\n\n return vec4(position, 0.0, 1.0);\n}\n\nfn filterTextureCoord( aPosition:vec2 ) -> vec2\n{\n return aPosition * (gfu.uOutputFrame.zw * gfu.uInputSize.zw);\n}\n\nfn globalTextureCoord( aPosition:vec2 ) -> vec2\n{\n return (aPosition.xy / gfu.uGlobalFrame.zw) + (gfu.uGlobalFrame.xy / gfu.uGlobalFrame.zw); \n}\n\nfn getFilterCoord(aPosition:vec2 ) -> vec2\n{\n return ( filterUniforms.uFilterMatrix * vec3( filterTextureCoord(aPosition), 1.0) ).xy;\n}\n\nfn getSize() -> vec2\n{\n\n \n return gfu.uGlobalFrame.zw;\n}\n \n@vertex\nfn mainVertex(\n @location(0) aPosition : vec2, \n) -> VSOutput {\n return VSOutput(\n filterVertexPosition(aPosition),\n filterTextureCoord(aPosition),\n getFilterCoord(aPosition)\n );\n}\n\n@fragment\nfn mainFragment(\n @location(0) uv: vec2,\n @location(1) filterUv: vec2,\n @builtin(position) position: vec4\n) -> @location(0) vec4 {\n\n var map = textureSample(uMapTexture, uMapSampler, filterUv);\n\n var offset = gfu.uInputSize.zw * (filterUniforms.uRotation * (map.xy - 0.5)) * filterUniforms.uScale; \n \n return textureSample(uTexture, uSampler, clamp(uv + offset, gfu.uInputClamp.xy, gfu.uInputClamp.zw));\n}"; + +"use strict"; +var __defProp$p = Object.defineProperty; +var __defProps$b = Object.defineProperties; +var __getOwnPropDescs$b = Object.getOwnPropertyDescriptors; +var __getOwnPropSymbols$p = Object.getOwnPropertySymbols; +var __hasOwnProp$p = Object.prototype.hasOwnProperty; +var __propIsEnum$p = Object.prototype.propertyIsEnumerable; +var __defNormalProp$p = (obj, key, value) => key in obj ? __defProp$p(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; +var __spreadValues$p = (a, b) => { + for (var prop in b || (b = {})) + if (__hasOwnProp$p.call(b, prop)) + __defNormalProp$p(a, prop, b[prop]); + if (__getOwnPropSymbols$p) + for (var prop of __getOwnPropSymbols$p(b)) { + if (__propIsEnum$p.call(b, prop)) + __defNormalProp$p(a, prop, b[prop]); + } + return a; +}; +var __spreadProps$b = (a, b) => __defProps$b(a, __getOwnPropDescs$b(b)); +var __objRest$a = (source2, exclude) => { + var target = {}; + for (var prop in source2) + if (__hasOwnProp$p.call(source2, prop) && exclude.indexOf(prop) < 0) + target[prop] = source2[prop]; + if (source2 != null && __getOwnPropSymbols$p) + for (var prop of __getOwnPropSymbols$p(source2)) { + if (exclude.indexOf(prop) < 0 && __propIsEnum$p.call(source2, prop)) + target[prop] = source2[prop]; + } + return target; +}; +class DisplacementFilter extends Filter { + constructor(...args) { + let options = args[0]; + if (options instanceof Sprite) { + if (args[1]) { + deprecation(v8_0_0, "DisplacementFilter now uses options object instead of params. {sprite, scale}"); + } + options = { sprite: options, scale: args[1] }; + } + const _a = options, { sprite, scale: scaleOption } = _a, rest = __objRest$a(_a, ["sprite", "scale"]); + let scale = scaleOption != null ? scaleOption : 20; + if (typeof scale === "number") { + scale = new Point(scale, scale); + } + const filterUniforms = new UniformGroup({ + uFilterMatrix: { value: new Matrix(), type: "mat3x3" }, + uScale: { value: scale, type: "vec2" }, + uRotation: { value: new Float32Array([0, 0, 0, 0]), type: "mat2x2" } + }); + const glProgram = GlProgram.from({ + vertex: vertex$1, + fragment: fragment$2, + name: "displacement-filter" + }); + const gpuProgram = GpuProgram.from({ + vertex: { + source: source$2, + entryPoint: "mainVertex" + }, + fragment: { + source: source$2, + entryPoint: "mainFragment" + } + }); + const textureSource = sprite.texture.source; + super(__spreadProps$b(__spreadValues$p({}, rest), { + gpuProgram, + glProgram, + resources: { + filterUniforms, + uMapTexture: textureSource, + uMapSampler: textureSource.style + } + })); + this._sprite = options.sprite; + this._sprite.renderable = false; + } + /** + * Applies the filter. + * @param filterManager - The manager. + * @param input - The input target. + * @param output - The output target. + * @param clearMode - clearMode. + */ + apply(filterManager, input, output, clearMode) { + const uniforms = this.resources.filterUniforms.uniforms; + filterManager.calculateSpriteMatrix( + uniforms.uFilterMatrix, + this._sprite + ); + const wt = this._sprite.worldTransform; + const lenX = Math.sqrt(wt.a * wt.a + wt.b * wt.b); + const lenY = Math.sqrt(wt.c * wt.c + wt.d * wt.d); + if (lenX !== 0 && lenY !== 0) { + uniforms.uRotation[0] = wt.a / lenX; + uniforms.uRotation[1] = wt.b / lenX; + uniforms.uRotation[2] = wt.c / lenY; + uniforms.uRotation[3] = wt.d / lenY; + } + this.resources.uMapTexture = this._sprite.texture.source; + filterManager.applyFilter(this, input, output, clearMode); + } + /** scaleX, scaleY for displacements */ + get scale() { + return this.resources.filterUniforms.uniforms.uScale; + } +} + +var fragment$1 = "\nin vec2 vTextureCoord;\nin vec4 vColor;\n\nout vec4 finalColor;\n\nuniform float uNoise;\nuniform float uSeed;\nuniform sampler2D uTexture;\n\nfloat rand(vec2 co)\n{\n return fract(sin(dot(co.xy, vec2(12.9898, 78.233))) * 43758.5453);\n}\n\nvoid main()\n{\n vec4 color = texture(uTexture, vTextureCoord);\n float randomValue = rand(gl_FragCoord.xy * uSeed);\n float diff = (randomValue - 0.5) * uNoise;\n\n // Un-premultiply alpha before applying the color matrix. See issue #3539.\n if (color.a > 0.0) {\n color.rgb /= color.a;\n }\n\n color.r += diff;\n color.g += diff;\n color.b += diff;\n\n // Premultiply alpha again.\n color.rgb *= color.a;\n\n finalColor = color;\n}\n"; + +var source$1 = "\n\nstruct GlobalFilterUniforms {\n uInputSize:vec4,\n uInputPixel:vec4,\n uInputClamp:vec4,\n uOutputFrame:vec4,\n uGlobalFrame:vec4,\n uOutputTexture:vec4,\n};\n\nstruct NoiseUniforms {\n uNoise:f32,\n uSeed:f32,\n};\n\n@group(0) @binding(0) var gfu: GlobalFilterUniforms;\n@group(0) @binding(1) var uTexture: texture_2d;\n@group(0) @binding(2) var uSampler : sampler;\n\n@group(1) @binding(0) var noiseUniforms : NoiseUniforms;\n\nstruct VSOutput {\n @builtin(position) position: vec4,\n @location(0) uv : vec2\n };\n\nfn filterVertexPosition(aPosition:vec2) -> vec4\n{\n var position = aPosition * gfu.uOutputFrame.zw + gfu.uOutputFrame.xy;\n\n position.x = position.x * (2.0 / gfu.uOutputTexture.x) - 1.0;\n position.y = position.y * (2.0*gfu.uOutputTexture.z / gfu.uOutputTexture.y) - gfu.uOutputTexture.z;\n\n return vec4(position, 0.0, 1.0);\n}\n\nfn filterTextureCoord( aPosition:vec2 ) -> vec2\n{\n return aPosition * (gfu.uOutputFrame.zw * gfu.uInputSize.zw);\n}\n\nfn globalTextureCoord( aPosition:vec2 ) -> vec2\n{\n return (aPosition.xy / gfu.uGlobalFrame.zw) + (gfu.uGlobalFrame.xy / gfu.uGlobalFrame.zw); \n}\n\nfn getSize() -> vec2\n{\n return gfu.uGlobalFrame.zw;\n}\n \n@vertex\nfn mainVertex(\n @location(0) aPosition : vec2, \n) -> VSOutput {\n return VSOutput(\n filterVertexPosition(aPosition),\n filterTextureCoord(aPosition)\n );\n}\n\nfn rand(co:vec2) -> f32\n{\n return fract(sin(dot(co.xy, vec2(12.9898, 78.233))) * 43758.5453);\n}\n\n\n\n@fragment\nfn mainFragment(\n @location(0) uv: vec2,\n @builtin(position) position: vec4\n) -> @location(0) vec4 {\n\n var pixelPosition = globalTextureCoord(position.xy);// / (getSize());//- gfu.uOutputFrame.xy);\n \n \n var sample = textureSample(uTexture, uSampler, uv);\n var randomValue = rand(pixelPosition.xy * noiseUniforms.uSeed);\n var diff = (randomValue - 0.5) * noiseUniforms.uNoise;\n \n // Un-premultiply alpha before applying the color matrix. See issue #3539.\n if (sample.a > 0.0) {\n sample.r /= sample.a;\n sample.g /= sample.a;\n sample.b /= sample.a;\n }\n\n sample.r += diff;\n sample.g += diff;\n sample.b += diff;\n\n // Premultiply alpha again.\n sample.r *= sample.a;\n sample.g *= sample.a;\n sample.b *= sample.a;\n \n return sample;\n}"; + +"use strict"; +var __defProp$o = Object.defineProperty; +var __defProps$a = Object.defineProperties; +var __getOwnPropDescs$a = Object.getOwnPropertyDescriptors; +var __getOwnPropSymbols$o = Object.getOwnPropertySymbols; +var __hasOwnProp$o = Object.prototype.hasOwnProperty; +var __propIsEnum$o = Object.prototype.propertyIsEnumerable; +var __defNormalProp$o = (obj, key, value) => key in obj ? __defProp$o(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; +var __spreadValues$o = (a, b) => { + for (var prop in b || (b = {})) + if (__hasOwnProp$o.call(b, prop)) + __defNormalProp$o(a, prop, b[prop]); + if (__getOwnPropSymbols$o) + for (var prop of __getOwnPropSymbols$o(b)) { + if (__propIsEnum$o.call(b, prop)) + __defNormalProp$o(a, prop, b[prop]); + } + return a; +}; +var __spreadProps$a = (a, b) => __defProps$a(a, __getOwnPropDescs$a(b)); +var __objRest$9 = (source2, exclude) => { + var target = {}; + for (var prop in source2) + if (__hasOwnProp$o.call(source2, prop) && exclude.indexOf(prop) < 0) + target[prop] = source2[prop]; + if (source2 != null && __getOwnPropSymbols$o) + for (var prop of __getOwnPropSymbols$o(source2)) { + if (exclude.indexOf(prop) < 0 && __propIsEnum$o.call(source2, prop)) + target[prop] = source2[prop]; + } + return target; +}; +const _NoiseFilter = class _NoiseFilter extends Filter { + /** + * @param options - The options of the noise filter. + */ + constructor(options = {}) { + options = __spreadValues$o(__spreadValues$o({}, _NoiseFilter.defaultOptions), options); + const gpuProgram = GpuProgram.from({ + vertex: { + source: source$1, + entryPoint: "mainVertex" + }, + fragment: { + source: source$1, + entryPoint: "mainFragment" + } + }); + const glProgram = GlProgram.from({ + vertex: vertex$2, + fragment: fragment$1, + name: "noise-filter" + }); + const _a = options, { noise, seed } = _a, rest = __objRest$9(_a, ["noise", "seed"]); + super(__spreadProps$a(__spreadValues$o({}, rest), { + gpuProgram, + glProgram, + resources: { + noiseUniforms: new UniformGroup({ + uNoise: { value: 1, type: "f32" }, + uSeed: { value: 1, type: "f32" } + }) + } + })); + this.noise = noise; + this.seed = seed != null ? seed : Math.random(); + } + /** + * The amount of noise to apply, this value should be in the range (0, 1]. + * @default 0.5 + */ + get noise() { + return this.resources.noiseUniforms.uniforms.uNoise; + } + set noise(value) { + this.resources.noiseUniforms.uniforms.uNoise = value; + } + /** A seed value to apply to the random noise generation. `Math.random()` is a good value to use. */ + get seed() { + return this.resources.noiseUniforms.uniforms.uSeed; + } + set seed(value) { + this.resources.noiseUniforms.uniforms.uSeed = value; + } +}; +_NoiseFilter.defaultOptions = { + noise: 0.5 +}; +let NoiseFilter = _NoiseFilter; + +var fragment = "in vec2 vMaskCoord;\nin vec2 vTextureCoord;\n\nuniform sampler2D uTexture;\nuniform sampler2D uMaskTexture;\n\nuniform float uAlpha;\nuniform vec4 uMaskClamp;\n\nout vec4 finalColor;\n\nvoid main(void)\n{\n float clip = step(3.5,\n step(uMaskClamp.x, vMaskCoord.x) +\n step(uMaskClamp.y, vMaskCoord.y) +\n step(vMaskCoord.x, uMaskClamp.z) +\n step(vMaskCoord.y, uMaskClamp.w));\n\n // TODO look into why this is needed\n float npmAlpha = uAlpha; \n vec4 original = texture(uTexture, vTextureCoord);\n vec4 masky = texture(uMaskTexture, vMaskCoord);\n float alphaMul = 1.0 - npmAlpha * (1.0 - masky.a);\n\n original *= (alphaMul * masky.r * uAlpha * clip);\n\n finalColor = original;\n}\n"; + +var vertex = "in vec2 aPosition;\n\nout vec2 vTextureCoord;\nout vec2 vMaskCoord;\n\n\nuniform vec4 uInputSize;\nuniform vec4 uOutputFrame;\nuniform vec4 uOutputTexture;\nuniform mat3 uFilterMatrix;\n\nvec4 filterVertexPosition( vec2 aPosition )\n{\n vec2 position = aPosition * uOutputFrame.zw + uOutputFrame.xy;\n \n position.x = position.x * (2.0 / uOutputTexture.x) - 1.0;\n position.y = position.y * (2.0*uOutputTexture.z / uOutputTexture.y) - uOutputTexture.z;\n\n return vec4(position, 0.0, 1.0);\n}\n\nvec2 filterTextureCoord( vec2 aPosition )\n{\n return aPosition * (uOutputFrame.zw * uInputSize.zw);\n}\n\nvec2 getFilterCoord( vec2 aPosition )\n{\n return ( uFilterMatrix * vec3( filterTextureCoord(aPosition), 1.0) ).xy;\n} \n\nvoid main(void)\n{\n gl_Position = filterVertexPosition(aPosition);\n vTextureCoord = filterTextureCoord(aPosition);\n vMaskCoord = getFilterCoord(aPosition);\n}\n"; + +var source = "struct GlobalFilterUniforms {\n uInputSize:vec4,\n uInputPixel:vec4,\n uInputClamp:vec4,\n uOutputFrame:vec4,\n uGlobalFrame:vec4,\n uOutputTexture:vec4, \n};\n\nstruct MaskUniforms {\n uFilterMatrix:mat3x3,\n uMaskClamp:vec4,\n uAlpha:f32,\n};\n\n\n@group(0) @binding(0) var gfu: GlobalFilterUniforms;\n@group(0) @binding(1) var uTexture: texture_2d;\n@group(0) @binding(2) var uSampler : sampler;\n\n@group(1) @binding(0) var filterUniforms : MaskUniforms;\n@group(1) @binding(1) var uMaskTexture: texture_2d;\n\nstruct VSOutput {\n @builtin(position) position: vec4,\n @location(0) uv : vec2,\n @location(1) filterUv : vec2,\n };\n\nfn filterVertexPosition(aPosition:vec2) -> vec4\n{\n var position = aPosition * gfu.uOutputFrame.zw + gfu.uOutputFrame.xy;\n\n position.x = position.x * (2.0 / gfu.uOutputTexture.x) - 1.0;\n position.y = position.y * (2.0*gfu.uOutputTexture.z / gfu.uOutputTexture.y) - gfu.uOutputTexture.z;\n\n return vec4(position, 0.0, 1.0);\n}\n\nfn filterTextureCoord( aPosition:vec2 ) -> vec2\n{\n return aPosition * (gfu.uOutputFrame.zw * gfu.uInputSize.zw);\n}\n\nfn globalTextureCoord( aPosition:vec2 ) -> vec2\n{\n return (aPosition.xy / gfu.uGlobalFrame.zw) + (gfu.uGlobalFrame.xy / gfu.uGlobalFrame.zw); \n}\n\nfn getFilterCoord(aPosition:vec2 ) -> vec2\n{\n return ( filterUniforms.uFilterMatrix * vec3( filterTextureCoord(aPosition), 1.0) ).xy;\n}\n\nfn getSize() -> vec2\n{\n\n \n return gfu.uGlobalFrame.zw;\n}\n \n@vertex\nfn mainVertex(\n @location(0) aPosition : vec2, \n) -> VSOutput {\n return VSOutput(\n filterVertexPosition(aPosition),\n filterTextureCoord(aPosition),\n getFilterCoord(aPosition)\n );\n}\n\n@fragment\nfn mainFragment(\n @location(0) uv: vec2,\n @location(1) filterUv: vec2,\n @builtin(position) position: vec4\n) -> @location(0) vec4 {\n\n var maskClamp = filterUniforms.uMaskClamp;\n\n var clip = step(3.5,\n step(maskClamp.x, filterUv.x) +\n step(maskClamp.y, filterUv.y) +\n step(filterUv.x, maskClamp.z) +\n step(filterUv.y, maskClamp.w));\n\n var mask = textureSample(uMaskTexture, uSampler, filterUv);\n var source = textureSample(uTexture, uSampler, uv);\n \n var npmAlpha = 0.0;\n\n var alphaMul = 1.0 - npmAlpha * (1.0 - mask.a);\n\n var a = (alphaMul * mask.r) * clip;\n\n return vec4(source.rgb, source.a) * a;\n}"; + +"use strict"; +var __defProp$n = Object.defineProperty; +var __defProps$9 = Object.defineProperties; +var __getOwnPropDescs$9 = Object.getOwnPropertyDescriptors; +var __getOwnPropSymbols$n = Object.getOwnPropertySymbols; +var __hasOwnProp$n = Object.prototype.hasOwnProperty; +var __propIsEnum$n = Object.prototype.propertyIsEnumerable; +var __defNormalProp$n = (obj, key, value) => key in obj ? __defProp$n(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; +var __spreadValues$n = (a, b) => { + for (var prop in b || (b = {})) + if (__hasOwnProp$n.call(b, prop)) + __defNormalProp$n(a, prop, b[prop]); + if (__getOwnPropSymbols$n) + for (var prop of __getOwnPropSymbols$n(b)) { + if (__propIsEnum$n.call(b, prop)) + __defNormalProp$n(a, prop, b[prop]); + } + return a; +}; +var __spreadProps$9 = (a, b) => __defProps$9(a, __getOwnPropDescs$9(b)); +var __objRest$8 = (source2, exclude) => { + var target = {}; + for (var prop in source2) + if (__hasOwnProp$n.call(source2, prop) && exclude.indexOf(prop) < 0) + target[prop] = source2[prop]; + if (source2 != null && __getOwnPropSymbols$n) + for (var prop of __getOwnPropSymbols$n(source2)) { + if (exclude.indexOf(prop) < 0 && __propIsEnum$n.call(source2, prop)) + target[prop] = source2[prop]; + } + return target; +}; +class MaskFilter extends Filter { + constructor(options) { + const _a = options, { sprite } = _a, rest = __objRest$8(_a, ["sprite"]); + const textureMatrix = new TextureMatrix(sprite.texture); + const filterUniforms = new UniformGroup({ + uFilterMatrix: { value: new Matrix(), type: "mat3x3" }, + uMaskClamp: { value: textureMatrix.uClampFrame, type: "vec4" }, + uAlpha: { value: 1, type: "f32" } + }); + const gpuProgram = GpuProgram.from({ + vertex: { + source, + entryPoint: "mainVertex" + }, + fragment: { + source, + entryPoint: "mainFragment" + } + }); + const glProgram = GlProgram.from({ + vertex, + fragment, + name: "mask-filter" + }); + super(__spreadProps$9(__spreadValues$n({}, rest), { + gpuProgram, + glProgram, + resources: { + filterUniforms, + uMaskTexture: sprite.texture.source + } + })); + this.sprite = sprite; + this._textureMatrix = textureMatrix; + } + apply(filterManager, input, output, clearMode) { + this._textureMatrix.texture = this.sprite.texture; + filterManager.calculateSpriteMatrix( + this.resources.filterUniforms.uniforms.uFilterMatrix, + this.sprite + ).prepend(this._textureMatrix.mapCoord); + this.resources.uMaskTexture = this.sprite.texture.source; + filterManager.applyFilter(this, input, output, clearMode); + } +} + +var hsl = "fn getLuminosity(c: vec3) -> f32 {\n return 0.3 * c.r + 0.59 * c.g + 0.11 * c.b;\n}\n\nfn setLuminosity(c: vec3, lum: f32) -> vec3 {\n let d: f32 = lum - getLuminosity(c);\n let newColor: vec3 = c.rgb + vec3(d, d, d);\n\n // clip back into legal range\n let newLum: f32 = getLuminosity(newColor);\n let cMin: f32 = min(newColor.r, min(newColor.g, newColor.b));\n let cMax: f32 = max(newColor.r, max(newColor.g, newColor.b));\n\n let t1: f32 = newLum / (newLum - cMin);\n let t2: f32 = (1.0 - newLum) / (cMax - newLum);\n\n let finalColor = mix(vec3(newLum, newLum, newLum), newColor, select(select(1.0, t2, cMax > 1.0), t1, cMin < 0.0));\n\n return finalColor;\n}\n\nfn getSaturation(c: vec3) -> f32 {\n return max(c.r, max(c.g, c.b)) - min(c.r, min(c.g, c.b));\n}\n\n// Set saturation if color components are sorted in ascending order.\nfn setSaturationMinMidMax(cSorted: vec3, s: f32) -> vec3 {\n var result: vec3;\n if (cSorted.z > cSorted.x) {\n let newY = (((cSorted.y - cSorted.x) * s) / (cSorted.z - cSorted.x));\n result = vec3(0.0, newY, s);\n } else {\n result = vec3(0.0, 0.0, 0.0);\n }\n return vec3(result.x, result.y, result.z);\n}\n\nfn setSaturation(c: vec3, s: f32) -> vec3 {\n var result: vec3 = c;\n\n if (c.r <= c.g && c.r <= c.b) {\n if (c.g <= c.b) {\n result = setSaturationMinMidMax(result, s);\n } else {\n var temp: vec3 = vec3(result.r, result.b, result.g);\n temp = setSaturationMinMidMax(temp, s);\n result = vec3(temp.r, temp.b, temp.g);\n }\n } else if (c.g <= c.r && c.g <= c.b) {\n if (c.r <= c.b) {\n var temp: vec3 = vec3(result.g, result.r, result.b);\n temp = setSaturationMinMidMax(temp, s);\n result = vec3(temp.g, temp.r, temp.b);\n } else {\n var temp: vec3 = vec3(result.g, result.b, result.r);\n temp = setSaturationMinMidMax(temp, s);\n result = vec3(temp.g, temp.b, temp.r);\n }\n } else {\n if (c.r <= c.g) {\n var temp: vec3 = vec3(result.b, result.r, result.g);\n temp = setSaturationMinMidMax(temp, s);\n result = vec3(temp.b, temp.r, temp.g);\n } else {\n var temp: vec3 = vec3(result.b, result.g, result.r);\n temp = setSaturationMinMidMax(temp, s);\n result = vec3(temp.b, temp.g, temp.r);\n }\n }\n\n return result;\n}"; + +"use strict"; + +"use strict"; + +"use strict"; + +"use strict"; + +"use strict"; + +"use strict"; +class Triangle { + /** + * @param x - The X coord of the first point. + * @param y - The Y coord of the first point. + * @param x2 - The X coord of the second point. + * @param y2 - The Y coord of the second point. + * @param x3 - The X coord of the third point. + * @param y3 - The Y coord of the third point. + */ + constructor(x = 0, y = 0, x2 = 0, y2 = 0, x3 = 0, y3 = 0) { + /** + * The type of the object, mainly used to avoid `instanceof` checks + * @default 'triangle' + */ + this.type = "triangle"; + this.x = x; + this.y = y; + this.x2 = x2; + this.y2 = y2; + this.x3 = x3; + this.y3 = y3; + } + /** + * Checks whether the x and y coordinates given are contained within this triangle + * @param x - The X coordinate of the point to test + * @param y - The Y coordinate of the point to test + * @returns Whether the x/y coordinates are within this Triangle + */ + contains(x, y) { + const s = (this.x - this.x3) * (y - this.y3) - (this.y - this.y3) * (x - this.x3); + const t = (this.x2 - this.x) * (y - this.y) - (this.y2 - this.y) * (x - this.x); + if (s < 0 !== t < 0 && s !== 0 && t !== 0) { + return false; + } + const d = (this.x3 - this.x2) * (y - this.y2) - (this.y3 - this.y2) * (x - this.x2); + return d === 0 || d < 0 === s + t <= 0; + } + /** + * Checks whether the x and y coordinates given are contained within this triangle including the stroke. + * @param pointX - The X coordinate of the point to test + * @param pointY - The Y coordinate of the point to test + * @param strokeWidth - The width of the line to check + * @returns Whether the x/y coordinates are within this triangle + */ + strokeContains(pointX, pointY, strokeWidth) { + const halfStrokeWidth = strokeWidth / 2; + const halfStrokeWidthSquared = halfStrokeWidth * halfStrokeWidth; + const { x, x2, x3, y, y2, y3 } = this; + if (squaredDistanceToLineSegment(pointX, pointY, x, y, x2, y3) <= halfStrokeWidthSquared || squaredDistanceToLineSegment(pointX, pointY, x2, y2, x3, y3) <= halfStrokeWidthSquared || squaredDistanceToLineSegment(pointX, pointY, x3, y3, x, y) <= halfStrokeWidthSquared) { + return true; + } + return false; + } + /** + * Creates a clone of this Triangle + * @returns a copy of the triangle + */ + clone() { + const triangle = new Triangle( + this.x, + this.y, + this.x2, + this.y2, + this.x3, + this.y3 + ); + return triangle; + } + /** + * Copies another triangle to this one. + * @param triangle - The triangle to copy from. + * @returns Returns itself. + */ + copyFrom(triangle) { + this.x = triangle.x; + this.y = triangle.y; + this.x2 = triangle.x2; + this.y2 = triangle.y2; + this.x3 = triangle.x3; + this.y3 = triangle.y3; + return this; + } + /** + * Copies this triangle to another one. + * @param triangle - The triangle to copy to. + * @returns Returns given parameter. + */ + copyTo(triangle) { + triangle.copyFrom(this); + return triangle; + } + /** + * Returns the framing rectangle of the triangle as a Rectangle object + * @param out - optional rectangle to store the result + * @returns The framing rectangle + */ + getBounds(out) { + out = out || new Rectangle(); + const minX = Math.min(this.x, this.x2, this.x3); + const maxX = Math.max(this.x, this.x2, this.x3); + const minY = Math.min(this.y, this.y2, this.y3); + const maxY = Math.max(this.y, this.y2, this.y3); + out.x = minX; + out.y = minY; + out.width = maxX - minX; + out.height = maxY - minY; + return out; + } +} + +"use strict"; + +"use strict"; +const _PrepareBase = class _PrepareBase { + /** + * * @param {Renderer} renderer - A reference to the current renderer + * @param renderer + */ + constructor(renderer) { + /** called per frame by the ticker, defer processing to next tick */ + this._tick = () => { + this.timeout = setTimeout(this._processQueue, 0); + }; + /** process the queue up to max item limit per frame */ + this._processQueue = () => { + const { queue } = this; + let itemsProcessed = 0; + while (queue.length && itemsProcessed < _PrepareBase.uploadsPerFrame) { + const queueItem = queue.shift(); + this.uploadQueueItem(queueItem); + itemsProcessed++; + } + if (queue.length) { + Ticker.system.addOnce(this._tick, this, UPDATE_PRIORITY.UTILITY); + } else { + this._resolve(); + } + }; + this.renderer = renderer; + this.queue = []; + this.resolves = []; + } + /** + * Return a copy of the queue + * @returns {PrepareQueueItem[]} The queue + */ + getQueue() { + return [...this.queue]; + } + /** + * Add a textures or graphics resource to the queue + * @param {PrepareSourceItem | PrepareSourceItem[]} resource + */ + add(resource) { + const resourceArray = Array.isArray(resource) ? resource : [resource]; + for (const resourceItem of resourceArray) { + if (resourceItem instanceof Container) { + this._addContainer(resourceItem); + } else { + this.resolveQueueItem(resourceItem, this.queue); + } + } + return this; + } + /** + * Recursively add a container and its children to the queue + * @param {Container} container - The container to add to the queue + */ + _addContainer(container) { + this.resolveQueueItem(container, this.queue); + for (const child of container.children) { + this._addContainer(child); + } + } + /** + * Upload all the textures and graphics to the GPU (optionally add more resources to the queue first) + * @param {PrepareSourceItem | PrepareSourceItem[] | undefined} resource + */ + upload(resource) { + if (resource) { + this.add(resource); + } + return new Promise((resolve) => { + if (this.queue.length) { + this.resolves.push(resolve); + this.dedupeQueue(); + Ticker.system.addOnce(this._tick, this, UPDATE_PRIORITY.UTILITY); + } else { + resolve(); + } + }); + } + /** eliminate duplicates before processing */ + dedupeQueue() { + const hash = /* @__PURE__ */ Object.create(null); + let nextUnique = 0; + for (let i = 0; i < this.queue.length; i++) { + const current = this.queue[i]; + if (!hash[current.uid]) { + hash[current.uid] = true; + this.queue[nextUnique++] = current; + } + } + this.queue.length = nextUnique; + } + /** Call all the resolve callbacks */ + _resolve() { + const { resolves } = this; + const array = resolves.slice(0); + resolves.length = 0; + for (const resolve of array) { + resolve(); + } + } +}; +/** The number of uploads to process per frame */ +_PrepareBase.uploadsPerFrame = 4; +let PrepareBase = _PrepareBase; + +"use strict"; +var __defProp$m = Object.defineProperty; +var __getOwnPropSymbols$m = Object.getOwnPropertySymbols; +var __hasOwnProp$m = Object.prototype.hasOwnProperty; +var __propIsEnum$m = Object.prototype.propertyIsEnumerable; +var __defNormalProp$m = (obj, key, value) => key in obj ? __defProp$m(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; +var __spreadValues$m = (a, b) => { + for (var prop in b || (b = {})) + if (__hasOwnProp$m.call(b, prop)) + __defNormalProp$m(a, prop, b[prop]); + if (__getOwnPropSymbols$m) + for (var prop of __getOwnPropSymbols$m(b)) { + if (__propIsEnum$m.call(b, prop)) + __defNormalProp$m(a, prop, b[prop]); + } + return a; +}; +var __objRest$7 = (source, exclude) => { + var target = {}; + for (var prop in source) + if (__hasOwnProp$m.call(source, prop) && exclude.indexOf(prop) < 0) + target[prop] = source[prop]; + if (source != null && __getOwnPropSymbols$m) + for (var prop of __getOwnPropSymbols$m(source)) { + if (exclude.indexOf(prop) < 0 && __propIsEnum$m.call(source, prop)) + target[prop] = source[prop]; + } + return target; +}; +const tempPolygon = new Polygon(); +class Mesh extends Container { + constructor(...args) { + var _b; + let options = args[0]; + if (options instanceof Geometry) { + deprecation(v8_0_0, "Mesh: use new Mesh({ geometry, shader }) instead"); + options = { + geometry: options, + shader: args[1] + }; + if (args[3]) { + deprecation(v8_0_0, "Mesh: drawMode argument has been removed, use geometry.topology instead"); + options.geometry.topology = args[3]; + } + } + const _a = options, { geometry, shader, texture, roundPixels, state } = _a, rest = __objRest$7(_a, ["geometry", "shader", "texture", "roundPixels", "state"]); + super(__spreadValues$m({ + label: "Mesh" + }, rest)); + this.renderPipeId = "mesh"; + this.canBundle = true; + this._roundPixels = 0; + this.allowChildren = false; + this.shader = shader; + this.texture = (_b = texture != null ? texture : shader == null ? void 0 : shader.texture) != null ? _b : Texture.WHITE; + this.state = state != null ? state : State.for2d(); + this._geometry = geometry; + this._geometry.on("update", this.onViewUpdate, this); + this.roundPixels = roundPixels != null ? roundPixels : false; + } + /** + * Whether or not to round the x/y position of the mesh. + * @type {boolean} + */ + get roundPixels() { + return !!this._roundPixels; + } + set roundPixels(value) { + this._roundPixels = value ? 1 : 0; + } + /** Alias for {@link scene.Mesh#shader}. */ + get material() { + deprecation(v8_0_0, "mesh.material property has been removed, use mesh.shader instead"); + return this._shader; + } + /** + * Represents the vertex and fragment shaders that processes the geometry and runs on the GPU. + * Can be shared between multiple Mesh objects. + */ + set shader(value) { + if (this._shader === value) + return; + this._shader = value; + this.onViewUpdate(); + } + get shader() { + return this._shader; + } + /** + * Includes vertex positions, face indices, colors, UVs, and + * custom attributes within buffers, reducing the cost of passing all + * this data to the GPU. Can be shared between multiple Mesh objects. + */ + set geometry(value) { + var _a; + if (this._geometry === value) + return; + (_a = this._geometry) == null ? void 0 : _a.off("update", this.onViewUpdate, this); + value.on("update", this.onViewUpdate, this); + this._geometry = value; + this.onViewUpdate(); + } + get geometry() { + return this._geometry; + } + /** The texture that the Mesh uses. Null for non-MeshMaterial shaders */ + set texture(value) { + value || (value = Texture.EMPTY); + const currentTexture = this._texture; + if (currentTexture === value) + return; + if (currentTexture && currentTexture.dynamic) + currentTexture.off("update", this.onViewUpdate, this); + if (value.dynamic) + value.on("update", this.onViewUpdate, this); + if (this.shader) { + this.shader.texture = value; + } + this._texture = value; + this.onViewUpdate(); + } + get texture() { + return this._texture; + } + get batched() { + if (this._shader) + return false; + if (this._geometry instanceof MeshGeometry) { + if (this._geometry.batchMode === "auto") { + return this._geometry.positions.length / 2 <= 100; + } + return this._geometry.batchMode === "batch"; + } + return false; + } + /** + * The local bounds of the mesh. + * @type {rendering.Bounds} + */ + get bounds() { + return this._geometry.bounds; + } + /** + * Adds the bounds of this object to the bounds object. + * @param bounds - The output bounds object. + */ + addBounds(bounds) { + bounds.addBounds(this.geometry.bounds); + } + /** + * Checks if the object contains the given point. + * @param point - The point to check + */ + containsPoint(point) { + const { x, y } = point; + if (!this.bounds.containsPoint(x, y)) + return false; + const vertices = this.geometry.getBuffer("aPosition").data; + const points = tempPolygon.points; + const indices = this.geometry.getIndex().data; + const len = indices.length; + const step = this.geometry.topology === "triangle-strip" ? 3 : 1; + for (let i = 0; i + 2 < len; i += step) { + const ind0 = indices[i] * 2; + const ind1 = indices[i + 1] * 2; + const ind2 = indices[i + 2] * 2; + points[0] = vertices[ind0]; + points[1] = vertices[ind0 + 1]; + points[2] = vertices[ind1]; + points[3] = vertices[ind1 + 1]; + points[4] = vertices[ind2]; + points[5] = vertices[ind2 + 1]; + if (tempPolygon.contains(x, y)) { + return true; + } + } + return false; + } + /** @ignore */ + onViewUpdate() { + this._didChangeId += 1 << 12; + if (this.didViewUpdate) + return; + this.didViewUpdate = true; + if (this.renderGroup) { + this.renderGroup.onChildViewUpdate(this); + } + } + /** + * Destroys this sprite renderable and optionally its texture. + * @param options - Options parameter. A boolean will act as if all options + * have been set to that value + * @param {boolean} [options.texture=false] - Should it destroy the current texture of the renderable as well + * @param {boolean} [options.textureSource=false] - Should it destroy the textureSource of the renderable as well + */ + destroy(options) { + var _a; + super.destroy(options); + const destroyTexture = typeof options === "boolean" ? options : options == null ? void 0 : options.texture; + if (destroyTexture) { + const destroyTextureSource = typeof options === "boolean" ? options : options == null ? void 0 : options.textureSource; + this._texture.destroy(destroyTextureSource); + } + (_a = this._geometry) == null ? void 0 : _a.off("update", this.onViewUpdate, this); + this._texture = null; + this._geometry = null; + this._shader = null; + } +} + +"use strict"; +class AnimatedSprite extends Sprite { + /** + * @param textures - An array of {@link Texture} or frame + * objects that make up the animation. + * @param {boolean} [autoUpdate=true] - Whether to use Ticker.shared to auto update animation time. + */ + constructor(textures, autoUpdate = true) { + super(textures[0] instanceof Texture ? textures[0] : textures[0].texture); + this._textures = null; + this._durations = null; + this._autoUpdate = autoUpdate; + this._isConnectedToTicker = false; + this.animationSpeed = 1; + this.loop = true; + this.updateAnchor = false; + this.onComplete = null; + this.onFrameChange = null; + this.onLoop = null; + this._currentTime = 0; + this._playing = false; + this._previousFrame = null; + this.textures = textures; + } + /** Stops the AnimatedSprite. */ + stop() { + if (!this._playing) { + return; + } + this._playing = false; + if (this._autoUpdate && this._isConnectedToTicker) { + Ticker.shared.remove(this.update, this); + this._isConnectedToTicker = false; + } + } + /** Plays the AnimatedSprite. */ + play() { + if (this._playing) { + return; + } + this._playing = true; + if (this._autoUpdate && !this._isConnectedToTicker) { + Ticker.shared.add(this.update, this, UPDATE_PRIORITY.HIGH); + this._isConnectedToTicker = true; + } + } + /** + * Stops the AnimatedSprite and goes to a specific frame. + * @param frameNumber - Frame index to stop at. + */ + gotoAndStop(frameNumber) { + this.stop(); + this.currentFrame = frameNumber; + } + /** + * Goes to a specific frame and begins playing the AnimatedSprite. + * @param frameNumber - Frame index to start at. + */ + gotoAndPlay(frameNumber) { + this.currentFrame = frameNumber; + this.play(); + } + /** + * Updates the object transform for rendering. + * @param ticker - the ticker to use to update the object. + */ + update(ticker) { + if (!this._playing) { + return; + } + const deltaTime = ticker.deltaTime; + const elapsed = this.animationSpeed * deltaTime; + const previousFrame = this.currentFrame; + if (this._durations !== null) { + let lag = this._currentTime % 1 * this._durations[this.currentFrame]; + lag += elapsed / 60 * 1e3; + while (lag < 0) { + this._currentTime--; + lag += this._durations[this.currentFrame]; + } + const sign = Math.sign(this.animationSpeed * deltaTime); + this._currentTime = Math.floor(this._currentTime); + while (lag >= this._durations[this.currentFrame]) { + lag -= this._durations[this.currentFrame] * sign; + this._currentTime += sign; + } + this._currentTime += lag / this._durations[this.currentFrame]; + } else { + this._currentTime += elapsed; + } + if (this._currentTime < 0 && !this.loop) { + this.gotoAndStop(0); + if (this.onComplete) { + this.onComplete(); + } + } else if (this._currentTime >= this._textures.length && !this.loop) { + this.gotoAndStop(this._textures.length - 1); + if (this.onComplete) { + this.onComplete(); + } + } else if (previousFrame !== this.currentFrame) { + if (this.loop && this.onLoop) { + if (this.animationSpeed > 0 && this.currentFrame < previousFrame || this.animationSpeed < 0 && this.currentFrame > previousFrame) { + this.onLoop(); + } + } + this._updateTexture(); + } + } + /** Updates the displayed texture to match the current frame index. */ + _updateTexture() { + const currentFrame = this.currentFrame; + if (this._previousFrame === currentFrame) { + return; + } + this._previousFrame = currentFrame; + this.texture = this._textures[currentFrame]; + if (this.updateAnchor) { + this.anchor.copyFrom(this.texture.defaultAnchor); + } + if (this.onFrameChange) { + this.onFrameChange(this.currentFrame); + } + } + /** Stops the AnimatedSprite and destroys it. */ + destroy() { + this.stop(); + super.destroy(); + this.onComplete = null; + this.onFrameChange = null; + this.onLoop = null; + } + /** + * A short hand way of creating an AnimatedSprite from an array of frame ids. + * @param frames - The array of frames ids the AnimatedSprite will use as its texture frames. + * @returns - The new animated sprite with the specified frames. + */ + static fromFrames(frames) { + const textures = []; + for (let i = 0; i < frames.length; ++i) { + textures.push(Texture.from(frames[i])); + } + return new AnimatedSprite(textures); + } + /** + * A short hand way of creating an AnimatedSprite from an array of image ids. + * @param images - The array of image urls the AnimatedSprite will use as its texture frames. + * @returns The new animate sprite with the specified images as frames. + */ + static fromImages(images) { + const textures = []; + for (let i = 0; i < images.length; ++i) { + textures.push(Texture.from(images[i])); + } + return new AnimatedSprite(textures); + } + /** + * The total number of frames in the AnimatedSprite. This is the same as number of textures + * assigned to the AnimatedSprite. + * @readonly + * @default 0 + */ + get totalFrames() { + return this._textures.length; + } + /** The array of textures used for this AnimatedSprite. */ + get textures() { + return this._textures; + } + set textures(value) { + if (value[0] instanceof Texture) { + this._textures = value; + this._durations = null; + } else { + this._textures = []; + this._durations = []; + for (let i = 0; i < value.length; i++) { + this._textures.push(value[i].texture); + this._durations.push(value[i].time); + } + } + this._previousFrame = null; + this.gotoAndStop(0); + this._updateTexture(); + } + /** The AnimatedSprite's current frame index. */ + get currentFrame() { + let currentFrame = Math.floor(this._currentTime) % this._textures.length; + if (currentFrame < 0) { + currentFrame += this._textures.length; + } + return currentFrame; + } + set currentFrame(value) { + if (value < 0 || value > this.totalFrames - 1) { + throw new Error(`[AnimatedSprite]: Invalid frame index value ${value}, expected to be between 0 and totalFrames ${this.totalFrames}.`); + } + const previousFrame = this.currentFrame; + this._currentTime = value; + if (previousFrame !== this.currentFrame) { + this._updateTexture(); + } + } + /** + * Indicates if the AnimatedSprite is currently playing. + * @readonly + */ + get playing() { + return this._playing; + } + /** Whether to use Ticker.shared to auto update animation time. */ + get autoUpdate() { + return this._autoUpdate; + } + set autoUpdate(value) { + if (value !== this._autoUpdate) { + this._autoUpdate = value; + if (!this._autoUpdate && this._isConnectedToTicker) { + Ticker.shared.remove(this.update, this); + this._isConnectedToTicker = false; + } else if (this._autoUpdate && !this._isConnectedToTicker && this._playing) { + Ticker.shared.add(this.update, this); + this._isConnectedToTicker = true; + } + } + } +} + +"use strict"; +class Transform { + /** + * @param options - Options for the transform. + * @param options.matrix - The matrix to use. + * @param options.observer - The observer to use. + */ + constructor({ matrix, observer } = {}) { + this.dirty = true; + this._matrix = matrix != null ? matrix : new Matrix(); + this.observer = observer; + this.position = new ObservablePoint(this, 0, 0); + this.scale = new ObservablePoint(this, 1, 1); + this.pivot = new ObservablePoint(this, 0, 0); + this.skew = new ObservablePoint(this, 0, 0); + this._rotation = 0; + this._cx = 1; + this._sx = 0; + this._cy = 0; + this._sy = 1; + } + /** + * This matrix is computed by combining this Transforms position, scale, rotation, skew, and pivot + * properties into a single matrix. + * @readonly + */ + get matrix() { + const lt = this._matrix; + if (!this.dirty) + return lt; + lt.a = this._cx * this.scale.x; + lt.b = this._sx * this.scale.x; + lt.c = this._cy * this.scale.y; + lt.d = this._sy * this.scale.y; + lt.tx = this.position.x - (this.pivot.x * lt.a + this.pivot.y * lt.c); + lt.ty = this.position.y - (this.pivot.x * lt.b + this.pivot.y * lt.d); + this.dirty = false; + return lt; + } + /** + * Called when a value changes. + * @param point + * @internal + * @private + */ + _onUpdate(point) { + var _a; + this.dirty = true; + if (point === this.skew) { + this.updateSkew(); + } + (_a = this.observer) == null ? void 0 : _a._onUpdate(this); + } + /** Called when the skew or the rotation changes. */ + updateSkew() { + this._cx = Math.cos(this._rotation + this.skew.y); + this._sx = Math.sin(this._rotation + this.skew.y); + this._cy = -Math.sin(this._rotation - this.skew.x); + this._sy = Math.cos(this._rotation - this.skew.x); + this.dirty = true; + } + toString() { + return `[pixi.js/math:Transform position=(${this.position.x}, ${this.position.y}) rotation=${this.rotation} scale=(${this.scale.x}, ${this.scale.y}) skew=(${this.skew.x}, ${this.skew.y}) ]`; + } + /** + * Decomposes a matrix and sets the transforms properties based on it. + * @param matrix - The matrix to decompose + */ + setFromMatrix(matrix) { + matrix.decompose(this); + this.dirty = true; + } + /** The rotation of the object in radians. */ + get rotation() { + return this._rotation; + } + set rotation(value) { + if (this._rotation !== value) { + this._rotation = value; + this._onUpdate(this.skew); + } + } +} + +"use strict"; +var __defProp$l = Object.defineProperty; +var __getOwnPropSymbols$l = Object.getOwnPropertySymbols; +var __hasOwnProp$l = Object.prototype.hasOwnProperty; +var __propIsEnum$l = Object.prototype.propertyIsEnumerable; +var __defNormalProp$l = (obj, key, value) => key in obj ? __defProp$l(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; +var __spreadValues$l = (a, b) => { + for (var prop in b || (b = {})) + if (__hasOwnProp$l.call(b, prop)) + __defNormalProp$l(a, prop, b[prop]); + if (__getOwnPropSymbols$l) + for (var prop of __getOwnPropSymbols$l(b)) { + if (__propIsEnum$l.call(b, prop)) + __defNormalProp$l(a, prop, b[prop]); + } + return a; +}; +var __objRest$6 = (source, exclude) => { + var target = {}; + for (var prop in source) + if (__hasOwnProp$l.call(source, prop) && exclude.indexOf(prop) < 0) + target[prop] = source[prop]; + if (source != null && __getOwnPropSymbols$l) + for (var prop of __getOwnPropSymbols$l(source)) { + if (exclude.indexOf(prop) < 0 && __propIsEnum$l.call(source, prop)) + target[prop] = source[prop]; + } + return target; +}; +const _TilingSprite = class _TilingSprite extends Container { + constructor(...args) { + let options = args[0] || {}; + if (options instanceof Texture) { + options = { texture: options }; + } + if (args.length > 1) { + deprecation(v8_0_0, "use new TilingSprite({ texture, width:100, height:100 }) instead"); + options.width = args[1]; + options.height = args[2]; + } + options = __spreadValues$l(__spreadValues$l({}, _TilingSprite.defaultOptions), options); + const _a = options != null ? options : {}, { + texture, + anchor, + tilePosition, + tileScale, + tileRotation, + width, + height, + applyAnchorToTexture, + roundPixels + } = _a, rest = __objRest$6(_a, [ + "texture", + "anchor", + "tilePosition", + "tileScale", + "tileRotation", + "width", + "height", + "applyAnchorToTexture", + "roundPixels" + ]); + super(__spreadValues$l({ + label: "TilingSprite" + }, rest)); + this.renderPipeId = "tilingSprite"; + this.canBundle = true; + this.batched = true; + this._roundPixels = 0; + this._bounds = { minX: 0, maxX: 1, minY: 0, maxY: 0 }; + this._boundsDirty = true; + this.allowChildren = false; + this._anchor = new ObservablePoint(this); + this._applyAnchorToTexture = applyAnchorToTexture; + this.texture = texture; + this._width = width != null ? width : texture.width; + this._height = height != null ? height : texture.height; + this._tileTransform = new Transform({ + observer: { + _onUpdate: () => this.onViewUpdate() + } + }); + if (anchor) + this.anchor = anchor; + this.tilePosition = tilePosition; + this.tileScale = tileScale; + this.tileRotation = tileRotation; + this.roundPixels = roundPixels != null ? roundPixels : false; + } + /** + * Creates a new tiling sprite. + * @param source - The source to create the texture from. + * @param options - The options for creating the tiling sprite. + * @returns A new tiling sprite. + */ + static from(source, options = {}) { + if (typeof source === "string") { + return new _TilingSprite(__spreadValues$l({ + texture: Cache.get(source) + }, options)); + } + return new _TilingSprite(__spreadValues$l({ + texture: source + }, options)); + } + /** + * Changes frame clamping in corresponding textureMatrix + * Change to -0.5 to add a pixel to the edge, recommended for transparent trimmed textures in atlas + * @default 0.5 + * @member {number} + */ + get clampMargin() { + return this._texture.textureMatrix.clampMargin; + } + set clampMargin(value) { + this._texture.textureMatrix.clampMargin = value; + } + /** + * The anchor sets the origin point of the sprite. The default value is taken from the {@link Texture} + * and passed to the constructor. + * + * The default is `(0,0)`, this means the sprite's origin is the top left. + * + * Setting the anchor to `(0.5,0.5)` means the sprite's origin is centered. + * + * Setting the anchor to `(1,1)` would mean the sprite's origin point will be the bottom right corner. + * + * If you pass only single parameter, it will set both x and y to the same value as shown in the example below. + * @example + * import { TilingSprite } from 'pixi.js'; + * + * const sprite = new TilingSprite({texture: Texture.WHITE}); + * sprite.anchor.set(0.5); // This will set the origin to center. (0.5) is same as (0.5, 0.5). + */ + get anchor() { + return this._anchor; + } + set anchor(value) { + typeof value === "number" ? this._anchor.set(value) : this._anchor.copyFrom(value); + } + /** The offset of the image that is being tiled. */ + get tilePosition() { + return this._tileTransform.position; + } + set tilePosition(value) { + this._tileTransform.position.copyFrom(value); + } + /** The scaling of the image that is being tiled. */ + get tileScale() { + return this._tileTransform.scale; + } + set tileScale(value) { + typeof value === "number" ? this._tileTransform.scale.set(value) : this._tileTransform.scale.copyFrom(value); + } + set tileRotation(value) { + this._tileTransform.rotation = value; + } + /** The rotation of the image that is being tiled. */ + get tileRotation() { + return this._tileTransform.rotation; + } + /** The transform of the image that is being tiled. */ + get tileTransform() { + return this._tileTransform; + } + /** + * Whether or not to round the x/y position of the sprite. + * @type {boolean} + */ + get roundPixels() { + return !!this._roundPixels; + } + set roundPixels(value) { + this._roundPixels = value ? 1 : 0; + } + /** + * The local bounds of the sprite. + * @type {rendering.Bounds} + */ + get bounds() { + if (this._boundsDirty) { + this._updateBounds(); + this._boundsDirty = false; + } + return this._bounds; + } + set texture(value) { + value || (value = Texture.EMPTY); + const currentTexture = this._texture; + if (currentTexture === value) + return; + if (currentTexture && currentTexture.dynamic) + currentTexture.off("update", this.onViewUpdate, this); + if (value.dynamic) + value.on("update", this.onViewUpdate, this); + this._texture = value; + this.onViewUpdate(); + } + /** The texture that the sprite is using. */ + get texture() { + return this._texture; + } + /** The width of the tiling area. */ + set width(value) { + this._width = value; + this.onViewUpdate(); + } + get width() { + return this._width; + } + set height(value) { + this._height = value; + this.onViewUpdate(); + } + /** The height of the tiling area. */ + get height() { + return this._height; + } + _updateBounds() { + const bounds = this._bounds; + const anchor = this._anchor; + const width = this._width; + const height = this._height; + bounds.maxX = -anchor._x * width; + bounds.minX = bounds.maxX + width; + bounds.maxY = -anchor._y * height; + bounds.minY = bounds.maxY + height; + } + /** + * Adds the bounds of this object to the bounds object. + * @param bounds - The output bounds object. + */ + addBounds(bounds) { + const _bounds = this.bounds; + bounds.addFrame( + _bounds.minX, + _bounds.minY, + _bounds.maxX, + _bounds.maxY + ); + } + /** + * Checks if the object contains the given point. + * @param point - The point to check + */ + containsPoint(point) { + const width = this.bounds.minX; + const height = this.bounds.minY; + const x1 = -width * this._anchor._x; + let y1 = 0; + if (point.x >= x1 && point.x <= x1 + width) { + y1 = -height * this._anchor._y; + if (point.y >= y1 && point.y <= y1 + height) + return true; + } + return false; + } + onViewUpdate() { + this._boundsDirty = true; + this._didTilingSpriteUpdate = true; + this._didChangeId += 1 << 12; + if (this.didViewUpdate) + return; + this.didViewUpdate = true; + if (this.renderGroup) { + this.renderGroup.onChildViewUpdate(this); + } + } + /** + * Destroys this sprite renderable and optionally its texture. + * @param options - Options parameter. A boolean will act as if all options + * have been set to that value + * @param {boolean} [options.texture=false] - Should it destroy the current texture of the renderable as well + * @param {boolean} [options.textureSource=false] - Should it destroy the textureSource of the renderable as well + */ + destroy(options = false) { + super.destroy(options); + this._anchor = null; + this._tileTransform = null; + this._bounds = null; + const destroyTexture = typeof options === "boolean" ? options : options == null ? void 0 : options.texture; + if (destroyTexture) { + const destroyTextureSource = typeof options === "boolean" ? options : options == null ? void 0 : options.textureSource; + this._texture.destroy(destroyTextureSource); + } + this._texture = null; + } +}; +/** default options for the TilingSprite */ +_TilingSprite.defaultOptions = { + /** The texture to use for the sprite. */ + texture: Texture.EMPTY, + /** The anchor point of the sprite */ + anchor: { x: 0, y: 0 }, + /** The offset of the image that is being tiled. */ + tilePosition: { x: 0, y: 0 }, + /** Scaling of the image that is being tiled. */ + tileScale: { x: 1, y: 1 }, + /** The rotation of the image that is being tiled. */ + tileRotation: 0, + /** TODO */ + applyAnchorToTexture: false +}; +let TilingSprite = _TilingSprite; + +"use strict"; +var __defProp$k = Object.defineProperty; +var __getOwnPropSymbols$k = Object.getOwnPropertySymbols; +var __hasOwnProp$k = Object.prototype.hasOwnProperty; +var __propIsEnum$k = Object.prototype.propertyIsEnumerable; +var __defNormalProp$k = (obj, key, value) => key in obj ? __defProp$k(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; +var __spreadValues$k = (a, b) => { + for (var prop in b || (b = {})) + if (__hasOwnProp$k.call(b, prop)) + __defNormalProp$k(a, prop, b[prop]); + if (__getOwnPropSymbols$k) + for (var prop of __getOwnPropSymbols$k(b)) { + if (__propIsEnum$k.call(b, prop)) + __defNormalProp$k(a, prop, b[prop]); + } + return a; +}; +var __objRest$5 = (source, exclude) => { + var target = {}; + for (var prop in source) + if (__hasOwnProp$k.call(source, prop) && exclude.indexOf(prop) < 0) + target[prop] = source[prop]; + if (source != null && __getOwnPropSymbols$k) + for (var prop of __getOwnPropSymbols$k(source)) { + if (exclude.indexOf(prop) < 0 && __propIsEnum$k.call(source, prop)) + target[prop] = source[prop]; + } + return target; +}; +class AbstractText extends Container { + constructor(options, styleClass) { + const _a = options, { text, resolution, style, anchor, width, height, roundPixels } = _a, rest = __objRest$5(_a, ["text", "resolution", "style", "anchor", "width", "height", "roundPixels"]); + super(__spreadValues$k({}, rest)); + this.batched = true; + /** + * The resolution / device pixel ratio of the canvas. + * @default 1 + */ + this.resolution = null; + this._didTextUpdate = true; + this._roundPixels = 0; + this._bounds = new Bounds(); + this._boundsDirty = true; + this._styleClass = styleClass; + this.text = text != null ? text : ""; + this.style = style; + this.resolution = resolution != null ? resolution : null; + this.allowChildren = false; + this._anchor = new ObservablePoint( + { + _onUpdate: () => { + this.onViewUpdate(); + } + } + ); + if (anchor) + this.anchor = anchor; + this.roundPixels = roundPixels != null ? roundPixels : false; + if (width) + this.width = width; + if (height) + this.height = height; + } + /** + * The anchor sets the origin point of the text. + * The default is `(0,0)`, this means the text's origin is the top left. + * + * Setting the anchor to `(0.5,0.5)` means the text's origin is centered. + * + * Setting the anchor to `(1,1)` would mean the text's origin point will be the bottom right corner. + * + * If you pass only single parameter, it will set both x and y to the same value as shown in the example below. + * @example + * import { Text } from 'pixi.js'; + * + * const text = new Text('hello world'); + * text.anchor.set(0.5); // This will set the origin to center. (0.5) is same as (0.5, 0.5). + */ + get anchor() { + return this._anchor; + } + set anchor(value) { + typeof value === "number" ? this._anchor.set(value) : this._anchor.copyFrom(value); + } + /** + * Whether or not to round the x/y position of the text. + * @type {boolean} + */ + get roundPixels() { + return !!this._roundPixels; + } + set roundPixels(value) { + this._roundPixels = value ? 1 : 0; + } + /** Set the copy for the text object. To split a line you can use '\n'. */ + set text(value) { + value = value.toString(); + if (this._text === value) + return; + this._text = value; + this.onViewUpdate(); + } + get text() { + return this._text; + } + get style() { + return this._style; + } + /** + * Set the style of the text. + * + * Set up an event listener to listen for changes on the style object and mark the text as dirty. + * + * If setting the `style` can also be partial {@link AnyTextStyleOptions}. + * @type { + * text.TextStyle | + * Partial | + * text.TextStyleOptions | + * text.HTMLTextStyle | + * Partial | + * text.HTMLTextStyleOptions + * } + */ + set style(style) { + var _a; + style = style || {}; + (_a = this._style) == null ? void 0 : _a.off("update", this.onViewUpdate, this); + if (style instanceof this._styleClass) { + this._style = style; + } else { + this._style = new this._styleClass(style); + } + this._style.on("update", this.onViewUpdate, this); + this.onViewUpdate(); + } + /** + * The local bounds of the Text. + * @type {rendering.Bounds} + */ + get bounds() { + if (this._boundsDirty) { + this._updateBounds(); + this._boundsDirty = false; + } + return this._bounds; + } + /** The width of the sprite, setting this will actually modify the scale to achieve the value set. */ + get width() { + return Math.abs(this.scale.x) * this.bounds.width; + } + set width(value) { + this._setWidth(value, this.bounds.width); + } + /** The height of the sprite, setting this will actually modify the scale to achieve the value set. */ + get height() { + return Math.abs(this.scale.y) * this.bounds.height; + } + set height(value) { + this._setHeight(value, this.bounds.height); + } + /** + * Retrieves the size of the Text as a [Size]{@link Size} object. + * This is faster than get the width and height separately. + * @param out - Optional object to store the size in. + * @returns - The size of the Text. + */ + getSize(out) { + if (!out) { + out = {}; + } + out.width = Math.abs(this.scale.x) * this.bounds.width; + out.height = Math.abs(this.scale.y) * this.bounds.height; + return out; + } + /** + * Sets the size of the Text to the specified width and height. + * This is faster than setting the width and height separately. + * @param value - This can be either a number or a [Size]{@link Size} object. + * @param height - The height to set. Defaults to the value of `width` if not provided. + */ + setSize(value, height) { + var _a; + let convertedWidth; + let convertedHeight; + if (typeof value !== "object") { + convertedWidth = value; + convertedHeight = height != null ? height : value; + } else { + convertedWidth = value.width; + convertedHeight = (_a = value.height) != null ? _a : value.width; + } + if (convertedWidth !== void 0) { + this._setWidth(convertedWidth, this.bounds.width); + } + if (convertedHeight !== void 0) { + this._setHeight(convertedHeight, this.bounds.height); + } + } + /** + * Adds the bounds of this text to the bounds object. + * @param bounds - The output bounds object. + */ + addBounds(bounds) { + const _bounds = this.bounds; + bounds.addFrame( + _bounds.minX, + _bounds.minY, + _bounds.maxX, + _bounds.maxY + ); + } + /** + * Checks if the text contains the given point. + * @param point - The point to check + */ + containsPoint(point) { + const width = this.bounds.maxX; + const height = this.bounds.maxY; + const x1 = -width * this.anchor.x; + let y1 = 0; + if (point.x >= x1 && point.x <= x1 + width) { + y1 = -height * this.anchor.y; + if (point.y >= y1 && point.y <= y1 + height) + return true; + } + return false; + } + onViewUpdate() { + this._didChangeId += 1 << 12; + this._boundsDirty = true; + if (this.didViewUpdate) + return; + this.didViewUpdate = true; + this._didTextUpdate = true; + if (this.renderGroup) { + this.renderGroup.onChildViewUpdate(this); + } + } + _getKey() { + return `${this.text}:${this._style.styleKey}`; + } + /** + * Destroys this text renderable and optionally its style texture. + * @param options - Options parameter. A boolean will act as if all options + * have been set to that value + * @param {boolean} [options.texture=false] - Should it destroy the texture of the text style + * @param {boolean} [options.textureSource=false] - Should it destroy the textureSource of the text style + * @param {boolean} [options.style=false] - Should it destroy the style of the text + */ + destroy(options = false) { + super.destroy(options); + this.owner = null; + this._bounds = null; + this._anchor = null; + if (typeof options === "boolean" ? options : options == null ? void 0 : options.style) { + this._style.destroy(options); + } + this._style = null; + this._text = null; + } +} +function ensureOptions(args, name) { + var _a; + let options = (_a = args[0]) != null ? _a : {}; + if (typeof options === "string" || args[1]) { + deprecation(v8_0_0, `use new ${name}({ text: "hi!", style }) instead`); + options = { + text: options, + style: args[1] + }; + } + return options; +} + +"use strict"; +class Text extends AbstractText { + constructor(...args) { + const options = ensureOptions(args, "Text"); + super(options, TextStyle); + this.renderPipeId = "text"; + } + _updateBounds() { + const bounds = this._bounds; + const padding = this._style.padding; + const anchor = this._anchor; + const canvasMeasurement = CanvasTextMetrics.measureText( + this._text, + this._style + ); + const { width, height } = canvasMeasurement; + bounds.minX = -anchor._x * width - padding; + bounds.maxX = bounds.minX + width; + bounds.minY = -anchor._y * height - padding; + bounds.maxY = bounds.minY + height; + } +} + +"use strict"; +class PrepareQueue extends PrepareBase { + /** + * Resolve the given resource type and return an item for the queue + * @param source + * @param queue + */ + resolveQueueItem(source, queue) { + if (source instanceof Container) { + this.resolveContainerQueueItem(source, queue); + } else if (source instanceof TextureSource || source instanceof Texture) { + queue.push(source.source); + } else if (source instanceof GraphicsContext) { + queue.push(source); + } + return null; + } + /** + * Resolve the given container and return an item for the queue + * @param container + * @param queue + */ + resolveContainerQueueItem(container, queue) { + if (container instanceof Sprite || container instanceof TilingSprite || container instanceof Mesh) { + queue.push(container.texture.source); + } else if (container instanceof Text) { + queue.push(container); + } else if (container instanceof Graphics) { + queue.push(container.context); + } else if (container instanceof AnimatedSprite) { + container.textures.forEach((textureOrFrame) => { + if (textureOrFrame.source) { + queue.push(textureOrFrame.source); + } else { + queue.push(textureOrFrame.texture.source); + } + }); + } + } + /** + * Resolve the given graphics context and return an item for the queue + * @param graphicsContext + */ + resolveGraphicsContextQueueItem(graphicsContext) { + this.renderer.graphicsContext.getContextRenderData(graphicsContext); + const { instructions } = graphicsContext; + for (const instruction of instructions) { + if (instruction.action === "texture") { + const { image } = instruction.data; + return image.source; + } else if (instruction.action === "fill") { + const { texture } = instruction.data.style; + return texture.source; + } + } + return null; + } +} + +"use strict"; +class BitmapText extends AbstractText { + constructor(...args) { + var _a, _b, _c; + const options = ensureOptions(args, "BitmapText"); + (_a = options.style) != null ? _a : options.style = options.style || {}; + (_c = (_b = options.style).fill) != null ? _c : _b.fill = 16777215; + super(options, TextStyle); + this.renderPipeId = "bitmapText"; + } + _updateBounds() { + const bounds = this._bounds; + const padding = this._style.padding; + const anchor = this._anchor; + const bitmapMeasurement = BitmapFontManager.measureText(this.text, this._style); + const scale = bitmapMeasurement.scale; + const offset = bitmapMeasurement.offsetY * scale; + const width = bitmapMeasurement.width * scale; + const height = bitmapMeasurement.height * scale; + bounds.minX = -anchor._x * width - padding; + bounds.maxX = bounds.minX + width; + bounds.minY = -anchor._y * (height + offset) - padding; + bounds.maxY = bounds.minY + height; + } +} + +"use strict"; +class HTMLText extends AbstractText { + constructor(...args) { + const options = ensureOptions(args, "HtmlText"); + super(options, HTMLTextStyle); + this.renderPipeId = "htmlText"; + } + _updateBounds() { + const bounds = this._bounds; + const padding = this._style.padding; + const anchor = this._anchor; + const htmlMeasurement = measureHtmlText(this.text, this._style); + const { width, height } = htmlMeasurement; + bounds.minX = -anchor._x * width - padding; + bounds.maxX = bounds.minX + width; + bounds.minY = -anchor._y * height - padding; + bounds.maxY = bounds.minY + height; + } +} + +"use strict"; +class PrepareUpload extends PrepareQueue { + /** + * Upload the given queue item + * @param item + */ + uploadQueueItem(item) { + if (item instanceof TextureSource) { + this.uploadTextureSource(item); + } else if (item instanceof Text) { + this.uploadText(item); + } else if (item instanceof HTMLText) { + this.uploadHTMLText(item); + } else if (item instanceof BitmapText) { + this.uploadBitmapText(item); + } else if (item instanceof GraphicsContext) { + this.uploadGraphicsContext(item); + } + } + uploadTextureSource(textureSource) { + this.renderer.texture.initSource(textureSource); + } + uploadText(_text) { + this.renderer.renderPipes.text.initGpuText(_text); + } + uploadBitmapText(_text) { + this.renderer.renderPipes.bitmapText.initGpuText(_text); + } + uploadHTMLText(_text) { + this.renderer.renderPipes.htmlText.initGpuText(_text); + } + /** + * Resolve the given graphics context and return an item for the queue + * @param graphicsContext + */ + uploadGraphicsContext(graphicsContext) { + this.renderer.graphicsContext.getContextRenderData(graphicsContext); + const { instructions } = graphicsContext; + for (const instruction of instructions) { + if (instruction.action === "texture") { + const { image } = instruction.data; + this.uploadTextureSource(image.source); + } else if (instruction.action === "fill") { + const { texture } = instruction.data.style; + this.uploadTextureSource(texture.source); + } + } + return null; + } +} + +"use strict"; +class PrepareSystem extends PrepareUpload { + /** Destroys the plugin, don't use after this. */ + destroy() { + clearTimeout(this.timeout); + this.renderer = null; + this.queue = null; + this.resolves = null; + } +} +/** @ignore */ +PrepareSystem.extension = { + type: [ + ExtensionType.WebGLSystem, + ExtensionType.WebGPUSystem + ], + name: "prepare" +}; + +"use strict"; + +"use strict"; +class GlBatchAdaptor { + constructor() { + this._didUpload = false; + this._tempState = State.for2d(); + } + init(batcherPipe) { + const glProgram = compileHighShaderGlProgram({ + name: "batch", + bits: [ + colorBitGl, + generateTextureBatchBitGl(MAX_TEXTURES), + roundPixelsBitGl + ] + }); + this._shader = new Shader({ + glProgram, + resources: { + batchSamplers: batchSamplersUniformGroup + } + }); + batcherPipe.renderer.runners.contextChange.add(this); + } + contextChange() { + this._didUpload = false; + } + start(batchPipe, geometry) { + const renderer = batchPipe.renderer; + renderer.shader.bind(this._shader, this._didUpload); + renderer.shader.updateUniformGroup(renderer.globalUniforms.uniformGroup); + renderer.geometry.bind(geometry, this._shader.glProgram); + } + execute(batchPipe, batch) { + const renderer = batchPipe.renderer; + this._didUpload = true; + this._tempState.blendMode = batch.blendMode; + renderer.state.set(this._tempState); + const textures = batch.textures.textures; + for (let i = 0; i < textures.length; i++) { + renderer.texture.bind(textures[i], i); + } + renderer.geometry.draw("triangle-list", batch.size, batch.start); + } + destroy() { + this._shader.destroy(true); + this._shader = null; + } +} +/** @ignore */ +GlBatchAdaptor.extension = { + type: [ + ExtensionType.WebGLPipesAdaptor + ], + name: "batch" +}; + +"use strict"; +function generateGPULayout(maxTextures) { + const gpuLayout = []; + let bindIndex = 0; + for (let i = 0; i < maxTextures; i++) { + gpuLayout[bindIndex] = { + texture: { + sampleType: "float", + viewDimension: "2d", + multisampled: false + }, + binding: bindIndex, + visibility: GPUShaderStage.FRAGMENT + }; + bindIndex++; + gpuLayout[bindIndex] = { + sampler: { + type: "filtering" + }, + binding: bindIndex, + visibility: GPUShaderStage.FRAGMENT + }; + bindIndex++; + } + return gpuLayout; +} + +"use strict"; +function generateLayout(maxTextures) { + const layout = {}; + let bindIndex = 0; + for (let i = 0; i < maxTextures; i++) { + layout[`textureSource${i + 1}`] = bindIndex++; + layout[`textureSampler${i + 1}`] = bindIndex++; + } + return layout; +} + +"use strict"; +const tempState = State.for2d(); +class GpuBatchAdaptor { + init() { + const gpuProgram = compileHighShaderGpuProgram({ + name: "batch", + bits: [ + colorBit, + generateTextureBatchBit(MAX_TEXTURES), + roundPixelsBit + ] + }); + this._shader = new Shader({ + gpuProgram, + groups: { + // these will be dynamically allocated + } + }); + } + start(batchPipe, geometry) { + const renderer = batchPipe.renderer; + const encoder = renderer.encoder; + const program = this._shader.gpuProgram; + this._geometry = geometry; + encoder.setGeometry(geometry); + tempState.blendMode = "normal"; + renderer.pipeline.getPipeline( + geometry, + program, + tempState + ); + const globalUniformsBindGroup = renderer.globalUniforms.bindGroup; + encoder.resetBindGroup(1); + encoder.setBindGroup(0, globalUniformsBindGroup, program); + } + execute(batchPipe, batch) { + const program = this._shader.gpuProgram; + const renderer = batchPipe.renderer; + const encoder = renderer.encoder; + if (!batch.bindGroup) { + const textureBatch = batch.textures; + batch.bindGroup = getTextureBatchBindGroup(textureBatch.textures, textureBatch.count); + } + tempState.blendMode = batch.blendMode; + const gpuBindGroup = renderer.bindGroup.getBindGroup( + batch.bindGroup, + program, + 1 + ); + const pipeline = renderer.pipeline.getPipeline( + this._geometry, + program, + tempState + ); + batch.bindGroup._touch(renderer.textureGC.count); + encoder.setPipeline(pipeline); + encoder.renderPassEncoder.setBindGroup(1, gpuBindGroup); + encoder.renderPassEncoder.drawIndexed(batch.size, 1, batch.start); + } + destroy() { + this._shader.destroy(true); + this._shader = null; + } +} +/** @ignore */ +GpuBatchAdaptor.extension = { + type: [ + ExtensionType.WebGPUPipesAdaptor + ], + name: "batch" +}; + +"use strict"; +class BatcherPipe { + constructor(renderer, adaptor) { + this.state = State.for2d(); + this._batches = /* @__PURE__ */ Object.create(null); + this._geometries = /* @__PURE__ */ Object.create(null); + this.renderer = renderer; + this._adaptor = adaptor; + this._adaptor.init(this); + } + buildStart(instructionSet) { + if (!this._batches[instructionSet.uid]) { + const batcher = new Batcher(); + this._batches[instructionSet.uid] = batcher; + this._geometries[batcher.uid] = new BatchGeometry(); + } + this._activeBatch = this._batches[instructionSet.uid]; + this._activeGeometry = this._geometries[this._activeBatch.uid]; + this._activeBatch.begin(); + } + addToBatch(batchableObject) { + this._activeBatch.add(batchableObject); + } + break(instructionSet) { + this._activeBatch.break(instructionSet); + } + buildEnd(instructionSet) { + const activeBatch = this._activeBatch; + const geometry = this._activeGeometry; + activeBatch.finish(instructionSet); + geometry.indexBuffer.setDataWithSize(activeBatch.indexBuffer, activeBatch.indexSize, true); + geometry.buffers[0].setDataWithSize(activeBatch.attributeBuffer.float32View, activeBatch.attributeSize, false); + } + upload(instructionSet) { + const batcher = this._batches[instructionSet.uid]; + const geometry = this._geometries[batcher.uid]; + if (batcher.dirty) { + batcher.dirty = false; + geometry.buffers[0].update(batcher.attributeSize * 4); + } + } + execute(batch) { + if (batch.action === "startBatch") { + const batcher = batch.batcher; + const geometry = this._geometries[batcher.uid]; + this._adaptor.start(this, geometry); + } + this._adaptor.execute(this, batch); + } + destroy() { + this.state = null; + this.renderer = null; + this._adaptor.destroy(); + this._adaptor = null; + for (const i in this._batches) { + this._batches[i].destroy(); + } + this._batches = null; + for (const i in this._geometries) { + this._geometries[i].destroy(); + } + this._geometries = null; + } +} +/** @ignore */ +BatcherPipe.extension = { + type: [ + ExtensionType.WebGLPipes, + ExtensionType.WebGPUPipes, + ExtensionType.CanvasPipes + ], + name: "batch" +}; + +"use strict"; + +"use strict"; +function formatShader(shader) { + const spl = shader.split(/([\n{}])/g).map((a) => a.trim()).filter((a) => a.length); + let indent = ""; + const formatted = spl.map((a) => { + let indentedLine = indent + a; + if (a === "{") { + indent += " "; + } else if (a === "}") { + indent = indent.substr(0, indent.length - 4); + indentedLine = indent + a; + } + return indentedLine; + }).join("\n"); + return formatted; +} + +"use strict"; +const textureBit = { + name: "texture-bit", + vertex: { + header: ( + /* wgsl */ + ` struct TextureUniforms { uTextureMatrix:mat3x3, } @group(2) @binding(2) var textureUniforms : TextureUniforms; - `,main:` + ` + ), + main: ( + /* wgsl */ + ` uv = (textureUniforms.uTextureMatrix * vec3(uv, 1.0)).xy; - `},fragment:{header:` + ` + ) + }, + fragment: { + header: ( + /* wgsl */ + ` @group(2) @binding(0) var uTexture: texture_2d; @group(2) @binding(1) var uSampler: sampler; - `,main:` + ` + ), + main: ( + /* wgsl */ + ` outColor = textureSample(uTexture, uSampler, vUV); - `}},Km={name:"texture-bit",vertex:{header:` + ` + ) + } +}; +const textureBitGl = { + name: "texture-bit", + vertex: { + header: ( + /* glsl */ + ` uniform mat3 uTextureMatrix; - `,main:` + ` + ), + main: ( + /* glsl */ + ` uv = (uTextureMatrix * vec3(uv, 1.0)).xy; - `},fragment:{header:` + ` + ) + }, + fragment: { + header: ( + /* glsl */ + ` uniform sampler2D uTexture; - `,main:` + ` + ), + main: ( + /* glsl */ + ` outColor = texture(uTexture, vUV); - `}};function qm(r,t){const e=r.root,s=r.instructionSet;s.reset(),t.batch.buildStart(s),t.blendMode.buildStart(),t.colorMask.buildStart(),e.sortableChildren&&e.sortChildren(),Zm(e,s,t,!0),t.batch.buildEnd(s),t.blendMode.buildEnd(s)}function Hr(r,t,e){r.globalDisplayStatus<7||!r.includeInBuild||(r.sortableChildren&&r.sortChildren(),r.isSimple?jS(r,t,e):Zm(r,t,e,!1))}function jS(r,t,e){if(r.renderPipeId&&(e.blendMode.setBlendMode(r,r.groupBlendMode,t),r.didViewUpdate=!1,e[r.renderPipeId].addRenderable(r,t)),!r.isRenderGroupRoot){const s=r.children,i=s.length;for(let n=0;n=0;o--){const a=r.effects[o];e[a.pipe].pop(a,r,t)}}}const VS=new lt;class WS extends ts{constructor(){super({filters:[new wm({sprite:new Ft(A.EMPTY)})]})}get sprite(){return this.filters[0].sprite}set sprite(t){this.filters[0].sprite=t}}class Pa{constructor(t){this._activeMaskStage=[],this._renderer=t}push(t,e,s){const i=this._renderer;if(i.renderPipes.batch.break(s),s.add({renderPipeId:"alphaMask",action:"pushMaskBegin",mask:t,canBundle:!1,maskedContainer:e}),t.renderMaskToTexture){const n=t.mask;n.includeInBuild=!0,Hr(n,s,i.renderPipes),n.includeInBuild=!1}i.renderPipes.batch.break(s),s.add({renderPipeId:"alphaMask",action:"pushMaskEnd",mask:t,maskedContainer:e,canBundle:!1})}pop(t,e,s){this._renderer.renderPipes.batch.break(s),s.add({renderPipeId:"alphaMask",action:"popMaskEnd",mask:t,canBundle:!1})}execute(t){const e=this._renderer,s=t.mask.renderMaskToTexture;if(t.action==="pushMaskBegin"){const i=H.get(WS);if(s){t.mask.mask.measurable=!0;const n=nr(t.mask.mask,!0,VS);t.mask.mask.measurable=!1,n.ceil();const o=ut.getOptimalTexture(n.width,n.height,1,!1);e.renderTarget.push(o,!0),e.globalUniforms.push({offset:n,worldColor:4294967295});const a=i.sprite;a.texture=o,a.worldTransform.tx=n.minX,a.worldTransform.ty=n.minY,this._activeMaskStage.push({filterEffect:i,maskedContainer:t.maskedContainer,filterTexture:o})}else i.sprite=t.mask.mask,this._activeMaskStage.push({filterEffect:i,maskedContainer:t.maskedContainer})}else if(t.action==="pushMaskEnd"){const i=this._activeMaskStage[this._activeMaskStage.length-1];s&&(e.renderTarget.pop(),e.globalUniforms.pop()),e.filter.push({renderPipeId:"filter",action:"pushFilter",container:i.maskedContainer,filterEffect:i.filterEffect,canBundle:!1})}else if(t.action==="popMaskEnd"){e.filter.pop();const i=this._activeMaskStage.pop();s&&ut.returnTexture(i.filterTexture),H.return(i.filterEffect)}}destroy(){this._renderer=null,this._activeMaskStage=null}}Pa.extension={type:[v.WebGLPipes,v.WebGPUPipes,v.CanvasPipes],name:"alphaMask"};class wa{constructor(t){this._colorStack=[],this._colorStackIndex=0,this._currentColor=0,this._renderer=t}buildStart(){this._colorStack[0]=15,this._colorStackIndex=1,this._currentColor=15}push(t,e,s){this._renderer.renderPipes.batch.break(s);const i=this._colorStack;i[this._colorStackIndex]=i[this._colorStackIndex-1]&t.mask;const n=this._colorStack[this._colorStackIndex];n!==this._currentColor&&(this._currentColor=n,s.add({renderPipeId:"colorMask",colorMask:n,canBundle:!1})),this._colorStackIndex++}pop(t,e,s){this._renderer.renderPipes.batch.break(s);const i=this._colorStack;this._colorStackIndex--;const n=i[this._colorStackIndex-1];n!==this._currentColor&&(this._currentColor=n,s.add({renderPipeId:"colorMask",colorMask:n,canBundle:!1}))}execute(t){this._renderer.colorMask.setMask(t.colorMask)}destroy(){this._colorStack=null}}wa.extension={type:[v.WebGLPipes,v.WebGPUPipes,v.CanvasPipes],name:"colorMask"};class YS{constructor(t){this.priority=0,this.pipe="scissorMask",this.mask=t,this.mask.renderable=!1,this.mask.measurable=!1}addBounds(t,e){ps(this.mask,t,e)}addLocalBounds(t,e){fs(this.mask,t,e)}containsPoint(t,e){const s=this.mask;return e(s,t)}reset(){this.mask.measurable=!0,this.mask=null}destroy(){this.reset()}}class Ra{constructor(t){this._maskStackHash={},this._maskHash=new WeakMap,this._renderer=t}push(t,e,s){var i,n;const o=t,a=this._renderer;a.renderPipes.batch.break(s),a.renderPipes.blendMode.setBlendMode(o.mask,"none",s),s.add({renderPipeId:"stencilMask",action:"pushMaskBegin",mask:t,canBundle:!1});const u=o.mask;u.includeInBuild=!0,this._maskHash.has(o)||this._maskHash.set(o,{instructionsStart:0,instructionsLength:0});const l=this._maskHash.get(o);l.instructionsStart=s.instructionSize,Hr(u,s,a.renderPipes),u.includeInBuild=!1,a.renderPipes.batch.break(s),s.add({renderPipeId:"stencilMask",action:"pushMaskEnd",mask:t,canBundle:!1});const h=s.instructionSize-l.instructionsStart-1;l.instructionsLength=h;const c=a.renderTarget.renderTarget.uid;(n=(i=this._maskStackHash)[c])!=null||(i[c]=0)}pop(t,e,s){const i=t,n=this._renderer;n.renderPipes.batch.break(s),n.renderPipes.blendMode.setBlendMode(i.mask,"none",s),s.add({renderPipeId:"stencilMask",action:"popMaskBegin",canBundle:!1});const o=this._maskHash.get(t);for(let a=0;a(r[r.ELEMENT_ARRAY_BUFFER=34963]="ELEMENT_ARRAY_BUFFER",r[r.ARRAY_BUFFER=34962]="ARRAY_BUFFER",r[r.UNIFORM_BUFFER=35345]="UNIFORM_BUFFER",r))(Xr||{});class Qm{constructor(t,e){this.buffer=t||null,this.updateID=-1,this.byteLength=-1,this.type=e}}class Ma{constructor(t){this._gpuBuffers=Object.create(null),this._boundBufferBases=Object.create(null),this._renderer=t}destroy(){this._renderer=null,this._gl=null,this._gpuBuffers=null,this._boundBufferBases=null}contextChange(){this._gpuBuffers=Object.create(null),this._gl=this._renderer.gl}getGlBuffer(t){return this._gpuBuffers[t.uid]||this.createGLBuffer(t)}bind(t){const{_gl:e}=this,s=this.getGlBuffer(t);e.bindBuffer(s.type,s.buffer)}bindBufferBase(t,e){const{_gl:s}=this;if(this._boundBufferBases[e]!==t){const i=this.getGlBuffer(t);this._boundBufferBases[e]=t,s.bindBufferBase(s.UNIFORM_BUFFER,e,i.buffer)}}bindBufferRange(t,e,s){const{_gl:i}=this;s=s||0;const n=this.getGlBuffer(t);i.bindBufferRange(i.UNIFORM_BUFFER,e||0,n.buffer,s*256,256)}updateBuffer(t){const{_gl:e}=this,s=this.getGlBuffer(t);if(t._updateID===s.updateID)return s;s.updateID=t._updateID,e.bindBuffer(s.type,s.buffer);const i=t.data;if(s.byteLength>=t.data.byteLength)e.bufferSubData(s.type,0,i,0,t._updateSize/i.BYTES_PER_ELEMENT);else{const n=t.descriptor.usage&$.STATIC?e.STATIC_DRAW:e.DYNAMIC_DRAW;s.byteLength=i.byteLength,e.bufferData(s.type,i,n)}return s}destroyAll(){const t=this._gl;for(const e in this._gpuBuffers)t.deleteBuffer(this._gpuBuffers[e].buffer);this._gpuBuffers=Object.create(null)}onBufferDestroy(t,e){const s=this._gpuBuffers[t.uid],i=this._gl;e||i.deleteBuffer(s.buffer),this._gpuBuffers[t.uid]=null}createGLBuffer(t){const{_gl:e}=this;let s=Xr.ARRAY_BUFFER;t.descriptor.usage&$.INDEX?s=Xr.ELEMENT_ARRAY_BUFFER:t.descriptor.usage&$.UNIFORM&&(s=Xr.UNIFORM_BUFFER);const i=new Qm(e.createBuffer(),s);return this._gpuBuffers[t.uid]=i,t.on("destroy",this.onBufferDestroy,this),i}}Ma.extension={type:[v.WebGLSystem],name:"buffer"};var KS=Object.defineProperty,qS=Object.defineProperties,ZS=Object.getOwnPropertyDescriptors,Jm=Object.getOwnPropertySymbols,QS=Object.prototype.hasOwnProperty,JS=Object.prototype.propertyIsEnumerable,tg=(r,t,e)=>t in r?KS(r,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):r[t]=e,_i=(r,t)=>{for(var e in t||(t={}))QS.call(t,e)&&tg(r,e,t[e]);if(Jm)for(var e of Jm(t))JS.call(t,e)&&tg(r,e,t[e]);return r},eg=(r,t)=>qS(r,ZS(t));const Oa=class Fx{constructor(t){this.supports={uint32Indices:!0,uniformBufferObject:!0,vertexArrayObject:!0,srgbTextures:!0,nonPowOf2wrapping:!0,msaa:!0,nonPowOf2mipmaps:!0},this._renderer=t,this.extensions=Object.create(null),this.handleContextLost=this.handleContextLost.bind(this),this.handleContextRestored=this.handleContextRestored.bind(this)}get isLost(){return!this.gl||this.gl.isContextLost()}contextChange(t){this.gl=t,this._renderer.gl=t}init(t){var e,s;if(t=_i(_i({},Fx.defaultOptions),t),t.context)this.initFromContext(t.context);else{const i=this._renderer.background.alpha<1,n=(e=t.premultipliedAlpha)!=null?e:!0,o=t.antialias&&!this._renderer.backBuffer.useBackBuffer;this.createContext(t.preferWebGLVersion,{alpha:i,premultipliedAlpha:n,antialias:o,stencil:!0,preserveDrawingBuffer:t.preserveDrawingBuffer,powerPreference:(s=t.powerPreference)!=null?s:"default"})}}initFromContext(t){this.gl=t,this.webGLVersion=t instanceof X.get().getWebGL2RenderingContext()?2:1,this.getExtensions(),this.validateContext(t),this._renderer.runners.contextChange.emit(t);const e=this._renderer.view.canvas;e.addEventListener("webglcontextlost",this.handleContextLost,!1),e.addEventListener("webglcontextrestored",this.handleContextRestored,!1)}createContext(t,e){let s;const i=this._renderer.view.canvas;if(t===2&&(s=i.getContext("webgl2",e)),!s&&(s=i.getContext("webgl",e),!s))throw new Error("This browser does not support WebGL. Try using the canvas renderer");this.gl=s,this.initFromContext(this.gl)}getExtensions(){const{gl:t}=this,e={anisotropicFiltering:t.getExtension("EXT_texture_filter_anisotropic"),floatTextureLinear:t.getExtension("OES_texture_float_linear"),s3tc:t.getExtension("WEBGL_compressed_texture_s3tc"),s3tc_sRGB:t.getExtension("WEBGL_compressed_texture_s3tc_srgb"),etc:t.getExtension("WEBGL_compressed_texture_etc"),etc1:t.getExtension("WEBGL_compressed_texture_etc1"),pvrtc:t.getExtension("WEBGL_compressed_texture_pvrtc")||t.getExtension("WEBKIT_WEBGL_compressed_texture_pvrtc"),atc:t.getExtension("WEBGL_compressed_texture_atc"),astc:t.getExtension("WEBGL_compressed_texture_astc"),bptc:t.getExtension("EXT_texture_compression_bptc"),rgtc:t.getExtension("EXT_texture_compression_rgtc"),loseContext:t.getExtension("WEBGL_lose_context")};this.webGLVersion===1?this.extensions=eg(_i({},e),{drawBuffers:t.getExtension("WEBGL_draw_buffers"),depthTexture:t.getExtension("WEBGL_depth_texture"),vertexArrayObject:t.getExtension("OES_vertex_array_object")||t.getExtension("MOZ_OES_vertex_array_object")||t.getExtension("WEBKIT_OES_vertex_array_object"),uint32ElementIndex:t.getExtension("OES_element_index_uint"),floatTexture:t.getExtension("OES_texture_float"),floatTextureLinear:t.getExtension("OES_texture_float_linear"),textureHalfFloat:t.getExtension("OES_texture_half_float"),textureHalfFloatLinear:t.getExtension("OES_texture_half_float_linear"),vertexAttribDivisorANGLE:t.getExtension("ANGLE_instanced_arrays"),srgb:t.getExtension("EXT_sRGB")}):this.extensions=eg(_i({},e),{colorBufferFloat:t.getExtension("EXT_color_buffer_float")})}handleContextLost(t){t.preventDefault(),this._contextLossForced&&(this._contextLossForced=!1,setTimeout(()=>{var e;this.gl.isContextLost()&&((e=this.extensions.loseContext)==null||e.restoreContext())},0))}handleContextRestored(){this._renderer.runners.contextChange.emit(this.gl)}destroy(){var t;const e=this._renderer.view.canvas;this._renderer=null,e.removeEventListener("webglcontextlost",this.handleContextLost),e.removeEventListener("webglcontextrestored",this.handleContextRestored),this.gl.useProgram(null),(t=this.extensions.loseContext)==null||t.loseContext()}forceContextLoss(){var t;(t=this.extensions.loseContext)==null||t.loseContext(),this._contextLossForced=!0}validateContext(t){const e=t.getContextAttributes();e&&e.stencil;const s=this.supports,i=this.webGLVersion===2,n=this.extensions;s.uint32Indices=i||!!n.uint32ElementIndex,s.uniformBufferObject=i,s.vertexArrayObject=i||!!n.vertexArrayObject,s.srgbTextures=i||!!n.srgb,s.nonPowOf2wrapping=i,s.nonPowOf2mipmaps=i,s.msaa=i,s.uint32Indices}};Oa.extension={type:[v.WebGLSystem],name:"context"},Oa.defaultOptions={context:null,premultipliedAlpha:!0,preserveDrawingBuffer:!1,powerPreference:void 0,preferWebGLVersion:2};let rg=Oa,Ca=0;const sg=500;function xi(...r){Ca!==sg&&(Ca++,Ca===sg?console.warn("PixiJS Warning: too many warnings, no more warnings will be reported to the console by PixiJS."):console.warn("PixiJS Warning: ",...r))}function Ga(r,t){var e,s,i,n;for(const o in r.attributes){const a=r.attributes[o],u=t[o];u?((e=a.location)!=null||(a.location=u.location),(s=a.format)!=null||(a.format=u.format),(i=a.offset)!=null||(a.offset=u.offset),(n=a.instance)!=null||(a.instance=u.instance)):xi(`Attribute ${o} is not present in the shader, but is present in the geometry. Unable to infer attribute details.`)}t2(r)}function t2(r){var t,e;const{buffers:s,attributes:i}=r,n={},o={};for(const a in s){const u=s[a];n[u.uid]=0,o[u.uid]=0}for(const a in i){const u=i[a];n[u.buffer.uid]+=Fe(u.format).stride}for(const a in i){const u=i[a];(t=u.stride)!=null||(u.stride=n[u.buffer.uid]),(e=u.start)!=null||(u.start=o[u.buffer.uid]),o[u.buffer.uid]+=Fe(u.format).stride}}var bi=(r=>(r[r.RGBA=6408]="RGBA",r[r.RGB=6407]="RGB",r[r.RG=33319]="RG",r[r.RED=6403]="RED",r[r.RGBA_INTEGER=36249]="RGBA_INTEGER",r[r.RGB_INTEGER=36248]="RGB_INTEGER",r[r.RG_INTEGER=33320]="RG_INTEGER",r[r.RED_INTEGER=36244]="RED_INTEGER",r[r.ALPHA=6406]="ALPHA",r[r.LUMINANCE=6409]="LUMINANCE",r[r.LUMINANCE_ALPHA=6410]="LUMINANCE_ALPHA",r[r.DEPTH_COMPONENT=6402]="DEPTH_COMPONENT",r[r.DEPTH_STENCIL=34041]="DEPTH_STENCIL",r))(bi||{}),Ia=(r=>(r[r.TEXTURE_2D=3553]="TEXTURE_2D",r[r.TEXTURE_CUBE_MAP=34067]="TEXTURE_CUBE_MAP",r[r.TEXTURE_2D_ARRAY=35866]="TEXTURE_2D_ARRAY",r[r.TEXTURE_CUBE_MAP_POSITIVE_X=34069]="TEXTURE_CUBE_MAP_POSITIVE_X",r[r.TEXTURE_CUBE_MAP_NEGATIVE_X=34070]="TEXTURE_CUBE_MAP_NEGATIVE_X",r[r.TEXTURE_CUBE_MAP_POSITIVE_Y=34071]="TEXTURE_CUBE_MAP_POSITIVE_Y",r[r.TEXTURE_CUBE_MAP_NEGATIVE_Y=34072]="TEXTURE_CUBE_MAP_NEGATIVE_Y",r[r.TEXTURE_CUBE_MAP_POSITIVE_Z=34073]="TEXTURE_CUBE_MAP_POSITIVE_Z",r[r.TEXTURE_CUBE_MAP_NEGATIVE_Z=34074]="TEXTURE_CUBE_MAP_NEGATIVE_Z",r))(Ia||{}),ig=(r=>(r[r.CLAMP=33071]="CLAMP",r[r.REPEAT=10497]="REPEAT",r[r.MIRRORED_REPEAT=33648]="MIRRORED_REPEAT",r))(ig||{}),N=(r=>(r[r.UNSIGNED_BYTE=5121]="UNSIGNED_BYTE",r[r.UNSIGNED_SHORT=5123]="UNSIGNED_SHORT",r[r.UNSIGNED_SHORT_5_6_5=33635]="UNSIGNED_SHORT_5_6_5",r[r.UNSIGNED_SHORT_4_4_4_4=32819]="UNSIGNED_SHORT_4_4_4_4",r[r.UNSIGNED_SHORT_5_5_5_1=32820]="UNSIGNED_SHORT_5_5_5_1",r[r.UNSIGNED_INT=5125]="UNSIGNED_INT",r[r.UNSIGNED_INT_10F_11F_11F_REV=35899]="UNSIGNED_INT_10F_11F_11F_REV",r[r.UNSIGNED_INT_2_10_10_10_REV=33640]="UNSIGNED_INT_2_10_10_10_REV",r[r.UNSIGNED_INT_24_8=34042]="UNSIGNED_INT_24_8",r[r.UNSIGNED_INT_5_9_9_9_REV=35902]="UNSIGNED_INT_5_9_9_9_REV",r[r.BYTE=5120]="BYTE",r[r.SHORT=5122]="SHORT",r[r.INT=5124]="INT",r[r.FLOAT=5126]="FLOAT",r[r.FLOAT_32_UNSIGNED_INT_24_8_REV=36269]="FLOAT_32_UNSIGNED_INT_24_8_REV",r[r.HALF_FLOAT=36193]="HALF_FLOAT",r))(N||{});const ng={uint8x2:N.UNSIGNED_BYTE,uint8x4:N.UNSIGNED_BYTE,sint8x2:N.BYTE,sint8x4:N.BYTE,unorm8x2:N.UNSIGNED_BYTE,unorm8x4:N.UNSIGNED_BYTE,snorm8x2:N.BYTE,snorm8x4:N.BYTE,uint16x2:N.UNSIGNED_SHORT,uint16x4:N.UNSIGNED_SHORT,sint16x2:N.SHORT,sint16x4:N.SHORT,unorm16x2:N.UNSIGNED_SHORT,unorm16x4:N.UNSIGNED_SHORT,snorm16x2:N.SHORT,snorm16x4:N.SHORT,float16x2:N.HALF_FLOAT,float16x4:N.HALF_FLOAT,float32:N.FLOAT,float32x2:N.FLOAT,float32x3:N.FLOAT,float32x4:N.FLOAT,uint32:N.UNSIGNED_INT,uint32x2:N.UNSIGNED_INT,uint32x3:N.UNSIGNED_INT,uint32x4:N.UNSIGNED_INT,sint32:N.INT,sint32x2:N.INT,sint32x3:N.INT,sint32x4:N.INT};function og(r){var t;return(t=ng[r])!=null?t:ng.float32}const e2={"point-list":0,"line-list":1,"line-strip":3,"triangle-list":4,"triangle-strip":5};class Ba{constructor(t){this._geometryVaoHash=Object.create(null),this._renderer=t,this._activeGeometry=null,this._activeVao=null,this.hasVao=!0,this.hasInstance=!0}contextChange(){const t=this.gl=this._renderer.gl;if(!this._renderer.context.supports.vertexArrayObject)throw new Error("[PixiJS] Vertex Array Objects are not supported on this device");const e=this._renderer.context.extensions.vertexArrayObject;e&&(t.createVertexArray=()=>e.createVertexArrayOES(),t.bindVertexArray=i=>e.bindVertexArrayOES(i),t.deleteVertexArray=i=>e.deleteVertexArrayOES(i));const s=this._renderer.context.extensions.vertexAttribDivisorANGLE;s&&(t.drawArraysInstanced=(i,n,o,a)=>{s.drawArraysInstancedANGLE(i,n,o,a)},t.drawElementsInstanced=(i,n,o,a,u)=>{s.drawElementsInstancedANGLE(i,n,o,a,u)},t.vertexAttribDivisor=(i,n)=>s.vertexAttribDivisorANGLE(i,n)),this._activeGeometry=null,this._activeVao=null,this._geometryVaoHash=Object.create(null)}bind(t,e){const s=this.gl;this._activeGeometry=t;const i=this.getVao(t,e);this._activeVao!==i&&(this._activeVao=i,s.bindVertexArray(i)),this.updateBuffers()}reset(){this.unbind()}updateBuffers(){const t=this._activeGeometry,e=this._renderer.buffer;for(let s=0;s1?n.drawElementsInstanced(a,e||o.indexBuffer.data.length,l,(s||0)*u,i):n.drawElements(a,e||o.indexBuffer.data.length,l,(s||0)*u)}else i>1?n.drawArraysInstanced(a,s||0,e||o.getSize(),i):n.drawArrays(a,s||0,e||o.getSize());return this}unbind(){this.gl.bindVertexArray(null),this._activeVao=null,this._activeGeometry=null}destroy(){this._renderer=null,this.gl=null,this._activeVao=null,this._activeGeometry=null}}Ba.extension={type:[v.WebGLSystem],name:"geometry"};var r2=Object.defineProperty,ag=Object.getOwnPropertySymbols,s2=Object.prototype.hasOwnProperty,i2=Object.prototype.propertyIsEnumerable,ug=(r,t,e)=>t in r?r2(r,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):r[t]=e,lg=(r,t)=>{for(var e in t||(t={}))s2.call(t,e)&&ug(r,e,t[e]);if(ag)for(var e of ag(t))i2.call(t,e)&&ug(r,e,t[e]);return r};const n2=new Oe({attributes:{aPosition:[-1,-1,3,-1,-1,3]}}),Fa=class Dx{constructor(t){this.useBackBuffer=!1,this._useBackBufferThisRender=!1,this._renderer=t}init(t={}){const{useBackBuffer:e,antialias:s}=lg(lg({},Dx.defaultOptions),t);this.useBackBuffer=e,this._antialias=s,this._renderer.context.supports.msaa||(xi("antialiasing, is not supported on when using the back buffer"),this._antialias=!1),this._state=Ct.for2d();const i=new Rt({vertex:` + ` + ) + } +}; + +"use strict"; +function buildInstructions(renderGroup, renderPipes) { + const root = renderGroup.root; + const instructionSet = renderGroup.instructionSet; + instructionSet.reset(); + renderPipes.batch.buildStart(instructionSet); + renderPipes.blendMode.buildStart(); + renderPipes.colorMask.buildStart(); + if (root.sortableChildren) { + root.sortChildren(); + } + collectAllRenderablesAdvanced(root, instructionSet, renderPipes, true); + renderPipes.batch.buildEnd(instructionSet); + renderPipes.blendMode.buildEnd(instructionSet); +} +function collectAllRenderables(container, instructionSet, rendererPipes) { + if (container.globalDisplayStatus < 7 || !container.includeInBuild) + return; + if (container.sortableChildren) { + container.sortChildren(); + } + if (container.isSimple) { + collectAllRenderablesSimple(container, instructionSet, rendererPipes); + } else { + collectAllRenderablesAdvanced(container, instructionSet, rendererPipes, false); + } +} +function collectAllRenderablesSimple(container, instructionSet, renderPipes) { + if (container.renderPipeId) { + renderPipes.blendMode.setBlendMode(container, container.groupBlendMode, instructionSet); + container.didViewUpdate = false; + const rp = renderPipes; + rp[container.renderPipeId].addRenderable(container, instructionSet); + } + if (!container.isRenderGroupRoot) { + const children = container.children; + const length = children.length; + for (let i = 0; i < length; i++) { + collectAllRenderables(children[i], instructionSet, renderPipes); + } + } +} +function collectAllRenderablesAdvanced(container, instructionSet, renderPipes, isRoot) { + if (!isRoot && container.isRenderGroupRoot) { + renderPipes.renderGroup.addRenderGroup(container.renderGroup, instructionSet); + } else { + for (let i = 0; i < container.effects.length; i++) { + const effect = container.effects[i]; + const pipe = renderPipes[effect.pipe]; + pipe.push(effect, container, instructionSet); + } + const renderPipeId = container.renderPipeId; + if (renderPipeId) { + renderPipes.blendMode.setBlendMode(container, container.groupBlendMode, instructionSet); + container.didViewUpdate = false; + const pipe = renderPipes[renderPipeId]; + pipe.addRenderable(container, instructionSet); + } + const children = container.children; + if (children.length) { + for (let i = 0; i < children.length; i++) { + collectAllRenderables(children[i], instructionSet, renderPipes); + } + } + for (let i = container.effects.length - 1; i >= 0; i--) { + const effect = container.effects[i]; + const pipe = renderPipes[effect.pipe]; + pipe.pop(effect, container, instructionSet); + } + } +} + +"use strict"; +const tempBounds$1 = new Bounds(); +class AlphaMaskEffect extends FilterEffect { + constructor() { + super({ + filters: [new MaskFilter({ + sprite: new Sprite(Texture.EMPTY) + })] + }); + } + get sprite() { + return this.filters[0].sprite; + } + set sprite(value) { + this.filters[0].sprite = value; + } +} +class AlphaMaskPipe { + constructor(renderer) { + this._activeMaskStage = []; + this._renderer = renderer; + } + push(mask, maskedContainer, instructionSet) { + const renderer = this._renderer; + renderer.renderPipes.batch.break(instructionSet); + instructionSet.add({ + renderPipeId: "alphaMask", + action: "pushMaskBegin", + mask, + canBundle: false, + maskedContainer + }); + if (mask.renderMaskToTexture) { + const maskContainer = mask.mask; + maskContainer.includeInBuild = true; + collectAllRenderables( + maskContainer, + instructionSet, + renderer.renderPipes + ); + maskContainer.includeInBuild = false; + } + renderer.renderPipes.batch.break(instructionSet); + instructionSet.add({ + renderPipeId: "alphaMask", + action: "pushMaskEnd", + mask, + maskedContainer, + canBundle: false + }); + } + pop(mask, _maskedContainer, instructionSet) { + const renderer = this._renderer; + renderer.renderPipes.batch.break(instructionSet); + instructionSet.add({ + renderPipeId: "alphaMask", + action: "popMaskEnd", + mask, + canBundle: false + }); + } + execute(instruction) { + const renderer = this._renderer; + const renderMask = instruction.mask.renderMaskToTexture; + if (instruction.action === "pushMaskBegin") { + const filterEffect = BigPool.get(AlphaMaskEffect); + if (renderMask) { + instruction.mask.mask.measurable = true; + const bounds = getGlobalBounds(instruction.mask.mask, true, tempBounds$1); + instruction.mask.mask.measurable = false; + bounds.ceil(); + const filterTexture = TexturePool.getOptimalTexture( + bounds.width, + bounds.height, + 1, + false + ); + renderer.renderTarget.push(filterTexture, true); + renderer.globalUniforms.push({ + offset: bounds, + worldColor: 4294967295 + }); + const sprite = filterEffect.sprite; + sprite.texture = filterTexture; + sprite.worldTransform.tx = bounds.minX; + sprite.worldTransform.ty = bounds.minY; + this._activeMaskStage.push({ + filterEffect, + maskedContainer: instruction.maskedContainer, + filterTexture + }); + } else { + filterEffect.sprite = instruction.mask.mask; + this._activeMaskStage.push({ + filterEffect, + maskedContainer: instruction.maskedContainer + }); + } + } else if (instruction.action === "pushMaskEnd") { + const maskData = this._activeMaskStage[this._activeMaskStage.length - 1]; + if (renderMask) { + renderer.renderTarget.pop(); + renderer.globalUniforms.pop(); + } + renderer.filter.push({ + renderPipeId: "filter", + action: "pushFilter", + container: maskData.maskedContainer, + filterEffect: maskData.filterEffect, + canBundle: false + }); + } else if (instruction.action === "popMaskEnd") { + renderer.filter.pop(); + const maskData = this._activeMaskStage.pop(); + if (renderMask) { + TexturePool.returnTexture(maskData.filterTexture); + } + BigPool.return(maskData.filterEffect); + } + } + destroy() { + this._renderer = null; + this._activeMaskStage = null; + } +} +/** @ignore */ +AlphaMaskPipe.extension = { + type: [ + ExtensionType.WebGLPipes, + ExtensionType.WebGPUPipes, + ExtensionType.CanvasPipes + ], + name: "alphaMask" +}; + +"use strict"; +class ColorMaskPipe { + constructor(renderer) { + this._colorStack = []; + this._colorStackIndex = 0; + this._currentColor = 0; + this._renderer = renderer; + } + buildStart() { + this._colorStack[0] = 15; + this._colorStackIndex = 1; + this._currentColor = 15; + } + push(mask, _container, instructionSet) { + const renderer = this._renderer; + renderer.renderPipes.batch.break(instructionSet); + const colorStack = this._colorStack; + colorStack[this._colorStackIndex] = colorStack[this._colorStackIndex - 1] & mask.mask; + const currentColor = this._colorStack[this._colorStackIndex]; + if (currentColor !== this._currentColor) { + this._currentColor = currentColor; + instructionSet.add({ + renderPipeId: "colorMask", + colorMask: currentColor, + canBundle: false + }); + } + this._colorStackIndex++; + } + pop(_mask, _container, instructionSet) { + const renderer = this._renderer; + renderer.renderPipes.batch.break(instructionSet); + const colorStack = this._colorStack; + this._colorStackIndex--; + const currentColor = colorStack[this._colorStackIndex - 1]; + if (currentColor !== this._currentColor) { + this._currentColor = currentColor; + instructionSet.add({ + renderPipeId: "colorMask", + colorMask: currentColor, + canBundle: false + }); + } + } + execute(instruction) { + const renderer = this._renderer; + renderer.colorMask.setMask(instruction.colorMask); + } + destroy() { + this._colorStack = null; + } +} +/** @ignore */ +ColorMaskPipe.extension = { + type: [ + ExtensionType.WebGLPipes, + ExtensionType.WebGPUPipes, + ExtensionType.CanvasPipes + ], + name: "colorMask" +}; + +"use strict"; +class ScissorMask { + constructor(mask) { + this.priority = 0; + this.pipe = "scissorMask"; + this.mask = mask; + this.mask.renderable = false; + this.mask.measurable = false; + } + addBounds(bounds, skipUpdateTransform) { + addMaskBounds(this.mask, bounds, skipUpdateTransform); + } + addLocalBounds(bounds, localRoot) { + addMaskLocalBounds(this.mask, bounds, localRoot); + } + containsPoint(point, hitTestFn) { + const mask = this.mask; + return hitTestFn(mask, point); + } + reset() { + this.mask.measurable = true; + this.mask = null; + } + destroy() { + this.reset(); + } +} + +"use strict"; +class StencilMaskPipe { + constructor(renderer) { + // used when building and also when executing.. + this._maskStackHash = {}; + this._maskHash = /* @__PURE__ */ new WeakMap(); + this._renderer = renderer; + } + push(mask, _container, instructionSet) { + var _a, _b; + const effect = mask; + const renderer = this._renderer; + renderer.renderPipes.batch.break(instructionSet); + renderer.renderPipes.blendMode.setBlendMode(effect.mask, "none", instructionSet); + instructionSet.add({ + renderPipeId: "stencilMask", + action: "pushMaskBegin", + mask, + canBundle: false + }); + const maskContainer = effect.mask; + maskContainer.includeInBuild = true; + if (!this._maskHash.has(effect)) { + this._maskHash.set(effect, { + instructionsStart: 0, + instructionsLength: 0 + }); + } + const maskData = this._maskHash.get(effect); + maskData.instructionsStart = instructionSet.instructionSize; + collectAllRenderables( + maskContainer, + instructionSet, + renderer.renderPipes + ); + maskContainer.includeInBuild = false; + renderer.renderPipes.batch.break(instructionSet); + instructionSet.add({ + renderPipeId: "stencilMask", + action: "pushMaskEnd", + mask, + canBundle: false + }); + const instructionsLength = instructionSet.instructionSize - maskData.instructionsStart - 1; + maskData.instructionsLength = instructionsLength; + const renderTargetUid = renderer.renderTarget.renderTarget.uid; + (_b = (_a = this._maskStackHash)[renderTargetUid]) != null ? _b : _a[renderTargetUid] = 0; + } + pop(mask, _container, instructionSet) { + const effect = mask; + const renderer = this._renderer; + renderer.renderPipes.batch.break(instructionSet); + renderer.renderPipes.blendMode.setBlendMode(effect.mask, "none", instructionSet); + instructionSet.add({ + renderPipeId: "stencilMask", + action: "popMaskBegin", + canBundle: false + }); + const maskData = this._maskHash.get(mask); + for (let i = 0; i < maskData.instructionsLength; i++) { + instructionSet.instructions[instructionSet.instructionSize++] = instructionSet.instructions[maskData.instructionsStart++]; + } + instructionSet.add({ + renderPipeId: "stencilMask", + action: "popMaskEnd", + canBundle: false + }); + } + execute(instruction) { + var _a, _b; + const renderer = this._renderer; + const renderTargetUid = renderer.renderTarget.renderTarget.uid; + let maskStackIndex = (_b = (_a = this._maskStackHash)[renderTargetUid]) != null ? _b : _a[renderTargetUid] = 0; + if (instruction.action === "pushMaskBegin") { + renderer.renderTarget.ensureDepthStencil(); + renderer.stencil.setStencilMode(STENCIL_MODES.RENDERING_MASK_ADD, maskStackIndex); + maskStackIndex++; + renderer.colorMask.setMask(0); + } else if (instruction.action === "pushMaskEnd") { + renderer.stencil.setStencilMode(STENCIL_MODES.MASK_ACTIVE, maskStackIndex); + renderer.colorMask.setMask(15); + } else if (instruction.action === "popMaskBegin") { + renderer.colorMask.setMask(0); + if (maskStackIndex !== 0) { + renderer.stencil.setStencilMode(STENCIL_MODES.RENDERING_MASK_REMOVE, maskStackIndex); + } else { + renderer.renderTarget.clear(null, CLEAR.STENCIL); + renderer.stencil.setStencilMode(STENCIL_MODES.DISABLED, maskStackIndex); + } + maskStackIndex--; + } else if (instruction.action === "popMaskEnd") { + renderer.stencil.setStencilMode(STENCIL_MODES.MASK_ACTIVE, maskStackIndex); + renderer.colorMask.setMask(15); + } + this._maskStackHash[renderTargetUid] = maskStackIndex; + } + destroy() { + this._renderer = null; + this._maskStackHash = null; + this._maskHash = null; + } +} +StencilMaskPipe.extension = { + type: [ + ExtensionType.WebGLPipes, + ExtensionType.WebGPUPipes, + ExtensionType.CanvasPipes + ], + name: "stencilMask" +}; + +"use strict"; +var BUFFER_TYPE = /* @__PURE__ */ ((BUFFER_TYPE2) => { + BUFFER_TYPE2[BUFFER_TYPE2["ELEMENT_ARRAY_BUFFER"] = 34963] = "ELEMENT_ARRAY_BUFFER"; + BUFFER_TYPE2[BUFFER_TYPE2["ARRAY_BUFFER"] = 34962] = "ARRAY_BUFFER"; + BUFFER_TYPE2[BUFFER_TYPE2["UNIFORM_BUFFER"] = 35345] = "UNIFORM_BUFFER"; + return BUFFER_TYPE2; +})(BUFFER_TYPE || {}); + +"use strict"; +class GlBuffer { + constructor(buffer, type) { + this.buffer = buffer || null; + this.updateID = -1; + this.byteLength = -1; + this.type = type; + } +} + +"use strict"; +class GlBufferSystem { + /** + * @param {Renderer} renderer - The renderer this System works for. + */ + constructor(renderer) { + this._gpuBuffers = /* @__PURE__ */ Object.create(null); + /** Cache keeping track of the base bound buffer bases */ + this._boundBufferBases = /* @__PURE__ */ Object.create(null); + this._renderer = renderer; + } + /** + * @ignore + */ + destroy() { + this._renderer = null; + this._gl = null; + this._gpuBuffers = null; + this._boundBufferBases = null; + } + /** Sets up the renderer context and necessary buffers. */ + contextChange() { + this._gpuBuffers = /* @__PURE__ */ Object.create(null); + this._gl = this._renderer.gl; + } + getGlBuffer(buffer) { + return this._gpuBuffers[buffer.uid] || this.createGLBuffer(buffer); + } + /** + * This binds specified buffer. On first run, it will create the webGL buffers for the context too + * @param buffer - the buffer to bind to the renderer + */ + bind(buffer) { + const { _gl: gl } = this; + const glBuffer = this.getGlBuffer(buffer); + gl.bindBuffer(glBuffer.type, glBuffer.buffer); + } + /** + * Binds an uniform buffer to at the given index. + * + * A cache is used so a buffer will not be bound again if already bound. + * @param buffer - the buffer to bind + * @param index - the base index to bind it to. + */ + bindBufferBase(buffer, index) { + const { _gl: gl } = this; + if (this._boundBufferBases[index] !== buffer) { + const glBuffer = this.getGlBuffer(buffer); + this._boundBufferBases[index] = buffer; + gl.bindBufferBase(gl.UNIFORM_BUFFER, index, glBuffer.buffer); + } + } + /** + * Binds a buffer whilst also binding its range. + * This will make the buffer start from the offset supplied rather than 0 when it is read. + * @param buffer - the buffer to bind + * @param index - the base index to bind at, defaults to 0 + * @param offset - the offset to bind at (this is blocks of 256). 0 = 0, 1 = 256, 2 = 512 etc + */ + bindBufferRange(buffer, index, offset) { + const { _gl: gl } = this; + offset = offset || 0; + const glBuffer = this.getGlBuffer(buffer); + gl.bindBufferRange(gl.UNIFORM_BUFFER, index || 0, glBuffer.buffer, offset * 256, 256); + } + /** + * Will ensure the data in the buffer is uploaded to the GPU. + * @param {Buffer} buffer - the buffer to update + */ + updateBuffer(buffer) { + const { _gl: gl } = this; + const glBuffer = this.getGlBuffer(buffer); + if (buffer._updateID === glBuffer.updateID) { + return glBuffer; + } + glBuffer.updateID = buffer._updateID; + gl.bindBuffer(glBuffer.type, glBuffer.buffer); + const data = buffer.data; + if (glBuffer.byteLength >= buffer.data.byteLength) { + gl.bufferSubData(glBuffer.type, 0, data, 0, buffer._updateSize / data.BYTES_PER_ELEMENT); + } else { + const drawType = buffer.descriptor.usage & BufferUsage.STATIC ? gl.STATIC_DRAW : gl.DYNAMIC_DRAW; + glBuffer.byteLength = data.byteLength; + gl.bufferData(glBuffer.type, data, drawType); + } + return glBuffer; + } + /** dispose all WebGL resources of all managed buffers */ + destroyAll() { + const gl = this._gl; + for (const id in this._gpuBuffers) { + gl.deleteBuffer(this._gpuBuffers[id].buffer); + } + this._gpuBuffers = /* @__PURE__ */ Object.create(null); + } + /** + * Disposes buffer + * @param {Buffer} buffer - buffer with data + * @param {boolean} [contextLost=false] - If context was lost, we suppress deleteVertexArray + */ + onBufferDestroy(buffer, contextLost) { + const glBuffer = this._gpuBuffers[buffer.uid]; + const gl = this._gl; + if (!contextLost) { + gl.deleteBuffer(glBuffer.buffer); + } + this._gpuBuffers[buffer.uid] = null; + } + /** + * creates and attaches a GLBuffer object tied to the current context. + * @param buffer + * @protected + */ + createGLBuffer(buffer) { + const { _gl: gl } = this; + let type = BUFFER_TYPE.ARRAY_BUFFER; + if (buffer.descriptor.usage & BufferUsage.INDEX) { + type = BUFFER_TYPE.ELEMENT_ARRAY_BUFFER; + } else if (buffer.descriptor.usage & BufferUsage.UNIFORM) { + type = BUFFER_TYPE.UNIFORM_BUFFER; + } + const glBuffer = new GlBuffer(gl.createBuffer(), type); + this._gpuBuffers[buffer.uid] = glBuffer; + buffer.on("destroy", this.onBufferDestroy, this); + return glBuffer; + } +} +/** @ignore */ +GlBufferSystem.extension = { + type: [ + ExtensionType.WebGLSystem + ], + name: "buffer" +}; + +"use strict"; +var __defProp$j = Object.defineProperty; +var __defProps$8 = Object.defineProperties; +var __getOwnPropDescs$8 = Object.getOwnPropertyDescriptors; +var __getOwnPropSymbols$j = Object.getOwnPropertySymbols; +var __hasOwnProp$j = Object.prototype.hasOwnProperty; +var __propIsEnum$j = Object.prototype.propertyIsEnumerable; +var __defNormalProp$j = (obj, key, value) => key in obj ? __defProp$j(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; +var __spreadValues$j = (a, b) => { + for (var prop in b || (b = {})) + if (__hasOwnProp$j.call(b, prop)) + __defNormalProp$j(a, prop, b[prop]); + if (__getOwnPropSymbols$j) + for (var prop of __getOwnPropSymbols$j(b)) { + if (__propIsEnum$j.call(b, prop)) + __defNormalProp$j(a, prop, b[prop]); + } + return a; +}; +var __spreadProps$8 = (a, b) => __defProps$8(a, __getOwnPropDescs$8(b)); +const _GlContextSystem = class _GlContextSystem { + /** @param renderer - The renderer this System works for. */ + constructor(renderer) { + /** + * Features supported by current renderer. + * @type {object} + * @readonly + */ + this.supports = { + /** Support for 32-bit indices buffer. */ + uint32Indices: true, + /** Support for UniformBufferObjects */ + uniformBufferObject: true, + /** Support for VertexArrayObjects */ + vertexArrayObject: true, + /** Support for SRGB texture format */ + srgbTextures: true, + /** Support for wrapping modes if a texture is non-power of two */ + nonPowOf2wrapping: true, + /** Support for MSAA (antialiasing of dynamic textures) */ + msaa: true, + /** Support for mipmaps if a texture is non-power of two */ + nonPowOf2mipmaps: true + }; + this._renderer = renderer; + this.extensions = /* @__PURE__ */ Object.create(null); + this.handleContextLost = this.handleContextLost.bind(this); + this.handleContextRestored = this.handleContextRestored.bind(this); + } + /** + * `true` if the context is lost + * @readonly + */ + get isLost() { + return !this.gl || this.gl.isContextLost(); + } + /** + * Handles the context change event. + * @param {WebGLRenderingContext} gl - New WebGL context. + */ + contextChange(gl) { + this.gl = gl; + this._renderer.gl = gl; + } + init(options) { + var _a, _b; + options = __spreadValues$j(__spreadValues$j({}, _GlContextSystem.defaultOptions), options); + if (options.context) { + this.initFromContext(options.context); + } else { + const alpha = this._renderer.background.alpha < 1; + const premultipliedAlpha = (_a = options.premultipliedAlpha) != null ? _a : true; + const antialias = options.antialias && !this._renderer.backBuffer.useBackBuffer; + this.createContext(options.preferWebGLVersion, { + alpha, + premultipliedAlpha, + antialias, + stencil: true, + preserveDrawingBuffer: options.preserveDrawingBuffer, + powerPreference: (_b = options.powerPreference) != null ? _b : "default" + }); + } + } + /** + * Initializes the context. + * @protected + * @param {WebGLRenderingContext} gl - WebGL context + */ + initFromContext(gl) { + this.gl = gl; + this.webGLVersion = gl instanceof DOMAdapter.get().getWebGLRenderingContext() ? 1 : 2; + this.getExtensions(); + this.validateContext(gl); + this._renderer.runners.contextChange.emit(gl); + const element = this._renderer.view.canvas; + element.addEventListener("webglcontextlost", this.handleContextLost, false); + element.addEventListener("webglcontextrestored", this.handleContextRestored, false); + } + /** + * Initialize from context options + * @protected + * @see https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/getContext + * @param preferWebGLVersion + * @param {object} options - context attributes + */ + createContext(preferWebGLVersion, options) { + let gl; + const canvas = this._renderer.view.canvas; + if (preferWebGLVersion === 2) { + gl = canvas.getContext("webgl2", options); + } + if (!gl) { + gl = canvas.getContext("webgl", options); + if (!gl) { + throw new Error("This browser does not support WebGL. Try using the canvas renderer"); + } + } + this.gl = gl; + this.initFromContext(this.gl); + } + /** Auto-populate the {@link GlContextSystem.extensions extensions}. */ + getExtensions() { + const { gl } = this; + const common = { + anisotropicFiltering: gl.getExtension("EXT_texture_filter_anisotropic"), + floatTextureLinear: gl.getExtension("OES_texture_float_linear"), + s3tc: gl.getExtension("WEBGL_compressed_texture_s3tc"), + s3tc_sRGB: gl.getExtension("WEBGL_compressed_texture_s3tc_srgb"), + // eslint-disable-line camelcase + etc: gl.getExtension("WEBGL_compressed_texture_etc"), + etc1: gl.getExtension("WEBGL_compressed_texture_etc1"), + pvrtc: gl.getExtension("WEBGL_compressed_texture_pvrtc") || gl.getExtension("WEBKIT_WEBGL_compressed_texture_pvrtc"), + atc: gl.getExtension("WEBGL_compressed_texture_atc"), + astc: gl.getExtension("WEBGL_compressed_texture_astc"), + bptc: gl.getExtension("EXT_texture_compression_bptc"), + rgtc: gl.getExtension("EXT_texture_compression_rgtc"), + loseContext: gl.getExtension("WEBGL_lose_context") + }; + if (this.webGLVersion === 1) { + this.extensions = __spreadProps$8(__spreadValues$j({}, common), { + drawBuffers: gl.getExtension("WEBGL_draw_buffers"), + depthTexture: gl.getExtension("WEBGL_depth_texture"), + vertexArrayObject: gl.getExtension("OES_vertex_array_object") || gl.getExtension("MOZ_OES_vertex_array_object") || gl.getExtension("WEBKIT_OES_vertex_array_object"), + uint32ElementIndex: gl.getExtension("OES_element_index_uint"), + // Floats and half-floats + floatTexture: gl.getExtension("OES_texture_float"), + floatTextureLinear: gl.getExtension("OES_texture_float_linear"), + textureHalfFloat: gl.getExtension("OES_texture_half_float"), + textureHalfFloatLinear: gl.getExtension("OES_texture_half_float_linear"), + vertexAttribDivisorANGLE: gl.getExtension("ANGLE_instanced_arrays"), + srgb: gl.getExtension("EXT_sRGB") + }); + } else { + this.extensions = __spreadProps$8(__spreadValues$j({}, common), { + colorBufferFloat: gl.getExtension("EXT_color_buffer_float") + }); + const provokeExt = gl.getExtension("WEBGL_provoking_vertex"); + if (provokeExt) { + provokeExt.provokingVertexWEBGL(provokeExt.FIRST_VERTEX_CONVENTION_WEBGL); + } + } + } + /** + * Handles a lost webgl context + * @param {WebGLContextEvent} event - The context lost event. + */ + handleContextLost(event) { + event.preventDefault(); + if (this._contextLossForced) { + this._contextLossForced = false; + setTimeout(() => { + var _a; + if (this.gl.isContextLost()) { + (_a = this.extensions.loseContext) == null ? void 0 : _a.restoreContext(); + } + }, 0); + } + } + /** Handles a restored webgl context. */ + handleContextRestored() { + this._renderer.runners.contextChange.emit(this.gl); + } + destroy() { + var _a; + const element = this._renderer.view.canvas; + this._renderer = null; + element.removeEventListener("webglcontextlost", this.handleContextLost); + element.removeEventListener("webglcontextrestored", this.handleContextRestored); + this.gl.useProgram(null); + (_a = this.extensions.loseContext) == null ? void 0 : _a.loseContext(); + } + /** + * this function can be called to force a webGL context loss + * this will release all resources on the GPU. + * Useful if you need to put Pixi to sleep, and save some GPU memory + * + * As soon as render is called - all resources will be created again. + */ + forceContextLoss() { + var _a; + (_a = this.extensions.loseContext) == null ? void 0 : _a.loseContext(); + this._contextLossForced = true; + } + /** + * Validate context. + * @param {WebGLRenderingContext} gl - Render context. + */ + validateContext(gl) { + const attributes = gl.getContextAttributes(); + if (attributes && !attributes.stencil) { + warn("Provided WebGL context does not have a stencil buffer, masks may not render correctly"); + } + const supports = this.supports; + const isWebGl2 = this.webGLVersion === 2; + const extensions = this.extensions; + supports.uint32Indices = isWebGl2 || !!extensions.uint32ElementIndex; + supports.uniformBufferObject = isWebGl2; + supports.vertexArrayObject = isWebGl2 || !!extensions.vertexArrayObject; + supports.srgbTextures = isWebGl2 || !!extensions.srgb; + supports.nonPowOf2wrapping = isWebGl2; + supports.nonPowOf2mipmaps = isWebGl2; + supports.msaa = isWebGl2; + if (!supports.uint32Indices) { + warn("Provided WebGL context does not support 32 index buffer, large scenes may not render correctly"); + } + } +}; +/** @ignore */ +_GlContextSystem.extension = { + type: [ + ExtensionType.WebGLSystem + ], + name: "context" +}; +/** The default options for the system. */ +_GlContextSystem.defaultOptions = { + /** + * {@link WebGLOptions.context} + * @default null + */ + context: null, + /** + * {@link WebGLOptions.premultipliedAlpha} + * @default true + */ + premultipliedAlpha: true, + /** + * {@link WebGLOptions.preserveDrawingBuffer} + * @default false + */ + preserveDrawingBuffer: false, + /** + * {@link WebGLOptions.powerPreference} + * @default default + */ + powerPreference: void 0, + /** + * {@link WebGLOptions.webGLVersion} + * @default 2 + */ + preferWebGLVersion: 2 +}; +let GlContextSystem = _GlContextSystem; + +"use strict"; + +"use strict"; + +"use strict"; +function ensureAttributes(geometry, extractedData) { + var _a, _b, _c, _d; + for (const i in geometry.attributes) { + const attribute = geometry.attributes[i]; + const attributeData = extractedData[i]; + if (attributeData) { + (_a = attribute.location) != null ? _a : attribute.location = attributeData.location; + (_b = attribute.format) != null ? _b : attribute.format = attributeData.format; + (_c = attribute.offset) != null ? _c : attribute.offset = attributeData.offset; + (_d = attribute.instance) != null ? _d : attribute.instance = attributeData.instance; + } else { + warn(`Attribute ${i} is not present in the shader, but is present in the geometry. Unable to infer attribute details.`); + } + } + ensureStartAndStride(geometry); +} +function ensureStartAndStride(geometry) { + var _a, _b; + const { buffers, attributes } = geometry; + const tempStride = {}; + const tempStart = {}; + for (const j in buffers) { + const buffer = buffers[j]; + tempStride[buffer.uid] = 0; + tempStart[buffer.uid] = 0; + } + for (const j in attributes) { + const attribute = attributes[j]; + tempStride[attribute.buffer.uid] += getAttributeInfoFromFormat(attribute.format).stride; + } + for (const j in attributes) { + const attribute = attributes[j]; + (_a = attribute.stride) != null ? _a : attribute.stride = tempStride[attribute.buffer.uid]; + (_b = attribute.start) != null ? _b : attribute.start = tempStart[attribute.buffer.uid]; + tempStart[attribute.buffer.uid] += getAttributeInfoFromFormat(attribute.format).stride; + } +} + +"use strict"; +var GL_FORMATS = /* @__PURE__ */ ((GL_FORMATS2) => { + GL_FORMATS2[GL_FORMATS2["RGBA"] = 6408] = "RGBA"; + GL_FORMATS2[GL_FORMATS2["RGB"] = 6407] = "RGB"; + GL_FORMATS2[GL_FORMATS2["RG"] = 33319] = "RG"; + GL_FORMATS2[GL_FORMATS2["RED"] = 6403] = "RED"; + GL_FORMATS2[GL_FORMATS2["RGBA_INTEGER"] = 36249] = "RGBA_INTEGER"; + GL_FORMATS2[GL_FORMATS2["RGB_INTEGER"] = 36248] = "RGB_INTEGER"; + GL_FORMATS2[GL_FORMATS2["RG_INTEGER"] = 33320] = "RG_INTEGER"; + GL_FORMATS2[GL_FORMATS2["RED_INTEGER"] = 36244] = "RED_INTEGER"; + GL_FORMATS2[GL_FORMATS2["ALPHA"] = 6406] = "ALPHA"; + GL_FORMATS2[GL_FORMATS2["LUMINANCE"] = 6409] = "LUMINANCE"; + GL_FORMATS2[GL_FORMATS2["LUMINANCE_ALPHA"] = 6410] = "LUMINANCE_ALPHA"; + GL_FORMATS2[GL_FORMATS2["DEPTH_COMPONENT"] = 6402] = "DEPTH_COMPONENT"; + GL_FORMATS2[GL_FORMATS2["DEPTH_STENCIL"] = 34041] = "DEPTH_STENCIL"; + return GL_FORMATS2; +})(GL_FORMATS || {}); +var GL_TARGETS = /* @__PURE__ */ ((GL_TARGETS2) => { + GL_TARGETS2[GL_TARGETS2["TEXTURE_2D"] = 3553] = "TEXTURE_2D"; + GL_TARGETS2[GL_TARGETS2["TEXTURE_CUBE_MAP"] = 34067] = "TEXTURE_CUBE_MAP"; + GL_TARGETS2[GL_TARGETS2["TEXTURE_2D_ARRAY"] = 35866] = "TEXTURE_2D_ARRAY"; + GL_TARGETS2[GL_TARGETS2["TEXTURE_CUBE_MAP_POSITIVE_X"] = 34069] = "TEXTURE_CUBE_MAP_POSITIVE_X"; + GL_TARGETS2[GL_TARGETS2["TEXTURE_CUBE_MAP_NEGATIVE_X"] = 34070] = "TEXTURE_CUBE_MAP_NEGATIVE_X"; + GL_TARGETS2[GL_TARGETS2["TEXTURE_CUBE_MAP_POSITIVE_Y"] = 34071] = "TEXTURE_CUBE_MAP_POSITIVE_Y"; + GL_TARGETS2[GL_TARGETS2["TEXTURE_CUBE_MAP_NEGATIVE_Y"] = 34072] = "TEXTURE_CUBE_MAP_NEGATIVE_Y"; + GL_TARGETS2[GL_TARGETS2["TEXTURE_CUBE_MAP_POSITIVE_Z"] = 34073] = "TEXTURE_CUBE_MAP_POSITIVE_Z"; + GL_TARGETS2[GL_TARGETS2["TEXTURE_CUBE_MAP_NEGATIVE_Z"] = 34074] = "TEXTURE_CUBE_MAP_NEGATIVE_Z"; + return GL_TARGETS2; +})(GL_TARGETS || {}); +var GL_WRAP_MODES = /* @__PURE__ */ ((GL_WRAP_MODES2) => { + GL_WRAP_MODES2[GL_WRAP_MODES2["CLAMP"] = 33071] = "CLAMP"; + GL_WRAP_MODES2[GL_WRAP_MODES2["REPEAT"] = 10497] = "REPEAT"; + GL_WRAP_MODES2[GL_WRAP_MODES2["MIRRORED_REPEAT"] = 33648] = "MIRRORED_REPEAT"; + return GL_WRAP_MODES2; +})(GL_WRAP_MODES || {}); +var GL_TYPES = /* @__PURE__ */ ((GL_TYPES2) => { + GL_TYPES2[GL_TYPES2["UNSIGNED_BYTE"] = 5121] = "UNSIGNED_BYTE"; + GL_TYPES2[GL_TYPES2["UNSIGNED_SHORT"] = 5123] = "UNSIGNED_SHORT"; + GL_TYPES2[GL_TYPES2["UNSIGNED_SHORT_5_6_5"] = 33635] = "UNSIGNED_SHORT_5_6_5"; + GL_TYPES2[GL_TYPES2["UNSIGNED_SHORT_4_4_4_4"] = 32819] = "UNSIGNED_SHORT_4_4_4_4"; + GL_TYPES2[GL_TYPES2["UNSIGNED_SHORT_5_5_5_1"] = 32820] = "UNSIGNED_SHORT_5_5_5_1"; + GL_TYPES2[GL_TYPES2["UNSIGNED_INT"] = 5125] = "UNSIGNED_INT"; + GL_TYPES2[GL_TYPES2["UNSIGNED_INT_10F_11F_11F_REV"] = 35899] = "UNSIGNED_INT_10F_11F_11F_REV"; + GL_TYPES2[GL_TYPES2["UNSIGNED_INT_2_10_10_10_REV"] = 33640] = "UNSIGNED_INT_2_10_10_10_REV"; + GL_TYPES2[GL_TYPES2["UNSIGNED_INT_24_8"] = 34042] = "UNSIGNED_INT_24_8"; + GL_TYPES2[GL_TYPES2["UNSIGNED_INT_5_9_9_9_REV"] = 35902] = "UNSIGNED_INT_5_9_9_9_REV"; + GL_TYPES2[GL_TYPES2["BYTE"] = 5120] = "BYTE"; + GL_TYPES2[GL_TYPES2["SHORT"] = 5122] = "SHORT"; + GL_TYPES2[GL_TYPES2["INT"] = 5124] = "INT"; + GL_TYPES2[GL_TYPES2["FLOAT"] = 5126] = "FLOAT"; + GL_TYPES2[GL_TYPES2["FLOAT_32_UNSIGNED_INT_24_8_REV"] = 36269] = "FLOAT_32_UNSIGNED_INT_24_8_REV"; + GL_TYPES2[GL_TYPES2["HALF_FLOAT"] = 36193] = "HALF_FLOAT"; + return GL_TYPES2; +})(GL_TYPES || {}); + +"use strict"; +const infoMap = { + uint8x2: GL_TYPES.UNSIGNED_BYTE, + uint8x4: GL_TYPES.UNSIGNED_BYTE, + sint8x2: GL_TYPES.BYTE, + sint8x4: GL_TYPES.BYTE, + unorm8x2: GL_TYPES.UNSIGNED_BYTE, + unorm8x4: GL_TYPES.UNSIGNED_BYTE, + snorm8x2: GL_TYPES.BYTE, + snorm8x4: GL_TYPES.BYTE, + uint16x2: GL_TYPES.UNSIGNED_SHORT, + uint16x4: GL_TYPES.UNSIGNED_SHORT, + sint16x2: GL_TYPES.SHORT, + sint16x4: GL_TYPES.SHORT, + unorm16x2: GL_TYPES.UNSIGNED_SHORT, + unorm16x4: GL_TYPES.UNSIGNED_SHORT, + snorm16x2: GL_TYPES.SHORT, + snorm16x4: GL_TYPES.SHORT, + float16x2: GL_TYPES.HALF_FLOAT, + float16x4: GL_TYPES.HALF_FLOAT, + float32: GL_TYPES.FLOAT, + float32x2: GL_TYPES.FLOAT, + float32x3: GL_TYPES.FLOAT, + float32x4: GL_TYPES.FLOAT, + uint32: GL_TYPES.UNSIGNED_INT, + uint32x2: GL_TYPES.UNSIGNED_INT, + uint32x3: GL_TYPES.UNSIGNED_INT, + uint32x4: GL_TYPES.UNSIGNED_INT, + sint32: GL_TYPES.INT, + sint32x2: GL_TYPES.INT, + sint32x3: GL_TYPES.INT, + sint32x4: GL_TYPES.INT +}; +function getGlTypeFromFormat(format) { + var _a; + return (_a = infoMap[format]) != null ? _a : infoMap.float32; +} + +"use strict"; +const topologyToGlMap = { + "point-list": 0, + "line-list": 1, + "line-strip": 3, + "triangle-list": 4, + "triangle-strip": 5 +}; +class GlGeometrySystem { + /** @param renderer - The renderer this System works for. */ + constructor(renderer) { + this._geometryVaoHash = /* @__PURE__ */ Object.create(null); + this._renderer = renderer; + this._activeGeometry = null; + this._activeVao = null; + this.hasVao = true; + this.hasInstance = true; + } + /** Sets up the renderer context and necessary buffers. */ + contextChange() { + const gl = this.gl = this._renderer.gl; + if (!this._renderer.context.supports.vertexArrayObject) { + throw new Error("[PixiJS] Vertex Array Objects are not supported on this device"); + } + const nativeVaoExtension = this._renderer.context.extensions.vertexArrayObject; + if (nativeVaoExtension) { + gl.createVertexArray = () => nativeVaoExtension.createVertexArrayOES(); + gl.bindVertexArray = (vao) => nativeVaoExtension.bindVertexArrayOES(vao); + gl.deleteVertexArray = (vao) => nativeVaoExtension.deleteVertexArrayOES(vao); + } + const nativeInstancedExtension = this._renderer.context.extensions.vertexAttribDivisorANGLE; + if (nativeInstancedExtension) { + gl.drawArraysInstanced = (a, b, c, d) => { + nativeInstancedExtension.drawArraysInstancedANGLE(a, b, c, d); + }; + gl.drawElementsInstanced = (a, b, c, d, e) => { + nativeInstancedExtension.drawElementsInstancedANGLE(a, b, c, d, e); + }; + gl.vertexAttribDivisor = (a, b) => nativeInstancedExtension.vertexAttribDivisorANGLE(a, b); + } + this._activeGeometry = null; + this._activeVao = null; + this._geometryVaoHash = /* @__PURE__ */ Object.create(null); + } + /** + * Binds geometry so that is can be drawn. Creating a Vao if required + * @param geometry - Instance of geometry to bind. + * @param program - Instance of program to use vao for. + */ + bind(geometry, program) { + const gl = this.gl; + this._activeGeometry = geometry; + const vao = this.getVao(geometry, program); + if (this._activeVao !== vao) { + this._activeVao = vao; + gl.bindVertexArray(vao); + } + this.updateBuffers(); + } + /** Reset and unbind any active VAO and geometry. */ + reset() { + this.unbind(); + } + /** Update buffers of the currently bound geometry. */ + updateBuffers() { + const geometry = this._activeGeometry; + const bufferSystem = this._renderer.buffer; + for (let i = 0; i < geometry.buffers.length; i++) { + const buffer = geometry.buffers[i]; + bufferSystem.updateBuffer(buffer); + } + } + /** + * Check compatibility between a geometry and a program + * @param geometry - Geometry instance. + * @param program - Program instance. + */ + checkCompatibility(geometry, program) { + const geometryAttributes = geometry.attributes; + const shaderAttributes = program._attributeData; + for (const j in shaderAttributes) { + if (!geometryAttributes[j]) { + throw new Error(`shader and geometry incompatible, geometry missing the "${j}" attribute`); + } + } + } + /** + * Takes a geometry and program and generates a unique signature for them. + * @param geometry - To get signature from. + * @param program - To test geometry against. + * @returns - Unique signature of the geometry and program + */ + getSignature(geometry, program) { + const attribs = geometry.attributes; + const shaderAttributes = program._attributeData; + const strings = ["g", geometry.uid]; + for (const i in attribs) { + if (shaderAttributes[i]) { + strings.push(i, shaderAttributes[i].location); + } + } + return strings.join("-"); + } + getVao(geometry, program) { + var _a; + return ((_a = this._geometryVaoHash[geometry.uid]) == null ? void 0 : _a[program._key]) || this.initGeometryVao(geometry, program); + } + /** + * Creates or gets Vao with the same structure as the geometry and stores it on the geometry. + * If vao is created, it is bound automatically. We use a shader to infer what and how to set up the + * attribute locations. + * @param geometry - Instance of geometry to to generate Vao for. + * @param program + * @param _incRefCount - Increment refCount of all geometry buffers. + */ + initGeometryVao(geometry, program, _incRefCount = true) { + const gl = this._renderer.gl; + const bufferSystem = this._renderer.buffer; + this._renderer.shader._getProgramData(program); + this.checkCompatibility(geometry, program); + const signature = this.getSignature(geometry, program); + if (!this._geometryVaoHash[geometry.uid]) { + this._geometryVaoHash[geometry.uid] = /* @__PURE__ */ Object.create(null); + geometry.on("destroy", this.onGeometryDestroy, this); + } + const vaoObjectHash = this._geometryVaoHash[geometry.uid]; + let vao = vaoObjectHash[signature]; + if (vao) { + vaoObjectHash[program._key] = vao; + return vao; + } + ensureAttributes(geometry, program._attributeData); + const buffers = geometry.buffers; + vao = gl.createVertexArray(); + gl.bindVertexArray(vao); + for (let i = 0; i < buffers.length; i++) { + const buffer = buffers[i]; + bufferSystem.bind(buffer); + } + this.activateVao(geometry, program); + vaoObjectHash[program._key] = vao; + vaoObjectHash[signature] = vao; + gl.bindVertexArray(null); + return vao; + } + /** + * Disposes geometry. + * @param geometry - Geometry with buffers. Only VAO will be disposed + * @param [contextLost=false] - If context was lost, we suppress deleteVertexArray + */ + onGeometryDestroy(geometry, contextLost) { + const vaoObjectHash = this._geometryVaoHash[geometry.uid]; + const gl = this.gl; + if (vaoObjectHash) { + if (contextLost) { + for (const i in vaoObjectHash) { + if (this._activeVao !== vaoObjectHash[i]) { + this.unbind(); + } + gl.deleteVertexArray(vaoObjectHash[i]); + } + } + this._geometryVaoHash[geometry.uid] = null; + } + } + /** + * Dispose all WebGL resources of all managed geometries. + * @param [contextLost=false] - If context was lost, we suppress `gl.delete` calls + */ + destroyAll(contextLost = false) { + const gl = this.gl; + for (const i in this._geometryVaoHash) { + if (contextLost) { + for (const j in this._geometryVaoHash[i]) { + const vaoObjectHash = this._geometryVaoHash[i]; + if (this._activeVao !== vaoObjectHash) { + this.unbind(); + } + gl.deleteVertexArray(vaoObjectHash[j]); + } + } + this._geometryVaoHash[i] = null; + } + } + /** + * Activate vertex array object. + * @param geometry - Geometry instance. + * @param program - Shader program instance. + */ + activateVao(geometry, program) { + var _a; + const gl = this._renderer.gl; + const bufferSystem = this._renderer.buffer; + const attributes = geometry.attributes; + if (geometry.indexBuffer) { + bufferSystem.bind(geometry.indexBuffer); + } + let lastBuffer = null; + for (const j in attributes) { + const attribute = attributes[j]; + const buffer = attribute.buffer; + const glBuffer = bufferSystem.getGlBuffer(buffer); + const programAttrib = program._attributeData[j]; + if (programAttrib) { + if (lastBuffer !== glBuffer) { + bufferSystem.bind(buffer); + lastBuffer = glBuffer; + } + const location = attribute.location; + gl.enableVertexAttribArray(location); + const attributeInfo = getAttributeInfoFromFormat(attribute.format); + const type = getGlTypeFromFormat(attribute.format); + if (((_a = programAttrib.format) == null ? void 0 : _a.substring(1, 4)) === "int") { + gl.vertexAttribIPointer( + location, + attributeInfo.size, + type, + attribute.stride, + attribute.offset + ); + } else { + gl.vertexAttribPointer( + location, + attributeInfo.size, + type, + attributeInfo.normalised, + attribute.stride, + attribute.offset + ); + } + if (attribute.instance) { + if (this.hasInstance) { + gl.vertexAttribDivisor(location, 1); + } else { + throw new Error("geometry error, GPU Instancing is not supported on this device"); + } + } + } + } + } + /** + * Draws the currently bound geometry. + * @param topology - The type primitive to render. + * @param size - The number of elements to be rendered. If not specified, all vertices after the + * starting vertex will be drawn. + * @param start - The starting vertex in the geometry to start drawing from. If not specified, + * drawing will start from the first vertex. + * @param instanceCount - The number of instances of the set of elements to execute. If not specified, + * all instances will be drawn. + */ + draw(topology, size, start, instanceCount) { + const { gl } = this._renderer; + const geometry = this._activeGeometry; + const glTopology = topologyToGlMap[geometry.topology || topology]; + instanceCount || (instanceCount = geometry.instanceCount); + if (geometry.indexBuffer) { + const byteSize = geometry.indexBuffer.data.BYTES_PER_ELEMENT; + const glType = byteSize === 2 ? gl.UNSIGNED_SHORT : gl.UNSIGNED_INT; + if (instanceCount > 1) { + gl.drawElementsInstanced(glTopology, size || geometry.indexBuffer.data.length, glType, (start || 0) * byteSize, instanceCount); + } else { + gl.drawElements(glTopology, size || geometry.indexBuffer.data.length, glType, (start || 0) * byteSize); + } + } else if (instanceCount > 1) { + gl.drawArraysInstanced(glTopology, start || 0, size || geometry.getSize(), instanceCount); + } else { + gl.drawArrays(glTopology, start || 0, size || geometry.getSize()); + } + return this; + } + /** Unbind/reset everything. */ + unbind() { + this.gl.bindVertexArray(null); + this._activeVao = null; + this._activeGeometry = null; + } + destroy() { + this._renderer = null; + this.gl = null; + this._activeVao = null; + this._activeGeometry = null; + } +} +/** @ignore */ +GlGeometrySystem.extension = { + type: [ + ExtensionType.WebGLSystem + ], + name: "geometry" +}; + +"use strict"; +var __defProp$i = Object.defineProperty; +var __getOwnPropSymbols$i = Object.getOwnPropertySymbols; +var __hasOwnProp$i = Object.prototype.hasOwnProperty; +var __propIsEnum$i = Object.prototype.propertyIsEnumerable; +var __defNormalProp$i = (obj, key, value) => key in obj ? __defProp$i(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; +var __spreadValues$i = (a, b) => { + for (var prop in b || (b = {})) + if (__hasOwnProp$i.call(b, prop)) + __defNormalProp$i(a, prop, b[prop]); + if (__getOwnPropSymbols$i) + for (var prop of __getOwnPropSymbols$i(b)) { + if (__propIsEnum$i.call(b, prop)) + __defNormalProp$i(a, prop, b[prop]); + } + return a; +}; +const bigTriangleGeometry = new Geometry({ + attributes: { + aPosition: [ + -1, + -1, + // Bottom left corner + 3, + -1, + // Bottom right corner, extending beyond right edge + -1, + 3 + // Top left corner, extending beyond top edge + ] + } +}); +const _GlBackBufferSystem = class _GlBackBufferSystem { + constructor(renderer) { + /** if true, the back buffer is used */ + this.useBackBuffer = false; + this._useBackBufferThisRender = false; + this._renderer = renderer; + } + init(options = {}) { + const { useBackBuffer, antialias } = __spreadValues$i(__spreadValues$i({}, _GlBackBufferSystem.defaultOptions), options); + this.useBackBuffer = useBackBuffer; + this._antialias = antialias; + if (!this._renderer.context.supports.msaa) { + warn("antialiasing, is not supported on when using the back buffer"); + this._antialias = false; + } + this._state = State.for2d(); + const bigTriangleProgram = new GlProgram({ + vertex: ` attribute vec2 aPosition; out vec2 vUv; @@ -1679,7 +33893,8 @@ fn setSaturation(c: vec3, s: f32) -> vec3 { // flip dem UVs vUv.y = 1.0 - vUv.y; - }`,fragment:` + }`, + fragment: ` in vec2 vUv; out vec4 finalColor; @@ -1687,7 +33902,421 @@ fn setSaturation(c: vec3, s: f32) -> vec3 { void main() { finalColor = texture(uTexture, vUv); - }`,name:"big-triangle"});this._bigTriangleShader=new St({glProgram:i,resources:{uTexture:A.WHITE.source}})}renderStart(t){const e=this._renderer.renderTarget.getRenderTarget(t.target);if(this._useBackBufferThisRender=this.useBackBuffer&&!!e.isRoot,this._useBackBufferThisRender){const s=this._renderer.renderTarget.getRenderTarget(t.target);this._targetTexture=s.colorTexture,t.target=this._getBackBufferTexture(s.colorTexture)}}renderEnd(){this._presentBackBuffer()}_presentBackBuffer(){const t=this._renderer;t.renderTarget.finishRenderPass(),this._useBackBufferThisRender&&(t.renderTarget.bind(this._targetTexture,!1),this._bigTriangleShader.resources.uTexture=this._backBufferTexture.source,t.encoder.draw({geometry:n2,shader:this._bigTriangleShader,state:this._state}))}_getBackBufferTexture(t){return this._backBufferTexture=this._backBufferTexture||new A({source:new et({width:t.width,height:t.height,resolution:t._resolution,antialias:this._antialias})}),this._backBufferTexture.source.resize(t.width,t.height,t._resolution),this._backBufferTexture}destroy(){this._backBufferTexture&&(this._backBufferTexture.destroy(),this._backBufferTexture=null)}};Fa.extension={type:[v.WebGLSystem],name:"backBuffer",priority:1},Fa.defaultOptions={useBackBuffer:!1};let hg=Fa;class Da{constructor(t){this._colorMaskCache=15,this._renderer=t}setMask(t){this._colorMaskCache!==t&&(this._colorMaskCache=t,this._renderer.gl.colorMask(!!(t&8),!!(t&4),!!(t&2),!!(t&1)))}}Da.extension={type:[v.WebGLSystem],name:"colorMask"};class Ua{constructor(t){this.commandFinished=Promise.resolve(),this._renderer=t}setGeometry(t,e){this._renderer.geometry.bind(t,e.glProgram)}finishRenderPass(){}draw(t){const e=this._renderer,{geometry:s,shader:i,state:n,skipSync:o,topology:a,size:u,start:l,instanceCount:h}=t;e.shader.bind(i,o),e.geometry.bind(s,e.shader._activeProgram),n&&e.state.set(n),e.geometry.draw(a,u,l,h!=null?h:s.instanceCount)}destroy(){this._renderer=null}}Ua.extension={type:[v.WebGLSystem],name:"encoder"};class cg{constructor(){this.width=-1,this.height=-1,this.msaa=!1,this.msaaRenderBuffer=[]}}const re=[];re[st.NONE]=void 0,re[st.DISABLED]={stencilWriteMask:0,stencilReadMask:0},re[st.RENDERING_MASK_ADD]={stencilFront:{compare:"equal",passOp:"increment-clamp"},stencilBack:{compare:"equal",passOp:"increment-clamp"}},re[st.RENDERING_MASK_REMOVE]={stencilFront:{compare:"equal",passOp:"decrement-clamp"},stencilBack:{compare:"equal",passOp:"decrement-clamp"}},re[st.MASK_ACTIVE]={stencilWriteMask:0,stencilFront:{compare:"equal",passOp:"keep"},stencilBack:{compare:"equal",passOp:"keep"}};class ka{constructor(t){this._stencilCache={enabled:!1,stencilReference:0,stencilMode:st.NONE},this._renderTargetStencilState=Object.create(null),t.renderTarget.onRenderTargetChange.add(this)}contextChange(t){this._gl=t,this._comparisonFuncMapping={always:t.ALWAYS,never:t.NEVER,equal:t.EQUAL,"not-equal":t.NOTEQUAL,less:t.LESS,"less-equal":t.LEQUAL,greater:t.GREATER,"greater-equal":t.GEQUAL},this._stencilOpsMapping={keep:t.KEEP,zero:t.ZERO,replace:t.REPLACE,invert:t.INVERT,"increment-clamp":t.INCR,"decrement-clamp":t.DECR,"increment-wrap":t.INCR_WRAP,"decrement-wrap":t.DECR_WRAP},this._stencilCache.enabled=!1,this._stencilCache.stencilMode=st.NONE,this._stencilCache.stencilReference=0}onRenderTargetChange(t){if(this._activeRenderTarget===t)return;this._activeRenderTarget=t;let e=this._renderTargetStencilState[t.uid];e||(e=this._renderTargetStencilState[t.uid]={stencilMode:st.DISABLED,stencilReference:0}),this.setStencilMode(e.stencilMode,e.stencilReference)}setStencilMode(t,e){const s=this._renderTargetStencilState[this._activeRenderTarget.uid],i=this._gl,n=re[t],o=this._stencilCache;if(s.stencilMode=t,s.stencilReference=e,t===st.DISABLED){this._stencilCache.enabled&&(this._stencilCache.enabled=!1,i.disable(i.STENCIL_TEST));return}this._stencilCache.enabled||(this._stencilCache.enabled=!0,i.enable(i.STENCIL_TEST)),(t!==o.stencilMode||o.stencilReference!==e)&&(o.stencilMode=t,o.stencilReference=e,i.stencilFunc(this._comparisonFuncMapping[n.stencilBack.compare],e,255),i.stencilOp(i.KEEP,i.KEEP,this._stencilOpsMapping[n.stencilBack.passOp]))}}ka.extension={type:[v.WebGLSystem],name:"stencil"};class La{constructor(t){this._syncFunctionHash=Object.create(null),this._adaptor=t,this._systemCheck()}_systemCheck(){if(!Yo())throw new Error("Current environment does not allow unsafe-eval, please use pixi.js/unsafe-eval module to enable support.")}ensureUniformGroup(t){const e=this.getUniformGroupData(t);t.buffer||(t.buffer=new _t({data:new Float32Array(e.layout.size/4),usage:$.UNIFORM|$.COPY_DST}))}getUniformGroupData(t){return this._syncFunctionHash[t._signature]||this._initUniformGroup(t)}_initUniformGroup(t){const e=t._signature;let s=this._syncFunctionHash[e];if(!s){const i=Object.keys(t.uniformStructures).map(a=>t.uniformStructures[a]),n=this._adaptor.createUboElements(i),o=this._generateUboSync(n.uboElements);s=this._syncFunctionHash[e]={layout:n,syncFunction:o}}return this._syncFunctionHash[e]}_generateUboSync(t){return this._adaptor.generateUboSync(t)}syncUniformGroup(t,e,s){const i=this.getUniformGroupData(t);return t.buffer||(t.buffer=new _t({data:new Float32Array(i.layout.size/4),usage:$.UNIFORM|$.COPY_DST})),e||(e=t.buffer.data),s||(s=0),i.syncFunction(t.uniforms,e,s),!0}updateUniformGroup(t){if(t.isStatic&&!t._dirtyId)return!1;t._dirtyId=0;const e=this.syncUniformGroup(t);return t.buffer.update(),e}destroy(){this._syncFunctionHash=null}}const $a={f32:4,"vec2":8,"vec3":12,"vec4":16,"mat2x2":32,"mat3x3":48,"mat4x4":64};function dg(r){const t=r.map(n=>({data:n,offset:0,size:0}));let e=0,s=0,i=0;for(let n=0;n1&&(e=Math.max(e,16)*o.data.size),o.size=e,s%e!==0&&s<16){const a=s%e%16;s+=a,i+=a}s+e>16?(i=Math.ceil(i/16)*16,o.offset=i,i+=e,s=e):(o.offset=i,s+=e,i+=e)}return i=Math.ceil(i/16)*16,{uboElements:t,size:i}}const se=[{type:"mat3x3",test:r=>r.value.a!==void 0,ubo:` + }`, + name: "big-triangle" + }); + this._bigTriangleShader = new Shader({ + glProgram: bigTriangleProgram, + resources: { + uTexture: Texture.WHITE.source + } + }); + } + /** + * This is called before the RenderTargetSystem is started. This is where + * we replace the target with the back buffer if required. + * @param options - The options for this render. + */ + renderStart(options) { + const renderTarget = this._renderer.renderTarget.getRenderTarget(options.target); + this._useBackBufferThisRender = this.useBackBuffer && !!renderTarget.isRoot; + if (this._useBackBufferThisRender) { + const renderTarget2 = this._renderer.renderTarget.getRenderTarget(options.target); + this._targetTexture = renderTarget2.colorTexture; + options.target = this._getBackBufferTexture(renderTarget2.colorTexture); + } + } + renderEnd() { + this._presentBackBuffer(); + } + _presentBackBuffer() { + const renderer = this._renderer; + renderer.renderTarget.finishRenderPass(); + if (!this._useBackBufferThisRender) + return; + renderer.renderTarget.bind(this._targetTexture, false); + this._bigTriangleShader.resources.uTexture = this._backBufferTexture.source; + renderer.encoder.draw({ + geometry: bigTriangleGeometry, + shader: this._bigTriangleShader, + state: this._state + }); + } + _getBackBufferTexture(targetSourceTexture) { + this._backBufferTexture = this._backBufferTexture || new Texture({ + source: new TextureSource({ + width: targetSourceTexture.width, + height: targetSourceTexture.height, + resolution: targetSourceTexture._resolution, + antialias: this._antialias + }) + }); + this._backBufferTexture.source.resize( + targetSourceTexture.width, + targetSourceTexture.height, + targetSourceTexture._resolution + ); + return this._backBufferTexture; + } + /** destroys the back buffer */ + destroy() { + if (this._backBufferTexture) { + this._backBufferTexture.destroy(); + this._backBufferTexture = null; + } + } +}; +/** @ignore */ +_GlBackBufferSystem.extension = { + type: [ + ExtensionType.WebGLSystem + ], + name: "backBuffer", + priority: 1 +}; +/** default options for the back buffer system */ +_GlBackBufferSystem.defaultOptions = { + /** if true will use the back buffer where required */ + useBackBuffer: false +}; +let GlBackBufferSystem = _GlBackBufferSystem; + +"use strict"; +class GlColorMaskSystem { + constructor(renderer) { + this._colorMaskCache = 15; + this._renderer = renderer; + } + setMask(colorMask) { + if (this._colorMaskCache === colorMask) + return; + this._colorMaskCache = colorMask; + this._renderer.gl.colorMask( + !!(colorMask & 8), + !!(colorMask & 4), + !!(colorMask & 2), + !!(colorMask & 1) + ); + } +} +/** @ignore */ +GlColorMaskSystem.extension = { + type: [ + ExtensionType.WebGLSystem + ], + name: "colorMask" +}; + +"use strict"; +class GlEncoderSystem { + constructor(renderer) { + this.commandFinished = Promise.resolve(); + this._renderer = renderer; + } + setGeometry(geometry, shader) { + this._renderer.geometry.bind(geometry, shader.glProgram); + } + finishRenderPass() { + } + draw(options) { + const renderer = this._renderer; + const { geometry, shader, state, skipSync, topology: type, size, start, instanceCount } = options; + renderer.shader.bind(shader, skipSync); + renderer.geometry.bind(geometry, renderer.shader._activeProgram); + if (state) { + renderer.state.set(state); + } + renderer.geometry.draw(type, size, start, instanceCount != null ? instanceCount : geometry.instanceCount); + } + destroy() { + this._renderer = null; + } +} +/** @ignore */ +GlEncoderSystem.extension = { + type: [ + ExtensionType.WebGLSystem + ], + name: "encoder" +}; + +"use strict"; +class GlRenderTarget { + constructor() { + this.width = -1; + this.height = -1; + this.msaa = false; + this.msaaRenderBuffer = []; + } +} + +"use strict"; +const GpuStencilModesToPixi = []; +GpuStencilModesToPixi[STENCIL_MODES.NONE] = void 0; +GpuStencilModesToPixi[STENCIL_MODES.DISABLED] = { + stencilWriteMask: 0, + stencilReadMask: 0 +}; +GpuStencilModesToPixi[STENCIL_MODES.RENDERING_MASK_ADD] = { + stencilFront: { + compare: "equal", + passOp: "increment-clamp" + }, + stencilBack: { + compare: "equal", + passOp: "increment-clamp" + } +}; +GpuStencilModesToPixi[STENCIL_MODES.RENDERING_MASK_REMOVE] = { + stencilFront: { + compare: "equal", + passOp: "decrement-clamp" + }, + stencilBack: { + compare: "equal", + passOp: "decrement-clamp" + } +}; +GpuStencilModesToPixi[STENCIL_MODES.MASK_ACTIVE] = { + stencilWriteMask: 0, + stencilFront: { + compare: "equal", + passOp: "keep" + }, + stencilBack: { + compare: "equal", + passOp: "keep" + } +}; + +"use strict"; +class GlStencilSystem { + constructor(renderer) { + this._stencilCache = { + enabled: false, + stencilReference: 0, + stencilMode: STENCIL_MODES.NONE + }; + this._renderTargetStencilState = /* @__PURE__ */ Object.create(null); + renderer.renderTarget.onRenderTargetChange.add(this); + } + contextChange(gl) { + this._gl = gl; + this._comparisonFuncMapping = { + always: gl.ALWAYS, + never: gl.NEVER, + equal: gl.EQUAL, + "not-equal": gl.NOTEQUAL, + less: gl.LESS, + "less-equal": gl.LEQUAL, + greater: gl.GREATER, + "greater-equal": gl.GEQUAL + }; + this._stencilOpsMapping = { + keep: gl.KEEP, + zero: gl.ZERO, + replace: gl.REPLACE, + invert: gl.INVERT, + "increment-clamp": gl.INCR, + "decrement-clamp": gl.DECR, + "increment-wrap": gl.INCR_WRAP, + "decrement-wrap": gl.DECR_WRAP + }; + this._stencilCache.enabled = false; + this._stencilCache.stencilMode = STENCIL_MODES.NONE; + this._stencilCache.stencilReference = 0; + } + onRenderTargetChange(renderTarget) { + if (this._activeRenderTarget === renderTarget) + return; + this._activeRenderTarget = renderTarget; + let stencilState = this._renderTargetStencilState[renderTarget.uid]; + if (!stencilState) { + stencilState = this._renderTargetStencilState[renderTarget.uid] = { + stencilMode: STENCIL_MODES.DISABLED, + stencilReference: 0 + }; + } + this.setStencilMode(stencilState.stencilMode, stencilState.stencilReference); + } + setStencilMode(stencilMode, stencilReference) { + const stencilState = this._renderTargetStencilState[this._activeRenderTarget.uid]; + const gl = this._gl; + const mode = GpuStencilModesToPixi[stencilMode]; + const _stencilCache = this._stencilCache; + stencilState.stencilMode = stencilMode; + stencilState.stencilReference = stencilReference; + if (stencilMode === STENCIL_MODES.DISABLED) { + if (this._stencilCache.enabled) { + this._stencilCache.enabled = false; + gl.disable(gl.STENCIL_TEST); + } + return; + } + if (!this._stencilCache.enabled) { + this._stencilCache.enabled = true; + gl.enable(gl.STENCIL_TEST); + } + if (stencilMode !== _stencilCache.stencilMode || _stencilCache.stencilReference !== stencilReference) { + _stencilCache.stencilMode = stencilMode; + _stencilCache.stencilReference = stencilReference; + gl.stencilFunc(this._comparisonFuncMapping[mode.stencilBack.compare], stencilReference, 255); + gl.stencilOp(gl.KEEP, gl.KEEP, this._stencilOpsMapping[mode.stencilBack.passOp]); + } + } +} +/** @ignore */ +GlStencilSystem.extension = { + type: [ + ExtensionType.WebGLSystem + ], + name: "stencil" +}; + +"use strict"; +class UboSystem { + constructor(adaptor) { + /** Cache of uniform buffer layouts and sync functions, so we don't have to re-create them */ + this._syncFunctionHash = /* @__PURE__ */ Object.create(null); + this._adaptor = adaptor; + this._systemCheck(); + } + /** + * Overrideable function by `pixi.js/unsafe-eval` to silence + * throwing an error if platform doesn't support unsafe-evals. + * @private + */ + _systemCheck() { + if (!unsafeEvalSupported()) { + throw new Error("Current environment does not allow unsafe-eval, please use pixi.js/unsafe-eval module to enable support."); + } + } + ensureUniformGroup(uniformGroup) { + const uniformData = this.getUniformGroupData(uniformGroup); + uniformGroup.buffer || (uniformGroup.buffer = new Buffer({ + data: new Float32Array(uniformData.layout.size / 4), + usage: BufferUsage.UNIFORM | BufferUsage.COPY_DST + })); + } + getUniformGroupData(uniformGroup) { + return this._syncFunctionHash[uniformGroup._signature] || this._initUniformGroup(uniformGroup); + } + _initUniformGroup(uniformGroup) { + const uniformGroupSignature = uniformGroup._signature; + let uniformData = this._syncFunctionHash[uniformGroupSignature]; + if (!uniformData) { + const elements = Object.keys(uniformGroup.uniformStructures).map((i) => uniformGroup.uniformStructures[i]); + const layout = this._adaptor.createUboElements(elements); + const syncFunction = this._generateUboSync(layout.uboElements); + uniformData = this._syncFunctionHash[uniformGroupSignature] = { + layout, + syncFunction + }; + } + return this._syncFunctionHash[uniformGroupSignature]; + } + _generateUboSync(uboElements) { + return this._adaptor.generateUboSync(uboElements); + } + syncUniformGroup(uniformGroup, data, offset) { + const uniformGroupData = this.getUniformGroupData(uniformGroup); + uniformGroup.buffer || (uniformGroup.buffer = new Buffer({ + data: new Float32Array(uniformGroupData.layout.size / 4), + usage: BufferUsage.UNIFORM | BufferUsage.COPY_DST + })); + data || (data = uniformGroup.buffer.data); + offset || (offset = 0); + uniformGroupData.syncFunction(uniformGroup.uniforms, data, offset); + return true; + } + updateUniformGroup(uniformGroup) { + if (uniformGroup.isStatic && !uniformGroup._dirtyId) + return false; + uniformGroup._dirtyId = 0; + const synced = this.syncUniformGroup(uniformGroup); + uniformGroup.buffer.update(); + return synced; + } + destroy() { + this._syncFunctionHash = null; + } +} + +"use strict"; +const WGSL_TO_STD40_SIZE = { + f32: 4, + "vec2": 8, + "vec3": 12, + "vec4": 16, + "mat2x2": 16 * 2, + "mat3x3": 16 * 3, + "mat4x4": 16 * 4 + // TODO - not essential for now but support these in the future + // int: 4, + // ivec2: 8, + // ivec3: 12, + // ivec4: 16, + // uint: 4, + // uvec2: 8, + // uvec3: 12, + // uvec4: 16, + // bool: 4, + // bvec2: 8, + // bvec3: 12, + // bvec4: 16, + // mat2: 16 * 2, + // mat3: 16 * 3, + // mat4: 16 * 4, +}; +function createUboElementsSTD40(uniformData) { + const uboElements = uniformData.map((data) => ({ + data, + offset: 0, + size: 0 + })); + let size = 0; + let chunkSize = 0; + let offset = 0; + for (let i = 0; i < uboElements.length; i++) { + const uboElement = uboElements[i]; + size = WGSL_TO_STD40_SIZE[uboElement.data.type]; + if (!size) { + throw new Error(`Unknown type ${uboElement.data.type}`); + } + if (uboElement.data.size > 1) { + size = Math.max(size, 16) * uboElement.data.size; + } + uboElement.size = size; + if (chunkSize % size !== 0 && chunkSize < 16) { + const lineUpValue = chunkSize % size % 16; + chunkSize += lineUpValue; + offset += lineUpValue; + } + if (chunkSize + size > 16) { + offset = Math.ceil(offset / 16) * 16; + uboElement.offset = offset; + offset += size; + chunkSize = size; + } else { + uboElement.offset = offset; + chunkSize += size; + offset += size; + } + } + offset = Math.ceil(offset / 16) * 16; + return { uboElements, size: offset }; +} + +"use strict"; +const uniformParsers = [ + // uploading pixi matrix object to mat3 + { + type: "mat3x3", + test: (data) => { + const value = data.value; + return value.a !== void 0; + }, + ubo: ` var matrix = uv[name].toArray(true); data[offset] = matrix[0]; data[offset + 1] = matrix[1]; @@ -1698,15 +34327,23 @@ fn setSaturation(c: vec3, s: f32) -> vec3 { data[offset + 8] = matrix[6]; data[offset + 9] = matrix[7]; data[offset + 10] = matrix[8]; - `,uniform:` + `, + uniform: ` gl.uniformMatrix3fv(ud[name].location, false, uv[name].toArray(true)); - `},{type:"vec4",test:r=>r.type==="vec4"&&r.size===1&&r.value.width!==void 0,ubo:` + ` + }, + // uploading a pixi rectangle as a vec4 + { + type: "vec4", + test: (data) => data.type === "vec4" && data.size === 1 && data.value.width !== void 0, + ubo: ` v = uv[name]; data[offset] = v.x; data[offset + 1] = v.y; data[offset + 2] = v.width; data[offset + 3] = v.height; - `,uniform:` + `, + uniform: ` cv = ud[name].value; v = uv[name]; if (cv[0] !== v.x || cv[1] !== v.y || cv[2] !== v.width || cv[3] !== v.height) { @@ -1716,11 +34353,18 @@ fn setSaturation(c: vec3, s: f32) -> vec3 { cv[3] = v.height; gl.uniform4f(ud[name].location, v.x, v.y, v.width, v.height); } - `},{type:"vec2",test:r=>r.type==="vec2"&&r.size===1&&r.value.x!==void 0,ubo:` + ` + }, + // uploading a pixi point as a vec2 + { + type: "vec2", + test: (data) => data.type === "vec2" && data.size === 1 && data.value.x !== void 0, + ubo: ` v = uv[name]; data[offset] = v.x; data[offset + 1] = v.y; - `,uniform:` + `, + uniform: ` cv = ud[name].value; v = uv[name]; if (cv[0] !== v.x || cv[1] !== v.y) { @@ -1728,13 +34372,20 @@ fn setSaturation(c: vec3, s: f32) -> vec3 { cv[1] = v.y; gl.uniform2f(ud[name].location, v.x, v.y); } - `},{type:"vec4",test:r=>r.type==="vec4"&&r.size===1&&r.value.red!==void 0,ubo:` + ` + }, + // uploading a pixi color as a vec4 + { + type: "vec4", + test: (data) => data.type === "vec4" && data.size === 1 && data.value.red !== void 0, + ubo: ` v = uv[name]; data[offset] = v.red; data[offset + 1] = v.green; data[offset + 2] = v.blue; data[offset + 3] = v.alpha; - `,uniform:` + `, + uniform: ` cv = ud[name].value; v = uv[name]; if (cv[0] !== v.red || cv[1] !== v.green || cv[2] !== v.blue || cv[3] !== v.alpha) { @@ -1744,12 +34395,19 @@ fn setSaturation(c: vec3, s: f32) -> vec3 { cv[3] = v.alpha; gl.uniform4f(ud[name].location, v.red, v.green, v.blue, v.alpha); } - `},{type:"vec3",test:r=>r.type==="vec3"&&r.size===1&&r.value.red!==void 0,ubo:` + ` + }, + // uploading a pixi color as a vec3 + { + type: "vec3", + test: (data) => data.type === "vec3" && data.size === 1 && data.value.red !== void 0, + ubo: ` v = uv[name]; data[offset] = v.red; data[offset + 1] = v.green; data[offset + 2] = v.blue; - `,uniform:` + `, + uniform: ` cv = ud[name].value; v = uv[name]; if (cv[0] !== v.red || cv[1] !== v.green || cv[2] !== v.blue) { @@ -1758,38 +34416,118 @@ fn setSaturation(c: vec3, s: f32) -> vec3 { cv[2] = v.blue; gl.uniform3f(ud[name].location, v.red, v.green, v.blue); } - `}];function Na(r,t,e,s){const i=[` + ` + } +]; + +"use strict"; +function createUboSyncFunction(uboElements, parserCode, arrayGenerationFunction, singleSettersMap) { + const funcFragments = [` var v = null; var v2 = null; var t = 0; var index = 0; var name = null; var arrayOffset = null; - `];let n=0;for(let a=0;a1)c=u.offset/4,i.push(e(u,c-n));else{const d=s[u.data.type];c=u.offset/4,i.push(` - v = uv.${l}; - offset += ${c-n}; - ${d}; - `)}n=c}const o=i.join(` -`);return new Function("uv","data","offset",o)}var o2=Object.defineProperty,a2=Object.defineProperties,u2=Object.getOwnPropertyDescriptors,pg=Object.getOwnPropertySymbols,l2=Object.prototype.hasOwnProperty,h2=Object.prototype.propertyIsEnumerable,fg=(r,t,e)=>t in r?o2(r,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):r[t]=e,c2=(r,t)=>{for(var e in t||(t={}))l2.call(t,e)&&fg(r,e,t[e]);if(pg)for(var e of pg(t))h2.call(t,e)&&fg(r,e,t[e]);return r},d2=(r,t)=>a2(r,u2(t));function Ve(r,t){return` - for (let i = 0; i < ${r*t}; i++) { - data[offset + (((i / ${r})|0) * 4) + (i % ${r})] = v[i]; + `]; + let prev = 0; + for (let i = 0; i < uboElements.length; i++) { + const uboElement = uboElements[i]; + const name = uboElement.data.name; + let parsed = false; + let offset = 0; + for (let j = 0; j < uniformParsers.length; j++) { + const uniformParser = uniformParsers[j]; + if (uniformParser.test(uboElement.data)) { + offset = uboElement.offset / 4; + funcFragments.push( + `name = "${name}";`, + `offset += ${offset - prev};`, + uniformParsers[j][parserCode] || uniformParsers[j].ubo + ); + parsed = true; + break; + } + } + if (!parsed) { + if (uboElement.data.size > 1) { + offset = uboElement.offset / 4; + funcFragments.push(arrayGenerationFunction(uboElement, offset - prev)); + } else { + const template = singleSettersMap[uboElement.data.type]; + offset = uboElement.offset / 4; + funcFragments.push( + /* wgsl */ + ` + v = uv.${name}; + offset += ${offset - prev}; + ${template}; + ` + ); + } + } + prev = offset; + } + const fragmentSrc = funcFragments.join("\n"); + return new Function( + "uv", + "data", + "offset", + fragmentSrc + ); +} + +"use strict"; +var __defProp$h = Object.defineProperty; +var __defProps$7 = Object.defineProperties; +var __getOwnPropDescs$7 = Object.getOwnPropertyDescriptors; +var __getOwnPropSymbols$h = Object.getOwnPropertySymbols; +var __hasOwnProp$h = Object.prototype.hasOwnProperty; +var __propIsEnum$h = Object.prototype.propertyIsEnumerable; +var __defNormalProp$h = (obj, key, value) => key in obj ? __defProp$h(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; +var __spreadValues$h = (a, b) => { + for (var prop in b || (b = {})) + if (__hasOwnProp$h.call(b, prop)) + __defNormalProp$h(a, prop, b[prop]); + if (__getOwnPropSymbols$h) + for (var prop of __getOwnPropSymbols$h(b)) { + if (__propIsEnum$h.call(b, prop)) + __defNormalProp$h(a, prop, b[prop]); + } + return a; +}; +var __spreadProps$7 = (a, b) => __defProps$7(a, __getOwnPropDescs$7(b)); +function loopMatrix(col, row) { + const total = col * row; + return ` + for (let i = 0; i < ${total}; i++) { + data[offset + (((i / ${col})|0) * 4) + (i % ${col})] = v[i]; } - `}const Ha={f32:` - data[offset] = v;`,i32:` - data[offset] = v;`,"vec2":` + `; +} +const uboSyncFunctionsSTD40 = { + f32: ` + data[offset] = v;`, + i32: ` + data[offset] = v;`, + "vec2": ` data[offset] = v[0]; - data[offset + 1] = v[1];`,"vec3":` + data[offset + 1] = v[1];`, + "vec3": ` data[offset] = v[0]; data[offset + 1] = v[1]; - data[offset + 2] = v[2];`,"vec4":` + data[offset + 2] = v[2];`, + "vec4": ` data[offset] = v[0]; data[offset + 1] = v[1]; data[offset + 2] = v[2]; - data[offset + 3] = v[3];`,"mat2x2":` + data[offset + 3] = v[3];`, + "mat2x2": ` data[offset] = v[0]; data[offset + 1] = v[1]; data[offset + 4] = v[2]; - data[offset + 5] = v[3];`,"mat3x3":` + data[offset + 5] = v[3];`, + "mat3x3": ` data[offset] = v[0]; data[offset + 1] = v[1]; data[offset + 2] = v[2]; @@ -1798,172 +34536,5711 @@ fn setSaturation(c: vec3, s: f32) -> vec3 { data[offset + 6] = v[5]; data[offset + 8] = v[6]; data[offset + 9] = v[7]; - data[offset + 10] = v[8];`,"mat4x4":` + data[offset + 10] = v[8];`, + "mat4x4": ` for (let i = 0; i < 16; i++) { data[offset + i] = v[i]; - }`,"mat3x2":Ve(3,2),"mat4x2":Ve(4,2),"mat2x3":Ve(2,3),"mat4x3":Ve(4,3),"mat2x4":Ve(2,4),"mat3x4":Ve(3,4)},mg=d2(c2({},Ha),{"mat2x2":` + }`, + "mat3x2": loopMatrix(3, 2), + "mat4x2": loopMatrix(4, 2), + "mat2x3": loopMatrix(2, 3), + "mat4x3": loopMatrix(4, 3), + "mat2x4": loopMatrix(2, 4), + "mat3x4": loopMatrix(3, 4) +}; +const uboSyncFunctionsWGSL = __spreadProps$7(__spreadValues$h({}, uboSyncFunctionsSTD40), { + "mat2x2": ` data[offset] = v[0]; data[offset + 1] = v[1]; data[offset + 2] = v[2]; data[offset + 3] = v[3]; - `});function gg(r,t){const e=Math.max($a[r.data.type]/16,1),s=r.data.value.length/r.data.size,i=(4-s%4)%4;return` - v = uv.${r.data.name}; - offset += ${t}; + ` +}); + +"use strict"; +function generateArraySyncSTD40(uboElement, offsetToAdd) { + const rowSize = Math.max(WGSL_TO_STD40_SIZE[uboElement.data.type] / 16, 1); + const elementSize = uboElement.data.value.length / uboElement.data.size; + const remainder = (4 - elementSize % 4) % 4; + return ` + v = uv.${uboElement.data.name}; + offset += ${offsetToAdd}; arrayOffset = offset; t = 0; - for(var i=0; i < ${r.data.size*e}; i++) + for(var i=0; i < ${uboElement.data.size * rowSize}; i++) { - for(var j = 0; j < ${s}; j++) + for(var j = 0; j < ${elementSize}; j++) { data[arrayOffset++] = v[t++]; } - ${i!==0?`arrayOffset += ${i};`:""} + ${remainder !== 0 ? `arrayOffset += ${remainder};` : ""} } - `}function _g(r){return Na(r,"uboStd40",gg,Ha)}class Xa extends La{constructor(){super({createUboElements:dg,generateUboSync:_g})}}Xa.extension={type:[v.WebGLSystem],name:"ubo"};class xg{constructor(){this._clearColorCache=[0,0,0,0],this._viewPortCache=new z}init(t,e){this._renderer=t,this._renderTargetSystem=e,t.runners.contextChange.add(this)}contextChange(){this._clearColorCache=[0,0,0,0],this._viewPortCache=new z}copyToTexture(t,e,s,i,n){const o=this._renderTargetSystem,a=this._renderer,u=o.getGpuRenderTarget(t),l=a.gl;return this.finishRenderPass(t),l.bindFramebuffer(l.FRAMEBUFFER,u.resolveTargetFramebuffer),a.texture.bind(e,0),l.copyTexSubImage2D(l.TEXTURE_2D,0,n.x,n.y,s.x,s.y,i.width,i.height),e}startRenderPass(t,e=!0,s,i){const n=this._renderTargetSystem,o=t.colorTexture,a=n.getGpuRenderTarget(t);let u=i.y;t.isRoot&&(u=o.pixelHeight-i.height),t.colorTextures.forEach(c=>{this._renderer.texture.unbind(c)});const l=this._renderer.gl;l.bindFramebuffer(l.FRAMEBUFFER,a.framebuffer);const h=this._viewPortCache;(h.x!==i.x||h.y!==u||h.width!==i.width||h.height!==i.height)&&(h.x=i.x,h.y=u,h.width=i.width,h.height=i.height,l.viewport(i.x,u,i.width,i.height)),!a.depthStencilRenderBuffer&&(t.stencil||t.depth)&&this._initStencil(a),this.clear(t,e,s)}finishRenderPass(t){const e=this._renderTargetSystem.getGpuRenderTarget(t);if(!e.msaa)return;const s=this._renderer.gl;s.bindFramebuffer(s.FRAMEBUFFER,e.resolveTargetFramebuffer),s.bindFramebuffer(s.READ_FRAMEBUFFER,e.framebuffer),s.blitFramebuffer(0,0,e.width,e.height,0,0,e.width,e.height,s.COLOR_BUFFER_BIT,s.NEAREST),s.bindFramebuffer(s.FRAMEBUFFER,e.framebuffer)}initGpuRenderTarget(t){const e=this._renderer.gl,s=new cg;return Qt.test(t.colorTexture.resource)?(s.framebuffer=null,s):(this._initColor(t,s),e.bindFramebuffer(e.FRAMEBUFFER,null),s)}clear(t,e,s){if(!e)return;const i=this._renderTargetSystem;typeof e=="boolean"&&(e=e?pt.ALL:pt.NONE);const n=this._renderer.gl;if(e&pt.COLOR){s!=null||(s=i.defaultClearColor);const o=this._clearColorCache,a=s;(o[0]!==a[0]||o[1]!==a[1]||o[2]!==a[2]||o[3]!==a[3])&&(o[0]=a[0],o[1]=a[1],o[2]=a[2],o[3]=a[3],n.clearColor(a[0],a[1],a[2],a[3]))}n.clear(e)}resizeGpuRenderTarget(t){if(t.isRoot)return;const e=this._renderTargetSystem.getGpuRenderTarget(t);this._resizeColor(t,e),t.stencil&&this._resizeStencil(e)}_initColor(t,e){const s=this._renderer,i=s.gl,n=i.createFramebuffer();if(e.resolveTargetFramebuffer=n,i.bindFramebuffer(i.FRAMEBUFFER,n),e.width=t.colorTexture.source.pixelWidth,e.height=t.colorTexture.source.pixelHeight,t.colorTextures.forEach((o,a)=>{const u=o.source;u.antialias&&(s.context.supports.msaa?e.msaa=!0:xi("[RenderTexture] Antialiasing on textures is not supported in WebGL1")),s.texture.bindSource(u,0);const l=s.texture.getGlSource(u).texture;i.framebufferTexture2D(i.FRAMEBUFFER,i.COLOR_ATTACHMENT0+a,3553,l,0)}),e.msaa){const o=i.createFramebuffer();e.framebuffer=o,i.bindFramebuffer(i.FRAMEBUFFER,o),t.colorTextures.forEach((a,u)=>{const l=i.createRenderbuffer();e.msaaRenderBuffer[u]=l})}else e.framebuffer=n;this._resizeColor(t,e)}_resizeColor(t,e){const s=t.colorTexture.source;if(e.width=s.pixelWidth,e.height=s.pixelHeight,t.colorTextures.forEach((i,n)=>{n!==0&&i.source.resize(s.width,s.height,s._resolution)}),e.msaa){const i=this._renderer,n=i.gl,o=e.framebuffer;n.bindFramebuffer(n.FRAMEBUFFER,o),t.colorTextures.forEach((a,u)=>{const l=a.source;i.texture.bindSource(l,0);const h=i.texture.getGlSource(l).internalFormat,c=e.msaaRenderBuffer[u];n.bindRenderbuffer(n.RENDERBUFFER,c),n.renderbufferStorageMultisample(n.RENDERBUFFER,4,h,l.pixelWidth,l.pixelHeight),n.framebufferRenderbuffer(n.FRAMEBUFFER,n.COLOR_ATTACHMENT0+u,n.RENDERBUFFER,c)})}}_initStencil(t){if(t.framebuffer===null)return;const e=this._renderer.gl,s=e.createRenderbuffer();t.depthStencilRenderBuffer=s,e.bindRenderbuffer(e.RENDERBUFFER,s),e.framebufferRenderbuffer(e.FRAMEBUFFER,e.DEPTH_STENCIL_ATTACHMENT,e.RENDERBUFFER,s),this._resizeStencil(t)}_resizeStencil(t){const e=this._renderer.gl;e.bindRenderbuffer(e.RENDERBUFFER,t.depthStencilRenderBuffer),t.msaa?e.renderbufferStorageMultisample(e.RENDERBUFFER,4,e.DEPTH24_STENCIL8,t.width,t.height):e.renderbufferStorage(e.RENDERBUFFER,this._renderer.context.webGLVersion===2?e.DEPTH24_STENCIL8:e.DEPTH_STENCIL,t.width,t.height)}}function bg(r,t,e,s,i,n){const o=n?1:-1;return r.identity(),r.a=1/s*2,r.d=o*(1/i*2),r.tx=-1-t*r.a,r.ty=-o-e*r.d,r}var p2=Object.defineProperty,vg=Object.getOwnPropertySymbols,f2=Object.prototype.hasOwnProperty,m2=Object.prototype.propertyIsEnumerable,yg=(r,t,e)=>t in r?p2(r,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):r[t]=e,g2=(r,t)=>{for(var e in t||(t={}))f2.call(t,e)&&yg(r,e,t[e]);if(vg)for(var e of vg(t))m2.call(t,e)&&yg(r,e,t[e]);return r};const We=new Map;function za(r,t){if(!We.has(r)){const e=new A({source:new Qt(g2({resource:r},t))}),s=()=>{We.get(r)===e&&We.delete(r)};e.once("destroy",s),e.source.once("destroy",s),We.set(r,e)}return We.get(r)}function _2(r){return We.has(r)}function Tg(r){const t=r.colorTexture.source.resource;return globalThis.HTMLCanvasElement&&t instanceof HTMLCanvasElement&&document.body.contains(t)}var x2=Object.defineProperty,Sg=Object.getOwnPropertySymbols,b2=Object.prototype.hasOwnProperty,v2=Object.prototype.propertyIsEnumerable,Eg=(r,t,e)=>t in r?x2(r,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):r[t]=e,Ag=(r,t)=>{for(var e in t||(t={}))b2.call(t,e)&&Eg(r,e,t[e]);if(Sg)for(var e of Sg(t))v2.call(t,e)&&Eg(r,e,t[e]);return r};const Pg=class Ux{constructor(t={}){if(this.uid=Z("renderTarget"),this.colorTextures=[],this.dirtyId=0,this.isRoot=!1,this._size=new Float32Array(2),t=Ag(Ag({},Ux.defaultOptions),t),this.stencil=t.stencil,this.depth=t.depth,this.isRoot=t.isRoot,typeof t.colorTextures=="number")for(let e=0;es.source)];const e=this.colorTexture.source;this.resize(e.width,e.height,e._resolution)}this.colorTexture.source.on("resize",this.onSourceResize,this),(t.depthStencilTexture||this.stencil)&&(t.depthStencilTexture instanceof A||t.depthStencilTexture instanceof et?this.depthStencilTexture=t.depthStencilTexture.source:this.ensureDepthStencilTexture())}get size(){const t=this._size;return t[0]=this.pixelWidth,t[1]=this.pixelHeight,t}get width(){return this.colorTexture.source.width}get height(){return this.colorTexture.source.height}get pixelWidth(){return this.colorTexture.source.pixelWidth}get pixelHeight(){return this.colorTexture.source.pixelHeight}get resolution(){return this.colorTexture.source._resolution}get colorTexture(){return this.colorTextures[0]}onSourceResize(t){this.resize(t.width,t.height,t._resolution,!0)}ensureDepthStencilTexture(){this.depthStencilTexture||(this.depthStencilTexture=new et({width:this.width,height:this.height,resolution:this.resolution,format:"depth24plus-stencil8",autoGenerateMipmaps:!1,antialias:!1,mipLevelCount:1}))}resize(t,e,s=this.resolution,i=!1){this.dirtyId++,this.colorTextures.forEach((n,o)=>{i&&o===0||n.source.resize(t,e,s)}),this.depthStencilTexture&&this.depthStencilTexture.source.resize(t,e,s)}destroy(){this.colorTexture.source.off("resize",this.onSourceResize,this),this.depthStencilTexture&&(this.depthStencilTexture.destroy(),delete this.depthStencilTexture)}};Pg.defaultOptions={width:0,height:0,resolution:1,colorTextures:1,stencil:!1,depth:!1,antialias:!1,isRoot:!1};let vi=Pg;class ja{constructor(t){this.rootViewPort=new z,this.viewport=new z,this.onRenderTargetChange=new Ko("onRenderTargetChange"),this.projectionMatrix=new G,this.defaultClearColor=[0,0,0,0],this._renderSurfaceToRenderTargetHash=new Map,this._gpuRenderTargetHash=Object.create(null),this._renderTargetStack=[],this._renderer=t}finishRenderPass(){this.adaptor.finishRenderPass(this.renderTarget)}renderStart({target:t,clear:e,clearColor:s,frame:i}){this._renderTargetStack.length=0,this.push(t,e,s,i),this.rootViewPort.copyFrom(this.viewport),this.rootRenderTarget=this.renderTarget,this.renderingToScreen=Tg(this.rootRenderTarget)}bind(t,e=!0,s,i){const n=this.getRenderTarget(t),o=this.renderTarget!==n;this.renderTarget=n,this.renderSurface=t;const a=this.getGpuRenderTarget(n);(n.pixelWidth!==a.width||n.pixelHeight!==a.height)&&(this.adaptor.resizeGpuRenderTarget(n),a.width=n.pixelWidth,a.height=n.pixelHeight);const u=n.colorTexture,l=this.viewport,h=u.pixelWidth,c=u.pixelHeight;if(!i&&t instanceof A&&(i=t.frame),i){const d=u._resolution;l.x=i.x*d+.5|0,l.y=i.y*d+.5|0,l.width=i.width*d+.5|0,l.height=i.height*d+.5|0}else l.x=0,l.y=0,l.width=h,l.height=c;return bg(this.projectionMatrix,0,0,l.width/u.resolution,l.height/u.resolution,!n.isRoot),this.adaptor.startRenderPass(n,e,s,l),o&&this.onRenderTargetChange.emit(n),n}clear(t,e=pt.ALL,s){e&&(t&&(t=this.getRenderTarget(t)),this.adaptor.clear(t||this.renderTarget,e,s,this.viewport))}contextChange(){this._gpuRenderTargetHash=Object.create(null)}push(t,e=pt.ALL,s,i){const n=this.bind(t,e,s,i);return this._renderTargetStack.push({renderTarget:n,frame:i}),n}pop(){this._renderTargetStack.pop();const t=this._renderTargetStack[this._renderTargetStack.length-1];this.bind(t.renderTarget,!1,null,t.frame)}getRenderTarget(t){var e;return t.isTexture&&(t=t.source),(e=this._renderSurfaceToRenderTargetHash.get(t))!=null?e:this._initRenderTarget(t)}copyToTexture(t,e,s,i,n){s.x<0&&(i.width+=s.x,n.x-=s.x,s.x=0),s.y<0&&(i.height+=s.y,n.y-=s.y,s.y=0);const{pixelWidth:o,pixelHeight:a}=t;return i.width=Math.min(i.width,o-s.x),i.height=Math.min(i.height,a-s.y),this.adaptor.copyToTexture(t,e,s,i,n)}ensureDepthStencil(){this.renderTarget.stencil||(this.renderTarget.stencil=!0,this.adaptor.startRenderPass(this.renderTarget,!1,null,this.viewport))}destroy(){this._renderer=null,this._renderSurfaceToRenderTargetHash.forEach((t,e)=>{t!==e&&t.destroy()}),this._renderSurfaceToRenderTargetHash.clear(),this._gpuRenderTargetHash=Object.create(null)}_initRenderTarget(t){let e=null;return Qt.test(t)&&(t=za(t)),t instanceof vi?e=t:t instanceof et&&(e=new vi({colorTextures:[t]}),Qt.test(t.source.resource)&&(e.isRoot=!0),t.on("destroy",()=>{e.destroy()})),this._renderSurfaceToRenderTargetHash.set(t,e),e}getGpuRenderTarget(t){return this._gpuRenderTargetHash[t.uid]||(this._gpuRenderTargetHash[t.uid]=this.adaptor.initGpuRenderTarget(t))}}class Va extends ja{constructor(t){super(t),this.adaptor=new xg,this.adaptor.init(t,this)}}Va.extension={type:[v.WebGLSystem],name:"renderTarget"};class yi extends ct{constructor({buffer:t,offset:e,size:s}){super(),this.uid=Z("buffer"),this._resourceType="bufferResource",this._touched=0,this._resourceId=Z("resource"),this._bufferResource=!0,this.buffer=t,this.offset=e|0,this.size=s,this.buffer.on("change",this.onBufferChange,this)}onBufferChange(){this._resourceId=Z("resource"),this.emit("change",this)}destroy(t=!1){t&&this.buffer.destroy(),this.buffer=null}}function wg(r,t){const e=[],s=[` + `; +} + +"use strict"; +function createUboSyncFunctionSTD40(uboElements) { + return createUboSyncFunction( + uboElements, + "uboStd40", + generateArraySyncSTD40, + uboSyncFunctionsSTD40 + ); +} + +"use strict"; +class GlUboSystem extends UboSystem { + constructor() { + super({ + createUboElements: createUboElementsSTD40, + generateUboSync: createUboSyncFunctionSTD40 + }); + } +} +/** @ignore */ +GlUboSystem.extension = { + type: [ExtensionType.WebGLSystem], + name: "ubo" +}; + +"use strict"; +class GlRenderTargetAdaptor { + constructor() { + this._clearColorCache = [0, 0, 0, 0]; + this._viewPortCache = new Rectangle(); + } + init(renderer, renderTargetSystem) { + this._renderer = renderer; + this._renderTargetSystem = renderTargetSystem; + renderer.runners.contextChange.add(this); + } + contextChange() { + this._clearColorCache = [0, 0, 0, 0]; + this._viewPortCache = new Rectangle(); + } + copyToTexture(sourceRenderSurfaceTexture, destinationTexture, originSrc, size, originDest) { + const renderTargetSystem = this._renderTargetSystem; + const renderer = this._renderer; + const glRenderTarget = renderTargetSystem.getGpuRenderTarget(sourceRenderSurfaceTexture); + const gl = renderer.gl; + this.finishRenderPass(sourceRenderSurfaceTexture); + gl.bindFramebuffer(gl.FRAMEBUFFER, glRenderTarget.resolveTargetFramebuffer); + renderer.texture.bind(destinationTexture, 0); + gl.copyTexSubImage2D( + gl.TEXTURE_2D, + 0, + originDest.x, + originDest.y, + originSrc.x, + originSrc.y, + size.width, + size.height + ); + return destinationTexture; + } + startRenderPass(renderTarget, clear = true, clearColor, viewport) { + const renderTargetSystem = this._renderTargetSystem; + const source = renderTarget.colorTexture; + const gpuRenderTarget = renderTargetSystem.getGpuRenderTarget(renderTarget); + let viewPortY = viewport.y; + if (renderTarget.isRoot) { + viewPortY = source.pixelHeight - viewport.height; + } + renderTarget.colorTextures.forEach((texture) => { + this._renderer.texture.unbind(texture); + }); + const gl = this._renderer.gl; + gl.bindFramebuffer(gl.FRAMEBUFFER, gpuRenderTarget.framebuffer); + const viewPortCache = this._viewPortCache; + if (viewPortCache.x !== viewport.x || viewPortCache.y !== viewPortY || viewPortCache.width !== viewport.width || viewPortCache.height !== viewport.height) { + viewPortCache.x = viewport.x; + viewPortCache.y = viewPortY; + viewPortCache.width = viewport.width; + viewPortCache.height = viewport.height; + gl.viewport( + viewport.x, + viewPortY, + viewport.width, + viewport.height + ); + } + if (!gpuRenderTarget.depthStencilRenderBuffer && (renderTarget.stencil || renderTarget.depth)) { + this._initStencil(gpuRenderTarget); + } + this.clear(renderTarget, clear, clearColor); + } + finishRenderPass(renderTarget) { + const renderTargetSystem = this._renderTargetSystem; + const glRenderTarget = renderTargetSystem.getGpuRenderTarget(renderTarget); + if (!glRenderTarget.msaa) + return; + const gl = this._renderer.gl; + gl.bindFramebuffer(gl.FRAMEBUFFER, glRenderTarget.resolveTargetFramebuffer); + gl.bindFramebuffer(gl.READ_FRAMEBUFFER, glRenderTarget.framebuffer); + gl.blitFramebuffer( + 0, + 0, + glRenderTarget.width, + glRenderTarget.height, + 0, + 0, + glRenderTarget.width, + glRenderTarget.height, + gl.COLOR_BUFFER_BIT, + gl.NEAREST + ); + gl.bindFramebuffer(gl.FRAMEBUFFER, glRenderTarget.framebuffer); + } + initGpuRenderTarget(renderTarget) { + const renderer = this._renderer; + const gl = renderer.gl; + const glRenderTarget = new GlRenderTarget(); + if (CanvasSource.test(renderTarget.colorTexture.resource)) { + glRenderTarget.framebuffer = null; + return glRenderTarget; + } + this._initColor(renderTarget, glRenderTarget); + gl.bindFramebuffer(gl.FRAMEBUFFER, null); + return glRenderTarget; + } + clear(_renderTarget, clear, clearColor) { + if (!clear) + return; + const renderTargetSystem = this._renderTargetSystem; + if (typeof clear === "boolean") { + clear = clear ? CLEAR.ALL : CLEAR.NONE; + } + const gl = this._renderer.gl; + if (clear & CLEAR.COLOR) { + clearColor != null ? clearColor : clearColor = renderTargetSystem.defaultClearColor; + const clearColorCache = this._clearColorCache; + const clearColorArray = clearColor; + if (clearColorCache[0] !== clearColorArray[0] || clearColorCache[1] !== clearColorArray[1] || clearColorCache[2] !== clearColorArray[2] || clearColorCache[3] !== clearColorArray[3]) { + clearColorCache[0] = clearColorArray[0]; + clearColorCache[1] = clearColorArray[1]; + clearColorCache[2] = clearColorArray[2]; + clearColorCache[3] = clearColorArray[3]; + gl.clearColor(clearColorArray[0], clearColorArray[1], clearColorArray[2], clearColorArray[3]); + } + } + gl.clear(clear); + } + resizeGpuRenderTarget(renderTarget) { + if (renderTarget.isRoot) + return; + const renderTargetSystem = this._renderTargetSystem; + const glRenderTarget = renderTargetSystem.getGpuRenderTarget(renderTarget); + this._resizeColor(renderTarget, glRenderTarget); + if (renderTarget.stencil) { + this._resizeStencil(glRenderTarget); + } + } + _initColor(renderTarget, glRenderTarget) { + const renderer = this._renderer; + const gl = renderer.gl; + const resolveTargetFramebuffer = gl.createFramebuffer(); + glRenderTarget.resolveTargetFramebuffer = resolveTargetFramebuffer; + gl.bindFramebuffer(gl.FRAMEBUFFER, resolveTargetFramebuffer); + glRenderTarget.width = renderTarget.colorTexture.source.pixelWidth; + glRenderTarget.height = renderTarget.colorTexture.source.pixelHeight; + renderTarget.colorTextures.forEach((colorTexture, i) => { + const source = colorTexture.source; + if (source.antialias) { + if (renderer.context.supports.msaa) { + glRenderTarget.msaa = true; + } else { + warn("[RenderTexture] Antialiasing on textures is not supported in WebGL1"); + } + } + renderer.texture.bindSource(source, 0); + const glSource = renderer.texture.getGlSource(source); + const glTexture = glSource.texture; + gl.framebufferTexture2D( + gl.FRAMEBUFFER, + gl.COLOR_ATTACHMENT0 + i, + 3553, + // texture.target, + glTexture, + 0 + ); + }); + if (glRenderTarget.msaa) { + const viewFramebuffer = gl.createFramebuffer(); + glRenderTarget.framebuffer = viewFramebuffer; + gl.bindFramebuffer(gl.FRAMEBUFFER, viewFramebuffer); + renderTarget.colorTextures.forEach((_, i) => { + const msaaRenderBuffer = gl.createRenderbuffer(); + glRenderTarget.msaaRenderBuffer[i] = msaaRenderBuffer; + }); + } else { + glRenderTarget.framebuffer = resolveTargetFramebuffer; + } + this._resizeColor(renderTarget, glRenderTarget); + } + _resizeColor(renderTarget, glRenderTarget) { + const source = renderTarget.colorTexture.source; + glRenderTarget.width = source.pixelWidth; + glRenderTarget.height = source.pixelHeight; + renderTarget.colorTextures.forEach((colorTexture, i) => { + if (i === 0) + return; + colorTexture.source.resize(source.width, source.height, source._resolution); + }); + if (glRenderTarget.msaa) { + const renderer = this._renderer; + const gl = renderer.gl; + const viewFramebuffer = glRenderTarget.framebuffer; + gl.bindFramebuffer(gl.FRAMEBUFFER, viewFramebuffer); + renderTarget.colorTextures.forEach((colorTexture, i) => { + const source2 = colorTexture.source; + renderer.texture.bindSource(source2, 0); + const glSource = renderer.texture.getGlSource(source2); + const glInternalFormat = glSource.internalFormat; + const msaaRenderBuffer = glRenderTarget.msaaRenderBuffer[i]; + gl.bindRenderbuffer( + gl.RENDERBUFFER, + msaaRenderBuffer + ); + gl.renderbufferStorageMultisample( + gl.RENDERBUFFER, + 4, + glInternalFormat, + source2.pixelWidth, + source2.pixelHeight + ); + gl.framebufferRenderbuffer( + gl.FRAMEBUFFER, + gl.COLOR_ATTACHMENT0 + i, + gl.RENDERBUFFER, + msaaRenderBuffer + ); + }); + } + } + _initStencil(glRenderTarget) { + if (glRenderTarget.framebuffer === null) + return; + const gl = this._renderer.gl; + const depthStencilRenderBuffer = gl.createRenderbuffer(); + glRenderTarget.depthStencilRenderBuffer = depthStencilRenderBuffer; + gl.bindRenderbuffer( + gl.RENDERBUFFER, + depthStencilRenderBuffer + ); + gl.framebufferRenderbuffer( + gl.FRAMEBUFFER, + gl.DEPTH_STENCIL_ATTACHMENT, + gl.RENDERBUFFER, + depthStencilRenderBuffer + ); + this._resizeStencil(glRenderTarget); + } + _resizeStencil(glRenderTarget) { + const gl = this._renderer.gl; + gl.bindRenderbuffer( + gl.RENDERBUFFER, + glRenderTarget.depthStencilRenderBuffer + ); + if (glRenderTarget.msaa) { + gl.renderbufferStorageMultisample( + gl.RENDERBUFFER, + 4, + gl.DEPTH24_STENCIL8, + glRenderTarget.width, + glRenderTarget.height + ); + } else { + gl.renderbufferStorage( + gl.RENDERBUFFER, + this._renderer.context.webGLVersion === 2 ? gl.DEPTH24_STENCIL8 : gl.DEPTH_STENCIL, + glRenderTarget.width, + glRenderTarget.height + ); + } + } +} + +"use strict"; +function calculateProjection(pm, x, y, width, height, flipY) { + const sign = flipY ? 1 : -1; + pm.identity(); + pm.a = 1 / width * 2; + pm.d = sign * (1 / height * 2); + pm.tx = -1 - x * pm.a; + pm.ty = -sign - y * pm.d; + return pm; +} + +"use strict"; +var __defProp$g = Object.defineProperty; +var __getOwnPropSymbols$g = Object.getOwnPropertySymbols; +var __hasOwnProp$g = Object.prototype.hasOwnProperty; +var __propIsEnum$g = Object.prototype.propertyIsEnumerable; +var __defNormalProp$g = (obj, key, value) => key in obj ? __defProp$g(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; +var __spreadValues$g = (a, b) => { + for (var prop in b || (b = {})) + if (__hasOwnProp$g.call(b, prop)) + __defNormalProp$g(a, prop, b[prop]); + if (__getOwnPropSymbols$g) + for (var prop of __getOwnPropSymbols$g(b)) { + if (__propIsEnum$g.call(b, prop)) + __defNormalProp$g(a, prop, b[prop]); + } + return a; +}; +const canvasCache = /* @__PURE__ */ new Map(); +function getCanvasTexture(canvas, options) { + if (!canvasCache.has(canvas)) { + const texture = new Texture({ + source: new CanvasSource(__spreadValues$g({ + resource: canvas + }, options)) + }); + const onDestroy = () => { + if (canvasCache.get(canvas) === texture) { + canvasCache.delete(canvas); + } + }; + texture.once("destroy", onDestroy); + texture.source.once("destroy", onDestroy); + canvasCache.set(canvas, texture); + } + return canvasCache.get(canvas); +} +function hasCachedCanvasTexture(canvas) { + return canvasCache.has(canvas); +} + +"use strict"; +function isRenderingToScreen(renderTarget) { + const resource = renderTarget.colorTexture.source.resource; + return globalThis.HTMLCanvasElement && resource instanceof HTMLCanvasElement && document.body.contains(resource); +} + +"use strict"; +var __defProp$f = Object.defineProperty; +var __getOwnPropSymbols$f = Object.getOwnPropertySymbols; +var __hasOwnProp$f = Object.prototype.hasOwnProperty; +var __propIsEnum$f = Object.prototype.propertyIsEnumerable; +var __defNormalProp$f = (obj, key, value) => key in obj ? __defProp$f(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; +var __spreadValues$f = (a, b) => { + for (var prop in b || (b = {})) + if (__hasOwnProp$f.call(b, prop)) + __defNormalProp$f(a, prop, b[prop]); + if (__getOwnPropSymbols$f) + for (var prop of __getOwnPropSymbols$f(b)) { + if (__propIsEnum$f.call(b, prop)) + __defNormalProp$f(a, prop, b[prop]); + } + return a; +}; +const _RenderTarget = class _RenderTarget { + /** + * @param [descriptor] - Options for creating a render target. + */ + constructor(descriptor = {}) { + this.uid = uid("renderTarget"); + /** + * An array of textures that can be written to by the GPU - mostly this has one texture in Pixi, but you could + * write to multiple if required! (eg deferred lighting) + */ + this.colorTextures = []; + this.dirtyId = 0; + this.isRoot = false; + this._size = new Float32Array(2); + descriptor = __spreadValues$f(__spreadValues$f({}, _RenderTarget.defaultOptions), descriptor); + this.stencil = descriptor.stencil; + this.depth = descriptor.depth; + this.isRoot = descriptor.isRoot; + if (typeof descriptor.colorTextures === "number") { + for (let i = 0; i < descriptor.colorTextures; i++) { + this.colorTextures.push( + new TextureSource({ + width: descriptor.width, + height: descriptor.height, + resolution: descriptor.resolution, + antialias: descriptor.antialias + }) + ); + } + } else { + this.colorTextures = [...descriptor.colorTextures.map((texture) => texture.source)]; + const colorSource = this.colorTexture.source; + this.resize(colorSource.width, colorSource.height, colorSource._resolution); + } + this.colorTexture.source.on("resize", this.onSourceResize, this); + if (descriptor.depthStencilTexture || this.stencil) { + if (descriptor.depthStencilTexture instanceof Texture || descriptor.depthStencilTexture instanceof TextureSource) { + this.depthStencilTexture = descriptor.depthStencilTexture.source; + } else { + this.ensureDepthStencilTexture(); + } + } + } + get size() { + const _size = this._size; + _size[0] = this.pixelWidth; + _size[1] = this.pixelHeight; + return _size; + } + get width() { + return this.colorTexture.source.width; + } + get height() { + return this.colorTexture.source.height; + } + get pixelWidth() { + return this.colorTexture.source.pixelWidth; + } + get pixelHeight() { + return this.colorTexture.source.pixelHeight; + } + get resolution() { + return this.colorTexture.source._resolution; + } + get colorTexture() { + return this.colorTextures[0]; + } + onSourceResize(source) { + this.resize(source.width, source.height, source._resolution, true); + } + /** + * This will ensure a depthStencil texture is created for this render target. + * Most likely called by the mask system to make sure we have stencil buffer added. + * @internal + * @ignore + */ + ensureDepthStencilTexture() { + if (!this.depthStencilTexture) { + this.depthStencilTexture = new TextureSource({ + width: this.width, + height: this.height, + resolution: this.resolution, + format: "depth24plus-stencil8", + autoGenerateMipmaps: false, + antialias: false, + mipLevelCount: 1 + // sampleCount: handled by the render target system.. + }); + } + } + resize(width, height, resolution = this.resolution, skipColorTexture = false) { + this.dirtyId++; + this.colorTextures.forEach((colorTexture, i) => { + if (skipColorTexture && i === 0) + return; + colorTexture.source.resize(width, height, resolution); + }); + if (this.depthStencilTexture) { + this.depthStencilTexture.source.resize(width, height, resolution); + } + } + destroy() { + this.colorTexture.source.off("resize", this.onSourceResize, this); + if (this.depthStencilTexture) { + this.depthStencilTexture.destroy(); + delete this.depthStencilTexture; + } + } +}; +/** The default options for a render target */ +_RenderTarget.defaultOptions = { + /** the width of the RenderTarget */ + width: 0, + /** the height of the RenderTarget */ + height: 0, + /** the resolution of the RenderTarget */ + resolution: 1, + /** an array of textures, or a number indicating how many color textures there should be */ + colorTextures: 1, + /** should this render target have a stencil buffer? */ + stencil: false, + /** should this render target have a depth buffer? */ + depth: false, + /** should this render target be antialiased? */ + antialias: false, + // save on perf by default! + /** is this a root element, true if this is gl context owners render target */ + isRoot: false +}; +let RenderTarget = _RenderTarget; + +"use strict"; +class RenderTargetSystem { + constructor(renderer) { + /** This is the root viewport for the render pass*/ + this.rootViewPort = new Rectangle(); + /** the current viewport that the gpu is using */ + this.viewport = new Rectangle(); + /** + * a runner that lets systems know if the active render target has changed. + * Eg the Stencil System needs to know so it can manage the stencil buffer + */ + this.onRenderTargetChange = new SystemRunner("onRenderTargetChange"); + /** the projection matrix that is used by the shaders based on the active render target and the viewport */ + this.projectionMatrix = new Matrix(); + /** the default clear color for render targets */ + this.defaultClearColor = [0, 0, 0, 0]; + /** + * a hash that stores the render target for a given render surface. When you pass in a texture source, + * a render target is created for it. This map stores and makes it easy to retrieve the render target + */ + this._renderSurfaceToRenderTargetHash = /* @__PURE__ */ new Map(); + /** A hash that stores a gpu render target for a given render target. */ + this._gpuRenderTargetHash = /* @__PURE__ */ Object.create(null); + /** + * A stack that stores the render target and frame that is currently being rendered to. + * When push is called, the current render target is stored in this stack. + * When pop is called, the previous render target is restored. + */ + this._renderTargetStack = []; + this._renderer = renderer; + } + /** called when dev wants to finish a render pass */ + finishRenderPass() { + this.adaptor.finishRenderPass(this.renderTarget); + } + /** + * called when the renderer starts to render a scene. + * @param options + * @param options.target - the render target to render to + * @param options.clear - the clear mode to use. Can be true or a CLEAR number 'COLOR | DEPTH | STENCIL' 0b111 + * @param options.clearColor - the color to clear to + * @param options.frame - the frame to render to + */ + renderStart({ + target, + clear, + clearColor, + frame + }) { + this._renderTargetStack.length = 0; + this.push( + target, + clear, + clearColor, + frame + ); + this.rootViewPort.copyFrom(this.viewport); + this.rootRenderTarget = this.renderTarget; + this.renderingToScreen = isRenderingToScreen(this.rootRenderTarget); + } + /** + * Binding a render surface! This is the main function of the render target system. + * It will take the RenderSurface (which can be a texture, canvas, or render target) and bind it to the renderer. + * Once bound all draw calls will be rendered to the render surface. + * + * If a frame is not provide and the render surface is a texture, the frame of the texture will be used. + * @param renderSurface - the render surface to bind + * @param clear - the clear mode to use. Can be true or a CLEAR number 'COLOR | DEPTH | STENCIL' 0b111 + * @param clearColor - the color to clear to + * @param frame - the frame to render to + * @returns the render target that was bound + */ + bind(renderSurface, clear = true, clearColor, frame) { + const renderTarget = this.getRenderTarget(renderSurface); + const didChange = this.renderTarget !== renderTarget; + this.renderTarget = renderTarget; + this.renderSurface = renderSurface; + const gpuRenderTarget = this.getGpuRenderTarget(renderTarget); + if (renderTarget.pixelWidth !== gpuRenderTarget.width || renderTarget.pixelHeight !== gpuRenderTarget.height) { + this.adaptor.resizeGpuRenderTarget(renderTarget); + gpuRenderTarget.width = renderTarget.pixelWidth; + gpuRenderTarget.height = renderTarget.pixelHeight; + } + const source = renderTarget.colorTexture; + const viewport = this.viewport; + const pixelWidth = source.pixelWidth; + const pixelHeight = source.pixelHeight; + if (!frame && renderSurface instanceof Texture) { + frame = renderSurface.frame; + } + if (frame) { + const resolution = source._resolution; + viewport.x = frame.x * resolution + 0.5 | 0; + viewport.y = frame.y * resolution + 0.5 | 0; + viewport.width = frame.width * resolution + 0.5 | 0; + viewport.height = frame.height * resolution + 0.5 | 0; + } else { + viewport.x = 0; + viewport.y = 0; + viewport.width = pixelWidth; + viewport.height = pixelHeight; + } + calculateProjection( + this.projectionMatrix, + 0, + 0, + viewport.width / source.resolution, + viewport.height / source.resolution, + !renderTarget.isRoot + ); + this.adaptor.startRenderPass(renderTarget, clear, clearColor, viewport); + if (didChange) { + this.onRenderTargetChange.emit(renderTarget); + } + return renderTarget; + } + clear(target, clear = CLEAR.ALL, clearColor) { + if (!clear) + return; + if (target) { + target = this.getRenderTarget(target); + } + this.adaptor.clear( + target || this.renderTarget, + clear, + clearColor, + this.viewport + ); + } + contextChange() { + this._gpuRenderTargetHash = /* @__PURE__ */ Object.create(null); + } + /** + * Push a render surface to the renderer. This will bind the render surface to the renderer, + * @param renderSurface - the render surface to push + * @param clear - the clear mode to use. Can be true or a CLEAR number 'COLOR | DEPTH | STENCIL' 0b111 + * @param clearColor - the color to clear to + * @param frame - the frame to use when rendering to the render surface + */ + push(renderSurface, clear = CLEAR.ALL, clearColor, frame) { + const renderTarget = this.bind(renderSurface, clear, clearColor, frame); + this._renderTargetStack.push({ + renderTarget, + frame + }); + return renderTarget; + } + /** Pops the current render target from the renderer and restores the previous render target. */ + pop() { + this._renderTargetStack.pop(); + const currentRenderTargetData = this._renderTargetStack[this._renderTargetStack.length - 1]; + this.bind(currentRenderTargetData.renderTarget, false, null, currentRenderTargetData.frame); + } + /** + * Gets the render target from the provide render surface. Eg if its a texture, + * it will return the render target for the texture. + * If its a render target, it will return the same render target. + * @param renderSurface - the render surface to get the render target for + * @returns the render target for the render surface + */ + getRenderTarget(renderSurface) { + var _a; + if (renderSurface.isTexture) { + renderSurface = renderSurface.source; + } + return (_a = this._renderSurfaceToRenderTargetHash.get(renderSurface)) != null ? _a : this._initRenderTarget(renderSurface); + } + /** + * Copies a render surface to another texture + * @param sourceRenderSurfaceTexture - the render surface to copy from + * @param destinationTexture - the texture to copy to + * @param originSrc - the origin of the copy + * @param originSrc.x - the x origin of the copy + * @param originSrc.y - the y origin of the copy + * @param size - the size of the copy + * @param size.width - the width of the copy + * @param size.height - the height of the copy + * @param originDest - the destination origin (top left to paste from!) + * @param originDest.x - the x origin of the paste + * @param originDest.y - the y origin of the paste + */ + copyToTexture(sourceRenderSurfaceTexture, destinationTexture, originSrc, size, originDest) { + if (originSrc.x < 0) { + size.width += originSrc.x; + originDest.x -= originSrc.x; + originSrc.x = 0; + } + if (originSrc.y < 0) { + size.height += originSrc.y; + originDest.y -= originSrc.y; + originSrc.y = 0; + } + const { pixelWidth, pixelHeight } = sourceRenderSurfaceTexture; + size.width = Math.min(size.width, pixelWidth - originSrc.x); + size.height = Math.min(size.height, pixelHeight - originSrc.y); + return this.adaptor.copyToTexture( + sourceRenderSurfaceTexture, + destinationTexture, + originSrc, + size, + originDest + ); + } + /** + * ensures that we have a depth stencil buffer available to render to + * This is used by the mask system to make sure we have a stencil buffer. + */ + ensureDepthStencil() { + if (!this.renderTarget.stencil) { + this.renderTarget.stencil = true; + this.adaptor.startRenderPass(this.renderTarget, false, null, this.viewport); + } + } + /** nukes the render target system */ + destroy() { + this._renderer = null; + this._renderSurfaceToRenderTargetHash.forEach((renderTarget, key) => { + if (renderTarget !== key) { + renderTarget.destroy(); + } + }); + this._renderSurfaceToRenderTargetHash.clear(); + this._gpuRenderTargetHash = /* @__PURE__ */ Object.create(null); + } + _initRenderTarget(renderSurface) { + let renderTarget = null; + if (CanvasSource.test(renderSurface)) { + renderSurface = getCanvasTexture(renderSurface); + } + if (renderSurface instanceof RenderTarget) { + renderTarget = renderSurface; + } else if (renderSurface instanceof TextureSource) { + renderTarget = new RenderTarget({ + colorTextures: [renderSurface] + }); + if (CanvasSource.test(renderSurface.source.resource)) { + renderTarget.isRoot = true; + } + renderSurface.on("destroy", () => { + renderTarget.destroy(); + }); + } + this._renderSurfaceToRenderTargetHash.set(renderSurface, renderTarget); + return renderTarget; + } + getGpuRenderTarget(renderTarget) { + return this._gpuRenderTargetHash[renderTarget.uid] || (this._gpuRenderTargetHash[renderTarget.uid] = this.adaptor.initGpuRenderTarget(renderTarget)); + } +} + +"use strict"; +class GlRenderTargetSystem extends RenderTargetSystem { + constructor(renderer) { + super(renderer); + this.adaptor = new GlRenderTargetAdaptor(); + this.adaptor.init(renderer, this); + } +} +/** @ignore */ +GlRenderTargetSystem.extension = { + type: [ExtensionType.WebGLSystem], + name: "renderTarget" +}; + +"use strict"; + +"use strict"; +class BufferResource extends EventEmitter { + /** + * Create a new Buffer Resource. + * @param options - The options for the buffer resource + * @param options.buffer - The underlying buffer that this resource is using + * @param options.offset - The offset of the buffer this resource is using. + * If not provided, then it will use the offset of the buffer. + * @param options.size - The size of the buffer this resource is using. + * If not provided, then it will use the size of the buffer. + */ + constructor({ buffer, offset, size }) { + super(); + /** + * emits when the underlying buffer has changed shape (i.e. resized) + * letting the renderer know that it needs to discard the old buffer on the GPU and create a new one + * @event change + */ + /** + * a unique id for this uniform group used through the renderer + * @internal + * @ignore + */ + this.uid = uid("buffer"); + /** + * a resource type, used to identify how to handle it when its in a bind group / shader resource + * @internal + * @ignore + */ + this._resourceType = "bufferResource"; + /** + * used internally to know if a uniform group was used in the last render pass + * @internal + * @ignore + */ + this._touched = 0; + /** + * the resource id used internally by the renderer to build bind group keys + * @internal + * @ignore + */ + this._resourceId = uid("resource"); + /** + * A cheeky hint to the GL renderer to let it know this is a BufferResource + * @internal + * @ignore + */ + this._bufferResource = true; + /** + * Has the Buffer resource been destroyed? + * @readonly + */ + this.destroyed = false; + this.buffer = buffer; + this.offset = offset | 0; + this.size = size; + this.buffer.on("change", this.onBufferChange, this); + } + onBufferChange() { + this._resourceId = uid("resource"); + this.emit("change", this); + } + /** + * Destroys this resource. Make sure the underlying buffer is not used anywhere else + * if you want to destroy it as well, or code will explode + * @param destroyBuffer - Should the underlying buffer be destroyed as well? + */ + destroy(destroyBuffer = false) { + this.destroyed = true; + if (destroyBuffer) { + this.buffer.destroy(); + } + this.emit("change", this); + this.buffer = null; + } +} + +"use strict"; +function generateShaderSyncCode(shader, shaderSystem) { + const funcFragments = []; + const headerFragments = [` var g = s.groups; var sS = r.shader; var p = s.glProgram; var ugS = r.uniformGroup; var resources; - `];let i=!1,n=0,o=0;const a=t._getProgramData(r.glProgram);for(const l in r.groups){const h=r.groups[l];e.push(` - resources = g[${l}].resources; - `);for(const c in h.resources){const d=h.resources[c];if(d instanceof it)d.ubo?e.push(` + `]; + let addedTextreSystem = false; + let blockIndex = 0; + let textureCount = 0; + const programData = shaderSystem._getProgramData(shader.glProgram); + for (const i in shader.groups) { + const group = shader.groups[i]; + funcFragments.push(` + resources = g[${i}].resources; + `); + for (const j in group.resources) { + const resource = group.resources[j]; + if (resource instanceof UniformGroup) { + if (resource.ubo) { + funcFragments.push(` sS.bindUniformBlock( - resources[${c}], - sS._uniformBindMap[${l}[${c}], - ${n++} + resources[${j}], + sS._uniformBindMap[${i}[${j}], + ${blockIndex++} ); - `):e.push(` - ugS.updateUniformGroup(resources[${c}], p, sD); - `);else if(d instanceof yi)e.push(` + `); + } else { + funcFragments.push(` + ugS.updateUniformGroup(resources[${j}], p, sD); + `); + } + } else if (resource instanceof BufferResource) { + funcFragments.push(` sS.bindUniformBlock( - resources[${c}], - sS._uniformBindMap[${l}[${c}], - ${n++} + resources[${j}], + sS._uniformBindMap[${i}[${j}], + ${blockIndex++} ); - `);else if(d instanceof et){const p=r._uniformBindMap[l][c],f=a.uniformData[p];f&&(i||(i=!0,s.push(` + `); + } else if (resource instanceof TextureSource) { + const uniformName = shader._uniformBindMap[i][j]; + const uniformData = programData.uniformData[uniformName]; + if (uniformData) { + if (!addedTextreSystem) { + addedTextreSystem = true; + headerFragments.push(` var tS = r.texture; - `)),t._gl.uniform1i(f.location,o),e.push(` - tS.bind(resources[${c}], ${o}); - `),o++)}}}const u=[...s,...e].join(` -`);return new Function("r","s","sD",u)}class y2{}class Rg{constructor(t,e){this.program=t,this.uniformData=e,this.uniformGroups={},this.uniformDirtyGroups={},this.uniformBlockBindings={}}destroy(){this.uniformData=null,this.uniformGroups=null,this.uniformDirtyGroups=null,this.uniformBlockBindings=null,this.program=null}}function Wa(r,t,e){const s=r.createShader(t);return r.shaderSource(s,e),r.compileShader(s),s}function Ya(r){const t=new Array(r);for(let e=0;eo>a?1:-1);for(let o=0;o`${h}: ${l}`),s=r.getShaderInfoLog(t),i=s.split(` -`),n={},o=i.map(l=>parseFloat(l.replace(/^ERROR\: 0\:([\d]+)\:.*$/,"$1"))).filter(l=>l&&!n[l]?(n[l]=!0,!0):!1),a=[""];o.forEach(l=>{e[l-1]=`%c${e[l-1]}%c`,a.push("background: #FF0000; color:#FFFFFF; font-size: 10px","font-size: 10px")});const u=e.join(` -`);a[0]=u,console.error(s),console.groupCollapsed("click to view full shader code"),console.warn(...a),console.groupEnd()}function Fg(r,t,e,s){r.getProgramParameter(t,r.LINK_STATUS)||(r.getShaderParameter(e,r.COMPILE_STATUS)||Bg(r,e),r.getShaderParameter(s,r.COMPILE_STATUS)||Bg(r,s),console.error("PixiJS Error: Could not initialize shader."),r.getProgramInfoLog(t)!==""&&console.warn("PixiJS Warning: gl.getProgramInfoLog()",r.getProgramInfoLog(t)))}function Dg(r,t){const e=Wa(r,r.VERTEX_SHADER,t.vertex),s=Wa(r,r.FRAGMENT_SHADER,t.fragment),i=r.createProgram();r.attachShader(i,e),r.attachShader(i,s);const n=t.transformFeedbackVaryings;n&&(typeof r.transformFeedbackVaryings!="function"||r.transformFeedbackVaryings(i,n.names,n.bufferMode==="separate"?r.SEPARATE_ATTRIBS:r.INTERLEAVED_ATTRIBS)),r.linkProgram(i),r.getProgramParameter(i,r.LINK_STATUS)||Fg(r,i,e,s),t._attributeData=Cg(i,r,!/^[ \t]*#[ \t]*version[ \t]+300[ \t]+es[ \t]*$/m.test(t.vertex)),t._uniformData=Ig(i,r),t._uniformBlockData=Gg(i,r),r.deleteShader(e),r.deleteShader(s);const o={};for(const a in t._uniformData){const u=t._uniformData[a];o[a]={location:r.getUniformLocation(i,a),value:Ka(u.type,u.size)}}return new Rg(i,o)}const Si={textureCount:0,blockIndex:0};class Za{constructor(t){this._activeProgram=null,this._programDataHash=Object.create(null),this._nextIndex=0,this._boundUniformsIdsToIndexHash=Object.create(null),this._boundIndexToUniformsHash=Object.create(null),this._shaderSyncFunctions=Object.create(null),this._renderer=t}contextChange(t){this._gl=t,this._maxBindings=t.MAX_UNIFORM_BUFFER_BINDINGS?t.getParameter(t.MAX_UNIFORM_BUFFER_BINDINGS):0,this._programDataHash=Object.create(null),this._boundUniformsIdsToIndexHash=Object.create(null),this._boundIndexToUniformsHash=Object.create(null),this._activeProgram=null}bind(t,e){if(this._setProgram(t.glProgram),e)return;Si.textureCount=0,Si.blockIndex=0;let s=this._shaderSyncFunctions[t.glProgram._key];s||(s=this._shaderSyncFunctions[t.glProgram._key]=this._generateShaderSync(t,this)),s(this._renderer,t,Si)}updateUniformGroup(t){this._renderer.uniformGroup.updateUniformGroup(t,this._activeProgram,Si)}bindUniformBlock(t,e,s=0){const i=this._renderer.buffer,n=this._getProgramData(this._activeProgram),o=t._bufferResource;o&&this._renderer.ubo.updateUniformGroup(t),i.updateBuffer(t.buffer);let a=this._boundUniformsIdsToIndexHash[t.uid];if(a===void 0){const h=this._nextIndex++%this._maxBindings,c=this._boundIndexToUniformsHash[h];c&&(this._boundUniformsIdsToIndexHash[c.uid]=void 0),a=this._boundUniformsIdsToIndexHash[t.uid]=h,this._boundIndexToUniformsHash[h]=t,o?i.bindBufferRange(t.buffer,h,t.offset):i.bindBufferBase(t.buffer,h)}const u=this._gl,l=this._activeProgram._uniformBlockData[e].index;n.uniformBlockBindings[s]!==a&&(n.uniformBlockBindings[s]=a,u.uniformBlockBinding(n.program,l,a))}_setProgram(t){if(this._activeProgram===t)return;this._activeProgram=t;const e=this._getProgramData(t);this._gl.useProgram(e.program)}_getProgramData(t){return this._programDataHash[t._key]||this._createProgramData(t)}_createProgramData(t){const e=t._key;return this._programDataHash[e]=Dg(this._gl,t),this._programDataHash[e]}destroy(){for(const t of Object.keys(this._programDataHash))this._programDataHash[t].destroy(),this._programDataHash[t]=null;this._programDataHash=null,this._boundUniformsIdsToIndexHash=null}_generateShaderSync(t,e){return wg(t,e)}}Za.extension={type:[v.WebGLSystem],name:"shader"};const Ug={f32:`if (cv !== v) { + `); + } + shaderSystem._gl.uniform1i(uniformData.location, textureCount); + funcFragments.push(` + tS.bind(resources[${j}], ${textureCount}); + `); + textureCount++; + } + } + } + } + const functionSource = [...headerFragments, ...funcFragments].join("\n"); + return new Function("r", "s", "sD", functionSource); +} + +"use strict"; +class IGLUniformData { +} +class GlProgramData { + /** + * Makes a new Pixi program. + * @param program - webgl program + * @param uniformData - uniforms + */ + constructor(program, uniformData) { + this.program = program; + this.uniformData = uniformData; + this.uniformGroups = {}; + this.uniformDirtyGroups = {}; + this.uniformBlockBindings = {}; + } + /** Destroys this program. */ + destroy() { + this.uniformData = null; + this.uniformGroups = null; + this.uniformDirtyGroups = null; + this.uniformBlockBindings = null; + this.program = null; + } +} + +"use strict"; +function compileShader(gl, type, src) { + const shader = gl.createShader(type); + gl.shaderSource(shader, src); + gl.compileShader(shader); + return shader; +} + +"use strict"; +function booleanArray(size) { + const array = new Array(size); + for (let i = 0; i < array.length; i++) { + array[i] = false; + } + return array; +} +function defaultValue(type, size) { + switch (type) { + case "float": + return 0; + case "vec2": + return new Float32Array(2 * size); + case "vec3": + return new Float32Array(3 * size); + case "vec4": + return new Float32Array(4 * size); + case "int": + case "uint": + case "sampler2D": + case "sampler2DArray": + return 0; + case "ivec2": + return new Int32Array(2 * size); + case "ivec3": + return new Int32Array(3 * size); + case "ivec4": + return new Int32Array(4 * size); + case "uvec2": + return new Uint32Array(2 * size); + case "uvec3": + return new Uint32Array(3 * size); + case "uvec4": + return new Uint32Array(4 * size); + case "bool": + return false; + case "bvec2": + return booleanArray(2 * size); + case "bvec3": + return booleanArray(3 * size); + case "bvec4": + return booleanArray(4 * size); + case "mat2": + return new Float32Array([ + 1, + 0, + 0, + 1 + ]); + case "mat3": + return new Float32Array([ + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1 + ]); + case "mat4": + return new Float32Array([ + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1 + ]); + } + return null; +} + +"use strict"; +let GL_TABLE = null; +const GL_TO_GLSL_TYPES = { + FLOAT: "float", + FLOAT_VEC2: "vec2", + FLOAT_VEC3: "vec3", + FLOAT_VEC4: "vec4", + INT: "int", + INT_VEC2: "ivec2", + INT_VEC3: "ivec3", + INT_VEC4: "ivec4", + UNSIGNED_INT: "uint", + UNSIGNED_INT_VEC2: "uvec2", + UNSIGNED_INT_VEC3: "uvec3", + UNSIGNED_INT_VEC4: "uvec4", + BOOL: "bool", + BOOL_VEC2: "bvec2", + BOOL_VEC3: "bvec3", + BOOL_VEC4: "bvec4", + FLOAT_MAT2: "mat2", + FLOAT_MAT3: "mat3", + FLOAT_MAT4: "mat4", + SAMPLER_2D: "sampler2D", + INT_SAMPLER_2D: "sampler2D", + UNSIGNED_INT_SAMPLER_2D: "sampler2D", + SAMPLER_CUBE: "samplerCube", + INT_SAMPLER_CUBE: "samplerCube", + UNSIGNED_INT_SAMPLER_CUBE: "samplerCube", + SAMPLER_2D_ARRAY: "sampler2DArray", + INT_SAMPLER_2D_ARRAY: "sampler2DArray", + UNSIGNED_INT_SAMPLER_2D_ARRAY: "sampler2DArray" +}; +const GLSL_TO_VERTEX_TYPES = { + float: "float32", + vec2: "float32x2", + vec3: "float32x3", + vec4: "float32x4", + int: "sint32", + ivec2: "sint32x2", + ivec3: "sint32x3", + ivec4: "sint32x4", + uint: "uint32", + uvec2: "uint32x2", + uvec3: "uint32x3", + uvec4: "uint32x4", + bool: "uint32", + bvec2: "uint32x2", + bvec3: "uint32x3", + bvec4: "uint32x4" +}; +function mapType(gl, type) { + if (!GL_TABLE) { + const typeNames = Object.keys(GL_TO_GLSL_TYPES); + GL_TABLE = {}; + for (let i = 0; i < typeNames.length; ++i) { + const tn = typeNames[i]; + GL_TABLE[gl[tn]] = GL_TO_GLSL_TYPES[tn]; + } + } + return GL_TABLE[type]; +} +function mapGlToVertexFormat(gl, type) { + const typeValue = mapType(gl, type); + return GLSL_TO_VERTEX_TYPES[typeValue] || "float32"; +} + +"use strict"; +function extractAttributesFromGlProgram(program, gl, sortAttributes = false) { + const attributes = {}; + const totalAttributes = gl.getProgramParameter(program, gl.ACTIVE_ATTRIBUTES); + for (let i = 0; i < totalAttributes; i++) { + const attribData = gl.getActiveAttrib(program, i); + if (attribData.name.startsWith("gl_")) { + continue; + } + const format = mapGlToVertexFormat(gl, attribData.type); + attributes[attribData.name] = { + location: 0, + // set further down.. + format, + stride: getAttributeInfoFromFormat(format).stride, + offset: 0, + instance: false, + start: 0 + }; + } + const keys = Object.keys(attributes); + if (sortAttributes) { + keys.sort((a, b) => a > b ? 1 : -1); + for (let i = 0; i < keys.length; i++) { + attributes[keys[i]].location = i; + gl.bindAttribLocation(program, i, keys[i]); + } + gl.linkProgram(program); + } else { + for (let i = 0; i < keys.length; i++) { + attributes[keys[i]].location = gl.getAttribLocation(program, keys[i]); + } + } + return attributes; +} + +"use strict"; +function getUboData(program, gl) { + if (!gl.ACTIVE_UNIFORM_BLOCKS) + return {}; + const uniformBlocks = {}; + const totalUniformsBlocks = gl.getProgramParameter(program, gl.ACTIVE_UNIFORM_BLOCKS); + for (let i = 0; i < totalUniformsBlocks; i++) { + const name = gl.getActiveUniformBlockName(program, i); + const uniformBlockIndex = gl.getUniformBlockIndex(program, name); + const size = gl.getActiveUniformBlockParameter(program, i, gl.UNIFORM_BLOCK_DATA_SIZE); + uniformBlocks[name] = { + name, + index: uniformBlockIndex, + size + }; + } + return uniformBlocks; +} + +"use strict"; +function getUniformData(program, gl) { + const uniforms = {}; + const totalUniforms = gl.getProgramParameter(program, gl.ACTIVE_UNIFORMS); + for (let i = 0; i < totalUniforms; i++) { + const uniformData = gl.getActiveUniform(program, i); + const name = uniformData.name.replace(/\[.*?\]$/, ""); + const isArray = !!uniformData.name.match(/\[.*?\]$/); + const type = mapType(gl, uniformData.type); + uniforms[name] = { + name, + index: i, + type, + size: uniformData.size, + isArray, + value: defaultValue(type, uniformData.size) + }; + } + return uniforms; +} + +"use strict"; +function logPrettyShaderError(gl, shader) { + const shaderSrc = gl.getShaderSource(shader).split("\n").map((line, index) => `${index}: ${line}`); + const shaderLog = gl.getShaderInfoLog(shader); + const splitShader = shaderLog.split("\n"); + const dedupe = {}; + const lineNumbers = splitShader.map((line) => parseFloat(line.replace(/^ERROR\: 0\:([\d]+)\:.*$/, "$1"))).filter((n) => { + if (n && !dedupe[n]) { + dedupe[n] = true; + return true; + } + return false; + }); + const logArgs = [""]; + lineNumbers.forEach((number) => { + shaderSrc[number - 1] = `%c${shaderSrc[number - 1]}%c`; + logArgs.push("background: #FF0000; color:#FFFFFF; font-size: 10px", "font-size: 10px"); + }); + const fragmentSourceToLog = shaderSrc.join("\n"); + logArgs[0] = fragmentSourceToLog; + console.error(shaderLog); + console.groupCollapsed("click to view full shader code"); + console.warn(...logArgs); + console.groupEnd(); +} +function logProgramError(gl, program, vertexShader, fragmentShader) { + if (!gl.getProgramParameter(program, gl.LINK_STATUS)) { + if (!gl.getShaderParameter(vertexShader, gl.COMPILE_STATUS)) { + logPrettyShaderError(gl, vertexShader); + } + if (!gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS)) { + logPrettyShaderError(gl, fragmentShader); + } + console.error("PixiJS Error: Could not initialize shader."); + if (gl.getProgramInfoLog(program) !== "") { + console.warn("PixiJS Warning: gl.getProgramInfoLog()", gl.getProgramInfoLog(program)); + } + } +} + +"use strict"; +function generateProgram(gl, program) { + const glVertShader = compileShader(gl, gl.VERTEX_SHADER, program.vertex); + const glFragShader = compileShader(gl, gl.FRAGMENT_SHADER, program.fragment); + const webGLProgram = gl.createProgram(); + gl.attachShader(webGLProgram, glVertShader); + gl.attachShader(webGLProgram, glFragShader); + const transformFeedbackVaryings = program.transformFeedbackVaryings; + if (transformFeedbackVaryings) { + if (typeof gl.transformFeedbackVaryings !== "function") { + warn(`TransformFeedback is not supported but TransformFeedbackVaryings are given.`); + } else { + gl.transformFeedbackVaryings( + webGLProgram, + transformFeedbackVaryings.names, + transformFeedbackVaryings.bufferMode === "separate" ? gl.SEPARATE_ATTRIBS : gl.INTERLEAVED_ATTRIBS + ); + } + } + gl.linkProgram(webGLProgram); + if (!gl.getProgramParameter(webGLProgram, gl.LINK_STATUS)) { + logProgramError(gl, webGLProgram, glVertShader, glFragShader); + } + program._attributeData = extractAttributesFromGlProgram( + webGLProgram, + gl, + !/^[ \t]*#[ \t]*version[ \t]+300[ \t]+es[ \t]*$/m.test(program.vertex) + ); + program._uniformData = getUniformData(webGLProgram, gl); + program._uniformBlockData = getUboData(webGLProgram, gl); + gl.deleteShader(glVertShader); + gl.deleteShader(glFragShader); + const uniformData = {}; + for (const i in program._uniformData) { + const data = program._uniformData[i]; + uniformData[i] = { + location: gl.getUniformLocation(webGLProgram, i), + value: defaultValue(data.type, data.size) + }; + } + const glProgram = new GlProgramData(webGLProgram, uniformData); + return glProgram; +} + +"use strict"; +const defaultSyncData = { + textureCount: 0, + blockIndex: 0 +}; +class GlShaderSystem { + constructor(renderer) { + /** + * @internal + * @private + */ + this._activeProgram = null; + this._programDataHash = /* @__PURE__ */ Object.create(null); + this._nextIndex = 0; + this._boundUniformsIdsToIndexHash = /* @__PURE__ */ Object.create(null); + this._boundIndexToUniformsHash = /* @__PURE__ */ Object.create(null); + this._shaderSyncFunctions = /* @__PURE__ */ Object.create(null); + this._renderer = renderer; + } + contextChange(gl) { + this._gl = gl; + this._maxBindings = gl.MAX_UNIFORM_BUFFER_BINDINGS ? gl.getParameter(gl.MAX_UNIFORM_BUFFER_BINDINGS) : 0; + this._programDataHash = /* @__PURE__ */ Object.create(null); + this._boundUniformsIdsToIndexHash = /* @__PURE__ */ Object.create(null); + this._boundIndexToUniformsHash = /* @__PURE__ */ Object.create(null); + this._activeProgram = null; + } + /** + * Changes the current shader to the one given in parameter. + * @param shader - the new shader + * @param skipSync - false if the shader should automatically sync its uniforms. + * @returns the glProgram that belongs to the shader. + */ + bind(shader, skipSync) { + this._setProgram(shader.glProgram); + if (skipSync) + return; + defaultSyncData.textureCount = 0; + defaultSyncData.blockIndex = 0; + let syncFunction = this._shaderSyncFunctions[shader.glProgram._key]; + if (!syncFunction) { + syncFunction = this._shaderSyncFunctions[shader.glProgram._key] = this._generateShaderSync(shader, this); + } + syncFunction(this._renderer, shader, defaultSyncData); + } + /** + * Updates the uniform group. + * @param uniformGroup - the uniform group to update + */ + updateUniformGroup(uniformGroup) { + this._renderer.uniformGroup.updateUniformGroup(uniformGroup, this._activeProgram, defaultSyncData); + } + /** + * Binds a uniform block to the shader. + * @param uniformGroup - the uniform group to bind + * @param name - the name of the uniform block + * @param index - the index of the uniform block + */ + bindUniformBlock(uniformGroup, name, index = 0) { + const bufferSystem = this._renderer.buffer; + const programData = this._getProgramData(this._activeProgram); + const isBufferResource = uniformGroup._bufferResource; + if (isBufferResource) { + this._renderer.ubo.updateUniformGroup(uniformGroup); + } + bufferSystem.updateBuffer(uniformGroup.buffer); + let boundIndex = this._boundUniformsIdsToIndexHash[uniformGroup.uid]; + if (boundIndex === void 0) { + const nextIndex = this._nextIndex++ % this._maxBindings; + const currentBoundUniformGroup = this._boundIndexToUniformsHash[nextIndex]; + if (currentBoundUniformGroup) { + this._boundUniformsIdsToIndexHash[currentBoundUniformGroup.uid] = void 0; + } + boundIndex = this._boundUniformsIdsToIndexHash[uniformGroup.uid] = nextIndex; + this._boundIndexToUniformsHash[nextIndex] = uniformGroup; + if (isBufferResource) { + bufferSystem.bindBufferRange(uniformGroup.buffer, nextIndex, uniformGroup.offset); + } else { + bufferSystem.bindBufferBase(uniformGroup.buffer, nextIndex); + } + } + const gl = this._gl; + const uniformBlockIndex = this._activeProgram._uniformBlockData[name].index; + if (programData.uniformBlockBindings[index] === boundIndex) + return; + programData.uniformBlockBindings[index] = boundIndex; + gl.uniformBlockBinding(programData.program, uniformBlockIndex, boundIndex); + } + _setProgram(program) { + if (this._activeProgram === program) + return; + this._activeProgram = program; + const programData = this._getProgramData(program); + this._gl.useProgram(programData.program); + } + /** + * @param program - the program to get the data for + * @internal + * @private + */ + _getProgramData(program) { + return this._programDataHash[program._key] || this._createProgramData(program); + } + _createProgramData(program) { + const key = program._key; + this._programDataHash[key] = generateProgram(this._gl, program); + return this._programDataHash[key]; + } + destroy() { + for (const key of Object.keys(this._programDataHash)) { + const programData = this._programDataHash[key]; + programData.destroy(); + this._programDataHash[key] = null; + } + this._programDataHash = null; + this._boundUniformsIdsToIndexHash = null; + } + /** + * Creates a function that can be executed that will sync the shader as efficiently as possible. + * Overridden by the unsafe eval package if you don't want eval used in your project. + * @param shader - the shader to generate the sync function for + * @param shaderSystem - the shader system to use + * @returns - the generated sync function + * @ignore + */ + _generateShaderSync(shader, shaderSystem) { + return generateShaderSyncCode(shader, shaderSystem); + } +} +/** @ignore */ +GlShaderSystem.extension = { + type: [ + ExtensionType.WebGLSystem + ], + name: "shader" +}; + +"use strict"; +const UNIFORM_TO_SINGLE_SETTERS = { + f32: `if (cv !== v) { cu.value = v; gl.uniform1f(location, v); - }`,"vec2":`if (cv[0] !== v[0] || cv[1] !== v[1]) { + }`, + "vec2": `if (cv[0] !== v[0] || cv[1] !== v[1]) { cv[0] = v[0]; cv[1] = v[1]; gl.uniform2f(location, v[0], v[1]); - }`,"vec3":`if (cv[0] !== v[0] || cv[1] !== v[1] || cv[2] !== v[2]) { + }`, + "vec3": `if (cv[0] !== v[0] || cv[1] !== v[1] || cv[2] !== v[2]) { cv[0] = v[0]; cv[1] = v[1]; cv[2] = v[2]; gl.uniform3f(location, v[0], v[1], v[2]); - }`,"vec4":`if (cv[0] !== v[0] || cv[1] !== v[1] || cv[2] !== v[2] || cv[3] !== v[3]) { + }`, + "vec4": `if (cv[0] !== v[0] || cv[1] !== v[1] || cv[2] !== v[2] || cv[3] !== v[3]) { cv[0] = v[0]; cv[1] = v[1]; cv[2] = v[2]; cv[3] = v[3]; gl.uniform4f(location, v[0], v[1], v[2], v[3]); - }`,i32:`if (cv !== v) { + }`, + i32: `if (cv !== v) { cu.value = v; gl.uniform1i(location, v); - }`,"vec2":`if (cv[0] !== v[0] || cv[1] !== v[1]) { + }`, + "vec2": `if (cv[0] !== v[0] || cv[1] !== v[1]) { cv[0] = v[0]; cv[1] = v[1]; gl.uniform2i(location, v[0], v[1]); - }`,"vec3":`if (cv[0] !== v[0] || cv[1] !== v[1] || cv[2] !== v[2]) { + }`, + "vec3": `if (cv[0] !== v[0] || cv[1] !== v[1] || cv[2] !== v[2]) { cv[0] = v[0]; cv[1] = v[1]; cv[2] = v[2]; gl.uniform3i(location, v[0], v[1], v[2]); - }`,"vec4":`if (cv[0] !== v[0] || cv[1] !== v[1] || cv[2] !== v[2] || cv[3] !== v[3]) { + }`, + "vec4": `if (cv[0] !== v[0] || cv[1] !== v[1] || cv[2] !== v[2] || cv[3] !== v[3]) { cv[0] = v[0]; cv[1] = v[1]; cv[2] = v[2]; cv[3] = v[3]; gl.uniform4i(location, v[0], v[1], v[2], v[3]); - }`,u32:`if (cv !== v) { + }`, + u32: `if (cv !== v) { cu.value = v; gl.uniform1ui(location, v); - }`,"vec2":`if (cv[0] !== v[0] || cv[1] !== v[1]) { + }`, + "vec2": `if (cv[0] !== v[0] || cv[1] !== v[1]) { cv[0] = v[0]; cv[1] = v[1]; gl.uniform2ui(location, v[0], v[1]); - }`,"vec3":`if (cv[0] !== v[0] || cv[1] !== v[1] || cv[2] !== v[2]) { + }`, + "vec3": `if (cv[0] !== v[0] || cv[1] !== v[1] || cv[2] !== v[2]) { cv[0] = v[0]; cv[1] = v[1]; cv[2] = v[2]; gl.uniform3ui(location, v[0], v[1], v[2]); - }`,"vec4":`if (cv[0] !== v[0] || cv[1] !== v[1] || cv[2] !== v[2] || cv[3] !== v[3]) { + }`, + "vec4": `if (cv[0] !== v[0] || cv[1] !== v[1] || cv[2] !== v[2] || cv[3] !== v[3]) { cv[0] = v[0]; cv[1] = v[1]; cv[2] = v[2]; cv[3] = v[3]; gl.uniform4ui(location, v[0], v[1], v[2], v[3]); - }`,bool:`if (cv !== v) { + }`, + bool: `if (cv !== v) { cu.value = v; gl.uniform1i(location, v); - }`,"vec2":`if (cv[0] !== v[0] || cv[1] !== v[1]) { + }`, + "vec2": `if (cv[0] !== v[0] || cv[1] !== v[1]) { cv[0] = v[0]; cv[1] = v[1]; gl.uniform2i(location, v[0], v[1]); - }`,"vec3":`if (cv[0] !== v[0] || cv[1] !== v[1] || cv[2] !== v[2]) { + }`, + "vec3": `if (cv[0] !== v[0] || cv[1] !== v[1] || cv[2] !== v[2]) { cv[0] = v[0]; cv[1] = v[1]; cv[2] = v[2]; gl.uniform3i(location, v[0], v[1], v[2]); - }`,"vec4":`if (cv[0] !== v[0] || cv[1] !== v[1] || cv[2] !== v[2] || cv[3] !== v[3]) { + }`, + "vec4": `if (cv[0] !== v[0] || cv[1] !== v[1] || cv[2] !== v[2] || cv[3] !== v[3]) { cv[0] = v[0]; cv[1] = v[1]; cv[2] = v[2]; cv[3] = v[3]; gl.uniform4i(location, v[0], v[1], v[2], v[3]); - }`,"mat2x2":"gl.uniformMatrix2fv(location, false, v);","mat3x3":"gl.uniformMatrix3fv(location, false, v);","mat4x4":"gl.uniformMatrix4fv(location, false, v);"},kg={f32:"gl.uniform1fv(location, v);","vec2":"gl.uniform2fv(location, v);","vec3":"gl.uniform3fv(location, v);","vec4":"gl.uniform4fv(location, v);","mat2x2":"gl.uniformMatrix2fv(location, false, v);","mat3x3":"gl.uniformMatrix3fv(location, false, v);","mat4x4":"gl.uniformMatrix4fv(location, false, v);",i32:"gl.uniform1iv(location, v);","vec2":"gl.uniform2iv(location, v);","vec3":"gl.uniform3iv(location, v);","vec4":"gl.uniform4iv(location, v);",u32:"gl.uniform1iv(location, v);","vec2":"gl.uniform2iv(location, v);","vec3":"gl.uniform3iv(location, v);","vec4":"gl.uniform4iv(location, v);",bool:"gl.uniform1iv(location, v);","vec2":"gl.uniform2iv(location, v);","vec3":"gl.uniform3iv(location, v);","vec4":"gl.uniform4iv(location, v);"};function Lg(r,t){const e=[` + }`, + "mat2x2": `gl.uniformMatrix2fv(location, false, v);`, + "mat3x3": `gl.uniformMatrix3fv(location, false, v);`, + "mat4x4": `gl.uniformMatrix4fv(location, false, v);` +}; +const UNIFORM_TO_ARRAY_SETTERS = { + f32: `gl.uniform1fv(location, v);`, + "vec2": `gl.uniform2fv(location, v);`, + "vec3": `gl.uniform3fv(location, v);`, + "vec4": `gl.uniform4fv(location, v);`, + "mat2x2": `gl.uniformMatrix2fv(location, false, v);`, + "mat3x3": `gl.uniformMatrix3fv(location, false, v);`, + "mat4x4": `gl.uniformMatrix4fv(location, false, v);`, + i32: `gl.uniform1iv(location, v);`, + "vec2": `gl.uniform2iv(location, v);`, + "vec3": `gl.uniform3iv(location, v);`, + "vec4": `gl.uniform4iv(location, v);`, + u32: `gl.uniform1iv(location, v);`, + "vec2": `gl.uniform2iv(location, v);`, + "vec3": `gl.uniform3iv(location, v);`, + "vec4": `gl.uniform4iv(location, v);`, + bool: `gl.uniform1iv(location, v);`, + "vec2": `gl.uniform2iv(location, v);`, + "vec3": `gl.uniform3iv(location, v);`, + "vec4": `gl.uniform4iv(location, v);` +}; + +"use strict"; +function generateUniformsSync(group, uniformData) { + const funcFragments = [` var v = null; var cv = null; var cu = null; var t = 0; var gl = renderer.gl; var name = null; - `];for(const s in r.uniforms){if(!t[s]){r.uniforms[s]instanceof it?r.uniforms[s].ubo?e.push(` - renderer.shader.bindUniformBlock(uv.${s}, "${s}"); - `):e.push(` - renderer.shader.updateUniformGroup(uv.${s}); - `):r.uniforms[s]instanceof yi&&e.push(` - renderer.shader.bindBufferResource(uv.${s}, "${s}"); - `);continue}const i=r.uniformStructures[s];let n=!1;for(let o=0;o>1,s++;this.stateId=t.data}for(let e=0;e>1,1),i=Math.max(i>>1,1)}}},Ja={id:"image",upload(r,t,e,s){const i=r.alphaMode==="premultiply-alpha-on-upload";e.pixelStorei(e.UNPACK_PREMULTIPLY_ALPHA_WEBGL,i);const n=t.width,o=t.height,a=r.pixelWidth,u=r.pixelHeight,l=r.resourceWidth,h=r.resourceHeight;l1){const l=Math.min(r.maxAnisotropy,t.getParameter(s.MAX_TEXTURE_MAX_ANISOTROPY_EXT));t[i](u,s.TEXTURE_MAX_ANISOTROPY_EXT,l)}r.compare&&t[i](u,t.TEXTURE_COMPARE_FUNC,Yg[r.compare])}function Kg(r){return{r8unorm:r.RED,r8snorm:r.RED,r8uint:r.RED,r8sint:r.RED,r16uint:r.RED,r16sint:r.RED,r16float:r.RED,rg8unorm:r.RG,rg8snorm:r.RG,rg8uint:r.RG,rg8sint:r.RG,r32uint:r.RED,r32sint:r.RED,r32float:r.RED,rg16uint:r.RG,rg16sint:r.RG,rg16float:r.RG,rgba8unorm:r.RGBA,"rgba8unorm-srgb":r.RGBA,rgba8snorm:r.RGBA,rgba8uint:r.RGBA,rgba8sint:r.RGBA,bgra8unorm:r.RGBA,"bgra8unorm-srgb":r.RGBA,rgb9e5ufloat:r.RGB,rgb10a2unorm:r.RGBA,rg11b10ufloat:r.RGB,rg32uint:r.RG,rg32sint:r.RG,rg32float:r.RG,rgba16uint:r.RGBA,rgba16sint:r.RGBA,rgba16float:r.RGBA,rgba32uint:r.RGBA,rgba32sint:r.RGBA,rgba32float:r.RGBA,stencil8:r.STENCIL_INDEX8,depth16unorm:r.DEPTH_COMPONENT,depth24plus:r.DEPTH_COMPONENT,"depth24plus-stencil8":r.DEPTH_STENCIL,depth32float:r.DEPTH_COMPONENT,"depth32float-stencil8":r.DEPTH_STENCIL}}var I2=Object.defineProperty,B2=Object.defineProperties,F2=Object.getOwnPropertyDescriptors,qg=Object.getOwnPropertySymbols,D2=Object.prototype.hasOwnProperty,U2=Object.prototype.propertyIsEnumerable,Zg=(r,t,e)=>t in r?I2(r,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):r[t]=e,Ee=(r,t)=>{for(var e in t||(t={}))D2.call(t,e)&&Zg(r,e,t[e]);if(qg)for(var e of qg(t))U2.call(t,e)&&Zg(r,e,t[e]);return r},k2=(r,t)=>B2(r,F2(t));function Qg(r,t){let e={},s=r.RGBA;return r instanceof X.get().getWebGL2RenderingContext()?(e={"rgba8unorm-srgb":r.SRGB8_ALPHA8,"bgra8unorm-srgb":r.SRGB8_ALPHA8},s=r.RGBA8):t.srgb&&(e={"rgba8unorm-srgb":t.srgb.SRGB8_ALPHA8_EXT,"bgra8unorm-srgb":t.srgb.SRGB8_ALPHA8_EXT}),Ee(Ee(Ee(Ee(Ee(Ee(k2(Ee({r8unorm:r.R8,r8snorm:r.R8_SNORM,r8uint:r.R8UI,r8sint:r.R8I,r16uint:r.R16UI,r16sint:r.R16I,r16float:r.R16F,rg8unorm:r.RG8,rg8snorm:r.RG8_SNORM,rg8uint:r.RG8UI,rg8sint:r.RG8I,r32uint:r.R32UI,r32sint:r.R32I,r32float:r.R32F,rg16uint:r.RG16UI,rg16sint:r.RG16I,rg16float:r.RG16F,rgba8unorm:r.RGBA},e),{rgba8snorm:r.RGBA8_SNORM,rgba8uint:r.RGBA8UI,rgba8sint:r.RGBA8I,bgra8unorm:s,rgb9e5ufloat:r.RGB9_E5,rgb10a2unorm:r.RGB10_A2,rg11b10ufloat:r.R11F_G11F_B10F,rg32uint:r.RG32UI,rg32sint:r.RG32I,rg32float:r.RG32F,rgba16uint:r.RGBA16UI,rgba16sint:r.RGBA16I,rgba16float:r.RGBA16F,rgba32uint:r.RGBA32UI,rgba32sint:r.RGBA32I,rgba32float:r.RGBA32F,stencil8:r.STENCIL_INDEX8,depth16unorm:r.DEPTH_COMPONENT16,depth24plus:r.DEPTH_COMPONENT24,"depth24plus-stencil8":r.DEPTH24_STENCIL8,depth32float:r.DEPTH_COMPONENT32F,"depth32float-stencil8":r.DEPTH32F_STENCIL8}),t.s3tc?{"bc1-rgba-unorm":t.s3tc.COMPRESSED_RGBA_S3TC_DXT1_EXT,"bc2-rgba-unorm":t.s3tc.COMPRESSED_RGBA_S3TC_DXT3_EXT,"bc3-rgba-unorm":t.s3tc.COMPRESSED_RGBA_S3TC_DXT5_EXT}:{}),t.s3tc_sRGB?{"bc1-rgba-unorm-srgb":t.s3tc_sRGB.COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT,"bc2-rgba-unorm-srgb":t.s3tc_sRGB.COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT,"bc3-rgba-unorm-srgb":t.s3tc_sRGB.COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT}:{}),t.rgtc?{"bc4-r-unorm":t.rgtc.COMPRESSED_RED_RGTC1_EXT,"bc4-r-snorm":t.rgtc.COMPRESSED_SIGNED_RED_RGTC1_EXT,"bc5-rg-unorm":t.rgtc.COMPRESSED_RED_GREEN_RGTC2_EXT,"bc5-rg-snorm":t.rgtc.COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT}:{}),t.bptc?{"bc6h-rgb-float":t.bptc.COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT,"bc6h-rgb-ufloat":t.bptc.COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT,"bc7-rgba-unorm":t.bptc.COMPRESSED_RGBA_BPTC_UNORM_EXT,"bc7-rgba-unorm-srgb":t.bptc.COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT}:{}),t.etc?{"etc2-rgb8unorm":t.etc.COMPRESSED_RGB8_ETC2,"etc2-rgb8unorm-srgb":t.etc.COMPRESSED_SRGB8_ETC2,"etc2-rgb8a1unorm":t.etc.COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2,"etc2-rgb8a1unorm-srgb":t.etc.COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2,"etc2-rgba8unorm":t.etc.COMPRESSED_RGBA8_ETC2_EAC,"etc2-rgba8unorm-srgb":t.etc.COMPRESSED_SRGB8_ALPHA8_ETC2_EAC,"eac-r11unorm":t.etc.COMPRESSED_R11_EAC,"eac-rg11unorm":t.etc.COMPRESSED_SIGNED_RG11_EAC}:{}),t.astc?{"astc-4x4-unorm":t.astc.COMPRESSED_RGBA_ASTC_4x4_KHR,"astc-4x4-unorm-srgb":t.astc.COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR,"astc-5x4-unorm":t.astc.COMPRESSED_RGBA_ASTC_5x4_KHR,"astc-5x4-unorm-srgb":t.astc.COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR,"astc-5x5-unorm":t.astc.COMPRESSED_RGBA_ASTC_5x5_KHR,"astc-5x5-unorm-srgb":t.astc.COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR,"astc-6x5-unorm":t.astc.COMPRESSED_RGBA_ASTC_6x5_KHR,"astc-6x5-unorm-srgb":t.astc.COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR,"astc-6x6-unorm":t.astc.COMPRESSED_RGBA_ASTC_6x6_KHR,"astc-6x6-unorm-srgb":t.astc.COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR,"astc-8x5-unorm":t.astc.COMPRESSED_RGBA_ASTC_8x5_KHR,"astc-8x5-unorm-srgb":t.astc.COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR,"astc-8x6-unorm":t.astc.COMPRESSED_RGBA_ASTC_8x6_KHR,"astc-8x6-unorm-srgb":t.astc.COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR,"astc-8x8-unorm":t.astc.COMPRESSED_RGBA_ASTC_8x8_KHR,"astc-8x8-unorm-srgb":t.astc.COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR,"astc-10x5-unorm":t.astc.COMPRESSED_RGBA_ASTC_10x5_KHR,"astc-10x5-unorm-srgb":t.astc.COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR,"astc-10x6-unorm":t.astc.COMPRESSED_RGBA_ASTC_10x6_KHR,"astc-10x6-unorm-srgb":t.astc.COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR,"astc-10x8-unorm":t.astc.COMPRESSED_RGBA_ASTC_10x8_KHR,"astc-10x8-unorm-srgb":t.astc.COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR,"astc-10x10-unorm":t.astc.COMPRESSED_RGBA_ASTC_10x10_KHR,"astc-10x10-unorm-srgb":t.astc.COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR,"astc-12x10-unorm":t.astc.COMPRESSED_RGBA_ASTC_12x10_KHR,"astc-12x10-unorm-srgb":t.astc.COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR,"astc-12x12-unorm":t.astc.COMPRESSED_RGBA_ASTC_12x12_KHR,"astc-12x12-unorm-srgb":t.astc.COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR}:{})}function Jg(r){return{r8unorm:r.UNSIGNED_BYTE,r8snorm:r.BYTE,r8uint:r.UNSIGNED_BYTE,r8sint:r.BYTE,r16uint:r.UNSIGNED_SHORT,r16sint:r.SHORT,r16float:r.HALF_FLOAT,rg8unorm:r.UNSIGNED_BYTE,rg8snorm:r.BYTE,rg8uint:r.UNSIGNED_BYTE,rg8sint:r.BYTE,r32uint:r.UNSIGNED_INT,r32sint:r.INT,r32float:r.FLOAT,rg16uint:r.UNSIGNED_SHORT,rg16sint:r.SHORT,rg16float:r.HALF_FLOAT,rgba8unorm:r.UNSIGNED_BYTE,"rgba8unorm-srgb":r.UNSIGNED_BYTE,rgba8snorm:r.BYTE,rgba8uint:r.UNSIGNED_BYTE,rgba8sint:r.BYTE,bgra8unorm:r.UNSIGNED_BYTE,"bgra8unorm-srgb":r.UNSIGNED_BYTE,rgb9e5ufloat:r.UNSIGNED_INT_5_9_9_9_REV,rgb10a2unorm:r.UNSIGNED_INT_2_10_10_10_REV,rg11b10ufloat:r.UNSIGNED_INT_10F_11F_11F_REV,rg32uint:r.UNSIGNED_INT,rg32sint:r.INT,rg32float:r.FLOAT,rgba16uint:r.UNSIGNED_SHORT,rgba16sint:r.SHORT,rgba16float:r.HALF_FLOAT,rgba32uint:r.UNSIGNED_INT,rgba32sint:r.INT,rgba32float:r.FLOAT,stencil8:r.UNSIGNED_BYTE,depth16unorm:r.UNSIGNED_SHORT,depth24plus:r.UNSIGNED_INT,"depth24plus-stencil8":r.UNSIGNED_INT_24_8,depth32float:r.FLOAT,"depth32float-stencil8":r.FLOAT_32_UNSIGNED_INT_24_8_REV}}function L2(r){r instanceof Uint8ClampedArray&&(r=new Uint8Array(r.buffer));const t=r.length;for(let e=0;e1,this._renderer.context.extensions.anisotropicFiltering,"texParameteri",s.TEXTURE_2D,!this._renderer.context.supports.nonPowOf2wrapping&&!t.isPowerOfTwo,e)}onSourceUnload(t){const e=this._glTextures[t.uid];e&&(this.unbind(t),this._glTextures[t.uid]=null,this._gl.deleteTexture(e.texture))}onSourceUpdate(t){const e=this._gl,s=this.getGlSource(t);e.bindTexture(e.TEXTURE_2D,s.texture),this._boundTextures[this._activeTextureLocation]=t,this._uploads[t.uploadMethodId]?this._uploads[t.uploadMethodId].upload(t,s,e,this._renderer.context.webGLVersion):e.texImage2D(e.TEXTURE_2D,0,e.RGBA,t.pixelWidth,t.pixelHeight,0,e.RGBA,e.UNSIGNED_BYTE,null),t.autoGenerateMipmaps&&t.mipLevelCount>1&&this.onUpdateMipmaps(t,!1)}onUpdateMipmaps(t,e=!0){e&&this.bindSource(t,0);const s=this.getGlSource(t);this._gl.generateMipmap(s.target)}onSourceDestroy(t){t.off("destroy",this.onSourceDestroy,this),t.off("update",this.onSourceUpdate,this),t.off("resize",this.onSourceUpdate,this),t.off("unload",this.onSourceUnload,this),t.off("styleChange",this.onStyleChange,this),t.off("updateMipmaps",this.onUpdateMipmaps,this),this.managedTextures.splice(this.managedTextures.indexOf(t),1),this.onSourceUnload(t)}_initSampler(t){const e=this._gl,s=this._gl.createSampler();return this._glSamplers[t._resourceId]=s,eu(t,e,this._boundTextures[this._activeTextureLocation].mipLevelCount>1,this._renderer.context.extensions.anisotropicFiltering,"samplerParameteri",s,!1,!0),this._glSamplers[t._resourceId]}_getGlSampler(t){return this._glSamplers[t._resourceId]||this._initSampler(t)}getGlSource(t){return this._glTextures[t.uid]||this._initSource(t)}generateCanvas(t){const{pixels:e,width:s,height:i}=this.getPixels(t),n=X.get().createCanvas();n.width=s,n.height=i;const o=n.getContext("2d");if(o){const a=o.createImageData(s,i);a.data.set(e),o.putImageData(a,0,0)}return n}getPixels(t){const e=t.source.resolution,s=t.frame,i=Math.max(Math.round(s.width*e),1),n=Math.max(Math.round(s.height*e),1),o=new Uint8Array($2*i*n),a=this._renderer,u=a.renderTarget.getRenderTarget(t),l=a.renderTarget.getGpuRenderTarget(u),h=a.gl;return h.bindFramebuffer(h.FRAMEBUFFER,l.resolveTargetFramebuffer),h.readPixels(Math.round(s.x*e),Math.round(s.y*e),i,n,h.RGBA,h.UNSIGNED_BYTE,o),{pixels:new Uint8ClampedArray(o.buffer),width:i,height:n}}destroy(){this.managedTextures.slice().forEach(t=>this.onSourceDestroy(t)),this.managedTextures=null,this._renderer=null}}ru.extension={type:[v.WebGLSystem],name:"texture"};class su{init(){const t=new it({uColor:{value:new Float32Array([1,1,1,1]),type:"vec4"},uTransformMatrix:{value:new G,type:"mat3x3"},uRound:{value:0,type:"f32"}}),e=ke({name:"graphics",bits:[ks,$s(wt),zs,$e]});this.shader=new St({glProgram:e,resources:{localUniforms:t,batchSamplers:Ns}})}execute(t,e){const s=e.context,i=s.customShader||this.shader,n=t.renderer,o=n.graphicsContext,{geometry:a,instructions:u}=o.getContextRenderData(s);i.groups[0]=n.globalUniforms.bindGroup,n.shader.bind(i),n.geometry.bind(a,i.glProgram);const l=u.instructions;for(let h=0;h",value:new G}}}})}execute(t,e){const s=t.renderer;let i=e._shader;if(i){if(!i.glProgram)return}else{i=this._shader;const n=e.texture,o=n.source;i.resources.uTexture=o,i.resources.uSampler=o.style,i.resources.textureUniforms.uniforms.uTextureMatrix=n.textureMatrix.mapCoord}i.groups[100]=s.globalUniforms.bindGroup,i.groups[101]=t.localUniformsBindGroup,s.encoder.draw({geometry:e._geometry,shader:i,state:e.state})}destroy(){this._shader.destroy(!0),this._shader=null}}iu.extension={type:[v.WebGLPipesAdaptor],name:"mesh"};class nu{constructor(t){this._renderer=t}addRenderable(t,e){this._renderer.renderPipes.batch.break(e),e.add(t)}execute(t){t.isRenderable&&t.render(this._renderer)}destroy(){this._renderer=null}}nu.extension={type:[v.WebGLPipes,v.WebGPUPipes,v.CanvasPipes],name:"customRender"};function ou(r,t){const e=r.instructionSet,s=e.instructions;for(let i=0;i1?1:e,r.worldAlpha=e,r.worldColorAlpha=r.worldColor+((e*255|0)<<24)}function hu(r,t,e){if(t===r.updateTick)return;r.updateTick=t,r.didChange=!1;const s=r.localTransform;r.updateLocalTransform();const i=r.parent;if(i&&!i.isRenderGroupRoot?(e=e|r._updateFlags,r.relativeGroupTransform.appendFrom(s,i.relativeGroupTransform),e&&e_(r,i,e)):(e=r._updateFlags,r.relativeGroupTransform.copyFrom(s),e&&e_(r,N2,e)),!r.isRenderGroupRoot){const n=r.children,o=n.length;for(let u=0;u1?1:s,r.groupAlpha=s,r.groupColorAlpha=r.groupColor+((s*255|0)<<24)}e&Qi&&(r.groupBlendMode=r.localBlendMode==="inherit"?t.groupBlendMode:r.localBlendMode),e&ar&&(r.globalDisplayStatus=r.localDisplayStatus&t.globalDisplayStatus),r._updateFlags=0}function r_(r,t){const{list:e,index:s}=r.childrenRenderablesToUpdate;let i=!1;for(let n=0;n{this.destroyRenderable(t)}),e}destroy(){for(const t in this._gpuSpriteHash)H.return(this._gpuSpriteHash[t]);this._gpuSpriteHash=null,this._renderer=null}}du.extension={type:[v.WebGLPipes,v.WebGPUPipes,v.CanvasPipes],name:"sprite"};var z2=Object.defineProperty,s_=Object.getOwnPropertySymbols,j2=Object.prototype.hasOwnProperty,V2=Object.prototype.propertyIsEnumerable,i_=(r,t,e)=>t in r?z2(r,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):r[t]=e,n_=(r,t)=>{for(var e in t||(t={}))j2.call(t,e)&&i_(r,e,t[e]);if(s_)for(var e of s_(t))V2.call(t,e)&&i_(r,e,t[e]);return r};const pu=class kx{constructor(){this.clearBeforeRender=!0,this._backgroundColor=new W(0),this.color=this._backgroundColor,this.alpha=1}init(t){t=n_(n_({},kx.defaultOptions),t),this.clearBeforeRender=t.clearBeforeRender,this.color=t.background||t.backgroundColor||this._backgroundColor,this.alpha=t.backgroundAlpha,this._backgroundColor.setAlpha(t.backgroundAlpha)}get color(){return this._backgroundColor}set color(t){this._backgroundColor.setValue(t)}get alpha(){return this._backgroundColor.alpha}set alpha(t){this._backgroundColor.setAlpha(t)}get colorRgba(){return this._backgroundColor.toArray()}destroy(){}};pu.extension={type:[v.WebGLSystem,v.WebGPUSystem,v.CanvasSystem],name:"background",priority:0},pu.defaultOptions={backgroundAlpha:1,backgroundColor:0,clearBeforeRender:!0};let o_=pu;const zr={};D.handle(v.BlendMode,r=>{if(!r.name)throw new Error("BlendMode extension must have a name property");zr[r.name]=r.ref},r=>{delete zr[r.name]});class fu{constructor(t){this._isAdvanced=!1,this._filterHash=Object.create(null),this._renderer=t}setBlendMode(t,e,s){if(this._activeBlendMode===e){this._isAdvanced&&this._renderableList.push(t);return}this._activeBlendMode=e,this._isAdvanced&&this._endAdvancedBlendMode(s),this._isAdvanced=!!zr[e],this._isAdvanced&&(this._beginAdvancedBlendMode(s),this._renderableList.push(t))}_beginAdvancedBlendMode(t){this._renderer.renderPipes.batch.break(t);const e=this._activeBlendMode;if(!zr[e])return;this._filterHash[e]||(this._filterHash[e]=new ts({filters:[new zr[e]]}));const s={renderPipeId:"filter",action:"pushFilter",renderables:[],filterEffect:this._filterHash[e],canBundle:!1};this._renderableList=s.renderables,t.add(s)}_endAdvancedBlendMode(t){this._renderableList=null,this._renderer.renderPipes.batch.break(t),t.add({renderPipeId:"filter",action:"popFilter",canBundle:!1})}buildStart(){this._isAdvanced=!1}buildEnd(t){this._isAdvanced&&this._endAdvancedBlendMode(t)}destroy(){this._renderer=null,this._renderableList=null;for(const t in this._filterHash)this._filterHash[t].destroy();this._filterHash=null}}fu.extension={type:[v.WebGLPipes,v.WebGPUPipes,v.CanvasPipes],name:"blendMode"};var W2=Object.defineProperty,a_=Object.getOwnPropertySymbols,Y2=Object.prototype.hasOwnProperty,K2=Object.prototype.propertyIsEnumerable,u_=(r,t,e)=>t in r?W2(r,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):r[t]=e,mu=(r,t)=>{for(var e in t||(t={}))Y2.call(t,e)&&u_(r,e,t[e]);if(a_)for(var e of a_(t))K2.call(t,e)&&u_(r,e,t[e]);return r};const gu={png:"image/png",jpg:"image/jpeg",webp:"image/webp"},_u=class Lx{constructor(t){this._renderer=t}_normalizeOptions(t,e={}){return t instanceof V||t instanceof A?mu({target:t},e):mu(mu({},e),t)}async image(t){const e=new Image;return e.src=await this.base64(t),e}async base64(t){t=this._normalizeOptions(t,Lx.defaultImageOptions);const{format:e,quality:s}=t,i=this.canvas(t);if(i.toBlob!==void 0)return new Promise((n,o)=>{i.toBlob(a=>{if(!a){o(new Error("ICanvas.toBlob failed!"));return}const u=new FileReader;u.onload=()=>n(u.result),u.onerror=o,u.readAsDataURL(a)},gu[e],s)});if(i.toDataURL!==void 0)return i.toDataURL(gu[e],s);if(i.convertToBlob!==void 0){const n=await i.convertToBlob({type:gu[e],quality:s});return new Promise((o,a)=>{const u=new FileReader;u.onload=()=>o(u.result),u.onerror=a,u.readAsDataURL(n)})}throw new Error("Extract.base64() requires ICanvas.toDataURL, ICanvas.toBlob, or ICanvas.convertToBlob to be implemented")}canvas(t){t=this._normalizeOptions(t);const e=t.target,s=this._renderer;if(e instanceof A)return s.texture.generateCanvas(e);const i=s.textureGenerator.generateTexture(t),n=s.texture.generateCanvas(i);return i.destroy(),n}pixels(t){t=this._normalizeOptions(t);const e=t.target,s=this._renderer,i=e instanceof A?e:s.textureGenerator.generateTexture(t),n=s.texture.getPixels(i);return e instanceof V&&i.destroy(),n}texture(t){return t=this._normalizeOptions(t),t.target instanceof A?t.target:this._renderer.textureGenerator.generateTexture(t)}download(t){var e;t=this._normalizeOptions(t);const s=this.canvas(t),i=document.createElement("a");i.download=(e=t.filename)!=null?e:"image.png",i.href=s.toDataURL("image/png"),document.body.appendChild(i),i.click(),document.body.removeChild(i)}log(t){var e;const s=(e=t.width)!=null?e:200;t=this._normalizeOptions(t);const i=this.canvas(t),n=i.toDataURL();console.log(`[Pixi Texture] ${i.width}px ${i.height}px`);const o=["font-size: 1px;",`padding: ${s}px 300px;`,`background: url(${n}) no-repeat;`,"background-size: contain;"].join(" ");console.log("%c ",o)}destroy(){this._renderer=null}};_u.extension={type:[v.WebGLSystem,v.WebGPUSystem],name:"extract"},_u.defaultImageOptions={format:"png",quality:1};let l_=_u;class h_ extends A{static create(t){return new A({source:new et(t)})}resize(t,e,s){return this.source.resize(t,e,s),this}}var q2=Object.defineProperty,Z2=Object.defineProperties,Q2=Object.getOwnPropertyDescriptors,c_=Object.getOwnPropertySymbols,J2=Object.prototype.hasOwnProperty,tE=Object.prototype.propertyIsEnumerable,d_=(r,t,e)=>t in r?q2(r,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):r[t]=e,eE=(r,t)=>{for(var e in t||(t={}))J2.call(t,e)&&d_(r,e,t[e]);if(c_)for(var e of c_(t))tE.call(t,e)&&d_(r,e,t[e]);return r},rE=(r,t)=>Z2(r,Q2(t));const sE=new z,iE=new lt,nE=[0,0,0,0];class xu{constructor(t){this._renderer=t}generateTexture(t){var e;t instanceof V&&(t={target:t,frame:void 0,textureSourceOptions:{},resolution:void 0});const s=t.resolution||this._renderer.resolution,i=t.antialias||this._renderer.view.antialias,n=t.target;let o=t.clearColor;o?o=Array.isArray(o)&&o.length===4?o:W.shared.setValue(o).toArray():o=nE;const a=((e=t.frame)==null?void 0:e.copyTo(sE))||is(n,iE).rectangle;a.width=Math.max(a.width,1/s)|0,a.height=Math.max(a.height,1/s)|0;const u=h_.create(rE(eE({},t.textureSourceOptions),{width:a.width,height:a.height,resolution:s,antialias:i})),l=G.shared.translate(-a.x,-a.y);return this._renderer.render({container:n,transform:l,target:u,clearColor:o}),u}destroy(){this._renderer=null}}xu.extension={type:[v.WebGLSystem,v.WebGPUSystem],name:"textureGenerator"};class bu{constructor(t){this._stackIndex=0,this._globalUniformDataStack=[],this._uniformsPool=[],this._activeUniforms=[],this._bindGroupPool=[],this._activeBindGroups=[],this._renderer=t}reset(){this._stackIndex=0;for(let t=0;t"},uWorldTransformMatrix:{value:new G,type:"mat3x3"},uWorldColorAlpha:{value:new Float32Array(4),type:"vec4"},uResolution:{value:[0,0],type:"vec2"}},{isStatic:!0})}destroy(){this._renderer=null}}bu.extension={type:[v.WebGLSystem,v.WebGPUSystem,v.CanvasSystem],name:"globalUniforms"};let p_=!1;const vu="8.0.5";function f_(r){if(!p_){if(X.get().getNavigator().userAgent.toLowerCase().indexOf("chrome")>-1){const t=[`%c %c %c %c %c PixiJS %c v${vu} (${r}) http://www.pixijs.com/ + v = uv["${i}"]; + ${template};`); + } + } + return new Function("ud", "uv", "renderer", "syncData", funcFragments.join("\n")); +} -`,"background: #E72264; padding:5px 0;","background: #6CA2EA; padding:5px 0;","background: #B5D33D; padding:5px 0;","background: #FED23F; padding:5px 0;","color: #FFFFFF; background: #E72264; padding:5px 0;","color: #E72264; background: #FFFFFF; padding:5px 0;"];globalThis.console.log(...t)}else globalThis.console&&globalThis.console.log(`PixiJS ${vu} - ${r} - http://www.pixijs.com/`);p_=!0}}class Ai{constructor(t){this._renderer=t}init(t){if(t.hello){let e=this._renderer.name;this._renderer.type===xt.WEBGL&&(e+=` ${this._renderer.context.webGLVersion}`),f_(e)}}}Ai.extension={type:[v.WebGLSystem,v.WebGPUSystem,v.CanvasSystem],name:"hello",priority:-2},Ai.defaultOptions={hello:!1};var oE=Object.defineProperty,m_=Object.getOwnPropertySymbols,aE=Object.prototype.hasOwnProperty,uE=Object.prototype.propertyIsEnumerable,g_=(r,t,e)=>t in r?oE(r,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):r[t]=e,__=(r,t)=>{for(var e in t||(t={}))aE.call(t,e)&&g_(r,e,t[e]);if(m_)for(var e of m_(t))uE.call(t,e)&&g_(r,e,t[e]);return r};const yu=class $x{constructor(t){this._renderer=t,this.count=0,this.checkCount=0}init(t){t=__(__({},$x.defaultOptions),t),this.checkCountMax=t.textureGCCheckCountMax,this.maxIdle=t.textureGCAMaxIdle,this.active=t.textureGCActive}postrender(){this._renderer.renderingToScreen&&(this.count++,this.active&&(this.checkCount++,this.checkCount>this.checkCountMax&&(this.checkCount=0,this.run())))}run(){const t=this._renderer.texture.managedTextures;for(let e=0;e-1&&this.count-s._touched>this.maxIdle&&(s._touched=-1,s.unload())}}destroy(){this._renderer=null}};yu.extension={type:[v.WebGLSystem,v.WebGPUSystem],name:"textureGC"},yu.defaultOptions={textureGCActive:!0,textureGCAMaxIdle:60*60,textureGCCheckCountMax:600};let Tu=yu;D.add(Tu);var lE=Object.defineProperty,x_=Object.getOwnPropertySymbols,hE=Object.prototype.hasOwnProperty,cE=Object.prototype.propertyIsEnumerable,b_=(r,t,e)=>t in r?lE(r,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):r[t]=e,v_=(r,t)=>{for(var e in t||(t={}))hE.call(t,e)&&b_(r,e,t[e]);if(x_)for(var e of x_(t))cE.call(t,e)&&b_(r,e,t[e]);return r};const Su=class Nx{get resolution(){return this.texture.source._resolution}set resolution(t){this.texture.source.resize(this.texture.source.width,this.texture.source.height,t)}init(t){t=v_(v_({},Nx.defaultOptions),t),t.view&&(t.canvas=t.view),this.screen=new z(0,0,t.width,t.height),this.canvas=t.canvas||X.get().createCanvas(),this.antialias=!!t.antialias,this.texture=za(this.canvas,t),this.renderTarget=new vi({colorTextures:[this.texture],depth:!!t.depth,isRoot:!0}),this.texture.source.transparent=t.backgroundAlpha<1,this.multiView=!!t.multiView,this.autoDensity&&(this.canvas.style.width=`${this.texture.width}px`,this.canvas.style.height=`${this.texture.height}px`),this.resolution=t.resolution}resize(t,e,s){this.texture.source.resize(t,e,s),this.screen.width=this.texture.frame.width,this.screen.height=this.texture.frame.height,this.autoDensity&&(this.canvas.style.width=`${t}px`,this.canvas.style.height=`${e}px`)}destroy(t=!1){(typeof t=="boolean"?t:t!=null&&t.removeView)&&this.canvas.parentNode&&this.canvas.parentNode.removeChild(this.canvas)}};Su.extension={type:[v.WebGLSystem,v.WebGPUSystem,v.CanvasSystem],name:"view",priority:0},Su.defaultOptions={width:800,height:600,autoDensity:!1,antialias:!1};let y_=Su;const Eu=[o_,bu,Ai,y_,cu,Tu,xu,l_],Au=[fu,Aa,du,au,Pa,Ra,wa,nu],dE=[...Eu,Xa,hg,rg,Ma,ru,Va,Ba,Qa,Za,Ua,Hg,ka,Da],pE=[...Au],fE=[Sa,iu,su],T_=[],S_=[],E_=[];D.handleByNamedList(v.WebGLSystem,T_),D.handleByNamedList(v.WebGLPipes,S_),D.handleByNamedList(v.WebGLPipesAdaptor,E_),D.add(...dE,...pE,...fE);class A_ extends Or{constructor(){const t={name:"webgl",type:xt.WEBGL,systems:T_,renderPipes:S_,renderPipeAdaptors:E_};super(t)}}var mE={__proto__:null,WebGLRenderer:A_};class Pu{constructor(t){this._hash=Object.create(null),this._renderer=t}contextChange(t){this._gpu=t}getBindGroup(t,e,s){return t._updateKey(),this._hash[t._key]||this._createBindGroup(t,e,s)}_createBindGroup(t,e,s){var i;const n=this._gpu.device,o=e.layout[s],a=[],u=this._renderer;for(const c in o){const d=(i=t.resources[c])!=null?i:t.resources[o[c]];let p;if(d._resourceType==="uniformGroup"){const f=d;u.ubo.updateUniformGroup(f);const g=f.buffer;p={buffer:u.buffer.getGPUBuffer(g),offset:0,size:g.descriptor.size}}else if(d._resourceType==="buffer"){const f=d;p={buffer:u.buffer.getGPUBuffer(f),offset:0,size:f.descriptor.size}}else if(d._resourceType==="bufferResource"){const f=d;p={buffer:u.buffer.getGPUBuffer(f.buffer),offset:f.offset,size:f.size}}else if(d._resourceType==="textureSampler"){const f=d;p=u.texture.getGpuSampler(f)}else if(d._resourceType==="textureSource"){const f=d;p=u.texture.getGpuSource(f).createView({})}a.push({binding:o[c],resource:p})}const l=u.shader.getProgramData(e).bindGroups[s],h=n.createBindGroup({layout:l,entries:a});return this._hash[t._key]=h,h}destroy(){for(const t of Object.keys(this._hash))this._hash[t]=null;this._hash=null,this._renderer=null}}Pu.extension={type:[v.WebGPUSystem],name:"bindGroup"};class wu{constructor(){this._gpuBuffers=Object.create(null),this._managedBuffers=[]}contextChange(t){this._gpu=t}getGPUBuffer(t){return this._gpuBuffers[t.uid]||this.createGPUBuffer(t)}updateBuffer(t){const e=this._gpuBuffers[t.uid]||this.createGPUBuffer(t),s=t.data;return t._updateID&&s&&(t._updateID=0,this._gpu.device.queue.writeBuffer(e,0,s.buffer,0,(t._updateSize||s.byteLength)+3&-4)),e}destroyAll(){for(const t in this._gpuBuffers)this._gpuBuffers[t].destroy();this._gpuBuffers={}}createGPUBuffer(t){this._gpuBuffers[t.uid]||(t.on("update",this.updateBuffer,this),t.on("change",this.onBufferChange,this),t.on("destroy",this.onBufferDestroy,this));const e=this._gpu.device.createBuffer(t.descriptor);return t._updateID=0,t.data&&(_s(t.data.buffer,e.getMappedRange()),e.unmap()),this._gpuBuffers[t.uid]=e,this._managedBuffers.push(t),e}onBufferChange(t){this._gpuBuffers[t.uid].destroy(),t._updateID=0,this._gpuBuffers[t.uid]=this.createGPUBuffer(t)}onBufferDestroy(t){this._managedBuffers.splice(this._managedBuffers.indexOf(t),1),this._destroyBuffer(t)}destroy(){this._managedBuffers.forEach(t=>this._destroyBuffer(t)),this._managedBuffers=null,this._gpuBuffers=null}_destroyBuffer(t){this._gpuBuffers[t.uid].destroy(),t.off("update",this.updateBuffer,this),t.off("change",this.onBufferChange,this),t.off("destroy",this.onBufferDestroy,this),this._gpuBuffers[t.uid]=null}}wu.extension={type:[v.WebGPUSystem],name:"buffer"};function gE(r,t){const e=r.descriptor.size,s=t.gpu.device,i=new _t({data:new Float32Array(24e5),usage:$.MAP_READ|$.COPY_DST}),n=t.buffer.createGPUBuffer(i),o=s.createCommandEncoder();o.copyBufferToBuffer(t.buffer.getGPUBuffer(r),0,n,0,e),s.queue.submit([o.finish()]),n.mapAsync(GPUMapMode.READ,0,e).then(()=>{n.getMappedRange(0,e),n.unmap()})}class P_{constructor({minUniformOffsetAlignment:t}){this._minUniformOffsetAlignment=256,this.byteIndex=0,this._minUniformOffsetAlignment=t,this.data=new Float32Array(65535)}clear(){this.byteIndex=0}addEmptyGroup(t){if(t>this._minUniformOffsetAlignment/4)throw new Error(`UniformBufferBatch: array is too large: ${t*4}`);const e=this.byteIndex;let s=e+t*4;if(s=Math.ceil(s/this._minUniformOffsetAlignment)*this._minUniformOffsetAlignment,s>this.data.length*4)throw new Error("UniformBufferBatch: ubo batch got too big");return this.byteIndex=s,e}addGroup(t){const e=this.addEmptyGroup(t.length);for(let s=0;s{this.gpu=e,this._renderer.runners.contextChange.emit(this.gpu)}),this._initPromise)}contextChange(t){this._renderer.gpu=t}async _createDeviceAndAdaptor(t){const e=await navigator.gpu.requestAdapter({powerPreference:t.powerPreference,forceFallbackAdapter:t.forceFallbackAdapter}),s=["texture-compression-bc","texture-compression-astc","texture-compression-etc2"].filter(n=>e.features.has(n)),i=await e.requestDevice({requiredFeatures:s});return{adapter:e,device:i}}destroy(){this.gpu=null,this._renderer=null}}Pi.extension={type:[v.WebGPUSystem],name:"device"},Pi.defaultOptions={powerPreference:void 0,forceFallbackAdapter:!1};var _E=Object.defineProperty,w_=Object.getOwnPropertySymbols,xE=Object.prototype.hasOwnProperty,bE=Object.prototype.propertyIsEnumerable,R_=(r,t,e)=>t in r?_E(r,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):r[t]=e,M_=(r,t)=>{for(var e in t||(t={}))xE.call(t,e)&&R_(r,e,t[e]);if(w_)for(var e of w_(t))bE.call(t,e)&&R_(r,e,t[e]);return r};class Mu{constructor(t){this._boundBindGroup=Object.create(null),this._boundVertexBuffer=Object.create(null),this._renderer=t}renderStart(){this.commandFinished=new Promise(t=>{this._resolveCommandFinished=t}),this.commandEncoder=this._renderer.gpu.device.createCommandEncoder()}beginRenderPass(t){this.endRenderPass(),this._clearCache(),this.renderPassEncoder=this.commandEncoder.beginRenderPass(t.descriptor)}endRenderPass(){this.renderPassEncoder&&this.renderPassEncoder.end(),this.renderPassEncoder=null}setViewport(t){this.renderPassEncoder.setViewport(t.x,t.y,t.width,t.height,0,1)}setPipelineFromGeometryProgramAndState(t,e,s,i){const n=this._renderer.pipeline.getPipeline(t,e,s,i);this.setPipeline(n)}setPipeline(t){this._boundPipeline!==t&&(this._boundPipeline=t,this.renderPassEncoder.setPipeline(t))}_setVertexBuffer(t,e){this._boundVertexBuffer[t]!==e&&(this._boundVertexBuffer[t]=e,this.renderPassEncoder.setVertexBuffer(t,this._renderer.buffer.updateBuffer(e)))}_setIndexBuffer(t){if(this._boundIndexBuffer===t)return;this._boundIndexBuffer=t;const e=t.data.BYTES_PER_ELEMENT===2?"uint16":"uint32";this.renderPassEncoder.setIndexBuffer(this._renderer.buffer.updateBuffer(t),e)}resetBindGroup(t){this._boundBindGroup[t]=null}setBindGroup(t,e,s){if(this._boundBindGroup[t]===e)return;this._boundBindGroup[t]=e,e._touch(this._renderer.textureGC.count);const i=this._renderer.bindGroup.getBindGroup(e,s,t);this.renderPassEncoder.setBindGroup(t,i)}setGeometry(t){for(const e in t.attributes){const s=t.attributes[e];this._setVertexBuffer(s.location,s.buffer)}t.indexBuffer&&this._setIndexBuffer(t.indexBuffer)}_setShaderBindGroups(t,e){for(const s in t.groups){const i=t.groups[s];e||this._syncBindGroup(i),this.setBindGroup(s,i,t.gpuProgram)}}_syncBindGroup(t){for(const e in t.resources){const s=t.resources[e];s.isUniformGroup&&this._renderer.ubo.updateUniformGroup(s)}}draw(t){const{geometry:e,shader:s,state:i,topology:n,size:o,start:a,instanceCount:u,skipSync:l}=t;this.setPipelineFromGeometryProgramAndState(e,s.gpuProgram,i,n),this.setGeometry(e),this._setShaderBindGroups(s,l),e.indexBuffer?this.renderPassEncoder.drawIndexed(o||e.indexBuffer.data.length,u||e.instanceCount,a||0):this.renderPassEncoder.draw(o||e.getSize(),u||e.instanceCount,a||0)}finishRenderPass(){this.renderPassEncoder&&(this.renderPassEncoder.end(),this.renderPassEncoder=null)}postrender(){this.finishRenderPass(),this._gpu.device.queue.submit([this.commandEncoder.finish()]),this._resolveCommandFinished(),this.commandEncoder=null}restoreRenderPass(){const t=this._renderer.renderTarget.adaptor.getDescriptor(this._renderer.renderTarget.renderTarget,!1,[0,0,0,1]);this.renderPassEncoder=this.commandEncoder.beginRenderPass(t);const e=this._boundPipeline,s=M_({},this._boundVertexBuffer),i=this._boundIndexBuffer,n=M_({},this._boundBindGroup);this._clearCache();const o=this._renderer.renderTarget.viewport;this.renderPassEncoder.setViewport(o.x,o.y,o.width,o.height,0,1),this.setPipeline(e);for(const a in s)this._setVertexBuffer(a,s[a]);for(const a in n)this.setBindGroup(a,n[a],null);this._setIndexBuffer(i)}_clearCache(){for(let t=0;t<16;t++)this._boundBindGroup[t]=null,this._boundVertexBuffer[t]=null;this._boundIndexBuffer=null,this._boundPipeline=null}destroy(){this._renderer=null,this._gpu=null,this._boundBindGroup=null,this._boundVertexBuffer=null,this._boundIndexBuffer=null,this._boundPipeline=null}contextChange(t){this._gpu=t}}Mu.extension={type:[v.WebGPUSystem],name:"encoder",priority:1};class Ou{constructor(t){this._renderTargetStencilState=Object.create(null),this._renderer=t,t.renderTarget.onRenderTargetChange.add(this)}onRenderTargetChange(t){let e=this._renderTargetStencilState[t.uid];e||(e=this._renderTargetStencilState[t.uid]={stencilMode:st.DISABLED,stencilReference:0}),this._activeRenderTarget=t,this.setStencilMode(e.stencilMode,e.stencilReference)}setStencilMode(t,e){const s=this._renderTargetStencilState[this._activeRenderTarget.uid];s.stencilMode=t,s.stencilReference=e;const i=this._renderer;i.pipeline.setStencilMode(t),i.encoder.renderPassEncoder.setStencilReference(e)}destroy(){this._renderer.renderTarget.onRenderTargetChange.remove(this),this._renderer=null,this._activeRenderTarget=null,this._renderTargetStencilState=null}}Ou.extension={type:[v.WebGPUSystem],name:"stencil"};const jr={i32:{align:4,size:4},u32:{align:4,size:4},f32:{align:4,size:4},f16:{align:2,size:2},"vec2":{align:8,size:8},"vec2":{align:8,size:8},"vec2":{align:8,size:8},"vec2":{align:4,size:4},"vec3":{align:16,size:12},"vec3":{align:16,size:12},"vec3":{align:16,size:12},"vec3":{align:8,size:6},"vec4":{align:16,size:16},"vec4":{align:16,size:16},"vec4":{align:16,size:16},"vec4":{align:8,size:8},"mat2x2":{align:8,size:16},"mat2x2":{align:4,size:8},"mat3x2":{align:8,size:24},"mat3x2":{align:4,size:12},"mat4x2":{align:8,size:32},"mat4x2":{align:4,size:16},"mat2x3":{align:16,size:32},"mat2x3":{align:8,size:16},"mat3x3":{align:16,size:48},"mat3x3":{align:8,size:24},"mat4x3":{align:16,size:64},"mat4x3":{align:8,size:32},"mat2x4":{align:16,size:32},"mat2x4":{align:8,size:16},"mat3x4":{align:16,size:48},"mat3x4":{align:8,size:24},"mat4x4":{align:16,size:64},"mat4x4":{align:8,size:32}};function O_(r){const t=r.map(s=>({data:s,offset:0,size:0}));let e=0;for(let s=0;s1&&(n=Math.max(n,o)*i.data.size),e=Math.ceil(e/o)*o,i.size=n,i.offset=e,e+=n}return e=Math.ceil(e/16)*16,{uboElements:t,size:e}}function C_(r,t){const{size:e,align:s}=jr[r.data.type],i=(s-e)/4;return` - v = uv.${r.data.name}; - ${t!==0?`offset += ${t};`:""} +"use strict"; +class GlUniformGroupSystem { + /** @param renderer - The renderer this System works for. */ + constructor(renderer) { + /** Cache to holds the generated functions. Stored against UniformObjects unique signature. */ + this._cache = {}; + this._uniformGroupSyncHash = {}; + this._renderer = renderer; + this.gl = null; + this._cache = {}; + } + contextChange(gl) { + this.gl = gl; + } + /** + * Uploads the uniforms values to the currently bound shader. + * @param group - the uniforms values that be applied to the current shader + * @param program + * @param syncData + * @param syncData.textureCount + */ + updateUniformGroup(group, program, syncData) { + const programData = this._renderer.shader._getProgramData(program); + if (!group.isStatic || group._dirtyId !== programData.uniformDirtyGroups[group.uid]) { + programData.uniformDirtyGroups[group.uid] = group._dirtyId; + const syncFunc = this._getUniformSyncFunction(group, program); + syncFunc(programData.uniformData, group.uniforms, this._renderer, syncData); + } + } + /** + * Overrideable by the pixi.js/unsafe-eval package to use static syncUniforms instead. + * @param group + * @param program + */ + _getUniformSyncFunction(group, program) { + var _a; + return ((_a = this._uniformGroupSyncHash[group._signature]) == null ? void 0 : _a[program._key]) || this._createUniformSyncFunction(group, program); + } + _createUniformSyncFunction(group, program) { + const uniformGroupSyncHash = this._uniformGroupSyncHash[group._signature] || (this._uniformGroupSyncHash[group._signature] = {}); + const id = this._getSignature(group, program._uniformData, "u"); + if (!this._cache[id]) { + this._cache[id] = this._generateUniformsSync(group, program._uniformData); + } + uniformGroupSyncHash[program._key] = this._cache[id]; + return uniformGroupSyncHash[program._key]; + } + _generateUniformsSync(group, uniformData) { + return generateUniformsSync(group, uniformData); + } + /** + * Takes a uniform group and data and generates a unique signature for them. + * @param group - The uniform group to get signature of + * @param group.uniforms + * @param uniformData - Uniform information generated by the shader + * @param preFix + * @returns Unique signature of the uniform group + */ + _getSignature(group, uniformData, preFix) { + const uniforms = group.uniforms; + const strings = [`${preFix}-`]; + for (const i in uniforms) { + strings.push(i); + if (uniformData[i]) { + strings.push(uniformData[i].type); + } + } + return strings.join("-"); + } + /** Destroys this System and removes all its textures. */ + destroy() { + this._renderer = null; + this._cache = null; + } +} +/** @ignore */ +GlUniformGroupSystem.extension = { + type: [ + ExtensionType.WebGLSystem + ], + name: "uniformGroup" +}; + +"use strict"; +function migrateFragmentFromV7toV8(fragmentShader) { + fragmentShader = fragmentShader.replaceAll("texture2D", "texture").replaceAll("gl_FragColor", "finalColor").replaceAll("varying", "in"); + fragmentShader = ` + out vec4 finalColor; + ${fragmentShader} + `; + return fragmentShader; +} + +"use strict"; +const GLSL_TO_SIZE = { + float: 1, + vec2: 2, + vec3: 3, + vec4: 4, + int: 1, + ivec2: 2, + ivec3: 3, + ivec4: 4, + uint: 1, + uvec2: 2, + uvec3: 3, + uvec4: 4, + bool: 1, + bvec2: 2, + bvec3: 3, + bvec4: 4, + mat2: 4, + mat3: 9, + mat4: 16, + sampler2D: 1 +}; +function mapSize(type) { + return GLSL_TO_SIZE[type]; +} + +"use strict"; +function mapWebGLBlendModesToPixi(gl) { + const blendMap = {}; + blendMap.normal = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; + blendMap.add = [gl.ONE, gl.ONE]; + blendMap.multiply = [gl.DST_COLOR, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; + blendMap.screen = [gl.ONE, gl.ONE_MINUS_SRC_COLOR, gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; + blendMap.none = [0, 0]; + blendMap["normal-npm"] = [gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; + blendMap["add-npm"] = [gl.SRC_ALPHA, gl.ONE, gl.ONE, gl.ONE]; + blendMap["screen-npm"] = [gl.SRC_ALPHA, gl.ONE_MINUS_SRC_COLOR, gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; + blendMap.erase = [gl.ZERO, gl.ONE_MINUS_SRC_ALPHA]; + return blendMap; +} + +"use strict"; +const BLEND = 0; +const OFFSET = 1; +const CULLING = 2; +const DEPTH_TEST = 3; +const WINDING = 4; +const DEPTH_MASK = 5; +const _GlStateSystem = class _GlStateSystem { + constructor() { + this.gl = null; + this.stateId = 0; + this.polygonOffset = 0; + this.blendMode = "none"; + this._blendEq = false; + this.map = []; + this.map[BLEND] = this.setBlend; + this.map[OFFSET] = this.setOffset; + this.map[CULLING] = this.setCullFace; + this.map[DEPTH_TEST] = this.setDepthTest; + this.map[WINDING] = this.setFrontFace; + this.map[DEPTH_MASK] = this.setDepthMask; + this.checks = []; + this.defaultState = State.for2d(); + } + contextChange(gl) { + this.gl = gl; + this.blendModesMap = mapWebGLBlendModesToPixi(gl); + this.reset(); + } + /** + * Sets the current state + * @param {*} state - The state to set. + */ + set(state) { + state = state || this.defaultState; + if (this.stateId !== state.data) { + let diff = this.stateId ^ state.data; + let i = 0; + while (diff) { + if (diff & 1) { + this.map[i].call(this, !!(state.data & 1 << i)); + } + diff = diff >> 1; + i++; + } + this.stateId = state.data; + } + for (let i = 0; i < this.checks.length; i++) { + this.checks[i](this, state); + } + } + /** + * Sets the state, when previous state is unknown. + * @param {*} state - The state to set + */ + forceState(state) { + state = state || this.defaultState; + for (let i = 0; i < this.map.length; i++) { + this.map[i].call(this, !!(state.data & 1 << i)); + } + for (let i = 0; i < this.checks.length; i++) { + this.checks[i](this, state); + } + this.stateId = state.data; + } + /** + * Sets whether to enable or disable blending. + * @param value - Turn on or off WebGl blending. + */ + setBlend(value) { + this._updateCheck(_GlStateSystem._checkBlendMode, value); + this.gl[value ? "enable" : "disable"](this.gl.BLEND); + } + /** + * Sets whether to enable or disable polygon offset fill. + * @param value - Turn on or off webgl polygon offset testing. + */ + setOffset(value) { + this._updateCheck(_GlStateSystem._checkPolygonOffset, value); + this.gl[value ? "enable" : "disable"](this.gl.POLYGON_OFFSET_FILL); + } + /** + * Sets whether to enable or disable depth test. + * @param value - Turn on or off webgl depth testing. + */ + setDepthTest(value) { + this.gl[value ? "enable" : "disable"](this.gl.DEPTH_TEST); + } + /** + * Sets whether to enable or disable depth mask. + * @param value - Turn on or off webgl depth mask. + */ + setDepthMask(value) { + this.gl.depthMask(value); + } + /** + * Sets whether to enable or disable cull face. + * @param {boolean} value - Turn on or off webgl cull face. + */ + setCullFace(value) { + this.gl[value ? "enable" : "disable"](this.gl.CULL_FACE); + } + /** + * Sets the gl front face. + * @param {boolean} value - true is clockwise and false is counter-clockwise + */ + setFrontFace(value) { + this.gl.frontFace(this.gl[value ? "CW" : "CCW"]); + } + /** + * Sets the blend mode. + * @param {number} value - The blend mode to set to. + */ + setBlendMode(value) { + if (!this.blendModesMap[value]) { + value = "normal"; + } + if (value === this.blendMode) { + return; + } + this.blendMode = value; + const mode = this.blendModesMap[value]; + const gl = this.gl; + if (mode.length === 2) { + gl.blendFunc(mode[0], mode[1]); + } else { + gl.blendFuncSeparate(mode[0], mode[1], mode[2], mode[3]); + } + if (mode.length === 6) { + this._blendEq = true; + gl.blendEquationSeparate(mode[4], mode[5]); + } else if (this._blendEq) { + this._blendEq = false; + gl.blendEquationSeparate(gl.FUNC_ADD, gl.FUNC_ADD); + } + } + /** + * Sets the polygon offset. + * @param {number} value - the polygon offset + * @param {number} scale - the polygon offset scale + */ + setPolygonOffset(value, scale) { + this.gl.polygonOffset(value, scale); + } + // used + /** Resets all the logic and disables the VAOs. */ + reset() { + this.gl.pixelStorei(this.gl.UNPACK_FLIP_Y_WEBGL, false); + this.forceState(this.defaultState); + this._blendEq = true; + this.blendMode = ""; + this.setBlendMode("normal"); + } + /** + * Checks to see which updates should be checked based on which settings have been activated. + * + * For example, if blend is enabled then we should check the blend modes each time the state is changed + * or if polygon fill is activated then we need to check if the polygon offset changes. + * The idea is that we only check what we have too. + * @param func - the checking function to add or remove + * @param value - should the check function be added or removed. + */ + _updateCheck(func, value) { + const index = this.checks.indexOf(func); + if (value && index === -1) { + this.checks.push(func); + } else if (!value && index !== -1) { + this.checks.splice(index, 1); + } + } + /** + * A private little wrapper function that we call to check the blend mode. + * @param system - the System to perform the state check on + * @param state - the state that the blendMode will pulled from + */ + static _checkBlendMode(system, state) { + system.setBlendMode(state.blendMode); + } + /** + * A private little wrapper function that we call to check the polygon offset. + * @param system - the System to perform the state check on + * @param state - the state that the blendMode will pulled from + */ + static _checkPolygonOffset(system, state) { + system.setPolygonOffset(1, state.polygonOffset); + } + /** + * @ignore + */ + destroy() { + this.gl = null; + this.checks.length = 0; + } +}; +/** @ignore */ +_GlStateSystem.extension = { + type: [ + ExtensionType.WebGLSystem + ], + name: "state" +}; +let GlStateSystem = _GlStateSystem; + +"use strict"; +class GlTexture { + constructor(texture) { + this.target = GL_TARGETS.TEXTURE_2D; + this.texture = texture; + this.width = -1; + this.height = -1; + this.type = GL_TYPES.UNSIGNED_BYTE; + this.internalFormat = GL_FORMATS.RGBA; + this.format = GL_FORMATS.RGBA; + this.samplerType = 0; + } +} + +"use strict"; +const glUploadBufferImageResource = { + id: "image", + upload(source, glTexture, gl) { + if (glTexture.width === source.width || glTexture.height === source.height) { + gl.texSubImage2D( + gl.TEXTURE_2D, + 0, + 0, + 0, + glTexture.format, + glTexture.type, + source.resource + ); + } else { + gl.texImage2D( + glTexture.target, + 0, + glTexture.internalFormat, + source.width, + source.height, + 0, + glTexture.format, + glTexture.type, + source.resource + ); + } + glTexture.width = source.width; + glTexture.height = source.height; + } +}; + +"use strict"; +const compressedFormatMap = { + "bc1-rgba-unorm": true, + "bc1-rgba-unorm-srgb": true, + "bc2-rgba-unorm": true, + "bc2-rgba-unorm-srgb": true, + "bc3-rgba-unorm": true, + "bc3-rgba-unorm-srgb": true, + "bc4-r-unorm": true, + "bc4-r-snorm": true, + "bc5-rg-unorm": true, + "bc5-rg-snorm": true, + "bc6h-rgb-ufloat": true, + "bc6h-rgb-float": true, + "bc7-rgba-unorm": true, + "bc7-rgba-unorm-srgb": true, + // ETC2 compressed formats usable if "texture-compression-etc2" is both + // supported by the device/user agent and enabled in requestDevice. + "etc2-rgb8unorm": true, + "etc2-rgb8unorm-srgb": true, + "etc2-rgb8a1unorm": true, + "etc2-rgb8a1unorm-srgb": true, + "etc2-rgba8unorm": true, + "etc2-rgba8unorm-srgb": true, + "eac-r11unorm": true, + "eac-r11snorm": true, + "eac-rg11unorm": true, + "eac-rg11snorm": true, + // ASTC compressed formats usable if "texture-compression-astc" is both + // supported by the device/user agent and enabled in requestDevice. + "astc-4x4-unorm": true, + "astc-4x4-unorm-srgb": true, + "astc-5x4-unorm": true, + "astc-5x4-unorm-srgb": true, + "astc-5x5-unorm": true, + "astc-5x5-unorm-srgb": true, + "astc-6x5-unorm": true, + "astc-6x5-unorm-srgb": true, + "astc-6x6-unorm": true, + "astc-6x6-unorm-srgb": true, + "astc-8x5-unorm": true, + "astc-8x5-unorm-srgb": true, + "astc-8x6-unorm": true, + "astc-8x6-unorm-srgb": true, + "astc-8x8-unorm": true, + "astc-8x8-unorm-srgb": true, + "astc-10x5-unorm": true, + "astc-10x5-unorm-srgb": true, + "astc-10x6-unorm": true, + "astc-10x6-unorm-srgb": true, + "astc-10x8-unorm": true, + "astc-10x8-unorm-srgb": true, + "astc-10x10-unorm": true, + "astc-10x10-unorm-srgb": true, + "astc-12x10-unorm": true, + "astc-12x10-unorm-srgb": true, + "astc-12x12-unorm": true, + "astc-12x12-unorm-srgb": true +}; +const glUploadCompressedTextureResource = { + id: "compressed", + upload(source, glTexture, gl) { + gl.pixelStorei(gl.UNPACK_ALIGNMENT, 4); + let mipWidth = source.pixelWidth; + let mipHeight = source.pixelHeight; + const compressed = !!compressedFormatMap[source.format]; + for (let i = 0; i < source.resource.length; i++) { + const levelBuffer = source.resource[i]; + if (compressed) { + gl.compressedTexImage2D( + gl.TEXTURE_2D, + i, + glTexture.internalFormat, + mipWidth, + mipHeight, + 0, + levelBuffer + ); + } else { + gl.texImage2D( + gl.TEXTURE_2D, + i, + glTexture.internalFormat, + mipWidth, + mipHeight, + 0, + glTexture.format, + glTexture.type, + levelBuffer + ); + } + mipWidth = Math.max(mipWidth >> 1, 1); + mipHeight = Math.max(mipHeight >> 1, 1); + } + } +}; + +"use strict"; +const glUploadImageResource = { + id: "image", + upload(source, glTexture, gl, webGLVersion) { + const premultipliedAlpha = source.alphaMode === "premultiply-alpha-on-upload"; + gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, premultipliedAlpha); + const glWidth = glTexture.width; + const glHeight = glTexture.height; + const textureWidth = source.pixelWidth; + const textureHeight = source.pixelHeight; + const resourceWidth = source.resourceWidth; + const resourceHeight = source.resourceHeight; + if (resourceWidth < textureWidth || resourceHeight < textureHeight) { + if (glWidth !== textureWidth || glHeight !== textureHeight) { + gl.texImage2D( + glTexture.target, + 0, + glTexture.internalFormat, + textureWidth, + textureHeight, + 0, + glTexture.format, + glTexture.type, + null + ); + } + if (webGLVersion === 2) { + gl.texSubImage2D( + gl.TEXTURE_2D, + 0, + 0, + 0, + resourceWidth, + resourceHeight, + glTexture.format, + glTexture.type, + source.resource + ); + } else { + gl.texSubImage2D( + gl.TEXTURE_2D, + 0, + 0, + 0, + glTexture.format, + glTexture.type, + source.resource + ); + } + } else if (glWidth === textureWidth || glHeight === textureHeight) { + gl.texSubImage2D( + gl.TEXTURE_2D, + 0, + 0, + 0, + glTexture.format, + glTexture.type, + source.resource + ); + } else if (webGLVersion === 2) { + gl.texImage2D( + glTexture.target, + 0, + glTexture.internalFormat, + textureWidth, + textureHeight, + 0, + glTexture.format, + glTexture.type, + source.resource + ); + } else { + gl.texImage2D( + glTexture.target, + 0, + glTexture.internalFormat, + glTexture.format, + glTexture.type, + source.resource + ); + } + glTexture.width = textureWidth; + glTexture.height = textureHeight; + } +}; + +"use strict"; +const glUploadVideoResource = { + id: "video", + upload(source, glTexture, gl, webGLVersion) { + if (!source.isValid) { + gl.texImage2D( + glTexture.target, + 0, + glTexture.internalFormat, + 1, + 1, + 0, + glTexture.format, + glTexture.type, + null + ); + return; + } + glUploadImageResource.upload(source, glTexture, gl, webGLVersion); + } +}; + +"use strict"; +const scaleModeToGlFilter = { + linear: 9729, + nearest: 9728 +}; +const mipmapScaleModeToGlFilter = { + linear: { + linear: 9987, + nearest: 9985 + }, + nearest: { + linear: 9986, + nearest: 9984 + } +}; +const wrapModeToGlAddress = { + "clamp-to-edge": 33071, + repeat: 10497, + "mirror-repeat": 33648 +}; +const compareModeToGlCompare = { + never: 512, + less: 513, + equal: 514, + "less-equal": 515, + greater: 516, + "not-equal": 517, + "greater-equal": 518, + always: 519 +}; + +"use strict"; +function applyStyleParams(style, gl, mipmaps, anisotropicExt, glFunctionName, firstParam, forceClamp, firstCreation) { + const castParam = firstParam; + if (!firstCreation || style.addressModeU !== "repeat" || style.addressModeV !== "repeat" || style.addressModeW !== "repeat") { + const wrapModeS = wrapModeToGlAddress[forceClamp ? "clamp-to-edge" : style.addressModeU]; + const wrapModeT = wrapModeToGlAddress[forceClamp ? "clamp-to-edge" : style.addressModeV]; + const wrapModeR = wrapModeToGlAddress[forceClamp ? "clamp-to-edge" : style.addressModeW]; + gl[glFunctionName](castParam, gl.TEXTURE_WRAP_S, wrapModeS); + gl[glFunctionName](castParam, gl.TEXTURE_WRAP_T, wrapModeT); + if (gl.TEXTURE_WRAP_R) + gl[glFunctionName](castParam, gl.TEXTURE_WRAP_R, wrapModeR); + } + if (!firstCreation || style.magFilter !== "linear") { + gl[glFunctionName](castParam, gl.TEXTURE_MAG_FILTER, scaleModeToGlFilter[style.magFilter]); + } + if (mipmaps) { + if (!firstCreation || style.mipmapFilter !== "linear") { + const glFilterMode = mipmapScaleModeToGlFilter[style.minFilter][style.mipmapFilter]; + gl[glFunctionName](castParam, gl.TEXTURE_MIN_FILTER, glFilterMode); + } + } else { + gl[glFunctionName](castParam, gl.TEXTURE_MIN_FILTER, scaleModeToGlFilter[style.minFilter]); + } + if (anisotropicExt && style.maxAnisotropy > 1) { + const level = Math.min(style.maxAnisotropy, gl.getParameter(anisotropicExt.MAX_TEXTURE_MAX_ANISOTROPY_EXT)); + gl[glFunctionName](castParam, anisotropicExt.TEXTURE_MAX_ANISOTROPY_EXT, level); + } + if (style.compare) { + gl[glFunctionName](castParam, gl.TEXTURE_COMPARE_FUNC, compareModeToGlCompare[style.compare]); + } +} + +"use strict"; +function mapFormatToGlFormat(gl) { + return { + // 8-bit formats + r8unorm: gl.RED, + r8snorm: gl.RED, + r8uint: gl.RED, + r8sint: gl.RED, + // 16-bit formats + r16uint: gl.RED, + r16sint: gl.RED, + r16float: gl.RED, + rg8unorm: gl.RG, + rg8snorm: gl.RG, + rg8uint: gl.RG, + rg8sint: gl.RG, + // 32-bit formats + r32uint: gl.RED, + r32sint: gl.RED, + r32float: gl.RED, + rg16uint: gl.RG, + rg16sint: gl.RG, + rg16float: gl.RG, + rgba8unorm: gl.RGBA, + "rgba8unorm-srgb": gl.RGBA, + // Packed 32-bit formats + rgba8snorm: gl.RGBA, + rgba8uint: gl.RGBA, + rgba8sint: gl.RGBA, + bgra8unorm: gl.RGBA, + "bgra8unorm-srgb": gl.RGBA, + rgb9e5ufloat: gl.RGB, + rgb10a2unorm: gl.RGBA, + rg11b10ufloat: gl.RGB, + // 64-bit formats + rg32uint: gl.RG, + rg32sint: gl.RG, + rg32float: gl.RG, + rgba16uint: gl.RGBA, + rgba16sint: gl.RGBA, + rgba16float: gl.RGBA, + // 128-bit formats + rgba32uint: gl.RGBA, + rgba32sint: gl.RGBA, + rgba32float: gl.RGBA, + // Depth/stencil formats + stencil8: gl.STENCIL_INDEX8, + depth16unorm: gl.DEPTH_COMPONENT, + depth24plus: gl.DEPTH_COMPONENT, + "depth24plus-stencil8": gl.DEPTH_STENCIL, + depth32float: gl.DEPTH_COMPONENT, + "depth32float-stencil8": gl.DEPTH_STENCIL + }; +} + +"use strict"; +var __defProp$e = Object.defineProperty; +var __defProps$6 = Object.defineProperties; +var __getOwnPropDescs$6 = Object.getOwnPropertyDescriptors; +var __getOwnPropSymbols$e = Object.getOwnPropertySymbols; +var __hasOwnProp$e = Object.prototype.hasOwnProperty; +var __propIsEnum$e = Object.prototype.propertyIsEnumerable; +var __defNormalProp$e = (obj, key, value) => key in obj ? __defProp$e(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; +var __spreadValues$e = (a, b) => { + for (var prop in b || (b = {})) + if (__hasOwnProp$e.call(b, prop)) + __defNormalProp$e(a, prop, b[prop]); + if (__getOwnPropSymbols$e) + for (var prop of __getOwnPropSymbols$e(b)) { + if (__propIsEnum$e.call(b, prop)) + __defNormalProp$e(a, prop, b[prop]); + } + return a; +}; +var __spreadProps$6 = (a, b) => __defProps$6(a, __getOwnPropDescs$6(b)); +function mapFormatToGlInternalFormat(gl, extensions) { + let srgb = {}; + let bgra8unorm = gl.RGBA; + if (!(gl instanceof DOMAdapter.get().getWebGLRenderingContext())) { + srgb = { + "rgba8unorm-srgb": gl.SRGB8_ALPHA8, + "bgra8unorm-srgb": gl.SRGB8_ALPHA8 + }; + bgra8unorm = gl.RGBA8; + } else if (extensions.srgb) { + srgb = { + "rgba8unorm-srgb": extensions.srgb.SRGB8_ALPHA8_EXT, + "bgra8unorm-srgb": extensions.srgb.SRGB8_ALPHA8_EXT + }; + } + return __spreadValues$e(__spreadValues$e(__spreadValues$e(__spreadValues$e(__spreadValues$e(__spreadValues$e(__spreadProps$6(__spreadValues$e({ + // 8-bit formats + r8unorm: gl.R8, + r8snorm: gl.R8_SNORM, + r8uint: gl.R8UI, + r8sint: gl.R8I, + // 16-bit formats + r16uint: gl.R16UI, + r16sint: gl.R16I, + r16float: gl.R16F, + rg8unorm: gl.RG8, + rg8snorm: gl.RG8_SNORM, + rg8uint: gl.RG8UI, + rg8sint: gl.RG8I, + // 32-bit formats + r32uint: gl.R32UI, + r32sint: gl.R32I, + r32float: gl.R32F, + rg16uint: gl.RG16UI, + rg16sint: gl.RG16I, + rg16float: gl.RG16F, + rgba8unorm: gl.RGBA + }, srgb), { + // Packed 32-bit formats + rgba8snorm: gl.RGBA8_SNORM, + rgba8uint: gl.RGBA8UI, + rgba8sint: gl.RGBA8I, + bgra8unorm, + rgb9e5ufloat: gl.RGB9_E5, + rgb10a2unorm: gl.RGB10_A2, + rg11b10ufloat: gl.R11F_G11F_B10F, + // 64-bit formats + rg32uint: gl.RG32UI, + rg32sint: gl.RG32I, + rg32float: gl.RG32F, + rgba16uint: gl.RGBA16UI, + rgba16sint: gl.RGBA16I, + rgba16float: gl.RGBA16F, + // 128-bit formats + rgba32uint: gl.RGBA32UI, + rgba32sint: gl.RGBA32I, + rgba32float: gl.RGBA32F, + // Depth/stencil formats + stencil8: gl.STENCIL_INDEX8, + depth16unorm: gl.DEPTH_COMPONENT16, + depth24plus: gl.DEPTH_COMPONENT24, + "depth24plus-stencil8": gl.DEPTH24_STENCIL8, + depth32float: gl.DEPTH_COMPONENT32F, + "depth32float-stencil8": gl.DEPTH32F_STENCIL8 + }), extensions.s3tc ? { + "bc1-rgba-unorm": extensions.s3tc.COMPRESSED_RGBA_S3TC_DXT1_EXT, + "bc2-rgba-unorm": extensions.s3tc.COMPRESSED_RGBA_S3TC_DXT3_EXT, + "bc3-rgba-unorm": extensions.s3tc.COMPRESSED_RGBA_S3TC_DXT5_EXT + } : {}), extensions.s3tc_sRGB ? { + "bc1-rgba-unorm-srgb": extensions.s3tc_sRGB.COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT, + "bc2-rgba-unorm-srgb": extensions.s3tc_sRGB.COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, + "bc3-rgba-unorm-srgb": extensions.s3tc_sRGB.COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT + } : {}), extensions.rgtc ? { + "bc4-r-unorm": extensions.rgtc.COMPRESSED_RED_RGTC1_EXT, + "bc4-r-snorm": extensions.rgtc.COMPRESSED_SIGNED_RED_RGTC1_EXT, + "bc5-rg-unorm": extensions.rgtc.COMPRESSED_RED_GREEN_RGTC2_EXT, + "bc5-rg-snorm": extensions.rgtc.COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT + } : {}), extensions.bptc ? { + "bc6h-rgb-float": extensions.bptc.COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT, + "bc6h-rgb-ufloat": extensions.bptc.COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT, + "bc7-rgba-unorm": extensions.bptc.COMPRESSED_RGBA_BPTC_UNORM_EXT, + "bc7-rgba-unorm-srgb": extensions.bptc.COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT + } : {}), extensions.etc ? { + "etc2-rgb8unorm": extensions.etc.COMPRESSED_RGB8_ETC2, + "etc2-rgb8unorm-srgb": extensions.etc.COMPRESSED_SRGB8_ETC2, + "etc2-rgb8a1unorm": extensions.etc.COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2, + "etc2-rgb8a1unorm-srgb": extensions.etc.COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2, + "etc2-rgba8unorm": extensions.etc.COMPRESSED_RGBA8_ETC2_EAC, + "etc2-rgba8unorm-srgb": extensions.etc.COMPRESSED_SRGB8_ALPHA8_ETC2_EAC, + "eac-r11unorm": extensions.etc.COMPRESSED_R11_EAC, + // 'eac-r11snorm' + "eac-rg11unorm": extensions.etc.COMPRESSED_SIGNED_RG11_EAC + // 'eac-rg11snorm' + } : {}), extensions.astc ? { + "astc-4x4-unorm": extensions.astc.COMPRESSED_RGBA_ASTC_4x4_KHR, + "astc-4x4-unorm-srgb": extensions.astc.COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR, + "astc-5x4-unorm": extensions.astc.COMPRESSED_RGBA_ASTC_5x4_KHR, + "astc-5x4-unorm-srgb": extensions.astc.COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR, + "astc-5x5-unorm": extensions.astc.COMPRESSED_RGBA_ASTC_5x5_KHR, + "astc-5x5-unorm-srgb": extensions.astc.COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR, + "astc-6x5-unorm": extensions.astc.COMPRESSED_RGBA_ASTC_6x5_KHR, + "astc-6x5-unorm-srgb": extensions.astc.COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR, + "astc-6x6-unorm": extensions.astc.COMPRESSED_RGBA_ASTC_6x6_KHR, + "astc-6x6-unorm-srgb": extensions.astc.COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR, + "astc-8x5-unorm": extensions.astc.COMPRESSED_RGBA_ASTC_8x5_KHR, + "astc-8x5-unorm-srgb": extensions.astc.COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR, + "astc-8x6-unorm": extensions.astc.COMPRESSED_RGBA_ASTC_8x6_KHR, + "astc-8x6-unorm-srgb": extensions.astc.COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR, + "astc-8x8-unorm": extensions.astc.COMPRESSED_RGBA_ASTC_8x8_KHR, + "astc-8x8-unorm-srgb": extensions.astc.COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR, + "astc-10x5-unorm": extensions.astc.COMPRESSED_RGBA_ASTC_10x5_KHR, + "astc-10x5-unorm-srgb": extensions.astc.COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR, + "astc-10x6-unorm": extensions.astc.COMPRESSED_RGBA_ASTC_10x6_KHR, + "astc-10x6-unorm-srgb": extensions.astc.COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR, + "astc-10x8-unorm": extensions.astc.COMPRESSED_RGBA_ASTC_10x8_KHR, + "astc-10x8-unorm-srgb": extensions.astc.COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR, + "astc-10x10-unorm": extensions.astc.COMPRESSED_RGBA_ASTC_10x10_KHR, + "astc-10x10-unorm-srgb": extensions.astc.COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR, + "astc-12x10-unorm": extensions.astc.COMPRESSED_RGBA_ASTC_12x10_KHR, + "astc-12x10-unorm-srgb": extensions.astc.COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR, + "astc-12x12-unorm": extensions.astc.COMPRESSED_RGBA_ASTC_12x12_KHR, + "astc-12x12-unorm-srgb": extensions.astc.COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR + } : {}); +} + +"use strict"; +function mapFormatToGlType(gl) { + return { + // 8-bit formats + r8unorm: gl.UNSIGNED_BYTE, + r8snorm: gl.BYTE, + r8uint: gl.UNSIGNED_BYTE, + r8sint: gl.BYTE, + // 16-bit formats + r16uint: gl.UNSIGNED_SHORT, + r16sint: gl.SHORT, + r16float: gl.HALF_FLOAT, + rg8unorm: gl.UNSIGNED_BYTE, + rg8snorm: gl.BYTE, + rg8uint: gl.UNSIGNED_BYTE, + rg8sint: gl.BYTE, + // 32-bit formats + r32uint: gl.UNSIGNED_INT, + r32sint: gl.INT, + r32float: gl.FLOAT, + rg16uint: gl.UNSIGNED_SHORT, + rg16sint: gl.SHORT, + rg16float: gl.HALF_FLOAT, + rgba8unorm: gl.UNSIGNED_BYTE, + "rgba8unorm-srgb": gl.UNSIGNED_BYTE, + // Packed 32-bit formats + rgba8snorm: gl.BYTE, + rgba8uint: gl.UNSIGNED_BYTE, + rgba8sint: gl.BYTE, + bgra8unorm: gl.UNSIGNED_BYTE, + "bgra8unorm-srgb": gl.UNSIGNED_BYTE, + rgb9e5ufloat: gl.UNSIGNED_INT_5_9_9_9_REV, + rgb10a2unorm: gl.UNSIGNED_INT_2_10_10_10_REV, + rg11b10ufloat: gl.UNSIGNED_INT_10F_11F_11F_REV, + // 64-bit formats + rg32uint: gl.UNSIGNED_INT, + rg32sint: gl.INT, + rg32float: gl.FLOAT, + rgba16uint: gl.UNSIGNED_SHORT, + rgba16sint: gl.SHORT, + rgba16float: gl.HALF_FLOAT, + // 128-bit formats + rgba32uint: gl.UNSIGNED_INT, + rgba32sint: gl.INT, + rgba32float: gl.FLOAT, + // Depth/stencil formats + stencil8: gl.UNSIGNED_BYTE, + depth16unorm: gl.UNSIGNED_SHORT, + depth24plus: gl.UNSIGNED_INT, + "depth24plus-stencil8": gl.UNSIGNED_INT_24_8, + depth32float: gl.FLOAT, + "depth32float-stencil8": gl.FLOAT_32_UNSIGNED_INT_24_8_REV + }; +} + +"use strict"; +function unpremultiplyAlpha$1(pixels) { + if (pixels instanceof Uint8ClampedArray) { + pixels = new Uint8Array(pixels.buffer); + } + const n = pixels.length; + for (let i = 0; i < n; i += 4) { + const alpha = pixels[i + 3]; + if (alpha !== 0) { + const a = 255.001 / alpha; + pixels[i] = pixels[i] * a + 0.5; + pixels[i + 1] = pixels[i + 1] * a + 0.5; + pixels[i + 2] = pixels[i + 2] * a + 0.5; + } + } +} + +"use strict"; +const BYTES_PER_PIXEL = 4; +class GlTextureSystem { + constructor(renderer) { + this.managedTextures = []; + this._glTextures = /* @__PURE__ */ Object.create(null); + this._glSamplers = /* @__PURE__ */ Object.create(null); + this._boundTextures = []; + this._activeTextureLocation = -1; + this._boundSamplers = /* @__PURE__ */ Object.create(null); + this._uploads = { + image: glUploadImageResource, + buffer: glUploadBufferImageResource, + video: glUploadVideoResource, + compressed: glUploadCompressedTextureResource + }; + // TODO - separate samplers will be a cool thing to add, but not right now! + this._useSeparateSamplers = false; + this._renderer = renderer; + } + contextChange(gl) { + this._gl = gl; + if (!this._mapFormatToInternalFormat) { + this._mapFormatToInternalFormat = mapFormatToGlInternalFormat(gl, this._renderer.context.extensions); + this._mapFormatToType = mapFormatToGlType(gl); + this._mapFormatToFormat = mapFormatToGlFormat(gl); + } + this._glTextures = /* @__PURE__ */ Object.create(null); + this._glSamplers = /* @__PURE__ */ Object.create(null); + this._boundSamplers = /* @__PURE__ */ Object.create(null); + for (let i = 0; i < 16; i++) { + this.bind(Texture.EMPTY, i); + } + } + initSource(source) { + this.bind(source); + } + bind(texture, location = 0) { + const source = texture.source; + if (texture) { + this.bindSource(source, location); + if (this._useSeparateSamplers) { + this._bindSampler(source.style, location); + } + } else { + this.bindSource(null, location); + if (this._useSeparateSamplers) { + this._bindSampler(null, location); + } + } + } + bindSource(source, location = 0) { + const gl = this._gl; + source._touched = this._renderer.textureGC.count; + if (this._boundTextures[location] !== source) { + this._boundTextures[location] = source; + this._activateLocation(location); + source = source || Texture.EMPTY.source; + const glTexture = this.getGlSource(source); + gl.bindTexture(glTexture.target, glTexture.texture); + } + } + _bindSampler(style, location = 0) { + const gl = this._gl; + if (!style) { + this._boundSamplers[location] = null; + gl.bindSampler(location, null); + return; + } + const sampler = this._getGlSampler(style); + if (this._boundSamplers[location] !== sampler) { + this._boundSamplers[location] = sampler; + gl.bindSampler(location, sampler); + } + } + unbind(texture) { + const source = texture.source; + const boundTextures = this._boundTextures; + const gl = this._gl; + for (let i = 0; i < boundTextures.length; i++) { + if (boundTextures[i] === source) { + this._activateLocation(i); + const glTexture = this.getGlSource(source); + gl.bindTexture(glTexture.target, null); + boundTextures[i] = null; + } + } + } + _activateLocation(location) { + if (this._activeTextureLocation !== location) { + this._activeTextureLocation = location; + this._gl.activeTexture(this._gl.TEXTURE0 + location); + } + } + _initSource(source) { + const gl = this._gl; + const glTexture = new GlTexture(gl.createTexture()); + glTexture.type = this._mapFormatToType[source.format]; + glTexture.internalFormat = this._mapFormatToInternalFormat[source.format]; + glTexture.format = this._mapFormatToFormat[source.format]; + if (source.autoGenerateMipmaps && (this._renderer.context.supports.nonPowOf2mipmaps || source.isPowerOfTwo)) { + const biggestDimension = Math.max(source.width, source.height); + source.mipLevelCount = Math.floor(Math.log2(biggestDimension)) + 1; + } + this._glTextures[source.uid] = glTexture; + if (!this.managedTextures.includes(source)) { + source.on("update", this.onSourceUpdate, this); + source.on("resize", this.onSourceUpdate, this); + source.on("styleChange", this.onStyleChange, this); + source.on("destroy", this.onSourceDestroy, this); + source.on("unload", this.onSourceUnload, this); + source.on("updateMipmaps", this.onUpdateMipmaps, this); + this.managedTextures.push(source); + } + this.onSourceUpdate(source); + this.updateStyle(source, false); + return glTexture; + } + onStyleChange(source) { + this.updateStyle(source, false); + } + updateStyle(source, firstCreation) { + const gl = this._gl; + const glTexture = this.getGlSource(source); + gl.bindTexture(gl.TEXTURE_2D, glTexture.texture); + this._boundTextures[this._activeTextureLocation] = source; + applyStyleParams( + source.style, + gl, + source.mipLevelCount > 1, + this._renderer.context.extensions.anisotropicFiltering, + "texParameteri", + gl.TEXTURE_2D, + // will force a clamp to edge if the texture is not a power of two + !this._renderer.context.supports.nonPowOf2wrapping && !source.isPowerOfTwo, + firstCreation + ); + } + onSourceUnload(source) { + const glTexture = this._glTextures[source.uid]; + if (!glTexture) + return; + this.unbind(source); + this._glTextures[source.uid] = null; + this._gl.deleteTexture(glTexture.texture); + } + onSourceUpdate(source) { + const gl = this._gl; + const glTexture = this.getGlSource(source); + gl.bindTexture(gl.TEXTURE_2D, glTexture.texture); + this._boundTextures[this._activeTextureLocation] = source; + if (this._uploads[source.uploadMethodId]) { + this._uploads[source.uploadMethodId].upload(source, glTexture, gl, this._renderer.context.webGLVersion); + } else { + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, source.pixelWidth, source.pixelHeight, 0, gl.RGBA, gl.UNSIGNED_BYTE, null); + } + if (source.autoGenerateMipmaps && source.mipLevelCount > 1) { + this.onUpdateMipmaps(source, false); + } + } + onUpdateMipmaps(source, bind = true) { + if (bind) + this.bindSource(source, 0); + const glTexture = this.getGlSource(source); + this._gl.generateMipmap(glTexture.target); + } + onSourceDestroy(source) { + source.off("destroy", this.onSourceDestroy, this); + source.off("update", this.onSourceUpdate, this); + source.off("resize", this.onSourceUpdate, this); + source.off("unload", this.onSourceUnload, this); + source.off("styleChange", this.onStyleChange, this); + source.off("updateMipmaps", this.onUpdateMipmaps, this); + this.managedTextures.splice(this.managedTextures.indexOf(source), 1); + this.onSourceUnload(source); + } + _initSampler(style) { + const gl = this._gl; + const glSampler = this._gl.createSampler(); + this._glSamplers[style._resourceId] = glSampler; + applyStyleParams( + style, + gl, + this._boundTextures[this._activeTextureLocation].mipLevelCount > 1, + this._renderer.context.extensions.anisotropicFiltering, + "samplerParameteri", + glSampler, + false, + true + ); + return this._glSamplers[style._resourceId]; + } + _getGlSampler(sampler) { + return this._glSamplers[sampler._resourceId] || this._initSampler(sampler); + } + getGlSource(source) { + return this._glTextures[source.uid] || this._initSource(source); + } + generateCanvas(texture) { + const { pixels, width, height } = this.getPixels(texture); + const canvas = DOMAdapter.get().createCanvas(); + canvas.width = width; + canvas.height = height; + const ctx = canvas.getContext("2d"); + if (ctx) { + const imageData = ctx.createImageData(width, height); + imageData.data.set(pixels); + ctx.putImageData(imageData, 0, 0); + } + return canvas; + } + getPixels(texture) { + const resolution = texture.source.resolution; + const frame = texture.frame; + const width = Math.max(Math.round(frame.width * resolution), 1); + const height = Math.max(Math.round(frame.height * resolution), 1); + const pixels = new Uint8Array(BYTES_PER_PIXEL * width * height); + const renderer = this._renderer; + const renderTarget = renderer.renderTarget.getRenderTarget(texture); + const glRenterTarget = renderer.renderTarget.getGpuRenderTarget(renderTarget); + const gl = renderer.gl; + gl.bindFramebuffer(gl.FRAMEBUFFER, glRenterTarget.resolveTargetFramebuffer); + gl.readPixels( + Math.round(frame.x * resolution), + Math.round(frame.y * resolution), + width, + height, + gl.RGBA, + gl.UNSIGNED_BYTE, + pixels + ); + if (false) { + unpremultiplyAlpha(pixels); + } + return { pixels: new Uint8ClampedArray(pixels.buffer), width, height }; + } + destroy() { + this.managedTextures.slice().forEach((source) => this.onSourceDestroy(source)); + this.managedTextures = null; + this._renderer = null; + } +} +/** @ignore */ +GlTextureSystem.extension = { + type: [ + ExtensionType.WebGLSystem + ], + name: "texture" +}; + +"use strict"; + +"use strict"; +class GlGraphicsAdaptor { + init() { + const uniforms = new UniformGroup({ + uColor: { value: new Float32Array([1, 1, 1, 1]), type: "vec4" }, + uTransformMatrix: { value: new Matrix(), type: "mat3x3" }, + uRound: { value: 0, type: "f32" } + }); + const glProgram = compileHighShaderGlProgram({ + name: "graphics", + bits: [ + colorBitGl, + generateTextureBatchBitGl(MAX_TEXTURES), + localUniformBitGl, + roundPixelsBitGl + ] + }); + this.shader = new Shader({ + glProgram, + resources: { + localUniforms: uniforms, + batchSamplers: batchSamplersUniformGroup + } + }); + } + execute(graphicsPipe, renderable) { + const context = renderable.context; + const shader = context.customShader || this.shader; + const renderer = graphicsPipe.renderer; + const contextSystem = renderer.graphicsContext; + const { + geometry, + instructions + } = contextSystem.getContextRenderData(context); + shader.groups[0] = renderer.globalUniforms.bindGroup; + renderer.shader.bind(shader); + renderer.geometry.bind(geometry, shader.glProgram); + const batches = instructions.instructions; + for (let i = 0; i < instructions.instructionSize; i++) { + const batch = batches[i]; + if (batch.size) { + for (let j = 0; j < batch.textures.textures.length; j++) { + renderer.texture.bind(batch.textures.textures[j], j); + } + renderer.geometry.draw("triangle-list", batch.size, batch.start); + } + } + } + destroy() { + this.shader.destroy(true); + this.shader = null; + } +} +/** @ignore */ +GlGraphicsAdaptor.extension = { + type: [ + ExtensionType.WebGLPipesAdaptor + ], + name: "graphics" +}; + +"use strict"; +class GlMeshAdaptor { + init() { + const glProgram = compileHighShaderGlProgram({ + name: "mesh", + bits: [ + localUniformBitGl, + textureBitGl, + roundPixelsBitGl + ] + }); + this._shader = new Shader({ + glProgram, + resources: { + uTexture: Texture.EMPTY.source, + textureUniforms: { + uTextureMatrix: { type: "mat3x3", value: new Matrix() } + } + } + }); + } + execute(meshPipe, mesh) { + const renderer = meshPipe.renderer; + let shader = mesh._shader; + if (!shader) { + shader = this._shader; + const texture = mesh.texture; + const source = texture.source; + shader.resources.uTexture = source; + shader.resources.uSampler = source.style; + shader.resources.textureUniforms.uniforms.uTextureMatrix = texture.textureMatrix.mapCoord; + } else if (!shader.glProgram) { + warn("Mesh shader has no glProgram", mesh.shader); + return; + } + shader.groups[100] = renderer.globalUniforms.bindGroup; + shader.groups[101] = meshPipe.localUniformsBindGroup; + renderer.encoder.draw({ + geometry: mesh._geometry, + shader, + state: mesh.state + }); + } + destroy() { + this._shader.destroy(true); + this._shader = null; + } +} +GlMeshAdaptor.extension = { + type: [ + ExtensionType.WebGLPipesAdaptor + ], + name: "mesh" +}; + +"use strict"; +class CustomRenderPipe { + constructor(renderer) { + this._renderer = renderer; + } + addRenderable(container, instructionSet) { + this._renderer.renderPipes.batch.break(instructionSet); + instructionSet.add(container); + } + execute(container) { + if (!container.isRenderable) + return; + container.render(this._renderer); + } + destroy() { + this._renderer = null; + } +} +CustomRenderPipe.extension = { + type: [ + ExtensionType.WebGLPipes, + ExtensionType.WebGPUPipes, + ExtensionType.CanvasPipes + ], + name: "customRender" +}; + +"use strict"; +function executeInstructions(renderGroup, renderer) { + const instructionSet = renderGroup.instructionSet; + const instructions = instructionSet.instructions; + for (let i = 0; i < instructionSet.instructionSize; i++) { + const instruction = instructions[i]; + renderer[instruction.renderPipeId].execute(instruction); + } +} + +"use strict"; +class RenderGroupPipe { + constructor(renderer) { + this._renderer = renderer; + } + addRenderGroup(renderGroup, instructionSet) { + this._renderer.renderPipes.batch.break(instructionSet); + instructionSet.add(renderGroup); + } + execute(renderGroup) { + if (!renderGroup.isRenderable) + return; + this._renderer.globalUniforms.push({ + worldTransformMatrix: renderGroup.worldTransform, + worldColor: renderGroup.worldColorAlpha + }); + executeInstructions(renderGroup, this._renderer.renderPipes); + this._renderer.globalUniforms.pop(); + } + destroy() { + this._renderer = null; + } +} +RenderGroupPipe.extension = { + type: [ + ExtensionType.WebGLPipes, + ExtensionType.WebGPUPipes, + ExtensionType.CanvasPipes + ], + name: "renderGroup" +}; + +"use strict"; +function collectRenderGroups(renderGroup, out = []) { + out.push(renderGroup); + for (let i = 0; i < renderGroup.renderGroupChildren.length; i++) { + collectRenderGroups(renderGroup.renderGroupChildren[i], out); + } + return out; +} + +"use strict"; +const tempContainer = new Container(); +function updateRenderGroupTransforms(renderGroup, updateChildRenderGroups = false) { + updateRenderGroupTransform(renderGroup); + const childrenToUpdate = renderGroup.childrenToUpdate; + const updateTick = renderGroup.updateTick; + renderGroup.updateTick++; + for (const j in childrenToUpdate) { + const childrenAtDepth = childrenToUpdate[j]; + const list = childrenAtDepth.list; + const index = childrenAtDepth.index; + for (let i = 0; i < index; i++) { + updateTransformAndChildren(list[i], updateTick, 0); + } + childrenAtDepth.index = 0; + } + if (updateChildRenderGroups) { + for (let i = 0; i < renderGroup.renderGroupChildren.length; i++) { + updateRenderGroupTransforms(renderGroup.renderGroupChildren[i], updateChildRenderGroups); + } + } +} +function updateRenderGroupTransform(renderGroup) { + const root = renderGroup.root; + let worldAlpha; + if (renderGroup.renderGroupParent) { + const renderGroupParent = renderGroup.renderGroupParent; + renderGroup.worldTransform.appendFrom( + root.relativeGroupTransform, + renderGroupParent.worldTransform + ); + renderGroup.worldColor = mixColors( + root.groupColor, + renderGroupParent.worldColor + ); + worldAlpha = root.groupAlpha * renderGroupParent.worldAlpha; + } else { + renderGroup.worldTransform.copyFrom(root.localTransform); + renderGroup.worldColor = root.localColor; + worldAlpha = root.localAlpha; + } + worldAlpha = worldAlpha < 0 ? 0 : worldAlpha > 1 ? 1 : worldAlpha; + renderGroup.worldAlpha = worldAlpha; + renderGroup.worldColorAlpha = renderGroup.worldColor + ((worldAlpha * 255 | 0) << 24); +} +function updateTransformAndChildren(container, updateTick, updateFlags) { + if (updateTick === container.updateTick) + return; + container.updateTick = updateTick; + container.didChange = false; + const localTransform = container.localTransform; + container.updateLocalTransform(); + const parent = container.parent; + if (parent && !parent.isRenderGroupRoot) { + updateFlags = updateFlags | container._updateFlags; + container.relativeGroupTransform.appendFrom( + localTransform, + parent.relativeGroupTransform + ); + if (updateFlags) { + updateColorBlendVisibility(container, parent, updateFlags); + } + } else { + updateFlags = container._updateFlags; + container.relativeGroupTransform.copyFrom(localTransform); + if (updateFlags) { + updateColorBlendVisibility(container, tempContainer, updateFlags); + } + } + if (!container.isRenderGroupRoot) { + const children = container.children; + const length = children.length; + for (let i = 0; i < length; i++) { + updateTransformAndChildren(children[i], updateTick, updateFlags); + } + const renderGroup = container.renderGroup; + if (container.renderPipeId && !renderGroup.structureDidChange) { + renderGroup.updateRenderable(container); + } + } +} +function updateColorBlendVisibility(container, parent, updateFlags) { + if (updateFlags & UPDATE_COLOR) { + container.groupColor = mixColors( + container.localColor, + parent.groupColor + ); + let groupAlpha = container.localAlpha * parent.groupAlpha; + groupAlpha = groupAlpha < 0 ? 0 : groupAlpha > 1 ? 1 : groupAlpha; + container.groupAlpha = groupAlpha; + container.groupColorAlpha = container.groupColor + ((groupAlpha * 255 | 0) << 24); + } + if (updateFlags & UPDATE_BLEND) { + container.groupBlendMode = container.localBlendMode === "inherit" ? parent.groupBlendMode : container.localBlendMode; + } + if (updateFlags & UPDATE_VISIBLE) { + container.globalDisplayStatus = container.localDisplayStatus & parent.globalDisplayStatus; + } + container._updateFlags = 0; +} + +"use strict"; +function validateRenderables(renderGroup, renderPipes) { + const { list, index } = renderGroup.childrenRenderablesToUpdate; + let rebuildRequired = false; + for (let i = 0; i < index; i++) { + const container = list[i]; + const renderable = container; + const pipe = renderPipes[renderable.renderPipeId]; + rebuildRequired = pipe.validateRenderable(container); + if (rebuildRequired) { + break; + } + } + renderGroup.structureDidChange = rebuildRequired; + return rebuildRequired; +} + +"use strict"; +const tempMatrix = new Matrix(); +class RenderGroupSystem { + constructor(renderer) { + this._renderer = renderer; + } + render({ container, transform }) { + container.isRenderGroup = true; + const parent = container.parent; + const renderGroupParent = container.renderGroup.renderGroupParent; + container.parent = null; + container.renderGroup.renderGroupParent = null; + const renderer = this._renderer; + const renderGroups = collectRenderGroups(container.renderGroup, []); + let originalLocalTransform = tempMatrix; + if (transform) { + originalLocalTransform = originalLocalTransform.copyFrom(container.renderGroup.localTransform); + container.renderGroup.localTransform.copyFrom(transform); + } + const renderPipes = renderer.renderPipes; + for (let i = 0; i < renderGroups.length; i++) { + const renderGroup = renderGroups[i]; + renderGroup.runOnRender(); + renderGroup.instructionSet.renderPipes = renderPipes; + if (!renderGroup.structureDidChange) { + validateRenderables(renderGroup, renderPipes); + } + updateRenderGroupTransforms(renderGroup); + if (renderGroup.structureDidChange) { + renderGroup.structureDidChange = false; + buildInstructions(renderGroup, renderPipes); + } else { + updateRenderables(renderGroup); + } + renderGroup.childrenRenderablesToUpdate.index = 0; + renderer.renderPipes.batch.upload(renderGroup.instructionSet); + } + renderer.globalUniforms.start({ + worldTransformMatrix: transform ? container.renderGroup.localTransform : container.renderGroup.worldTransform, + worldColor: container.renderGroup.worldColorAlpha + }); + executeInstructions(container.renderGroup, renderPipes); + if (renderPipes.uniformBatch) { + renderPipes.uniformBatch.renderEnd(); + } + if (transform) { + container.renderGroup.localTransform.copyFrom(originalLocalTransform); + } + container.parent = parent; + container.renderGroup.renderGroupParent = renderGroupParent; + } + destroy() { + this._renderer = null; + } +} +/** @ignore */ +RenderGroupSystem.extension = { + type: [ + ExtensionType.WebGLSystem, + ExtensionType.WebGPUSystem, + ExtensionType.CanvasSystem + ], + name: "renderGroup" +}; +function updateRenderables(renderGroup) { + const { list, index } = renderGroup.childrenRenderablesToUpdate; + for (let i = 0; i < index; i++) { + const container = list[i]; + if (container.didViewUpdate) { + renderGroup.updateRenderable(container); + } + } +} + +"use strict"; +class SpritePipe { + constructor(renderer) { + this._gpuSpriteHash = /* @__PURE__ */ Object.create(null); + this._renderer = renderer; + } + addRenderable(sprite, _instructionSet) { + const gpuSprite = this._getGpuSprite(sprite); + if (sprite._didSpriteUpdate) + this._updateBatchableSprite(sprite, gpuSprite); + this._renderer.renderPipes.batch.addToBatch(gpuSprite); + } + updateRenderable(sprite) { + const gpuSprite = this._gpuSpriteHash[sprite.uid]; + if (sprite._didSpriteUpdate) + this._updateBatchableSprite(sprite, gpuSprite); + gpuSprite.batcher.updateElement(gpuSprite); + } + validateRenderable(sprite) { + const texture = sprite._texture; + const gpuSprite = this._getGpuSprite(sprite); + if (gpuSprite.texture._source !== texture._source) { + return !gpuSprite.batcher.checkAndUpdateTexture(gpuSprite, texture); + } + return false; + } + destroyRenderable(sprite) { + const batchableSprite = this._gpuSpriteHash[sprite.uid]; + BigPool.return(batchableSprite); + this._gpuSpriteHash[sprite.uid] = null; + } + _updateBatchableSprite(sprite, batchableSprite) { + sprite._didSpriteUpdate = false; + batchableSprite.bounds = sprite.bounds; + batchableSprite.texture = sprite._texture; + } + _getGpuSprite(sprite) { + return this._gpuSpriteHash[sprite.uid] || this._initGPUSprite(sprite); + } + _initGPUSprite(sprite) { + const batchableSprite = BigPool.get(BatchableSprite); + batchableSprite.renderable = sprite; + batchableSprite.texture = sprite._texture; + batchableSprite.bounds = sprite.bounds; + batchableSprite.roundPixels = this._renderer._roundPixels | sprite._roundPixels; + this._gpuSpriteHash[sprite.uid] = batchableSprite; + sprite._didSpriteUpdate = false; + sprite.on("destroyed", () => { + this.destroyRenderable(sprite); + }); + return batchableSprite; + } + destroy() { + for (const i in this._gpuSpriteHash) { + BigPool.return(this._gpuSpriteHash[i]); + } + this._gpuSpriteHash = null; + this._renderer = null; + } +} +/** @ignore */ +SpritePipe.extension = { + type: [ + ExtensionType.WebGLPipes, + ExtensionType.WebGPUPipes, + ExtensionType.CanvasPipes + ], + name: "sprite" +}; + +"use strict"; +var __defProp$d = Object.defineProperty; +var __getOwnPropSymbols$d = Object.getOwnPropertySymbols; +var __hasOwnProp$d = Object.prototype.hasOwnProperty; +var __propIsEnum$d = Object.prototype.propertyIsEnumerable; +var __defNormalProp$d = (obj, key, value) => key in obj ? __defProp$d(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; +var __spreadValues$d = (a, b) => { + for (var prop in b || (b = {})) + if (__hasOwnProp$d.call(b, prop)) + __defNormalProp$d(a, prop, b[prop]); + if (__getOwnPropSymbols$d) + for (var prop of __getOwnPropSymbols$d(b)) { + if (__propIsEnum$d.call(b, prop)) + __defNormalProp$d(a, prop, b[prop]); + } + return a; +}; +const _BackgroundSystem = class _BackgroundSystem { + constructor() { + this.clearBeforeRender = true; + this._backgroundColor = new Color(0); + this.color = this._backgroundColor; + this.alpha = 1; + } + /** + * initiates the background system + * @param options - the options for the background colors + */ + init(options) { + options = __spreadValues$d(__spreadValues$d({}, _BackgroundSystem.defaultOptions), options); + this.clearBeforeRender = options.clearBeforeRender; + this.color = options.background || options.backgroundColor || this._backgroundColor; + this.alpha = options.backgroundAlpha; + this._backgroundColor.setAlpha(options.backgroundAlpha); + } + /** The background color to fill if not transparent */ + get color() { + return this._backgroundColor; + } + set color(value) { + this._backgroundColor.setValue(value); + } + /** The background color alpha. Setting this to 0 will make the canvas transparent. */ + get alpha() { + return this._backgroundColor.alpha; + } + set alpha(value) { + this._backgroundColor.setAlpha(value); + } + /** The background color as an [R, G, B, A] array. */ + get colorRgba() { + return this._backgroundColor.toArray(); + } + /** + * destroys the background system + * @internal + * @ignore + */ + destroy() { + } +}; +/** @ignore */ +_BackgroundSystem.extension = { + type: [ + ExtensionType.WebGLSystem, + ExtensionType.WebGPUSystem, + ExtensionType.CanvasSystem + ], + name: "background", + priority: 0 +}; +/** default options used by the system */ +_BackgroundSystem.defaultOptions = { + /** + * {@link WebGLOptions.backgroundAlpha} + * @default 1 + */ + backgroundAlpha: 1, + /** + * {@link WebGLOptions.backgroundColor} + * @default 0x000000 + */ + backgroundColor: 0, + /** + * {@link WebGLOptions.clearBeforeRender} + * @default true + */ + clearBeforeRender: true +}; +let BackgroundSystem = _BackgroundSystem; + +"use strict"; +const BLEND_MODE_FILTERS = {}; +extensions.handle(ExtensionType.BlendMode, (value) => { + if (!value.name) { + throw new Error("BlendMode extension must have a name property"); + } + BLEND_MODE_FILTERS[value.name] = value.ref; +}, (value) => { + delete BLEND_MODE_FILTERS[value.name]; +}); +class BlendModePipe { + constructor(renderer) { + this._isAdvanced = false; + this._filterHash = /* @__PURE__ */ Object.create(null); + this._renderer = renderer; + } + /** + * This ensures that a blendMode switch is added to the instruction set if the blend mode has changed. + * @param renderable - The renderable we are adding to the instruction set + * @param blendMode - The blend mode of the renderable + * @param instructionSet - The instruction set we are adding to + */ + setBlendMode(renderable, blendMode, instructionSet) { + if (this._activeBlendMode === blendMode) { + if (this._isAdvanced) + this._renderableList.push(renderable); + return; + } + this._activeBlendMode = blendMode; + if (this._isAdvanced) { + this._endAdvancedBlendMode(instructionSet); + } + this._isAdvanced = !!BLEND_MODE_FILTERS[blendMode]; + if (this._isAdvanced) { + this._beginAdvancedBlendMode(instructionSet); + this._renderableList.push(renderable); + } + } + _beginAdvancedBlendMode(instructionSet) { + this._renderer.renderPipes.batch.break(instructionSet); + const blendMode = this._activeBlendMode; + if (!BLEND_MODE_FILTERS[blendMode]) { + warn(`Unable to assign BlendMode: '${blendMode}'. You may want to include: import 'pixi.js/advanced-blend-modes'`); + return; + } + if (!this._filterHash[blendMode]) { + this._filterHash[blendMode] = new FilterEffect({ + filters: [new BLEND_MODE_FILTERS[blendMode]()] + }); + } + const instruction = { + renderPipeId: "filter", + action: "pushFilter", + renderables: [], + filterEffect: this._filterHash[blendMode], + canBundle: false + }; + this._renderableList = instruction.renderables; + instructionSet.add(instruction); + } + _endAdvancedBlendMode(instructionSet) { + this._renderableList = null; + this._renderer.renderPipes.batch.break(instructionSet); + instructionSet.add({ + renderPipeId: "filter", + action: "popFilter", + canBundle: false + }); + } + /** + * called when the instruction build process is starting this will reset internally to the default blend mode + * @internal + * @ignore + */ + buildStart() { + this._isAdvanced = false; + } + /** + * called when the instruction build process is finished, ensuring that if there is an advanced blend mode + * active, we add the final render instructions added to the instruction set + * @param instructionSet - The instruction set we are adding to + * @internal + * @ignore + */ + buildEnd(instructionSet) { + if (this._isAdvanced) { + this._endAdvancedBlendMode(instructionSet); + } + } + /** + * @internal + * @ignore + */ + destroy() { + this._renderer = null; + this._renderableList = null; + for (const i in this._filterHash) { + this._filterHash[i].destroy(); + } + this._filterHash = null; + } +} +/** @ignore */ +BlendModePipe.extension = { + type: [ + ExtensionType.WebGLPipes, + ExtensionType.WebGPUPipes, + ExtensionType.CanvasPipes + ], + name: "blendMode" +}; + +"use strict"; +var __defProp$c = Object.defineProperty; +var __getOwnPropSymbols$c = Object.getOwnPropertySymbols; +var __hasOwnProp$c = Object.prototype.hasOwnProperty; +var __propIsEnum$c = Object.prototype.propertyIsEnumerable; +var __defNormalProp$c = (obj, key, value) => key in obj ? __defProp$c(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; +var __spreadValues$c = (a, b) => { + for (var prop in b || (b = {})) + if (__hasOwnProp$c.call(b, prop)) + __defNormalProp$c(a, prop, b[prop]); + if (__getOwnPropSymbols$c) + for (var prop of __getOwnPropSymbols$c(b)) { + if (__propIsEnum$c.call(b, prop)) + __defNormalProp$c(a, prop, b[prop]); + } + return a; +}; +const imageTypes = { + png: "image/png", + jpg: "image/jpeg", + webp: "image/webp" +}; +const _ExtractSystem = class _ExtractSystem { + /** @param renderer - The renderer this System works for. */ + constructor(renderer) { + this._renderer = renderer; + } + _normalizeOptions(options, defaults = {}) { + if (options instanceof Container || options instanceof Texture) { + return __spreadValues$c({ + target: options + }, defaults); + } + return __spreadValues$c(__spreadValues$c({}, defaults), options); + } + /** + * Will return a HTML Image of the target + * @param options - The options for creating the image, or the target to extract + * @returns - HTML Image of the target + */ + async image(options) { + const image = new Image(); + image.src = await this.base64(options); + return image; + } + /** + * Will return a base64 encoded string of this target. It works by calling + * `Extract.canvas` and then running toDataURL on that. + * @param options - The options for creating the image, or the target to extract + */ + async base64(options) { + options = this._normalizeOptions( + options, + _ExtractSystem.defaultImageOptions + ); + const { format, quality } = options; + const canvas = this.canvas(options); + if (canvas.toBlob !== void 0) { + return new Promise((resolve, reject) => { + canvas.toBlob((blob) => { + if (!blob) { + reject(new Error("ICanvas.toBlob failed!")); + return; + } + const reader = new FileReader(); + reader.onload = () => resolve(reader.result); + reader.onerror = reject; + reader.readAsDataURL(blob); + }, imageTypes[format], quality); + }); + } + if (canvas.toDataURL !== void 0) { + return canvas.toDataURL(imageTypes[format], quality); + } + if (canvas.convertToBlob !== void 0) { + const blob = await canvas.convertToBlob({ type: imageTypes[format], quality }); + return new Promise((resolve, reject) => { + const reader = new FileReader(); + reader.onload = () => resolve(reader.result); + reader.onerror = reject; + reader.readAsDataURL(blob); + }); + } + throw new Error("Extract.base64() requires ICanvas.toDataURL, ICanvas.toBlob, or ICanvas.convertToBlob to be implemented"); + } + /** + * Creates a Canvas element, renders this target to it and then returns it. + * @param options - The options for creating the canvas, or the target to extract + * @returns - A Canvas element with the texture rendered on. + */ + canvas(options) { + options = this._normalizeOptions(options); + const target = options.target; + const renderer = this._renderer; + if (target instanceof Texture) { + return renderer.texture.generateCanvas(target); + } + const texture = renderer.textureGenerator.generateTexture(options); + const canvas = renderer.texture.generateCanvas(texture); + texture.destroy(); + return canvas; + } + /** + * Will return a one-dimensional array containing the pixel data of the entire texture in RGBA + * order, with integer values between 0 and 255 (included). + * @param options - The options for extracting the image, or the target to extract + * @returns - One-dimensional array containing the pixel data of the entire texture + */ + pixels(options) { + options = this._normalizeOptions(options); + const target = options.target; + const renderer = this._renderer; + const texture = target instanceof Texture ? target : renderer.textureGenerator.generateTexture(options); + const pixelInfo = renderer.texture.getPixels(texture); + if (target instanceof Container) { + texture.destroy(); + } + return pixelInfo; + } + /** + * Will return a texture of the target + * @param options - The options for creating the texture, or the target to extract + * @returns - A texture of the target + */ + texture(options) { + options = this._normalizeOptions(options); + if (options.target instanceof Texture) + return options.target; + return this._renderer.textureGenerator.generateTexture(options); + } + /** + * Will extract a HTMLImage of the target and download it + * @param options - The options for downloading and extracting the image, or the target to extract + */ + download(options) { + var _a; + options = this._normalizeOptions(options); + const canvas = this.canvas(options); + const link = document.createElement("a"); + link.download = (_a = options.filename) != null ? _a : "image.png"; + link.href = canvas.toDataURL("image/png"); + document.body.appendChild(link); + link.click(); + document.body.removeChild(link); + } + /** + * Logs the target to the console as an image. This is a useful way to debug what's happening in the renderer. + * @param options - The options for logging the image, or the target to log + */ + log(options) { + var _a; + const width = (_a = options.width) != null ? _a : 200; + options = this._normalizeOptions(options); + const canvas = this.canvas(options); + const base64 = canvas.toDataURL(); + console.log(`[Pixi Texture] ${canvas.width}px ${canvas.height}px`); + const style = [ + "font-size: 1px;", + `padding: ${width}px ${300}px;`, + `background: url(${base64}) no-repeat;`, + "background-size: contain;" + ].join(" "); + console.log("%c ", style); + } + destroy() { + this._renderer = null; + } +}; +/** @ignore */ +_ExtractSystem.extension = { + type: [ + ExtensionType.WebGLSystem, + ExtensionType.WebGPUSystem + ], + name: "extract" +}; +/** Default options for creating an image. */ +_ExtractSystem.defaultImageOptions = { + /** The format of the image. */ + format: "png", + /** The quality of the image. */ + quality: 1 +}; +let ExtractSystem = _ExtractSystem; + +"use strict"; +class RenderTexture extends Texture { + static create(options) { + return new Texture({ + source: new TextureSource(options) + }); + } + /** + * Resizes the render texture. + * @param width - The new width of the render texture. + * @param height - The new height of the render texture. + * @param resolution - The new resolution of the render texture. + * @returns This texture. + */ + resize(width, height, resolution) { + this.source.resize(width, height, resolution); + return this; + } +} + +"use strict"; +var __defProp$b = Object.defineProperty; +var __defProps$5 = Object.defineProperties; +var __getOwnPropDescs$5 = Object.getOwnPropertyDescriptors; +var __getOwnPropSymbols$b = Object.getOwnPropertySymbols; +var __hasOwnProp$b = Object.prototype.hasOwnProperty; +var __propIsEnum$b = Object.prototype.propertyIsEnumerable; +var __defNormalProp$b = (obj, key, value) => key in obj ? __defProp$b(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; +var __spreadValues$b = (a, b) => { + for (var prop in b || (b = {})) + if (__hasOwnProp$b.call(b, prop)) + __defNormalProp$b(a, prop, b[prop]); + if (__getOwnPropSymbols$b) + for (var prop of __getOwnPropSymbols$b(b)) { + if (__propIsEnum$b.call(b, prop)) + __defNormalProp$b(a, prop, b[prop]); + } + return a; +}; +var __spreadProps$5 = (a, b) => __defProps$5(a, __getOwnPropDescs$5(b)); +const tempRect = new Rectangle(); +const tempBounds = new Bounds(); +const noColor = [0, 0, 0, 0]; +class GenerateTextureSystem { + constructor(renderer) { + this._renderer = renderer; + } + /** + * A Useful function that returns a texture of the display object that can then be used to create sprites + * This can be quite useful if your container is complicated and needs to be reused multiple times. + * @param {GenerateTextureOptions | Container} options - Generate texture options. + * @param {Container} [options.container] - If not given, the renderer's resolution is used. + * @param {Rectangle} options.region - The region of the container, that shall be rendered, + * @param {number} [options.resolution] - The resolution of the texture being generated. + * if no region is specified, defaults to the local bounds of the container. + * @param {GenerateTextureSourceOptions} [options.textureSourceOptions] - Texture options for GPU. + * @returns a shiny new texture of the container passed in + */ + generateTexture(options) { + var _a; + if (options instanceof Container) { + options = { + target: options, + frame: void 0, + textureSourceOptions: {}, + resolution: void 0 + }; + } + const resolution = options.resolution || this._renderer.resolution; + const antialias = options.antialias || this._renderer.view.antialias; + const container = options.target; + let clearColor = options.clearColor; + if (clearColor) { + const isRGBAArray = Array.isArray(clearColor) && clearColor.length === 4; + clearColor = isRGBAArray ? clearColor : Color.shared.setValue(clearColor).toArray(); + } else { + clearColor = noColor; + } + const region = ((_a = options.frame) == null ? void 0 : _a.copyTo(tempRect)) || getLocalBounds(container, tempBounds).rectangle; + region.width = Math.max(region.width, 1 / resolution) | 0; + region.height = Math.max(region.height, 1 / resolution) | 0; + const target = RenderTexture.create(__spreadProps$5(__spreadValues$b({}, options.textureSourceOptions), { + width: region.width, + height: region.height, + resolution, + antialias + })); + const transform = Matrix.shared.translate(-region.x, -region.y); + this._renderer.render({ + container, + transform, + target, + clearColor + }); + return target; + } + destroy() { + this._renderer = null; + } +} +/** @ignore */ +GenerateTextureSystem.extension = { + type: [ + ExtensionType.WebGLSystem, + ExtensionType.WebGPUSystem + ], + name: "textureGenerator" +}; + +"use strict"; +class GlobalUniformSystem { + constructor(renderer) { + this._stackIndex = 0; + this._globalUniformDataStack = []; + this._uniformsPool = []; + this._activeUniforms = []; + this._bindGroupPool = []; + this._activeBindGroups = []; + this._renderer = renderer; + } + reset() { + this._stackIndex = 0; + for (let i = 0; i < this._activeUniforms.length; i++) { + this._uniformsPool.push(this._activeUniforms[i]); + } + for (let i = 0; i < this._activeBindGroups.length; i++) { + this._bindGroupPool.push(this._activeBindGroups[i]); + } + this._activeUniforms.length = 0; + this._activeBindGroups.length = 0; + } + start(options) { + this.reset(); + this.push(options); + } + bind({ + size, + projectionMatrix, + worldTransformMatrix, + worldColor, + offset + }) { + const renderTarget = this._renderer.renderTarget.renderTarget; + const currentGlobalUniformData = this._stackIndex ? this._globalUniformDataStack[this._stackIndex - 1] : { + projectionData: renderTarget, + worldTransformMatrix: new Matrix(), + worldColor: 4294967295, + offset: new Point() + }; + const globalUniformData = { + projectionMatrix: projectionMatrix || this._renderer.renderTarget.projectionMatrix, + resolution: size || renderTarget.size, + worldTransformMatrix: worldTransformMatrix || currentGlobalUniformData.worldTransformMatrix, + worldColor: worldColor || currentGlobalUniformData.worldColor, + offset: offset || currentGlobalUniformData.offset, + bindGroup: null + }; + const uniformGroup = this._uniformsPool.pop() || this._createUniforms(); + this._activeUniforms.push(uniformGroup); + const uniforms = uniformGroup.uniforms; + uniforms.uProjectionMatrix = globalUniformData.projectionMatrix; + uniforms.uResolution = globalUniformData.resolution; + uniforms.uWorldTransformMatrix.copyFrom(globalUniformData.worldTransformMatrix); + uniforms.uWorldTransformMatrix.tx -= globalUniformData.offset.x; + uniforms.uWorldTransformMatrix.ty -= globalUniformData.offset.y; + color32BitToUniform( + globalUniformData.worldColor, + uniforms.uWorldColorAlpha, + 0 + ); + uniformGroup.update(); + let bindGroup; + if (this._renderer.renderPipes.uniformBatch) { + bindGroup = this._renderer.renderPipes.uniformBatch.getUniformBindGroup(uniformGroup, false); + } else { + bindGroup = this._bindGroupPool.pop() || new BindGroup(); + this._activeBindGroups.push(bindGroup); + bindGroup.setResource(uniformGroup, 0); + } + globalUniformData.bindGroup = bindGroup; + this._currentGlobalUniformData = globalUniformData; + } + push(options) { + this.bind(options); + this._globalUniformDataStack[this._stackIndex++] = this._currentGlobalUniformData; + } + pop() { + this._currentGlobalUniformData = this._globalUniformDataStack[--this._stackIndex - 1]; + if (this._renderer.type === RendererType.WEBGL) { + this._currentGlobalUniformData.bindGroup.resources[0].update(); + } + } + get bindGroup() { + return this._currentGlobalUniformData.bindGroup; + } + get uniformGroup() { + return this._currentGlobalUniformData.bindGroup.resources[0]; + } + _createUniforms() { + const globalUniforms = new UniformGroup({ + uProjectionMatrix: { value: new Matrix(), type: "mat3x3" }, + uWorldTransformMatrix: { value: new Matrix(), type: "mat3x3" }, + // TODO - someone smart - set this to be a unorm8x4 rather than a vec4 + uWorldColorAlpha: { value: new Float32Array(4), type: "vec4" }, + uResolution: { value: [0, 0], type: "vec2" } + }, { + isStatic: true + }); + return globalUniforms; + } + destroy() { + this._renderer = null; + } +} +/** @ignore */ +GlobalUniformSystem.extension = { + type: [ + ExtensionType.WebGLSystem, + ExtensionType.WebGPUSystem, + ExtensionType.CanvasSystem + ], + name: "globalUniforms" +}; + +"use strict"; +let saidHello = false; +const VERSION = "8.1.0"; +function sayHello(type) { + if (saidHello) { + return; + } + if (DOMAdapter.get().getNavigator().userAgent.toLowerCase().indexOf("chrome") > -1) { + const args = [ + `%c %c %c %c %c PixiJS %c v${VERSION} (${type}) http://www.pixijs.com/ + +`, + "background: #E72264; padding:5px 0;", + "background: #6CA2EA; padding:5px 0;", + "background: #B5D33D; padding:5px 0;", + "background: #FED23F; padding:5px 0;", + "color: #FFFFFF; background: #E72264; padding:5px 0;", + "color: #E72264; background: #FFFFFF; padding:5px 0;" + ]; + globalThis.console.log(...args); + } else if (globalThis.console) { + globalThis.console.log(`PixiJS ${VERSION} - ${type} - http://www.pixijs.com/`); + } + saidHello = true; +} + +"use strict"; +class HelloSystem { + constructor(renderer) { + this._renderer = renderer; + } + /** + * It all starts here! This initiates every system, passing in the options for any system by name. + * @param options - the config for the renderer and all its systems + */ + init(options) { + if (options.hello) { + let name = this._renderer.name; + if (this._renderer.type === RendererType.WEBGL) { + name += ` ${this._renderer.context.webGLVersion}`; + } + sayHello(name); + } + } +} +/** @ignore */ +HelloSystem.extension = { + type: [ + ExtensionType.WebGLSystem, + ExtensionType.WebGPUSystem, + ExtensionType.CanvasSystem + ], + name: "hello", + priority: -2 +}; +/** The default options for the system. */ +HelloSystem.defaultOptions = { + /** {@link WebGLOptions.hello} */ + hello: false +}; + +"use strict"; +var __defProp$a = Object.defineProperty; +var __getOwnPropSymbols$a = Object.getOwnPropertySymbols; +var __hasOwnProp$a = Object.prototype.hasOwnProperty; +var __propIsEnum$a = Object.prototype.propertyIsEnumerable; +var __defNormalProp$a = (obj, key, value) => key in obj ? __defProp$a(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; +var __spreadValues$a = (a, b) => { + for (var prop in b || (b = {})) + if (__hasOwnProp$a.call(b, prop)) + __defNormalProp$a(a, prop, b[prop]); + if (__getOwnPropSymbols$a) + for (var prop of __getOwnPropSymbols$a(b)) { + if (__propIsEnum$a.call(b, prop)) + __defNormalProp$a(a, prop, b[prop]); + } + return a; +}; +const _TextureGCSystem = class _TextureGCSystem { + /** @param renderer - The renderer this System works for. */ + constructor(renderer) { + this._renderer = renderer; + this.count = 0; + this.checkCount = 0; + } + init(options) { + options = __spreadValues$a(__spreadValues$a({}, _TextureGCSystem.defaultOptions), options); + this.checkCountMax = options.textureGCCheckCountMax; + this.maxIdle = options.textureGCAMaxIdle; + this.active = options.textureGCActive; + } + /** + * Checks to see when the last time a texture was used. + * If the texture has not been used for a specified amount of time, it will be removed from the GPU. + */ + postrender() { + if (!this._renderer.renderingToScreen) { + return; + } + this.count++; + if (!this.active) + return; + this.checkCount++; + if (this.checkCount > this.checkCountMax) { + this.checkCount = 0; + this.run(); + } + } + /** + * Checks to see when the last time a texture was used. + * If the texture has not been used for a specified amount of time, it will be removed from the GPU. + */ + run() { + const managedTextures = this._renderer.texture.managedTextures; + for (let i = 0; i < managedTextures.length; i++) { + const texture = managedTextures[i]; + if (texture.autoGarbageCollect && texture.resource && texture._touched > -1 && this.count - texture._touched > this.maxIdle) { + texture._touched = -1; + texture.unload(); + } + } + } + destroy() { + this._renderer = null; + } +}; +/** @ignore */ +_TextureGCSystem.extension = { + type: [ + ExtensionType.WebGLSystem, + ExtensionType.WebGPUSystem + ], + name: "textureGC" +}; +/** default options for the TextureGCSystem */ +_TextureGCSystem.defaultOptions = { + /** + * If set to true, this will enable the garbage collector on the GPU. + * @default true + */ + textureGCActive: true, + /** + * The maximum idle frames before a texture is destroyed by garbage collection. + * @default 60 * 60 + */ + textureGCAMaxIdle: 60 * 60, + /** + * Frames between two garbage collections. + * @default 600 + */ + textureGCCheckCountMax: 600 +}; +let TextureGCSystem = _TextureGCSystem; +extensions.add(TextureGCSystem); + +"use strict"; +var __defProp$9 = Object.defineProperty; +var __getOwnPropSymbols$9 = Object.getOwnPropertySymbols; +var __hasOwnProp$9 = Object.prototype.hasOwnProperty; +var __propIsEnum$9 = Object.prototype.propertyIsEnumerable; +var __defNormalProp$9 = (obj, key, value) => key in obj ? __defProp$9(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; +var __spreadValues$9 = (a, b) => { + for (var prop in b || (b = {})) + if (__hasOwnProp$9.call(b, prop)) + __defNormalProp$9(a, prop, b[prop]); + if (__getOwnPropSymbols$9) + for (var prop of __getOwnPropSymbols$9(b)) { + if (__propIsEnum$9.call(b, prop)) + __defNormalProp$9(a, prop, b[prop]); + } + return a; +}; +const _ViewSystem = class _ViewSystem { + /** The resolution / device pixel ratio of the renderer. */ + get resolution() { + return this.texture.source._resolution; + } + set resolution(value) { + this.texture.source.resize( + this.texture.source.width, + this.texture.source.height, + value + ); + } + /** + * initiates the view system + * @param options - the options for the view + */ + init(options) { + options = __spreadValues$9(__spreadValues$9({}, _ViewSystem.defaultOptions), options); + if (options.view) { + deprecation(v8_0_0, "ViewSystem.view has been renamed to ViewSystem.canvas"); + options.canvas = options.view; + } + this.screen = new Rectangle(0, 0, options.width, options.height); + this.canvas = options.canvas || DOMAdapter.get().createCanvas(); + this.antialias = !!options.antialias; + this.texture = getCanvasTexture(this.canvas, options); + this.renderTarget = new RenderTarget({ + colorTextures: [this.texture], + depth: !!options.depth, + isRoot: true + }); + this.texture.source.transparent = options.backgroundAlpha < 1; + this.multiView = !!options.multiView; + if (this.autoDensity) { + this.canvas.style.width = `${this.texture.width}px`; + this.canvas.style.height = `${this.texture.height}px`; + } + this.resolution = options.resolution; + } + /** + * Resizes the screen and canvas to the specified dimensions. + * @param desiredScreenWidth - The new width of the screen. + * @param desiredScreenHeight - The new height of the screen. + * @param resolution + */ + resize(desiredScreenWidth, desiredScreenHeight, resolution) { + this.texture.source.resize(desiredScreenWidth, desiredScreenHeight, resolution); + this.screen.width = this.texture.frame.width; + this.screen.height = this.texture.frame.height; + if (this.autoDensity) { + this.canvas.style.width = `${desiredScreenWidth}px`; + this.canvas.style.height = `${desiredScreenHeight}px`; + } + } + /** + * Destroys this System and optionally removes the canvas from the dom. + * @param {options | false} options - The options for destroying the view, or "false". + * @param options.removeView - Whether to remove the view element from the DOM. Defaults to `false`. + */ + destroy(options = false) { + const removeView = typeof options === "boolean" ? options : !!(options == null ? void 0 : options.removeView); + if (removeView && this.canvas.parentNode) { + this.canvas.parentNode.removeChild(this.canvas); + } + } +}; +/** @ignore */ +_ViewSystem.extension = { + type: [ + ExtensionType.WebGLSystem, + ExtensionType.WebGPUSystem, + ExtensionType.CanvasSystem + ], + name: "view", + priority: 0 +}; +/** The default options for the view system. */ +_ViewSystem.defaultOptions = { + /** + * {@link WebGLOptions.width} + * @default 800 + */ + width: 800, + /** + * {@link WebGLOptions.height} + * @default 600 + */ + height: 600, + /** + * {@link WebGLOptions.autoDensity} + * @default false + */ + autoDensity: false, + /** + * {@link WebGLOptions.antialias} + * @default false + */ + antialias: false +}; +let ViewSystem = _ViewSystem; + +"use strict"; +const SharedSystems = [ + BackgroundSystem, + GlobalUniformSystem, + HelloSystem, + ViewSystem, + RenderGroupSystem, + TextureGCSystem, + GenerateTextureSystem, + ExtractSystem +]; +const SharedRenderPipes = [ + BlendModePipe, + BatcherPipe, + SpritePipe, + RenderGroupPipe, + AlphaMaskPipe, + StencilMaskPipe, + ColorMaskPipe, + CustomRenderPipe +]; + +"use strict"; +const DefaultWebGLSystems = [ + ...SharedSystems, + GlUboSystem, + GlBackBufferSystem, + GlContextSystem, + GlBufferSystem, + GlTextureSystem, + GlRenderTargetSystem, + GlGeometrySystem, + GlUniformGroupSystem, + GlShaderSystem, + GlEncoderSystem, + GlStateSystem, + GlStencilSystem, + GlColorMaskSystem +]; +const DefaultWebGLPipes = [...SharedRenderPipes]; +const DefaultWebGLAdapters = [GlBatchAdaptor, GlMeshAdaptor, GlGraphicsAdaptor]; +const systems$1 = []; +const renderPipes$1 = []; +const renderPipeAdaptors$1 = []; +extensions.handleByNamedList(ExtensionType.WebGLSystem, systems$1); +extensions.handleByNamedList(ExtensionType.WebGLPipes, renderPipes$1); +extensions.handleByNamedList(ExtensionType.WebGLPipesAdaptor, renderPipeAdaptors$1); +extensions.add(...DefaultWebGLSystems, ...DefaultWebGLPipes, ...DefaultWebGLAdapters); +class WebGLRenderer extends AbstractRenderer { + constructor() { + const systemConfig = { + name: "webgl", + type: RendererType.WEBGL, + systems: systems$1, + renderPipes: renderPipes$1, + renderPipeAdaptors: renderPipeAdaptors$1 + }; + super(systemConfig); + } +} + +var WebGLRenderer$1 = { + __proto__: null, + WebGLRenderer: WebGLRenderer +}; + +"use strict"; +class BindGroupSystem { + constructor(renderer) { + this._hash = /* @__PURE__ */ Object.create(null); + this._renderer = renderer; + } + contextChange(gpu) { + this._gpu = gpu; + } + getBindGroup(bindGroup, program, groupIndex) { + bindGroup._updateKey(); + const gpuBindGroup = this._hash[bindGroup._key] || this._createBindGroup(bindGroup, program, groupIndex); + return gpuBindGroup; + } + _createBindGroup(group, program, groupIndex) { + var _a; + const device = this._gpu.device; + const groupLayout = program.layout[groupIndex]; + const entries = []; + const renderer = this._renderer; + for (const j in groupLayout) { + const resource = (_a = group.resources[j]) != null ? _a : group.resources[groupLayout[j]]; + let gpuResource; + if (resource._resourceType === "uniformGroup") { + const uniformGroup = resource; + renderer.ubo.updateUniformGroup(uniformGroup); + const buffer = uniformGroup.buffer; + gpuResource = { + buffer: renderer.buffer.getGPUBuffer(buffer), + offset: 0, + size: buffer.descriptor.size + }; + } else if (resource._resourceType === "buffer") { + const buffer = resource; + gpuResource = { + buffer: renderer.buffer.getGPUBuffer(buffer), + offset: 0, + size: buffer.descriptor.size + }; + } else if (resource._resourceType === "bufferResource") { + const bufferResource = resource; + gpuResource = { + buffer: renderer.buffer.getGPUBuffer(bufferResource.buffer), + offset: bufferResource.offset, + size: bufferResource.size + }; + } else if (resource._resourceType === "textureSampler") { + const sampler = resource; + gpuResource = renderer.texture.getGpuSampler(sampler); + } else if (resource._resourceType === "textureSource") { + const texture = resource; + gpuResource = renderer.texture.getGpuSource(texture).createView({}); + } + entries.push({ + binding: groupLayout[j], + resource: gpuResource + }); + } + const layout = renderer.shader.getProgramData(program).bindGroups[groupIndex]; + const gpuBindGroup = device.createBindGroup({ + layout, + entries + }); + this._hash[group._key] = gpuBindGroup; + return gpuBindGroup; + } + destroy() { + for (const key of Object.keys(this._hash)) { + this._hash[key] = null; + } + this._hash = null; + this._renderer = null; + } +} +/** @ignore */ +BindGroupSystem.extension = { + type: [ + ExtensionType.WebGPUSystem + ], + name: "bindGroup" +}; + +"use strict"; +class GpuBufferSystem { + constructor() { + this._gpuBuffers = /* @__PURE__ */ Object.create(null); + this._managedBuffers = []; + } + contextChange(gpu) { + this._gpu = gpu; + } + getGPUBuffer(buffer) { + return this._gpuBuffers[buffer.uid] || this.createGPUBuffer(buffer); + } + updateBuffer(buffer) { + const gpuBuffer = this._gpuBuffers[buffer.uid] || this.createGPUBuffer(buffer); + const data = buffer.data; + if (buffer._updateID && data) { + buffer._updateID = 0; + this._gpu.device.queue.writeBuffer( + gpuBuffer, + 0, + data.buffer, + 0, + // round to the nearest 4 bytes + (buffer._updateSize || data.byteLength) + 3 & ~3 + ); + } + return gpuBuffer; + } + /** dispose all WebGL resources of all managed buffers */ + destroyAll() { + for (const id in this._gpuBuffers) { + this._gpuBuffers[id].destroy(); + } + this._gpuBuffers = {}; + } + createGPUBuffer(buffer) { + if (!this._gpuBuffers[buffer.uid]) { + buffer.on("update", this.updateBuffer, this); + buffer.on("change", this.onBufferChange, this); + buffer.on("destroy", this.onBufferDestroy, this); + } + const gpuBuffer = this._gpu.device.createBuffer(buffer.descriptor); + buffer._updateID = 0; + if (buffer.data) { + fastCopy(buffer.data.buffer, gpuBuffer.getMappedRange()); + gpuBuffer.unmap(); + } + this._gpuBuffers[buffer.uid] = gpuBuffer; + this._managedBuffers.push(buffer); + return gpuBuffer; + } + onBufferChange(buffer) { + const gpuBuffer = this._gpuBuffers[buffer.uid]; + gpuBuffer.destroy(); + buffer._updateID = 0; + this._gpuBuffers[buffer.uid] = this.createGPUBuffer(buffer); + } + /** + * Disposes buffer + * @param buffer - buffer with data + */ + onBufferDestroy(buffer) { + this._managedBuffers.splice(this._managedBuffers.indexOf(buffer), 1); + this._destroyBuffer(buffer); + } + destroy() { + this._managedBuffers.forEach((buffer) => this._destroyBuffer(buffer)); + this._managedBuffers = null; + this._gpuBuffers = null; + } + _destroyBuffer(buffer) { + const gpuBuffer = this._gpuBuffers[buffer.uid]; + gpuBuffer.destroy(); + buffer.off("update", this.updateBuffer, this); + buffer.off("change", this.onBufferChange, this); + buffer.off("destroy", this.onBufferDestroy, this); + this._gpuBuffers[buffer.uid] = null; + } +} +/** @ignore */ +GpuBufferSystem.extension = { + type: [ + ExtensionType.WebGPUSystem + ], + name: "buffer" +}; + +"use strict"; +function GpuReadBuffer(buffer, renderer) { + const bufferSize = buffer.descriptor.size; + const device = renderer.gpu.device; + const stagingBuffer = new Buffer({ + data: new Float32Array(24e5), + usage: BufferUsage.MAP_READ | BufferUsage.COPY_DST + }); + const stagingGPUBuffer = renderer.buffer.createGPUBuffer(stagingBuffer); + const commandEncoder = device.createCommandEncoder(); + commandEncoder.copyBufferToBuffer( + renderer.buffer.getGPUBuffer(buffer), + 0, + // Source offset + stagingGPUBuffer, + 0, + // Destination offset + bufferSize + ); + device.queue.submit([commandEncoder.finish()]); + void stagingGPUBuffer.mapAsync( + GPUMapMode.READ, + 0, + // Offset + bufferSize + // Length + ).then(() => { + stagingGPUBuffer.getMappedRange(0, bufferSize); + stagingGPUBuffer.unmap(); + }); +} + +"use strict"; +class UboBatch { + constructor({ minUniformOffsetAlignment }) { + this._minUniformOffsetAlignment = 256; + this.byteIndex = 0; + this._minUniformOffsetAlignment = minUniformOffsetAlignment; + this.data = new Float32Array(65535); + } + clear() { + this.byteIndex = 0; + } + addEmptyGroup(size) { + if (size > this._minUniformOffsetAlignment / 4) { + throw new Error(`UniformBufferBatch: array is too large: ${size * 4}`); + } + const start = this.byteIndex; + let newSize = start + size * 4; + newSize = Math.ceil(newSize / this._minUniformOffsetAlignment) * this._minUniformOffsetAlignment; + if (newSize > this.data.length * 4) { + throw new Error("UniformBufferBatch: ubo batch got too big"); + } + this.byteIndex = newSize; + return start; + } + addGroup(array) { + const offset = this.addEmptyGroup(array.length); + for (let i = 0; i < array.length; i++) { + this.data[offset / 4 + i] = array[i]; + } + return offset; + } + destroy() { + this._buffer.destroy(); + this._buffer = null; + this.data = null; + } +} + +"use strict"; +class GpuColorMaskSystem { + constructor(renderer) { + this._colorMaskCache = 15; + this._renderer = renderer; + } + setMask(colorMask) { + if (this._colorMaskCache === colorMask) + return; + this._colorMaskCache = colorMask; + this._renderer.pipeline.setColorMask(colorMask); + } + destroy() { + this._renderer = null; + this._colorMaskCache = null; + } +} +/** @ignore */ +GpuColorMaskSystem.extension = { + type: [ + ExtensionType.WebGPUSystem + ], + name: "colorMask" +}; + +"use strict"; +class GpuDeviceSystem { + /** + * @param {WebGPURenderer} renderer - The renderer this System works for. + */ + constructor(renderer) { + this._renderer = renderer; + } + async init(options) { + if (this._initPromise) + return this._initPromise; + this._initPromise = this._createDeviceAndAdaptor(options).then((gpu) => { + this.gpu = gpu; + this._renderer.runners.contextChange.emit(this.gpu); + }); + return this._initPromise; + } + /** + * Handle the context change event + * @param gpu + */ + contextChange(gpu) { + this._renderer.gpu = gpu; + } + /** + * Helper class to create a WebGL Context + * @param {object} options - An options object that gets passed in to the canvas element containing the + * context attributes + * @see https://developer.mozilla.org/en/docs/Web/API/HTMLCanvasElement/getContext + * @returns {WebGLRenderingContext} the WebGL context + */ + async _createDeviceAndAdaptor(options) { + const adapter = await navigator.gpu.requestAdapter({ + powerPreference: options.powerPreference, + forceFallbackAdapter: options.forceFallbackAdapter + }); + const requiredFeatures = [ + "texture-compression-bc", + "texture-compression-astc", + "texture-compression-etc2" + ].filter((feature) => adapter.features.has(feature)); + const device = await adapter.requestDevice({ + requiredFeatures + }); + return { adapter, device }; + } + destroy() { + this.gpu = null; + this._renderer = null; + } +} +/** @ignore */ +GpuDeviceSystem.extension = { + type: [ + ExtensionType.WebGPUSystem + ], + name: "device" +}; +/** The default options for the GpuDeviceSystem. */ +GpuDeviceSystem.defaultOptions = { + /** + * {@link WebGPUOptions.powerPreference} + * @default default + */ + powerPreference: void 0, + /** + * Force the use of the fallback adapter + * @default false + */ + forceFallbackAdapter: false +}; + +"use strict"; +var __defProp$8 = Object.defineProperty; +var __getOwnPropSymbols$8 = Object.getOwnPropertySymbols; +var __hasOwnProp$8 = Object.prototype.hasOwnProperty; +var __propIsEnum$8 = Object.prototype.propertyIsEnumerable; +var __defNormalProp$8 = (obj, key, value) => key in obj ? __defProp$8(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; +var __spreadValues$8 = (a, b) => { + for (var prop in b || (b = {})) + if (__hasOwnProp$8.call(b, prop)) + __defNormalProp$8(a, prop, b[prop]); + if (__getOwnPropSymbols$8) + for (var prop of __getOwnPropSymbols$8(b)) { + if (__propIsEnum$8.call(b, prop)) + __defNormalProp$8(a, prop, b[prop]); + } + return a; +}; +class GpuEncoderSystem { + constructor(renderer) { + this._boundBindGroup = /* @__PURE__ */ Object.create(null); + this._boundVertexBuffer = /* @__PURE__ */ Object.create(null); + this._renderer = renderer; + } + renderStart() { + this.commandFinished = new Promise((resolve) => { + this._resolveCommandFinished = resolve; + }); + this.commandEncoder = this._renderer.gpu.device.createCommandEncoder(); + } + beginRenderPass(gpuRenderTarget) { + this.endRenderPass(); + this._clearCache(); + this.renderPassEncoder = this.commandEncoder.beginRenderPass(gpuRenderTarget.descriptor); + } + endRenderPass() { + if (this.renderPassEncoder) { + this.renderPassEncoder.end(); + } + this.renderPassEncoder = null; + } + setViewport(viewport) { + this.renderPassEncoder.setViewport(viewport.x, viewport.y, viewport.width, viewport.height, 0, 1); + } + setPipelineFromGeometryProgramAndState(geometry, program, state, topology) { + const pipeline = this._renderer.pipeline.getPipeline(geometry, program, state, topology); + this.setPipeline(pipeline); + } + setPipeline(pipeline) { + if (this._boundPipeline === pipeline) + return; + this._boundPipeline = pipeline; + this.renderPassEncoder.setPipeline(pipeline); + } + _setVertexBuffer(index, buffer) { + if (this._boundVertexBuffer[index] === buffer) + return; + this._boundVertexBuffer[index] = buffer; + this.renderPassEncoder.setVertexBuffer(index, this._renderer.buffer.updateBuffer(buffer)); + } + _setIndexBuffer(buffer) { + if (this._boundIndexBuffer === buffer) + return; + this._boundIndexBuffer = buffer; + const indexFormat = buffer.data.BYTES_PER_ELEMENT === 2 ? "uint16" : "uint32"; + this.renderPassEncoder.setIndexBuffer(this._renderer.buffer.updateBuffer(buffer), indexFormat); + } + resetBindGroup(index) { + this._boundBindGroup[index] = null; + } + setBindGroup(index, bindGroup, program) { + if (this._boundBindGroup[index] === bindGroup) + return; + this._boundBindGroup[index] = bindGroup; + bindGroup._touch(this._renderer.textureGC.count); + const gpuBindGroup = this._renderer.bindGroup.getBindGroup(bindGroup, program, index); + this.renderPassEncoder.setBindGroup(index, gpuBindGroup); + } + setGeometry(geometry) { + for (const i in geometry.attributes) { + const attribute = geometry.attributes[i]; + this._setVertexBuffer(attribute.location, attribute.buffer); + } + if (geometry.indexBuffer) { + this._setIndexBuffer(geometry.indexBuffer); + } + } + _setShaderBindGroups(shader, skipSync) { + for (const i in shader.groups) { + const bindGroup = shader.groups[i]; + if (!skipSync) { + this._syncBindGroup(bindGroup); + } + this.setBindGroup(i, bindGroup, shader.gpuProgram); + } + } + _syncBindGroup(bindGroup) { + for (const j in bindGroup.resources) { + const resource = bindGroup.resources[j]; + if (resource.isUniformGroup) { + this._renderer.ubo.updateUniformGroup(resource); + } + } + } + draw(options) { + const { geometry, shader, state, topology, size, start, instanceCount, skipSync } = options; + this.setPipelineFromGeometryProgramAndState(geometry, shader.gpuProgram, state, topology); + this.setGeometry(geometry); + this._setShaderBindGroups(shader, skipSync); + if (geometry.indexBuffer) { + this.renderPassEncoder.drawIndexed( + size || geometry.indexBuffer.data.length, + instanceCount || geometry.instanceCount, + start || 0 + ); + } else { + this.renderPassEncoder.draw(size || geometry.getSize(), instanceCount || geometry.instanceCount, start || 0); + } + } + finishRenderPass() { + if (this.renderPassEncoder) { + this.renderPassEncoder.end(); + this.renderPassEncoder = null; + } + } + postrender() { + this.finishRenderPass(); + this._gpu.device.queue.submit([this.commandEncoder.finish()]); + this._resolveCommandFinished(); + this.commandEncoder = null; + } + // restores a render pass if finishRenderPass was called + // not optimised as really used for debugging! + // used when we want to stop drawing and log a texture.. + restoreRenderPass() { + const descriptor = this._renderer.renderTarget.adaptor.getDescriptor( + this._renderer.renderTarget.renderTarget, + false, + [0, 0, 0, 1] + ); + this.renderPassEncoder = this.commandEncoder.beginRenderPass(descriptor); + const boundPipeline = this._boundPipeline; + const boundVertexBuffer = __spreadValues$8({}, this._boundVertexBuffer); + const boundIndexBuffer = this._boundIndexBuffer; + const boundBindGroup = __spreadValues$8({}, this._boundBindGroup); + this._clearCache(); + const viewport = this._renderer.renderTarget.viewport; + this.renderPassEncoder.setViewport(viewport.x, viewport.y, viewport.width, viewport.height, 0, 1); + this.setPipeline(boundPipeline); + for (const i in boundVertexBuffer) { + this._setVertexBuffer(i, boundVertexBuffer[i]); + } + for (const i in boundBindGroup) { + this.setBindGroup(i, boundBindGroup[i], null); + } + this._setIndexBuffer(boundIndexBuffer); + } + _clearCache() { + for (let i = 0; i < 16; i++) { + this._boundBindGroup[i] = null; + this._boundVertexBuffer[i] = null; + } + this._boundIndexBuffer = null; + this._boundPipeline = null; + } + destroy() { + this._renderer = null; + this._gpu = null; + this._boundBindGroup = null; + this._boundVertexBuffer = null; + this._boundIndexBuffer = null; + this._boundPipeline = null; + } + contextChange(gpu) { + this._gpu = gpu; + } +} +/** @ignore */ +GpuEncoderSystem.extension = { + type: [ExtensionType.WebGPUSystem], + name: "encoder", + priority: 1 +}; + +"use strict"; +class GpuStencilSystem { + constructor(renderer) { + this._renderTargetStencilState = /* @__PURE__ */ Object.create(null); + this._renderer = renderer; + renderer.renderTarget.onRenderTargetChange.add(this); + } + onRenderTargetChange(renderTarget) { + let stencilState = this._renderTargetStencilState[renderTarget.uid]; + if (!stencilState) { + stencilState = this._renderTargetStencilState[renderTarget.uid] = { + stencilMode: STENCIL_MODES.DISABLED, + stencilReference: 0 + }; + } + this._activeRenderTarget = renderTarget; + this.setStencilMode(stencilState.stencilMode, stencilState.stencilReference); + } + setStencilMode(stencilMode, stencilReference) { + const stencilState = this._renderTargetStencilState[this._activeRenderTarget.uid]; + stencilState.stencilMode = stencilMode; + stencilState.stencilReference = stencilReference; + const renderer = this._renderer; + renderer.pipeline.setStencilMode(stencilMode); + renderer.encoder.renderPassEncoder.setStencilReference(stencilReference); + } + destroy() { + this._renderer.renderTarget.onRenderTargetChange.remove(this); + this._renderer = null; + this._activeRenderTarget = null; + this._renderTargetStencilState = null; + } +} +/** @ignore */ +GpuStencilSystem.extension = { + type: [ + ExtensionType.WebGPUSystem + ], + name: "stencil" +}; + +"use strict"; +const WGSL_ALIGN_SIZE_DATA = { + i32: { align: 4, size: 4 }, + u32: { align: 4, size: 4 }, + f32: { align: 4, size: 4 }, + f16: { align: 2, size: 2 }, + "vec2": { align: 8, size: 8 }, + "vec2": { align: 8, size: 8 }, + "vec2": { align: 8, size: 8 }, + "vec2": { align: 4, size: 4 }, + "vec3": { align: 16, size: 12 }, + "vec3": { align: 16, size: 12 }, + "vec3": { align: 16, size: 12 }, + "vec3": { align: 8, size: 6 }, + "vec4": { align: 16, size: 16 }, + "vec4": { align: 16, size: 16 }, + "vec4": { align: 16, size: 16 }, + "vec4": { align: 8, size: 8 }, + "mat2x2": { align: 8, size: 16 }, + "mat2x2": { align: 4, size: 8 }, + "mat3x2": { align: 8, size: 24 }, + "mat3x2": { align: 4, size: 12 }, + "mat4x2": { align: 8, size: 32 }, + "mat4x2": { align: 4, size: 16 }, + "mat2x3": { align: 16, size: 32 }, + "mat2x3": { align: 8, size: 16 }, + "mat3x3": { align: 16, size: 48 }, + "mat3x3": { align: 8, size: 24 }, + "mat4x3": { align: 16, size: 64 }, + "mat4x3": { align: 8, size: 32 }, + "mat2x4": { align: 16, size: 32 }, + "mat2x4": { align: 8, size: 16 }, + "mat3x4": { align: 16, size: 48 }, + "mat3x4": { align: 8, size: 24 }, + "mat4x4": { align: 16, size: 64 }, + "mat4x4": { align: 8, size: 32 } +}; +function createUboElementsWGSL(uniformData) { + const uboElements = uniformData.map((data) => ({ + data, + offset: 0, + size: 0 + })); + let offset = 0; + for (let i = 0; i < uboElements.length; i++) { + const uboElement = uboElements[i]; + let size = WGSL_ALIGN_SIZE_DATA[uboElement.data.type].size; + const align = WGSL_ALIGN_SIZE_DATA[uboElement.data.type].align; + if (!WGSL_ALIGN_SIZE_DATA[uboElement.data.type]) { + throw new Error(`[Pixi.js] WebGPU UniformBuffer: Unknown type ${uboElement.data.type}`); + } + if (uboElement.data.size > 1) { + size = Math.max(size, align) * uboElement.data.size; + } + offset = Math.ceil(offset / align) * align; + uboElement.size = size; + uboElement.offset = offset; + offset += size; + } + offset = Math.ceil(offset / 16) * 16; + return { uboElements, size: offset }; +} + +"use strict"; +function generateArraySyncWGSL(uboElement, offsetToAdd) { + const { size, align } = WGSL_ALIGN_SIZE_DATA[uboElement.data.type]; + const remainder = (align - size) / 4; + return ` + v = uv.${uboElement.data.name}; + ${offsetToAdd !== 0 ? `offset += ${offsetToAdd};` : ""} arrayOffset = offset; t = 0; - for(var i=0; i < ${r.data.size*(e/4)}; i++) + for(var i=0; i < ${uboElement.data.size * (size / 4)}; i++) { - for(var j = 0; j < ${e/4}; j++) + for(var j = 0; j < ${size / 4}; j++) { data[arrayOffset++] = v[t++]; } - ${i!==0?`arrayOffset += ${i};`:""} + ${remainder !== 0 ? `arrayOffset += ${remainder};` : ""} } - `}function G_(r){return Na(r,"uboWgsl",C_,mg)}class Cu extends La{constructor(){super({createUboElements:O_,generateUboSync:G_})}}Cu.extension={type:[v.WebGPUSystem],name:"ubo"};const ie=128;class Gu{constructor(t){this._bindGroupHash=Object.create(null),this._buffers=[],this._bindGroups=[],this._bufferResources=[],this._renderer=t,this._batchBuffer=new P_({minUniformOffsetAlignment:ie});const e=256/ie;for(let s=0;st in r?vE(r,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):r[t]=e,AE=(r,t)=>{for(var e in t||(t={}))SE.call(t,e)&&B_(r,e,t[e]);if(I_)for(var e of I_(t))EE.call(t,e)&&B_(r,e,t[e]);return r},PE=(r,t)=>yE(r,TE(t));const wE={"point-list":0,"line-list":1,"line-strip":2,"triangle-list":3,"triangle-strip":4};function RE(r,t,e,s,i){return r<<24|t<<16|e<<10|s<<5|i}function ME(r,t,e,s){return e<<6|r<<3|s<<1|t}class Iu{constructor(t){this._moduleCache=Object.create(null),this._bufferLayoutsCache=Object.create(null),this._pipeCache=Object.create(null),this._pipeStateCaches=Object.create(null),this._colorMask=15,this._multisampleCount=1,this._renderer=t}contextChange(t){this._gpu=t,this.setStencilMode(st.DISABLED),this._updatePipeHash()}setMultisampleCount(t){this._multisampleCount!==t&&(this._multisampleCount=t,this._updatePipeHash())}setRenderTarget(t){this._multisampleCount=t.msaaSamples,this._depthStencilAttachment=t.descriptor.depthStencilAttachment?1:0,this._updatePipeHash()}setColorMask(t){this._colorMask!==t&&(this._colorMask=t,this._updatePipeHash())}setStencilMode(t){this._stencilMode!==t&&(this._stencilMode=t,this._stencilState=re[t],this._updatePipeHash())}setPipeline(t,e,s,i){const n=this.getPipeline(t,e,s);i.setPipeline(n)}getPipeline(t,e,s,i){t._layoutKey||(Ga(t,e.attributeData),this._generateBufferKey(t)),i=i||t.topology;const n=RE(t._layoutKey,e._layoutKey,s.data,s._blendModeId,wE[i]);return this._pipeCache[n]?this._pipeCache[n]:(this._pipeCache[n]=this._createPipeline(t,e,s,i),this._pipeCache[n])}_createPipeline(t,e,s,i){const n=this._gpu.device,o=this._createVertexBufferLayouts(t),a=this._renderer.state.getColorTargets(s);a[0].writeMask=this._stencilMode===st.RENDERING_MASK_ADD?0:this._colorMask;const u=this._renderer.shader.getProgramData(e).pipeline,l={vertex:{module:this._getModule(e.vertex.source),entryPoint:e.vertex.entryPoint,buffers:o},fragment:{module:this._getModule(e.fragment.source),entryPoint:e.fragment.entryPoint,targets:a},primitive:{topology:i,cullMode:s.cullMode},layout:u,multisample:{count:this._multisampleCount},label:"PIXI Pipeline"};return this._depthStencilAttachment&&(l.depthStencil=PE(AE({},this._stencilState),{format:"depth24plus-stencil8",depthWriteEnabled:s.depthTest,depthCompare:s.depthTest?"less":"always"})),n.createRenderPipeline(l)}_getModule(t){return this._moduleCache[t]||this._createModule(t)}_createModule(t){const e=this._gpu.device;return this._moduleCache[t]=e.createShaderModule({code:t}),this._moduleCache[t]}_generateBufferKey(t){const e=[];let s=0;const i=Object.keys(t.attributes).sort();for(let o=0;o{const i={arrayStride:0,stepMode:"vertex",attributes:[]},n=i.attributes;for(const o in t.attributes){const a=t.attributes[o];a.buffer===s&&(i.arrayStride=a.stride,i.stepMode=a.instance?"instance":"vertex",n.push({shaderLocation:a.location,offset:a.offset,format:a.format}))}n.length&&e.push(i)}),this._bufferLayoutsCache[t._layoutKey]=e,e}_updatePipeHash(){const t=ME(this._stencilMode,this._multisampleCount,this._colorMask,this._depthStencilAttachment);this._pipeStateCaches[t]||(this._pipeStateCaches[t]=Object.create(null)),this._pipeCache=this._pipeStateCaches[t]}destroy(){this._renderer=null,this._bufferLayoutsCache=null}}Iu.extension={type:[v.WebGPUSystem],name:"pipeline"};class F_{constructor(){this.contexts=[],this.msaaTextures=[],this.msaaSamples=1}}class D_{init(t,e){this._renderer=t,this._renderTargetSystem=e}copyToTexture(t,e,s,i,n){const o=this._renderer,a=this._getGpuColorTexture(t),u=o.texture.getGpuSource(e.source);return o.encoder.commandEncoder.copyTextureToTexture({texture:a,origin:s},{texture:u,origin:n},i),e}startRenderPass(t,e=!0,s,i){const n=this._renderTargetSystem.getGpuRenderTarget(t),o=this.getDescriptor(t,e,s);n.descriptor=o,this._renderer.pipeline.setRenderTarget(n),this._renderer.encoder.beginRenderPass(n),this._renderer.encoder.setViewport(i)}finishRenderPass(){this._renderer.encoder.endRenderPass()}_getGpuColorTexture(t){const e=this._renderTargetSystem.getGpuRenderTarget(t);return e.contexts[0]?e.contexts[0].getCurrentTexture():this._renderer.texture.getGpuSource(t.colorTextures[0].source)}getDescriptor(t,e,s){typeof e=="boolean"&&(e=e?pt.ALL:pt.NONE);const i=this._renderTargetSystem,n=i.getGpuRenderTarget(t),o=t.colorTextures.map((u,l)=>{const h=n.contexts[l];let c,d;h?c=h.getCurrentTexture().createView():c=this._renderer.texture.getGpuSource(u).createView({mipLevelCount:1}),n.msaaTextures[l]&&(d=c,c=this._renderer.texture.getTextureView(n.msaaTextures[l]));const p=e&pt.COLOR?"clear":"load";return s!=null||(s=i.defaultClearColor),{view:c,resolveTarget:d,clearValue:s,storeOp:"store",loadOp:p}});let a;if((t.stencil||t.depth)&&!t.depthStencilTexture&&(t.ensureDepthStencilTexture(),t.depthStencilTexture.source.sampleCount=n.msaa?4:1),t.depthStencilTexture){const u=e&pt.STENCIL?"clear":"load",l=e&pt.DEPTH?"clear":"load";a={view:this._renderer.texture.getGpuSource(t.depthStencilTexture.source).createView(),stencilStoreOp:"store",stencilLoadOp:u,depthClearValue:1,depthLoadOp:l,depthStoreOp:"store"}}return{colorAttachments:o,depthStencilAttachment:a}}clear(t,e=!0,s,i){if(!e)return;const{gpu:n,encoder:o}=this._renderer,a=n.device;if(o.commandEncoder===null){const u=a.createCommandEncoder(),l=this.getDescriptor(t,e,s),h=u.beginRenderPass(l);h.setViewport(i.x,i.y,i.width,i.height,0,1),h.end();const c=u.finish();a.queue.submit([c])}else this.startRenderPass(t,e,s,i)}initGpuRenderTarget(t){t.isRoot=!0;const e=new F_;return t.colorTextures.forEach((s,i)=>{if(Qt.test(s.resource)){const n=s.resource.getContext("webgpu"),o=s.transparent?"premultiplied":"opaque";try{n.configure({device:this._renderer.gpu.device,usage:GPUTextureUsage.TEXTURE_BINDING|GPUTextureUsage.COPY_DST|GPUTextureUsage.RENDER_ATTACHMENT|GPUTextureUsage.COPY_SRC,format:"bgra8unorm",alphaMode:o})}catch(a){console.error(a)}e.contexts[i]=n}if(e.msaa=s.source.antialias,s.source.antialias){const n=new et({width:0,height:0,sampleCount:4});e.msaaTextures[i]=n}}),e.msaa&&(e.msaaSamples=4,t.depthStencilTexture&&(t.depthStencilTexture.source.sampleCount=4)),e}ensureDepthStencilTexture(t){const e=this._renderTargetSystem.getGpuRenderTarget(t);t.depthStencilTexture&&e.msaa&&(t.depthStencilTexture.source.sampleCount=4)}resizeGpuRenderTarget(t){const e=this._renderTargetSystem.getGpuRenderTarget(t);e.width=t.width,e.height=t.height,e.msaa&&t.colorTextures.forEach((s,i)=>{const n=e.msaaTextures[i];n==null||n.resize(s.source.width,s.source.height,s.source._resolution)})}}class Bu extends ja{constructor(t){super(t),this.adaptor=new D_,this.adaptor.init(t,this)}}Bu.extension={type:[v.WebGPUSystem],name:"renderTarget"};class Fu{constructor(){this._gpuProgramData=Object.create(null)}contextChange(t){this._gpu=t}getProgramData(t){return this._gpuProgramData[t._layoutKey]||this._createGPUProgramData(t)}_createGPUProgramData(t){const e=this._gpu.device,s=t.gpuLayout.map(n=>e.createBindGroupLayout({entries:n})),i={bindGroupLayouts:s};return this._gpuProgramData[t._layoutKey]={bindGroups:s,pipeline:e.createPipelineLayout(i)},this._gpuProgramData[t._layoutKey]}destroy(){this._gpu=null,this._gpuProgramData=null}}Fu.extension={type:[v.WebGPUSystem],name:"shader"};const vt={};vt.normal={alpha:{srcFactor:"one",dstFactor:"one-minus-src-alpha",operation:"add"},color:{srcFactor:"one",dstFactor:"one-minus-src-alpha",operation:"add"}},vt.add={alpha:{srcFactor:"src-alpha",dstFactor:"one-minus-src-alpha",operation:"add"},color:{srcFactor:"one",dstFactor:"one",operation:"add"}},vt.multiply={alpha:{srcFactor:"one",dstFactor:"one-minus-src-alpha",operation:"add"},color:{srcFactor:"dst",dstFactor:"one-minus-src-alpha",operation:"add"}},vt.screen={alpha:{srcFactor:"one",dstFactor:"one-minus-src-alpha",operation:"add"},color:{srcFactor:"one",dstFactor:"one-minus-src",operation:"add"}},vt.overlay={alpha:{srcFactor:"one",dstFactor:"one-minus-src-alpha",operation:"add"},color:{srcFactor:"one",dstFactor:"one-minus-src",operation:"add"}},vt.none={alpha:{srcFactor:"one",dstFactor:"one-minus-src-alpha",operation:"add"},color:{srcFactor:"zero",dstFactor:"zero",operation:"add"}},vt["normal-npm"]={alpha:{srcFactor:"one",dstFactor:"one-minus-src-alpha",operation:"add"},color:{srcFactor:"src-alpha",dstFactor:"one-minus-src-alpha",operation:"add"}},vt["add-npm"]={alpha:{srcFactor:"one",dstFactor:"one",operation:"add"},color:{srcFactor:"src-alpha",dstFactor:"one",operation:"add"}},vt["screen-npm"]={alpha:{srcFactor:"one",dstFactor:"one-minus-src-alpha",operation:"add"},color:{srcFactor:"src-alpha",dstFactor:"one-minus-src",operation:"add"}},vt.erase={alpha:{srcFactor:"zero",dstFactor:"one-minus-src-alpha",operation:"add"},color:{srcFactor:"zero",dstFactor:"one-minus-src",operation:"add"}};class Du{constructor(){this.defaultState=new Ct,this.defaultState.blend=!0}contextChange(t){this.gpu=t}getColorTargets(t){return[{format:"bgra8unorm",writeMask:0,blend:vt[t.blendMode]||vt.normal}]}destroy(){this.gpu=null}}Du.extension={type:[v.WebGPUSystem],name:"state"};const U_={type:"image",upload(r,t,e){const s=r.resource,i=(r.pixelWidth|0)*(r.pixelHeight|0),n=s.byteLength/i;e.device.queue.writeTexture({texture:t},s,{offset:0,rowsPerImage:r.pixelHeight,bytesPerRow:r.pixelHeight*n},{width:r.pixelWidth,height:r.pixelHeight,depthOrArrayLayers:1})}},Uu={"bc1-rgba-unorm":{blockBytes:8,blockWidth:4,blockHeight:4},"bc2-rgba-unorm":{blockBytes:16,blockWidth:4,blockHeight:4},"bc3-rgba-unorm":{blockBytes:16,blockWidth:4,blockHeight:4},"bc7-rgba-unorm":{blockBytes:16,blockWidth:4,blockHeight:4},"etc1-rgb-unorm":{blockBytes:8,blockWidth:4,blockHeight:4},"etc2-rgba8unorm":{blockBytes:16,blockWidth:4,blockHeight:4},"astc-4x4-unorm":{blockBytes:16,blockWidth:4,blockHeight:4}},OE={blockBytes:4,blockWidth:1,blockHeight:1},k_={type:"compressed",upload(r,t,e){let s=r.pixelWidth,i=r.pixelHeight;const n=Uu[r.format]||OE;for(let o=0;o>1,1),i=Math.max(i>>1,1)}}},ku={type:"image",upload(r,t,e){const s=r.resource;if(!s)return;const i=Math.min(t.width,r.resourceWidth||r.pixelWidth),n=Math.min(t.height,r.resourceHeight||r.pixelHeight),o=r.alphaMode==="premultiply-alpha-on-upload";e.device.queue.copyExternalImageToTexture({source:s},{texture:t,premultipliedAlpha:o},{width:i,height:n})}},L_={type:"video",upload(r,t,e){ku.upload(r,t,e)}};class $_{constructor(t){this.device=t,this.sampler=t.createSampler({minFilter:"linear"}),this.pipelines={}}_getMipmapPipeline(t){let e=this.pipelines[t];return e||(this.mipmapShaderModule||(this.mipmapShaderModule=this.device.createShaderModule({code:` + `; +} + +"use strict"; +function createUboSyncFunctionWGSL(uboElements) { + return createUboSyncFunction( + uboElements, + "uboWgsl", + generateArraySyncWGSL, + uboSyncFunctionsWGSL + ); +} + +"use strict"; +class GpuUboSystem extends UboSystem { + constructor() { + super({ + createUboElements: createUboElementsWGSL, + generateUboSync: createUboSyncFunctionWGSL + }); + } +} +/** @ignore */ +GpuUboSystem.extension = { + type: [ExtensionType.WebGPUSystem], + name: "ubo" +}; + +"use strict"; +const minUniformOffsetAlignment = 128; +class GpuUniformBatchPipe { + constructor(renderer) { + this._bindGroupHash = /* @__PURE__ */ Object.create(null); + // number of buffers.. + this._buffers = []; + this._bindGroups = []; + this._bufferResources = []; + this._renderer = renderer; + this._batchBuffer = new UboBatch({ minUniformOffsetAlignment }); + const totalBuffers = 256 / minUniformOffsetAlignment; + for (let i = 0; i < totalBuffers; i++) { + let usage = BufferUsage.UNIFORM | BufferUsage.COPY_DST; + if (i === 0) + usage |= BufferUsage.COPY_SRC; + this._buffers.push(new Buffer({ + data: this._batchBuffer.data, + usage + })); + } + } + renderEnd() { + this._uploadBindGroups(); + this._resetBindGroups(); + } + _resetBindGroups() { + for (const i in this._bindGroupHash) { + this._bindGroupHash[i] = null; + } + this._batchBuffer.clear(); + } + // just works for single bind groups for now + getUniformBindGroup(group, duplicate) { + if (!duplicate && this._bindGroupHash[group.uid]) { + return this._bindGroupHash[group.uid]; + } + this._renderer.ubo.ensureUniformGroup(group); + const data = group.buffer.data; + const offset = this._batchBuffer.addEmptyGroup(data.length); + this._renderer.ubo.syncUniformGroup(group, this._batchBuffer.data, offset / 4); + this._bindGroupHash[group.uid] = this._getBindGroup(offset / minUniformOffsetAlignment); + return this._bindGroupHash[group.uid]; + } + getUboResource(group) { + this._renderer.ubo.updateUniformGroup(group); + const data = group.buffer.data; + const offset = this._batchBuffer.addGroup(data); + return this._getBufferResource(offset / minUniformOffsetAlignment); + } + getArrayBindGroup(data) { + const offset = this._batchBuffer.addGroup(data); + return this._getBindGroup(offset / minUniformOffsetAlignment); + } + getArrayBufferResource(data) { + const offset = this._batchBuffer.addGroup(data); + const index = offset / minUniformOffsetAlignment; + return this._getBufferResource(index); + } + _getBufferResource(index) { + if (!this._bufferResources[index]) { + const buffer = this._buffers[index % 2]; + this._bufferResources[index] = new BufferResource({ + buffer, + offset: (index / 2 | 0) * 256, + size: minUniformOffsetAlignment + }); + } + return this._bufferResources[index]; + } + _getBindGroup(index) { + if (!this._bindGroups[index]) { + const bindGroup = new BindGroup({ + 0: this._getBufferResource(index) + }); + this._bindGroups[index] = bindGroup; + } + return this._bindGroups[index]; + } + _uploadBindGroups() { + const bufferSystem = this._renderer.buffer; + const firstBuffer = this._buffers[0]; + firstBuffer.update(this._batchBuffer.byteIndex); + bufferSystem.updateBuffer(firstBuffer); + const commandEncoder = this._renderer.gpu.device.createCommandEncoder(); + for (let i = 1; i < this._buffers.length; i++) { + const buffer = this._buffers[i]; + commandEncoder.copyBufferToBuffer( + bufferSystem.getGPUBuffer(firstBuffer), + minUniformOffsetAlignment, + bufferSystem.getGPUBuffer(buffer), + 0, + this._batchBuffer.byteIndex + ); + } + this._renderer.gpu.device.queue.submit([commandEncoder.finish()]); + } + destroy() { + for (let i = 0; i < this._bindGroups.length; i++) { + this._bindGroups[i].destroy(); + } + this._bindGroups = null; + this._bindGroupHash = null; + for (let i = 0; i < this._buffers.length; i++) { + this._buffers[i].destroy(); + } + this._buffers = null; + for (let i = 0; i < this._bufferResources.length; i++) { + this._bufferResources[i].destroy(); + } + this._bufferResources = null; + this._batchBuffer.destroy(); + this._bindGroupHash = null; + this._renderer = null; + } +} +/** @ignore */ +GpuUniformBatchPipe.extension = { + type: [ + ExtensionType.WebGPUPipes + ], + name: "uniformBatch" +}; + +"use strict"; +var __defProp$7 = Object.defineProperty; +var __defProps$4 = Object.defineProperties; +var __getOwnPropDescs$4 = Object.getOwnPropertyDescriptors; +var __getOwnPropSymbols$7 = Object.getOwnPropertySymbols; +var __hasOwnProp$7 = Object.prototype.hasOwnProperty; +var __propIsEnum$7 = Object.prototype.propertyIsEnumerable; +var __defNormalProp$7 = (obj, key, value) => key in obj ? __defProp$7(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; +var __spreadValues$7 = (a, b) => { + for (var prop in b || (b = {})) + if (__hasOwnProp$7.call(b, prop)) + __defNormalProp$7(a, prop, b[prop]); + if (__getOwnPropSymbols$7) + for (var prop of __getOwnPropSymbols$7(b)) { + if (__propIsEnum$7.call(b, prop)) + __defNormalProp$7(a, prop, b[prop]); + } + return a; +}; +var __spreadProps$4 = (a, b) => __defProps$4(a, __getOwnPropDescs$4(b)); +const topologyStringToId = { + "point-list": 0, + "line-list": 1, + "line-strip": 2, + "triangle-list": 3, + "triangle-strip": 4 +}; +function getGraphicsStateKey(geometryLayout, shaderKey, state, blendMode, topology) { + return geometryLayout << 24 | shaderKey << 16 | state << 10 | blendMode << 5 | topology; +} +function getGlobalStateKey(stencilStateId, multiSampleCount, colorMask, renderTarget) { + return colorMask << 6 | stencilStateId << 3 | renderTarget << 1 | multiSampleCount; +} +class PipelineSystem { + constructor(renderer) { + this._moduleCache = /* @__PURE__ */ Object.create(null); + this._bufferLayoutsCache = /* @__PURE__ */ Object.create(null); + this._pipeCache = /* @__PURE__ */ Object.create(null); + this._pipeStateCaches = /* @__PURE__ */ Object.create(null); + this._colorMask = 15; + this._multisampleCount = 1; + this._renderer = renderer; + } + contextChange(gpu) { + this._gpu = gpu; + this.setStencilMode(STENCIL_MODES.DISABLED); + this._updatePipeHash(); + } + setMultisampleCount(multisampleCount) { + if (this._multisampleCount === multisampleCount) + return; + this._multisampleCount = multisampleCount; + this._updatePipeHash(); + } + setRenderTarget(renderTarget) { + this._multisampleCount = renderTarget.msaaSamples; + this._depthStencilAttachment = renderTarget.descriptor.depthStencilAttachment ? 1 : 0; + this._updatePipeHash(); + } + setColorMask(colorMask) { + if (this._colorMask === colorMask) + return; + this._colorMask = colorMask; + this._updatePipeHash(); + } + setStencilMode(stencilMode) { + if (this._stencilMode === stencilMode) + return; + this._stencilMode = stencilMode; + this._stencilState = GpuStencilModesToPixi[stencilMode]; + this._updatePipeHash(); + } + setPipeline(geometry, program, state, passEncoder) { + const pipeline = this.getPipeline(geometry, program, state); + passEncoder.setPipeline(pipeline); + } + getPipeline(geometry, program, state, topology) { + if (!geometry._layoutKey) { + ensureAttributes(geometry, program.attributeData); + this._generateBufferKey(geometry); + } + topology = topology || geometry.topology; + const key = getGraphicsStateKey( + geometry._layoutKey, + program._layoutKey, + state.data, + state._blendModeId, + topologyStringToId[topology] + ); + if (this._pipeCache[key]) + return this._pipeCache[key]; + this._pipeCache[key] = this._createPipeline(geometry, program, state, topology); + return this._pipeCache[key]; + } + _createPipeline(geometry, program, state, topology) { + const device = this._gpu.device; + const buffers = this._createVertexBufferLayouts(geometry); + const blendModes = this._renderer.state.getColorTargets(state); + blendModes[0].writeMask = this._stencilMode === STENCIL_MODES.RENDERING_MASK_ADD ? 0 : this._colorMask; + const layout = this._renderer.shader.getProgramData(program).pipeline; + const descriptor = { + // TODO later check if its helpful to create.. + // layout, + vertex: { + module: this._getModule(program.vertex.source), + entryPoint: program.vertex.entryPoint, + // geometry.. + buffers + }, + fragment: { + module: this._getModule(program.fragment.source), + entryPoint: program.fragment.entryPoint, + targets: blendModes + }, + primitive: { + topology, + cullMode: state.cullMode + }, + layout, + multisample: { + count: this._multisampleCount + }, + // depthStencil, + label: `PIXI Pipeline` + }; + if (this._depthStencilAttachment) { + descriptor.depthStencil = __spreadProps$4(__spreadValues$7({}, this._stencilState), { + format: "depth24plus-stencil8", + depthWriteEnabled: state.depthTest, + depthCompare: state.depthTest ? "less" : "always" + }); + } + const pipeline = device.createRenderPipeline(descriptor); + return pipeline; + } + _getModule(code) { + return this._moduleCache[code] || this._createModule(code); + } + _createModule(code) { + const device = this._gpu.device; + this._moduleCache[code] = device.createShaderModule({ + code + }); + return this._moduleCache[code]; + } + _generateBufferKey(geometry) { + const keyGen = []; + let index = 0; + const attributeKeys = Object.keys(geometry.attributes).sort(); + for (let i = 0; i < attributeKeys.length; i++) { + const attribute = geometry.attributes[attributeKeys[i]]; + keyGen[index++] = attribute.location; + keyGen[index++] = attribute.offset; + keyGen[index++] = attribute.format; + keyGen[index++] = attribute.stride; + } + const stringKey = keyGen.join(""); + geometry._layoutKey = createIdFromString(stringKey, "geometry"); + return geometry._layoutKey; + } + _createVertexBufferLayouts(geometry) { + if (this._bufferLayoutsCache[geometry._layoutKey]) { + return this._bufferLayoutsCache[geometry._layoutKey]; + } + const vertexBuffersLayout = []; + geometry.buffers.forEach((buffer) => { + const bufferEntry = { + arrayStride: 0, + stepMode: "vertex", + attributes: [] + }; + const bufferEntryAttributes = bufferEntry.attributes; + for (const i in geometry.attributes) { + const attribute = geometry.attributes[i]; + if (attribute.buffer === buffer) { + bufferEntry.arrayStride = attribute.stride; + bufferEntry.stepMode = attribute.instance ? "instance" : "vertex"; + bufferEntryAttributes.push({ + shaderLocation: attribute.location, + offset: attribute.offset, + format: attribute.format + }); + } + } + if (bufferEntryAttributes.length) { + vertexBuffersLayout.push(bufferEntry); + } + }); + this._bufferLayoutsCache[geometry._layoutKey] = vertexBuffersLayout; + return vertexBuffersLayout; + } + _updatePipeHash() { + const key = getGlobalStateKey( + this._stencilMode, + this._multisampleCount, + this._colorMask, + this._depthStencilAttachment + ); + if (!this._pipeStateCaches[key]) { + this._pipeStateCaches[key] = /* @__PURE__ */ Object.create(null); + } + this._pipeCache = this._pipeStateCaches[key]; + } + destroy() { + this._renderer = null; + this._bufferLayoutsCache = null; + } +} +/** @ignore */ +PipelineSystem.extension = { + type: [ExtensionType.WebGPUSystem], + name: "pipeline" +}; + +"use strict"; +class GpuRenderTarget { + constructor() { + this.contexts = []; + this.msaaTextures = []; + this.msaaSamples = 1; + } +} + +"use strict"; +class GpuRenderTargetAdaptor { + init(renderer, renderTargetSystem) { + this._renderer = renderer; + this._renderTargetSystem = renderTargetSystem; + } + copyToTexture(sourceRenderSurfaceTexture, destinationTexture, originSrc, size, originDest) { + const renderer = this._renderer; + const baseGpuTexture = this._getGpuColorTexture( + sourceRenderSurfaceTexture + ); + const backGpuTexture = renderer.texture.getGpuSource( + destinationTexture.source + ); + renderer.encoder.commandEncoder.copyTextureToTexture( + { + texture: baseGpuTexture, + origin: originSrc + }, + { + texture: backGpuTexture, + origin: originDest + }, + size + ); + return destinationTexture; + } + startRenderPass(renderTarget, clear = true, clearColor, viewport) { + const renderTargetSystem = this._renderTargetSystem; + const gpuRenderTarget = renderTargetSystem.getGpuRenderTarget(renderTarget); + const descriptor = this.getDescriptor(renderTarget, clear, clearColor); + gpuRenderTarget.descriptor = descriptor; + this._renderer.pipeline.setRenderTarget(gpuRenderTarget); + this._renderer.encoder.beginRenderPass(gpuRenderTarget); + this._renderer.encoder.setViewport(viewport); + } + finishRenderPass() { + this._renderer.encoder.endRenderPass(); + } + /** + * returns the gpu texture for the first color texture in the render target + * mainly used by the filter manager to get copy the texture for blending + * @param renderTarget + * @returns a gpu texture + */ + _getGpuColorTexture(renderTarget) { + const gpuRenderTarget = this._renderTargetSystem.getGpuRenderTarget(renderTarget); + if (gpuRenderTarget.contexts[0]) { + return gpuRenderTarget.contexts[0].getCurrentTexture(); + } + return this._renderer.texture.getGpuSource( + renderTarget.colorTextures[0].source + ); + } + getDescriptor(renderTarget, clear, clearValue) { + if (typeof clear === "boolean") { + clear = clear ? CLEAR.ALL : CLEAR.NONE; + } + const renderTargetSystem = this._renderTargetSystem; + const gpuRenderTarget = renderTargetSystem.getGpuRenderTarget(renderTarget); + const colorAttachments = renderTarget.colorTextures.map( + (texture, i) => { + const context = gpuRenderTarget.contexts[i]; + let view; + let resolveTarget; + if (context) { + const currentTexture = context.getCurrentTexture(); + const canvasTextureView = currentTexture.createView(); + view = canvasTextureView; + } else { + view = this._renderer.texture.getGpuSource(texture).createView({ + mipLevelCount: 1 + }); + } + if (gpuRenderTarget.msaaTextures[i]) { + resolveTarget = view; + view = this._renderer.texture.getTextureView( + gpuRenderTarget.msaaTextures[i] + ); + } + const loadOp = clear & CLEAR.COLOR ? "clear" : "load"; + clearValue != null ? clearValue : clearValue = renderTargetSystem.defaultClearColor; + return { + view, + resolveTarget, + clearValue, + storeOp: "store", + loadOp + }; + } + ); + let depthStencilAttachment; + if ((renderTarget.stencil || renderTarget.depth) && !renderTarget.depthStencilTexture) { + renderTarget.ensureDepthStencilTexture(); + renderTarget.depthStencilTexture.source.sampleCount = gpuRenderTarget.msaa ? 4 : 1; + } + if (renderTarget.depthStencilTexture) { + const stencilLoadOp = clear & CLEAR.STENCIL ? "clear" : "load"; + const depthLoadOp = clear & CLEAR.DEPTH ? "clear" : "load"; + depthStencilAttachment = { + view: this._renderer.texture.getGpuSource(renderTarget.depthStencilTexture.source).createView(), + stencilStoreOp: "store", + stencilLoadOp, + depthClearValue: 1, + depthLoadOp, + depthStoreOp: "store" + }; + } + const descriptor = { + colorAttachments, + depthStencilAttachment + }; + return descriptor; + } + clear(renderTarget, clear = true, clearColor, viewport) { + if (!clear) + return; + const { gpu, encoder } = this._renderer; + const device = gpu.device; + const standAlone = encoder.commandEncoder === null; + if (standAlone) { + const commandEncoder = device.createCommandEncoder(); + const renderPassDescriptor = this.getDescriptor(renderTarget, clear, clearColor); + const passEncoder = commandEncoder.beginRenderPass(renderPassDescriptor); + passEncoder.setViewport(viewport.x, viewport.y, viewport.width, viewport.height, 0, 1); + passEncoder.end(); + const gpuCommands = commandEncoder.finish(); + device.queue.submit([gpuCommands]); + } else { + this.startRenderPass(renderTarget, clear, clearColor, viewport); + } + } + initGpuRenderTarget(renderTarget) { + renderTarget.isRoot = true; + const gpuRenderTarget = new GpuRenderTarget(); + renderTarget.colorTextures.forEach((colorTexture, i) => { + if (CanvasSource.test(colorTexture.resource)) { + const context = colorTexture.resource.getContext( + "webgpu" + ); + const alphaMode = colorTexture.transparent ? "premultiplied" : "opaque"; + try { + context.configure({ + device: this._renderer.gpu.device, + // eslint-disable-next-line max-len + usage: GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_DST | GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.COPY_SRC, + format: "bgra8unorm", + alphaMode + }); + } catch (e) { + console.error(e); + } + gpuRenderTarget.contexts[i] = context; + } + gpuRenderTarget.msaa = colorTexture.source.antialias; + if (colorTexture.source.antialias) { + const msaaTexture = new TextureSource({ + width: 0, + height: 0, + sampleCount: 4 + }); + gpuRenderTarget.msaaTextures[i] = msaaTexture; + } + }); + if (gpuRenderTarget.msaa) { + gpuRenderTarget.msaaSamples = 4; + if (renderTarget.depthStencilTexture) { + renderTarget.depthStencilTexture.source.sampleCount = 4; + } + } + return gpuRenderTarget; + } + ensureDepthStencilTexture(renderTarget) { + const gpuRenderTarget = this._renderTargetSystem.getGpuRenderTarget(renderTarget); + if (renderTarget.depthStencilTexture && gpuRenderTarget.msaa) { + renderTarget.depthStencilTexture.source.sampleCount = 4; + } + } + resizeGpuRenderTarget(renderTarget) { + const gpuRenderTarget = this._renderTargetSystem.getGpuRenderTarget(renderTarget); + gpuRenderTarget.width = renderTarget.width; + gpuRenderTarget.height = renderTarget.height; + if (gpuRenderTarget.msaa) { + renderTarget.colorTextures.forEach((colorTexture, i) => { + const msaaTexture = gpuRenderTarget.msaaTextures[i]; + msaaTexture == null ? void 0 : msaaTexture.resize( + colorTexture.source.width, + colorTexture.source.height, + colorTexture.source._resolution + ); + }); + } + } +} + +"use strict"; +class GpuRenderTargetSystem extends RenderTargetSystem { + constructor(renderer) { + super(renderer); + this.adaptor = new GpuRenderTargetAdaptor(); + this.adaptor.init(renderer, this); + } +} +/** @ignore */ +GpuRenderTargetSystem.extension = { + type: [ExtensionType.WebGPUSystem], + name: "renderTarget" +}; + +"use strict"; + +"use strict"; +class GpuShaderSystem { + constructor() { + this._gpuProgramData = /* @__PURE__ */ Object.create(null); + } + contextChange(gpu) { + this._gpu = gpu; + } + getProgramData(program) { + return this._gpuProgramData[program._layoutKey] || this._createGPUProgramData(program); + } + _createGPUProgramData(program) { + const device = this._gpu.device; + const bindGroups = program.gpuLayout.map((group) => device.createBindGroupLayout({ entries: group })); + const pipelineLayoutDesc = { bindGroupLayouts: bindGroups }; + this._gpuProgramData[program._layoutKey] = { + bindGroups, + pipeline: device.createPipelineLayout(pipelineLayoutDesc) + }; + return this._gpuProgramData[program._layoutKey]; + } + destroy() { + this._gpu = null; + this._gpuProgramData = null; + } +} +/** @ignore */ +GpuShaderSystem.extension = { + type: [ + ExtensionType.WebGPUSystem + ], + name: "shader" +}; + +"use strict"; +const GpuBlendModesToPixi = {}; +GpuBlendModesToPixi.normal = { + alpha: { + srcFactor: "one", + dstFactor: "one-minus-src-alpha", + operation: "add" + }, + color: { + srcFactor: "one", + dstFactor: "one-minus-src-alpha", + operation: "add" + } +}; +GpuBlendModesToPixi.add = { + alpha: { + srcFactor: "src-alpha", + dstFactor: "one-minus-src-alpha", + operation: "add" + }, + color: { + srcFactor: "one", + dstFactor: "one", + operation: "add" + } +}; +GpuBlendModesToPixi.multiply = { + alpha: { + srcFactor: "one", + dstFactor: "one-minus-src-alpha", + operation: "add" + }, + color: { + srcFactor: "dst", + dstFactor: "one-minus-src-alpha", + operation: "add" + } +}; +GpuBlendModesToPixi.screen = { + alpha: { + srcFactor: "one", + dstFactor: "one-minus-src-alpha", + operation: "add" + }, + color: { + srcFactor: "one", + dstFactor: "one-minus-src", + operation: "add" + } +}; +GpuBlendModesToPixi.overlay = { + alpha: { + srcFactor: "one", + dstFactor: "one-minus-src-alpha", + operation: "add" + }, + color: { + srcFactor: "one", + dstFactor: "one-minus-src", + operation: "add" + } +}; +GpuBlendModesToPixi.none = { + alpha: { + srcFactor: "one", + dstFactor: "one-minus-src-alpha", + operation: "add" + }, + color: { + srcFactor: "zero", + dstFactor: "zero", + operation: "add" + } +}; +GpuBlendModesToPixi["normal-npm"] = { + alpha: { + srcFactor: "one", + dstFactor: "one-minus-src-alpha", + operation: "add" + }, + color: { + srcFactor: "src-alpha", + dstFactor: "one-minus-src-alpha", + operation: "add" + } +}; +GpuBlendModesToPixi["add-npm"] = { + alpha: { + srcFactor: "one", + dstFactor: "one", + operation: "add" + }, + color: { + srcFactor: "src-alpha", + dstFactor: "one", + operation: "add" + } +}; +GpuBlendModesToPixi["screen-npm"] = { + alpha: { + srcFactor: "one", + dstFactor: "one-minus-src-alpha", + operation: "add" + }, + color: { + srcFactor: "src-alpha", + dstFactor: "one-minus-src", + operation: "add" + } +}; +GpuBlendModesToPixi.erase = { + alpha: { + srcFactor: "zero", + dstFactor: "one-minus-src-alpha", + operation: "add" + }, + color: { + srcFactor: "zero", + dstFactor: "one-minus-src", + operation: "add" + } +}; + +"use strict"; +class GpuStateSystem { + constructor() { + this.defaultState = new State(); + this.defaultState.blend = true; + } + contextChange(gpu) { + this.gpu = gpu; + } + /** + * Gets the blend mode data for the current state + * @param state - The state to get the blend mode from + */ + getColorTargets(state) { + const blend = GpuBlendModesToPixi[state.blendMode] || GpuBlendModesToPixi.normal; + return [ + { + format: "bgra8unorm", + writeMask: 0, + blend + } + ]; + } + destroy() { + this.gpu = null; + } +} +/** @ignore */ +GpuStateSystem.extension = { + type: [ + ExtensionType.WebGPUSystem + ], + name: "state" +}; + +"use strict"; +const gpuUploadBufferImageResource = { + type: "image", + upload(source, gpuTexture, gpu) { + const resource = source.resource; + const total = (source.pixelWidth | 0) * (source.pixelHeight | 0); + const bytesPerPixel = resource.byteLength / total; + gpu.device.queue.writeTexture( + { texture: gpuTexture }, + resource, + { + offset: 0, + rowsPerImage: source.pixelHeight, + bytesPerRow: source.pixelHeight * bytesPerPixel + }, + { + width: source.pixelWidth, + height: source.pixelHeight, + depthOrArrayLayers: 1 + } + ); + } +}; + +"use strict"; +const blockDataMap = { + "bc1-rgba-unorm": { blockBytes: 8, blockWidth: 4, blockHeight: 4 }, + "bc2-rgba-unorm": { blockBytes: 16, blockWidth: 4, blockHeight: 4 }, + "bc3-rgba-unorm": { blockBytes: 16, blockWidth: 4, blockHeight: 4 }, + "bc7-rgba-unorm": { blockBytes: 16, blockWidth: 4, blockHeight: 4 }, + "etc1-rgb-unorm": { blockBytes: 8, blockWidth: 4, blockHeight: 4 }, + "etc2-rgba8unorm": { blockBytes: 16, blockWidth: 4, blockHeight: 4 }, + "astc-4x4-unorm": { blockBytes: 16, blockWidth: 4, blockHeight: 4 } +}; +const defaultBlockData = { blockBytes: 4, blockWidth: 1, blockHeight: 1 }; +const gpuUploadCompressedTextureResource = { + type: "compressed", + upload(source, gpuTexture, gpu) { + let mipWidth = source.pixelWidth; + let mipHeight = source.pixelHeight; + const blockData = blockDataMap[source.format] || defaultBlockData; + for (let i = 0; i < source.resource.length; i++) { + const levelBuffer = source.resource[i]; + const bytesPerRow = Math.ceil(mipWidth / blockData.blockWidth) * blockData.blockBytes; + gpu.device.queue.writeTexture( + { + texture: gpuTexture, + mipLevel: i + }, + levelBuffer, + { + offset: 0, + bytesPerRow + }, + { + width: Math.ceil(mipWidth / blockData.blockWidth) * blockData.blockWidth, + height: Math.ceil(mipHeight / blockData.blockHeight) * blockData.blockHeight, + depthOrArrayLayers: 1 + } + ); + mipWidth = Math.max(mipWidth >> 1, 1); + mipHeight = Math.max(mipHeight >> 1, 1); + } + } +}; + +"use strict"; +const gpuUploadImageResource = { + type: "image", + upload(source, gpuTexture, gpu) { + const resource = source.resource; + if (!resource) + return; + const width = Math.min(gpuTexture.width, source.resourceWidth || source.pixelWidth); + const height = Math.min(gpuTexture.height, source.resourceHeight || source.pixelHeight); + const premultipliedAlpha = source.alphaMode === "premultiply-alpha-on-upload"; + gpu.device.queue.copyExternalImageToTexture( + { source: resource }, + { texture: gpuTexture, premultipliedAlpha }, + { + width, + height + } + ); + } +}; + +"use strict"; +const gpuUploadVideoResource = { + type: "video", + upload(source, gpuTexture, gpu) { + gpuUploadImageResource.upload(source, gpuTexture, gpu); + } +}; + +"use strict"; +class GpuMipmapGenerator { + constructor(device) { + this.device = device; + this.sampler = device.createSampler({ minFilter: "linear" }); + this.pipelines = {}; + } + _getMipmapPipeline(format) { + let pipeline = this.pipelines[format]; + if (!pipeline) { + if (!this.mipmapShaderModule) { + this.mipmapShaderModule = this.device.createShaderModule({ + code: ( + /* wgsl */ + ` var pos : array, 3> = array, 3>( vec2(-1.0, -1.0), vec2(-1.0, 3.0), vec2(3.0, -1.0)); @@ -1987,10 +40264,1587 @@ fn setSaturation(c: vec3, s: f32) -> vec3 { fn fragmentMain(@location(0) texCoord : vec2) -> @location(0) vec4 { return textureSample(img, imgSampler, texCoord); } - `})),e=this.device.createRenderPipeline({layout:"auto",vertex:{module:this.mipmapShaderModule,entryPoint:"vertexMain"},fragment:{module:this.mipmapShaderModule,entryPoint:"fragmentMain",targets:[{format:t}]}}),this.pipelines[t]=e),e}generateMipmap(t){const e=this._getMipmapPipeline(t.format);if(t.dimension==="3d"||t.dimension==="1d")throw new Error("Generating mipmaps for non-2d textures is currently unsupported!");let s=t;const i=t.depthOrArrayLayers||1,n=t.usage&GPUTextureUsage.RENDER_ATTACHMENT;if(!n){const u={size:{width:Math.ceil(t.width/2),height:Math.ceil(t.height/2),depthOrArrayLayers:i},format:t.format,usage:GPUTextureUsage.TEXTURE_BINDING|GPUTextureUsage.COPY_SRC|GPUTextureUsage.RENDER_ATTACHMENT,mipLevelCount:t.mipLevelCount-1};s=this.device.createTexture(u)}const o=this.device.createCommandEncoder({}),a=e.getBindGroupLayout(0);for(let u=0;u1&&this.onUpdateMipmaps(t))}onSourceUnload(t){const e=this._gpuSources[t.uid];e&&(this._gpuSources[t.uid]=null,e.destroy())}onUpdateMipmaps(t){this._mipmapGenerator||(this._mipmapGenerator=new $_(this._gpu.device));const e=this.getGpuSource(t);this._mipmapGenerator.generateMipmap(e)}onSourceDestroy(t){t.off("update",this.onSourceUpdate,this),t.off("unload",this.onSourceUnload,this),t.off("destroy",this.onSourceDestroy,this),t.off("resize",this.onSourceResize,this),t.off("updateMipmaps",this.onUpdateMipmaps,this),this.managedTextures.splice(this.managedTextures.indexOf(t),1),this.onSourceUnload(t)}onSourceResize(t){const e=this._gpuSources[t.uid];e?(e.width!==t.pixelWidth||e.height!==t.pixelHeight)&&(this._textureViewHash[t.uid]=null,this._bindGroupHash[t.uid]=null,this.onSourceUnload(t),this.initSource(t)):this.initSource(t)}_initSampler(t){return this._gpuSamplers[t._resourceId]=this._gpu.device.createSampler(t),this._gpuSamplers[t._resourceId]}getGpuSampler(t){return this._gpuSamplers[t._resourceId]||this._initSampler(t)}getGpuSource(t){return this._gpuSources[t.uid]||this.initSource(t)}getTextureBindGroup(t){var e;return(e=this._bindGroupHash[t.uid])!=null?e:this._createTextureBindGroup(t)}_createTextureBindGroup(t){const e=t.source,s=e.uid;return this._bindGroupHash[s]=new Lt({0:e,1:e.style}),this._bindGroupHash[s]}getTextureView(t){var e;const s=t.source;return(e=this._textureViewHash[s.uid])!=null?e:this._createTextureView(s)}_createTextureView(t){return this._textureViewHash[t.uid]=this.getGpuSource(t).createView(),this._textureViewHash[t.uid]}generateCanvas(t){const e=this._renderer,s=e.gpu.device.createCommandEncoder(),i=X.get().createCanvas();i.width=t.source.pixelWidth,i.height=t.source.pixelHeight;const n=i.getContext("webgpu");return n.configure({device:e.gpu.device,usage:GPUTextureUsage.COPY_DST|GPUTextureUsage.COPY_SRC,format:navigator.gpu.getPreferredCanvasFormat(),alphaMode:"premultiplied"}),s.copyTextureToTexture({texture:e.texture.getGpuSource(t.source),origin:{x:0,y:0}},{texture:n.getCurrentTexture()},{width:i.width,height:i.height}),e.gpu.device.queue.submit([s.finish()]),i}getPixels(t){const e=this.generateCanvas(t),s=jt.getOptimalCanvasAndContext(e.width,e.height),i=s.context;i.drawImage(e,0,0);const{width:n,height:o}=e,a=i.getImageData(0,0,n,o),u=new Uint8ClampedArray(a.data.buffer);return jt.returnCanvasAndContext(s),{pixels:u,width:n,height:o}}destroy(){this.managedTextures.slice().forEach(t=>this.onSourceDestroy(t)),this.managedTextures=null;for(const t of Object.keys(this._bindGroupHash)){const e=Number(t),s=this._bindGroupHash[e];s==null||s.destroy(),this._bindGroupHash[e]=null}this._gpu=null,this._mipmapGenerator=null,this._gpuSources=null,this._bindGroupHash=null,this._textureViewHash=null,this._gpuSamplers=null}}Lu.extension={type:[v.WebGPUSystem],name:"texture"};class $u{init(){const t=new it({uTransformMatrix:{value:new G,type:"mat3x3"},uColor:{value:new Float32Array([1,1,1,1]),type:"vec4"},uRound:{value:0,type:"f32"}}),e=Ue({name:"graphics",bits:[Us,Ls(wt),rp,Le]});this.shader=new St({gpuProgram:e,resources:{localUniforms:t}})}execute(t,e){const s=e.context,i=s.customShader||this.shader,n=t.renderer,o=n.graphicsContext,{geometry:a,instructions:u}=o.getContextRenderData(s),l=n.encoder;l.setPipelineFromGeometryProgramAndState(a,i.gpuProgram,t.state),l.setGeometry(a);const h=n.globalUniforms.bindGroup;l.setBindGroup(0,h,i.gpuProgram);const c=n.renderPipes.uniformBatch.getUniformBindGroup(i.resources.localUniforms,!0);l.setBindGroup(2,c,i.gpuProgram);const d=u.instructions;for(let p=0;p",value:new G}}}})}execute(t,e){const s=t.renderer;let i=e._shader;if(!i)i=this._shader,i.resources.uTexture=e.texture.source,i.resources.uSampler=e.texture.source.style,i.resources.textureUniforms.uniforms.uTextureMatrix=e.texture.textureMatrix.mapCoord;else if(!i.gpuProgram)return;const n=i.gpuProgram;if(n.autoAssignGlobalUniforms&&(i.groups[0]=s.globalUniforms.bindGroup),n.autoAssignLocalUniforms){const o=t.localUniforms;i.groups[1]=s.renderPipes.uniformBatch.getUniformBindGroup(o,!0)}s.encoder.draw({geometry:e._geometry,shader:i,state:e.state})}destroy(){this._shader.destroy(!0),this._shader=null}}Nu.extension={type:[v.WebGPUPipesAdaptor],name:"mesh"};const CE=[...Eu,Cu,Mu,Pi,wu,Lu,Bu,Fu,Du,Iu,Ru,Ou,Pu],GE=[...Au,Gu],IE=[Ea,Nu,$u],N_=[],H_=[],X_=[];D.handleByNamedList(v.WebGPUSystem,N_),D.handleByNamedList(v.WebGPUPipes,H_),D.handleByNamedList(v.WebGPUPipesAdaptor,X_),D.add(...CE,...GE,...IE);class z_ extends Or{constructor(){const t={name:"webgpu",type:xt.WEBGPU,systems:N_,renderPipes:H_,renderPipeAdaptors:X_};super(t)}}var BE={__proto__:null,WebGPURenderer:z_};const FE={POINTS:"point-list",LINES:"line-list",LINE_STRIP:"line-strip",TRIANGLES:"triangle-list",TRIANGLE_STRIP:"triangle-strip"},DE=new Proxy(FE,{get(r,t){return r[t]}}),UE=new z(0,0,1,1);function kE(r,t,e){e||(e=UE);const s=t.pixelWidth,i=t.pixelHeight;return r.x=e.x*s|0,r.y=e.y*i|0,r.width=e.width*s|0,r.height=e.height*i|0,r}var j_=(r=>(r[r.NONE=0]="NONE",r[r.LOW=2]="LOW",r[r.MEDIUM=4]="MEDIUM",r[r.HIGH=8]="HIGH",r))(j_||{}),Hu=(r=>(r.CLAMP="clamp-to-edge",r.REPEAT="repeat",r.MIRRORED_REPEAT="mirror-repeat",r))(Hu||{});const LE=new Proxy(Hu,{get(r,t){return r[t]}});var Xu=(r=>(r.NEAREST="nearest",r.LINEAR="linear",r))(Xu||{});const $E=new Proxy(Xu,{get(r,t){return r[t]}});class NE{constructor(){this.x0=0,this.y0=0,this.x1=1,this.y1=0,this.x2=1,this.y2=1,this.x3=0,this.y3=1,this.uvsFloat32=new Float32Array(8)}set(t,e,s){const i=e.width,n=e.height;if(s){const o=t.width/2/i,a=t.height/2/n,u=t.x/i+o,l=t.y/n+a;s=U.add(s,U.NW),this.x0=u+o*U.uX(s),this.y0=l+a*U.uY(s),s=U.add(s,2),this.x1=u+o*U.uX(s),this.y1=l+a*U.uY(s),s=U.add(s,2),this.x2=u+o*U.uX(s),this.y2=l+a*U.uY(s),s=U.add(s,2),this.x3=u+o*U.uX(s),this.y3=l+a*U.uY(s)}else this.x0=t.x/i,this.y0=t.y/n,this.x1=(t.x+t.width)/i,this.y1=t.y/n,this.x2=(t.x+t.width)/i,this.y2=(t.y+t.height)/n,this.x3=t.x/i,this.y3=(t.y+t.height)/n;this.uvsFloat32[0]=this.x0,this.uvsFloat32[1]=this.y0,this.uvsFloat32[2]=this.x1,this.uvsFloat32[3]=this.y1,this.uvsFloat32[4]=this.x2,this.uvsFloat32[5]=this.y2,this.uvsFloat32[6]=this.x3,this.uvsFloat32[7]=this.y3}}let HE=0;function XE(){return HE++}function zE(r){const t=r.toString(),e=t.indexOf("{"),s=t.lastIndexOf("}");if(e===-1||s===-1)throw new Error("getFunctionBody: No body found in function definition");return t.slice(e+1,s).trim()}var jE=Object.defineProperty,wi=Object.getOwnPropertySymbols,V_=Object.prototype.hasOwnProperty,W_=Object.prototype.propertyIsEnumerable,Y_=(r,t,e)=>t in r?jE(r,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):r[t]=e,VE=(r,t)=>{for(var e in t||(t={}))V_.call(t,e)&&Y_(r,e,t[e]);if(wi)for(var e of wi(t))W_.call(t,e)&&Y_(r,e,t[e]);return r},WE=(r,t)=>{var e={};for(var s in r)V_.call(r,s)&&t.indexOf(s)<0&&(e[s]=r[s]);if(r!=null&&wi)for(var s of wi(r))t.indexOf(s)<0&&W_.call(r,s)&&(e[s]=r[s]);return e};class YE extends V{constructor(t){var e,s;typeof t=="function"&&(t={render:t});const i=t,{render:n}=i,o=WE(i,["render"]);super(VE({label:"RenderContainer"},o)),this.batched=!1,this.bounds=new lt,this.canBundle=!1,this.renderPipeId="customRender",n&&(this.render=n),this.containsPoint=(e=t.containsPoint)!=null?e:()=>!1,this.addBounds=(s=t.addBounds)!=null?s:()=>!1}render(t){}}function KE(r,t){if(r===16777215||!t)return t;if(t===16777215||!r)return r;const e=r>>16&255,s=r>>8&255,i=r&255,n=t>>16&255,o=t>>8&255,a=t&255,u=e*n/255,l=s*o/255,h=i*a/255;return(u<<16)+(l<<8)+h}function qE(r,t){const e=t._scale,s=t._pivot,i=t._position,n=e._x,o=e._y,a=s._x,u=s._y;r.a=t._cx*n,r.b=t._sx*n,r.c=t._cy*o,r.d=t._sy*o,r.tx=i._x-(a*r.a+u*r.c),r.ty=i._y-(a*r.b+u*r.d)}function ZE(r,t,e){const s=r.a,i=r.b,n=r.c,o=r.d,a=r.tx,u=r.ty,l=t.a,h=t.b,c=t.c,d=t.d;e.a=s*l+i*c,e.b=s*h+i*d,e.c=n*l+o*c,e.d=n*h+o*d,e.tx=a*l+u*c+t.tx,e.ty=a*h+u*d+t.ty}const QE={rectangle:Dn,polygon:Fn,triangle:Un,circle:_e,ellipse:_e,roundedRectangle:_e};function JE(r){r instanceof ne&&(r={path:r,textureMatrix:null,out:null});const t=[],e=[],s=[],i=r.path.shapePath,n=r.textureMatrix;i.shapePrimitives.forEach(({shape:a,transform:u})=>{const l=s.length,h=t.length/2,c=[],d=QE[a.type];d.build(a,c),u&&xs(c,u),d.triangulate(c,t,2,h,s,l);const p=e.length/2;n?(u&&n.append(u.clone().invert()),wn(t,2,h,e,p,2,t.length/2-h,n)):Rn(e,p,2,t.length/2-h)});const o=r.out;return o?(o.positions=new Float32Array(t),o.uvs=new Float32Array(e),o.indices=new Uint32Array(s),o):new Jt({positions:new Float32Array(t),uvs:new Float32Array(e),indices:new Uint32Array(s)})}var tA=Object.defineProperty,eA=Object.defineProperties,rA=Object.getOwnPropertyDescriptors,Ri=Object.getOwnPropertySymbols,K_=Object.prototype.hasOwnProperty,q_=Object.prototype.propertyIsEnumerable,Z_=(r,t,e)=>t in r?tA(r,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):r[t]=e,sA=(r,t)=>{for(var e in t||(t={}))K_.call(t,e)&&Z_(r,e,t[e]);if(Ri)for(var e of Ri(t))q_.call(t,e)&&Z_(r,e,t[e]);return r},iA=(r,t)=>eA(r,rA(t)),nA=(r,t)=>{var e={};for(var s in r)K_.call(r,s)&&t.indexOf(s)<0&&(e[s]=r[s]);if(r!=null&&Ri)for(var s of Ri(r))t.indexOf(s)<0&&q_.call(r,s)&&(e[s]=r[s]);return e};class oA extends $r{constructor(t){const e=t,{texture:s,verticesX:i,verticesY:n}=e,o=nA(e,["texture","verticesX","verticesY"]),a=new Ho(Zt({width:s.width,height:s.height,verticesX:i,verticesY:n}));super(Zt(iA(sA({},o),{geometry:a,texture:s}))),this.texture=s,this.autoResize=!0}textureUpdated(){const t=this.geometry,{width:e,height:s}=this.texture;this.autoResize&&(t.width!==e||t.height!==s)&&(t.width=e,t.height=s,t.build({}))}set texture(t){var e;(e=this._texture)==null||e.off("update",this.textureUpdated,this),super.texture=t,t.on("update",this.textureUpdated,this),this.textureUpdated()}get texture(){return this._texture}destroy(t){this.texture.off("update",this.textureUpdated,this),super.destroy(t)}}var aA=Object.defineProperty,Q_=Object.getOwnPropertySymbols,uA=Object.prototype.hasOwnProperty,lA=Object.prototype.propertyIsEnumerable,J_=(r,t,e)=>t in r?aA(r,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):r[t]=e,tx=(r,t)=>{for(var e in t||(t={}))uA.call(t,e)&&J_(r,e,t[e]);if(Q_)for(var e of Q_(t))lA.call(t,e)&&J_(r,e,t[e]);return r};const ex=class Hx extends Jt{constructor(t){const{width:e,points:s,textureScale:i}=tx(tx({},Hx.defaultOptions),t);super({positions:new Float32Array(s.length*4),uvs:new Float32Array(s.length*4),indices:new Uint32Array((s.length-1)*6)}),this.points=s,this._width=e,this.textureScale=i,this._build()}get width(){return this._width}_build(){const t=this.points;if(!t)return;const e=this.getBuffer("aPosition"),s=this.getBuffer("aUV"),i=this.getIndex();if(t.length<1)return;e.data.length/4!==t.length&&(e.data=new Float32Array(t.length*4),s.data=new Float32Array(t.length*4),i.data=new Uint16Array((t.length-1)*6));const n=s.data,o=i.data;n[0]=0,n[1]=0,n[2]=0,n[3]=1;let a=0,u=t[0];const l=this._width*this.textureScale,h=t.length;for(let d=0;d0){const f=u.x-t[d].x,g=u.y-t[d].y,m=Math.sqrt(f*f+g*g);u=t[d],a+=m/l}else a=d/(h-1);n[p]=a,n[p+1]=0,n[p+2]=a,n[p+3]=1}let c=0;for(let d=0;d0?this.textureScale*this._width/2:this._width/2;for(let l=0;l1&&(d=1);const p=Math.sqrt(i*i+n*n);p<1e-6?(i=0,n=0):(i/=p,n/=p,i*=u,n*=u),o[c]=h.x+i,o[c+1]=h.y+n,o[c+2]=h.x-i,o[c+3]=h.y-n,e=h}this.buffers[0].update()}update(){this.textureScale>0?this._build():this.updateVertices()}};ex.defaultOptions={width:200,points:[],textureScale:0};let rx=ex;var hA=Object.defineProperty,cA=Object.defineProperties,dA=Object.getOwnPropertyDescriptors,Mi=Object.getOwnPropertySymbols,sx=Object.prototype.hasOwnProperty,ix=Object.prototype.propertyIsEnumerable,nx=(r,t,e)=>t in r?hA(r,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):r[t]=e,zu=(r,t)=>{for(var e in t||(t={}))sx.call(t,e)&&nx(r,e,t[e]);if(Mi)for(var e of Mi(t))ix.call(t,e)&&nx(r,e,t[e]);return r},pA=(r,t)=>cA(r,dA(t)),fA=(r,t)=>{var e={};for(var s in r)sx.call(r,s)&&t.indexOf(s)<0&&(e[s]=r[s]);if(r!=null&&Mi)for(var s of Mi(r))t.indexOf(s)<0&&ix.call(r,s)&&(e[s]=r[s]);return e};const ox=class Xx extends $r{constructor(t){const e=zu(zu({},Xx.defaultOptions),t),{texture:s,points:i,textureScale:n}=e,o=fA(e,["texture","points","textureScale"]),a=new rx(Zt({width:s.height,points:i,textureScale:n}));n>0&&(s.source.style.addressMode="repeat"),super(Zt(pA(zu({},o),{texture:s,geometry:a}))),this.autoUpdate=!0,this.onRender=this._render}_render(){const t=this.geometry;(this.autoUpdate||t._width!==this.texture.height)&&(t._width=this.texture.height,t.update())}};ox.defaultOptions={textureScale:0};let mA=ox;var gA=Object.defineProperty,_A=Object.defineProperties,xA=Object.getOwnPropertyDescriptors,Oi=Object.getOwnPropertySymbols,ax=Object.prototype.hasOwnProperty,ux=Object.prototype.propertyIsEnumerable,lx=(r,t,e)=>t in r?gA(r,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):r[t]=e,bA=(r,t)=>{for(var e in t||(t={}))ax.call(t,e)&&lx(r,e,t[e]);if(Oi)for(var e of Oi(t))ux.call(t,e)&&lx(r,e,t[e]);return r},vA=(r,t)=>_A(r,xA(t)),yA=(r,t)=>{var e={};for(var s in r)ax.call(r,s)&&t.indexOf(s)<0&&(e[s]=r[s]);if(r!=null&&Oi)for(var s of Oi(r))t.indexOf(s)<0&&ux.call(r,s)&&(e[s]=r[s]);return e};class TA extends $r{constructor(t){const e=t,{texture:s,vertices:i,uvs:n,indices:o,topology:a}=e,u=yA(e,["texture","vertices","uvs","indices","topology"]),l=new Jt(Zt({positions:i,uvs:n,indices:o,topology:a}));super(Zt(vA(bA({},u),{texture:s,geometry:l}))),this.autoUpdate=!0,this.onRender=this._render}get vertices(){return this.geometry.getBuffer("aPosition").data}set vertices(t){this.geometry.getBuffer("aPosition").data=t}_render(){this.autoUpdate&&this.geometry.getBuffer("aPosition").update()}}function SA(r,t){const{width:e,height:s}=r.frame;return t.scale(1/e,1/s),t}var EA=Object.defineProperty,Ci=Object.getOwnPropertySymbols,hx=Object.prototype.hasOwnProperty,cx=Object.prototype.propertyIsEnumerable,dx=(r,t,e)=>t in r?EA(r,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):r[t]=e,AA=(r,t)=>{for(var e in t||(t={}))hx.call(t,e)&&dx(r,e,t[e]);if(Ci)for(var e of Ci(t))cx.call(t,e)&&dx(r,e,t[e]);return r},PA=(r,t)=>{var e={};for(var s in r)hx.call(r,s)&&t.indexOf(s)<0&&(e[s]=r[s]);if(r!=null&&Ci)for(var s of Ci(r))t.indexOf(s)<0&&cx.call(r,s)&&(e[s]=r[s]);return e};const px=class zx extends V{constructor(t){var e,s,i,n,o,a,u,l,h,c;t instanceof A&&(t={texture:t});const d=t,{width:p,height:f,leftWidth:g,rightWidth:m,topHeight:_,bottomHeight:x,texture:b,roundPixels:y}=d,S=PA(d,["width","height","leftWidth","rightWidth","topHeight","bottomHeight","texture","roundPixels"]);super(AA({label:"NineSliceSprite"},S)),this._roundPixels=0,this.renderPipeId="nineSliceSprite",this.batched=!0,this._didSpriteUpdate=!0,this.bounds={minX:0,minY:0,maxX:0,maxY:0},this._leftWidth=(s=g!=null?g:(e=b==null?void 0:b.defaultBorders)==null?void 0:e.left)!=null?s:te.defaultOptions.leftWidth,this._topHeight=(n=_!=null?_:(i=b==null?void 0:b.defaultBorders)==null?void 0:i.top)!=null?n:te.defaultOptions.topHeight,this._rightWidth=(a=m!=null?m:(o=b==null?void 0:b.defaultBorders)==null?void 0:o.right)!=null?a:te.defaultOptions.rightWidth,this._bottomHeight=(l=x!=null?x:(u=b==null?void 0:b.defaultBorders)==null?void 0:u.bottom)!=null?l:te.defaultOptions.bottomHeight,this.bounds.maxX=this._width=(h=p!=null?p:b.width)!=null?h:te.defaultOptions.width,this.bounds.maxY=this._height=(c=f!=null?f:b.height)!=null?c:te.defaultOptions.height,this.allowChildren=!1,this.texture=b!=null?b:zx.defaultOptions.texture,this.roundPixels=y!=null?y:!1}get width(){return this._width}set width(t){this.bounds.maxX=this._width=t,this.onViewUpdate()}get height(){return this._height}set height(t){this.bounds.maxY=this._height=t,this.onViewUpdate()}get leftWidth(){return this._leftWidth}set leftWidth(t){this._leftWidth=t,this.onViewUpdate()}get topHeight(){return this._topHeight}set topHeight(t){this._topHeight=t,this.onViewUpdate()}get rightWidth(){return this._rightWidth}set rightWidth(t){this._rightWidth=t,this.onViewUpdate()}get bottomHeight(){return this._bottomHeight}set bottomHeight(t){this._bottomHeight=t,this.onViewUpdate()}get texture(){return this._texture}set texture(t){t||(t=A.EMPTY);const e=this._texture;e!==t&&(e&&e.dynamic&&e.off("update",this.onViewUpdate,this),t.dynamic&&t.on("update",this.onViewUpdate,this),this._texture=t,this.onViewUpdate())}get roundPixels(){return!!this._roundPixels}set roundPixels(t){this._roundPixels=t?1:0}get originalWidth(){return this._texture.width}get originalHeight(){return this._texture.height}onViewUpdate(){this._didChangeId+=4096,this._didSpriteUpdate=!0,!this.didViewUpdate&&(this.didViewUpdate=!0,this.renderGroup&&this.renderGroup.onChildViewUpdate(this))}addBounds(t){const e=this.bounds;t.addFrame(e.minX,e.minY,e.maxX,e.maxY)}containsPoint(t){const e=this.bounds;return t.x>=e.minX&&t.x<=e.maxX&&t.y>=e.minY&&t.y<=e.maxY}destroy(t){if(super.destroy(t),typeof t=="boolean"?t:t==null?void 0:t.texture){const e=typeof t=="boolean"?t:t==null?void 0:t.textureSource;this._texture.destroy(e)}this._texture=null,this.bounds=null}};px.defaultOptions={texture:A.EMPTY};let fx=px;class wA extends fx{constructor(...t){let e=t[0];e instanceof A&&(e={texture:e,leftWidth:t[1],topHeight:t[2],rightWidth:t[3],bottomHeight:t[4]}),super(e)}}function RA(r,t){return t instanceof Wt||t instanceof Pe?t:r==="html"?new Pe(t):new Wt(t)}const MA=/^\s*data:(?:([\w-]+)\/([\w+.-]+))?(?:;charset=([\w-]+))?(?:;(base64))?,(.*)/i,mx={},OA="8.0.0";function CA(r,t,e=3){if(mx[t])return;let s=new Error().stack;typeof s=="undefined"?console.warn("PixiJS Deprecation Warning: ",`${t} -Deprecated since v${r}`):(s=s.split(` -`).splice(e).join(` -`),console.groupCollapsed?(console.groupCollapsed("%cPixiJS Deprecation Warning: %c%s","color:#614108;background:#fffbe6","font-weight:normal;color:#614108;background:#fffbe6",`${t} -Deprecated since v${r}`),console.warn(s),console.groupEnd()):(console.warn("PixiJS Deprecation Warning: ",`${t} -Deprecated since v${r}`),console.warn(s))),mx[t]=!0}async function GA(r,t,e=200){const s=await t.extract.base64(r);await t.encoder.commandFinished;const i=e;console.log(`logging texture ${r.source.width}px ${r.source.height}px`);const n=["font-size: 1px;",`padding: ${i}px 300px;`,`background: url(${s}) no-repeat;`,"background-size: contain;"].join(" ");console.log("%c ",n)}var IA=Object.defineProperty,BA=Object.defineProperties,FA=Object.getOwnPropertyDescriptors,gx=Object.getOwnPropertySymbols,DA=Object.prototype.hasOwnProperty,UA=Object.prototype.propertyIsEnumerable,_x=(r,t,e)=>t in r?IA(r,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):r[t]=e,xx=(r,t)=>{for(var e in t||(t={}))DA.call(t,e)&&_x(r,e,t[e]);if(gx)for(var e of gx(t))UA.call(t,e)&&_x(r,e,t[e]);return r},kA=(r,t)=>BA(r,FA(t));const LA=["#000080","#228B22","#8B0000","#4169E1","#008080","#800000","#9400D3","#FF8C00","#556B2F","#8B008B"];let $A=0;function bx(r,t=0,e={color:"#000000"}){r.isRenderGroupRoot&&(e.color=LA[$A++]);let s="";for(let o=0;o 1) { + this.onUpdateMipmaps(source); + } + } + onSourceUnload(source) { + const gpuTexture = this._gpuSources[source.uid]; + if (gpuTexture) { + this._gpuSources[source.uid] = null; + gpuTexture.destroy(); + } + } + onUpdateMipmaps(source) { + if (!this._mipmapGenerator) { + this._mipmapGenerator = new GpuMipmapGenerator(this._gpu.device); + } + const gpuTexture = this.getGpuSource(source); + this._mipmapGenerator.generateMipmap(gpuTexture); + } + onSourceDestroy(source) { + source.off("update", this.onSourceUpdate, this); + source.off("unload", this.onSourceUnload, this); + source.off("destroy", this.onSourceDestroy, this); + source.off("resize", this.onSourceResize, this); + source.off("updateMipmaps", this.onUpdateMipmaps, this); + this.managedTextures.splice(this.managedTextures.indexOf(source), 1); + this.onSourceUnload(source); + } + onSourceResize(source) { + const gpuTexture = this._gpuSources[source.uid]; + if (!gpuTexture) { + this.initSource(source); + } else if (gpuTexture.width !== source.pixelWidth || gpuTexture.height !== source.pixelHeight) { + this._textureViewHash[source.uid] = null; + this._bindGroupHash[source.uid] = null; + this.onSourceUnload(source); + this.initSource(source); + } + } + _initSampler(sampler) { + this._gpuSamplers[sampler._resourceId] = this._gpu.device.createSampler(sampler); + return this._gpuSamplers[sampler._resourceId]; + } + getGpuSampler(sampler) { + return this._gpuSamplers[sampler._resourceId] || this._initSampler(sampler); + } + getGpuSource(source) { + return this._gpuSources[source.uid] || this.initSource(source); + } + getTextureBindGroup(texture) { + var _a; + return (_a = this._bindGroupHash[texture.uid]) != null ? _a : this._createTextureBindGroup(texture); + } + _createTextureBindGroup(texture) { + const source = texture.source; + const bindGroupId = source.uid; + this._bindGroupHash[bindGroupId] = new BindGroup({ + 0: source, + 1: source.style + }); + return this._bindGroupHash[bindGroupId]; + } + getTextureView(texture) { + var _a; + const source = texture.source; + return (_a = this._textureViewHash[source.uid]) != null ? _a : this._createTextureView(source); + } + _createTextureView(texture) { + this._textureViewHash[texture.uid] = this.getGpuSource(texture).createView(); + return this._textureViewHash[texture.uid]; + } + generateCanvas(texture) { + const renderer = this._renderer; + const commandEncoder = renderer.gpu.device.createCommandEncoder(); + const canvas = DOMAdapter.get().createCanvas(); + canvas.width = texture.source.pixelWidth; + canvas.height = texture.source.pixelHeight; + const context = canvas.getContext("webgpu"); + context.configure({ + device: renderer.gpu.device, + // eslint-disable-next-line max-len + usage: GPUTextureUsage.COPY_DST | GPUTextureUsage.COPY_SRC, + format: navigator.gpu.getPreferredCanvasFormat(), + alphaMode: "premultiplied" + }); + commandEncoder.copyTextureToTexture({ + texture: renderer.texture.getGpuSource(texture.source), + origin: { + x: 0, + y: 0 + } + }, { + texture: context.getCurrentTexture() + }, { + width: canvas.width, + height: canvas.height + }); + renderer.gpu.device.queue.submit([commandEncoder.finish()]); + return canvas; + } + getPixels(texture) { + const webGPUCanvas = this.generateCanvas(texture); + const canvasAndContext = CanvasPool.getOptimalCanvasAndContext(webGPUCanvas.width, webGPUCanvas.height); + const context = canvasAndContext.context; + context.drawImage(webGPUCanvas, 0, 0); + const { width, height } = webGPUCanvas; + const imageData = context.getImageData(0, 0, width, height); + const pixels = new Uint8ClampedArray(imageData.data.buffer); + CanvasPool.returnCanvasAndContext(canvasAndContext); + return { pixels, width, height }; + } + destroy() { + this.managedTextures.slice().forEach((source) => this.onSourceDestroy(source)); + this.managedTextures = null; + for (const k of Object.keys(this._bindGroupHash)) { + const key = Number(k); + const bindGroup = this._bindGroupHash[key]; + bindGroup == null ? void 0 : bindGroup.destroy(); + this._bindGroupHash[key] = null; + } + this._gpu = null; + this._mipmapGenerator = null; + this._gpuSources = null; + this._bindGroupHash = null; + this._textureViewHash = null; + this._gpuSamplers = null; + } +} +/** @ignore */ +GpuTextureSystem.extension = { + type: [ + ExtensionType.WebGPUSystem + ], + name: "texture" +}; + +"use strict"; + +"use strict"; +class GpuGraphicsAdaptor { + init() { + const localUniforms = new UniformGroup({ + uTransformMatrix: { value: new Matrix(), type: "mat3x3" }, + uColor: { value: new Float32Array([1, 1, 1, 1]), type: "vec4" }, + uRound: { value: 0, type: "f32" } + }); + const gpuProgram = compileHighShaderGpuProgram({ + name: "graphics", + bits: [ + colorBit, + generateTextureBatchBit(MAX_TEXTURES), + localUniformBitGroup2, + roundPixelsBit + ] + }); + this.shader = new Shader({ + gpuProgram, + resources: { + // added on the fly! + localUniforms + } + }); + } + execute(graphicsPipe, renderable) { + const context = renderable.context; + const shader = context.customShader || this.shader; + const renderer = graphicsPipe.renderer; + const contextSystem = renderer.graphicsContext; + const { + geometry, + instructions + } = contextSystem.getContextRenderData(context); + const encoder = renderer.encoder; + encoder.setPipelineFromGeometryProgramAndState( + geometry, + shader.gpuProgram, + graphicsPipe.state + ); + encoder.setGeometry(geometry); + const globalUniformsBindGroup = renderer.globalUniforms.bindGroup; + encoder.setBindGroup(0, globalUniformsBindGroup, shader.gpuProgram); + const localBindGroup = renderer.renderPipes.uniformBatch.getUniformBindGroup(shader.resources.localUniforms, true); + encoder.setBindGroup(2, localBindGroup, shader.gpuProgram); + const batches = instructions.instructions; + for (let i = 0; i < instructions.instructionSize; i++) { + const batch = batches[i]; + shader.groups[1] = batch.bindGroup; + if (!batch.gpuBindGroup) { + const textureBatch = batch.textures; + batch.bindGroup = getTextureBatchBindGroup(textureBatch.textures, textureBatch.count); + batch.gpuBindGroup = renderer.bindGroup.getBindGroup( + batch.bindGroup, + shader.gpuProgram, + 1 + ); + } + encoder.setBindGroup(1, batch.bindGroup, shader.gpuProgram); + encoder.renderPassEncoder.drawIndexed(batch.size, 1, batch.start); + } + } + destroy() { + this.shader.destroy(true); + this.shader = null; + } +} +/** @ignore */ +GpuGraphicsAdaptor.extension = { + type: [ + ExtensionType.WebGPUPipesAdaptor + ], + name: "graphics" +}; + +"use strict"; +class GpuMeshAdapter { + init() { + const gpuProgram = compileHighShaderGpuProgram({ + name: "mesh", + bits: [ + localUniformBit, + textureBit, + roundPixelsBit + ] + }); + this._shader = new Shader({ + gpuProgram, + resources: { + uTexture: Texture.EMPTY._source, + uSampler: Texture.EMPTY._source.style, + textureUniforms: { + uTextureMatrix: { type: "mat3x3", value: new Matrix() } + } + } + }); + } + execute(meshPipe, mesh) { + const renderer = meshPipe.renderer; + let shader = mesh._shader; + if (!shader) { + shader = this._shader; + shader.resources.uTexture = mesh.texture.source; + shader.resources.uSampler = mesh.texture.source.style; + shader.resources.textureUniforms.uniforms.uTextureMatrix = mesh.texture.textureMatrix.mapCoord; + } else if (!shader.gpuProgram) { + warn("Mesh shader has no gpuProgram", mesh.shader); + return; + } + const gpuProgram = shader.gpuProgram; + if (gpuProgram.autoAssignGlobalUniforms) { + shader.groups[0] = renderer.globalUniforms.bindGroup; + } + if (gpuProgram.autoAssignLocalUniforms) { + const localUniforms = meshPipe.localUniforms; + shader.groups[1] = renderer.renderPipes.uniformBatch.getUniformBindGroup(localUniforms, true); + } + renderer.encoder.draw({ + geometry: mesh._geometry, + shader, + state: mesh.state + }); + } + destroy() { + this._shader.destroy(true); + this._shader = null; + } +} +/** @ignore */ +GpuMeshAdapter.extension = { + type: [ + ExtensionType.WebGPUPipesAdaptor + ], + name: "mesh" +}; + +"use strict"; +const DefaultWebGPUSystems = [ + ...SharedSystems, + GpuUboSystem, + GpuEncoderSystem, + GpuDeviceSystem, + GpuBufferSystem, + GpuTextureSystem, + GpuRenderTargetSystem, + GpuShaderSystem, + GpuStateSystem, + PipelineSystem, + GpuColorMaskSystem, + GpuStencilSystem, + BindGroupSystem +]; +const DefaultWebGPUPipes = [...SharedRenderPipes, GpuUniformBatchPipe]; +const DefaultWebGPUAdapters = [GpuBatchAdaptor, GpuMeshAdapter, GpuGraphicsAdaptor]; +const systems = []; +const renderPipes = []; +const renderPipeAdaptors = []; +extensions.handleByNamedList(ExtensionType.WebGPUSystem, systems); +extensions.handleByNamedList(ExtensionType.WebGPUPipes, renderPipes); +extensions.handleByNamedList(ExtensionType.WebGPUPipesAdaptor, renderPipeAdaptors); +extensions.add(...DefaultWebGPUSystems, ...DefaultWebGPUPipes, ...DefaultWebGPUAdapters); +class WebGPURenderer extends AbstractRenderer { + constructor() { + const systemConfig = { + name: "webgpu", + type: RendererType.WEBGPU, + systems, + renderPipes, + renderPipeAdaptors + }; + super(systemConfig); + } +} + +var WebGPURenderer$1 = { + __proto__: null, + WebGPURenderer: WebGPURenderer +}; + +"use strict"; +const DEPRECATED_DRAW_MODES = { + POINTS: "point-list", + LINES: "line-list", + LINE_STRIP: "line-strip", + TRIANGLES: "triangle-list", + TRIANGLE_STRIP: "triangle-strip" +}; +const DRAW_MODES = new Proxy(DEPRECATED_DRAW_MODES, { + get(target, prop) { + deprecation(v8_0_0, `DRAW_MODES.${prop} is deprecated, use '${DEPRECATED_DRAW_MODES[prop]}' instead`); + return target[prop]; + } +}); + +"use strict"; + +"use strict"; + +"use strict"; + +"use strict"; +const fullFrame = new Rectangle(0, 0, 1, 1); +function viewportFromFrame(viewport, source, frame) { + frame || (frame = fullFrame); + const pixelWidth = source.pixelWidth; + const pixelHeight = source.pixelHeight; + viewport.x = frame.x * pixelWidth | 0; + viewport.y = frame.y * pixelHeight | 0; + viewport.width = frame.width * pixelWidth | 0; + viewport.height = frame.height * pixelHeight | 0; + return viewport; +} + +"use strict"; + +"use strict"; + +"use strict"; + +"use strict"; +var MSAA_QUALITY = /* @__PURE__ */ ((MSAA_QUALITY2) => { + MSAA_QUALITY2[MSAA_QUALITY2["NONE"] = 0] = "NONE"; + MSAA_QUALITY2[MSAA_QUALITY2["LOW"] = 2] = "LOW"; + MSAA_QUALITY2[MSAA_QUALITY2["MEDIUM"] = 4] = "MEDIUM"; + MSAA_QUALITY2[MSAA_QUALITY2["HIGH"] = 8] = "HIGH"; + return MSAA_QUALITY2; +})(MSAA_QUALITY || {}); +var DEPRECATED_WRAP_MODES = /* @__PURE__ */ ((DEPRECATED_WRAP_MODES2) => { + DEPRECATED_WRAP_MODES2["CLAMP"] = "clamp-to-edge"; + DEPRECATED_WRAP_MODES2["REPEAT"] = "repeat"; + DEPRECATED_WRAP_MODES2["MIRRORED_REPEAT"] = "mirror-repeat"; + return DEPRECATED_WRAP_MODES2; +})(DEPRECATED_WRAP_MODES || {}); +const WRAP_MODES = new Proxy(DEPRECATED_WRAP_MODES, { + get(target, prop) { + deprecation(v8_0_0, `DRAW_MODES.${prop} is deprecated, use '${DEPRECATED_WRAP_MODES[prop]}' instead`); + return target[prop]; + } +}); +var DEPRECATED_SCALE_MODES = /* @__PURE__ */ ((DEPRECATED_SCALE_MODES2) => { + DEPRECATED_SCALE_MODES2["NEAREST"] = "nearest"; + DEPRECATED_SCALE_MODES2["LINEAR"] = "linear"; + return DEPRECATED_SCALE_MODES2; +})(DEPRECATED_SCALE_MODES || {}); +const SCALE_MODES = new Proxy(DEPRECATED_SCALE_MODES, { + get(target, prop) { + deprecation(v8_0_0, `DRAW_MODES.${prop} is deprecated, use '${DEPRECATED_SCALE_MODES[prop]}' instead`); + return target[prop]; + } +}); + +"use strict"; + +"use strict"; +class TextureUvs { + constructor() { + this.x0 = 0; + this.y0 = 0; + this.x1 = 1; + this.y1 = 0; + this.x2 = 1; + this.y2 = 1; + this.x3 = 0; + this.y3 = 1; + this.uvsFloat32 = new Float32Array(8); + } + /** + * Sets the texture Uvs based on the given frame information. + * @protected + * @param frame - The frame of the texture + * @param baseFrame - The base frame of the texture + * @param rotate - Rotation of frame, see {@link groupD8} + */ + set(frame, baseFrame, rotate) { + const tw = baseFrame.width; + const th = baseFrame.height; + if (rotate) { + const w2 = frame.width / 2 / tw; + const h2 = frame.height / 2 / th; + const cX = frame.x / tw + w2; + const cY = frame.y / th + h2; + rotate = groupD8.add(rotate, groupD8.NW); + this.x0 = cX + w2 * groupD8.uX(rotate); + this.y0 = cY + h2 * groupD8.uY(rotate); + rotate = groupD8.add(rotate, 2); + this.x1 = cX + w2 * groupD8.uX(rotate); + this.y1 = cY + h2 * groupD8.uY(rotate); + rotate = groupD8.add(rotate, 2); + this.x2 = cX + w2 * groupD8.uX(rotate); + this.y2 = cY + h2 * groupD8.uY(rotate); + rotate = groupD8.add(rotate, 2); + this.x3 = cX + w2 * groupD8.uX(rotate); + this.y3 = cY + h2 * groupD8.uY(rotate); + } else { + this.x0 = frame.x / tw; + this.y0 = frame.y / th; + this.x1 = (frame.x + frame.width) / tw; + this.y1 = frame.y / th; + this.x2 = (frame.x + frame.width) / tw; + this.y2 = (frame.y + frame.height) / th; + this.x3 = frame.x / tw; + this.y3 = (frame.y + frame.height) / th; + } + this.uvsFloat32[0] = this.x0; + this.uvsFloat32[1] = this.y0; + this.uvsFloat32[2] = this.x1; + this.uvsFloat32[3] = this.y1; + this.uvsFloat32[4] = this.x2; + this.uvsFloat32[5] = this.y2; + this.uvsFloat32[6] = this.x3; + this.uvsFloat32[7] = this.y3; + } + toString() { + return `[pixi.js/core:TextureUvs x0=${this.x0} y0=${this.y0} x1=${this.x1} y1=${this.y1} x2=${this.x2} y2=${this.y2} x3=${this.x3} y3=${this.y3}]`; + } +} + +"use strict"; +let uidCount = 0; +function generateUID() { + return uidCount++; +} + +"use strict"; +function parseFunctionBody(fn) { + const fnStr = fn.toString(); + const bodyStart = fnStr.indexOf("{"); + const bodyEnd = fnStr.lastIndexOf("}"); + if (bodyStart === -1 || bodyEnd === -1) { + throw new Error("getFunctionBody: No body found in function definition"); + } + return fnStr.slice(bodyStart + 1, bodyEnd).trim(); +} + +"use strict"; + +"use strict"; + +"use strict"; + +"use strict"; + +"use strict"; +var __defProp$6 = Object.defineProperty; +var __getOwnPropSymbols$6 = Object.getOwnPropertySymbols; +var __hasOwnProp$6 = Object.prototype.hasOwnProperty; +var __propIsEnum$6 = Object.prototype.propertyIsEnumerable; +var __defNormalProp$6 = (obj, key, value) => key in obj ? __defProp$6(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; +var __spreadValues$6 = (a, b) => { + for (var prop in b || (b = {})) + if (__hasOwnProp$6.call(b, prop)) + __defNormalProp$6(a, prop, b[prop]); + if (__getOwnPropSymbols$6) + for (var prop of __getOwnPropSymbols$6(b)) { + if (__propIsEnum$6.call(b, prop)) + __defNormalProp$6(a, prop, b[prop]); + } + return a; +}; +var __objRest$4 = (source, exclude) => { + var target = {}; + for (var prop in source) + if (__hasOwnProp$6.call(source, prop) && exclude.indexOf(prop) < 0) + target[prop] = source[prop]; + if (source != null && __getOwnPropSymbols$6) + for (var prop of __getOwnPropSymbols$6(source)) { + if (exclude.indexOf(prop) < 0 && __propIsEnum$6.call(source, prop)) + target[prop] = source[prop]; + } + return target; +}; +class RenderContainer extends Container { + /** + * @param options - The options for the container. + */ + constructor(options) { + var _b, _c; + if (typeof options === "function") { + options = { render: options }; + } + const _a = options, { render } = _a, rest = __objRest$4(_a, ["render"]); + super(__spreadValues$6({ + label: "RenderContainer" + }, rest)); + this.batched = false; + /** + * The local bounds of the sprite. + * @type {rendering.Bounds} + */ + this.bounds = new Bounds(); + this.canBundle = false; + this.renderPipeId = "customRender"; + if (render) + this.render = render; + this.containsPoint = (_b = options.containsPoint) != null ? _b : () => false; + this.addBounds = (_c = options.addBounds) != null ? _c : () => false; + } + /** + * An overrideable function that can be used to render the object using the current renderer. + * @param _renderer - The current renderer + */ + render(_renderer) { + } +} + +"use strict"; +function multiplyHexColors(color1, color2) { + if (color1 === 16777215 || !color2) + return color2; + if (color2 === 16777215 || !color1) + return color1; + const r1 = color1 >> 16 & 255; + const g1 = color1 >> 8 & 255; + const b1 = color1 & 255; + const r2 = color2 >> 16 & 255; + const g2 = color2 >> 8 & 255; + const b2 = color2 & 255; + const r = r1 * r2 / 255; + const g = g1 * g2 / 255; + const b = b1 * b2 / 255; + return (r << 16) + (g << 8) + b; +} + +"use strict"; +function updateLocalTransform(lt, container) { + const scale = container._scale; + const pivot = container._pivot; + const position = container._position; + const sx = scale._x; + const sy = scale._y; + const px = pivot._x; + const py = pivot._y; + lt.a = container._cx * sx; + lt.b = container._sx * sx; + lt.c = container._cy * sy; + lt.d = container._sy * sy; + lt.tx = position._x - (px * lt.a + py * lt.c); + lt.ty = position._y - (px * lt.b + py * lt.d); +} + +"use strict"; +function updateWorldTransform(local, parent, world) { + const lta = local.a; + const ltb = local.b; + const ltc = local.c; + const ltd = local.d; + const lttx = local.tx; + const ltty = local.ty; + const pta = parent.a; + const ptb = parent.b; + const ptc = parent.c; + const ptd = parent.d; + world.a = lta * pta + ltb * ptc; + world.b = lta * ptb + ltb * ptd; + world.c = ltc * pta + ltd * ptc; + world.d = ltc * ptb + ltd * ptd; + world.tx = lttx * pta + ltty * ptc + parent.tx; + world.ty = lttx * ptb + ltty * ptd + parent.ty; +} + +"use strict"; + +"use strict"; +const buildMap = { + rectangle: buildRectangle, + polygon: buildPolygon, + triangle: buildTriangle, + circle: buildCircle, + ellipse: buildCircle, + roundedRectangle: buildCircle +}; +function buildGeometryFromPath(options) { + if (options instanceof GraphicsPath) { + options = { + path: options, + textureMatrix: null, + out: null + }; + } + const vertices = []; + const uvs = []; + const indices = []; + const shapePath = options.path.shapePath; + const textureMatrix = options.textureMatrix; + shapePath.shapePrimitives.forEach(({ shape, transform: matrix }) => { + const indexOffset = indices.length; + const vertOffset = vertices.length / 2; + const points = []; + const build = buildMap[shape.type]; + build.build(shape, points); + if (matrix) { + transformVertices(points, matrix); + } + build.triangulate(points, vertices, 2, vertOffset, indices, indexOffset); + const uvsOffset = uvs.length / 2; + if (textureMatrix) { + if (matrix) { + textureMatrix.append(matrix.clone().invert()); + } + buildUvs(vertices, 2, vertOffset, uvs, uvsOffset, 2, vertices.length / 2 - vertOffset, textureMatrix); + } else { + buildSimpleUvs(uvs, uvsOffset, 2, vertices.length / 2 - vertOffset); + } + }); + const out = options.out; + if (out) { + out.positions = new Float32Array(vertices); + out.uvs = new Float32Array(uvs); + out.indices = new Uint32Array(indices); + return out; + } + const geometry = new MeshGeometry({ + positions: new Float32Array(vertices), + uvs: new Float32Array(uvs), + indices: new Uint32Array(indices) + }); + return geometry; +} + +"use strict"; +var __defProp$5 = Object.defineProperty; +var __defProps$3 = Object.defineProperties; +var __getOwnPropDescs$3 = Object.getOwnPropertyDescriptors; +var __getOwnPropSymbols$5 = Object.getOwnPropertySymbols; +var __hasOwnProp$5 = Object.prototype.hasOwnProperty; +var __propIsEnum$5 = Object.prototype.propertyIsEnumerable; +var __defNormalProp$5 = (obj, key, value) => key in obj ? __defProp$5(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; +var __spreadValues$5 = (a, b) => { + for (var prop in b || (b = {})) + if (__hasOwnProp$5.call(b, prop)) + __defNormalProp$5(a, prop, b[prop]); + if (__getOwnPropSymbols$5) + for (var prop of __getOwnPropSymbols$5(b)) { + if (__propIsEnum$5.call(b, prop)) + __defNormalProp$5(a, prop, b[prop]); + } + return a; +}; +var __spreadProps$3 = (a, b) => __defProps$3(a, __getOwnPropDescs$3(b)); +var __objRest$3 = (source, exclude) => { + var target = {}; + for (var prop in source) + if (__hasOwnProp$5.call(source, prop) && exclude.indexOf(prop) < 0) + target[prop] = source[prop]; + if (source != null && __getOwnPropSymbols$5) + for (var prop of __getOwnPropSymbols$5(source)) { + if (exclude.indexOf(prop) < 0 && __propIsEnum$5.call(source, prop)) + target[prop] = source[prop]; + } + return target; +}; +class MeshPlane extends Mesh { + /** + * @param options - Options to be applied to MeshPlane + */ + constructor(options) { + const _a = options, { texture, verticesX, verticesY } = _a, rest = __objRest$3(_a, ["texture", "verticesX", "verticesY"]); + const planeGeometry = new PlaneGeometry(definedProps({ + width: texture.width, + height: texture.height, + verticesX, + verticesY + })); + super(definedProps(__spreadProps$3(__spreadValues$5({}, rest), { geometry: planeGeometry, texture }))); + this.texture = texture; + this.autoResize = true; + } + /** + * Method used for overrides, to do something in case texture frame was changed. + * Meshes based on plane can override it and change more details based on texture. + */ + textureUpdated() { + const geometry = this.geometry; + const { width, height } = this.texture; + if (this.autoResize && (geometry.width !== width || geometry.height !== height)) { + geometry.width = width; + geometry.height = height; + geometry.build({}); + } + } + set texture(value) { + var _a; + (_a = this._texture) == null ? void 0 : _a.off("update", this.textureUpdated, this); + super.texture = value; + value.on("update", this.textureUpdated, this); + this.textureUpdated(); + } + /** The texture of the MeshPlane */ + get texture() { + return this._texture; + } + /** + * Destroys this sprite renderable and optionally its texture. + * @param options - Options parameter. A boolean will act as if all options + * have been set to that value + * @param {boolean} [options.texture=false] - Should it destroy the current texture of the renderable as well + * @param {boolean} [options.textureSource=false] - Should it destroy the textureSource of the renderable as well + */ + destroy(options) { + this.texture.off("update", this.textureUpdated, this); + super.destroy(options); + } +} + +"use strict"; +var __defProp$4 = Object.defineProperty; +var __getOwnPropSymbols$4 = Object.getOwnPropertySymbols; +var __hasOwnProp$4 = Object.prototype.hasOwnProperty; +var __propIsEnum$4 = Object.prototype.propertyIsEnumerable; +var __defNormalProp$4 = (obj, key, value) => key in obj ? __defProp$4(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; +var __spreadValues$4 = (a, b) => { + for (var prop in b || (b = {})) + if (__hasOwnProp$4.call(b, prop)) + __defNormalProp$4(a, prop, b[prop]); + if (__getOwnPropSymbols$4) + for (var prop of __getOwnPropSymbols$4(b)) { + if (__propIsEnum$4.call(b, prop)) + __defNormalProp$4(a, prop, b[prop]); + } + return a; +}; +const _RopeGeometry = class _RopeGeometry extends MeshGeometry { + /** + * @param options - Options to be applied to rope geometry + */ + constructor(options) { + const { width, points, textureScale } = __spreadValues$4(__spreadValues$4({}, _RopeGeometry.defaultOptions), options); + super({ + positions: new Float32Array(points.length * 4), + uvs: new Float32Array(points.length * 4), + indices: new Uint32Array((points.length - 1) * 6) + }); + this.points = points; + this._width = width; + this.textureScale = textureScale; + this._build(); + } + /** + * The width (i.e., thickness) of the rope. + * @readonly + */ + get width() { + return this._width; + } + /** Refreshes Rope indices and uvs */ + _build() { + const points = this.points; + if (!points) + return; + const vertexBuffer = this.getBuffer("aPosition"); + const uvBuffer = this.getBuffer("aUV"); + const indexBuffer = this.getIndex(); + if (points.length < 1) { + return; + } + if (vertexBuffer.data.length / 4 !== points.length) { + vertexBuffer.data = new Float32Array(points.length * 4); + uvBuffer.data = new Float32Array(points.length * 4); + indexBuffer.data = new Uint16Array((points.length - 1) * 6); + } + const uvs = uvBuffer.data; + const indices = indexBuffer.data; + uvs[0] = 0; + uvs[1] = 0; + uvs[2] = 0; + uvs[3] = 1; + let amount = 0; + let prev = points[0]; + const textureWidth = this._width * this.textureScale; + const total = points.length; + for (let i = 0; i < total; i++) { + const index = i * 4; + if (this.textureScale > 0) { + const dx = prev.x - points[i].x; + const dy = prev.y - points[i].y; + const distance = Math.sqrt(dx * dx + dy * dy); + prev = points[i]; + amount += distance / textureWidth; + } else { + amount = i / (total - 1); + } + uvs[index] = amount; + uvs[index + 1] = 0; + uvs[index + 2] = amount; + uvs[index + 3] = 1; + } + let indexCount = 0; + for (let i = 0; i < total - 1; i++) { + const index = i * 2; + indices[indexCount++] = index; + indices[indexCount++] = index + 1; + indices[indexCount++] = index + 2; + indices[indexCount++] = index + 2; + indices[indexCount++] = index + 1; + indices[indexCount++] = index + 3; + } + uvBuffer.update(); + indexBuffer.update(); + this.updateVertices(); + } + /** refreshes vertices of Rope mesh */ + updateVertices() { + const points = this.points; + if (points.length < 1) { + return; + } + let lastPoint = points[0]; + let nextPoint; + let perpX = 0; + let perpY = 0; + const vertices = this.buffers[0].data; + const total = points.length; + const halfWidth = this.textureScale > 0 ? this.textureScale * this._width / 2 : this._width / 2; + for (let i = 0; i < total; i++) { + const point = points[i]; + const index = i * 4; + if (i < points.length - 1) { + nextPoint = points[i + 1]; + } else { + nextPoint = point; + } + perpY = -(nextPoint.x - lastPoint.x); + perpX = nextPoint.y - lastPoint.y; + let ratio = (1 - i / (total - 1)) * 10; + if (ratio > 1) { + ratio = 1; + } + const perpLength = Math.sqrt(perpX * perpX + perpY * perpY); + if (perpLength < 1e-6) { + perpX = 0; + perpY = 0; + } else { + perpX /= perpLength; + perpY /= perpLength; + perpX *= halfWidth; + perpY *= halfWidth; + } + vertices[index] = point.x + perpX; + vertices[index + 1] = point.y + perpY; + vertices[index + 2] = point.x - perpX; + vertices[index + 3] = point.y - perpY; + lastPoint = point; + } + this.buffers[0].update(); + } + /** Refreshes Rope indices and uvs */ + update() { + if (this.textureScale > 0) { + this._build(); + } else { + this.updateVertices(); + } + } +}; +/** Default options for RopeGeometry constructor. */ +_RopeGeometry.defaultOptions = { + /** The width (i.e., thickness) of the rope. */ + width: 200, + /** An array of points that determine the rope. */ + points: [], + /** Rope texture scale, if zero then the rope texture is stretched. */ + textureScale: 0 +}; +let RopeGeometry = _RopeGeometry; + +"use strict"; +var __defProp$3 = Object.defineProperty; +var __defProps$2 = Object.defineProperties; +var __getOwnPropDescs$2 = Object.getOwnPropertyDescriptors; +var __getOwnPropSymbols$3 = Object.getOwnPropertySymbols; +var __hasOwnProp$3 = Object.prototype.hasOwnProperty; +var __propIsEnum$3 = Object.prototype.propertyIsEnumerable; +var __defNormalProp$3 = (obj, key, value) => key in obj ? __defProp$3(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; +var __spreadValues$3 = (a, b) => { + for (var prop in b || (b = {})) + if (__hasOwnProp$3.call(b, prop)) + __defNormalProp$3(a, prop, b[prop]); + if (__getOwnPropSymbols$3) + for (var prop of __getOwnPropSymbols$3(b)) { + if (__propIsEnum$3.call(b, prop)) + __defNormalProp$3(a, prop, b[prop]); + } + return a; +}; +var __spreadProps$2 = (a, b) => __defProps$2(a, __getOwnPropDescs$2(b)); +var __objRest$2 = (source, exclude) => { + var target = {}; + for (var prop in source) + if (__hasOwnProp$3.call(source, prop) && exclude.indexOf(prop) < 0) + target[prop] = source[prop]; + if (source != null && __getOwnPropSymbols$3) + for (var prop of __getOwnPropSymbols$3(source)) { + if (exclude.indexOf(prop) < 0 && __propIsEnum$3.call(source, prop)) + target[prop] = source[prop]; + } + return target; +}; +const _MeshRope = class _MeshRope extends Mesh { + /** + * Note: The wrap mode of the texture is set to REPEAT if `textureScale` is positive. + * @param options + * @param options.texture - The texture to use on the rope. + * @param options.points - An array of {@link math.Point} objects to construct this rope. + * @param {number} options.textureScale - Optional. Positive values scale rope texture + * keeping its aspect ratio. You can reduce alpha channel artifacts by providing a larger texture + * and downsampling here. If set to zero, texture will be stretched instead. + */ + constructor(options) { + const _a = __spreadValues$3(__spreadValues$3({}, _MeshRope.defaultOptions), options), { texture, points, textureScale } = _a, rest = __objRest$2(_a, ["texture", "points", "textureScale"]); + const ropeGeometry = new RopeGeometry(definedProps({ width: texture.height, points, textureScale })); + if (textureScale > 0) { + texture.source.style.addressMode = "repeat"; + } + super(definedProps(__spreadProps$2(__spreadValues$3({}, rest), { + texture, + geometry: ropeGeometry + }))); + this.autoUpdate = true; + this.onRender = this._render; + } + _render() { + const geometry = this.geometry; + if (this.autoUpdate || geometry._width !== this.texture.height) { + geometry._width = this.texture.height; + geometry.update(); + } + } +}; +_MeshRope.defaultOptions = { + textureScale: 0 +}; +let MeshRope = _MeshRope; + +"use strict"; +var __defProp$2 = Object.defineProperty; +var __defProps$1 = Object.defineProperties; +var __getOwnPropDescs$1 = Object.getOwnPropertyDescriptors; +var __getOwnPropSymbols$2 = Object.getOwnPropertySymbols; +var __hasOwnProp$2 = Object.prototype.hasOwnProperty; +var __propIsEnum$2 = Object.prototype.propertyIsEnumerable; +var __defNormalProp$2 = (obj, key, value) => key in obj ? __defProp$2(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; +var __spreadValues$2 = (a, b) => { + for (var prop in b || (b = {})) + if (__hasOwnProp$2.call(b, prop)) + __defNormalProp$2(a, prop, b[prop]); + if (__getOwnPropSymbols$2) + for (var prop of __getOwnPropSymbols$2(b)) { + if (__propIsEnum$2.call(b, prop)) + __defNormalProp$2(a, prop, b[prop]); + } + return a; +}; +var __spreadProps$1 = (a, b) => __defProps$1(a, __getOwnPropDescs$1(b)); +var __objRest$1 = (source, exclude) => { + var target = {}; + for (var prop in source) + if (__hasOwnProp$2.call(source, prop) && exclude.indexOf(prop) < 0) + target[prop] = source[prop]; + if (source != null && __getOwnPropSymbols$2) + for (var prop of __getOwnPropSymbols$2(source)) { + if (exclude.indexOf(prop) < 0 && __propIsEnum$2.call(source, prop)) + target[prop] = source[prop]; + } + return target; +}; +class MeshSimple extends Mesh { + /** + * @param options - Options to be used for construction + */ + constructor(options) { + const _a = options, { texture, vertices, uvs, indices, topology } = _a, rest = __objRest$1(_a, ["texture", "vertices", "uvs", "indices", "topology"]); + const geometry = new MeshGeometry(definedProps({ + positions: vertices, + uvs, + indices, + topology + })); + super(definedProps(__spreadProps$1(__spreadValues$2({}, rest), { + texture, + geometry + }))); + this.autoUpdate = true; + this.onRender = this._render; + } + /** + * Collection of vertices data. + * @type {Float32Array} + */ + get vertices() { + return this.geometry.getBuffer("aPosition").data; + } + set vertices(value) { + this.geometry.getBuffer("aPosition").data = value; + } + _render() { + if (this.autoUpdate) { + this.geometry.getBuffer("aPosition").update(); + } + } +} + +"use strict"; +function getTextureDefaultMatrix(texture, out) { + const { width, height } = texture.frame; + out.scale(1 / width, 1 / height); + return out; +} + +"use strict"; +var __defProp$1 = Object.defineProperty; +var __getOwnPropSymbols$1 = Object.getOwnPropertySymbols; +var __hasOwnProp$1 = Object.prototype.hasOwnProperty; +var __propIsEnum$1 = Object.prototype.propertyIsEnumerable; +var __defNormalProp$1 = (obj, key, value) => key in obj ? __defProp$1(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; +var __spreadValues$1 = (a, b) => { + for (var prop in b || (b = {})) + if (__hasOwnProp$1.call(b, prop)) + __defNormalProp$1(a, prop, b[prop]); + if (__getOwnPropSymbols$1) + for (var prop of __getOwnPropSymbols$1(b)) { + if (__propIsEnum$1.call(b, prop)) + __defNormalProp$1(a, prop, b[prop]); + } + return a; +}; +var __objRest = (source, exclude) => { + var target = {}; + for (var prop in source) + if (__hasOwnProp$1.call(source, prop) && exclude.indexOf(prop) < 0) + target[prop] = source[prop]; + if (source != null && __getOwnPropSymbols$1) + for (var prop of __getOwnPropSymbols$1(source)) { + if (exclude.indexOf(prop) < 0 && __propIsEnum$1.call(source, prop)) + target[prop] = source[prop]; + } + return target; +}; +const _NineSliceSprite = class _NineSliceSprite extends Container { + /** + * @param {scene.NineSliceSpriteOptions|Texture} options - Options to use + * @param options.texture - The texture to use on the NineSliceSprite. + * @param options.leftWidth - Width of the left vertical bar (A) + * @param options.topHeight - Height of the top horizontal bar (C) + * @param options.rightWidth - Width of the right vertical bar (B) + * @param options.bottomHeight - Height of the bottom horizontal bar (D) + * @param options.width - Width of the NineSliceSprite, + * setting this will actually modify the vertices and not the UV's of this plane. + * @param options.height - Height of the NineSliceSprite, + * setting this will actually modify the vertices and not UV's of this plane. + */ + constructor(options) { + var _b, _c, _d, _e, _f, _g, _h, _i, _j, _k; + if (options instanceof Texture) { + options = { texture: options }; + } + const _a = options, { + width, + height, + leftWidth, + rightWidth, + topHeight, + bottomHeight, + texture, + roundPixels + } = _a, rest = __objRest(_a, [ + "width", + "height", + "leftWidth", + "rightWidth", + "topHeight", + "bottomHeight", + "texture", + "roundPixels" + ]); + super(__spreadValues$1({ + label: "NineSliceSprite" + }, rest)); + this._roundPixels = 0; + this.renderPipeId = "nineSliceSprite"; + this.batched = true; + this._didSpriteUpdate = true; + this.bounds = { minX: 0, minY: 0, maxX: 0, maxY: 0 }; + this._leftWidth = (_c = leftWidth != null ? leftWidth : (_b = texture == null ? void 0 : texture.defaultBorders) == null ? void 0 : _b.left) != null ? _c : NineSliceGeometry.defaultOptions.leftWidth; + this._topHeight = (_e = topHeight != null ? topHeight : (_d = texture == null ? void 0 : texture.defaultBorders) == null ? void 0 : _d.top) != null ? _e : NineSliceGeometry.defaultOptions.topHeight; + this._rightWidth = (_g = rightWidth != null ? rightWidth : (_f = texture == null ? void 0 : texture.defaultBorders) == null ? void 0 : _f.right) != null ? _g : NineSliceGeometry.defaultOptions.rightWidth; + this._bottomHeight = (_i = bottomHeight != null ? bottomHeight : (_h = texture == null ? void 0 : texture.defaultBorders) == null ? void 0 : _h.bottom) != null ? _i : NineSliceGeometry.defaultOptions.bottomHeight; + this.bounds.maxX = this._width = (_j = width != null ? width : texture.width) != null ? _j : NineSliceGeometry.defaultOptions.width; + this.bounds.maxY = this._height = (_k = height != null ? height : texture.height) != null ? _k : NineSliceGeometry.defaultOptions.height; + this.allowChildren = false; + this.texture = texture != null ? texture : _NineSliceSprite.defaultOptions.texture; + this.roundPixels = roundPixels != null ? roundPixels : false; + } + /** The width of the NineSliceSprite, setting this will actually modify the vertices and UV's of this plane. */ + get width() { + return this._width; + } + set width(value) { + this.bounds.maxX = this._width = value; + this.onViewUpdate(); + } + /** The height of the NineSliceSprite, setting this will actually modify the vertices and UV's of this plane. */ + get height() { + return this._height; + } + set height(value) { + this.bounds.maxY = this._height = value; + this.onViewUpdate(); + } + /** The width of the left column (a) of the NineSliceSprite. */ + get leftWidth() { + return this._leftWidth; + } + set leftWidth(value) { + this._leftWidth = value; + this.onViewUpdate(); + } + /** The width of the right column (b) of the NineSliceSprite. */ + get topHeight() { + return this._topHeight; + } + set topHeight(value) { + this._topHeight = value; + this.onViewUpdate(); + } + /** The width of the right column (b) of the NineSliceSprite. */ + get rightWidth() { + return this._rightWidth; + } + set rightWidth(value) { + this._rightWidth = value; + this.onViewUpdate(); + } + /** The width of the right column (b) of the NineSliceSprite. */ + get bottomHeight() { + return this._bottomHeight; + } + set bottomHeight(value) { + this._bottomHeight = value; + this.onViewUpdate(); + } + /** The texture that the NineSliceSprite is using. */ + get texture() { + return this._texture; + } + set texture(value) { + value || (value = Texture.EMPTY); + const currentTexture = this._texture; + if (currentTexture === value) + return; + if (currentTexture && currentTexture.dynamic) + currentTexture.off("update", this.onViewUpdate, this); + if (value.dynamic) + value.on("update", this.onViewUpdate, this); + this._texture = value; + this.onViewUpdate(); + } + /** + * Whether or not to round the x/y position of the sprite. + * @type {boolean} + */ + get roundPixels() { + return !!this._roundPixels; + } + set roundPixels(value) { + this._roundPixels = value ? 1 : 0; + } + /** The original width of the texture */ + get originalWidth() { + return this._texture.width; + } + /** The original height of the texture */ + get originalHeight() { + return this._texture.height; + } + onViewUpdate() { + this._didChangeId += 1 << 12; + this._didSpriteUpdate = true; + if (this.didViewUpdate) + return; + this.didViewUpdate = true; + if (this.renderGroup) { + this.renderGroup.onChildViewUpdate(this); + } + } + /** + * Adds the bounds of this object to the bounds object. + * @param bounds - The output bounds object. + */ + addBounds(bounds) { + const _bounds = this.bounds; + bounds.addFrame(_bounds.minX, _bounds.minY, _bounds.maxX, _bounds.maxY); + } + /** + * Checks if the object contains the given point. + * @param point - The point to check + */ + containsPoint(point) { + const bounds = this.bounds; + if (point.x >= bounds.minX && point.x <= bounds.maxX) { + if (point.y >= bounds.minY && point.y <= bounds.maxY) { + return true; + } + } + return false; + } + /** + * Destroys this sprite renderable and optionally its texture. + * @param options - Options parameter. A boolean will act as if all options + * have been set to that value + * @param {boolean} [options.texture=false] - Should it destroy the current texture of the renderable as well + * @param {boolean} [options.textureSource=false] - Should it destroy the textureSource of the renderable as well + */ + destroy(options) { + super.destroy(options); + const destroyTexture = typeof options === "boolean" ? options : options == null ? void 0 : options.texture; + if (destroyTexture) { + const destroyTextureSource = typeof options === "boolean" ? options : options == null ? void 0 : options.textureSource; + this._texture.destroy(destroyTextureSource); + } + this._texture = null; + this.bounds = null; + } +}; +/** The default options, used to override the initial values of any options passed in the constructor. */ +_NineSliceSprite.defaultOptions = { + /** @default Texture.EMPTY */ + texture: Texture.EMPTY +}; +let NineSliceSprite = _NineSliceSprite; +class NineSlicePlane extends NineSliceSprite { + constructor(...args) { + let options = args[0]; + if (options instanceof Texture) { + deprecation(v8_0_0, "NineSlicePlane now uses the options object {texture, leftWidth, rightWidth, topHeight, bottomHeight}"); + options = { + texture: options, + leftWidth: args[1], + topHeight: args[2], + rightWidth: args[3], + bottomHeight: args[4] + }; + } + deprecation(v8_0_0, "NineSlicePlane is deprecated. Use NineSliceSprite instead."); + super(options); + } +} + +"use strict"; +function ensureTextStyle(renderMode, style) { + if (style instanceof TextStyle || style instanceof HTMLTextStyle) { + return style; + } + return renderMode === "html" ? new HTMLTextStyle(style) : new TextStyle(style); +} + +"use strict"; + +"use strict"; + +"use strict"; + +"use strict"; +const DATA_URI = /^\s*data:(?:([\w-]+)\/([\w+.-]+))?(?:;charset=([\w-]+))?(?:;(base64))?,(.*)/i; + +"use strict"; +async function logDebugTexture(texture, renderer, size = 200) { + const base64 = await renderer.extract.base64(texture); + await renderer.encoder.commandFinished; + const width = size; + console.log(`logging texture ${texture.source.width}px ${texture.source.height}px`); + const style = [ + "font-size: 1px;", + `padding: ${width}px ${300}px;`, + `background: url(${base64}) no-repeat;`, + "background-size: contain;" + ].join(" "); + console.log("%c ", style); +} + +"use strict"; +var __defProp = Object.defineProperty; +var __defProps = Object.defineProperties; +var __getOwnPropDescs = Object.getOwnPropertyDescriptors; +var __getOwnPropSymbols = Object.getOwnPropertySymbols; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __propIsEnum = Object.prototype.propertyIsEnumerable; +var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; +var __spreadValues = (a, b) => { + for (var prop in b || (b = {})) + if (__hasOwnProp.call(b, prop)) + __defNormalProp(a, prop, b[prop]); + if (__getOwnPropSymbols) + for (var prop of __getOwnPropSymbols(b)) { + if (__propIsEnum.call(b, prop)) + __defNormalProp(a, prop, b[prop]); + } + return a; +}; +var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b)); +const colors = [ + "#000080", + // Navy Blue + "#228B22", + // Forest Green + "#8B0000", + // Dark Red + "#4169E1", + // Royal Blue + "#008080", + // Teal + "#800000", + // Maroon + "#9400D3", + // Dark Violet + "#FF8C00", + // Dark Orange + "#556B2F", + // Olive Green + "#8B008B" + // Dark Magenta +]; +let colorTick = 0; +function logScene(container, depth = 0, data = { color: "#000000" }) { + if (container.isRenderGroupRoot) { + data.color = colors[colorTick++]; + } + let spaces = ""; + for (let i = 0; i < depth; i++) { + spaces += " "; + } + let label = container.label; + if (!label && container instanceof Sprite) { + label = `sprite:${container.texture.label}`; + } + let output = `%c ${spaces}|- ${label} (worldX:${container.worldTransform.tx}, relativeRenderX:${container.relativeGroupTransform.tx}, renderX:${container.groupTransform.tx}, localX:${container.x})`; + if (container.isRenderGroupRoot) { + output += " (RenderGroup)"; + } + if (container.filters) { + output += "(*filters)"; + } + console.log(output, `color:${data.color}; font-weight:bold;`); + depth++; + for (let i = 0; i < container.children.length; i++) { + const child = container.children[i]; + logScene(child, depth, __spreadValues({}, data)); + } +} +function logRenderGroupScene(renderGroup, depth = 0, data = { index: 0, color: "#000000" }) { + let spaces = ""; + for (let i = 0; i < depth; i++) { + spaces += " "; + } + const output = `%c ${spaces}- ${data.index}: ${renderGroup.root.label} worldX:${renderGroup.worldTransform.tx}`; + console.log(output, `color:${data.color}; font-weight:bold;`); + depth++; + for (let i = 0; i < renderGroup.renderGroupChildren.length; i++) { + const child = renderGroup.renderGroupChildren[i]; + logRenderGroupScene(child, depth, __spreadProps(__spreadValues({}, data), { index: i })); + } +} + +"use strict"; + +"use strict"; + +"use strict"; + +export { AbstractBitmapFont, AbstractRenderer, AbstractText, AccessibilitySystem, AlphaFilter, AlphaMask, AlphaMaskPipe, AnimatedSprite, Application, Assets, AssetsClass, BLEND_TO_NPM, BUFFER_TYPE, BackgroundLoader, BackgroundSystem, Batch, BatchGeometry, BatchTextureArray, BatchableGraphics, BatchableMesh, BatchableSprite, Batcher, BatcherPipe, BigPool, BindGroup, BindGroupSystem, BitmapFont, BitmapFontManager, BitmapText, BitmapTextPipe, BlendModeFilter, BlendModePipe, BlurFilter, BlurFilterPass, Bounds, BrowserAdapter, Buffer, BufferImageSource, BufferResource, BufferUsage, CLEAR, Cache, CanvasPool, CanvasPoolClass, CanvasSource, CanvasTextMetrics, CanvasTextPipe, CanvasTextSystem, Circle, Color, ColorMask, ColorMaskPipe, ColorMatrixFilter, CompressedSource, Container, Culler, CullerPlugin, CustomRenderPipe, DATA_URI, DDS, DEG_TO_RAD, DEPRECATED_SCALE_MODES, DEPRECATED_WRAP_MODES, DOMAdapter, DRAW_MODES, DXGI_TO_TEXTURE_FORMAT, DisplacementFilter, DynamicBitmapFont, Ellipse, EventBoundary, EventEmitter, EventSystem, EventsTicker, ExtensionType, ExtractSystem, FOURCC_TO_TEXTURE_FORMAT, FederatedContainer, FederatedEvent, FederatedMouseEvent, FederatedPointerEvent, FederatedWheelEvent, FillGradient, FillPattern, Filter, FilterEffect, FilterPipe, FilterSystem, FontStylePromiseCache, GAUSSIAN_VALUES, GL_FORMATS, GL_INTERNAL_FORMAT, GL_TARGETS, GL_TYPES, GL_WRAP_MODES, GenerateTextureSystem, Geometry, GlBackBufferSystem, GlBatchAdaptor, GlBuffer, GlBufferSystem, GlColorMaskSystem, GlContextSystem, GlEncoderSystem, GlGeometrySystem, GlGraphicsAdaptor, GlMeshAdaptor, GlProgram, GlProgramData, GlRenderTarget, GlRenderTargetAdaptor, GlRenderTargetSystem, GlShaderSystem, GlStateSystem, GlStencilSystem, GlTexture, GlTextureSystem, GlUboSystem, GlUniformGroupSystem, GlobalUniformSystem, GpuBatchAdaptor, GpuBlendModesToPixi, GpuBufferSystem, GpuColorMaskSystem, GpuDeviceSystem, GpuEncoderSystem, GpuGraphicsAdaptor, GpuGraphicsContext, GpuMeshAdapter, GpuMipmapGenerator, GpuProgram, GpuReadBuffer, GpuRenderTarget, GpuRenderTargetAdaptor, GpuRenderTargetSystem, GpuShaderSystem, GpuStateSystem, GpuStencilModesToPixi, GpuStencilSystem, GpuTextureSystem, GpuUboSystem, GpuUniformBatchPipe, Graphics, GraphicsContext, GraphicsContextRenderData, GraphicsContextSystem, GraphicsPath, GraphicsPipe, HTMLText, HTMLTextPipe, HTMLTextRenderData, HTMLTextStyle, HTMLTextSystem, HelloSystem, IGLUniformData, ImageSource, InstructionSet, KTX, Loader, LoaderParserPriority, MAX_TEXTURES, MSAA_QUALITY, MaskEffectManager, MaskEffectManagerClass, MaskFilter, Matrix, Mesh, MeshGeometry, MeshPipe, MeshPlane, MeshRope, MeshSimple, NOOP, NineSliceGeometry, NineSlicePlane, NineSliceSprite, NineSliceSpritePipe, NoiseFilter, ObservablePoint, PI_2, PipelineSystem, PlaneGeometry, Point, Polygon, Pool, PoolGroupClass, PrepareBase, PrepareQueue, PrepareSystem, PrepareUpload, QuadGeometry, RAD_TO_DEG, Rectangle, RenderContainer, RenderGroup, RenderGroupPipe, RenderGroupSystem, RenderTarget, RenderTargetSystem, RenderTexture, RendererType, ResizePlugin, Resolver, RopeGeometry, RoundedRectangle, SCALE_MODES, STENCIL_MODES, SVGParser, SVGToGraphicsPath, ScissorMask, SdfShader, Shader, ShaderStage, ShapePath, SharedRenderPipes, SharedSystems, Sprite, SpritePipe, Spritesheet, State, StencilMask, StencilMaskPipe, SystemRunner, TEXTURE_FORMAT_BLOCK_SIZE, Text, TextStyle, Texture, TextureGCSystem, TextureMatrix, TexturePool, TexturePoolClass, TextureSource, TextureStyle, TextureUvs, Ticker, TickerListener, TickerPlugin, TilingSprite, TilingSpritePipe, TilingSpriteShader, Transform, Triangle, UNIFORM_TO_ARRAY_SETTERS, UNIFORM_TO_SINGLE_SETTERS, UPDATE_BLEND, UPDATE_COLOR, UPDATE_PRIORITY, UPDATE_TRANSFORM, UPDATE_VISIBLE, UboBatch, UboSystem, UniformGroup, VERSION, VideoSource, ViewSystem, ViewableBuffer, WGSL_ALIGN_SIZE_DATA, WGSL_TO_STD40_SIZE, WRAP_MODES, WebGLRenderer, WebGPURenderer, WorkerManager, _getGlobalBounds, _getGlobalBoundsRecursive, accessibilityTarget, addBits, addMaskBounds, addMaskLocalBounds, addProgramDefines, fragment$4 as alphaFrag, source$5 as alphaWgsl, applyMatrix, applyStyleParams, assignWithIgnore, autoDetectEnvironment, autoDetectRenderer, autoDetectSource, basisTranscoderUrls, batchSamplersUniformGroup, bitmapFontCachePlugin, bitmapFontTextParser, bitmapFontXMLParser, bitmapFontXMLStringParser, blendTemplateFrag, blendTemplateVert, blendTemplate as blendTemplateWgsl, blockDataMap, source$4 as blurTemplateWgsl, boundsPool, browserExt, buildAdaptiveBezier, buildAdaptiveQuadratic, buildArc, buildArcTo, buildArcToSvg, buildCircle, buildContextBatches, buildGeometryFromPath, buildInstructions, buildLine, buildPolygon, buildRectangle, buildSimpleUvs, buildTriangle, buildUvs, cacheTextureArray, calculateProjection, checkChildrenDidChange, checkDataUrl, checkExtension, childrenHelperMixin, closePointEps, collectAllRenderables, collectRenderGroups, color32BitToUniform, colorBit, colorBitGl, fragment$3 as colorMatrixFilterFrag, source$3 as colorMatrixFilterWgsl, colorToUniform, compareModeToGlCompare, compileHighShader, compileHighShaderGl, compileHighShaderGlProgram, compileHighShaderGpuProgram, compileHooks, compileInputs, compileOutputs, compileShader, convertFillInputToFillStyle, convertFormatIfRequired, convertToList, copySearchParams, createIdFromString, createLevelBuffers, createLevelBuffersFromKTX, createStringVariations, createTexture, createUboElementsSTD40, createUboElementsWGSL, createUboSyncFunction, createUboSyncFunctionSTD40, createUboSyncFunctionWGSL, crossOrigin, cullingMixin, curveEps, vertex$2 as defaultFilterVert, defaultValue, definedProps, deprecation, detectAvif, detectBasis, detectCompressed, detectDefaults, detectMp4, detectOgv, detectVideoAlphaMode, detectWebm, detectWebp, determineCrossOrigin, fragment$2 as displacementFrag, vertex$1 as displacementVert, source$2 as displacementWgsl, earcut$1 as earcut, effectsMixin, ensureAttributes, ensureIsBuffer, ensureOptions, ensurePrecision, ensureTextStyle, executeInstructions, extensions, extractAttributesFromGlProgram, extractAttributesFromGpuProgram, extractFontFamilies, extractStructAndGroups, fastCopy, findHooksRx, findMixin, fontStringFromTextStyle, formatShader, fragmentGPUTemplate, fragmentGlTemplate, generateArraySyncSTD40, generateArraySyncWGSL, generateBlurFragSource, generateBlurGlProgram, generateBlurProgram, generateBlurVertSource, generateGPULayout, generateGpuLayoutGroups, generateLayout, generateLayoutHash, generateProgram, generateShaderSyncCode, generateTextStyleKey, generateTextureBatchBit, generateTextureBatchBitGl, generateUID, generateUniformsSync, getAdjustedBlendModeBlend, getAttributeInfoFromFormat, getBitmapTextLayout, getCanvasBoundingBox, getCanvasFillStyle, getCanvasTexture, getDefaultUniformValue, getFastGlobalBounds, getFontCss, getFontFamilyName, getGeometryBounds, getGlTypeFromFormat, getGlobalBounds, getGlobalRenderableBounds, getLocalBounds, getMatrixRelativeToParent, getMaxFragmentPrecision, getOrientationOfPoints, getParent, getPo2TextureFromSource, getResolutionOfUrl, getSVGUrl, getSupportedCompressedTextureFormats, getSupportedGPUCompressedTextureFormats, getSupportedGlCompressedTextureFormats, getSupportedTextureFormats, getTemporaryCanvasFromImage, getTestContext, getTextureBatchBindGroup, getTextureDefaultMatrix, getTextureFormatFromKTXTexture, getUboData, getUniformData, getUrlExtension, glFormatToGPUFormat, glUploadBufferImageResource, glUploadCompressedTextureResource, glUploadImageResource, glUploadVideoResource, globalUniformsBit, globalUniformsBitGl, globalUniformsUBOBitGl, gpuFormatToBasisTranscoderFormat, gpuFormatToKTXBasisTranscoderFormat, gpuUploadBufferImageResource, gpuUploadCompressedTextureResource, gpuUploadImageResource, gpuUploadVideoResource, groupD8, hasCachedCanvasTexture, hsl as hslWgsl, hslgl, hslgpu, injectBits, insertVersion, isMobile, isPow2, isRenderingToScreen, isSafari, isSingleItem, isWebGLSupported, isWebGPUSupported, ktxTranscoderUrls, loadBasis, loadBasisOnWorker, loadBitmapFont, loadDDS, loadFontAsBase64, loadFontCSS, loadImageBitmap, loadJson, loadKTX, loadKTX2, loadKTX2onWorker, loadSVGImage, loadSvg, loadTextures, loadTxt, loadVideoTextures, loadWebFont, localUniformBit, localUniformBitGl, localUniformBitGroup2, localUniformMSDFBit, localUniformMSDFBitGl, log2, logDebugTexture, logProgramError, logRenderGroupScene, logScene, mSDFBit, mSDFBitGl, mapFormatToGlFormat, mapFormatToGlInternalFormat, mapFormatToGlType, mapGlToVertexFormat, mapSize, mapType, mapWebGLBlendModesToPixi, fragment as maskFrag, vertex as maskVert, source as maskWgsl, matrixPool, measureHtmlText, measureMixin, migrateFragmentFromV7toV8, mipmapScaleModeToGlFilter, mixColors, mixHexColors, mixStandardAnd32BitColors, multiplyHexColors, nextPow2, fragment$1 as noiseFrag, source$1 as noiseWgsl, nonCompressedFormats, normalizeExtensionPriority, nssvg, nsxhtml, onRenderMixin, parseDDS, parseFunctionBody, parseKTX, path, preloadVideo, removeItems, removeStructAndGroupDuplicates, resetUids, resolveCharacters, resolveCompressedTextureUrl, resolveJsonUrl, resolveTextureUrl, resourceToTexture, roundPixelsBit, roundPixelsBitGl, roundedShapeArc, roundedShapeQuadraticCurve, sayHello, scaleModeToGlFilter, setBasisTranscoderPath, setKTXTranscoderPath, setPositions, setProgramName, setUvs, sortMixin, spritesheetAsset, squaredDistanceToLineSegment, stripVersion, testImageFormat, testVideoFormat, textStyleToCSS, textureBit, textureBitGl, textureFrom, tilingBit, tilingBitGl, toLocalGlobalMixin, transformVertices, triangulateWithHoles, uboSyncFunctionsSTD40, uboSyncFunctionsWGSL, uid, uniformParsers, unpremultiplyAlpha$1 as unpremultiplyAlpha, unsafeEvalSupported, updateLocalTransform, updateQuadBounds, updateRenderGroupTransform, updateRenderGroupTransforms, updateTransformAndChildren, updateTransformBackwards, updateWorldTransform, v8_0_0, validFormats, validateRenderables, vertexGPUTemplate, vertexGlTemplate, viewportFromFrame, vkFormatToGPUFormat, warn, wrapModeToGlAddress }; +//# sourceMappingURL=pixi.mjs.map