ecspresso 0.13.3 → 0.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (82) hide show
  1. package/dist/bindings/react/index.d.ts +29 -0
  2. package/dist/ecspresso.d.ts +5 -0
  3. package/dist/entity-manager.d.ts +4 -0
  4. package/dist/hierarchy-manager.d.ts +7 -0
  5. package/dist/index.js +2 -2
  6. package/dist/index.js.map +8 -8
  7. package/dist/plugins/ai/behavior-tree.d.ts +369 -0
  8. package/dist/plugins/ai/behavior-tree.js +4 -0
  9. package/dist/plugins/ai/behavior-tree.js.map +10 -0
  10. package/dist/plugins/ai/detection.d.ts +17 -0
  11. package/dist/plugins/ai/detection.js +2 -2
  12. package/dist/plugins/ai/detection.js.map +3 -3
  13. package/dist/plugins/ai/flocking.d.ts +97 -0
  14. package/dist/plugins/ai/flocking.js +4 -0
  15. package/dist/plugins/ai/flocking.js.map +12 -0
  16. package/dist/plugins/audio/audio.js +2 -2
  17. package/dist/plugins/audio/audio.js.map +2 -2
  18. package/dist/plugins/combat/health.js +2 -2
  19. package/dist/plugins/combat/health.js.map +2 -2
  20. package/dist/plugins/combat/projectile.js +2 -2
  21. package/dist/plugins/combat/projectile.js.map +2 -2
  22. package/dist/plugins/debug/diagnostics.js +3 -3
  23. package/dist/plugins/debug/diagnostics.js.map +2 -2
  24. package/dist/plugins/input/input.js +2 -2
  25. package/dist/plugins/input/input.js.map +2 -2
  26. package/dist/plugins/input/selection.js +2 -2
  27. package/dist/plugins/input/selection.js.map +2 -2
  28. package/dist/plugins/isometric/depth-sort.js +2 -2
  29. package/dist/plugins/isometric/depth-sort.js.map +2 -2
  30. package/dist/plugins/isometric/projection.js +2 -2
  31. package/dist/plugins/isometric/projection.js.map +2 -2
  32. package/dist/plugins/physics/collision.js +2 -2
  33. package/dist/plugins/physics/collision.js.map +3 -3
  34. package/dist/plugins/physics/collision3D.d.ts +83 -0
  35. package/dist/plugins/physics/collision3D.js +4 -0
  36. package/dist/plugins/physics/collision3D.js.map +13 -0
  37. package/dist/plugins/physics/physics2D.js +2 -2
  38. package/dist/plugins/physics/physics2D.js.map +3 -3
  39. package/dist/plugins/physics/physics3D.d.ts +140 -0
  40. package/dist/plugins/physics/physics3D.js +4 -0
  41. package/dist/plugins/physics/physics3D.js.map +11 -0
  42. package/dist/plugins/physics/steering.js +2 -2
  43. package/dist/plugins/physics/steering.js.map +2 -2
  44. package/dist/plugins/rendering/particles.js +2 -2
  45. package/dist/plugins/rendering/particles.js.map +2 -2
  46. package/dist/plugins/rendering/renderer2D.js +2 -2
  47. package/dist/plugins/rendering/renderer2D.js.map +3 -3
  48. package/dist/plugins/rendering/renderer3D.d.ts +226 -0
  49. package/dist/plugins/rendering/renderer3D.js +4052 -0
  50. package/dist/plugins/rendering/renderer3D.js.map +12 -0
  51. package/dist/plugins/rendering/sprite-animation.js +2 -2
  52. package/dist/plugins/rendering/sprite-animation.js.map +2 -2
  53. package/dist/plugins/scripting/coroutine.js +2 -2
  54. package/dist/plugins/scripting/coroutine.js.map +2 -2
  55. package/dist/plugins/scripting/state-machine.js +2 -2
  56. package/dist/plugins/scripting/state-machine.js.map +2 -2
  57. package/dist/plugins/scripting/timers.js +2 -2
  58. package/dist/plugins/scripting/timers.js.map +2 -2
  59. package/dist/plugins/scripting/tween.js +2 -2
  60. package/dist/plugins/scripting/tween.js.map +2 -2
  61. package/dist/plugins/spatial/bounds.js +2 -2
  62. package/dist/plugins/spatial/bounds.js.map +2 -2
  63. package/dist/plugins/spatial/camera.js +2 -2
  64. package/dist/plugins/spatial/camera.js.map +2 -2
  65. package/dist/plugins/spatial/camera3D.d.ts +92 -0
  66. package/dist/plugins/spatial/camera3D.js +4 -0
  67. package/dist/plugins/spatial/camera3D.js.map +10 -0
  68. package/dist/plugins/spatial/spatial-index.js +2 -2
  69. package/dist/plugins/spatial/spatial-index.js.map +3 -3
  70. package/dist/plugins/spatial/spatial-index3D.d.ts +80 -0
  71. package/dist/plugins/spatial/spatial-index3D.js +4 -0
  72. package/dist/plugins/spatial/spatial-index3D.js.map +11 -0
  73. package/dist/plugins/spatial/transform.js +2 -2
  74. package/dist/plugins/spatial/transform.js.map +3 -3
  75. package/dist/plugins/spatial/transform3D.d.ts +148 -0
  76. package/dist/plugins/spatial/transform3D.js +4 -0
  77. package/dist/plugins/spatial/transform3D.js.map +10 -0
  78. package/dist/resource-manager.d.ts +24 -0
  79. package/dist/utils/math.d.ts +65 -1
  80. package/dist/utils/narrowphase3D.d.ts +120 -0
  81. package/dist/utils/spatial-hash3D.d.ts +72 -0
  82. package/package.json +42 -2
@@ -0,0 +1,29 @@
1
+ import type ECSpresso from 'ecspresso';
2
+ /**
3
+ * React context for providing the ECS instance to the component tree.
4
+ * Wrap your UI root with `<EcsContext.Provider value={ecs}>`.
5
+ */
6
+ declare const EcsContext: import("react").Context<ECSpresso<any, string, string, string, string> | null>;
7
+ export { EcsContext };
8
+ /**
9
+ * Creates typed hooks bound to a specific world config.
10
+ *
11
+ * Call once at module scope with your world type, then use the
12
+ * returned hooks in components anywhere under the `EcsContext.Provider`.
13
+ *
14
+ * @example
15
+ * ```tsx
16
+ * const ecs = ECSpresso.create()
17
+ * .withResourceTypes<{ score: number; health: number }>()
18
+ * .withEventTypes<{ enemyKilled: { id: number } }>()
19
+ * .build();
20
+ *
21
+ * type ECS = typeof ecs;
22
+ * const { useResource, useEvent, useEcs } = createEcsHooks<ECS>();
23
+ * ```
24
+ */
25
+ export declare function createEcsHooks<W extends ECSpresso<any>>(): {
26
+ readonly useEcs: () => W;
27
+ readonly useResource: <K extends keyof W["_cfg"]["resources"] & string>(key: K) => W["_cfg"]["resources"][K];
28
+ readonly useEvent: <E extends keyof W["_cfg"]["events"] & string>(type: E, callback: (data: W["_cfg"]["events"][E]) => void) => void;
29
+ };
@@ -318,6 +318,11 @@ export default class ECSpresso<Cfg extends WorldConfig = EmptyConfig, Labels ext
318
318
  * @returns Unsubscribe function
319
319
  */
320
320
  onResourceChange<K extends keyof Cfg['resources']>(key: K, callback: (newValue: Cfg['resources'][K], oldValue: Cfg['resources'][K]) => void): () => void;
321
+ /**
322
+ * Whether a resource has active change subscribers.
323
+ * Used by the system builder to skip caching for observed resources.
324
+ */
325
+ isResourceObserved<K extends keyof Cfg['resources']>(key: K): boolean;
321
326
  /**
322
327
  * Get all resource keys that are currently registered
323
328
  * @returns Array of resource keys
@@ -221,6 +221,10 @@ export default class EntityManager<ComponentTypes> {
221
221
  * @returns true if entityId is an ancestor of descendantId
222
222
  */
223
223
  isAncestorOf(entityId: number, descendantId: number): boolean;
224
+ /**
225
+ * Returns true when at least one parent-child relationship exists.
226
+ */
227
+ get hasHierarchy(): boolean;
224
228
  /**
225
229
  * Get all root entities (entities that have children but no parent)
226
230
  * @returns Readonly array of root entity IDs
@@ -8,6 +8,8 @@ export default class HierarchyManager {
8
8
  private parentMap;
9
9
  /** parentId -> ordered childIds */
10
10
  private childrenMap;
11
+ /** Pre-allocated flat BFS queue for forEachInHierarchy [entityId, parentId (-1=null), depth, ...] */
12
+ private _bfsQueue;
11
13
  /**
12
14
  * Set the parent of an entity.
13
15
  * @param childId The entity to set as a child
@@ -95,6 +97,11 @@ export default class HierarchyManager {
95
97
  * @returns true if entityId is an ancestor of descendantId
96
98
  */
97
99
  isAncestorOf(entityId: number, descendantId: number): boolean;
