@oasys/oecs 0.5.0 → 0.5.2
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.
- package/CHANGELOG.md +108 -1
- package/README.md +20 -8
- package/dist/core/ecs/archetype.d.cts +3 -3
- package/dist/core/ecs/archetype.d.ts +3 -3
- package/dist/core/ecs/component.d.cts +25 -0
- package/dist/core/ecs/component.d.ts +25 -0
- package/dist/core/ecs/component.d.ts.map +1 -1
- package/dist/core/ecs/ecs.d.cts +67 -49
- package/dist/core/ecs/ecs.d.ts +67 -49
- package/dist/core/ecs/ecs.d.ts.map +1 -1
- package/dist/core/ecs/entity.d.cts +1 -1
- package/dist/core/ecs/entity.d.ts +1 -1
- package/dist/core/ecs/facades.d.cts +1 -1
- package/dist/core/ecs/facades.d.ts +1 -1
- package/dist/core/ecs/host_commands.d.cts +30 -20
- package/dist/core/ecs/host_commands.d.ts +30 -20
- package/dist/core/ecs/host_commands.d.ts.map +1 -1
- package/dist/core/ecs/index.d.cts +3 -3
- package/dist/core/ecs/index.d.ts +3 -3
- package/dist/core/ecs/index.d.ts.map +1 -1
- package/dist/core/ecs/observer.d.cts +1 -1
- package/dist/core/ecs/observer.d.ts +1 -1
- package/dist/core/ecs/observer.d.ts.map +1 -1
- package/dist/core/ecs/query.d.cts +22 -6
- package/dist/core/ecs/query.d.ts +22 -6
- package/dist/core/ecs/query.d.ts.map +1 -1
- package/dist/core/ecs/ref.d.ts.map +1 -1
- package/dist/core/ecs/run_condition.d.cts +1 -1
- package/dist/core/ecs/run_condition.d.ts +1 -1
- package/dist/core/ecs/run_condition.d.ts.map +1 -1
- package/dist/core/ecs/store.d.cts +10 -23
- package/dist/core/ecs/store.d.ts +10 -23
- package/dist/core/ecs/store.d.ts.map +1 -1
- package/dist/dev_flag.d.cts +0 -15
- package/dist/dev_flag.d.ts +0 -15
- package/dist/dev_flag.d.ts.map +1 -1
- package/dist/extensions/editor/editor.d.cts +31 -29
- package/dist/extensions/editor/editor.d.ts +31 -29
- package/dist/extensions/editor/editor.d.ts.map +1 -1
- package/dist/extensions/editor/field_handle.d.cts +3 -3
- package/dist/extensions/editor/field_handle.d.ts +3 -3
- package/dist/extensions/editor/field_handle.d.ts.map +1 -1
- package/dist/extensions/editor/index.cjs +1 -1
- package/dist/extensions/editor/index.development.cjs +1 -0
- package/dist/extensions/editor/index.development.js +239 -0
- package/dist/extensions/editor/index.js +53 -51
- package/dist/extensions/reactive/index.development.cjs +1 -0
- package/dist/extensions/reactive/index.development.js +215 -0
- package/dist/extensions/solid/index.development.cjs +1 -0
- package/dist/extensions/solid/index.development.js +40 -0
- package/dist/{host_commands-i4cAeyL5.js → host_commands-BI8pEmjH.js} +26 -18
- package/dist/{host_commands-BF8QMi3c.cjs → host_commands-CxhpzMx9.cjs} +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +3 -3
- package/dist/index.d.ts +3 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.development.cjs +1 -0
- package/dist/index.development.js +8116 -0
- package/dist/index.js +269 -214
- package/dist/internal-BMDgWZbt.js +2485 -0
- package/dist/internal-LiTSB_tG.cjs +2 -0
- package/dist/internal.cjs +1 -1
- package/dist/internal.development.cjs +1 -0
- package/dist/internal.development.js +24 -0
- package/dist/internal.js +1 -1
- package/dist/interop-DqxleBo7.js +18 -0
- package/dist/interop-T1HZ-Dpa.cjs +1 -0
- package/dist/kernel-Cz2Kxlwl.js +240 -0
- package/dist/kernel-sw7ScKWu.cjs +1 -0
- package/dist/primitives.development.cjs +1 -0
- package/dist/primitives.development.js +45 -0
- package/dist/reactive/index.development.cjs +1 -0
- package/dist/reactive/index.development.js +18 -0
- package/dist/shallow-9S1pY_Iw.js +159 -0
- package/dist/shallow-C5YmTbtb.cjs +1 -0
- package/dist/shared.development.cjs +1 -0
- package/dist/shared.development.js +7 -0
- package/dist/version.d.cts +1 -1
- package/dist/version.d.ts +1 -1
- package/package.json +31 -2
package/dist/index.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const h=require("./host_commands-BF8QMi3c.cjs"),T=require("./typed_arrays-D3NmwtCG.cjs"),U=require("./shared-BymrGTyR.cjs"),O=!1,Rt=c=>h.validateAndCast(c),ht=Object.freeze({});function vt(c){const t=(e=>({def:t,values:e??ht}));return Object.defineProperty(t,"id",{value:c,enumerable:!1}),t}function Ft(c,...t){return{def:c,values:t[0]??ht}}function j(c){return typeof c=="function"?c:c.def}function Y(c){return typeof c=="function"?ht:c.values}class B extends Error{constructor(t){super(t),this.name="StoreRestoreError"}}function Lt(c){const t=c.view.getUint32(h.STORE_HEADER_OFFSETS.capacity,!0);return new Uint8Array(c.buffer,0,t)}function Bt(c,t=U.DEFAULT_SAB_ALLOCATOR){const e=new DataView(c.buffer,c.byteOffset,c.byteLength);if(c.byteLength<h.STORE_HEADER_BYTES)throw new B(`snapshot too small: ${c.byteLength} bytes (header alone needs ${h.STORE_HEADER_BYTES})`);const s=e.getUint32(h.STORE_HEADER_OFFSETS.magic,!0);if(s!==h.STORE_MAGIC)throw new B(`bad magic: 0x${s.toString(16).padStart(8,"0")} (expected 0x${h.STORE_MAGIC.toString(16).padStart(8,"0")})`);const n=e.getUint32(h.STORE_HEADER_OFFSETS.sim_abi_version,!0);if(n!==h.SIM_ABI_VERSION)throw new B(`incompatible sim_abi_version: snapshot=${n}, build=${h.SIM_ABI_VERSION}`);const r=t(c.byteLength);new Uint8Array(r).set(c);const i=new DataView(r),o=h.readStoreHeader(i);if(o.layoutDescriptorOff<0||o.layoutDescriptorOff>r.byteLength)throw new B(`layout_descriptor_off ${o.layoutDescriptorOff} is outside the snapshot (${r.byteLength} bytes)`);try{const a=h.readLayoutDescriptorRegion(i,o.layoutDescriptorOff,o.archetypeCount),l=h.buildArchetypeViews(r,a);return{buffer:r,view:i,header:o,archetypes:l}}catch(a){throw a instanceof RangeError?new B(`snapshot layout is corrupt or truncated: a descriptor offset or column extent reads past the ${r.byteLength}-byte buffer (${a.message})`):a}}const Gt=c=>h.validateAndCast(c);class $t{fieldNames;columns;reader;_readerLen;constructor(t){this.fieldNames=t,this.columns=[];for(let n=0;n<t.length;n++)this.columns.push([]);const e={};for(let n=0;n<t.length;n++)e[t[n]]=this.columns[n];const s={length:0,...e};this._readerLen=s,this.reader=s}emit(t){const e=this.fieldNames,s=this.columns;for(let n=0;n<e.length;n++)s[n].push(t[e[n]]);this._readerLen.length++}emitSignal(){this._readerLen.length++}clear(){this._readerLen.length=0;const t=this.columns;for(let e=0;e<t.length;e++)t[e].length=0}}function Pt(c){return h.unsafeCast(Symbol(c))}function Ut(c){return h.unsafeCast(Symbol(c))}class Ht{channels=[];dirtyChannels=[];count=0;keyMap=new Map;registerEvent(t){const e=Gt(this.count++),s=new $t(t);return this.channels.push(s),h.unsafeCast(e)}emitEvent(t,e){const s=t,n=this.channels[s],r=n.reader.length===0;n.emit(e),r&&this.dirtyChannels.push(s)}emitSignal(t){const e=t,s=this.channels[e],n=s.reader.length===0;s.emitSignal(),n&&this.dirtyChannels.push(e)}getEventReader(t){return this.channels[t].reader}clearEvents(){const t=this.dirtyChannels,e=this.channels;for(let s=0;s<t.length;s++)e[t[s]].clear();t.length=0}devBufferedEventCount(){const t=this.dirtyChannels,e=this.channels;let s=0;for(let n=0;n<t.length;n++)s+=e[t[n]].reader.length;return s}registerEventByKey(t,e){if(this.keyMap.has(t))throw new h.ECSError(h.ECS_ERROR.EVENT_ALREADY_REGISTERED,`event '${t.description??"<unnamed>"}' is already registered`,{event:t.description});const s=this.registerEvent(e);return this.keyMap.set(t,s),s}getEventDefByKey(t){const e=this.keyMap.get(t);if(e===void 0)throw new h.ECSError(h.ECS_ERROR.EVENT_NOT_REGISTERED,`event '${t.description??"<unnamed>"}' is not registered — call ecs.events.register(key, fields) at world setup`,{event:t.description});return e}hasEventKey(t){return this.keyMap.has(t)}}class Vt{map=new Map;register(t,e){if(this.map.has(t))throw new h.ECSError(h.ECS_ERROR.RESOURCE_ALREADY_REGISTERED,`resource '${t.description??"<unnamed>"}' is already registered — remove() it first if you meant to replace it`,{resource:t.description});this.map.set(t,e)}get(t){if(!this.map.has(t))throw new h.ECSError(h.ECS_ERROR.RESOURCE_NOT_REGISTERED,`resource read: '${t.description??"<unnamed>"}' is not registered — call ecs.resources.register(key, value) at world setup`,{resource:t.description});return this.map.get(t)}set(t,e){if(!this.map.has(t))throw new h.ECSError(h.ECS_ERROR.RESOURCE_NOT_REGISTERED,`resource write: '${t.description??"<unnamed>"}' is not registered — call ecs.resources.register(key, value) at world setup`,{resource:t.description});this.map.set(t,e)}remove(t){if(!this.map.has(t))throw new h.ECSError(h.ECS_ERROR.RESOURCE_NOT_REGISTERED,`resource remove: '${t.description??"<unnamed>"}' is not registered — call ecs.resources.register(key, value) at world setup`,{resource:t.description});this.map.delete(t)}has(t){return this.map.has(t)}}class q extends Error{capacity;requested;constructor(t,e){super(`BufferBackedColumn overflow: requested length ${e} exceeds capacity ${t}`),this.name="StoreColumnOverflowError",this.capacity=t,this.requested=e}}class qt{_buf;_capacity;_len=0;constructor(t){this._buf=t,this._capacity=t.length}refreshView(t){if(t.length<this._len)throw new q(t.length,this._len);this._buf=t,this._capacity=t.length}get length(){return this._len}get capacity(){return this._capacity}push(t){if(this._len>=this._capacity)throw new q(this._capacity,this._len+1);this._buf[this._len++]=t}pop(){return this._buf[--this._len]}get(t){return this._buf[t]}setAt(t,e){this._buf[t]=e}swapRemove(t){const e=this._buf[t];return this._buf[t]=this._buf[--this._len],e}clear(){this._len=0}setLength(t){if(t>this._capacity)throw new q(this._capacity,t);this._len=t}get buf(){return this._buf}view(){return this._buf.subarray(0,this._len)}[Symbol.iterator](){let t=0;const e=this._buf,s=this._len;return{next(){return t<s?{value:e[t++],done:!1}:{value:0,done:!0}}}}ensureCapacity(t){if(t>this._capacity)throw new q(this._capacity,t)}bulkAppend(t,e,s){this.ensureCapacity(this._len+s),this._buf.set(t.subarray(e,e+s),this._len),this._len+=s}bulkAppendZeroes(t){this.ensureCapacity(this._len+t),this._buf.fill(0,this._len,this._len+t),this._len+=t}bulkAppendValue(t,e){this.ensureCapacity(this._len+e),this._buf.fill(t,this._len,this._len+e),this._len+=e}}const ut=c=>h.validateAndCast(c);class at{id;mask;hasColumns;materializesRows;_entityIds;length=0;enabledCount=0;_flushSeenEpoch=-1;_flushPreLen=0;_flushPreEnabled=0;_iterDepth=0;edges=[];batchTransitionMaps=new Map;compositeAddEdges=null;_flatColumns=[];_storeArchetypeId=null;_colOffset=[];_fieldCount=[];_fieldIndex=[];_fieldNames=[];columnGroups=[];_columnIds=[];_changedTick=[];_mutGroupCache=[];_readGroupCache=[];growHandler=null;constructor(t,e,s,n=h.DEFAULT_COLUMN_CAPACITY,r){if(this.id=t,this.mask=e,this._entityIds=new T.GrowableUint32Array(n),s){let i=0;for(let o=0;o<s.length;o++){const a=s[o],l=a.componentId,u=new Array(a.fieldNames.length);if(this._colOffset[l]=i,this._fieldCount[l]=a.fieldNames.length,this._fieldIndex[l]=a.fieldIndex,this._fieldNames[l]=a.fieldNames,a.fieldNames.length>0&&!r)throw new h.ECSError(h.ECS_ERROR.COMPONENT_NOT_REGISTERED,`Archetype ${t}: layouts with fields require a columnFactory — use Archetype.fromColumnStore for SAB-backed columns, or pass a heap factory explicitly in tests`);for(let d=0;d<a.fieldNames.length;d++){const f=a.fieldTypes[d],p=r(a.componentId,d,f);u[d]=p,this._flatColumns[i++]=p}this.columnGroups[l]={layout:a,columns:u},this._columnIds.push(l),this._changedTick[l]=0}}this.hasColumns=this._columnIds.length>0,this.materializesRows=!e.isEmpty()}static fromColumnStore(t,e,s,n,r){const i=n.archetypes.get(r);if(!i)throw new h.ECSError(h.ECS_ERROR.COMPONENT_NOT_REGISTERED,`ColumnStore has no archetype ${r}`);const o=(l,u)=>{const d=i.columns.get(h.columnKey(l,u));if(!d)throw new h.ECSError(h.ECS_ERROR.COMPONENT_NOT_REGISTERED,`ColumnStore archetype ${r} has no column for (${l}, ${u})`);return new qt(d.view)},a=new at(t,e,s,i.rowCapacity,o);return a._storeArchetypeId=r,a}get isBufferBacked(){return this._storeArchetypeId!==null}refreshViews(t){if(this._storeArchetypeId===null)throw new h.ECSError(h.ECS_ERROR.COMPONENT_NOT_REGISTERED,`Archetype ${this.id} is not SAB-backed`);const e=t.archetypes.get(this._storeArchetypeId);if(!e)throw new h.ECSError(h.ECS_ERROR.COMPONENT_NOT_REGISTERED,`new ColumnStore has no archetype ${this._storeArchetypeId}`);const s=e.columnsInOrder,n=this._flatColumns;for(let r=0;r<s.length;r++)n[r].refreshView(s[r].view)}get entityCount(){return et?this.length:this.enabledCount}get totalCount(){return this.length}get disabledCount(){return this.length-this.enabledCount}get entityIds(){return this._entityIds.buf}swapRows(t,e){if(t===e)return;const s=this._entityIds.buf,n=s[t];s[t]=s[e],s[e]=n;const r=this._flatColumns;for(let i=0;i<r.length;i++){const o=r[i].buf,a=o[t];o[t]=o[e],o[e]=a}}_placeTail(t,e){const s=this.enabledCount;if(s===t)return this.enabledCount=t+1,t;if(this.swapRows(s,t),e!==void 0){const n=this._entityIds.buf;e[h.getEntityIndex(n[t])]=t}return this.enabledCount=s+1,s}_placeTailBulk(t,e){return this.enabledCount+=e,t}disableRow(t,e){const s=this.enabledCount-1;if(t!==s){this.swapRows(t,s);const n=this._entityIds.buf;e[h.getEntityIndex(n[t])]=t,e[h.getEntityIndex(n[s])]=s}this.enabledCount=s}enableRow(t,e){const s=this.enabledCount;if(t!==s){this.swapRows(t,s);const n=this._entityIds.buf;e[h.getEntityIndex(n[t])]=t,e[h.getEntityIndex(n[s])]=s}this.enabledCount=s+1}removeRow(t,e){if(this.enabledCount===this.length){const s=this._entityIds.buf,n=this.length-1;if(t!==n){if(s[t]=s[n],this.hasColumns){const r=this._flatColumns;for(let i=0;i<r.length;i++)r[i].swapRemove(t)}e[h.getEntityIndex(s[t])]=t}else if(this.hasColumns){const r=this._flatColumns;for(let i=0;i<r.length;i++)r[i].pop()}this._entityIds.pop(),this.length=n,this.enabledCount=n;return}this._removeRowPartitioned(t,e)}_removeRowPartitioned(t,e){const s=this._entityIds.buf,n=this.hasColumns,r=this.enabledCount,i=this.length-1;if(t>=r){if(t!==i){if(s[t]=s[i],n){const a=this._flatColumns;for(let l=0;l<a.length;l++)a[l].swapRemove(t)}e[h.getEntityIndex(s[t])]=t}else if(n){const a=this._flatColumns;for(let l=0;l<a.length;l++)a[l].pop()}this._entityIds.pop(),this.length--;return}const o=r-1;if(t!==o&&(this.swapRows(t,o),e[h.getEntityIndex(s[t])]=t),o!==i){if(s[o]=s[i],n){const a=this._flatColumns;for(let l=0;l<a.length;l++)a[l].swapRemove(o)}e[h.getEntityIndex(s[o])]=o}else if(n){const a=this._flatColumns;for(let l=0;l<a.length;l++)a[l].pop()}this._entityIds.pop(),this.length--,this.enabledCount=o}get entityList(){return this._entityIds.view()}hasComponent(t){return this.mask.has(t)}matches(t){return this.mask.contains(t)}getColumnRead(t,e){const s=t.id,n=this._fieldIndex[s][e];return this._flatColumns[this._colOffset[s]+n].buf}getColumnsRead(t,...e){return e.map(n=>this.getColumnRead(t,n))}getOptionalColumnRead(t,e){const s=t.id,n=this._colOffset[s];if(n===void 0)return;const r=this._fieldIndex[s][e];return this._flatColumns[n+r].buf}getColumn(t,e,s){const n=t.id;this._changedTick[n]=s;const r=this._fieldIndex[n][e];return this._flatColumns[this._colOffset[n]+r].buf}columnGroupMut(t,e){const s=t.id;this._changedTick[s]=e;const n=this._colOffset[s],r=this._fieldNames[s],i=this._flatColumns;let o=this._mutGroupCache[s];o===void 0&&(o={},this._mutGroupCache[s]=o);for(let a=0;a<r.length;a++)o[r[a]]=i[n+a].buf;return o}columnGroupRead(t){const e=t.id,s=this._colOffset[e],n=this._fieldNames[e],r=this._flatColumns;let i=this._readGroupCache[e];i===void 0&&(i={},this._readGroupCache[e]=i);for(let o=0;o<n.length;o++)i[n[o]]=r[s+o].buf;return i}writeFields(t,e,s,n){const r=e,i=this._colOffset[r];if(i===void 0)return;this._changedTick[r]=n;const o=this._fieldNames[r],a=this._flatColumns;for(let l=0;l<o.length;l++)a[i+l].buf[t]=s[o[l]]??0}bulkWriteFields(t,e,s,n,r){const i=s,o=this._colOffset[i];if(o===void 0)return;this._changedTick[i]=r;const a=this._fieldNames[i],l=this._flatColumns,u=t+e;for(let d=0;d<a.length;d++)l[o+d].buf.fill(n[a[d]]??0,t,u)}writeFieldsPositional(t,e,s,n){const r=e,i=this._colOffset[r];if(i===void 0)return;this._changedTick[r]=n;const o=this._flatColumns;for(let a=0;a<s.length;a++)o[i+a].buf[t]=s[a]}readField(t,e,s){const n=e,r=this._colOffset[n];if(r===void 0)return NaN;const i=this._fieldIndex[n][s];return i===void 0?NaN:this._flatColumns[r+i].buf[t]}copySharedFrom(t,e,s,n){const r=t._colOffset,i=t._fieldCount,o=t._flatColumns,a=this._flatColumns,l=this._columnIds;for(let u=0;u<l.length;u++){const d=l[u],f=r[d];if(f===void 0)continue;this._changedTick[d]=n;const p=this._colOffset[d],y=i[d];for(let g=0;g<y;g++)a[p+g].buf[s]=o[f+g].buf[e]}}addEntity(t,e){const s=this._flatColumns;s.length>0&&this.length>=s[0].buf.length&&this.growHandler!==null&&this.growHandler(this,1);const n=this.length;this._entityIds.push(t);for(let r=0;r<s.length;r++)s[r].push(0);return this.length++,this._placeTail(n,e)}removeEntity(t){const e=this.length-1;let s=h.NO_SWAP;const n=this._flatColumns,r=this._entityIds.buf;if(t!==e){r[t]=r[e],s=h.getEntityIndex(r[t]);for(let i=0;i<n.length;i++)n[i].swapRemove(t)}else for(let i=0;i<n.length;i++)n[i].pop();return this._entityIds.pop(),this.length--,t<this.enabledCount&&this.enabledCount--,s}addEntityTag(t,e){const s=this.length;return this._entityIds.push(t),this.length++,this._placeTail(s,e)}addEntities(t,e=t.length){if(e===0)return this.length;const s=this._flatColumns;s.length>0&&this.length+e>s[0].buf.length&&this.growHandler!==null&&this.growHandler(this,e);const n=this.length;this._entityIds.bulkAppend(t,0,e);for(let r=0;r<s.length;r++)s[r].bulkAppendZeroes(e);return this.length+=e,this._placeTailBulk(n,e)}addEntitiesTag(t,e=t.length){if(e===0)return this.length;const s=this.length;return this._entityIds.bulkAppend(t,0,e),this.length+=e,this._placeTailBulk(s,e)}ensureRowCapacity(t){const e=this._flatColumns;e.length>0&&this.length+t>e[0].buf.length&&this.growHandler!==null&&this.growHandler(this,t)}addEntityWithValues(t,e,s,n){const r=this._flatColumns;r.length>0&&this.length>=r[0].buf.length&&this.growHandler!==null&&this.growHandler(this,1);const i=this.length;this._entityIds.push(t);for(let a=0;a<r.length;a++)r[a].push(e[a]);this.length++;const o=this._columnIds;for(let a=0;a<o.length;a++)this._changedTick[o[a]]=s;return this._placeTail(i,n)}addEntitiesWithValues(t,e,s,n){if(e===0)return this.length;const r=this._flatColumns;r.length>0&&this.length+e>r[0].buf.length&&this.growHandler!==null&&this.growHandler(this,e);const i=this.length;this._entityIds.bulkAppend(t,0,e);for(let a=0;a<r.length;a++)r[a].bulkAppendValue(s[a],e);this.length+=e;const o=this._columnIds;for(let a=0;a<o.length;a++)this._changedTick[o[a]]=n;return this._placeTailBulk(i,e)}removeEntityTag(t){const e=this.length-1;let s=h.NO_SWAP;const n=this._entityIds.buf;return t!==e&&(n[t]=n[e],s=h.getEntityIndex(n[t])),this._entityIds.pop(),this.length--,t<this.enabledCount&&this.enabledCount--,s}moveEntityFrom(t,e,s,n,r,i){const o=e>=t.enabledCount;if(!this.materializesRows){t.removeRow(e,i),A[0]=h.UNASSIGNED,A[1]=h.NO_SWAP;return}const a=this._flatColumns;a.length>0&&this.length>=a[0].buf.length&&this.growHandler!==null&&this.growHandler(this,1);const l=this.length;this._entityIds.push(s);const u=t._flatColumns;for(let p=0;p<a.length;p++){const y=n[p];a[p].push(y>=0?u[y].buf[e]:0)}const d=this._columnIds;for(let p=0;p<d.length;p++)this._changedTick[d[p]]=r;this.length++;const f=o?l:this._placeTail(l,i);t.removeRow(e,i),A[0]=f,A[1]=h.NO_SWAP}moveEntityFromTag(t,e,s,n){const r=e>=t.enabledCount;if(!this.materializesRows){t.removeRow(e,n),A[0]=h.UNASSIGNED,A[1]=h.NO_SWAP;return}const i=this.length;this._entityIds.push(s),this.length++;const o=r?i:this._placeTail(i,n);t.removeRow(e,n),A[0]=o,A[1]=h.NO_SWAP}bulkMoveAllFrom(t,e,s){const n=t.length;if(n===0)return this.length;const r=this._flatColumns;r.length>0&&this.length+n>r[0].buf.length&&this.growHandler!==null&&this.growHandler(this,n);const i=this.length,o=t._flatColumns;this._entityIds.bulkAppend(t._entityIds.buf,0,n);for(let l=0;l<r.length;l++){const u=e[l];u>=0?r[l].bulkAppend(o[u].buf,0,n):r[l].bulkAppendZeroes(n)}const a=this._columnIds;for(let l=0;l<a.length;l++)this._changedTick[a[l]]=s;return this.length+=n,this.enabledCount=i+t.enabledCount,t.clearRows(),i}clearRows(){this.length=0,this.enabledCount=0,this._entityIds.clear();const t=this._flatColumns;for(let e=0;e<t.length;e++)t[e].clear()}restoreHostRows(t,e){const s=t.length;this._entityIds.clear(),this._entityIds.ensureCapacity(s);for(let r=0;r<s;r++)this._entityIds.push(t[r]);const n=this._flatColumns;for(let r=0;r<n.length;r++)n[r].setLength(s);this.length=s,this.enabledCount=e}getEdge(t){return this.edges[t]}setEdge(t,e){this.edges[t]=e}getBatchTransitionMap(t){const e=this.batchTransitionMaps.get(t.id);if(e!==void 0)return e;const s=st(this,t);return this.batchTransitionMaps.set(t.id,s),s}getCompositeAddEdge(t){return this.compositeAddEdges===null?void 0:this.compositeAddEdges.get(t)}cacheCompositeAddEdge(t,e,s){(this.compositeAddEdges??=new Map).set(t,{target:e,map:s})}}const A=[0,h.NO_SWAP];let et=!1;function x(c){const t=et;return et=c,t}function st(c,t){const e=t._flatColumns,s=new Int16Array(e.length),n=t._columnIds,r=c._colOffset,i=t._colOffset,o=t._fieldCount;for(let a=0;a<n.length;a++){const l=n[a],u=i[l],d=o[l],f=r[l];if(f!==void 0)for(let p=0;p<d;p++)s[u+p]=f+p;else for(let p=0;p<d;p++)s[u+p]=-1}return s}const bt=c=>h.validateAndCast(c),$=Object.freeze([]);function dt(c){return typeof c=="object"&&!Array.isArray(c)}function Wt(c){let t=$;c.spawns!==void 0&&c.spawns.length>0&&(t=c.spawns.map(s=>dt(s)?s.defs:s));let e=$;if(c.despawns!==void 0&&c.despawns.length>0){const s=[];for(const n of c.despawns)dt(n)?s.push(...n.defs):s.push(n);e=s}return{reads:c.reads,writes:c.writes,spawns:t,despawns:e,transitions:c.transitions??$,resourceReads:c.resourceReads??$,resourceWrites:c.resourceWrites??$,sparseReads:c.sparseReads,sparseWrites:c.sparseWrites,relationReads:c.relationReads,relationWrites:c.relationWrites}}const nt=Object.freeze({reads:Object.freeze([]),writes:Object.freeze([]),spawns:Object.freeze([]),despawns:Object.freeze([]),transitions:Object.freeze([]),resourceReads:Object.freeze([]),resourceWrites:Object.freeze([]),sparseReads:Object.freeze([]),sparseWrites:Object.freeze([]),relationReads:Object.freeze([]),relationWrites:Object.freeze([])}),zt=Symbol.dispose??Symbol.for("Symbol.dispose"),X=(1<<20)-1;let jt=0;function Yt(c,t){const e={...nt,...t,id:bt(jt++),name:c,fn:Kt};return Object.freeze(e)}function Kt(){}function ft(c){const t=new Set;if(c)for(let e=0;e<c.length;e++)t.add(c[e].id);return t}function Xt(c){const t=(i,o)=>i.cid-o.cid||i.id-o.id,e=new Map,s=new Map;for(const i of c)e.set(i,[]),s.set(i,0);for(const i of c)if(i.writes.size!==0)for(const o of c){if(i===o)continue;let a=!1;for(const l of i.writes)if(o.reads.has(l)){a=!0;break}a&&(e.get(i).push(o),s.set(o,s.get(o)+1))}const n=c.filter(i=>s.get(i)===0).sort(t),r=[];for(;n.length>0;){const i=n.shift();r.push(i);for(const o of e.get(i)){const a=s.get(o)-1;s.set(o,a),a===0&&(n.push(o),n.sort(t))}}if(r.length!==c.length){const i=new Set(r);for(const o of c.slice().sort(t))i.has(o)||r.push(o)}return r}class Qt{constructor(t,e){this.store=t,this.ctx=e}entries=[];byCid=new Map;_topo=null;_addBuckets=new Map;_remBuckets=new Map;_disBuckets=new Map;_enaBuckets=new Map;_radixOut=[];_radixC0=new Int32Array(1024);_radixC1=new Int32Array(1024);_setDrainCache=new Map;get count(){return this.entries.length}descriptors(){const t=new Array(this.entries.length);for(let e=0;e<this.entries.length;e++)t[e]=this.entries[e].descriptor;return t}register(t,e){const s=t.id,n=e.granularity??"archetype",r=e.onSet!==void 0&&n==="entity",i=e.onSet!==void 0&&n!=="entity",o=e.access??{},a=Yt(e.name??`observer(${h.componentDebugName(t)??s})`,o),l={id:a.id,cid:s,def:t,onAdd:e.onAdd,onRemove:e.onRemove,onDisable:e.onDisable,onEnable:e.onEnable,onSetEntity:r?e.onSet:void 0,onSetArch:i?e.onSet:void 0,descriptor:a,writes:ft(o.writes),reads:ft(o.reads),yieldExisting:e.yieldExisting??!1,lastSetTick:0,disposed:!1};this.entries.push(l);let u=this.byCid.get(s);u===void 0&&(u=[],this.byCid.set(s,u)),u.push(l),this._topo=null,this._reconfigureComponent(s),l.yieldExisting&&l.onAdd!==void 0&&this._yieldExisting(l);const d=()=>this._dispose(l);return{dispose:d,[zt]:d}}_dispose(t){if(t.disposed)return;t.disposed=!0;const e=this.entries.indexOf(t);e>=0&&this.entries.splice(e,1);const s=this.byCid.get(t.cid);if(s!==void 0){const n=s.indexOf(t);n>=0&&s.splice(n,1),s.length===0&&this.byCid.delete(t.cid)}this._topo=null,this._reconfigureComponent(t.cid)}_reconfigureComponent(t){const e=this.byCid.get(t);let s=!1,n=!1,r=!1,i=!1,o=!1;if(e!==void 0)for(let a=0;a<e.length;a++){const l=e[a];l.onAdd!==void 0&&(s=!0),l.onRemove!==void 0&&(n=!0),l.onDisable!==void 0&&(r=!0),l.onEnable!==void 0&&(i=!0),l.onSetEntity!==void 0&&(o=!0)}this.store._configureComponentObservation(t,s,n,r,i,o)}getTopo(){return this._topo===null&&(this._topo=Xt(this.entries)),this._topo}dispatchStructural(t){this._bucket(t.addComp,t.addEid,t.addLen,this._addBuckets),this._bucket(t.remComp,t.remEid,t.remLen,this._remBuckets),this._bucket(t.disComp,t.disEid,t.disLen,this._disBuckets),this._bucket(t.enaComp,t.enaEid,t.enaLen,this._enaBuckets);const e=this.getTopo();for(let s=0;s<e.length;s++){const n=e[s];if(!n.disposed){if(n.onRemove!==void 0){const r=this._remBuckets.get(n.cid);r!==void 0&&r.length>0&&this._fireEach(n,n.onRemove,r,"remove")}if(n.onAdd!==void 0){const r=this._addBuckets.get(n.cid);r!==void 0&&r.length>0&&this._fireEach(n,n.onAdd,r,"add")}if(n.onDisable!==void 0){const r=this._disBuckets.get(n.cid);r!==void 0&&r.length>0&&this._fireEach(n,n.onDisable,r,"disable")}if(n.onEnable!==void 0){const r=this._enaBuckets.get(n.cid);r!==void 0&&r.length>0&&this._fireEach(n,n.onEnable,r,"enable")}}}this._clearBuckets(this._addBuckets),this._clearBuckets(this._remBuckets),this._clearBuckets(this._disBuckets),this._clearBuckets(this._enaBuckets)}_fireEach(t,e,s,n){z(s,this._radixOut,this._radixC0,this._radixC1);try{const r=O?this.store._trace:null;for(let i=0;i<s.length;i++)e(h.unsafeCast(s[i]),this.ctx)}finally{}}_bucket(t,e,s,n){for(let r=0;r<s;r++){const i=t[r];let o=n.get(i);o===void 0&&(o=[],n.set(i,o)),o.push(e[r])}}_clearBuckets(t){for(const e of t.values())e.length=0}dispatchSet(t){if(this.entries.length===0)return;const e=this.getTopo(),s=this._setDrainCache;for(let n=0;n<e.length;n++){const r=e[n];r.onSetEntity!==void 0?this._dispatchSetEntity(r,s):r.onSetArch!==void 0&&this._dispatchSetArch(r,t)}for(const n of s.values())n.length=0;s.clear()}_dispatchSetEntity(t,e){let s=e.get(t.cid);if(s===void 0&&(s=this.store._takeDirty(t.cid),z(s,this._radixOut,this._radixC0,this._radixC1),e.set(t.cid,s)),s.length===0)return;const n=t.def,r=t.onSetEntity;try{for(let i=0;i<s.length;i++){const o=h.unsafeCast(s[i]);this.store.isAlive(o)&&this.store.hasComponent(o,n)&&!this.store.isDisabled(o)&&r(o,this.ctx)}}finally{}}_dispatchSetArch(t,e){const s=t.onSetArch,n=t.lastSetTick;try{this.store._forEachChangedArchetype(t.cid,n,r=>{s(r,this.ctx)})}finally{}t.lastSetTick=e+1}_yieldExisting(t){const e=t.onAdd,s=this.store._collectEntitiesWithComponent(t.cid);if(s.length!==0){z(s,this._radixOut,this._radixC0,this._radixC1);try{for(let n=0;n<s.length;n++)e(h.unsafeCast(s[n]),this.ctx)}finally{}}}}function z(c,t,e,s){const n=c.length;if(!(n<2)){t.length<n&&(t.length=n),e.fill(0),s.fill(0);for(let r=0;r<n;r++){const i=c[r]&X;e[i&1023]++,s[i>>10&1023]++}for(let r=1;r<1024;r++)e[r]+=e[r-1],s[r]+=s[r-1];for(let r=n-1;r>=0;r--){const i=c[r];t[--e[i&X&1023]]=i}for(let r=n-1;r>=0;r--){const i=t[r];c[--s[(i&X)>>10&1023]]=i}}}class Zt{constructor(t){this.host=t}relations=[];_hasTargetCleanup=!1;_hierarchyRadixOut=[];_hierarchyRadixC0=new Int32Array(1024);_hierarchyRadixC1=new Int32Array(1024);get stores(){return this.relations}get count(){return this.relations.length}get hasTargetCleanup(){return this._hasTargetCleanup}registerRelation(t){const e=t?.multi===!0,s=t?.exclusive===!0;if(e&&s)throw new h.ECSError(h.ECS_ERROR.RELATION_MODE_INVALID,"register_relation: a relation cannot be both exclusive and multi-target");const n=!e,r=t?.onDeleteTarget??h.DEFAULT_ON_DELETE_TARGET,i=n?this.host.pushSparseStore([h.RELATION_TARGET_FIELD],["f64"]):this.host.pushSparseStore([],[]),o=this.relations.length;return this.relations.push(h.makeRelationStore(n,i,this.host.sparseStoreOf(i),r)),r!=="orphan"&&(this._hasTargetCleanup=!0),h.unsafeCast(o)}relationOf(t){const e=t,s=this.relations[e];if(s===void 0)throw new h.ECSError(h.ECS_ERROR.RELATION_NOT_REGISTERED,`relation ${e} is not registered`);return s}addRelation(t,e,s){const n=this.relationOf(e);this.host.isAlive(t)&&this.host.isAlive(s)&&n.link(t,s)}removeRelation(t,e,s){const n=this.relationOf(e);this.host.isAlive(t)&&n.unlink(t,s)}targetOf(t,e){return this.relationOf(e).singleTarget(h.getEntityIndex(t))}targetsOf(t,e){return this.relationOf(e).targetsOf(h.getEntityIndex(t))}sourcesOf(t,e){return this.relationOf(e).sourcesOf(t)}hasRelation(t,e){return this.host.hasSparse(t,this.relationOf(e).sparse)}pairsOf(t){const e=this.relationOf(t),s=[],n=this.host.entityGenerations();return e.forEachCanonicalPair(r=>h.createEntityId(r,n[r]),(r,i)=>s.push([r,i])),s}sourcesOfAny(t){const e=[],s=this.relations;for(let n=0;n<s.length;n++){const r=h.unsafeCast(n),i=s[n].sourcesOf(t);for(let o=0;o<i.length;o++)e.push([r,i[o]])}return e}relationBackingSparseId(t){return this.relationOf(t).sparse}forEachRelationTargetMatch(t,e,s,n,r,i,o,a){const l=this.relations;if(l.length===0)return;const u=new Set;for(let E=0;E<l.length;E++){const _=l[E].sourcesOf(t);for(let m=0;m<_.length;m++)u.add(_[m])}if(u.size===0)return;const d=Array.from(u).sort((E,_)=>E-_),f=this.host.sparseStores(),p=this.host.entityArchetype(),y=this.host.entityRow(),g=this.host.archetypes();for(let E=0;E<d.length;E++){const _=h.unsafeCast(d[E]),m=h.getEntityIndex(_),S=p[m];if(S===h.UNASSIGNED)continue;const v=g[S],C=v.mask;if(!C.contains(e)||s!==null&&C.overlaps(s)||n!==null&&!C.overlaps(n))continue;let R=!0;for(let w=0;w<r.length;w++)if(!f[r[w]].has(m)){R=!1;break}if(R){for(let w=0;w<i.length;w++)if(f[i[w]].has(m)){R=!1;break}if(R){if(!o){const w=y[m];if(w!==h.UNASSIGNED&&w>=v.enabledCount)continue}a(_)}}}}compactRelations(){const t=this.relations;if(t.length===0)return 0;const e=n=>this.host.isAlive(n);let s=0;for(let n=0;n<t.length;n++)s+=t[n].pruneDeadReverse(e);return s}ancestorsOf(t,e){const s=this.relationOf(e),n=this.host.sparseStoreOf(s.sparse),r=[t],i=new Set([h.getEntityIndex(t)]);let o=t;for(;;){const a=n.getField(h.getEntityIndex(o),0);if(a===void 0)break;const l=h.unsafeCast(a);if(!this.host.isAlive(l)){r.push(l);break}const u=h.getEntityIndex(l);if(i.has(u))break;i.add(u),o=l,r.push(o)}return r}rootOf(t,e){const s=this.ancestorsOf(t,e);return s[s.length-1]}cascadeOf(t,e){const s=this.relationOf(e),n=[t],r=new Set([h.getEntityIndex(t)]);for(let i=0;i<n.length;i++){const o=s.sourcesOf(n[i]);for(let a=0;a<o.length;a++){const l=o[a],u=h.getEntityIndex(l);r.has(u)||(r.add(u),n.push(l))}}return n}purgeSource(t){const e=this.relations;for(let s=0;s<e.length;s++)e[s].purgeSource(t)}cleanupTarget(t,e){const s=this.relations;for(let n=0;n<s.length;n++){const r=s[n];if(r.onDeleteTarget==="orphan")continue;const i=r.sourcesOf(t);if(i.length!==0){if(r.onDeleteTarget==="delete"){for(let o=0;o<i.length;o++)e.push(i[o]);continue}for(let o=0;o<i.length;o++)r.unlink(i[o],t)}}}forEachHierarchyMatch(t,e,s,n,r,i,o,a,l,u){const d=this.relationOf(o),f=[];if(this.host.forEachSparseMatch(t,e,s,n,r,i,_=>f.push(_),l),f.length===0)return;z(f,this._hierarchyRadixOut,this._hierarchyRadixC0,this._hierarchyRadixC1);const p=this.host.sparseStoreOf(d.sparse),y=new Map,g=new Set,E=[];for(let _=0;_<f.length;_++){const m=f[_],S=this._hierarchyDepthOf(h.getEntityIndex(m),p,y,g);if(S>a)continue;let v=E[S];v===void 0&&(v=[],E[S]=v),v.push(m)}for(let _=0;_<E.length;_++){const m=E[_];if(m!==void 0)for(let S=0;S<m.length;S++)u(m[S])}}_hierarchyDepthOf(t,e,s,n){const r=[];let i=t,o=0;for(;;){const l=s.get(i);if(l!==void 0){o=l;break}const u=e.getField(i,0);let d=-1;if(u!==void 0){const f=h.unsafeCast(u);this.host.isAlive(f)&&(d=h.getEntityIndex(f))}if(d===-1){s.set(i,0),o=0;break}if(n.has(d)){s.set(i,0),o=0;break}r.push(i),n.add(i),i=d}let a=o;for(let l=r.length-1;l>=0;l--)a+=1,s.set(r[l],a),n.delete(r[l]);return s.get(t)}}class Jt{_generations;_lengthView;_highWater=0;_freeIndices=[];_aliveCount=0;_capacity;lastIndex=0;constructor(t,e,s){this._capacity=t,this._generations=e,this._lengthView=s}replantViews(t,e){this._generations=t,this._lengthView=e}get generations(){return this._generations}get highWater(){return this._highWater}get aliveCount(){return this._aliveCount}get freeCount(){return this._freeIndices.length}alloc(){let t,e;if(this._freeIndices.length>0)t=this._freeIndices.pop(),e=this._generations[t];else{if(this._highWater>=this._capacity)throw new h.ECSError(h.ECS_ERROR.EID_MAX_INDEX_OVERFLOW,`entityIndexCapacity (${this._capacity}) exhausted; raise it in ECSOptions.memory or destroy unused entities`);t=this._highWater++,this._generations[t]=h.INITIAL_GENERATION,e=h.INITIAL_GENERATION,this._lengthView[0]=this._highWater}return this._aliveCount++,this.lastIndex=t,h.createEntityId(t,e)}ensureCapacity(t){const e=t-this._freeIndices.length;if(e>0&&this._highWater+e>this._capacity)throw new h.ECSError(h.ECS_ERROR.EID_MAX_INDEX_OVERFLOW,`entityIndexCapacity (${this._capacity}) cannot fit ${t} new entities (${this._freeIndices.length} free, high-water ${this._highWater}); raise it in ECSOptions.memory or destroy unused entities`)}recycle(t,e){const s=e+1;s<h.RETIRED_GENERATION?(this._generations[t]=s,this._freeIndices.push(t)):this._generations[t]=h.RETIRED_GENERATION,this._aliveCount--}isAliveIndex(t,e){return t<this._highWater&&this._generations[t]===e}publishLength(){this._lengthView[0]=this._highWater}snapshotFreeIndices(){return this._freeIndices.slice()}setHighWater(t){this._highWater=t}restoreHostState(t,e){this._freeIndices.length=0;for(let s=0;s<t.length;s++)this._freeIndices.push(t[s]);this._aliveCount=e}}const pt=65536;class te{destroyIds=[];addIds=[];addDefs=[];addValues=[];removeIds=[];removeDefs=[];toggleIds=[];toggleDisable=[];_flushing=!1;host;obsEvents;constructor(t,e){this.host=t,this.obsEvents=e}queueDestroy(t){this.destroyIds.push(t)}queueAdd(t,e,s){this.addIds.push(t),this.addDefs.push(e),this.addValues.push(s)}queueRemove(t,e){this.removeIds.push(t),this.removeDefs.push(e)}queueToggle(t,e){this.toggleIds.push(t),this.toggleDisable.push(e)}get destroyCount(){return this.destroyIds.length}get structuralCount(){return this.addIds.length+this.removeIds.length}get toggleCount(){return this.toggleIds.length}flushDestroyed(){this._flushing||this.host.applyDestroys()}flushStructural(){if(this.host.structuralObserverCount()===0&&this.host.toggleObserverCount()===0){this.addIds.length>0&&this.host.applyAdds(),this.removeIds.length>0&&this.host.applyRemoves(),this.toggleIds.length>0&&this.host.applyToggles();return}if(this._flushing)return;this._flushing=!0;const t=this.obsEvents,e=this.host.structuralObserverHook();try{let s=0;for(;this.addIds.length>0||this.removeIds.length>0||this.destroyIds.length>0||this.toggleIds.length>0;){if(++s>pt)throw new h.ECSError(h.ECS_ERROR.OBSERVER_NON_CONVERGENT,`observer cascade did not converge after ${pt} rounds — two observers likely enqueue each other's structural ops forever`);t.addLen=0,t.remLen=0,t.disLen=0,t.enaLen=0,this.addIds.length>0||this.removeIds.length>0?(this.addIds.length>0&&this.host.applyAdds(),this.removeIds.length>0&&this.host.applyRemoves()):this.destroyIds.length>0?this.host.applyDestroys():this.host.applyToggles(),e!==null&&(t.addLen>0||t.remLen>0||t.disLen>0||t.enaLen>0)&&e(t)}}finally{this._flushing=!1}}}function It(c,t){let e=c;const s=new Array(t.length);for(let n=0;n<t.length;n++){const r=t[n],i=new Array(r.columns.length);for(let o=0;o<r.columns.length;o++){const a=r.columns[o];e=h.alignUp(e,a.stride),i[o]={componentId:a.componentId,fieldId:a.fieldId,typeTag:a.typeTag,byteOff:e,stride:a.stride},e+=a.stride*r.rowCapacity}s[n]={archetypeId:r.archetypeId,componentMask:r.componentMask,rowCount:0,enabledCount:0,rowCapacity:r.rowCapacity,columns:i}}if(e>h.STORE_MAX_BYTE_OFFSET)throw new h.StoreLayoutOverflowError(e);return{descriptors:s,newTotal:e}}function At(c,t){const e=c._allocator(t),s=e!==c.buffer?new DataView(e):c.view;return{grownBuffer:e,newView:s}}function ee(c){const t={};for(let n=0;n<h.STORE_PREFIX_REGIONS.length;n++){const r=h.STORE_PREFIX_REGIONS[n],i=c.view.getUint32(h.STORE_HEADER_OFFSETS[r.headerOff],!0);i!==0&&r.readOptions(c.view,i,t)}const e=h.readHeaderRegionTable(c.view);e.length>0&&(t.regions=e.map(n=>({id:n.regionId,name:`region:${n.regionId}`,bytes:n.byteLength,init:()=>{}})));const s=c.view.getUint32(h.STORE_HEADER_OFFSETS.bindings_off,!0);if(s!==0){const n=c.view.getUint32(h.STORE_HEADER_OFFSETS.layout_descriptor_off,!0);t.bindingsRegionBytes=n-s}return h.isColumnStoreInternal(c)&&c._reservedDescriptorBytes>0&&(t.reservedDescriptorBytes=c._reservedDescriptorBytes),t}function se(c){const t=new Map;for(let n=0;n<h.STORE_PREFIX_REGIONS.length;n++){const r=h.STORE_PREFIX_REGIONS[n],i=c.view.getUint32(h.STORE_HEADER_OFFSETS[r.headerOff],!0);if(i===0)continue;const o=r.regionBytes(c.view,i);t.set(r.headerOff,new Uint8Array(c.buffer,i,o).slice())}const e=new Map,s=h.readHeaderRegionTable(c.view);for(let n=0;n<s.length;n++){const r=s[n];e.set(r.regionId,new Uint8Array(c.buffer,r.byteOffset,r.byteLength).slice())}return{mechanism:t,consumer:e}}function ne(c,t){for(const[e,s]of t.mechanism){const n=c.view.getUint32(h.STORE_HEADER_OFFSETS[e],!0);new Uint8Array(c.buffer,n,s.byteLength).set(s)}for(const[e,s]of t.consumer){const n=h.findRegionOffset(c.view,e);if(n===0)continue;new Uint8Array(c.buffer,n,s.byteLength).set(s)}}function re(c,t){const e=new Map;for(const[s,n]of c.archetypes){const r=t.get(s)??0;if(r===0)continue;const i=[];for(let o=0;o<n.columnsInOrder.length;o++){const a=n.columnsInOrder[o],l=r*a.stride,u=new Uint8Array(l);u.set(new Uint8Array(a.view.buffer,a.view.byteOffset,l)),i.push(u)}e.set(s,i)}return e}function ie(c,t){for(const[e,s]of t){const n=c.archetypes.get(e);if(n===void 0)throw new Error(`restore_column_snapshots: new store missing archetype ${e} (internal)`);const r=n.columnsInOrder;for(let i=0;i<s.length;i++){const o=r[i].view;new Uint8Array(o.buffer,o.byteOffset,s[i].byteLength).set(s[i])}}}function Ot(c,t,e,s){const n=c.view.getUint32(h.STORE_HEADER_OFFSETS.view_stamp,!0),r=re(c,e),i=se(c),o=ee(c),a=h.createColumnStore(t,s,o);ie(a,r),ne(a,i);const l=n+1>>>0;return a.view.setUint32(h.STORE_HEADER_OFFSETS.view_stamp,l,!0),{store:{...a,header:{...a.header,viewStamp:l}},oldViewStamp:n,newViewStamp:l}}function oe(c,t,e){const s=new Array(t.length);for(let _=0;_<t.length;_++){const m=t[_],S=c.archetypes.get(m.archetypeId);s[_]={archetypeId:m.archetypeId,componentMask:S.componentMask,rowCapacity:m.newRowCapacity,columns:S.columnsInOrder}}const{descriptors:n,newTotal:r}=It(c.buffer.byteLength,s),i=new Map;for(let _=0;_<n.length;_++)i.set(n[_].archetypeId,n[_]);const{grownBuffer:o,newView:a}=At(c,r),l=new Uint8Array(o);for(let _=0;_<t.length;_++){const m=t[_],S=c.archetypes.get(m.archetypeId),v=i.get(m.archetypeId);for(let C=0;C<S.columnsInOrder.length;C++){const R=S.columnsInOrder[C],w=m.rowCount*R.stride;w>0&&l.copyWithin(v.columns[C].byteOff,R.byteOff,R.byteOff+w)}}let u=e;for(const[_,m]of c.archetypes){const S=i.get(_);S!==void 0&&h.writeArchetypeDescriptor(a,u,S),u+=h.archetypeDescriptorBytes(m.columnsInOrder.length)}const d=a.getUint32(h.STORE_HEADER_OFFSETS.view_stamp,!0),f=d+1>>>0;a.setUint32(h.STORE_HEADER_OFFSETS.view_stamp,f,!0),a.setUint32(h.STORE_HEADER_OFFSETS.capacity,r,!0);const p=h.buildArchetypeViews(o,[...i.values()]),y=new Map;for(const[_,m]of c.archetypes){const S=p.get(_);y.set(_,S??m)}const g={buffer:o,view:a,header:{...c.header,viewStamp:f,capacity:r},archetypes:y,_regionBytes:c._regionBytes,_allocator:c._allocator,_reservedDescriptorBytes:c._reservedDescriptorBytes},E=new Array(t.length);for(let _=0;_<t.length;_++)E[_]=t[_].archetypeId;return{store:g,oldViewStamp:d,newViewStamp:f,viewsPreserved:!0,grownArchetypeIds:E}}class Q extends Error{constructor(t){super(t),this.name="StoreGrowError"}}function he(c,t,e){const s=new Map;for(let u=0;u<t.archetypes.length;u++){const d=t.archetypes[u];s.set(d.archetypeId,d)}const n=[],r=[];for(const[u,d]of c.archetypes){const f=s.get(u),p=f?.newRowCapacity??d.rowCapacity;if(p<(f?.rowCount??0))throw new Q(`archetype ${u}: new_row_capacity ${p} < row_count ${f?.rowCount}`);if(p<d.rowCapacity)throw new Q(`archetype ${u}: shrinking from ${d.rowCapacity} to ${p} is not supported`);p>d.rowCapacity&&r.push({archetypeId:u,newRowCapacity:p,rowCount:f?.rowCount??0}),n.push({archetypeId:u,componentMask:d.componentMask,rowCapacity:p,columns:d.columnsInOrder})}const i=new Map;for(const[u,d]of c.archetypes){const p=s.get(u)?.rowCount??0;if(p>d.rowCapacity)throw new Q(`archetype ${u}: row_count ${p} > old row_capacity ${d.rowCapacity}`);p>0&&i.set(u,p)}if(e?.isInPlace===!0&&h.isColumnStoreInternal(c)&&c._allocator===e&&r.length>0){const u=c.view.getUint32(h.STORE_HEADER_OFFSETS.layout_descriptor_off,!0);return oe(c,r,u)}const{store:o,oldViewStamp:a,newViewStamp:l}=Ot(c,n,i,e);return{store:o,oldViewStamp:a,newViewStamp:l,viewsPreserved:!1,grownArchetypeIds:[]}}class L extends Error{constructor(t){super(t),this.name="StoreExtendError"}}function ae(c,t,e){if(t.newArchetypes.length===0)throw new L("extend plan has no new archetypes; use grow_column_store for resizes");const s=new Set;for(let l=0;l<t.newArchetypes.length;l++){const u=t.newArchetypes[l].archetypeId;if(s.has(u))throw new L(`duplicate archetype_id ${u} in extend plan`);if(c.archetypes.has(u))throw new L(`archetype_id ${u} already exists in the SAB; use grow_column_store to resize it`);s.add(u)}const n=new Map;if(t.existing)for(let l=0;l<t.existing.length;l++){const u=t.existing[l];if(!c.archetypes.has(u.archetypeId))throw new L(`existing row_count names unknown archetype_id ${u.archetypeId}`);if(u.rowCount<0)throw new L(`archetype ${u.archetypeId}: row_count must be non-negative (got ${u.rowCount})`);if(u.rowCount>0){const d=c.archetypes.get(u.archetypeId);if(u.rowCount>d.rowCapacity)throw new L(`archetype ${u.archetypeId}: row_count ${u.rowCount} > old row_capacity ${d.rowCapacity}`)}n.set(u.archetypeId,u.rowCount)}if(e?.isInPlace===!0&&h.isColumnStoreInternal(c)&&c._allocator===e){const l=c.view.getUint32(h.STORE_HEADER_OFFSETS.layout_descriptor_off,!0);let u=0;for(const[,f]of c.archetypes)u+=h.archetypeDescriptorBytes(f.columnsInOrder.length);let d=0;for(let f=0;f<t.newArchetypes.length;f++)d+=h.archetypeDescriptorBytes(t.newArchetypes[f].columns.length);if(u+d<=c._regionBytes)return ce(c,t.newArchetypes,l,u)}const r=[];for(const[l,u]of c.archetypes)r.push({archetypeId:l,componentMask:u.componentMask,rowCapacity:u.rowCapacity,columns:u.columnsInOrder});for(let l=0;l<t.newArchetypes.length;l++)r.push(t.newArchetypes[l]);const{store:i,oldViewStamp:o,newViewStamp:a}=Ot(c,r,n,e);return{store:i,oldViewStamp:o,newViewStamp:a,viewsPreserved:!1}}function ce(c,t,e,s){const n=new Array(t.length);for(let E=0;E<t.length;E++){const _=t[E];n[E]={archetypeId:_.archetypeId,componentMask:_.componentMask,rowCapacity:_.rowCapacity,columns:_.columns.map(m=>({componentId:m.componentId,fieldId:m.fieldId,typeTag:m.typeTag,stride:h.TYPE_TAG_STRIDE[m.typeTag]}))}}const{descriptors:r,newTotal:i}=It(c.buffer.byteLength,n),{grownBuffer:o,newView:a}=At(c,i);let l=e+s;for(let E=0;E<r.length;E++)l=h.writeArchetypeDescriptor(a,l,r[E]);const u=a.getUint32(h.STORE_HEADER_OFFSETS.view_stamp,!0),d=c.archetypes.size+t.length;a.setUint32(h.STORE_HEADER_OFFSETS.archetype_count,d,!0),a.setUint32(h.STORE_HEADER_OFFSETS.capacity,i,!0);const f=u+1>>>0;a.setUint32(h.STORE_HEADER_OFFSETS.view_stamp,f,!0);const p=h.buildArchetypeViews(o,r),y=new Map;for(const[E,_]of c.archetypes)y.set(E,_);for(const[E,_]of p)y.set(E,_);return{store:{buffer:o,view:a,header:{...c.header,viewStamp:f,capacity:i,archetypeCount:d},archetypes:y,_regionBytes:c._regionBytes,_allocator:c._allocator,_reservedDescriptorBytes:c._reservedDescriptorBytes},oldViewStamp:u,newViewStamp:f,viewsPreserved:!0}}const rt=810766935,K=1;class b extends Error{constructor(t){super(t),this.name="ECSRestoreError"}}const G=4;function le(c){const t=c.freeIndices.length,e=c.archetypeRows.length,s=G*(4+t+1+e*3),n=new Uint8Array(s),r=new DataView(n.buffer);let i=0;const o=a=>{r.setUint32(i,a,!0),i+=G};o(c.tick),o(c.entityHighWater),o(c.entityAliveCount),o(t);for(let a=0;a<t;a++)o(c.freeIndices[a]);o(e);for(let a=0;a<e;a++){const l=c.archetypeRows[a];o(l.archetypeId),o(l.length),o(l.enabledCount)}return n}function ue(c){const t=new DataView(c.buffer,c.byteOffset,c.byteLength),e=c.byteLength;let s=0;const n=p=>{if(s+p>e)throw new b(`host-state truncated: need ${p} more bytes at offset ${s}, have ${e-s}`)},r=()=>{n(G);const p=t.getUint32(s,!0);return s+=G,p},i=r(),o=r(),a=r(),l=r(),u=new Array(l);for(let p=0;p<l;p++)u[p]=r();const d=r(),f=new Array(d);for(let p=0;p<d;p++){const y=r(),g=r(),E=r();f[p]={archetypeId:y,length:g,enabledCount:E}}if(s!==e)throw new b(`host-state has ${e-s} trailing bytes after the last archetype (not a canonical encoding)`);return{tick:i,entityHighWater:o,entityAliveCount:a,freeIndices:u,archetypeRows:f}}function de(c,t,e){const s=G*5,n=new Uint8Array(s+c.length+t.length+e.length),r=new DataView(n.buffer);return r.setUint32(0,rt,!0),r.setUint32(4,K,!0),r.setUint32(8,c.length,!0),r.setUint32(12,t.length,!0),r.setUint32(16,e.length,!0),n.set(c,s),n.set(t,s+c.length),n.set(e,s+c.length+t.length),n}function fe(c){const t=G*5;if(c.byteLength<t)throw new b(`world snapshot too small: ${c.byteLength} bytes (frame header needs ${t})`);const e=new DataView(c.buffer,c.byteOffset,c.byteLength),s=e.getUint32(0,!0);if(s!==rt)throw new b(`bad world-snapshot magic: 0x${s.toString(16).padStart(8,"0")} (expected 0x${rt.toString(16).padStart(8,"0")}). A bare dense (SAB) snapshot is not a combined world snapshot — pass the bytes from ECS.snapshot(), not snapshotColumnStore().`);const n=e.getUint32(4,!0);if(n!==K)throw new b(`incompatible world-snapshot version: snapshot=${n}, build=${K}`);const r=e.getUint32(8,!0),i=e.getUint32(12,!0),o=e.getUint32(16,!0);if(t+r+i+o!==c.byteLength)throw new b(`world-snapshot frame mismatch: header declares ${t}+${r}+${i}+${o}=${t+r+i+o} bytes, buffer is ${c.byteLength}`);const a=c.byteOffset,l=c.buffer;return{dense:new Uint8Array(l,a+t,r),sparse:new Uint8Array(l,a+t+r,i),host:new Uint8Array(l,a+t+r+i,o)}}function pe(c,t,e){if(c.byteLength<h.STORE_HEADER_BYTES)throw new b(`dense section too small: ${c.byteLength} bytes (SAB header needs ${h.STORE_HEADER_BYTES})`);const s=new DataView(c.buffer,c.byteOffset,c.byteLength),n=s.getUint32(h.STORE_HEADER_OFFSETS.magic,!0);if(n!==h.STORE_MAGIC)throw new b(`dense section bad magic: 0x${n.toString(16).padStart(8,"0")} (expected SAB magic 0x${h.STORE_MAGIC.toString(16).padStart(8,"0")})`);const r=s.getUint32(h.STORE_HEADER_OFFSETS.sim_abi_version,!0);if(r!==h.SIM_ABI_VERSION)throw new b(`dense section incompatible sim_abi_version: snapshot=${r}, build=${h.SIM_ABI_VERSION}`);const i=h.readStoreHeader(s);if(i.layoutDescriptorOff<0||i.layoutDescriptorOff>c.byteLength)throw new b(`dense layoutDescriptorOff ${i.layoutDescriptorOff} is outside the section (${c.byteLength} bytes)`);const o=i.entityIndexOff;if(o<0||o+h.ENTITY_INDEX_HEADER_BYTES>c.byteLength)throw new b(`dense entityIndexOff ${o} is outside the section (${c.byteLength} bytes)`);const a=s.getUint32(o+h.ENTITY_INDEX_HEADER_OFFSETS.capacity,!0);if(a!==e)throw new b(`entity-index capacity mismatch: live=${e}, snapshot=${a}`);let l;try{l=h.readLayoutDescriptorRegion(s,i.layoutDescriptorOff,i.archetypeCount)}catch(u){throw u instanceof RangeError?new b(`dense section layout is corrupt or truncated: a descriptor reads past the ${c.byteLength}-byte section (${u.message})`):u}if(t.size!==l.length)throw new b(`archetype-set mismatch: the live world has ${t.size} SAB archetypes, the snapshot has ${l.length}. restoreInto requires an identical archetype set (prewarm the world so its archetype set is stable, per ADR on no-lazy archetypes).`);for(let u=0;u<l.length;u++){const d=l[u],f=t.get(d.archetypeId);if(f===void 0)throw new b(`archetype-set mismatch: snapshot archetype ${d.archetypeId} is absent from the live world`);if(!_e(f.componentMask,d.componentMask))throw new b(`archetype ${d.archetypeId} component-mask mismatch between the live world and the snapshot (different component registration)`);const p=f.columnsInOrder,y=d.columns;if(p.length!==y.length)throw new b(`archetype ${d.archetypeId} column-count mismatch: live=${p.length}, snapshot=${y.length}`);for(let g=0;g<p.length;g++)if(p[g].componentId!==y[g].componentId||p[g].fieldId!==y[g].fieldId||p[g].typeTag!==y[g].typeTag)throw new b(`archetype ${d.archetypeId} column ${g} layout mismatch: live=(c${p[g].componentId},f${p[g].fieldId},t${p[g].typeTag}), snapshot=(c${y[g].componentId},f${y[g].fieldId},t${y[g].typeTag})`)}}function _e(c,t){if(c.length!==t.length)return!1;for(let e=0;e<c.length;e++)if(c[e]!==t[e])return!1;return!0}class ge{host;allocator;constructor(t,e){this.host=t,this.allocator=e}snapshotSparse(){const t=h.snapshotSparseStores(this.host.sparseStores()),e=h.snapshotRelations(this.host.relationStores()),s=new Uint8Array(8+t.length+e.length),n=new DataView(s.buffer);return n.setUint32(0,t.length,!0),n.setUint32(4,e.length,!0),s.set(t,8),s.set(e,8+t.length),s}restoreSparse(t){const e=new DataView(t.buffer,t.byteOffset,t.byteLength);if(t.byteLength<8)throw new h.SparseRestoreError(`sparse snapshot truncated: need 8 header bytes, have ${t.byteLength}`);const s=e.getUint32(0,!0),n=e.getUint32(4,!0);if(8+s+n!==t.byteLength)throw new h.SparseRestoreError(`sparse snapshot frame mismatch: header declares 8+${s}+${n}=${8+s+n} bytes, buffer is ${t.byteLength}`);h.restoreSparseStores(this.host.sparseStores(),t.subarray(8,8+s)),this.rebuildRelationIndices(t.subarray(8+s,8+s+n))}rebuildRelationIndices(t){const e=this.host.generations(),s=r=>h.createEntityId(r,e[r]),n=this.host.relationStores();h.restoreRelations(n,t,s);for(let r=0;r<n.length;r++)n[r].rebuildReverseFromForward(s)}snapshot(){this.host.publishRowCounts();const t=new Uint8Array(Lt(this.host.columnStore())),e=this.snapshotSparse(),s=le(this.collectHostState());return de(t,e,s)}collectHostState(){const t=[],e=this.host.archetypes();for(let s=0;s<e.length;s++){const n=e[s];n.isBufferBacked&&t.push({archetypeId:n.id,length:n.length,enabledCount:n.enabledCount})}return{tick:this.host.tick(),entityHighWater:this.allocator.highWater,entityAliveCount:this.allocator.aliveCount,freeIndices:this.allocator.snapshotFreeIndices(),archetypeRows:t}}restoreInto(t){const e=fe(t),s=ue(e.host);pe(e.dense,this.host.columnStore().archetypes,this.host.entityIndexCapacity()),this.assertSparseSectionMatches(e.sparse);const n=Bt(e.dense,this.host.bufferAllocator());this.host.mountRestoredDense(n),this.host.reconstructHostRows(s),this.allocator.restoreHostState(s.freeIndices,s.entityAliveCount),this.host.setTick(s.tick),this.host.invalidateQueryCaches(),this.restoreSparse(e.sparse)}assertSparseSectionMatches(t){const e=new DataView(t.buffer,t.byteOffset,t.byteLength);if(t.byteLength<8)throw new h.SparseRestoreError(`sparse snapshot truncated: need 8 header bytes, have ${t.byteLength}`);const s=e.getUint32(0,!0),n=e.getUint32(4,!0);if(8+s+n!==t.byteLength)throw new h.SparseRestoreError(`sparse snapshot frame mismatch: header declares 8+${s}+${n}=${8+s+n} bytes, buffer is ${t.byteLength}`);h.validateSparseStores(this.host.sparseStores(),t.subarray(8,8+s))}}function Tt(c,t,e){const s=c.get(t);s!==void 0?s.push(e):c.set(t,[e])}class ye{archetypes=[];componentIndex=[];archetypeMap=new Map;nextArchetypeId=0;host;constructor(t){this.host=t}get(t){return this.archetypes[t]}getOrCreateFromMask(t){const e=t.hash(),s=this.lookup(t,e);if(s!==null)return s;const n=ut(this.nextArchetypeId++),r=this.buildLayouts(t);return this.host.extendStore([_t(n,t,r,this.host.initialCapacity())]),this.install(n,t,r,e),n}createManyFromMasks(t){const e=new Array(t.length),s=[],n=[],r=[],i=[];for(let a=0;a<t.length;a++){const l=t[a],u=l.hash(),d=this.lookup(l,u);if(d!==null){e[a]=d;continue}let f=!1;for(let y=0;y<s.length;y++)if(n[y]===u&&s[y].equals(l)){e[a]=i[y],f=!0;break}if(f)continue;const p=ut(this.nextArchetypeId++);s.push(l),n.push(u),r.push(this.buildLayouts(l)),i.push(p),e[a]=p}if(s.length===0)return e;const o=new Array(s.length);for(let a=0;a<s.length;a++)o[a]=_t(i[a],s[a],r[a],this.host.initialCapacity());this.host.extendStore(o);for(let a=0;a<s.length;a++)this.install(i[a],s[a],r[a],n[a]);return e}lookup(t,e){const s=this.archetypeMap.get(e);if(s===void 0)return null;for(let n=0;n<s.length;n++)if(this.archetypes[s[n]].mask.equals(t))return s[n];return null}buildLayouts(t){const e=[],s=this.host.componentMetas();return t.forEach(n=>{const r=n,i=s[r];i&&i.fieldNames.length>0&&e.push({componentId:r,fieldNames:i.fieldNames,fieldIndex:i.fieldIndex,fieldTypes:i.fieldTypes})}),e}install(t,e,s,n){const r=e.copy(),i=this.host.materialize(t,r,s);this.archetypes.push(i),Tt(this.archetypeMap,n,t),e.forEach(o=>{const a=o;let l=this.componentIndex[a];l===void 0&&(l=[],this.componentIndex[a]=l),l.push(t)}),this.host.fanIntoQueries(i)}resolveAdd(t,e){const s=this.get(t);if(s.mask.has(e))return t;const n=s.getEdge(e);if(n?.add!=null)return n.add;const r=this.getOrCreateFromMask(s.mask.copyWithSet(e));return this.cacheEdge(s,this.get(r),e),r}resolveRemove(t,e){const s=this.get(t);if(!s.mask.has(e))return t;const n=s.getEdge(e);if(n?.remove!=null)return n.remove;const r=this.getOrCreateFromMask(s.mask.copyWithClear(e));return this.cacheEdge(this.get(r),s,e),r}cacheEdge(t,e,s){const n=t.getEdge(s)??{add:null,remove:null,addMap:null,removeMap:null};n.add=e.id,n.addMap=st(t,e),t.setEdge(s,n);const r=e.getEdge(s)??{add:null,remove:null,addMap:null,removeMap:null};r.remove=t.id,r.removeMap=st(e,t),e.setEdge(s,r)}}function _t(c,t,e,s){const n=[];for(let o=0;o<e.length;o++){const a=e[o],l=a.fieldTypes;for(let u=0;u<l.length;u++)n.push({componentId:a.componentId,fieldId:u,typeTag:h.TYPED_ARRAY_TAG_TO_TYPE_TAG[l[u]]})}const r=t._words,i=new Array(h.COMPONENT_MASK_WORDS);for(let o=0;o<h.COMPONENT_MASK_WORDS;o++)i[o]=(r[o]??0)>>>0;return{archetypeId:c,componentMask:i,rowCapacity:s,columns:n}}const Ee=[],gt=-1,Z=new DataView(new ArrayBuffer(8)),yt=129,me=7,J=-1;class we{entityAllocator;componentMetas=[];componentCount=0;sparseStores=[];sparseNames=[];relationService;events=new Ht;archGraph;registeredQueries=[];emptyArchetypeId;entityArchetype;entityRow;_deferred;_snapshots;_tick=0;_trace=null;_structuralObserverCount=0;_toggleObserverCount=0;_obsEvents={addComp:[],addEid:[],addLen:0,remComp:[],remEid:[],remLen:0,disComp:[],disEid:[],disLen:0,enaComp:[],enaEid:[],enaLen:0};_structuralObserverHook=null;setStructuralObserverHook(t){this._structuralObserverHook=t}_collectDestroyEid=0;_collectDestroyRemoveBit=t=>{if(!this.componentMetas[t].obsRem)return;const e=this._obsEvents;e.remComp[e.remLen]=t,e.remEid[e.remLen]=this._collectDestroyEid,e.remLen++};_collectToggleEid=0;_collectDisableBit=t=>{if(!this.componentMetas[t].obsDisable)return;const e=this._obsEvents;e.disComp[e.disLen]=t,e.disEid[e.disLen]=this._collectToggleEid,e.disLen++};_collectEnableBit=t=>{if(!this.componentMetas[t].obsEnable)return;const e=this._obsEvents;e.enaComp[e.enaLen]=t,e.enaEid[e.enaLen]=this._collectToggleEid,e.enaLen++};_toggleInitial=new Map;_anyDirtyTracked=!1;_dirtyTrackedCids=[];_dirtyLists=[];_dirtyMarks=[];_rowCountsDirty=!1;_queryDirtyEpoch=0;initialCapacity;_scratchTargetMask=new T.BitSet;_columnStore;_growHandler=(t,e)=>{const s=t.id,n=this._columnStore.archetypes.get(s);if(n===void 0)throw new h.ECSError(h.ECS_ERROR.ARCHETYPE_NOT_FOUND,`grow_handler invoked on archetype ${s} which has no SAB region`);const r=n.rowCapacity,i=t.length+e;let o=r>0?r:1;for(;o<i;)o=o*2;const a=[],l=this.archGraph.archetypes;for(let d=0;d<l.length;d++){const f=l[d],p=this._columnStore.archetypes.get(f.id);p!==void 0&&a.push({archetypeId:f.id,newRowCapacity:f.id===s?o:p.rowCapacity,rowCount:f.hasColumns?f.length:0})}let u;try{u=he(this._columnStore,{archetypes:a},this._bufferAllocator)}catch(d){throw d instanceof U.StoreCapExceededError?this._capExceededError(d):d}if(this._columnStore=u.store,u.viewsPreserved){const d=u.grownArchetypeIds;for(let f=0;f<d.length;f++){const p=this.archGet(d[f]);p.isBufferBacked&&p.refreshViews(this._columnStore)}}else for(let d=0;d<l.length;d++)l[d].isBufferBacked&&l[d].refreshViews(this._columnStore);this._handleBufferResized()};_capExceededError(t){const e=this._capContext,s=this.entityAllocator.aliveCount,n=`SAB grow refused: requested ${t.requestedBytes} bytes exceeds `+(t.capBytes!==null?`the ${t.capBytes}-byte cap.`:"the backing's ceiling.");let r;if(e===void 0)r=` The ECS holds ${s} live entities (no sizing intent declared).`;else if(e.budgetEntities!==null){const i=(s/e.budgetEntities).toFixed(1);r=` Declared ${e.intentLabel}; the ECS holds ${s} live entities (${i}× the budget) — runaway entity creation upstream, or an under-declared budget. Raise the budget only if a ${s}-entity ECS is intended.`}else r=` Declared ${e.intentLabel}; the ECS holds ${s} live entities.`;return new h.ECSError(h.ECS_ERROR.STORE_CAP_EXCEEDED,n+r+` The cap is a hard ceiling with no grow-beyond fallback (#380) — diagnose growth before raising it. Caused by: ${t.message}`)}_bufferAllocator;_capContext;_onBufferResized;constructor(t){const e=typeof t=="number"?{initialCapacity:t}:t??{};if(this.initialCapacity=e.initialCapacity??h.DEFAULT_COLUMN_CAPACITY,this._bufferAllocator=e.bufferAllocator??U.growableSabAllocator(),this._bufferAllocator.isInPlace!==!0)throw new h.ECSError(h.ECS_ERROR.INVALID_MEMORY_OPTIONS,"Store requires an in-place SAB allocator (ADR-0008): the flush loops keep writing through hoisted entity-index views across grows, so a non-in-place allocator (e.g. DEFAULT_SAB_ALLOCATOR) corrupts the entity→row mapping. Use growable_sab_allocator / wasm_memory_allocator; non-in-place allocators are snapshot/test sizing utilities only.");this._capContext=e.capContext,this._onBufferResized=e.onBufferResized,this._entityIndexCapacity=e.entityIndexCapacity??h.ENTITY_INDEX_DEFAULT_CAPACITY,this._regions=e.regions,this._bindingsRegionBytes=e.bindingsRegionBytes??0,this._deterministic=e.deterministic??!1,this._deferred=new te({applyAdds:()=>this._flushAdds(),applyRemoves:()=>this._flushRemoves(),applyDestroys:()=>this._drainDestroyed(),applyToggles:()=>this._flushToggles(),structuralObserverCount:()=>this._structuralObserverCount,toggleObserverCount:()=>this._toggleObserverCount,structuralObserverHook:()=>this._structuralObserverHook},this._obsEvents),this.relationService=new Zt({isAlive:n=>this.isAlive(n),hasSparse:(n,r)=>this.hasSparse(n,r),pushSparseStore:(n,r)=>this._pushSparseStore(n,r),sparseStoreOf:n=>this.sparseStoreOf(n),sparseStores:()=>this.sparseStores,entityGenerations:()=>this.entityAllocator.generations,entityArchetype:()=>this.entityArchetype,entityRow:()=>this.entityRow,archetypes:()=>this.archGraph.archetypes,forEachSparseMatch:(n,r,i,o,a,l,u,d)=>this._forEachSparseMatch(n,r,i,o,a,l,u,d)}),this._columnStore=h.createColumnStore([],this._bufferAllocator,{reservedDescriptorBytes:64*1024,entityIndexCapacity:this._entityIndexCapacity,eventRingCapacitySlots:h.EVENT_RING_DEFAULT_CAPACITY_SLOTS,commandRingCapacitySlots:h.COMMAND_RING_DEFAULT_CAPACITY_SLOTS,actionRingCapacitySlots:h.ACTION_RING_DEFAULT_CAPACITY_SLOTS,regions:this._regions,bindingsRegionBytes:this._bindingsRegionBytes});const s=h.buildEntityIndexViews(this._columnStore.buffer,this._columnStore.header.entityIndexOff,this._entityIndexCapacity);this.entityArchetype=s.archetypes,this.entityRow=s.rows,this.entityAllocator=new Jt(this._entityIndexCapacity,s.generations,new Uint32Array(this._columnStore.buffer,this._columnStore.header.entityIndexOff+h.ENTITY_INDEX_HEADER_OFFSETS.length,1)),this._snapshots=new ge({sparseStores:()=>this.sparseStores,relationStores:()=>this.relationService.stores,generations:()=>this.entityAllocator.generations,archetypes:()=>this.archGraph.archetypes,columnStore:()=>this._columnStore,bufferAllocator:()=>this._bufferAllocator,entityIndexCapacity:()=>this._entityIndexCapacity,tick:()=>this._tick,setTick:n=>{this._tick=n},publishRowCounts:()=>this.publishRowCountsToDescriptor(),mountRestoredDense:n=>this._mountRestoredDense(n),reconstructHostRows:n=>this._reconstructHostRows(n),invalidateQueryCaches:()=>{this._queryDirtyEpoch++,this._rowCountsDirty=!0}},this.entityAllocator),this.archGraph=new ye({componentMetas:()=>this.componentMetas,initialCapacity:()=>this.initialCapacity,extendStore:n=>this._archExtendStoreWithNewSpecs(n),materialize:(n,r,i)=>this._materializeArchetype(n,r,i),fanIntoQueries:n=>this._fanIntoQueries(n)}),this.emptyArchetypeId=this.archGetOrCreateFromMask(new T.BitSet)}_entityIndexCapacity;_regions;_bindingsRegionBytes;_deterministic;get deterministic(){return this._deterministic}_requireDeterministic(t){if(!this._deterministic)throw new h.ECSError(h.ECS_ERROR.DETERMINISM_DISABLED,`${t} requires determinism — construct the Store/ECS with { deterministic: true }. The canonical-ordering determinism surface (state_hash / snapshot_sparse / restore_sparse) is opt-in; see ADR-0020.`)}_rejectNonDeterministicFields(t,e,s){if(this._deterministic)for(let n=0;n<e.length;n++){const r=e[n];if(r==="f32"||r==="f64")throw new h.ECSError(h.ECS_ERROR.NON_DETERMINISTIC_COLUMN_TYPE,`Cannot register ${s} field "${t[n]}" as "${r}" on a { deterministic: true } world: floating-point columns round differently across V8 / Bun / Zig (1-ULP IEEE-754), breaking cross-host state_hash agreement (ADR-0020). Use an integer type (e.g. "i32") — represent fractional quantities as fixed-point (Q16.16). Note the array shorthand defaults to "f64", so pass an explicit integer type there.`,{field:t[n],type:r,kind:s})}}_refreshEntityIndexViews(){const t=this._columnStore.view.getUint32(h.STORE_HEADER_OFFSETS.entity_index_off,!0),e=h.buildEntityIndexViews(this._columnStore.buffer,t,this._entityIndexCapacity);this.entityArchetype=e.archetypes,this.entityRow=e.rows,this.entityAllocator.replantViews(e.generations,new Uint32Array(this._columnStore.buffer,t+h.ENTITY_INDEX_HEADER_OFFSETS.length,1))}_handleBufferResized(){this._refreshEntityIndexViews(),this.entityAllocator.publishLength(),this._onBufferResized?.()}get columnStore(){return this._columnStore}regionOffset(t){return h.findRegionOffset(this._columnStore.view,t)}regionHandle(t){const e=h.findRegionEntry(this._columnStore.view,t);return e===null?null:{buffer:this._columnStore.buffer,view:this._columnStore.view,offset:e.byteOffset,bytes:e.byteLength}}publishRowCountsToDescriptor(){if(!this._rowCountsDirty)return;const t=this._columnStore.view;let e=t.getUint32(h.STORE_HEADER_OFFSETS.layout_descriptor_off,!0);const s=this.archGraph.archetypes;for(let n=0;n<s.length;n++){const r=s[n];if(!r.isBufferBacked)continue;const i=t.getUint32(e+h.ARCHETYPE_DESCRIPTOR_OFFSETS.column_count,!0);t.setUint32(e+h.ARCHETYPE_DESCRIPTOR_OFFSETS.row_count,r.hasColumns?r.length:0,!0),t.setUint32(e+h.ARCHETYPE_DESCRIPTOR_OFFSETS.enabled_count,r.hasColumns?r.enabledCount:0,!0),e+=h.ARCHETYPE_DESCRIPTOR_HEADER_BYTES+i*h.COLUMN_DESCRIPTOR_BYTES}this._rowCountsDirty=!1}stateHash(){this._requireDeterministic("state_hash()");let t=h.FNV1A_OFFSET_BASIS;const e=this.archGraph.archetypes;for(let r=0;r<e.length;r++){const i=e[r],o=i.id,a=i.length;if(t=h.fnv1aStepWord(t,o),t=h.fnv1aStepWord(t,a),t=h.fnv1aStepWord(t,i.enabledCount),a===0)continue;const l=i._flatColumns;for(let u=0;u<l.length;u++){const d=l[u].buf,f=a*d.BYTES_PER_ELEMENT,p=new Uint8Array(d.buffer,d.byteOffset,f),y=f>>>2;let g=0;for(let _=0;_<y;_++){const m=(p[g]|p[g+1]<<8|p[g+2]<<16|p[g+3]<<24)>>>0;t=(t^m)>>>0,t=Math.imul(t,h.FNV1A_PRIME),g+=4}const E=f&3;if(E!==0){let _=p[g];E>1&&(_|=p[g+1]<<8),E>2&&(_|=p[g+2]<<16),t=(t^_>>>0)>>>0,t=Math.imul(t,h.FNV1A_PRIME)}}}const s=this.sparseStores;for(let r=0;r<s.length;r++){const i=s[r];t=h.fnv1aStepWord(t,r),t=h.fnv1aStepWord(t,i.size);const o=i.canonicalIndices();for(let a=0;a<o.length;a++){const l=o[a];t=h.fnv1aStepWord(t,l);const u=i.getRow(l);for(let d=0;d<u.length;d++)Z.setFloat64(0,u[d],!0),t=h.fnv1aStepWord(t,Z.getUint32(0,!0)),t=h.fnv1aStepWord(t,Z.getUint32(4,!0))}}const n=this.relationService.stores;for(let r=0;r<n.length;r++){const i=n[r];i.exclusive||(t=h.fnv1aStepWord(t,r),i.forEachCanonicalTargetSet((o,a)=>{t=h.fnv1aStepWord(t,o),t=h.fnv1aStepWord(t,a.length);for(let l=0;l<a.length;l++)t=h.fnv1aStepWord(t,a[l])}))}return t>>>0}archGet(t){return this.archGraph.get(t)}entityIdAtRow(t,e){return this.archGet(t).entityIds[e]}archGetOrCreateFromMask(t){return this.archGraph.getOrCreateFromMask(t)}archCreateManyFromMasks(t){return this.archGraph.createManyFromMasks(t)}_archExtendStoreWithNewSpecs(t){const e=[],s=this.archGraph.archetypes;for(let r=0;r<s.length;r++){const i=s[r],o=this._columnStore.archetypes.get(i.id);o!==void 0&&e.push({archetypeId:i.id,newRowCapacity:o.rowCapacity,rowCount:i.hasColumns?i.length:0})}let n;try{n=ae(this._columnStore,{newArchetypes:t,existing:e},this._bufferAllocator)}catch(r){throw r instanceof U.StoreCapExceededError?this._capExceededError(r):r}if(this._columnStore=n.store,!n.viewsPreserved)for(let r=0;r<s.length;r++)s[r].isBufferBacked&&s[r].refreshViews(this._columnStore);this._handleBufferResized()}_materializeArchetype(t,e,s){const n=at.fromColumnStore(t,e,s,this._columnStore,t);return n.growHandler=this._growHandler,n}_fanIntoQueries(t){const e=this.registeredQueries;for(let s=0;s<e.length;s++){const n=e[s];t.matches(n.includeMask)&&(!n.excludeMask||!t.mask.overlaps(n.excludeMask))&&(!n.anyOfMask||t.mask.overlaps(n.anyOfMask))&&n.result.push(t)}}archResolveAdd(t,e){return this.archGraph.resolveAdd(t,e)}archResolveRemove(t,e){return this.archGraph.resolveRemove(t,e)}createEntity(){const t=this.entityAllocator.alloc(),e=this.entityAllocator.lastIndex;return this.entityArchetype[e]=this.emptyArchetypeId,this.entityRow[e]=h.UNASSIGNED,t}_allocEntity(){return this.entityAllocator.alloc()}_ensureEntityIndexCapacity(t){this.entityAllocator.ensureCapacity(t)}resolveTemplate(t){const e=new T.BitSet;for(let a=0;a<t.length;a++)e.set(t[a].def.id);const s=this.archGetOrCreateFromMask(e),n=this.archGet(s),r=new Array(n._flatColumns.length).fill(0),i=new Map,o=new Array(t.length);for(let a=0;a<t.length;a++){o[a]=t[a].def;const l=t[a].def.id,u=this.componentMetas[l];if(u===void 0)throw new h.ECSError(h.ECS_ERROR.COMPONENT_NOT_REGISTERED,`template: component ${l} is not registered`);const d=t[a].values??h.EMPTY_VALUES,f=n._colOffset[l];for(let p=0;p<u.fieldNames.length;p++){const y=u.fieldNames[p];r[f+p]=d[y]??0,i.set(y,i.has(y)?gt:f+p)}}return{archetypeId:s,flatValues:r,overrideIndex:i,defs:o}}_resolveOverrideColumn(t,e){const s=t.overrideIndex.get(e);return s===void 0||s===gt?-1:s}_applyOverrides(t,e,s,n){const r=t._flatColumns;for(const i in n){if(n[i]===void 0)continue;const o=this._resolveOverrideColumn(s,i);o>=0&&(r[o].buf[e]=n[i])}}_applyOverridesRange(t,e,s,n,r){const i=t._flatColumns;for(const o in r){if(r[o]===void 0)continue;const a=this._resolveOverrideColumn(n,o);a>=0&&i[a].buf.fill(r[o],e,e+s)}}spawn(t,e){const s=this.archGraph.archetypes[t.archetypeId];s.materializesRows&&s.ensureRowCapacity(1);const n=this._allocEntity(),r=this.entityAllocator.lastIndex;if(!s.materializesRows)return this.entityArchetype[r]=t.archetypeId,this.entityRow[r]=h.UNASSIGNED,n;const i=s.length,o=s.enabledCount,a=s.addEntityWithValues(n,t.flatValues,this._tick,this.entityRow);return e!==void 0&&this._applyOverrides(s,a,t,e),this.entityArchetype[r]=t.archetypeId,this.entityRow[r]=a,this._onArchGrow(s,i,o),n}spawnMany(t,e,s){if(e<=0)return[];const n=this.archGraph.archetypes[t.archetypeId];this._ensureEntityIndexCapacity(e),n.ensureRowCapacity(e);const r=new Array(e),i=new Uint32Array(e);for(let f=0;f<e;f++){const p=this._allocEntity();i[f]=p,r[f]=p}const o=this.entityArchetype,a=this.entityRow;if(!n.materializesRows){for(let f=0;f<e;f++){const p=h.getEntityIndex(r[f]);o[p]=t.archetypeId,a[p]=h.UNASSIGNED}return r}const l=n.length,u=n.enabledCount;if(n.disabledCount>0){for(let f=0;f<e;f++){const p=n.addEntityWithValues(r[f],t.flatValues,this._tick,a),y=h.getEntityIndex(r[f]);o[y]=t.archetypeId,a[y]=p,s!==void 0&&this._applyOverrides(n,p,t,s)}return this._onArchGrow(n,l,u),r}const d=n.addEntitiesWithValues(i,e,t.flatValues,this._tick);for(let f=0;f<e;f++){const p=h.getEntityIndex(r[f]);o[p]=t.archetypeId,a[p]=d+f}return s!==void 0&&this._applyOverridesRange(n,d,e,t,s),this._onArchGrow(n,l,u),r}destroyEntity(t){if(!this.isAlive(t))return;if(!this.relationService.hasTargetCleanup){this._destroyOne(t,null);return}const e=[t];for(let s=0;s<e.length;s++){const n=e[s];this.isAlive(n)&&this._destroyOne(n,e)}}_destroyOne(t,e){const s=h.getEntityIndex(t),n=this.entityRow[s];if(n!==h.UNASSIGNED){const r=this.archGet(this.entityArchetype[s]),i=r.length;r.removeRow(n,this.entityRow),this._onArchLenChange(r,i)}this.entityArchetype[s]=h.UNASSIGNED,this.entityRow[s]=h.UNASSIGNED,this.relationService.count>0&&(this.relationService.purgeSource(t),e!==null&&this.relationService.cleanupTarget(t,e)),this.sparseStores.length>0&&this._purgeSparse(s),this._anyDirtyTracked&&this._clearDirtyForIndex(s),this.entityAllocator.recycle(s,h.getEntityGeneration(t))}isAlive(t){if(t<0||t>h.MAX_ENTITY_ID)return!1;const e=h.getEntityGeneration(t);if(e===h.RETIRED_GENERATION)return!1;const s=h.getEntityIndex(t);return this.entityAllocator.isAliveIndex(s,e)}get entityCount(){return this.entityAllocator.aliveCount}_onArchLenChange(t,e){this._rowCountsDirty=!0,e===0!=(t.length===0)&&this._queryDirtyEpoch++}_onArchGrow(t,e,s){this._rowCountsDirty=!0,(e===0||s===0&&t.enabledCount!==0)&&this._queryDirtyEpoch++}_onArchEnabledChange(t,e){this._rowCountsDirty=!0,e===0!=(t.enabledCount===0)&&this._queryDirtyEpoch++}disableEntity(t){if(!this.isAlive(t))return;const e=h.getEntityIndex(t),s=this.entityRow[e];if(s===h.UNASSIGNED)return;const n=this.archGet(this.entityArchetype[e]);if(s>=n.enabledCount)return;const r=n.enabledCount;n.disableRow(s,this.entityRow),this._onArchEnabledChange(n,r)}enableEntity(t){if(!this.isAlive(t))return;const e=h.getEntityIndex(t),s=this.entityRow[e];if(s===h.UNASSIGNED)return;const n=this.archGet(this.entityArchetype[e]);if(s<n.enabledCount)return;const r=n.enabledCount;n.enableRow(s,this.entityRow),this._onArchEnabledChange(n,r)}isDisabled(t){if(!this.isAlive(t))return!1;const e=h.getEntityIndex(t),s=this.entityRow[e];if(s===h.UNASSIGNED)return!1;const n=this.archGet(this.entityArchetype[e]);return s>=n.enabledCount}_flushEpoch=0;_flushTouched=[];_settleFlushDirty(){const t=this._flushTouched;if(t.length===0)return;this._rowCountsDirty=!0;let e=!1;for(let s=0;s<t.length;s++){const n=t[s];(n._flushPreLen===0!=(n.length===0)||n._flushPreEnabled===0!=(n.enabledCount===0))&&(e=!0)}e&&this._queryDirtyEpoch++,t.length=0,this._flushEpoch++}destroyEntityDeferred(t){this._deferred.queueDestroy(t)}disableEntityDeferred(t){this._deferred.queueToggle(t,!0)}enableEntityDeferred(t){this._deferred.queueToggle(t,!1)}_flushToggles(){const t=this._deferred.toggleIds,e=this._deferred.toggleDisable,s=t.length;if(!(this._toggleObserverCount>0)){for(let i=0;i<s;i++){const o=t[i];this.isAlive(o)&&(e[i]?this.disableEntity(o):this.enableEntity(o))}t.length=0,e.length=0;return}const r=this._toggleInitial;for(let i=0;i<s;i++){const o=t[i];this.isAlive(o)&&(r.has(o)||r.set(o,this.isDisabled(o)))}for(let i=0;i<s;i++){const o=t[i];this.isAlive(o)&&(e[i]?this.disableEntity(o):this.enableEntity(o))}t.length=0,e.length=0;for(const[i,o]of r){if(!this.isAlive(i))continue;const a=this.isDisabled(i);o!==a&&this._collectToggle(i,a)}r.clear()}_collectToggle(t,e){const s=h.getEntityIndex(t);if(this.entityRow[s]===h.UNASSIGNED)return;const n=this.archGet(this.entityArchetype[s]);this._collectToggleEid=t,n.mask.forEach(e?this._collectDisableBit:this._collectEnableBit)}get pendingToggleCount(){return this._deferred.toggleCount}flushDestroyed(){this._deferred.flushDestroyed()}_drainDestroyed(){const t=this._deferred.destroyIds;if(t.length===0)return;const e=this.entityAllocator,s=this.entityArchetype,n=this.entityRow,r=e.generations,i=this.archGraph.archetypes,o=e.highWater;let a=!1,l=!1;const u=this.sparseStores.length>0,d=this.relationService.count>0,f=d&&this.relationService.hasTargetCleanup,p=this._anyDirtyTracked,y=this._structuralObserverCount>0;for(let g=0;g<t.length;g++){const E=t[g],_=E&h.INDEX_MASK,m=E>>h.INDEX_BITS;if(_>=o||r[_]!==m)continue;const S=n[_];if(S!==h.UNASSIGNED){const v=i[s[_]];y&&(this._collectDestroyEid=E,v.mask.forEach(this._collectDestroyRemoveBit)),v.removeRow(S,n),a=!0,v.length===0&&(l=!0)}d&&this.relationService.purgeSource(E),f&&this.relationService.cleanupTarget(E,t),u&&this._purgeSparse(_),p&&this._clearDirtyForIndex(_),s[_]=h.UNASSIGNED,n[_]=h.UNASSIGNED,e.recycle(_,m)}t.length=0,a&&(this._rowCountsDirty=!0,l&&this._queryDirtyEpoch++)}get pendingDestroyCount(){return this._deferred.destroyCount}addComponentDeferred(t,e,s){this._deferred.queueAdd(t,e,s??h.EMPTY_VALUES)}removeComponentDeferred(t,e){this._deferred.queueRemove(t,e)}flushStructural(){this._deferred.flushStructural()}_flushAdds(){const t=this._deferred.addIds,e=this._deferred.addDefs,s=this._deferred.addValues,n=t.length,r=this.entityArchetype,i=this.entityRow,o=this.entityAllocator.generations,a=this.archGraph.archetypes,l=this.componentMetas,u=this.entityAllocator.highWater,d=this._tick,f=this._flushEpoch,p=this._flushTouched,y=this._structuralObserverCount>0,g=this._obsEvents;for(let E=0;E<n;E++){const _=t[E],m=_&h.INDEX_MASK,S=_>>h.INDEX_BITS;if(m>=u||o[m]!==S)continue;const v=r[m],C=e[E].id,R=a[v],w=l[C];if(R.mask.has(C)){w.fieldNames.length>0&&R.writeFields(i[m],C,s[E],d);continue}const k=this.archResolveAdd(v,C),I=a[k],F=i[m],lt=!I.hasColumns&&!R.hasColumns;F!==h.UNASSIGNED&&R._flushSeenEpoch!==f&&(R._flushSeenEpoch=f,R._flushPreLen=R.length,R._flushPreEnabled=R.enabledCount,p.push(R)),I._flushSeenEpoch!==f&&(I._flushSeenEpoch=f,I._flushPreLen=I.length,I._flushPreEnabled=I.enabledCount,p.push(I));let V;if(F!==h.UNASSIGNED){if(lt)I.moveEntityFromTag(R,F,_,i);else{const Nt=R.getEdge(C);I.moveEntityFrom(R,F,_,Nt.addMap,d,i)}V=A[0]}else V=lt?I.addEntityTag(_,i):I.addEntity(_,i);w.fieldNames.length>0&&I.writeFields(V,C,s[E],d),r[m]=k,i[m]=V,y&&w.obsAdd&&(g.addComp[g.addLen]=C,g.addEid[g.addLen]=_,g.addLen++)}t.length=0,e.length=0,s.length=0,this._settleFlushDirty()}_flushRemoves(){const t=this._deferred.removeIds,e=this._deferred.removeDefs,s=t.length,n=this.entityArchetype,r=this.entityRow,i=this.entityAllocator.generations,o=this.archGraph.archetypes,a=this.entityAllocator.highWater,l=this._tick,u=this._flushEpoch,d=this._flushTouched,f=this.componentMetas,p=this._structuralObserverCount>0,y=this._obsEvents;for(let g=0;g<s;g++){const E=t[g],_=E&h.INDEX_MASK,m=E>>h.INDEX_BITS;if(_>=a||i[_]!==m)continue;const S=n[_],v=e[g].id,C=o[S];if(!C.mask.has(v))continue;const R=this.archResolveRemove(S,v),w=o[R],k=r[_],I=!w.hasColumns&&!C.hasColumns;if(C._flushSeenEpoch!==u&&(C._flushSeenEpoch=u,C._flushPreLen=C.length,C._flushPreEnabled=C.enabledCount,d.push(C)),w._flushSeenEpoch!==u&&(w._flushSeenEpoch=u,w._flushPreLen=w.length,w._flushPreEnabled=w.enabledCount,d.push(w)),I)w.moveEntityFromTag(C,k,E,r);else{const F=C.getEdge(v);w.moveEntityFrom(C,k,E,F.removeMap,l,r)}n[_]=R,r[_]=A[0],p&&f[v].obsRem&&(y.remComp[y.remLen]=v,y.remEid[y.remLen]=E,y.remLen++)}t.length=0,e.length=0,this._settleFlushDirty()}get pendingStructuralCount(){return this._deferred.structuralCount}_configureComponentObservation(t,e,s,n,r,i){const o=this.componentMetas[t];if(o===void 0)throw new h.ECSError(h.ECS_ERROR.COMPONENT_NOT_REGISTERED,`observe(): component ${t} is not registered`);const a=o.obsAdd||o.obsRem;o.obsAdd=e,o.obsRem=s;const l=e||s;a&&!l?this._structuralObserverCount--:!a&&l&&this._structuralObserverCount++;const u=o.obsDisable||o.obsEnable;o.obsDisable=n,o.obsEnable=r;const d=n||r;if(u&&!d?this._toggleObserverCount--:!u&&d&&this._toggleObserverCount++,i&&!o.trackDirty)o.trackDirty=!0,this._dirtyLists[t]===void 0&&(this._dirtyLists[t]=[],this._dirtyMarks[t]=new Uint8Array(Math.max(1,this.entityAllocator.generations.length))),this._dirtyTrackedCids.push(t),this._anyDirtyTracked=!0;else if(!i&&o.trackDirty){o.trackDirty=!1;const f=this._dirtyTrackedCids.indexOf(t);f>=0&&this._dirtyTrackedCids.splice(f,1),this._anyDirtyTracked=this._dirtyTrackedCids.length>0;const p=this._dirtyLists[t],y=this._dirtyMarks[t];if(p!==void 0&&y!==void 0){for(let g=0;g<p.length;g++)y[p[g]&h.INDEX_MASK]=0;p.length=0}}}_noteSet(t,e){const s=t.id,n=this.componentMetas[s];if(n===void 0||!n.trackDirty)return;const r=e&h.INDEX_MASK;let i=this._dirtyMarks[s];r>=i.length&&(i=this._growDirtyMarks(s,r)),i[r]===0&&(i[r]=1,this._dirtyLists[s].push(e))}_growDirtyMarks(t,e){const s=this._dirtyMarks[t];let n=Math.max(1,s.length);for(;n<=e;)n*=2;const r=new Uint8Array(n);return r.set(s),this._dirtyMarks[t]=r,r}_takeDirty(t){const e=this._dirtyLists[t];if(e===void 0||e.length===0)return Ee;this._dirtyLists[t]=[];const s=this._dirtyMarks[t];for(let n=0;n<e.length;n++)s[e[n]&h.INDEX_MASK]=0;return e}_clearDirtyForIndex(t){const e=this._dirtyTrackedCids;for(let s=0;s<e.length;s++){const n=this._dirtyMarks[e[s]];n!==void 0&&t<n.length&&(n[t]=0)}}_forEachChangedArchetype(t,e,s){const n=this.archGraph.componentIndex[t];if(n===void 0)return;const r=this.archGraph.archetypes;for(let i=0;i<n.length;i++){const o=r[n[i]];o.length>0&&o._changedTick[t]>=e&&s(o)}}_collectEntitiesWithComponent(t){const e=[],s=this.archGraph.componentIndex[t];if(s===void 0)return e;const n=this.archGraph.archetypes;for(let r=0;r<s.length;r++){const i=n[s[r]],o=i.entityIds;for(let a=0;a<i.enabledCount;a++)e.push(h.unsafeCast(o[a]))}return e}registerComponent(t,e){if(this.componentCount>=h.STORE_DESCRIPTOR_COMPONENT_LIMIT)throw new h.ECSError(h.ECS_ERROR.COMPONENT_LIMIT_EXCEEDED,`Cannot register more than ${h.STORE_DESCRIPTOR_COMPONENT_LIMIT} components: the SAB archetype descriptor mask is ${h.STORE_DESCRIPTOR_COMPONENT_LIMIT} bits wide. Widen the descriptor mask (descriptor.ts + abi.zig, a SIM_ABI_VERSION bump) to raise it.`,{componentCount:this.componentCount,limit:h.STORE_DESCRIPTOR_COMPONENT_LIMIT});const s=Object.keys(t),n=new Array(s.length),r=Object.create(null);for(let a=0;a<s.length;a++)r[s[a]]=a,n[a]=t[s[a]];this._rejectNonDeterministicFields(s,n,"component");const i=Rt(this.componentCount++);this.componentMetas.push({name:e,fieldNames:s,fieldIndex:r,fieldTypes:n,obsAdd:!1,obsRem:!1,obsDisable:!1,obsEnable:!1,trackDirty:!1});const o=vt(i);return e!==void 0&&h.setComponentDebugName(o,e),o}componentLabel(t){const e=this.componentMetas[t]?.name;return e!==void 0?`'${e}' (component ${t})`:`component ${t}`}fieldIdOf(t,e){const s=t.id,n=this.componentMetas[s];if(n===void 0)throw new h.ECSError(h.ECS_ERROR.COMPONENT_NOT_REGISTERED,`field_id_of: component ${s} is not registered`);const r=n.fieldIndex[e];if(r===void 0)throw new h.ECSError(h.ECS_ERROR.FIELD_NOT_REGISTERED,`field_id_of: component ${s} has no field "${e}"`);return r}registerSparseComponent(t,e){const s=Object.keys(t),n=new Array(s.length);for(let r=0;r<s.length;r++)n[r]=t[s[r]];return this._rejectNonDeterministicFields(s,n,"sparse component"),this._pushSparseStore(s,n,e)}sparseLabel(t){const e=this.sparseNames[t];return e!==void 0?`'${e}' (sparse component ${t})`:`sparse component ${t}`}_pushSparseStore(t,e,s){const n=this.sparseStores.length;return this.sparseStores.push(new h.SparseComponentStore(t,e)),this.sparseNames.push(s),h.unsafeCast(n)}sparseStoreOf(t){const e=t,s=this.sparseStores[e];if(s===void 0)throw new h.ECSError(h.ECS_ERROR.COMPONENT_NOT_REGISTERED,`sparse component ${e} is not registered`);return s}addSparse(t,e,s){this.isAlive(t)&&this.sparseStoreOf(e).setRow(h.getEntityIndex(t),s??h.EMPTY_VALUES)}removeSparse(t,e){this.isAlive(t)&&this.sparseStoreOf(e).remove(h.getEntityIndex(t))}hasSparse(t,e){return this.isAlive(t)?this.sparseStoreOf(e).has(h.getEntityIndex(t)):!1}getSparseField(t,e,s){const n=this.sparseStoreOf(e),r=n.fieldIndex[s];if(r===void 0)return 0;const i=n.getField(h.getEntityIndex(t),r);return i===void 0?0:i}setSparseField(t,e,s,n){const r=this.sparseStoreOf(e),i=r.fieldIndex[s];i!==void 0&&r.setField(h.getEntityIndex(t),i,n)}_purgeSparse(t){const e=this.sparseStores;for(let s=0;s<e.length;s++)e[s].remove(t)}snapshotSparse(){return this._requireDeterministic("snapshot_sparse()"),this._snapshots.snapshotSparse()}restoreSparse(t){this._requireDeterministic("restore_sparse()"),this._snapshots.restoreSparse(t)}snapshot(){return this._requireDeterministic("snapshot()"),this._snapshots.snapshot()}restoreInto(t){this._requireDeterministic("restoreInto()"),this._snapshots.restoreInto(t)}_mountRestoredDense(t){this._columnStore=t;const e=this.archGraph.archetypes;for(let s=0;s<e.length;s++)e[s].isBufferBacked&&e[s].refreshViews(this._columnStore);this.entityAllocator.setHighWater(t.view.getUint32(t.header.entityIndexOff+h.ENTITY_INDEX_HEADER_OFFSETS.length,!0)),this._handleBufferResized()}_reconstructHostRows(t){const e=this.entityAllocator.highWater,s=this.entityArchetype,n=this.entityRow,r=this.entityAllocator.generations,i=new Map;for(let o=0;o<e;o++){const a=s[o];if(a===h.UNASSIGNED)continue;const l=n[o];if(l===h.UNASSIGNED)continue;let u=i.get(a);u===void 0&&(u=[],i.set(a,u)),u[l]=h.createEntityId(o,r[o])}for(let o=0;o<t.archetypeRows.length;o++){const a=t.archetypeRows[o],l=this.archGet(a.archetypeId),u=i.get(a.archetypeId)??[];l.restoreHostRows(u,a.enabledCount)}}registerRelation(t){return this.relationService.registerRelation(t)}get relationCount(){return this.relationService.count}addRelation(t,e,s){this.relationService.addRelation(t,e,s)}removeRelation(t,e,s){this.relationService.removeRelation(t,e,s)}targetOf(t,e){return this.relationService.targetOf(t,e)}targetsOf(t,e){return this.relationService.targetsOf(t,e)}sourcesOf(t,e){return this.relationService.sourcesOf(t,e)}hasRelation(t,e){return this.relationService.hasRelation(t,e)}pairsOf(t){return this.relationService.pairsOf(t)}sourcesOfAny(t){return this.relationService.sourcesOfAny(t)}relationBackingSparseId(t){return this.relationService.relationBackingSparseId(t)}_forEachRelationTargetMatch(t,e,s,n,r,i,o,a){this.relationService.forEachRelationTargetMatch(t,e,s,n,r,i,o,a)}compactRelations(){return this.relationService.compactRelations()}ancestorsOf(t,e){return this.relationService.ancestorsOf(t,e)}rootOf(t,e){return this.relationService.rootOf(t,e)}cascadeOf(t,e){return this.relationService.cascadeOf(t,e)}_forEachSparseMatch(t,e,s,n,r,i,o,a){const l=this.sparseStores;if(n.length>0){let d=l[n[0]];for(let _=1;_<n.length;_++){const m=l[n[_]];m.size<d.size&&(d=m)}const f=d.indices,p=this.entityAllocator.generations,y=this.entityArchetype,g=this.entityRow,E=this.archGraph.archetypes;for(let _=0;_<f.length;_++){const m=f[_];let S=!0;for(let w=0;w<n.length;w++){const k=l[n[w]];if(k!==d&&!k.has(m)){S=!1;break}}if(!S)continue;for(let w=0;w<r.length;w++)if(l[r[w]].has(m)){S=!1;break}if(!S)continue;const v=y[m];if(v===h.UNASSIGNED)continue;const C=E[v],R=C.mask;if(R.contains(t)&&!(e!==null&&R.overlaps(e))&&!(s!==null&&!R.overlaps(s))){if(!a){const w=g[m];if(w!==h.UNASSIGNED&&w>=C.enabledCount)continue}o(h.createEntityId(m,p[m]))}}return}const u=r.length>0;for(let d=0;d<i.length;d++){const f=i[d],p=f.entityIds,y=a?f.totalCount:f.enabledCount;for(let g=0;g<y;g++){const E=p[g];if(u){const _=h.getEntityIndex(E);let m=!1;for(let S=0;S<r.length;S++)if(l[r[S]].has(_)){m=!0;break}if(m)continue}o(E)}}}_forEachHierarchyMatch(t,e,s,n,r,i,o,a,l,u){this.relationService.forEachHierarchyMatch(t,e,s,n,r,i,o,a,l,u)}addComponent(t,e,s){if(!this.isAlive(t))return;const n=h.getEntityIndex(t),r=this.entityArchetype[n],i=this.archGet(r);if(i.hasComponent(e.id)){i.writeFields(this.entityRow[n],e.id,s,this._tick);return}const o=this.archResolveAdd(r,e.id),a=this.archGet(o),l=this.entityRow[n];let u;if(l!==h.UNASSIGNED){const d=i.length,f=a.length,p=a.enabledCount,y=i.getEdge(e.id);!a.hasColumns&&!i.hasColumns?a.moveEntityFromTag(i,l,t,this.entityRow):a.moveEntityFrom(i,l,t,y.addMap,this._tick,this.entityRow),u=A[0],this._onArchLenChange(i,d),this._onArchGrow(a,f,p)}else{const d=a.length,f=a.enabledCount;u=a.hasColumns?a.addEntity(t,this.entityRow):a.addEntityTag(t,this.entityRow),this._onArchGrow(a,d,f)}a.writeFields(u,e.id,s,this._tick),this.entityArchetype[n]=o,this.entityRow[n]=u}addComponents(t,e){if(!this.isAlive(t))return;const s=h.getEntityIndex(t),n=this.entityArchetype[s],r=this.archGet(n),i=e.length;let o=i;for(let f=0;f<i;f++){const p=e[f].def.id;if(p>=yt-1||i>me){o=J;break}o=o*yt+(p+1)}if(o!==J){const f=r.getCompositeAddEdge(o);if(f!==void 0){this._addComponentsInto(t,s,r,this.archGet(f.target),f.target,f.map,e);return}}let a=null;for(let f=0;f<i;f++){const p=e[f].def.id;a!==null?a.set(p):r.mask.has(p)||(a=r.mask.copyInto(this._scratchTargetMask),a.set(p))}if(a===null){const f=this.entityRow[s];for(let p=0;p<i;p++)r.writeFields(f,e[p].def.id,e[p].values??h.EMPTY_VALUES,this._tick);return}const l=this.archGetOrCreateFromMask(a),u=this.archGet(l),d=r.getBatchTransitionMap(u);o!==J&&r.cacheCompositeAddEdge(o,l,d),this._addComponentsInto(t,s,r,u,l,d,e)}_addComponentsInto(t,e,s,n,r,i,o){const a=this.entityRow[e];let l;if(a!==h.UNASSIGNED){const u=s.length,d=n.length,f=n.enabledCount;n.moveEntityFrom(s,a,t,i,this._tick,this.entityRow),l=A[0],this._onArchLenChange(s,u),this._onArchGrow(n,d,f)}else{const u=n.length,d=n.enabledCount;l=n.addEntity(t,this.entityRow),this._onArchGrow(n,u,d)}for(let u=0;u<o.length;u++)n.writeFields(l,o[u].def.id,o[u].values??h.EMPTY_VALUES,this._tick);this.entityArchetype[e]=r,this.entityRow[e]=l}removeComponent(t,e){if(!this.isAlive(t))return;const s=h.getEntityIndex(t),n=this.entityArchetype[s],r=this.archGet(n);if(!r.hasComponent(e.id))return;const i=this.archResolveRemove(n,e.id),o=this.archGet(i),a=this.entityRow[s],l=r.getEdge(e.id),u=!o.hasColumns&&!r.hasColumns,d=r.length,f=o.length,p=o.enabledCount;u?o.moveEntityFromTag(r,a,t,this.entityRow):o.moveEntityFrom(r,a,t,l.removeMap,this._tick,this.entityRow),this.entityArchetype[s]=i,this.entityRow[s]=A[0],this._onArchLenChange(r,d),this._onArchGrow(o,f,p)}removeComponents(t,e){if(!this.isAlive(t))return;const s=h.getEntityIndex(t),n=this.entityArchetype[s],r=this.archGet(n);let i=null;for(let y=0;y<e.length;y++){const g=e[y].id;i!==null?i.clear(g):r.mask.has(g)&&(i=r.mask.copyInto(this._scratchTargetMask),i.clear(g))}if(i===null)return;const o=this.archGetOrCreateFromMask(i),a=this.archGet(o),l=this.entityRow[s],u=r.length,d=a.length,f=a.enabledCount,p=r.getBatchTransitionMap(a);a.moveEntityFrom(r,l,t,p,this._tick,this.entityRow),this.entityArchetype[s]=o,this.entityRow[s]=A[0],this._onArchLenChange(r,u),this._onArchGrow(a,d,f)}hasComponent(t,e){if(!this.isAlive(t))return!1;const s=h.getEntityIndex(t);return this.archGet(this.entityArchetype[s]).hasComponent(e.id)}batchAddComponent(t,e,s){const n=this.archGet(t);if(n.length===0)return;const r=e.id;if(n.mask.has(r))return;const i=this.archResolveAdd(n.id,r),o=this.archGet(i);if(n.disabledCount>0||o.disabledCount>0)throw new h.ECSError(h.ECS_ERROR.PARTITION_BULK_INTO_DISABLED,"batchAddComponent is unsupported on archetypes with disabled entities — enable them first or use per-entity addComponent");const a=n.getEdge(r),l=n.length,u=l,d=o.length,f=o.enabledCount,p=this.entityArchetype,y=this.entityRow,g=o.bulkMoveAllFrom(n,a.addMap,this._tick);for(let _=0;_<l;_++){const m=h.getEntityIndex(o.entityIds[g+_]);p[m]=i,y[m]=g+_}this.componentMetas[r].fieldNames.length>0&&s&&o.bulkWriteFields(g,l,r,s,this._tick),this._onArchLenChange(n,u),this._onArchGrow(o,d,f)}batchRemoveComponent(t,e){const s=this.archGet(t);if(s.length===0)return;const n=e.id;if(!s.mask.has(n))return;const r=this.archResolveRemove(s.id,n),i=this.archGet(r);if(s.disabledCount>0||i.disabledCount>0)throw new h.ECSError(h.ECS_ERROR.PARTITION_BULK_INTO_DISABLED,"batchRemoveComponent is unsupported on archetypes with disabled entities — enable them first or use per-entity removeComponent");const o=s.getEdge(n),a=s.length,l=a,u=this.entityArchetype,d=this.entityRow;if(!i.materializesRows){const g=s.entityIds;for(let E=0;E<a;E++){const _=h.getEntityIndex(g[E]);u[_]=r,d[_]=h.UNASSIGNED}s.clearRows(),this._onArchLenChange(s,l);return}const f=i.length,p=i.enabledCount,y=i.bulkMoveAllFrom(s,o.removeMap,this._tick);for(let g=0;g<a;g++){const E=h.getEntityIndex(i.entityIds[y+g]);u[E]=r,d[E]=y+g}this._onArchLenChange(s,l),this._onArchGrow(i,f,p)}getEntityArchetype(t){return this.archGet(this.entityArchetype[h.getEntityIndex(t)])}getEntityRow(t){return this.entityRow[h.getEntityIndex(t)]}getMatchingArchetypes(t,e,s){const n=t._words;let r=!1;for(let l=0;l<n.length;l++)if(n[l]!==0){r=!0;break}if(!r){const l=this.archGraph.archetypes,u=[];for(let d=0;d<l.length;d++){const f=l[d];(!e||!f.mask.overlaps(e))&&(!s||f.mask.overlaps(s))&&u.push(f)}return u}let i,o=!1;for(let l=0;l<n.length;l++){let u=n[l];if(u===0)continue;const d=l<<T.BITS_PER_WORD_SHIFT;for(;u!==0;){const f=u&-u>>>0,p=d+(T.BITS_PER_WORD_MASK-Math.clz32(f));u^=f;const y=this.archGraph.componentIndex[p];if(y===void 0||y.length===0){o=!0;break}(!i||y.length<i.length)&&(i=y)}if(o)break}if(o||!i)return[];const a=[];for(let l=0;l<i.length;l++){const u=this.archGet(i[l]);u.matches(t)&&(!e||!u.mask.overlaps(e))&&(!s||u.mask.overlaps(s))&&a.push(u)}return a}registerQuery(t,e,s){const n=this.getMatchingArchetypes(t,e,s);return this.registeredQueries.push({includeMask:t.copy(),excludeMask:e?e.copy():null,anyOfMask:s?s.copy():null,result:n,query:null}),n}updateQueryRef(t,e){const s=this.registeredQueries;for(let n=0;n<s.length;n++)if(s[n].result===t){s[n].query=e;return}}get archetypeCount(){return this.archGraph.archetypes.length}registerEvent(t){return this.events.registerEvent(t)}emitEvent(t,e){this.events.emitEvent(t,e)}emitSignal(t){this.events.emitSignal(t)}getEventReader(t){return this.events.getEventReader(t)}clearEvents(){this.events.clearEvents()}_devBufferedEventCount(){return this.events.devBufferedEventCount()}registerEventByKey(t,e){return this.events.registerEventByKey(t,e)}getEventDefByKey(t){return this.events.getEventDefByKey(t)}hasEventKey(t){return this.events.hasEventKey(t)}resources=new Vt;registerResource(t,e){this.resources.register(t,e)}getResource(t){return this.resources.get(t)}setResource(t,e){this.resources.set(t,e)}removeResource(t){this.resources.remove(t)}hasResource(t){return this.resources.has(t)}}class Se{store;constructor(t){this.store=t}register(t){return this.store.registerRelation(t)}get count(){return this.store.relationCount}add(t,e,s){return this.store.addRelation(t,e,s),this}remove(t,e,s){return this.store.removeRelation(t,e,s),this}has(t,e){return this.store.hasRelation(t,e)}targetOf(t,e){return this.store.targetOf(t,e)}targetsOf(t,e){return this.store.targetsOf(t,e)}sourcesOf(t,e){return this.store.sourcesOf(t,e)}pairsOf(t){return this.store.pairsOf(t)}sourcesOfAny(t){return this.store.sourcesOfAny(t)}ancestorsOf(t,e){return this.store.ancestorsOf(t,e)}rootOf(t,e){return this.store.rootOf(t,e)}cascadeOf(t,e){return this.store.cascadeOf(t,e)}compact(){return this.store.compactRelations()}}class Ce{store;constructor(t){this.store=t}register(t,e){this.store.registerEventByKey(t,e)}registerSignal(t){this.store.registerEventByKey(t,[])}emit(t,e){const s=this.store.getEventDefByKey(t);e===void 0?this.store.emitSignal(s):this.store.emitEvent(s,e)}read(t){const e=this.store.getEventDefByKey(t);return this.store.getEventReader(e)}}class Re{store;constructor(t){this.store=t}register(t,e){this.store.registerResource(t,e)}get(t){return h.unsafeCast(this.store.getResource(t))}set(t,e){this.store.setResource(t,e)}remove(t){this.store.removeResource(t)}has(t){return this.store.hasResource(t)}}class ve{store;constructor(t){this.store=t}get deterministic(){return this.store.deterministic}stateHash(){return this.store.stateHash()}capture(){return this.store.snapshot()}restore(t){this.store.restoreInto(t)}captureSparse(){return this.store.snapshotSparse()}restoreSparse(t){this.store.restoreSparse(t)}}const Et=new WeakMap;function it(c,t){let e=Et.get(c);if(!e){e=Object.create(null);const{fieldNames:n}=c.layout;for(let r=0;r<n.length;r++){const i=c.columns[r];Object.defineProperty(e,n[r],{get(){return i.buf[this._row]},set(o){i.buf[this._row]=o},enumerable:!0,configurable:!1})}Et.set(c,e)}const s=Object.create(e);return s._row=t,s}class be{dedup=new Map;andSingle=new Map;notSingle=new Map;anyOfSingle=new Map;changedSingle=new Map;optionalSingle=new Map;withSparseSingle=new Map;withoutSparseSingle=new Map;withRelationSingle=new Map;withoutRelationSingle=new Map;includeDisabledSingle=new Map;hierarchySingle=new Map;findDedup(t,e,s,n){const r=this.dedup.get(t);if(r)for(let i=0;i<r.length;i++){const o=r[i];if(!(!o.includeMask.equals(e)||!(s===null?o.excludeMask===null:o.excludeMask!==null&&o.excludeMask.equals(s))||!(n===null?o.anyOfMask===null:o.anyOfMask!==null&&o.anyOfMask.equals(n))))return o}}addDedup(t,e){Tt(this.dedup,t,e)}}const mt=Object.freeze([]),Ie=Object.freeze([]),wt=Object.freeze([]),ot=Number.POSITIVE_INFINITY;function P(c,t){return(c<<16|t)>>>0}function W(c,t){for(let e=0;e<c.length;e++)if(c[e]===t)return c;return[...c,t]}function Ae(c,t){for(let e=0;e<c.length;e++)if(c[e]===t)return c;return[...c,t]}function St(c,t){for(let e=0;e<c.length;e++)if(c[e]===t)return c;return[...c,t]}class Dt{_arch;_tick=0;mut(t){return this._arch.columnGroupMut(t,this._tick)}read(t){return this._arch.columnGroupRead(t)}}class D{_archetypes;_defs;_resolver;_include;_exclude;_anyOf;_nonEmptyArchetypes=[];_lastSeenEpoch=-1;_id;_sparseInclude;_sparseExclude;_optional;_includeDisabled;_relationIncludes;_relationExcludes;_hierarchy;constructor(t,e,s,n,r,i,o,a=mt,l=mt,u=Ie,d=!1,f=wt,p=wt,y=null){this._archetypes=t,this._defs=e,this._resolver=s,this._include=n,this._exclude=r,this._anyOf=i,this._id=o,this._sparseInclude=a,this._sparseExclude=l,this._optional=u,this._includeDisabled=d,this._relationIncludes=f,this._relationExcludes=p,this._hierarchy=y}_assertDenseOnly(t){if(this._sparseInclude.length>0||this._sparseExclude.length>0||this._relationIncludes.length>0||this._relationExcludes.length>0||this._hierarchy!==null)throw new h.ECSError(h.ECS_ERROR.SPARSE_QUERY_DENSE_PATH,`Query.${t} ignores sparse / relation-wildcard / hierarchy terms (withSparse / withoutSparse / withRelation / withoutRelation / hierarchy) — it walks only the dense archetype list and would return the wrong result (a hierarchy term has no per-archetype span — its order spans archetypes). Iterate this query with forEachEntity instead.`)}_isDenseOnly(){return this._sparseInclude.length===0&&this._sparseExclude.length===0&&this._relationIncludes.length===0&&this._relationExcludes.length===0&&this._hierarchy===null}firstEntity(){if(this._isDenseOnly()){const e=this._nonEmpty();for(let s=0;s<e.length;s++)if((this._includeDisabled?e[s].totalCount:e[s].enabledCount)>0)return e[s].entityIds[0];return}let t;return this.forEachEntity(e=>{t===void 0&&(t=e)}),t}singleEntity(){return this.firstEntity()}_countViaWalk(){let t=0;return this.forEachEntity(()=>{t++}),t}get archetypeCount(){return this._archetypes.length}get entityCount(){const t=this._nonEmpty();let e=0;if(this._includeDisabled)for(let s=0;s<t.length;s++)e+=t[s].totalCount;else for(let s=0;s<t.length;s++)e+=t[s].enabledCount;return e}get archetypes(){return this._archetypes}_carryNondense(t){return this._optional.length===0&&this._sparseInclude.length===0&&this._sparseExclude.length===0&&!this._includeDisabled&&this._relationIncludes.length===0&&this._relationExcludes.length===0&&this._hierarchy===null?t:new D(t._archetypes,t._defs,this._resolver,t._include,t._exclude,t._anyOf,this._resolver._nextQueryId(),this._sparseInclude,this._sparseExclude,this._optional,this._includeDisabled,this._relationIncludes,this._relationExcludes,this._hierarchy)}and(...t){if(t.length===1){const s=t[0].id,n=(this._id<<16|s)>>>0,r=this._resolver._caches.andSingle.get(n);return r!==void 0?r:this._andMiss(t[0],s,n)}let e=this;for(let s=0;s<t.length;s++)e=e.and(t[s]);return e}_andMiss(t,e,s){const n=this._include.copy(),r=this._defs.slice();n.has(e)||(n.set(e),r.push(t));const i=this._carryNondense(this._resolver._resolveQuery(n,this._exclude,this._anyOf,r));return this._resolver._caches.andSingle.set(s,i),i}without(...t){if(t.length===1){const s=t[0].id,n=(this._id<<16|s)>>>0,r=this._resolver._caches.notSingle.get(n);return r!==void 0?r:this._notMiss(s,n)}let e=this;for(let s=0;s<t.length;s++)e=e.without(t[s]);return e}_notMiss(t,e){const s=this._exclude?this._exclude.copy():new T.BitSet;s.set(t);const n=this._carryNondense(this._resolver._resolveQuery(this._include,s,this._anyOf,this._defs));return this._resolver._caches.notSingle.set(e,n),n}withSparse(...t){if(t.length===1)return this._withSparseOne(t[0]);let e=this;for(let s=0;s<t.length;s++)e=e._withSparseOne(t[s]);return e}_withSparseOne(t){const e=P(this._id,t),s=this._resolver._caches.withSparseSingle,n=s.get(e);if(n!==void 0)return n;const r=this._deriveSparse(W(this._sparseInclude,t),this._sparseExclude);return s.set(e,r),r}withoutSparse(...t){if(t.length===1)return this._withoutSparseOne(t[0]);let e=this;for(let s=0;s<t.length;s++)e=e._withoutSparseOne(t[s]);return e}_withoutSparseOne(t){const e=P(this._id,t),s=this._resolver._caches.withoutSparseSingle,n=s.get(e);if(n!==void 0)return n;const r=this._deriveSparse(this._sparseInclude,W(this._sparseExclude,t));return s.set(e,r),r}_deriveSparse(t,e){return new D(this._archetypes,this._defs,this._resolver,this._include,this._exclude,this._anyOf,this._resolver._nextQueryId(),t,e,this._optional,this._includeDisabled,this._relationIncludes,this._relationExcludes,this._hierarchy)}withRelation(...t){if(t.length===1)return this._withRelationOne(t[0]);let e=this;for(let s=0;s<t.length;s++)e=e._withRelationOne(t[s]);return e}_withRelationOne(t){const e=P(this._id,t),s=this._resolver._caches.withRelationSingle,n=s.get(e);if(n!==void 0)return n;const r=this._resolver._relationBackingSparseId(t),i=this._deriveRelation(W(this._sparseInclude,r),this._sparseExclude,St(this._relationIncludes,t),this._relationExcludes);return s.set(e,i),i}withoutRelation(...t){if(t.length===1)return this._withoutRelationOne(t[0]);let e=this;for(let s=0;s<t.length;s++)e=e._withoutRelationOne(t[s]);return e}_withoutRelationOne(t){const e=P(this._id,t),s=this._resolver._caches.withoutRelationSingle,n=s.get(e);if(n!==void 0)return n;const r=this._resolver._relationBackingSparseId(t),i=this._deriveRelation(this._sparseInclude,W(this._sparseExclude,r),this._relationIncludes,St(this._relationExcludes,t));return s.set(e,i),i}_deriveRelation(t,e,s,n){return new D(this._archetypes,this._defs,this._resolver,this._include,this._exclude,this._anyOf,this._resolver._nextQueryId(),t,e,this._optional,this._includeDisabled,s,n,this._hierarchy)}hierarchy(t,e=ot){if(e===ot){const s=P(this._id,t),n=this._resolver._caches.hierarchySingle,r=n.get(s);if(r!==void 0)return r;const i=this._deriveHierarchy({relation:t,maxDepth:e});return n.set(s,i),i}return this._deriveHierarchy({relation:t,maxDepth:e})}_deriveHierarchy(t){return new D(this._archetypes,this._defs,this._resolver,this._include,this._exclude,this._anyOf,this._resolver._nextQueryId(),this._sparseInclude,this._sparseExclude,this._optional,this._includeDisabled,this._relationIncludes,this._relationExcludes,t)}_checkRelationAccess(){for(let t=0;t<this._relationIncludes.length;t++)h.accessCheck.checkRelationRead(this._relationIncludes[t]);for(let t=0;t<this._relationExcludes.length;t++)h.accessCheck.checkRelationRead(this._relationExcludes[t])}forEachRelatedTo(t,e){this._resolver._forEachRelationTargetMatch(t,this._include,this._exclude,this._anyOf,this._sparseInclude,this._sparseExclude,this._includeDisabled,e)}optional(...t){if(t.length===1)return this._optionalOne(t[0].id);let e=this;for(let s=0;s<t.length;s++)e=e._optionalOne(t[s].id);return e}_optionalOne(t){const e=(this._id<<16|t)>>>0,s=this._resolver._caches.optionalSingle,n=s.get(e);if(n!==void 0)return n;const r=this._deriveOptional(Ae(this._optional,t));return s.set(e,r),r}_deriveOptional(t){return new D(this._archetypes,this._defs,this._resolver,this._include,this._exclude,this._anyOf,this._resolver._nextQueryId(),this._sparseInclude,this._sparseExclude,t,this._includeDisabled,this._relationIncludes,this._relationExcludes,this._hierarchy)}includeDisabled(){if(this._includeDisabled)return this;const t=this._resolver._caches.includeDisabledSingle,e=t.get(this._id);if(e!==void 0)return e;const s=new D(this._archetypes,this._defs,this._resolver,this._include,this._exclude,this._anyOf,this._resolver._nextQueryId(),this._sparseInclude,this._sparseExclude,this._optional,!0,this._relationIncludes,this._relationExcludes,this._hierarchy);return t.set(this._id,s),s}forEach(t){if(this._includeDisabled){this._forEachIncludeDisabled(t);return}const e=this._nonEmpty();for(let s=0;s<e.length;s++)t(e[s])}_forEachIncludeDisabled(t){const e=x(!0);try{this._forEachInner(t)}finally{x(e)}}eachChunk(t){if(this._includeDisabled){const e=x(!0);try{this._eachChunkInner(t)}finally{x(e)}return}this._eachChunkInner(t)}_eachChunkInner(t){const e=new Dt;e._tick=this._resolver._getCurrentTick();const s=this._nonEmpty();for(let n=0;n<s.length;n++)e._arch=s[n],t(e,s[n].entityCount)}forEachUntil(t){if(this._includeDisabled){const e=x(!0);try{return this._forEachUntilInner(t)}finally{x(e)}}return this._forEachUntilInner(t)}_forEachUntilInner(t){const e=this._nonEmpty();for(let s=0;s<e.length;s++)if(t(e[s]))return!0;return!1}_forEachInner(t){const e=this._nonEmpty();for(let s=0;s<e.length;s++)t(e[s])}forEachEntity(t){if(this._hierarchy!==null){this._resolver._forEachHierarchyMatch(this._include,this._exclude,this._anyOf,this._sparseInclude,this._sparseExclude,this._nonEmpty(),this._hierarchy.relation,this._hierarchy.maxDepth,this._includeDisabled,t);return}this._resolver._forEachSparseMatch(this._include,this._exclude,this._anyOf,this._sparseInclude,this._sparseExclude,this._nonEmpty(),t,this._includeDisabled)}_nonEmpty(){const t=this._resolver._getQueryDirtyEpoch();return this._lastSeenEpoch!==t&&this._rebuildNonEmpty(t),this._nonEmptyArchetypes}_rebuildNonEmpty(t){const e=this._archetypes,s=[];if(this._includeDisabled)for(let n=0;n<e.length;n++)e[n].totalCount>0&&s.push(e[n]);else for(let n=0;n<e.length;n++)e[n].enabledCount>0&&s.push(e[n]);this._nonEmptyArchetypes=s,this._lastSeenEpoch=t}anyOf(...t){if(t.length===1){const s=t[0].id,n=(this._id<<16|s)>>>0,r=this._resolver._caches.anyOfSingle.get(n);return r!==void 0?r:this._anyOfMiss(s,n)}let e=this;for(let s=0;s<t.length;s++)e=e.anyOf(t[s]);return e}_anyOfMiss(t,e){const s=this._anyOf?this._anyOf.copy():new T.BitSet;s.set(t);const n=this._carryNondense(this._resolver._resolveQuery(this._include,this._exclude,s,this._defs));return this._resolver._caches.anyOfSingle.set(e,n),n}changed(...t){if(t.length===1){const s=t[0].id,n=(this._id<<16|s)>>>0,r=this._resolver._caches.changedSingle.get(n);return r!==void 0?r:this._changedMiss(s,n)}const e=new Array(t.length);for(let s=0;s<t.length;s++)e[s]=t[s].id;return new M(this,e)}_changedMiss(t,e){const s=new M(this,[t]);return this._resolver._caches.changedSingle.set(e,s),s}_ctxLastRunTick(){return this._resolver._getLastRunTick()}}class kt{constructor(t){this._resolver=t}with(...t){const e=new T.BitSet;for(let s=0;s<t.length;s++)e.set(t[s].id);return this._resolver._resolveQuery(e,null,null,t)}}class xt{constructor(t){this.store=t}spawn(...t){const e=this.store.createEntity();for(let s=0;s<t.length;s++){const n=j(t[s]);this.store.addComponentDeferred(e,n,Y(t[s]))}return e}add(t,...e){if(e.length===2&&typeof e[0]=="function"&&e[1]!==null&&typeof e[1]=="object"&&typeof e[1].def!="function"){const s=e[0];return this.store.addComponentDeferred(t,s,e[1]),this}for(let s=0;s<e.length;s++){const n=e[s],r=j(n);this.store.addComponentDeferred(t,r,Y(n))}return this}remove(t,e){return this.store.removeComponentDeferred(t,e),this}despawn(t){const e=t;return this.store.destroyEntityDeferred(e),this}disable(t){return this.store.disableEntityDeferred(t),this}enable(t){return this.store.enableEntityDeferred(t),this}}class Mt{constructor(t){this.store=t,this.commands=new xt(t)}lastRunTick=0;commands;get ecsTick(){return this.store._tick}get _trace(){return this.store._trace}isAlive(t){return this.store.isAlive(t)}hasComponent(t,e){return this.store.hasComponent(t,e)}getField(t,e,s){const n=this.store.getEntityArchetype(t),r=this.store.getEntityRow(t);return n.readField(r,e.id,s)}tryGetField(t,e,s){if(!this.store.hasComponent(t,e))return;const n=this.store.getEntityArchetype(t),r=this.store.getEntityRow(t);return n.readField(r,e.id,s)}setField(t,e,s,n){const r=this.store.getEntityArchetype(t),i=this.store.getEntityRow(t),o=r.getColumn(e,s,this.store._tick);o[i]=n,this.store._anyDirtyTracked&&this.store._noteSet(e,t)}updateField(t,e,s,n){const r=this.store.getEntityArchetype(t),i=this.store.getEntityRow(t),o=n(r.readField(i,e.id,s)),a=r.getColumn(e,s,this.store._tick);return a[i]=o,this.store._anyDirtyTracked&&this.store._noteSet(e,t),o}markChanged(t,e){this.store._anyDirtyTracked&&this.store._noteSet(e,t)}ref(t,e){const s=this.store.getEntityArchetype(e),n=this.store.getEntityRow(e);return s._changedTick[t.id]=this.store._tick,it(s.columnGroups[t.id],n)}refRead(t,e){const s=this.store.getEntityArchetype(e),n=this.store.getEntityRow(e);return it(s.columnGroups[t.id],n)}isDisabled(t){return this.store.isDisabled(t)}addSparse(t,e,...s){return this.store.addSparse(t,e,s[0]),this}removeSparse(t,e){return this.store.removeSparse(t,e),this}hasSparse(t,e){return this.store.hasSparse(t,e)}getSparseField(t,e,s){return this.store.getSparseField(t,e,s)}setSparseField(t,e,s,n){this.store.setSparseField(t,e,s,n)}addRelation(t,e,s){return this.store.addRelation(t,e,s),this}removeRelation(t,e,s){return this.store.removeRelation(t,e,s),this}targetOf(t,e){return this.store.targetOf(t,e)}targetsOf(t,e){return this.store.targetsOf(t,e)}sourcesOf(t,e){return this.store.sourcesOf(t,e)}hasRelation(t,e){return this.store.hasRelation(t,e)}flush(){this.store.flushStructural(),this.store.flushDestroyed(),this.store.publishRowCountsToDescriptor()}emit(t,e){const s=this.store.getEventDefByKey(t);e===void 0?this.store.emitSignal(s):this.store.emitEvent(s,e)}read(t){const e=this.store.getEventDefByKey(t);return this.store.getEventReader(e)}resource(t){return h.unsafeCast(this.store.getResource(t))}setResource(t,e){this.store.setResource(t,e)}removeResource(t){this.store.removeResource(t)}hasResource(t){return this.store.hasResource(t)}}class M{_query;_changedIds;constructor(t,e){this._query=t,this._changedIds=e}and(...t){return new M(this._query.and(...t),this._changedIds)}without(...t){return new M(this._query.without(...t),this._changedIds)}anyOf(...t){return new M(this._query.anyOf(...t),this._changedIds)}optional(...t){return new M(this._query.optional(...t),this._changedIds)}forEach(t){if(this._query._includeDisabled){this._forEachIncludeDisabled(t);return}const e=this._query._ctxLastRunTick(),s=this._query._nonEmpty(),n=this._changedIds;for(let r=0;r<s.length;r++){const i=s[r];for(let o=0;o<n.length;o++)if(i._changedTick[n[o]]>=e){t(i);break}}}_forEachIncludeDisabled(t){const e=x(!0);try{this._forEachInner(t)}finally{x(e)}}_forEachInner(t){const e=this._query._ctxLastRunTick(),s=this._query._nonEmpty(),n=this._changedIds;for(let r=0;r<s.length;r++){const i=s[r];for(let o=0;o<n.length;o++)if(i._changedTick[n[o]]>=e){t(i);break}}}}function Ct(c){if(!(c>0)||!Number.isFinite(c))throw new h.ECSError(h.ECS_ERROR.INVALID_FIXED_TIMESTEP,`fixedTimestep must be a finite number > 0, got ${c}`);return c}function Oe(c){if(!Number.isInteger(c)||c<1)throw new h.ECSError(h.ECS_ERROR.INVALID_MAX_FIXED_STEPS,`maxFixedSteps must be an integer >= 1, got ${c}`);return c}class Te{store;schedule;ctx;_observers;relations;events;resources;snapshots;systems=new Set;nextSystemId=0;_tick=0;_updating=!1;_fixedTimestep;_accumulator=0;_maxFixedSteps;scratchMask=new T.BitSet;_nextQueryIdCounter=0;_caches=new be;_layoutSubscribers=[];_backend=null;_memory;get memoryPlan(){return this._memory}get wasmMemory(){return this._memory.wasmMemory}constructor(t){const e=Object.prototype.hasOwnProperty;if(t!==void 0&&(e.call(t,"initial_capacity")||e.call(t,"buffer_allocator")))throw new h.ECSError(h.ECS_ERROR.INVALID_MEMORY_OPTIONS,"ECSOptions.initial_capacity / buffer_allocator were replaced by ECSOptions.memory: initial_capacity → memory.columnCapacity (or memory.budget); buffer_allocator → memory.wasm (WASM-backed) or memory.allocator (custom in-place).");const s=h.resolveECSMemory(t?.memory);this._memory=s,this.store=new we({initialCapacity:s.columnCapacity,bufferAllocator:s.allocator,entityIndexCapacity:s.entityIndexCapacity,capContext:{capBytes:s.capBytes,intentLabel:s.intentLabel,budgetEntities:s.budgetEntities},onBufferResized:()=>{const n=this._layoutSubscribers;for(let r=0;r<n.length;r++)n[r].setLayout(0)},regions:t?.regions,bindingsRegionBytes:t?.bindingsRegionBytes,deterministic:t?.deterministic}),this.schedule=new h.Schedule(t?.onWarn),this.relations=new Se(this.store),this.events=new Ce(this.store),this.resources=new Re(this.store),this.snapshots=new ve(this.store),this.ctx=new Mt(this.store),this._observers=new Qt(this.store,this.ctx),this.store.setStructuralObserverHook(n=>this._observers.dispatchStructural(n)),this._fixedTimestep=Ct(t?.fixedTimestep??h.DEFAULT_FIXED_TIMESTEP),this._maxFixedSteps=Oe(t?.maxFixedSteps??h.DEFAULT_MAX_FIXED_STEPS)}regionHandles(...t){const e=new Array(t.length);let s=null;for(let n=0;n<t.length;n++){const r=this.store.regionHandle(t[n]);r===null?(s??=[]).push(t[n]):e[n]=r}if(s!==null)throw new h.ECSError(h.ECS_ERROR.REGION_NOT_DECLARED,`region_handles: region id(s) [${s.join(", ")}] not declared — pass them via ECSOptions.regions`);return e}onStoreLayoutPublished(t){return this._layoutSubscribers.push(t),t.setLayout(0),()=>{const e=this._layoutSubscribers.indexOf(t);e>=0&&this._layoutSubscribers.splice(e,1)}}attachBackend(t){this._backend=t,this.schedule.setBackend(t);const e=this.onStoreLayoutPublished(t);return()=>{e(),this._backend===t&&(this._backend=null,this.schedule.setBackend(null))}}get fixedTimestep(){return this._fixedTimestep}set fixedTimestep(t){this._fixedTimestep=Ct(t)}get fixedAlpha(){return this._accumulator/this._fixedTimestep}setTrace(t){}registerComponent(t,e,s){if(Array.isArray(t)){const r=typeof e=="string"?e:"f64",i=Object.create(null);for(const o of t)i[o]=r;return this.store.registerComponent(i,s?.name)}const n=typeof e=="object"?e:s;return this.store.registerComponent(t,n?.name)}registerSparseComponent(t,e,s){if(Array.isArray(t)){const r=typeof e=="string"?e:"f64",i=Object.create(null);for(const o of t)i[o]=r;return this.store.registerSparseComponent(i,s?.name)}const n=typeof e=="object"?e:s;return this.store.registerSparseComponent(t,n?.name)}spawn(t,e){return t===void 0?this.store.createEntity():this.store.spawn(t,e)}spawnBundle(...t){const e=this.store.createEntity();for(let s=0;s<t.length;s++){const n=j(t[s]);this.store.addComponent(e,n,Y(t[s]))}return e}_assertHostMutationOutsideSystem(t,e){if(this._updating&&h.accessCheck.current()!==null){const s=h.accessCheck.current(),n=s.name??`system_${s.id}`;throw new h.ECSError(h.ECS_ERROR.ACCESS_UNDECLARED,`ecs.${t} called from inside system '${n}' — host ${t} is immediate and unsafe mid-iteration (and invisible to observers); use ${e} instead`,{op:t})}}despawn(t){this.store.destroyEntity(t)}disable(t){return this.store.disableEntity(t),this}enable(t){return this.store.enableEntity(t),this}addComponent(t,e,s){const n=j(e);return this.store.addComponent(t,n,s??Y(e)),this}addComponents(t,e){return this.store.addComponents(t,e),this}removeComponent(t,e){return this.store.removeComponent(t,e),this}removeComponents(t,e){return this.store.removeComponents(t,e),this}batchAddComponent(t,e,s){return this.store.batchAddComponent(t,e,s),this}batchRemoveComponent(t,e){return this.store.batchRemoveComponent(t,e),this}getField(t,e,s){const n=this.store.getEntityArchetype(t),r=this.store.getEntityRow(t);return n.readField(r,e.id,s)}refRead(t,e){const s=this.store.getEntityArchetype(e),n=this.store.getEntityRow(e);return it(s.columnGroups[t.id],n)}tryGetField(t,e,s){if(!this.store.hasComponent(t,e))return;const n=this.store.getEntityArchetype(t),r=this.store.getEntityRow(t);return n.readField(r,e.id,s)}setField(t,e,s,n){const r=this.store.getEntityArchetype(t),i=this.store.getEntityRow(t),o=r.getColumn(e,s,this.store._tick);o[i]=n,this.store._anyDirtyTracked&&this.store._noteSet(e,t)}updateField(t,e,s,n){const r=n(this.getField(t,e,s));return this.setField(t,e,s,r),r}query(...t){const e=this.scratchMask;e._words.fill(0);for(let s=0;s<t.length;s++)e.set(t[s].id);return this._resolveQuery(e.copy(),null,null,t)}_nextQueryId(){return this._nextQueryIdCounter++}_resolveQuery(t,e,s,n){const r=t.hash(),i=e?e.hash():0,o=s?s.hash():0,a=r^Math.imul(i,h.HASH_GOLDEN_RATIO)^Math.imul(o,h.HASH_SECONDARY_PRIME)|0,l=this._caches.findDedup(a,t,e,s);if(l!==void 0)return l.query;const u=this.store.registerQuery(t,e??void 0,s??void 0),d=new D(u,n,this,t.copy(),e?.copy()??null,s?.copy()??null,this._nextQueryIdCounter++);return this.store.updateQueryRef(u,d),this._caches.addDedup(a,{includeMask:t.copy(),excludeMask:e?.copy()??null,anyOfMask:s?.copy()??null,query:d}),d}registerSystem(t,e){let s;if(typeof t=="function")if(e!==void 0){const i=e(new kt(this)),o=this.ctx,a=t;s={...nt,fn:(l,u)=>a(i,o,u)}}else s={...nt,fn:t};else s=t;const n=bt(this.nextSystemId++),r=Object.freeze({...s,...Wt(s),id:n});return this.systems.add(r),r}removeSystem(t){this.schedule.removeSystem(t),t.onRemoved?.(),this.systems.delete(t)}get systemCount(){return this.systems.size}startup(){this.prewarmArchetypes();try{for(const t of this.systems.values())if(t.onAdded!==void 0)try{t.onAdded(this.ctx)}finally{}this.schedule.runStartup(this.ctx,this._tick)}finally{}this.store.clearEvents()}prewarmArchetypes(){const t=De([...this.systems,...this._observers.descriptors()]);t.length!==0&&this.store.archCreateManyFromMasks(t)}update(t){try{if(this.store._tick=this._tick,this.store.publishRowCountsToDescriptor(),this.schedule.hasFixedSystems()){this._accumulator+=t;const s=this._maxFixedSteps*this._fixedTimestep;for(this._accumulator>s&&(this._accumulator=s);this._accumulator>=this._fixedTimestep;)this.schedule.runFixedUpdate(this.ctx,this._fixedTimestep,this._tick),this._accumulator-=this._fixedTimestep}this.schedule.runUpdate(this.ctx,t,this._tick);const e=O?this.store._devBufferedEventCount():0;this._observers.dispatchSet(this._tick),O&&this.store._devBufferedEventCount(),this.store.clearEvents(),this._tick++}finally{}}dispose(){for(const t of this.systems.values())t.dispose?.(),t.onRemoved?.();this.systems.clear(),this.schedule.clear()}regionOffset(t){return this.store.regionOffset(t)}regionHandle(t){return this.store.regionHandle(t)}fieldId(t,e){return this.store.fieldIdOf(t,e)}entityIdAtRow(t,e){return this.store.entityIdAtRow(t,e)}get columnStore(){return this.store.columnStore}get archetypeCount(){return this.store.archetypeCount}registerTag(){return this.store.registerComponent({})}registerSparseTag(){return this.store.registerSparseComponent({})}template(t){return this.store.resolveTemplate(t)}spawnMany(t,e,s){return this.store.spawnMany(t,e,s)}isAlive(t){return this.store.isAlive(t)}get entityCount(){return this.store.entityCount}hasComponent(t,e){return this.store.hasComponent(t,e)}isDisabled(t){return this.store.isDisabled(t)}addSparse(t,e,s){return this.store.addSparse(t,e,s),this}removeSparse(t,e){return this.store.removeSparse(t,e),this}hasSparse(t,e){return this.store.hasSparse(t,e)}getSparseField(t,e,s){return this.store.getSparseField(t,e,s)}setSparseField(t,e,s,n){this.store.setSparseField(t,e,s,n)}_getLastRunTick(){return this.ctx.lastRunTick}_getCurrentTick(){return this.store._tick}_getQueryDirtyEpoch(){return this.store._queryDirtyEpoch}_forEachSparseMatch(t,e,s,n,r,i,o,a){this.store._forEachSparseMatch(t,e,s,n,r,i,o,a)}_relationBackingSparseId(t){return this.store.relationBackingSparseId(t)}_forEachRelationTargetMatch(t,e,s,n,r,i,o,a){this.store._forEachRelationTargetMatch(t,e,s,n,r,i,o,a)}_forEachHierarchyMatch(t,e,s,n,r,i,o,a,l,u){this.store._forEachHierarchyMatch(t,e,s,n,r,i,o,a,l,u)}addSystems(t,...e){return this.schedule.addSystems(t,...e),this}configureSet(t,e){return this.schedule.configureSet(t,e),this}observe(t,e){return this._observers.register(t,e)}publishArchetypeRowCounts(){this.store.publishRowCountsToDescriptor()}flush(){this.ctx.flush()}}function De(c){const t=new Map,e=[],s=o=>{const a=o.hash(),l=t.get(a);if(l!==void 0){for(let u=0;u<l.length;u++)if(l[u].equals(o))return;l.push(o)}else t.set(a,[o]);e.push(o)},n=o=>{const a=new T.BitSet;for(let l=0;l<o.length;l++)a.set(o[l].id);return a},r=[];for(const o of c){const a=o.transitions;for(let l=0;l<a.length;l++){const u=a[l];r.push({whenHas:n(u.whenHas),add:u.add,remove:u.remove})}}for(const o of c){const a=o.spawns;for(let l=0;l<a.length;l++)s(n(a[l]))}for(;e.length>0;){const o=e.pop();for(let a=0;a<r.length;a++){const l=r[a];if(!o.contains(l.whenHas))continue;const u=o.copy();if(l.add!==void 0)for(let d=0;d<l.add.length;d++)u.set(l.add[d].id);if(l.remove!==void 0)for(let d=0;d<l.remove.length;d++)u.clear(l.remove[d].id);s(u)}}const i=[];for(const o of t.values())for(let a=0;a<o.length;a++)i.push(o[a]);return i}function ke(c,t){return{name:`runIfResourceEq(${c.description??"?"})`,resourceReads:[c],evaluate:e=>e.resource(c)===t}}function xe(c,t=0){const e=(t%c+c)%c;return{name:`runEveryNTicks(${c}${e!==0?`, +${e}`:""})`,evaluate:s=>(s.ecsTick-e)%c===0}}function Me(c){return{name:"runIfAnyMatch",reads:c._defs,evaluate:()=>c.entityCount>0}}function ct(c){const t=[],e=[];for(const s of c)s.reads&&t.push(...s.reads),s.resourceReads&&e.push(...s.resourceReads);return{...t.length>0?{reads:t}:{},...e.length>0?{resourceReads:e}:{}}}function Ne(c){return{name:`not(${c.name})`,...ct([c]),evaluate:t=>!c.evaluate(t)}}function Fe(...c){return{name:`allOf(${c.map(t=>t.name).join(", ")})`,...ct(c),evaluate:t=>c.every(e=>e.evaluate(t))}}function Le(...c){return{name:`anyOf(${c.map(t=>t.name).join(", ")})`,...ct(c),evaluate:t=>c.some(e=>e.evaluate(t))}}function Be(c){return c.kind==="spawn"&&c.onSpawned!==void 0?{kind:"spawn",components:c.components}:c}class Ge{seed;_startup=[];_ticks=[];sink=this._startup;constructor(t=0){this.seed=t}openTick(t,e){const s=this._ticks[this._ticks.length-1];if(s!==void 0&&s.tick===t){this.sink=s.commands;return}const n=[];this._ticks.push({tick:t,dt:e,commands:n}),this.sink=n}record=t=>{this.sink.push(Be(t))};log(){return{seed:this.seed,startup:this._startup,ticks:this._ticks}}snapshotLog(){return{seed:this.seed,startup:this._startup.map(t=>({...t})),ticks:this._ticks.map(t=>({...t,commands:t.commands.map(e=>({...e}))}))}}}const H="__component_def";function $e(c){return JSON.stringify(c,(t,e)=>{if(typeof e=="function"&&"id"in e)return{[H]:e.id};if(e!==null&&typeof e=="object"&&H in e)throw new h.ECSError(h.ECS_ERROR.COMMAND_LOG_TAG_COLLISION,`Cannot serialize the command log: a value object owns a field named "${H}", the reserved tag the serializer uses for component defs. Rename that component field so the log can round-trip losslessly.`);return e})}function Pe(c){return JSON.parse(c,(t,e)=>e!==null&&typeof e=="object"&&H in e?vt(Rt(e[H])):e)}function Ue(c,t,e,s){for(const i of e.startup)t.push(i);c.startup();const n=s?.hash??c.snapshots.deterministic,r=[];for(const i of e.ticks){for(const o of i.commands)t.push(o);c.update(i.dt),n&&r.push(c.snapshots.stateHash())}return{startupCommands:e.startup.length,ticks:e.ticks.length,stateHashes:r}}function tt(c){return c.name??`system#${c.id}`}class He{_frames=[];_current=null;tickBegin(t,e){const s={tick:t,dt:e,events:[]};this._current=s,this._frames.push(s)}tickEnd(t){this._current=null}systemStart(t,e){this._current?.events.push({kind:"system_start",system:tt(t),phase:e})}systemEnd(t){this._current?.events.push({kind:"system_end",system:tt(t)})}commandQueued(t,e,s){this._current?.events.push({kind:"command_queued",op:t,entity:e,component:s})}flushBegin(t){this._current?.events.push({kind:"flush_begin",phase:t})}flushEnd(t){this._current?.events.push({kind:"flush_end",phase:t})}phaseBoundary(t){}observerFired(t,e,s,n){this._current?.events.push({kind:"observer_fired",op:t,component:e,entity:s,observer:tt(n)})}eventEmitted(t){this._current?.events.push({kind:"event_emitted",key:t})}eventRead(t,e){this._current?.events.push({kind:"event_read",key:t,count:e})}frames(){return this._frames}reset(){this._frames.length=0,this._current=null}}function N(c,t){if(!(t>=0)||!Number.isFinite(t))throw new h.ECSError(h.ECS_ERROR.INVALID_FRAME_STEP,`${c} must be a finite number >= 0, got ${t}`);return t}function Ve(c){if(!Number.isInteger(c)||c<0)throw new h.ECSError(h.ECS_ERROR.INVALID_FRAME_STEP,`frame count must be an integer >= 0, got ${c}`);return c}class qe{ecs;requestFrame;cancelFrame;frameHandle=null;lastTimestampMs=null;running=!1;_fixedDt;_maxDt;constructor(t,e={}){this.ecs=t,this._fixedDt=N("fixedDt",e.fixedDt??1/60),this._maxDt=N("maxDt",e.maxDt??.25);const s=globalThis;this.requestFrame=e.requestFrame??s.requestAnimationFrame?.bind(globalThis),this.cancelFrame=e.cancelFrame??s.cancelAnimationFrame?.bind(globalThis),e.autoStart===!0&&this.play()}get fixedDt(){return this._fixedDt}set fixedDt(t){this._fixedDt=N("fixedDt",t)}get maxDt(){return this._maxDt}set maxDt(t){this._maxDt=N("maxDt",t)}get isRunning(){return this.running}step(t=this._fixedDt){this.ecs.update(N("dt",t))}stepFrames(t,e=this._fixedDt){Ve(t);const s=N("dt",e);for(let n=0;n<t;n++)this.ecs.update(s)}play(){if(!this.running){if(this.requestFrame===void 0)throw new h.ECSError(h.ECS_ERROR.INVALID_FRAME_STEP,"FrameStepper.play() requires requestAnimationFrame or a requestFrame option");this.running=!0,this.lastTimestampMs=null,this.scheduleNextFrame()}}pause(){this.running=!1,this.lastTimestampMs=null,this.frameHandle!==null&&this.cancelFrame!==void 0&&this.cancelFrame(this.frameHandle),this.frameHandle=null}toggle(){this.running?this.pause():this.play()}dispose(){this.pause()}scheduleNextFrame(){this.frameHandle=this.requestFrame?.(this.onFrame)??null}onFrame=t=>{if(!this.running)return;const e=this.lastTimestampMs===null?this._fixedDt:(t-this.lastTimestampMs)/1e3;this.lastTimestampMs=t,this.ecs.update(Math.min(N("dt",e),this._maxDt)),this.running&&this.scheduleNextFrame()}}function We(c,t){return c.relations.register({exclusive:!0,onDeleteTarget:t?.onDeleteTarget??"clear"})}function ze(c,t){return c.relations.register({exclusive:!0,onDeleteTarget:t?.onDeleteTarget??"delete"})}function je(c){return h.unsafeCast(Symbol(c))}const Ye="0.5.0";exports.ANY_RELATION=h.ANY_RELATION;exports.ECSError=h.ECSError;exports.ECS_ERROR=h.ECS_ERROR;exports.HostCommandQueue=h.HostCommandQueue;exports.SCHEDULE=h.SCHEDULE;exports.SparseRestoreError=h.SparseRestoreError;exports.applyHostCommand=h.applyHostCommand;exports.getEntityIndex=h.getEntityIndex;exports.installHostCommandSeam=h.installHostCommandSeam;exports.isEcsError=h.isEcsError;exports.spawnEntry=h.spawnEntry;exports.systemSet=h.systemSet;exports.uninstallHostCommandSeam=h.uninstallHostCommandSeam;exports.SabUnavailableError=U.SabUnavailableError;exports.ChangedQuery=M;exports.ChunkColumns=Dt;exports.Commands=xt;exports.ECS=Te;exports.ECSRestoreError=b;exports.ECS_SNAPSHOT_VERSION=K;exports.FrameStepper=qe;exports.FrameTraceRecorder=He;exports.HIERARCHY_UNBOUNDED=ot;exports.HostCommandRecorder=Ge;exports.Query=D;exports.QueryBuilder=kt;exports.StoreRestoreError=B;exports.SystemContext=Mt;exports.VERSION=Ye;exports.allOf=Fe;exports.anyOf=Le;exports.bundle=Ft;exports.deserializeCommandLog=Pe;exports.eventKey=Pt;exports.not=Ne;exports.registerChildOf=ze;exports.registerIsA=We;exports.replayCommandLog=Ue;exports.resourceKey=je;exports.runEveryNTicks=xe;exports.runIfAnyMatch=Me;exports.runIfResourceEq=ke;exports.serializeCommandLog=$e;exports.signalKey=Ut;
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const h=require("./host_commands-CxhpzMx9.cjs"),T=require("./typed_arrays-D3NmwtCG.cjs"),V=require("./shared-BymrGTyR.cjs"),O=!1,Rt=c=>h.validateAndCast(c),ht=Object.freeze({});function vt(c){const t=(e=>({def:t,values:e??ht}));return Object.defineProperty(t,"id",{value:c,enumerable:!1}),t}function Ft(c,...t){return{def:c,values:t[0]??ht}}function G(c){return typeof c=="function"?c:c.def}function $(c){return typeof c=="function"?ht:c.values}class B extends Error{constructor(t){super(t),this.name="StoreRestoreError"}}function Lt(c){const t=c.view.getUint32(h.STORE_HEADER_OFFSETS.capacity,!0);return new Uint8Array(c.buffer,0,t)}function Bt(c,t=V.DEFAULT_SAB_ALLOCATOR){const e=new DataView(c.buffer,c.byteOffset,c.byteLength);if(c.byteLength<h.STORE_HEADER_BYTES)throw new B(`snapshot too small: ${c.byteLength} bytes (header alone needs ${h.STORE_HEADER_BYTES})`);const s=e.getUint32(h.STORE_HEADER_OFFSETS.magic,!0);if(s!==h.STORE_MAGIC)throw new B(`bad magic: 0x${s.toString(16).padStart(8,"0")} (expected 0x${h.STORE_MAGIC.toString(16).padStart(8,"0")})`);const n=e.getUint32(h.STORE_HEADER_OFFSETS.sim_abi_version,!0);if(n!==h.SIM_ABI_VERSION)throw new B(`incompatible sim_abi_version: snapshot=${n}, build=${h.SIM_ABI_VERSION}`);const r=t(c.byteLength);new Uint8Array(r).set(c);const i=new DataView(r),o=h.readStoreHeader(i);if(o.layoutDescriptorOff<0||o.layoutDescriptorOff>r.byteLength)throw new B(`layout_descriptor_off ${o.layoutDescriptorOff} is outside the snapshot (${r.byteLength} bytes)`);try{const a=h.readLayoutDescriptorRegion(i,o.layoutDescriptorOff,o.archetypeCount),l=h.buildArchetypeViews(r,a);return{buffer:r,view:i,header:o,archetypes:l}}catch(a){throw a instanceof RangeError?new B(`snapshot layout is corrupt or truncated: a descriptor offset or column extent reads past the ${r.byteLength}-byte buffer (${a.message})`):a}}const Gt=c=>h.validateAndCast(c);class $t{fieldNames;columns;reader;_readerLen;constructor(t){this.fieldNames=t,this.columns=[];for(let n=0;n<t.length;n++)this.columns.push([]);const e={};for(let n=0;n<t.length;n++)e[t[n]]=this.columns[n];const s={length:0,...e};this._readerLen=s,this.reader=s}emit(t){const e=this.fieldNames,s=this.columns;for(let n=0;n<e.length;n++)s[n].push(t[e[n]]);this._readerLen.length++}emitSignal(){this._readerLen.length++}clear(){this._readerLen.length=0;const t=this.columns;for(let e=0;e<t.length;e++)t[e].length=0}}function Pt(c){return h.unsafeCast(Symbol(c))}function Ut(c){return h.unsafeCast(Symbol(c))}class Ht{channels=[];dirtyChannels=[];count=0;keyMap=new Map;registerEvent(t){const e=Gt(this.count++),s=new $t(t);return this.channels.push(s),h.unsafeCast(e)}emitEvent(t,e){const s=t,n=this.channels[s],r=n.reader.length===0;n.emit(e),r&&this.dirtyChannels.push(s)}emitSignal(t){const e=t,s=this.channels[e],n=s.reader.length===0;s.emitSignal(),n&&this.dirtyChannels.push(e)}getEventReader(t){return this.channels[t].reader}clearEvents(){const t=this.dirtyChannels,e=this.channels;for(let s=0;s<t.length;s++)e[t[s]].clear();t.length=0}devBufferedEventCount(){const t=this.dirtyChannels,e=this.channels;let s=0;for(let n=0;n<t.length;n++)s+=e[t[n]].reader.length;return s}registerEventByKey(t,e){if(this.keyMap.has(t))throw new h.ECSError(h.ECS_ERROR.EVENT_ALREADY_REGISTERED,`event '${t.description??"<unnamed>"}' is already registered`,{event:t.description});const s=this.registerEvent(e);return this.keyMap.set(t,s),s}getEventDefByKey(t){const e=this.keyMap.get(t);if(e===void 0)throw new h.ECSError(h.ECS_ERROR.EVENT_NOT_REGISTERED,`event '${t.description??"<unnamed>"}' is not registered — call ecs.events.register(key, fields) at world setup`,{event:t.description});return e}hasEventKey(t){return this.keyMap.has(t)}}class Vt{map=new Map;register(t,e){if(this.map.has(t))throw new h.ECSError(h.ECS_ERROR.RESOURCE_ALREADY_REGISTERED,`resource '${t.description??"<unnamed>"}' is already registered — remove() it first if you meant to replace it`,{resource:t.description});this.map.set(t,e)}get(t){if(!this.map.has(t))throw new h.ECSError(h.ECS_ERROR.RESOURCE_NOT_REGISTERED,`resource read: '${t.description??"<unnamed>"}' is not registered — call ecs.resources.register(key, value) at world setup`,{resource:t.description});return this.map.get(t)}set(t,e){if(!this.map.has(t))throw new h.ECSError(h.ECS_ERROR.RESOURCE_NOT_REGISTERED,`resource write: '${t.description??"<unnamed>"}' is not registered — call ecs.resources.register(key, value) at world setup`,{resource:t.description});this.map.set(t,e)}remove(t){if(!this.map.has(t))throw new h.ECSError(h.ECS_ERROR.RESOURCE_NOT_REGISTERED,`resource remove: '${t.description??"<unnamed>"}' is not registered — call ecs.resources.register(key, value) at world setup`,{resource:t.description});this.map.delete(t)}has(t){return this.map.has(t)}}class z extends Error{capacity;requested;constructor(t,e){super(`BufferBackedColumn overflow: requested length ${e} exceeds capacity ${t}`),this.name="StoreColumnOverflowError",this.capacity=t,this.requested=e}}class qt{_buf;_capacity;_len=0;constructor(t){this._buf=t,this._capacity=t.length}refreshView(t){if(t.length<this._len)throw new z(t.length,this._len);this._buf=t,this._capacity=t.length}get length(){return this._len}get capacity(){return this._capacity}push(t){if(this._len>=this._capacity)throw new z(this._capacity,this._len+1);this._buf[this._len++]=t}pop(){return this._buf[--this._len]}get(t){return this._buf[t]}setAt(t,e){this._buf[t]=e}swapRemove(t){const e=this._buf[t];return this._buf[t]=this._buf[--this._len],e}clear(){this._len=0}setLength(t){if(t>this._capacity)throw new z(this._capacity,t);this._len=t}get buf(){return this._buf}view(){return this._buf.subarray(0,this._len)}[Symbol.iterator](){let t=0;const e=this._buf,s=this._len;return{next(){return t<s?{value:e[t++],done:!1}:{value:0,done:!0}}}}ensureCapacity(t){if(t>this._capacity)throw new z(this._capacity,t)}bulkAppend(t,e,s){this.ensureCapacity(this._len+s),this._buf.set(t.subarray(e,e+s),this._len),this._len+=s}bulkAppendZeroes(t){this.ensureCapacity(this._len+t),this._buf.fill(0,this._len,this._len+t),this._len+=t}bulkAppendValue(t,e){this.ensureCapacity(this._len+e),this._buf.fill(t,this._len,this._len+e),this._len+=e}}const ut=c=>h.validateAndCast(c);class at{id;mask;hasColumns;materializesRows;_entityIds;length=0;enabledCount=0;_flushSeenEpoch=-1;_flushPreLen=0;_flushPreEnabled=0;_iterDepth=0;edges=[];batchTransitionMaps=new Map;compositeAddEdges=null;_flatColumns=[];_storeArchetypeId=null;_colOffset=[];_fieldCount=[];_fieldIndex=[];_fieldNames=[];columnGroups=[];_columnIds=[];_changedTick=[];_mutGroupCache=[];_readGroupCache=[];growHandler=null;constructor(t,e,s,n=h.DEFAULT_COLUMN_CAPACITY,r){if(this.id=t,this.mask=e,this._entityIds=new T.GrowableUint32Array(n),s){let i=0;for(let o=0;o<s.length;o++){const a=s[o],l=a.componentId,u=new Array(a.fieldNames.length);if(this._colOffset[l]=i,this._fieldCount[l]=a.fieldNames.length,this._fieldIndex[l]=a.fieldIndex,this._fieldNames[l]=a.fieldNames,a.fieldNames.length>0&&!r)throw new h.ECSError(h.ECS_ERROR.COMPONENT_NOT_REGISTERED,`Archetype ${t}: layouts with fields require a columnFactory — use Archetype.fromColumnStore for SAB-backed columns, or pass a heap factory explicitly in tests`);for(let d=0;d<a.fieldNames.length;d++){const f=a.fieldTypes[d],p=r(a.componentId,d,f);u[d]=p,this._flatColumns[i++]=p}this.columnGroups[l]={layout:a,columns:u},this._columnIds.push(l),this._changedTick[l]=0}}this.hasColumns=this._columnIds.length>0,this.materializesRows=!e.isEmpty()}static fromColumnStore(t,e,s,n,r){const i=n.archetypes.get(r);if(!i)throw new h.ECSError(h.ECS_ERROR.COMPONENT_NOT_REGISTERED,`ColumnStore has no archetype ${r}`);const o=(l,u)=>{const d=i.columns.get(h.columnKey(l,u));if(!d)throw new h.ECSError(h.ECS_ERROR.COMPONENT_NOT_REGISTERED,`ColumnStore archetype ${r} has no column for (${l}, ${u})`);return new qt(d.view)},a=new at(t,e,s,i.rowCapacity,o);return a._storeArchetypeId=r,a}get isBufferBacked(){return this._storeArchetypeId!==null}refreshViews(t){if(this._storeArchetypeId===null)throw new h.ECSError(h.ECS_ERROR.COMPONENT_NOT_REGISTERED,`Archetype ${this.id} is not SAB-backed`);const e=t.archetypes.get(this._storeArchetypeId);if(!e)throw new h.ECSError(h.ECS_ERROR.COMPONENT_NOT_REGISTERED,`new ColumnStore has no archetype ${this._storeArchetypeId}`);const s=e.columnsInOrder,n=this._flatColumns;for(let r=0;r<s.length;r++)n[r].refreshView(s[r].view)}get entityCount(){return et?this.length:this.enabledCount}get totalCount(){return this.length}get disabledCount(){return this.length-this.enabledCount}get entityIds(){return this._entityIds.buf}swapRows(t,e){if(t===e)return;const s=this._entityIds.buf,n=s[t];s[t]=s[e],s[e]=n;const r=this._flatColumns;for(let i=0;i<r.length;i++){const o=r[i].buf,a=o[t];o[t]=o[e],o[e]=a}}_placeTail(t,e){const s=this.enabledCount;if(s===t)return this.enabledCount=t+1,t;if(this.swapRows(s,t),e!==void 0){const n=this._entityIds.buf;e[h.getEntityIndex(n[t])]=t}return this.enabledCount=s+1,s}_placeTailBulk(t,e){return this.enabledCount+=e,t}disableRow(t,e){const s=this.enabledCount-1;if(t!==s){this.swapRows(t,s);const n=this._entityIds.buf;e[h.getEntityIndex(n[t])]=t,e[h.getEntityIndex(n[s])]=s}this.enabledCount=s}enableRow(t,e){const s=this.enabledCount;if(t!==s){this.swapRows(t,s);const n=this._entityIds.buf;e[h.getEntityIndex(n[t])]=t,e[h.getEntityIndex(n[s])]=s}this.enabledCount=s+1}removeRow(t,e){if(this.enabledCount===this.length){const s=this._entityIds.buf,n=this.length-1;if(t!==n){if(s[t]=s[n],this.hasColumns){const r=this._flatColumns;for(let i=0;i<r.length;i++)r[i].swapRemove(t)}e[h.getEntityIndex(s[t])]=t}else if(this.hasColumns){const r=this._flatColumns;for(let i=0;i<r.length;i++)r[i].pop()}this._entityIds.pop(),this.length=n,this.enabledCount=n;return}this._removeRowPartitioned(t,e)}_removeRowPartitioned(t,e){const s=this._entityIds.buf,n=this.hasColumns,r=this.enabledCount,i=this.length-1;if(t>=r){if(t!==i){if(s[t]=s[i],n){const a=this._flatColumns;for(let l=0;l<a.length;l++)a[l].swapRemove(t)}e[h.getEntityIndex(s[t])]=t}else if(n){const a=this._flatColumns;for(let l=0;l<a.length;l++)a[l].pop()}this._entityIds.pop(),this.length--;return}const o=r-1;if(t!==o&&(this.swapRows(t,o),e[h.getEntityIndex(s[t])]=t),o!==i){if(s[o]=s[i],n){const a=this._flatColumns;for(let l=0;l<a.length;l++)a[l].swapRemove(o)}e[h.getEntityIndex(s[o])]=o}else if(n){const a=this._flatColumns;for(let l=0;l<a.length;l++)a[l].pop()}this._entityIds.pop(),this.length--,this.enabledCount=o}get entityList(){return this._entityIds.view()}hasComponent(t){return this.mask.has(t)}matches(t){return this.mask.contains(t)}getColumnRead(t,e){const s=t.id,n=this._fieldIndex[s][e];return this._flatColumns[this._colOffset[s]+n].buf}getColumnsRead(t,...e){return e.map(n=>this.getColumnRead(t,n))}getOptionalColumnRead(t,e){const s=t.id,n=this._colOffset[s];if(n===void 0)return;const r=this._fieldIndex[s][e];return this._flatColumns[n+r].buf}getColumn(t,e,s){const n=t.id;this._changedTick[n]=s;const r=this._fieldIndex[n][e];return this._flatColumns[this._colOffset[n]+r].buf}columnGroupMut(t,e){const s=t.id;this._changedTick[s]=e;const n=this._colOffset[s],r=this._fieldNames[s],i=this._flatColumns;let o=this._mutGroupCache[s];o===void 0&&(o={},this._mutGroupCache[s]=o);for(let a=0;a<r.length;a++)o[r[a]]=i[n+a].buf;return o}columnGroupRead(t){const e=t.id,s=this._colOffset[e],n=this._fieldNames[e],r=this._flatColumns;let i=this._readGroupCache[e];i===void 0&&(i={},this._readGroupCache[e]=i);for(let o=0;o<n.length;o++)i[n[o]]=r[s+o].buf;return i}writeFields(t,e,s,n){const r=e,i=this._colOffset[r];if(i===void 0)return;this._changedTick[r]=n;const o=this._fieldNames[r],a=this._flatColumns;for(let l=0;l<o.length;l++)a[i+l].buf[t]=s[o[l]]??0}bulkWriteFields(t,e,s,n,r){const i=s,o=this._colOffset[i];if(o===void 0)return;this._changedTick[i]=r;const a=this._fieldNames[i],l=this._flatColumns,u=t+e;for(let d=0;d<a.length;d++)l[o+d].buf.fill(n[a[d]]??0,t,u)}writeFieldsPositional(t,e,s,n){const r=e,i=this._colOffset[r];if(i===void 0)return;this._changedTick[r]=n;const o=this._flatColumns;for(let a=0;a<s.length;a++)o[i+a].buf[t]=s[a]}readField(t,e,s){const n=e,r=this._colOffset[n];if(r===void 0)return NaN;const i=this._fieldIndex[n][s];return i===void 0?NaN:this._flatColumns[r+i].buf[t]}copySharedFrom(t,e,s,n){const r=t._colOffset,i=t._fieldCount,o=t._flatColumns,a=this._flatColumns,l=this._columnIds;for(let u=0;u<l.length;u++){const d=l[u],f=r[d];if(f===void 0)continue;this._changedTick[d]=n;const p=this._colOffset[d],y=i[d];for(let g=0;g<y;g++)a[p+g].buf[s]=o[f+g].buf[e]}}addEntity(t,e){const s=this._flatColumns;s.length>0&&this.length>=s[0].buf.length&&this.growHandler!==null&&this.growHandler(this,1);const n=this.length;this._entityIds.push(t);for(let r=0;r<s.length;r++)s[r].push(0);return this.length++,this._placeTail(n,e)}removeEntity(t){const e=this.length-1;let s=h.NO_SWAP;const n=this._flatColumns,r=this._entityIds.buf;if(t!==e){r[t]=r[e],s=h.getEntityIndex(r[t]);for(let i=0;i<n.length;i++)n[i].swapRemove(t)}else for(let i=0;i<n.length;i++)n[i].pop();return this._entityIds.pop(),this.length--,t<this.enabledCount&&this.enabledCount--,s}addEntityTag(t,e){const s=this.length;return this._entityIds.push(t),this.length++,this._placeTail(s,e)}addEntities(t,e=t.length){if(e===0)return this.length;const s=this._flatColumns;s.length>0&&this.length+e>s[0].buf.length&&this.growHandler!==null&&this.growHandler(this,e);const n=this.length;this._entityIds.bulkAppend(t,0,e);for(let r=0;r<s.length;r++)s[r].bulkAppendZeroes(e);return this.length+=e,this._placeTailBulk(n,e)}addEntitiesTag(t,e=t.length){if(e===0)return this.length;const s=this.length;return this._entityIds.bulkAppend(t,0,e),this.length+=e,this._placeTailBulk(s,e)}ensureRowCapacity(t){const e=this._flatColumns;e.length>0&&this.length+t>e[0].buf.length&&this.growHandler!==null&&this.growHandler(this,t)}addEntityWithValues(t,e,s,n){const r=this._flatColumns;r.length>0&&this.length>=r[0].buf.length&&this.growHandler!==null&&this.growHandler(this,1);const i=this.length;this._entityIds.push(t);for(let a=0;a<r.length;a++)r[a].push(e[a]);this.length++;const o=this._columnIds;for(let a=0;a<o.length;a++)this._changedTick[o[a]]=s;return this._placeTail(i,n)}addEntitiesWithValues(t,e,s,n){if(e===0)return this.length;const r=this._flatColumns;r.length>0&&this.length+e>r[0].buf.length&&this.growHandler!==null&&this.growHandler(this,e);const i=this.length;this._entityIds.bulkAppend(t,0,e);for(let a=0;a<r.length;a++)r[a].bulkAppendValue(s[a],e);this.length+=e;const o=this._columnIds;for(let a=0;a<o.length;a++)this._changedTick[o[a]]=n;return this._placeTailBulk(i,e)}removeEntityTag(t){const e=this.length-1;let s=h.NO_SWAP;const n=this._entityIds.buf;return t!==e&&(n[t]=n[e],s=h.getEntityIndex(n[t])),this._entityIds.pop(),this.length--,t<this.enabledCount&&this.enabledCount--,s}moveEntityFrom(t,e,s,n,r,i){const o=e>=t.enabledCount;if(!this.materializesRows){t.removeRow(e,i),A[0]=h.UNASSIGNED,A[1]=h.NO_SWAP;return}const a=this._flatColumns;a.length>0&&this.length>=a[0].buf.length&&this.growHandler!==null&&this.growHandler(this,1);const l=this.length;this._entityIds.push(s);const u=t._flatColumns;for(let p=0;p<a.length;p++){const y=n[p];a[p].push(y>=0?u[y].buf[e]:0)}const d=this._columnIds;for(let p=0;p<d.length;p++)this._changedTick[d[p]]=r;this.length++;const f=o?l:this._placeTail(l,i);t.removeRow(e,i),A[0]=f,A[1]=h.NO_SWAP}moveEntityFromTag(t,e,s,n){const r=e>=t.enabledCount;if(!this.materializesRows){t.removeRow(e,n),A[0]=h.UNASSIGNED,A[1]=h.NO_SWAP;return}const i=this.length;this._entityIds.push(s),this.length++;const o=r?i:this._placeTail(i,n);t.removeRow(e,n),A[0]=o,A[1]=h.NO_SWAP}bulkMoveAllFrom(t,e,s){const n=t.length;if(n===0)return this.length;const r=this._flatColumns;r.length>0&&this.length+n>r[0].buf.length&&this.growHandler!==null&&this.growHandler(this,n);const i=this.length,o=t._flatColumns;this._entityIds.bulkAppend(t._entityIds.buf,0,n);for(let l=0;l<r.length;l++){const u=e[l];u>=0?r[l].bulkAppend(o[u].buf,0,n):r[l].bulkAppendZeroes(n)}const a=this._columnIds;for(let l=0;l<a.length;l++)this._changedTick[a[l]]=s;return this.length+=n,this.enabledCount=i+t.enabledCount,t.clearRows(),i}clearRows(){this.length=0,this.enabledCount=0,this._entityIds.clear();const t=this._flatColumns;for(let e=0;e<t.length;e++)t[e].clear()}restoreHostRows(t,e){const s=t.length;this._entityIds.clear(),this._entityIds.ensureCapacity(s);for(let r=0;r<s;r++)this._entityIds.push(t[r]);const n=this._flatColumns;for(let r=0;r<n.length;r++)n[r].setLength(s);this.length=s,this.enabledCount=e}getEdge(t){return this.edges[t]}setEdge(t,e){this.edges[t]=e}getBatchTransitionMap(t){const e=this.batchTransitionMaps.get(t.id);if(e!==void 0)return e;const s=st(this,t);return this.batchTransitionMaps.set(t.id,s),s}getCompositeAddEdge(t){return this.compositeAddEdges===null?void 0:this.compositeAddEdges.get(t)}cacheCompositeAddEdge(t,e,s){(this.compositeAddEdges??=new Map).set(t,{target:e,map:s})}}const A=[0,h.NO_SWAP];let et=!1;function x(c){const t=et;return et=c,t}function st(c,t){const e=t._flatColumns,s=new Int16Array(e.length),n=t._columnIds,r=c._colOffset,i=t._colOffset,o=t._fieldCount;for(let a=0;a<n.length;a++){const l=n[a],u=i[l],d=o[l],f=r[l];if(f!==void 0)for(let p=0;p<d;p++)s[u+p]=f+p;else for(let p=0;p<d;p++)s[u+p]=-1}return s}const bt=c=>h.validateAndCast(c),U=Object.freeze([]);function dt(c){return typeof c=="object"&&!Array.isArray(c)}function Wt(c){let t=U;c.spawns!==void 0&&c.spawns.length>0&&(t=c.spawns.map(s=>dt(s)?s.defs:s));let e=U;if(c.despawns!==void 0&&c.despawns.length>0){const s=[];for(const n of c.despawns)dt(n)?s.push(...n.defs):s.push(n);e=s}return{reads:c.reads,writes:c.writes,spawns:t,despawns:e,transitions:c.transitions??U,resourceReads:c.resourceReads??U,resourceWrites:c.resourceWrites??U,sparseReads:c.sparseReads,sparseWrites:c.sparseWrites,relationReads:c.relationReads,relationWrites:c.relationWrites}}const nt=Object.freeze({reads:Object.freeze([]),writes:Object.freeze([]),spawns:Object.freeze([]),despawns:Object.freeze([]),transitions:Object.freeze([]),resourceReads:Object.freeze([]),resourceWrites:Object.freeze([]),sparseReads:Object.freeze([]),sparseWrites:Object.freeze([]),relationReads:Object.freeze([]),relationWrites:Object.freeze([])}),zt=Symbol.dispose??Symbol.for("Symbol.dispose"),X=(1<<20)-1;let jt=0;function Yt(c,t){const e={...nt,...t,id:bt(jt++),name:c,fn:Kt};return Object.freeze(e)}function Kt(){}function ft(c){const t=new Set;if(c)for(let e=0;e<c.length;e++)t.add(c[e].id);return t}function Xt(c){const t=(i,o)=>i.cid-o.cid||i.id-o.id,e=new Map,s=new Map;for(const i of c)e.set(i,[]),s.set(i,0);for(const i of c)if(i.writes.size!==0)for(const o of c){if(i===o)continue;let a=!1;for(const l of i.writes)if(o.reads.has(l)){a=!0;break}a&&(e.get(i).push(o),s.set(o,s.get(o)+1))}const n=c.filter(i=>s.get(i)===0).sort(t),r=[];for(;n.length>0;){const i=n.shift();r.push(i);for(const o of e.get(i)){const a=s.get(o)-1;s.set(o,a),a===0&&(n.push(o),n.sort(t))}}if(r.length!==c.length){const i=new Set(r);for(const o of c.slice().sort(t))i.has(o)||r.push(o)}return r}class Qt{constructor(t,e){this.store=t,this.ctx=e}entries=[];byCid=new Map;_topo=null;_addBuckets=new Map;_remBuckets=new Map;_disBuckets=new Map;_enaBuckets=new Map;_radixOut=[];_radixC0=new Int32Array(1024);_radixC1=new Int32Array(1024);_setDrainCache=new Map;get count(){return this.entries.length}descriptors(){const t=new Array(this.entries.length);for(let e=0;e<this.entries.length;e++)t[e]=this.entries[e].descriptor;return t}register(t,e){const s=t.id,n=e.granularity??"archetype",r=e.onSet!==void 0&&n==="entity",i=e.onSet!==void 0&&n!=="entity",o=e.access??{},a=Yt(e.name??`observer(${h.componentDebugName(t)??s})`,o),l={id:a.id,cid:s,def:t,onAdd:e.onAdd,onRemove:e.onRemove,onDisable:e.onDisable,onEnable:e.onEnable,onSetEntity:r?e.onSet:void 0,onSetArch:i?e.onSet:void 0,descriptor:a,writes:ft(o.writes),reads:ft(o.reads),yieldExisting:e.yieldExisting??!1,lastSetTick:0,disposed:!1};this.entries.push(l);let u=this.byCid.get(s);u===void 0&&(u=[],this.byCid.set(s,u)),u.push(l),this._topo=null,this._reconfigureComponent(s),l.yieldExisting&&l.onAdd!==void 0&&this._yieldExisting(l);const d=()=>this._dispose(l);return{dispose:d,[zt]:d}}_dispose(t){if(t.disposed)return;t.disposed=!0;const e=this.entries.indexOf(t);e>=0&&this.entries.splice(e,1);const s=this.byCid.get(t.cid);if(s!==void 0){const n=s.indexOf(t);n>=0&&s.splice(n,1),s.length===0&&this.byCid.delete(t.cid)}this._topo=null,this._reconfigureComponent(t.cid)}_reconfigureComponent(t){const e=this.byCid.get(t);let s=!1,n=!1,r=!1,i=!1,o=!1;if(e!==void 0)for(let a=0;a<e.length;a++){const l=e[a];l.onAdd!==void 0&&(s=!0),l.onRemove!==void 0&&(n=!0),l.onDisable!==void 0&&(r=!0),l.onEnable!==void 0&&(i=!0),l.onSetEntity!==void 0&&(o=!0)}this.store._configureComponentObservation(t,s,n,r,i,o)}getTopo(){return this._topo===null&&(this._topo=Xt(this.entries)),this._topo}dispatchStructural(t){this._bucket(t.addComp,t.addEid,t.addLen,this._addBuckets),this._bucket(t.remComp,t.remEid,t.remLen,this._remBuckets),this._bucket(t.disComp,t.disEid,t.disLen,this._disBuckets),this._bucket(t.enaComp,t.enaEid,t.enaLen,this._enaBuckets);const e=this.getTopo();for(let s=0;s<e.length;s++){const n=e[s];if(!n.disposed){if(n.onRemove!==void 0){const r=this._remBuckets.get(n.cid);r!==void 0&&r.length>0&&this._fireEach(n,n.onRemove,r,"remove")}if(n.onAdd!==void 0){const r=this._addBuckets.get(n.cid);r!==void 0&&r.length>0&&this._fireEach(n,n.onAdd,r,"add")}if(n.onDisable!==void 0){const r=this._disBuckets.get(n.cid);r!==void 0&&r.length>0&&this._fireEach(n,n.onDisable,r,"disable")}if(n.onEnable!==void 0){const r=this._enaBuckets.get(n.cid);r!==void 0&&r.length>0&&this._fireEach(n,n.onEnable,r,"enable")}}}this._clearBuckets(this._addBuckets),this._clearBuckets(this._remBuckets),this._clearBuckets(this._disBuckets),this._clearBuckets(this._enaBuckets)}_fireEach(t,e,s,n){Y(s,this._radixOut,this._radixC0,this._radixC1);try{const r=O?this.store._trace:null;for(let i=0;i<s.length;i++)e(h.unsafeCast(s[i]),this.ctx)}finally{}}_bucket(t,e,s,n){for(let r=0;r<s;r++){const i=t[r];let o=n.get(i);o===void 0&&(o=[],n.set(i,o)),o.push(e[r])}}_clearBuckets(t){for(const e of t.values())e.length=0}dispatchSet(t){if(this.entries.length===0)return;const e=this.getTopo(),s=this._setDrainCache;for(let n=0;n<e.length;n++){const r=e[n];r.onSetEntity!==void 0?this._dispatchSetEntity(r,s):r.onSetArch!==void 0&&this._dispatchSetArch(r,t)}for(const n of s.values())n.length=0;s.clear()}_dispatchSetEntity(t,e){let s=e.get(t.cid);if(s===void 0&&(s=this.store._takeDirty(t.cid),Y(s,this._radixOut,this._radixC0,this._radixC1),e.set(t.cid,s)),s.length===0)return;const n=t.def,r=t.onSetEntity;try{for(let i=0;i<s.length;i++){const o=h.unsafeCast(s[i]);this.store.isAlive(o)&&this.store.hasComponent(o,n)&&!this.store.isDisabled(o)&&r(o,this.ctx)}}finally{}}_dispatchSetArch(t,e){const s=t.onSetArch,n=t.lastSetTick;try{this.store._forEachChangedArchetype(t.cid,n,r=>{s(r,this.ctx)})}finally{}t.lastSetTick=e+1}_yieldExisting(t){const e=t.onAdd,s=this.store._collectEntitiesWithComponent(t.cid);if(s.length!==0){Y(s,this._radixOut,this._radixC0,this._radixC1);try{for(let n=0;n<s.length;n++)e(h.unsafeCast(s[n]),this.ctx)}finally{}}}}function Y(c,t,e,s){const n=c.length;if(!(n<2)){t.length<n&&(t.length=n),e.fill(0),s.fill(0);for(let r=0;r<n;r++){const i=c[r]&X;e[i&1023]++,s[i>>10&1023]++}for(let r=1;r<1024;r++)e[r]+=e[r-1],s[r]+=s[r-1];for(let r=n-1;r>=0;r--){const i=c[r];t[--e[i&X&1023]]=i}for(let r=n-1;r>=0;r--){const i=t[r];c[--s[(i&X)>>10&1023]]=i}}}class Zt{constructor(t){this.host=t}relations=[];_hasTargetCleanup=!1;_hierarchyRadixOut=[];_hierarchyRadixC0=new Int32Array(1024);_hierarchyRadixC1=new Int32Array(1024);get stores(){return this.relations}get count(){return this.relations.length}get hasTargetCleanup(){return this._hasTargetCleanup}registerRelation(t){const e=t?.multi===!0,s=t?.exclusive===!0;if(e&&s)throw new h.ECSError(h.ECS_ERROR.RELATION_MODE_INVALID,"register_relation: a relation cannot be both exclusive and multi-target");const n=!e,r=t?.onDeleteTarget??h.DEFAULT_ON_DELETE_TARGET,i=n?this.host.pushSparseStore([h.RELATION_TARGET_FIELD],["f64"]):this.host.pushSparseStore([],[]),o=this.relations.length;return this.relations.push(h.makeRelationStore(n,i,this.host.sparseStoreOf(i),r)),r!=="orphan"&&(this._hasTargetCleanup=!0),h.unsafeCast(o)}relationOf(t){const e=t,s=this.relations[e];if(s===void 0)throw new h.ECSError(h.ECS_ERROR.RELATION_NOT_REGISTERED,`relation ${e} is not registered`);return s}addRelation(t,e,s){const n=this.relationOf(e);this.host.isAlive(t)&&this.host.isAlive(s)&&n.link(t,s)}removeRelation(t,e,s){const n=this.relationOf(e);this.host.isAlive(t)&&n.unlink(t,s)}targetOf(t,e){return this.relationOf(e).singleTarget(h.getEntityIndex(t))}targetsOf(t,e){return this.relationOf(e).targetsOf(h.getEntityIndex(t))}sourcesOf(t,e){return this.relationOf(e).sourcesOf(t)}hasRelation(t,e){return this.host.hasSparse(t,this.relationOf(e).sparse)}pairsOf(t){const e=this.relationOf(t),s=[],n=this.host.entityGenerations();return e.forEachCanonicalPair(r=>h.createEntityId(r,n[r]),(r,i)=>s.push([r,i])),s}sourcesOfAny(t){const e=[],s=this.relations;for(let n=0;n<s.length;n++){const r=h.unsafeCast(n),i=s[n].sourcesOf(t);for(let o=0;o<i.length;o++)e.push([r,i[o]])}return e}relationBackingSparseId(t){return this.relationOf(t).sparse}forEachRelationTargetMatch(t,e,s,n,r,i,o,a){const l=this.relations;if(l.length===0)return;const u=new Set;for(let E=0;E<l.length;E++){const _=l[E].sourcesOf(t);for(let m=0;m<_.length;m++)u.add(_[m])}if(u.size===0)return;const d=Array.from(u).sort((E,_)=>E-_),f=this.host.sparseStores(),p=this.host.entityArchetype(),y=this.host.entityRow(),g=this.host.archetypes();for(let E=0;E<d.length;E++){const _=h.unsafeCast(d[E]),m=h.getEntityIndex(_),S=p[m];if(S===h.UNASSIGNED)continue;const v=g[S],C=v.mask;if(!C.contains(e)||s!==null&&C.overlaps(s)||n!==null&&!C.overlaps(n))continue;let R=!0;for(let w=0;w<r.length;w++)if(!f[r[w]].has(m)){R=!1;break}if(R){for(let w=0;w<i.length;w++)if(f[i[w]].has(m)){R=!1;break}if(R){if(!o){const w=y[m];if(w!==h.UNASSIGNED&&w>=v.enabledCount)continue}a(_)}}}}compactRelations(){const t=this.relations;if(t.length===0)return 0;const e=n=>this.host.isAlive(n);let s=0;for(let n=0;n<t.length;n++)s+=t[n].pruneDeadReverse(e);return s}ancestorsOf(t,e){const s=this.relationOf(e),n=this.host.sparseStoreOf(s.sparse),r=[t],i=new Set([h.getEntityIndex(t)]);let o=t;for(;;){const a=n.getField(h.getEntityIndex(o),0);if(a===void 0)break;const l=h.unsafeCast(a);if(!this.host.isAlive(l)){r.push(l);break}const u=h.getEntityIndex(l);if(i.has(u))break;i.add(u),o=l,r.push(o)}return r}rootOf(t,e){const s=this.ancestorsOf(t,e);return s[s.length-1]}cascadeOf(t,e){const s=this.relationOf(e),n=[t],r=new Set([h.getEntityIndex(t)]);for(let i=0;i<n.length;i++){const o=s.sourcesOf(n[i]);for(let a=0;a<o.length;a++){const l=o[a],u=h.getEntityIndex(l);r.has(u)||(r.add(u),n.push(l))}}return n}purgeSource(t){const e=this.relations;for(let s=0;s<e.length;s++)e[s].purgeSource(t)}cleanupTarget(t,e){const s=this.relations;for(let n=0;n<s.length;n++){const r=s[n];if(r.onDeleteTarget==="orphan")continue;const i=r.sourcesOf(t);if(i.length!==0){if(r.onDeleteTarget==="delete"){for(let o=0;o<i.length;o++)e.push(i[o]);continue}for(let o=0;o<i.length;o++)r.unlink(i[o],t)}}}forEachHierarchyMatch(t,e,s,n,r,i,o,a,l,u){const d=this.relationOf(o),f=[];if(this.host.forEachSparseMatch(t,e,s,n,r,i,_=>f.push(_),l),f.length===0)return;Y(f,this._hierarchyRadixOut,this._hierarchyRadixC0,this._hierarchyRadixC1);const p=this.host.sparseStoreOf(d.sparse),y=new Map,g=new Set,E=[];for(let _=0;_<f.length;_++){const m=f[_],S=this._hierarchyDepthOf(h.getEntityIndex(m),p,y,g);if(S>a)continue;let v=E[S];v===void 0&&(v=[],E[S]=v),v.push(m)}for(let _=0;_<E.length;_++){const m=E[_];if(m!==void 0)for(let S=0;S<m.length;S++)u(m[S])}}_hierarchyDepthOf(t,e,s,n){const r=[];let i=t,o=0;for(;;){const l=s.get(i);if(l!==void 0){o=l;break}const u=e.getField(i,0);let d=-1;if(u!==void 0){const f=h.unsafeCast(u);this.host.isAlive(f)&&(d=h.getEntityIndex(f))}if(d===-1){s.set(i,0),o=0;break}if(n.has(d)){s.set(i,0),o=0;break}r.push(i),n.add(i),i=d}let a=o;for(let l=r.length-1;l>=0;l--)a+=1,s.set(r[l],a),n.delete(r[l]);return s.get(t)}}class Jt{_generations;_lengthView;_highWater=0;_freeIndices=[];_aliveCount=0;_capacity;lastIndex=0;constructor(t,e,s){this._capacity=t,this._generations=e,this._lengthView=s}replantViews(t,e){this._generations=t,this._lengthView=e}get generations(){return this._generations}get highWater(){return this._highWater}get aliveCount(){return this._aliveCount}get freeCount(){return this._freeIndices.length}alloc(){let t,e;if(this._freeIndices.length>0)t=this._freeIndices.pop(),e=this._generations[t];else{if(this._highWater>=this._capacity)throw new h.ECSError(h.ECS_ERROR.EID_MAX_INDEX_OVERFLOW,`entityIndexCapacity (${this._capacity}) exhausted; raise it in ECSOptions.memory or destroy unused entities`);t=this._highWater++,this._generations[t]=h.INITIAL_GENERATION,e=h.INITIAL_GENERATION,this._lengthView[0]=this._highWater}return this._aliveCount++,this.lastIndex=t,h.createEntityId(t,e)}ensureCapacity(t){const e=t-this._freeIndices.length;if(e>0&&this._highWater+e>this._capacity)throw new h.ECSError(h.ECS_ERROR.EID_MAX_INDEX_OVERFLOW,`entityIndexCapacity (${this._capacity}) cannot fit ${t} new entities (${this._freeIndices.length} free, high-water ${this._highWater}); raise it in ECSOptions.memory or destroy unused entities`)}recycle(t,e){const s=e+1;s<h.RETIRED_GENERATION?(this._generations[t]=s,this._freeIndices.push(t)):this._generations[t]=h.RETIRED_GENERATION,this._aliveCount--}isAliveIndex(t,e){return t<this._highWater&&this._generations[t]===e}publishLength(){this._lengthView[0]=this._highWater}snapshotFreeIndices(){return this._freeIndices.slice()}setHighWater(t){this._highWater=t}restoreHostState(t,e){this._freeIndices.length=0;for(let s=0;s<t.length;s++)this._freeIndices.push(t[s]);this._aliveCount=e}}const pt=65536;class te{destroyIds=[];addIds=[];addDefs=[];addValues=[];removeIds=[];removeDefs=[];toggleIds=[];toggleDisable=[];_flushing=!1;host;obsEvents;constructor(t,e){this.host=t,this.obsEvents=e}queueDestroy(t){this.destroyIds.push(t)}queueAdd(t,e,s){this.addIds.push(t),this.addDefs.push(e),this.addValues.push(s)}queueRemove(t,e){this.removeIds.push(t),this.removeDefs.push(e)}queueToggle(t,e){this.toggleIds.push(t),this.toggleDisable.push(e)}get destroyCount(){return this.destroyIds.length}get structuralCount(){return this.addIds.length+this.removeIds.length}get toggleCount(){return this.toggleIds.length}flushDestroyed(){this._flushing||this.host.applyDestroys()}flushStructural(){if(this.host.structuralObserverCount()===0&&this.host.toggleObserverCount()===0){this.addIds.length>0&&this.host.applyAdds(),this.removeIds.length>0&&this.host.applyRemoves(),this.toggleIds.length>0&&this.host.applyToggles();return}if(this._flushing)return;this._flushing=!0;const t=this.obsEvents,e=this.host.structuralObserverHook();try{let s=0;for(;this.addIds.length>0||this.removeIds.length>0||this.destroyIds.length>0||this.toggleIds.length>0;){if(++s>pt)throw new h.ECSError(h.ECS_ERROR.OBSERVER_NON_CONVERGENT,`observer cascade did not converge after ${pt} rounds — two observers likely enqueue each other's structural ops forever`);t.addLen=0,t.remLen=0,t.disLen=0,t.enaLen=0,this.addIds.length>0||this.removeIds.length>0?(this.addIds.length>0&&this.host.applyAdds(),this.removeIds.length>0&&this.host.applyRemoves()):this.destroyIds.length>0?this.host.applyDestroys():this.host.applyToggles(),e!==null&&(t.addLen>0||t.remLen>0||t.disLen>0||t.enaLen>0)&&e(t)}}finally{this._flushing=!1}}}function It(c,t){let e=c;const s=new Array(t.length);for(let n=0;n<t.length;n++){const r=t[n],i=new Array(r.columns.length);for(let o=0;o<r.columns.length;o++){const a=r.columns[o];e=h.alignUp(e,a.stride),i[o]={componentId:a.componentId,fieldId:a.fieldId,typeTag:a.typeTag,byteOff:e,stride:a.stride},e+=a.stride*r.rowCapacity}s[n]={archetypeId:r.archetypeId,componentMask:r.componentMask,rowCount:0,enabledCount:0,rowCapacity:r.rowCapacity,columns:i}}if(e>h.STORE_MAX_BYTE_OFFSET)throw new h.StoreLayoutOverflowError(e);return{descriptors:s,newTotal:e}}function At(c,t){const e=c._allocator(t),s=e!==c.buffer?new DataView(e):c.view;return{grownBuffer:e,newView:s}}function ee(c){const t={};for(let n=0;n<h.STORE_PREFIX_REGIONS.length;n++){const r=h.STORE_PREFIX_REGIONS[n],i=c.view.getUint32(h.STORE_HEADER_OFFSETS[r.headerOff],!0);i!==0&&r.readOptions(c.view,i,t)}const e=h.readHeaderRegionTable(c.view);e.length>0&&(t.regions=e.map(n=>({id:n.regionId,name:`region:${n.regionId}`,bytes:n.byteLength,init:()=>{}})));const s=c.view.getUint32(h.STORE_HEADER_OFFSETS.bindings_off,!0);if(s!==0){const n=c.view.getUint32(h.STORE_HEADER_OFFSETS.layout_descriptor_off,!0);t.bindingsRegionBytes=n-s}return h.isColumnStoreInternal(c)&&c._reservedDescriptorBytes>0&&(t.reservedDescriptorBytes=c._reservedDescriptorBytes),t}function se(c){const t=new Map;for(let n=0;n<h.STORE_PREFIX_REGIONS.length;n++){const r=h.STORE_PREFIX_REGIONS[n],i=c.view.getUint32(h.STORE_HEADER_OFFSETS[r.headerOff],!0);if(i===0)continue;const o=r.regionBytes(c.view,i);t.set(r.headerOff,new Uint8Array(c.buffer,i,o).slice())}const e=new Map,s=h.readHeaderRegionTable(c.view);for(let n=0;n<s.length;n++){const r=s[n];e.set(r.regionId,new Uint8Array(c.buffer,r.byteOffset,r.byteLength).slice())}return{mechanism:t,consumer:e}}function ne(c,t){for(const[e,s]of t.mechanism){const n=c.view.getUint32(h.STORE_HEADER_OFFSETS[e],!0);new Uint8Array(c.buffer,n,s.byteLength).set(s)}for(const[e,s]of t.consumer){const n=h.findRegionOffset(c.view,e);if(n===0)continue;new Uint8Array(c.buffer,n,s.byteLength).set(s)}}function re(c,t){const e=new Map;for(const[s,n]of c.archetypes){const r=t.get(s)??0;if(r===0)continue;const i=[];for(let o=0;o<n.columnsInOrder.length;o++){const a=n.columnsInOrder[o],l=r*a.stride,u=new Uint8Array(l);u.set(new Uint8Array(a.view.buffer,a.view.byteOffset,l)),i.push(u)}e.set(s,i)}return e}function ie(c,t){for(const[e,s]of t){const n=c.archetypes.get(e);if(n===void 0)throw new Error(`restore_column_snapshots: new store missing archetype ${e} (internal)`);const r=n.columnsInOrder;for(let i=0;i<s.length;i++){const o=r[i].view;new Uint8Array(o.buffer,o.byteOffset,s[i].byteLength).set(s[i])}}}function Ot(c,t,e,s){const n=c.view.getUint32(h.STORE_HEADER_OFFSETS.view_stamp,!0),r=re(c,e),i=se(c),o=ee(c),a=h.createColumnStore(t,s,o);ie(a,r),ne(a,i);const l=n+1>>>0;return a.view.setUint32(h.STORE_HEADER_OFFSETS.view_stamp,l,!0),{store:{...a,header:{...a.header,viewStamp:l}},oldViewStamp:n,newViewStamp:l}}function oe(c,t,e){const s=new Array(t.length);for(let _=0;_<t.length;_++){const m=t[_],S=c.archetypes.get(m.archetypeId);s[_]={archetypeId:m.archetypeId,componentMask:S.componentMask,rowCapacity:m.newRowCapacity,columns:S.columnsInOrder}}const{descriptors:n,newTotal:r}=It(c.buffer.byteLength,s),i=new Map;for(let _=0;_<n.length;_++)i.set(n[_].archetypeId,n[_]);const{grownBuffer:o,newView:a}=At(c,r),l=new Uint8Array(o);for(let _=0;_<t.length;_++){const m=t[_],S=c.archetypes.get(m.archetypeId),v=i.get(m.archetypeId);for(let C=0;C<S.columnsInOrder.length;C++){const R=S.columnsInOrder[C],w=m.rowCount*R.stride;w>0&&l.copyWithin(v.columns[C].byteOff,R.byteOff,R.byteOff+w)}}let u=e;for(const[_,m]of c.archetypes){const S=i.get(_);S!==void 0&&h.writeArchetypeDescriptor(a,u,S),u+=h.archetypeDescriptorBytes(m.columnsInOrder.length)}const d=a.getUint32(h.STORE_HEADER_OFFSETS.view_stamp,!0),f=d+1>>>0;a.setUint32(h.STORE_HEADER_OFFSETS.view_stamp,f,!0),a.setUint32(h.STORE_HEADER_OFFSETS.capacity,r,!0);const p=h.buildArchetypeViews(o,[...i.values()]),y=new Map;for(const[_,m]of c.archetypes){const S=p.get(_);y.set(_,S??m)}const g={buffer:o,view:a,header:{...c.header,viewStamp:f,capacity:r},archetypes:y,_regionBytes:c._regionBytes,_allocator:c._allocator,_reservedDescriptorBytes:c._reservedDescriptorBytes},E=new Array(t.length);for(let _=0;_<t.length;_++)E[_]=t[_].archetypeId;return{store:g,oldViewStamp:d,newViewStamp:f,viewsPreserved:!0,grownArchetypeIds:E}}class Q extends Error{constructor(t){super(t),this.name="StoreGrowError"}}function he(c,t,e){const s=new Map;for(let u=0;u<t.archetypes.length;u++){const d=t.archetypes[u];s.set(d.archetypeId,d)}const n=[],r=[];for(const[u,d]of c.archetypes){const f=s.get(u),p=f?.newRowCapacity??d.rowCapacity;if(p<(f?.rowCount??0))throw new Q(`archetype ${u}: new_row_capacity ${p} < row_count ${f?.rowCount}`);if(p<d.rowCapacity)throw new Q(`archetype ${u}: shrinking from ${d.rowCapacity} to ${p} is not supported`);p>d.rowCapacity&&r.push({archetypeId:u,newRowCapacity:p,rowCount:f?.rowCount??0}),n.push({archetypeId:u,componentMask:d.componentMask,rowCapacity:p,columns:d.columnsInOrder})}const i=new Map;for(const[u,d]of c.archetypes){const p=s.get(u)?.rowCount??0;if(p>d.rowCapacity)throw new Q(`archetype ${u}: row_count ${p} > old row_capacity ${d.rowCapacity}`);p>0&&i.set(u,p)}if(e?.isInPlace===!0&&h.isColumnStoreInternal(c)&&c._allocator===e&&r.length>0){const u=c.view.getUint32(h.STORE_HEADER_OFFSETS.layout_descriptor_off,!0);return oe(c,r,u)}const{store:o,oldViewStamp:a,newViewStamp:l}=Ot(c,n,i,e);return{store:o,oldViewStamp:a,newViewStamp:l,viewsPreserved:!1,grownArchetypeIds:[]}}class L extends Error{constructor(t){super(t),this.name="StoreExtendError"}}function ae(c,t,e){if(t.newArchetypes.length===0)throw new L("extend plan has no new archetypes; use grow_column_store for resizes");const s=new Set;for(let l=0;l<t.newArchetypes.length;l++){const u=t.newArchetypes[l].archetypeId;if(s.has(u))throw new L(`duplicate archetype_id ${u} in extend plan`);if(c.archetypes.has(u))throw new L(`archetype_id ${u} already exists in the SAB; use grow_column_store to resize it`);s.add(u)}const n=new Map;if(t.existing)for(let l=0;l<t.existing.length;l++){const u=t.existing[l];if(!c.archetypes.has(u.archetypeId))throw new L(`existing row_count names unknown archetype_id ${u.archetypeId}`);if(u.rowCount<0)throw new L(`archetype ${u.archetypeId}: row_count must be non-negative (got ${u.rowCount})`);if(u.rowCount>0){const d=c.archetypes.get(u.archetypeId);if(u.rowCount>d.rowCapacity)throw new L(`archetype ${u.archetypeId}: row_count ${u.rowCount} > old row_capacity ${d.rowCapacity}`)}n.set(u.archetypeId,u.rowCount)}if(e?.isInPlace===!0&&h.isColumnStoreInternal(c)&&c._allocator===e){const l=c.view.getUint32(h.STORE_HEADER_OFFSETS.layout_descriptor_off,!0);let u=0;for(const[,f]of c.archetypes)u+=h.archetypeDescriptorBytes(f.columnsInOrder.length);let d=0;for(let f=0;f<t.newArchetypes.length;f++)d+=h.archetypeDescriptorBytes(t.newArchetypes[f].columns.length);if(u+d<=c._regionBytes)return ce(c,t.newArchetypes,l,u)}const r=[];for(const[l,u]of c.archetypes)r.push({archetypeId:l,componentMask:u.componentMask,rowCapacity:u.rowCapacity,columns:u.columnsInOrder});for(let l=0;l<t.newArchetypes.length;l++)r.push(t.newArchetypes[l]);const{store:i,oldViewStamp:o,newViewStamp:a}=Ot(c,r,n,e);return{store:i,oldViewStamp:o,newViewStamp:a,viewsPreserved:!1}}function ce(c,t,e,s){const n=new Array(t.length);for(let E=0;E<t.length;E++){const _=t[E];n[E]={archetypeId:_.archetypeId,componentMask:_.componentMask,rowCapacity:_.rowCapacity,columns:_.columns.map(m=>({componentId:m.componentId,fieldId:m.fieldId,typeTag:m.typeTag,stride:h.TYPE_TAG_STRIDE[m.typeTag]}))}}const{descriptors:r,newTotal:i}=It(c.buffer.byteLength,n),{grownBuffer:o,newView:a}=At(c,i);let l=e+s;for(let E=0;E<r.length;E++)l=h.writeArchetypeDescriptor(a,l,r[E]);const u=a.getUint32(h.STORE_HEADER_OFFSETS.view_stamp,!0),d=c.archetypes.size+t.length;a.setUint32(h.STORE_HEADER_OFFSETS.archetype_count,d,!0),a.setUint32(h.STORE_HEADER_OFFSETS.capacity,i,!0);const f=u+1>>>0;a.setUint32(h.STORE_HEADER_OFFSETS.view_stamp,f,!0);const p=h.buildArchetypeViews(o,r),y=new Map;for(const[E,_]of c.archetypes)y.set(E,_);for(const[E,_]of p)y.set(E,_);return{store:{buffer:o,view:a,header:{...c.header,viewStamp:f,capacity:i,archetypeCount:d},archetypes:y,_regionBytes:c._regionBytes,_allocator:c._allocator,_reservedDescriptorBytes:c._reservedDescriptorBytes},oldViewStamp:u,newViewStamp:f,viewsPreserved:!0}}const rt=810766935,K=1;class b extends Error{constructor(t){super(t),this.name="ECSRestoreError"}}const P=4;function le(c){const t=c.freeIndices.length,e=c.archetypeRows.length,s=P*(4+t+1+e*3),n=new Uint8Array(s),r=new DataView(n.buffer);let i=0;const o=a=>{r.setUint32(i,a,!0),i+=P};o(c.tick),o(c.entityHighWater),o(c.entityAliveCount),o(t);for(let a=0;a<t;a++)o(c.freeIndices[a]);o(e);for(let a=0;a<e;a++){const l=c.archetypeRows[a];o(l.archetypeId),o(l.length),o(l.enabledCount)}return n}function ue(c){const t=new DataView(c.buffer,c.byteOffset,c.byteLength),e=c.byteLength;let s=0;const n=p=>{if(s+p>e)throw new b(`host-state truncated: need ${p} more bytes at offset ${s}, have ${e-s}`)},r=()=>{n(P);const p=t.getUint32(s,!0);return s+=P,p},i=r(),o=r(),a=r(),l=r(),u=new Array(l);for(let p=0;p<l;p++)u[p]=r();const d=r(),f=new Array(d);for(let p=0;p<d;p++){const y=r(),g=r(),E=r();f[p]={archetypeId:y,length:g,enabledCount:E}}if(s!==e)throw new b(`host-state has ${e-s} trailing bytes after the last archetype (not a canonical encoding)`);return{tick:i,entityHighWater:o,entityAliveCount:a,freeIndices:u,archetypeRows:f}}function de(c,t,e){const s=P*5,n=new Uint8Array(s+c.length+t.length+e.length),r=new DataView(n.buffer);return r.setUint32(0,rt,!0),r.setUint32(4,K,!0),r.setUint32(8,c.length,!0),r.setUint32(12,t.length,!0),r.setUint32(16,e.length,!0),n.set(c,s),n.set(t,s+c.length),n.set(e,s+c.length+t.length),n}function fe(c){const t=P*5;if(c.byteLength<t)throw new b(`world snapshot too small: ${c.byteLength} bytes (frame header needs ${t})`);const e=new DataView(c.buffer,c.byteOffset,c.byteLength),s=e.getUint32(0,!0);if(s!==rt)throw new b(`bad world-snapshot magic: 0x${s.toString(16).padStart(8,"0")} (expected 0x${rt.toString(16).padStart(8,"0")}). A bare dense (SAB) snapshot is not a combined world snapshot — pass the bytes from ECS.snapshot(), not snapshotColumnStore().`);const n=e.getUint32(4,!0);if(n!==K)throw new b(`incompatible world-snapshot version: snapshot=${n}, build=${K}`);const r=e.getUint32(8,!0),i=e.getUint32(12,!0),o=e.getUint32(16,!0);if(t+r+i+o!==c.byteLength)throw new b(`world-snapshot frame mismatch: header declares ${t}+${r}+${i}+${o}=${t+r+i+o} bytes, buffer is ${c.byteLength}`);const a=c.byteOffset,l=c.buffer;return{dense:new Uint8Array(l,a+t,r),sparse:new Uint8Array(l,a+t+r,i),host:new Uint8Array(l,a+t+r+i,o)}}function pe(c,t,e){if(c.byteLength<h.STORE_HEADER_BYTES)throw new b(`dense section too small: ${c.byteLength} bytes (SAB header needs ${h.STORE_HEADER_BYTES})`);const s=new DataView(c.buffer,c.byteOffset,c.byteLength),n=s.getUint32(h.STORE_HEADER_OFFSETS.magic,!0);if(n!==h.STORE_MAGIC)throw new b(`dense section bad magic: 0x${n.toString(16).padStart(8,"0")} (expected SAB magic 0x${h.STORE_MAGIC.toString(16).padStart(8,"0")})`);const r=s.getUint32(h.STORE_HEADER_OFFSETS.sim_abi_version,!0);if(r!==h.SIM_ABI_VERSION)throw new b(`dense section incompatible sim_abi_version: snapshot=${r}, build=${h.SIM_ABI_VERSION}`);const i=h.readStoreHeader(s);if(i.layoutDescriptorOff<0||i.layoutDescriptorOff>c.byteLength)throw new b(`dense layoutDescriptorOff ${i.layoutDescriptorOff} is outside the section (${c.byteLength} bytes)`);const o=i.entityIndexOff;if(o<0||o+h.ENTITY_INDEX_HEADER_BYTES>c.byteLength)throw new b(`dense entityIndexOff ${o} is outside the section (${c.byteLength} bytes)`);const a=s.getUint32(o+h.ENTITY_INDEX_HEADER_OFFSETS.capacity,!0);if(a!==e)throw new b(`entity-index capacity mismatch: live=${e}, snapshot=${a}`);let l;try{l=h.readLayoutDescriptorRegion(s,i.layoutDescriptorOff,i.archetypeCount)}catch(u){throw u instanceof RangeError?new b(`dense section layout is corrupt or truncated: a descriptor reads past the ${c.byteLength}-byte section (${u.message})`):u}if(t.size!==l.length)throw new b(`archetype-set mismatch: the live world has ${t.size} SAB archetypes, the snapshot has ${l.length}. restoreInto requires an identical archetype set (prewarm the world so its archetype set is stable, per ADR on no-lazy archetypes).`);for(let u=0;u<l.length;u++){const d=l[u],f=t.get(d.archetypeId);if(f===void 0)throw new b(`archetype-set mismatch: snapshot archetype ${d.archetypeId} is absent from the live world`);if(!_e(f.componentMask,d.componentMask))throw new b(`archetype ${d.archetypeId} component-mask mismatch between the live world and the snapshot (different component registration)`);const p=f.columnsInOrder,y=d.columns;if(p.length!==y.length)throw new b(`archetype ${d.archetypeId} column-count mismatch: live=${p.length}, snapshot=${y.length}`);for(let g=0;g<p.length;g++)if(p[g].componentId!==y[g].componentId||p[g].fieldId!==y[g].fieldId||p[g].typeTag!==y[g].typeTag)throw new b(`archetype ${d.archetypeId} column ${g} layout mismatch: live=(c${p[g].componentId},f${p[g].fieldId},t${p[g].typeTag}), snapshot=(c${y[g].componentId},f${y[g].fieldId},t${y[g].typeTag})`)}}function _e(c,t){if(c.length!==t.length)return!1;for(let e=0;e<c.length;e++)if(c[e]!==t[e])return!1;return!0}class ge{host;allocator;constructor(t,e){this.host=t,this.allocator=e}snapshotSparse(){const t=h.snapshotSparseStores(this.host.sparseStores()),e=h.snapshotRelations(this.host.relationStores()),s=new Uint8Array(8+t.length+e.length),n=new DataView(s.buffer);return n.setUint32(0,t.length,!0),n.setUint32(4,e.length,!0),s.set(t,8),s.set(e,8+t.length),s}restoreSparse(t){const e=new DataView(t.buffer,t.byteOffset,t.byteLength);if(t.byteLength<8)throw new h.SparseRestoreError(`sparse snapshot truncated: need 8 header bytes, have ${t.byteLength}`);const s=e.getUint32(0,!0),n=e.getUint32(4,!0);if(8+s+n!==t.byteLength)throw new h.SparseRestoreError(`sparse snapshot frame mismatch: header declares 8+${s}+${n}=${8+s+n} bytes, buffer is ${t.byteLength}`);h.restoreSparseStores(this.host.sparseStores(),t.subarray(8,8+s)),this.rebuildRelationIndices(t.subarray(8+s,8+s+n))}rebuildRelationIndices(t){const e=this.host.generations(),s=r=>h.createEntityId(r,e[r]),n=this.host.relationStores();h.restoreRelations(n,t,s);for(let r=0;r<n.length;r++)n[r].rebuildReverseFromForward(s)}snapshot(){this.host.publishRowCounts();const t=new Uint8Array(Lt(this.host.columnStore())),e=this.snapshotSparse(),s=le(this.collectHostState());return de(t,e,s)}collectHostState(){const t=[],e=this.host.archetypes();for(let s=0;s<e.length;s++){const n=e[s];n.isBufferBacked&&t.push({archetypeId:n.id,length:n.length,enabledCount:n.enabledCount})}return{tick:this.host.tick(),entityHighWater:this.allocator.highWater,entityAliveCount:this.allocator.aliveCount,freeIndices:this.allocator.snapshotFreeIndices(),archetypeRows:t}}restoreInto(t){const e=fe(t),s=ue(e.host);pe(e.dense,this.host.columnStore().archetypes,this.host.entityIndexCapacity()),this.assertSparseSectionMatches(e.sparse);const n=Bt(e.dense,this.host.bufferAllocator());this.host.mountRestoredDense(n),this.host.reconstructHostRows(s),this.allocator.restoreHostState(s.freeIndices,s.entityAliveCount),this.host.setTick(s.tick),this.host.invalidateQueryCaches(),this.restoreSparse(e.sparse)}assertSparseSectionMatches(t){const e=new DataView(t.buffer,t.byteOffset,t.byteLength);if(t.byteLength<8)throw new h.SparseRestoreError(`sparse snapshot truncated: need 8 header bytes, have ${t.byteLength}`);const s=e.getUint32(0,!0),n=e.getUint32(4,!0);if(8+s+n!==t.byteLength)throw new h.SparseRestoreError(`sparse snapshot frame mismatch: header declares 8+${s}+${n}=${8+s+n} bytes, buffer is ${t.byteLength}`);h.validateSparseStores(this.host.sparseStores(),t.subarray(8,8+s))}}function Tt(c,t,e){const s=c.get(t);s!==void 0?s.push(e):c.set(t,[e])}class ye{archetypes=[];componentIndex=[];archetypeMap=new Map;nextArchetypeId=0;host;constructor(t){this.host=t}get(t){return this.archetypes[t]}getOrCreateFromMask(t){const e=t.hash(),s=this.lookup(t,e);if(s!==null)return s;const n=ut(this.nextArchetypeId++),r=this.buildLayouts(t);return this.host.extendStore([_t(n,t,r,this.host.initialCapacity())]),this.install(n,t,r,e),n}createManyFromMasks(t){const e=new Array(t.length),s=[],n=[],r=[],i=[];for(let a=0;a<t.length;a++){const l=t[a],u=l.hash(),d=this.lookup(l,u);if(d!==null){e[a]=d;continue}let f=!1;for(let y=0;y<s.length;y++)if(n[y]===u&&s[y].equals(l)){e[a]=i[y],f=!0;break}if(f)continue;const p=ut(this.nextArchetypeId++);s.push(l),n.push(u),r.push(this.buildLayouts(l)),i.push(p),e[a]=p}if(s.length===0)return e;const o=new Array(s.length);for(let a=0;a<s.length;a++)o[a]=_t(i[a],s[a],r[a],this.host.initialCapacity());this.host.extendStore(o);for(let a=0;a<s.length;a++)this.install(i[a],s[a],r[a],n[a]);return e}lookup(t,e){const s=this.archetypeMap.get(e);if(s===void 0)return null;for(let n=0;n<s.length;n++)if(this.archetypes[s[n]].mask.equals(t))return s[n];return null}buildLayouts(t){const e=[],s=this.host.componentMetas();return t.forEach(n=>{const r=n,i=s[r];i&&i.fieldNames.length>0&&e.push({componentId:r,fieldNames:i.fieldNames,fieldIndex:i.fieldIndex,fieldTypes:i.fieldTypes})}),e}install(t,e,s,n){const r=e.copy(),i=this.host.materialize(t,r,s);this.archetypes.push(i),Tt(this.archetypeMap,n,t),e.forEach(o=>{const a=o;let l=this.componentIndex[a];l===void 0&&(l=[],this.componentIndex[a]=l),l.push(t)}),this.host.fanIntoQueries(i)}resolveAdd(t,e){const s=this.get(t);if(s.mask.has(e))return t;const n=s.getEdge(e);if(n?.add!=null)return n.add;const r=this.getOrCreateFromMask(s.mask.copyWithSet(e));return this.cacheEdge(s,this.get(r),e),r}resolveRemove(t,e){const s=this.get(t);if(!s.mask.has(e))return t;const n=s.getEdge(e);if(n?.remove!=null)return n.remove;const r=this.getOrCreateFromMask(s.mask.copyWithClear(e));return this.cacheEdge(this.get(r),s,e),r}cacheEdge(t,e,s){const n=t.getEdge(s)??{add:null,remove:null,addMap:null,removeMap:null};n.add=e.id,n.addMap=st(t,e),t.setEdge(s,n);const r=e.getEdge(s)??{add:null,remove:null,addMap:null,removeMap:null};r.remove=t.id,r.removeMap=st(e,t),e.setEdge(s,r)}}function _t(c,t,e,s){const n=[];for(let o=0;o<e.length;o++){const a=e[o],l=a.fieldTypes;for(let u=0;u<l.length;u++)n.push({componentId:a.componentId,fieldId:u,typeTag:h.TYPED_ARRAY_TAG_TO_TYPE_TAG[l[u]]})}const r=t._words,i=new Array(h.COMPONENT_MASK_WORDS);for(let o=0;o<h.COMPONENT_MASK_WORDS;o++)i[o]=(r[o]??0)>>>0;return{archetypeId:c,componentMask:i,rowCapacity:s,columns:n}}const Ee=[],gt=-1,Z=new DataView(new ArrayBuffer(8)),yt=129,me=7,J=-1;class we{entityAllocator;componentMetas=[];componentCount=0;sparseStores=[];sparseNames=[];relationService;events=new Ht;archGraph;registeredQueries=[];emptyArchetypeId;entityArchetype;entityRow;_deferred;_snapshots;_tick=0;_trace=null;_structuralObserverCount=0;_toggleObserverCount=0;_obsEvents={addComp:[],addEid:[],addLen:0,remComp:[],remEid:[],remLen:0,disComp:[],disEid:[],disLen:0,enaComp:[],enaEid:[],enaLen:0};_structuralObserverHook=null;setStructuralObserverHook(t){this._structuralObserverHook=t}_collectDestroyEid=0;_collectDestroyRemoveBit=t=>{if(!this.componentMetas[t].obsRem)return;const e=this._obsEvents;e.remComp[e.remLen]=t,e.remEid[e.remLen]=this._collectDestroyEid,e.remLen++};_collectToggleEid=0;_collectDisableBit=t=>{if(!this.componentMetas[t].obsDisable)return;const e=this._obsEvents;e.disComp[e.disLen]=t,e.disEid[e.disLen]=this._collectToggleEid,e.disLen++};_collectEnableBit=t=>{if(!this.componentMetas[t].obsEnable)return;const e=this._obsEvents;e.enaComp[e.enaLen]=t,e.enaEid[e.enaLen]=this._collectToggleEid,e.enaLen++};_toggleInitial=new Map;_anyDirtyTracked=!1;_dirtyTrackedCids=[];_dirtyLists=[];_dirtyMarks=[];_rowCountsDirty=!1;_queryDirtyEpoch=0;initialCapacity;_scratchTargetMask=new T.BitSet;_columnStore;_growHandler=(t,e)=>{const s=t.id,n=this._columnStore.archetypes.get(s);if(n===void 0)throw new h.ECSError(h.ECS_ERROR.ARCHETYPE_NOT_FOUND,`grow_handler invoked on archetype ${s} which has no SAB region`);const r=n.rowCapacity,i=t.length+e;let o=r>0?r:1;for(;o<i;)o=o*2;const a=[],l=this.archGraph.archetypes;for(let d=0;d<l.length;d++){const f=l[d],p=this._columnStore.archetypes.get(f.id);p!==void 0&&a.push({archetypeId:f.id,newRowCapacity:f.id===s?o:p.rowCapacity,rowCount:f.hasColumns?f.length:0})}let u;try{u=he(this._columnStore,{archetypes:a},this._bufferAllocator)}catch(d){throw d instanceof V.StoreCapExceededError?this._capExceededError(d):d}if(this._columnStore=u.store,u.viewsPreserved){const d=u.grownArchetypeIds;for(let f=0;f<d.length;f++){const p=this.archGet(d[f]);p.isBufferBacked&&p.refreshViews(this._columnStore)}}else for(let d=0;d<l.length;d++)l[d].isBufferBacked&&l[d].refreshViews(this._columnStore);this._handleBufferResized()};_capExceededError(t){const e=this._capContext,s=this.entityAllocator.aliveCount,n=`SAB grow refused: requested ${t.requestedBytes} bytes exceeds `+(t.capBytes!==null?`the ${t.capBytes}-byte cap.`:"the backing's ceiling.");let r;if(e===void 0)r=` The ECS holds ${s} live entities (no sizing intent declared).`;else if(e.budgetEntities!==null){const i=(s/e.budgetEntities).toFixed(1);r=` Declared ${e.intentLabel}; the ECS holds ${s} live entities (${i}× the budget) — runaway entity creation upstream, or an under-declared budget. Raise the budget only if a ${s}-entity ECS is intended.`}else r=` Declared ${e.intentLabel}; the ECS holds ${s} live entities.`;return new h.ECSError(h.ECS_ERROR.STORE_CAP_EXCEEDED,n+r+` The cap is a hard ceiling with no grow-beyond fallback (#380) — diagnose growth before raising it. Caused by: ${t.message}`)}_bufferAllocator;_capContext;_onBufferResized;constructor(t){const e=typeof t=="number"?{initialCapacity:t}:t??{};if(this.initialCapacity=e.initialCapacity??h.DEFAULT_COLUMN_CAPACITY,this._bufferAllocator=e.bufferAllocator??V.growableSabAllocator(),this._bufferAllocator.isInPlace!==!0)throw new h.ECSError(h.ECS_ERROR.INVALID_MEMORY_OPTIONS,"Store requires an in-place SAB allocator (ADR-0008): the flush loops keep writing through hoisted entity-index views across grows, so a non-in-place allocator (e.g. DEFAULT_SAB_ALLOCATOR) corrupts the entity→row mapping. Use growable_sab_allocator / wasm_memory_allocator; non-in-place allocators are snapshot/test sizing utilities only.");this._capContext=e.capContext,this._onBufferResized=e.onBufferResized,this._entityIndexCapacity=e.entityIndexCapacity??h.ENTITY_INDEX_DEFAULT_CAPACITY,this._regions=e.regions,this._bindingsRegionBytes=e.bindingsRegionBytes??0,this._deterministic=e.deterministic??!1,this._deferred=new te({applyAdds:()=>this._flushAdds(),applyRemoves:()=>this._flushRemoves(),applyDestroys:()=>this._drainDestroyed(),applyToggles:()=>this._flushToggles(),structuralObserverCount:()=>this._structuralObserverCount,toggleObserverCount:()=>this._toggleObserverCount,structuralObserverHook:()=>this._structuralObserverHook},this._obsEvents),this.relationService=new Zt({isAlive:n=>this.isAlive(n),hasSparse:(n,r)=>this.hasSparse(n,r),pushSparseStore:(n,r)=>this._pushSparseStore(n,r),sparseStoreOf:n=>this.sparseStoreOf(n),sparseStores:()=>this.sparseStores,entityGenerations:()=>this.entityAllocator.generations,entityArchetype:()=>this.entityArchetype,entityRow:()=>this.entityRow,archetypes:()=>this.archGraph.archetypes,forEachSparseMatch:(n,r,i,o,a,l,u,d)=>this._forEachSparseMatch(n,r,i,o,a,l,u,d)}),this._columnStore=h.createColumnStore([],this._bufferAllocator,{reservedDescriptorBytes:64*1024,entityIndexCapacity:this._entityIndexCapacity,eventRingCapacitySlots:h.EVENT_RING_DEFAULT_CAPACITY_SLOTS,commandRingCapacitySlots:h.COMMAND_RING_DEFAULT_CAPACITY_SLOTS,actionRingCapacitySlots:h.ACTION_RING_DEFAULT_CAPACITY_SLOTS,regions:this._regions,bindingsRegionBytes:this._bindingsRegionBytes});const s=h.buildEntityIndexViews(this._columnStore.buffer,this._columnStore.header.entityIndexOff,this._entityIndexCapacity);this.entityArchetype=s.archetypes,this.entityRow=s.rows,this.entityAllocator=new Jt(this._entityIndexCapacity,s.generations,new Uint32Array(this._columnStore.buffer,this._columnStore.header.entityIndexOff+h.ENTITY_INDEX_HEADER_OFFSETS.length,1)),this._snapshots=new ge({sparseStores:()=>this.sparseStores,relationStores:()=>this.relationService.stores,generations:()=>this.entityAllocator.generations,archetypes:()=>this.archGraph.archetypes,columnStore:()=>this._columnStore,bufferAllocator:()=>this._bufferAllocator,entityIndexCapacity:()=>this._entityIndexCapacity,tick:()=>this._tick,setTick:n=>{this._tick=n},publishRowCounts:()=>this.publishRowCountsToDescriptor(),mountRestoredDense:n=>this._mountRestoredDense(n),reconstructHostRows:n=>this._reconstructHostRows(n),invalidateQueryCaches:()=>{this._queryDirtyEpoch++,this._rowCountsDirty=!0}},this.entityAllocator),this.archGraph=new ye({componentMetas:()=>this.componentMetas,initialCapacity:()=>this.initialCapacity,extendStore:n=>this._archExtendStoreWithNewSpecs(n),materialize:(n,r,i)=>this._materializeArchetype(n,r,i),fanIntoQueries:n=>this._fanIntoQueries(n)}),this.emptyArchetypeId=this.archGetOrCreateFromMask(new T.BitSet)}_entityIndexCapacity;_regions;_bindingsRegionBytes;_deterministic;get deterministic(){return this._deterministic}_requireDeterministic(t){if(!this._deterministic)throw new h.ECSError(h.ECS_ERROR.DETERMINISM_DISABLED,`${t} requires determinism — construct the Store/ECS with { deterministic: true }. The canonical-ordering determinism surface (state_hash / snapshot_sparse / restore_sparse) is opt-in; see ADR-0020.`)}_rejectNonDeterministicFields(t,e,s){if(this._deterministic)for(let n=0;n<e.length;n++){const r=e[n];if(r==="f32"||r==="f64")throw new h.ECSError(h.ECS_ERROR.NON_DETERMINISTIC_COLUMN_TYPE,`Cannot register ${s} field "${t[n]}" as "${r}" on a { deterministic: true } world: floating-point columns round differently across V8 / Bun / Zig (1-ULP IEEE-754), breaking cross-host state_hash agreement (ADR-0020). Use an integer type (e.g. "i32") — represent fractional quantities as fixed-point (Q16.16). Note the array shorthand defaults to "f64", so pass an explicit integer type there.`,{field:t[n],type:r,kind:s})}}_refreshEntityIndexViews(){const t=this._columnStore.view.getUint32(h.STORE_HEADER_OFFSETS.entity_index_off,!0),e=h.buildEntityIndexViews(this._columnStore.buffer,t,this._entityIndexCapacity);this.entityArchetype=e.archetypes,this.entityRow=e.rows,this.entityAllocator.replantViews(e.generations,new Uint32Array(this._columnStore.buffer,t+h.ENTITY_INDEX_HEADER_OFFSETS.length,1))}_handleBufferResized(){this._refreshEntityIndexViews(),this.entityAllocator.publishLength(),this._onBufferResized?.()}get columnStore(){return this._columnStore}regionOffset(t){return h.findRegionOffset(this._columnStore.view,t)}regionHandle(t){const e=h.findRegionEntry(this._columnStore.view,t);return e===null?null:{buffer:this._columnStore.buffer,view:this._columnStore.view,offset:e.byteOffset,bytes:e.byteLength}}publishRowCountsToDescriptor(){if(!this._rowCountsDirty)return;const t=this._columnStore.view;let e=t.getUint32(h.STORE_HEADER_OFFSETS.layout_descriptor_off,!0);const s=this.archGraph.archetypes;for(let n=0;n<s.length;n++){const r=s[n];if(!r.isBufferBacked)continue;const i=t.getUint32(e+h.ARCHETYPE_DESCRIPTOR_OFFSETS.column_count,!0);t.setUint32(e+h.ARCHETYPE_DESCRIPTOR_OFFSETS.row_count,r.hasColumns?r.length:0,!0),t.setUint32(e+h.ARCHETYPE_DESCRIPTOR_OFFSETS.enabled_count,r.hasColumns?r.enabledCount:0,!0),e+=h.ARCHETYPE_DESCRIPTOR_HEADER_BYTES+i*h.COLUMN_DESCRIPTOR_BYTES}this._rowCountsDirty=!1}stateHash(){this._requireDeterministic("state_hash()");let t=h.FNV1A_OFFSET_BASIS;const e=this.archGraph.archetypes;for(let r=0;r<e.length;r++){const i=e[r],o=i.id,a=i.length;if(t=h.fnv1aStepWord(t,o),t=h.fnv1aStepWord(t,a),t=h.fnv1aStepWord(t,i.enabledCount),a===0)continue;const l=i._flatColumns;for(let u=0;u<l.length;u++){const d=l[u].buf,f=a*d.BYTES_PER_ELEMENT,p=new Uint8Array(d.buffer,d.byteOffset,f),y=f>>>2;let g=0;for(let _=0;_<y;_++){const m=(p[g]|p[g+1]<<8|p[g+2]<<16|p[g+3]<<24)>>>0;t=(t^m)>>>0,t=Math.imul(t,h.FNV1A_PRIME),g+=4}const E=f&3;if(E!==0){let _=p[g];E>1&&(_|=p[g+1]<<8),E>2&&(_|=p[g+2]<<16),t=(t^_>>>0)>>>0,t=Math.imul(t,h.FNV1A_PRIME)}}}const s=this.sparseStores;for(let r=0;r<s.length;r++){const i=s[r];t=h.fnv1aStepWord(t,r),t=h.fnv1aStepWord(t,i.size);const o=i.canonicalIndices();for(let a=0;a<o.length;a++){const l=o[a];t=h.fnv1aStepWord(t,l);const u=i.getRow(l);for(let d=0;d<u.length;d++)Z.setFloat64(0,u[d],!0),t=h.fnv1aStepWord(t,Z.getUint32(0,!0)),t=h.fnv1aStepWord(t,Z.getUint32(4,!0))}}const n=this.relationService.stores;for(let r=0;r<n.length;r++){const i=n[r];i.exclusive||(t=h.fnv1aStepWord(t,r),i.forEachCanonicalTargetSet((o,a)=>{t=h.fnv1aStepWord(t,o),t=h.fnv1aStepWord(t,a.length);for(let l=0;l<a.length;l++)t=h.fnv1aStepWord(t,a[l])}))}return t>>>0}archGet(t){return this.archGraph.get(t)}entityIdAtRow(t,e){return this.archGet(t).entityIds[e]}archGetOrCreateFromMask(t){return this.archGraph.getOrCreateFromMask(t)}archCreateManyFromMasks(t){return this.archGraph.createManyFromMasks(t)}_archExtendStoreWithNewSpecs(t){const e=[],s=this.archGraph.archetypes;for(let r=0;r<s.length;r++){const i=s[r],o=this._columnStore.archetypes.get(i.id);o!==void 0&&e.push({archetypeId:i.id,newRowCapacity:o.rowCapacity,rowCount:i.hasColumns?i.length:0})}let n;try{n=ae(this._columnStore,{newArchetypes:t,existing:e},this._bufferAllocator)}catch(r){throw r instanceof V.StoreCapExceededError?this._capExceededError(r):r}if(this._columnStore=n.store,!n.viewsPreserved)for(let r=0;r<s.length;r++)s[r].isBufferBacked&&s[r].refreshViews(this._columnStore);this._handleBufferResized()}_materializeArchetype(t,e,s){const n=at.fromColumnStore(t,e,s,this._columnStore,t);return n.growHandler=this._growHandler,n}_fanIntoQueries(t){const e=this.registeredQueries;for(let s=0;s<e.length;s++){const n=e[s];t.matches(n.includeMask)&&(!n.excludeMask||!t.mask.overlaps(n.excludeMask))&&(!n.anyOfMask||t.mask.overlaps(n.anyOfMask))&&n.result.push(t)}}archResolveAdd(t,e){return this.archGraph.resolveAdd(t,e)}archResolveRemove(t,e){return this.archGraph.resolveRemove(t,e)}createEntity(){const t=this.entityAllocator.alloc(),e=this.entityAllocator.lastIndex;return this.entityArchetype[e]=this.emptyArchetypeId,this.entityRow[e]=h.UNASSIGNED,t}_allocEntity(){return this.entityAllocator.alloc()}_ensureEntityIndexCapacity(t){this.entityAllocator.ensureCapacity(t)}resolveTemplate(t){const e=new T.BitSet;for(let a=0;a<t.length;a++)e.set(t[a].def.id);const s=this.archGetOrCreateFromMask(e),n=this.archGet(s),r=new Array(n._flatColumns.length).fill(0),i=new Map,o=new Array(t.length);for(let a=0;a<t.length;a++){o[a]=t[a].def;const l=t[a].def.id,u=this.componentMetas[l];if(u===void 0)throw new h.ECSError(h.ECS_ERROR.COMPONENT_NOT_REGISTERED,`template: component ${l} is not registered`);const d=t[a].values??h.EMPTY_VALUES,f=n._colOffset[l];for(let p=0;p<u.fieldNames.length;p++){const y=u.fieldNames[p];r[f+p]=d[y]??0,i.set(y,i.has(y)?gt:f+p)}}return{archetypeId:s,flatValues:r,overrideIndex:i,defs:o}}_resolveOverrideColumn(t,e){const s=t.overrideIndex.get(e);return s===void 0||s===gt?-1:s}_applyOverrides(t,e,s,n){const r=t._flatColumns;for(const i in n){if(n[i]===void 0)continue;const o=this._resolveOverrideColumn(s,i);o>=0&&(r[o].buf[e]=n[i])}}_applyOverridesRange(t,e,s,n,r){const i=t._flatColumns;for(const o in r){if(r[o]===void 0)continue;const a=this._resolveOverrideColumn(n,o);a>=0&&i[a].buf.fill(r[o],e,e+s)}}spawn(t,e){const s=this.archGraph.archetypes[t.archetypeId];s.materializesRows&&s.ensureRowCapacity(1);const n=this._allocEntity(),r=this.entityAllocator.lastIndex;if(!s.materializesRows)return this.entityArchetype[r]=t.archetypeId,this.entityRow[r]=h.UNASSIGNED,n;const i=s.length,o=s.enabledCount,a=s.addEntityWithValues(n,t.flatValues,this._tick,this.entityRow);return e!==void 0&&this._applyOverrides(s,a,t,e),this.entityArchetype[r]=t.archetypeId,this.entityRow[r]=a,this._onArchGrow(s,i,o),n}spawnMany(t,e,s){if(e<=0)return[];const n=this.archGraph.archetypes[t.archetypeId];this._ensureEntityIndexCapacity(e),n.ensureRowCapacity(e);const r=new Array(e),i=new Uint32Array(e);for(let f=0;f<e;f++){const p=this._allocEntity();i[f]=p,r[f]=p}const o=this.entityArchetype,a=this.entityRow;if(!n.materializesRows){for(let f=0;f<e;f++){const p=h.getEntityIndex(r[f]);o[p]=t.archetypeId,a[p]=h.UNASSIGNED}return r}const l=n.length,u=n.enabledCount;if(n.disabledCount>0){for(let f=0;f<e;f++){const p=n.addEntityWithValues(r[f],t.flatValues,this._tick,a),y=h.getEntityIndex(r[f]);o[y]=t.archetypeId,a[y]=p,s!==void 0&&this._applyOverrides(n,p,t,s)}return this._onArchGrow(n,l,u),r}const d=n.addEntitiesWithValues(i,e,t.flatValues,this._tick);for(let f=0;f<e;f++){const p=h.getEntityIndex(r[f]);o[p]=t.archetypeId,a[p]=d+f}return s!==void 0&&this._applyOverridesRange(n,d,e,t,s),this._onArchGrow(n,l,u),r}destroyEntity(t){if(!this.isAlive(t))return;if(!this.relationService.hasTargetCleanup){this._destroyOne(t,null);return}const e=[t];for(let s=0;s<e.length;s++){const n=e[s];this.isAlive(n)&&this._destroyOne(n,e)}}_destroyOne(t,e){const s=h.getEntityIndex(t),n=this.entityRow[s];if(n!==h.UNASSIGNED){const r=this.archGet(this.entityArchetype[s]),i=r.length;r.removeRow(n,this.entityRow),this._onArchLenChange(r,i)}this.entityArchetype[s]=h.UNASSIGNED,this.entityRow[s]=h.UNASSIGNED,this.relationService.count>0&&(this.relationService.purgeSource(t),e!==null&&this.relationService.cleanupTarget(t,e)),this.sparseStores.length>0&&this._purgeSparse(s),this._anyDirtyTracked&&this._clearDirtyForIndex(s),this.entityAllocator.recycle(s,h.getEntityGeneration(t))}isAlive(t){if(t<0||t>h.MAX_ENTITY_ID)return!1;const e=h.getEntityGeneration(t);if(e===h.RETIRED_GENERATION)return!1;const s=h.getEntityIndex(t);return this.entityAllocator.isAliveIndex(s,e)}get entityCount(){return this.entityAllocator.aliveCount}_onArchLenChange(t,e){this._rowCountsDirty=!0,e===0!=(t.length===0)&&this._queryDirtyEpoch++}_onArchGrow(t,e,s){this._rowCountsDirty=!0,(e===0||s===0&&t.enabledCount!==0)&&this._queryDirtyEpoch++}_onArchEnabledChange(t,e){this._rowCountsDirty=!0,e===0!=(t.enabledCount===0)&&this._queryDirtyEpoch++}disableEntity(t){if(!this.isAlive(t))return;const e=h.getEntityIndex(t),s=this.entityRow[e];if(s===h.UNASSIGNED)return;const n=this.archGet(this.entityArchetype[e]);if(s>=n.enabledCount)return;const r=n.enabledCount;n.disableRow(s,this.entityRow),this._onArchEnabledChange(n,r)}enableEntity(t){if(!this.isAlive(t))return;const e=h.getEntityIndex(t),s=this.entityRow[e];if(s===h.UNASSIGNED)return;const n=this.archGet(this.entityArchetype[e]);if(s<n.enabledCount)return;const r=n.enabledCount;n.enableRow(s,this.entityRow),this._onArchEnabledChange(n,r)}isDisabled(t){if(!this.isAlive(t))return!1;const e=h.getEntityIndex(t),s=this.entityRow[e];if(s===h.UNASSIGNED)return!1;const n=this.archGet(this.entityArchetype[e]);return s>=n.enabledCount}_flushEpoch=0;_flushTouched=[];_settleFlushDirty(){const t=this._flushTouched;if(t.length===0)return;this._rowCountsDirty=!0;let e=!1;for(let s=0;s<t.length;s++){const n=t[s];(n._flushPreLen===0!=(n.length===0)||n._flushPreEnabled===0!=(n.enabledCount===0))&&(e=!0)}e&&this._queryDirtyEpoch++,t.length=0,this._flushEpoch++}destroyEntityDeferred(t){this._deferred.queueDestroy(t)}disableEntityDeferred(t){this._deferred.queueToggle(t,!0)}enableEntityDeferred(t){this._deferred.queueToggle(t,!1)}_flushToggles(){const t=this._deferred.toggleIds,e=this._deferred.toggleDisable,s=t.length;if(!(this._toggleObserverCount>0)){for(let i=0;i<s;i++){const o=t[i];this.isAlive(o)&&(e[i]?this.disableEntity(o):this.enableEntity(o))}t.length=0,e.length=0;return}const r=this._toggleInitial;for(let i=0;i<s;i++){const o=t[i];this.isAlive(o)&&(r.has(o)||r.set(o,this.isDisabled(o)))}for(let i=0;i<s;i++){const o=t[i];this.isAlive(o)&&(e[i]?this.disableEntity(o):this.enableEntity(o))}t.length=0,e.length=0;for(const[i,o]of r){if(!this.isAlive(i))continue;const a=this.isDisabled(i);o!==a&&this._collectToggle(i,a)}r.clear()}_collectToggle(t,e){const s=h.getEntityIndex(t);if(this.entityRow[s]===h.UNASSIGNED)return;const n=this.archGet(this.entityArchetype[s]);this._collectToggleEid=t,n.mask.forEach(e?this._collectDisableBit:this._collectEnableBit)}get pendingToggleCount(){return this._deferred.toggleCount}flushDestroyed(){this._deferred.flushDestroyed()}_drainDestroyed(){const t=this._deferred.destroyIds;if(t.length===0)return;const e=this.entityAllocator,s=this.entityArchetype,n=this.entityRow,r=e.generations,i=this.archGraph.archetypes,o=e.highWater;let a=!1,l=!1;const u=this.sparseStores.length>0,d=this.relationService.count>0,f=d&&this.relationService.hasTargetCleanup,p=this._anyDirtyTracked,y=this._structuralObserverCount>0;for(let g=0;g<t.length;g++){const E=t[g],_=E&h.INDEX_MASK,m=E>>h.INDEX_BITS;if(_>=o||r[_]!==m)continue;const S=n[_];if(S!==h.UNASSIGNED){const v=i[s[_]];y&&(this._collectDestroyEid=E,v.mask.forEach(this._collectDestroyRemoveBit)),v.removeRow(S,n),a=!0,v.length===0&&(l=!0)}d&&this.relationService.purgeSource(E),f&&this.relationService.cleanupTarget(E,t),u&&this._purgeSparse(_),p&&this._clearDirtyForIndex(_),s[_]=h.UNASSIGNED,n[_]=h.UNASSIGNED,e.recycle(_,m)}t.length=0,a&&(this._rowCountsDirty=!0,l&&this._queryDirtyEpoch++)}get pendingDestroyCount(){return this._deferred.destroyCount}addComponentDeferred(t,e,s){this._deferred.queueAdd(t,e,s??h.EMPTY_VALUES)}removeComponentDeferred(t,e){this._deferred.queueRemove(t,e)}flushStructural(){this._deferred.flushStructural()}_flushAdds(){const t=this._deferred.addIds,e=this._deferred.addDefs,s=this._deferred.addValues,n=t.length,r=this.entityArchetype,i=this.entityRow,o=this.entityAllocator.generations,a=this.archGraph.archetypes,l=this.componentMetas,u=this.entityAllocator.highWater,d=this._tick,f=this._flushEpoch,p=this._flushTouched,y=this._structuralObserverCount>0,g=this._obsEvents;for(let E=0;E<n;E++){const _=t[E],m=_&h.INDEX_MASK,S=_>>h.INDEX_BITS;if(m>=u||o[m]!==S)continue;const v=r[m],C=e[E].id,R=a[v],w=l[C];if(R.mask.has(C)){w.fieldNames.length>0&&R.writeFields(i[m],C,s[E],d);continue}const k=this.archResolveAdd(v,C),I=a[k],F=i[m],lt=!I.hasColumns&&!R.hasColumns;F!==h.UNASSIGNED&&R._flushSeenEpoch!==f&&(R._flushSeenEpoch=f,R._flushPreLen=R.length,R._flushPreEnabled=R.enabledCount,p.push(R)),I._flushSeenEpoch!==f&&(I._flushSeenEpoch=f,I._flushPreLen=I.length,I._flushPreEnabled=I.enabledCount,p.push(I));let W;if(F!==h.UNASSIGNED){if(lt)I.moveEntityFromTag(R,F,_,i);else{const Nt=R.getEdge(C);I.moveEntityFrom(R,F,_,Nt.addMap,d,i)}W=A[0]}else W=lt?I.addEntityTag(_,i):I.addEntity(_,i);w.fieldNames.length>0&&I.writeFields(W,C,s[E],d),r[m]=k,i[m]=W,y&&w.obsAdd&&(g.addComp[g.addLen]=C,g.addEid[g.addLen]=_,g.addLen++)}t.length=0,e.length=0,s.length=0,this._settleFlushDirty()}_flushRemoves(){const t=this._deferred.removeIds,e=this._deferred.removeDefs,s=t.length,n=this.entityArchetype,r=this.entityRow,i=this.entityAllocator.generations,o=this.archGraph.archetypes,a=this.entityAllocator.highWater,l=this._tick,u=this._flushEpoch,d=this._flushTouched,f=this.componentMetas,p=this._structuralObserverCount>0,y=this._obsEvents;for(let g=0;g<s;g++){const E=t[g],_=E&h.INDEX_MASK,m=E>>h.INDEX_BITS;if(_>=a||i[_]!==m)continue;const S=n[_],v=e[g].id,C=o[S];if(!C.mask.has(v))continue;const R=this.archResolveRemove(S,v),w=o[R],k=r[_],I=!w.hasColumns&&!C.hasColumns;if(C._flushSeenEpoch!==u&&(C._flushSeenEpoch=u,C._flushPreLen=C.length,C._flushPreEnabled=C.enabledCount,d.push(C)),w._flushSeenEpoch!==u&&(w._flushSeenEpoch=u,w._flushPreLen=w.length,w._flushPreEnabled=w.enabledCount,d.push(w)),I)w.moveEntityFromTag(C,k,E,r);else{const F=C.getEdge(v);w.moveEntityFrom(C,k,E,F.removeMap,l,r)}n[_]=R,r[_]=A[0],p&&f[v].obsRem&&(y.remComp[y.remLen]=v,y.remEid[y.remLen]=E,y.remLen++)}t.length=0,e.length=0,this._settleFlushDirty()}get pendingStructuralCount(){return this._deferred.structuralCount}_configureComponentObservation(t,e,s,n,r,i){const o=this.componentMetas[t];if(o===void 0)throw new h.ECSError(h.ECS_ERROR.COMPONENT_NOT_REGISTERED,`observe(): component ${t} is not registered`);const a=o.obsAdd||o.obsRem;o.obsAdd=e,o.obsRem=s;const l=e||s;a&&!l?this._structuralObserverCount--:!a&&l&&this._structuralObserverCount++;const u=o.obsDisable||o.obsEnable;o.obsDisable=n,o.obsEnable=r;const d=n||r;if(u&&!d?this._toggleObserverCount--:!u&&d&&this._toggleObserverCount++,i&&!o.trackDirty)o.trackDirty=!0,this._dirtyLists[t]===void 0&&(this._dirtyLists[t]=[],this._dirtyMarks[t]=new Uint8Array(Math.max(1,this.entityAllocator.generations.length))),this._dirtyTrackedCids.push(t),this._anyDirtyTracked=!0;else if(!i&&o.trackDirty){o.trackDirty=!1;const f=this._dirtyTrackedCids.indexOf(t);f>=0&&this._dirtyTrackedCids.splice(f,1),this._anyDirtyTracked=this._dirtyTrackedCids.length>0;const p=this._dirtyLists[t],y=this._dirtyMarks[t];if(p!==void 0&&y!==void 0){for(let g=0;g<p.length;g++)y[p[g]&h.INDEX_MASK]=0;p.length=0}}}_noteSet(t,e){const s=t.id,n=this.componentMetas[s];if(n===void 0||!n.trackDirty)return;const r=e&h.INDEX_MASK;let i=this._dirtyMarks[s];r>=i.length&&(i=this._growDirtyMarks(s,r)),i[r]===0&&(i[r]=1,this._dirtyLists[s].push(e))}_growDirtyMarks(t,e){const s=this._dirtyMarks[t];let n=Math.max(1,s.length);for(;n<=e;)n*=2;const r=new Uint8Array(n);return r.set(s),this._dirtyMarks[t]=r,r}_takeDirty(t){const e=this._dirtyLists[t];if(e===void 0||e.length===0)return Ee;this._dirtyLists[t]=[];const s=this._dirtyMarks[t];for(let n=0;n<e.length;n++)s[e[n]&h.INDEX_MASK]=0;return e}_clearDirtyForIndex(t){const e=this._dirtyTrackedCids;for(let s=0;s<e.length;s++){const n=this._dirtyMarks[e[s]];n!==void 0&&t<n.length&&(n[t]=0)}}_forEachChangedArchetype(t,e,s){const n=this.archGraph.componentIndex[t];if(n===void 0)return;const r=this.archGraph.archetypes;for(let i=0;i<n.length;i++){const o=r[n[i]];o.length>0&&o._changedTick[t]>=e&&s(o)}}_collectEntitiesWithComponent(t){const e=[],s=this.archGraph.componentIndex[t];if(s===void 0)return e;const n=this.archGraph.archetypes;for(let r=0;r<s.length;r++){const i=n[s[r]],o=i.entityIds;for(let a=0;a<i.enabledCount;a++)e.push(h.unsafeCast(o[a]))}return e}registerComponent(t,e){if(this.componentCount>=h.STORE_DESCRIPTOR_COMPONENT_LIMIT)throw new h.ECSError(h.ECS_ERROR.COMPONENT_LIMIT_EXCEEDED,`Cannot register more than ${h.STORE_DESCRIPTOR_COMPONENT_LIMIT} components: the SAB archetype descriptor mask is ${h.STORE_DESCRIPTOR_COMPONENT_LIMIT} bits wide. Widen the descriptor mask (descriptor.ts + abi.zig, a SIM_ABI_VERSION bump) to raise it.`,{componentCount:this.componentCount,limit:h.STORE_DESCRIPTOR_COMPONENT_LIMIT});const s=Object.keys(t),n=new Array(s.length),r=Object.create(null);for(let a=0;a<s.length;a++)r[s[a]]=a,n[a]=t[s[a]];this._rejectNonDeterministicFields(s,n,"component");const i=Rt(this.componentCount++);this.componentMetas.push({name:e,fieldNames:s,fieldIndex:r,fieldTypes:n,obsAdd:!1,obsRem:!1,obsDisable:!1,obsEnable:!1,trackDirty:!1});const o=vt(i);return e!==void 0&&h.setComponentDebugName(o,e),o}componentLabel(t){const e=this.componentMetas[t]?.name;return e!==void 0?`'${e}' (component ${t})`:`component ${t}`}fieldIdOf(t,e){const s=t.id,n=this.componentMetas[s];if(n===void 0)throw new h.ECSError(h.ECS_ERROR.COMPONENT_NOT_REGISTERED,`field_id_of: component ${s} is not registered`);const r=n.fieldIndex[e];if(r===void 0)throw new h.ECSError(h.ECS_ERROR.FIELD_NOT_REGISTERED,`field_id_of: component ${s} has no field "${e}"`);return r}registerSparseComponent(t,e){const s=Object.keys(t),n=new Array(s.length);for(let r=0;r<s.length;r++)n[r]=t[s[r]];return this._rejectNonDeterministicFields(s,n,"sparse component"),this._pushSparseStore(s,n,e)}sparseLabel(t){const e=this.sparseNames[t];return e!==void 0?`'${e}' (sparse component ${t})`:`sparse component ${t}`}_pushSparseStore(t,e,s){const n=this.sparseStores.length;return this.sparseStores.push(new h.SparseComponentStore(t,e)),this.sparseNames.push(s),h.unsafeCast(n)}sparseStoreOf(t){const e=t,s=this.sparseStores[e];if(s===void 0)throw new h.ECSError(h.ECS_ERROR.COMPONENT_NOT_REGISTERED,`sparse component ${e} is not registered`);return s}addSparse(t,e,s){this.isAlive(t)&&this.sparseStoreOf(e).setRow(h.getEntityIndex(t),s??h.EMPTY_VALUES)}removeSparse(t,e){this.isAlive(t)&&this.sparseStoreOf(e).remove(h.getEntityIndex(t))}hasSparse(t,e){return this.isAlive(t)?this.sparseStoreOf(e).has(h.getEntityIndex(t)):!1}getSparseField(t,e,s){const n=this.sparseStoreOf(e),r=n.fieldIndex[s];if(r===void 0)return 0;const i=n.getField(h.getEntityIndex(t),r);return i===void 0?0:i}setSparseField(t,e,s,n){const r=this.sparseStoreOf(e),i=r.fieldIndex[s];i!==void 0&&r.setField(h.getEntityIndex(t),i,n)}_purgeSparse(t){const e=this.sparseStores;for(let s=0;s<e.length;s++)e[s].remove(t)}snapshotSparse(){return this._requireDeterministic("snapshot_sparse()"),this._snapshots.snapshotSparse()}restoreSparse(t){this._requireDeterministic("restore_sparse()"),this._snapshots.restoreSparse(t)}snapshot(){return this._requireDeterministic("snapshot()"),this._snapshots.snapshot()}restoreInto(t){this._requireDeterministic("restoreInto()"),this._snapshots.restoreInto(t)}_mountRestoredDense(t){this._columnStore=t;const e=this.archGraph.archetypes;for(let s=0;s<e.length;s++)e[s].isBufferBacked&&e[s].refreshViews(this._columnStore);this.entityAllocator.setHighWater(t.view.getUint32(t.header.entityIndexOff+h.ENTITY_INDEX_HEADER_OFFSETS.length,!0)),this._handleBufferResized()}_reconstructHostRows(t){const e=this.entityAllocator.highWater,s=this.entityArchetype,n=this.entityRow,r=this.entityAllocator.generations,i=new Map;for(let o=0;o<e;o++){const a=s[o];if(a===h.UNASSIGNED)continue;const l=n[o];if(l===h.UNASSIGNED)continue;let u=i.get(a);u===void 0&&(u=[],i.set(a,u)),u[l]=h.createEntityId(o,r[o])}for(let o=0;o<t.archetypeRows.length;o++){const a=t.archetypeRows[o],l=this.archGet(a.archetypeId),u=i.get(a.archetypeId)??[];l.restoreHostRows(u,a.enabledCount)}}registerRelation(t){return this.relationService.registerRelation(t)}get relationCount(){return this.relationService.count}addRelation(t,e,s){this.relationService.addRelation(t,e,s)}removeRelation(t,e,s){this.relationService.removeRelation(t,e,s)}targetOf(t,e){return this.relationService.targetOf(t,e)}targetsOf(t,e){return this.relationService.targetsOf(t,e)}sourcesOf(t,e){return this.relationService.sourcesOf(t,e)}hasRelation(t,e){return this.relationService.hasRelation(t,e)}pairsOf(t){return this.relationService.pairsOf(t)}sourcesOfAny(t){return this.relationService.sourcesOfAny(t)}relationBackingSparseId(t){return this.relationService.relationBackingSparseId(t)}_forEachRelationTargetMatch(t,e,s,n,r,i,o,a){this.relationService.forEachRelationTargetMatch(t,e,s,n,r,i,o,a)}compactRelations(){return this.relationService.compactRelations()}ancestorsOf(t,e){return this.relationService.ancestorsOf(t,e)}rootOf(t,e){return this.relationService.rootOf(t,e)}cascadeOf(t,e){return this.relationService.cascadeOf(t,e)}_forEachSparseMatch(t,e,s,n,r,i,o,a){const l=this.sparseStores;if(n.length>0){let d=l[n[0]];for(let _=1;_<n.length;_++){const m=l[n[_]];m.size<d.size&&(d=m)}const f=d.indices,p=this.entityAllocator.generations,y=this.entityArchetype,g=this.entityRow,E=this.archGraph.archetypes;for(let _=0;_<f.length;_++){const m=f[_];let S=!0;for(let w=0;w<n.length;w++){const k=l[n[w]];if(k!==d&&!k.has(m)){S=!1;break}}if(!S)continue;for(let w=0;w<r.length;w++)if(l[r[w]].has(m)){S=!1;break}if(!S)continue;const v=y[m];if(v===h.UNASSIGNED)continue;const C=E[v],R=C.mask;if(R.contains(t)&&!(e!==null&&R.overlaps(e))&&!(s!==null&&!R.overlaps(s))){if(!a){const w=g[m];if(w!==h.UNASSIGNED&&w>=C.enabledCount)continue}o(h.createEntityId(m,p[m]))}}return}const u=r.length>0;for(let d=0;d<i.length;d++){const f=i[d],p=f.entityIds,y=a?f.totalCount:f.enabledCount;for(let g=0;g<y;g++){const E=p[g];if(u){const _=h.getEntityIndex(E);let m=!1;for(let S=0;S<r.length;S++)if(l[r[S]].has(_)){m=!0;break}if(m)continue}o(E)}}}_forEachHierarchyMatch(t,e,s,n,r,i,o,a,l,u){this.relationService.forEachHierarchyMatch(t,e,s,n,r,i,o,a,l,u)}addComponent(t,e,s){if(!this.isAlive(t))return;const n=h.getEntityIndex(t),r=this.entityArchetype[n],i=this.archGet(r);if(i.hasComponent(e.id)){i.writeFields(this.entityRow[n],e.id,s,this._tick);return}const o=this.archResolveAdd(r,e.id),a=this.archGet(o),l=this.entityRow[n];let u;if(l!==h.UNASSIGNED){const d=i.length,f=a.length,p=a.enabledCount,y=i.getEdge(e.id);!a.hasColumns&&!i.hasColumns?a.moveEntityFromTag(i,l,t,this.entityRow):a.moveEntityFrom(i,l,t,y.addMap,this._tick,this.entityRow),u=A[0],this._onArchLenChange(i,d),this._onArchGrow(a,f,p)}else{const d=a.length,f=a.enabledCount;u=a.hasColumns?a.addEntity(t,this.entityRow):a.addEntityTag(t,this.entityRow),this._onArchGrow(a,d,f)}a.writeFields(u,e.id,s,this._tick),this.entityArchetype[n]=o,this.entityRow[n]=u}addComponents(t,e){if(!this.isAlive(t))return;const s=h.getEntityIndex(t),n=this.entityArchetype[s],r=this.archGet(n),i=e.length;let o=i;for(let f=0;f<i;f++){const p=e[f].def.id;if(p>=yt-1||i>me){o=J;break}o=o*yt+(p+1)}if(o!==J){const f=r.getCompositeAddEdge(o);if(f!==void 0){this._addComponentsInto(t,s,r,this.archGet(f.target),f.target,f.map,e);return}}let a=null;for(let f=0;f<i;f++){const p=e[f].def.id;a!==null?a.set(p):r.mask.has(p)||(a=r.mask.copyInto(this._scratchTargetMask),a.set(p))}if(a===null){const f=this.entityRow[s];for(let p=0;p<i;p++)r.writeFields(f,e[p].def.id,e[p].values??h.EMPTY_VALUES,this._tick);return}const l=this.archGetOrCreateFromMask(a),u=this.archGet(l),d=r.getBatchTransitionMap(u);o!==J&&r.cacheCompositeAddEdge(o,l,d),this._addComponentsInto(t,s,r,u,l,d,e)}_addComponentsInto(t,e,s,n,r,i,o){const a=this.entityRow[e];let l;if(a!==h.UNASSIGNED){const u=s.length,d=n.length,f=n.enabledCount;n.moveEntityFrom(s,a,t,i,this._tick,this.entityRow),l=A[0],this._onArchLenChange(s,u),this._onArchGrow(n,d,f)}else{const u=n.length,d=n.enabledCount;l=n.addEntity(t,this.entityRow),this._onArchGrow(n,u,d)}for(let u=0;u<o.length;u++)n.writeFields(l,o[u].def.id,o[u].values??h.EMPTY_VALUES,this._tick);this.entityArchetype[e]=r,this.entityRow[e]=l}removeComponent(t,e){if(!this.isAlive(t))return;const s=h.getEntityIndex(t),n=this.entityArchetype[s],r=this.archGet(n);if(!r.hasComponent(e.id))return;const i=this.archResolveRemove(n,e.id),o=this.archGet(i),a=this.entityRow[s],l=r.getEdge(e.id),u=!o.hasColumns&&!r.hasColumns,d=r.length,f=o.length,p=o.enabledCount;u?o.moveEntityFromTag(r,a,t,this.entityRow):o.moveEntityFrom(r,a,t,l.removeMap,this._tick,this.entityRow),this.entityArchetype[s]=i,this.entityRow[s]=A[0],this._onArchLenChange(r,d),this._onArchGrow(o,f,p)}removeComponents(t,e){if(!this.isAlive(t))return;const s=h.getEntityIndex(t),n=this.entityArchetype[s],r=this.archGet(n);let i=null;for(let y=0;y<e.length;y++){const g=e[y].id;i!==null?i.clear(g):r.mask.has(g)&&(i=r.mask.copyInto(this._scratchTargetMask),i.clear(g))}if(i===null)return;const o=this.archGetOrCreateFromMask(i),a=this.archGet(o),l=this.entityRow[s],u=r.length,d=a.length,f=a.enabledCount,p=r.getBatchTransitionMap(a);a.moveEntityFrom(r,l,t,p,this._tick,this.entityRow),this.entityArchetype[s]=o,this.entityRow[s]=A[0],this._onArchLenChange(r,u),this._onArchGrow(a,d,f)}hasComponent(t,e){if(!this.isAlive(t))return!1;const s=h.getEntityIndex(t);return this.archGet(this.entityArchetype[s]).hasComponent(e.id)}batchAddComponent(t,e,s){const n=this.archGet(t);if(n.length===0)return;const r=e.id;if(n.mask.has(r))return;const i=this.archResolveAdd(n.id,r),o=this.archGet(i);if(n.disabledCount>0||o.disabledCount>0)throw new h.ECSError(h.ECS_ERROR.PARTITION_BULK_INTO_DISABLED,"batchAddComponent is unsupported on archetypes with disabled entities — enable them first or use per-entity addComponent");const a=n.getEdge(r),l=n.length,u=l,d=o.length,f=o.enabledCount,p=this.entityArchetype,y=this.entityRow,g=o.bulkMoveAllFrom(n,a.addMap,this._tick);for(let _=0;_<l;_++){const m=h.getEntityIndex(o.entityIds[g+_]);p[m]=i,y[m]=g+_}this.componentMetas[r].fieldNames.length>0&&s&&o.bulkWriteFields(g,l,r,s,this._tick),this._onArchLenChange(n,u),this._onArchGrow(o,d,f)}batchRemoveComponent(t,e){const s=this.archGet(t);if(s.length===0)return;const n=e.id;if(!s.mask.has(n))return;const r=this.archResolveRemove(s.id,n),i=this.archGet(r);if(s.disabledCount>0||i.disabledCount>0)throw new h.ECSError(h.ECS_ERROR.PARTITION_BULK_INTO_DISABLED,"batchRemoveComponent is unsupported on archetypes with disabled entities — enable them first or use per-entity removeComponent");const o=s.getEdge(n),a=s.length,l=a,u=this.entityArchetype,d=this.entityRow;if(!i.materializesRows){const g=s.entityIds;for(let E=0;E<a;E++){const _=h.getEntityIndex(g[E]);u[_]=r,d[_]=h.UNASSIGNED}s.clearRows(),this._onArchLenChange(s,l);return}const f=i.length,p=i.enabledCount,y=i.bulkMoveAllFrom(s,o.removeMap,this._tick);for(let g=0;g<a;g++){const E=h.getEntityIndex(i.entityIds[y+g]);u[E]=r,d[E]=y+g}this._onArchLenChange(s,l),this._onArchGrow(i,f,p)}getEntityArchetype(t){return this.archGet(this.entityArchetype[h.getEntityIndex(t)])}getEntityRow(t){return this.entityRow[h.getEntityIndex(t)]}getMatchingArchetypes(t,e,s){const n=t._words;let r=!1;for(let l=0;l<n.length;l++)if(n[l]!==0){r=!0;break}if(!r){const l=this.archGraph.archetypes,u=[];for(let d=0;d<l.length;d++){const f=l[d];(!e||!f.mask.overlaps(e))&&(!s||f.mask.overlaps(s))&&u.push(f)}return u}let i,o=!1;for(let l=0;l<n.length;l++){let u=n[l];if(u===0)continue;const d=l<<T.BITS_PER_WORD_SHIFT;for(;u!==0;){const f=u&-u>>>0,p=d+(T.BITS_PER_WORD_MASK-Math.clz32(f));u^=f;const y=this.archGraph.componentIndex[p];if(y===void 0||y.length===0){o=!0;break}(!i||y.length<i.length)&&(i=y)}if(o)break}if(o||!i)return[];const a=[];for(let l=0;l<i.length;l++){const u=this.archGet(i[l]);u.matches(t)&&(!e||!u.mask.overlaps(e))&&(!s||u.mask.overlaps(s))&&a.push(u)}return a}registerQuery(t,e,s){const n=this.getMatchingArchetypes(t,e,s);return this.registeredQueries.push({includeMask:t.copy(),excludeMask:e?e.copy():null,anyOfMask:s?s.copy():null,result:n,query:null}),n}updateQueryRef(t,e){const s=this.registeredQueries;for(let n=0;n<s.length;n++)if(s[n].result===t){s[n].query=e;return}}get archetypeCount(){return this.archGraph.archetypes.length}registerEvent(t){return this.events.registerEvent(t)}emitEvent(t,e){this.events.emitEvent(t,e)}emitSignal(t){this.events.emitSignal(t)}getEventReader(t){return this.events.getEventReader(t)}clearEvents(){this.events.clearEvents()}_devBufferedEventCount(){return this.events.devBufferedEventCount()}registerEventByKey(t,e){return this.events.registerEventByKey(t,e)}getEventDefByKey(t){return this.events.getEventDefByKey(t)}hasEventKey(t){return this.events.hasEventKey(t)}resources=new Vt;registerResource(t,e){this.resources.register(t,e)}getResource(t){return this.resources.get(t)}setResource(t,e){this.resources.set(t,e)}removeResource(t){this.resources.remove(t)}hasResource(t){return this.resources.has(t)}}class Se{store;constructor(t){this.store=t}register(t){return this.store.registerRelation(t)}get count(){return this.store.relationCount}add(t,e,s){return this.store.addRelation(t,e,s),this}remove(t,e,s){return this.store.removeRelation(t,e,s),this}has(t,e){return this.store.hasRelation(t,e)}targetOf(t,e){return this.store.targetOf(t,e)}targetsOf(t,e){return this.store.targetsOf(t,e)}sourcesOf(t,e){return this.store.sourcesOf(t,e)}pairsOf(t){return this.store.pairsOf(t)}sourcesOfAny(t){return this.store.sourcesOfAny(t)}ancestorsOf(t,e){return this.store.ancestorsOf(t,e)}rootOf(t,e){return this.store.rootOf(t,e)}cascadeOf(t,e){return this.store.cascadeOf(t,e)}compact(){return this.store.compactRelations()}}class Ce{store;constructor(t){this.store=t}register(t,e){this.store.registerEventByKey(t,e)}registerSignal(t){this.store.registerEventByKey(t,[])}emit(t,e){const s=this.store.getEventDefByKey(t);e===void 0?this.store.emitSignal(s):this.store.emitEvent(s,e)}read(t){const e=this.store.getEventDefByKey(t);return this.store.getEventReader(e)}}class Re{store;constructor(t){this.store=t}register(t,e){this.store.registerResource(t,e)}get(t){return h.unsafeCast(this.store.getResource(t))}set(t,e){this.store.setResource(t,e)}remove(t){this.store.removeResource(t)}has(t){return this.store.hasResource(t)}}class ve{store;constructor(t){this.store=t}get deterministic(){return this.store.deterministic}stateHash(){return this.store.stateHash()}capture(){return this.store.snapshot()}restore(t){this.store.restoreInto(t)}captureSparse(){return this.store.snapshotSparse()}restoreSparse(t){this.store.restoreSparse(t)}}const Et=new WeakMap;function it(c,t){let e=Et.get(c);if(!e){e=Object.create(null);const{fieldNames:n}=c.layout;for(let r=0;r<n.length;r++){const i=c.columns[r];Object.defineProperty(e,n[r],{get(){return i.buf[this._row]},set(o){i.buf[this._row]=o},enumerable:!0,configurable:!1})}Et.set(c,e)}const s=Object.create(e);return s._row=t,s}class be{dedup=new Map;andSingle=new Map;notSingle=new Map;anyOfSingle=new Map;changedSingle=new Map;optionalSingle=new Map;withSparseSingle=new Map;withoutSparseSingle=new Map;withRelationSingle=new Map;withoutRelationSingle=new Map;includeDisabledSingle=new Map;hierarchySingle=new Map;findDedup(t,e,s,n){const r=this.dedup.get(t);if(r)for(let i=0;i<r.length;i++){const o=r[i];if(!(!o.includeMask.equals(e)||!(s===null?o.excludeMask===null:o.excludeMask!==null&&o.excludeMask.equals(s))||!(n===null?o.anyOfMask===null:o.anyOfMask!==null&&o.anyOfMask.equals(n))))return o}}addDedup(t,e){Tt(this.dedup,t,e)}}const mt=Object.freeze([]),Ie=Object.freeze([]),wt=Object.freeze([]),ot=Number.POSITIVE_INFINITY;function H(c,t){return(c<<16|t)>>>0}function j(c,t){for(let e=0;e<c.length;e++)if(c[e]===t)return c;return[...c,t]}function Ae(c,t){for(let e=0;e<c.length;e++)if(c[e]===t)return c;return[...c,t]}function St(c,t){for(let e=0;e<c.length;e++)if(c[e]===t)return c;return[...c,t]}class Dt{_arch;_tick=0;mut(t){return this._arch.columnGroupMut(t,this._tick)}read(t){return this._arch.columnGroupRead(t)}}class D{_archetypes;_defs;_resolver;_include;_exclude;_anyOf;_nonEmptyArchetypes=[];_lastSeenEpoch=-1;_id;_sparseInclude;_sparseExclude;_optional;_includeDisabled;_relationIncludes;_relationExcludes;_hierarchy;constructor(t,e,s,n,r,i,o,a=mt,l=mt,u=Ie,d=!1,f=wt,p=wt,y=null){this._archetypes=t,this._defs=e,this._resolver=s,this._include=n,this._exclude=r,this._anyOf=i,this._id=o,this._sparseInclude=a,this._sparseExclude=l,this._optional=u,this._includeDisabled=d,this._relationIncludes=f,this._relationExcludes=p,this._hierarchy=y}_assertDenseOnly(t){if(this._sparseInclude.length>0||this._sparseExclude.length>0||this._relationIncludes.length>0||this._relationExcludes.length>0||this._hierarchy!==null)throw new h.ECSError(h.ECS_ERROR.SPARSE_QUERY_DENSE_PATH,`Query.${t} ignores sparse / relation-wildcard / hierarchy terms (withSparse / withoutSparse / withRelation / withoutRelation / hierarchy) — it walks only the dense archetype list and would return the wrong result (a hierarchy term has no per-archetype span — its order spans archetypes). Iterate this query with forEachEntity instead.`)}_isDenseOnly(){return this._sparseInclude.length===0&&this._sparseExclude.length===0&&this._relationIncludes.length===0&&this._relationExcludes.length===0&&this._hierarchy===null}firstEntity(){if(this._isDenseOnly()){const e=this._nonEmpty();for(let s=0;s<e.length;s++)if((this._includeDisabled?e[s].totalCount:e[s].enabledCount)>0)return e[s].entityIds[0];return}let t;return this.forEachEntity(e=>{t===void 0&&(t=e)}),t}singleEntity(){return this.firstEntity()}_countViaWalk(){let t=0;return this.forEachEntity(()=>{t++}),t}get archetypeCount(){return this._archetypes.length}get entityCount(){const t=this._nonEmpty();let e=0;if(this._includeDisabled)for(let s=0;s<t.length;s++)e+=t[s].totalCount;else for(let s=0;s<t.length;s++)e+=t[s].enabledCount;return e}get archetypes(){return this._archetypes}_carryNondense(t){return this._optional.length===0&&this._sparseInclude.length===0&&this._sparseExclude.length===0&&!this._includeDisabled&&this._relationIncludes.length===0&&this._relationExcludes.length===0&&this._hierarchy===null?t:new D(t._archetypes,t._defs,this._resolver,t._include,t._exclude,t._anyOf,this._resolver._nextQueryId(),this._sparseInclude,this._sparseExclude,this._optional,this._includeDisabled,this._relationIncludes,this._relationExcludes,this._hierarchy)}and(...t){if(t.length===1){const s=t[0].id,n=(this._id<<16|s)>>>0,r=this._resolver._caches.andSingle.get(n);return r!==void 0?r:this._andMiss(t[0],s,n)}let e=this;for(let s=0;s<t.length;s++)e=e.and(t[s]);return e}_andMiss(t,e,s){const n=this._include.copy(),r=this._defs.slice();n.has(e)||(n.set(e),r.push(t));const i=this._carryNondense(this._resolver._resolveQuery(n,this._exclude,this._anyOf,r));return this._resolver._caches.andSingle.set(s,i),i}without(...t){if(t.length===1){const s=t[0].id,n=(this._id<<16|s)>>>0,r=this._resolver._caches.notSingle.get(n);return r!==void 0?r:this._notMiss(s,n)}let e=this;for(let s=0;s<t.length;s++)e=e.without(t[s]);return e}_notMiss(t,e){const s=this._exclude?this._exclude.copy():new T.BitSet;s.set(t);const n=this._carryNondense(this._resolver._resolveQuery(this._include,s,this._anyOf,this._defs));return this._resolver._caches.notSingle.set(e,n),n}withSparse(...t){if(t.length===1)return this._withSparseOne(t[0]);let e=this;for(let s=0;s<t.length;s++)e=e._withSparseOne(t[s]);return e}_withSparseOne(t){const e=H(this._id,t),s=this._resolver._caches.withSparseSingle,n=s.get(e);if(n!==void 0)return n;const r=this._deriveSparse(j(this._sparseInclude,t),this._sparseExclude);return s.set(e,r),r}withoutSparse(...t){if(t.length===1)return this._withoutSparseOne(t[0]);let e=this;for(let s=0;s<t.length;s++)e=e._withoutSparseOne(t[s]);return e}_withoutSparseOne(t){const e=H(this._id,t),s=this._resolver._caches.withoutSparseSingle,n=s.get(e);if(n!==void 0)return n;const r=this._deriveSparse(this._sparseInclude,j(this._sparseExclude,t));return s.set(e,r),r}_deriveSparse(t,e){return new D(this._archetypes,this._defs,this._resolver,this._include,this._exclude,this._anyOf,this._resolver._nextQueryId(),t,e,this._optional,this._includeDisabled,this._relationIncludes,this._relationExcludes,this._hierarchy)}withRelation(...t){if(t.length===1)return this._withRelationOne(t[0]);let e=this;for(let s=0;s<t.length;s++)e=e._withRelationOne(t[s]);return e}_withRelationOne(t){const e=H(this._id,t),s=this._resolver._caches.withRelationSingle,n=s.get(e);if(n!==void 0)return n;const r=this._resolver._relationBackingSparseId(t),i=this._deriveRelation(j(this._sparseInclude,r),this._sparseExclude,St(this._relationIncludes,t),this._relationExcludes);return s.set(e,i),i}withoutRelation(...t){if(t.length===1)return this._withoutRelationOne(t[0]);let e=this;for(let s=0;s<t.length;s++)e=e._withoutRelationOne(t[s]);return e}_withoutRelationOne(t){const e=H(this._id,t),s=this._resolver._caches.withoutRelationSingle,n=s.get(e);if(n!==void 0)return n;const r=this._resolver._relationBackingSparseId(t),i=this._deriveRelation(this._sparseInclude,j(this._sparseExclude,r),this._relationIncludes,St(this._relationExcludes,t));return s.set(e,i),i}_deriveRelation(t,e,s,n){return new D(this._archetypes,this._defs,this._resolver,this._include,this._exclude,this._anyOf,this._resolver._nextQueryId(),t,e,this._optional,this._includeDisabled,s,n,this._hierarchy)}hierarchy(t,e=ot){if(e===ot){const s=H(this._id,t),n=this._resolver._caches.hierarchySingle,r=n.get(s);if(r!==void 0)return r;const i=this._deriveHierarchy({relation:t,maxDepth:e});return n.set(s,i),i}return this._deriveHierarchy({relation:t,maxDepth:e})}_deriveHierarchy(t){return new D(this._archetypes,this._defs,this._resolver,this._include,this._exclude,this._anyOf,this._resolver._nextQueryId(),this._sparseInclude,this._sparseExclude,this._optional,this._includeDisabled,this._relationIncludes,this._relationExcludes,t)}_checkRelationAccess(){for(let t=0;t<this._relationIncludes.length;t++)h.accessCheck.checkRelationRead(this._relationIncludes[t]);for(let t=0;t<this._relationExcludes.length;t++)h.accessCheck.checkRelationRead(this._relationExcludes[t])}forEachRelatedTo(t,e){this._resolver._forEachRelationTargetMatch(t,this._include,this._exclude,this._anyOf,this._sparseInclude,this._sparseExclude,this._includeDisabled,e)}optional(...t){if(t.length===1)return this._optionalOne(t[0].id);let e=this;for(let s=0;s<t.length;s++)e=e._optionalOne(t[s].id);return e}_optionalOne(t){const e=(this._id<<16|t)>>>0,s=this._resolver._caches.optionalSingle,n=s.get(e);if(n!==void 0)return n;const r=this._deriveOptional(Ae(this._optional,t));return s.set(e,r),r}_deriveOptional(t){return new D(this._archetypes,this._defs,this._resolver,this._include,this._exclude,this._anyOf,this._resolver._nextQueryId(),this._sparseInclude,this._sparseExclude,t,this._includeDisabled,this._relationIncludes,this._relationExcludes,this._hierarchy)}includeDisabled(){if(this._includeDisabled)return this;const t=this._resolver._caches.includeDisabledSingle,e=t.get(this._id);if(e!==void 0)return e;const s=new D(this._archetypes,this._defs,this._resolver,this._include,this._exclude,this._anyOf,this._resolver._nextQueryId(),this._sparseInclude,this._sparseExclude,this._optional,!0,this._relationIncludes,this._relationExcludes,this._hierarchy);return t.set(this._id,s),s}forEach(t){if(this._includeDisabled){this._forEachIncludeDisabled(t);return}const e=this._nonEmpty();for(let s=0;s<e.length;s++)t(e[s])}_forEachIncludeDisabled(t){const e=x(!0);try{this._forEachInner(t)}finally{x(e)}}eachChunk(t){if(this._includeDisabled){const e=x(!0);try{this._eachChunkInner(t)}finally{x(e)}return}this._eachChunkInner(t)}_eachChunkInner(t){const e=new Dt;e._tick=this._resolver._getCurrentTick();const s=this._nonEmpty();for(let n=0;n<s.length;n++)e._arch=s[n],t(e,s[n].entityCount)}forEachUntil(t){if(this._includeDisabled){const e=x(!0);try{return this._forEachUntilInner(t)}finally{x(e)}}return this._forEachUntilInner(t)}_forEachUntilInner(t){const e=this._nonEmpty();for(let s=0;s<e.length;s++)if(t(e[s]))return!0;return!1}_forEachInner(t){const e=this._nonEmpty();for(let s=0;s<e.length;s++)t(e[s])}forEachEntity(t){if(this._hierarchy!==null){this._resolver._forEachHierarchyMatch(this._include,this._exclude,this._anyOf,this._sparseInclude,this._sparseExclude,this._nonEmpty(),this._hierarchy.relation,this._hierarchy.maxDepth,this._includeDisabled,t);return}this._resolver._forEachSparseMatch(this._include,this._exclude,this._anyOf,this._sparseInclude,this._sparseExclude,this._nonEmpty(),t,this._includeDisabled)}_nonEmpty(){const t=this._resolver._getQueryDirtyEpoch();return this._lastSeenEpoch!==t&&this._rebuildNonEmpty(t),this._nonEmptyArchetypes}_rebuildNonEmpty(t){const e=this._archetypes,s=[];if(this._includeDisabled)for(let n=0;n<e.length;n++)e[n].totalCount>0&&s.push(e[n]);else for(let n=0;n<e.length;n++)e[n].enabledCount>0&&s.push(e[n]);this._nonEmptyArchetypes=s,this._lastSeenEpoch=t}anyOf(...t){if(t.length===1){const s=t[0].id,n=(this._id<<16|s)>>>0,r=this._resolver._caches.anyOfSingle.get(n);return r!==void 0?r:this._anyOfMiss(s,n)}let e=this;for(let s=0;s<t.length;s++)e=e.anyOf(t[s]);return e}_anyOfMiss(t,e){const s=this._anyOf?this._anyOf.copy():new T.BitSet;s.set(t);const n=this._carryNondense(this._resolver._resolveQuery(this._include,this._exclude,s,this._defs));return this._resolver._caches.anyOfSingle.set(e,n),n}changed(...t){if(t.length===1){const s=t[0].id,n=(this._id<<16|s)>>>0,r=this._resolver._caches.changedSingle.get(n);return r!==void 0?r:this._changedMiss(s,n)}const e=new Array(t.length);for(let s=0;s<t.length;s++)e[s]=t[s].id;return new M(this,e)}_changedMiss(t,e){const s=new M(this,[t]);return this._resolver._caches.changedSingle.set(e,s),s}_ctxLastRunTick(){return this._resolver._getLastRunTick()}}class kt{constructor(t){this._resolver=t}with(...t){const e=new T.BitSet;for(let s=0;s<t.length;s++)e.set(t[s].id);return this._resolver._resolveQuery(e,null,null,t)}}class xt{constructor(t){this.store=t}spawn(...t){const e=this.store.createEntity();for(let s=0;s<t.length;s++){const n=G(t[s]);this.store.addComponentDeferred(e,n,$(t[s]))}return e}add(t,...e){if(e.length===2&&typeof e[0]=="function"&&e[1]!==null&&typeof e[1]=="object"&&typeof e[1].def!="function"){const s=e[0];return this.store.addComponentDeferred(t,s,e[1]),this}for(let s=0;s<e.length;s++){const n=e[s],r=G(n);this.store.addComponentDeferred(t,r,$(n))}return this}remove(t,e){return this.store.removeComponentDeferred(t,e),this}despawn(t){const e=t;return this.store.destroyEntityDeferred(e),this}disable(t){return this.store.disableEntityDeferred(t),this}enable(t){return this.store.enableEntityDeferred(t),this}}class Mt{constructor(t){this.store=t,this.commands=new xt(t)}lastRunTick=0;commands;get ecsTick(){return this.store._tick}get _trace(){return this.store._trace}isAlive(t){return this.store.isAlive(t)}hasComponent(t,e){return this.store.hasComponent(t,e)}getField(t,e,s){const n=this.store.getEntityArchetype(t),r=this.store.getEntityRow(t);return n.readField(r,e.id,s)}tryGetField(t,e,s){if(!this.store.hasComponent(t,e))return;const n=this.store.getEntityArchetype(t),r=this.store.getEntityRow(t);return n.readField(r,e.id,s)}setField(t,e,s,n){const r=this.store.getEntityArchetype(t),i=this.store.getEntityRow(t),o=r.getColumn(e,s,this.store._tick);o[i]=n,this.store._anyDirtyTracked&&this.store._noteSet(e,t)}updateField(t,e,s,n){const r=this.store.getEntityArchetype(t),i=this.store.getEntityRow(t),o=n(r.readField(i,e.id,s)),a=r.getColumn(e,s,this.store._tick);return a[i]=o,this.store._anyDirtyTracked&&this.store._noteSet(e,t),o}markChanged(t,e){this.store._anyDirtyTracked&&this.store._noteSet(e,t)}ref(t,e){const s=this.store.getEntityArchetype(e),n=this.store.getEntityRow(e);return s._changedTick[t.id]=this.store._tick,it(s.columnGroups[t.id],n)}refRead(t,e){const s=this.store.getEntityArchetype(e),n=this.store.getEntityRow(e);return it(s.columnGroups[t.id],n)}isDisabled(t){return this.store.isDisabled(t)}addSparse(t,e,...s){return this.store.addSparse(t,e,s[0]),this}removeSparse(t,e){return this.store.removeSparse(t,e),this}hasSparse(t,e){return this.store.hasSparse(t,e)}getSparseField(t,e,s){return this.store.getSparseField(t,e,s)}setSparseField(t,e,s,n){this.store.setSparseField(t,e,s,n)}addRelation(t,e,s){return this.store.addRelation(t,e,s),this}removeRelation(t,e,s){return this.store.removeRelation(t,e,s),this}targetOf(t,e){return this.store.targetOf(t,e)}targetsOf(t,e){return this.store.targetsOf(t,e)}sourcesOf(t,e){return this.store.sourcesOf(t,e)}hasRelation(t,e){return this.store.hasRelation(t,e)}flush(){this.store.flushStructural(),this.store.flushDestroyed(),this.store.publishRowCountsToDescriptor()}emit(t,e){const s=this.store.getEventDefByKey(t);e===void 0?this.store.emitSignal(s):this.store.emitEvent(s,e)}read(t){const e=this.store.getEventDefByKey(t);return this.store.getEventReader(e)}getResource(t){return h.unsafeCast(this.store.getResource(t))}setResource(t,e){this.store.setResource(t,e)}removeResource(t){this.store.removeResource(t)}hasResource(t){return this.store.hasResource(t)}}class M{_query;_changedIds;constructor(t,e){this._query=t,this._changedIds=e}and(...t){return new M(this._query.and(...t),this._changedIds)}without(...t){return new M(this._query.without(...t),this._changedIds)}anyOf(...t){return new M(this._query.anyOf(...t),this._changedIds)}optional(...t){return new M(this._query.optional(...t),this._changedIds)}forEach(t){if(this._query._includeDisabled){this._forEachIncludeDisabled(t);return}const e=this._query._ctxLastRunTick(),s=this._query._nonEmpty(),n=this._changedIds;for(let r=0;r<s.length;r++){const i=s[r];for(let o=0;o<n.length;o++)if(i._changedTick[n[o]]>=e){t(i);break}}}_forEachIncludeDisabled(t){const e=x(!0);try{this._forEachInner(t)}finally{x(e)}}_forEachInner(t){const e=this._query._ctxLastRunTick(),s=this._query._nonEmpty(),n=this._changedIds;for(let r=0;r<s.length;r++){const i=s[r];for(let o=0;o<n.length;o++)if(i._changedTick[n[o]]>=e){t(i);break}}}}function Ct(c){if(!(c>0)||!Number.isFinite(c))throw new h.ECSError(h.ECS_ERROR.INVALID_FIXED_TIMESTEP,`fixedTimestep must be a finite number > 0, got ${c}`);return c}function Oe(c){if(!Number.isInteger(c)||c<1)throw new h.ECSError(h.ECS_ERROR.INVALID_MAX_FIXED_STEPS,`maxFixedSteps must be an integer >= 1, got ${c}`);return c}class Te{store;schedule;ctx;_observers;relations;events;resources;snapshots;systems=new Set;nextSystemId=0;_tick=0;_updating=!1;_fixedTimestep;_accumulator=0;_maxFixedSteps;scratchMask=new T.BitSet;_nextQueryIdCounter=0;_caches=new be;_layoutSubscribers=[];_backend=null;_memory;get memoryPlan(){return this._memory}get wasmMemory(){return this._memory.wasmMemory}constructor(t){const e=Object.prototype.hasOwnProperty;if(t!==void 0&&(e.call(t,"initial_capacity")||e.call(t,"buffer_allocator")))throw new h.ECSError(h.ECS_ERROR.INVALID_MEMORY_OPTIONS,"ECSOptions.initial_capacity / buffer_allocator were replaced by ECSOptions.memory: initial_capacity → memory.columnCapacity (or memory.budget); buffer_allocator → memory.wasm (WASM-backed) or memory.allocator (custom in-place).");const s=h.resolveECSMemory(t?.memory);this._memory=s,this.store=new we({initialCapacity:s.columnCapacity,bufferAllocator:s.allocator,entityIndexCapacity:s.entityIndexCapacity,capContext:{capBytes:s.capBytes,intentLabel:s.intentLabel,budgetEntities:s.budgetEntities},onBufferResized:()=>{const n=this._layoutSubscribers;for(let r=0;r<n.length;r++)n[r].setLayout(0)},regions:t?.regions,bindingsRegionBytes:t?.bindingsRegionBytes,deterministic:t?.deterministic}),this.schedule=new h.Schedule(t?.onWarn),this.relations=new Se(this.store),this.events=new Ce(this.store),this.resources=new Re(this.store),this.snapshots=new ve(this.store),this.ctx=new Mt(this.store),this._observers=new Qt(this.store,this.ctx),this.store.setStructuralObserverHook(n=>this._observers.dispatchStructural(n)),this._fixedTimestep=Ct(t?.fixedTimestep??h.DEFAULT_FIXED_TIMESTEP),this._maxFixedSteps=Oe(t?.maxFixedSteps??h.DEFAULT_MAX_FIXED_STEPS)}regionHandles(...t){const e=new Array(t.length);let s=null;for(let n=0;n<t.length;n++){const r=this.store.regionHandle(t[n]);r===null?(s??=[]).push(t[n]):e[n]=r}if(s!==null)throw new h.ECSError(h.ECS_ERROR.REGION_NOT_DECLARED,`region_handles: region id(s) [${s.join(", ")}] not declared — pass them via ECSOptions.regions`);return e}onStoreLayoutPublished(t){return this._layoutSubscribers.push(t),t.setLayout(0),()=>{const e=this._layoutSubscribers.indexOf(t);e>=0&&this._layoutSubscribers.splice(e,1)}}attachBackend(t){this._backend=t,this.schedule.setBackend(t);const e=this.onStoreLayoutPublished(t);return()=>{e(),this._backend===t&&(this._backend=null,this.schedule.setBackend(null))}}get fixedTimestep(){return this._fixedTimestep}set fixedTimestep(t){this._fixedTimestep=Ct(t)}get fixedAlpha(){return this._accumulator/this._fixedTimestep}setTrace(t){}registerComponent(t,e,s){if(Array.isArray(t)){const r=typeof e=="string"?e:"f64",i=Object.create(null);for(const o of t)i[o]=r;return this.store.registerComponent(i,s?.name)}const n=typeof e=="object"?e:s;return this.store.registerComponent(t,n?.name)}registerSparseComponent(t,e,s){if(Array.isArray(t)){const r=typeof e=="string"?e:"f64",i=Object.create(null);for(const o of t)i[o]=r;return this.store.registerSparseComponent(i,s?.name)}const n=typeof e=="object"?e:s;return this.store.registerSparseComponent(t,n?.name)}spawn(t,e){return t===void 0?this.store.createEntity():this.store.spawn(t,e)}spawnBundle(...t){const e=this.store.createEntity();for(let s=0;s<t.length;s++){const n=t[s],r=G(n);this.store.addComponent(e,r,$(n))}return e}spawnMany(t,e,s){return this.store.spawnMany(t,e,s)}_assertHostMutationOutsideSystem(t,e){if(this._updating&&h.accessCheck.current()!==null){const s=h.accessCheck.current(),n=s.name??`system_${s.id}`;throw new h.ECSError(h.ECS_ERROR.ACCESS_UNDECLARED,`ecs.${t} called from inside system '${n}' — host ${t} is immediate and unsafe mid-iteration (and invisible to observers); use ${e} instead`,{op:t})}}despawn(t){return this.store.destroyEntity(t),this}disable(t){return this.store.disableEntity(t),this}enable(t){return this.store.enableEntity(t),this}addComponent(t,e,s){const n=G(e);return this.store.addComponent(t,n,s??$(e)),this}addComponents(t,...e){const s=[];for(let n=0;n<e.length;n++){const r=e[n];s.push({def:G(r),values:$(r)})}return this.store.addComponents(t,s),this}removeComponent(t,e){return this.store.removeComponent(t,e),this}removeComponents(t,...e){return this.store.removeComponents(t,e),this}batchAddComponent(t,e,s){return this.store.batchAddComponent(t,e,s),this}batchRemoveComponent(t,e){return this.store.batchRemoveComponent(t,e),this}getField(t,e,s){const n=this.store.getEntityArchetype(t),r=this.store.getEntityRow(t);return n.readField(r,e.id,s)}refRead(t,e){const s=this.store.getEntityArchetype(e),n=this.store.getEntityRow(e);return it(s.columnGroups[t.id],n)}tryGetField(t,e,s){if(!this.store.hasComponent(t,e))return;const n=this.store.getEntityArchetype(t),r=this.store.getEntityRow(t);return n.readField(r,e.id,s)}setField(t,e,s,n){const r=this.store.getEntityArchetype(t),i=this.store.getEntityRow(t),o=r.getColumn(e,s,this.store._tick);o[i]=n,this.store._anyDirtyTracked&&this.store._noteSet(e,t)}updateField(t,e,s,n){const r=n(this.getField(t,e,s));return this.setField(t,e,s,r),r}query(...t){const e=this.scratchMask;e._words.fill(0);for(let s=0;s<t.length;s++)e.set(t[s].id);return this._resolveQuery(e.copy(),null,null,t)}_nextQueryId(){return this._nextQueryIdCounter++}_resolveQuery(t,e,s,n){const r=t.hash(),i=e?e.hash():0,o=s?s.hash():0,a=r^Math.imul(i,h.HASH_GOLDEN_RATIO)^Math.imul(o,h.HASH_SECONDARY_PRIME)|0,l=this._caches.findDedup(a,t,e,s);if(l!==void 0)return l.query;const u=this.store.registerQuery(t,e??void 0,s??void 0),d=new D(u,n,this,t.copy(),e?.copy()??null,s?.copy()??null,this._nextQueryIdCounter++);return this.store.updateQueryRef(u,d),this._caches.addDedup(a,{includeMask:t.copy(),excludeMask:e?.copy()??null,anyOfMask:s?.copy()??null,query:d}),d}registerSystem(t,e){let s;if(typeof t=="function")if(e!==void 0){const i=e(new kt(this)),o=this.ctx,a=t;s={...nt,fn:(l,u)=>a(i,o,u)}}else s={...nt,fn:t};else s=t;const n=bt(this.nextSystemId++),r=Object.freeze({...s,...Wt(s),id:n});return this.systems.add(r),r}removeSystem(t){return this.schedule.removeSystem(t),t.onRemoved?.(),this.systems.delete(t),this}get systemCount(){return this.systems.size}startup(){this.prewarmArchetypes();try{for(const t of this.systems.values())if(t.onAdded!==void 0)try{t.onAdded(this.ctx)}finally{}this.schedule.runStartup(this.ctx,this._tick)}finally{}this.store.clearEvents()}prewarmArchetypes(){const t=De([...this.systems,...this._observers.descriptors()]);t.length!==0&&this.store.archCreateManyFromMasks(t)}update(t){try{if(this.store._tick=this._tick,this.store.publishRowCountsToDescriptor(),this.schedule.hasFixedSystems()){this._accumulator+=t;const s=this._maxFixedSteps*this._fixedTimestep;for(this._accumulator>s&&(this._accumulator=s);this._accumulator>=this._fixedTimestep;)this.schedule.runFixedUpdate(this.ctx,this._fixedTimestep,this._tick),this._accumulator-=this._fixedTimestep}this.schedule.runUpdate(this.ctx,t,this._tick);const e=O?this.store._devBufferedEventCount():0;this._observers.dispatchSet(this._tick),O&&this.store._devBufferedEventCount(),this.store.clearEvents(),this._tick++}finally{}}dispose(){for(const t of this.systems.values())t.dispose?.(),t.onRemoved?.();this.systems.clear(),this.schedule.clear()}template(...t){const e=[];for(let s=0;s<t.length;s++){const n=t[s];e.push({def:G(n),values:$(n)})}return this.store.resolveTemplate(e)}regionOffset(t){return this.store.regionOffset(t)}regionHandle(t){return this.store.regionHandle(t)}fieldId(t,e){return this.store.fieldIdOf(t,e)}entityIdAtRow(t,e){return this.store.entityIdAtRow(t,e)}get columnStore(){return this.store.columnStore}get archetypeCount(){return this.store.archetypeCount}registerTag(){return this.store.registerComponent({})}registerSparseTag(){return this.store.registerSparseComponent({})}isAlive(t){return this.store.isAlive(t)}get entityCount(){return this.store.entityCount}hasComponent(t,e){return this.store.hasComponent(t,e)}isDisabled(t){return this.store.isDisabled(t)}addSparse(t,e,s){return this.store.addSparse(t,e,s),this}removeSparse(t,e){return this.store.removeSparse(t,e),this}hasSparse(t,e){return this.store.hasSparse(t,e)}getSparseField(t,e,s){return this.store.getSparseField(t,e,s)}setSparseField(t,e,s,n){this.store.setSparseField(t,e,s,n)}_getLastRunTick(){return this.ctx.lastRunTick}_getCurrentTick(){return this.store._tick}_getQueryDirtyEpoch(){return this.store._queryDirtyEpoch}_forEachSparseMatch(t,e,s,n,r,i,o,a){this.store._forEachSparseMatch(t,e,s,n,r,i,o,a)}_relationBackingSparseId(t){return this.store.relationBackingSparseId(t)}_forEachRelationTargetMatch(t,e,s,n,r,i,o,a){this.store._forEachRelationTargetMatch(t,e,s,n,r,i,o,a)}_forEachHierarchyMatch(t,e,s,n,r,i,o,a,l,u){this.store._forEachHierarchyMatch(t,e,s,n,r,i,o,a,l,u)}addSystems(t,...e){return this.schedule.addSystems(t,...e),this}configureSet(t,e){return this.schedule.configureSet(t,e),this}observe(t,e){return this._observers.register(t,e)}publishArchetypeRowCounts(){this.store.publishRowCountsToDescriptor()}flush(){this.ctx.flush()}}function De(c){const t=new Map,e=[],s=o=>{const a=o.hash(),l=t.get(a);if(l!==void 0){for(let u=0;u<l.length;u++)if(l[u].equals(o))return;l.push(o)}else t.set(a,[o]);e.push(o)},n=o=>{const a=new T.BitSet;for(let l=0;l<o.length;l++)a.set(o[l].id);return a},r=[];for(const o of c){const a=o.transitions;for(let l=0;l<a.length;l++){const u=a[l];r.push({whenHas:n(u.whenHas),add:u.add,remove:u.remove})}}for(const o of c){const a=o.spawns;for(let l=0;l<a.length;l++)s(n(a[l]))}for(;e.length>0;){const o=e.pop();for(let a=0;a<r.length;a++){const l=r[a];if(!o.contains(l.whenHas))continue;const u=o.copy();if(l.add!==void 0)for(let d=0;d<l.add.length;d++)u.set(l.add[d].id);if(l.remove!==void 0)for(let d=0;d<l.remove.length;d++)u.clear(l.remove[d].id);s(u)}}const i=[];for(const o of t.values())for(let a=0;a<o.length;a++)i.push(o[a]);return i}function ke(c,t){return{name:`runIfResourceEq(${c.description??"?"})`,resourceReads:[c],evaluate:e=>e.getResource(c)===t}}function xe(c,t=0){const e=(t%c+c)%c;return{name:`runEveryNTicks(${c}${e!==0?`, +${e}`:""})`,evaluate:s=>(s.ecsTick-e)%c===0}}function Me(c){return{name:"runIfAnyMatch",reads:c._defs,evaluate:()=>c.entityCount>0}}function ct(c){const t=[],e=[];for(const s of c)s.reads&&t.push(...s.reads),s.resourceReads&&e.push(...s.resourceReads);return{...t.length>0?{reads:t}:{},...e.length>0?{resourceReads:e}:{}}}function Ne(c){return{name:`not(${c.name})`,...ct([c]),evaluate:t=>!c.evaluate(t)}}function Fe(...c){return{name:`allOf(${c.map(t=>t.name).join(", ")})`,...ct(c),evaluate:t=>c.every(e=>e.evaluate(t))}}function Le(...c){return{name:`anyOf(${c.map(t=>t.name).join(", ")})`,...ct(c),evaluate:t=>c.some(e=>e.evaluate(t))}}function Be(c){return c.kind==="spawn"&&c.onSpawned!==void 0?{kind:"spawn",components:c.components}:c}class Ge{seed;_startup=[];_ticks=[];sink=this._startup;constructor(t=0){this.seed=t}openTick(t,e){const s=this._ticks[this._ticks.length-1];if(s!==void 0&&s.tick===t){this.sink=s.commands;return}const n=[];this._ticks.push({tick:t,dt:e,commands:n}),this.sink=n}record=t=>{this.sink.push(Be(t))};log(){return{seed:this.seed,startup:this._startup,ticks:this._ticks}}snapshotLog(){return{seed:this.seed,startup:this._startup.map(t=>({...t})),ticks:this._ticks.map(t=>({...t,commands:t.commands.map(e=>({...e}))}))}}}const q="__component_def";function $e(c){return JSON.stringify(c,(t,e)=>{if(typeof e=="function"&&"id"in e)return{[q]:e.id};if(e!==null&&typeof e=="object"&&q in e)throw new h.ECSError(h.ECS_ERROR.COMMAND_LOG_TAG_COLLISION,`Cannot serialize the command log: a value object owns a field named "${q}", the reserved tag the serializer uses for component defs. Rename that component field so the log can round-trip losslessly.`);return e})}function Pe(c){return JSON.parse(c,(t,e)=>e!==null&&typeof e=="object"&&q in e?vt(Rt(e[q])):e)}function Ue(c,t,e,s){for(const i of e.startup)t.push(i);c.startup();const n=s?.hash??c.snapshots.deterministic,r=[];for(const i of e.ticks){for(const o of i.commands)t.push(o);c.update(i.dt),n&&r.push(c.snapshots.stateHash())}return{startupCommands:e.startup.length,ticks:e.ticks.length,stateHashes:r}}function tt(c){return c.name??`system#${c.id}`}class He{_frames=[];_current=null;tickBegin(t,e){const s={tick:t,dt:e,events:[]};this._current=s,this._frames.push(s)}tickEnd(t){this._current=null}systemStart(t,e){this._current?.events.push({kind:"system_start",system:tt(t),phase:e})}systemEnd(t){this._current?.events.push({kind:"system_end",system:tt(t)})}commandQueued(t,e,s){this._current?.events.push({kind:"command_queued",op:t,entity:e,component:s})}flushBegin(t){this._current?.events.push({kind:"flush_begin",phase:t})}flushEnd(t){this._current?.events.push({kind:"flush_end",phase:t})}phaseBoundary(t){}observerFired(t,e,s,n){this._current?.events.push({kind:"observer_fired",op:t,component:e,entity:s,observer:tt(n)})}eventEmitted(t){this._current?.events.push({kind:"event_emitted",key:t})}eventRead(t,e){this._current?.events.push({kind:"event_read",key:t,count:e})}frames(){return this._frames}reset(){this._frames.length=0,this._current=null}}function N(c,t){if(!(t>=0)||!Number.isFinite(t))throw new h.ECSError(h.ECS_ERROR.INVALID_FRAME_STEP,`${c} must be a finite number >= 0, got ${t}`);return t}function Ve(c){if(!Number.isInteger(c)||c<0)throw new h.ECSError(h.ECS_ERROR.INVALID_FRAME_STEP,`frame count must be an integer >= 0, got ${c}`);return c}class qe{ecs;requestFrame;cancelFrame;frameHandle=null;lastTimestampMs=null;running=!1;_fixedDt;_maxDt;constructor(t,e={}){this.ecs=t,this._fixedDt=N("fixedDt",e.fixedDt??1/60),this._maxDt=N("maxDt",e.maxDt??.25);const s=globalThis;this.requestFrame=e.requestFrame??s.requestAnimationFrame?.bind(globalThis),this.cancelFrame=e.cancelFrame??s.cancelAnimationFrame?.bind(globalThis),e.autoStart===!0&&this.play()}get fixedDt(){return this._fixedDt}set fixedDt(t){this._fixedDt=N("fixedDt",t)}get maxDt(){return this._maxDt}set maxDt(t){this._maxDt=N("maxDt",t)}get isRunning(){return this.running}step(t=this._fixedDt){this.ecs.update(N("dt",t))}stepFrames(t,e=this._fixedDt){Ve(t);const s=N("dt",e);for(let n=0;n<t;n++)this.ecs.update(s)}play(){if(!this.running){if(this.requestFrame===void 0)throw new h.ECSError(h.ECS_ERROR.INVALID_FRAME_STEP,"FrameStepper.play() requires requestAnimationFrame or a requestFrame option");this.running=!0,this.lastTimestampMs=null,this.scheduleNextFrame()}}pause(){this.running=!1,this.lastTimestampMs=null,this.frameHandle!==null&&this.cancelFrame!==void 0&&this.cancelFrame(this.frameHandle),this.frameHandle=null}toggle(){this.running?this.pause():this.play()}dispose(){this.pause()}scheduleNextFrame(){this.frameHandle=this.requestFrame?.(this.onFrame)??null}onFrame=t=>{if(!this.running)return;const e=this.lastTimestampMs===null?this._fixedDt:(t-this.lastTimestampMs)/1e3;this.lastTimestampMs=t,this.ecs.update(Math.min(N("dt",e),this._maxDt)),this.running&&this.scheduleNextFrame()}}function We(c,t){return c.relations.register({exclusive:!0,onDeleteTarget:t?.onDeleteTarget??"clear"})}function ze(c,t){return c.relations.register({exclusive:!0,onDeleteTarget:t?.onDeleteTarget??"delete"})}function je(c){return h.unsafeCast(Symbol(c))}const Ye="0.5.2";exports.ANY_RELATION=h.ANY_RELATION;exports.ECSError=h.ECSError;exports.ECS_ERROR=h.ECS_ERROR;exports.HostCommandQueue=h.HostCommandQueue;exports.SCHEDULE=h.SCHEDULE;exports.SparseRestoreError=h.SparseRestoreError;exports.applyHostCommand=h.applyHostCommand;exports.getEntityIndex=h.getEntityIndex;exports.installHostCommandSeam=h.installHostCommandSeam;exports.isEcsError=h.isEcsError;exports.spawnEntry=h.spawnEntry;exports.systemSet=h.systemSet;exports.uninstallHostCommandSeam=h.uninstallHostCommandSeam;exports.SabUnavailableError=V.SabUnavailableError;exports.ChangedQuery=M;exports.ChunkColumns=Dt;exports.Commands=xt;exports.ECS=Te;exports.ECSRestoreError=b;exports.ECS_SNAPSHOT_VERSION=K;exports.FrameStepper=qe;exports.FrameTraceRecorder=He;exports.HIERARCHY_UNBOUNDED=ot;exports.HostCommandRecorder=Ge;exports.Query=D;exports.QueryBuilder=kt;exports.StoreRestoreError=B;exports.SystemContext=Mt;exports.VERSION=Ye;exports.allOf=Fe;exports.anyOf=Le;exports.bundle=Ft;exports.deserializeCommandLog=Pe;exports.eventKey=Pt;exports.not=Ne;exports.registerChildOf=ze;exports.registerIsA=We;exports.replayCommandLog=Ue;exports.resourceKey=je;exports.runEveryNTicks=xe;exports.runIfAnyMatch=Me;exports.runIfResourceEq=ke;exports.serializeCommandLog=$e;exports.signalKey=Ut;
|