100
+ /**
101
+ * Returns true when at least one parent-child relationship exists.
102
+ * O(1) — checks Map size, no iteration.
103
+ */
104
+ get hasHierarchy(): boolean;
98
105
  /**
99
106
  * Get all root entities (entities that have children but no parent).
100
107
  * @returns Readonly array of root entity IDs
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- var l=((j)=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(j,{get:($,G)=>(typeof require<"u"?require:$)[G]}):j)(function(j){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+j+'" is not supported')});class M{parentMap=new Map;childrenMap=new Map;setParent(j,$){if(j===$)throw Error(`Cannot set entity ${j} as its own parent`);if(this.wouldCreateCycle(j,$))throw Error("Cannot set parent: would create circular reference");let G=this.parentMap.get(j);if(G!==void 0){let X=this.childrenMap.get(G);if(X){let Y=X.indexOf(j);if(Y!==-1)X.splice(Y,1)}}this.parentMap.set(j,$);let J=this.childrenMap.get($);if(J)J.push(j);else this.childrenMap.set($,[j]);return this}removeParent(j){let $=this.parentMap.get(j);if($===void 0)return!1;let G=this.childrenMap.get($);if(G){let J=G.indexOf(j);if(J!==-1)G.splice(J,1)}return this.parentMap.delete(j),!0}getParent(j){return this.parentMap.get(j)??null}getChildren(j){let $=this.childrenMap.get(j);return $?[...$]:[]}getChildAt(j,$){if($<0)return null;let G=this.childrenMap.get(j);if(!G||$>=G.length)return null;return G[$]??null}getChildIndex(j,$){let G=this.childrenMap.get(j);if(!G)return-1;return G.indexOf($)}removeEntity(j){let $=this.parentMap.get(j)??null;if($!==null){let X=this.childrenMap.get($);if(X){let Y=X.indexOf(j);if(Y!==-1)X.splice(Y,1)}}this.parentMap.delete(j);let G=this.childrenMap.get(j)??[],J=[...G];for(let X of G)this.parentMap.delete(X);return this.childrenMap.delete(j),{oldParent:$,orphanedChildren:J}}getAncestors(j){let $=[],G=this.parentMap.get(j);while(G!==void 0)$.push(G),G=this.parentMap.get(G);return $}getDescendants(j){let $=[],G=this.childrenMap.get(j);if(!G)return $;let J=G.slice().reverse();while(J.length>0){let X=J.pop();$.push(X);let Y=this.childrenMap.get(X);if(Y)for(let Z=Y.length-1;Z>=0;Z--)J.push(Y[Z])}return $}getRoot(j){let $=j,G=this.parentMap.get($);while(G!==void 0)$=G,G=this.parentMap.get($);return $}getSiblings(j){let $=this.parentMap.get(j);if($===void 0)return[];let G=this.childrenMap.get($);if(!G)return[];return G.filter((J)=>J!==j)}isDescendantOf(j,$){if(j===$)return!1;let G=this.parentMap.get(j);while(G!==void 0){if(G===$)return!0;G=this.parentMap.get(G)}return!1}isAncestorOf(j,$){return this.isDescendantOf($,j)}getRootEntities(){let j=[];for(let $ of this.childrenMap.keys())if(!this.parentMap.has($))j.push($);return j}wouldCreateCycle(j,$){let G=$;while(G!==void 0){if(G===j)return!0;G=this.parentMap.get(G)}return!1}forEachInHierarchy(j,$){let G=$?.roots??this.getRootEntities(),J=[];for(let X of G)J.push({entityId:X,parentId:null,depth:0});for(let X of J){j(X.entityId,X.parentId,X.depth);let Y=this.childrenMap.get(X.entityId);if(Y)for(let Z of Y)J.push({entityId:Z,parentId:X.entityId,depth:X.depth+1})}}*hierarchyIterator(j){let $=j?.roots??this.getRootEntities(),G=[];for(let J of $)G.push({entityId:J,parentId:null,depth:0});for(let J of G){yield J;let X=this.childrenMap.get(J.entityId);if(X)for(let Y of X)G.push({entityId:Y,parentId:J.entityId,depth:J.depth+1})}}}class T{callbacks=[];_iterDepth=0;_pendingRemovals=[];add(j){this.callbacks.push(j)}remove(j){if(this._iterDepth>0){this._pendingRemovals.push(j);return}let $=this.callbacks.indexOf(j);if($!==-1)this.callbacks.splice($,1)}invoke(j){this._iterDepth++;let $=this.callbacks.length;for(let G=0;G<$;G++){let J=this.callbacks[G];if(J)J(j)}if(this._iterDepth--,this._iterDepth===0&&this._pendingRemovals.length>0){for(let G of this._pendingRemovals){let J=this.callbacks.indexOf(G);if(J!==-1)this.callbacks.splice(J,1)}this._pendingRemovals.length=0}}}class H{nextId=1;entities=new Map;componentIndices=new Map;addedCallbacks=new Map;removedCallbacks=new Map;hierarchyManager=new M;disposeCallbacks=new Map;changeSeqs=new Map;_changeSeq=0;_afterComponentAddedHooks=[];_afterEntityMutatedHooks=[];_afterComponentRemovedHooks=[];_beforeEntityRemovedHooks=[];_afterParentChangedHooks=[];_batchingDepth=0;_batchedEntityIds=new Set;_pendingBatchKeys=null;get entityCount(){return this.entities.size}createEntity(){let j=this.nextId++,$={id:j,components:{}};return this.entities.set(j,$),$}registerDispose(j,$){this.disposeCallbacks.set(j,$)}getDisposeCallbacks(){return this.disposeCallbacks}invokeDispose(j,$,G){let J=this.disposeCallbacks.get(j);if(!J)return;try{J({value:$,entityId:G})}catch(X){console.warn(`Component dispose callback for '${String(j)}' threw:`,X)}}addComponent(j,$,G){let J=this.entities.get(j);if(!J)throw Error(`Cannot add component '${String($)}': Entity with ID ${j} does not exist`);let X=J.components[$];if(X!==void 0)this.invokeDispose($,X,J.id);if(J.components[$]=G,!this.componentIndices.has($))this.componentIndices.set($,new Set);this.componentIndices.get($)?.add(J.id);let Y=this.addedCallbacks.get($);if(Y)Y.invoke({value:G,entity:J});this._batchingDepth++;for(let Z of this._afterComponentAddedHooks)Z(J.id,$);if(this._batchedEntityIds.add(J.id),this._batchingDepth--,this._batchingDepth===0){for(let Z of this._batchedEntityIds)for(let F of this._afterEntityMutatedHooks)F(Z);this._batchedEntityIds.clear()}return this}addComponents(j,$){let G=this.entities.get(j);if(!G)throw Error(`Cannot add components: Entity with ID ${j} does not exist`);let J=this._pendingBatchKeys;this._pendingBatchKeys=new Set(Object.keys($)),this._batchingDepth++;for(let X in $)this.addComponent(G.id,X,$[X]);if(this._batchingDepth--,this._pendingBatchKeys=J,this._batchingDepth===0){for(let X of this._batchedEntityIds)for(let Y of this._afterEntityMutatedHooks)Y(X);this._batchedEntityIds.clear()}return this}removeComponent(j,$){let G=this.entities.get(j);if(!G)throw Error(`Cannot remove component '${String($)}': Entity with ID ${j} does not exist`);let J=G.components[$];if(J!==void 0)this.invokeDispose($,J,G.id);delete G.components[$];let X=this.removedCallbacks.get($);if(X&&J!==void 0)X.invoke({value:J,entity:G});if(this.componentIndices.get($)?.delete(G.id),J!==void 0)for(let Y of this._afterComponentRemovedHooks)Y(G.id,$);return this}getComponent(j,$){let G=this.entities.get(j);if(!G)throw Error(`Cannot get component '${String($)}': Entity with ID ${j} does not exist`);return G.components[$]}getEntitiesWithQuery(j=[],$=[],G,J,X){return this.getEntitiesWithQueryInto([],j,$,G,J,X)}getEntitiesWithQueryInto(j,$=[],G=[],J,X,Y){j.length=0;let Z=J!==void 0&&J.length>0&&X!==void 0,F=Y!==void 0&&Y.length>0;if($.length===0){if(G.length===0&&!Z&&!F){for(let D of this.entities.values())j.push(D);return j}for(let D of this.entities.values()){if(G.length>0&&!G.every((L)=>!(L in D.components)))continue;if(Z){let L=this.changeSeqs.get(D.id);if(!L)continue;if(!J.some((B)=>(L.get(B)??-1)>X))continue}if(F&&!this.parentHasComponents(D.id,Y))continue;j.push(D)}return j}let A=$[0];if(A===void 0)return j;let O=$.reduce((D,L)=>{let B=this.componentIndices.get(L)?.size??0,Q=this.componentIndices.get(D)?.size??1/0;return B<Q?L:D},A),W=this.componentIndices.get(O);if(!W||W.size===0)return j;let _=G.length>0;for(let D of W){let L=this.entities.get(D);if(L&&$.every((B)=>(B in L.components))&&(!_||G.every((B)=>!(B in L.components)))){if(Z){let B=this.changeSeqs.get(D);if(!B||!J.some((Q)=>(B.get(Q)??-1)>X))continue}if(F&&!this.parentHasComponents(D,Y))continue;j.push(L)}}return j}parentHasComponents(j,$){let G=this.hierarchyManager.getParent(j);if(G===null)return!1;let J=this.entities.get(G);if(!J)return!1;for(let X of $)if(!(X in J.components))return!1;return!0}removeEntity(j,$){let G=this.entities.get(j);if(!G)return!1;if($?.cascade??!0){let X=this.hierarchyManager.getDescendants(G.id);for(let Y=X.length-1;Y>=0;Y--){let Z=X[Y];if(Z===void 0)continue;for(let F of this._beforeEntityRemovedHooks)F(Z)}for(let Y of this._beforeEntityRemovedHooks)Y(G.id);for(let Y=X.length-1;Y>=0;Y--){let Z=X[Y];if(Z===void 0)continue;this.removeEntityInternal(Z)}}else for(let X of this._beforeEntityRemovedHooks)X(G.id);return this.removeEntityInternal(G.id)}removeEntityInternal(j){let $=this.entities.get(j);if(!$)return!1;this.hierarchyManager.removeEntity(j);for(let G of Object.keys($.components)){let J=$.components[G];if(J!==void 0){this.invokeDispose(G,J,$.id);let X=this.removedCallbacks.get(G);if(X)X.invoke({value:J,entity:$})}this.componentIndices.get(G)?.delete($.id)}return this.changeSeqs.delete($.id),this.entities.delete($.id)}getEntity(j){return this.entities.get(j)}onComponentAdded(j,$){let G=$,J=this.addedCallbacks.get(j);if(!J)J=new T,this.addedCallbacks.set(j,J);return J.add(G),()=>{this.addedCallbacks.get(j)?.remove(G)}}onComponentRemoved(j,$){let G=$,J=this.removedCallbacks.get(j);if(!J)J=new T,this.removedCallbacks.set(j,J);return J.add(G),()=>{this.removedCallbacks.get(j)?.remove(G)}}onAfterComponentAdded(j){return this._afterComponentAddedHooks.push(j),()=>{let $=this._afterComponentAddedHooks.indexOf(j);if($!==-1)this._afterComponentAddedHooks.splice($,1)}}onAfterEntityMutated(j){return this._afterEntityMutatedHooks.push(j),()=>{let $=this._afterEntityMutatedHooks.indexOf(j);if($!==-1)this._afterEntityMutatedHooks.splice($,1)}}onAfterComponentRemoved(j){return this._afterComponentRemovedHooks.push(j),()=>{let $=this._afterComponentRemovedHooks.indexOf(j);if($!==-1)this._afterComponentRemovedHooks.splice($,1)}}onBeforeEntityRemoved(j){return this._beforeEntityRemovedHooks.push(j),()=>{let $=this._beforeEntityRemovedHooks.indexOf(j);if($!==-1)this._beforeEntityRemovedHooks.splice($,1)}}onAfterParentChanged(j){return this._afterParentChangedHooks.push(j),()=>{let $=this._afterParentChangedHooks.indexOf(j);if($!==-1)this._afterParentChangedHooks.splice($,1)}}get changeSeq(){return this._changeSeq}markChanged(j,$){let G=++this._changeSeq,J=this.changeSeqs.get(j);if(!J)J=new Map,this.changeSeqs.set(j,J);J.set($,G)}getChangeSeq(j,$){return this.changeSeqs.get(j)?.get($)??-1}spawnChild(j,$){let G=this.createEntity();return this.addComponents(G.id,$),this.setParent(G.id,j),G}setParent(j,$){this.hierarchyManager.setParent(j,$);for(let G of this._afterParentChangedHooks)G(j);return this}removeParent(j){let $=this.hierarchyManager.removeParent(j);if($)for(let G of this._afterParentChangedHooks)G(j);return $}getParent(j){return this.hierarchyManager.getParent(j)}getChildren(j){return this.hierarchyManager.getChildren(j)}getChildAt(j,$){return this.hierarchyManager.getChildAt(j,$)}getChildIndex(j,$){return this.hierarchyManager.getChildIndex(j,$)}getAncestors(j){return this.hierarchyManager.getAncestors(j)}getDescendants(j){return this.hierarchyManager.getDescendants(j)}getRoot(j){return this.hierarchyManager.getRoot(j)}getSiblings(j){return this.hierarchyManager.getSiblings(j)}isDescendantOf(j,$){return this.hierarchyManager.isDescendantOf(j,$)}isAncestorOf(j,$){return this.hierarchyManager.isAncestorOf(j,$)}getRootEntities(){return this.hierarchyManager.getRootEntities()}forEachInHierarchy(j,$){this.hierarchyManager.forEachInHierarchy(j,$)}hierarchyIterator(j){return this.hierarchyManager.hierarchyIterator(j)}}class V{handlers=new Map;subscribe(j,$){return this.addHandler(j,$,!1)}once(j,$){return this.addHandler(j,$,!0)}unsubscribe(j,$){let G=this.handlers.get(j);if(!G)return!1;let J=G.findIndex((X)=>X.callback===$);if(J===-1)return!1;return G.splice(J,1),!0}addHandler(j,$,G){let J=this.handlers.get(j);if(!J)J=[],this.handlers.set(j,J);let X={callback:$,once:G};return J.push(X),()=>{let Y=this.handlers.get(j);if(Y){let Z=Y.indexOf(X);if(Z!==-1)Y.splice(Z,1)}}}publish(...[j,$]){let G=this.handlers.get(j);if(!G||G.length===0)return;let J=!1,X=G.length;for(let Y=0;Y<X&&Y<G.length;Y++){let Z=G[Y];if(!Z)continue;if(Z.callback($),Z.once)J=!0}if(J){for(let Y=G.length-1;Y>=0;Y--)if(G[Y]?.once)G.splice(Y,1)}}clear(){this.handlers.clear()}clearEvent(j){this.handlers.delete(j)}}var x=Symbol("resource-direct");function I(j){return{[x]:j}}function u(j){return typeof j==="object"&&j!==null&&"factory"in j&&typeof j.factory==="function"}function m(j){return typeof j==="object"&&j!==null&&x in j}function f(j,$){let G=[],J=new Set,X=new Set;function Y(Z,F=[]){if(J.has(Z))return;if(X.has(Z))throw Error(`Circular resource dependency: ${[...F,Z].join(" -> ")}`);X.add(Z);for(let A of $(Z)){let O=j.find((W)=>W===A);if(O)Y(O,[...F,Z])}X.delete(Z),J.add(Z),G.push(Z)}for(let Z of j)Y(Z);return G}class E{resources=new Map;resourceFactories=new Map;resourceDependencies=new Map;resourceDisposers=new Map;initializedResourceKeys=new Set;_changeSubscribers=new Map;add(j,$){let G=(J)=>{this.resources.set(j,J),this.initializedResourceKeys.add(j),this.resourceDependencies.set(j,[])};if(u($)){if(this.resourceFactories.set(j,$.factory),this.resourceDependencies.set(j,$.dependsOn??[]),$.onDispose)this.resourceDisposers.set(j,$.onDispose)}else if(m($))G($[x]);else if(typeof $==="function")this.resourceFactories.set(j,$),this.resourceDependencies.set(j,[]);else G($);return this}tryGet(j,...$){if(!this.has(j))return;return this.get(j,...$)}get(j,...$){let G=this.resources.get(j);if(G!==void 0)return G;let J=this.resourceFactories.get(j);if(J===void 0)throw Error(`Resource ${String(j)} not found`);let X=$[0],Y=J(X);if(!(Y instanceof Promise))this.resources.set(j,Y),this.initializedResourceKeys.add(j);return Y}has(j){return this.resources.has(j)||this.resourceFactories.has(j)}remove(j){let $=this.resources.delete(j),G=this.resourceFactories.delete(j);return this.resourceDependencies.delete(j),this.resourceDisposers.delete(j),this.initializedResourceKeys.delete(j),$||G}getKeys(){let j=new Set([...this.resources.keys(),...this.resourceFactories.keys()]);return Array.from(j)}needsInitialization(j){return this.resourceFactories.has(j)&&!this.initializedResourceKeys.has(j)}getPendingInitializationKeys(){return Array.from(this.resourceFactories.keys()).filter((j)=>!this.initializedResourceKeys.has(j))}async initializeResource(j,...$){if(!this.resourceFactories.has(j)||this.initializedResourceKeys.has(j))return;let G=this.resourceFactories.get(j);if(!G)return;let J=$[0],X=await G(J);this.resources.set(j,X),this.initializedResourceKeys.add(j),this.resourceFactories.delete(j)}async initializeResources(...j){let $=j.slice(1),G=$.length===0?this.getPendingInitializationKeys():$;if(G.length===0)return;let J=f(G,(X)=>[...this.resourceDependencies.get(X)??[]]);for(let X of J)await this.initializeResource(X,...j.slice(0,1))}getDependencies(j){return this.resourceDependencies.get(j)??[]}async disposeResource(j,...$){if(!this.resources.has(j)&&!this.resourceFactories.has(j))return!1;if(this.initializedResourceKeys.has(j)){let G=this.resourceDisposers.get(j),J=this.resources.get(j);if(G&&J!==void 0){let X=$[0];await G(J,X)}}return this.resources.delete(j),this.resourceFactories.delete(j),this.resourceDependencies.delete(j),this.resourceDisposers.delete(j),this.initializedResourceKeys.delete(j),this._changeSubscribers.delete(j),!0}onResourceChange(j,$){let G=this._changeSubscribers.get(j),J=G??new Set;if(!G)this._changeSubscribers.set(j,J);let X=$;return J.add(X),()=>{if(J.delete(X),J.size===0)this._changeSubscribers.delete(j)}}notifyChange(j,$,G){if(Object.is($,G))return;let J=this._changeSubscribers.get(j);if(!J||J.size===0)return;let X=[...J];for(let Y of X)Y($,G)}async disposeResources(...j){let $=Array.from(this.initializedResourceKeys);if($.length===0)return;let G=f($,(J)=>[...this.resourceDependencies.get(J)??[]]).reverse();for(let J of G)await this.disposeResource(J,...j)}}class R{queries=new Map;entityManager;_hasParentHasQueries=!1;constructor(j){this.entityManager=j}get hasParentHasQueries(){return this._hasParentHasQueries}addQuery(j,$){let G={definition:$,matchingEntities:new Set};if(this.queries.set(j,G),$.parentHas?.length)this._hasParentHasQueries=!0;let J=this.entityManager.getEntitiesWithQuery($.with,$.without??[]);for(let X of J)if(this.entityMatchesQuery(X,G.definition))G.matchingEntities.add(X.id),G.definition.onEnter?.(X)}removeQuery(j){let $=this.queries.delete(j);if($)this._recalcParentHasFlag();return $}entityMatchesQuery(j,$){for(let G of $.with)if(!(G in j.components))return!1;if($.without){for(let G of $.without)if(G in j.components)return!1}if($.parentHas?.length){let G=this.entityManager.getParent(j.id);if(G===null)return!1;let J=this.entityManager.getEntity(G);if(!J)return!1;for(let X of $.parentHas)if(!(X in J.components))return!1}return!0}_applyQueryTransition(j,$){let G=$.matchingEntities.has(j.id),J=this.entityMatchesQuery(j,$.definition);if(!G&&J)$.matchingEntities.add(j.id),$.definition.onEnter?.(j);else if(G&&!J)$.matchingEntities.delete(j.id),$.definition.onExit?.(j.id)}onComponentAdded(j,$){for(let[,G]of this.queries)this._applyQueryTransition(j,G);if(this._hasParentHasQueries)this._recheckChildren(j.id)}onComponentRemoved(j,$){for(let[,G]of this.queries)this._applyQueryTransition(j,G);if(this._hasParentHasQueries)this._recheckChildren(j.id)}onEntityRemoved(j){for(let[$,G]of this.queries)if(G.matchingEntities.has(j))G.matchingEntities.delete(j),G.definition.onExit?.(j)}recheckEntity(j){for(let[,$]of this.queries)this._applyQueryTransition(j,$)}recheckEntityAndChildren(j){if(this.recheckEntity(j),this._hasParentHasQueries)this._recheckChildren(j.id)}_recheckChildren(j){let $=this.entityManager.getChildren(j);for(let G of $){let J=this.entityManager.getEntity(G);if(J)this.recheckEntity(J)}}_recalcParentHasFlag(){this._hasParentHasQueries=!1;for(let[,j]of this.queries)if(j.definition.parentHas?.length){this._hasParentHasQueries=!0;return}}}class w{commands=[];removeEntity(j,$){this.commands.push((G)=>{G.removeEntity(j,$)})}addComponent(j,$,G){this.commands.push((J)=>{J.addComponent(j,$,G)})}removeComponent(j,$){this.commands.push((G)=>{G.removeComponent(j,$)})}spawn(j){this.commands.push(($)=>{$.spawn(j)})}spawnChild(j,$){this.commands.push((G)=>{G.spawnChild(j,$)})}addComponents(j,$){this.commands.push((G)=>{G.addComponents(j,$)})}setParent(j,$){this.commands.push((G)=>{G.setParent(j,$)})}mutateComponent(j,$,G){this.commands.push((J)=>{J.mutateComponent(j,$,G)})}markChanged(j,$){this.commands.push((G)=>{G.markChanged(j,$)})}removeParent(j){this.commands.push(($)=>{$.removeParent(j)})}playback(j){for(let $ of this.commands)try{$(j)}catch(G){console.warn("CommandBuffer: Command failed during playback:",G)}this.commands.length=0}clear(){this.commands.length=0}get length(){return this.commands.length}}class b{_id;constructor(j){this._id=j}withComponentTypes(){return this}withEventTypes(){return this}withResourceTypes(){return this}withAssetTypes(){return this}withScreenTypes(){return this}withLabels(){return this}withGroups(){return this}withAssetGroupNames(){return this}withReactiveQueryNames(){return this}requires(){return this}install(j){return{id:this._id,install:j}}}function P(j){return new b(j)}class S{_label;queries={};processFunction;detachFunction;initializeFunction;eventHandlers;_priority=0;_phase="update";_groups=[];_inScreens;_excludeScreens;_requiredAssets;_runWhenEmpty=!1;_entityEnterHandlers={};_resourceKeys;constructor(j){this._label=j}get label(){return this._label}_createSystemObject(){let j={label:this._label,entityQueries:this.queries,priority:this._priority,phase:this._phase};if(this.processFunction)j.process=this.processFunction;if(this.detachFunction)j.onDetach=this.detachFunction;if(this.initializeFunction)j.onInitialize=this.initializeFunction;if(this.eventHandlers)j.eventHandlers=this.eventHandlers;if(this._groups.length>0)j.groups=[...this._groups];if(this._inScreens)j.inScreens=this._inScreens;if(this._excludeScreens)j.excludeScreens=this._excludeScreens;if(this._requiredAssets)j.requiredAssets=this._requiredAssets;if(this._runWhenEmpty)j.runWhenEmpty=!0;if(Object.keys(this._entityEnterHandlers).length>0)j.onEntityEnter={...this._entityEnterHandlers};return j}setPriority(j){return this._priority=j,this}inPhase(j){return this._phase=j,this}inGroup(j){if(!this._groups.includes(j))this._groups.push(j);return this}inScreens(j){return this._inScreens=[...j],this}excludeScreens(j){return this._excludeScreens=[...j],this}requiresAssets(j){return this._requiredAssets=[...j],this}runWhenEmpty(){return this._runWhenEmpty=!0,this}withResources(j){return this._resourceKeys=[...j],this}addQuery(j,$){let G=this;return G.queries={...this.queries,[j]:$},G}setProcess(j){if(this._resourceKeys?.length){let $=this._resourceKeys,G;this.processFunction=(J)=>{if(!G){G={};for(let X of $)G[X]=J.ecs.getResource(X)}J.resources=G,j(J)}}else this.processFunction=j;return this}setOnEntityEnter(j,$){return this._entityEnterHandlers[j]=$,this}setOnDetach(j){return this.detachFunction=j,this}setOnInitialize(j){return this.initializeFunction=j,this}setEventHandlers(j){return this.eventHandlers=j,this}}function g(j,$,G){let J=new Set,X=[$];while(X.length>0){let Y=X.pop();if(Y===void 0)break;if(Y===j)throw Error(`Circular required component dependency: '${String(j)}' -> '${String($)}' -> ... -> '${String(j)}'`);if(J.has(Y))continue;J.add(Y);let Z=G(Y);if(Z)for(let F of Z)X.push(F.component)}}var N="0.13.3";class U{assets=new Map;groups=new Map;eventBus=null;setEventBus(j){this.eventBus=j}register(j,$){if(this.assets.set(j,{definition:$,status:"pending"}),$.group){let G=this.groups.get($.group)??new Set;G.add(j),this.groups.set($.group,G)}}async loadEagerAssets(){let j=[];for(let[$,G]of this.assets)if(G.definition.eager&&G.status==="pending")j.push($);await Promise.all(j.map(($)=>this.loadAsset($)))}async loadAsset(j){let $=this.assets.get(j);if(!$)throw Error(`Asset '${String(j)}' not found`);if($.status==="loaded"&&$.value!==void 0)return $.value;if($.status==="loading"&&$.loadPromise)return $.loadPromise;if($.status==="failed")$.status="pending";$.status="loading",$.loadPromise=$.definition.loader();try{let G=await $.loadPromise;return $.value=G,$.status="loaded",$.loadPromise=void 0,this.eventBus?.publish("assetLoaded",{key:j}),this.checkGroupProgress($.definition.group),G}catch(G){let J=G instanceof Error?G:Error(String(G));throw $.status="failed",$.error=J,$.loadPromise=void 0,this.eventBus?.publish("assetFailed",{key:j,error:J}),J}}async loadAssetGroup(j){let $=this.groups.get(j);if(!$||$.size===0)throw Error(`Asset group '${j}' not found or empty`);await Promise.all(Array.from($).map((G)=>this.loadAsset(G)))}get(j){let $=this.assets.get(j);if(!$)throw Error(`Asset '${String(j)}' not found`);if($.status!=="loaded"||$.value===void 0)throw Error(`Asset '${String(j)}' is not loaded (status: ${$.status})`);return $.value}tryGet(j){let $=this.assets.get(j);if(!$||$.status!=="loaded")return;return $.value}getHandle(j){let $=this.assets.get(j);if(!$)throw Error(`Asset '${String(j)}' not found`);let G=this;return{get status(){return $.status},get isLoaded(){return $.status==="loaded"},get(){return G.get(j)},tryGet(){return G.tryGet(j)}}}getStatus(j){let $=this.assets.get(j);if(!$)throw Error(`Asset '${String(j)}' not found`);return $.status}isLoaded(j){return this.assets.get(j)?.status==="loaded"}isGroupLoaded(j){let $=this.groups.get(j);if(!$||$.size===0)return!1;for(let G of $){let J=this.assets.get(G);if(!J||J.status!=="loaded")return!1}return!0}getGroupProgress(j){return this.getGroupProgressDetails(j).progress}getGroupProgressDetails(j){let $=this.groups.get(j);if(!$||$.size===0)return{loaded:0,total:0,progress:0};let G=0;for(let X of $)if(this.assets.get(X)?.status==="loaded")G++;let J=$.size;return{loaded:G,total:J,progress:G/J}}checkGroupProgress(j){if(!j||!this.eventBus)return;let $=j,G=this.getGroupProgressDetails($);if(this.eventBus.publish("assetGroupProgress",{group:$,...G}),G.loaded===G.total)this.eventBus.publish("assetGroupLoaded",{group:$})}createResource(){let j=this;return{getStatus($){return j.getStatus($)},isLoaded($){return j.isLoaded($)},isGroupLoaded($){return j.isGroupLoaded($)},getGroupProgress($){return j.getGroupProgress($)},get($){return j.get($)},tryGet($){return j.tryGet($)},getHandle($){return j.getHandle($)}}}getKeys(){return Array.from(this.assets.keys())}getGroupNames(){return Array.from(this.groups.keys())}getGroupKeys(j){let $=this.groups.get(j);return $?Array.from($):[]}}class h{manager;constructor(j){this.manager=j}add(j,$){return this.manager.register(j,{loader:$,eager:!0}),this}addWithConfig(j,$){return this.manager.register(j,$),this}addGroup(j,$){for(let[G,J]of Object.entries($))this.manager.register(G,{loader:J,eager:!1,group:j});return this}getManager(){return this.manager}}function C(j){return new h(j??new U)}class K{screens=new Map;currentScreen=null;screenStack=[];eventBus=null;assetManager=null;ecs=null;setDependencies(j,$,G){this.eventBus=j,this.assetManager=$,this.ecs=G}requireEcs(){if(!this.ecs)throw Error("ScreenManager: dependencies not set. Call setDependencies() first.");return this.ecs}register(j,$){this.screens.set(j,{definition:$})}async setScreen(j,$){let G=this.screens.get(j);if(!G)throw Error(`Screen '${String(j)}' not found`);await this.verifyRequiredAssets(G.definition.requiredAssets,G.definition.requiredAssetGroups);while(this.screenStack.length>0){let X=this.screenStack.pop();if(X)await this.exitScreen(X.name)}if(this.currentScreen)await this.exitScreen(this.currentScreen.name);let J=G.definition.initialState($);this.currentScreen={name:j,config:$,state:J},await G.definition.onEnter?.({config:$,ecs:this.requireEcs()}),this.eventBus?.publish("screenEnter",{screen:j,config:$})}async pushScreen(j,$){let G=this.screens.get(j);if(!G)throw Error(`Screen '${String(j)}' not found`);if(await this.verifyRequiredAssets(G.definition.requiredAssets,G.definition.requiredAssetGroups),this.currentScreen)this.screenStack.push(this.currentScreen);let J=G.definition.initialState($);this.currentScreen={name:j,config:$,state:J},await G.definition.onEnter?.({config:$,ecs:this.requireEcs()}),this.eventBus?.publish("screenPush",{screen:j,config:$})}async popScreen(){if(this.screenStack.length===0)throw Error("Cannot pop screen: stack is empty");if(this.currentScreen)await this.exitScreen(this.currentScreen.name),this.eventBus?.publish("screenPop",{screen:this.currentScreen.name});this.currentScreen=this.screenStack.pop()??null}async exitScreen(j){let $=this.screens.get(j);if($?.definition.onExit)await $.definition.onExit(this.requireEcs());this.eventBus?.publish("screenExit",{screen:j})}async verifyRequiredAssets(j,$){if(!this.assetManager)return;if(j){for(let G of j)if(!this.assetManager.isLoaded(G))await this.assetManager.loadAsset(G)}if($){for(let G of $)if(!this.assetManager.isGroupLoaded(G))await this.assetManager.loadAssetGroup(G)}}getCurrentScreen(){return this.currentScreen?.name??null}getConfig(j){if(!this.currentScreen)throw Error("No current screen");if(j!==void 0&&this.currentScreen.name!==j)throw Error(`Expected current screen '${String(j)}', but current is '${String(this.currentScreen.name)}'`);return this.currentScreen.config}tryGetConfig(j){if(!this.currentScreen)return;if(j!==void 0&&this.currentScreen.name!==j)return;return this.currentScreen.config}getState(j){if(!this.currentScreen)throw Error("No current screen");if(j!==void 0&&this.currentScreen.name!==j)throw Error(`Expected current screen '${String(j)}', but current is '${String(this.currentScreen.name)}'`);return this.currentScreen.state}tryGetState(j){if(!this.currentScreen)return;if(j!==void 0&&this.currentScreen.name!==j)return;return this.currentScreen.state}updateState(j,$){if(!this.currentScreen)throw Error("No current screen");if($!==void 0&&this.currentScreen.name!==$)throw Error(`Expected current screen '${String($)}', but current is '${String(this.currentScreen.name)}'`);let G=typeof j==="function"?j(this.currentScreen.state):j;this.currentScreen.state={...this.currentScreen.state,...G}}getStackDepth(){return this.screenStack.length}isOverlay(){return this.screenStack.length>0}isActive(j){if(this.currentScreen?.name===j)return!0;return this.screenStack.some(($)=>$.name===j)}isCurrent(j){return this.currentScreen?.name===j}createResource(){let j=this;return{get current(){return j.getCurrentScreen()},get config(){return j.tryGetConfig()??null},get state(){return j.tryGetState()??null},set state($){if(j.currentScreen&&$!==null)j.currentScreen.state=$},get stack(){return j.screenStack},get isOverlay(){return j.isOverlay()},get stackDepth(){return j.getStackDepth()},isActive($){return j.isActive($)},isCurrent($){return j.isCurrent($)}}}getScreenNames(){return Array.from(this.screens.keys())}hasScreen(j){return this.screens.has(j)}}class k{manager;constructor(j){this.manager=j}add(j,$){return this.manager.register(j,$),this}getManager(){return this.manager}}function q(j){return new k(j??new K)}class v{assetConfigurator=null;screenConfigurator=null;pendingResources=[];pendingDisposeCallbacks=[];pendingRequiredComponents=[];pendingPlugins=[];_fixedDt=null;constructor(){}withPlugin(j){return this.pendingPlugins.push(j),this}withComponentTypes(){return this}withEventTypes(){return this}withResourceTypes(){return this}withResource(j,$){return this.pendingResources.push({key:j,value:$}),this}withDispose(j,$){return this.pendingDisposeCallbacks.push({key:j,callback:$}),this}withRequired(j,$,G){return this.pendingRequiredComponents.push({trigger:j,required:$,factory:G}),this}withAssets(j){let $=C();return j($),this.assetConfigurator=$,this}withScreens(j){let $=q();return j($),this.screenConfigurator=$,this}withFixedTimestep(j){return this._fixedDt=j,this}withReactiveQueryNames(){return this}pluginFactory(){return(j)=>P(j.id).install(j.install)}build(){let j=new z;for(let $ of this.pendingPlugins)j.installPlugin($);for(let{key:$,value:G}of this.pendingResources)j.addResource($,G);for(let{key:$,callback:G}of this.pendingDisposeCallbacks)j.registerDispose($,G);for(let{trigger:$,required:G,factory:J}of this.pendingRequiredComponents)j.registerRequired($,G,J);if(this.assetConfigurator)j._setAssetManager(this.assetConfigurator.getManager());else if(j._hasPendingPluginAssets())j._setAssetManager(new U);if(this.screenConfigurator)j._setScreenManager(this.screenConfigurator.getManager());else if(j._hasPendingPluginScreens())j._setScreenManager(new K);if(this._fixedDt!==null)j._setFixedDt(this._fixedDt);return j}}var p=["preUpdate","fixedUpdate","update","postUpdate","render"];class z{static VERSION=N;_entityManager;_eventBus;_resourceManager;_commandBuffer;_systems=[];_phaseSystems={preUpdate:[],fixedUpdate:[],update:[],postUpdate:[],render:[]};_installedPlugins=new Set;_disabledGroups=new Set;_assetManager=null;_screenManager=null;_reactiveQueryManager;_postUpdateHooks=[];_currentTick=0;_systemLastSeqs=new Map;_changeThreshold=0;_fixedDt=0.016666666666666666;_fixedAccumulator=0;_interpolationAlpha=0;_maxFixedSteps=8;_requiredComponents=new Map;_pendingPluginAssets=[];_pendingPluginScreens=[];_diagnosticsEnabled=!1;_systemTimings=new Map;_phaseTimings={preUpdate:0,fixedUpdate:0,update:0,postUpdate:0,render:0};_entityEnterTracking=new Map;_entityEnterFrameSet=new Set;_systemContexts=new WeakMap;_pendingFinalizers=[];_batchingRegistrations=!1;constructor(){this._entityManager=new H,this._eventBus=new V,this._resourceManager=new E,this._reactiveQueryManager=new R(this._entityManager),this._commandBuffer=new w,this._subscribeLifecycleHooks()}_subscribeLifecycleHooks(){this._entityManager.onAfterComponentAdded((j,$)=>{this._entityManager.markChanged(j,$);let G=this._requiredComponents.get($);if(G){let J=this._entityManager.getEntity(j);if(J){let X=J.components[$];for(let{component:Y,factory:Z}of G){if(this._entityManager._pendingBatchKeys?.has(Y))continue;if(!(Y in J.components))this._entityManager.addComponent(j,Y,Z(X))}}}}),this._entityManager.onAfterEntityMutated((j)=>{let $=this._entityManager.getEntity(j);if($)this._reactiveQueryManager.recheckEntityAndChildren($)}),this._entityManager.onAfterComponentRemoved((j,$)=>{let G=this._entityManager.getEntity(j);if(G)this._reactiveQueryManager.onComponentRemoved(G,$)}),this._entityManager.onBeforeEntityRemoved((j)=>{this._reactiveQueryManager.onEntityRemoved(j)}),this._entityManager.onAfterParentChanged((j)=>{if(this._reactiveQueryManager.hasParentHasQueries){let $=this._entityManager.getEntity(j);if($)this._reactiveQueryManager.recheckEntity($)}})}static create(){return new v}addSystem(j){let $=new S(j);return this._pendingFinalizers.push(()=>{this._registerSystem($._createSystemObject())}),$}_finalizePendingBuilders(){if(this._pendingFinalizers.length===0)return;this._batchingRegistrations=!0;while(this._pendingFinalizers.length>0){let j=this._pendingFinalizers;this._pendingFinalizers=[];for(let $ of j)$()}this._batchingRegistrations=!1,this._rebuildPhaseSystems()}update(j){this._finalizePendingBuilders();let $=this._screenManager?.getCurrentScreen()??null,G=this._diagnosticsEnabled;this._runPhase("preUpdate",j,$,G);let J=G?performance.now():0;this._fixedAccumulator+=j;let X=0;while(this._fixedAccumulator>=this._fixedDt&&X<this._maxFixedSteps)this._executePhase(this._phaseSystems.fixedUpdate,this._fixedDt,$),this._commandBuffer.playback(this),this._fixedAccumulator-=this._fixedDt,X++;if(this._fixedAccumulator>=this._fixedDt)this._fixedAccumulator=0;if(G)this._phaseTimings.fixedUpdate=performance.now()-J;this._interpolationAlpha=this._fixedAccumulator/this._fixedDt,this._runPhase("update",j,$,G),this._runPhase("postUpdate",j,$,G);for(let Y of this._postUpdateHooks)Y({ecs:this,dt:j});this._runPhase("render",j,$,G),this._changeThreshold=this._entityManager.changeSeq,this._currentTick++}_executePhase(j,$,G){for(let J of j){if(!J.process&&!J.onEntityEnter)continue;if(J.groups?.length){let W=!1;for(let _ of J.groups)if(this._disabledGroups.has(_)){W=!0;break}if(W)continue}if(J.inScreens?.length){if(G===null||!J.inScreens.includes(G))continue}if(J.excludeScreens?.length){if(G!==null&&J.excludeScreens.includes(G))continue}if(J.requiredAssets?.length&&this._assetManager){let W=!0;for(let _ of J.requiredAssets)if(!this._assetManager.isLoaded(_)){W=!1;break}if(!W)continue}let X=this._systemLastSeqs.get(J)??0;this._changeThreshold=X;let Y=this._systemContexts.get(J);if(!Y)Y={queries:{},dt:0,ecs:this},this._systemContexts.set(J,Y);Y.dt=$;let Z=Y.queries,F=!1,A=!1;if(J.entityQueries)for(let W in J.entityQueries){A=!0;let _=J.entityQueries[W];if(_){let L=Z[W]??(Z[W]=[]);if(this._entityManager.getEntitiesWithQueryInto(L,_.with,_.without||[],_.changed,_.changed?this._changeThreshold:void 0,_.parentHas),L.length)F=!0}}let O=this._entityEnterTracking.get(J);if(O&&J.onEntityEnter)for(let W in J.onEntityEnter){let _=Z[W],D=O.get(W);if(!_||!D)continue;let L=J.onEntityEnter[W];if(!L)continue;let B=this._entityEnterFrameSet;B.clear();for(let Q of _)if(B.add(Q.id),!D.has(Q.id))D.add(Q.id),L({entity:Q,ecs:this});for(let Q of D)if(!B.has(Q))D.delete(Q)}if(J.process){if(this._diagnosticsEnabled){let W=performance.now();if(F||J.runWhenEmpty)J.process(Y);else if(!A)J.process(Y);this._systemTimings.set(J.label,performance.now()-W)}else if(F||J.runWhenEmpty)J.process(Y);else if(!A)J.process(Y)}this._systemLastSeqs.set(J,this._entityManager.changeSeq)}}_runPhase(j,$,G,J){if(J){let X=performance.now();this._executePhase(this._phaseSystems[j],$,G),this._phaseTimings[j]=performance.now()-X}else this._executePhase(this._phaseSystems[j],$,G);this._commandBuffer.playback(this)}async initialize(){if(this._finalizePendingBuilders(),await this.initializeResources(),this._assetManager)this._assetManager.setEventBus(this._eventBus),await this._assetManager.loadEagerAssets(),this._resourceManager.add("$assets",this._assetManager.createResource());if(this._screenManager)this._screenManager.setDependencies(this._eventBus,this._assetManager,this),this._resourceManager.add("$screen",this._screenManager.createResource());for(let j of this._systems)await j.onInitialize?.(this)}async initializeResources(...j){await this._resourceManager.initializeResources(this,...j)}_rebuildPhaseSystems(){for(let j of p)this._phaseSystems[j]=[];for(let j of this._systems){let $=j.phase??"update";this._phaseSystems[$].push(j)}for(let j of p)this._phaseSystems[j].sort(($,G)=>{let J=$.priority??0;return(G.priority??0)-J})}updateSystemPriority(j,$){this._finalizePendingBuilders();let G=this._systems.find((J)=>J.label===j);if(!G)return!1;return G.priority=$,this._rebuildPhaseSystems(),!0}updateSystemPhase(j,$){this._finalizePendingBuilders();let G=this._systems.find((J)=>J.label===j);if(!G)return!1;return G.phase=$,this._rebuildPhaseSystems(),!0}get interpolationAlpha(){return this._interpolationAlpha}get fixedDt(){return this._fixedDt}disableSystemGroup(j){this._disabledGroups.add(j)}enableSystemGroup(j){this._disabledGroups.delete(j)}isSystemGroupEnabled(j){return!this._disabledGroups.has(j)}getSystemsInGroup(j){return this._finalizePendingBuilders(),this._systems.filter(($)=>$.groups?.includes(j)).map(($)=>$.label)}removeSystem(j){this._finalizePendingBuilders();let $=this._systems.findIndex((J)=>J.label===j);if($===-1)return!1;let G=this._systems[$];if(!G)return!1;if(G.onDetach)G.onDetach(this);return this._systems.splice($,1),this._systemLastSeqs.delete(G),this._entityEnterTracking.delete(G),this._rebuildPhaseSystems(),!0}_registerSystem(j){if(this._systems.push(j),this._systemLastSeqs.set(j,this._changeThreshold),!this._batchingRegistrations)this._rebuildPhaseSystems();if(j.onEntityEnter){let $=new Map;for(let G in j.onEntityEnter)$.set(G,new Set);this._entityEnterTracking.set(j,$)}if(!j.eventHandlers)return;for(let $ in j.eventHandlers){let G=j.eventHandlers[$];if(G)this._eventBus.subscribe($,(J)=>{G({data:J,ecs:this})})}}hasResource(j){return this._resourceManager.has(j)}getResource(j){if(!this._resourceManager.has(j))throw Error(`Resource '${String(j)}' not found. Available resources: [${this.getResourceKeys().map(($)=>String($)).join(", ")}]`);return this._resourceManager.get(j,this)}tryGetResource(j){let $=j;if(!this._resourceManager.has($))return;return this._resourceManager.get($,this)}addResource(j,$){return this._resourceManager.add(j,$),this}removeResource(j){return this._resourceManager.remove(j)}async disposeResource(j){return this._resourceManager.disposeResource(j,this)}async disposeResources(){return this._resourceManager.disposeResources(this)}updateResource(j,$){let G=this.getResource(j),J=$(G);return this._resourceManager.add(j,J),this._resourceManager.notifyChange(j,J,G),this}setResource(j,$){let G=this.tryGetResource(j);if(this._resourceManager.add(j,$),G!==void 0)this._resourceManager.notifyChange(j,$,G);return this}onResourceChange(j,$){return this._resourceManager.onResourceChange(j,$)}getResourceKeys(){return this._resourceManager.getKeys()}resourceNeedsInitialization(j){return this._resourceManager.needsInitialization(j)}getEntity(j){return this._entityManager.getEntity(j)}getComponent(j,$){return this._entityManager.getComponent(j,$)}addComponent(j,$,G){this._entityManager.addComponent(j,$,G)}addComponents(j,$){this._entityManager.addComponents(j,$)}removeComponent(j,$){this._entityManager.removeComponent(j,$)}hasComponent(j,$){return this._entityManager.getComponent(j,$)!==void 0}spawn(j){let $=this._entityManager.createEntity();return this._entityManager.addComponents($.id,j),$}getEntitiesWithQuery(j,$=[],G,J){return this._entityManager.getEntitiesWithQuery(j,$,G,G?this._changeThreshold:void 0,J)}getSingleton(j,$=[]){let G=this._entityManager.getEntitiesWithQuery(j,$);if(G.length===0)throw Error(`getSingleton: no entity matches query with=[${String(j)}] without=[${String($)}]`);if(G.length>1)throw Error(`getSingleton: expected 1 entity but found ${G.length} matching query with=[${String(j)}] without=[${String($)}]`);let J=G[0];if(!J)throw Error("getSingleton: unexpected empty result");return J}tryGetSingleton(j,$=[]){let G=this._entityManager.getEntitiesWithQuery(j,$);if(G.length===0)return;if(G.length>1)throw Error(`tryGetSingleton: expected 0 or 1 entity but found ${G.length} matching query with=[${String(j)}] without=[${String($)}]`);return G[0]}removeEntity(j,$){return this._entityManager.removeEntity(j,$)}spawnChild(j,$){let G=this._entityManager.spawnChild(j,$);return this._emitHierarchyChanged(G.id,null,j),G}setParent(j,$){let G=this._entityManager.getParent(j);return this._entityManager.setParent(j,$),this._emitHierarchyChanged(j,G,$),this}removeParent(j){let $=this._entityManager.getParent(j),G=this._entityManager.removeParent(j);if(G)this._emitHierarchyChanged(j,$,null);return G}getParent(j){return this._entityManager.getParent(j)}getChildren(j){return this._entityManager.getChildren(j)}getChildAt(j,$){return this._entityManager.getChildAt(j,$)}getChildIndex(j,$){return this._entityManager.getChildIndex(j,$)}getAncestors(j){return this._entityManager.getAncestors(j)}getDescendants(j){return this._entityManager.getDescendants(j)}getRoot(j){return this._entityManager.getRoot(j)}getSiblings(j){return this._entityManager.getSiblings(j)}isDescendantOf(j,$){return this._entityManager.isDescendantOf(j,$)}isAncestorOf(j,$){return this._entityManager.isAncestorOf(j,$)}getRootEntities(){return this._entityManager.getRootEntities()}forEachInHierarchy(j,$){this._entityManager.forEachInHierarchy(j,$)}hierarchyIterator(j){return this._entityManager.hierarchyIterator(j)}_emitHierarchyChanged(j,$,G){this._eventBus.publish("hierarchyChanged",{entityId:j,oldParent:$,newParent:G})}get installedPlugins(){return Array.from(this._installedPlugins)}get entityManager(){return this._entityManager}get eventBus(){return this._finalizePendingBuilders(),this._eventBus}get commands(){return this._commandBuffer}get currentTick(){return this._currentTick}get changeThreshold(){return this._changeThreshold}enableDiagnostics(j){if(this._diagnosticsEnabled=j,!j)this._systemTimings.clear(),this._phaseTimings={preUpdate:0,fixedUpdate:0,update:0,postUpdate:0,render:0}}get diagnosticsEnabled(){return this._diagnosticsEnabled}get systemTimings(){return this._systemTimings}get phaseTimings(){return this._phaseTimings}get entityCount(){return this._entityManager.entityCount}mutateComponent(j,$,G){let J=this._entityManager.getComponent(j,$);if(J===void 0)throw Error(`Entity ${j} does not have component "${String($)}"`);return G(J),this._entityManager.markChanged(j,$),J}markChanged(j,$){this._entityManager.markChanged(j,$)}registerDispose(j,$){this._entityManager.registerDispose(j,$)}registerRequired(j,$,G){if(String(j)===String($))throw Error(`Cannot require a component to depend on itself: '${String(j)}'`);let J=this._requiredComponents.get(j)??[];if(J.some((X)=>X.component===$))throw Error(`Required component '${String($)}' already registered for trigger '${String(j)}'`);this._checkRequiredCycle(j,$),J.push({component:$,factory:G}),this._requiredComponents.set(j,J)}_checkRequiredCycle(j,$){g(j,$,(G)=>this._requiredComponents.get(G))}onComponentAdded(j,$){return this._entityManager.onComponentAdded(j,$)}onComponentRemoved(j,$){return this._entityManager.onComponentRemoved(j,$)}addReactiveQuery(j,$){this._reactiveQueryManager.addQuery(j,$)}removeReactiveQuery(j){return this._reactiveQueryManager.removeQuery(j)}on(j,$){return this._eventBus.subscribe(j,$)}off(j,$){return this._eventBus.unsubscribe(j,$)}onPostUpdate(j){return this._postUpdateHooks.push(j),()=>{let $=this._postUpdateHooks.indexOf(j);if($!==-1)this._postUpdateHooks.splice($,1)}}requireAssetManager(){if(!this._assetManager)throw Error("Asset manager not configured. Use withAssets() in builder.");return this._assetManager}getAsset(j){return this.requireAssetManager().get(j)}tryGetAsset(j){return this._assetManager?.tryGet(j)}getAssetHandle(j){return this.requireAssetManager().getHandle(j)}isAssetLoaded(j){return this._assetManager?.isLoaded(j)??!1}async loadAsset(j){return this.requireAssetManager().loadAsset(j)}async loadAssetGroup(j){return this.requireAssetManager().loadAssetGroup(j)}isAssetGroupLoaded(j){return this._assetManager?.isGroupLoaded(j)??!1}getAssetGroupProgress(j){return this._assetManager?.getGroupProgress(j)??0}requireScreenManager(){if(!this._screenManager)throw Error("Screen manager not configured. Use withScreens() in builder.");return this._screenManager}async setScreen(j,$){return this.requireScreenManager().setScreen(j,$)}async pushScreen(j,$){return this.requireScreenManager().pushScreen(j,$)}async popScreen(){return this.requireScreenManager().popScreen()}getCurrentScreen(){return this._screenManager?.getCurrentScreen()??null}getScreenConfig(j){return this.requireScreenManager().getConfig(j)}tryGetScreenConfig(j){return this._screenManager?.tryGetConfig(j)??void 0}getScreenState(j){return this.requireScreenManager().getState(j)}tryGetScreenState(j){return this._screenManager?.tryGetState(j)??void 0}updateScreenState(j,$){if(typeof j==="string")this.requireScreenManager().updateState($,j);else this.requireScreenManager().updateState(j)}isCurrentScreen(j){return this._screenManager?.isCurrent(j)??!1}isScreenActive(j){return this._screenManager?.isActive(j)??!1}getScreenStackDepth(){return this._screenManager?.getStackDepth()??0}_setAssetManager(j){this._assetManager=j;for(let[$,G]of this._pendingPluginAssets)this._assetManager.register($,G);this._pendingPluginAssets=[]}_setScreenManager(j){this._screenManager=j;for(let[$,G]of this._pendingPluginScreens)this._screenManager.register($,G);this._pendingPluginScreens=[]}_hasPendingPluginAssets(){return this._pendingPluginAssets.length>0}_hasPendingPluginScreens(){return this._pendingPluginScreens.length>0}_setFixedDt(j){this._fixedDt=j}_registerAsset(j,$){this._pendingPluginAssets.push([j,$])}_registerScreen(j,$){this._pendingPluginScreens.push([j,$])}installPlugin(j){if(this._installedPlugins.has(j.id))return this;return this._installedPlugins.add(j.id),j.install(this),this}pluginFactory(){return(j)=>P(j.id).install(j.install)}getHelpers(j){return j(this)}}function Vj(j){return j}function Rj(j,$){return{x:j,y:$}}function wj(){return{x:0,y:0}}function Sj(j,$){return{x:j.x+$.x,y:j.y+$.y}}function Tj(j,$){return{x:j.x-$.x,y:j.y-$.y}}function xj(j,$){return{x:j.x*$,y:j.y*$}}function Cj(j){return{x:-j.x,y:-j.y}}function qj(j,$){return j.x*$.x+j.y*$.y}function vj(j,$){return j.x*$.y-j.y*$.x}function fj(j){return j.x*j.x+j.y*j.y}function bj(j){return Math.sqrt(j.x*j.x+j.y*j.y)}function gj(j){let $=Math.sqrt(j.x*j.x+j.y*j.y);if($===0)return{x:0,y:0};return{x:j.x/$,y:j.y/$}}function Nj(j,$){let G=j.x-$.x,J=j.y-$.y;return G*G+J*J}function hj(j,$){let G=j.x-$.x,J=j.y-$.y;return Math.sqrt(G*G+J*J)}function kj(j,$,G=0.0000000001){return Math.abs(j.x-$.x)<=G&&Math.abs(j.y-$.y)<=G}var aj=z;export{wj as vec2Zero,Tj as vec2Sub,xj as vec2Scale,gj as vec2Normalize,Cj as vec2Negate,fj as vec2LengthSq,bj as vec2Length,kj as vec2Equals,qj as vec2Dot,Nj as vec2DistanceSq,hj as vec2Distance,vj as vec2Cross,Sj as vec2Add,Rj as vec2,I as directValue,P as definePlugin,aj as default,q as createScreenConfigurator,Vj as createQueryDefinition,C as createAssetConfigurator,S as SystemBuilder,K as ScreenManager,U as AssetManager};
1
+ var i=Object.defineProperty;var l=(j)=>j;function c(j,D){this[j]=l.bind(null,D)}var t=(j,D)=>{for(var $ in D)i(j,$,{get:D[$],enumerable:!0,configurable:!0,set:c.bind(D,$)})};var n=(j,D)=>()=>(j&&(D=j(j=0)),D);var e=((j)=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(j,{get:(D,$)=>(typeof require<"u"?require:D)[$]}):j)(function(j){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+j+'" is not supported')});class H{parentMap=new Map;childrenMap=new Map;_bfsQueue=[];setParent(j,D){if(j===D)throw Error(`Cannot set entity ${j} as its own parent`);if(this.wouldCreateCycle(j,D))throw Error("Cannot set parent: would create circular reference");let $=this.parentMap.get(j);if($!==void 0){let J=this.childrenMap.get($);if(J){let X=J.indexOf(j);if(X!==-1)J.splice(X,1)}}this.parentMap.set(j,D);let G=this.childrenMap.get(D);if(G)G.push(j);else this.childrenMap.set(D,[j]);return this}removeParent(j){let D=this.parentMap.get(j);if(D===void 0)return!1;let $=this.childrenMap.get(D);if($){let G=$.indexOf(j);if(G!==-1)$.splice(G,1)}return this.parentMap.delete(j),!0}getParent(j){return this.parentMap.get(j)??null}getChildren(j){let D=this.childrenMap.get(j);return D?[...D]:[]}getChildAt(j,D){if(D<0)return null;let $=this.childrenMap.get(j);if(!$||D>=$.length)return null;return $[D]??null}getChildIndex(j,D){let $=this.childrenMap.get(j);if(!$)return-1;return $.indexOf(D)}removeEntity(j){let D=this.parentMap.get(j)??null;if(D!==null){let J=this.childrenMap.get(D);if(J){let X=J.indexOf(j);if(X!==-1)J.splice(X,1)}}this.parentMap.delete(j);let $=this.childrenMap.get(j)??[],G=[...$];for(let J of $)this.parentMap.delete(J);return this.childrenMap.delete(j),{oldParent:D,orphanedChildren:G}}getAncestors(j){let D=[],$=this.parentMap.get(j);while($!==void 0)D.push($),$=this.parentMap.get($);return D}getDescendants(j){let D=[],$=this.childrenMap.get(j);if(!$)return D;let G=$.slice().reverse();while(G.length>0){let J=G.pop();D.push(J);let X=this.childrenMap.get(J);if(X)for(let Y=X.length-1;Y>=0;Y--)G.push(X[Y])}return D}getRoot(j){let D=j,$=this.parentMap.get(D);while($!==void 0)D=$,$=this.parentMap.get(D);return D}getSiblings(j){let D=this.parentMap.get(j);if(D===void 0)return[];let $=this.childrenMap.get(D);if(!$)return[];return $.filter((G)=>G!==j)}isDescendantOf(j,D){if(j===D)return!1;let $=this.parentMap.get(j);while($!==void 0){if($===D)return!0;$=this.parentMap.get($)}return!1}isAncestorOf(j,D){return this.isDescendantOf(D,j)}get hasHierarchy(){return this.childrenMap.size>0}getRootEntities(){let j=[];for(let D of this.childrenMap.keys())if(!this.parentMap.has(D))j.push(D);return j}wouldCreateCycle(j,D){let $=D;while($!==void 0){if($===j)return!0;$=this.parentMap.get($)}return!1}forEachInHierarchy(j,D){let $=D?.roots??this.getRootEntities(),G=this._bfsQueue;G.length=0;for(let J of $)G.push(J,-1,0);for(let J=0;J<G.length;J+=3){let X=G[J],Y=G[J+1],L=G[J+2];j(X,Y===-1?null:Y,L);let B=this.childrenMap.get(X);if(B){let Q=L+1;for(let Z of B)G.push(Z,X,Q)}}}*hierarchyIterator(j){let D=j?.roots??this.getRootEntities(),$=[];for(let G of D)$.push({entityId:G,parentId:null,depth:0});for(let G of $){yield G;let J=this.childrenMap.get(G.entityId);if(J)for(let X of J)$.push({entityId:X,parentId:G.entityId,depth:G.depth+1})}}}function v(j,D){for(let $ of D)if(!($ in j))return!1;return!0}function N(j,D){for(let $ of D)if($ in j)return!0;return!1}function b(j,D,$){if(!j)return!1;for(let G of D)if((j.get(G)??-1)>$)return!0;return!1}class T{callbacks=[];_iterDepth=0;_pendingRemovals=[];add(j){this.callbacks.push(j)}remove(j){if(this._iterDepth>0){this._pendingRemovals.push(j);return}let D=this.callbacks.indexOf(j);if(D!==-1)this.callbacks.splice(D,1)}invoke(j){this._iterDepth++;let D=this.callbacks.length;for(let $=0;$<D;$++){let G=this.callbacks[$];if(G)G(j)}if(this._iterDepth--,this._iterDepth===0&&this._pendingRemovals.length>0){for(let $ of this._pendingRemovals){let G=this.callbacks.indexOf($);if(G!==-1)this.callbacks.splice(G,1)}this._pendingRemovals.length=0}}}class z{nextId=1;entities=new Map;componentIndices=new Map;addedCallbacks=new Map;removedCallbacks=new Map;hierarchyManager=new H;disposeCallbacks=new Map;changeSeqs=new Map;_changeSeq=0;_afterComponentAddedHooks=[];_afterEntityMutatedHooks=[];_afterComponentRemovedHooks=[];_beforeEntityRemovedHooks=[];_afterParentChangedHooks=[];_batchingDepth=0;_batchedEntityIds=new Set;_pendingBatchKeys=null;get entityCount(){return this.entities.size}createEntity(){let j=this.nextId++,D={id:j,components:{}};return this.entities.set(j,D),D}registerDispose(j,D){this.disposeCallbacks.set(j,D)}getDisposeCallbacks(){return this.disposeCallbacks}invokeDispose(j,D,$){let G=this.disposeCallbacks.get(j);if(!G)return;try{G({value:D,entityId:$})}catch(J){console.warn(`Component dispose callback for '${String(j)}' threw:`,J)}}addComponent(j,D,$){let G=this.entities.get(j);if(!G)throw Error(`Cannot add component '${String(D)}': Entity with ID ${j} does not exist`);let J=G.components[D];if(J!==void 0)this.invokeDispose(D,J,G.id);if(G.components[D]=$,!this.componentIndices.has(D))this.componentIndices.set(D,new Set);this.componentIndices.get(D)?.add(G.id);let X=this.addedCallbacks.get(D);if(X)X.invoke({value:$,entity:G});this._batchingDepth++;for(let Y of this._afterComponentAddedHooks)Y(G.id,D);if(this._batchedEntityIds.add(G.id),this._batchingDepth--,this._batchingDepth===0){for(let Y of this._batchedEntityIds)for(let L of this._afterEntityMutatedHooks)L(Y);this._batchedEntityIds.clear()}return this}addComponents(j,D){let $=this.entities.get(j);if(!$)throw Error(`Cannot add components: Entity with ID ${j} does not exist`);let G=this._pendingBatchKeys;this._pendingBatchKeys=new Set(Object.keys(D)),this._batchingDepth++;for(let J in D)this.addComponent($.id,J,D[J]);if(this._batchingDepth--,this._pendingBatchKeys=G,this._batchingDepth===0){for(let J of this._batchedEntityIds)for(let X of this._afterEntityMutatedHooks)X(J);this._batchedEntityIds.clear()}return this}removeComponent(j,D){let $=this.entities.get(j);if(!$)throw Error(`Cannot remove component '${String(D)}': Entity with ID ${j} does not exist`);let G=$.components[D];if(G!==void 0)this.invokeDispose(D,G,$.id);delete $.components[D];let J=this.removedCallbacks.get(D);if(J&&G!==void 0)J.invoke({value:G,entity:$});if(this.componentIndices.get(D)?.delete($.id),G!==void 0)for(let X of this._afterComponentRemovedHooks)X($.id,D);return this}getComponent(j,D){let $=this.entities.get(j);if(!$)throw Error(`Cannot get component '${String(D)}': Entity with ID ${j} does not exist`);return $.components[D]}getEntitiesWithQuery(j=[],D=[],$,G,J){return this.getEntitiesWithQueryInto([],j,D,$,G,J)}getEntitiesWithQueryInto(j,D=[],$=[],G,J,X){j.length=0;let Y=G!==void 0&&G.length>0&&J!==void 0,L=X!==void 0&&X.length>0;if(D.length===0){if($.length===0&&!Y&&!L){for(let W of this.entities.values())j.push(W);return j}for(let W of this.entities.values()){if($.length>0&&N(W.components,$))continue;if(Y&&!b(this.changeSeqs.get(W.id),G,J))continue;if(L&&!this.parentHasComponents(W.id,X))continue;j.push(W)}return j}let B=D[0];if(B===void 0)return j;let Q=B,Z=this.componentIndices.get(B)?.size??0;for(let W=1;W<D.length;W++){let _=D[W];if(_===void 0)continue;let U=this.componentIndices.get(_)?.size??0;if(U<Z)Q=_,Z=U}let F=this.componentIndices.get(Q);if(!F||F.size===0)return j;for(let W of F){let _=this.entities.get(W);if(!_)continue;if(!v(_.components,D))continue;if($.length>0&&N(_.components,$))continue;if(Y&&!b(this.changeSeqs.get(W),G,J))continue;if(L&&!this.parentHasComponents(W,X))continue;j.push(_)}return j}parentHasComponents(j,D){let $=this.hierarchyManager.getParent(j);if($===null)return!1;let G=this.entities.get($);if(!G)return!1;return v(G.components,D)}removeEntity(j,D){let $=this.entities.get(j);if(!$)return!1;if(D?.cascade??!0){let J=this.hierarchyManager.getDescendants($.id);for(let X=J.length-1;X>=0;X--){let Y=J[X];if(Y===void 0)continue;for(let L of this._beforeEntityRemovedHooks)L(Y)}for(let X of this._beforeEntityRemovedHooks)X($.id);for(let X=J.length-1;X>=0;X--){let Y=J[X];if(Y===void 0)continue;this.removeEntityInternal(Y)}}else for(let J of this._beforeEntityRemovedHooks)J($.id);return this.removeEntityInternal($.id)}removeEntityInternal(j){let D=this.entities.get(j);if(!D)return!1;this.hierarchyManager.removeEntity(j);for(let $ of Object.keys(D.components)){let G=D.components[$];if(G!==void 0){this.invokeDispose($,G,D.id);let J=this.removedCallbacks.get($);if(J)J.invoke({value:G,entity:D})}this.componentIndices.get($)?.delete(D.id)}return this.changeSeqs.delete(D.id),this.entities.delete(D.id)}getEntity(j){return this.entities.get(j)}onComponentAdded(j,D){let $=D,G=this.addedCallbacks.get(j);if(!G)G=new T,this.addedCallbacks.set(j,G);return G.add($),()=>{this.addedCallbacks.get(j)?.remove($)}}onComponentRemoved(j,D){let $=D,G=this.removedCallbacks.get(j);if(!G)G=new T,this.removedCallbacks.set(j,G);return G.add($),()=>{this.removedCallbacks.get(j)?.remove($)}}onAfterComponentAdded(j){return this._afterComponentAddedHooks.push(j),()=>{let D=this._afterComponentAddedHooks.indexOf(j);if(D!==-1)this._afterComponentAddedHooks.splice(D,1)}}onAfterEntityMutated(j){return this._afterEntityMutatedHooks.push(j),()=>{let D=this._afterEntityMutatedHooks.indexOf(j);if(D!==-1)this._afterEntityMutatedHooks.splice(D,1)}}onAfterComponentRemoved(j){return this._afterComponentRemovedHooks.push(j),()=>{let D=this._afterComponentRemovedHooks.indexOf(j);if(D!==-1)this._afterComponentRemovedHooks.splice(D,1)}}onBeforeEntityRemoved(j){return this._beforeEntityRemovedHooks.push(j),()=>{let D=this._beforeEntityRemovedHooks.indexOf(j);if(D!==-1)this._beforeEntityRemovedHooks.splice(D,1)}}onAfterParentChanged(j){return this._afterParentChangedHooks.push(j),()=>{let D=this._afterParentChangedHooks.indexOf(j);if(D!==-1)this._afterParentChangedHooks.splice(D,1)}}get changeSeq(){return this._changeSeq}markChanged(j,D){let $=++this._changeSeq,G=this.changeSeqs.get(j);if(!G)G=new Map,this.changeSeqs.set(j,G);G.set(D,$)}getChangeSeq(j,D){return this.changeSeqs.get(j)?.get(D)??-1}spawnChild(j,D){let $=this.createEntity();return this.addComponents($.id,D),this.setParent($.id,j),$}setParent(j,D){this.hierarchyManager.setParent(j,D);for(let $ of this._afterParentChangedHooks)$(j);return this}removeParent(j){let D=this.hierarchyManager.removeParent(j);if(D)for(let $ of this._afterParentChangedHooks)$(j);return D}getParent(j){return this.hierarchyManager.getParent(j)}getChildren(j){return this.hierarchyManager.getChildren(j)}getChildAt(j,D){return this.hierarchyManager.getChildAt(j,D)}getChildIndex(j,D){return this.hierarchyManager.getChildIndex(j,D)}getAncestors(j){return this.hierarchyManager.getAncestors(j)}getDescendants(j){return this.hierarchyManager.getDescendants(j)}getRoot(j){return this.hierarchyManager.getRoot(j)}getSiblings(j){return this.hierarchyManager.getSiblings(j)}isDescendantOf(j,D){return this.hierarchyManager.isDescendantOf(j,D)}isAncestorOf(j,D){return this.hierarchyManager.isAncestorOf(j,D)}get hasHierarchy(){return this.hierarchyManager.hasHierarchy}getRootEntities(){return this.hierarchyManager.getRootEntities()}forEachInHierarchy(j,D){this.hierarchyManager.forEachInHierarchy(j,D)}hierarchyIterator(j){return this.hierarchyManager.hierarchyIterator(j)}}class E{handlers=new Map;subscribe(j,D){return this.addHandler(j,D,!1)}once(j,D){return this.addHandler(j,D,!0)}unsubscribe(j,D){let $=this.handlers.get(j);if(!$)return!1;let G=$.findIndex((J)=>J.callback===D);if(G===-1)return!1;return $.splice(G,1),!0}addHandler(j,D,$){let G=this.handlers.get(j);if(!G)G=[],this.handlers.set(j,G);let J={callback:D,once:$};return G.push(J),()=>{let X=this.handlers.get(j);if(X){let Y=X.indexOf(J);if(Y!==-1)X.splice(Y,1)}}}publish(...[j,D]){let $=this.handlers.get(j);if(!$||$.length===0)return;let G=!1,J=$.length;for(let X=0;X<J&&X<$.length;X++){let Y=$[X];if(!Y)continue;if(Y.callback(D),Y.once)G=!0}if(G){for(let X=$.length-1;X>=0;X--)if($[X]?.once)$.splice(X,1)}}clear(){this.handlers.clear()}clearEvent(j){this.handlers.delete(j)}}var C=Symbol("resource-direct");function d(j){return{[C]:j}}function x(j){if(typeof j==="object"&&j!==null&&!Array.isArray(j))return{...j};return{$value:j}}function y(j,D){if(typeof j==="object"&&j!==null&&!Array.isArray(j)){let $=j;for(let G in D)if(!Object.is($[G],D[G]))return!0;return!1}return!Object.is(j,D.$value)}function o(j){return typeof j==="object"&&j!==null&&"factory"in j&&typeof j.factory==="function"}function r(j){return typeof j==="object"&&j!==null&&C in j}function p(j,D){let $=[],G=new Set,J=new Set;function X(Y,L=[]){if(G.has(Y))return;if(J.has(Y))throw Error(`Circular resource dependency: ${[...L,Y].join(" -> ")}`);J.add(Y);for(let B of D(Y)){let Q=j.find((Z)=>Z===B);if(Q)X(Q,[...L,Y])}J.delete(Y),G.add(Y),$.push(Y)}for(let Y of j)X(Y);return $}class V{resources=new Map;resourceFactories=new Map;resourceDependencies=new Map;resourceDisposers=new Map;initializedResourceKeys=new Set;_changeSubscribers=new Map;_observedSnapshots=new Map;add(j,D){let $=(G)=>{this.resources.set(j,G),this.initializedResourceKeys.add(j),this.resourceDependencies.set(j,[])};if(o(D)){if(this.resourceFactories.set(j,D.factory),this.resourceDependencies.set(j,D.dependsOn??[]),D.onDispose)this.resourceDisposers.set(j,D.onDispose)}else if(r(D))$(D[C]);else if(typeof D==="function")this.resourceFactories.set(j,D),this.resourceDependencies.set(j,[]);else $(D);return this}tryGet(j,...D){if(!this.has(j))return;return this.get(j,...D)}get(j,...D){let $=this.resources.get(j);if($!==void 0)return $;let G=this.resourceFactories.get(j);if(G===void 0)throw Error(`Resource ${String(j)} not found`);let J=D[0],X=G(J);if(!(X instanceof Promise))this.resources.set(j,X),this.initializedResourceKeys.add(j);return X}has(j){return this.resources.has(j)||this.resourceFactories.has(j)}remove(j){let D=this.resources.delete(j),$=this.resourceFactories.delete(j);return this.resourceDependencies.delete(j),this.resourceDisposers.delete(j),this.initializedResourceKeys.delete(j),D||$}getKeys(){let j=new Set([...this.resources.keys(),...this.resourceFactories.keys()]);return Array.from(j)}needsInitialization(j){return this.resourceFactories.has(j)&&!this.initializedResourceKeys.has(j)}getPendingInitializationKeys(){return Array.from(this.resourceFactories.keys()).filter((j)=>!this.initializedResourceKeys.has(j))}async initializeResource(j,...D){if(!this.resourceFactories.has(j)||this.initializedResourceKeys.has(j))return;let $=this.resourceFactories.get(j);if(!$)return;let G=D[0],J=await $(G);this.resources.set(j,J),this.initializedResourceKeys.add(j),this.resourceFactories.delete(j)}async initializeResources(...j){let D=j.slice(1),$=D.length===0?this.getPendingInitializationKeys():D;if($.length===0)return;let G=p($,(J)=>[...this.resourceDependencies.get(J)??[]]);for(let J of G)await this.initializeResource(J,...j.slice(0,1))}getDependencies(j){return this.resourceDependencies.get(j)??[]}async disposeResource(j,...D){if(!this.resources.has(j)&&!this.resourceFactories.has(j))return!1;if(this.initializedResourceKeys.has(j)){let $=this.resourceDisposers.get(j),G=this.resources.get(j);if($&&G!==void 0){let J=D[0];await $(G,J)}}return this.resources.delete(j),this.resourceFactories.delete(j),this.resourceDependencies.delete(j),this.resourceDisposers.delete(j),this.initializedResourceKeys.delete(j),this._changeSubscribers.delete(j),!0}onResourceChange(j,D){let $=this._changeSubscribers.get(j),G=$??new Set;if(!$){this._changeSubscribers.set(j,G);let X=this.resources.get(j);this._observedSnapshots.set(j,x(X))}let J=D;return G.add(J),()=>{if(G.delete(J),G.size===0)this._changeSubscribers.delete(j),this._observedSnapshots.delete(j)}}notifyChange(j,D,$){if(Object.is(D,$))return;let G=this._changeSubscribers.get(j);if(!G||G.size===0)return;if(this._observedSnapshots.has(j))this._observedSnapshots.set(j,x(D));let J=[...G];for(let X of J)X(D,$)}isObserved(j){return this._observedSnapshots.has(j)}flushObserved(){if(this._observedSnapshots.size===0)return;for(let[j,D]of this._observedSnapshots){let $=this.resources.get(j);if(!y($,D))continue;let G="$value"in D?D.$value:D,J=x($),X=this._changeSubscribers.get(j);for(let Y of X)Y($,G);this._observedSnapshots.set(j,J)}}async disposeResources(...j){let D=Array.from(this.initializedResourceKeys);if(D.length===0)return;let $=p(D,(G)=>[...this.resourceDependencies.get(G)??[]]).reverse();for(let G of $)await this.disposeResource(G,...j)}}class R{queries=new Map;entityManager;_hasParentHasQueries=!1;constructor(j){this.entityManager=j}get hasParentHasQueries(){return this._hasParentHasQueries}addQuery(j,D){let $={definition:D,matchingEntities:new Set};if(this.queries.set(j,$),D.parentHas?.length)this._hasParentHasQueries=!0;let G=this.entityManager.getEntitiesWithQuery(D.with,D.without??[]);for(let J of G)if(this.entityMatchesQuery(J,$.definition))$.matchingEntities.add(J.id),$.definition.onEnter?.(J)}removeQuery(j){let D=this.queries.delete(j);if(D)this._recalcParentHasFlag();return D}entityMatchesQuery(j,D){for(let $ of D.with)if(!($ in j.components))return!1;if(D.without){for(let $ of D.without)if($ in j.components)return!1}if(D.parentHas?.length){let $=this.entityManager.getParent(j.id);if($===null)return!1;let G=this.entityManager.getEntity($);if(!G)return!1;for(let J of D.parentHas)if(!(J in G.components))return!1}return!0}_applyQueryTransition(j,D){let $=D.matchingEntities.has(j.id),G=this.entityMatchesQuery(j,D.definition);if(!$&&G)D.matchingEntities.add(j.id),D.definition.onEnter?.(j);else if($&&!G)D.matchingEntities.delete(j.id),D.definition.onExit?.(j.id)}onComponentAdded(j,D){for(let[,$]of this.queries)this._applyQueryTransition(j,$);if(this._hasParentHasQueries)this._recheckChildren(j.id)}onComponentRemoved(j,D){for(let[,$]of this.queries)this._applyQueryTransition(j,$);if(this._hasParentHasQueries)this._recheckChildren(j.id)}onEntityRemoved(j){for(let[D,$]of this.queries)if($.matchingEntities.has(j))$.matchingEntities.delete(j),$.definition.onExit?.(j)}recheckEntity(j){for(let[,D]of this.queries)this._applyQueryTransition(j,D)}recheckEntityAndChildren(j){if(this.recheckEntity(j),this._hasParentHasQueries)this._recheckChildren(j.id)}_recheckChildren(j){let D=this.entityManager.getChildren(j);for(let $ of D){let G=this.entityManager.getEntity($);if(G)this.recheckEntity(G)}}_recalcParentHasFlag(){this._hasParentHasQueries=!1;for(let[,j]of this.queries)if(j.definition.parentHas?.length){this._hasParentHasQueries=!0;return}}}class w{commands=[];removeEntity(j,D){this.commands.push(($)=>{$.removeEntity(j,D)})}addComponent(j,D,$){this.commands.push((G)=>{G.addComponent(j,D,$)})}removeComponent(j,D){this.commands.push(($)=>{$.removeComponent(j,D)})}spawn(j){this.commands.push((D)=>{D.spawn(j)})}spawnChild(j,D){this.commands.push(($)=>{$.spawnChild(j,D)})}addComponents(j,D){this.commands.push(($)=>{$.addComponents(j,D)})}setParent(j,D){this.commands.push(($)=>{$.setParent(j,D)})}mutateComponent(j,D,$){this.commands.push((G)=>{G.mutateComponent(j,D,$)})}markChanged(j,D){this.commands.push(($)=>{$.markChanged(j,D)})}removeParent(j){this.commands.push((D)=>{D.removeParent(j)})}playback(j){for(let D of this.commands)try{D(j)}catch($){console.warn("CommandBuffer: Command failed during playback:",$)}this.commands.length=0}clear(){this.commands.length=0}get length(){return this.commands.length}}class k{_id;constructor(j){this._id=j}withComponentTypes(){return this}withEventTypes(){return this}withResourceTypes(){return this}withAssetTypes(){return this}withScreenTypes(){return this}withLabels(){return this}withGroups(){return this}withAssetGroupNames(){return this}withReactiveQueryNames(){return this}requires(){return this}install(j){return{id:this._id,install:j}}}function M(j){return new k(j)}class S{_label;queries={};processFunction;detachFunction;initializeFunction;eventHandlers;_priority=0;_phase="update";_groups=[];_inScreens;_excludeScreens;_requiredAssets;_runWhenEmpty=!1;_entityEnterHandlers={};_resourceKeys;constructor(j){this._label=j}get label(){return this._label}_createSystemObject(){let j={label:this._label,entityQueries:this.queries,priority:this._priority,phase:this._phase};if(this.processFunction)j.process=this.processFunction;if(this.detachFunction)j.onDetach=this.detachFunction;if(this.initializeFunction)j.onInitialize=this.initializeFunction;if(this.eventHandlers)j.eventHandlers=this.eventHandlers;if(this._groups.length>0)j.groups=[...this._groups];if(this._inScreens)j.inScreens=this._inScreens;if(this._excludeScreens)j.excludeScreens=this._excludeScreens;if(this._requiredAssets)j.requiredAssets=this._requiredAssets;if(this._runWhenEmpty)j.runWhenEmpty=!0;if(Object.keys(this._entityEnterHandlers).length>0)j.onEntityEnter={...this._entityEnterHandlers};return j}setPriority(j){return this._priority=j,this}inPhase(j){return this._phase=j,this}inGroup(j){if(!this._groups.includes(j))this._groups.push(j);return this}inScreens(j){return this._inScreens=[...j],this}excludeScreens(j){return this._excludeScreens=[...j],this}requiresAssets(j){return this._requiredAssets=[...j],this}runWhenEmpty(){return this._runWhenEmpty=!0,this}withResources(j){return this._resourceKeys=[...j],this}addQuery(j,D){let $=this;return $.queries={...this.queries,[j]:D},$}setProcess(j){if(this._resourceKeys?.length){let D=this._resourceKeys,$={},G=!1;this.processFunction=(J)=>{for(let X of D)if(!G||J.ecs.isResourceObserved(X))$[X]=J.ecs.getResource(X);G=!0,J.resources=$,j(J)}}else this.processFunction=j;return this}setOnEntityEnter(j,D){return this._entityEnterHandlers[j]=D,this}setOnDetach(j){return this.detachFunction=j,this}setOnInitialize(j){return this.initializeFunction=j,this}setEventHandlers(j){return this.eventHandlers=j,this}}function h(j,D,$){let G=new Set,J=[D];while(J.length>0){let X=J.pop();if(X===void 0)break;if(X===j)throw Error(`Circular required component dependency: '${String(j)}' -> '${String(D)}' -> ... -> '${String(j)}'`);if(G.has(X))continue;G.add(X);let Y=$(X);if(Y)for(let L of Y)J.push(L.component)}}var I="0.14.0";class K{assets=new Map;groups=new Map;eventBus=null;setEventBus(j){this.eventBus=j}register(j,D){if(this.assets.set(j,{definition:D,status:"pending"}),D.group){let $=this.groups.get(D.group)??new Set;$.add(j),this.groups.set(D.group,$)}}async loadEagerAssets(){let j=[];for(let[D,$]of this.assets)if($.definition.eager&&$.status==="pending")j.push(D);await Promise.all(j.map((D)=>this.loadAsset(D)))}async loadAsset(j){let D=this.assets.get(j);if(!D)throw Error(`Asset '${String(j)}' not found`);if(D.status==="loaded"&&D.value!==void 0)return D.value;if(D.status==="loading"&&D.loadPromise)return D.loadPromise;if(D.status==="failed")D.status="pending";D.status="loading",D.loadPromise=D.definition.loader();try{let $=await D.loadPromise;return D.value=$,D.status="loaded",D.loadPromise=void 0,this.eventBus?.publish("assetLoaded",{key:j}),this.checkGroupProgress(D.definition.group),$}catch($){let G=$ instanceof Error?$:Error(String($));throw D.status="failed",D.error=G,D.loadPromise=void 0,this.eventBus?.publish("assetFailed",{key:j,error:G}),G}}async loadAssetGroup(j){let D=this.groups.get(j);if(!D||D.size===0)throw Error(`Asset group '${j}' not found or empty`);await Promise.all(Array.from(D).map(($)=>this.loadAsset($)))}get(j){let D=this.assets.get(j);if(!D)throw Error(`Asset '${String(j)}' not found`);if(D.status!=="loaded"||D.value===void 0)throw Error(`Asset '${String(j)}' is not loaded (status: ${D.status})`);return D.value}tryGet(j){let D=this.assets.get(j);if(!D||D.status!=="loaded")return;return D.value}getHandle(j){let D=this.assets.get(j);if(!D)throw Error(`Asset '${String(j)}' not found`);let $=this;return{get status(){return D.status},get isLoaded(){return D.status==="loaded"},get(){return $.get(j)},tryGet(){return $.tryGet(j)}}}getStatus(j){let D=this.assets.get(j);if(!D)throw Error(`Asset '${String(j)}' not found`);return D.status}isLoaded(j){return this.assets.get(j)?.status==="loaded"}isGroupLoaded(j){let D=this.groups.get(j);if(!D||D.size===0)return!1;for(let $ of D){let G=this.assets.get($);if(!G||G.status!=="loaded")return!1}return!0}getGroupProgress(j){return this.getGroupProgressDetails(j).progress}getGroupProgressDetails(j){let D=this.groups.get(j);if(!D||D.size===0)return{loaded:0,total:0,progress:0};let $=0;for(let J of D)if(this.assets.get(J)?.status==="loaded")$++;let G=D.size;return{loaded:$,total:G,progress:$/G}}checkGroupProgress(j){if(!j||!this.eventBus)return;let D=j,$=this.getGroupProgressDetails(D);if(this.eventBus.publish("assetGroupProgress",{group:D,...$}),$.loaded===$.total)this.eventBus.publish("assetGroupLoaded",{group:D})}createResource(){let j=this;return{getStatus(D){return j.getStatus(D)},isLoaded(D){return j.isLoaded(D)},isGroupLoaded(D){return j.isGroupLoaded(D)},getGroupProgress(D){return j.getGroupProgress(D)},get(D){return j.get(D)},tryGet(D){return j.tryGet(D)},getHandle(D){return j.getHandle(D)}}}getKeys(){return Array.from(this.assets.keys())}getGroupNames(){return Array.from(this.groups.keys())}getGroupKeys(j){let D=this.groups.get(j);return D?Array.from(D):[]}}class u{manager;constructor(j){this.manager=j}add(j,D){return this.manager.register(j,{loader:D,eager:!0}),this}addWithConfig(j,D){return this.manager.register(j,D),this}addGroup(j,D){for(let[$,G]of Object.entries(D))this.manager.register($,{loader:G,eager:!1,group:j});return this}getManager(){return this.manager}}function q(j){return new u(j??new K)}class A{screens=new Map;currentScreen=null;screenStack=[];eventBus=null;assetManager=null;ecs=null;setDependencies(j,D,$){this.eventBus=j,this.assetManager=D,this.ecs=$}requireEcs(){if(!this.ecs)throw Error("ScreenManager: dependencies not set. Call setDependencies() first.");return this.ecs}register(j,D){this.screens.set(j,{definition:D})}async setScreen(j,D){let $=this.screens.get(j);if(!$)throw Error(`Screen '${String(j)}' not found`);await this.verifyRequiredAssets($.definition.requiredAssets,$.definition.requiredAssetGroups);while(this.screenStack.length>0){let J=this.screenStack.pop();if(J)await this.exitScreen(J.name)}if(this.currentScreen)await this.exitScreen(this.currentScreen.name);let G=$.definition.initialState(D);this.currentScreen={name:j,config:D,state:G},await $.definition.onEnter?.({config:D,ecs:this.requireEcs()}),this.eventBus?.publish("screenEnter",{screen:j,config:D})}async pushScreen(j,D){let $=this.screens.get(j);if(!$)throw Error(`Screen '${String(j)}' not found`);if(await this.verifyRequiredAssets($.definition.requiredAssets,$.definition.requiredAssetGroups),this.currentScreen)this.screenStack.push(this.currentScreen);let G=$.definition.initialState(D);this.currentScreen={name:j,config:D,state:G},await $.definition.onEnter?.({config:D,ecs:this.requireEcs()}),this.eventBus?.publish("screenPush",{screen:j,config:D})}async popScreen(){if(this.screenStack.length===0)throw Error("Cannot pop screen: stack is empty");if(this.currentScreen)await this.exitScreen(this.currentScreen.name),this.eventBus?.publish("screenPop",{screen:this.currentScreen.name});this.currentScreen=this.screenStack.pop()??null}async exitScreen(j){let D=this.screens.get(j);if(D?.definition.onExit)await D.definition.onExit(this.requireEcs());this.eventBus?.publish("screenExit",{screen:j})}async verifyRequiredAssets(j,D){if(!this.assetManager)return;if(j){for(let $ of j)if(!this.assetManager.isLoaded($))await this.assetManager.loadAsset($)}if(D){for(let $ of D)if(!this.assetManager.isGroupLoaded($))await this.assetManager.loadAssetGroup($)}}getCurrentScreen(){return this.currentScreen?.name??null}getConfig(j){if(!this.currentScreen)throw Error("No current screen");if(j!==void 0&&this.currentScreen.name!==j)throw Error(`Expected current screen '${String(j)}', but current is '${String(this.currentScreen.name)}'`);return this.currentScreen.config}tryGetConfig(j){if(!this.currentScreen)return;if(j!==void 0&&this.currentScreen.name!==j)return;return this.currentScreen.config}getState(j){if(!this.currentScreen)throw Error("No current screen");if(j!==void 0&&this.currentScreen.name!==j)throw Error(`Expected current screen '${String(j)}', but current is '${String(this.currentScreen.name)}'`);return this.currentScreen.state}tryGetState(j){if(!this.currentScreen)return;if(j!==void 0&&this.currentScreen.name!==j)return;return this.currentScreen.state}updateState(j,D){if(!this.currentScreen)throw Error("No current screen");if(D!==void 0&&this.currentScreen.name!==D)throw Error(`Expected current screen '${String(D)}', but current is '${String(this.currentScreen.name)}'`);let $=typeof j==="function"?j(this.currentScreen.state):j;this.currentScreen.state={...this.currentScreen.state,...$}}getStackDepth(){return this.screenStack.length}isOverlay(){return this.screenStack.length>0}isActive(j){if(this.currentScreen?.name===j)return!0;return this.screenStack.some((D)=>D.name===j)}isCurrent(j){return this.currentScreen?.name===j}createResource(){let j=this;return{get current(){return j.getCurrentScreen()},get config(){return j.tryGetConfig()??null},get state(){return j.tryGetState()??null},set state(D){if(j.currentScreen&&D!==null)j.currentScreen.state=D},get stack(){return j.screenStack},get isOverlay(){return j.isOverlay()},get stackDepth(){return j.getStackDepth()},isActive(D){return j.isActive(D)},isCurrent(D){return j.isCurrent(D)}}}getScreenNames(){return Array.from(this.screens.keys())}hasScreen(j){return this.screens.has(j)}}class s{manager;constructor(j){this.manager=j}add(j,D){return this.manager.register(j,D),this}getManager(){return this.manager}}function f(j){return new s(j??new A)}class g{assetConfigurator=null;screenConfigurator=null;pendingResources=[];pendingDisposeCallbacks=[];pendingRequiredComponents=[];pendingPlugins=[];_fixedDt=null;constructor(){}withPlugin(j){return this.pendingPlugins.push(j),this}withComponentTypes(){return this}withEventTypes(){return this}withResourceTypes(){return this}withResource(j,D){return this.pendingResources.push({key:j,value:D}),this}withDispose(j,D){return this.pendingDisposeCallbacks.push({key:j,callback:D}),this}withRequired(j,D,$){return this.pendingRequiredComponents.push({trigger:j,required:D,factory:$}),this}withAssets(j){let D=q();return j(D),this.assetConfigurator=D,this}withScreens(j){let D=f();return j(D),this.screenConfigurator=D,this}withFixedTimestep(j){return this._fixedDt=j,this}withReactiveQueryNames(){return this}pluginFactory(){return(j)=>M(j.id).install(j.install)}build(){let j=new P;for(let D of this.pendingPlugins)j.installPlugin(D);for(let{key:D,value:$}of this.pendingResources)j.addResource(D,$);for(let{key:D,callback:$}of this.pendingDisposeCallbacks)j.registerDispose(D,$);for(let{trigger:D,required:$,factory:G}of this.pendingRequiredComponents)j.registerRequired(D,$,G);if(this.assetConfigurator)j._setAssetManager(this.assetConfigurator.getManager());else if(j._hasPendingPluginAssets())j._setAssetManager(new K);if(this.screenConfigurator)j._setScreenManager(this.screenConfigurator.getManager());else if(j._hasPendingPluginScreens())j._setScreenManager(new A);if(this._fixedDt!==null)j._setFixedDt(this._fixedDt);return j}}var m=["preUpdate","fixedUpdate","update","postUpdate","render"];class P{static VERSION=I;_entityManager;_eventBus;_resourceManager;_commandBuffer;_systems=[];_phaseSystems={preUpdate:[],fixedUpdate:[],update:[],postUpdate:[],render:[]};_installedPlugins=new Set;_disabledGroups=new Set;_assetManager=null;_screenManager=null;_reactiveQueryManager;_postUpdateHooks=[];_currentTick=0;_systemLastSeqs=new Map;_changeThreshold=0;_fixedDt=0.016666666666666666;_fixedAccumulator=0;_interpolationAlpha=0;_maxFixedSteps=8;_requiredComponents=new Map;_pendingPluginAssets=[];_pendingPluginScreens=[];_diagnosticsEnabled=!1;_systemTimings=new Map;_phaseTimings={preUpdate:0,fixedUpdate:0,update:0,postUpdate:0,render:0};_entityEnterTracking=new Map;_entityEnterFrameSet=new Set;_systemContexts=new WeakMap;_pendingFinalizers=[];_batchingRegistrations=!1;constructor(){this._entityManager=new z,this._eventBus=new E,this._resourceManager=new V,this._reactiveQueryManager=new R(this._entityManager),this._commandBuffer=new w,this._subscribeLifecycleHooks()}_subscribeLifecycleHooks(){this._entityManager.onAfterComponentAdded((j,D)=>{this._entityManager.markChanged(j,D);let $=this._requiredComponents.get(D);if($){let G=this._entityManager.getEntity(j);if(G){let J=G.components[D];for(let{component:X,factory:Y}of $){if(this._entityManager._pendingBatchKeys?.has(X))continue;if(!(X in G.components))this._entityManager.addComponent(j,X,Y(J))}}}}),this._entityManager.onAfterEntityMutated((j)=>{let D=this._entityManager.getEntity(j);if(D)this._reactiveQueryManager.recheckEntityAndChildren(D)}),this._entityManager.onAfterComponentRemoved((j,D)=>{let $=this._entityManager.getEntity(j);if($)this._reactiveQueryManager.onComponentRemoved($,D)}),this._entityManager.onBeforeEntityRemoved((j)=>{this._reactiveQueryManager.onEntityRemoved(j)}),this._entityManager.onAfterParentChanged((j)=>{if(this._reactiveQueryManager.hasParentHasQueries){let D=this._entityManager.getEntity(j);if(D)this._reactiveQueryManager.recheckEntity(D)}})}static create(){return new g}addSystem(j){let D=new S(j);return this._pendingFinalizers.push(()=>{this._registerSystem(D._createSystemObject())}),D}_finalizePendingBuilders(){if(this._pendingFinalizers.length===0)return;this._batchingRegistrations=!0;while(this._pendingFinalizers.length>0){let j=this._pendingFinalizers;this._pendingFinalizers=[];for(let D of j)D()}this._batchingRegistrations=!1,this._rebuildPhaseSystems()}update(j){this._finalizePendingBuilders();let D=this._screenManager?.getCurrentScreen()??null,$=this._diagnosticsEnabled;this._runPhase("preUpdate",j,D,$);let G=$?performance.now():0;this._fixedAccumulator+=j;let J=0;while(this._fixedAccumulator>=this._fixedDt&&J<this._maxFixedSteps)this._executePhase(this._phaseSystems.fixedUpdate,this._fixedDt,D),this._commandBuffer.playback(this),this._fixedAccumulator-=this._fixedDt,J++;if(this._fixedAccumulator>=this._fixedDt)this._fixedAccumulator=0;if($)this._phaseTimings.fixedUpdate=performance.now()-G;this._interpolationAlpha=this._fixedAccumulator/this._fixedDt,this._runPhase("update",j,D,$),this._runPhase("postUpdate",j,D,$);for(let X of this._postUpdateHooks)X({ecs:this,dt:j});this._runPhase("render",j,D,$),this._resourceManager.flushObserved(),this._changeThreshold=this._entityManager.changeSeq,this._currentTick++}_executePhase(j,D,$){for(let G of j){if(!G.process&&!G.onEntityEnter)continue;if(G.groups?.length){let Z=!1;for(let F of G.groups)if(this._disabledGroups.has(F)){Z=!0;break}if(Z)continue}if(G.inScreens?.length){if($===null||!G.inScreens.includes($))continue}if(G.excludeScreens?.length){if($!==null&&G.excludeScreens.includes($))continue}if(G.requiredAssets?.length&&this._assetManager){let Z=!0;for(let F of G.requiredAssets)if(!this._assetManager.isLoaded(F)){Z=!1;break}if(!Z)continue}let J=this._systemLastSeqs.get(G)??0;this._changeThreshold=J;let X=this._systemContexts.get(G);if(!X)X={queries:{},dt:0,ecs:this},this._systemContexts.set(G,X);X.dt=D;let Y=X.queries,L=!1,B=!1;if(G.entityQueries)for(let Z in G.entityQueries){B=!0;let F=G.entityQueries[Z];if(F){let _=Y[Z]??(Y[Z]=[]);if(this._entityManager.getEntitiesWithQueryInto(_,F.with,F.without||[],F.changed,F.changed?this._changeThreshold:void 0,F.parentHas),_.length)L=!0}}let Q=this._entityEnterTracking.get(G);if(Q&&G.onEntityEnter)for(let Z in G.onEntityEnter){let F=Y[Z],W=Q.get(Z);if(!F||!W)continue;let _=G.onEntityEnter[Z];if(!_)continue;let U=this._entityEnterFrameSet;U.clear();for(let O of F)if(U.add(O.id),!W.has(O.id))W.add(O.id),_({entity:O,ecs:this});for(let O of W)if(!U.has(O))W.delete(O)}if(G.process){if(this._diagnosticsEnabled){let Z=performance.now();if(L||G.runWhenEmpty)G.process(X);else if(!B)G.process(X);this._systemTimings.set(G.label,performance.now()-Z)}else if(L||G.runWhenEmpty)G.process(X);else if(!B)G.process(X)}this._systemLastSeqs.set(G,this._entityManager.changeSeq)}}_runPhase(j,D,$,G){if(G){let J=performance.now();this._executePhase(this._phaseSystems[j],D,$),this._phaseTimings[j]=performance.now()-J}else this._executePhase(this._phaseSystems[j],D,$);this._commandBuffer.playback(this)}async initialize(){if(this._finalizePendingBuilders(),await this.initializeResources(),this._assetManager)this._assetManager.setEventBus(this._eventBus),await this._assetManager.loadEagerAssets(),this._resourceManager.add("$assets",this._assetManager.createResource());if(this._screenManager)this._screenManager.setDependencies(this._eventBus,this._assetManager,this),this._resourceManager.add("$screen",this._screenManager.createResource());for(let j of this._systems)await j.onInitialize?.(this)}async initializeResources(...j){await this._resourceManager.initializeResources(this,...j)}_rebuildPhaseSystems(){for(let j of m)this._phaseSystems[j]=[];for(let j of this._systems){let D=j.phase??"update";this._phaseSystems[D].push(j)}for(let j of m)this._phaseSystems[j].sort((D,$)=>{let G=D.priority??0;return($.priority??0)-G})}updateSystemPriority(j,D){this._finalizePendingBuilders();let $=this._systems.find((G)=>G.label===j);if(!$)return!1;return $.priority=D,this._rebuildPhaseSystems(),!0}updateSystemPhase(j,D){this._finalizePendingBuilders();let $=this._systems.find((G)=>G.label===j);if(!$)return!1;return $.phase=D,this._rebuildPhaseSystems(),!0}get interpolationAlpha(){return this._interpolationAlpha}get fixedDt(){return this._fixedDt}disableSystemGroup(j){this._disabledGroups.add(j)}enableSystemGroup(j){this._disabledGroups.delete(j)}isSystemGroupEnabled(j){return!this._disabledGroups.has(j)}getSystemsInGroup(j){return this._finalizePendingBuilders(),this._systems.filter((D)=>D.groups?.includes(j)).map((D)=>D.label)}removeSystem(j){this._finalizePendingBuilders();let D=this._systems.findIndex((G)=>G.label===j);if(D===-1)return!1;let $=this._systems[D];if(!$)return!1;if($.onDetach)$.onDetach(this);return this._systems.splice(D,1),this._systemLastSeqs.delete($),this._entityEnterTracking.delete($),this._rebuildPhaseSystems(),!0}_registerSystem(j){if(this._systems.push(j),this._systemLastSeqs.set(j,this._changeThreshold),!this._batchingRegistrations)this._rebuildPhaseSystems();if(j.onEntityEnter){let D=new Map;for(let $ in j.onEntityEnter)D.set($,new Set);this._entityEnterTracking.set(j,D)}if(!j.eventHandlers)return;for(let D in j.eventHandlers){let $=j.eventHandlers[D];if($)this._eventBus.subscribe(D,(G)=>{$({data:G,ecs:this})})}}hasResource(j){return this._resourceManager.has(j)}getResource(j){if(!this._resourceManager.has(j))throw Error(`Resource '${String(j)}' not found. Available resources: [${this.getResourceKeys().map((D)=>String(D)).join(", ")}]`);return this._resourceManager.get(j,this)}tryGetResource(j){let D=j;if(!this._resourceManager.has(D))return;return this._resourceManager.get(D,this)}addResource(j,D){return this._resourceManager.add(j,D),this}removeResource(j){return this._resourceManager.remove(j)}async disposeResource(j){return this._resourceManager.disposeResource(j,this)}async disposeResources(){return this._resourceManager.disposeResources(this)}updateResource(j,D){let $=this.getResource(j),G=D($);return this._resourceManager.add(j,G),this._resourceManager.notifyChange(j,G,$),this}setResource(j,D){let $=this.tryGetResource(j);if(this._resourceManager.add(j,D),$!==void 0)this._resourceManager.notifyChange(j,D,$);return this}onResourceChange(j,D){return this._resourceManager.onResourceChange(j,D)}isResourceObserved(j){return this._resourceManager.isObserved(j)}getResourceKeys(){return this._resourceManager.getKeys()}resourceNeedsInitialization(j){return this._resourceManager.needsInitialization(j)}getEntity(j){return this._entityManager.getEntity(j)}getComponent(j,D){return this._entityManager.getComponent(j,D)}addComponent(j,D,$){this._entityManager.addComponent(j,D,$)}addComponents(j,D){this._entityManager.addComponents(j,D)}removeComponent(j,D){this._entityManager.removeComponent(j,D)}hasComponent(j,D){return this._entityManager.getComponent(j,D)!==void 0}spawn(j){let D=this._entityManager.createEntity();return this._entityManager.addComponents(D.id,j),D}getEntitiesWithQuery(j,D=[],$,G){return this._entityManager.getEntitiesWithQuery(j,D,$,$?this._changeThreshold:void 0,G)}getSingleton(j,D=[]){let $=this._entityManager.getEntitiesWithQuery(j,D);if($.length===0)throw Error(`getSingleton: no entity matches query with=[${String(j)}] without=[${String(D)}]`);if($.length>1)throw Error(`getSingleton: expected 1 entity but found ${$.length} matching query with=[${String(j)}] without=[${String(D)}]`);let G=$[0];if(!G)throw Error("getSingleton: unexpected empty result");return G}tryGetSingleton(j,D=[]){let $=this._entityManager.getEntitiesWithQuery(j,D);if($.length===0)return;if($.length>1)throw Error(`tryGetSingleton: expected 0 or 1 entity but found ${$.length} matching query with=[${String(j)}] without=[${String(D)}]`);return $[0]}removeEntity(j,D){return this._entityManager.removeEntity(j,D)}spawnChild(j,D){let $=this._entityManager.spawnChild(j,D);return this._emitHierarchyChanged($.id,null,j),$}setParent(j,D){let $=this._entityManager.getParent(j);return this._entityManager.setParent(j,D),this._emitHierarchyChanged(j,$,D),this}removeParent(j){let D=this._entityManager.getParent(j),$=this._entityManager.removeParent(j);if($)this._emitHierarchyChanged(j,D,null);return $}getParent(j){return this._entityManager.getParent(j)}getChildren(j){return this._entityManager.getChildren(j)}getChildAt(j,D){return this._entityManager.getChildAt(j,D)}getChildIndex(j,D){return this._entityManager.getChildIndex(j,D)}getAncestors(j){return this._entityManager.getAncestors(j)}getDescendants(j){return this._entityManager.getDescendants(j)}getRoot(j){return this._entityManager.getRoot(j)}getSiblings(j){return this._entityManager.getSiblings(j)}isDescendantOf(j,D){return this._entityManager.isDescendantOf(j,D)}isAncestorOf(j,D){return this._entityManager.isAncestorOf(j,D)}getRootEntities(){return this._entityManager.getRootEntities()}forEachInHierarchy(j,D){this._entityManager.forEachInHierarchy(j,D)}hierarchyIterator(j){return this._entityManager.hierarchyIterator(j)}_emitHierarchyChanged(j,D,$){this._eventBus.publish("hierarchyChanged",{entityId:j,oldParent:D,newParent:$})}get installedPlugins(){return Array.from(this._installedPlugins)}get entityManager(){return this._entityManager}get eventBus(){return this._finalizePendingBuilders(),this._eventBus}get commands(){return this._commandBuffer}get currentTick(){return this._currentTick}get changeThreshold(){return this._changeThreshold}enableDiagnostics(j){if(this._diagnosticsEnabled=j,!j)this._systemTimings.clear(),this._phaseTimings={preUpdate:0,fixedUpdate:0,update:0,postUpdate:0,render:0}}get diagnosticsEnabled(){return this._diagnosticsEnabled}get systemTimings(){return this._systemTimings}get phaseTimings(){return this._phaseTimings}get entityCount(){return this._entityManager.entityCount}mutateComponent(j,D,$){let G=this._entityManager.getComponent(j,D);if(G===void 0)throw Error(`Entity ${j} does not have component "${String(D)}"`);return $(G),this._entityManager.markChanged(j,D),G}markChanged(j,D){this._entityManager.markChanged(j,D)}registerDispose(j,D){this._entityManager.registerDispose(j,D)}registerRequired(j,D,$){if(String(j)===String(D))throw Error(`Cannot require a component to depend on itself: '${String(j)}'`);let G=this._requiredComponents.get(j)??[];if(G.some((J)=>J.component===D))throw Error(`Required component '${String(D)}' already registered for trigger '${String(j)}'`);this._checkRequiredCycle(j,D),G.push({component:D,factory:$}),this._requiredComponents.set(j,G)}_checkRequiredCycle(j,D){h(j,D,($)=>this._requiredComponents.get($))}onComponentAdded(j,D){return this._entityManager.onComponentAdded(j,D)}onComponentRemoved(j,D){return this._entityManager.onComponentRemoved(j,D)}addReactiveQuery(j,D){this._reactiveQueryManager.addQuery(j,D)}removeReactiveQuery(j){return this._reactiveQueryManager.removeQuery(j)}on(j,D){return this._eventBus.subscribe(j,D)}off(j,D){return this._eventBus.unsubscribe(j,D)}onPostUpdate(j){return this._postUpdateHooks.push(j),()=>{let D=this._postUpdateHooks.indexOf(j);if(D!==-1)this._postUpdateHooks.splice(D,1)}}requireAssetManager(){if(!this._assetManager)throw Error("Asset manager not configured. Use withAssets() in builder.");return this._assetManager}getAsset(j){return this.requireAssetManager().get(j)}tryGetAsset(j){return this._assetManager?.tryGet(j)}getAssetHandle(j){return this.requireAssetManager().getHandle(j)}isAssetLoaded(j){return this._assetManager?.isLoaded(j)??!1}async loadAsset(j){return this.requireAssetManager().loadAsset(j)}async loadAssetGroup(j){return this.requireAssetManager().loadAssetGroup(j)}isAssetGroupLoaded(j){return this._assetManager?.isGroupLoaded(j)??!1}getAssetGroupProgress(j){return this._assetManager?.getGroupProgress(j)??0}requireScreenManager(){if(!this._screenManager)throw Error("Screen manager not configured. Use withScreens() in builder.");return this._screenManager}async setScreen(j,D){return this.requireScreenManager().setScreen(j,D)}async pushScreen(j,D){return this.requireScreenManager().pushScreen(j,D)}async popScreen(){return this.requireScreenManager().popScreen()}getCurrentScreen(){return this._screenManager?.getCurrentScreen()??null}getScreenConfig(j){return this.requireScreenManager().getConfig(j)}tryGetScreenConfig(j){return this._screenManager?.tryGetConfig(j)??void 0}getScreenState(j){return this.requireScreenManager().getState(j)}tryGetScreenState(j){return this._screenManager?.tryGetState(j)??void 0}updateScreenState(j,D){if(typeof j==="string")this.requireScreenManager().updateState(D,j);else this.requireScreenManager().updateState(j)}isCurrentScreen(j){return this._screenManager?.isCurrent(j)??!1}isScreenActive(j){return this._screenManager?.isActive(j)??!1}getScreenStackDepth(){return this._screenManager?.getStackDepth()??0}_setAssetManager(j){this._assetManager=j;for(let[D,$]of this._pendingPluginAssets)this._assetManager.register(D,$);this._pendingPluginAssets=[]}_setScreenManager(j){this._screenManager=j;for(let[D,$]of this._pendingPluginScreens)this._screenManager.register(D,$);this._pendingPluginScreens=[]}_hasPendingPluginAssets(){return this._pendingPluginAssets.length>0}_hasPendingPluginScreens(){return this._pendingPluginScreens.length>0}_setFixedDt(j){this._fixedDt=j}_registerAsset(j,D){this._pendingPluginAssets.push([j,D])}_registerScreen(j,D){this._pendingPluginScreens.push([j,D])}installPlugin(j){if(this._installedPlugins.has(j.id))return this;return this._installedPlugins.add(j.id),j.install(this),this}pluginFactory(){return(j)=>M(j.id).install(j.install)}getHelpers(j){return j(this)}}function gj(j){return j}function Nj(j,D){return{x:j,y:D}}function bj(){return{x:0,y:0}}function pj(j,D){return{x:j.x+D.x,y:j.y+D.y}}function kj(j,D){return{x:j.x-D.x,y:j.y-D.y}}function hj(j,D){return{x:j.x*D,y:j.y*D}}function Ij(j){return{x:-j.x,y:-j.y}}function uj(j,D){return j.x*D.x+j.y*D.y}function sj(j,D){return j.x*D.y-j.y*D.x}function mj(j){return j.x*j.x+j.y*j.y}function ij(j){return Math.sqrt(j.x*j.x+j.y*j.y)}function lj(j){let D=Math.sqrt(j.x*j.x+j.y*j.y);if(D===0)return{x:0,y:0};return{x:j.x/D,y:j.y/D}}function cj(j,D){let $=j.x-D.x,G=j.y-D.y;return $*$+G*G}function dj(j,D){let $=j.x-D.x,G=j.y-D.y;return Math.sqrt($*$+G*G)}function yj(j,D,$=0.0000000001){return Math.abs(j.x-D.x)<=$&&Math.abs(j.y-D.y)<=$}function oj(j,D,$){return{x:j,y:D,z:$}}function rj(){return{x:0,y:0,z:0}}function aj(j,D){return{x:j.x+D.x,y:j.y+D.y,z:j.z+D.z}}function tj(j,D){return{x:j.x-D.x,y:j.y-D.y,z:j.z-D.z}}function nj(j,D){return{x:j.x*D,y:j.y*D,z:j.z*D}}function ej(j){return{x:-j.x,y:-j.y,z:-j.z}}function j3(j,D){return j.x*D.x+j.y*D.y+j.z*D.z}function D3(j,D){return{x:j.y*D.z-j.z*D.y,y:j.z*D.x-j.x*D.z,z:j.x*D.y-j.y*D.x}}function $3(j){return j.x*j.x+j.y*j.y+j.z*j.z}function G3(j){return Math.sqrt(j.x*j.x+j.y*j.y+j.z*j.z)}function J3(j){let D=Math.sqrt(j.x*j.x+j.y*j.y+j.z*j.z);if(D===0)return{x:0,y:0,z:0};return{x:j.x/D,y:j.y/D,z:j.z/D}}function X3(j,D){let $=j.x-D.x,G=j.y-D.y,J=j.z-D.z;return $*$+G*G+J*J}function Y3(j,D){let $=j.x-D.x,G=j.y-D.y,J=j.z-D.z;return Math.sqrt($*$+G*G+J*J)}function Z3(j,D,$=0.0000000001){return Math.abs(j.x-D.x)<=$&&Math.abs(j.y-D.y)<=$&&Math.abs(j.z-D.z)<=$}var H3=P;export{rj as vec3Zero,tj as vec3Sub,nj as vec3Scale,J3 as vec3Normalize,ej as vec3Negate,$3 as vec3LengthSq,G3 as vec3Length,Z3 as vec3Equals,j3 as vec3Dot,X3 as vec3DistanceSq,Y3 as vec3Distance,D3 as vec3Cross,aj as vec3Add,oj as vec3,bj as vec2Zero,kj as vec2Sub,hj as vec2Scale,lj as vec2Normalize,Ij as vec2Negate,mj as vec2LengthSq,ij as vec2Length,yj as vec2Equals,uj as vec2Dot,cj as vec2DistanceSq,dj as vec2Distance,sj as vec2Cross,pj as vec2Add,Nj as vec2,d as directValue,M as definePlugin,H3 as default,f as createScreenConfigurator,gj as createQueryDefinition,q as createAssetConfigurator,S as SystemBuilder,A as ScreenManager,K as AssetManager};
2
2
 
3
- //# debugId=288843F194C573FA64756E2164756E21
3
+ //# debugId=A90B4643B329FEF164756E2164756E21
4
4
  //# sourceMappingURL=index.js.map